Browse Source

encoding/prototext: fix parsing of field names

Previous code tries to do all-lowercase match all non-extension field
names to match group field names, which is incorrect. Fix to check for
only group field type and make sure that the format is correct as well.

Fixes golang/protobuf#878.

Fix typo in text proto string in internal/impl/message_test.go that
wasn't caught before due to above issue.

Change-Id: Ief952907306435ed76a095e96e29fcc9c0027b73
Reviewed-on: https://go-review.googlesource.com/c/protobuf/+/183737
Reviewed-by: Joe Tsai <thebrokentoaster@gmail.com>
Herbie Ong 6 years ago
parent
commit
20aefe9c5e
3 changed files with 24 additions and 4 deletions
  1. 12 2
      encoding/prototext/decode.go
  2. 10 0
      encoding/prototext/decode_test.go
  3. 2 2
      internal/impl/message_test.go

+ 12 - 2
encoding/prototext/decode.go

@@ -95,9 +95,19 @@ func (o UnmarshalOptions) unmarshalMessage(tmsg [][2]text.Value, m pref.Message)
 		case text.Name:
 			name, _ = tkey.Name()
 			fd = fieldDescs.ByName(name)
+			// The proto name of a group field is in all lowercase. However, the
+			// textproto field name is the type name. Check to make sure that
+			// group name is correct.
 			if fd == nil {
-				// Check if this is a group field.
-				fd = fieldDescs.ByName(pref.Name(strings.ToLower(string(name))))
+				gd := fieldDescs.ByName(pref.Name(strings.ToLower(string(name))))
+				if gd != nil && gd.Kind() == pref.GroupKind && gd.Message().Name() == name {
+					fd = gd
+				}
+			} else {
+				if fd.Kind() == pref.GroupKind && fd.Message().Name() != name {
+					// Reset fd to nil because name does not match.
+					fd = nil
+				}
 			}
 		case text.String:
 			// Handle extensions only. This code path is not for Any.

+ 10 - 0
encoding/prototext/decode_test.go

@@ -120,6 +120,11 @@ opt_string: "谷歌"
 			OptBytes:    []byte("\xe8\xb0\xb7\xe6\xad\x8c"),
 			OptString:   scalar.String("谷歌"),
 		},
+	}, {
+		desc:         "case sensitive",
+		inputMessage: &pb3.Scalars{},
+		inputText:    `S_BOOL: true`,
+		wantErr:      true,
 	}, {
 		desc:         "proto3 scalars",
 		inputMessage: &pb3.Scalars{},
@@ -403,6 +408,11 @@ OptGroup: {}
 			OptNested: &pb2.Nested{},
 			Optgroup:  &pb2.Nests_OptGroup{},
 		},
+	}, {
+		desc:         "group field name",
+		inputMessage: &pb2.Nests{},
+		inputText:    `optgroup: {}`,
+		wantErr:      true,
 	}, {
 		desc:         "proto2 nested messages",
 		inputMessage: &pb2.Nests{},

+ 2 - 2
internal/impl/message_test.go

@@ -990,8 +990,8 @@ var enumMessagesType = pimpl.MessageInfo{GoType: reflect.TypeOf(new(EnumMessages
 		field: [
 			{name:"f1"  number:1  label:LABEL_OPTIONAL type:TYPE_ENUM    type_name:".EnumProto2" default_value:"BEEF"},
 			{name:"f2"  number:2  label:LABEL_OPTIONAL type:TYPE_ENUM    type_name:".EnumProto3" default_value:"BRAVO"},
-			{name:"f3"  number:3  label:LABEL_OPTIONAL type:TYPE_MESSAGE type_Name:".google.golang.org.proto2_20180125.Message"},
-			{name:"f4"  number:4  label:LABEL_OPTIONAL type:TYPE_MESSAGE type_Name:".EnumMessages"},
+			{name:"f3"  number:3  label:LABEL_OPTIONAL type:TYPE_MESSAGE type_name:".google.golang.org.proto2_20180125.Message"},
+			{name:"f4"  number:4  label:LABEL_OPTIONAL type:TYPE_MESSAGE type_name:".EnumMessages"},
 			{name:"f5"  number:5  label:LABEL_REPEATED type:TYPE_ENUM    type_name:".EnumProto2"},
 			{name:"f6"  number:6  label:LABEL_REPEATED type:TYPE_MESSAGE type_name:".ScalarProto2"},
 			{name:"f7"  number:7  label:LABEL_REPEATED type:TYPE_MESSAGE type_name:".EnumMessages.F7Entry"},