diff options
author | ph10 <ph10@6239d852-aaf2-0410-a92c-79f79f948069> | 2015-03-25 17:01:04 +0000 |
---|---|---|
committer | ph10 <ph10@6239d852-aaf2-0410-a92c-79f79f948069> | 2015-03-25 17:01:04 +0000 |
commit | b89f6825a248eaec7383071cfb75c9343ef4ba89 (patch) | |
tree | c4a04963925a695c4eb693a53365f49eb4824528 /src/pcre2_auto_possess.c | |
parent | c7be550583855d8e7c0152fd8b45d51265846134 (diff) | |
download | pcre2-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.c | 18 |
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) { |