diff options
author | The Android Open Source Project <initial-contribution@android.com> | 2008-10-21 07:00:00 -0700 |
---|---|---|
committer | The Android Open Source Project <initial-contribution@android.com> | 2008-10-21 07:00:00 -0700 |
commit | 9364f22aed35e1a1e9d07c121510f80be3ab0502 (patch) | |
tree | d49911209b132da58d838efa852daf28d516df21 /JavaScriptCore/pcre/pcre_compile.cpp | |
parent | 87eb0cb35bad8784770ebc807e6c982432e47107 (diff) | |
download | external_webkit-9364f22aed35e1a1e9d07c121510f80be3ab0502.zip external_webkit-9364f22aed35e1a1e9d07c121510f80be3ab0502.tar.gz external_webkit-9364f22aed35e1a1e9d07c121510f80be3ab0502.tar.bz2 |
Initial Contribution
Diffstat (limited to 'JavaScriptCore/pcre/pcre_compile.cpp')
-rw-r--r-- | JavaScriptCore/pcre/pcre_compile.cpp | 52 |
1 files changed, 46 insertions, 6 deletions
diff --git a/JavaScriptCore/pcre/pcre_compile.cpp b/JavaScriptCore/pcre/pcre_compile.cpp index fe027b1..49b9a58 100644 --- a/JavaScriptCore/pcre/pcre_compile.cpp +++ b/JavaScriptCore/pcre/pcre_compile.cpp @@ -1985,13 +1985,27 @@ static int bracketFindFirstAssertedCharacter(const unsigned char* code, bool ina return c; } +static inline int multiplyWithOverflowCheck(int a, int b) +{ + if (!a || !b) + return 0; + if (a > MAX_PATTERN_SIZE / b) + return -1; + return a * b; +} + static int calculateCompiledPatternLength(const UChar* pattern, int patternLength, JSRegExpIgnoreCaseOption ignoreCase, CompileData& cd, ErrorCode& errorcode) { /* Make a pass over the pattern to compute the amount of store required to hold the compiled code. This does not have to be perfect as long as errors are overestimates. */ - + + if (patternLength > MAX_PATTERN_SIZE) { + errorcode = ERR16; + return -1; + } + int length = 1 + LINK_SIZE; /* For initial BRA plus length */ int branch_extra = 0; int lastitemlength = 0; @@ -2413,9 +2427,21 @@ static int calculateCompiledPatternLength(const UChar* pattern, int patternLengt maxval-1 times; each replication acquires an OP_BRAZERO plus a nesting bracket set. */ + int repeatsLength; if (minRepeats == 0) { length++; - if (maxRepeats > 0) length += (maxRepeats - 1) * (duplength + 3 + 2 * LINK_SIZE); + if (maxRepeats > 0) { + repeatsLength = multiplyWithOverflowCheck(maxRepeats - 1, duplength + 3 + 2 * LINK_SIZE); + if (repeatsLength < 0) { + errorcode = ERR16; + return -1; + } + length += repeatsLength; + if (length > MAX_PATTERN_SIZE) { + errorcode = ERR16; + return -1; + } + } } /* When the minimum is greater than zero, we have to replicate up to @@ -2425,10 +2451,24 @@ static int calculateCompiledPatternLength(const UChar* pattern, int patternLengt but one of the optional copies. */ else { - length += (minRepeats - 1) * duplength; - if (maxRepeats > minRepeats) /* Need this test as maxRepeats=-1 means no limit */ - length += (maxRepeats - minRepeats) * (duplength + 3 + 2 * LINK_SIZE) - - (2 + 2 * LINK_SIZE); + repeatsLength = multiplyWithOverflowCheck(minRepeats - 1, duplength); + if (repeatsLength < 0) { + errorcode = ERR16; + return -1; + } + length += repeatsLength; + if (maxRepeats > minRepeats) { /* Need this test as maxRepeats=-1 means no limit */ + repeatsLength = multiplyWithOverflowCheck(maxRepeats - minRepeats, duplength + 3 + 2 * LINK_SIZE); + if (repeatsLength < 0) { + errorcode = ERR16; + return -1; + } + length += repeatsLength - (2 + 2 * LINK_SIZE); + } + if (length > MAX_PATTERN_SIZE) { + errorcode = ERR16; + return -1; + } } /* Allow space for once brackets for "possessive quantifier" */ |