summaryrefslogtreecommitdiff
path: root/src/pcre2_auto_possess.c
diff options
context:
space:
mode:
authorph10 <ph10@6239d852-aaf2-0410-a92c-79f79f948069>2015-03-25 17:01:04 +0000
committerph10 <ph10@6239d852-aaf2-0410-a92c-79f79f948069>2015-03-25 17:01:04 +0000
commitb89f6825a248eaec7383071cfb75c9343ef4ba89 (patch)
treec4a04963925a695c4eb693a53365f49eb4824528 /src/pcre2_auto_possess.c
parentc7be550583855d8e7c0152fd8b45d51265846134 (diff)
downloadpcre2-b89f6825a248eaec7383071cfb75c9343ef4ba89.tar.gz
Add recursion limit to auto-possessification code.
git-svn-id: svn://vcs.exim.org/pcre2/code/trunk@232 6239d852-aaf2-0410-a92c-79f79f948069
Diffstat (limited to 'src/pcre2_auto_possess.c')
-rw-r--r--src/pcre2_auto_possess.c18
1 files changed, 13 insertions, 5 deletions
diff --git a/src/pcre2_auto_possess.c b/src/pcre2_auto_possess.c
index e25ec43..f2ada6d 100644
--- a/src/pcre2_auto_possess.c
+++ b/src/pcre2_auto_possess.c
@@ -561,13 +561,15 @@ Arguments:
utf TRUE in UTF mode
cb compile data block
base_list the data list of the base opcode
+ base_end the end of the data list
+ rec_limit points to recursion depth counter
Returns: TRUE if the auto-possessification is possible
*/
static BOOL
compare_opcodes(PCRE2_SPTR code, BOOL utf, const compile_block *cb,
- const uint32_t *base_list, PCRE2_SPTR base_end)
+ const uint32_t *base_list, PCRE2_SPTR base_end, int *rec_limit)
{
PCRE2_UCHAR c;
uint32_t list[8];
@@ -584,6 +586,8 @@ uint32_t chr;
BOOL accepted, invert_bits;
BOOL entered_a_group = FALSE;
+if (--(*rec_limit) <= 0) return FALSE; /* Recursion has gone too deep */
+
/* Note: the base_list[1] contains whether the current opcode has a greedy
(represented by a non-zero value) quantifier. This is a different from
other character type lists, which store here that the character iterator
@@ -660,7 +664,8 @@ for(;;)
while (*next_code == OP_ALT)
{
- if (!compare_opcodes(code, utf, cb, base_list, base_end)) return FALSE;
+ if (!compare_opcodes(code, utf, cb, base_list, base_end, rec_limit))
+ return FALSE;
code = next_code + 1 + LINK_SIZE;
next_code += GET(next_code, 1);
}
@@ -680,7 +685,7 @@ for(;;)
/* The bracket content will be checked by the OP_BRA/OP_CBRA case above. */
next_code += 1 + LINK_SIZE;
- if (!compare_opcodes(next_code, utf, cb, base_list, base_end))
+ if (!compare_opcodes(next_code, utf, cb, base_list, base_end, rec_limit))
return FALSE;
code += PRIV(OP_lengths)[c];
@@ -1116,6 +1121,7 @@ register PCRE2_UCHAR c;
PCRE2_SPTR end;
PCRE2_UCHAR *repeat_opcode;
uint32_t list[8];
+int rec_limit;
for (;;)
{
@@ -1130,7 +1136,8 @@ for (;;)
get_chr_property_list(code, utf, cb->fcc, list) : NULL;
list[1] = c == OP_STAR || c == OP_PLUS || c == OP_QUERY || c == OP_UPTO;
- if (end != NULL && compare_opcodes(end, utf, cb, list, end))
+ rec_limit = 10000;
+ if (end != NULL && compare_opcodes(end, utf, cb, list, end, &rec_limit))
{
switch(c)
{
@@ -1186,7 +1193,8 @@ for (;;)
list[1] = (c & 1) == 0;
- if (compare_opcodes(end, utf, cb, list, end))
+ rec_limit = 10000;
+ if (compare_opcodes(end, utf, cb, list, end, &rec_limit))
{
switch (c)
{