...
1
2
3
4
5
6
7
8
9 package prototext_test
10
11 import (
12 "math"
13 "testing"
14
15 "github.com/google/go-cmp/cmp"
16 "google.golang.org/protobuf/encoding/prototext"
17 "google.golang.org/protobuf/proto"
18 "google.golang.org/protobuf/reflect/protoreflect"
19 "google.golang.org/protobuf/testing/protocmp"
20
21 testfuzzpb "google.golang.org/protobuf/internal/testprotos/editionsfuzztest"
22 )
23
24
25
26
27
28
29 func roundTripAndCompareProto(t *testing.T, wireBytes []byte, messages ...proto.Message) {
30 for _, msg := range messages {
31 src := msg.ProtoReflect().Type().New().Interface()
32
33 if err := proto.Unmarshal(wireBytes, src); err != nil {
34
35
36 return
37 }
38
39
40 src.ProtoReflect().SetUnknown(nil)
41 var ranger func(protoreflect.FieldDescriptor, protoreflect.Value) bool
42 stripUnknown := func(m protoreflect.Message) {
43 m.SetUnknown(nil)
44 m.Range(ranger)
45 }
46 ranger = func(fd protoreflect.FieldDescriptor, v protoreflect.Value) bool {
47 switch {
48 case fd.IsMap():
49 if fd.MapValue().Message() != nil {
50 v.Map().Range(func(_ protoreflect.MapKey, v protoreflect.Value) bool {
51 stripUnknown(v.Message())
52 return true
53 })
54 }
55 case fd.Message() != nil:
56 if fd.Cardinality() == protoreflect.Repeated {
57 l := v.List()
58 for i := 0; i < l.Len(); i++ {
59 stripUnknown(l.Get(i).Message())
60 }
61 } else {
62 stripUnknown(v.Message())
63 }
64 }
65 return true
66 }
67 stripUnknown(src.ProtoReflect())
68
69 textFormat, err := prototext.Marshal(src)
70 if err != nil {
71 t.Errorf("failed to marshal messsage to text format: %v\nmessage: %v", err, src)
72 }
73 dst := msg.ProtoReflect().Type().New().Interface()
74
75 if err := (prototext.Unmarshal(textFormat, dst)); err != nil {
76 t.Errorf("failed to unmarshal messsage from text format: %v\ntext format: %s", err, textFormat)
77 }
78
79
80
81 optNaN64 := cmp.Comparer(func(x, y float32) bool {
82 return (math.IsNaN(float64(x)) && math.IsNaN(float64(y))) || x == y
83 })
84 optNaN32 := cmp.Comparer(func(x, y float64) bool {
85 return (math.IsNaN(x) && math.IsNaN(y)) || x == y
86 })
87 if diff := cmp.Diff(src, dst, protocmp.Transform(), optNaN64, optNaN32); diff != "" {
88 t.Error(diff)
89 }
90 }
91 }
92
93 func FuzzEncodeDecodeRoundTrip(f *testing.F) {
94 f.Add([]byte("Hello World!"))
95 f.Fuzz(func(t *testing.T, in []byte) {
96 roundTripAndCompareProto(t, in, (*testfuzzpb.TestAllTypesProto2)(nil), (*testfuzzpb.TestAllTypesProto2Editions)(nil), (*testfuzzpb.TestAllTypesProto3)(nil), (*testfuzzpb.TestAllTypesProto3Editions)(nil))
97 })
98 }
99
View as plain text