Skip to content

Commit e15d53e

Browse files
committed
Fix similar_escape() to convert parentheses to non-capturing style.
This is needed to avoid unwanted interference with SUBSTRING behavior, as per bug #5257 from Roman Kononov. Also, add some basic intelligence about character classes (bracket expressions) since we now have several behaviors that aren't appropriate inside a character class. As with the previous patch in this area, I'm reluctant to back-patch since it might affect applications that are relying on the prior behavior.
1 parent 2b59274 commit e15d53e

File tree

1 file changed

+26
-5
lines changed

1 file changed

+26
-5
lines changed

src/backend/utils/adt/regexp.c

Lines changed: 26 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88
*
99
*
1010
* IDENTIFICATION
11-
* $PostgreSQL: pgsql/src/backend/utils/adt/regexp.c,v 1.85 2010/01/02 16:57:55 momjian Exp $
11+
* $PostgreSQL: pgsql/src/backend/utils/adt/regexp.c,v 1.86 2010/01/02 20:59:16 tgl Exp $
1212
*
1313
* Alistair Crooks added the code for the regex caching
1414
* agc - cached the regular expressions used - there's a good chance
@@ -640,6 +640,7 @@ similar_escape(PG_FUNCTION_ARGS)
640640
int plen,
641641
elen;
642642
bool afterescape = false;
643+
bool incharclass = false;
643644
int nquotes = 0;
644645

645646
/* This function is not strict, so must test explicitly */
@@ -682,10 +683,10 @@ similar_escape(PG_FUNCTION_ARGS)
682683
*/
683684

684685
/*
685-
* We need room for the prefix/postfix plus as many as 2 output bytes per
686-
* input byte
686+
* We need room for the prefix/postfix plus as many as 3 output bytes per
687+
* input byte; since the input is at most 1GB this can't overflow
687688
*/
688-
result = (text *) palloc(VARHDRSZ + 6 + 2 * plen);
689+
result = (text *) palloc(VARHDRSZ + 6 + 3 * plen);
689690
r = VARDATA(result);
690691

691692
*r++ = '^';
@@ -699,7 +700,7 @@ similar_escape(PG_FUNCTION_ARGS)
699700

700701
if (afterescape)
701702
{
702-
if (pchar == '"') /* for SUBSTRING patterns */
703+
if (pchar == '"' && !incharclass) /* for SUBSTRING patterns */
703704
*r++ = ((nquotes++ % 2) == 0) ? '(' : ')';
704705
else
705706
{
@@ -713,13 +714,33 @@ similar_escape(PG_FUNCTION_ARGS)
713714
/* SQL99 escape character; do not send to output */
714715
afterescape = true;
715716
}
717+
else if (incharclass)
718+
{
719+
if (pchar == '\\')
720+
*r++ = '\\';
721+
*r++ = pchar;
722+
if (pchar == ']')
723+
incharclass = false;
724+
}
725+
else if (pchar == '[')
726+
{
727+
*r++ = pchar;
728+
incharclass = true;
729+
}
716730
else if (pchar == '%')
717731
{
718732
*r++ = '.';
719733
*r++ = '*';
720734
}
721735
else if (pchar == '_')
722736
*r++ = '.';
737+
else if (pchar == '(')
738+
{
739+
/* convert to non-capturing parenthesis */
740+
*r++ = '(';
741+
*r++ = '?';
742+
*r++ = ':';
743+
}
723744
else if (pchar == '\\' || pchar == '.' ||
724745
pchar == '^' || pchar == '$')
725746
{

0 commit comments

Comments
 (0)
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy