mirror of
https://github.com/mruby/mruby
synced 2026-06-08 16:11:16 +00:00
mruby-regexp: handle \b inside character class as backspace
Inside `[...]`, `\b` denotes U+0008 (backspace) -- the same as MRI/Onigmo and PCRE. parse_escape() was missing the case, so the backslash was dropped and the bare letter `b` was inserted into the class. `[\b]` therefore matched every `b` instead of backspace. Add `case 'b': return '\b';` to parse_escape(). The function is only reached from the character-class body and range endpoints; the top-level dispatcher emits RE_WBOUND for `\b` before falling through, so the word-boundary semantics outside `[...]` are unchanged. Reported by Sam Ruby in matz/spinel#632; same engine bug affects both spinel and mruby. Co-authored-by: Claude <noreply@anthropic.com>
This commit is contained in:
@@ -214,6 +214,8 @@ parse_escape(re_compiler *c)
|
||||
case 'v': return '\v';
|
||||
case 'a': return '\a';
|
||||
case 'e': return 0x1b;
|
||||
case 'b': return '\b'; /* backspace; only reachable inside [...] since the
|
||||
top-level dispatcher emits RE_WBOUND for `\b` */
|
||||
default: return ch; /* literal: \., \\, \/, \(, etc. */
|
||||
}
|
||||
}
|
||||
|
||||
@@ -47,6 +47,14 @@ assert("Regexp - character class") do
|
||||
assert_equal "abc", md[0]
|
||||
end
|
||||
|
||||
assert("Regexp - \\b inside character class is backspace") do
|
||||
# Outside [...], \b is the word boundary assertion; inside [...]
|
||||
# it must mean U+0008 (backspace), matching MRI/Onigmo.
|
||||
assert_equal "Ruby", "Ruby".gsub(/[\b]/, "X")
|
||||
assert_equal "aXc", "a\bc".gsub(/[\b]/, "X")
|
||||
assert_equal ["\b", "\t", "\n"], "ABC\b\t\n".scan(/[\b-\n]/)
|
||||
end
|
||||
|
||||
assert("Regexp - dot") do
|
||||
re = Regexp.new("a.c")
|
||||
assert_true re.match?("abc")
|
||||
|
||||
Reference in New Issue
Block a user