2018-12-06 15:28:53 -08:00
|
|
|
// Copyright 2018 The Go Authors. All rights reserved.
|
|
|
|
// Use of this source code is governed by a BSD-style
|
|
|
|
// license that can be found in the LICENSE file.
|
|
|
|
|
2019-05-14 12:44:37 -07:00
|
|
|
package prototext_test
|
2018-12-06 15:28:53 -08:00
|
|
|
|
|
|
|
import (
|
|
|
|
"math"
|
2019-10-31 17:10:15 -07:00
|
|
|
"strings"
|
2018-12-06 15:28:53 -08:00
|
|
|
"testing"
|
|
|
|
|
2019-05-14 12:44:37 -07:00
|
|
|
"google.golang.org/protobuf/encoding/prototext"
|
2019-07-09 22:38:15 -07:00
|
|
|
"google.golang.org/protobuf/internal/flags"
|
2019-05-13 23:55:40 -07:00
|
|
|
"google.golang.org/protobuf/proto"
|
2022-05-24 05:12:23 +09:00
|
|
|
"google.golang.org/protobuf/reflect/protoregistry"
|
2018-12-06 15:28:53 -08:00
|
|
|
|
2019-07-09 22:38:15 -07:00
|
|
|
testpb "google.golang.org/protobuf/internal/testprotos/test"
|
|
|
|
weakpb "google.golang.org/protobuf/internal/testprotos/test/weak1"
|
2020-01-10 23:31:25 -08:00
|
|
|
pb2 "google.golang.org/protobuf/internal/testprotos/textpb2"
|
|
|
|
pb3 "google.golang.org/protobuf/internal/testprotos/textpb3"
|
2024-02-23 13:03:15 +01:00
|
|
|
pbeditions "google.golang.org/protobuf/internal/testprotos/textpbeditions"
|
2019-05-16 12:47:20 -07:00
|
|
|
"google.golang.org/protobuf/types/known/anypb"
|
2018-12-06 15:28:53 -08:00
|
|
|
)
|
|
|
|
|
|
|
|
func TestUnmarshal(t *testing.T) {
|
|
|
|
tests := []struct {
|
|
|
|
desc string
|
2019-05-14 12:44:37 -07:00
|
|
|
umo prototext.UnmarshalOptions
|
2018-12-13 14:19:50 -08:00
|
|
|
inputMessage proto.Message
|
2018-12-06 15:28:53 -08:00
|
|
|
inputText string
|
2018-12-13 14:19:50 -08:00
|
|
|
wantMessage proto.Message
|
2019-10-31 17:10:15 -07:00
|
|
|
wantErr string // Expected error substring.
|
2019-07-09 22:38:15 -07:00
|
|
|
skip bool
|
2018-12-06 15:28:53 -08:00
|
|
|
}{{
|
|
|
|
desc: "proto2 empty message",
|
|
|
|
inputMessage: &pb2.Scalars{},
|
|
|
|
wantMessage: &pb2.Scalars{},
|
|
|
|
}, {
|
2019-02-13 14:13:21 -08:00
|
|
|
desc: "proto2 optional scalars set to zero values",
|
2018-12-06 15:28:53 -08:00
|
|
|
inputMessage: &pb2.Scalars{},
|
|
|
|
inputText: `opt_bool: false
|
|
|
|
opt_int32: 0
|
|
|
|
opt_int64: 0
|
|
|
|
opt_uint32: 0
|
|
|
|
opt_uint64: 0
|
|
|
|
opt_sint32: 0
|
|
|
|
opt_sint64: 0
|
|
|
|
opt_fixed32: 0
|
|
|
|
opt_fixed64: 0
|
|
|
|
opt_sfixed32: 0
|
|
|
|
opt_sfixed64: 0
|
|
|
|
opt_float: 0
|
|
|
|
opt_double: 0
|
|
|
|
opt_bytes: ""
|
|
|
|
opt_string: ""
|
|
|
|
`,
|
|
|
|
wantMessage: &pb2.Scalars{
|
2019-07-10 16:17:16 -07:00
|
|
|
OptBool: proto.Bool(false),
|
|
|
|
OptInt32: proto.Int32(0),
|
|
|
|
OptInt64: proto.Int64(0),
|
|
|
|
OptUint32: proto.Uint32(0),
|
|
|
|
OptUint64: proto.Uint64(0),
|
|
|
|
OptSint32: proto.Int32(0),
|
|
|
|
OptSint64: proto.Int64(0),
|
|
|
|
OptFixed32: proto.Uint32(0),
|
|
|
|
OptFixed64: proto.Uint64(0),
|
|
|
|
OptSfixed32: proto.Int32(0),
|
|
|
|
OptSfixed64: proto.Int64(0),
|
|
|
|
OptFloat: proto.Float32(0),
|
|
|
|
OptDouble: proto.Float64(0),
|
2018-12-06 15:28:53 -08:00
|
|
|
OptBytes: []byte{},
|
2019-07-10 16:17:16 -07:00
|
|
|
OptString: proto.String(""),
|
2018-12-06 15:28:53 -08:00
|
|
|
},
|
2024-02-23 13:03:15 +01:00
|
|
|
}, {
|
|
|
|
desc: "protoeditions explicit scalars set to zero values",
|
|
|
|
inputMessage: &pbeditions.Scalars{},
|
|
|
|
inputText: `opt_bool: false
|
|
|
|
opt_int32: 0
|
|
|
|
opt_int64: 0
|
|
|
|
opt_uint32: 0
|
|
|
|
opt_uint64: 0
|
|
|
|
opt_sint32: 0
|
|
|
|
opt_sint64: 0
|
|
|
|
opt_fixed32: 0
|
|
|
|
opt_fixed64: 0
|
|
|
|
opt_sfixed32: 0
|
|
|
|
opt_sfixed64: 0
|
|
|
|
opt_float: 0
|
|
|
|
opt_double: 0
|
|
|
|
opt_bytes: ""
|
|
|
|
opt_string: ""
|
|
|
|
`,
|
|
|
|
wantMessage: &pbeditions.Scalars{
|
|
|
|
OptBool: proto.Bool(false),
|
|
|
|
OptInt32: proto.Int32(0),
|
|
|
|
OptInt64: proto.Int64(0),
|
|
|
|
OptUint32: proto.Uint32(0),
|
|
|
|
OptUint64: proto.Uint64(0),
|
|
|
|
OptSint32: proto.Int32(0),
|
|
|
|
OptSint64: proto.Int64(0),
|
|
|
|
OptFixed32: proto.Uint32(0),
|
|
|
|
OptFixed64: proto.Uint64(0),
|
|
|
|
OptSfixed32: proto.Int32(0),
|
|
|
|
OptSfixed64: proto.Int64(0),
|
|
|
|
OptFloat: proto.Float32(0),
|
|
|
|
OptDouble: proto.Float64(0),
|
|
|
|
OptBytes: []byte{},
|
|
|
|
OptString: proto.String(""),
|
|
|
|
},
|
|
|
|
}, {
|
|
|
|
desc: "protoeditions implicit scalars set to zero values",
|
|
|
|
inputMessage: &pbeditions.ImplicitScalars{},
|
|
|
|
inputText: `s_bool: false
|
|
|
|
s_int32: 0
|
|
|
|
s_int64: 0
|
|
|
|
s_uint32: 0
|
|
|
|
s_uint64: 0
|
|
|
|
s_sint32: 0
|
|
|
|
s_sint64: 0
|
|
|
|
s_fixed32: 0
|
|
|
|
s_fixed64: 0
|
|
|
|
s_sfixed32: 0
|
|
|
|
s_sfixed64: 0
|
|
|
|
s_float: 0
|
|
|
|
s_double: 0
|
|
|
|
s_bytes: ""
|
|
|
|
s_string: ""
|
|
|
|
`,
|
|
|
|
wantMessage: &pbeditions.ImplicitScalars{},
|
2018-12-06 15:28:53 -08:00
|
|
|
}, {
|
2019-02-13 14:13:21 -08:00
|
|
|
desc: "proto3 scalars set to zero values",
|
2018-12-06 15:28:53 -08:00
|
|
|
inputMessage: &pb3.Scalars{},
|
|
|
|
inputText: `s_bool: false
|
|
|
|
s_int32: 0
|
|
|
|
s_int64: 0
|
|
|
|
s_uint32: 0
|
|
|
|
s_uint64: 0
|
|
|
|
s_sint32: 0
|
|
|
|
s_sint64: 0
|
|
|
|
s_fixed32: 0
|
|
|
|
s_fixed64: 0
|
|
|
|
s_sfixed32: 0
|
|
|
|
s_sfixed64: 0
|
|
|
|
s_float: 0
|
|
|
|
s_double: 0
|
|
|
|
s_bytes: ""
|
|
|
|
s_string: ""
|
|
|
|
`,
|
|
|
|
wantMessage: &pb3.Scalars{},
|
2020-04-28 14:44:38 -07:00
|
|
|
}, {
|
|
|
|
desc: "proto3 optional set to zero values",
|
|
|
|
inputMessage: &pb3.Proto3Optional{},
|
|
|
|
inputText: `opt_bool: false
|
|
|
|
opt_int32: 0
|
|
|
|
opt_int64: 0
|
|
|
|
opt_uint32: 0
|
|
|
|
opt_uint64: 0
|
|
|
|
opt_float: 0
|
|
|
|
opt_double: 0
|
|
|
|
opt_string: ""
|
|
|
|
opt_bytes: ""
|
|
|
|
opt_enum: ZERO
|
|
|
|
opt_message: {}
|
|
|
|
`,
|
|
|
|
wantMessage: &pb3.Proto3Optional{
|
|
|
|
OptBool: proto.Bool(false),
|
|
|
|
OptInt32: proto.Int32(0),
|
|
|
|
OptInt64: proto.Int64(0),
|
|
|
|
OptUint32: proto.Uint32(0),
|
|
|
|
OptUint64: proto.Uint64(0),
|
|
|
|
OptFloat: proto.Float32(0),
|
|
|
|
OptDouble: proto.Float64(0),
|
|
|
|
OptString: proto.String(""),
|
|
|
|
OptBytes: []byte{},
|
|
|
|
OptEnum: pb3.Enum_ZERO.Enum(),
|
|
|
|
OptMessage: &pb3.Nested{},
|
|
|
|
},
|
2018-12-06 15:28:53 -08:00
|
|
|
}, {
|
2019-02-13 14:13:21 -08:00
|
|
|
desc: "proto2 optional scalars",
|
2018-12-06 15:28:53 -08:00
|
|
|
inputMessage: &pb2.Scalars{},
|
|
|
|
inputText: `opt_bool: true
|
|
|
|
opt_int32: 255
|
|
|
|
opt_int64: 3735928559
|
|
|
|
opt_uint32: 0xff
|
|
|
|
opt_uint64: 0xdeadbeef
|
|
|
|
opt_sint32: -1001
|
2023-03-02 19:40:35 -05:00
|
|
|
opt_sint64: - 0xffff
|
2018-12-06 15:28:53 -08:00
|
|
|
opt_fixed64: 64
|
2023-03-02 19:40:35 -05:00
|
|
|
opt_sfixed32: - 32
|
2018-12-06 15:28:53 -08:00
|
|
|
opt_float: 1.234
|
|
|
|
opt_double: 1.23e+100
|
|
|
|
opt_bytes: "\xe8\xb0\xb7\xe6\xad\x8c"
|
|
|
|
opt_string: "谷歌"
|
|
|
|
`,
|
|
|
|
wantMessage: &pb2.Scalars{
|
2019-07-10 16:17:16 -07:00
|
|
|
OptBool: proto.Bool(true),
|
|
|
|
OptInt32: proto.Int32(0xff),
|
|
|
|
OptInt64: proto.Int64(0xdeadbeef),
|
|
|
|
OptUint32: proto.Uint32(0xff),
|
|
|
|
OptUint64: proto.Uint64(0xdeadbeef),
|
|
|
|
OptSint32: proto.Int32(-1001),
|
|
|
|
OptSint64: proto.Int64(-0xffff),
|
|
|
|
OptFixed64: proto.Uint64(64),
|
|
|
|
OptSfixed32: proto.Int32(-32),
|
|
|
|
OptFloat: proto.Float32(1.234),
|
|
|
|
OptDouble: proto.Float64(1.23e100),
|
2018-12-06 15:28:53 -08:00
|
|
|
OptBytes: []byte("\xe8\xb0\xb7\xe6\xad\x8c"),
|
2019-07-10 16:17:16 -07:00
|
|
|
OptString: proto.String("谷歌"),
|
2018-12-06 15:28:53 -08:00
|
|
|
},
|
2024-02-23 13:03:15 +01:00
|
|
|
}, {
|
|
|
|
desc: "protoeditions explicit scalars",
|
|
|
|
inputMessage: &pbeditions.Scalars{},
|
|
|
|
inputText: `opt_bool: true
|
|
|
|
opt_int32: 255
|
|
|
|
opt_int64: 3735928559
|
|
|
|
opt_uint32: 0xff
|
|
|
|
opt_uint64: 0xdeadbeef
|
|
|
|
opt_sint32: -1001
|
|
|
|
opt_sint64: - 0xffff
|
|
|
|
opt_fixed64: 64
|
|
|
|
opt_sfixed32: - 32
|
|
|
|
opt_float: 1.234
|
|
|
|
opt_double: 1.23e+100
|
|
|
|
opt_bytes: "\xe8\xb0\xb7\xe6\xad\x8c"
|
|
|
|
opt_string: "谷歌"
|
|
|
|
`,
|
|
|
|
wantMessage: &pbeditions.Scalars{
|
|
|
|
OptBool: proto.Bool(true),
|
|
|
|
OptInt32: proto.Int32(0xff),
|
|
|
|
OptInt64: proto.Int64(0xdeadbeef),
|
|
|
|
OptUint32: proto.Uint32(0xff),
|
|
|
|
OptUint64: proto.Uint64(0xdeadbeef),
|
|
|
|
OptSint32: proto.Int32(-1001),
|
|
|
|
OptSint64: proto.Int64(-0xffff),
|
|
|
|
OptFixed64: proto.Uint64(64),
|
|
|
|
OptSfixed32: proto.Int32(-32),
|
|
|
|
OptFloat: proto.Float32(1.234),
|
|
|
|
OptDouble: proto.Float64(1.23e100),
|
|
|
|
OptBytes: []byte("\xe8\xb0\xb7\xe6\xad\x8c"),
|
|
|
|
OptString: proto.String("谷歌"),
|
|
|
|
},
|
2019-06-24 19:21:46 -07:00
|
|
|
}, {
|
|
|
|
desc: "case sensitive",
|
|
|
|
inputMessage: &pb3.Scalars{},
|
|
|
|
inputText: `S_BOOL: true`,
|
2019-10-31 17:10:15 -07:00
|
|
|
wantErr: "unknown field: S_BOOL",
|
2018-12-06 15:28:53 -08:00
|
|
|
}, {
|
2019-02-13 14:13:21 -08:00
|
|
|
desc: "proto3 scalars",
|
2018-12-06 15:28:53 -08:00
|
|
|
inputMessage: &pb3.Scalars{},
|
|
|
|
inputText: `s_bool: true
|
|
|
|
s_int32: 255
|
|
|
|
s_int64: 3735928559
|
|
|
|
s_uint32: 0xff
|
|
|
|
s_uint64: 0xdeadbeef
|
|
|
|
s_sint32: -1001
|
2023-03-02 19:40:35 -05:00
|
|
|
s_sint64: - #
|
|
|
|
0xffff
|
2018-12-06 15:28:53 -08:00
|
|
|
s_fixed64: 64
|
|
|
|
s_sfixed32: -32
|
|
|
|
s_float: 1.234
|
|
|
|
s_double: 1.23e+100
|
|
|
|
s_bytes: "\xe8\xb0\xb7\xe6\xad\x8c"
|
|
|
|
s_string: "谷歌"
|
|
|
|
`,
|
|
|
|
wantMessage: &pb3.Scalars{
|
|
|
|
SBool: true,
|
|
|
|
SInt32: 0xff,
|
|
|
|
SInt64: 0xdeadbeef,
|
|
|
|
SUint32: 0xff,
|
|
|
|
SUint64: 0xdeadbeef,
|
|
|
|
SSint32: -1001,
|
|
|
|
SSint64: -0xffff,
|
|
|
|
SFixed64: 64,
|
|
|
|
SSfixed32: -32,
|
|
|
|
SFloat: 1.234,
|
|
|
|
SDouble: 1.23e100,
|
|
|
|
SBytes: []byte("\xe8\xb0\xb7\xe6\xad\x8c"),
|
|
|
|
SString: "谷歌",
|
|
|
|
},
|
2019-04-08 17:32:44 -07:00
|
|
|
}, {
|
encoding/prototext: adjust handling of invalid UTF-8
The following changes are made:
* Permit invalid UTF-8 in proto2. This goes against specified behavior,
but matches functional behavior in wire marshaling (not just for Go,
but also in the other major language implementations as well).
* The Format function is specified as ignoring errors since its intended
purpose is to surface information to the human user even if it's not
exactly parsible back into a message. As such, add an unexported
allowInvalidUTF8 option that is specially used by Format.
* Add an EmitASCII option that forces the formatting of
strings and bytes to always be encoded as ASCII.
This ensures that the entire output is always ASCII as well.
Note that we do not replicate this behavior for protojson since:
* The JSON format fundamentally has a stricter and well-specified
grammar for exactly what is valid/invalid, while the text format
has not had a well-specified grammar for the longest time,
leading to all sorts of weird usages due to Hyrum's law.
* This is to ease migration from the legacy implementation,
which did permit invalid UTF-8 in proto2.
* The EmitASCII option relies on the ability to always escape
Unicode characters using ASCII escape sequences, but this is not
possible in JSON since the grammar only has an escape sequence defined
for Unicode characters \u0000 to \uffff, inclusive.
However, Unicode v12.0.0 defines characters up to \U0010FFFF,
which is beyond what the JSON grammar provides escape sequences for.
Change-Id: I2b524a904e9ec59f9ed5500e299613bc27c31a14
Reviewed-on: https://go-review.googlesource.com/c/protobuf/+/233077
Reviewed-by: Herbie Ong <herbie@google.com>
2020-05-07 15:10:54 -07:00
|
|
|
desc: "proto2 string with invalid UTF-8",
|
|
|
|
inputMessage: &pb2.Scalars{},
|
|
|
|
inputText: `opt_string: "abc\xff"`,
|
|
|
|
wantMessage: &pb2.Scalars{
|
|
|
|
OptString: proto.String("abc\xff"),
|
|
|
|
},
|
2024-02-23 13:03:15 +01:00
|
|
|
}, {
|
|
|
|
desc: "protoeditions unvalidated string with invalid UTF-8",
|
|
|
|
inputMessage: &pbeditions.Scalars{},
|
|
|
|
inputText: `opt_string: "abc\xff"`,
|
|
|
|
wantMessage: &pbeditions.Scalars{
|
|
|
|
OptString: proto.String("abc\xff"),
|
|
|
|
},
|
encoding/prototext: adjust handling of invalid UTF-8
The following changes are made:
* Permit invalid UTF-8 in proto2. This goes against specified behavior,
but matches functional behavior in wire marshaling (not just for Go,
but also in the other major language implementations as well).
* The Format function is specified as ignoring errors since its intended
purpose is to surface information to the human user even if it's not
exactly parsible back into a message. As such, add an unexported
allowInvalidUTF8 option that is specially used by Format.
* Add an EmitASCII option that forces the formatting of
strings and bytes to always be encoded as ASCII.
This ensures that the entire output is always ASCII as well.
Note that we do not replicate this behavior for protojson since:
* The JSON format fundamentally has a stricter and well-specified
grammar for exactly what is valid/invalid, while the text format
has not had a well-specified grammar for the longest time,
leading to all sorts of weird usages due to Hyrum's law.
* This is to ease migration from the legacy implementation,
which did permit invalid UTF-8 in proto2.
* The EmitASCII option relies on the ability to always escape
Unicode characters using ASCII escape sequences, but this is not
possible in JSON since the grammar only has an escape sequence defined
for Unicode characters \u0000 to \uffff, inclusive.
However, Unicode v12.0.0 defines characters up to \U0010FFFF,
which is beyond what the JSON grammar provides escape sequences for.
Change-Id: I2b524a904e9ec59f9ed5500e299613bc27c31a14
Reviewed-on: https://go-review.googlesource.com/c/protobuf/+/233077
Reviewed-by: Herbie Ong <herbie@google.com>
2020-05-07 15:10:54 -07:00
|
|
|
}, {
|
|
|
|
desc: "proto3 string with invalid UTF-8",
|
2019-04-08 17:32:44 -07:00
|
|
|
inputMessage: &pb3.Scalars{},
|
|
|
|
inputText: `s_string: "abc\xff"`,
|
2019-10-31 17:10:15 -07:00
|
|
|
wantErr: "(line 1:11): contains invalid UTF-8",
|
2018-12-06 15:28:53 -08:00
|
|
|
}, {
|
|
|
|
desc: "proto2 message contains unknown field",
|
|
|
|
inputMessage: &pb2.Scalars{},
|
|
|
|
inputText: "unknown_field: 123",
|
2019-10-31 17:10:15 -07:00
|
|
|
wantErr: "unknown field",
|
2018-12-06 15:28:53 -08:00
|
|
|
}, {
|
|
|
|
desc: "proto3 message contains unknown field",
|
|
|
|
inputMessage: &pb3.Scalars{},
|
|
|
|
inputText: "unknown_field: 456",
|
2019-10-31 17:10:15 -07:00
|
|
|
wantErr: "unknown field",
|
2019-09-15 00:17:39 -07:00
|
|
|
}, {
|
|
|
|
desc: "proto2 message contains discarded unknown field",
|
|
|
|
umo: prototext.UnmarshalOptions{DiscardUnknown: true},
|
|
|
|
inputMessage: &pb2.Scalars{},
|
|
|
|
inputText: `unknown_field:123 1000:"hello"`,
|
2024-02-23 13:03:15 +01:00
|
|
|
}, {
|
|
|
|
desc: "protoeditions message contains discarded unknown field",
|
|
|
|
umo: prototext.UnmarshalOptions{DiscardUnknown: true},
|
|
|
|
inputMessage: &pbeditions.Scalars{},
|
|
|
|
inputText: `unknown_field:123 1000:"hello"`,
|
2019-09-15 00:17:39 -07:00
|
|
|
}, {
|
|
|
|
desc: "proto3 message contains discarded unknown field",
|
|
|
|
umo: prototext.UnmarshalOptions{DiscardUnknown: true},
|
|
|
|
inputMessage: &pb3.Scalars{},
|
|
|
|
inputText: `unknown_field:456 1000:"goodbye"`,
|
|
|
|
}, {
|
|
|
|
desc: "proto2 message cannot parse field number",
|
|
|
|
umo: prototext.UnmarshalOptions{DiscardUnknown: true},
|
|
|
|
inputMessage: &pb2.Scalars{},
|
|
|
|
inputText: `13:"hello"`,
|
2019-10-31 17:10:15 -07:00
|
|
|
wantErr: "cannot specify field by number",
|
2021-05-05 15:13:31 -07:00
|
|
|
}, {
|
|
|
|
desc: "unknown list field",
|
|
|
|
umo: prototext.UnmarshalOptions{DiscardUnknown: true},
|
|
|
|
inputMessage: &pb2.Scalars{},
|
|
|
|
inputText: `unknown_field: { strings: [ "" ] }`,
|
|
|
|
}, {
|
|
|
|
desc: "unknown list of list field",
|
|
|
|
umo: prototext.UnmarshalOptions{DiscardUnknown: true},
|
|
|
|
inputMessage: &pb2.Scalars{},
|
|
|
|
inputText: `unknown_field: { strings: [ [ ] ] }`,
|
|
|
|
wantErr: `(line 1:29): invalid scalar value: [`,
|
2023-09-26 14:56:57 -04:00
|
|
|
}, {
|
|
|
|
desc: "unknown list of message field",
|
|
|
|
umo: prototext.UnmarshalOptions{DiscardUnknown: true},
|
|
|
|
inputMessage: &pb2.Scalars{},
|
|
|
|
inputText: `unknown_field: [ { a: "b" }, { c: "d" } ]`,
|
2019-09-15 00:17:39 -07:00
|
|
|
}, {
|
|
|
|
desc: "proto3 message cannot parse field number",
|
|
|
|
umo: prototext.UnmarshalOptions{DiscardUnknown: true},
|
|
|
|
inputMessage: &pb3.Scalars{},
|
|
|
|
inputText: `13:"goodbye"`,
|
2019-10-31 17:10:15 -07:00
|
|
|
wantErr: "cannot specify field by number",
|
2018-12-06 15:28:53 -08:00
|
|
|
}, {
|
|
|
|
desc: "proto2 numeric key field",
|
|
|
|
inputMessage: &pb2.Scalars{},
|
|
|
|
inputText: "1: true",
|
2019-10-31 17:10:15 -07:00
|
|
|
wantErr: "cannot specify field by number",
|
2018-12-06 15:28:53 -08:00
|
|
|
}, {
|
|
|
|
desc: "proto3 numeric key field",
|
|
|
|
inputMessage: &pb3.Scalars{},
|
|
|
|
inputText: "1: true",
|
2019-10-31 17:10:15 -07:00
|
|
|
wantErr: "cannot specify field by number",
|
2018-12-06 15:28:53 -08:00
|
|
|
}, {
|
|
|
|
desc: "invalid bool value",
|
|
|
|
inputMessage: &pb3.Scalars{},
|
|
|
|
inputText: "s_bool: 123",
|
2019-10-31 17:10:15 -07:00
|
|
|
wantErr: "invalid value for bool",
|
2018-12-06 15:28:53 -08:00
|
|
|
}, {
|
|
|
|
desc: "invalid int32 value",
|
|
|
|
inputMessage: &pb3.Scalars{},
|
|
|
|
inputText: "s_int32: not_a_num",
|
2019-10-31 17:10:15 -07:00
|
|
|
wantErr: "invalid value for int32",
|
2018-12-06 15:28:53 -08:00
|
|
|
}, {
|
|
|
|
desc: "invalid int64 value",
|
|
|
|
inputMessage: &pb3.Scalars{},
|
|
|
|
inputText: "s_int64: 'not a num either'",
|
2019-10-31 17:10:15 -07:00
|
|
|
wantErr: "invalid value for int64",
|
2018-12-06 15:28:53 -08:00
|
|
|
}, {
|
|
|
|
desc: "invalid uint32 value",
|
|
|
|
inputMessage: &pb3.Scalars{},
|
|
|
|
inputText: "s_fixed32: -42",
|
2019-10-31 17:10:15 -07:00
|
|
|
wantErr: "invalid value for fixed32",
|
2018-12-06 15:28:53 -08:00
|
|
|
}, {
|
|
|
|
desc: "invalid uint64 value",
|
|
|
|
inputMessage: &pb3.Scalars{},
|
|
|
|
inputText: "s_uint64: -47",
|
2019-10-31 17:10:15 -07:00
|
|
|
wantErr: "invalid value for uint64",
|
2018-12-06 15:28:53 -08:00
|
|
|
}, {
|
|
|
|
desc: "invalid sint32 value",
|
|
|
|
inputMessage: &pb3.Scalars{},
|
|
|
|
inputText: "s_sint32: '42'",
|
2019-10-31 17:10:15 -07:00
|
|
|
wantErr: "invalid value for sint32",
|
2018-12-06 15:28:53 -08:00
|
|
|
}, {
|
|
|
|
desc: "invalid sint64 value",
|
|
|
|
inputMessage: &pb3.Scalars{},
|
|
|
|
inputText: "s_sint64: '-47'",
|
2019-10-31 17:10:15 -07:00
|
|
|
wantErr: "invalid value for sint64",
|
2018-12-06 15:28:53 -08:00
|
|
|
}, {
|
|
|
|
desc: "invalid fixed32 value",
|
|
|
|
inputMessage: &pb3.Scalars{},
|
|
|
|
inputText: "s_fixed32: -42",
|
2019-10-31 17:10:15 -07:00
|
|
|
wantErr: "invalid value for fixed32",
|
2018-12-06 15:28:53 -08:00
|
|
|
}, {
|
|
|
|
desc: "invalid fixed64 value",
|
|
|
|
inputMessage: &pb3.Scalars{},
|
|
|
|
inputText: "s_fixed64: -42",
|
2019-10-31 17:10:15 -07:00
|
|
|
wantErr: "invalid value for fixed64",
|
2018-12-06 15:28:53 -08:00
|
|
|
}, {
|
|
|
|
desc: "invalid sfixed32 value",
|
|
|
|
inputMessage: &pb3.Scalars{},
|
|
|
|
inputText: "s_sfixed32: 'not valid'",
|
2019-10-31 17:10:15 -07:00
|
|
|
wantErr: "invalid value for sfixed32",
|
2018-12-06 15:28:53 -08:00
|
|
|
}, {
|
|
|
|
desc: "invalid sfixed64 value",
|
|
|
|
inputMessage: &pb3.Scalars{},
|
|
|
|
inputText: "s_sfixed64: bad",
|
2019-10-31 17:10:15 -07:00
|
|
|
wantErr: "invalid value for sfixed64",
|
2023-03-13 11:21:46 -07:00
|
|
|
}, {
|
|
|
|
desc: "incomplete number value",
|
|
|
|
inputMessage: &pb3.Scalars{},
|
|
|
|
inputText: `s_int32: - `,
|
|
|
|
wantErr: "(line 1:10): invalid scalar value: -",
|
2018-12-06 15:28:53 -08:00
|
|
|
}, {
|
2019-10-31 17:10:15 -07:00
|
|
|
desc: "conformance: FloatFieldMaxValue",
|
|
|
|
inputMessage: &pb2.Scalars{},
|
|
|
|
inputText: `opt_float: 3.4028235e+38`,
|
|
|
|
wantMessage: &pb2.Scalars{
|
|
|
|
OptFloat: proto.Float32(3.40282347e+38),
|
2018-12-06 15:28:53 -08:00
|
|
|
},
|
|
|
|
}, {
|
2019-10-31 17:10:15 -07:00
|
|
|
desc: "conformance: FloatFieldLargerThanUint64",
|
|
|
|
inputMessage: &pb2.Scalars{},
|
|
|
|
inputText: `opt_float: 18446744073709551616`,
|
|
|
|
wantMessage: &pb2.Scalars{
|
|
|
|
OptFloat: proto.Float32(1.84467441e+19),
|
2018-12-06 15:28:53 -08:00
|
|
|
},
|
|
|
|
}, {
|
2019-10-31 17:10:15 -07:00
|
|
|
desc: "conformance: FloatFieldTooLarge",
|
|
|
|
inputMessage: &pb2.Scalars{},
|
|
|
|
inputText: `opt_float: 3.4028235e+39`,
|
|
|
|
wantMessage: &pb2.Scalars{
|
|
|
|
OptFloat: proto.Float32(float32(math.Inf(1))),
|
2018-12-06 15:28:53 -08:00
|
|
|
},
|
|
|
|
}, {
|
|
|
|
desc: "invalid string value",
|
|
|
|
inputMessage: &pb3.Scalars{},
|
|
|
|
inputText: "s_string: invalid_string",
|
2019-10-31 17:10:15 -07:00
|
|
|
wantErr: "invalid value for string type",
|
2018-12-06 15:28:53 -08:00
|
|
|
}, {
|
|
|
|
desc: "proto2 bytes set to empty string",
|
|
|
|
inputMessage: &pb2.Scalars{},
|
|
|
|
inputText: "opt_bytes: ''",
|
|
|
|
wantMessage: &pb2.Scalars{
|
|
|
|
OptBytes: []byte(""),
|
|
|
|
},
|
|
|
|
}, {
|
|
|
|
desc: "proto3 bytes set to empty string",
|
|
|
|
inputMessage: &pb3.Scalars{},
|
|
|
|
inputText: "s_bytes: ''",
|
|
|
|
wantMessage: &pb3.Scalars{},
|
|
|
|
}, {
|
|
|
|
desc: "proto2 duplicate singular field",
|
|
|
|
inputMessage: &pb2.Scalars{},
|
|
|
|
inputText: `
|
|
|
|
opt_bool: true
|
|
|
|
opt_bool: false
|
|
|
|
`,
|
2019-10-31 17:10:15 -07:00
|
|
|
wantErr: `(line 3:1): non-repeated field "opt_bool" is repeated`,
|
2018-12-06 15:28:53 -08:00
|
|
|
}, {
|
2019-02-13 14:13:21 -08:00
|
|
|
desc: "proto2 more duplicate singular field",
|
2018-12-06 15:28:53 -08:00
|
|
|
inputMessage: &pb2.Scalars{},
|
|
|
|
inputText: `
|
2019-02-13 14:13:21 -08:00
|
|
|
opt_bool: true
|
|
|
|
opt_string: "hello"
|
|
|
|
opt_bool: false
|
2018-12-06 15:28:53 -08:00
|
|
|
`,
|
2019-10-31 17:10:15 -07:00
|
|
|
wantErr: `(line 4:1): non-repeated field "opt_bool" is repeated`,
|
2018-12-06 15:28:53 -08:00
|
|
|
}, {
|
2019-02-13 14:13:21 -08:00
|
|
|
desc: "proto2 invalid singular field",
|
2018-12-06 15:28:53 -08:00
|
|
|
inputMessage: &pb2.Scalars{},
|
|
|
|
inputText: `
|
2019-02-13 14:13:21 -08:00
|
|
|
opt_bool: [true, false]
|
2018-12-06 15:28:53 -08:00
|
|
|
`,
|
2019-10-31 17:10:15 -07:00
|
|
|
wantErr: "(line 2:11): unexpected token: [",
|
2018-12-06 15:28:53 -08:00
|
|
|
}, {
|
|
|
|
desc: "proto3 duplicate singular field",
|
|
|
|
inputMessage: &pb3.Scalars{},
|
|
|
|
inputText: `
|
|
|
|
s_bool: false
|
|
|
|
s_bool: true
|
|
|
|
`,
|
2019-10-31 17:10:15 -07:00
|
|
|
wantErr: `non-repeated field "s_bool" is repeated`,
|
2018-12-06 15:28:53 -08:00
|
|
|
}, {
|
|
|
|
desc: "proto3 more duplicate singular field",
|
|
|
|
inputMessage: &pb3.Scalars{},
|
|
|
|
inputText: `
|
|
|
|
s_bool: false
|
|
|
|
s_string: ""
|
|
|
|
s_bool: true
|
|
|
|
`,
|
2019-10-31 17:10:15 -07:00
|
|
|
wantErr: `non-repeated field "s_bool" is repeated`,
|
2018-12-06 15:28:53 -08:00
|
|
|
}, {
|
|
|
|
desc: "proto2 enum",
|
|
|
|
inputMessage: &pb2.Enums{},
|
|
|
|
inputText: `
|
2019-02-13 14:13:21 -08:00
|
|
|
opt_enum: ONE
|
2018-12-06 15:28:53 -08:00
|
|
|
opt_nested_enum: UNO
|
|
|
|
`,
|
|
|
|
wantMessage: &pb2.Enums{
|
2019-02-13 14:13:21 -08:00
|
|
|
OptEnum: pb2.Enum_ONE.Enum(),
|
2018-12-06 15:28:53 -08:00
|
|
|
OptNestedEnum: pb2.Enums_UNO.Enum(),
|
|
|
|
},
|
2024-02-23 13:03:15 +01:00
|
|
|
}, {
|
|
|
|
desc: "protoeditions closed enum",
|
|
|
|
inputMessage: &pbeditions.Enums{},
|
|
|
|
inputText: `
|
|
|
|
opt_enum: ONE
|
|
|
|
opt_nested_enum: UNO
|
|
|
|
`,
|
|
|
|
wantMessage: &pbeditions.Enums{
|
|
|
|
OptEnum: pbeditions.Enum_ONE.Enum(),
|
|
|
|
OptNestedEnum: pbeditions.Enums_UNO.Enum(),
|
|
|
|
},
|
|
|
|
}, {
|
|
|
|
desc: "protoeditions open enum",
|
|
|
|
inputMessage: &pbeditions.Enums{},
|
|
|
|
inputText: `
|
|
|
|
implicit_enum: EINS
|
|
|
|
implicit_nested_enum: ZEHN
|
|
|
|
`,
|
|
|
|
wantMessage: &pbeditions.Enums{
|
|
|
|
ImplicitEnum: pbeditions.OpenEnum_EINS,
|
|
|
|
ImplicitNestedEnum: pbeditions.Enums_ZEHN,
|
|
|
|
},
|
|
|
|
}, {
|
|
|
|
desc: "protoeditions enum numeric value",
|
|
|
|
inputMessage: &pbeditions.Enums{},
|
|
|
|
inputText: `
|
|
|
|
implicit_enum: 1
|
|
|
|
implicit_nested_enum: 10
|
|
|
|
`,
|
|
|
|
wantMessage: &pbeditions.Enums{
|
|
|
|
ImplicitEnum: pbeditions.OpenEnum_EINS,
|
|
|
|
ImplicitNestedEnum: pbeditions.Enums_ZEHN,
|
|
|
|
},
|
2018-12-06 15:28:53 -08:00
|
|
|
}, {
|
|
|
|
desc: "proto2 enum set to numeric values",
|
|
|
|
inputMessage: &pb2.Enums{},
|
|
|
|
inputText: `
|
2019-02-13 14:13:21 -08:00
|
|
|
opt_enum: 2
|
2018-12-06 15:28:53 -08:00
|
|
|
opt_nested_enum: 2
|
|
|
|
`,
|
|
|
|
wantMessage: &pb2.Enums{
|
2019-02-13 14:13:21 -08:00
|
|
|
OptEnum: pb2.Enum_TWO.Enum(),
|
2018-12-06 15:28:53 -08:00
|
|
|
OptNestedEnum: pb2.Enums_DOS.Enum(),
|
|
|
|
},
|
|
|
|
}, {
|
|
|
|
desc: "proto2 enum set to unnamed numeric values",
|
|
|
|
inputMessage: &pb2.Enums{},
|
|
|
|
inputText: `
|
|
|
|
opt_enum: 101
|
|
|
|
opt_nested_enum: -101
|
|
|
|
`,
|
|
|
|
wantMessage: &pb2.Enums{
|
2019-07-09 23:11:13 -07:00
|
|
|
OptEnum: pb2.Enum(101).Enum(),
|
|
|
|
OptNestedEnum: pb2.Enums_NestedEnum(-101).Enum(),
|
2018-12-06 15:28:53 -08:00
|
|
|
},
|
|
|
|
}, {
|
|
|
|
desc: "proto2 enum set to invalid named",
|
|
|
|
inputMessage: &pb2.Enums{},
|
|
|
|
inputText: `
|
2019-02-13 14:13:21 -08:00
|
|
|
opt_enum: UNNAMED
|
2018-12-06 15:28:53 -08:00
|
|
|
opt_nested_enum: UNNAMED_TOO
|
|
|
|
`,
|
2019-10-31 17:10:15 -07:00
|
|
|
wantErr: "invalid value for enum type: UNNAMED",
|
2018-12-06 15:28:53 -08:00
|
|
|
}, {
|
|
|
|
desc: "proto3 enum name value",
|
|
|
|
inputMessage: &pb3.Enums{},
|
|
|
|
inputText: `
|
|
|
|
s_enum: ONE
|
|
|
|
s_nested_enum: DIEZ
|
|
|
|
`,
|
|
|
|
wantMessage: &pb3.Enums{
|
|
|
|
SEnum: pb3.Enum_ONE,
|
|
|
|
SNestedEnum: pb3.Enums_DIEZ,
|
|
|
|
},
|
|
|
|
}, {
|
|
|
|
desc: "proto3 enum numeric value",
|
|
|
|
inputMessage: &pb3.Enums{},
|
|
|
|
inputText: `
|
|
|
|
s_enum: 2
|
2019-02-13 14:13:21 -08:00
|
|
|
s_nested_enum: 2
|
2018-12-06 15:28:53 -08:00
|
|
|
`,
|
|
|
|
wantMessage: &pb3.Enums{
|
|
|
|
SEnum: pb3.Enum_TWO,
|
2019-02-13 14:13:21 -08:00
|
|
|
SNestedEnum: pb3.Enums_DOS,
|
2018-12-06 15:28:53 -08:00
|
|
|
},
|
|
|
|
}, {
|
|
|
|
desc: "proto3 enum unnamed numeric value",
|
|
|
|
inputMessage: &pb3.Enums{},
|
|
|
|
inputText: `
|
|
|
|
s_enum: 0x7fffffff
|
|
|
|
s_nested_enum: -0x80000000
|
|
|
|
`,
|
|
|
|
wantMessage: &pb3.Enums{
|
|
|
|
SEnum: 0x7fffffff,
|
|
|
|
SNestedEnum: -0x80000000,
|
|
|
|
},
|
|
|
|
}, {
|
|
|
|
desc: "proto2 nested empty messages",
|
|
|
|
inputMessage: &pb2.Nests{},
|
|
|
|
inputText: `
|
|
|
|
opt_nested: {}
|
2019-01-14 15:32:26 -08:00
|
|
|
OptGroup: {}
|
2019-10-31 17:10:15 -07:00
|
|
|
`,
|
|
|
|
wantMessage: &pb2.Nests{
|
|
|
|
OptNested: &pb2.Nested{},
|
|
|
|
Optgroup: &pb2.Nests_OptGroup{},
|
|
|
|
},
|
2024-02-23 13:03:15 +01:00
|
|
|
}, {
|
|
|
|
desc: "protoeditions nested empty messages",
|
|
|
|
inputMessage: &pbeditions.Nests{},
|
|
|
|
inputText: `
|
|
|
|
opt_nested: {}
|
|
|
|
OptGroup: {}
|
2024-04-02 12:59:48 -07:00
|
|
|
delimited_field: {}
|
2024-02-23 13:03:15 +01:00
|
|
|
`,
|
|
|
|
wantMessage: &pbeditions.Nests{
|
2024-04-02 12:59:48 -07:00
|
|
|
OptNested: &pbeditions.Nested{},
|
|
|
|
Optgroup: &pbeditions.Nests_OptGroup{},
|
|
|
|
DelimitedField: &pbeditions.Nests_OptGroup{},
|
2024-02-23 13:03:15 +01:00
|
|
|
},
|
2019-10-31 17:10:15 -07:00
|
|
|
}, {
|
|
|
|
desc: "message fields with no field separator",
|
|
|
|
inputMessage: &pb2.Nests{},
|
|
|
|
inputText: `
|
|
|
|
opt_nested {}
|
|
|
|
OptGroup {}
|
2018-12-06 15:28:53 -08:00
|
|
|
`,
|
|
|
|
wantMessage: &pb2.Nests{
|
|
|
|
OptNested: &pb2.Nested{},
|
|
|
|
Optgroup: &pb2.Nests_OptGroup{},
|
|
|
|
},
|
2024-02-23 13:03:15 +01:00
|
|
|
}, {
|
|
|
|
desc: "message fields with no field separator",
|
|
|
|
inputMessage: &pbeditions.Nests{},
|
|
|
|
inputText: `
|
|
|
|
opt_nested {}
|
|
|
|
OptGroup {}
|
2024-04-02 12:59:48 -07:00
|
|
|
delimited_field {}
|
2024-02-23 13:03:15 +01:00
|
|
|
`,
|
|
|
|
wantMessage: &pbeditions.Nests{
|
2024-04-02 12:59:48 -07:00
|
|
|
OptNested: &pbeditions.Nested{},
|
|
|
|
Optgroup: &pbeditions.Nests_OptGroup{},
|
|
|
|
DelimitedField: &pbeditions.Nests_OptGroup{},
|
2024-02-23 13:03:15 +01:00
|
|
|
},
|
2019-06-24 19:21:46 -07:00
|
|
|
}, {
|
|
|
|
desc: "group field name",
|
|
|
|
inputMessage: &pb2.Nests{},
|
|
|
|
inputText: `optgroup: {}`,
|
2024-05-02 12:57:08 +02:00
|
|
|
wantMessage: &pb2.Nests{
|
|
|
|
Optgroup: &pb2.Nests_OptGroup{},
|
|
|
|
},
|
2024-02-23 13:03:15 +01:00
|
|
|
}, {
|
2024-05-02 12:57:08 +02:00
|
|
|
desc: "delimited encoded group-like message field name",
|
2024-02-23 13:03:15 +01:00
|
|
|
inputMessage: &pbeditions.Nests{},
|
2024-05-02 12:57:08 +02:00
|
|
|
inputText: `optgroup {}`,
|
|
|
|
wantMessage: &pbeditions.Nests{
|
|
|
|
Optgroup: &pbeditions.Nests_OptGroup{},
|
|
|
|
},
|
2024-04-02 12:59:48 -07:00
|
|
|
}, {
|
|
|
|
desc: "delimited encoded message field name",
|
|
|
|
inputMessage: &pbeditions.Nests{},
|
|
|
|
inputText: `Delimited_Field: {}`,
|
|
|
|
wantErr: "unknown field: Delimited_Field",
|
2018-12-06 15:28:53 -08:00
|
|
|
}, {
|
|
|
|
desc: "proto2 nested messages",
|
|
|
|
inputMessage: &pb2.Nests{},
|
|
|
|
inputText: `
|
|
|
|
opt_nested: {
|
|
|
|
opt_string: "nested message"
|
|
|
|
opt_nested: {
|
|
|
|
opt_string: "another nested message"
|
|
|
|
}
|
|
|
|
}
|
|
|
|
`,
|
|
|
|
wantMessage: &pb2.Nests{
|
|
|
|
OptNested: &pb2.Nested{
|
2019-07-10 16:17:16 -07:00
|
|
|
OptString: proto.String("nested message"),
|
2018-12-06 15:28:53 -08:00
|
|
|
OptNested: &pb2.Nested{
|
2019-07-10 16:17:16 -07:00
|
|
|
OptString: proto.String("another nested message"),
|
2018-12-06 15:28:53 -08:00
|
|
|
},
|
|
|
|
},
|
|
|
|
},
|
2024-02-23 13:03:15 +01:00
|
|
|
}, {
|
|
|
|
desc: "protoeditions delimited encoded nested messages",
|
|
|
|
inputMessage: &pbeditions.Nests{},
|
|
|
|
inputText: `
|
|
|
|
opt_nested: {
|
|
|
|
opt_string: "nested message"
|
|
|
|
opt_nested: {
|
|
|
|
opt_string: "another nested message"
|
|
|
|
}
|
|
|
|
}
|
|
|
|
`,
|
|
|
|
wantMessage: &pbeditions.Nests{
|
|
|
|
OptNested: &pbeditions.Nested{
|
|
|
|
OptString: proto.String("nested message"),
|
|
|
|
OptNested: &pbeditions.Nested{
|
|
|
|
OptString: proto.String("another nested message"),
|
|
|
|
},
|
|
|
|
},
|
|
|
|
},
|
2018-12-06 15:28:53 -08:00
|
|
|
}, {
|
|
|
|
desc: "proto3 nested empty message",
|
|
|
|
inputMessage: &pb3.Nests{},
|
|
|
|
inputText: "s_nested: {}",
|
|
|
|
wantMessage: &pb3.Nests{
|
|
|
|
SNested: &pb3.Nested{},
|
|
|
|
},
|
|
|
|
}, {
|
|
|
|
desc: "proto3 nested message",
|
|
|
|
inputMessage: &pb3.Nests{},
|
|
|
|
inputText: `
|
|
|
|
s_nested: {
|
|
|
|
s_string: "nested message"
|
|
|
|
s_nested: {
|
|
|
|
s_string: "another nested message"
|
|
|
|
}
|
|
|
|
}
|
|
|
|
`,
|
|
|
|
wantMessage: &pb3.Nests{
|
|
|
|
SNested: &pb3.Nested{
|
|
|
|
SString: "nested message",
|
|
|
|
SNested: &pb3.Nested{
|
|
|
|
SString: "another nested message",
|
|
|
|
},
|
|
|
|
},
|
|
|
|
},
|
2019-04-08 17:32:44 -07:00
|
|
|
}, {
|
|
|
|
desc: "proto3 nested message contains invalid UTF-8",
|
|
|
|
inputMessage: &pb3.Nests{},
|
|
|
|
inputText: `s_nested: {
|
|
|
|
s_string: "abc\xff"
|
|
|
|
}
|
|
|
|
`,
|
2019-10-31 17:10:15 -07:00
|
|
|
wantErr: "contains invalid UTF-8",
|
2018-12-06 15:28:53 -08:00
|
|
|
}, {
|
2019-02-13 14:13:21 -08:00
|
|
|
desc: "oneof set to empty string",
|
|
|
|
inputMessage: &pb3.Oneofs{},
|
|
|
|
inputText: "oneof_string: ''",
|
|
|
|
wantMessage: &pb3.Oneofs{
|
|
|
|
Union: &pb3.Oneofs_OneofString{},
|
2018-12-06 15:28:53 -08:00
|
|
|
},
|
|
|
|
}, {
|
2019-02-13 14:13:21 -08:00
|
|
|
desc: "oneof set to string",
|
|
|
|
inputMessage: &pb3.Oneofs{},
|
|
|
|
inputText: "oneof_string: 'hello'",
|
|
|
|
wantMessage: &pb3.Oneofs{
|
|
|
|
Union: &pb3.Oneofs_OneofString{
|
|
|
|
OneofString: "hello",
|
2018-12-06 15:28:53 -08:00
|
|
|
},
|
|
|
|
},
|
|
|
|
}, {
|
2019-02-13 14:13:21 -08:00
|
|
|
desc: "oneof set to enum",
|
|
|
|
inputMessage: &pb3.Oneofs{},
|
|
|
|
inputText: "oneof_enum: TEN",
|
|
|
|
wantMessage: &pb3.Oneofs{
|
|
|
|
Union: &pb3.Oneofs_OneofEnum{
|
|
|
|
OneofEnum: pb3.Enum_TEN,
|
2018-12-06 15:28:53 -08:00
|
|
|
},
|
|
|
|
},
|
|
|
|
}, {
|
2019-02-13 14:13:21 -08:00
|
|
|
desc: "oneof set to empty message",
|
|
|
|
inputMessage: &pb3.Oneofs{},
|
|
|
|
inputText: "oneof_nested: {}",
|
|
|
|
wantMessage: &pb3.Oneofs{
|
|
|
|
Union: &pb3.Oneofs_OneofNested{
|
|
|
|
OneofNested: &pb3.Nested{},
|
|
|
|
},
|
|
|
|
},
|
|
|
|
}, {
|
|
|
|
desc: "oneof set to message",
|
|
|
|
inputMessage: &pb3.Oneofs{},
|
2018-12-06 15:28:53 -08:00
|
|
|
inputText: `
|
2019-02-13 14:13:21 -08:00
|
|
|
oneof_nested: {
|
|
|
|
s_string: "nested message"
|
2018-12-06 15:28:53 -08:00
|
|
|
}
|
|
|
|
`,
|
2019-02-13 14:13:21 -08:00
|
|
|
wantMessage: &pb3.Oneofs{
|
|
|
|
Union: &pb3.Oneofs_OneofNested{
|
|
|
|
OneofNested: &pb3.Nested{
|
|
|
|
SString: "nested message",
|
2018-12-06 15:28:53 -08:00
|
|
|
},
|
|
|
|
},
|
|
|
|
},
|
2019-01-07 18:56:57 -08:00
|
|
|
}, {
|
2019-04-02 20:19:36 -07:00
|
|
|
desc: "oneof set to more than one field",
|
2019-02-13 14:13:21 -08:00
|
|
|
inputMessage: &pb3.Oneofs{},
|
2019-01-07 18:56:57 -08:00
|
|
|
inputText: `
|
2019-04-02 20:19:36 -07:00
|
|
|
oneof_enum: ZERO
|
|
|
|
oneof_string: "hello"
|
2019-01-07 18:56:57 -08:00
|
|
|
`,
|
2019-10-31 17:10:15 -07:00
|
|
|
wantErr: `error parsing "oneof_string", oneof pb3.Oneofs.union is already set`,
|
2018-12-06 15:28:53 -08:00
|
|
|
}, {
|
|
|
|
desc: "repeated scalar using same field name",
|
|
|
|
inputMessage: &pb2.Repeats{},
|
|
|
|
inputText: `
|
|
|
|
rpt_string: "a"
|
|
|
|
rpt_string: "b"
|
|
|
|
rpt_int32: 0xff
|
|
|
|
rpt_float: 1.23
|
|
|
|
rpt_bytes: "bytes"
|
|
|
|
`,
|
|
|
|
wantMessage: &pb2.Repeats{
|
|
|
|
RptString: []string{"a", "b"},
|
|
|
|
RptInt32: []int32{0xff},
|
|
|
|
RptFloat: []float32{1.23},
|
|
|
|
RptBytes: [][]byte{[]byte("bytes")},
|
|
|
|
},
|
|
|
|
}, {
|
|
|
|
desc: "repeated using mix of [] and repeated field name",
|
|
|
|
inputMessage: &pb2.Repeats{},
|
|
|
|
inputText: `
|
|
|
|
rpt_string: "a"
|
|
|
|
rpt_bool: true
|
|
|
|
rpt_string: ["x", "y"]
|
|
|
|
rpt_bool: [ false, true ]
|
|
|
|
rpt_string: "b"
|
|
|
|
`,
|
|
|
|
wantMessage: &pb2.Repeats{
|
|
|
|
RptString: []string{"a", "x", "y", "b"},
|
|
|
|
RptBool: []bool{true, false, true},
|
|
|
|
},
|
2019-04-08 17:32:44 -07:00
|
|
|
}, {
|
encoding/prototext: adjust handling of invalid UTF-8
The following changes are made:
* Permit invalid UTF-8 in proto2. This goes against specified behavior,
but matches functional behavior in wire marshaling (not just for Go,
but also in the other major language implementations as well).
* The Format function is specified as ignoring errors since its intended
purpose is to surface information to the human user even if it's not
exactly parsible back into a message. As such, add an unexported
allowInvalidUTF8 option that is specially used by Format.
* Add an EmitASCII option that forces the formatting of
strings and bytes to always be encoded as ASCII.
This ensures that the entire output is always ASCII as well.
Note that we do not replicate this behavior for protojson since:
* The JSON format fundamentally has a stricter and well-specified
grammar for exactly what is valid/invalid, while the text format
has not had a well-specified grammar for the longest time,
leading to all sorts of weird usages due to Hyrum's law.
* This is to ease migration from the legacy implementation,
which did permit invalid UTF-8 in proto2.
* The EmitASCII option relies on the ability to always escape
Unicode characters using ASCII escape sequences, but this is not
possible in JSON since the grammar only has an escape sequence defined
for Unicode characters \u0000 to \uffff, inclusive.
However, Unicode v12.0.0 defines characters up to \U0010FFFF,
which is beyond what the JSON grammar provides escape sequences for.
Change-Id: I2b524a904e9ec59f9ed5500e299613bc27c31a14
Reviewed-on: https://go-review.googlesource.com/c/protobuf/+/233077
Reviewed-by: Herbie Ong <herbie@google.com>
2020-05-07 15:10:54 -07:00
|
|
|
desc: "repeated proto2 contains invalid UTF-8",
|
2019-04-08 17:32:44 -07:00
|
|
|
inputMessage: &pb2.Repeats{},
|
|
|
|
inputText: `rpt_string: "abc\xff"`,
|
encoding/prototext: adjust handling of invalid UTF-8
The following changes are made:
* Permit invalid UTF-8 in proto2. This goes against specified behavior,
but matches functional behavior in wire marshaling (not just for Go,
but also in the other major language implementations as well).
* The Format function is specified as ignoring errors since its intended
purpose is to surface information to the human user even if it's not
exactly parsible back into a message. As such, add an unexported
allowInvalidUTF8 option that is specially used by Format.
* Add an EmitASCII option that forces the formatting of
strings and bytes to always be encoded as ASCII.
This ensures that the entire output is always ASCII as well.
Note that we do not replicate this behavior for protojson since:
* The JSON format fundamentally has a stricter and well-specified
grammar for exactly what is valid/invalid, while the text format
has not had a well-specified grammar for the longest time,
leading to all sorts of weird usages due to Hyrum's law.
* This is to ease migration from the legacy implementation,
which did permit invalid UTF-8 in proto2.
* The EmitASCII option relies on the ability to always escape
Unicode characters using ASCII escape sequences, but this is not
possible in JSON since the grammar only has an escape sequence defined
for Unicode characters \u0000 to \uffff, inclusive.
However, Unicode v12.0.0 defines characters up to \U0010FFFF,
which is beyond what the JSON grammar provides escape sequences for.
Change-Id: I2b524a904e9ec59f9ed5500e299613bc27c31a14
Reviewed-on: https://go-review.googlesource.com/c/protobuf/+/233077
Reviewed-by: Herbie Ong <herbie@google.com>
2020-05-07 15:10:54 -07:00
|
|
|
wantMessage: &pb2.Repeats{
|
|
|
|
RptString: []string{"abc\xff"},
|
|
|
|
},
|
|
|
|
}, {
|
|
|
|
desc: "repeated proto3 contains invalid UTF-8",
|
|
|
|
inputMessage: &pb3.Repeats{},
|
|
|
|
inputText: `rpt_string: "abc\xff"`,
|
2019-10-31 17:10:15 -07:00
|
|
|
wantErr: "contains invalid UTF-8",
|
2018-12-06 15:28:53 -08:00
|
|
|
}, {
|
|
|
|
desc: "repeated enums",
|
|
|
|
inputMessage: &pb2.Enums{},
|
|
|
|
inputText: `
|
2019-02-13 14:13:21 -08:00
|
|
|
rpt_enum: TEN
|
2018-12-06 15:28:53 -08:00
|
|
|
rpt_enum: 1
|
|
|
|
rpt_nested_enum: [DOS, 2]
|
|
|
|
rpt_enum: 42
|
|
|
|
rpt_nested_enum: -47
|
|
|
|
`,
|
|
|
|
wantMessage: &pb2.Enums{
|
2019-02-13 14:13:21 -08:00
|
|
|
RptEnum: []pb2.Enum{pb2.Enum_TEN, pb2.Enum_ONE, 42},
|
2018-12-06 15:28:53 -08:00
|
|
|
RptNestedEnum: []pb2.Enums_NestedEnum{pb2.Enums_DOS, pb2.Enums_DOS, -47},
|
|
|
|
},
|
|
|
|
}, {
|
|
|
|
desc: "repeated nested messages",
|
|
|
|
inputMessage: &pb2.Nests{},
|
|
|
|
inputText: `
|
|
|
|
rpt_nested: {
|
|
|
|
opt_string: "repeat nested one"
|
|
|
|
}
|
|
|
|
rpt_nested: {
|
|
|
|
opt_string: "repeat nested two"
|
|
|
|
opt_nested: {
|
|
|
|
opt_string: "inside repeat nested two"
|
|
|
|
}
|
|
|
|
}
|
|
|
|
rpt_nested: {}
|
|
|
|
`,
|
|
|
|
wantMessage: &pb2.Nests{
|
|
|
|
RptNested: []*pb2.Nested{
|
|
|
|
{
|
2019-07-10 16:17:16 -07:00
|
|
|
OptString: proto.String("repeat nested one"),
|
2018-12-06 15:28:53 -08:00
|
|
|
},
|
|
|
|
{
|
2019-07-10 16:17:16 -07:00
|
|
|
OptString: proto.String("repeat nested two"),
|
2018-12-06 15:28:53 -08:00
|
|
|
OptNested: &pb2.Nested{
|
2019-07-10 16:17:16 -07:00
|
|
|
OptString: proto.String("inside repeat nested two"),
|
2018-12-06 15:28:53 -08:00
|
|
|
},
|
|
|
|
},
|
|
|
|
{},
|
|
|
|
},
|
|
|
|
},
|
|
|
|
}, {
|
|
|
|
desc: "repeated group fields",
|
|
|
|
inputMessage: &pb2.Nests{},
|
|
|
|
inputText: `
|
2019-01-14 15:32:26 -08:00
|
|
|
RptGroup: {
|
2019-02-13 14:13:21 -08:00
|
|
|
rpt_string: "hello"
|
|
|
|
rpt_string: "world"
|
2018-12-06 15:28:53 -08:00
|
|
|
}
|
2019-01-14 15:32:26 -08:00
|
|
|
RptGroup: {}
|
2018-12-06 15:28:53 -08:00
|
|
|
`,
|
|
|
|
wantMessage: &pb2.Nests{
|
|
|
|
Rptgroup: []*pb2.Nests_RptGroup{
|
|
|
|
{
|
2019-02-13 14:13:21 -08:00
|
|
|
RptString: []string{"hello", "world"},
|
2018-12-06 15:28:53 -08:00
|
|
|
},
|
|
|
|
{},
|
|
|
|
},
|
|
|
|
},
|
2024-02-23 13:03:15 +01:00
|
|
|
}, {
|
|
|
|
desc: "repeated delimited encoded message fields",
|
|
|
|
inputMessage: &pbeditions.Nests{},
|
|
|
|
inputText: `
|
|
|
|
RptGroup: {
|
|
|
|
rpt_string: "hello"
|
|
|
|
rpt_string: "world"
|
|
|
|
}
|
|
|
|
RptGroup: {}
|
|
|
|
`,
|
|
|
|
wantMessage: &pbeditions.Nests{
|
|
|
|
Rptgroup: []*pbeditions.Nests_RptGroup{
|
|
|
|
{
|
|
|
|
RptString: []string{"hello", "world"},
|
|
|
|
},
|
|
|
|
{},
|
|
|
|
},
|
|
|
|
},
|
2019-10-31 17:10:15 -07:00
|
|
|
}, {
|
|
|
|
desc: "repeated message fields without field separator",
|
|
|
|
inputMessage: &pb2.Nests{},
|
|
|
|
inputText: `
|
|
|
|
rpt_nested {
|
|
|
|
opt_string: "repeat nested one"
|
|
|
|
}
|
|
|
|
rpt_nested: [
|
|
|
|
{
|
|
|
|
opt_string: "repeat nested two"
|
|
|
|
},
|
|
|
|
{}
|
|
|
|
]
|
|
|
|
`,
|
|
|
|
wantMessage: &pb2.Nests{
|
|
|
|
RptNested: []*pb2.Nested{
|
|
|
|
{
|
|
|
|
OptString: proto.String("repeat nested one"),
|
|
|
|
},
|
|
|
|
{
|
|
|
|
OptString: proto.String("repeat nested two"),
|
|
|
|
},
|
|
|
|
{},
|
|
|
|
},
|
|
|
|
},
|
|
|
|
}, {
|
|
|
|
desc: "bools",
|
|
|
|
inputMessage: &pb2.Repeats{},
|
|
|
|
inputText: `
|
|
|
|
rpt_bool: [ True, true, t, 1, False, false, f, 0 ]
|
|
|
|
`,
|
|
|
|
wantMessage: &pb2.Repeats{
|
|
|
|
RptBool: []bool{true, true, true, true, false, false, false, false},
|
|
|
|
},
|
|
|
|
}, {
|
|
|
|
desc: "special floats and doubles",
|
|
|
|
inputMessage: &pb2.Repeats{},
|
|
|
|
inputText: `
|
|
|
|
rpt_float: [ inf, Inf, infinity, InFiniTy, -inf, -inF, -infinitY, -InfinitY, nan, NaN, Nan ],
|
|
|
|
rpt_double: [ inf, Inf, infinity, InFiniTy, -inf, -inF, -infinitY, -InfinitY, nan, NaN, Nan ],
|
|
|
|
`,
|
|
|
|
wantMessage: &pb2.Repeats{
|
|
|
|
RptFloat: []float32{
|
|
|
|
float32(math.Inf(1)),
|
|
|
|
float32(math.Inf(1)),
|
|
|
|
float32(math.Inf(1)),
|
|
|
|
float32(math.Inf(1)),
|
|
|
|
float32(math.Inf(-1)),
|
|
|
|
float32(math.Inf(-1)),
|
|
|
|
float32(math.Inf(-1)),
|
|
|
|
float32(math.Inf(-1)),
|
|
|
|
float32(math.NaN()),
|
|
|
|
float32(math.NaN()),
|
|
|
|
float32(math.NaN()),
|
|
|
|
},
|
|
|
|
RptDouble: []float64{
|
|
|
|
math.Inf(1),
|
|
|
|
math.Inf(1),
|
|
|
|
math.Inf(1),
|
|
|
|
math.Inf(1),
|
|
|
|
math.Inf(-1),
|
|
|
|
math.Inf(-1),
|
|
|
|
math.Inf(-1),
|
|
|
|
math.Inf(-1),
|
|
|
|
math.NaN(),
|
|
|
|
math.NaN(),
|
|
|
|
math.NaN(),
|
|
|
|
},
|
|
|
|
},
|
2018-12-06 15:28:53 -08:00
|
|
|
}, {
|
|
|
|
desc: "map fields 1",
|
2019-02-13 14:13:21 -08:00
|
|
|
inputMessage: &pb3.Maps{},
|
2018-12-06 15:28:53 -08:00
|
|
|
inputText: `
|
|
|
|
int32_to_str: {
|
|
|
|
key: -101
|
|
|
|
value: "-101"
|
|
|
|
}
|
2019-10-31 17:10:15 -07:00
|
|
|
int32_to_str {
|
2018-12-06 15:28:53 -08:00
|
|
|
key: 0
|
|
|
|
value: "zero"
|
|
|
|
}
|
|
|
|
bool_to_uint32: {
|
|
|
|
key: false
|
|
|
|
value: 101
|
|
|
|
}
|
2019-02-13 14:13:21 -08:00
|
|
|
int32_to_str: {
|
|
|
|
key: 255
|
|
|
|
value: "0xff"
|
2018-12-06 15:28:53 -08:00
|
|
|
}
|
2019-10-31 17:10:15 -07:00
|
|
|
bool_to_uint32 {
|
2018-12-06 15:28:53 -08:00
|
|
|
key: true
|
|
|
|
value: 42
|
|
|
|
}
|
|
|
|
`,
|
2019-02-13 14:13:21 -08:00
|
|
|
wantMessage: &pb3.Maps{
|
2018-12-06 15:28:53 -08:00
|
|
|
Int32ToStr: map[int32]string{
|
|
|
|
-101: "-101",
|
|
|
|
0xff: "0xff",
|
|
|
|
0: "zero",
|
|
|
|
},
|
|
|
|
BoolToUint32: map[bool]uint32{
|
|
|
|
true: 42,
|
|
|
|
false: 101,
|
|
|
|
},
|
|
|
|
},
|
|
|
|
}, {
|
|
|
|
desc: "map fields 2",
|
2019-02-13 14:13:21 -08:00
|
|
|
inputMessage: &pb3.Maps{},
|
2018-12-06 15:28:53 -08:00
|
|
|
inputText: `
|
|
|
|
uint64_to_enum: {
|
|
|
|
key: 1
|
2019-02-13 14:13:21 -08:00
|
|
|
value: ONE
|
2018-12-06 15:28:53 -08:00
|
|
|
}
|
|
|
|
uint64_to_enum: {
|
|
|
|
key: 2
|
2019-02-13 14:13:21 -08:00
|
|
|
value: 2
|
2018-12-06 15:28:53 -08:00
|
|
|
}
|
|
|
|
uint64_to_enum: {
|
|
|
|
key: 10
|
2019-02-13 14:13:21 -08:00
|
|
|
value: 101
|
2018-12-06 15:28:53 -08:00
|
|
|
}
|
|
|
|
`,
|
2019-02-13 14:13:21 -08:00
|
|
|
wantMessage: &pb3.Maps{
|
|
|
|
Uint64ToEnum: map[uint64]pb3.Enum{
|
|
|
|
1: pb3.Enum_ONE,
|
|
|
|
2: pb3.Enum_TWO,
|
|
|
|
10: 101,
|
2018-12-06 15:28:53 -08:00
|
|
|
},
|
|
|
|
},
|
|
|
|
}, {
|
|
|
|
desc: "map fields 3",
|
2019-02-13 14:13:21 -08:00
|
|
|
inputMessage: &pb3.Maps{},
|
2018-12-06 15:28:53 -08:00
|
|
|
inputText: `
|
|
|
|
str_to_nested: {
|
|
|
|
key: "nested_one"
|
2019-10-31 17:10:15 -07:00
|
|
|
value {
|
2019-02-13 14:13:21 -08:00
|
|
|
s_string: "nested in a map"
|
2018-12-06 15:28:53 -08:00
|
|
|
}
|
|
|
|
}
|
|
|
|
`,
|
2019-02-13 14:13:21 -08:00
|
|
|
wantMessage: &pb3.Maps{
|
|
|
|
StrToNested: map[string]*pb3.Nested{
|
|
|
|
"nested_one": &pb3.Nested{
|
|
|
|
SString: "nested in a map",
|
2018-12-06 15:28:53 -08:00
|
|
|
},
|
|
|
|
},
|
|
|
|
},
|
|
|
|
}, {
|
|
|
|
desc: "map fields 4",
|
2019-02-13 14:13:21 -08:00
|
|
|
inputMessage: &pb3.Maps{},
|
2018-12-06 15:28:53 -08:00
|
|
|
inputText: `
|
|
|
|
str_to_oneofs: {
|
|
|
|
key: "nested"
|
|
|
|
value: {
|
2019-02-13 14:13:21 -08:00
|
|
|
oneof_nested: {
|
|
|
|
s_string: "nested oneof in map field value"
|
2018-12-06 15:28:53 -08:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
str_to_oneofs: {
|
|
|
|
key: "string"
|
|
|
|
value: {
|
2019-02-13 14:13:21 -08:00
|
|
|
oneof_string: "hello"
|
2018-12-06 15:28:53 -08:00
|
|
|
}
|
|
|
|
}
|
|
|
|
`,
|
2019-02-13 14:13:21 -08:00
|
|
|
wantMessage: &pb3.Maps{
|
|
|
|
StrToOneofs: map[string]*pb3.Oneofs{
|
|
|
|
"string": &pb3.Oneofs{
|
|
|
|
Union: &pb3.Oneofs_OneofString{
|
|
|
|
OneofString: "hello",
|
2018-12-06 15:28:53 -08:00
|
|
|
},
|
|
|
|
},
|
2019-02-13 14:13:21 -08:00
|
|
|
"nested": &pb3.Oneofs{
|
|
|
|
Union: &pb3.Oneofs_OneofNested{
|
|
|
|
OneofNested: &pb3.Nested{
|
|
|
|
SString: "nested oneof in map field value",
|
2018-12-06 15:28:53 -08:00
|
|
|
},
|
|
|
|
},
|
|
|
|
},
|
|
|
|
},
|
|
|
|
},
|
|
|
|
}, {
|
|
|
|
desc: "map contains duplicate keys",
|
2019-02-13 14:13:21 -08:00
|
|
|
inputMessage: &pb3.Maps{},
|
2018-12-06 15:28:53 -08:00
|
|
|
inputText: `
|
|
|
|
int32_to_str: {
|
|
|
|
key: 0
|
|
|
|
value: "cero"
|
|
|
|
}
|
|
|
|
int32_to_str: {
|
|
|
|
key: 0
|
|
|
|
value: "zero"
|
|
|
|
}
|
|
|
|
`,
|
2019-02-13 14:13:21 -08:00
|
|
|
wantMessage: &pb3.Maps{
|
2018-12-06 15:28:53 -08:00
|
|
|
Int32ToStr: map[int32]string{
|
|
|
|
0: "zero",
|
|
|
|
},
|
|
|
|
},
|
|
|
|
}, {
|
|
|
|
desc: "map contains duplicate key fields",
|
2019-02-13 14:13:21 -08:00
|
|
|
inputMessage: &pb3.Maps{},
|
2018-12-06 15:28:53 -08:00
|
|
|
inputText: `
|
|
|
|
int32_to_str: {
|
|
|
|
key: 0
|
|
|
|
key: 1
|
|
|
|
value: "cero"
|
|
|
|
}
|
|
|
|
`,
|
2019-10-31 17:10:15 -07:00
|
|
|
wantErr: `map entry "key" cannot be repeated`,
|
2018-12-06 15:28:53 -08:00
|
|
|
}, {
|
|
|
|
desc: "map contains duplicate value fields",
|
2019-02-13 14:13:21 -08:00
|
|
|
inputMessage: &pb3.Maps{},
|
2018-12-06 15:28:53 -08:00
|
|
|
inputText: `
|
|
|
|
int32_to_str: {
|
|
|
|
key: 1
|
|
|
|
value: "cero"
|
|
|
|
value: "uno"
|
|
|
|
}
|
|
|
|
`,
|
2019-10-31 17:10:15 -07:00
|
|
|
wantErr: `map entry "value" cannot be repeated`,
|
2018-12-06 15:28:53 -08:00
|
|
|
}, {
|
|
|
|
desc: "map contains missing key",
|
2019-02-13 14:13:21 -08:00
|
|
|
inputMessage: &pb3.Maps{},
|
2018-12-06 15:28:53 -08:00
|
|
|
inputText: `
|
|
|
|
int32_to_str: {
|
|
|
|
value: "zero"
|
|
|
|
}
|
2019-02-13 14:13:21 -08:00
|
|
|
bool_to_uint32: {
|
|
|
|
value: 47
|
|
|
|
}
|
|
|
|
str_to_nested: {
|
|
|
|
value: {}
|
|
|
|
}
|
2018-12-06 15:28:53 -08:00
|
|
|
`,
|
2019-02-13 14:13:21 -08:00
|
|
|
wantMessage: &pb3.Maps{
|
2018-12-06 15:28:53 -08:00
|
|
|
Int32ToStr: map[int32]string{
|
|
|
|
0: "zero",
|
|
|
|
},
|
2019-02-13 14:13:21 -08:00
|
|
|
BoolToUint32: map[bool]uint32{
|
|
|
|
false: 47,
|
|
|
|
},
|
|
|
|
StrToNested: map[string]*pb3.Nested{
|
|
|
|
"": {},
|
|
|
|
},
|
2018-12-06 15:28:53 -08:00
|
|
|
},
|
|
|
|
}, {
|
|
|
|
desc: "map contains missing value",
|
2019-02-13 14:13:21 -08:00
|
|
|
inputMessage: &pb3.Maps{},
|
2018-12-06 15:28:53 -08:00
|
|
|
inputText: `
|
|
|
|
int32_to_str: {
|
|
|
|
key: 100
|
|
|
|
}
|
2019-02-13 14:13:21 -08:00
|
|
|
bool_to_uint32: {
|
|
|
|
key: true
|
|
|
|
}
|
|
|
|
uint64_to_enum: {
|
|
|
|
key: 101
|
|
|
|
}
|
|
|
|
str_to_nested: {
|
|
|
|
key: "hello"
|
|
|
|
}
|
2018-12-06 15:28:53 -08:00
|
|
|
`,
|
2019-02-13 14:13:21 -08:00
|
|
|
wantMessage: &pb3.Maps{
|
2018-12-06 15:28:53 -08:00
|
|
|
Int32ToStr: map[int32]string{
|
|
|
|
100: "",
|
|
|
|
},
|
2019-02-13 14:13:21 -08:00
|
|
|
BoolToUint32: map[bool]uint32{
|
|
|
|
true: 0,
|
|
|
|
},
|
|
|
|
Uint64ToEnum: map[uint64]pb3.Enum{
|
|
|
|
101: pb3.Enum_ZERO,
|
|
|
|
},
|
|
|
|
StrToNested: map[string]*pb3.Nested{
|
|
|
|
"hello": {},
|
|
|
|
},
|
2018-12-06 15:28:53 -08:00
|
|
|
},
|
|
|
|
}, {
|
|
|
|
desc: "map contains missing key and value",
|
2019-02-13 14:13:21 -08:00
|
|
|
inputMessage: &pb3.Maps{},
|
|
|
|
inputText: `
|
|
|
|
int32_to_str: {}
|
|
|
|
bool_to_uint32: {}
|
|
|
|
uint64_to_enum: {}
|
|
|
|
str_to_nested: {}
|
|
|
|
`,
|
|
|
|
wantMessage: &pb3.Maps{
|
|
|
|
Int32ToStr: map[int32]string{
|
|
|
|
0: "",
|
|
|
|
},
|
|
|
|
BoolToUint32: map[bool]uint32{
|
|
|
|
false: 0,
|
|
|
|
},
|
|
|
|
Uint64ToEnum: map[uint64]pb3.Enum{
|
|
|
|
0: pb3.Enum_ZERO,
|
|
|
|
},
|
|
|
|
StrToNested: map[string]*pb3.Nested{
|
|
|
|
"": {},
|
|
|
|
},
|
|
|
|
},
|
|
|
|
}, {
|
|
|
|
desc: "map contains overriding entries",
|
|
|
|
inputMessage: &pb3.Maps{},
|
2018-12-06 15:28:53 -08:00
|
|
|
inputText: `
|
2019-02-13 14:13:21 -08:00
|
|
|
int32_to_str: {
|
|
|
|
key: 0
|
|
|
|
}
|
|
|
|
int32_to_str: {
|
|
|
|
value: "empty"
|
|
|
|
}
|
2018-12-06 15:28:53 -08:00
|
|
|
int32_to_str: {}
|
|
|
|
`,
|
2019-02-13 14:13:21 -08:00
|
|
|
wantMessage: &pb3.Maps{
|
2018-12-06 15:28:53 -08:00
|
|
|
Int32ToStr: map[int32]string{
|
|
|
|
0: "",
|
|
|
|
},
|
|
|
|
},
|
2019-04-08 17:32:44 -07:00
|
|
|
}, {
|
encoding/prototext: adjust handling of invalid UTF-8
The following changes are made:
* Permit invalid UTF-8 in proto2. This goes against specified behavior,
but matches functional behavior in wire marshaling (not just for Go,
but also in the other major language implementations as well).
* The Format function is specified as ignoring errors since its intended
purpose is to surface information to the human user even if it's not
exactly parsible back into a message. As such, add an unexported
allowInvalidUTF8 option that is specially used by Format.
* Add an EmitASCII option that forces the formatting of
strings and bytes to always be encoded as ASCII.
This ensures that the entire output is always ASCII as well.
Note that we do not replicate this behavior for protojson since:
* The JSON format fundamentally has a stricter and well-specified
grammar for exactly what is valid/invalid, while the text format
has not had a well-specified grammar for the longest time,
leading to all sorts of weird usages due to Hyrum's law.
* This is to ease migration from the legacy implementation,
which did permit invalid UTF-8 in proto2.
* The EmitASCII option relies on the ability to always escape
Unicode characters using ASCII escape sequences, but this is not
possible in JSON since the grammar only has an escape sequence defined
for Unicode characters \u0000 to \uffff, inclusive.
However, Unicode v12.0.0 defines characters up to \U0010FFFF,
which is beyond what the JSON grammar provides escape sequences for.
Change-Id: I2b524a904e9ec59f9ed5500e299613bc27c31a14
Reviewed-on: https://go-review.googlesource.com/c/protobuf/+/233077
Reviewed-by: Herbie Ong <herbie@google.com>
2020-05-07 15:10:54 -07:00
|
|
|
desc: "proto2 map field value contains invalid UTF-8",
|
|
|
|
inputMessage: &pb2.Maps{},
|
|
|
|
inputText: `int32_to_str: {
|
|
|
|
key: 101
|
|
|
|
value: "abc\xff"
|
|
|
|
}
|
|
|
|
`,
|
|
|
|
wantMessage: &pb2.Maps{
|
|
|
|
Int32ToStr: map[int32]string{101: "abc\xff"},
|
|
|
|
},
|
|
|
|
}, {
|
|
|
|
desc: "proto2 map field key contains invalid UTF-8",
|
|
|
|
inputMessage: &pb2.Maps{},
|
|
|
|
inputText: `str_to_nested: {
|
|
|
|
key: "abc\xff"
|
|
|
|
value: {}
|
|
|
|
}
|
|
|
|
`,
|
|
|
|
wantMessage: &pb2.Maps{
|
|
|
|
StrToNested: map[string]*pb2.Nested{"abc\xff": {}},
|
|
|
|
},
|
|
|
|
}, {
|
|
|
|
desc: "proto3 map field value contains invalid UTF-8",
|
2019-04-08 17:32:44 -07:00
|
|
|
inputMessage: &pb3.Maps{},
|
|
|
|
inputText: `int32_to_str: {
|
|
|
|
key: 101
|
|
|
|
value: "abc\xff"
|
|
|
|
}
|
|
|
|
`,
|
2019-10-31 17:10:15 -07:00
|
|
|
wantErr: "contains invalid UTF-8",
|
2019-04-08 17:32:44 -07:00
|
|
|
}, {
|
encoding/prototext: adjust handling of invalid UTF-8
The following changes are made:
* Permit invalid UTF-8 in proto2. This goes against specified behavior,
but matches functional behavior in wire marshaling (not just for Go,
but also in the other major language implementations as well).
* The Format function is specified as ignoring errors since its intended
purpose is to surface information to the human user even if it's not
exactly parsible back into a message. As such, add an unexported
allowInvalidUTF8 option that is specially used by Format.
* Add an EmitASCII option that forces the formatting of
strings and bytes to always be encoded as ASCII.
This ensures that the entire output is always ASCII as well.
Note that we do not replicate this behavior for protojson since:
* The JSON format fundamentally has a stricter and well-specified
grammar for exactly what is valid/invalid, while the text format
has not had a well-specified grammar for the longest time,
leading to all sorts of weird usages due to Hyrum's law.
* This is to ease migration from the legacy implementation,
which did permit invalid UTF-8 in proto2.
* The EmitASCII option relies on the ability to always escape
Unicode characters using ASCII escape sequences, but this is not
possible in JSON since the grammar only has an escape sequence defined
for Unicode characters \u0000 to \uffff, inclusive.
However, Unicode v12.0.0 defines characters up to \U0010FFFF,
which is beyond what the JSON grammar provides escape sequences for.
Change-Id: I2b524a904e9ec59f9ed5500e299613bc27c31a14
Reviewed-on: https://go-review.googlesource.com/c/protobuf/+/233077
Reviewed-by: Herbie Ong <herbie@google.com>
2020-05-07 15:10:54 -07:00
|
|
|
desc: "proto3 map field key contains invalid UTF-8",
|
2019-04-08 17:32:44 -07:00
|
|
|
inputMessage: &pb3.Maps{},
|
|
|
|
inputText: `str_to_nested: {
|
|
|
|
key: "abc\xff"
|
|
|
|
value: {}
|
|
|
|
}
|
|
|
|
`,
|
2019-10-31 17:10:15 -07:00
|
|
|
wantErr: "contains invalid UTF-8",
|
2018-12-06 15:28:53 -08:00
|
|
|
}, {
|
|
|
|
desc: "map contains unknown field",
|
2019-02-13 14:13:21 -08:00
|
|
|
inputMessage: &pb3.Maps{},
|
2018-12-06 15:28:53 -08:00
|
|
|
inputText: `
|
|
|
|
int32_to_str: {
|
|
|
|
key: 0
|
|
|
|
value: "cero"
|
|
|
|
unknown: "bad"
|
|
|
|
}
|
|
|
|
`,
|
2019-10-31 17:10:15 -07:00
|
|
|
wantErr: `(line 5:3): unknown map entry field "unknown"`,
|
2018-12-06 15:28:53 -08:00
|
|
|
}, {
|
|
|
|
desc: "map contains extension-like key field",
|
2019-02-13 14:13:21 -08:00
|
|
|
inputMessage: &pb3.Maps{},
|
2018-12-06 15:28:53 -08:00
|
|
|
inputText: `
|
|
|
|
int32_to_str: {
|
|
|
|
[key]: 10
|
|
|
|
value: "ten"
|
|
|
|
}
|
|
|
|
`,
|
2019-10-31 17:10:15 -07:00
|
|
|
wantErr: `unknown map entry field "[key]"`,
|
2018-12-06 15:28:53 -08:00
|
|
|
}, {
|
|
|
|
desc: "map contains invalid key",
|
2019-02-13 14:13:21 -08:00
|
|
|
inputMessage: &pb3.Maps{},
|
2018-12-06 15:28:53 -08:00
|
|
|
inputText: `
|
|
|
|
int32_to_str: {
|
|
|
|
key: "invalid"
|
|
|
|
value: "cero"
|
|
|
|
}
|
|
|
|
`,
|
2019-10-31 17:10:15 -07:00
|
|
|
wantErr: "(line 3:8): invalid value for int32 type",
|
2018-12-06 15:28:53 -08:00
|
|
|
}, {
|
|
|
|
desc: "map contains invalid value",
|
2019-02-13 14:13:21 -08:00
|
|
|
inputMessage: &pb3.Maps{},
|
2018-12-06 15:28:53 -08:00
|
|
|
inputText: `
|
|
|
|
int32_to_str: {
|
|
|
|
key: 100
|
|
|
|
value: 101
|
|
|
|
}
|
2019-12-22 09:46:57 -08:00
|
|
|
`,
|
2019-10-31 17:10:15 -07:00
|
|
|
wantErr: "(line 4:10): invalid value for string type",
|
2019-12-22 09:46:57 -08:00
|
|
|
}, {
|
|
|
|
desc: "map contains invalid message value",
|
|
|
|
inputMessage: &pb3.Maps{},
|
|
|
|
inputText: `
|
|
|
|
str_to_nested: {
|
|
|
|
key: "one"
|
|
|
|
value: 1
|
|
|
|
}
|
2018-12-06 15:28:53 -08:00
|
|
|
`,
|
2019-10-31 17:10:15 -07:00
|
|
|
wantErr: "syntax error (line 4:10): unexpected token: 1",
|
2018-12-06 15:28:53 -08:00
|
|
|
}, {
|
|
|
|
desc: "map using mix of [] and repeated",
|
2019-02-13 14:13:21 -08:00
|
|
|
inputMessage: &pb3.Maps{},
|
2018-12-06 15:28:53 -08:00
|
|
|
inputText: `
|
|
|
|
int32_to_str: {
|
|
|
|
key: 1
|
|
|
|
value: "one"
|
|
|
|
}
|
|
|
|
int32_to_str: [
|
|
|
|
{
|
|
|
|
key: 2
|
|
|
|
value: "not this"
|
|
|
|
},
|
|
|
|
{
|
|
|
|
},
|
|
|
|
{
|
|
|
|
key: 3
|
|
|
|
value: "three"
|
|
|
|
}
|
|
|
|
]
|
|
|
|
int32_to_str: {
|
|
|
|
key: 2
|
|
|
|
value: "two"
|
|
|
|
}
|
|
|
|
`,
|
2019-02-13 14:13:21 -08:00
|
|
|
wantMessage: &pb3.Maps{
|
2018-12-06 15:28:53 -08:00
|
|
|
Int32ToStr: map[int32]string{
|
|
|
|
0: "",
|
|
|
|
1: "one",
|
|
|
|
2: "two",
|
|
|
|
3: "three",
|
|
|
|
},
|
|
|
|
},
|
|
|
|
}, {
|
2019-03-26 16:26:22 -07:00
|
|
|
desc: "required fields not set",
|
2018-12-06 15:28:53 -08:00
|
|
|
inputMessage: &pb2.Requireds{},
|
2019-10-31 17:10:15 -07:00
|
|
|
wantErr: "required field",
|
2018-12-06 15:28:53 -08:00
|
|
|
}, {
|
2019-03-26 16:26:22 -07:00
|
|
|
desc: "required field set",
|
2018-12-06 15:28:53 -08:00
|
|
|
inputMessage: &pb2.PartialRequired{},
|
|
|
|
inputText: "req_string: 'this is required'",
|
|
|
|
wantMessage: &pb2.PartialRequired{
|
2019-07-10 16:17:16 -07:00
|
|
|
ReqString: proto.String("this is required"),
|
2018-12-06 15:28:53 -08:00
|
|
|
},
|
|
|
|
}, {
|
2019-03-26 16:26:22 -07:00
|
|
|
desc: "required fields partially set",
|
2018-12-06 15:28:53 -08:00
|
|
|
inputMessage: &pb2.Requireds{},
|
|
|
|
inputText: `
|
|
|
|
req_bool: false
|
|
|
|
req_sfixed64: 3203386110
|
|
|
|
req_string: "hello"
|
2019-02-13 14:13:21 -08:00
|
|
|
req_enum: ONE
|
2018-12-06 15:28:53 -08:00
|
|
|
`,
|
|
|
|
wantMessage: &pb2.Requireds{
|
2019-07-10 16:17:16 -07:00
|
|
|
ReqBool: proto.Bool(false),
|
|
|
|
ReqSfixed64: proto.Int64(0xbeefcafe),
|
|
|
|
ReqString: proto.String("hello"),
|
2019-02-13 14:13:21 -08:00
|
|
|
ReqEnum: pb2.Enum_ONE.Enum(),
|
2018-12-06 15:28:53 -08:00
|
|
|
},
|
2019-10-31 17:10:15 -07:00
|
|
|
wantErr: "required field",
|
2018-12-06 15:28:53 -08:00
|
|
|
}, {
|
2019-03-26 16:26:22 -07:00
|
|
|
desc: "required fields partially set with AllowPartial",
|
2019-05-14 12:44:37 -07:00
|
|
|
umo: prototext.UnmarshalOptions{AllowPartial: true},
|
2019-03-26 16:26:22 -07:00
|
|
|
inputMessage: &pb2.Requireds{},
|
|
|
|
inputText: `
|
|
|
|
req_bool: false
|
|
|
|
req_sfixed64: 3203386110
|
|
|
|
req_string: "hello"
|
|
|
|
req_enum: ONE
|
|
|
|
`,
|
|
|
|
wantMessage: &pb2.Requireds{
|
2019-07-10 16:17:16 -07:00
|
|
|
ReqBool: proto.Bool(false),
|
|
|
|
ReqSfixed64: proto.Int64(0xbeefcafe),
|
|
|
|
ReqString: proto.String("hello"),
|
2019-03-26 16:26:22 -07:00
|
|
|
ReqEnum: pb2.Enum_ONE.Enum(),
|
|
|
|
},
|
|
|
|
}, {
|
|
|
|
desc: "required fields all set",
|
2018-12-06 15:28:53 -08:00
|
|
|
inputMessage: &pb2.Requireds{},
|
|
|
|
inputText: `
|
|
|
|
req_bool: false
|
|
|
|
req_sfixed64: 0
|
|
|
|
req_double: 0
|
|
|
|
req_string: ""
|
2019-02-13 14:13:21 -08:00
|
|
|
req_enum: ONE
|
2018-12-06 15:28:53 -08:00
|
|
|
req_nested: {}
|
|
|
|
`,
|
|
|
|
wantMessage: &pb2.Requireds{
|
2019-07-10 16:17:16 -07:00
|
|
|
ReqBool: proto.Bool(false),
|
|
|
|
ReqSfixed64: proto.Int64(0),
|
|
|
|
ReqDouble: proto.Float64(0),
|
|
|
|
ReqString: proto.String(""),
|
2019-02-13 14:13:21 -08:00
|
|
|
ReqEnum: pb2.Enum_ONE.Enum(),
|
2018-12-06 15:28:53 -08:00
|
|
|
ReqNested: &pb2.Nested{},
|
|
|
|
},
|
|
|
|
}, {
|
|
|
|
desc: "indirect required field",
|
|
|
|
inputMessage: &pb2.IndirectRequired{},
|
|
|
|
inputText: "opt_nested: {}",
|
|
|
|
wantMessage: &pb2.IndirectRequired{
|
|
|
|
OptNested: &pb2.NestedWithRequired{},
|
|
|
|
},
|
2019-10-31 17:10:15 -07:00
|
|
|
wantErr: "required field",
|
2019-03-26 16:26:22 -07:00
|
|
|
}, {
|
|
|
|
desc: "indirect required field with AllowPartial",
|
2019-05-14 12:44:37 -07:00
|
|
|
umo: prototext.UnmarshalOptions{AllowPartial: true},
|
2019-03-26 16:26:22 -07:00
|
|
|
inputMessage: &pb2.IndirectRequired{},
|
|
|
|
inputText: "opt_nested: {}",
|
|
|
|
wantMessage: &pb2.IndirectRequired{
|
|
|
|
OptNested: &pb2.NestedWithRequired{},
|
|
|
|
},
|
2018-12-06 15:28:53 -08:00
|
|
|
}, {
|
|
|
|
desc: "indirect required field in repeated",
|
|
|
|
inputMessage: &pb2.IndirectRequired{},
|
|
|
|
inputText: `
|
|
|
|
rpt_nested: {
|
|
|
|
req_string: "one"
|
|
|
|
}
|
|
|
|
rpt_nested: {}
|
|
|
|
`,
|
|
|
|
wantMessage: &pb2.IndirectRequired{
|
|
|
|
RptNested: []*pb2.NestedWithRequired{
|
|
|
|
{
|
2019-07-10 16:17:16 -07:00
|
|
|
ReqString: proto.String("one"),
|
2018-12-06 15:28:53 -08:00
|
|
|
},
|
|
|
|
{},
|
2019-03-26 16:26:22 -07:00
|
|
|
},
|
|
|
|
},
|
2019-10-31 17:10:15 -07:00
|
|
|
wantErr: "required field",
|
2019-03-26 16:26:22 -07:00
|
|
|
}, {
|
|
|
|
desc: "indirect required field in repeated with AllowPartial",
|
2019-05-14 12:44:37 -07:00
|
|
|
umo: prototext.UnmarshalOptions{AllowPartial: true},
|
2019-03-26 16:26:22 -07:00
|
|
|
inputMessage: &pb2.IndirectRequired{},
|
|
|
|
inputText: `
|
|
|
|
rpt_nested: {
|
|
|
|
req_string: "one"
|
|
|
|
}
|
|
|
|
rpt_nested: {}
|
|
|
|
`,
|
|
|
|
wantMessage: &pb2.IndirectRequired{
|
|
|
|
RptNested: []*pb2.NestedWithRequired{
|
2018-12-06 15:28:53 -08:00
|
|
|
{
|
2019-07-10 16:17:16 -07:00
|
|
|
ReqString: proto.String("one"),
|
2018-12-06 15:28:53 -08:00
|
|
|
},
|
2019-03-26 16:26:22 -07:00
|
|
|
{},
|
2018-12-06 15:28:53 -08:00
|
|
|
},
|
|
|
|
},
|
|
|
|
}, {
|
|
|
|
desc: "indirect required field in map",
|
|
|
|
inputMessage: &pb2.IndirectRequired{},
|
|
|
|
inputText: `
|
|
|
|
str_to_nested: {
|
|
|
|
key: "missing"
|
|
|
|
}
|
|
|
|
str_to_nested: {
|
|
|
|
key: "contains"
|
|
|
|
value: {
|
|
|
|
req_string: "here"
|
|
|
|
}
|
|
|
|
}
|
|
|
|
`,
|
|
|
|
wantMessage: &pb2.IndirectRequired{
|
|
|
|
StrToNested: map[string]*pb2.NestedWithRequired{
|
|
|
|
"missing": &pb2.NestedWithRequired{},
|
|
|
|
"contains": &pb2.NestedWithRequired{
|
2019-07-10 16:17:16 -07:00
|
|
|
ReqString: proto.String("here"),
|
2018-12-06 15:28:53 -08:00
|
|
|
},
|
|
|
|
},
|
|
|
|
},
|
2019-10-31 17:10:15 -07:00
|
|
|
wantErr: "required field",
|
2019-03-26 16:26:22 -07:00
|
|
|
}, {
|
|
|
|
desc: "indirect required field in map with AllowPartial",
|
2019-05-14 12:44:37 -07:00
|
|
|
umo: prototext.UnmarshalOptions{AllowPartial: true},
|
2019-03-26 16:26:22 -07:00
|
|
|
inputMessage: &pb2.IndirectRequired{},
|
|
|
|
inputText: `
|
|
|
|
str_to_nested: {
|
|
|
|
key: "missing"
|
|
|
|
}
|
|
|
|
str_to_nested: {
|
|
|
|
key: "contains"
|
|
|
|
value: {
|
|
|
|
req_string: "here"
|
|
|
|
}
|
|
|
|
}
|
|
|
|
`,
|
|
|
|
wantMessage: &pb2.IndirectRequired{
|
|
|
|
StrToNested: map[string]*pb2.NestedWithRequired{
|
|
|
|
"missing": &pb2.NestedWithRequired{},
|
|
|
|
"contains": &pb2.NestedWithRequired{
|
2019-07-10 16:17:16 -07:00
|
|
|
ReqString: proto.String("here"),
|
2019-03-26 16:26:22 -07:00
|
|
|
},
|
|
|
|
},
|
|
|
|
},
|
2019-02-13 14:13:21 -08:00
|
|
|
}, {
|
|
|
|
desc: "indirect required field in oneof",
|
|
|
|
inputMessage: &pb2.IndirectRequired{},
|
|
|
|
inputText: `oneof_nested: {}
|
|
|
|
`,
|
|
|
|
wantMessage: &pb2.IndirectRequired{
|
|
|
|
Union: &pb2.IndirectRequired_OneofNested{
|
|
|
|
OneofNested: &pb2.NestedWithRequired{},
|
|
|
|
},
|
|
|
|
},
|
2019-10-31 17:10:15 -07:00
|
|
|
wantErr: "required field",
|
2019-03-26 16:26:22 -07:00
|
|
|
}, {
|
|
|
|
desc: "indirect required field in oneof with AllowPartial",
|
2019-05-14 12:44:37 -07:00
|
|
|
umo: prototext.UnmarshalOptions{AllowPartial: true},
|
2019-03-26 16:26:22 -07:00
|
|
|
inputMessage: &pb2.IndirectRequired{},
|
|
|
|
inputText: `oneof_nested: {}
|
|
|
|
`,
|
|
|
|
wantMessage: &pb2.IndirectRequired{
|
|
|
|
Union: &pb2.IndirectRequired_OneofNested{
|
|
|
|
OneofNested: &pb2.NestedWithRequired{},
|
|
|
|
},
|
|
|
|
},
|
2018-12-13 14:41:22 -08:00
|
|
|
}, {
|
|
|
|
desc: "ignore reserved field",
|
|
|
|
inputMessage: &pb2.Nests{},
|
|
|
|
inputText: "reserved_field: 'ignore this'",
|
|
|
|
wantMessage: &pb2.Nests{},
|
2018-12-18 18:04:31 -08:00
|
|
|
}, {
|
|
|
|
desc: "extensions of non-repeated fields",
|
|
|
|
inputMessage: &pb2.Extensions{},
|
|
|
|
inputText: `opt_string: "non-extension field"
|
|
|
|
[pb2.opt_ext_bool]: true
|
|
|
|
opt_bool: true
|
|
|
|
[pb2.opt_ext_nested]: {
|
|
|
|
opt_string: "nested in an extension"
|
|
|
|
opt_nested: {
|
|
|
|
opt_string: "another nested in an extension"
|
|
|
|
}
|
|
|
|
}
|
|
|
|
[pb2.opt_ext_string]: "extension field"
|
|
|
|
opt_int32: 42
|
2019-02-13 14:13:21 -08:00
|
|
|
[pb2.opt_ext_enum]: TEN
|
2018-12-18 18:04:31 -08:00
|
|
|
`,
|
|
|
|
wantMessage: func() proto.Message {
|
|
|
|
m := &pb2.Extensions{
|
2019-07-10 16:17:16 -07:00
|
|
|
OptString: proto.String("non-extension field"),
|
|
|
|
OptBool: proto.Bool(true),
|
|
|
|
OptInt32: proto.Int32(42),
|
2018-12-18 18:04:31 -08:00
|
|
|
}
|
2019-08-02 16:58:08 -07:00
|
|
|
proto.SetExtension(m, pb2.E_OptExtBool, true)
|
|
|
|
proto.SetExtension(m, pb2.E_OptExtString, "extension field")
|
|
|
|
proto.SetExtension(m, pb2.E_OptExtEnum, pb2.Enum_TEN)
|
|
|
|
proto.SetExtension(m, pb2.E_OptExtNested, &pb2.Nested{
|
2019-07-10 16:17:16 -07:00
|
|
|
OptString: proto.String("nested in an extension"),
|
2018-12-18 18:04:31 -08:00
|
|
|
OptNested: &pb2.Nested{
|
2019-07-10 16:17:16 -07:00
|
|
|
OptString: proto.String("another nested in an extension"),
|
2018-12-18 18:04:31 -08:00
|
|
|
},
|
|
|
|
})
|
|
|
|
return m
|
|
|
|
}(),
|
2019-04-08 17:32:44 -07:00
|
|
|
}, {
|
|
|
|
desc: "extension field contains invalid UTF-8",
|
|
|
|
inputMessage: &pb2.Extensions{},
|
|
|
|
inputText: `[pb2.opt_ext_string]: "abc\xff"`,
|
encoding/prototext: adjust handling of invalid UTF-8
The following changes are made:
* Permit invalid UTF-8 in proto2. This goes against specified behavior,
but matches functional behavior in wire marshaling (not just for Go,
but also in the other major language implementations as well).
* The Format function is specified as ignoring errors since its intended
purpose is to surface information to the human user even if it's not
exactly parsible back into a message. As such, add an unexported
allowInvalidUTF8 option that is specially used by Format.
* Add an EmitASCII option that forces the formatting of
strings and bytes to always be encoded as ASCII.
This ensures that the entire output is always ASCII as well.
Note that we do not replicate this behavior for protojson since:
* The JSON format fundamentally has a stricter and well-specified
grammar for exactly what is valid/invalid, while the text format
has not had a well-specified grammar for the longest time,
leading to all sorts of weird usages due to Hyrum's law.
* This is to ease migration from the legacy implementation,
which did permit invalid UTF-8 in proto2.
* The EmitASCII option relies on the ability to always escape
Unicode characters using ASCII escape sequences, but this is not
possible in JSON since the grammar only has an escape sequence defined
for Unicode characters \u0000 to \uffff, inclusive.
However, Unicode v12.0.0 defines characters up to \U0010FFFF,
which is beyond what the JSON grammar provides escape sequences for.
Change-Id: I2b524a904e9ec59f9ed5500e299613bc27c31a14
Reviewed-on: https://go-review.googlesource.com/c/protobuf/+/233077
Reviewed-by: Herbie Ong <herbie@google.com>
2020-05-07 15:10:54 -07:00
|
|
|
wantMessage: func() proto.Message {
|
|
|
|
m := &pb2.Extensions{}
|
|
|
|
proto.SetExtension(m, pb2.E_OptExtString, "abc\xff")
|
|
|
|
return m
|
|
|
|
}(),
|
2018-12-18 18:04:31 -08:00
|
|
|
}, {
|
|
|
|
desc: "extensions of repeated fields",
|
|
|
|
inputMessage: &pb2.Extensions{},
|
2019-02-13 14:13:21 -08:00
|
|
|
inputText: `[pb2.rpt_ext_enum]: TEN
|
2018-12-18 18:04:31 -08:00
|
|
|
[pb2.rpt_ext_enum]: 101
|
|
|
|
[pb2.rpt_ext_fixed32]: 42
|
2019-02-13 14:13:21 -08:00
|
|
|
[pb2.rpt_ext_enum]: ONE
|
2018-12-18 18:04:31 -08:00
|
|
|
[pb2.rpt_ext_nested]: {
|
|
|
|
opt_string: "one"
|
|
|
|
}
|
|
|
|
[pb2.rpt_ext_nested]: {
|
|
|
|
opt_string: "two"
|
|
|
|
}
|
|
|
|
[pb2.rpt_ext_fixed32]: 47
|
|
|
|
[pb2.rpt_ext_nested]: {
|
|
|
|
opt_string: "three"
|
|
|
|
}
|
|
|
|
`,
|
|
|
|
wantMessage: func() proto.Message {
|
|
|
|
m := &pb2.Extensions{}
|
2019-08-29 11:42:57 -07:00
|
|
|
proto.SetExtension(m, pb2.E_RptExtEnum, []pb2.Enum{pb2.Enum_TEN, 101, pb2.Enum_ONE})
|
|
|
|
proto.SetExtension(m, pb2.E_RptExtFixed32, []uint32{42, 47})
|
|
|
|
proto.SetExtension(m, pb2.E_RptExtNested, []*pb2.Nested{
|
2019-07-10 16:17:16 -07:00
|
|
|
&pb2.Nested{OptString: proto.String("one")},
|
|
|
|
&pb2.Nested{OptString: proto.String("two")},
|
|
|
|
&pb2.Nested{OptString: proto.String("three")},
|
2018-12-18 18:04:31 -08:00
|
|
|
})
|
|
|
|
return m
|
|
|
|
}(),
|
|
|
|
}, {
|
|
|
|
desc: "extensions of non-repeated fields in another message",
|
|
|
|
inputMessage: &pb2.Extensions{},
|
|
|
|
inputText: `[pb2.ExtensionsContainer.opt_ext_bool]: true
|
2019-02-13 14:13:21 -08:00
|
|
|
[pb2.ExtensionsContainer.opt_ext_enum]: TEN
|
2018-12-18 18:04:31 -08:00
|
|
|
[pb2.ExtensionsContainer.opt_ext_nested]: {
|
|
|
|
opt_string: "nested in an extension"
|
|
|
|
opt_nested: {
|
|
|
|
opt_string: "another nested in an extension"
|
|
|
|
}
|
|
|
|
}
|
|
|
|
[pb2.ExtensionsContainer.opt_ext_string]: "extension field"
|
|
|
|
`,
|
|
|
|
wantMessage: func() proto.Message {
|
|
|
|
m := &pb2.Extensions{}
|
2019-08-02 16:58:08 -07:00
|
|
|
proto.SetExtension(m, pb2.E_ExtensionsContainer_OptExtBool, true)
|
|
|
|
proto.SetExtension(m, pb2.E_ExtensionsContainer_OptExtString, "extension field")
|
|
|
|
proto.SetExtension(m, pb2.E_ExtensionsContainer_OptExtEnum, pb2.Enum_TEN)
|
|
|
|
proto.SetExtension(m, pb2.E_ExtensionsContainer_OptExtNested, &pb2.Nested{
|
2019-07-10 16:17:16 -07:00
|
|
|
OptString: proto.String("nested in an extension"),
|
2018-12-18 18:04:31 -08:00
|
|
|
OptNested: &pb2.Nested{
|
2019-07-10 16:17:16 -07:00
|
|
|
OptString: proto.String("another nested in an extension"),
|
2018-12-18 18:04:31 -08:00
|
|
|
},
|
|
|
|
})
|
|
|
|
return m
|
|
|
|
}(),
|
|
|
|
}, {
|
|
|
|
desc: "extensions of repeated fields in another message",
|
|
|
|
inputMessage: &pb2.Extensions{},
|
|
|
|
inputText: `opt_string: "non-extension field"
|
|
|
|
opt_bool: true
|
|
|
|
opt_int32: 42
|
|
|
|
[pb2.ExtensionsContainer.rpt_ext_nested]: {
|
|
|
|
opt_string: "one"
|
|
|
|
}
|
2019-02-13 14:13:21 -08:00
|
|
|
[pb2.ExtensionsContainer.rpt_ext_enum]: TEN
|
2018-12-18 18:04:31 -08:00
|
|
|
[pb2.ExtensionsContainer.rpt_ext_nested]: {
|
|
|
|
opt_string: "two"
|
|
|
|
}
|
|
|
|
[pb2.ExtensionsContainer.rpt_ext_enum]: 101
|
|
|
|
[pb2.ExtensionsContainer.rpt_ext_string]: "hello"
|
2019-02-13 14:13:21 -08:00
|
|
|
[pb2.ExtensionsContainer.rpt_ext_enum]: ONE
|
2018-12-18 18:04:31 -08:00
|
|
|
[pb2.ExtensionsContainer.rpt_ext_nested]: {
|
|
|
|
opt_string: "three"
|
|
|
|
}
|
|
|
|
[pb2.ExtensionsContainer.rpt_ext_string]: "world"
|
|
|
|
`,
|
|
|
|
wantMessage: func() proto.Message {
|
|
|
|
m := &pb2.Extensions{
|
2019-07-10 16:17:16 -07:00
|
|
|
OptString: proto.String("non-extension field"),
|
|
|
|
OptBool: proto.Bool(true),
|
|
|
|
OptInt32: proto.Int32(42),
|
2018-12-18 18:04:31 -08:00
|
|
|
}
|
2019-08-29 11:42:57 -07:00
|
|
|
proto.SetExtension(m, pb2.E_ExtensionsContainer_RptExtEnum, []pb2.Enum{pb2.Enum_TEN, 101, pb2.Enum_ONE})
|
|
|
|
proto.SetExtension(m, pb2.E_ExtensionsContainer_RptExtString, []string{"hello", "world"})
|
|
|
|
proto.SetExtension(m, pb2.E_ExtensionsContainer_RptExtNested, []*pb2.Nested{
|
2019-07-10 16:17:16 -07:00
|
|
|
&pb2.Nested{OptString: proto.String("one")},
|
|
|
|
&pb2.Nested{OptString: proto.String("two")},
|
|
|
|
&pb2.Nested{OptString: proto.String("three")},
|
2018-12-18 18:04:31 -08:00
|
|
|
})
|
|
|
|
return m
|
|
|
|
}(),
|
|
|
|
}, {
|
|
|
|
desc: "invalid extension field name",
|
|
|
|
inputMessage: &pb2.Extensions{},
|
|
|
|
inputText: "[pb2.invalid_message_field]: true",
|
2019-10-31 17:10:15 -07:00
|
|
|
wantErr: "unknown field",
|
2019-01-07 18:56:57 -08:00
|
|
|
}, {
|
|
|
|
desc: "MessageSet",
|
|
|
|
inputMessage: &pb2.MessageSet{},
|
|
|
|
inputText: `
|
|
|
|
[pb2.MessageSetExtension]: {
|
|
|
|
opt_string: "a messageset extension"
|
|
|
|
}
|
|
|
|
[pb2.MessageSetExtension.ext_nested]: {
|
|
|
|
opt_string: "just a regular extension"
|
|
|
|
}
|
|
|
|
[pb2.MessageSetExtension.not_message_set_extension]: {
|
|
|
|
opt_string: "not a messageset extension"
|
|
|
|
}
|
|
|
|
`,
|
|
|
|
wantMessage: func() proto.Message {
|
|
|
|
m := &pb2.MessageSet{}
|
2019-08-02 16:58:08 -07:00
|
|
|
proto.SetExtension(m, pb2.E_MessageSetExtension_MessageSetExtension, &pb2.MessageSetExtension{
|
2019-07-10 16:17:16 -07:00
|
|
|
OptString: proto.String("a messageset extension"),
|
2019-01-07 18:56:57 -08:00
|
|
|
})
|
2019-08-02 16:58:08 -07:00
|
|
|
proto.SetExtension(m, pb2.E_MessageSetExtension_NotMessageSetExtension, &pb2.MessageSetExtension{
|
2019-07-10 16:17:16 -07:00
|
|
|
OptString: proto.String("not a messageset extension"),
|
2019-01-07 18:56:57 -08:00
|
|
|
})
|
2019-08-02 16:58:08 -07:00
|
|
|
proto.SetExtension(m, pb2.E_MessageSetExtension_ExtNested, &pb2.Nested{
|
2019-07-10 16:17:16 -07:00
|
|
|
OptString: proto.String("just a regular extension"),
|
2019-01-07 18:56:57 -08:00
|
|
|
})
|
|
|
|
return m
|
|
|
|
}(),
|
2019-08-08 13:31:59 -07:00
|
|
|
skip: !flags.ProtoLegacy,
|
2019-01-07 18:56:57 -08:00
|
|
|
}, {
|
|
|
|
desc: "not real MessageSet 1",
|
|
|
|
inputMessage: &pb2.FakeMessageSet{},
|
|
|
|
inputText: `
|
|
|
|
[pb2.FakeMessageSetExtension.message_set_extension]: {
|
|
|
|
opt_string: "not a messageset extension"
|
|
|
|
}
|
|
|
|
`,
|
|
|
|
wantMessage: func() proto.Message {
|
|
|
|
m := &pb2.FakeMessageSet{}
|
2019-08-02 16:58:08 -07:00
|
|
|
proto.SetExtension(m, pb2.E_FakeMessageSetExtension_MessageSetExtension, &pb2.FakeMessageSetExtension{
|
2019-07-10 16:17:16 -07:00
|
|
|
OptString: proto.String("not a messageset extension"),
|
2019-01-07 18:56:57 -08:00
|
|
|
})
|
|
|
|
return m
|
|
|
|
}(),
|
2019-08-08 13:31:59 -07:00
|
|
|
skip: !flags.ProtoLegacy,
|
2019-01-07 18:56:57 -08:00
|
|
|
}, {
|
|
|
|
desc: "not real MessageSet 2",
|
|
|
|
inputMessage: &pb2.FakeMessageSet{},
|
|
|
|
inputText: `
|
|
|
|
[pb2.FakeMessageSetExtension]: {
|
|
|
|
opt_string: "not a messageset extension"
|
|
|
|
}
|
|
|
|
`,
|
2020-06-25 17:35:32 -07:00
|
|
|
wantErr: `unable to resolve [[pb2.FakeMessageSetExtension]]: found wrong type`,
|
2019-08-08 13:31:59 -07:00
|
|
|
skip: !flags.ProtoLegacy,
|
2019-01-07 18:56:57 -08:00
|
|
|
}, {
|
|
|
|
desc: "not real MessageSet 3",
|
|
|
|
inputMessage: &pb2.MessageSet{},
|
|
|
|
inputText: `
|
|
|
|
[pb2.message_set_extension]: {
|
|
|
|
opt_string: "another not a messageset extension"
|
2019-03-20 18:05:16 -07:00
|
|
|
}`,
|
2019-01-07 18:56:57 -08:00
|
|
|
wantMessage: func() proto.Message {
|
|
|
|
m := &pb2.MessageSet{}
|
2019-08-02 16:58:08 -07:00
|
|
|
proto.SetExtension(m, pb2.E_MessageSetExtension, &pb2.FakeMessageSetExtension{
|
2019-07-10 16:17:16 -07:00
|
|
|
OptString: proto.String("another not a messageset extension"),
|
2019-01-07 18:56:57 -08:00
|
|
|
})
|
|
|
|
return m
|
|
|
|
}(),
|
2019-08-08 13:31:59 -07:00
|
|
|
skip: !flags.ProtoLegacy,
|
2019-01-04 14:08:41 -08:00
|
|
|
}, {
|
|
|
|
desc: "Any not expanded",
|
2019-05-16 12:47:20 -07:00
|
|
|
inputMessage: &anypb.Any{},
|
2019-03-20 18:05:16 -07:00
|
|
|
inputText: `
|
2019-01-04 14:08:41 -08:00
|
|
|
type_url: "pb2.Nested"
|
|
|
|
value: "some bytes"
|
|
|
|
`,
|
2019-05-16 12:47:20 -07:00
|
|
|
wantMessage: &anypb.Any{
|
2019-03-20 18:05:16 -07:00
|
|
|
TypeUrl: "pb2.Nested",
|
|
|
|
Value: []byte("some bytes"),
|
2019-01-04 14:08:41 -08:00
|
|
|
},
|
|
|
|
}, {
|
|
|
|
desc: "Any not expanded missing value",
|
2019-05-16 12:47:20 -07:00
|
|
|
inputMessage: &anypb.Any{},
|
2019-03-20 18:05:16 -07:00
|
|
|
inputText: `type_url: "pb2.Nested"`,
|
2019-05-16 12:47:20 -07:00
|
|
|
wantMessage: &anypb.Any{
|
2019-03-20 18:05:16 -07:00
|
|
|
TypeUrl: "pb2.Nested",
|
2019-01-04 14:08:41 -08:00
|
|
|
},
|
|
|
|
}, {
|
|
|
|
desc: "Any not expanded missing type_url",
|
2019-05-16 12:47:20 -07:00
|
|
|
inputMessage: &anypb.Any{},
|
2019-03-20 18:05:16 -07:00
|
|
|
inputText: `value: "some bytes"`,
|
2019-05-16 12:47:20 -07:00
|
|
|
wantMessage: &anypb.Any{
|
2019-03-20 18:05:16 -07:00
|
|
|
Value: []byte("some bytes"),
|
2019-01-04 14:08:41 -08:00
|
|
|
},
|
|
|
|
}, {
|
2019-10-08 13:24:16 -07:00
|
|
|
desc: "Any expanded",
|
2019-05-16 12:47:20 -07:00
|
|
|
inputMessage: &anypb.Any{},
|
2019-03-20 18:05:16 -07:00
|
|
|
inputText: `
|
|
|
|
[foobar/pb2.Nested]: {
|
|
|
|
opt_string: "embedded inside Any"
|
|
|
|
opt_nested: {
|
|
|
|
opt_string: "inception"
|
2019-01-04 14:08:41 -08:00
|
|
|
}
|
|
|
|
}
|
|
|
|
`,
|
|
|
|
wantMessage: func() proto.Message {
|
|
|
|
m := &pb2.Nested{
|
2019-07-10 16:17:16 -07:00
|
|
|
OptString: proto.String("embedded inside Any"),
|
2019-01-04 14:08:41 -08:00
|
|
|
OptNested: &pb2.Nested{
|
2019-07-10 16:17:16 -07:00
|
|
|
OptString: proto.String("inception"),
|
2019-01-04 14:08:41 -08:00
|
|
|
},
|
|
|
|
}
|
2019-03-15 19:32:38 -07:00
|
|
|
b, err := proto.MarshalOptions{Deterministic: true}.Marshal(m)
|
2019-01-04 14:08:41 -08:00
|
|
|
if err != nil {
|
|
|
|
t.Fatalf("error in binary marshaling message for Any.value: %v", err)
|
|
|
|
}
|
2019-05-16 12:47:20 -07:00
|
|
|
return &anypb.Any{
|
2019-03-20 18:05:16 -07:00
|
|
|
TypeUrl: "foobar/pb2.Nested",
|
|
|
|
Value: b,
|
2019-01-04 14:08:41 -08:00
|
|
|
}
|
|
|
|
}(),
|
|
|
|
}, {
|
2019-10-08 13:24:16 -07:00
|
|
|
desc: "Any expanded with empty value",
|
2019-05-16 12:47:20 -07:00
|
|
|
inputMessage: &anypb.Any{},
|
2019-03-20 18:05:16 -07:00
|
|
|
inputText: `[foo.com/pb2.Nested]: {}`,
|
2019-05-16 12:47:20 -07:00
|
|
|
wantMessage: &anypb.Any{
|
2019-03-20 18:05:16 -07:00
|
|
|
TypeUrl: "foo.com/pb2.Nested",
|
2019-01-04 14:08:41 -08:00
|
|
|
},
|
|
|
|
}, {
|
2019-10-08 13:24:16 -07:00
|
|
|
desc: "Any expanded with missing required",
|
2019-05-16 12:47:20 -07:00
|
|
|
inputMessage: &anypb.Any{},
|
2019-03-20 18:05:16 -07:00
|
|
|
inputText: `
|
|
|
|
[pb2.PartialRequired]: {
|
|
|
|
opt_string: "embedded inside Any"
|
2019-01-04 14:08:41 -08:00
|
|
|
}
|
|
|
|
`,
|
|
|
|
wantMessage: func() proto.Message {
|
|
|
|
m := &pb2.PartialRequired{
|
2019-07-10 16:17:16 -07:00
|
|
|
OptString: proto.String("embedded inside Any"),
|
2019-01-04 14:08:41 -08:00
|
|
|
}
|
2019-04-03 12:17:24 -07:00
|
|
|
b, err := proto.MarshalOptions{
|
|
|
|
AllowPartial: true,
|
|
|
|
Deterministic: true,
|
|
|
|
}.Marshal(m)
|
2019-03-20 18:05:16 -07:00
|
|
|
if err != nil {
|
2019-01-04 14:08:41 -08:00
|
|
|
t.Fatalf("error in binary marshaling message for Any.value: %v", err)
|
|
|
|
}
|
2019-05-16 12:47:20 -07:00
|
|
|
return &anypb.Any{
|
2019-03-20 18:05:16 -07:00
|
|
|
TypeUrl: "pb2.PartialRequired",
|
|
|
|
Value: b,
|
2019-01-04 14:08:41 -08:00
|
|
|
}
|
|
|
|
}(),
|
2019-04-08 17:32:44 -07:00
|
|
|
}, {
|
2019-10-08 13:24:16 -07:00
|
|
|
desc: "Any with invalid UTF-8",
|
2019-05-16 12:47:20 -07:00
|
|
|
inputMessage: &anypb.Any{},
|
2019-04-08 17:32:44 -07:00
|
|
|
inputText: `
|
|
|
|
[pb3.Nested]: {
|
|
|
|
s_string: "abc\xff"
|
|
|
|
}
|
|
|
|
`,
|
2019-10-31 17:10:15 -07:00
|
|
|
wantErr: "contains invalid UTF-8",
|
2019-01-04 14:08:41 -08:00
|
|
|
}, {
|
|
|
|
desc: "Any expanded with unregistered type",
|
2022-05-24 05:12:23 +09:00
|
|
|
umo: prototext.UnmarshalOptions{Resolver: new(protoregistry.Types)},
|
2019-05-16 12:47:20 -07:00
|
|
|
inputMessage: &anypb.Any{},
|
2019-03-20 18:05:16 -07:00
|
|
|
inputText: `[SomeMessage]: {}`,
|
2019-10-31 17:10:15 -07:00
|
|
|
wantErr: "unable to resolve message [SomeMessage]",
|
2019-01-04 14:08:41 -08:00
|
|
|
}, {
|
2019-10-08 13:24:16 -07:00
|
|
|
desc: "Any expanded with invalid value",
|
2019-05-16 12:47:20 -07:00
|
|
|
inputMessage: &anypb.Any{},
|
2019-03-20 18:05:16 -07:00
|
|
|
inputText: `[pb2.Nested]: 123`,
|
2019-10-31 17:10:15 -07:00
|
|
|
wantErr: "unexpected token: 123",
|
2019-01-04 14:08:41 -08:00
|
|
|
}, {
|
2019-10-08 13:24:16 -07:00
|
|
|
desc: "Any expanded with unknown fields",
|
2019-05-16 12:47:20 -07:00
|
|
|
inputMessage: &anypb.Any{},
|
2019-03-20 18:05:16 -07:00
|
|
|
inputText: `
|
2019-01-04 14:08:41 -08:00
|
|
|
[pb2.Nested]: {}
|
|
|
|
unknown: ""
|
|
|
|
`,
|
2019-10-31 17:10:15 -07:00
|
|
|
wantErr: `invalid field name "unknown" in google.protobuf.Any message`,
|
2019-01-04 14:08:41 -08:00
|
|
|
}, {
|
2019-10-08 13:24:16 -07:00
|
|
|
desc: "Any contains expanded and unexpanded fields",
|
2019-05-16 12:47:20 -07:00
|
|
|
inputMessage: &anypb.Any{},
|
2019-03-20 18:05:16 -07:00
|
|
|
inputText: `
|
2019-01-04 14:08:41 -08:00
|
|
|
[pb2.Nested]: {}
|
|
|
|
type_url: "pb2.Nested"
|
|
|
|
`,
|
2019-10-31 17:10:15 -07:00
|
|
|
wantErr: "(line 3:1): conflict with [pb2.Nested] field",
|
2019-07-09 22:38:15 -07:00
|
|
|
}, {
|
|
|
|
desc: "weak fields",
|
|
|
|
inputMessage: &testpb.TestWeak{},
|
|
|
|
inputText: `weak_message1:{a:1}`,
|
|
|
|
wantMessage: func() *testpb.TestWeak {
|
|
|
|
m := new(testpb.TestWeak)
|
|
|
|
m.SetWeakMessage1(&weakpb.WeakImportMessage1{A: proto.Int32(1)})
|
|
|
|
return m
|
|
|
|
}(),
|
2019-08-08 13:31:59 -07:00
|
|
|
skip: !flags.ProtoLegacy,
|
2019-07-09 22:38:15 -07:00
|
|
|
}, {
|
|
|
|
desc: "weak fields; unknown field",
|
|
|
|
inputMessage: &testpb.TestWeak{},
|
|
|
|
inputText: `weak_message1:{a:1} weak_message2:{a:1}`,
|
2019-10-31 17:10:15 -07:00
|
|
|
wantErr: "unknown field: weak_message2", // weak_message2 is unknown since the package containing it is not imported
|
2019-08-08 13:31:59 -07:00
|
|
|
skip: !flags.ProtoLegacy,
|
2018-12-06 15:28:53 -08:00
|
|
|
}}
|
|
|
|
|
|
|
|
for _, tt := range tests {
|
|
|
|
tt := tt
|
2019-07-09 22:38:15 -07:00
|
|
|
if tt.skip {
|
|
|
|
continue
|
|
|
|
}
|
2018-12-06 15:28:53 -08:00
|
|
|
t.Run(tt.desc, func(t *testing.T) {
|
2019-05-14 16:05:06 -07:00
|
|
|
err := tt.umo.Unmarshal([]byte(tt.inputText), tt.inputMessage)
|
2019-10-31 17:10:15 -07:00
|
|
|
if err != nil {
|
|
|
|
if tt.wantErr == "" {
|
|
|
|
t.Errorf("Unmarshal() got unexpected error: %v", err)
|
|
|
|
} else if !strings.Contains(err.Error(), tt.wantErr) {
|
|
|
|
t.Errorf("Unmarshal() error got %q, want %q", err, tt.wantErr)
|
|
|
|
}
|
|
|
|
return
|
2018-12-06 15:28:53 -08:00
|
|
|
}
|
2019-10-31 17:10:15 -07:00
|
|
|
if tt.wantErr != "" {
|
|
|
|
t.Errorf("Unmarshal() got nil error, want error %q", tt.wantErr)
|
|
|
|
return
|
2018-12-06 15:28:53 -08:00
|
|
|
}
|
2019-05-16 15:53:25 -07:00
|
|
|
if tt.wantMessage != nil && !proto.Equal(tt.inputMessage, tt.wantMessage) {
|
2018-12-06 15:28:53 -08:00
|
|
|
t.Errorf("Unmarshal()\n<got>\n%v\n<want>\n%v\n", tt.inputMessage, tt.wantMessage)
|
|
|
|
}
|
|
|
|
})
|
|
|
|
}
|
|
|
|
}
|