fix(strutil): clamp Substr stop index to avoid out-of-range panic

Substr panicked with a slice-bounds error when a negative length trimmed
more runes than remained after pos, because stopIdx (strLn + length) could
fall before pos. Clamp stopIdx to pos so an over-long negative trim returns
an empty string, matching the existing pos >= strLn guard.
This commit is contained in:
dualfroz committed 2026-09-06 00:44:31 +02:00
1 parent d489e58561
commit fd69f1aadd
2 files changed
+12

No files matched your search

+6
View File
@@ -166,6 +166,12 @@ func Substr(s string, pos, length int) string {
stopIdx = strLn + length stopIdx = strLn + length
} }
// A negative length can move stopIdx before pos; clamp to avoid an
// out-of-range slice.
if stopIdx < pos {
stopIdx = pos
}
return string(runes[pos:stopIdx]) return string(runes[pos:stopIdx])
} }
+6
View File
@@ -120,6 +120,12 @@ func TestSubstr(t *testing.T) {
assert.Eq(t, "", strutil.Substr("abcDEF", 23, 5)) assert.Eq(t, "", strutil.Substr("abcDEF", 23, 5))
assert.Eq(t, "cDEF12", strutil.Substr("abcDEF123", 2, -1)) assert.Eq(t, "cDEF12", strutil.Substr("abcDEF123", 2, -1))
assert.Eq(t, "cDEF", strutil.Substr("abcDEF123", 2, -3)) assert.Eq(t, "cDEF", strutil.Substr("abcDEF123", 2, -3))
// negative length trimming more than the remaining substring must not
// panic; it should yield an empty string.
assert.Eq(t, "", strutil.Substr("hello", 4, -3))
assert.Eq(t, "", strutil.Substr("hello", 3, -5))
assert.Eq(t, "", strutil.Substr("abcDEF123", 8, -3))
} }
func TestSplitInlineComment(t *testing.T) { func TestSplitInlineComment(t *testing.T) {