Bug #18631


Range check breaks multiplex backreferences in regular expressions

Added by jirkamarsik (Jirka Marsik) over 2 years ago. Updated almost 2 years ago.

Target version:
ruby -v:
ruby 2.7.5p203 (2021-11-24) [x86_64-linux]


The regular expression engine can sometimes produce wrong results when using multiplex backreferences near the end of the input string.

irb(main):001:0> /(?<x>a)(?<x>aa)\k<x>/.match("aaaaa")
=> #<MatchData "aaaaa" x:"a" x:"aa">
irb(main):002:0> /(?<x>a)(?<x>aa)\k<x>/.match("aaaa")
=> nil
irb(main):003:0> /(?<x>a)(?<x>aa)\k<x>/.match("aaaab")
=> #<MatchData "aaaa" x:"a" x:"aa">

The second and third calls to match should produce the same result.

The cause is the DATA_ENSURE(n) macro in the OP_BACKREF_MULTI case in regexec.c ( Instead of using continue to try to match the other referents for the backref (as all the other branches do), the DATA_ENSURE macro uses goto fail and so skips the other referents of the multiplex backref. This means that after failing the range check, no other referent can match. By extending the input string in the third example above, we have avoided the bug and got the correct result.

Updated by jeremyevans0 (Jeremy Evans) about 2 years ago

I don't know much about this code, but the approach described does fix the issue. I submitted a pull request for it:

Actions #2

Updated by jeremyevans (Jeremy Evans) about 2 years ago

  • Status changed from Open to Closed

Applied in changeset git|6d3f447aecfb56f7d3edbdf9cc68e748e150d7d8.

Fix multiplex backreferencs near end of string in regexp match

Idea from Jirka Marsik.

Fixes [Bug #18631]

Actions #3

Updated by nagachika (Tomoyuki Chikanaga) about 2 years ago

  • Backport changed from 2.6: UNKNOWN, 2.7: UNKNOWN, 3.0: UNKNOWN, 3.1: UNKNOWN to 2.7: REQUIRED, 3.0: REQUIRED, 3.1: REQUIRED

Updated by nagachika (Tomoyuki Chikanaga) almost 2 years ago

  • Backport changed from 2.7: REQUIRED, 3.0: REQUIRED, 3.1: REQUIRED to 2.7: REQUIRED, 3.0: REQUIRED, 3.1: DONE

ruby_3_1 6b8bf6ba5d1893b3c933c2de3ada1eb59a94b644 merged revision(s) 6d3f447aecfb56f7d3edbdf9cc68e748e150d7d8.


Also available in: Atom PDF