Browse Source

Cherry-pick the fix for https://github.com/protocolbuffers/protobuf/issues/7463.

Joshua Haberman 5 years ago
parent
commit
c0b1ce00f3

+ 1 - 1
src/google/protobuf/generated_message_reflection.cc

@@ -1061,7 +1061,7 @@ void Reflection::ListFields(const Message& message,
         if (oneof_case_array[containing_oneof->index()] == field->number()) {
         if (oneof_case_array[containing_oneof->index()] == field->number()) {
           output->push_back(field);
           output->push_back(field);
         }
         }
-      } else if (has_bits) {
+      } else if (has_bits && has_bits_indices[i] != -1) {
         // Equivalent to: HasBit(message, field)
         // Equivalent to: HasBit(message, field)
         if (IsIndexInHasBitSet(has_bits, has_bits_indices[i])) {
         if (IsIndexInHasBitSet(has_bits, has_bits_indices[i])) {
           output->push_back(field);
           output->push_back(field);

+ 9 - 3
src/google/protobuf/proto3_arena_unittest.cc

@@ -217,9 +217,15 @@ TEST(Proto3OptionalTest, OptionalFieldDescriptor) {
 
 
   for (int i = 0; i < d->field_count(); i++) {
   for (int i = 0; i < d->field_count(); i++) {
     const FieldDescriptor* f = d->field(i);
     const FieldDescriptor* f = d->field(i);
-    EXPECT_TRUE(f->has_optional_keyword()) << f->full_name();
-    EXPECT_TRUE(f->has_presence()) << f->full_name();
-    EXPECT_TRUE(f->containing_oneof()) << f->full_name();
+    if (HasPrefixString(f->name(), "singular")) {
+      EXPECT_FALSE(f->has_optional_keyword()) << f->full_name();
+      EXPECT_FALSE(f->has_presence()) << f->full_name();
+      EXPECT_FALSE(f->containing_oneof()) << f->full_name();
+    } else {
+      EXPECT_TRUE(f->has_optional_keyword()) << f->full_name();
+      EXPECT_TRUE(f->has_presence()) << f->full_name();
+      EXPECT_TRUE(f->containing_oneof()) << f->full_name();
+    }
   }
   }
 }
 }
 
 

+ 4 - 0
src/google/protobuf/unittest_proto3_optional.proto

@@ -72,4 +72,8 @@ message TestProto3Optional {
   optional NestedMessage optional_nested_message = 18;
   optional NestedMessage optional_nested_message = 18;
   optional NestedMessage lazy_nested_message = 19 [lazy = true];
   optional NestedMessage lazy_nested_message = 19 [lazy = true];
   optional NestedEnum optional_nested_enum = 21;
   optional NestedEnum optional_nested_enum = 21;
+
+  // Add some non-optional fields to verify we can mix them.
+  int32 singular_int32 = 22;
+  int64 singular_int64 = 23;
 }
 }