Skip to content

Commit ba36ff8

Browse files
authoredOct 28, 2024
Fix out of range error for non-negative string indexing offsets (#1052)
* Fix out of range error for non-negative offsets * Update docs and failing conformance test
1 parent 3338c3f commit ba36ff8

File tree

4 files changed

+21
-12
lines changed

4 files changed

+21
-12
lines changed
 

‎conformance/BUILD.bazel

+3
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,9 @@ _TESTS_TO_SKIP = [
4747
"macros/map/map_extract_keys",
4848
"timestamps/duration_converters/get_milliseconds",
4949

50+
# Temporarily failing tests, need a spec update
51+
"string_ext/value_errors/indexof_out_of_range,lastindexof_out_of_range",
52+
5053
# Future enhancments.
5154
"enums/strong_proto2",
5255
"enums/strong_proto3",

‎ext/README.md

+3-1
Original file line numberDiff line numberDiff line change
@@ -593,7 +593,8 @@ Examples:
593593
'hello mellow'.indexOf('jello') // returns -1
594594
'hello mellow'.indexOf('', 2) // returns 2
595595
'hello mellow'.indexOf('ello', 2) // returns 7
596-
'hello mellow'.indexOf('ello', 20) // error
596+
'hello mellow'.indexOf('ello', 20) // returns -1
597+
'hello mellow'.indexOf('ello', -1) // error
597598

598599
### Join
599600

@@ -631,6 +632,7 @@ Examples:
631632
'hello mellow'.lastIndexOf('ello') // returns 7
632633
'hello mellow'.lastIndexOf('jello') // returns -1
633634
'hello mellow'.lastIndexOf('ello', 6) // returns 1
635+
'hello mellow'.lastIndexOf('ello', 20) // returns -1
634636
'hello mellow'.lastIndexOf('ello', -1) // error
635637

636638
### LowerAscii

‎ext/strings.go

+13-3
Original file line numberDiff line numberDiff line change
@@ -119,7 +119,8 @@ const (
119119
// 'hello mellow'.indexOf('jello') // returns -1
120120
// 'hello mellow'.indexOf('', 2) // returns 2
121121
// 'hello mellow'.indexOf('ello', 2) // returns 7
122-
// 'hello mellow'.indexOf('ello', 20) // error
122+
// 'hello mellow'.indexOf('ello', 20) // returns -1
123+
// 'hello mellow'.indexOf('ello', -1) // error
123124
//
124125
// # Join
125126
//
@@ -155,6 +156,7 @@ const (
155156
// 'hello mellow'.lastIndexOf('ello') // returns 7
156157
// 'hello mellow'.lastIndexOf('jello') // returns -1
157158
// 'hello mellow'.lastIndexOf('ello', 6) // returns 1
159+
// 'hello mellow'.lastIndexOf('ello', 20) // returns -1
158160
// 'hello mellow'.lastIndexOf('ello', -1) // error
159161
//
160162
// # LowerAscii
@@ -561,9 +563,13 @@ func indexOfOffset(str, substr string, offset int64) (int64, error) {
561563
off := int(offset)
562564
runes := []rune(str)
563565
subrunes := []rune(substr)
564-
if off < 0 || off >= len(runes) {
566+
if off < 0 {
565567
return -1, fmt.Errorf("index out of range: %d", off)
566568
}
569+
// If the offset exceeds the length, return -1 rather than error.
570+
if off >= len(runes) {
571+
return -1, nil
572+
}
567573
for i := off; i < len(runes)-(len(subrunes)-1); i++ {
568574
found := true
569575
for j := 0; j < len(subrunes); j++ {
@@ -594,9 +600,13 @@ func lastIndexOfOffset(str, substr string, offset int64) (int64, error) {
594600
off := int(offset)
595601
runes := []rune(str)
596602
subrunes := []rune(substr)
597-
if off < 0 || off >= len(runes) {
603+
if off < 0 {
598604
return -1, fmt.Errorf("index out of range: %d", off)
599605
}
606+
// If the offset is far greater than the length return -1
607+
if off >= len(runes) {
608+
return -1, nil
609+
}
600610
if off > len(runes)-len(subrunes) {
601611
off = len(runes) - len(subrunes)
602612
}

‎ext/strings_test.go

+2-8
Original file line numberDiff line numberDiff line change
@@ -150,18 +150,12 @@ var stringTests = []struct {
150150
expr: `'tacocat'.charAt(30) == ''`,
151151
err: "index out of range: 30",
152152
},
153-
{
154-
expr: `'tacocat'.indexOf('a', 30) == -1`,
155-
err: "index out of range: 30",
156-
},
153+
{expr: `'tacocat'.indexOf('a', 30) == -1`},
157154
{
158155
expr: `'tacocat'.lastIndexOf('a', -1) == -1`,
159156
err: "index out of range: -1",
160157
},
161-
{
162-
expr: `'tacocat'.lastIndexOf('a', 30) == -1`,
163-
err: "index out of range: 30",
164-
},
158+
{expr: `'tacocat'.lastIndexOf('a', 30) == -1`},
165159
{
166160
expr: `"tacocat".substring(40) == "cat"`,
167161
err: "index out of range: 40",

0 commit comments

Comments
 (0)