Commit 3efc4821 authored by Alexandru Moșoi's avatar Alexandru Moșoi Committed by Russ Cox

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
parent 6d0e3242
......@@ -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) {
......
......@@ -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.
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment