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

Commit2a4c46e

Browse files
committed
Fix array overrun in regex code.
zaptreesubs() was coded to unconditionally reset a capture subre'scorresponding pmatch[] entry. However, in regexes without backrefs, thatarray is caller-supplied and might not have as many entries as the regexhas capturing parens. So check the array length and do nothing if thereis no corresponding entry, much as subset() does. Failure to check thisresulted in a stack clobber in the case reported by Marko Kreen.This bug appears to have been latent in the regex library from thebeginning. It was not exposed because find() called dissect() notcdissect(), and the dissect() code path didn't ever call zaptreesubs()(formerly zapmem()). When I unified dissect() and cdissect() in commit4dd78bf, the problem was exposed.Now that I've seen this, I'm rather suspicious that we might need toback-patch it; but will refrain for now, for lack of evidence thatthe case can be hit in the previous coding.
1 parentace397e commit2a4c46e

File tree

3 files changed

+33
-4
lines changed

3 files changed

+33
-4
lines changed

‎src/backend/regex/regexec.c

Lines changed: 9 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -531,9 +531,14 @@ zaptreesubs(struct vars * v,
531531
{
532532
if (t->op=='(')
533533
{
534-
assert(t->subno>0);
535-
v->pmatch[t->subno].rm_so=-1;
536-
v->pmatch[t->subno].rm_eo=-1;
534+
intn=t->subno;
535+
536+
assert(n>0);
537+
if ((size_t)n<v->nmatch)
538+
{
539+
v->pmatch[n].rm_so=-1;
540+
v->pmatch[n].rm_eo=-1;
541+
}
537542
}
538543

539544
if (t->left!=NULL)
@@ -543,7 +548,7 @@ zaptreesubs(struct vars * v,
543548
}
544549

545550
/*
546-
* subset - setanysubexpressionrelevant to a successful subre
551+
* subset - set subexpressionmatch data for a successful subre
547552
*/
548553
staticvoid
549554
subset(structvars*v,

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

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -71,3 +71,22 @@ select 'abc abc abd' ~ '^(.+)( \1)+$' as f;
7171
f
7272
(1 row)
7373

74+
-- Test some cases that crashed in 9.2beta1 due to pmatch[] array overrun
75+
select substring('asd TO foo' from ' TO (([a-z0-9._]+|"([^"]+|"")+")+)');
76+
substring
77+
-----------
78+
foo
79+
(1 row)
80+
81+
select substring('a' from '((a))+');
82+
substring
83+
-----------
84+
a
85+
(1 row)
86+
87+
select substring('a' from '((a)+)');
88+
substring
89+
-----------
90+
a
91+
(1 row)
92+

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

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,3 +19,8 @@ select 'abc abc abd' ~ '^(\w+)( \1)+$' as f;
1919
select'abc abc abc' ~'^(.+)(\1)+$'as t;
2020
select'abc abd abc' ~'^(.+)(\1)+$'as f;
2121
select'abc abc abd' ~'^(.+)(\1)+$'as f;
22+
23+
-- Test some cases that crashed in 9.2beta1 due to pmatch[] array overrun
24+
selectsubstring('asd TO foo'from' TO (([a-z0-9._]+|"([^"]+|"")+")+)');
25+
selectsubstring('a'from'((a))+');
26+
selectsubstring('a'from'((a)+)');

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp