Skip to content

Commit 14f6746

Browse files
authored
validate offset on empty-string path in indexOf and lastIndexOf (#1335)
* validate offset on empty-string path in indexOf and lastIndexOf * clamp empty-string offset to string length in indexOf and lastIndexOf --------- Co-authored-by: alhudz <al.hudz.k@gmail.com>
1 parent 783267d commit 14f6746

2 files changed

Lines changed: 30 additions & 10 deletions

File tree

ext/strings.go

Lines changed: 18 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -663,15 +663,19 @@ func indexOf(str, substr string) (int64, error) {
663663
}
664664

665665
func indexOfOffset(str, substr string, offset int64) (int64, error) {
666-
if substr == "" {
667-
return offset, nil
668-
}
669666
off := int(offset)
670-
runes := []rune(str)
671-
subrunes := []rune(substr)
672667
if off < 0 {
673668
return -1, fmt.Errorf("index out of range: %d", off)
674669
}
670+
runes := []rune(str)
671+
if substr == "" {
672+
// The empty string matches at the search offset, clamped to the end of the string.
673+
if off > len(runes) {
674+
return int64(len(runes)), nil
675+
}
676+
return offset, nil
677+
}
678+
subrunes := []rune(substr)
675679
// If the offset exceeds the length, return -1 rather than error.
676680
if off >= len(runes) {
677681
return -1, nil
@@ -704,15 +708,19 @@ func lastIndexOf(str, substr string) (int64, error) {
704708
}
705709

706710
func lastIndexOfOffset(str, substr string, offset int64) (int64, error) {
707-
if substr == "" {
708-
return offset, nil
709-
}
710711
off := int(offset)
711-
runes := []rune(str)
712-
subrunes := []rune(substr)
713712
if off < 0 {
714713
return -1, fmt.Errorf("index out of range: %d", off)
715714
}
715+
runes := []rune(str)
716+
if substr == "" {
717+
// The empty string matches at the search offset, clamped to the end of the string.
718+
if off > len(runes) {
719+
return int64(len(runes)), nil
720+
}
721+
return offset, nil
722+
}
723+
subrunes := []rune(substr)
716724
// If the offset is far greater than the length return -1
717725
if off >= len(runes) {
718726
return -1, nil

ext/strings_test.go

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -146,11 +146,23 @@ var stringTests = []struct {
146146
err: "index out of range: 30",
147147
},
148148
{expr: `'tacocat'.indexOf('a', 30) == -1`},
149+
{expr: `'tacocat'.indexOf('', 7) == 7`},
150+
{expr: `'tacocat'.indexOf('', 30) == 7`},
151+
{
152+
expr: `'tacocat'.indexOf('', -1) == 0`,
153+
err: "index out of range: -1",
154+
},
149155
{
150156
expr: `'tacocat'.lastIndexOf('a', -1) == -1`,
151157
err: "index out of range: -1",
152158
},
153159
{expr: `'tacocat'.lastIndexOf('a', 30) == -1`},
160+
{expr: `'tacocat'.lastIndexOf('', 7) == 7`},
161+
{expr: `'tacocat'.lastIndexOf('', 30) == 7`},
162+
{
163+
expr: `'tacocat'.lastIndexOf('', -1) == 0`,
164+
err: "index out of range: -1",
165+
},
154166
{
155167
expr: `"tacocat".substring(40) == "cat"`,
156168
err: "index out of range: 40",

0 commit comments

Comments
 (0)