JavaScriptCore:
authordarin@apple.com <darin@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Mon, 17 Dec 2007 01:26:54 +0000 (01:26 +0000)
committerdarin@apple.com <darin@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Mon, 17 Dec 2007 01:26:54 +0000 (01:26 +0000)
        Reviewed by Maciej.

        - fix http://bugs.webkit.org/show_bug.cgi?id=16459
          REGRESSION: assertion failure with regexp with \B in a case-ignoring character range
          <rdar://problem/5646361>

        The problem was that \B was not handled properly in character classes.

        Test: fast/js/regexp-overflow.html

        * pcre/pcre_compile.cpp:
        (check_escape): Added handling of ESC_b and ESC_B in character classes here.
        Allows us to get rid of the handling of \b in character classes from all the
        call sites that handle it separately and to handle \B properly as well.
        (compileBranch): Remove the ESC_b handling, since it's not needed any more.
        (calculateCompiledPatternLengthAndFlags): Ditto.

LayoutTests:

        Reviewed by Maciej.

        - test for http://bugs.webkit.org/show_bug.cgi?id=16459
          REGRESSION: assertion failure with regexp with \B in a case-ignoring character range
          <rdar://problem/5646361>

        * fast/js/regexp-overflow-expected.txt: Updated.
        * fast/js/resources/regexp-overflow.js: Added test cases.

git-svn-id: https://svn.webkit.org/repository/webkit/trunk@28785 268f45cc-cd09-0410-ab3c-d52691b4dbfc

JavaScriptCore/ChangeLog
JavaScriptCore/pcre/pcre_compile.cpp
LayoutTests/ChangeLog
LayoutTests/fast/js/regexp-overflow-expected.txt
LayoutTests/fast/js/resources/regexp-overflow.js

index 161bb286eda564abd3a6cca5e7156b6eab5e6731..af137aa8d97132dfe03452f928992b580a8aec94 100644 (file)
@@ -1,3 +1,22 @@
+2007-12-16  Darin Adler  <darin@apple.com>
+
+        Reviewed by Maciej.
+
+        - fix http://bugs.webkit.org/show_bug.cgi?id=16459
+          REGRESSION: assertion failure with regexp with \B in a case-ignoring character range
+          <rdar://problem/5646361>
+
+        The problem was that \B was not handled properly in character classes.
+
+        Test: fast/js/regexp-overflow.html
+
+        * pcre/pcre_compile.cpp:
+        (check_escape): Added handling of ESC_b and ESC_B in character classes here.
+        Allows us to get rid of the handling of \b in character classes from all the
+        call sites that handle it separately and to handle \B properly as well.
+        (compileBranch): Remove the ESC_b handling, since it's not needed any more.
+        (calculateCompiledPatternLengthAndFlags): Ditto.
+
 2007-12-16  Mark Rowe  <mrowe@apple.com>
 
         Reviewed by Maciej Stachowiak.
