Actions
Bug #18631
closedRange check breaks multiplex backreferences in regular expressions
Status:
Closed
Assignee:
-
Target version:
-
ruby -v:
ruby 2.7.5p203 (2021-11-24) [x86_64-linux]
Description
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
(https://github.com/ruby/ruby/blob/master/regexec.c#L2646). 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.
Actions
Like0
Like0Like0Like0Like0