Tcl Source Code

View Ticket
Login
Ticket UUID: 75c9d9cece5612408603f4e56773f55ada24b2d7
Title: regexp sometimes allows an invalid backref to be matched
Type: Bug Created on: 2021-08-23 16:04:19
Submitter: tgl Assigned to: jan.nijtmans
Subsystem: 43. Regexp Severity: Minor
Priority: 5 Medium Last modified: 2026-10-11 16:50:48
Status: Closed Closed by: jan.nijtmans
Resolution: Fixed Closed on: 2026-10-11 16:50:48
Version: 8.6.18, 9.0.5, 9.1.0
Description:
$ tclsh
% regexp {^(.)\1|\1.}   {abcdef}
1
% regexp {^((.)\2|..)\2}        {abadef}
1

Of course, neither of these should match, because the (.) capture is within a failed alternative branch,
so the last backref to it should be deemed unable to match.

Analysis and fix for it in Postgres is here:

https://www.postgresql.org/message-id/151435.1629733387%40sss.pgh.pa.us

I doubt you can use the code change exactly as-is, because I don't think you ever adopted our changes
to create an explicit "iteration" subre type.  But the principle, and particularly the more careful
specification of cdissect's recursion rules, should still work for you.
User Comments:
serhiy.storchaka added on 2026-10-10 19:29:32:

Still the same in 8.6, 9.0 and 9.1. When the right side of a concatenation failed, ccondissect() and crevcondissect() left the captures of the left side set, so the next alternative's backref saw them.

Proposed fix in branch regexp-backref-failed-alt: your PostgreSQL change, which clears the left side's captures when the right side fails and defines the cdissect() rules for clearing match data. Tests reg-14.30 and 14.31 (your examples).


jan.nijtmans added on 2026-10-11 16:50:48:

Fixed in [9383b0c913592380|trunk], core-9-0-branch and core-8-6-branch

Many thanks!