Title: [259546] trunk
Revision
259546
Author
[email protected]
Date
2020-04-05 01:12:54 -0700 (Sun, 05 Apr 2020)

Log Message

Octal escapes should be max 3 digits and syntax errors in Unicode patterns
https://bugs.webkit.org/show_bug.cgi?id=167067

Reviewed by Ross Kirsling.

JSTests:

* test262/expectations.yaml: Mark 4 test cases as passing.

Source/_javascript_Core:

This patch:

a) Adds SyntaxError for octal escapes in Unicode patterns, while preserving /\0/u
being parsed as null character escape. Grammar: https://tc39.es/ecma262/#prod-CharacterEscape

b) Limits consumeOctal() to 3 digits only, preventing it from consuming leading zeros.
Grammar: https://tc39.es/ecma262/#prod-annexB-LegacyOctalEscapeSequence

Both changes align JSC with V8 and SpiderMonkey.

* yarr/YarrErrorCode.cpp:
(JSC::Yarr::errorMessage):
(JSC::Yarr::errorToThrow):
* yarr/YarrErrorCode.h:
* yarr/YarrParser.h:
(JSC::Yarr::Parser::parseEscape):
(JSC::Yarr::Parser::consumeOctal):

LayoutTests:

* fast/regex/script-tests/pcre-test-1.js:
* js/regexp-unicode-expected.txt:
* js/script-tests/regexp-unicode.js:

Modified Paths

Diff

Modified: trunk/JSTests/ChangeLog (259545 => 259546)


--- trunk/JSTests/ChangeLog	2020-04-05 06:17:21 UTC (rev 259545)
+++ trunk/JSTests/ChangeLog	2020-04-05 08:12:54 UTC (rev 259546)
@@ -1,3 +1,12 @@
+2020-04-05  Alexey Shvayka  <[email protected]>
+
+        Octal escapes should be max 3 digits and syntax errors in Unicode patterns
+        https://bugs.webkit.org/show_bug.cgi?id=167067
+
+        Reviewed by Ross Kirsling.
+
+        * test262/expectations.yaml: Mark 4 test cases as passing.
+
 2020-04-04  Alexey Shvayka  <[email protected]>
 
         '\u' should throw an early SyntaxError exception, but instead evaluates to 'u'

Modified: trunk/JSTests/test262/expectations.yaml (259545 => 259546)


--- trunk/JSTests/test262/expectations.yaml	2020-04-05 06:17:21 UTC (rev 259545)
+++ trunk/JSTests/test262/expectations.yaml	2020-04-05 08:12:54 UTC (rev 259546)
@@ -609,9 +609,6 @@
   default: 'Test262Error: An initialized binding is not created prior to evaluation Expected a ReferenceError to be thrown but no exception was thrown at all'
 test/annexB/language/global-code/switch-dflt-global-skip-early-err.js:
   default: "SyntaxError: Cannot declare a function that shadows a let/const/class/function variable 'f' in strict mode."
-test/annexB/language/literals/regexp/legacy-octal-escape.js:
-  default: "TypeError: null is not an object (evaluating '/\\0111/.exec('\\x091')[0]')"
-  strict mode: "TypeError: null is not an object (evaluating '/\\0111/.exec('\\x091')[0]')"
 test/annexB/language/statements/for-of/iterator-close-return-emulates-undefined-throws-when-called.js:
   default: 'Test262Error: Expected a TypeError to be thrown but no exception was thrown at all'
   strict mode: 'Test262Error: Expected a TypeError to be thrown but no exception was thrown at all'
@@ -1702,9 +1699,6 @@
 test/built-ins/RegExp/quantifier-integer-limit.js:
   default: 'SyntaxError: Invalid regular _expression_: number too large in {} quantifier'
   strict mode: 'SyntaxError: Invalid regular _expression_: number too large in {} quantifier'
-test/built-ins/RegExp/unicode_restricted_octal_escape.js:
-  default: 'Test262Error: RegExp("[\1]", "u"):  Expected a SyntaxError to be thrown but no exception was thrown at all'
-  strict mode: 'Test262Error: RegExp("[\1]", "u"):  Expected a SyntaxError to be thrown but no exception was thrown at all'
 test/built-ins/Set/proto-from-ctor-realm.js:
   default: 'Test262Error: Expected SameValue(«[object Set]», «[object Set]») to be true'
   strict mode: 'Test262Error: Expected SameValue(«[object Set]», «[object Set]») to be true'

Modified: trunk/LayoutTests/ChangeLog (259545 => 259546)


--- trunk/LayoutTests/ChangeLog	2020-04-05 06:17:21 UTC (rev 259545)
+++ trunk/LayoutTests/ChangeLog	2020-04-05 08:12:54 UTC (rev 259546)
@@ -1,3 +1,14 @@
+2020-04-05  Alexey Shvayka  <[email protected]>
+
+        Octal escapes should be max 3 digits and syntax errors in Unicode patterns
+        https://bugs.webkit.org/show_bug.cgi?id=167067
+
+        Reviewed by Ross Kirsling.
+
+        * fast/regex/script-tests/pcre-test-1.js:
+        * js/regexp-unicode-expected.txt:
+        * js/script-tests/regexp-unicode.js:
+
 2020-04-04  Lauro Moura  <[email protected]>
 
         [GTK] Update test baseline after r259438 and garden crashes

Modified: trunk/LayoutTests/fast/regex/script-tests/pcre-test-1.js (259545 => 259546)


--- trunk/LayoutTests/fast/regex/script-tests/pcre-test-1.js	2020-04-05 06:17:21 UTC (rev 259545)
+++ trunk/LayoutTests/fast/regex/script-tests/pcre-test-1.js	2020-04-05 08:12:54 UTC (rev 259546)
@@ -994,11 +994,11 @@
 shouldBe('regex63.exec(input0);', 'results');
 
 var regex64 = /abc\0def\00pqr\000xyz\0000AB/;
-var input0 = "abc\0def\0pqr\0xyz\0AB";
-var results = ["abc\0def\0pqr\0xyz\0AB"];
+var input0 = "abc\0def\0pqr\0xyz\0" + "0AB";
+var results = ["abc\0def\0pqr\0xyz\0" + "0AB"];
 shouldBe('regex64.exec(input0);', 'results');
-var input1 = "abc456 abc\0def\0pqr\0xyz\0ABCDE";
-var results = ["abc\0def\0pqr\0xyz\0AB"];
+var input1 = "abc456 abc\0def\0pqr\0xyz\0" + "0ABCDE";
+var results = ["abc\0def\0pqr\0xyz\0" + "0AB"];
 shouldBe('regex64.exec(input1);', 'results');
 
 var regex65 = /abc\x0def\x00pqr\x000xyz\x0000AB/;

Modified: trunk/LayoutTests/js/regexp-unicode-expected.txt (259545 => 259546)


--- trunk/LayoutTests/js/regexp-unicode-expected.txt	2020-04-05 06:17:21 UTC (rev 259545)
+++ trunk/LayoutTests/js/regexp-unicode-expected.txt	2020-04-05 08:12:54 UTC (rev 259546)
@@ -183,6 +183,9 @@
 PASS /{/u threw exception SyntaxError: Invalid regular _expression_: incomplete {} quantifier for Unicode pattern.
 PASS /[a-\d]/u threw exception SyntaxError: Invalid regular _expression_: invalid range in character class for Unicode pattern.
 PASS /]/u threw exception SyntaxError: Invalid regular _expression_: unmatched ] or } bracket for Unicode pattern.
+PASS /\5/u threw exception SyntaxError: Invalid regular _expression_: invalid backreference for Unicode pattern.
+PASS /\01/u threw exception SyntaxError: Invalid regular _expression_: invalid octal escape for Unicode pattern.
+PASS /[\23]/u threw exception SyntaxError: Invalid regular _expression_: invalid octal escape for Unicode pattern.
 PASS /\c9/u threw exception SyntaxError: Invalid regular _expression_: invalid \c escape for Unicode pattern.
 PASS r = new RegExp("\\-", "u") threw exception SyntaxError: Invalid regular _expression_: invalid escaped character for Unicode pattern.
 PASS r = new RegExp("\\a", "u") threw exception SyntaxError: Invalid regular _expression_: invalid escaped character for Unicode pattern.

Modified: trunk/LayoutTests/js/script-tests/regexp-unicode.js (259545 => 259546)


