fix: add gRPC nil/zero check in query (#13352)

This commit is contained in:
yihuang
2022-09-29 01:20:03 +00:00
committed by GitHub
parent 3d0e214446
commit a9f02d9cb7
4 changed files with 39 additions and 6 deletions
+5
View File
@@ -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()
}
+27
View File
@@ -3,15 +3,20 @@ package codec_test
import (
"errors"
"fmt"
"math"
"reflect"
"testing"
"github.com/cosmos/gogoproto/proto"
"github.com/stretchr/testify/require"
"google.golang.org/grpc/codes"
"google.golang.org/grpc/encoding"
"google.golang.org/grpc/status"
"github.com/cosmos/cosmos-sdk/codec"
"github.com/cosmos/cosmos-sdk/codec/types"
"github.com/cosmos/cosmos-sdk/testutil/testdata"
banktypes "github.com/cosmos/cosmos-sdk/x/bank/types"
)
func createTestInterfaceRegistry() types.InterfaceRegistry {
@@ -109,6 +114,28 @@ func TestProtoCodecMarshal(t *testing.T) {
err = cartoonCdc.UnmarshalInterface(bz, &cartoon)
require.NoError(t, err)
// test typed nil input shouldn't panic
var v *banktypes.QueryBalanceResponse
bz, err = grpcServerEncode(cartoonCdc.GRPCCodec(), v)
require.NoError(t, err)
require.Empty(t, bz)
}
// Emulate grpc server implementation
// https://github.com/grpc/grpc-go/blob/b1d7f56b81b7902d871111b82dec6ba45f854ede/rpc_util.go#L590
func grpcServerEncode(c encoding.Codec, msg interface{}) ([]byte, error) {
if msg == nil { // NOTE: typed nils will not be caught by this check
return nil, nil
}
b, err := c.Marshal(msg)
if err != nil {
return nil, status.Errorf(codes.Internal, "grpc: error while marshaling: %v", err.Error())
}
if uint(len(b)) > math.MaxUint32 {
return nil, status.Errorf(codes.ResourceExhausted, "grpc: message too large (%d bytes)", len(b))
}
return b, nil
}
func TestProtoCodecUnmarshalLengthPrefixedChecks(t *testing.T) {