diff --git a/jsonapi.go b/jsonapi.go index 1c22aebb..b2bcaa38 100644 --- a/jsonapi.go +++ b/jsonapi.go @@ -723,3 +723,22 @@ func RpcCommand(user string, password string, server string, message []byte) (Re } return result, err } + +// IsValidIdType checks that the Id field (which can go in any of the json +// messages is valid. json rpc 1.0 allows any (json) type, but we still need +// to prevent values that cannot be marshalled from going in. json rpc 2.0 +// (which bitcoind follows for some parts) only allows string, number, or null, +// so we restrict to that list. Ths is only necessary if you manually marshal +// a message. The normal btcjson functions only use string ids. +func IsValidIdType(id interface{}) bool { + switch id.(type) { + case int, int8, int16, int32, int64, + uint, uint8, uint16, uint32, uint64, + float32, float64, + string, + nil: + return true + default: + return false + } +} diff --git a/jsonapi_test.go b/jsonapi_test.go index 7896aa29..5fd5dcad 100644 --- a/jsonapi_test.go +++ b/jsonapi_test.go @@ -243,3 +243,26 @@ func TestRpcReply(t *testing.T) { } return } + +var idtests = []struct { + testId []interface{} + pass bool +}{ + {[]interface{}{"string test"}, true}, + {[]interface{}{1}, true}, + {[]interface{}{1.0}, true}, + {[]interface{}{nil}, true}, + {[]interface{}{make(chan int)}, false}, +} + +// TestIsValidIdType tests that IsValidIdType allows (and disallows the correct +// types. +func TestIsValidIdType(t *testing.T) { + for _, tt := range idtests { + res := btcjson.IsValidIdType(tt.testId[0]) + if res != tt.pass { + t.Errorf("Incorrect type result %v.", tt) + } + } + return +}