]> granicus.if.org Git - postgresql/commitdiff
Fix enforcement of restrictions inside regexp lookaround constraints.
authorTom Lane <tgl@sss.pgh.pa.us>
Sat, 7 Nov 2015 17:43:24 +0000 (12:43 -0500)
committerTom Lane <tgl@sss.pgh.pa.us>
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 aa759c264861b5e357c47910bf893fafe8ba1224..a165b3b1ca5676973376c13c0ef84f067b5135ec 100644 (file)
@@ -951,7 +951,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 f0e2fc9eb896786c3206ad88e68868867be317fe..07fb023534fa576e2b1a0357542c5acc5ce36a63 100644 (file)
@@ -490,3 +490,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 d3030af295d3852714c2dfa13ea2ca9597ef686d..c45bdc91d853419e2fd094adb4a18f9de1ab8e5e 100644 (file)
@@ -117,3 +117,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))';