encoding/textpb: add string fields UTF-8 validation
Change-Id: I15aec2b90efae9366eb496dc221b9e8cacd9d8e6
Reviewed-on: https://go-review.googlesource.com/c/protobuf/+/171122
Reviewed-by: Joe Tsai <thebrokentoaster@gmail.com>
diff --git a/encoding/textpb/encode_test.go b/encoding/textpb/encode_test.go
index 5b9ee38..3397d66 100644
--- a/encoding/textpb/encode_test.go
+++ b/encoding/textpb/encode_test.go
@@ -170,6 +170,14 @@
opt_string: "谷歌"
`,
}, {
+ desc: "string with invalid UTF-8",
+ input: &pb3.Scalars{
+ SString: "abc\xff",
+ },
+ want: `s_string: "abc\xff"
+`,
+ wantErr: true,
+ }, {
desc: "float nan",
input: &pb3.Scalars{
SFloat: float32(math.NaN()),
@@ -364,6 +372,18 @@
}
`,
}, {
+ desc: "proto3 nested message contains invalid UTF-8",
+ input: &pb3.Nests{
+ SNested: &pb3.Nested{
+ SString: "abc\xff",
+ },
+ },
+ want: `s_nested: {
+ s_string: "abc\xff"
+}
+`,
+ wantErr: true,
+ }, {
desc: "oneof not set",
input: &pb3.Oneofs{},
want: "\n",
@@ -473,6 +493,14 @@
rpt_bytes: "世界"
`,
}, {
+ desc: "repeated contains invalid UTF-8",
+ input: &pb2.Repeats{
+ RptString: []string{"abc\xff"},
+ },
+ want: `rpt_string: "abc\xff"
+`,
+ wantErr: true,
+ }, {
desc: "repeated enums",
input: &pb2.Enums{
RptEnum: []pb2.Enum{pb2.Enum_ONE, 2, pb2.Enum_TEN, 42},
@@ -671,6 +699,32 @@
}
`,
}, {
+ desc: "map field value contains invalid UTF-8",
+ input: &pb3.Maps{
+ Int32ToStr: map[int32]string{
+ 101: "abc\xff",
+ },
+ },
+ want: `int32_to_str: {
+ key: 101
+ value: "abc\xff"
+}
+`,
+ wantErr: true,
+ }, {
+ desc: "map field key contains invalid UTF-8",
+ input: &pb3.Maps{
+ StrToNested: map[string]*pb3.Nested{
+ "abc\xff": {},
+ },
+ },
+ want: `str_to_nested: {
+ key: "abc\xff"
+ value: {}
+}
+`,
+ wantErr: true,
+ }, {
desc: "map field contains nil value",
input: &pb3.Maps{
StrToNested: map[string]*pb3.Nested{
@@ -919,6 +973,16 @@
[pb2.opt_ext_string]: "extension field"
`,
}, {
+ desc: "extension field contains invalid UTF-8",
+ input: func() proto.Message {
+ m := &pb2.Extensions{}
+ setExtension(m, pb2.E_OptExtString, "abc\xff")
+ return m
+ }(),
+ want: `[pb2.opt_ext_string]: "abc\xff"
+`,
+ wantErr: true,
+ }, {
desc: "extension partial returns error",
input: func() proto.Message {
m := &pb2.Extensions{}
@@ -1178,6 +1242,29 @@
`,
wantErr: true,
}, {
+ desc: "Any with invalid UTF-8",
+ mo: textpb.MarshalOptions{
+ Resolver: preg.NewTypes((&pb3.Nested{}).ProtoReflect().Type()),
+ },
+ input: func() proto.Message {
+ m := &pb3.Nested{
+ SString: "abc\xff",
+ }
+ b, err := proto.MarshalOptions{Deterministic: true}.Marshal(m)
+ if err != nil {
+ t.Fatalf("error in binary marshaling message for Any.value: %v", err)
+ }
+ return &knownpb.Any{
+ TypeUrl: string(m.ProtoReflect().Type().FullName()),
+ Value: b,
+ }
+ }(),
+ want: `[pb3.Nested]: {
+ s_string: "abc\xff"
+}
+`,
+ wantErr: true,
+ }, {
desc: "Any with invalid value",
mo: textpb.MarshalOptions{
Resolver: preg.NewTypes((&pb2.Nested{}).ProtoReflect().Type()),