diff --git a/CHANGELOG.md b/CHANGELOG.md index c224e19799cf..17dca0370ada 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -66,6 +66,7 @@ Ref: https://keepachangelog.com/en/1.0.0/ * (export) [#13029](https://github.com/cosmos/cosmos-sdk/pull/13029) Fix exporting the blockParams regression. * [#13046](https://github.com/cosmos/cosmos-sdk/pull/13046) Fix missing return statement in BaseApp.Query. * (store) [#13336](https://github.com/cosmos/cosmos-sdk/pull/13336) Call streaming listeners for deliver tx event, it was removed accidentally, backport #13334. +* (grpc) [#13417](https://github.com/cosmos/cosmos-sdk/pull/13417) fix grpc query panic that could crash the node (backport #13352). ## [v0.46.1](https://github.com/cosmos/cosmos-sdk/releases/tag/v0.46.1) - 2022-08-24 diff --git a/baseapp/grpcrouter_test.go b/baseapp/grpcrouter_test.go index 232a6a2ad155..ff96647e7310 100644 --- a/baseapp/grpcrouter_test.go +++ b/baseapp/grpcrouter_test.go @@ -33,9 +33,9 @@ func TestGRPCQueryRouter(t *testing.T) { require.NotNil(t, res) require.Equal(t, "hello", res.Message) - require.Panics(t, func() { - _, _ = client.Echo(context.Background(), nil) - }) + res, err = client.Echo(context.Background(), nil) + require.Nil(t, err) + require.Empty(t, res.Message) res2, err := client.SayHello(context.Background(), &testdata.SayHelloRequest{Name: "Foo"}) require.Nil(t, err) @@ -151,9 +151,9 @@ func testQueryDataRacesSameHandler(t *testing.T, makeClientConn func(*baseapp.GR require.NotNil(t, res) require.Equal(t, "hello", res.Message) - require.Panics(t, func() { - _, _ = client.Echo(context.Background(), nil) - }) + res, err = client.Echo(context.Background(), nil) + require.Nil(t, err) + require.Empty(t, res.Message) res2, err := client.SayHello(context.Background(), &testdata.SayHelloRequest{Name: "Foo"}) require.Nil(t, err) diff --git a/codec/proto_codec.go b/codec/proto_codec.go index 31b716d8636e..b0e4cde0e29f 100644 --- a/codec/proto_codec.go +++ b/codec/proto_codec.go @@ -43,6 +43,11 @@ func NewProtoCodec(interfaceRegistry types.InterfaceRegistry) *ProtoCodec { // NOTE: this function must be used with a concrete type which // implements proto.Message. For interface please use the codec.MarshalInterface func (pc *ProtoCodec) Marshal(o ProtoMarshaler) ([]byte, error) { + // Size() check can catch the typed nil value. + if o == nil || o.Size() == 0 { + // return empty bytes instead of nil, because nil has special meaning in places like store.Set + return []byte{}, nil + } return o.Marshal() }