Skip to content

Commit ffade4a

Browse files
Create hardened versions of Get and Mutable for repeated_field.
Create `CheckedGetOrAbort` and `CheckedMutableOrAbort` for repeated_field.h. This is already similarly done for repeated_ptr_field.h. PiperOrigin-RevId: 723591137
1 parent af1e152 commit ffade4a

File tree

2 files changed

+51
-0
lines changed

2 files changed

+51
-0
lines changed

src/google/protobuf/repeated_field.h

+22
Original file line numberDiff line numberDiff line change
@@ -1437,6 +1437,28 @@ internal::RepeatedFieldBackInsertIterator<T> RepeatedFieldBackInserter(
14371437
return internal::RepeatedFieldBackInsertIterator<T>(mutable_field);
14381438
}
14391439

1440+
namespace internal {
1441+
template <typename T>
1442+
inline void CheckIndexInBoundsOrAbort(const RepeatedField<T>& field,
1443+
int index) {
1444+
if (ABSL_PREDICT_FALSE(index < 0 || index >= field.size())) {
1445+
LogIndexOutOfBoundsAndAbort(index, field.size());
1446+
}
1447+
}
1448+
1449+
template <typename T>
1450+
const T& CheckedGetOrAbort(const RepeatedField<T>& field, int index) {
1451+
CheckIndexInBoundsOrAbort(field, index);
1452+
return field.Get(index);
1453+
}
1454+
1455+
template <typename T>
1456+
inline T* CheckedMutableOrAbort(RepeatedField<T>* field, int index) {
1457+
CheckIndexInBoundsOrAbort(*field, index);
1458+
return field->Mutable(index);
1459+
}
1460+
} // namespace internal
1461+
14401462

14411463
} // namespace protobuf
14421464
} // namespace google

src/google/protobuf/repeated_field_unittest.cc

+29
Original file line numberDiff line numberDiff line change
@@ -1343,6 +1343,35 @@ TEST_F(RepeatedFieldInsertionIteratorsTest, Halves) {
13431343
protobuffer.repeated_double().end(), halves.begin()));
13441344
}
13451345

1346+
TEST(RepeatedField, CheckedGetOrAbortTest) {
1347+
RepeatedField<int> field;
1348+
1349+
// Empty container tests.
1350+
EXPECT_DEATH(CheckedGetOrAbort(field, -1), "index: -1, size: 0");
1351+
EXPECT_DEATH(CheckedGetOrAbort(field, field.size()), "index: 0, size: 0");
1352+
1353+
// Non-empty container tests
1354+
field.Add(5);
1355+
field.Add(4);
1356+
EXPECT_DEATH(CheckedGetOrAbort(field, 2), "index: 2, size: 2");
1357+
EXPECT_DEATH(CheckedGetOrAbort(field, -1), "index: -1, size: 2");
1358+
}
1359+
1360+
TEST(RepeatedField, CheckedMutableOrAbortTest) {
1361+
RepeatedField<int> field;
1362+
1363+
// Empty container tests.
1364+
EXPECT_DEATH(CheckedMutableOrAbort(&field, -1), "index: -1, size: 0");
1365+
EXPECT_DEATH(CheckedMutableOrAbort(&field, field.size()),
1366+
"index: 0, size: 0");
1367+
1368+
// Non-empty container tests
1369+
field.Add(5);
1370+
field.Add(4);
1371+
EXPECT_DEATH(CheckedMutableOrAbort(&field, 2), "index: 2, size: 2");
1372+
EXPECT_DEATH(CheckedMutableOrAbort(&field, -1), "index: -1, size: 2");
1373+
}
1374+
13461375
} // namespace
13471376

13481377
} // namespace protobuf

0 commit comments

Comments
 (0)