--- trunk/LayoutTests/js/script-tests/regexp-unicode.js	2020-04-05 06:17:21 UTC (rev 259545)
+++ trunk/LayoutTests/js/script-tests/regexp-unicode.js	2020-04-05 08:12:54 UTC (rev 259546)
@@ -232,6 +232,9 @@
 shouldThrow('/{/u', '"SyntaxError: Invalid regular _expression_: incomplete {} quantifier for Unicode pattern"');
 shouldThrow('/[a-\\d]/u', '"SyntaxError: Invalid regular _expression_: invalid range in character class for Unicode pattern"');
 shouldThrow('/]/u', '"SyntaxError: Invalid regular _expression_: unmatched ] or } bracket for Unicode pattern"');
+shouldThrow('/\\5/u', '"SyntaxError: Invalid regular _expression_: invalid backreference for Unicode pattern"');
+shouldThrow('/\\01/u', '"SyntaxError: Invalid regular _expression_: invalid octal escape for Unicode pattern"');
+shouldThrow('/[\\23]/u', '"SyntaxError: Invalid regular _expression_: invalid octal escape for Unicode pattern"');
 shouldThrow('/\\c9/u', '"SyntaxError: Invalid regular _expression_: invalid \\\\c escape for Unicode pattern"');
 
 var invalidEscapeException = "SyntaxError: Invalid regular _expression_: invalid escaped character for Unicode pattern";

Modified: trunk/Source/_javascript_Core/ChangeLog (259545 => 259546)


--- trunk/Source/_javascript_Core/ChangeLog	2020-04-05 06:17:21 UTC (rev 259545)
+++ trunk/Source/_javascript_Core/ChangeLog	2020-04-05 08:12:54 UTC (rev 259546)
@@ -1,3 +1,28 @@
+2020-04-05  Alexey Shvayka  <[email protected]>
+
+        Octal escapes should be max 3 digits and syntax errors in Unicode patterns
+        https://bugs.webkit.org/show_bug.cgi?id=167067
+
+        Reviewed by Ross Kirsling.
+
+        This patch:
+
+        a) Adds SyntaxError for octal escapes in Unicode patterns, while preserving /\0/u
+        being parsed as null character escape. Grammar: https://tc39.es/ecma262/#prod-CharacterEscape
+
+        b) Limits consumeOctal() to 3 digits only, preventing it from consuming leading zeros.
+        Grammar: https://tc39.es/ecma262/#prod-annexB-LegacyOctalEscapeSequence
+
+        Both changes align JSC with V8 and SpiderMonkey.
+
+        * yarr/YarrErrorCode.cpp:
+        (JSC::Yarr::errorMessage):
+        (JSC::Yarr::errorToThrow):
+        * yarr/YarrErrorCode.h:
+        * yarr/YarrParser.h:
+        (JSC::Yarr::Parser::parseEscape):
+        (JSC::Yarr::Parser::consumeOctal):
+
 2020-04-04  Keith Miller  <[email protected]>
 
         copy jsc CLI into _javascript_Core.framework earlier

Modified: trunk/Source/_javascript_Core/yarr/YarrErrorCode.cpp (259545 => 259546)


--- trunk/Source/_javascript_Core/yarr/YarrErrorCode.cpp	2020-04-05 06:17:21 UTC (rev 259545)
+++ trunk/Source/_javascript_Core/yarr/YarrErrorCode.cpp	2020-04-05 08:12:54 UTC (rev 259546)
@@ -56,6 +56,7 @@
         REGEXP_ERROR_PREFIX "invalid backreference for Unicode pattern",            // InvalidBackreference
         REGEXP_ERROR_PREFIX "invalid \\k<> named backreference",                    // InvalidNamedBackReference
         REGEXP_ERROR_PREFIX "invalid escaped character for Unicode pattern",        // InvalidIdentityEscape
+        REGEXP_ERROR_PREFIX "invalid octal escape for Unicode pattern",             // InvalidOctalEscape
         REGEXP_ERROR_PREFIX "invalid \\c escape for Unicode pattern",               // InvalidControlLetterEscape
         REGEXP_ERROR_PREFIX "invalid property _expression_",                          // InvalidUnicodePropertyExpression
         REGEXP_ERROR_PREFIX "too many nested disjunctions",                         // TooManyDisjunctions
