mirror of
https://github.com/protocolbuffers/protobuf-go.git
synced 2025-01-06 10:01:25 +00:00
cadb4ab3b1
Return the size of the field read from the validator, permitting us to avoid an extra parse when skipping over groups. Return an UnmarshalOutput from the validator, since it already combines two of the validator outputs: bytes read and initialization status. Remove initialization status from the ValidationStatus enum, since it's covered by the UnmarshalOutput. Change-Id: I3e684c45d15aa1992d8dc3bde0f608880d34a94b Reviewed-on: https://go-review.googlesource.com/c/protobuf/+/217763 Reviewed-by: Joe Tsai <joetsai@google.com>
65 lines
1.7 KiB
Go
65 lines
1.7 KiB
Go
// Copyright 2019 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.
|
|
|
|
// Package wirefuzz includes a fuzzer for the wire marshaler and unmarshaler.
|
|
package wirefuzz
|
|
|
|
import (
|
|
"fmt"
|
|
|
|
"google.golang.org/protobuf/internal/impl"
|
|
"google.golang.org/protobuf/proto"
|
|
"google.golang.org/protobuf/reflect/protoregistry"
|
|
piface "google.golang.org/protobuf/runtime/protoiface"
|
|
|
|
fuzzpb "google.golang.org/protobuf/internal/testprotos/fuzz"
|
|
)
|
|
|
|
// Fuzz is a fuzzer for proto.Marshal and proto.Unmarshal.
|
|
func Fuzz(data []byte) (score int) {
|
|
m1 := &fuzzpb.Fuzz{}
|
|
vout, valid := impl.Validate(data, m1.ProtoReflect().Type(), piface.UnmarshalOptions{
|
|
Resolver: protoregistry.GlobalTypes,
|
|
})
|
|
if err := (proto.UnmarshalOptions{
|
|
AllowPartial: true,
|
|
}).Unmarshal(data, m1); err != nil {
|
|
switch valid {
|
|
case impl.ValidationUnknown:
|
|
case impl.ValidationInvalid:
|
|
default:
|
|
panic("unmarshal error with validation status: " + valid.String())
|
|
}
|
|
return 0
|
|
}
|
|
switch valid {
|
|
case impl.ValidationUnknown:
|
|
case impl.ValidationValid:
|
|
default:
|
|
panic("unmarshal ok with validation status: " + valid.String())
|
|
}
|
|
if proto.IsInitialized(m1) != nil && vout.Initialized {
|
|
panic("validation reports partial message is initialized")
|
|
}
|
|
data1, err := proto.MarshalOptions{
|
|
AllowPartial: true,
|
|
}.Marshal(m1)
|
|
if err != nil {
|
|
panic(err)
|
|
}
|
|
if proto.Size(m1) != len(data1) {
|
|
panic(fmt.Errorf("size does not match output %v", m1))
|
|
}
|
|
m2 := &fuzzpb.Fuzz{}
|
|
if err := (proto.UnmarshalOptions{
|
|
AllowPartial: true,
|
|
}).Unmarshal(data1, m2); err != nil {
|
|
panic(err)
|
|
}
|
|
if !proto.Equal(m1, m2) {
|
|
panic("not equal")
|
|
}
|
|
return 1
|
|
}
|