...
1
2
3
4
5
6 package wirefuzz
7
8 import (
9 "fmt"
10
11 "google.golang.org/protobuf/internal/impl"
12 "google.golang.org/protobuf/proto"
13 "google.golang.org/protobuf/reflect/protoregistry"
14 piface "google.golang.org/protobuf/runtime/protoiface"
15
16 fuzzpb "google.golang.org/protobuf/internal/testprotos/fuzz"
17 )
18
19
20 func Fuzz(data []byte) (score int) {
21
22 m1 := &fuzzpb.Fuzz{}
23 mt := m1.ProtoReflect().Type()
24 _, valid := impl.Validate(mt, piface.UnmarshalInput{Buf: data})
25 if err := (proto.UnmarshalOptions{AllowPartial: true}).Unmarshal(data, m1); err != nil {
26 switch valid {
27 case impl.ValidationUnknown:
28 case impl.ValidationInvalid:
29 default:
30 panic("unmarshal error with validation status: " + valid.String())
31 }
32 return 0
33 }
34 switch valid {
35 case impl.ValidationUnknown:
36 case impl.ValidationValid:
37 default:
38 panic("unmarshal ok with validation status: " + valid.String())
39 }
40
41
42 checkInit := proto.CheckInitialized(m1) == nil
43 methods := m1.ProtoReflect().ProtoMethods()
44 in := piface.UnmarshalInput{Message: mt.New(), Resolver: protoregistry.GlobalTypes, Depth: 10000}
45 if checkInit {
46
47
48
49
50
51 in.Buf, _ = proto.Marshal(m1)
52 if out, _ := methods.Unmarshal(in); out.Flags&piface.UnmarshalInitialized == 0 {
53 panic("unmarshal reports initialized message as partial")
54 }
55 if out, _ := impl.Validate(mt, in); out.Flags&piface.UnmarshalInitialized == 0 {
56 panic("validate reports initialized message as partial")
57 }
58 } else {
59
60
61 in.Buf = data
62 if out, _ := methods.Unmarshal(in); out.Flags&piface.UnmarshalInitialized != 0 {
63 panic("unmarshal reports partial message as initialized")
64 }
65 if out, _ := impl.Validate(mt, in); out.Flags&piface.UnmarshalInitialized != 0 {
66 panic("validate reports partial message as initialized")
67 }
68 }
69
70
71 data1, err := proto.MarshalOptions{AllowPartial: !checkInit}.Marshal(m1)
72 if err != nil {
73 panic(err)
74 }
75 if proto.Size(m1) != len(data1) {
76 panic(fmt.Errorf("size does not match output: %d != %d", proto.Size(m1), len(data1)))
77 }
78 m2 := &fuzzpb.Fuzz{}
79 if err := (proto.UnmarshalOptions{AllowPartial: !checkInit}).Unmarshal(data1, m2); err != nil {
80 panic(err)
81 }
82 if !proto.Equal(m1, m2) {
83 panic("not equal")
84 }
85 return 1
86 }
87
View as plain text