gogo / protobuf

[Deprecated] Protocol Buffers for Go with Gadgets
Other
5.67k stars 809 forks source link

proto.Marshal panic! #523

Open ziranliu opened 5 years ago

ziranliu commented 5 years ago

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").

prestonvanloon commented 5 years ago

+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 commented 5 years ago

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

oguzyildizz commented 5 years ago

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

gurel commented 2 years ago

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