Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

gotoproto.customtype is broken after version 1.34 #4192

Closed
morningsend opened this issue Feb 5, 2021 · 1 comment
Closed

gotoproto.customtype is broken after version 1.34 #4192

morningsend opened this issue Feb 5, 2021 · 1 comment

Comments

@morningsend
Copy link

morningsend commented Feb 5, 2021

NOTE: if you are reporting is a potential security vulnerability or a crash,
please follow our CVE process at
https://github.com/grpc/proposal/blob/master/P4-grpc-cve-process.md instead of
filing an issue here.

Please see the FAQ in our main README.md, then answer the questions below
before submitting your issue.

What version of gRPC are you using?

1.34.0

What version of Go are you using (go version)?

$ go version
go version go1.15 darwin/amd64

What operating system (Linux, Windows, …) and version?

macOS Catalina 10.15.7

What did you do?

If possible, provide a recipe for reproducing the error.

To reproduce the bug, please build and run https://github.com/morningsend/gogoprotobug

Basically I have a proto file

// mystruct.proto
syntax = "proto3";

package pb;

import "github.com/gogo/protobuf/gogoproto/gogo.proto";

message MyMessage {
  bytes my_custom_field = 1 [(gogoproto.customtype) = "MyCustomField"];
}

message SayHelloResponse {
  string message = 1;
}

service Greeting {
  rpc SayHello(MyMessage) returns (SayHelloResponse) {}
}

and a struct implementing proto.Marshaler and proto.Unmarshaler

// my_custom_field.go
package pb

import proto "github.com/gogo/protobuf/proto"

type MyCustomField struct {
	data []byte
}

var _ proto.Marshaler = (*MyCustomField)(nil)
var _ proto.Unmarshaler = (*MyCustomField)(nil)

var data = []byte("hello")

func NewMyCustomField(data []byte) *MyCustomField {
	return &MyCustomField{
		data: data,
	}
}

func (f MyCustomField) Size() int {
	return len(f.data)
}

func (f MyCustomField) Marshal() ([]byte, error) {
	return f.data, nil
}

func (f MyCustomField) Unmarshal(data []byte) error {
	data_copy := make([]byte, len(data))
	copy(data_copy, data)
	f.data = data_copy
	return nil
}

func (f *MyCustomField) MarshalTo(dAtA []byte) (int, error) {
	return copy(dAtA, f.data), nil
}

I then try to invoke SayHello RPC, expecting an error.

package main

import (
	"context"
	"gogoprotobug/pb"
	"log"
	"net"

	"google.golang.org/grpc"
)

var address = "localhost:6000"

func main() {

	server := grpc.NewServer()

	l, err := net.Listen("tcp", address)
	if err != nil {
		log.Fatal(err)
	}

	go func() {
		if err := server.Serve(l); err != nil {
			log.Fatal(err)
		}
	}()

	conn, err := grpc.Dial(address, grpc.WithInsecure())
	if err != nil {
		log.Fatal(err)
	}
	sayHello := pb.NewGreetingClient(conn)
	_, err = sayHello.SayHello(context.Background(), &pb.MyMessage{
		MyCustomField: pb.NewMyCustomField([]byte("hello world")),
	})

	if err != nil {
		log.Fatal(err)
	}
}

What did you expect to see?

Expect to see gRPC error message, rather than code panic about marshaling error.

$ ./main 2021/02/05 19:02:50 rpc error: code = Unimplemented desc = unknown service pb.Greeting

This works on version 1.33.0

What did you see instead?

$ ./main 
panic: invalid Go type *pb.MyCustomField for field pb.MyMessage.my_custom_field

goroutine 1 [running]:
google.golang.org/protobuf/internal/impl.newSingularConverter(0x1623e20, 0x1510d80, 0x1623d00, 0xc0000c2000, 0xc0000ba17c, 0x13)
        /Users/zaiyang/repos/gogoprotobug/vendor/google.golang.org/protobuf/internal/impl/convert.go:143 +0xf17
google.golang.org/protobuf/internal/impl.NewConverter(0x1623e20, 0x1510d80, 0x1623d00, 0xc0000c2000, 0x1, 0x161c8e0)
        /Users/zaiyang/repos/gogoprotobug/vendor/google.golang.org/protobuf/internal/impl/convert.go:60 +0xdc
google.golang.org/protobuf/internal/impl.fieldInfoForScalar(0x1623d00, 0xc0000c2000, 0x151da57, 0xd, 0x0, 0x0, 0x1623e20, 0x1510d80, 0x151da66, 0x7f, ...)
        /Users/zaiyang/repos/gogoprotobug/vendor/google.golang.org/protobuf/internal/impl/message_reflect_field.go:234 +0x115
google.golang.org/protobuf/internal/impl.(*MessageInfo).makeKnownFieldsFunc(0xc0000bc000, 0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff, 0xc0000901e0, 0xc000090210, 0xc000090240, 0xc000090270)
        /Users/zaiyang/repos/gogoprotobug/vendor/google.golang.org/protobuf/internal/impl/message_reflect.go:67 +0x97d
