[ruby/strscan] scan_integer(base: 16) ignore x suffix if not

followed by hexadecimal
(https://github.com/ruby/strscan/pull/141)

Fix: https://github.com/ruby/strscan/issues/140

`0x<EOF>`, `0xZZZ` should be parsed as `0` instead of not matching at
all.

https://github.com/ruby/strscan/commit/c4e4795ed2
This commit is contained in:
Jean Boussier 2025-02-20 10:25:03 +01:00 committed by Hiroshi SHIBATA
parent 0f8a6e1f59
commit bf6c106d54
2 changed files with 15 additions and 10 deletions

View File

@ -1379,7 +1379,7 @@ strscan_scan_base16_integer(VALUE self)
len++;
}
if ((remaining_len >= (len + 2)) && ptr[len] == '0' && ptr[len + 1] == 'x') {
if ((remaining_len >= (len + 3)) && ptr[len] == '0' && ptr[len + 1] == 'x' && rb_isxdigit(ptr[len + 2])) {
len += 2;
}

View File

@ -1052,19 +1052,24 @@ module StringScannerTests
assert_predicate(s, :matched?)
s = create_string_scanner('0x')
assert_nil(s.scan_integer(base: 16))
assert_equal(0, s.pos)
refute_predicate(s, :matched?)
assert_equal(0, s.scan_integer(base: 16))
assert_equal(1, s.pos)
assert_predicate(s, :matched?)
s = create_string_scanner('0xyz')
assert_equal(0, s.scan_integer(base: 16))
assert_equal(1, s.pos)
assert_predicate(s, :matched?)
s = create_string_scanner('-0x')
assert_nil(s.scan_integer(base: 16))
assert_equal(0, s.pos)
refute_predicate(s, :matched?)
assert_equal(0, s.scan_integer(base: 16))
assert_equal(2, s.pos)
assert_predicate(s, :matched?)
s = create_string_scanner('+0x')
assert_nil(s.scan_integer(base: 16))
assert_equal(0, s.pos)
refute_predicate(s, :matched?)
assert_equal(0, s.scan_integer(base: 16))
assert_equal(2, s.pos)
assert_predicate(s, :matched?)
s = create_string_scanner('-123abc')
assert_equal(-0x123abc, s.scan_integer(base: 16))