diff --git a/src/backend/regex/regexec.c b/src/backend/regex/regexec.c index c9c73e978b6..5d7415b3c1a 100644 --- a/src/backend/regex/regexec.c +++ b/src/backend/regex/regexec.c @@ -531,9 +531,14 @@ zaptreesubs(struct vars * v, { if (t->op == '(') { - assert(t->subno > 0); - v->pmatch[t->subno].rm_so = -1; - v->pmatch[t->subno].rm_eo = -1; + int n = t->subno; + + assert(n > 0); + if ((size_t) n < v->nmatch) + { + v->pmatch[n].rm_so = -1; + v->pmatch[n].rm_eo = -1; + } } if (t->left != NULL) @@ -543,7 +548,7 @@ zaptreesubs(struct vars * v, } /* - * subset - set any subexpression relevant to a successful subre + * subset - set subexpression match data for a successful subre */ static void subset(struct vars * v, diff --git a/src/test/regress/expected/regex.out b/src/test/regress/expected/regex.out index 4acc4a47a03..dc0c713b408 100644 --- a/src/test/regress/expected/regex.out +++ b/src/test/regress/expected/regex.out @@ -71,3 +71,22 @@ select 'abc abc abd' ~ '^(.+)( \1)+$' as f; f (1 row) +-- Test some cases that crashed in 9.2beta1 due to pmatch[] array overrun +select substring('asd TO foo' from ' TO (([a-z0-9._]+|"([^"]+|"")+")+)'); + substring +----------- + foo +(1 row) + +select substring('a' from '((a))+'); + substring +----------- + a +(1 row) + +select substring('a' from '((a)+)'); + substring +----------- + a +(1 row) + diff --git a/src/test/regress/sql/regex.sql b/src/test/regress/sql/regex.sql index b5315a3df6d..9fdcb2f5bd5 100644 --- a/src/test/regress/sql/regex.sql +++ b/src/test/regress/sql/regex.sql @@ -19,3 +19,8 @@ select 'abc abc abd' ~ '^(\w+)( \1)+$' as f; select 'abc abc abc' ~ '^(.+)( \1)+$' as t; select 'abc abd abc' ~ '^(.+)( \1)+$' as f; select 'abc abc abd' ~ '^(.+)( \1)+$' as f; + +-- Test some cases that crashed in 9.2beta1 due to pmatch[] array overrun +select substring('asd TO foo' from ' TO (([a-z0-9._]+|"([^"]+|"")+")+)'); +select substring('a' from '((a))+'); +select substring('a' from '((a)+)');