From 4293093a1876369232bbd5296fa4128331b64bd9 Mon Sep 17 00:00:00 2001 From: Adam Schmideg Date: Fri, 7 Feb 2020 19:32:50 +0100 Subject: [PATCH] It's an error to pass in a non-nil value as result to an RPC call --- rpc/client.go | 3 +++ rpc/client_test.go | 23 +++++++++++++++++++++++ 2 files changed, 26 insertions(+) diff --git a/rpc/client.go b/rpc/client.go index dd06b9469e..1b6fd99a5d 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("Expected nil or pointer for result, got %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 0d55140222..85c23496be 100644 --- a/rpc/client_test.go +++ b/rpc/client_test.go @@ -49,6 +49,29 @@ 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 + if err := client.Call(&resultVar, "test_echo", "hello", 10, &echoArgs{"world"}); err != nil { + t.Errorf("Passing reference as result should be fine, but got an error: %v", err) + } + if resultVar.Int != 10 { + t.Errorf("Passing reference should work, but result is: %v", resultVar) + } + // 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()