mruby-regexp: reject a hex escape with no digit - #7260
Conversation
`parse_escape` read `\x` by taking up to two hex digits and returning
whatever it had, so `\x` followed by none came out as `\x00`. A pattern
handed to `Regexp.new` (a literal never gets this far, since the parser
refuses it) then compiled quietly to a NUL: `\x{41}` was a NUL and a
quantifier and matched 41 NUL bytes, and `\x` or `\xZ` was a NUL as well.
The same path serves a character class, so `[\x]` held a NUL. CRuby
raises for each of them.
```ruby
Regexp.new("\\x{41}") =~ "\0" * 41 # CRuby: RegexpError (invalid hex escape: /\x{41}/), mruby: 0
Regexp.new("\\x") =~ "\0" # CRuby: RegexpError (invalid hex escape: /\x/), mruby: 0
Regexp.new("[\\x]") =~ "\0" # CRuby: RegexpError (invalid hex escape: /[\x]/), mruby: 0
```
Raise `RegexpError` with CRuby's message when the escape reads no digit.
`\x4` and `\x4Z` still read one digit, as before. The README already says
there is no `\x{...}` escape; it now says that spelling raises, since the
brace is not a digit, rather than leaving the reader to find out what
`\x` alone comes to.
|
No actionable comments were generated in the recent review. 🎉 ℹ️ Recent review info⚙️ Run configurationConfiguration used: defaults Review profile: CHILL Plan: Pro Plus Run ID: 📒 Files selected for processing (3)
Included review availability: Your plan includes up to 8 reviews per rolling hour; 4 remain after this review. 📝 WalkthroughWalkthroughThe regexp compiler now requires at least one hexadecimal digit after ChangesRegexp hexadecimal escape validation
Estimated code review effort: 2 (Simple) | ~10 minutes Merge Risk: ⚪ Minimal · up to This localized change rejects malformed hexadecimal regexp escapes instead of silently compiling them as NUL bytes, with matching tests and documentation updates. No actionable merge-blocking risk remains after normal checks and review. Possibly related PRs
Suggested reviewers: 🚥 Pre-merge checks | ✅ 4 | ❌ 1❌ Failed checks (1 warning)
✅ Passed checks (4 passed)
✨ Finishing Touches🧪 Generate unit tests (beta)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
parse_escapeinre_compile.creads\xby taking up to two hex digits and returning whatever it has, so\xfollowed by no digit came out as\x00. A pattern handed toRegexp.newthen compiled quietly to a NUL (a regexp literal never gets this far, since the parser refuses/\x/as a syntax error, as CRuby's does):\x{41}was a NUL and a{41}quantifier and matched 41 NUL bytes,\xand\xZwere a NUL, and[\x]held a NUL because the class reads its escapes through the same function. This is the spelling the README's "No\x{...}hex escape" note steers a reader away from, and it did not fail, it matched something else.Fix
parse_escaperaisesRegexpErrorwith CRuby's message,invalid hex escape, when the digit loop read nothing. One digit is still enough (\x4,\x4Z), as before, and the check sits in the shared function, so a class atom ([\x],[\xZ],[a-\x]) is refused by the same line. The README's limitation note now says\x{...}raises, since the brace is not a hex digit, and the escape list says\xwith no digit raises.The
\x{...}form itself is still not implemented; this only makes the missing form an error rather than a silent NUL, which is what CRuby does with it too.Testing
mrbgems/mruby-regexp/test/regexp_syntax.rbgains "a hex escape needs at least one digit": the message for\x{41},\x, and[\x], plus\xZ,a\x,\x{},[\xZ],[\x{41}],[a-\x],[\x-z]raising, and\x4,\x4Z,[\x4]still matching"\x04". Every pattern in the block was run against CRuby 4.0.6 first and behaves the same there.Full suite green at every commit (one commit).
MRUBY_CONFIG)ci/gcc-clangfull-debugci/gcc-clangbintestci/gcc-clangcxx_abici/gcc-clangbyte-stringci/gcc-clangascii-caseEnvironment
Machine, toolchain, and the compile line of every build
Actual compile line of
src/string.cin eachbuild_config/ci/gcc-clang.rbbuild (-MMD -c,-I, and-odropped).full-debugis-O0becauseenable_debugappends-g3 -O0after the toolchain's-g -O3;cxx_abicompiles C as C++ withgcc -x c++ -std=gnu++03, g++ only links.Summary by CodeRabbit
Bug Fixes
\x,\xZ, and\x{...}now raiseRegexpError.Documentation