Skip to content

Commit e33e0d2

Browse files
Add ABSL_ATTRIBUTE_LIFETIME_BOUND attribute on generated oneof accessors.
This allows the compiler to statically detect use-after-free bugs. PiperOrigin-RevId: 569504371
1 parent 8f831e9 commit e33e0d2

File tree

8 files changed

+32
-7
lines changed

8 files changed

+32
-7
lines changed

java/core/src/test/java/com/google/protobuf/DescriptorsTest.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -920,10 +920,10 @@ public void testOneofDescriptor() throws Exception {
920920
assertThat(messageType.getOneofs().get(0)).isSameInstanceAs(oneofDescriptor);
921921
assertThat(oneofDescriptor.getName()).isEqualTo("oneof_field");
922922

923-
assertThat(oneofDescriptor.getFieldCount()).isEqualTo(4);
923+
assertThat(oneofDescriptor.getFieldCount()).isEqualTo(7);
924924
assertThat(field).isSameInstanceAs(oneofDescriptor.getField(1));
925925

926-
assertThat(oneofDescriptor.getFields()).hasSize(4);
926+
assertThat(oneofDescriptor.getFields()).hasSize(7);
927927
assertThat(field).isEqualTo(oneofDescriptor.getFields().get(1));
928928
}
929929

python/google/protobuf/internal/field_mask_test.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -53,7 +53,7 @@ def testDescriptorToFieldMask(self):
5353
mask = field_mask_pb2.FieldMask()
5454
msg_descriptor = unittest_pb2.TestAllTypes.DESCRIPTOR
5555
mask.AllFieldsFromDescriptor(msg_descriptor)
56-
self.assertEqual(76, len(mask.paths))
56+
self.assertEqual(79, len(mask.paths))
5757
self.assertTrue(mask.IsValidForDescriptor(msg_descriptor))
5858
for field in msg_descriptor.fields:
5959
self.assertTrue(field.name in mask.paths)

python/google/protobuf/internal/generator_test.py

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -344,8 +344,15 @@ def testOneof(self):
344344
self.assertEqual(0, desc.oneofs[0].index)
345345
self.assertIs(desc, desc.oneofs[0].containing_type)
346346
self.assertIs(desc.oneofs[0], desc.oneofs_by_name['oneof_field'])
347-
nested_names = set(['oneof_uint32', 'oneof_nested_message',
348-
'oneof_string', 'oneof_bytes'])
347+
nested_names = set([
348+
'oneof_uint32',
349+
'oneof_nested_message',
350+
'oneof_string',
351+
'oneof_bytes',
352+
'oneof_cord',
353+
'oneof_string_piece',
354+
'oneof_lazy_nested_message',
355+
])
349356
self.assertEqual(
350357
nested_names,
351358
set([field.name for field in desc.oneofs[0].fields]))

src/google/protobuf/compiler/cpp/field_generators/cord_field.cc

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -353,7 +353,8 @@ void CordOneofFieldGenerator::GenerateInlineAccessorDefinitions(
353353
}
354354
)cc");
355355
printer->Emit(R"cc(
356-
inline const ::absl::Cord& $classname$::$name$() const {
356+
inline const ::absl::Cord& $classname$::$name$() const
357+
ABSL_ATTRIBUTE_LIFETIME_BOUND {
357358
$annotate_get$;
358359
// @@protoc_insertion_point(field_get:$full_name$)
359360
return _internal_$name$();

src/google/protobuf/generated_message_tctable_gen.cc

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@
1414
#include <utility>
1515
#include <vector>
1616

17+
#include "absl/log/absl_check.h"
1718
#include "absl/strings/str_cat.h"
1819
#include "google/protobuf/descriptor.h"
1920
#include "google/protobuf/descriptor.pb.h"
@@ -731,6 +732,10 @@ TailCallTableInfo::TailCallTableInfo(
731732
const OptionProvider& option_provider,
732733
const std::vector<int>& has_bit_indices,
733734
const std::vector<int>& inlined_string_indices) {
735+
ABSL_DCHECK(std::is_sorted(ordered_fields.begin(), ordered_fields.end(),
736+
[](const auto* lhs, const auto* rhs) {
737+
return lhs->number() < rhs->number();
738+
}));
734739
// If this message has any inlined string fields, store the donation state
735740
// offset in the first auxiliary entry, which is kInlinedStringAuxIdx.
736741
if (!inlined_string_indices.empty()) {

src/google/protobuf/test_util.inc

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -295,7 +295,16 @@ inline void TestUtil::ModifyRepeatedFields(UNITTEST::TestAllTypes* message) {
295295
inline void TestUtil::SetOneofFields(UNITTEST::TestAllTypes* message) {
296296
message->set_oneof_uint32(601);
297297
message->mutable_oneof_nested_message()->set_bb(602);
298+
message->mutable_oneof_lazy_nested_message()->set_bb(605);
298299
message->set_oneof_string("603");
300+
#ifndef PROTOBUF_TEST_NO_DESCRIPTORS
301+
message->GetReflection()->SetString(
302+
message, message->GetDescriptor()->FindFieldByName("oneof_cord"), "606");
303+
message->GetReflection()->SetString(
304+
message, message->GetDescriptor()->FindFieldByName("oneof_string_piece"),
305+
"607");
306+
#endif // !PROTOBUF_TEST_NO_DESCRIPTORS
307+
// Must be last because tests are expecting it.
299308
message->set_oneof_bytes("604");
300309
}
301310

src/google/protobuf/unittest.proto

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -157,6 +157,9 @@ message TestAllTypes {
157157
NestedMessage oneof_nested_message = 112;
158158
string oneof_string = 113;
159159
bytes oneof_bytes = 114;
160+
string oneof_cord = 115 [ctype=CORD];
161+
string oneof_string_piece = 116 [ctype=STRING_PIECE];
162+
NestedMessage oneof_lazy_nested_message = 117 [lazy=true];
160163
}
161164
}
162165

src/google/protobuf/util/field_mask_util_test.cc

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -202,7 +202,7 @@ TEST(FieldMaskUtilTest, TestGetFieldMaskForAllFields) {
202202
EXPECT_TRUE(FieldMaskUtil::IsPathInFieldMask("bb", mask));
203203

204204
mask = FieldMaskUtil::GetFieldMaskForAllFields<TestAllTypes>();
205-
EXPECT_EQ(76, mask.paths_size());
205+
EXPECT_EQ(79, mask.paths_size());
206206
EXPECT_TRUE(FieldMaskUtil::IsPathInFieldMask("optional_int32", mask));
207207
EXPECT_TRUE(FieldMaskUtil::IsPathInFieldMask("optional_int64", mask));
208208
EXPECT_TRUE(FieldMaskUtil::IsPathInFieldMask("optional_uint32", mask));

0 commit comments

Comments
 (0)