]> Cypherpunks repositories - gostls13.git/commitdiff
net/rpc/jsonrpc: handles missing "params" in jsonrpc.
authorAlexandru Moșoi <brtzsnr@gmail.com>
Fri, 31 Aug 2012 19:52:27 +0000 (15:52 -0400)
committerRuss Cox <rsc@golang.org>
Fri, 31 Aug 2012 19:52:27 +0000 (15:52 -0400)
A crash happens in the first request in a connection
if "params" field is missing because c.req.Params is Nil.

Fixes #3848.

R=golang-dev, rsc
CC=golang-dev
https://golang.org/cl/6446051

src/pkg/net/rpc/jsonrpc/all_test.go
src/pkg/net/rpc/jsonrpc/server.go

index e6c7441f06b0a6bfde10ed7a7cc98e595363b385..71ae5fc519d7a5af977f0c741aec558319e998a0 100644 (file)
@@ -24,6 +24,12 @@ type Reply struct {
 
 type Arith int
 
+type ArithAddResp struct {
+       Id     interface{} `json:"id"`
+       Result Reply       `json:"result"`
+       Error  interface{} `json:"error"`
+}
+
 func (t *Arith) Add(args *Args, reply *Reply) error {
        reply.C = args.A + args.B
        return nil
@@ -50,13 +56,39 @@ func init() {
        rpc.Register(new(Arith))
 }
 
-func TestServer(t *testing.T) {
-       type addResp struct {
-               Id     interface{} `json:"id"`
-               Result Reply       `json:"result"`
-               Error  interface{} `json:"error"`
+func TestServerNoParams(t *testing.T) {
+       cli, srv := net.Pipe()
+       defer cli.Close()
+       go ServeConn(srv)
+       dec := json.NewDecoder(cli)
+
+       fmt.Fprintf(cli, `{"method": "Arith.Add", "id": "123"}`)
+       var resp ArithAddResp
+       if err := dec.Decode(&resp); err != nil {
+               t.Fatalf("Decode after no params: %s", err)
+       }
+       if resp.Error == nil {
+               t.Fatalf("Expected error, got nil")
+       }
+}
+
+func TestServerEmptyMessage(t *testing.T) {
+       cli, srv := net.Pipe()
+       defer cli.Close()
+       go ServeConn(srv)
+       dec := json.NewDecoder(cli)
+
+       fmt.Fprintf(cli, "{}")
+       var resp ArithAddResp
+       if err := dec.Decode(&resp); err != nil {
+               t.Fatalf("Decode after empty: %s", err)
        }
+       if resp.Error == nil {
+               t.Fatalf("Expected error, got nil")
+       }
+}
 
+func TestServer(t *testing.T) {
        cli, srv := net.Pipe()
        defer cli.Close()
        go ServeConn(srv)
@@ -65,7 +97,7 @@ func TestServer(t *testing.T) {
        // Send hand-coded requests to server, parse responses.
        for i := 0; i < 10; i++ {
                fmt.Fprintf(cli, `{"method": "Arith.Add", "id": "\u%04d", "params": [{"A": %d, "B": %d}]}`, i, i, i+1)
-               var resp addResp
+               var resp ArithAddResp
                err := dec.Decode(&resp)
                if err != nil {
                        t.Fatalf("Decode: %s", err)
@@ -80,15 +112,6 @@ func TestServer(t *testing.T) {
                        t.Fatalf("resp: bad result: %d+%d=%d", i, i+1, resp.Result.C)
                }
        }
-
-       fmt.Fprintf(cli, "{}\n")
-       var resp addResp
-       if err := dec.Decode(&resp); err != nil {
-               t.Fatalf("Decode after empty: %s", err)
-       }
-       if resp.Error == nil {
-               t.Fatalf("Expected error, got nil")
-       }
 }
 
 func TestClient(t *testing.T) {
index 4c54553a7238f583201e86bc4c0584f13dacc324..5bc05fd0a718fcc0df2f9e34470d1bd3b0462cf2 100644 (file)
@@ -12,6 +12,8 @@ import (
        "sync"
 )
 
+var errMissingParams = errors.New("jsonrpc: request body missing params")
+
 type serverCodec struct {
        dec *json.Decoder // for reading JSON values
        enc *json.Encoder // for writing JSON values
@@ -50,12 +52,8 @@ type serverRequest struct {
 
 func (r *serverRequest) reset() {
        r.Method = ""
-       if r.Params != nil {
-               *r.Params = (*r.Params)[0:0]
-       }
-       if r.Id != nil {
-               *r.Id = (*r.Id)[0:0]
-       }
+       r.Params = nil
+       r.Id = nil
 }
 
 type serverResponse struct {
@@ -88,6 +86,9 @@ func (c *serverCodec) ReadRequestBody(x interface{}) error {
        if x == nil {
                return nil
        }
+       if c.req.Params == nil {
+               return errMissingParams
+       }
        // JSON params is array value.
        // RPC params is struct.
        // Unmarshal into array containing struct for now.