@@ -21,7 +21,6 @@ import (
2121 "encoding/json"
2222 "reflect"
2323 "runtime"
24- "unsafe"
2524
2625 "github.com/bytedance/sonic/utf8"
2726 "github.com/bytedance/sonic/internal/encoder/alg"
@@ -181,16 +180,7 @@ func Encode(val interface{}, opts Options) ([]byte, error) {
181180 }
182181
183182 /* htmlescape or correct UTF-8 if opts enable */
184- old := buf
185- * buf = encodeFinish (* old , opts )
186- pbuf := ((* rt .GoSlice )(unsafe .Pointer (buf ))).Ptr
187- pold := ((* rt .GoSlice )(unsafe .Pointer (old ))).Ptr
188-
189- /* return when allocated a new buffer */
190- if pbuf != pold {
191- vars .FreeBytes (old )
192- return * buf , nil
193- }
183+ encodeFinishWithPool (buf , opts )
194184
195185 /* make a copy of the result */
196186 if rt .CanSizeResue (cap (* buf )) {
@@ -243,6 +233,20 @@ func encodeFinish(buf []byte, opts Options) []byte {
243233 return buf
244234}
245235
236+ func encodeFinishWithPool (buf * []byte , opts Options ) {
237+ if opts & EscapeHTML != 0 {
238+ dst := vars .NewBytes ()
239+ // put the result bytes to buf and the old buf to dst to return to the pool.
240+ // we cannot return buf to the pool because it will be used by the caller.
241+ * buf , * dst = HTMLEscape (* dst , * buf ), * buf
242+ vars .FreeBytes (dst )
243+ }
244+ if (opts & ValidateString != 0 ) && ! utf8 .Validate (* buf ) {
245+ dst := vars .NewBytes ()
246+ * buf , * dst = utf8 .CorrectWith (* dst , * buf , `\ufffd` ), * buf
247+ vars .FreeBytes (dst )
248+ }
249+ }
246250
247251// HTMLEscape appends to dst the JSON-encoded src with <, >, &, U+2028 and U+2029
248252// characters inside string literals changed to \u003c, \u003e, \u0026, \u2028, \u2029
0 commit comments