diff --git a/ext/strscan/strscan.c b/ext/strscan/strscan.c index da02291478..1894ed7fb3 100644 --- a/ext/strscan/strscan.c +++ b/ext/strscan/strscan.c @@ -1862,8 +1862,13 @@ strscan_integer_at(int argc, VALUE *argv, VALUE self) return Qnil; beg = adjust_register_position(p, p->regs.beg[i]); + if (beg > S_LEN(p)) + return Qnil; end = adjust_register_position(p, p->regs.end[i]); + end = minl(end, S_LEN(p)); len = end - beg; + if (len == 0) + return Qnil; ptr = S_PBEG(p) + beg; #ifdef HAVE_RB_INT_PARSE_CSTR { diff --git a/test/strscan/test_stringscanner.rb b/test/strscan/test_stringscanner.rb index 96a1badb1f..966d62b226 100644 --- a/test/strscan/test_stringscanner.rb +++ b/test/strscan/test_stringscanner.rb @@ -578,6 +578,26 @@ module StringScannerTests assert_integer_at(s, 0, 0) # 0xaf end + def test_integer_at_shrunk + omit("not supported on TruffleRuby") if RUBY_ENGINE == "truffleruby" + + s = create_string_scanner(+"before 29 after") + s.skip_until(" ") + assert_equal("29", s.scan(/\d+/)) + s.string.replace("before ") + assert_nil(s.integer_at(0)) + end + + def test_integer_at_shrunk_partial + omit("not supported on TruffleRuby") if RUBY_ENGINE == "truffleruby" + + s = create_string_scanner(+"before 29 after") + s.skip_until(" ") + assert_equal("29", s.scan(/\d+/)) + s.string.replace("before 2") + assert_integer_at(s, 2) + end + def test_pre_match s = create_string_scanner('a b c d e') s.scan(/\w/)