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

Commit3694b4d

Browse files
committed
Fix incorrect search for "x?" style matches in creviterdissect().
When the number of allowed iterations is limited (either a "?" quantifieror a bound expression), the last sub-match has to reach to the end of thetarget string. The previous coding here first tried the shortest possiblematch (one character, usually) and then gave up and back-tracked if thatdidn't work, typically leading to failure to match overall, as shown inbug #11478 from Christoph Berg. The minimum change to fix that would be tonot decrement k before "goto backtrack"; but that would be a pretty stupidsolution, because we'd laboriously try each possible sub-match lengthbefore finally discovering that only ending at the end can work. Instead,force the sub-match endpoint limit up to the end for even the firstshortest() call if we cannot have any more sub-matches after this one.Bug introduced in my rewrite that added the iterdissect logic, commit173e29a. The shortest-first search codewas too closely modeled on the longest-first code, which hasn't got thisissue since it tries a match reaching to the end to start with anyway.Back-patch to all affected branches.
1 parenta564307 commit3694b4d

File tree

3 files changed

+16
-0
lines changed

3 files changed

+16
-0
lines changed

‎src/backend/regex/regexec.c

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1190,6 +1190,10 @@ creviterdissect(struct vars * v,
11901190
(k >=min_matches||min_matches-k<end-limit))
11911191
limit++;
11921192

1193+
/* if this is the last allowed sub-match, it must reach to the end */
1194+
if (k >=max_matches)
1195+
limit=end;
1196+
11931197
/* try to find an endpoint for the k'th sub-match */
11941198
endpts[k]=shortest(v,d,endpts[k-1],limit,end,
11951199
(chr**)NULL, (int*)NULL);

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

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -188,3 +188,11 @@ select regexp_matches('Programmer', '(\w)(.*?\1)', 'g');
188188
{m,m}
189189
(2 rows)
190190

191+
-- Test for proper matching of non-greedy iteration (bug #11478)
192+
select regexp_matches('foo/bar/baz',
193+
'^([^/]+?)(?:/([^/]+?))(?:/([^/]+?))?$', '');
194+
regexp_matches
195+
----------------
196+
{foo,bar,baz}
197+
(1 row)
198+

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

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -46,3 +46,7 @@ select 'a' ~ '((((((a+|)+|)+|)+|)+|)+|)';
4646
-- https://core.tcl.tk/tcl/tktview/6585b21ca8fa6f3678d442b97241fdd43dba2ec0
4747
select'Programmer' ~'(\w).*?\1'as t;
4848
select regexp_matches('Programmer','(\w)(.*?\1)','g');
49+
50+
-- Test for proper matching of non-greedy iteration (bug #11478)
51+
select regexp_matches('foo/bar/baz',
52+
'^([^/]+?)(?:/([^/]+?))(?:/([^/]+?))?$','');

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp