From 8495668019501f68221a96cf4d6de01e8a2bb1af Mon Sep 17 00:00:00 2001 From: Jens Neuse Date: Tue, 29 Oct 2024 20:48:15 +0100 Subject: [PATCH 1/2] feat: unescape strings on parse to remove race --- arena.go | 6 ++++-- parser.go | 15 ++------------- 2 files changed, 6 insertions(+), 15 deletions(-) diff --git a/arena.go b/arena.go index a6665ca..fc3b600 100644 --- a/arena.go +++ b/arena.go @@ -57,10 +57,11 @@ func (a *Arena) NewArray() *Value { // The returned string is valid until Reset is called on a. func (a *Arena) NewString(s string) *Value { v := a.c.getValue() - v.t = typeRawString + v.t = TypeString bLen := len(a.b) a.b = escapeString(a.b, s) v.s = b2s(a.b[bLen+1 : len(a.b)-1]) + v.s = unescapeStringBestEffort(v.s) return v } @@ -69,10 +70,11 @@ func (a *Arena) NewString(s string) *Value { // The returned string is valid until Reset is called on a. func (a *Arena) NewStringBytes(b []byte) *Value { v := a.c.getValue() - v.t = typeRawString + v.t = TypeString bLen := len(a.b) a.b = escapeString(a.b, b2s(b)) v.s = b2s(a.b[bLen+1 : len(a.b)-1]) + v.s = unescapeStringBestEffort(v.s) return v } diff --git a/parser.go b/parser.go index cacf23d..841d345 100644 --- a/parser.go +++ b/parser.go @@ -131,8 +131,8 @@ func parseValue(s string, c *cache, depth int) (*Value, string, error) { return nil, tail, fmt.Errorf("cannot parse string: %s", err) } v := c.getValue() - v.t = typeRawString - v.s = ss + v.t = TypeString + v.s = unescapeStringBestEffort(ss) return v, tail, nil } if s[0] == 't' { @@ -618,11 +618,6 @@ type Value struct { // MarshalTo appends marshaled v to dst and returns the result. func (v *Value) MarshalTo(dst []byte) []byte { switch v.t { - case typeRawString: - dst = append(dst, '"') - dst = append(dst, v.s...) - dst = append(dst, '"') - return dst case TypeObject: return v.o.MarshalTo(dst) case TypeArray: @@ -688,8 +683,6 @@ const ( // TypeFalse is JSON false. TypeFalse Type = 6 - - typeRawString Type = 7 ) // String returns string representation of t. @@ -719,10 +712,6 @@ func (t Type) String() string { // Type returns the type of the v. func (v *Value) Type() Type { - if v.t == typeRawString { - v.s = unescapeStringBestEffort(v.s) - v.t = TypeString - } return v.t } From 6c05ee12f1e05eaf0051ca3ea9cccdebdc9cc160 Mon Sep 17 00:00:00 2001 From: Jens Neuse Date: Tue, 29 Oct 2024 21:08:26 +0100 Subject: [PATCH 2/2] chore: ignore lint --- parser.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/parser.go b/parser.go index 841d345..e498fc0 100644 --- a/parser.go +++ b/parser.go @@ -326,7 +326,7 @@ func escapeStringSlowPath(dst []byte, s string) []byte { dst = append(dst, []byte{'\\', 'u', '0', '0', '0', 0x57 + c}...) case c < 0x1a: dst = append(dst, []byte{'\\', 'u', '0', '0', '1', 0x20 + c}...) - case c < 0x20: + case c < 0x20: // lint:ignore dst = append(dst, []byte{'\\', 'u', '0', '0', '1', 0x47 + c}...) } }