Changeset 28833 in webkit


Ignore:
Timestamp:
Dec 18, 2007 11:30:05 AM (16 years ago)
Author:
Darin Adler
Message:

JavaScriptCore:

Reviewed by Geoff.

Test: fast/regex/slow.html

Slows down SunSpider a bit (about 1.01x); filed a bug to follow up on that:
http://bugs.webkit.org/show_bug.cgi?id=16503

  • pcre/pcre.h: Changed name of error code to not specifically mention "recursion".
  • pcre/pcre_exec.cpp: (match): Replaced the depth limit, MATCH_RECURSION_LIMIT, with a total match looping limit, matchLimit. Also eliminated the constants for MATCH_MATCH and MATCH_NOMATCH, since they are just true and false (1 and 0). (jsRegExpExecute): More of the MATCH_MATCH change.

LayoutTests:

Reviewed by Geoff.

  • fast/regex/resources: Added.
  • fast/regex/resources/TEMPLATE.html: Copied from fast/js/resources/TEMPLATE.html.
  • fast/regex/resources/slow.js: Added.
  • fast/regex/slow-expected.txt: Added.
  • fast/regex/slow.html: Added.
Location:
trunk
Files:
4 added
4 edited
1 copied

Legend:

Unmodified
Added
Removed
  • trunk/JavaScriptCore/ChangeLog

    r28799 r28833  
     12007-12-18  Darin Adler  <darin@apple.com>
     2
     3        Reviewed by Geoff.
     4
     5        - test for http://bugs.webkit.org/show_bug.cgi?id=16458
     6          REGRESSION (r28164): regular expressions can now hang due to lack of a match limit
     7          <rdar://problem/5636067>
     8
     9        Test: fast/regex/slow.html
     10
     11        Slows down SunSpider a bit (about 1.01x); filed a bug to follow up on that:
     12        http://bugs.webkit.org/show_bug.cgi?id=16503
     13
     14        * pcre/pcre.h: Changed name of error code to not specifically mention "recursion".
     15        * pcre/pcre_exec.cpp:
     16        (match): Replaced the depth limit, MATCH_RECURSION_LIMIT, with a total match looping
     17        limit, matchLimit. Also eliminated the constants for MATCH_MATCH and MATCH_NOMATCH,
     18        since they are just true and false (1 and 0).
     19        (jsRegExpExecute): More of the MATCH_MATCH change.
     20
    1212007-12-17  Darin Adler  <darin@apple.com>
    222
  • trunk/JavaScriptCore/pcre/pcre.h

    r28578 r28833  
    5252/* jsRegExpExecute error codes */
    5353const int JSRegExpErrorNoMatch = -1;
    54 const int JSRegExpErrorRecursionLimit = -2;
     54const int JSRegExpErrorHitLimit = -2;
    5555const int JSRegExpErrorNoMemory = -3;
    5656const int JSRegExpErrorInternal = -4;
  • trunk/JavaScriptCore/pcre/pcre_exec.cpp

    r28799 r28833  
    122122};
    123123
    124 /* Non-error returns from the match() function. Error returns are externally
    125 defined error codes, which are all negative. */
    126 
    127 #define MATCH_MATCH        1
    128 #define MATCH_NOMATCH      0
    129 
    130124/* The maximum remaining length of subject we are prepared to search for a
    131125req_byte match. */
     
    133127#define REQ_BYTE_MAX 1000
    134128
    135 /* The below limit restricts the number of recursive match calls in order to
    136 limit the maximum amount of storage.
    137  
    138 This limit is tied to the size of MatchFrame.  Right now we allow PCRE to allocate up
    139 to MATCH_RECURSION_LIMIT - 16 * sizeof(MatchFrame) bytes of "stack" space before we give up.
    140 Currently that's 100000 - 16 * (23 * 4)  ~ 90MB. */
    141 
    142 #define MATCH_RECURSION_LIMIT 100000
     129/* The below limit restricts the number of "recursive" match calls in order to
     130avoid spending exponential time on complex regular expressions. */
     131
     132static const unsigned matchLimit = 100000;
    143133
    144134#ifdef DEBUG
     
    252242
    253243#define RECURSIVE_MATCH_COMMON(num) \
    254     if (stack.size >= MATCH_RECURSION_LIMIT) \
    255         return matchError(JSRegExpErrorRecursionLimit, stack); \
    256244    goto RECURSE;\
    257245    RRETURN_##num: \
     
    292280   md          pointer to "static" info for the match
    293281
    294 Returns:       MATCH_MATCH if matched            )  these values are >= 0
    295                MATCH_NOMATCH if failed to match  )
     282Returns:       1 if matched          )  these values are >= 0
     283               0 if failed to match  )
    296284               a negative error value if aborted by an error condition
    297285                 (e.g. stopped by repeated call or recursion limit)
     
    408396static int match(const UChar* subjectPtr, const unsigned char* instructionPtr, int offsetTop, MatchData& md)
    409397{
    410     int isMatch = false;
     398    bool isMatch = false;
    411399    int min;
    412400    bool minimize = false; /* Initialization not really needed, but some compilers think so. */
     401    unsigned matchCount = 0;
    413402   
    414403    MatchStack stack;
     
    443432   
    444433RECURSE:
     434    if (++matchCount > matchLimit)
     435        return matchError(JSRegExpErrorHitLimit, stack);
    445436
    446437    /* Now start processing the operations. */
     
    564555               
    565556            /* End of a group, repeated or non-repeating. If we are at the end of
    566              an assertion "group", stop matching and return MATCH_MATCH, but record the
     557             an assertion "group", stop matching and return 1, but record the
    567558             current high water mark for use by positive assertions. Do this also
    568559             for the "once" (not-backup up) groups. */
     
    17801771   
    17811772RETURN:
    1782     ASSERT(isMatch == MATCH_MATCH || isMatch == MATCH_NOMATCH);
    17831773    return isMatch;
    17841774}
     
    20132003        /* When the result is no match, advance the pointer to the next character
    20142004         and continue. */
    2015        
    2016         if (returnCode == MATCH_NOMATCH) {
     2005        if (returnCode == false) {
    20172006            startMatch++;
    20182007            continue;
    20192008        }
    2020        
    2021         if (returnCode != MATCH_MATCH) {
     2009
     2010        if (returnCode != true) {
     2011            ASSERT(returnCode == JSRegExpErrorHitLimit || returnCode == JSRegExpErrorNoMemory);
    20222012            DPRINTF((">>>> error: returning %d\n", rc));
    20232013            return returnCode;
  • trunk/LayoutTests/ChangeLog

    r28831 r28833  
     12007-12-18  Darin Adler  <darin@apple.com>
     2
     3        Reviewed by Geoff.
     4
     5        - test for http://bugs.webkit.org/show_bug.cgi?id=16458
     6          REGRESSION (r28164): regular expressions can now hang due to lack of a match limit
     7
     8        * fast/regex/resources: Added.
     9        * fast/regex/resources/TEMPLATE.html: Copied from fast/js/resources/TEMPLATE.html.
     10        * fast/regex/resources/slow.js: Added.
     11        * fast/regex/slow-expected.txt: Added.
     12        * fast/regex/slow.html: Added.
     13
    1142007-12-18  Dan Bernstein  <mitz@apple.com>
    215
Note: See TracChangeset for help on using the changeset viewer.