Project

General

Profile

Actions

Bug #18631

closed

Range check breaks multiplex backreferences in regular expressions

Added by jirkamarsik (Jirka Marsik) about 2 years ago. Updated over 1 year ago.

Status:
Closed
Assignee:
-
Target version:
-
ruby -v:
ruby 2.7.5p203 (2021-11-24) [x86_64-linux]
[ruby-core:107892]

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

Also available in: Atom PDF

Like0
Like0Like0Like0Like0