Skip to content

Commit

Permalink
fix: Copy strings from tokens
Browse files Browse the repository at this point in the history
  • Loading branch information
romshark committed Mar 6, 2024
1 parent 3ca437c commit 921011a
Show file tree
Hide file tree
Showing 3 changed files with 11 additions and 13 deletions.
16 changes: 9 additions & 7 deletions internal/unescape/unescape.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,22 +8,24 @@ import (
// Valid returns the unescaped version of str relying on str to be valid.
// Don't use this function if str isn't guaranteed to contain no
// invalid escape sequences.
func Valid[S ~[]byte | ~string, O ~[]byte | ~string](str S) O {
func Valid[S []byte | string, O []byte | string](str S) O {
var oz O
if len(str) < 1 {
return oz
}

// Copy the string because it probably originates from a token
// which will be reused across Decode calls.
var s string
switch in := any(str).(type) {
case string:
s = in
cp := unsafe.Slice(unsafe.StringData(in), len(in))
copy(cp, in)
s = unsafe.String(unsafe.SliceData(cp), len(in))
case []byte:
// Avoid copying str to a string, treat the bytes as read-only instead
// since str is guaranteed to remain immutable.
s = unsafe.String(unsafe.SliceData(in), len(in))
default:
s = string(str)
s = string(in)
}

i := strings.IndexByte(s, '\\')
if i < 0 {
return O(s)
Expand Down
6 changes: 1 addition & 5 deletions internal/unescape/unescape_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -116,7 +116,7 @@ var tests = []test{
}(),
}

func runTestValid[S ~[]byte | ~string, O ~[]byte | ~string](
func runTestValid[S []byte | string, O []byte | string](
t *testing.T, name string, input S, expect O,
) {
t.Run(name, func(t *testing.T) {
Expand All @@ -138,7 +138,6 @@ func runTestValid[S ~[]byte | ~string, O ~[]byte | ~string](
}

func TestValid(t *testing.T) {
type CustomString string
for _, td := range tests {
runTestValid[string, string](
t, td.Name+"/string2string", td.Input, td.Expect,
Expand All @@ -152,9 +151,6 @@ func TestValid(t *testing.T) {
runTestValid[[]byte, string](
t, td.Name+"/bytes2string", []byte(td.Input), td.Expect,
)
runTestValid[CustomString, CustomString](
t, td.Name+"/bytes2string", CustomString(td.Input), CustomString(td.Expect),
)
}
}

Expand Down
2 changes: 1 addition & 1 deletion jscandec.go
Original file line number Diff line number Diff line change
Expand Up @@ -3524,7 +3524,7 @@ func fieldFrameIndexByName[S []byte | string](fields []fieldStackFrame, name S)
return noParentFrame
}

func decodeAny[S ~[]byte | ~string](
func decodeAny[S []byte | string](
str S, tokens []jscan.Token[S],
) (any, []jscan.Token[S], error) {
switch tokens[0].Type {
Expand Down

0 comments on commit 921011a

Please sign in to comment.