Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commite2bd904

Browse files
committed
Fix regex match failures for backrefs combined with non-greedy quantifiers.
An ancient logic error in cfindloop() could cause the regex engine to failto find matches that begin later than the start of the string. Thisfunction is only used when the regex pattern contains a back reference,and so far as we can tell the error is only reachable if the pattern isnon-greedy (i.e. its first quantifier uses the ? modifier). Furthermore,the actual match must begin after some potential match that satisfies theDFA but then fails the back-reference's match test.Reported and fixed by Jeevan Chalke, with cosmetic adjustments by me.
1 parent4cbe3ac commite2bd904

File tree

3 files changed

+31
-9
lines changed

3 files changed

+31
-9
lines changed

‎src/backend/regex/regexec.c

Lines changed: 11 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -487,19 +487,21 @@ cfindloop(struct vars * v,
487487
*coldp=cold;
488488
returner;
489489
}
490-
if ((shorter) ?end==estop :end==begin)
491-
{
492-
/* no point in trying again */
493-
*coldp=cold;
494-
returnREG_NOMATCH;
495-
}
496-
/* go around and try again */
490+
/* try next shorter/longer match with same begin point */
497491
if (shorter)
492+
{
493+
if (end==estop)
494+
break;/* NOTE BREAK OUT */
498495
estart=end+1;
496+
}
499497
else
498+
{
499+
if (end==begin)
500+
break;/* NOTE BREAK OUT */
500501
estop=end-1;
501-
}
502-
}
502+
}
503+
}/* end loop over endpoint positions */
504+
}/* end loop over beginning positions */
503505
}while (close<v->stop);
504506

505507
*coldp=cold;

‎src/test/regress/expected/regex.out

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -173,3 +173,18 @@ select 'a' ~ '((((((a+|)+|)+|)+|)+|)+|)';
173173
t
174174
(1 row)
175175

176+
-- Test backref in combination with non-greedy quantifier
177+
-- https://core.tcl.tk/tcl/tktview/6585b21ca8fa6f3678d442b97241fdd43dba2ec0
178+
select 'Programmer' ~ '(\w).*?\1' as t;
179+
t
180+
---
181+
t
182+
(1 row)
183+
184+
select regexp_matches('Programmer', '(\w)(.*?\1)', 'g');
185+
regexp_matches
186+
----------------
187+
{r,ogr}
188+
{m,m}
189+
(2 rows)
190+

‎src/test/regress/sql/regex.sql

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -41,3 +41,8 @@ select 'a' ~ '($|^)*';
4141
-- Test for infinite loop in fixempties() (Tcl bugs 3604074, 3606683)
4242
select'a' ~'((((((a)*)*)*)*)*)*';
4343
select'a' ~'((((((a+|)+|)+|)+|)+|)+|)';
44+
45+
-- Test backref in combination with non-greedy quantifier
46+
-- https://core.tcl.tk/tcl/tktview/6585b21ca8fa6f3678d442b97241fdd43dba2ec0
47+
select'Programmer' ~'(\w).*?\1'as t;
48+
select regexp_matches('Programmer','(\w)(.*?\1)','g');

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp