summaryrefslogtreecommitdiff
path: root/pcre/pcre_study.c
diff options
context:
space:
mode:
authorSergei Golubchik <serg@mariadb.org>2015-12-21 21:24:22 +0100
committerSergei Golubchik <serg@mariadb.org>2015-12-21 21:24:22 +0100
commita2bcee626d4ef2836e38e4932305871390164644 (patch)
treeb41e357427318bad8985078b91bbd2b0360defc8 /pcre/pcre_study.c
parent1788bfe93a745582d938a608d5959b7d2e6b2f23 (diff)
parent4fdf25afa8188905653a83e08fc387243e584600 (diff)
downloadmariadb-git-a2bcee626d4ef2836e38e4932305871390164644.tar.gz
Merge branch '10.0' into 10.1
Diffstat (limited to 'pcre/pcre_study.c')
-rw-r--r--pcre/pcre_study.c19
1 files changed, 13 insertions, 6 deletions
diff --git a/pcre/pcre_study.c b/pcre/pcre_study.c
index 998fe2325ef..7fd0ba0b3d8 100644
--- a/pcre/pcre_study.c
+++ b/pcre/pcre_study.c
@@ -71,6 +71,7 @@ Arguments:
startcode pointer to start of the whole pattern's code
options the compiling options
recurses chain of recurse_check to catch mutual recursion
+ countptr pointer to call count (to catch over complexity)
Returns: the minimum length
-1 if \C in UTF-8 mode or (*ACCEPT) was encountered
@@ -80,7 +81,8 @@ Returns: the minimum length
static int
find_minlength(const REAL_PCRE *re, const pcre_uchar *code,
- const pcre_uchar *startcode, int options, recurse_check *recurses)
+ const pcre_uchar *startcode, int options, recurse_check *recurses,
+ int *countptr)
{
int length = -1;
/* PCRE_UTF16 has the same value as PCRE_UTF8. */
@@ -90,6 +92,8 @@ recurse_check this_recurse;
register int branchlength = 0;
register pcre_uchar *cc = (pcre_uchar *)code + 1 + LINK_SIZE;
+if ((*countptr)++ > 1000) return -1; /* too complex */
+
if (*code == OP_CBRA || *code == OP_SCBRA ||
*code == OP_CBRAPOS || *code == OP_SCBRAPOS) cc += IMM2_SIZE;
@@ -131,7 +135,7 @@ for (;;)
case OP_SBRAPOS:
case OP_ONCE:
case OP_ONCE_NC:
- d = find_minlength(re, cc, startcode, options, recurses);
+ d = find_minlength(re, cc, startcode, options, recurses, countptr);
if (d < 0) return d;
branchlength += d;
do cc += GET(cc, 1); while (*cc == OP_ALT);
@@ -415,7 +419,8 @@ for (;;)
int dd;
this_recurse.prev = recurses;
this_recurse.group = cs;
- dd = find_minlength(re, cs, startcode, options, &this_recurse);
+ dd = find_minlength(re, cs, startcode, options, &this_recurse,
+ countptr);
if (dd < d) d = dd;
}
}
@@ -451,7 +456,8 @@ for (;;)
{
this_recurse.prev = recurses;
this_recurse.group = cs;
- d = find_minlength(re, cs, startcode, options, &this_recurse);
+ d = find_minlength(re, cs, startcode, options, &this_recurse,
+ countptr);
}
}
}
@@ -514,7 +520,7 @@ for (;;)
this_recurse.prev = recurses;
this_recurse.group = cs;
branchlength += find_minlength(re, cs, startcode, options,
- &this_recurse);
+ &this_recurse, countptr);
}
}
cc += 1 + LINK_SIZE;
@@ -1453,6 +1459,7 @@ pcre32_study(const pcre32 *external_re, int options, const char **errorptr)
#endif
{
int min;
+int count = 0;
BOOL bits_set = FALSE;
pcre_uint8 start_bits[32];
PUBL(extra) *extra = NULL;
@@ -1539,7 +1546,7 @@ if ((re->options & PCRE_ANCHORED) == 0 &&
/* Find the minimum length of subject string. */
-switch(min = find_minlength(re, code, code, re->options, NULL))
+switch(min = find_minlength(re, code, code, re->options, NULL, &count))
{
case -2: *errorptr = "internal error: missing capturing bracket"; return NULL;
case -3: *errorptr = "internal error: opcode not recognized"; return NULL;