smartcontract: unmarhal null values properly

First we unmarshal `null` to `[]byte`, then we marshal it to the empty
string.

Signed-off-by: Evgeniy Stratonikov <evgeniy@nspcc.ru>
This commit is contained in:
Evgeniy Stratonikov 2021-09-10 21:34:48 +03:00
parent 5209fe1e09
commit 918d7e65bf
2 changed files with 22 additions and 4 deletions

View file

@ -1,6 +1,7 @@
package smartcontract package smartcontract
import ( import (
"bytes"
"encoding/base64" "encoding/base64"
"encoding/binary" "encoding/binary"
"encoding/hex" "encoding/hex"
@ -54,6 +55,12 @@ func (p Parameter) MarshalJSON() ([]byte, error) {
resultRawValue json.RawMessage resultRawValue json.RawMessage
resultErr error resultErr error
) )
if p.Value == nil {
if _, ok := validParamTypes[p.Type]; ok && p.Type != UnknownType {
return json.Marshal(rawParameter{Type: p.Type})
}
return nil, fmt.Errorf("can't marshal %s", p.Type)
}
switch p.Type { switch p.Type {
case BoolType, StringType, Hash160Type, Hash256Type: case BoolType, StringType, Hash160Type, Hash256Type:
resultRawValue, resultErr = json.Marshal(p.Value) resultRawValue, resultErr = json.Marshal(p.Value)
@ -66,9 +73,7 @@ func (p Parameter) MarshalJSON() ([]byte, error) {
valStr := strconv.FormatInt(val, 10) valStr := strconv.FormatInt(val, 10)
resultRawValue = json.RawMessage(`"` + valStr + `"`) resultRawValue = json.RawMessage(`"` + valStr + `"`)
case PublicKeyType, ByteArrayType, SignatureType: case PublicKeyType, ByteArrayType, SignatureType:
if p.Value == nil { if p.Type == PublicKeyType {
resultRawValue = []byte("null")
} else if p.Type == PublicKeyType {
resultRawValue, resultErr = json.Marshal(hex.EncodeToString(p.Value.([]byte))) resultRawValue, resultErr = json.Marshal(hex.EncodeToString(p.Value.([]byte)))
} else { } else {
resultRawValue, resultErr = json.Marshal(base64.StdEncoding.EncodeToString(p.Value.([]byte))) resultRawValue, resultErr = json.Marshal(base64.StdEncoding.EncodeToString(p.Value.([]byte)))
@ -110,7 +115,8 @@ func (p *Parameter) UnmarshalJSON(data []byte) (err error) {
return return
} }
p.Type = r.Type p.Type = r.Type
if len(r.Value) == 0 { p.Value = nil
if len(r.Value) == 0 || bytes.Equal(r.Value, []byte("null")) {
return return
} }
switch r.Type { switch r.Type {

View file

@ -41,6 +41,10 @@ var marshalJSONTestCases = []struct {
input: Parameter{Type: ByteArrayType}, input: Parameter{Type: ByteArrayType},
result: `{"type":"ByteString","value":null}`, result: `{"type":"ByteString","value":null}`,
}, },
{
input: Parameter{Type: SignatureType},
result: `{"type":"Signature"}`,
},
{ {
input: Parameter{ input: Parameter{
Type: PublicKeyType, Type: PublicKeyType,
@ -195,6 +199,14 @@ var unmarshalJSONTestCases = []struct {
input: `{"type":"String","value":"Some string"}`, input: `{"type":"String","value":"Some string"}`,
result: Parameter{Type: StringType, Value: "Some string"}, result: Parameter{Type: StringType, Value: "Some string"},
}, },
{
input: `{"type":"Signature"}`,
result: Parameter{Type: SignatureType},
},
{
input: `{"type":"Signature","value":null }`,
result: Parameter{Type: SignatureType},
},
{ {
input: `{"type":"Array","value":[ input: `{"type":"Array","value":[
{"type": "String", "value": "str 1"}, {"type": "String", "value": "str 1"},