@@ -92,6 +93,7 @@
     case ErrorCode::InvalidBackreference:
     case ErrorCode::InvalidNamedBackReference:
     case ErrorCode::InvalidIdentityEscape:
+    case ErrorCode::InvalidOctalEscape:
     case ErrorCode::InvalidControlLetterEscape:
     case ErrorCode::InvalidUnicodePropertyExpression:
     case ErrorCode::OffsetTooLarge:

Modified: trunk/Source/_javascript_Core/yarr/YarrErrorCode.h (259545 => 259546)


--- trunk/Source/_javascript_Core/yarr/YarrErrorCode.h	2020-04-05 06:17:21 UTC (rev 259545)
+++ trunk/Source/_javascript_Core/yarr/YarrErrorCode.h	2020-04-05 08:12:54 UTC (rev 259546)
@@ -55,6 +55,7 @@
     InvalidBackreference,
     InvalidNamedBackReference,
     InvalidIdentityEscape,
+    InvalidOctalEscape,
     InvalidControlLetterEscape,
     InvalidUnicodePropertyExpression,
     TooManyDisjunctions,

Modified: trunk/Source/_javascript_Core/yarr/YarrParser.h (259545 => 259546)


--- trunk/Source/_javascript_Core/yarr/YarrParser.h	2020-04-05 06:17:21 UTC (rev 259545)
+++ trunk/Source/_javascript_Core/yarr/YarrParser.h	2020-04-05 08:12:54 UTC (rev 259546)
@@ -322,6 +322,23 @@
             delegate.atomBuiltInCharacterClass(BuiltInCharacterClassID::WordClassID, true);
             break;
 
+        case '0': {
+            consume();
+
+            if (!peekIsDigit()) {
+                delegate.atomPatternCharacter(0);
+                break;
+            }
+
+            if (m_isUnicode) {
+                m_errorCode = ErrorCode::InvalidOctalEscape;
+                break;
+            }
+
+            delegate.atomPatternCharacter(consumeOctal(2));
+            break;
+        }
+
         // DecimalEscape
         case '1':
         case '2':
@@ -332,7 +349,7 @@
         case '7':
         case '8':
         case '9': {
-            // To match Firefox, we parse an invalid backreference in the range [1-7] as an octal escape.
+            // For non-Unicode patterns, invalid backreferences are parsed as octal or decimal escapes.
             // First, try to parse this as backreference.
             if (!inCharacterClass) {
                 ParseState state = saveState();
@@ -345,23 +362,21 @@
                 }
 
                 restoreState(state);
+                if (m_isUnicode) {
+                    m_errorCode = ErrorCode::InvalidBackreference;
+                    break;
+                }
             }
 
-            // Not a backreference, and not octal. Just a number.
-            if (peek() >= '8') {
-                delegate.atomPatternCharacter(consume());
+            if (m_isUnicode) {
+                m_errorCode = ErrorCode::InvalidOctalEscape;
                 break;
             }
 
-            // Fall-through to handle this as an octal escape.
-            FALLTHROUGH;
+            delegate.atomPatternCharacter(peek() < '8' ? consumeOctal(3) : consume());
+            break;
         }
 
-        // Octal escape
-        case '0':
-            delegate.atomPatternCharacter(consumeOctal());
-            break;
-
         // ControlEscape
         case 'f':
             consume();
@@ -1066,14 +1081,13 @@
         return n.hasOverflowed() ? quantifyInfinite : n.unsafeGet();
     }
 
-    unsigned consumeOctal()
+    // https://tc39.es/ecma262/#prod-annexB-LegacyOctalEscapeSequence
+    unsigned consumeOctal(unsigned count)
     {
-        ASSERT(WTF::isASCIIOctalDigit(peek()));
-
-        unsigned n = consumeDigit();
-        while (n < 32 && !atEndOfPattern() && WTF::isASCIIOctalDigit(peek()))
-            n = n * 8 + consumeDigit();
-        return n;
+        unsigned octal = 0;
+        while (count-- && octal < 32 && !atEndOfPattern() && WTF::isASCIIOctalDigit(peek()))
+            octal = octal * 8 + consumeDigit();
+        return octal;
     }
 
     bool tryConsume(UChar ch)
_______________________________________________
webkit-changes mailing list
[email protected]
https://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to