protobuf icon indicating copy to clipboard operation
protobuf copied to clipboard

proto.Marshal panic!

Open ziranliu opened this issue 6 years ago • 4 comments

I found proto.Marshal() would panic in the following case:

test.proto:

syntax = "proto3";

package main;

message Foo {
}

message Bar {
    repeated Foo foos = 1;
}

run:

protoc --gofast_out=. test.proto

test.go:

package main

import (
	"fmt"

	proto "github.com/golang/protobuf/proto"
)

func main() {
	b := &Bar{
		Foos: []*Foo{nil},
	}
	_, err := proto.Marshal(b)
	fmt.Println(err)
}

run:

go run test.go test.pb.go

Then it will panic("panic: runtime error: invalid memory address or nil pointer dereference") . While the code generated by standard protobuf will returns an error("proto: repeated field Foos has nil element").

ziranliu avatar Dec 10 '18 14:12 ziranliu

+1, I would expect proto.Marshal to return an error in this case.

Likewise, this should be true:

var m *pb.MyMessage 
_, err := proto.Marshal(m) 
if err == nil {
  t.Errorf("no error returned when proto.Marshal called with nil value")
}

prestonvanloon avatar Dec 22 '18 19:12 prestonvanloon

After some further investigation, I think this is by design. It seems that protobuf uses some unsafe logic to achieve faster serialization times.

prestonvanloon avatar Mar 07 '19 15:03 prestonvanloon

@prestonvanloon how much time not doing a nil check saves, compared to always protect against crashes?

oguzyildizz avatar Jun 06 '19 20:06 oguzyildizz

Libraries should not panic the whole application when somethings go wrong, especially if it's API is returning an error.

gurel avatar Sep 30 '22 12:09 gurel