diff --git a/encode.go b/encode.go index dda693f..a3a6b5c 100644 --- a/encode.go +++ b/encode.go @@ -102,9 +102,11 @@ func (e *Encoder) EncodeWithOption(v interface{}, opts ...EncodeOption) error { if err := e.encode(v); err != nil { return err } + e.buf = append(e.buf, '\n') if _, err := e.w.Write(e.buf); err != nil { return err } + e.buf = e.buf[:0] return nil } @@ -315,6 +317,14 @@ func (e *Encoder) encodeNull() { e.buf = append(e.buf, 'n', 'u', 'l', 'l') } +func (e *Encoder) encodeKey(code *opcode) { + if e.enabledHTMLEscape { + e.encodeBytes(code.escapedKey) + } else { + e.encodeBytes(code.key) + } +} + func (e *Encoder) encodeString(s string) { if e.enabledHTMLEscape { e.encodeEscapedString(s) diff --git a/encode_compile.go b/encode_compile.go index d66cef1..798119f 100644 --- a/encode_compile.go +++ b/encode_compile.go @@ -1,6 +1,7 @@ package json import ( + "bytes" "fmt" "reflect" "unsafe" @@ -890,6 +891,12 @@ func (e *Encoder) compileStruct(ctx *encodeCompileContext, isPtr bool) (*opcode, } } key := fmt.Sprintf(`"%s":`, tag.key) + + var buf bytes.Buffer + enc := NewEncoder(&buf) + enc.encodeEscapedString(tag.key) + escapedKey := fmt.Sprintf(`%s:`, string(enc.buf)) + enc.release() fieldCode := &opcode{ typ: valueCode.typ, displayIdx: fieldOpcodeIndex, @@ -898,6 +905,7 @@ func (e *Encoder) compileStruct(ctx *encodeCompileContext, isPtr bool) (*opcode, indent: ctx.indent, anonymousKey: field.Anonymous, key: []byte(key), + escapedKey: []byte(escapedKey), isTaggedKey: tag.isTaggedKey, displayKey: tag.key, offset: field.Offset, diff --git a/encode_opcode.go b/encode_opcode.go index 19087c7..4b3ed1e 100644 --- a/encode_opcode.go +++ b/encode_opcode.go @@ -13,6 +13,7 @@ type opcode struct { typ *rtype // go type displayIdx int // opcode index key []byte // struct field key + escapedKey []byte // struct field key ( HTML escaped ) displayKey string // key text to display isTaggedKey bool // whether tagged key anonymousKey bool // whether anonymous key @@ -78,6 +79,7 @@ func (c *opcode) copy(codeMap map[uintptr]*opcode) *opcode { typ: c.typ, displayIdx: c.displayIdx, key: c.key, + escapedKey: c.escapedKey, displayKey: c.displayKey, isTaggedKey: c.isTaggedKey, anonymousKey: c.anonymousKey, diff --git a/encode_string.go b/encode_string.go index 8cd1228..f9ec629 100644 --- a/encode_string.go +++ b/encode_string.go @@ -308,22 +308,22 @@ func (e *Encoder) writeStringSlowPathWithHTMLEscaped(i int, s string, valLen int func (e *Encoder) encodeNoEscapedString(s string) { valLen := len(s) - e.buf = append(e.buf, '"') // write string, the fast path, without utf8 and escape support i := 0 for ; i < valLen; i++ { c := s[i] - if c > 31 && c != '"' && c != '\\' { - e.buf = append(e.buf, c) - } else { + if c <= 31 || c == '"' || c == '\\' { break } } + e.buf = append(e.buf, '"') if i == valLen { + e.buf = append(e.buf, s...) e.buf = append(e.buf, '"') return } + e.buf = append(e.buf, s[:i]...) e.writeStringSlowPath(i, s, valLen) } diff --git a/encode_vm.go b/encode_vm.go index 44f9b73..378e82a 100644 --- a/encode_vm.go +++ b/encode_vm.go @@ -215,7 +215,7 @@ func (e *Encoder) run(ctx *encodeRuntimeContext, code *opcode) error { return err } } else { - if err := compact(&buf, b, true); err != nil { + if err := compact(&buf, b, e.enabledHTMLEscape); err != nil { return err } } @@ -800,7 +800,7 @@ func (e *Encoder) run(ctx *encodeRuntimeContext, code *opcode) error { } else { e.encodeByte('{') if !code.anonymousKey { - e.encodeBytes(code.key) + e.encodeKey(code) } p := ptr + code.offset code = code.next @@ -828,7 +828,7 @@ func (e *Encoder) run(ctx *encodeRuntimeContext, code *opcode) error { code = code.end } else { e.encodeByte('{') - e.encodeBytes(code.key) + e.encodeKey(code) e.encodeInt(e.ptrToInt(ptr + code.offset)) code = code.next } @@ -840,7 +840,7 @@ func (e *Encoder) run(ctx *encodeRuntimeContext, code *opcode) error { if ptr == 0 { code = code.end } else { - e.encodeBytes(code.key) + e.encodeKey(code) e.encodeInt(e.ptrToInt(ptr + code.offset)) code = code.next } @@ -858,7 +858,7 @@ func (e *Encoder) run(ctx *encodeRuntimeContext, code *opcode) error { code = code.end } else { e.encodeByte('{') - e.encodeBytes(code.key) + e.encodeKey(code) e.encodeInt8(e.ptrToInt8(ptr + code.offset)) code = code.next } @@ -870,7 +870,7 @@ func (e *Encoder) run(ctx *encodeRuntimeContext, code *opcode) error { if ptr == 0 { code = code.end } else { - e.encodeBytes(code.key) + e.encodeKey(code) e.encodeInt8(e.ptrToInt8(ptr + code.offset)) code = code.next } @@ -888,7 +888,7 @@ func (e *Encoder) run(ctx *encodeRuntimeContext, code *opcode) error { code = code.end } else { e.encodeByte('{') - e.encodeBytes(code.key) + e.encodeKey(code) e.encodeInt16(e.ptrToInt16(ptr + code.offset)) code = code.next } @@ -900,7 +900,7 @@ func (e *Encoder) run(ctx *encodeRuntimeContext, code *opcode) error { if ptr == 0 { code = code.end } else { - e.encodeBytes(code.key) + e.encodeKey(code) e.encodeInt16(e.ptrToInt16(ptr + code.offset)) code = code.next } @@ -918,7 +918,7 @@ func (e *Encoder) run(ctx *encodeRuntimeContext, code *opcode) error { code = code.end } else { e.encodeByte('{') - e.encodeBytes(code.key) + e.encodeKey(code) e.encodeInt32(e.ptrToInt32(ptr + code.offset)) code = code.next } @@ -930,7 +930,7 @@ func (e *Encoder) run(ctx *encodeRuntimeContext, code *opcode) error { if ptr == 0 { code = code.end } else { - e.encodeBytes(code.key) + e.encodeKey(code) e.encodeInt32(e.ptrToInt32(ptr + code.offset)) code = code.next } @@ -948,7 +948,7 @@ func (e *Encoder) run(ctx *encodeRuntimeContext, code *opcode) error { code = code.end } else { e.encodeByte('{') - e.encodeBytes(code.key) + e.encodeKey(code) e.encodeInt64(e.ptrToInt64(ptr + code.offset)) code = code.next } @@ -960,7 +960,7 @@ func (e *Encoder) run(ctx *encodeRuntimeContext, code *opcode) error { if ptr == 0 { code = code.end } else { - e.encodeBytes(code.key) + e.encodeKey(code) e.encodeInt64(e.ptrToInt64(ptr + code.offset)) code = code.next } @@ -978,7 +978,7 @@ func (e *Encoder) run(ctx *encodeRuntimeContext, code *opcode) error { code = code.end } else { e.encodeByte('{') - e.encodeBytes(code.key) + e.encodeKey(code) e.encodeUint(e.ptrToUint(ptr + code.offset)) code = code.next } @@ -990,7 +990,7 @@ func (e *Encoder) run(ctx *encodeRuntimeContext, code *opcode) error { if ptr == 0 { code = code.end } else { - e.encodeBytes(code.key) + e.encodeKey(code) e.encodeUint(e.ptrToUint(ptr + code.offset)) code = code.next } @@ -1008,7 +1008,7 @@ func (e *Encoder) run(ctx *encodeRuntimeContext, code *opcode) error { code = code.end } else { e.encodeByte('{') - e.encodeBytes(code.key) + e.encodeKey(code) e.encodeUint8(e.ptrToUint8(ptr + code.offset)) code = code.next } @@ -1020,7 +1020,7 @@ func (e *Encoder) run(ctx *encodeRuntimeContext, code *opcode) error { if ptr == 0 { code = code.end } else { - e.encodeBytes(code.key) + e.encodeKey(code) e.encodeUint8(e.ptrToUint8(ptr + code.offset)) code = code.next } @@ -1038,7 +1038,7 @@ func (e *Encoder) run(ctx *encodeRuntimeContext, code *opcode) error { code = code.end } else { e.encodeByte('{') - e.encodeBytes(code.key) + e.encodeKey(code) e.encodeUint16(e.ptrToUint16(ptr + code.offset)) code = code.next } @@ -1050,7 +1050,7 @@ func (e *Encoder) run(ctx *encodeRuntimeContext, code *opcode) error { if ptr == 0 { code = code.end } else { - e.encodeBytes(code.key) + e.encodeKey(code) e.encodeUint16(e.ptrToUint16(ptr + code.offset)) code = code.next } @@ -1068,7 +1068,7 @@ func (e *Encoder) run(ctx *encodeRuntimeContext, code *opcode) error { code = code.end } else { e.encodeByte('{') - e.encodeBytes(code.key) + e.encodeKey(code) e.encodeUint32(e.ptrToUint32(ptr + code.offset)) code = code.next } @@ -1080,7 +1080,7 @@ func (e *Encoder) run(ctx *encodeRuntimeContext, code *opcode) error { if ptr == 0 { code = code.end } else { - e.encodeBytes(code.key) + e.encodeKey(code) e.encodeUint32(e.ptrToUint32(ptr + code.offset)) code = code.next } @@ -1098,7 +1098,7 @@ func (e *Encoder) run(ctx *encodeRuntimeContext, code *opcode) error { code = code.end } else { e.encodeByte('{') - e.encodeBytes(code.key) + e.encodeKey(code) e.encodeUint64(e.ptrToUint64(ptr + code.offset)) code = code.next } @@ -1110,7 +1110,7 @@ func (e *Encoder) run(ctx *encodeRuntimeContext, code *opcode) error { if ptr == 0 { code = code.end } else { - e.encodeBytes(code.key) + e.encodeKey(code) e.encodeUint64(e.ptrToUint64(ptr + code.offset)) code = code.next } @@ -1128,7 +1128,7 @@ func (e *Encoder) run(ctx *encodeRuntimeContext, code *opcode) error { code = code.end } else { e.encodeByte('{') - e.encodeBytes(code.key) + e.encodeKey(code) e.encodeFloat32(e.ptrToFloat32(ptr + code.offset)) code = code.next } @@ -1140,7 +1140,7 @@ func (e *Encoder) run(ctx *encodeRuntimeContext, code *opcode) error { if ptr == 0 { code = code.end } else { - e.encodeBytes(code.key) + e.encodeKey(code) e.encodeFloat32(e.ptrToFloat32(ptr + code.offset)) code = code.next } @@ -1165,7 +1165,7 @@ func (e *Encoder) run(ctx *encodeRuntimeContext, code *opcode) error { } } e.encodeByte('{') - e.encodeBytes(code.key) + e.encodeKey(code) e.encodeFloat64(v) code = code.next } @@ -1184,7 +1184,7 @@ func (e *Encoder) run(ctx *encodeRuntimeContext, code *opcode) error { Str: strconv.FormatFloat(v, 'g', -1, 64), } } - e.encodeBytes(code.key) + e.encodeKey(code) e.encodeFloat64(v) code = code.next } @@ -1202,7 +1202,7 @@ func (e *Encoder) run(ctx *encodeRuntimeContext, code *opcode) error { code = code.end } else { e.encodeByte('{') - e.encodeBytes(code.key) + e.encodeKey(code) e.encodeString(e.ptrToString(ptr + code.offset)) code = code.next } @@ -1214,7 +1214,7 @@ func (e *Encoder) run(ctx *encodeRuntimeContext, code *opcode) error { if ptr == 0 { code = code.end } else { - e.encodeBytes(code.key) + e.encodeKey(code) e.encodeString(e.ptrToString(ptr + code.offset)) code = code.next } @@ -1232,7 +1232,7 @@ func (e *Encoder) run(ctx *encodeRuntimeContext, code *opcode) error { code = code.end } else { e.encodeByte('{') - e.encodeBytes(code.key) + e.encodeKey(code) e.encodeBool(e.ptrToBool(ptr + code.offset)) code = code.next } @@ -1244,7 +1244,7 @@ func (e *Encoder) run(ctx *encodeRuntimeContext, code *opcode) error { if ptr == 0 { code = code.end } else { - e.encodeBytes(code.key) + e.encodeKey(code) e.encodeBool(e.ptrToBool(ptr + code.offset)) code = code.next } @@ -1262,7 +1262,7 @@ func (e *Encoder) run(ctx *encodeRuntimeContext, code *opcode) error { code = code.end } else { e.encodeByte('{') - e.encodeBytes(code.key) + e.encodeKey(code) e.encodeByteSlice(e.ptrToBytes(ptr + code.offset)) code = code.next } @@ -1274,7 +1274,7 @@ func (e *Encoder) run(ctx *encodeRuntimeContext, code *opcode) error { if ptr == 0 { code = code.end } else { - e.encodeBytes(code.key) + e.encodeKey(code) e.encodeByteSlice(e.ptrToBytes(ptr + code.offset)) code = code.next } @@ -1293,7 +1293,7 @@ func (e *Encoder) run(ctx *encodeRuntimeContext, code *opcode) error { } else { e.encodeByte('{') if !code.anonymousKey { - e.encodeBytes(code.key) + e.encodeKey(code) } code = code.next store(ctxptr, code.idx, ptr) @@ -1306,7 +1306,7 @@ func (e *Encoder) run(ctx *encodeRuntimeContext, code *opcode) error { if ptr == 0 { code = code.end } else { - e.encodeBytes(code.key) + e.encodeKey(code) store(ctxptr, code.idx, ptr) code = code.next } @@ -1326,7 +1326,7 @@ func (e *Encoder) run(ctx *encodeRuntimeContext, code *opcode) error { } else { e.encodeByte('{') if !code.anonymousKey { - e.encodeBytes(code.key) + e.encodeKey(code) } code = code.next store(ctxptr, code.idx, p) @@ -1340,7 +1340,7 @@ func (e *Encoder) run(ctx *encodeRuntimeContext, code *opcode) error { if p == 0 { code = code.end } else { - e.encodeBytes(code.key) + e.encodeKey(code) store(ctxptr, code.idx, p) code = code.next } @@ -1354,7 +1354,7 @@ func (e *Encoder) run(ctx *encodeRuntimeContext, code *opcode) error { code = code.end } else { e.encodeByte('{') - e.encodeBytes(code.key) + e.encodeKey(code) v := *(*interface{})(unsafe.Pointer(&interfaceHeader{ typ: code.typ, ptr: unsafe.Pointer(ptr + code.offset), @@ -1379,7 +1379,7 @@ func (e *Encoder) run(ctx *encodeRuntimeContext, code *opcode) error { ) } var buf bytes.Buffer - if err := compact(&buf, b, true); err != nil { + if err := compact(&buf, b, e.enabledHTMLEscape); err != nil { return err } e.encodeBytes(buf.Bytes()) @@ -1393,7 +1393,7 @@ func (e *Encoder) run(ctx *encodeRuntimeContext, code *opcode) error { if ptr == 0 { code = code.end } else { - e.encodeBytes(code.key) + e.encodeKey(code) v := *(*interface{})(unsafe.Pointer(&interfaceHeader{ typ: code.typ, ptr: unsafe.Pointer(ptr + code.offset), @@ -1418,7 +1418,7 @@ func (e *Encoder) run(ctx *encodeRuntimeContext, code *opcode) error { ) } var buf bytes.Buffer - if err := compact(&buf, b, true); err != nil { + if err := compact(&buf, b, e.enabledHTMLEscape); err != nil { return err } e.encodeBytes(buf.Bytes()) @@ -1434,7 +1434,7 @@ func (e *Encoder) run(ctx *encodeRuntimeContext, code *opcode) error { code = code.end } else { e.encodeByte('{') - e.encodeBytes(code.key) + e.encodeKey(code) v := *(*interface{})(unsafe.Pointer(&interfaceHeader{ typ: code.typ, ptr: unsafe.Pointer(ptr + code.offset), @@ -1463,7 +1463,7 @@ func (e *Encoder) run(ctx *encodeRuntimeContext, code *opcode) error { if ptr == 0 { code = code.end } else { - e.encodeBytes(code.key) + e.encodeKey(code) v := *(*interface{})(unsafe.Pointer(&interfaceHeader{ typ: code.typ, ptr: unsafe.Pointer(ptr + code.offset), @@ -1506,7 +1506,7 @@ func (e *Encoder) run(ctx *encodeRuntimeContext, code *opcode) error { e.encodeIndent(code.indent) e.encodeBytes([]byte{'{', '\n'}) e.encodeIndent(code.indent + 1) - e.encodeBytes(code.key) + e.encodeKey(code) e.encodeByte(' ') code = code.next store(ctxptr, code.idx, ptr) @@ -1527,7 +1527,7 @@ func (e *Encoder) run(ctx *encodeRuntimeContext, code *opcode) error { } else { e.encodeBytes([]byte{'{', '\n'}) e.encodeIndent(code.indent + 1) - e.encodeBytes(code.key) + e.encodeKey(code) e.encodeByte(' ') e.encodeInt(e.ptrToInt(ptr + code.offset)) code = code.next @@ -1545,7 +1545,7 @@ func (e *Encoder) run(ctx *encodeRuntimeContext, code *opcode) error { e.encodeIndent(code.indent) e.encodeBytes([]byte{'{', '\n'}) e.encodeIndent(code.indent + 1) - e.encodeBytes(code.key) + e.encodeKey(code) e.encodeByte(' ') e.encodeInt8(e.ptrToInt8(ptr)) code = code.next @@ -1562,7 +1562,7 @@ func (e *Encoder) run(ctx *encodeRuntimeContext, code *opcode) error { e.encodeIndent(code.indent) e.encodeBytes([]byte{'{', '\n'}) e.encodeIndent(code.indent + 1) - e.encodeBytes(code.key) + e.encodeKey(code) e.encodeByte(' ') e.encodeInt16(e.ptrToInt16(ptr)) code = code.next @@ -1580,7 +1580,7 @@ func (e *Encoder) run(ctx *encodeRuntimeContext, code *opcode) error { e.encodeIndent(code.indent) e.encodeBytes([]byte{'{', '\n'}) e.encodeIndent(code.indent + 1) - e.encodeBytes(code.key) + e.encodeKey(code) e.encodeByte(' ') e.encodeInt32(e.ptrToInt32(ptr)) code = code.next @@ -1598,7 +1598,7 @@ func (e *Encoder) run(ctx *encodeRuntimeContext, code *opcode) error { e.encodeIndent(code.indent) e.encodeBytes([]byte{'{', '\n'}) e.encodeIndent(code.indent + 1) - e.encodeBytes(code.key) + e.encodeKey(code) e.encodeByte(' ') e.encodeInt64(e.ptrToInt64(ptr)) code = code.next @@ -1616,7 +1616,7 @@ func (e *Encoder) run(ctx *encodeRuntimeContext, code *opcode) error { e.encodeIndent(code.indent) e.encodeBytes([]byte{'{', '\n'}) e.encodeIndent(code.indent + 1) - e.encodeBytes(code.key) + e.encodeKey(code) e.encodeByte(' ') e.encodeUint(e.ptrToUint(ptr)) code = code.next @@ -1634,7 +1634,7 @@ func (e *Encoder) run(ctx *encodeRuntimeContext, code *opcode) error { e.encodeIndent(code.indent) e.encodeBytes([]byte{'{', '\n'}) e.encodeIndent(code.indent + 1) - e.encodeBytes(code.key) + e.encodeKey(code) e.encodeByte(' ') e.encodeUint8(e.ptrToUint8(ptr)) code = code.next @@ -1652,7 +1652,7 @@ func (e *Encoder) run(ctx *encodeRuntimeContext, code *opcode) error { e.encodeIndent(code.indent) e.encodeBytes([]byte{'{', '\n'}) e.encodeIndent(code.indent + 1) - e.encodeBytes(code.key) + e.encodeKey(code) e.encodeByte(' ') e.encodeUint16(e.ptrToUint16(ptr)) code = code.next @@ -1670,7 +1670,7 @@ func (e *Encoder) run(ctx *encodeRuntimeContext, code *opcode) error { e.encodeIndent(code.indent) e.encodeBytes([]byte{'{', '\n'}) e.encodeIndent(code.indent + 1) - e.encodeBytes(code.key) + e.encodeKey(code) e.encodeByte(' ') e.encodeUint32(e.ptrToUint32(ptr)) code = code.next @@ -1688,7 +1688,7 @@ func (e *Encoder) run(ctx *encodeRuntimeContext, code *opcode) error { e.encodeIndent(code.indent) e.encodeBytes([]byte{'{', '\n'}) e.encodeIndent(code.indent + 1) - e.encodeBytes(code.key) + e.encodeKey(code) e.encodeByte(' ') e.encodeUint64(e.ptrToUint64(ptr)) code = code.next @@ -1706,7 +1706,7 @@ func (e *Encoder) run(ctx *encodeRuntimeContext, code *opcode) error { e.encodeIndent(code.indent) e.encodeBytes([]byte{'{', '\n'}) e.encodeIndent(code.indent + 1) - e.encodeBytes(code.key) + e.encodeKey(code) e.encodeByte(' ') e.encodeFloat32(e.ptrToFloat32(ptr)) code = code.next @@ -1731,7 +1731,7 @@ func (e *Encoder) run(ctx *encodeRuntimeContext, code *opcode) error { e.encodeIndent(code.indent) e.encodeBytes([]byte{'{', '\n'}) e.encodeIndent(code.indent + 1) - e.encodeBytes(code.key) + e.encodeKey(code) e.encodeByte(' ') e.encodeFloat64(v) code = code.next @@ -1749,7 +1749,7 @@ func (e *Encoder) run(ctx *encodeRuntimeContext, code *opcode) error { e.encodeIndent(code.indent) e.encodeBytes([]byte{'{', '\n'}) e.encodeIndent(code.indent + 1) - e.encodeBytes(code.key) + e.encodeKey(code) e.encodeByte(' ') e.encodeString(e.ptrToString(ptr)) code = code.next @@ -1767,7 +1767,7 @@ func (e *Encoder) run(ctx *encodeRuntimeContext, code *opcode) error { e.encodeIndent(code.indent) e.encodeBytes([]byte{'{', '\n'}) e.encodeIndent(code.indent + 1) - e.encodeBytes(code.key) + e.encodeKey(code) e.encodeByte(' ') e.encodeBool(e.ptrToBool(ptr)) code = code.next @@ -1785,7 +1785,7 @@ func (e *Encoder) run(ctx *encodeRuntimeContext, code *opcode) error { e.encodeIndent(code.indent) e.encodeBytes([]byte{'{', '\n'}) e.encodeIndent(code.indent + 1) - e.encodeBytes(code.key) + e.encodeKey(code) e.encodeByte(' ') s := base64.StdEncoding.EncodeToString(e.ptrToBytes(ptr)) e.encodeByte('"') @@ -1810,7 +1810,7 @@ func (e *Encoder) run(ctx *encodeRuntimeContext, code *opcode) error { if p == 0 || *(*uintptr)(unsafe.Pointer(p)) == 0 { code = code.nextField } else { - e.encodeBytes(code.key) + e.encodeKey(code) code = code.next store(ctxptr, code.idx, p) } @@ -1830,7 +1830,7 @@ func (e *Encoder) run(ctx *encodeRuntimeContext, code *opcode) error { if p == 0 || *(*uintptr)(unsafe.Pointer(p)) == 0 { code = code.nextField } else { - e.encodeBytes(code.key) + e.encodeKey(code) code = code.next store(ctxptr, code.idx, p) } @@ -1852,7 +1852,7 @@ func (e *Encoder) run(ctx *encodeRuntimeContext, code *opcode) error { if v == 0 { code = code.nextField } else { - e.encodeBytes(code.key) + e.encodeKey(code) e.encodeInt(v) code = code.next } @@ -1872,7 +1872,7 @@ func (e *Encoder) run(ctx *encodeRuntimeContext, code *opcode) error { if v == 0 { code = code.nextField } else { - e.encodeBytes(code.key) + e.encodeKey(code) e.encodeInt(v) code = code.next } @@ -1894,7 +1894,7 @@ func (e *Encoder) run(ctx *encodeRuntimeContext, code *opcode) error { if v == 0 { code = code.nextField } else { - e.encodeBytes(code.key) + e.encodeKey(code) e.encodeInt8(v) code = code.next } @@ -1914,7 +1914,7 @@ func (e *Encoder) run(ctx *encodeRuntimeContext, code *opcode) error { if v == 0 { code = code.nextField } else { - e.encodeBytes(code.key) + e.encodeKey(code) e.encodeInt8(v) code = code.next } @@ -1936,7 +1936,7 @@ func (e *Encoder) run(ctx *encodeRuntimeContext, code *opcode) error { if v == 0 { code = code.nextField } else { - e.encodeBytes(code.key) + e.encodeKey(code) e.encodeInt16(v) code = code.next } @@ -1956,7 +1956,7 @@ func (e *Encoder) run(ctx *encodeRuntimeContext, code *opcode) error { if v == 0 { code = code.nextField } else { - e.encodeBytes(code.key) + e.encodeKey(code) e.encodeInt16(v) code = code.next } @@ -1978,7 +1978,7 @@ func (e *Encoder) run(ctx *encodeRuntimeContext, code *opcode) error { if v == 0 { code = code.nextField } else { - e.encodeBytes(code.key) + e.encodeKey(code) e.encodeInt32(v) code = code.next } @@ -1998,7 +1998,7 @@ func (e *Encoder) run(ctx *encodeRuntimeContext, code *opcode) error { if v == 0 { code = code.nextField } else { - e.encodeBytes(code.key) + e.encodeKey(code) e.encodeInt32(v) code = code.next } @@ -2020,7 +2020,7 @@ func (e *Encoder) run(ctx *encodeRuntimeContext, code *opcode) error { if v == 0 { code = code.nextField } else { - e.encodeBytes(code.key) + e.encodeKey(code) e.encodeInt64(v) code = code.next } @@ -2040,7 +2040,7 @@ func (e *Encoder) run(ctx *encodeRuntimeContext, code *opcode) error { if v == 0 { code = code.nextField } else { - e.encodeBytes(code.key) + e.encodeKey(code) e.encodeInt64(v) code = code.next } @@ -2062,7 +2062,7 @@ func (e *Encoder) run(ctx *encodeRuntimeContext, code *opcode) error { if v == 0 { code = code.nextField } else { - e.encodeBytes(code.key) + e.encodeKey(code) e.encodeUint(v) code = code.next } @@ -2082,7 +2082,7 @@ func (e *Encoder) run(ctx *encodeRuntimeContext, code *opcode) error { if v == 0 { code = code.nextField } else { - e.encodeBytes(code.key) + e.encodeKey(code) e.encodeUint(v) code = code.next } @@ -2104,7 +2104,7 @@ func (e *Encoder) run(ctx *encodeRuntimeContext, code *opcode) error { if v == 0 { code = code.nextField } else { - e.encodeBytes(code.key) + e.encodeKey(code) e.encodeUint8(v) code = code.next } @@ -2124,7 +2124,7 @@ func (e *Encoder) run(ctx *encodeRuntimeContext, code *opcode) error { if v == 0 { code = code.nextField } else { - e.encodeBytes(code.key) + e.encodeKey(code) e.encodeUint8(v) code = code.next } @@ -2146,7 +2146,7 @@ func (e *Encoder) run(ctx *encodeRuntimeContext, code *opcode) error { if v == 0 { code = code.nextField } else { - e.encodeBytes(code.key) + e.encodeKey(code) e.encodeUint16(v) code = code.next } @@ -2166,7 +2166,7 @@ func (e *Encoder) run(ctx *encodeRuntimeContext, code *opcode) error { if v == 0 { code = code.nextField } else { - e.encodeBytes(code.key) + e.encodeKey(code) e.encodeUint16(v) code = code.next } @@ -2188,7 +2188,7 @@ func (e *Encoder) run(ctx *encodeRuntimeContext, code *opcode) error { if v == 0 { code = code.nextField } else { - e.encodeBytes(code.key) + e.encodeKey(code) e.encodeUint32(v) code = code.next } @@ -2208,7 +2208,7 @@ func (e *Encoder) run(ctx *encodeRuntimeContext, code *opcode) error { if v == 0 { code = code.nextField } else { - e.encodeBytes(code.key) + e.encodeKey(code) e.encodeUint32(v) code = code.next } @@ -2230,7 +2230,7 @@ func (e *Encoder) run(ctx *encodeRuntimeContext, code *opcode) error { if v == 0 { code = code.nextField } else { - e.encodeBytes(code.key) + e.encodeKey(code) e.encodeUint64(v) code = code.next } @@ -2250,7 +2250,7 @@ func (e *Encoder) run(ctx *encodeRuntimeContext, code *opcode) error { if v == 0 { code = code.nextField } else { - e.encodeBytes(code.key) + e.encodeKey(code) e.encodeUint64(v) code = code.next } @@ -2272,7 +2272,7 @@ func (e *Encoder) run(ctx *encodeRuntimeContext, code *opcode) error { if v == 0 { code = code.nextField } else { - e.encodeBytes(code.key) + e.encodeKey(code) e.encodeFloat32(v) code = code.next } @@ -2292,7 +2292,7 @@ func (e *Encoder) run(ctx *encodeRuntimeContext, code *opcode) error { if v == 0 { code = code.nextField } else { - e.encodeBytes(code.key) + e.encodeKey(code) e.encodeFloat32(v) code = code.next } @@ -2320,7 +2320,7 @@ func (e *Encoder) run(ctx *encodeRuntimeContext, code *opcode) error { Str: strconv.FormatFloat(v, 'g', -1, 64), } } - e.encodeBytes(code.key) + e.encodeKey(code) e.encodeFloat64(v) code = code.next } @@ -2346,7 +2346,7 @@ func (e *Encoder) run(ctx *encodeRuntimeContext, code *opcode) error { Str: strconv.FormatFloat(v, 'g', -1, 64), } } - e.encodeBytes(code.key) + e.encodeKey(code) e.encodeFloat64(v) code = code.next } @@ -2368,7 +2368,7 @@ func (e *Encoder) run(ctx *encodeRuntimeContext, code *opcode) error { if v == "" { code = code.nextField } else { - e.encodeBytes(code.key) + e.encodeKey(code) e.encodeString(v) code = code.next } @@ -2388,7 +2388,7 @@ func (e *Encoder) run(ctx *encodeRuntimeContext, code *opcode) error { if v == "" { code = code.nextField } else { - e.encodeBytes(code.key) + e.encodeKey(code) e.encodeString(v) code = code.next } @@ -2410,7 +2410,7 @@ func (e *Encoder) run(ctx *encodeRuntimeContext, code *opcode) error { if !v { code = code.nextField } else { - e.encodeBytes(code.key) + e.encodeKey(code) e.encodeBool(v) code = code.next } @@ -2430,7 +2430,7 @@ func (e *Encoder) run(ctx *encodeRuntimeContext, code *opcode) error { if !v { code = code.nextField } else { - e.encodeBytes(code.key) + e.encodeKey(code) e.encodeBool(v) code = code.next } @@ -2452,7 +2452,7 @@ func (e *Encoder) run(ctx *encodeRuntimeContext, code *opcode) error { if len(v) == 0 { code = code.nextField } else { - e.encodeBytes(code.key) + e.encodeKey(code) e.encodeByteSlice(v) code = code.next } @@ -2472,7 +2472,7 @@ func (e *Encoder) run(ctx *encodeRuntimeContext, code *opcode) error { if len(v) == 0 { code = code.nextField } else { - e.encodeBytes(code.key) + e.encodeKey(code) e.encodeByteSlice(v) code = code.next } @@ -2513,10 +2513,10 @@ func (e *Encoder) run(ctx *encodeRuntimeContext, code *opcode) error { code = code.nextField } else { var buf bytes.Buffer - if err := compact(&buf, b, true); err != nil { + if err := compact(&buf, b, e.enabledHTMLEscape); err != nil { return err } - e.encodeBytes(code.key) + e.encodeKey(code) e.encodeBytes(buf.Bytes()) code = code.next } @@ -2556,10 +2556,10 @@ func (e *Encoder) run(ctx *encodeRuntimeContext, code *opcode) error { code = code.nextField } else { var buf bytes.Buffer - if err := compact(&buf, b, true); err != nil { + if err := compact(&buf, b, e.enabledHTMLEscape); err != nil { return err } - e.encodeBytes(code.key) + e.encodeKey(code) e.encodeBytes(buf.Bytes()) code = code.next } @@ -2591,7 +2591,7 @@ func (e *Encoder) run(ctx *encodeRuntimeContext, code *opcode) error { Err: err, } } - e.encodeBytes(code.key) + e.encodeKey(code) e.encodeString(*(*string)(unsafe.Pointer(&bytes))) code = code.next } @@ -2620,7 +2620,7 @@ func (e *Encoder) run(ctx *encodeRuntimeContext, code *opcode) error { Err: err, } } - e.encodeBytes(code.key) + e.encodeKey(code) e.encodeString(*(*string)(unsafe.Pointer(&bytes))) code = code.next } @@ -2645,7 +2645,7 @@ func (e *Encoder) run(ctx *encodeRuntimeContext, code *opcode) error { code = code.nextField } else { e.encodeIndent(code.indent + 1) - e.encodeBytes(code.key) + e.encodeKey(code) e.encodeByte(' ') code = code.next store(ctxptr, code.idx, p) @@ -2671,7 +2671,7 @@ func (e *Encoder) run(ctx *encodeRuntimeContext, code *opcode) error { code = code.nextField } else { e.encodeIndent(code.indent + 1) - e.encodeBytes(code.key) + e.encodeKey(code) e.encodeByte(' ') e.encodeInt(v) code = code.next @@ -2697,7 +2697,7 @@ func (e *Encoder) run(ctx *encodeRuntimeContext, code *opcode) error { code = code.nextField } else { e.encodeIndent(code.indent + 1) - e.encodeBytes(code.key) + e.encodeKey(code) e.encodeByte(' ') e.encodeInt8(v) code = code.next @@ -2723,7 +2723,7 @@ func (e *Encoder) run(ctx *encodeRuntimeContext, code *opcode) error { code = code.nextField } else { e.encodeIndent(code.indent + 1) - e.encodeBytes(code.key) + e.encodeKey(code) e.encodeByte(' ') e.encodeInt16(v) code = code.next @@ -2749,7 +2749,7 @@ func (e *Encoder) run(ctx *encodeRuntimeContext, code *opcode) error { code = code.nextField } else { e.encodeIndent(code.indent + 1) - e.encodeBytes(code.key) + e.encodeKey(code) e.encodeByte(' ') e.encodeInt32(v) code = code.next @@ -2775,7 +2775,7 @@ func (e *Encoder) run(ctx *encodeRuntimeContext, code *opcode) error { code = code.nextField } else { e.encodeIndent(code.indent + 1) - e.encodeBytes(code.key) + e.encodeKey(code) e.encodeByte(' ') e.encodeInt64(v) code = code.next @@ -2801,7 +2801,7 @@ func (e *Encoder) run(ctx *encodeRuntimeContext, code *opcode) error { code = code.nextField } else { e.encodeIndent(code.indent + 1) - e.encodeBytes(code.key) + e.encodeKey(code) e.encodeByte(' ') e.encodeUint(v) code = code.next @@ -2827,7 +2827,7 @@ func (e *Encoder) run(ctx *encodeRuntimeContext, code *opcode) error { code = code.nextField } else { e.encodeIndent(code.indent + 1) - e.encodeBytes(code.key) + e.encodeKey(code) e.encodeByte(' ') e.encodeUint8(v) code = code.next @@ -2853,7 +2853,7 @@ func (e *Encoder) run(ctx *encodeRuntimeContext, code *opcode) error { code = code.nextField } else { e.encodeIndent(code.indent + 1) - e.encodeBytes(code.key) + e.encodeKey(code) e.encodeByte(' ') e.encodeUint16(v) code = code.next @@ -2879,7 +2879,7 @@ func (e *Encoder) run(ctx *encodeRuntimeContext, code *opcode) error { code = code.nextField } else { e.encodeIndent(code.indent + 1) - e.encodeBytes(code.key) + e.encodeKey(code) e.encodeByte(' ') e.encodeUint32(v) code = code.next @@ -2905,7 +2905,7 @@ func (e *Encoder) run(ctx *encodeRuntimeContext, code *opcode) error { code = code.nextField } else { e.encodeIndent(code.indent + 1) - e.encodeBytes(code.key) + e.encodeKey(code) e.encodeByte(' ') e.encodeUint64(v) code = code.next @@ -2931,7 +2931,7 @@ func (e *Encoder) run(ctx *encodeRuntimeContext, code *opcode) error { code = code.nextField } else { e.encodeIndent(code.indent + 1) - e.encodeBytes(code.key) + e.encodeKey(code) e.encodeByte(' ') e.encodeFloat32(v) code = code.next @@ -2963,7 +2963,7 @@ func (e *Encoder) run(ctx *encodeRuntimeContext, code *opcode) error { } } e.encodeIndent(code.indent + 1) - e.encodeBytes(code.key) + e.encodeKey(code) e.encodeByte(' ') e.encodeFloat64(v) code = code.next @@ -2989,7 +2989,7 @@ func (e *Encoder) run(ctx *encodeRuntimeContext, code *opcode) error { code = code.nextField } else { e.encodeIndent(code.indent + 1) - e.encodeBytes(code.key) + e.encodeKey(code) e.encodeByte(' ') e.encodeString(v) code = code.next @@ -3015,7 +3015,7 @@ func (e *Encoder) run(ctx *encodeRuntimeContext, code *opcode) error { code = code.nextField } else { e.encodeIndent(code.indent + 1) - e.encodeBytes(code.key) + e.encodeKey(code) e.encodeByte(' ') e.encodeBool(v) code = code.next @@ -3041,7 +3041,7 @@ func (e *Encoder) run(ctx *encodeRuntimeContext, code *opcode) error { code = code.nextField } else { e.encodeIndent(code.indent + 1) - e.encodeBytes(code.key) + e.encodeKey(code) e.encodeByte(' ') s := base64.StdEncoding.EncodeToString(v) e.encodeByte('"') @@ -3064,7 +3064,7 @@ func (e *Encoder) run(ctx *encodeRuntimeContext, code *opcode) error { } else { e.encodeByte('{') p := ptr + code.offset - e.encodeBytes(code.key) + e.encodeKey(code) code = code.next store(ctxptr, code.idx, p) } @@ -3079,7 +3079,7 @@ func (e *Encoder) run(ctx *encodeRuntimeContext, code *opcode) error { if ptr == 0 { code = code.end.next } else { - e.encodeBytes(code.key) + e.encodeKey(code) code = code.next store(ctxptr, code.idx, ptr+code.offset) } @@ -3096,7 +3096,7 @@ func (e *Encoder) run(ctx *encodeRuntimeContext, code *opcode) error { code = code.end.next } else { e.encodeByte('{') - e.encodeBytes(code.key) + e.encodeKey(code) e.encodeString(fmt.Sprint(e.ptrToInt(ptr + code.offset))) code = code.next } @@ -3111,7 +3111,7 @@ func (e *Encoder) run(ctx *encodeRuntimeContext, code *opcode) error { if ptr == 0 { code = code.end.next } else { - e.encodeBytes(code.key) + e.encodeKey(code) e.encodeString(fmt.Sprint(e.ptrToInt(ptr + code.offset))) code = code.next } @@ -3128,7 +3128,7 @@ func (e *Encoder) run(ctx *encodeRuntimeContext, code *opcode) error { code = code.end.next } else { e.encodeByte('{') - e.encodeBytes(code.key) + e.encodeKey(code) e.encodeString(fmt.Sprint(e.ptrToInt8(ptr + code.offset))) code = code.next } @@ -3143,7 +3143,7 @@ func (e *Encoder) run(ctx *encodeRuntimeContext, code *opcode) error { if ptr == 0 { code = code.end.next } else { - e.encodeBytes(code.key) + e.encodeKey(code) e.encodeString(fmt.Sprint(e.ptrToInt8(ptr + code.offset))) code = code.next } @@ -3160,7 +3160,7 @@ func (e *Encoder) run(ctx *encodeRuntimeContext, code *opcode) error { code = code.end.next } else { e.encodeByte('{') - e.encodeBytes(code.key) + e.encodeKey(code) e.encodeString(fmt.Sprint(e.ptrToInt16(ptr + code.offset))) code = code.next } @@ -3175,7 +3175,7 @@ func (e *Encoder) run(ctx *encodeRuntimeContext, code *opcode) error { if ptr == 0 { code = code.end.next } else { - e.encodeBytes(code.key) + e.encodeKey(code) e.encodeString(fmt.Sprint(e.ptrToInt16(ptr + code.offset))) code = code.next } @@ -3192,7 +3192,7 @@ func (e *Encoder) run(ctx *encodeRuntimeContext, code *opcode) error { code = code.end.next } else { e.encodeByte('{') - e.encodeBytes(code.key) + e.encodeKey(code) e.encodeString(fmt.Sprint(e.ptrToInt32(ptr + code.offset))) code = code.next } @@ -3207,7 +3207,7 @@ func (e *Encoder) run(ctx *encodeRuntimeContext, code *opcode) error { if ptr == 0 { code = code.end.next } else { - e.encodeBytes(code.key) + e.encodeKey(code) e.encodeString(fmt.Sprint(e.ptrToInt32(ptr + code.offset))) code = code.next } @@ -3224,7 +3224,7 @@ func (e *Encoder) run(ctx *encodeRuntimeContext, code *opcode) error { code = code.end.next } else { e.encodeByte('{') - e.encodeBytes(code.key) + e.encodeKey(code) e.encodeString(fmt.Sprint(e.ptrToInt64(ptr + code.offset))) code = code.next } @@ -3239,7 +3239,7 @@ func (e *Encoder) run(ctx *encodeRuntimeContext, code *opcode) error { if ptr == 0 { code = code.end.next } else { - e.encodeBytes(code.key) + e.encodeKey(code) e.encodeString(fmt.Sprint(e.ptrToInt64(ptr + code.offset))) code = code.next } @@ -3256,7 +3256,7 @@ func (e *Encoder) run(ctx *encodeRuntimeContext, code *opcode) error { code = code.end.next } else { e.encodeByte('{') - e.encodeBytes(code.key) + e.encodeKey(code) e.encodeString(fmt.Sprint(e.ptrToUint(ptr + code.offset))) code = code.next } @@ -3271,7 +3271,7 @@ func (e *Encoder) run(ctx *encodeRuntimeContext, code *opcode) error { if ptr == 0 { code = code.end.next } else { - e.encodeBytes(code.key) + e.encodeKey(code) e.encodeString(fmt.Sprint(e.ptrToUint(ptr + code.offset))) code = code.next } @@ -3288,7 +3288,7 @@ func (e *Encoder) run(ctx *encodeRuntimeContext, code *opcode) error { code = code.end.next } else { e.encodeByte('{') - e.encodeBytes(code.key) + e.encodeKey(code) e.encodeString(fmt.Sprint(e.ptrToUint8(ptr + code.offset))) code = code.next } @@ -3303,7 +3303,7 @@ func (e *Encoder) run(ctx *encodeRuntimeContext, code *opcode) error { if ptr == 0 { code = code.end.next } else { - e.encodeBytes(code.key) + e.encodeKey(code) e.encodeString(fmt.Sprint(e.ptrToUint8(ptr + code.offset))) code = code.next } @@ -3320,7 +3320,7 @@ func (e *Encoder) run(ctx *encodeRuntimeContext, code *opcode) error { code = code.end.next } else { e.encodeByte('{') - e.encodeBytes(code.key) + e.encodeKey(code) e.encodeString(fmt.Sprint(e.ptrToUint16(ptr + code.offset))) code = code.next } @@ -3335,7 +3335,7 @@ func (e *Encoder) run(ctx *encodeRuntimeContext, code *opcode) error { if ptr == 0 { code = code.end.next } else { - e.encodeBytes(code.key) + e.encodeKey(code) e.encodeString(fmt.Sprint(e.ptrToUint16(ptr + code.offset))) code = code.next } @@ -3352,7 +3352,7 @@ func (e *Encoder) run(ctx *encodeRuntimeContext, code *opcode) error { code = code.end.next } else { e.encodeByte('{') - e.encodeBytes(code.key) + e.encodeKey(code) e.encodeString(fmt.Sprint(e.ptrToUint32(ptr + code.offset))) code = code.next } @@ -3367,7 +3367,7 @@ func (e *Encoder) run(ctx *encodeRuntimeContext, code *opcode) error { if ptr == 0 { code = code.end.next } else { - e.encodeBytes(code.key) + e.encodeKey(code) e.encodeString(fmt.Sprint(e.ptrToUint32(ptr + code.offset))) code = code.next } @@ -3384,7 +3384,7 @@ func (e *Encoder) run(ctx *encodeRuntimeContext, code *opcode) error { code = code.end.next } else { e.encodeByte('{') - e.encodeBytes(code.key) + e.encodeKey(code) e.encodeString(fmt.Sprint(e.ptrToUint64(ptr + code.offset))) code = code.next } @@ -3399,7 +3399,7 @@ func (e *Encoder) run(ctx *encodeRuntimeContext, code *opcode) error { if ptr == 0 { code = code.end.next } else { - e.encodeBytes(code.key) + e.encodeKey(code) e.encodeString(fmt.Sprint(e.ptrToUint64(ptr + code.offset))) code = code.next } @@ -3416,7 +3416,7 @@ func (e *Encoder) run(ctx *encodeRuntimeContext, code *opcode) error { code = code.end.next } else { e.encodeByte('{') - e.encodeBytes(code.key) + e.encodeKey(code) e.encodeString(fmt.Sprint(e.ptrToFloat32(ptr + code.offset))) code = code.next } @@ -3431,7 +3431,7 @@ func (e *Encoder) run(ctx *encodeRuntimeContext, code *opcode) error { if ptr == 0 { code = code.end.next } else { - e.encodeBytes(code.key) + e.encodeKey(code) e.encodeString(fmt.Sprint(e.ptrToFloat32(ptr + code.offset))) code = code.next } @@ -3455,7 +3455,7 @@ func (e *Encoder) run(ctx *encodeRuntimeContext, code *opcode) error { Str: strconv.FormatFloat(v, 'g', -1, 64), } } - e.encodeBytes(code.key) + e.encodeKey(code) e.encodeString(fmt.Sprint(v)) code = code.next } @@ -3477,7 +3477,7 @@ func (e *Encoder) run(ctx *encodeRuntimeContext, code *opcode) error { Str: strconv.FormatFloat(v, 'g', -1, 64), } } - e.encodeBytes(code.key) + e.encodeKey(code) e.encodeString(fmt.Sprint(v)) code = code.next } @@ -3494,8 +3494,17 @@ func (e *Encoder) run(ctx *encodeRuntimeContext, code *opcode) error { code = code.end.next } else { e.encodeByte('{') - e.encodeBytes(code.key) - e.encodeString(strconv.Quote(e.ptrToString(ptr + code.offset))) + e.encodeKey(code) + var buf bytes.Buffer + enc := NewEncoder(&buf) + s := e.ptrToString(ptr + code.offset) + if e.enabledHTMLEscape { + enc.encodeEscapedString(s) + } else { + enc.encodeNoEscapedString(s) + } + e.encodeString(string(enc.buf)) + enc.release() code = code.next } case opStructFieldPtrAnonymousHeadStringTagString: @@ -3509,7 +3518,7 @@ func (e *Encoder) run(ctx *encodeRuntimeContext, code *opcode) error { if ptr == 0 { code = code.end.next } else { - e.encodeBytes(code.key) + e.encodeKey(code) e.encodeString(strconv.Quote(e.ptrToString(ptr + code.offset))) code = code.next } @@ -3526,7 +3535,7 @@ func (e *Encoder) run(ctx *encodeRuntimeContext, code *opcode) error { code = code.end.next } else { e.encodeByte('{') - e.encodeBytes(code.key) + e.encodeKey(code) e.encodeString(fmt.Sprint(e.ptrToBool(ptr + code.offset))) code = code.next } @@ -3541,7 +3550,7 @@ func (e *Encoder) run(ctx *encodeRuntimeContext, code *opcode) error { if ptr == 0 { code = code.end.next } else { - e.encodeBytes(code.key) + e.encodeKey(code) e.encodeString(fmt.Sprint(e.ptrToBool(ptr + code.offset))) code = code.next } @@ -3558,7 +3567,7 @@ func (e *Encoder) run(ctx *encodeRuntimeContext, code *opcode) error { code = code.end.next } else { e.encodeByte('{') - e.encodeBytes(code.key) + e.encodeKey(code) e.encodeByteSlice(e.ptrToBytes(ptr + code.offset)) code = code.next } @@ -3573,7 +3582,7 @@ func (e *Encoder) run(ctx *encodeRuntimeContext, code *opcode) error { if ptr == 0 { code = code.end.next } else { - e.encodeBytes(code.key) + e.encodeKey(code) e.encodeByteSlice(e.ptrToBytes(ptr + code.offset)) code = code.next } @@ -3607,12 +3616,12 @@ func (e *Encoder) run(ctx *encodeRuntimeContext, code *opcode) error { 0, ) } - e.encodeBytes(code.key) + e.encodeKey(code) e.encodeBytes([]byte{'"', '"'}) code = code.nextField } else { var buf bytes.Buffer - if err := compact(&buf, b, true); err != nil { + if err := compact(&buf, b, e.enabledHTMLEscape); err != nil { return err } e.encodeString(buf.String()) @@ -3647,15 +3656,15 @@ func (e *Encoder) run(ctx *encodeRuntimeContext, code *opcode) error { 0, ) } - e.encodeBytes(code.key) + e.encodeKey(code) e.encodeBytes([]byte{'"', '"'}) code = code.nextField } else { var buf bytes.Buffer - if err := compact(&buf, b, true); err != nil { + if err := compact(&buf, b, e.enabledHTMLEscape); err != nil { return err } - e.encodeBytes(code.key) + e.encodeKey(code) e.encodeString(buf.String()) code = code.next } @@ -3682,7 +3691,7 @@ func (e *Encoder) run(ctx *encodeRuntimeContext, code *opcode) error { Err: err, } } - e.encodeBytes(code.key) + e.encodeKey(code) e.encodeString(*(*string)(unsafe.Pointer(&bytes))) code = code.next } @@ -3706,7 +3715,7 @@ func (e *Encoder) run(ctx *encodeRuntimeContext, code *opcode) error { Err: err, } } - e.encodeBytes(code.key) + e.encodeKey(code) e.encodeString(*(*string)(unsafe.Pointer(&bytes))) code = code.next } @@ -3726,7 +3735,7 @@ func (e *Encoder) run(ctx *encodeRuntimeContext, code *opcode) error { e.encodeBytes([]byte{'{', '\n'}) p := ptr + code.offset e.encodeIndent(code.indent + 1) - e.encodeBytes(code.key) + e.encodeKey(code) e.encodeByte(' ') code = code.next store(ctxptr, code.idx, p) @@ -3746,7 +3755,7 @@ func (e *Encoder) run(ctx *encodeRuntimeContext, code *opcode) error { } else { e.encodeBytes([]byte{'{', '\n'}) e.encodeIndent(code.indent + 1) - e.encodeBytes(code.key) + e.encodeKey(code) e.encodeByte(' ') e.encodeString(fmt.Sprint(e.ptrToInt(ptr + code.offset))) code = code.next @@ -3766,7 +3775,7 @@ func (e *Encoder) run(ctx *encodeRuntimeContext, code *opcode) error { } else { e.encodeBytes([]byte{'{', '\n'}) e.encodeIndent(code.indent + 1) - e.encodeBytes(code.key) + e.encodeKey(code) e.encodeByte(' ') e.encodeString(fmt.Sprint(e.ptrToInt8(ptr + code.offset))) code = code.next @@ -3786,7 +3795,7 @@ func (e *Encoder) run(ctx *encodeRuntimeContext, code *opcode) error { } else { e.encodeBytes([]byte{'{', '\n'}) e.encodeIndent(code.indent + 1) - e.encodeBytes(code.key) + e.encodeKey(code) e.encodeByte(' ') e.encodeString(fmt.Sprint(e.ptrToInt16(ptr + code.offset))) code = code.next @@ -3806,7 +3815,7 @@ func (e *Encoder) run(ctx *encodeRuntimeContext, code *opcode) error { } else { e.encodeBytes([]byte{'{', '\n'}) e.encodeIndent(code.indent + 1) - e.encodeBytes(code.key) + e.encodeKey(code) e.encodeByte(' ') e.encodeString(fmt.Sprint(e.ptrToInt32(ptr + code.offset))) code = code.next @@ -3826,7 +3835,7 @@ func (e *Encoder) run(ctx *encodeRuntimeContext, code *opcode) error { } else { e.encodeBytes([]byte{'{', '\n'}) e.encodeIndent(code.indent + 1) - e.encodeBytes(code.key) + e.encodeKey(code) e.encodeByte(' ') e.encodeString(fmt.Sprint(e.ptrToInt64(ptr + code.offset))) code = code.next @@ -3846,7 +3855,7 @@ func (e *Encoder) run(ctx *encodeRuntimeContext, code *opcode) error { } else { e.encodeBytes([]byte{'{', '\n'}) e.encodeIndent(code.indent + 1) - e.encodeBytes(code.key) + e.encodeKey(code) e.encodeByte(' ') e.encodeString(fmt.Sprint(e.ptrToUint(ptr + code.offset))) code = code.next @@ -3866,7 +3875,7 @@ func (e *Encoder) run(ctx *encodeRuntimeContext, code *opcode) error { } else { e.encodeBytes([]byte{'{', '\n'}) e.encodeIndent(code.indent + 1) - e.encodeBytes(code.key) + e.encodeKey(code) e.encodeByte(' ') e.encodeString(fmt.Sprint(e.ptrToUint8(ptr + code.offset))) code = code.next @@ -3886,7 +3895,7 @@ func (e *Encoder) run(ctx *encodeRuntimeContext, code *opcode) error { } else { e.encodeBytes([]byte{'{', '\n'}) e.encodeIndent(code.indent + 1) - e.encodeBytes(code.key) + e.encodeKey(code) e.encodeByte(' ') e.encodeString(fmt.Sprint(e.ptrToUint16(ptr + code.offset))) code = code.next @@ -3906,7 +3915,7 @@ func (e *Encoder) run(ctx *encodeRuntimeContext, code *opcode) error { } else { e.encodeBytes([]byte{'{', '\n'}) e.encodeIndent(code.indent + 1) - e.encodeBytes(code.key) + e.encodeKey(code) e.encodeByte(' ') e.encodeString(fmt.Sprint(e.ptrToUint32(ptr + code.offset))) code = code.next @@ -3926,7 +3935,7 @@ func (e *Encoder) run(ctx *encodeRuntimeContext, code *opcode) error { } else { e.encodeBytes([]byte{'{', '\n'}) e.encodeIndent(code.indent + 1) - e.encodeBytes(code.key) + e.encodeKey(code) e.encodeByte(' ') e.encodeString(fmt.Sprint(e.ptrToUint64(ptr + code.offset))) code = code.next @@ -3946,7 +3955,7 @@ func (e *Encoder) run(ctx *encodeRuntimeContext, code *opcode) error { } else { e.encodeBytes([]byte{'{', '\n'}) e.encodeIndent(code.indent + 1) - e.encodeBytes(code.key) + e.encodeKey(code) e.encodeByte(' ') e.encodeString(fmt.Sprint(e.ptrToFloat32(ptr + code.offset))) code = code.next @@ -3973,7 +3982,7 @@ func (e *Encoder) run(ctx *encodeRuntimeContext, code *opcode) error { } } e.encodeIndent(code.indent + 1) - e.encodeBytes(code.key) + e.encodeKey(code) e.encodeByte(' ') e.encodeString(fmt.Sprint(v)) code = code.next @@ -3993,7 +4002,7 @@ func (e *Encoder) run(ctx *encodeRuntimeContext, code *opcode) error { } else { e.encodeBytes([]byte{'{', '\n'}) e.encodeIndent(code.indent + 1) - e.encodeBytes(code.key) + e.encodeKey(code) e.encodeByte(' ') e.encodeString(strconv.Quote(e.ptrToString(ptr + code.offset))) code = code.next @@ -4013,7 +4022,7 @@ func (e *Encoder) run(ctx *encodeRuntimeContext, code *opcode) error { } else { e.encodeBytes([]byte{'{', '\n'}) e.encodeIndent(code.indent + 1) - e.encodeBytes(code.key) + e.encodeKey(code) e.encodeByte(' ') e.encodeString(fmt.Sprint(e.ptrToBool(ptr + code.offset))) code = code.next @@ -4033,7 +4042,7 @@ func (e *Encoder) run(ctx *encodeRuntimeContext, code *opcode) error { } else { e.encodeBytes([]byte{'{', '\n'}) e.encodeIndent(code.indent + 1) - e.encodeBytes(code.key) + e.encodeKey(code) e.encodeByte(' ') s := base64.StdEncoding.EncodeToString( e.ptrToBytes(ptr + code.offset), @@ -4048,7 +4057,7 @@ func (e *Encoder) run(ctx *encodeRuntimeContext, code *opcode) error { e.encodeByte(',') } if !code.anonymousKey { - e.encodeBytes(code.key) + e.encodeKey(code) } ptr := load(ctxptr, code.headIdx) + code.offset code = code.next @@ -4058,7 +4067,7 @@ func (e *Encoder) run(ctx *encodeRuntimeContext, code *opcode) error { e.encodeByte(',') } ptr := load(ctxptr, code.headIdx) - e.encodeBytes(code.key) + e.encodeKey(code) e.encodeInt(e.ptrToInt(ptr + code.offset)) code = code.next case opStructFieldInt8: @@ -4066,7 +4075,7 @@ func (e *Encoder) run(ctx *encodeRuntimeContext, code *opcode) error { e.encodeByte(',') } ptr := load(ctxptr, code.headIdx) - e.encodeBytes(code.key) + e.encodeKey(code) e.encodeInt8(e.ptrToInt8(ptr + code.offset)) code = code.next case opStructFieldInt16: @@ -4074,7 +4083,7 @@ func (e *Encoder) run(ctx *encodeRuntimeContext, code *opcode) error { e.encodeByte(',') } ptr := load(ctxptr, code.headIdx) - e.encodeBytes(code.key) + e.encodeKey(code) e.encodeInt16(e.ptrToInt16(ptr + code.offset)) code = code.next case opStructFieldInt32: @@ -4082,7 +4091,7 @@ func (e *Encoder) run(ctx *encodeRuntimeContext, code *opcode) error { e.encodeByte(',') } ptr := load(ctxptr, code.headIdx) - e.encodeBytes(code.key) + e.encodeKey(code) e.encodeInt32(e.ptrToInt32(ptr + code.offset)) code = code.next case opStructFieldInt64: @@ -4090,7 +4099,7 @@ func (e *Encoder) run(ctx *encodeRuntimeContext, code *opcode) error { e.encodeByte(',') } ptr := load(ctxptr, code.headIdx) - e.encodeBytes(code.key) + e.encodeKey(code) e.encodeInt64(e.ptrToInt64(ptr + code.offset)) code = code.next case opStructFieldUint: @@ -4098,7 +4107,7 @@ func (e *Encoder) run(ctx *encodeRuntimeContext, code *opcode) error { e.encodeByte(',') } ptr := load(ctxptr, code.headIdx) - e.encodeBytes(code.key) + e.encodeKey(code) e.encodeUint(e.ptrToUint(ptr + code.offset)) code = code.next case opStructFieldUint8: @@ -4106,7 +4115,7 @@ func (e *Encoder) run(ctx *encodeRuntimeContext, code *opcode) error { e.encodeByte(',') } ptr := load(ctxptr, code.headIdx) - e.encodeBytes(code.key) + e.encodeKey(code) e.encodeUint8(e.ptrToUint8(ptr + code.offset)) code = code.next case opStructFieldUint16: @@ -4114,7 +4123,7 @@ func (e *Encoder) run(ctx *encodeRuntimeContext, code *opcode) error { e.encodeByte(',') } ptr := load(ctxptr, code.headIdx) - e.encodeBytes(code.key) + e.encodeKey(code) e.encodeUint16(e.ptrToUint16(ptr + code.offset)) code = code.next case opStructFieldUint32: @@ -4122,7 +4131,7 @@ func (e *Encoder) run(ctx *encodeRuntimeContext, code *opcode) error { e.encodeByte(',') } ptr := load(ctxptr, code.headIdx) - e.encodeBytes(code.key) + e.encodeKey(code) e.encodeUint32(e.ptrToUint32(ptr + code.offset)) code = code.next case opStructFieldUint64: @@ -4130,7 +4139,7 @@ func (e *Encoder) run(ctx *encodeRuntimeContext, code *opcode) error { e.encodeByte(',') } ptr := load(ctxptr, code.headIdx) - e.encodeBytes(code.key) + e.encodeKey(code) e.encodeUint64(e.ptrToUint64(ptr + code.offset)) code = code.next case opStructFieldFloat32: @@ -4138,7 +4147,7 @@ func (e *Encoder) run(ctx *encodeRuntimeContext, code *opcode) error { e.encodeByte(',') } ptr := load(ctxptr, code.headIdx) - e.encodeBytes(code.key) + e.encodeKey(code) e.encodeFloat32(e.ptrToFloat32(ptr + code.offset)) code = code.next case opStructFieldFloat64: @@ -4146,7 +4155,7 @@ func (e *Encoder) run(ctx *encodeRuntimeContext, code *opcode) error { e.encodeByte(',') } ptr := load(ctxptr, code.headIdx) - e.encodeBytes(code.key) + e.encodeKey(code) v := e.ptrToFloat64(ptr + code.offset) if math.IsInf(v, 0) || math.IsNaN(v) { return &UnsupportedValueError{ @@ -4161,7 +4170,7 @@ func (e *Encoder) run(ctx *encodeRuntimeContext, code *opcode) error { e.encodeByte(',') } ptr := load(ctxptr, code.headIdx) - e.encodeBytes(code.key) + e.encodeKey(code) e.encodeString(e.ptrToString(ptr + code.offset)) code = code.next case opStructFieldBool: @@ -4169,7 +4178,7 @@ func (e *Encoder) run(ctx *encodeRuntimeContext, code *opcode) error { e.encodeByte(',') } ptr := load(ctxptr, code.headIdx) - e.encodeBytes(code.key) + e.encodeKey(code) e.encodeBool(e.ptrToBool(ptr + code.offset)) code = code.next case opStructFieldBytes: @@ -4177,7 +4186,7 @@ func (e *Encoder) run(ctx *encodeRuntimeContext, code *opcode) error { e.encodeByte(',') } ptr := load(ctxptr, code.headIdx) - e.encodeBytes(code.key) + e.encodeKey(code) e.encodeByteSlice(e.ptrToBytes(ptr + code.offset)) code = code.next case opStructFieldMarshalJSON: @@ -4185,7 +4194,7 @@ func (e *Encoder) run(ctx *encodeRuntimeContext, code *opcode) error { e.encodeByte(',') } ptr := load(ctxptr, code.headIdx) - e.encodeBytes(code.key) + e.encodeKey(code) p := ptr + code.offset v := *(*interface{})(unsafe.Pointer(&interfaceHeader{ typ: code.typ, @@ -4199,7 +4208,7 @@ func (e *Encoder) run(ctx *encodeRuntimeContext, code *opcode) error { } } var buf bytes.Buffer - if err := compact(&buf, b, true); err != nil { + if err := compact(&buf, b, e.enabledHTMLEscape); err != nil { return err } e.encodeBytes(buf.Bytes()) @@ -4209,7 +4218,7 @@ func (e *Encoder) run(ctx *encodeRuntimeContext, code *opcode) error { e.encodeByte(',') } ptr := load(ctxptr, code.headIdx) - e.encodeBytes(code.key) + e.encodeKey(code) p := ptr + code.offset v := *(*interface{})(unsafe.Pointer(&interfaceHeader{ typ: code.typ, @@ -4228,7 +4237,7 @@ func (e *Encoder) run(ctx *encodeRuntimeContext, code *opcode) error { if e.buf[len(e.buf)-1] != '{' { e.encodeByte(',') } - e.encodeBytes(code.key) + e.encodeKey(code) ptr := load(ctxptr, code.headIdx) p := ptr + code.offset code = code.next @@ -4237,7 +4246,7 @@ func (e *Encoder) run(ctx *encodeRuntimeContext, code *opcode) error { if e.buf[len(e.buf)-1] != '{' { e.encodeByte(',') } - e.encodeBytes(code.key) + e.encodeKey(code) ptr := load(ctxptr, code.headIdx) p := ptr + code.offset code = code.next @@ -4246,7 +4255,7 @@ func (e *Encoder) run(ctx *encodeRuntimeContext, code *opcode) error { if e.buf[len(e.buf)-1] != '{' { e.encodeByte(',') } - e.encodeBytes(code.key) + e.encodeKey(code) ptr := load(ctxptr, code.headIdx) p := ptr + code.offset code = code.next @@ -4255,7 +4264,7 @@ func (e *Encoder) run(ctx *encodeRuntimeContext, code *opcode) error { if e.buf[len(e.buf)-1] != '{' { e.encodeByte(',') } - e.encodeBytes(code.key) + e.encodeKey(code) ptr := load(ctxptr, code.headIdx) p := ptr + code.offset code = code.next @@ -4264,7 +4273,7 @@ func (e *Encoder) run(ctx *encodeRuntimeContext, code *opcode) error { if e.buf[len(e.buf)-1] != '{' { e.encodeByte(',') } - e.encodeBytes(code.key) + e.encodeKey(code) ptr := load(ctxptr, code.headIdx) p := ptr + code.offset code = code.next @@ -4274,7 +4283,7 @@ func (e *Encoder) run(ctx *encodeRuntimeContext, code *opcode) error { e.encodeBytes([]byte{',', '\n'}) } e.encodeIndent(code.indent) - e.encodeBytes(code.key) + e.encodeKey(code) e.encodeByte(' ') ptr := load(ctxptr, code.headIdx) p := ptr + code.offset @@ -4285,7 +4294,7 @@ func (e *Encoder) run(ctx *encodeRuntimeContext, code *opcode) error { e.encodeBytes([]byte{',', '\n'}) } e.encodeIndent(code.indent) - e.encodeBytes(code.key) + e.encodeKey(code) e.encodeByte(' ') ptr := load(ctxptr, code.headIdx) e.encodeInt(e.ptrToInt(ptr + code.offset)) @@ -4295,7 +4304,7 @@ func (e *Encoder) run(ctx *encodeRuntimeContext, code *opcode) error { e.encodeBytes([]byte{',', '\n'}) } e.encodeIndent(code.indent) - e.encodeBytes(code.key) + e.encodeKey(code) e.encodeByte(' ') ptr := load(ctxptr, code.headIdx) e.encodeInt8(e.ptrToInt8(ptr + code.offset)) @@ -4305,7 +4314,7 @@ func (e *Encoder) run(ctx *encodeRuntimeContext, code *opcode) error { e.encodeBytes([]byte{',', '\n'}) } e.encodeIndent(code.indent) - e.encodeBytes(code.key) + e.encodeKey(code) e.encodeByte(' ') ptr := load(ctxptr, code.headIdx) e.encodeInt16(e.ptrToInt16(ptr + code.offset)) @@ -4315,7 +4324,7 @@ func (e *Encoder) run(ctx *encodeRuntimeContext, code *opcode) error { e.encodeBytes([]byte{',', '\n'}) } e.encodeIndent(code.indent) - e.encodeBytes(code.key) + e.encodeKey(code) e.encodeByte(' ') ptr := load(ctxptr, code.headIdx) e.encodeInt32(e.ptrToInt32(ptr + code.offset)) @@ -4325,7 +4334,7 @@ func (e *Encoder) run(ctx *encodeRuntimeContext, code *opcode) error { e.encodeBytes([]byte{',', '\n'}) } e.encodeIndent(code.indent) - e.encodeBytes(code.key) + e.encodeKey(code) e.encodeByte(' ') ptr := load(ctxptr, code.headIdx) e.encodeInt64(e.ptrToInt64(ptr + code.offset)) @@ -4335,7 +4344,7 @@ func (e *Encoder) run(ctx *encodeRuntimeContext, code *opcode) error { e.encodeBytes([]byte{',', '\n'}) } e.encodeIndent(code.indent) - e.encodeBytes(code.key) + e.encodeKey(code) e.encodeByte(' ') ptr := load(ctxptr, code.headIdx) e.encodeUint(e.ptrToUint(ptr + code.offset)) @@ -4345,7 +4354,7 @@ func (e *Encoder) run(ctx *encodeRuntimeContext, code *opcode) error { e.encodeBytes([]byte{',', '\n'}) } e.encodeIndent(code.indent) - e.encodeBytes(code.key) + e.encodeKey(code) e.encodeByte(' ') ptr := load(ctxptr, code.headIdx) e.encodeUint8(e.ptrToUint8(ptr + code.offset)) @@ -4355,7 +4364,7 @@ func (e *Encoder) run(ctx *encodeRuntimeContext, code *opcode) error { e.encodeBytes([]byte{',', '\n'}) } e.encodeIndent(code.indent) - e.encodeBytes(code.key) + e.encodeKey(code) e.encodeByte(' ') ptr := load(ctxptr, code.headIdx) e.encodeUint16(e.ptrToUint16(ptr + code.offset)) @@ -4365,7 +4374,7 @@ func (e *Encoder) run(ctx *encodeRuntimeContext, code *opcode) error { e.encodeBytes([]byte{',', '\n'}) } e.encodeIndent(code.indent) - e.encodeBytes(code.key) + e.encodeKey(code) e.encodeByte(' ') ptr := load(ctxptr, code.headIdx) e.encodeUint32(e.ptrToUint32(ptr + code.offset)) @@ -4375,7 +4384,7 @@ func (e *Encoder) run(ctx *encodeRuntimeContext, code *opcode) error { e.encodeBytes([]byte{',', '\n'}) } e.encodeIndent(code.indent) - e.encodeBytes(code.key) + e.encodeKey(code) e.encodeByte(' ') ptr := load(ctxptr, code.headIdx) e.encodeUint64(e.ptrToUint64(ptr + code.offset)) @@ -4385,7 +4394,7 @@ func (e *Encoder) run(ctx *encodeRuntimeContext, code *opcode) error { e.encodeBytes([]byte{',', '\n'}) } e.encodeIndent(code.indent) - e.encodeBytes(code.key) + e.encodeKey(code) e.encodeByte(' ') ptr := load(ctxptr, code.headIdx) e.encodeFloat32(e.ptrToFloat32(ptr + code.offset)) @@ -4395,7 +4404,7 @@ func (e *Encoder) run(ctx *encodeRuntimeContext, code *opcode) error { e.encodeBytes([]byte{',', '\n'}) } e.encodeIndent(code.indent) - e.encodeBytes(code.key) + e.encodeKey(code) e.encodeByte(' ') ptr := load(ctxptr, code.headIdx) v := e.ptrToFloat64(ptr + code.offset) @@ -4412,7 +4421,7 @@ func (e *Encoder) run(ctx *encodeRuntimeContext, code *opcode) error { e.encodeBytes([]byte{',', '\n'}) } e.encodeIndent(code.indent) - e.encodeBytes(code.key) + e.encodeKey(code) e.encodeByte(' ') ptr := load(ctxptr, code.headIdx) e.encodeString(e.ptrToString(ptr + code.offset)) @@ -4422,7 +4431,7 @@ func (e *Encoder) run(ctx *encodeRuntimeContext, code *opcode) error { e.encodeBytes([]byte{',', '\n'}) } e.encodeIndent(code.indent) - e.encodeBytes(code.key) + e.encodeKey(code) e.encodeByte(' ') ptr := load(ctxptr, code.headIdx) e.encodeBool(e.ptrToBool(ptr + code.offset)) @@ -4432,7 +4441,7 @@ func (e *Encoder) run(ctx *encodeRuntimeContext, code *opcode) error { e.encodeBytes([]byte{',', '\n'}) } e.encodeIndent(code.indent) - e.encodeBytes(code.key) + e.encodeKey(code) e.encodeByte(' ') ptr := load(ctxptr, code.headIdx) s := base64.StdEncoding.EncodeToString(e.ptrToBytes(ptr + code.offset)) @@ -4445,7 +4454,7 @@ func (e *Encoder) run(ctx *encodeRuntimeContext, code *opcode) error { e.encodeByte(',') } e.encodeIndent(code.indent) - e.encodeBytes(code.key) + e.encodeKey(code) e.encodeByte(' ') ptr := load(ctxptr, code.headIdx) p := ptr + code.offset @@ -4461,7 +4470,7 @@ func (e *Encoder) run(ctx *encodeRuntimeContext, code *opcode) error { } } var buf bytes.Buffer - if err := compact(&buf, b, true); err != nil { + if err := compact(&buf, b, e.enabledHTMLEscape); err != nil { return err } e.encodeBytes(buf.Bytes()) @@ -4471,7 +4480,7 @@ func (e *Encoder) run(ctx *encodeRuntimeContext, code *opcode) error { e.encodeBytes([]byte{',', '\n'}) } e.encodeIndent(code.indent) - e.encodeBytes(code.key) + e.encodeKey(code) e.encodeByte(' ') ptr := load(ctxptr, code.headIdx) p := ptr + code.offset @@ -4487,7 +4496,7 @@ func (e *Encoder) run(ctx *encodeRuntimeContext, code *opcode) error { e.encodeBytes([]byte{',', '\n'}) } e.encodeIndent(code.indent) - e.encodeBytes(code.key) + e.encodeKey(code) e.encodeByte(' ') ptr := load(ctxptr, code.headIdx) p := ptr + code.offset @@ -4503,7 +4512,7 @@ func (e *Encoder) run(ctx *encodeRuntimeContext, code *opcode) error { e.encodeBytes([]byte{',', '\n'}) } e.encodeIndent(code.indent) - e.encodeBytes(code.key) + e.encodeKey(code) e.encodeByte(' ') ptr := load(ctxptr, code.headIdx) p := ptr + code.offset @@ -4525,7 +4534,7 @@ func (e *Encoder) run(ctx *encodeRuntimeContext, code *opcode) error { e.encodeBytes([]byte{',', '\n'}) } e.encodeIndent(code.indent) - e.encodeBytes(code.key) + e.encodeKey(code) e.encodeByte(' ') ptr := load(ctxptr, code.headIdx) p := ptr + code.offset @@ -4549,7 +4558,7 @@ func (e *Encoder) run(ctx *encodeRuntimeContext, code *opcode) error { ptr := load(ctxptr, code.headIdx) p := ptr + code.offset e.encodeIndent(code.indent) - e.encodeBytes(code.key) + e.encodeKey(code) e.encodeByte(' ') if p == 0 { e.encodeBytes([]byte{'{', '}'}) @@ -4574,7 +4583,7 @@ func (e *Encoder) run(ctx *encodeRuntimeContext, code *opcode) error { if e.buf[len(e.buf)-1] != '{' { e.encodeByte(',') } - e.encodeBytes(code.key) + e.encodeKey(code) code = code.next store(ctxptr, code.idx, p) } @@ -4585,7 +4594,7 @@ func (e *Encoder) run(ctx *encodeRuntimeContext, code *opcode) error { if e.buf[len(e.buf)-1] != '{' { e.encodeByte(',') } - e.encodeBytes(code.key) + e.encodeKey(code) e.encodeInt(v) } code = code.next @@ -4596,7 +4605,7 @@ func (e *Encoder) run(ctx *encodeRuntimeContext, code *opcode) error { if e.buf[len(e.buf)-1] != '{' { e.encodeByte(',') } - e.encodeBytes(code.key) + e.encodeKey(code) e.encodeInt8(v) } code = code.next @@ -4607,7 +4616,7 @@ func (e *Encoder) run(ctx *encodeRuntimeContext, code *opcode) error { if e.buf[len(e.buf)-1] != '{' { e.encodeByte(',') } - e.encodeBytes(code.key) + e.encodeKey(code) e.encodeInt16(v) } code = code.next @@ -4618,7 +4627,7 @@ func (e *Encoder) run(ctx *encodeRuntimeContext, code *opcode) error { if e.buf[len(e.buf)-1] != '{' { e.encodeByte(',') } - e.encodeBytes(code.key) + e.encodeKey(code) e.encodeInt32(v) } code = code.next @@ -4629,7 +4638,7 @@ func (e *Encoder) run(ctx *encodeRuntimeContext, code *opcode) error { if e.buf[len(e.buf)-1] != '{' { e.encodeByte(',') } - e.encodeBytes(code.key) + e.encodeKey(code) e.encodeInt64(v) } code = code.next @@ -4640,7 +4649,7 @@ func (e *Encoder) run(ctx *encodeRuntimeContext, code *opcode) error { if e.buf[len(e.buf)-1] != '{' { e.encodeByte(',') } - e.encodeBytes(code.key) + e.encodeKey(code) e.encodeUint(v) } code = code.next @@ -4651,7 +4660,7 @@ func (e *Encoder) run(ctx *encodeRuntimeContext, code *opcode) error { if e.buf[len(e.buf)-1] != '{' { e.encodeByte(',') } - e.encodeBytes(code.key) + e.encodeKey(code) e.encodeUint8(v) } code = code.next @@ -4662,7 +4671,7 @@ func (e *Encoder) run(ctx *encodeRuntimeContext, code *opcode) error { if e.buf[len(e.buf)-1] != '{' { e.encodeByte(',') } - e.encodeBytes(code.key) + e.encodeKey(code) e.encodeUint16(v) } code = code.next @@ -4673,7 +4682,7 @@ func (e *Encoder) run(ctx *encodeRuntimeContext, code *opcode) error { if e.buf[len(e.buf)-1] != '{' { e.encodeByte(',') } - e.encodeBytes(code.key) + e.encodeKey(code) e.encodeUint32(v) } code = code.next @@ -4684,7 +4693,7 @@ func (e *Encoder) run(ctx *encodeRuntimeContext, code *opcode) error { if e.buf[len(e.buf)-1] != '{' { e.encodeByte(',') } - e.encodeBytes(code.key) + e.encodeKey(code) e.encodeUint64(v) } code = code.next @@ -4695,7 +4704,7 @@ func (e *Encoder) run(ctx *encodeRuntimeContext, code *opcode) error { if e.buf[len(e.buf)-1] != '{' { e.encodeByte(',') } - e.encodeBytes(code.key) + e.encodeKey(code) e.encodeFloat32(v) } code = code.next @@ -4712,7 +4721,7 @@ func (e *Encoder) run(ctx *encodeRuntimeContext, code *opcode) error { if e.buf[len(e.buf)-1] != '{' { e.encodeByte(',') } - e.encodeBytes(code.key) + e.encodeKey(code) e.encodeFloat64(v) } code = code.next @@ -4723,7 +4732,7 @@ func (e *Encoder) run(ctx *encodeRuntimeContext, code *opcode) error { if e.buf[len(e.buf)-1] != '{' { e.encodeByte(',') } - e.encodeBytes(code.key) + e.encodeKey(code) e.encodeString(v) } code = code.next @@ -4734,7 +4743,7 @@ func (e *Encoder) run(ctx *encodeRuntimeContext, code *opcode) error { if e.buf[len(e.buf)-1] != '{' { e.encodeByte(',') } - e.encodeBytes(code.key) + e.encodeKey(code) e.encodeBool(v) } code = code.next @@ -4745,7 +4754,7 @@ func (e *Encoder) run(ctx *encodeRuntimeContext, code *opcode) error { if e.buf[len(e.buf)-1] != '{' { e.encodeByte(',') } - e.encodeBytes(code.key) + e.encodeKey(code) e.encodeByteSlice(v) } code = code.next @@ -4765,7 +4774,7 @@ func (e *Encoder) run(ctx *encodeRuntimeContext, code *opcode) error { } } var buf bytes.Buffer - if err := compact(&buf, b, true); err != nil { + if err := compact(&buf, b, e.enabledHTMLEscape); err != nil { return err } e.encodeBytes(buf.Bytes()) @@ -4860,7 +4869,7 @@ func (e *Encoder) run(ctx *encodeRuntimeContext, code *opcode) error { e.encodeBytes([]byte{',', '\n'}) } e.encodeIndent(code.indent) - e.encodeBytes(code.key) + e.encodeKey(code) e.encodeByte(' ') code = code.next store(ctxptr, code.idx, p) @@ -4873,7 +4882,7 @@ func (e *Encoder) run(ctx *encodeRuntimeContext, code *opcode) error { e.encodeBytes([]byte{',', '\n'}) } e.encodeIndent(code.indent) - e.encodeBytes(code.key) + e.encodeKey(code) e.encodeByte(' ') e.encodeInt(v) } @@ -4886,7 +4895,7 @@ func (e *Encoder) run(ctx *encodeRuntimeContext, code *opcode) error { e.encodeBytes([]byte{',', '\n'}) } e.encodeIndent(code.indent) - e.encodeBytes(code.key) + e.encodeKey(code) e.encodeByte(' ') e.encodeInt8(v) } @@ -4899,7 +4908,7 @@ func (e *Encoder) run(ctx *encodeRuntimeContext, code *opcode) error { e.encodeBytes([]byte{',', '\n'}) } e.encodeIndent(code.indent) - e.encodeBytes(code.key) + e.encodeKey(code) e.encodeByte(' ') e.encodeInt16(v) } @@ -4912,7 +4921,7 @@ func (e *Encoder) run(ctx *encodeRuntimeContext, code *opcode) error { e.encodeBytes([]byte{',', '\n'}) } e.encodeIndent(code.indent) - e.encodeBytes(code.key) + e.encodeKey(code) e.encodeByte(' ') e.encodeInt32(v) } @@ -4925,7 +4934,7 @@ func (e *Encoder) run(ctx *encodeRuntimeContext, code *opcode) error { e.encodeBytes([]byte{',', '\n'}) } e.encodeIndent(code.indent) - e.encodeBytes(code.key) + e.encodeKey(code) e.encodeByte(' ') e.encodeInt64(v) } @@ -4938,7 +4947,7 @@ func (e *Encoder) run(ctx *encodeRuntimeContext, code *opcode) error { e.encodeBytes([]byte{',', '\n'}) } e.encodeIndent(code.indent) - e.encodeBytes(code.key) + e.encodeKey(code) e.encodeByte(' ') e.encodeUint(v) } @@ -4951,7 +4960,7 @@ func (e *Encoder) run(ctx *encodeRuntimeContext, code *opcode) error { e.encodeBytes([]byte{',', '\n'}) } e.encodeIndent(code.indent) - e.encodeBytes(code.key) + e.encodeKey(code) e.encodeByte(' ') e.encodeUint8(v) } @@ -4964,7 +4973,7 @@ func (e *Encoder) run(ctx *encodeRuntimeContext, code *opcode) error { e.encodeBytes([]byte{',', '\n'}) } e.encodeIndent(code.indent) - e.encodeBytes(code.key) + e.encodeKey(code) e.encodeByte(' ') e.encodeUint16(v) } @@ -4977,7 +4986,7 @@ func (e *Encoder) run(ctx *encodeRuntimeContext, code *opcode) error { e.encodeBytes([]byte{',', '\n'}) } e.encodeIndent(code.indent) - e.encodeBytes(code.key) + e.encodeKey(code) e.encodeByte(' ') e.encodeUint32(v) } @@ -4990,7 +4999,7 @@ func (e *Encoder) run(ctx *encodeRuntimeContext, code *opcode) error { e.encodeBytes([]byte{',', '\n'}) } e.encodeIndent(code.indent) - e.encodeBytes(code.key) + e.encodeKey(code) e.encodeByte(' ') e.encodeUint64(v) } @@ -5003,7 +5012,7 @@ func (e *Encoder) run(ctx *encodeRuntimeContext, code *opcode) error { e.encodeBytes([]byte{',', '\n'}) } e.encodeIndent(code.indent) - e.encodeBytes(code.key) + e.encodeKey(code) e.encodeByte(' ') e.encodeFloat32(v) } @@ -5022,7 +5031,7 @@ func (e *Encoder) run(ctx *encodeRuntimeContext, code *opcode) error { e.encodeBytes([]byte{',', '\n'}) } e.encodeIndent(code.indent) - e.encodeBytes(code.key) + e.encodeKey(code) e.encodeByte(' ') e.encodeFloat64(v) } @@ -5035,7 +5044,7 @@ func (e *Encoder) run(ctx *encodeRuntimeContext, code *opcode) error { e.encodeBytes([]byte{',', '\n'}) } e.encodeIndent(code.indent) - e.encodeBytes(code.key) + e.encodeKey(code) e.encodeByte(' ') e.encodeString(v) } @@ -5048,7 +5057,7 @@ func (e *Encoder) run(ctx *encodeRuntimeContext, code *opcode) error { e.encodeBytes([]byte{',', '\n'}) } e.encodeIndent(code.indent) - e.encodeBytes(code.key) + e.encodeKey(code) e.encodeByte(' ') e.encodeBool(v) } @@ -5061,7 +5070,7 @@ func (e *Encoder) run(ctx *encodeRuntimeContext, code *opcode) error { e.encodeBytes([]byte{',', '\n'}) } e.encodeIndent(code.indent) - e.encodeBytes(code.key) + e.encodeKey(code) e.encodeByte(' ') s := base64.StdEncoding.EncodeToString(v) e.encodeByte('"') @@ -5080,7 +5089,7 @@ func (e *Encoder) run(ctx *encodeRuntimeContext, code *opcode) error { e.encodeBytes([]byte{',', '\n'}) } e.encodeIndent(code.indent) - e.encodeBytes(code.key) + e.encodeKey(code) e.encodeByte(' ') code = code.next } @@ -5095,7 +5104,7 @@ func (e *Encoder) run(ctx *encodeRuntimeContext, code *opcode) error { e.encodeBytes([]byte{',', '\n'}) } e.encodeIndent(code.indent) - e.encodeBytes(code.key) + e.encodeKey(code) e.encodeByte(' ') code = code.next } @@ -5113,7 +5122,7 @@ func (e *Encoder) run(ctx *encodeRuntimeContext, code *opcode) error { e.encodeBytes([]byte{',', '\n'}) } e.encodeIndent(code.indent) - e.encodeBytes(code.key) + e.encodeKey(code) e.encodeByte(' ') code = code.next } @@ -5133,7 +5142,7 @@ func (e *Encoder) run(ctx *encodeRuntimeContext, code *opcode) error { e.encodeBytes([]byte{',', '\n'}) } e.encodeIndent(code.indent) - e.encodeBytes(code.key) + e.encodeKey(code) e.encodeByte(' ') code = code.next } @@ -5148,7 +5157,7 @@ func (e *Encoder) run(ctx *encodeRuntimeContext, code *opcode) error { e.encodeBytes([]byte{',', '\n'}) } e.encodeIndent(code.indent) - e.encodeBytes(code.key) + e.encodeKey(code) e.encodeByte(' ') headCode := code.next if headCode.next == headCode.end { @@ -5166,7 +5175,7 @@ func (e *Encoder) run(ctx *encodeRuntimeContext, code *opcode) error { if e.buf[len(e.buf)-1] != '{' { e.encodeByte(',') } - e.encodeBytes(code.key) + e.encodeKey(code) code = code.next store(ctxptr, code.idx, p) case opStructFieldStringTagInt: @@ -5174,7 +5183,7 @@ func (e *Encoder) run(ctx *encodeRuntimeContext, code *opcode) error { if e.buf[len(e.buf)-1] != '{' { e.encodeByte(',') } - e.encodeBytes(code.key) + e.encodeKey(code) e.encodeString(fmt.Sprint(e.ptrToInt(ptr + code.offset))) code = code.next case opStructFieldStringTagInt8: @@ -5182,7 +5191,7 @@ func (e *Encoder) run(ctx *encodeRuntimeContext, code *opcode) error { if e.buf[len(e.buf)-1] != '{' { e.encodeByte(',') } - e.encodeBytes(code.key) + e.encodeKey(code) e.encodeString(fmt.Sprint(e.ptrToInt8(ptr + code.offset))) code = code.next case opStructFieldStringTagInt16: @@ -5190,7 +5199,7 @@ func (e *Encoder) run(ctx *encodeRuntimeContext, code *opcode) error { if e.buf[len(e.buf)-1] != '{' { e.encodeByte(',') } - e.encodeBytes(code.key) + e.encodeKey(code) e.encodeString(fmt.Sprint(e.ptrToInt16(ptr + code.offset))) code = code.next case opStructFieldStringTagInt32: @@ -5198,7 +5207,7 @@ func (e *Encoder) run(ctx *encodeRuntimeContext, code *opcode) error { if e.buf[len(e.buf)-1] != '{' { e.encodeByte(',') } - e.encodeBytes(code.key) + e.encodeKey(code) e.encodeString(fmt.Sprint(e.ptrToInt32(ptr + code.offset))) code = code.next case opStructFieldStringTagInt64: @@ -5206,7 +5215,7 @@ func (e *Encoder) run(ctx *encodeRuntimeContext, code *opcode) error { if e.buf[len(e.buf)-1] != '{' { e.encodeByte(',') } - e.encodeBytes(code.key) + e.encodeKey(code) e.encodeString(fmt.Sprint(e.ptrToInt64(ptr + code.offset))) code = code.next case opStructFieldStringTagUint: @@ -5214,7 +5223,7 @@ func (e *Encoder) run(ctx *encodeRuntimeContext, code *opcode) error { if e.buf[len(e.buf)-1] != '{' { e.encodeByte(',') } - e.encodeBytes(code.key) + e.encodeKey(code) e.encodeString(fmt.Sprint(e.ptrToUint(ptr + code.offset))) code = code.next case opStructFieldStringTagUint8: @@ -5222,7 +5231,7 @@ func (e *Encoder) run(ctx *encodeRuntimeContext, code *opcode) error { if e.buf[len(e.buf)-1] != '{' { e.encodeByte(',') } - e.encodeBytes(code.key) + e.encodeKey(code) e.encodeString(fmt.Sprint(e.ptrToUint8(ptr + code.offset))) code = code.next case opStructFieldStringTagUint16: @@ -5230,7 +5239,7 @@ func (e *Encoder) run(ctx *encodeRuntimeContext, code *opcode) error { if e.buf[len(e.buf)-1] != '{' { e.encodeByte(',') } - e.encodeBytes(code.key) + e.encodeKey(code) e.encodeString(fmt.Sprint(e.ptrToUint16(ptr + code.offset))) code = code.next case opStructFieldStringTagUint32: @@ -5238,7 +5247,7 @@ func (e *Encoder) run(ctx *encodeRuntimeContext, code *opcode) error { if e.buf[len(e.buf)-1] != '{' { e.encodeByte(',') } - e.encodeBytes(code.key) + e.encodeKey(code) e.encodeString(fmt.Sprint(e.ptrToUint32(ptr + code.offset))) code = code.next case opStructFieldStringTagUint64: @@ -5246,7 +5255,7 @@ func (e *Encoder) run(ctx *encodeRuntimeContext, code *opcode) error { if e.buf[len(e.buf)-1] != '{' { e.encodeByte(',') } - e.encodeBytes(code.key) + e.encodeKey(code) e.encodeString(fmt.Sprint(e.ptrToUint64(ptr + code.offset))) code = code.next case opStructFieldStringTagFloat32: @@ -5254,7 +5263,7 @@ func (e *Encoder) run(ctx *encodeRuntimeContext, code *opcode) error { if e.buf[len(e.buf)-1] != '{' { e.encodeByte(',') } - e.encodeBytes(code.key) + e.encodeKey(code) e.encodeString(fmt.Sprint(e.ptrToFloat32(ptr + code.offset))) code = code.next case opStructFieldStringTagFloat64: @@ -5269,7 +5278,7 @@ func (e *Encoder) run(ctx *encodeRuntimeContext, code *opcode) error { if e.buf[len(e.buf)-1] != '{' { e.encodeByte(',') } - e.encodeBytes(code.key) + e.encodeKey(code) e.encodeString(fmt.Sprint(v)) code = code.next case opStructFieldStringTagString: @@ -5277,7 +5286,7 @@ func (e *Encoder) run(ctx *encodeRuntimeContext, code *opcode) error { if e.buf[len(e.buf)-1] != '{' { e.encodeByte(',') } - e.encodeBytes(code.key) + e.encodeKey(code) e.encodeString(strconv.Quote(e.ptrToString(ptr + code.offset))) code = code.next case opStructFieldStringTagBool: @@ -5285,7 +5294,7 @@ func (e *Encoder) run(ctx *encodeRuntimeContext, code *opcode) error { if e.buf[len(e.buf)-1] != '{' { e.encodeByte(',') } - e.encodeBytes(code.key) + e.encodeKey(code) e.encodeString(fmt.Sprint(e.ptrToBool(ptr + code.offset))) code = code.next case opStructFieldStringTagBytes: @@ -5294,7 +5303,7 @@ func (e *Encoder) run(ctx *encodeRuntimeContext, code *opcode) error { if e.buf[len(e.buf)-1] != '{' { e.encodeByte(',') } - e.encodeBytes(code.key) + e.encodeKey(code) e.encodeByteSlice(v) code = code.next case opStructFieldStringTagMarshalJSON: @@ -5312,7 +5321,7 @@ func (e *Encoder) run(ctx *encodeRuntimeContext, code *opcode) error { } } var buf bytes.Buffer - if err := compact(&buf, b, true); err != nil { + if err := compact(&buf, b, e.enabledHTMLEscape); err != nil { return err } e.encodeString(buf.String()) @@ -5340,7 +5349,7 @@ func (e *Encoder) run(ctx *encodeRuntimeContext, code *opcode) error { e.encodeBytes([]byte{',', '\n'}) } e.encodeIndent(code.indent) - e.encodeBytes(code.key) + e.encodeKey(code) e.encodeByte(' ') code = code.next store(ctxptr, code.idx, p) @@ -5350,7 +5359,7 @@ func (e *Encoder) run(ctx *encodeRuntimeContext, code *opcode) error { e.encodeBytes([]byte{',', '\n'}) } e.encodeIndent(code.indent) - e.encodeBytes(code.key) + e.encodeKey(code) e.encodeByte(' ') e.encodeString(fmt.Sprint(e.ptrToInt(ptr + code.offset))) code = code.next @@ -5360,7 +5369,7 @@ func (e *Encoder) run(ctx *encodeRuntimeContext, code *opcode) error { e.encodeBytes([]byte{',', '\n'}) } e.encodeIndent(code.indent) - e.encodeBytes(code.key) + e.encodeKey(code) e.encodeByte(' ') e.encodeString(fmt.Sprint(e.ptrToInt8(ptr + code.offset))) code = code.next @@ -5370,7 +5379,7 @@ func (e *Encoder) run(ctx *encodeRuntimeContext, code *opcode) error { e.encodeBytes([]byte{',', '\n'}) } e.encodeIndent(code.indent) - e.encodeBytes(code.key) + e.encodeKey(code) e.encodeByte(' ') e.encodeString(fmt.Sprint(e.ptrToInt16(ptr + code.offset))) code = code.next @@ -5380,7 +5389,7 @@ func (e *Encoder) run(ctx *encodeRuntimeContext, code *opcode) error { e.encodeBytes([]byte{',', '\n'}) } e.encodeIndent(code.indent) - e.encodeBytes(code.key) + e.encodeKey(code) e.encodeByte(' ') e.encodeString(fmt.Sprint(e.ptrToInt32(ptr + code.offset))) code = code.next @@ -5390,7 +5399,7 @@ func (e *Encoder) run(ctx *encodeRuntimeContext, code *opcode) error { e.encodeBytes([]byte{',', '\n'}) } e.encodeIndent(code.indent) - e.encodeBytes(code.key) + e.encodeKey(code) e.encodeByte(' ') e.encodeString(fmt.Sprint(e.ptrToInt64(ptr + code.offset))) code = code.next @@ -5400,7 +5409,7 @@ func (e *Encoder) run(ctx *encodeRuntimeContext, code *opcode) error { e.encodeBytes([]byte{',', '\n'}) } e.encodeIndent(code.indent) - e.encodeBytes(code.key) + e.encodeKey(code) e.encodeByte(' ') e.encodeString(fmt.Sprint(e.ptrToUint(ptr + code.offset))) code = code.next @@ -5410,7 +5419,7 @@ func (e *Encoder) run(ctx *encodeRuntimeContext, code *opcode) error { e.encodeBytes([]byte{',', '\n'}) } e.encodeIndent(code.indent) - e.encodeBytes(code.key) + e.encodeKey(code) e.encodeByte(' ') e.encodeString(fmt.Sprint(e.ptrToUint8(ptr + code.offset))) code = code.next @@ -5420,7 +5429,7 @@ func (e *Encoder) run(ctx *encodeRuntimeContext, code *opcode) error { e.encodeBytes([]byte{',', '\n'}) } e.encodeIndent(code.indent) - e.encodeBytes(code.key) + e.encodeKey(code) e.encodeByte(' ') e.encodeString(fmt.Sprint(e.ptrToUint16(ptr + code.offset))) code = code.next @@ -5430,7 +5439,7 @@ func (e *Encoder) run(ctx *encodeRuntimeContext, code *opcode) error { e.encodeBytes([]byte{',', '\n'}) } e.encodeIndent(code.indent) - e.encodeBytes(code.key) + e.encodeKey(code) e.encodeByte(' ') e.encodeString(fmt.Sprint(e.ptrToUint32(ptr + code.offset))) code = code.next @@ -5440,7 +5449,7 @@ func (e *Encoder) run(ctx *encodeRuntimeContext, code *opcode) error { e.encodeBytes([]byte{',', '\n'}) } e.encodeIndent(code.indent) - e.encodeBytes(code.key) + e.encodeKey(code) e.encodeByte(' ') e.encodeString(fmt.Sprint(e.ptrToUint64(ptr + code.offset))) code = code.next @@ -5450,7 +5459,7 @@ func (e *Encoder) run(ctx *encodeRuntimeContext, code *opcode) error { e.encodeBytes([]byte{',', '\n'}) } e.encodeIndent(code.indent) - e.encodeBytes(code.key) + e.encodeKey(code) e.encodeByte(' ') e.encodeString(fmt.Sprint(e.ptrToFloat32(ptr + code.offset))) code = code.next @@ -5467,7 +5476,7 @@ func (e *Encoder) run(ctx *encodeRuntimeContext, code *opcode) error { e.encodeBytes([]byte{',', '\n'}) } e.encodeIndent(code.indent) - e.encodeBytes(code.key) + e.encodeKey(code) e.encodeByte(' ') e.encodeString(fmt.Sprint(v)) code = code.next @@ -5477,7 +5486,7 @@ func (e *Encoder) run(ctx *encodeRuntimeContext, code *opcode) error { e.encodeBytes([]byte{',', '\n'}) } e.encodeIndent(code.indent) - e.encodeBytes(code.key) + e.encodeKey(code) e.encodeByte(' ') var b bytes.Buffer enc := NewEncoder(&b) @@ -5491,7 +5500,7 @@ func (e *Encoder) run(ctx *encodeRuntimeContext, code *opcode) error { e.encodeBytes([]byte{',', '\n'}) } e.encodeIndent(code.indent) - e.encodeBytes(code.key) + e.encodeKey(code) e.encodeByte(' ') e.encodeString(fmt.Sprint(e.ptrToBool(ptr + code.offset))) code = code.next @@ -5501,7 +5510,7 @@ func (e *Encoder) run(ctx *encodeRuntimeContext, code *opcode) error { e.encodeBytes([]byte{',', '\n'}) } e.encodeIndent(code.indent) - e.encodeBytes(code.key) + e.encodeKey(code) e.encodeByte(' ') s := base64.StdEncoding.EncodeToString( e.ptrToBytes(ptr + code.offset), @@ -5516,7 +5525,7 @@ func (e *Encoder) run(ctx *encodeRuntimeContext, code *opcode) error { e.encodeBytes([]byte{',', '\n'}) } e.encodeIndent(code.indent) - e.encodeBytes(code.key) + e.encodeKey(code) e.encodeByte(' ') p := ptr + code.offset v := *(*interface{})(unsafe.Pointer(&interfaceHeader{ @@ -5531,7 +5540,7 @@ func (e *Encoder) run(ctx *encodeRuntimeContext, code *opcode) error { } } var buf bytes.Buffer - if err := compact(&buf, b, true); err != nil { + if err := compact(&buf, b, e.enabledHTMLEscape); err != nil { return err } e.encodeString(buf.String()) @@ -5542,7 +5551,7 @@ func (e *Encoder) run(ctx *encodeRuntimeContext, code *opcode) error { e.encodeBytes([]byte{',', '\n'}) } e.encodeIndent(code.indent) - e.encodeBytes(code.key) + e.encodeKey(code) e.encodeByte(' ') p := ptr + code.offset v := *(*interface{})(unsafe.Pointer(&interfaceHeader{ diff --git a/json.go b/json.go index 19a2d72..b25f191 100644 --- a/json.go +++ b/json.go @@ -390,7 +390,8 @@ func HTMLEscape(dst *bytes.Buffer, src []byte) { } enc := NewEncoder(dst) enc.SetEscapeHTML(true) - enc.Encode(v) + enc.encode(v) + dst.Write(enc.buf) } // Valid reports whether data is a valid JSON encoding. diff --git a/stream_test.go b/stream_test.go new file mode 100644 index 0000000..c1cff8a --- /dev/null +++ b/stream_test.go @@ -0,0 +1,458 @@ +// Copyright 2010 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package json_test + +import ( + "bytes" + + "strings" + "testing" + + "github.com/goccy/go-json" +) + +// Test values for the stream test. +// One of each JSON kind. +var streamTest = []interface{}{ + 0.1, + "hello", + nil, + true, + false, + []interface{}{"a", "b", "c"}, + map[string]interface{}{"K": "Kelvin", "ß": "long s"}, + 3.14, // another value to make sure something can follow map +} + +var streamEncoded = `0.1 +"hello" +null +true +false +["a","b","c"] +{"ß":"long s","K":"Kelvin"} +3.14 +` + +func TestStreamEncoder(t *testing.T) { + for i := 0; i <= len(streamTest); i++ { + var buf bytes.Buffer + enc := json.NewEncoder(&buf) + // Check that enc.SetIndent("", "") turns off indentation. + enc.SetIndent(">", ".") + enc.SetIndent("", "") + for j, v := range streamTest[0:i] { + if err := enc.Encode(v); err != nil { + t.Fatalf("encode #%d: %v", j, err) + } + } + if have, want := buf.String(), nlines(streamEncoded, i); have != want { + t.Errorf("encoding %d items: mismatch", i) + diff(t, []byte(have), []byte(want)) + break + } + } +} + +var streamEncodedIndent = `0.1 +"hello" +null +true +false +[ +>."a", +>."b", +>."c" +>] +{ +>."ß": "long s", +>."K": "Kelvin" +>} +3.14 +` + +func TestEncoderIndent(t *testing.T) { + var buf bytes.Buffer + enc := json.NewEncoder(&buf) + enc.SetIndent(">", ".") + for _, v := range streamTest { + enc.Encode(v) + } + if have, want := buf.String(), streamEncodedIndent; have != want { + t.Error("indented encoding mismatch") + diff(t, []byte(have), []byte(want)) + } +} + +type strMarshaler string + +func (s strMarshaler) MarshalJSON() ([]byte, error) { + return []byte(s), nil +} + +type strPtrMarshaler string + +func (s *strPtrMarshaler) MarshalJSON() ([]byte, error) { + return []byte(*s), nil +} + +func TestEncoderSetEscapeHTML(t *testing.T) { + var c C + var ct CText + var tagStruct struct { + Valid int `json:"<>&#! "` + Invalid int `json:"\\"` + } + + // This case is particularly interesting, as we force the encoder to + // take the address of the Ptr field to use its MarshalJSON method. This + // is why the '&' is important. + marshalerStruct := &struct { + NonPtr strMarshaler + Ptr strPtrMarshaler + }{`""`, `""`} + + // https://golang.org/issue/34154 + stringOption := struct { + Bar string `json:"bar,string"` + }{`foobar`} + + for _, tt := range []struct { + name string + v interface{} + wantEscape string + want string + }{ + {"c", c, `"\u003c\u0026\u003e"`, `"<&>"`}, + {"ct", ct, `"\"\u003c\u0026\u003e\""`, `"\"<&>\""`}, + {`"<&>"`, "<&>", `"\u003c\u0026\u003e"`, `"<&>"`}, + { + "tagStruct", tagStruct, + `{"\u003c\u003e\u0026#! ":0,"Invalid":0}`, + `{"<>&#! ":0,"Invalid":0}`, + }, + { + `""`, marshalerStruct, + `{"NonPtr":"\u003cstr\u003e","Ptr":"\u003cstr\u003e"}`, + `{"NonPtr":"","Ptr":""}`, + }, + { + "stringOption", stringOption, + `{"bar":"\"\\u003chtml\\u003efoobar\\u003c/html\\u003e\""}`, + `{"bar":"\"foobar\""}`, + }, + } { + var buf bytes.Buffer + enc := json.NewEncoder(&buf) + if err := enc.Encode(tt.v); err != nil { + t.Errorf("Encode(%s): %s", tt.name, err) + continue + } + if got := strings.TrimSpace(buf.String()); got != tt.wantEscape { + t.Errorf("Encode(%s) = %#q, want %#q", tt.name, got, tt.wantEscape) + } + buf.Reset() + enc.SetEscapeHTML(false) + if err := enc.Encode(tt.v); err != nil { + t.Errorf("SetEscapeHTML(false) Encode(%s): %s", tt.name, err) + continue + } + if got := strings.TrimSpace(buf.String()); got != tt.want { + t.Errorf("SetEscapeHTML(false) Encode(%s) = %#q, want %#q", + tt.name, got, tt.want) + } + } +} + +func nlines(s string, n int) string { + if n <= 0 { + return "" + } + for i, c := range s { + if c == '\n' { + if n--; n == 0 { + return s[0 : i+1] + } + } + } + return s +} + +/* +func TestDecoder(t *testing.T) { + for i := 0; i <= len(streamTest); i++ { + // Use stream without newlines as input, + // just to stress the decoder even more. + // Our test input does not include back-to-back numbers. + // Otherwise stripping the newlines would + // merge two adjacent JSON values. + var buf bytes.Buffer + for _, c := range nlines(streamEncoded, i) { + if c != '\n' { + buf.WriteRune(c) + } + } + out := make([]interface{}, i) + dec := json.NewDecoder(&buf) + for j := range out { + if err := dec.Decode(&out[j]); err != nil { + t.Fatalf("decode #%d/%d: %v", j, i, err) + } + } + if !reflect.DeepEqual(out, streamTest[0:i]) { + t.Errorf("decoding %d items: mismatch", i) + for j := range out { + if !reflect.DeepEqual(out[j], streamTest[j]) { + t.Errorf("#%d: have %v want %v", j, out[j], streamTest[j]) + } + } + break + } + } +} + +func TestDecoderBuffered(t *testing.T) { + r := strings.NewReader(`{"Name": "Gopher"} extra `) + var m struct { + Name string + } + d := json.NewDecoder(r) + err := d.Decode(&m) + if err != nil { + t.Fatal(err) + } + if m.Name != "Gopher" { + t.Errorf("Name = %q; want Gopher", m.Name) + } + rest, err := ioutil.ReadAll(d.Buffered()) + if err != nil { + t.Fatal(err) + } + if g, w := string(rest), " extra "; g != w { + t.Errorf("Remaining = %q; want %q", g, w) + } +} + +func TestRawMessage(t *testing.T) { + var data struct { + X float64 + Id json.RawMessage + Y float32 + } + const raw = `["\u0056",null]` + const msg = `{"X":0.1,"Id":["\u0056",null],"Y":0.2}` + err := json.Unmarshal([]byte(msg), &data) + if err != nil { + t.Fatalf("Unmarshal: %v", err) + } + if string([]byte(data.Id)) != raw { + t.Fatalf("Raw mismatch: have %#q want %#q", []byte(data.Id), raw) + } + b, err := json.Marshal(&data) + if err != nil { + t.Fatalf("Marshal: %v", err) + } + if string(b) != msg { + t.Fatalf("Marshal: have %#q want %#q", b, msg) + } +} + +func TestNullRawMessage(t *testing.T) { + var data struct { + X float64 + Id json.RawMessage + IdPtr *json.RawMessage + Y float32 + } + const msg = `{"X":0.1,"Id":null,"IdPtr":null,"Y":0.2}` + err := json.Unmarshal([]byte(msg), &data) + if err != nil { + t.Fatalf("Unmarshal: %v", err) + } + if want, got := "null", string(data.Id); want != got { + t.Fatalf("Raw mismatch: have %q, want %q", got, want) + } + if data.IdPtr != nil { + t.Fatalf("Raw pointer mismatch: have non-nil, want nil") + } + b, err := json.Marshal(&data) + if err != nil { + t.Fatalf("Marshal: %v", err) + } + if string(b) != msg { + t.Fatalf("Marshal: have %#q want %#q", b, msg) + } +} + +var blockingTests = []string{ + `{"x": 1}`, + `[1, 2, 3]`, +} + +func TestBlocking(t *testing.T) { + for _, enc := range blockingTests { + r, w := net.Pipe() + go w.Write([]byte(enc)) + var val interface{} + + // If Decode reads beyond what w.Write writes above, + // it will block, and the test will deadlock. + if err := json.NewDecoder(r).Decode(&val); err != nil { + t.Errorf("decoding %s: %v", enc, err) + } + r.Close() + w.Close() + } +} + +type tokenStreamCase struct { + json string + expTokens []interface{} +} + +type decodeThis struct { + v interface{} +} + +var tokenStreamCases = []tokenStreamCase{ + // streaming token cases + {json: `10`, expTokens: []interface{}{float64(10)}}, + {json: ` [10] `, expTokens: []interface{}{ + json.Delim('['), float64(10), json.Delim(']')}}, + {json: ` [false,10,"b"] `, expTokens: []interface{}{ + json.Delim('['), false, float64(10), "b", json.Delim(']')}}, + {json: `{ "a": 1 }`, expTokens: []interface{}{ + json.Delim('{'), "a", float64(1), json.Delim('}')}}, + {json: `{"a": 1, "b":"3"}`, expTokens: []interface{}{ + json.Delim('{'), "a", float64(1), "b", "3", json.Delim('}')}}, + {json: ` [{"a": 1},{"a": 2}] `, expTokens: []interface{}{ + json.Delim('['), + json.Delim('{'), "a", float64(1), json.Delim('}'), + json.Delim('{'), "a", float64(2), json.Delim('}'), + json.Delim(']')}}, + {json: `{"obj": {"a": 1}}`, expTokens: []interface{}{ + json.Delim('{'), "obj", json.Delim('{'), "a", float64(1), json.Delim('}'), + json.Delim('}')}}, + {json: `{"obj": [{"a": 1}]}`, expTokens: []interface{}{ + json.Delim('{'), "obj", json.Delim('['), + json.Delim('{'), "a", float64(1), json.Delim('}'), + json.Delim(']'), json.Delim('}')}}, + + // streaming tokens with intermittent Decode() + {json: `{ "a": 1 }`, expTokens: []interface{}{ + json.Delim('{'), "a", + decodeThis{float64(1)}, + json.Delim('}')}}, + {json: ` [ { "a" : 1 } ] `, expTokens: []interface{}{ + json.Delim('['), + decodeThis{map[string]interface{}{"a": float64(1)}}, + json.Delim(']')}}, + {json: ` [{"a": 1},{"a": 2}] `, expTokens: []interface{}{ + json.Delim('['), + decodeThis{map[string]interface{}{"a": float64(1)}}, + decodeThis{map[string]interface{}{"a": float64(2)}}, + json.Delim(']')}}, + {json: `{ "obj" : [ { "a" : 1 } ] }`, expTokens: []interface{}{ + json.Delim('{'), "obj", json.Delim('['), + decodeThis{map[string]interface{}{"a": float64(1)}}, + json.Delim(']'), json.Delim('}')}}, + + {json: `{"obj": {"a": 1}}`, expTokens: []interface{}{ + json.Delim('{'), "obj", + decodeThis{map[string]interface{}{"a": float64(1)}}, + json.Delim('}')}}, + {json: `{"obj": [{"a": 1}]}`, expTokens: []interface{}{ + json.Delim('{'), "obj", + decodeThis{[]interface{}{ + map[string]interface{}{"a": float64(1)}, + }}, + json.Delim('}')}}, + {json: ` [{"a": 1} {"a": 2}] `, expTokens: []interface{}{ + json.Delim('['), + decodeThis{map[string]interface{}{"a": float64(1)}}, + decodeThis{json.NewSyntaxError("expected comma after array element", 11)}, + }}, + {json: `{ "` + strings.Repeat("a", 513) + `" 1 }`, expTokens: []interface{}{ + json.Delim('{'), strings.Repeat("a", 513), + decodeThis{json.NewSyntaxError("expected colon after object key", 518)}, + }}, + {json: `{ "\a" }`, expTokens: []interface{}{ + json.Delim('{'), + json.NewSyntaxError("invalid character 'a' in string escape code", 3), + }}, + {json: ` \a`, expTokens: []interface{}{ + json.NewSyntaxError("invalid character '\\\\' looking for beginning of value", 1), + }}, +} + +func TestDecodeInStream(t *testing.T) { + for ci, tcase := range tokenStreamCases { + + dec := json.NewDecoder(strings.NewReader(tcase.json)) + for i, etk := range tcase.expTokens { + + var tk interface{} + var err error + + if dt, ok := etk.(decodeThis); ok { + etk = dt.v + err = dec.Decode(&tk) + } else { + tk, err = dec.Token() + } + if experr, ok := etk.(error); ok { + if err == nil || !reflect.DeepEqual(err, experr) { + t.Errorf("case %v: Expected error %#v in %q, but was %#v", ci, experr, tcase.json, err) + } + break + } else if err == io.EOF { + t.Errorf("case %v: Unexpected EOF in %q", ci, tcase.json) + break + } else if err != nil { + t.Errorf("case %v: Unexpected error '%#v' in %q", ci, err, tcase.json) + break + } + if !reflect.DeepEqual(tk, etk) { + t.Errorf(`case %v: %q @ %v expected %T(%v) was %T(%v)`, ci, tcase.json, i, etk, etk, tk, tk) + break + } + } + } +} + +// Test from golang.org/issue/11893 +func TestHTTPDecoding(t *testing.T) { + const raw = `{ "foo": "bar" }` + + ts := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { + w.Write([]byte(raw)) + })) + defer ts.Close() + res, err := http.Get(ts.URL) + if err != nil { + log.Fatalf("GET failed: %v", err) + } + defer res.Body.Close() + + foo := struct { + Foo string + }{} + + d := json.NewDecoder(res.Body) + err = d.Decode(&foo) + if err != nil { + t.Fatalf("Decode: %v", err) + } + if foo.Foo != "bar" { + t.Errorf("decoded %q; want \"bar\"", foo.Foo) + } + + // make sure we get the EOF the second time + err = d.Decode(&foo) + if err != io.EOF { + t.Errorf("err = %v; want io.EOF", err) + } +} +*/ diff --git a/struct_field.go b/struct_field.go index bb822b3..6854548 100644 --- a/struct_field.go +++ b/struct_field.go @@ -3,6 +3,7 @@ package json import ( "reflect" "strings" + "unicode" ) func getTag(field reflect.StructField) string { @@ -46,13 +47,30 @@ func (t structTags) existsKey(key string) bool { return false } +func isValidTag(s string) bool { + if s == "" { + return false + } + for _, c := range s { + switch { + case strings.ContainsRune("!#$%&()*+-./:<=>?@[]^_{|}~ ", c): + // Backslash and quote chars are reserved, but + // otherwise any punctuation chars are allowed + // in a tag name. + case !unicode.IsLetter(c) && !unicode.IsDigit(c): + return false + } + } + return true +} + func structTagFromField(field reflect.StructField) *structTag { keyName := field.Name tag := getTag(field) st := &structTag{field: field} opts := strings.Split(tag, ",") if len(opts) > 0 { - if opts[0] != "" { + if opts[0] != "" && isValidTag(opts[0]) { keyName = opts[0] st.isTaggedKey = true }