[ruby/strscan] Fix a bug that inconsistency of IndexError vs nil for

unknown capture group
(https://github.com/ruby/strscan/pull/143)

Fix https://github.com/ruby/strscan/pull/139

Reported by Benoit Daloze. Thanks!!!

https://github.com/ruby/strscan/commit/bc8a0d2623
This commit is contained in:
NAITOH Jun 2025-02-23 16:52:32 +09:00 committed by Hiroshi SHIBATA
parent 36ab247e4d
commit 018943ba05
Notes: git 2025-02-25 06:37:05 +00:00
2 changed files with 39 additions and 18 deletions

View File

@ -1667,19 +1667,17 @@ strscan_matched_size(VALUE self)
static int
name_to_backref_number(struct re_registers *regs, VALUE regexp, const char* name, const char* name_end, rb_encoding *enc)
{
int num;
num = onig_name_to_backref_number(RREGEXP_PTR(regexp),
(const unsigned char* )name, (const unsigned char* )name_end, regs);
if (RTEST(regexp)) {
int num = onig_name_to_backref_number(RREGEXP_PTR(regexp),
(const unsigned char* )name,
(const unsigned char* )name_end,
regs);
if (num >= 1) {
return num;
}
else {
}
rb_enc_raise(enc, rb_eIndexError, "undefined group name reference: %.*s",
rb_long2int(name_end - name), name);
}
UNREACHABLE;
}
/*
@ -1768,7 +1766,6 @@ strscan_aref(VALUE self, VALUE idx)
idx = rb_sym2str(idx);
/* fall through */
case T_STRING:
if (!RTEST(p->regex)) return Qnil;
RSTRING_GETMEM(idx, name, i);
i = name_to_backref_number(&(p->regs), p->regex, name, name + i, rb_enc_get(idx));
break;

View File

@ -458,7 +458,31 @@ module StringScannerTests
def test_AREF
s = create_string_scanner('stra strb strc')
s.scan(/\w+/)
s.scan(/\s+/)
assert_nil( s[-2])
assert_nil( s[-1])
assert_nil( s[0])
assert_nil( s[1])
assert_nil( s[:c])
assert_nil( s['c'])
s.scan("not match")
assert_nil( s[-2])
assert_nil( s[-1])
assert_nil( s[0])
assert_nil( s[1])
assert_nil( s[:c])
assert_nil( s['c'])
s.check(/\w+/)
assert_nil( s[-2])
assert_equal('stra', s[-1])
assert_equal('stra', s[0])
assert_nil( s[1])
assert_raise(IndexError) { s[:c] }
assert_raise(IndexError) { s['c'] }
s.scan("stra")
assert_nil( s[-2])
assert_equal('stra', s[-1])
assert_equal('stra', s[0])
@ -903,11 +927,11 @@ module StringScannerTests
s = create_string_scanner('abc')
s.get_byte
assert_nil(s[:c])
assert_nil(s["c"])
assert_raise(IndexError) { s[:c] }
assert_raise(IndexError) { s['c'] }
s.getch
assert_nil(s[:c])
assert_nil(s["c"])
assert_raise(IndexError) { s[:c] }
assert_raise(IndexError) { s['c'] }
end
def test_size