From 172f7778fe498c383e0bdb234aaac4f61d4a2512 Mon Sep 17 00:00:00 2001 From: Adam Schmideg Date: Tue, 11 Feb 2020 09:48:58 +0100 Subject: [PATCH] rpc: add error when call result parameter is not addressable (#20638) --- rpc/client.go | 3 +++ rpc/client_test.go | 17 +++++++++++++++++ 2 files changed, 20 insertions(+) diff --git a/rpc/client.go b/rpc/client.go index dd06b9469..984f56bc6 100644 --- a/rpc/client.go +++ b/rpc/client.go @@ -276,6 +276,9 @@ func (c *Client) Call(result interface{}, method string, args ...interface{}) er // The result must be a pointer so that package json can unmarshal into it. You // can also pass nil, in which case the result is ignored. func (c *Client) CallContext(ctx context.Context, result interface{}, method string, args ...interface{}) error { + if result != nil && reflect.TypeOf(result).Kind() != reflect.Ptr { + return fmt.Errorf("call result parameter must be pointer or nil interface: %v", result) + } msg, err := c.newMessage(method, args...) if err != nil { return err diff --git a/rpc/client_test.go b/rpc/client_test.go index 0d5514022..9c7f72053 100644 --- a/rpc/client_test.go +++ b/rpc/client_test.go @@ -49,6 +49,23 @@ func TestClientRequest(t *testing.T) { } } +func TestClientResponseType(t *testing.T) { + server := newTestServer() + defer server.Stop() + client := DialInProc(server) + defer client.Close() + + if err := client.Call(nil, "test_echo", "hello", 10, &echoArgs{"world"}); err != nil { + t.Errorf("Passing nil as result should be fine, but got an error: %v", err) + } + var resultVar echoResult + // Note: passing the var, not a ref + err := client.Call(resultVar, "test_echo", "hello", 10, &echoArgs{"world"}) + if err == nil { + t.Error("Passing a var as result should be an error") + } +} + func TestClientBatchRequest(t *testing.T) { server := newTestServer() defer server.Stop()