Skip to content

Commit 72bd4ca

Browse files
authored
feature: use pool for EscapeHTML (bytedance#866)
1 parent 48ba40b commit 72bd4ca

1 file changed

Lines changed: 15 additions & 11 deletions

File tree

internal/encoder/encoder.go

Lines changed: 15 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -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

Comments
 (0)