| 2114 | } |
| 2115 | |
| 2116 | func TestInvalidUTF8(t *testing.T) { |
| 2117 | const invalidUTF8 = "\xde\xad\xbe\xef\x80\x00\xff" |
| 2118 | tests := []struct { |
| 2119 | label string |
| 2120 | proto2 proto.Message |
| 2121 | proto3 proto.Message |
| 2122 | want []byte |
| 2123 | }{{ |
| 2124 | label: "Scalar", |
| 2125 | proto2: &pb2.TestUTF8{Scalar: proto.String(invalidUTF8)}, |
| 2126 | proto3: &pb3.TestUTF8{Scalar: invalidUTF8}, |
| 2127 | want: []byte{0x0a, 0x07, 0xde, 0xad, 0xbe, 0xef, 0x80, 0x00, 0xff}, |
| 2128 | }, { |
| 2129 | label: "Vector", |
| 2130 | proto2: &pb2.TestUTF8{Vector: []string{invalidUTF8}}, |
| 2131 | proto3: &pb3.TestUTF8{Vector: []string{invalidUTF8}}, |
| 2132 | want: []byte{0x12, 0x07, 0xde, 0xad, 0xbe, 0xef, 0x80, 0x00, 0xff}, |
| 2133 | }, { |
| 2134 | label: "Oneof", |
| 2135 | proto2: &pb2.TestUTF8{Oneof: &pb2.TestUTF8_Field{invalidUTF8}}, |
| 2136 | proto3: &pb3.TestUTF8{Oneof: &pb3.TestUTF8_Field{invalidUTF8}}, |
| 2137 | want: []byte{0x1a, 0x07, 0xde, 0xad, 0xbe, 0xef, 0x80, 0x00, 0xff}, |
| 2138 | }, { |
| 2139 | label: "MapKey", |
| 2140 | proto2: &pb2.TestUTF8{MapKey: map[string]int64{invalidUTF8: 0}}, |
| 2141 | proto3: &pb3.TestUTF8{MapKey: map[string]int64{invalidUTF8: 0}}, |
| 2142 | want: []byte{0x22, 0x0b, 0x0a, 0x07, 0xde, 0xad, 0xbe, 0xef, 0x80, 0x00, 0xff, 0x10, 0x00}, |
| 2143 | }, { |
| 2144 | label: "MapValue", |
| 2145 | proto2: &pb2.TestUTF8{MapValue: map[int64]string{0: invalidUTF8}}, |
| 2146 | proto3: &pb3.TestUTF8{MapValue: map[int64]string{0: invalidUTF8}}, |
| 2147 | want: []byte{0x2a, 0x0b, 0x08, 0x00, 0x12, 0x07, 0xde, 0xad, 0xbe, 0xef, 0x80, 0x00, 0xff}, |
| 2148 | }} |
| 2149 | |
| 2150 | for _, tt := range tests { |
| 2151 | // Proto2 should not validate UTF-8. |
| 2152 | b, err := proto.Marshal(tt.proto2) |
| 2153 | if err != nil { |
| 2154 | t.Errorf("Marshal(proto2.%s) = %v, want nil", tt.label, err) |
| 2155 | } |
| 2156 | if !bytes.Equal(b, tt.want) { |
| 2157 | t.Errorf("Marshal(proto2.%s) = %x, want %x", tt.label, b, tt.want) |
| 2158 | } |
| 2159 | |
| 2160 | m := proto.Clone(tt.proto2) |
| 2161 | m.Reset() |
| 2162 | if err = proto.Unmarshal(tt.want, m); err != nil { |
| 2163 | t.Errorf("Unmarshal(proto2.%s) = %v, want nil", tt.label, err) |
| 2164 | } |
| 2165 | if !proto.Equal(m, tt.proto2) { |
| 2166 | t.Errorf("proto2.%s: output mismatch:\ngot %v\nwant %v", tt.label, m, tt.proto2) |
| 2167 | } |
| 2168 | |
| 2169 | // Proto3 should validate UTF-8. |
| 2170 | if _, err := proto.Marshal(tt.proto3); err == nil { |
| 2171 | t.Errorf("Marshal(proto3.%s) = %v, want non-nil", tt.label, err) |
| 2172 | } |
| 2173 | |