mirror of
https://github.com/golang/go
synced 2024-11-25 19:07:57 -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:
parent
6d0e3242eb
commit
3efc482190
@ -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) {
|
||||||
|
@ -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.
|
||||||
|
Loading…
Reference in New Issue
Block a user