@@ -254,7 +254,9 @@ func builtinStringReplace(call FunctionCall) Value {
254
254
argumentList [index ] = Value {}
255
255
}
256
256
}
257
- argumentList [matchCount + 0 ] = intValue (match [0 ])
257
+ // Replace expects rune offsets not byte offsets.
258
+ startIndex := utf8 .RuneCountInString (target [0 :match [0 ]])
259
+ argumentList [matchCount + 0 ] = intValue (startIndex )
258
260
argumentList [matchCount + 1 ] = stringValue (target )
259
261
replacement := replace .call (Value {}, argumentList , false , nativeFrame ).string ()
260
262
result = append (result , []byte (replacement )... )
@@ -394,16 +396,18 @@ func builtinStringSplit(call FunctionCall) Value {
394
396
}
395
397
}
396
398
399
+ // builtinStringSlice returns the string sliced by the given values
400
+ // which are rune not byte offsets, as per String.prototype.slice.
397
401
func builtinStringSlice (call FunctionCall ) Value {
398
402
checkObjectCoercible (call .runtime , call .This )
399
- target := call .This .string ()
403
+ target := [] rune ( call .This .string () )
400
404
401
405
length := int64 (len (target ))
402
406
start , end := rangeStartEnd (call .ArgumentList , length , false )
403
407
if end - start <= 0 {
404
408
return stringValue ("" )
405
409
}
406
- return stringValue (target [start :end ])
410
+ return stringValue (string ( target [start :end ]) )
407
411
}
408
412
409
413
func builtinStringSubstring (call FunctionCall ) Value {
0 commit comments