1
0
mirror of https://github.com/golang/go synced 2024-11-22 04:14:42 -07:00

net/rpc/jsonrpc: handles missing "params" in jsonrpc.

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
This commit is contained in:
Alexandru Moșoi 2012-08-31 15:52:27 -04:00 committed by Russ Cox
parent 6d0e3242eb
commit 3efc482190
2 changed files with 46 additions and 22 deletions

View File

@ -24,6 +24,12 @@ type Reply struct {
type Arith int 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 { func (t *Arith) Add(args *Args, reply *Reply) error {
reply.C = args.A + args.B reply.C = args.A + args.B
return nil return nil
@ -50,13 +56,39 @@ func init() {
rpc.Register(new(Arith)) rpc.Register(new(Arith))
} }
func TestServer(t *testing.T) { func TestServerNoParams(t *testing.T) {
type addResp struct { cli, srv := net.Pipe()
Id interface{} `json:"id"` defer cli.Close()
Result Reply `json:"result"` go ServeConn(srv)
Error interface{} `json:"error"` 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() cli, srv := net.Pipe()
defer cli.Close() defer cli.Close()
go ServeConn(srv) go ServeConn(srv)
@ -65,7 +97,7 @@ func TestServer(t *testing.T) {
// Send hand-coded requests to server, parse responses. // Send hand-coded requests to server, parse responses.
for i := 0; i < 10; i++ { for i := 0; i < 10; i++ {
fmt.Fprintf(cli, `{"method": "Arith.Add", "id": "\u%04d", "params": [{"A": %d, "B": %d}]}`, i, i, i+1) 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) err := dec.Decode(&resp)
if err != nil { if err != nil {
t.Fatalf("Decode: %s", err) 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) 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) { func TestClient(t *testing.T) {

View File

@ -12,6 +12,8 @@ import (
"sync" "sync"
) )
var errMissingParams = errors.New("jsonrpc: request body missing params")
type serverCodec struct { type serverCodec struct {
dec *json.Decoder // for reading JSON values dec *json.Decoder // for reading JSON values
enc *json.Encoder // for writing JSON values enc *json.Encoder // for writing JSON values
@ -50,12 +52,8 @@ type serverRequest struct {
func (r *serverRequest) reset() { func (r *serverRequest) reset() {
r.Method = "" r.Method = ""
if r.Params != nil { r.Params = nil
*r.Params = (*r.Params)[0:0] r.Id = nil
}
if r.Id != nil {
*r.Id = (*r.Id)[0:0]
}
} }
type serverResponse struct { type serverResponse struct {
@ -88,6 +86,9 @@ func (c *serverCodec) ReadRequestBody(x interface{}) error {
if x == nil { if x == nil {
return nil return nil
} }
if c.req.Params == nil {
return errMissingParams
}
// JSON params is array value. // JSON params is array value.
// RPC params is struct. // RPC params is struct.
// Unmarshal into array containing struct for now. // Unmarshal into array containing struct for now.