internal/impl: more checks for aberrant messages
When loading a *MessageInfo for a legacy message type, check to see if
the Go type contains at least one field which looks like a message
field. Specifically, look for at least one field with a `protobuf:` tag,
or an XXX_unrecognized field.
If a message has no recognizable fields, assume that it's something we
don't know how to interpret and treat it as an aberrant message.
Change-Id: If5c09087f1a0187271c98539d761395a2ee70a9e
Reviewed-on: https://go-review.googlesource.com/c/protobuf/+/210617
Reviewed-by: Joe Tsai <joetsai@google.com>
diff --git a/proto/methods_test.go b/proto/methods_test.go
index 385fcbf..91019fa 100644
--- a/proto/methods_test.go
+++ b/proto/methods_test.go
@@ -15,6 +15,8 @@
"google.golang.org/protobuf/internal/impl"
"google.golang.org/protobuf/proto"
+
+ legacypb "google.golang.org/protobuf/internal/testprotos/legacy"
)
type selfMarshaler struct {
@@ -84,19 +86,46 @@
const descPanicSelfMarshalerBytes = "bytes"
-func (m descPanicSelfMarshaler) Reset() {}
-func (m descPanicSelfMarshaler) ProtoMessage() {}
-func (m descPanicSelfMarshaler) Descriptor() ([]byte, []int) { panic("Descriptor method panics") }
-func (m descPanicSelfMarshaler) String() string { return "descPanicSelfMarshaler{}" }
-func (m descPanicSelfMarshaler) Marshal() ([]byte, error) {
+func (m *descPanicSelfMarshaler) Reset() {}
+func (m *descPanicSelfMarshaler) ProtoMessage() {}
+func (m *descPanicSelfMarshaler) Descriptor() ([]byte, []int) { panic("Descriptor method panics") }
+func (m *descPanicSelfMarshaler) String() string { return "descPanicSelfMarshaler{}" }
+func (m *descPanicSelfMarshaler) Marshal() ([]byte, error) {
return []byte(descPanicSelfMarshalerBytes), nil
}
func TestSelfMarshalerDescriptorPanics(t *testing.T) {
- m := descPanicSelfMarshaler{}
+ m := &descPanicSelfMarshaler{}
got, err := proto.Marshal(impl.Export{}.MessageOf(m).Interface())
want := []byte(descPanicSelfMarshalerBytes)
if err != nil || !bytes.Equal(got, want) {
t.Fatalf("proto.Marshal(%v) = %v, %v; want %v, nil", m, got, err, want)
}
}
+
+type descSelfMarshaler struct {
+ someField int // some non-generated field
+}
+
+const descSelfMarshalerBytes = "bytes"
+
+func (m *descSelfMarshaler) Reset() {}
+func (m *descSelfMarshaler) ProtoMessage() {}
+func (m *descSelfMarshaler) Descriptor() ([]byte, []int) {
+ return ((*legacypb.Legacy)(nil)).GetF1().Descriptor()
+}
+func (m *descSelfMarshaler) String() string {
+ return "descSelfMarshaler{}"
+}
+func (m *descSelfMarshaler) Marshal() ([]byte, error) {
+ return []byte(descSelfMarshalerBytes), nil
+}
+
+func TestSelfMarshalerWithDescriptor(t *testing.T) {
+ m := &descSelfMarshaler{}
+ got, err := proto.Marshal(impl.Export{}.MessageOf(m).Interface())
+ want := []byte(descSelfMarshalerBytes)
+ if err != nil || !bytes.Equal(got, want) {
+ t.Fatalf("proto.Marshal(%v) = %v, %v; want %v, nil", m, got, err, want)
+ }
+}