google.golang.org/protobuf/internal/impl.(*MessageInfo).makeReflectFuncs(0xc0000bc000, 0x1623e20, 0x1507440, 0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff, 0xc0000901e0, 0xc000090210, 0xc000090240, ...)
        /Users/zaiyang/repos/gogoprotobug/vendor/google.golang.org/protobuf/internal/impl/message_reflect.go:36 +0x65
google.golang.org/protobuf/internal/impl.(*MessageInfo).initOnce(0xc0000bc000)
        /Users/zaiyang/repos/gogoprotobug/vendor/google.golang.org/protobuf/internal/impl/message.go:90 +0x192
google.golang.org/protobuf/internal/impl.(*MessageInfo).init(...)
        /Users/zaiyang/repos/gogoprotobug/vendor/google.golang.org/protobuf/internal/impl/message.go:72
google.golang.org/protobuf/internal/impl.(*messageReflectWrapper).ProtoMethods(0xc000020150, 0xc0001c5860)
        /Users/zaiyang/repos/gogoprotobug/vendor/google.golang.org/protobuf/internal/impl/message_reflect_gen.go:150 +0x53
google.golang.org/protobuf/proto.protoMethods(...)
        /Users/zaiyang/repos/gogoprotobug/vendor/google.golang.org/protobuf/proto/proto_methods.go:18
google.golang.org/protobuf/proto.MarshalOptions.marshal(0xc000000001, 0x0, 0x0, 0x0, 0x1622b60, 0xc000020150, 0xc000020150, 0x1622b60, 0xc000020150, 0x15574c0, ...)
        /Users/zaiyang/repos/gogoprotobug/vendor/google.golang.org/protobuf/proto/encode.go:143 +0x49
google.golang.org/protobuf/proto.MarshalOptions.MarshalAppend(0x1000001, 0x0, 0x0, 0x0, 0x1613d80, 0xc000020150, 0x0, 0x9740008, 0x1a48108, 0x0, ...)
        /Users/zaiyang/repos/gogoprotobug/vendor/google.golang.org/protobuf/proto/encode.go:125 +0x98
github.com/golang/protobuf/proto.marshalAppend(0x0, 0x0, 0x0, 0x9740008, 0xc00013a2a0, 0xc000010000, 0xc0001c5a60, 0xc0001c5a60, 0x147c3ab, 0x14d7920, ...)
        /Users/zaiyang/repos/gogoprotobug/vendor/github.com/golang/protobuf/proto/wire.go:40 +0xc7
github.com/golang/protobuf/proto.Marshal(...)
        /Users/zaiyang/repos/gogoprotobug/vendor/github.com/golang/protobuf/proto/wire.go:23
google.golang.org/grpc/encoding/proto.codec.Marshal(0x15574c0, 0xc00013a2a0, 0x203000, 0x1, 0xc0001c5a88, 0x203000, 0x203000)
        /Users/zaiyang/repos/gogoprotobug/vendor/google.golang.org/grpc/encoding/proto/proto.go:39 +0x5f
google.golang.org/grpc.encode(0x1f27dd8, 0x1933838, 0x15574c0, 0xc00013a2a0, 0xc000121e50, 0xc000100000, 0x1a48108, 0x0, 0x0)
        /Users/zaiyang/repos/gogoprotobug/vendor/google.golang.org/grpc/rpc_util.go:592 +0x52
google.golang.org/grpc.prepareMsg(0x15574c0, 0xc00013a2a0, 0x1f27dd8, 0x1933838, 0x0, 0x0, 0x0, 0x0, 0x1, 0xc0001c5c10, ...)
        /Users/zaiyang/repos/gogoprotobug/vendor/google.golang.org/grpc/stream.go:1559 +0x107
google.golang.org/grpc.(*clientStream).SendMsg(0xc000141b00, 0x15574c0, 0xc00013a2a0, 0x0, 0x0)
        /Users/zaiyang/repos/gogoprotobug/vendor/google.golang.org/grpc/stream.go:740 +0x165
google.golang.org/grpc.invoke(0x161cf20, 0xc00012a000, 0x158ae8d, 0x15, 0x15574c0, 0xc00013a2a0, 0x155c720, 0xc000121e40, 0xc00019ae00, 0x0, ...)
        /Users/zaiyang/repos/gogoprotobug/vendor/google.golang.org/grpc/call.go:70 +0xe4
google.golang.org/grpc.(*ClientConn).Invoke(0xc00019ae00, 0x161cf20, 0xc00012a000, 0x158ae8d, 0x15, 0x15574c0, 0xc00013a2a0, 0x155c720, 0xc000121e40, 0x0, ...)
        /Users/zaiyang/repos/gogoprotobug/vendor/google.golang.org/grpc/call.go:37 +0x1b3
gogoprotobug/pb.(*greetingClient).SayHello(0xc00013a298, 0x161cf20, 0xc00012a000, 0xc00013a2a0, 0x0, 0x0, 0x0, 0xc00019ae00, 0x0, 0x0)
        /Users/zaiyang/repos/gogoprotobug/pb/mystruct.pb.go:162 +0xcf
main.main()
        /Users/zaiyang/repos/gogoprotobug/main.go:33 +0x32e

I believe this PR is the cause for this bug #3958

@dfawley
Copy link
Member

dfawley commented Feb 5, 2021

I believe this is the same as #4094.

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Projects
None yet
Development

No branches or pull requests

2 participants