Show
Ignore:
Timestamp:
03/27/08 23:41:17 (8 months ago)
Author:
mrowe@apple.com
Message:

2008-03-27 Darin Adler <darin@apple.com>

Reviewed by Mark Rowe.

<rdar://problem/5826236> Regular expressions with large nested repetition counts can have their
compiled length calculated incorrectly.

  • pcre/pcre_compile.cpp: (multiplyWithOverflowCheck): (calculateCompiledPatternLength): Check for overflow when dealing with nested repetition counts and bail with an error rather than returning incorrect results.

2008-03-27 Mark Rowe <mrowe@apple.com>

Reviewed by Adam Roben.

Tests for <rdar://problem/5826236> Regular expressions with large nested repetition counts can have their
compiled length calculated incorrectly.

  • fast/js/regexp-overflow-expected.txt:
  • fast/js/resources/regexp-overflow.js:
Files:
1 modified

Legend:

Unmodified
Added
Removed
  • trunk/JavaScriptCore/pcre/pcre_compile.cpp

    r29110 r31388  
    19861986} 
    19871987 
     1988static inline int multiplyWithOverflowCheck(int a, int b) 
     1989{ 
     1990    if (!a || !b) 
     1991        return 0; 
     1992    if (a > MAX_PATTERN_SIZE / b) 
     1993        return -1; 
     1994    return a * b; 
     1995} 
     1996 
    19881997static int calculateCompiledPatternLength(const UChar* pattern, int patternLength, JSRegExpIgnoreCaseOption ignoreCase, 
    19891998    CompileData& cd, ErrorCode& errorcode) 
     
    19922001     amount of store required to hold the compiled code. This does not have to be 
    19932002     perfect as long as errors are overestimates. */ 
    1994      
     2003 
     2004    if (patternLength > MAX_PATTERN_SIZE) { 
     2005        errorcode = ERR16; 
     2006        return -1; 
     2007    } 
     2008 
    19952009    int length = 1 + LINK_SIZE;      /* For initial BRA plus length */ 
    19962010    int branch_extra = 0; 
     
    24142428                 bracket set. */ 
    24152429                 
     2430                int repeatsLength; 
    24162431                if (minRepeats == 0) { 
    24172432                    length++; 
    2418                     if (maxRepeats > 0) length += (maxRepeats - 1) * (duplength + 3 + 2 * LINK_SIZE); 
     2433                    if (maxRepeats > 0) { 
     2434                        repeatsLength = multiplyWithOverflowCheck(maxRepeats - 1, duplength + 3 + 2 * LINK_SIZE); 
     2435                        if (repeatsLength < 0) { 
     2436                            errorcode = ERR16; 
     2437                            return -1; 
     2438                        } 
     2439                        length += repeatsLength; 
     2440                        if (length > MAX_PATTERN_SIZE) { 
     2441                            errorcode = ERR16; 
     2442                            return -1; 
     2443                        } 
     2444                    } 
    24192445                } 
    24202446                 
     
    24262452                 
    24272453                else { 
    2428                     length += (minRepeats - 1) * duplength; 
    2429                     if (maxRepeats > minRepeats)   /* Need this test as maxRepeats=-1 means no limit */ 
    2430                         length += (maxRepeats - minRepeats) * (duplength + 3 + 2 * LINK_SIZE) 
    2431                         - (2 + 2 * LINK_SIZE); 
     2454                    repeatsLength = multiplyWithOverflowCheck(minRepeats - 1, duplength); 
     2455                    if (repeatsLength < 0) { 
     2456                        errorcode = ERR16; 
     2457                        return -1; 
     2458                    } 
     2459                    length += repeatsLength; 
     2460                    if (maxRepeats > minRepeats) { /* Need this test as maxRepeats=-1 means no limit */ 
     2461                        repeatsLength = multiplyWithOverflowCheck(maxRepeats - minRepeats, duplength + 3 + 2 * LINK_SIZE); 
     2462                        if (repeatsLength < 0) { 
     2463                            errorcode = ERR16; 
     2464                            return -1; 
     2465                        } 
     2466                        length += repeatsLength - (2 + 2 * LINK_SIZE); 
     2467                    } 
     2468                    if (length > MAX_PATTERN_SIZE) { 
     2469                        errorcode = ERR16; 
     2470                        return -1; 
     2471                    } 
    24322472                } 
    24332473