stackitem: fix JSON encoding

Encode both `Buffer` and `ByteString` to UTF-8 bytes.
Follow https://github.com/neo-project/neo/pull/1715 .
This commit is contained in:
Evgenii Stratonikov 2020-12-11 13:23:07 +03:00
parent 3bbf7642ea
commit 18b331d765
2 changed files with 14 additions and 19 deletions

View file

@ -88,12 +88,16 @@ func toJSON(buf *io.BufBinWriter, item Item) {
return return
} }
w.WriteBytes([]byte(it.value.String())) w.WriteBytes([]byte(it.value.String()))
case *ByteArray: case *ByteArray, *Buffer:
w.WriteB('"') w.WriteB('"')
val := it.Value().([]byte) s, err := ToString(it)
b := make([]byte, base64.StdEncoding.EncodedLen(len(val))) if err != nil {
base64.StdEncoding.Encode(b, val) if buf.Err == nil {
w.WriteBytes(b) buf.Err = err
}
return
}
w.WriteBytes([]byte(s))
w.WriteB('"') w.WriteB('"')
case *Bool: case *Bool:
if it.value { if it.value {
@ -158,11 +162,7 @@ func (d *decoder) decode() (Item, error) {
return nil, nil return nil, nil
} }
case string: case string:
b, err := base64.StdEncoding.DecodeString(t) return NewByteArray([]byte(t)), nil
if err != nil {
return nil, err
}
return NewByteArray(b), nil
case float64: case float64:
if math.Floor(t) != t { if math.Floor(t) != t {
return nil, fmt.Errorf("real value is not allowed: %v", t) return nil, fmt.Errorf("real value is not allowed: %v", t)

View file

@ -1,7 +1,6 @@
package stackitem package stackitem
import ( import (
"encoding/base64"
"math/big" "math/big"
"testing" "testing"
@ -28,10 +27,9 @@ func getTestDecodeFunc(js string, expected ...interface{}) func(t *testing.T) {
} }
func TestFromToJSON(t *testing.T) { func TestFromToJSON(t *testing.T) {
var testBase64 = base64.StdEncoding.EncodeToString([]byte("test"))
t.Run("ByteString", func(t *testing.T) { t.Run("ByteString", func(t *testing.T) {
t.Run("Empty", getTestDecodeFunc(`""`, []byte{})) t.Run("Empty", getTestDecodeFunc(`""`, []byte{}))
t.Run("Base64", getTestDecodeFunc(`"`+testBase64+`"`, "test")) t.Run("Base64", getTestDecodeFunc(`"test"`, "test"))
}) })
t.Run("BigInteger", func(t *testing.T) { t.Run("BigInteger", func(t *testing.T) {
t.Run("ZeroFloat", getTestDecodeFunc(`12.000`, 12, nil)) t.Run("ZeroFloat", getTestDecodeFunc(`12.000`, 12, nil))
@ -46,7 +44,7 @@ func TestFromToJSON(t *testing.T) {
t.Run("Null", getTestDecodeFunc(`null`, Null{})) t.Run("Null", getTestDecodeFunc(`null`, Null{}))
t.Run("Array", func(t *testing.T) { t.Run("Array", func(t *testing.T) {
t.Run("Empty", getTestDecodeFunc(`[]`, NewArray([]Item{}))) t.Run("Empty", getTestDecodeFunc(`[]`, NewArray([]Item{})))
t.Run("Simple", getTestDecodeFunc((`[1,"`+testBase64+`",true,null]`), t.Run("Simple", getTestDecodeFunc((`[1,"test",true,null]`),
NewArray([]Item{NewBigInteger(big.NewInt(1)), NewByteArray([]byte("test")), NewBool(true), Null{}}))) NewArray([]Item{NewBigInteger(big.NewInt(1)), NewByteArray([]byte("test")), NewBool(true), Null{}})))
t.Run("Nested", getTestDecodeFunc(`[[],[{},null]]`, t.Run("Nested", getTestDecodeFunc(`[[],[{},null]]`,
NewArray([]Item{NewArray([]Item{}), NewArray([]Item{NewMap(), Null{}})}))) NewArray([]Item{NewArray([]Item{}), NewArray([]Item{NewMap(), Null{}})})))
@ -59,11 +57,10 @@ func TestFromToJSON(t *testing.T) {
large.Add(NewByteArray([]byte("arr")), NewArray([]Item{NewByteArray([]byte("test"))})) large.Add(NewByteArray([]byte("arr")), NewArray([]Item{NewByteArray([]byte("test"))}))
t.Run("Empty", getTestDecodeFunc(`{}`, NewMap())) t.Run("Empty", getTestDecodeFunc(`{}`, NewMap()))
t.Run("Small", getTestDecodeFunc(`{"a":3}`, small)) t.Run("Small", getTestDecodeFunc(`{"a":3}`, small))
t.Run("Big", getTestDecodeFunc(`{"3":{"a":3},"arr":["`+testBase64+`"]}`, large)) t.Run("Big", getTestDecodeFunc(`{"3":{"a":3},"arr":["test"]}`, large))
}) })
t.Run("Invalid", func(t *testing.T) { t.Run("Invalid", func(t *testing.T) {
t.Run("Empty", getTestDecodeFunc(``, nil)) t.Run("Empty", getTestDecodeFunc(``, nil))
t.Run("InvalidString", getTestDecodeFunc(`"not a base64"`, nil))
t.Run("InvalidArray", getTestDecodeFunc(`[}`, nil)) t.Run("InvalidArray", getTestDecodeFunc(`[}`, nil))
t.Run("InvalidMap", getTestDecodeFunc(`{]`, nil)) t.Run("InvalidMap", getTestDecodeFunc(`{]`, nil))
t.Run("InvalidMapValue", getTestDecodeFunc(`{"a":{]}`, nil)) t.Run("InvalidMapValue", getTestDecodeFunc(`{"a":{]}`, nil))
@ -79,9 +76,7 @@ func TestFromToJSON(t *testing.T) {
require.Error(t, err) require.Error(t, err)
}) })
t.Run("BigByteArray", func(t *testing.T) { t.Run("BigByteArray", func(t *testing.T) {
l := base64.StdEncoding.DecodedLen(MaxSize + 8) item := NewByteArray(make([]byte, MaxSize))
require.True(t, l < MaxSize) // check if test makes sense
item := NewByteArray(make([]byte, l))
_, err := ToJSON(item) _, err := ToJSON(item)
require.Error(t, err) require.Error(t, err)
}) })