Closed
Description
The following program fails:
package main
import (
"bytes"
"fmt"
"reflect"
pb "github.com/dvyukov/go-fuzz/examples/protobuf/pb"
"github.com/golang/protobuf/proto"
)
func main() {
data := []byte("\xf5\a\xb3\xc4\xe1\xbf")
v := new(pb.M18)
err := proto.Unmarshal(data, v)
if err != nil {
panic(err)
}
var buf bytes.Buffer
err = proto.MarshalText(&buf, v)
if err != nil {
fmt.Printf("failed to MarshalText: %#v\n", v)
panic(err)
}
v2 := new(pb.M18)
err = proto.UnmarshalText(buf.String(), v2)
if err != nil {
fmt.Printf("failed to UnmarshalText: %q\n", buf.Bytes())
panic(err)
}
if !reflect.DeepEqual(v, v2) {
fmt.Printf("v0: %#v\n", v)
fmt.Printf("v2: %#v\n", v2)
panic(fmt.Sprintf("non idempotent text marshal of %T", v))
}
}
proto: failed getting extension: unexpected EOF
v0: &example.M18{F0:(*string)(nil), XXX_extensions:map[int32]proto.Extension{126:proto.Extension{desc:(*proto.ExtensionDesc)(nil), value:interface {}(nil), enc:[]uint8{0xf5, 0x7, 0xb3, 0xc4, 0xe1, 0xbf}}}, XXX_unrecognized:[]uint8(nil)}
v2: &example.M18{F0:(*string)(nil), XXX_extensions:map[int32]proto.Extension(nil), XXX_unrecognized:[]uint8(nil)}
panic: non idempotent text marshal of *example.M18
There are 2 issues here:
- Part of the message gets lost.
- MarshalText prints to stderr. It should not. Either fail of be silent.
Definition of the protobuf is:
message M18 {
optional string f0 = 1;
extensions 100 to 199;
}
extend M18 {
optional int32 f1 = 126;
}
on commit 34a5f24