index a70577a2ef09c9bccfdc49244b2d90b2300d3c5d..473c5243069c6791d2c5ec5b61189d9ec1606a8a 100644 (file)
@@ -196,12 +196,17 @@ static int check_escape(const UChar** ptrptr, const UChar* patternEnd, ErrorCode
      Otherwise further processing may be required. */
     
     if (c < '0' || c > 'z') { /* Not alphameric */
-    } else if (int escapeValue = escapes[c - '0'])
+    } else if (int escapeValue = escapes[c - '0']) {
         c = escapeValue;
-    
+        if (isclass) {
+            if (-c == ESC_b)
+                c = '\b'; /* \b is backslash in a class */
+            else if (-c == ESC_B)
+                c = 'B'; /* and \B is a capital B in a class (in browsers event though ECMAScript 15.10.2.19 says it raises an error) */
+        }
     /* Escapes that need further processing, or are illegal. */
     
-    else {
+    else {
         switch (c) {
         case '1':
         case '2':
@@ -934,10 +939,6 @@ compileBranch(int options, int* brackets, uschar** codeptr,
                     
                     if (c == '\\') {
                         c = check_escape(&ptr, patternEnd, errorcodeptr, *brackets, true);
-                        
-                        if (-c == ESC_b)
-                            c = '\b';       /* \b is backslash in a class */
-                        
                         if (c < 0) {
                             class_charcount += 2;     /* Greater than 1 is what matters */
                             switch (-c) {
@@ -1006,16 +1007,10 @@ compileBranch(int options, int* brackets, uschar** codeptr,
                             const UChar* oldptr = ptr;
                             d = check_escape(&ptr, patternEnd, errorcodeptr, *brackets, true);
                             
-                            /* \b is backslash; \X is literal X; any other special means the '-'
-                             was literal */
-                            
+                            /* \X is literal X; any other special means the '-' was literal */
                             if (d < 0) {
-                                if (d == -ESC_b)
-                                    d = '\b';
-                                else {
-                                    ptr = oldptr - 2;
-                                    goto LONE_SINGLE_CHARACTER;  /* A few lines below */
-                                }
+                                ptr = oldptr - 2;
+                                goto LONE_SINGLE_CHARACTER;  /* A few lines below */
                             }
                         }
                         
@@ -2374,11 +2369,6 @@ static int calculateCompiledPatternLengthAndFlags(const UChar* pattern, int patt
                         if (errorcode != 0)
                             return -1;
                         
-                        /* \b is backspace inside a class; \X is literal */
-                        
-                        if (-c == ESC_b)
-                            c = '\b';
-                        
                         /* Handle escapes that turn into characters */
                         
                         if (c >= 0)
@@ -2413,8 +2403,6 @@ static int calculateCompiledPatternLengthAndFlags(const UChar* pattern, int patt
                                 d = check_escape(&ptr, patternEnd, &errorcode, bracount, true);
                                 if (errorcode != 0)
                                     return -1;
-                                if (-d == ESC_b)
-                                    d = '\b';        /* backspace */
                             }
                             else if ((ptr + 1 < patternEnd) && ptr[1] != ']')
                                 d = *++ptr;
index a6976507a4c11f711ce016cae3c848f646704b3c..c0dd164902e50db7f9a6d525b15566eb5c9cdbbf 100644 (file)
@@ -1,3 +1,14 @@
+2007-12-16  Darin Adler  <darin@apple.com>
+
+        Reviewed by Maciej.
+
+        - test for http://bugs.webkit.org/show_bug.cgi?id=16459
+          REGRESSION: assertion failure with regexp with \B in a case-ignoring character range
+          <rdar://problem/5646361>
+
+        * fast/js/regexp-overflow-expected.txt: Updated.
+        * fast/js/resources/regexp-overflow.js: Added test cases.
+
 2007-12-16  Darin Adler  <darin@apple.com>
 
         Reviewed by Maciej.
index 835be2341ca8d1c90a57935c2231c75edfb6056a..e9e7f38c6f4c389df4ba676d84977719d00fc0f0 100644 (file)
@@ -10,6 +10,8 @@ PASS /\[["'\s]{0,1}([\w-]*)["'\s]{0,1}([\W]{0,1}=){0,2}["'\s]{0,1}([\w-]*)["'\s]
 PASS /(x){0,2}/.exec("").toString() is ","
 PASS /[¡]{4,6}/.exec("¡¡¡¡").toString() is "¡¡¡¡"
 PASS /[¡]{1,100}[¡]{1,100}[¡]{1,100}[¡]{1,100}[¡]{1,100}[¡]{1,100}[¡]{1,100}[¡]{1,100}/.exec("¡¡¡¡¡¡¡¡").toString() is "¡¡¡¡¡¡¡¡"
+PASS /{([\D-\ca]]„£µ+?)}|[[\B-\u00d4]√π- ]]]{0,3}/i threw exception SyntaxError: Invalid regular expression: \B in character class.
+PASS /|[x\B-\u00b5]/i threw exception SyntaxError: Invalid regular expression: \B in character class.
 
 PASS successfullyParsed is true
 
index 7ced4f1b61dac3a13341d06cb7ee484e71209ff8..3a5f5d97e65123e0550443222cdb2eba2fc7f3a4 100644 (file)
@@ -17,6 +17,9 @@ shouldBe('/(x){0,2}/.exec("").toString()', '","');
 shouldBe('/[\u00A1]{4,6}/.exec("\u00A1\u00A1\u00A1\u00A1").toString()', '"\u00A1\u00A1\u00A1\u00A1"');
 shouldBe('/[\u00A1]{1,100}[\u00A1]{1,100}[\u00A1]{1,100}[\u00A1]{1,100}[\u00A1]{1,100}[\u00A1]{1,100}[\u00A1]{1,100}[\u00A1]{1,100}/.exec("\u00A1\u00A1\u00A1\u00A1\u00A1\u00A1\u00A1\u00A1").toString()', '"\u00A1\u00A1\u00A1\u00A1\u00A1\u00A1\u00A1\u00A1"');
 
+shouldBe('/{([\\D-\\ca]]„£µ+?)}|[[\\B-\\u00d4]√π- ]]]{0,3}/i.exec("B√π- ]]").toString()', '"B√π- ]],"');
+shouldBe('/|[x\\B-\\u00b5]/i.exec("").toString()', '""');
+
 debug('');
 
 var successfullyParsed = true;