From 84c8b8467189067e48c8aaf2f1839df710faaee5 Mon Sep 17 00:00:00 2001 From: Masaaki Goshima Date: Sat, 30 Jan 2021 01:14:22 +0900 Subject: [PATCH] Fix encoding of type which implemented MarshalJSON --- encode_vm.go | 81 +++++++++++++++++++++---------------- encode_vm_escaped.go | 63 +++++++++++++++-------------- encode_vm_escaped_indent.go | 76 ++++++++++++++++++++++++++-------- encode_vm_indent.go | 75 ++++++++++++++++++++++++++-------- 4 files changed, 195 insertions(+), 100 deletions(-) diff --git a/encode_vm.go b/encode_vm.go index 3f08600..8f78dd8 100644 --- a/encode_vm.go +++ b/encode_vm.go @@ -268,11 +268,13 @@ func (e *Encoder) run(ctx *encodeRuntimeContext, b []byte, codeSet *opcodeSet) ( 0, ) } - var buf bytes.Buffer - if err := compact(&buf, bb, e.enabledHTMLEscape); err != nil { + buf := bytes.NewBuffer(b) + //TODO: we should validate buffer with `compact` + if err := compact(buf, bb, false); err != nil { return nil, err } - b = append(append(b, buf.Bytes()...), ',') + b = buf.Bytes() + b = encodeComma(b) code = code.next case opMarshalText: ptr := load(ctxptr, code.idx) @@ -6632,11 +6634,12 @@ func (e *Encoder) run(ctx *encodeRuntimeContext, b []byte, codeSet *opcodeSet) ( 0, ) } - var buf bytes.Buffer - if err := compact(&buf, bb, e.enabledHTMLEscape); err != nil { + buf := bytes.NewBuffer(b) + //TODO: we should validate buffer with `compact` + if err := compact(buf, bb, false); err != nil { return nil, err } - b = append(b, buf.Bytes()...) + b = buf.Bytes() b = encodeComma(b) code = code.next } @@ -6667,11 +6670,12 @@ func (e *Encoder) run(ctx *encodeRuntimeContext, b []byte, codeSet *opcodeSet) ( 0, ) } - var buf bytes.Buffer - if err := compact(&buf, bb, e.enabledHTMLEscape); err != nil { + buf := bytes.NewBuffer(b) + //TODO: we should validate buffer with `compact` + if err := compact(buf, bb, false); err != nil { return nil, err } - b = append(b, buf.Bytes()...) + b = buf.Bytes() b = encodeComma(b) code = code.next } @@ -6864,12 +6868,13 @@ func (e *Encoder) run(ctx *encodeRuntimeContext, b []byte, codeSet *opcodeSet) ( } code = code.nextField } else { - var buf bytes.Buffer - if err := compact(&buf, bb, e.enabledHTMLEscape); err != nil { + b = append(b, code.key...) + buf := bytes.NewBuffer(b) + //TODO: we should validate buffer with `compact` + if err := compact(buf, bb, false); err != nil { return nil, err } - b = append(b, code.key...) - b = append(b, buf.Bytes()...) + b = buf.Bytes() b = encodeComma(b) code = code.next } @@ -6909,12 +6914,13 @@ func (e *Encoder) run(ctx *encodeRuntimeContext, b []byte, codeSet *opcodeSet) ( } code = code.nextField } else { - var buf bytes.Buffer - if err := compact(&buf, bb, e.enabledHTMLEscape); err != nil { + b = append(b, code.key...) + buf := bytes.NewBuffer(b) + //TODO: we should validate buffer with `compact` + if err := compact(buf, bb, false); err != nil { return nil, err } - b = append(b, code.key...) - b = append(b, buf.Bytes()...) + b = buf.Bytes() b = encodeComma(b) code = code.next } @@ -7131,9 +7137,10 @@ func (e *Encoder) run(ctx *encodeRuntimeContext, b []byte, codeSet *opcodeSet) ( code = code.nextField } else { var buf bytes.Buffer - if err := compact(&buf, bb, e.enabledHTMLEscape); err != nil { + if err := compact(&buf, bb, false); err != nil { return nil, err } + b = append(b, code.key...) b = encodeNoEscapedString(b, buf.String()) b = encodeComma(b) code = code.next @@ -7174,7 +7181,7 @@ func (e *Encoder) run(ctx *encodeRuntimeContext, b []byte, codeSet *opcodeSet) ( code = code.nextField } else { var buf bytes.Buffer - if err := compact(&buf, bb, e.enabledHTMLEscape); err != nil { + if err := compact(&buf, bb, false); err != nil { return nil, err } b = append(b, code.key...) @@ -7818,11 +7825,12 @@ func (e *Encoder) run(ctx *encodeRuntimeContext, b []byte, codeSet *opcodeSet) ( if err != nil { return nil, errMarshaler(code, err) } - var buf bytes.Buffer - if err := compact(&buf, bb, e.enabledHTMLEscape); err != nil { + buf := bytes.NewBuffer(b) + //TODO: we should validate buffer with `compact` + if err := compact(buf, bb, false); err != nil { return nil, err } - b = append(b, buf.Bytes()...) + b = buf.Bytes() b = encodeComma(b) code = code.next case opStructFieldStringTagMarshalJSON: @@ -7834,7 +7842,7 @@ func (e *Encoder) run(ctx *encodeRuntimeContext, b []byte, codeSet *opcodeSet) ( return nil, errMarshaler(code, err) } var buf bytes.Buffer - if err := compact(&buf, bb, e.enabledHTMLEscape); err != nil { + if err := compact(&buf, bb, false); err != nil { return nil, err } b = append(b, code.key...) @@ -7853,12 +7861,13 @@ func (e *Encoder) run(ctx *encodeRuntimeContext, b []byte, codeSet *opcodeSet) ( if err != nil { return nil, errMarshaler(code, err) } - var buf bytes.Buffer - if err := compact(&buf, bb, e.enabledHTMLEscape); err != nil { + b = append(b, code.key...) + buf := bytes.NewBuffer(b) + //TODO: we should validate buffer with `compact` + if err := compact(buf, bb, false); err != nil { return nil, err } - b = append(b, code.key...) - b = append(b, buf.Bytes()...) + b = buf.Bytes() b = encodeComma(b) } code = code.next @@ -9258,11 +9267,12 @@ func (e *Encoder) run(ctx *encodeRuntimeContext, b []byte, codeSet *opcodeSet) ( if err != nil { return nil, errMarshaler(code, err) } - var buf bytes.Buffer - if err := compact(&buf, bb, e.enabledHTMLEscape); err != nil { + buf := bytes.NewBuffer(b) + //TODO: we should validate buffer with `compact` + if err := compact(buf, bb, false); err != nil { return nil, err } - b = append(b, buf.Bytes()...) + b = buf.Bytes() b = appendStructEnd(b) code = code.next case opStructEndOmitEmptyMarshalJSON: @@ -9274,12 +9284,13 @@ func (e *Encoder) run(ctx *encodeRuntimeContext, b []byte, codeSet *opcodeSet) ( if err != nil { return nil, errMarshaler(code, err) } - var buf bytes.Buffer - if err := compact(&buf, bb, e.enabledHTMLEscape); err != nil { + b = append(b, code.key...) + buf := bytes.NewBuffer(b) + //TODO: we should validate buffer with `compact` + if err := compact(buf, bb, false); err != nil { return nil, err } - b = append(b, code.key...) - b = append(b, buf.Bytes()...) + b = buf.Bytes() b = appendStructEnd(b) } else { last := len(b) - 1 @@ -9300,7 +9311,7 @@ func (e *Encoder) run(ctx *encodeRuntimeContext, b []byte, codeSet *opcodeSet) ( return nil, errMarshaler(code, err) } var buf bytes.Buffer - if err := compact(&buf, bb, e.enabledHTMLEscape); err != nil { + if err := compact(&buf, bb, false); err != nil { return nil, err } b = append(b, code.key...) diff --git a/encode_vm_escaped.go b/encode_vm_escaped.go index 8085891..78cd64e 100644 --- a/encode_vm_escaped.go +++ b/encode_vm_escaped.go @@ -231,11 +231,12 @@ func (e *Encoder) runEscaped(ctx *encodeRuntimeContext, b []byte, codeSet *opcod 0, ) } - var buf bytes.Buffer - if err := compact(&buf, bb, e.enabledHTMLEscape); err != nil { + buf := bytes.NewBuffer(b) + if err := compact(buf, bb, true); err != nil { return nil, err } - b = append(append(b, buf.Bytes()...), ',') + b = buf.Bytes() + b = encodeComma(b) code = code.next case opMarshalText: ptr := load(ctxptr, code.idx) @@ -6599,11 +6600,11 @@ func (e *Encoder) runEscaped(ctx *encodeRuntimeContext, b []byte, codeSet *opcod 0, ) } - var buf bytes.Buffer - if err := compact(&buf, bb, e.enabledHTMLEscape); err != nil { + buf := bytes.NewBuffer(b) + if err := compact(buf, bb, true); err != nil { return nil, err } - b = append(b, buf.Bytes()...) + b = buf.Bytes() b = encodeComma(b) code = code.next } @@ -6634,11 +6635,11 @@ func (e *Encoder) runEscaped(ctx *encodeRuntimeContext, b []byte, codeSet *opcod 0, ) } - var buf bytes.Buffer - if err := compact(&buf, bb, e.enabledHTMLEscape); err != nil { + buf := bytes.NewBuffer(b) + if err := compact(buf, bb, true); err != nil { return nil, err } - b = append(b, buf.Bytes()...) + b = buf.Bytes() b = encodeComma(b) code = code.next } @@ -6831,12 +6832,12 @@ func (e *Encoder) runEscaped(ctx *encodeRuntimeContext, b []byte, codeSet *opcod } code = code.nextField } else { - var buf bytes.Buffer - if err := compact(&buf, bb, e.enabledHTMLEscape); err != nil { + b = append(b, code.escapedKey...) + buf := bytes.NewBuffer(b) + if err := compact(buf, bb, true); err != nil { return nil, err } - b = append(b, code.escapedKey...) - b = append(b, buf.Bytes()...) + b = buf.Bytes() b = encodeComma(b) code = code.next } @@ -6876,12 +6877,12 @@ func (e *Encoder) runEscaped(ctx *encodeRuntimeContext, b []byte, codeSet *opcod } code = code.nextField } else { - var buf bytes.Buffer - if err := compact(&buf, bb, e.enabledHTMLEscape); err != nil { + b = append(b, code.escapedKey...) + buf := bytes.NewBuffer(b) + if err := compact(buf, bb, true); err != nil { return nil, err } - b = append(b, code.escapedKey...) - b = append(b, buf.Bytes()...) + b = buf.Bytes() b = encodeComma(b) code = code.next } @@ -7804,11 +7805,11 @@ func (e *Encoder) runEscaped(ctx *encodeRuntimeContext, b []byte, codeSet *opcod if err != nil { return nil, errMarshaler(code, err) } - var buf bytes.Buffer - if err := compact(&buf, bb, e.enabledHTMLEscape); err != nil { + buf := bytes.NewBuffer(b) + if err := compact(buf, bb, true); err != nil { return nil, err } - b = append(b, buf.Bytes()...) + b = buf.Bytes() b = encodeComma(b) code = code.next case opStructFieldOmitEmptyMarshalJSON: @@ -7823,12 +7824,12 @@ func (e *Encoder) runEscaped(ctx *encodeRuntimeContext, b []byte, codeSet *opcod if err != nil { return nil, errMarshaler(code, err) } - var buf bytes.Buffer - if err := compact(&buf, bb, e.enabledHTMLEscape); err != nil { + b = append(b, code.escapedKey...) + buf := bytes.NewBuffer(b) + if err := compact(buf, bb, true); err != nil { return nil, err } - b = append(b, code.escapedKey...) - b = append(b, buf.Bytes()...) + b = buf.Bytes() b = encodeComma(b) } code = code.next @@ -9244,11 +9245,11 @@ func (e *Encoder) runEscaped(ctx *encodeRuntimeContext, b []byte, codeSet *opcod if err != nil { return nil, errMarshaler(code, err) } - var buf bytes.Buffer - if err := compact(&buf, bb, e.enabledHTMLEscape); err != nil { + buf := bytes.NewBuffer(b) + if err := compact(buf, bb, true); err != nil { return nil, err } - b = append(b, buf.Bytes()...) + b = buf.Bytes() b = appendStructEnd(b) code = code.next case opStructEndOmitEmptyMarshalJSON: @@ -9260,12 +9261,12 @@ func (e *Encoder) runEscaped(ctx *encodeRuntimeContext, b []byte, codeSet *opcod if err != nil { return nil, errMarshaler(code, err) } - var buf bytes.Buffer - if err := compact(&buf, bb, e.enabledHTMLEscape); err != nil { + b = append(b, code.escapedKey...) + buf := bytes.NewBuffer(b) + if err := compact(buf, bb, true); err != nil { return nil, err } - b = append(b, code.escapedKey...) - b = append(b, buf.Bytes()...) + b = buf.Bytes() b = appendStructEnd(b) } else { last := len(b) - 1 diff --git a/encode_vm_escaped_indent.go b/encode_vm_escaped_indent.go index a11a7fa..98bff40 100644 --- a/encode_vm_escaped_indent.go +++ b/encode_vm_escaped_indent.go @@ -8,6 +8,7 @@ import ( "reflect" "runtime" "sort" + "strings" "unsafe" ) @@ -232,16 +233,20 @@ func (e *Encoder) runEscapedIndent(ctx *encodeRuntimeContext, b []byte, codeSet 0, ) } - var buf bytes.Buffer + var compactBuf bytes.Buffer + if err := compact(&compactBuf, bb, true); err != nil { + return nil, err + } + var indentBuf bytes.Buffer if err := encodeWithIndent( - &buf, - bb, - string(e.prefix)+string(bytes.Repeat(e.indentStr, e.baseIndent+code.indent)), + &indentBuf, + compactBuf.Bytes(), + string(e.prefix)+strings.Repeat(string(e.indentStr), e.baseIndent+code.indent), string(e.indentStr), ); err != nil { return nil, err } - b = append(b, buf.Bytes()...) + b = append(b, indentBuf.Bytes()...) b = encodeIndentComma(b) code = code.next case opMarshalText: @@ -7619,11 +7624,20 @@ func (e *Encoder) runEscapedIndent(ctx *encodeRuntimeContext, b []byte, codeSet if err != nil { return nil, errMarshaler(code, err) } - var buf bytes.Buffer - if err := compact(&buf, bb, e.enabledHTMLEscape); err != nil { + var compactBuf bytes.Buffer + if err := compact(&compactBuf, bb, true); err != nil { return nil, err } - b = append(b, buf.Bytes()...) + var indentBuf bytes.Buffer + if err := encodeWithIndent( + &indentBuf, + compactBuf.Bytes(), + string(e.prefix)+strings.Repeat(string(e.indentStr), e.baseIndent+code.indent), + string(e.indentStr), + ); err != nil { + return nil, err + } + b = append(b, indentBuf.Bytes()...) b = encodeIndentComma(b) code = code.next case opStructFieldStringTagMarshalJSON: @@ -7637,11 +7651,21 @@ func (e *Encoder) runEscapedIndent(ctx *encodeRuntimeContext, b []byte, codeSet if err != nil { return nil, errMarshaler(code, err) } - var buf bytes.Buffer - if err := compact(&buf, bb, e.enabledHTMLEscape); err != nil { + var compactBuf bytes.Buffer + if err := compact(&compactBuf, bb, true); err != nil { return nil, err } - b = encodeEscapedString(b, buf.String()) + var indentBuf bytes.Buffer + if err := encodeWithIndent( + &indentBuf, + compactBuf.Bytes(), + string(e.prefix)+strings.Repeat(string(e.indentStr), e.baseIndent+code.indent), + string(e.indentStr), + ); err != nil { + return nil, err + } + b = append(b, indentBuf.Bytes()...) + b = encodeEscapedString(b, indentBuf.String()) b = encodeIndentComma(b) code = code.next case opStructFieldStringTagMarshalText: @@ -9189,11 +9213,20 @@ func (e *Encoder) runEscapedIndent(ctx *encodeRuntimeContext, b []byte, codeSet if err != nil { return nil, errMarshaler(code, err) } - var buf bytes.Buffer - if err := compact(&buf, bb, e.enabledHTMLEscape); err != nil { + var compactBuf bytes.Buffer + if err := compact(&compactBuf, bb, true); err != nil { return nil, err } - b = append(b, buf.Bytes()...) + var indentBuf bytes.Buffer + if err := encodeWithIndent( + &indentBuf, + compactBuf.Bytes(), + string(e.prefix)+strings.Repeat(string(e.indentStr), e.baseIndent+code.indent), + string(e.indentStr), + ); err != nil { + return nil, err + } + b = append(b, indentBuf.Bytes()...) b = e.appendStructEndIndent(b, code.indent-1) code = code.next case opStructEndStringTagMarshalJSON: @@ -9207,11 +9240,20 @@ func (e *Encoder) runEscapedIndent(ctx *encodeRuntimeContext, b []byte, codeSet if err != nil { return nil, errMarshaler(code, err) } - var buf bytes.Buffer - if err := compact(&buf, bb, e.enabledHTMLEscape); err != nil { + var compactBuf bytes.Buffer + if err := compact(&compactBuf, bb, true); err != nil { return nil, err } - b = encodeEscapedString(b, buf.String()) + var indentBuf bytes.Buffer + if err := encodeWithIndent( + &indentBuf, + compactBuf.Bytes(), + string(e.prefix)+strings.Repeat(string(e.indentStr), e.baseIndent+code.indent), + string(e.indentStr), + ); err != nil { + return nil, err + } + b = encodeEscapedString(b, indentBuf.String()) b = e.appendStructEndIndent(b, code.indent-1) code = code.next case opStructEndStringTagMarshalText: diff --git a/encode_vm_indent.go b/encode_vm_indent.go index 4800085..ec31248 100644 --- a/encode_vm_indent.go +++ b/encode_vm_indent.go @@ -8,6 +8,7 @@ import ( "reflect" "runtime" "sort" + "strings" "unsafe" ) @@ -232,16 +233,20 @@ func (e *Encoder) runIndent(ctx *encodeRuntimeContext, b []byte, codeSet *opcode 0, ) } - var buf bytes.Buffer + var compactBuf bytes.Buffer + if err := compact(&compactBuf, bb, false); err != nil { + return nil, err + } + var indentBuf bytes.Buffer if err := encodeWithIndent( - &buf, - bb, - string(e.prefix)+string(bytes.Repeat(e.indentStr, e.baseIndent+code.indent)), + &indentBuf, + compactBuf.Bytes(), + string(e.prefix)+strings.Repeat(string(e.indentStr), e.baseIndent+code.indent), string(e.indentStr), ); err != nil { return nil, err } - b = append(b, buf.Bytes()...) + b = append(b, indentBuf.Bytes()...) b = encodeIndentComma(b) code = code.next case opMarshalText: @@ -7619,11 +7624,20 @@ func (e *Encoder) runIndent(ctx *encodeRuntimeContext, b []byte, codeSet *opcode if err != nil { return nil, errMarshaler(code, err) } - var buf bytes.Buffer - if err := compact(&buf, bb, e.enabledHTMLEscape); err != nil { + var compactBuf bytes.Buffer + if err := compact(&compactBuf, bb, false); err != nil { return nil, err } - b = append(b, buf.Bytes()...) + var indentBuf bytes.Buffer + if err := encodeWithIndent( + &indentBuf, + compactBuf.Bytes(), + string(e.prefix)+strings.Repeat(string(e.indentStr), e.baseIndent+code.indent), + string(e.indentStr), + ); err != nil { + return nil, err + } + b = append(b, indentBuf.Bytes()...) b = encodeIndentComma(b) code = code.next case opStructFieldStringTagMarshalJSON: @@ -7637,11 +7651,20 @@ func (e *Encoder) runIndent(ctx *encodeRuntimeContext, b []byte, codeSet *opcode if err != nil { return nil, errMarshaler(code, err) } - var buf bytes.Buffer - if err := compact(&buf, bb, e.enabledHTMLEscape); err != nil { + var compactBuf bytes.Buffer + if err := compact(&compactBuf, bb, false); err != nil { return nil, err } - b = encodeNoEscapedString(b, buf.String()) + var indentBuf bytes.Buffer + if err := encodeWithIndent( + &indentBuf, + compactBuf.Bytes(), + string(e.prefix)+strings.Repeat(string(e.indentStr), e.baseIndent+code.indent), + string(e.indentStr), + ); err != nil { + return nil, err + } + b = encodeNoEscapedString(b, indentBuf.String()) b = encodeIndentComma(b) code = code.next case opStructFieldStringTagMarshalText: @@ -9189,11 +9212,20 @@ func (e *Encoder) runIndent(ctx *encodeRuntimeContext, b []byte, codeSet *opcode if err != nil { return nil, errMarshaler(code, err) } - var buf bytes.Buffer - if err := compact(&buf, bb, e.enabledHTMLEscape); err != nil { + var compactBuf bytes.Buffer + if err := compact(&compactBuf, bb, false); err != nil { return nil, err } - b = append(b, buf.Bytes()...) + var indentBuf bytes.Buffer + if err := encodeWithIndent( + &indentBuf, + compactBuf.Bytes(), + string(e.prefix)+strings.Repeat(string(e.indentStr), e.baseIndent+code.indent), + string(e.indentStr), + ); err != nil { + return nil, err + } + b = append(b, indentBuf.Bytes()...) b = e.appendStructEndIndent(b, code.indent-1) code = code.next case opStructEndStringTagMarshalJSON: @@ -9207,11 +9239,20 @@ func (e *Encoder) runIndent(ctx *encodeRuntimeContext, b []byte, codeSet *opcode if err != nil { return nil, errMarshaler(code, err) } - var buf bytes.Buffer - if err := compact(&buf, bb, e.enabledHTMLEscape); err != nil { + var compactBuf bytes.Buffer + if err := compact(&compactBuf, bb, false); err != nil { return nil, err } - b = encodeNoEscapedString(b, buf.String()) + var indentBuf bytes.Buffer + if err := encodeWithIndent( + &indentBuf, + compactBuf.Bytes(), + string(e.prefix)+strings.Repeat(string(e.indentStr), e.baseIndent+code.indent), + string(e.indentStr), + ); err != nil { + return nil, err + } + b = encodeNoEscapedString(b, indentBuf.String()) b = e.appendStructEndIndent(b, code.indent-1) code = code.next case opStructEndStringTagMarshalText: