proto: Prevent Any protos from being deserialized multiple times.
This avoids people specifying protos (inadvertently) as:
some_repeated_any {
[type.googleapis.com/a/path/proto.Type] {
blah: 1
}
[type.googleapis.com/a/path/proto.Type] {
blah: 2
}
}
when they meant:
some_repeated_any {
[type.googleapis.com/a/path/proto.Type] {
blah: 1
}
}
some_repeated_any {
[type.googleapis.com/a/path/proto.Type] {
blah: 2
}
}
diff --git a/proto/text_parser.go b/proto/text_parser.go
index 0b8c59f..7e6f145 100644
--- a/proto/text_parser.go
+++ b/proto/text_parser.go
@@ -44,6 +44,9 @@
"unicode/utf8"
)
+// Error string emitted when deserializing Any and fields are already set
+const anyRepeatedlyUnpacked = "Any message unpacked multiple times, or %q already set"
+
type ParseError struct {
Message string
Line int // 1-based line number
@@ -508,8 +511,16 @@
if err != nil {
return p.errorf("failed to marshal message of type %q: %v", messageName, err)
}
+ if fieldSet["type_url"] {
+ return p.errorf(anyRepeatedlyUnpacked, "type_url")
+ }
+ if fieldSet["value"] {
+ return p.errorf(anyRepeatedlyUnpacked, "value")
+ }
sv.FieldByName("TypeUrl").SetString(extName)
sv.FieldByName("Value").SetBytes(b)
+ fieldSet["type_url"] = true
+ fieldSet["value"] = true
continue
}