forked from TrueCloudLab/neoneo-go
Merge pull request #1794 from nspcc-dev/fix/json
stackitem: escape control characters in `ToJSON()`
This commit is contained in:
commit
0c04b403b4
2 changed files with 23 additions and 20 deletions
|
@ -66,16 +66,8 @@ func toJSON(buf *io.BufBinWriter, item Item) {
|
|||
for i := range it.value {
|
||||
// map key can always be converted to []byte
|
||||
// but are not always a valid UTF-8.
|
||||
key, err := ToString(it.value[i].Key)
|
||||
if err != nil {
|
||||
if buf.Err == nil {
|
||||
buf.Err = err
|
||||
}
|
||||
return
|
||||
}
|
||||
w.WriteB('"')
|
||||
w.WriteBytes([]byte(key))
|
||||
w.WriteBytes([]byte(`":`))
|
||||
writeJSONString(buf.BinWriter, it.value[i].Key)
|
||||
w.WriteBytes([]byte(`:`))
|
||||
toJSON(buf, it.value[i].Value)
|
||||
if i < len(it.value)-1 {
|
||||
w.WriteB(',')
|
||||
|
@ -89,16 +81,7 @@ func toJSON(buf *io.BufBinWriter, item Item) {
|
|||
}
|
||||
w.WriteBytes([]byte(it.value.String()))
|
||||
case *ByteArray, *Buffer:
|
||||
w.WriteB('"')
|
||||
s, err := ToString(it)
|
||||
if err != nil {
|
||||
if buf.Err == nil {
|
||||
buf.Err = err
|
||||
}
|
||||
return
|
||||
}
|
||||
w.WriteBytes([]byte(s))
|
||||
w.WriteB('"')
|
||||
writeJSONString(w, it)
|
||||
case *Bool:
|
||||
if it.value {
|
||||
w.WriteBytes([]byte("true"))
|
||||
|
@ -116,6 +99,21 @@ func toJSON(buf *io.BufBinWriter, item Item) {
|
|||
}
|
||||
}
|
||||
|
||||
// writeJSONString converts it to string and writes it to w as JSON value
|
||||
// surrounded in quotes with control characters escaped.
|
||||
func writeJSONString(w *io.BinWriter, it Item) {
|
||||
if w.Err != nil {
|
||||
return
|
||||
}
|
||||
s, err := ToString(it)
|
||||
if err != nil {
|
||||
w.Err = err
|
||||
return
|
||||
}
|
||||
data, _ := json.Marshal(s) // error never occurs because `ToString` checks for validity
|
||||
w.WriteBytes(data)
|
||||
}
|
||||
|
||||
// FromJSON decodes Item from JSON.
|
||||
// It behaves as following:
|
||||
// string -> ByteArray from base64
|
||||
|
|
|
@ -30,6 +30,7 @@ func TestFromToJSON(t *testing.T) {
|
|||
t.Run("ByteString", func(t *testing.T) {
|
||||
t.Run("Empty", getTestDecodeFunc(`""`, []byte{}))
|
||||
t.Run("Base64", getTestDecodeFunc(`"test"`, "test"))
|
||||
t.Run("Escape", getTestDecodeFunc(`"\"quotes\""`, `"quotes"`))
|
||||
})
|
||||
t.Run("BigInteger", func(t *testing.T) {
|
||||
t.Run("ZeroFloat", getTestDecodeFunc(`12.000`, 12, nil))
|
||||
|
@ -58,6 +59,10 @@ func TestFromToJSON(t *testing.T) {
|
|||
t.Run("Empty", getTestDecodeFunc(`{}`, NewMap()))
|
||||
t.Run("Small", getTestDecodeFunc(`{"a":3}`, small))
|
||||
t.Run("Big", getTestDecodeFunc(`{"3":{"a":3},"arr":["test"]}`, large))
|
||||
|
||||
m := NewMap()
|
||||
m.Add(NewByteArray([]byte("\t")), NewBool(true))
|
||||
t.Run("escape keys", getTestDecodeFunc(`{"\t":true}`, m))
|
||||
})
|
||||
t.Run("Invalid", func(t *testing.T) {
|
||||
t.Run("Empty", getTestDecodeFunc(``, nil))
|
||||
|
|
Loading…
Reference in a new issue