aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/backend/regex/regexec.c13
-rw-r--r--src/test/regress/expected/regex.out19
-rw-r--r--src/test/regress/sql/regex.sql5
3 files changed, 33 insertions, 4 deletions
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)+)');