diff --git a/codec/codec_test.go b/codec/codec_test.go index 5157e8b5..b05d1946 100644 --- a/codec/codec_test.go +++ b/codec/codec_test.go @@ -1470,6 +1470,21 @@ func TestJsonLargeInteger(t *testing.T) { } } +func TestJsonDecodeNonStringScalarInStringContext(t *testing.T) { + var b = `{"s.true": "true", "b.true": true, "s.false": "false", "b.false": false, "s.10": "10", "i.10": 10, "i.-10": -10}` + var golden = map[string]string{"s.true": "true", "b.true": "true", "s.false": "false", "b.false": "false", "s.10": "10", "i.10": "10", "i.-10": "-10"} + + var m map[string]string + d := NewDecoderBytes([]byte(b), testJsonH) + d.MustDecode(&m) + if err := deepEqual(golden, m); err == nil { + logT(t, "++++ match: decoded: %#v", m) + } else { + logT(t, "---- mismatch: %v ==> golden: %#v, decoded: %#v", err, golden, m) + failT(t) + } +} + // TODO: // Add Tests for: // - decoding empty list/map in stream into a nil slice/map diff --git a/codec/json.go b/codec/json.go index 463cae3d..df67d68c 100644 --- a/codec/json.go +++ b/codec/json.go @@ -702,7 +702,9 @@ LOOP: switch state { case 0: state = 2 - // do not add sign to the slice ... + if storeBytes { + d.bs = append(d.bs, b) + } b, eof = r.readn1eof() continue case 6: // typ = jsonNumFloat @@ -715,7 +717,9 @@ LOOP: case 0: state = 2 n.neg = true - // do not add sign to the slice ... + if storeBytes { + d.bs = append(d.bs, b) + } b, eof = r.readn1eof() continue case 6: // typ = jsonNumFloat @@ -981,16 +985,28 @@ func (d *jsonDecDriver) appendStringAsBytes() { d.tok = b } - // handle null as a string - if d.tok == 'n' { - d.readStrIdx(10, 13) // ull - d.bs = d.bs[:0] + if d.tok != '"' { + // d.d.errorf("json: expect char '%c' but got char '%c'", '"', d.tok) + // handle non-string scalar: null, true, false or a number + switch d.tok { + case 'n': + d.readStrIdx(10, 13) // ull + d.bs = d.bs[:0] + case 'f': + d.readStrIdx(5, 9) // alse + d.bs = d.bs[:5] + copy(d.bs, "false") + case 't': + d.readStrIdx(1, 4) // rue + d.bs = d.bs[:4] + copy(d.bs, "true") + default: + // try to parse a valid number + d.decNum(true) + } return } - if d.tok != '"' { - d.d.errorf("json: expect char '%c' but got char '%c'", '"', d.tok) - } d.tok = 0 v := d.bs[:0] @@ -1159,6 +1175,7 @@ func (d *jsonDecDriver) DecodeNaked() { type JsonHandle struct { textEncodingType BasicHandle + // RawBytesExt, if configured, is used to encode and decode raw bytes in a custom way. // If not configured, raw bytes are encoded to/from base64 text. RawBytesExt InterfaceExt