Fix enforcement of restrictions inside regexp lookaround constraints.
authorTom Lane
Sat, 7 Nov 2015 17:43:24 +0000 (12:43 -0500)
committerTom Lane
Sat, 7 Nov 2015 17:43:24 +0000 (12:43 -0500)
Lookahead and lookbehind constraints aren't allowed to contain backrefs,
and parentheses within them are always considered non-capturing.  Or so
says the manual.  But the regexp parser forgot about these rules once
inside a parenthesized subexpression, so that constructs like (\w)(?=(\1))
were accepted (but then not correctly executed --- a case like this acted
like (\w)(?=\w), without any enforcement that the two \w's match the same
text).  And in (?=((foo))) the innermost parentheses would be counted as
capturing parentheses, though no text would ever be captured for them.

To fix, properly pass down the "type" argument to the recursive invocation
of parse().

Back-patch to all supported branches; it was agreed that silent
misexecution of such patterns is worse than throwing an error, even though
new errors in minor releases are generally not desirable.

src/backend/regex/regcomp.c
src/test/regress/expected/regex.out
src/test/regress/sql/regex.sql

index cb4dd2d33958a815eed78103f08c79dff909b235..03133f4a048a75b5d421e831ff9aa4c5982e2a24 100644 (file)
@@ -944,7 +944,7 @@ parseqatom(struct vars * v,
            EMPTYARC(lp, s);
            EMPTYARC(s2, rp);
            NOERR();
-           atom = parse(v, ')', PLAIN, s, s2);
+           atom = parse(v, ')', type, s, s2);
            assert(SEE(')') || ISERR());
            NEXT();
            NOERR();
index be151858a3884a9c9f32d64608d80e959e8f912c..ba2923982f5ffa7f3bf59782915c73bda30cd333 100644 (file)
@@ -321,3 +321,8 @@ select 'a' ~ '()+\1';
  t
 (1 row)
 
+-- Error conditions
+select 'xyz' ~ 'x(\w)(?=\1)';  -- no backrefs in LACONs
+ERROR:  invalid regular expression: invalid backreference number
+select 'xyz' ~ 'x(\w)(?=(\1))';
+ERROR:  invalid regular expression: invalid backreference number
index c59fa35f24d81f5e2c4aceae0ada1ca3832f0ac4..7cf5e599822a6131e586520e9599f309506db94d 100644 (file)
@@ -82,3 +82,7 @@ select 'a' ~ '$()|^\1';
 select 'a' ~ '.. ()|\1';
 select 'a' ~ '()*\1';
 select 'a' ~ '()+\1';
+
+-- Error conditions
+select 'xyz' ~ 'x(\w)(?=\1)';  -- no backrefs in LACONs
+select 'xyz' ~ 'x(\w)(?=(\1))';