| Differences between
and this patch
- a/Source/JavaScriptCore/ChangeLog +25 lines
Lines 1-3 a/Source/JavaScriptCore/ChangeLog_sec1
1
2020-04-04  Alexey Shvayka  <shvaikalesh@gmail.com>
2
3
        Octal escapes should be max 3 digits and syntax errors in Unicode patterns
4
        https://bugs.webkit.org/show_bug.cgi?id=167067
5
6
        Reviewed by NOBODY (OOPS!).
7
8
        This patch:
9
10
        a) Adds SyntaxError for octal escapes in Unicode patterns, while preserving /\0/u
11
        being parsed as null character escape. Grammar: https://tc39.es/ecma262/#prod-CharacterEscape
12
13
        b) Limits consumeOctal() to 3 digits only, preventing it from consuming leading zeros.
14
        Grammar: https://tc39.es/ecma262/#prod-annexB-LegacyOctalEscapeSequence
15
16
        Both changes align JSC with V8 and SpiderMonkey.
17
18
        * yarr/YarrErrorCode.cpp:
19
        (JSC::Yarr::errorMessage):
20
        (JSC::Yarr::errorToThrow):
21
        * yarr/YarrErrorCode.h:
22
        * yarr/YarrParser.h:
23
        (JSC::Yarr::Parser::parseEscape):
24
        (JSC::Yarr::Parser::consumeOctal):
25
1
2020-04-03  Yusuke Suzuki  <ysuzuki@apple.com>
26
2020-04-03  Yusuke Suzuki  <ysuzuki@apple.com>
2
27
3
        [JSC] canonicalizeLocaleList should gracefully throw OOM error if input + error message is too large
28
        [JSC] canonicalizeLocaleList should gracefully throw OOM error if input + error message is too large
- a/Source/JavaScriptCore/yarr/YarrErrorCode.cpp +2 lines
Lines 56-61 const char* errorMessage(ErrorCode error) a/Source/JavaScriptCore/yarr/YarrErrorCode.cpp_sec1
56
        REGEXP_ERROR_PREFIX "invalid backreference for Unicode pattern",            // InvalidBackreference
56
        REGEXP_ERROR_PREFIX "invalid backreference for Unicode pattern",            // InvalidBackreference
57
        REGEXP_ERROR_PREFIX "invalid \\k<> named backreference",                    // InvalidNamedBackReference
57
        REGEXP_ERROR_PREFIX "invalid \\k<> named backreference",                    // InvalidNamedBackReference
58
        REGEXP_ERROR_PREFIX "invalid escaped character for Unicode pattern",        // InvalidIdentityEscape
58
        REGEXP_ERROR_PREFIX "invalid escaped character for Unicode pattern",        // InvalidIdentityEscape
59
        REGEXP_ERROR_PREFIX "invalid octal escape for Unicode pattern",             // InvalidOctalEscape
59
        REGEXP_ERROR_PREFIX "invalid \\c escape for Unicode pattern",               // InvalidControlLetterEscape
60
        REGEXP_ERROR_PREFIX "invalid \\c escape for Unicode pattern",               // InvalidControlLetterEscape
60
        REGEXP_ERROR_PREFIX "invalid property expression",                          // InvalidUnicodePropertyExpression
61
        REGEXP_ERROR_PREFIX "invalid property expression",                          // InvalidUnicodePropertyExpression
61
        REGEXP_ERROR_PREFIX "too many nested disjunctions",                         // TooManyDisjunctions
62
        REGEXP_ERROR_PREFIX "too many nested disjunctions",                         // TooManyDisjunctions
Lines 92-97 JSObject* errorToThrow(JSGlobalObject* globalObject, ErrorCode error) a/Source/JavaScriptCore/yarr/YarrErrorCode.cpp_sec2
92
    case ErrorCode::InvalidBackreference:
93
    case ErrorCode::InvalidBackreference:
93
    case ErrorCode::InvalidNamedBackReference:
94
    case ErrorCode::InvalidNamedBackReference:
94
    case ErrorCode::InvalidIdentityEscape:
95
    case ErrorCode::InvalidIdentityEscape:
96
    case ErrorCode::InvalidOctalEscape:
95
    case ErrorCode::InvalidControlLetterEscape:
97
    case ErrorCode::InvalidControlLetterEscape:
96
    case ErrorCode::InvalidUnicodePropertyExpression:
98
    case ErrorCode::InvalidUnicodePropertyExpression:
97
    case ErrorCode::OffsetTooLarge:
99
    case ErrorCode::OffsetTooLarge:
- a/Source/JavaScriptCore/yarr/YarrErrorCode.h +1 lines
Lines 55-60 enum class ErrorCode : uint8_t { a/Source/JavaScriptCore/yarr/YarrErrorCode.h_sec1
55
    InvalidBackreference,
55
    InvalidBackreference,
56
    InvalidNamedBackReference,
56
    InvalidNamedBackReference,
57
    InvalidIdentityEscape,
57
    InvalidIdentityEscape,
58
    InvalidOctalEscape,
58
    InvalidControlLetterEscape,
59
    InvalidControlLetterEscape,
59
    InvalidUnicodePropertyExpression,
60
    InvalidUnicodePropertyExpression,
60
    TooManyDisjunctions,
61
    TooManyDisjunctions,
- a/Source/JavaScriptCore/yarr/YarrParser.h -18 / +32 lines
Lines 322-327 private: a/Source/JavaScriptCore/yarr/YarrParser.h_sec1
322
            delegate.atomBuiltInCharacterClass(BuiltInCharacterClassID::WordClassID, true);
322
            delegate.atomBuiltInCharacterClass(BuiltInCharacterClassID::WordClassID, true);
323
            break;
323
            break;
324
324
325
        case '0': {
326
            consume();
327
328
            if (!peekIsDigit()) {
329
                delegate.atomPatternCharacter(0);
330
                break;
331
            }
332
333
            if (m_isUnicode) {
334
                m_errorCode = ErrorCode::InvalidOctalEscape;
335
                break;
336
            }
337
338
            delegate.atomPatternCharacter(consumeOctal(2));
339
            break;
340
        }
341
325
        // DecimalEscape
342
        // DecimalEscape
326
        case '1':
343
        case '1':
327
        case '2':
344
        case '2':
Lines 332-338 private: a/Source/JavaScriptCore/yarr/YarrParser.h_sec2
332
        case '7':
349
        case '7':
333
        case '8':
350
        case '8':
334
        case '9': {
351
        case '9': {
335
            // To match Firefox, we parse an invalid backreference in the range [1-7] as an octal escape.
352
            // For non-Unicode patterns, invalid backreferences are parsed as octal or decimal escapes.
336
            // First, try to parse this as backreference.
353
            // First, try to parse this as backreference.
337
            if (!inCharacterClass) {
354
            if (!inCharacterClass) {
338
                ParseState state = saveState();
355
                ParseState state = saveState();
Lines 345-366 private: a/Source/JavaScriptCore/yarr/YarrParser.h_sec3
345
                }
362
                }
346
363
347
                restoreState(state);
364
                restoreState(state);
365
                if (m_isUnicode) {
366
                    m_errorCode = ErrorCode::InvalidBackreference;
367
                    break;
368
                }
348
            }
369
            }
349
370
350
            // Not a backreference, and not octal. Just a number.
371
            if (m_isUnicode) {
351
            if (peek() >= '8') {
372
                m_errorCode = ErrorCode::InvalidOctalEscape;
352
                delegate.atomPatternCharacter(consume());
353
                break;
373
                break;
354
            }
374
            }
355
375
356
            // Fall-through to handle this as an octal escape.
376
            delegate.atomPatternCharacter(peek() < '8' ? consumeOctal(3) : consume());
357
            FALLTHROUGH;
358
        }
359
360
        // Octal escape
361
        case '0':
362
            delegate.atomPatternCharacter(consumeOctal());
363
            break;
377
            break;
378
        }
364
379
365
        // ControlEscape
380
        // ControlEscape
366
        case 'f':
381
        case 'f':
Lines 1066-1079 private: a/Source/JavaScriptCore/yarr/YarrParser.h_sec4
1066
        return n.hasOverflowed() ? quantifyInfinite : n.unsafeGet();
1081
        return n.hasOverflowed() ? quantifyInfinite : n.unsafeGet();
1067
    }
1082
    }
1068
1083
1069
    unsigned consumeOctal()
1084
    // https://tc39.es/ecma262/#prod-annexB-LegacyOctalEscapeSequence
1085
    unsigned consumeOctal(unsigned count)
1070
    {
1086
    {
1071
        ASSERT(WTF::isASCIIOctalDigit(peek()));
1087
        unsigned octal = 0;
1072
1088
        while (count-- && octal < 32 && !atEndOfPattern() && WTF::isASCIIOctalDigit(peek()))
1073
        unsigned n = consumeDigit();
1089
            octal = octal * 8 + consumeDigit();
1074
        while (n < 32 && !atEndOfPattern() && WTF::isASCIIOctalDigit(peek()))
1090
        return octal;
1075
            n = n * 8 + consumeDigit();
1076
        return n;
1077
    }
1091
    }
1078
1092
1079
    bool tryConsume(UChar ch)
1093
    bool tryConsume(UChar ch)
- a/LayoutTests/ChangeLog +10 lines
Lines 1-3 a/LayoutTests/ChangeLog_sec1
1
2020-04-04  Alexey Shvayka  <shvaikalesh@gmail.com>
2
3
        Octal escapes should be max 3 digits and syntax errors in Unicode patterns
4
        https://bugs.webkit.org/show_bug.cgi?id=167067
5
6
        Reviewed by NOBODY (OOPS!).
7
8
        * js/regexp-unicode-expected.txt:
9
        * js/script-tests/regexp-unicode.js:
10
1
2020-04-03  Truitt Savell  <tsavell@apple.com>
11
2020-04-03  Truitt Savell  <tsavell@apple.com>
2
12
3
        Unreviewed, reverting r259440.
13
        Unreviewed, reverting r259440.
- a/LayoutTests/js/regexp-unicode-expected.txt +3 lines
Lines 183-188 PASS r = new RegExp("𐐅{2147483648}", "u") threw exception SyntaxError: Invali a/LayoutTests/js/regexp-unicode-expected.txt_sec1
183
PASS /{/u threw exception SyntaxError: Invalid regular expression: incomplete {} quantifier for Unicode pattern.
183
PASS /{/u threw exception SyntaxError: Invalid regular expression: incomplete {} quantifier for Unicode pattern.
184
PASS /[a-\d]/u threw exception SyntaxError: Invalid regular expression: invalid range in character class for Unicode pattern.
184
PASS /[a-\d]/u threw exception SyntaxError: Invalid regular expression: invalid range in character class for Unicode pattern.
185
PASS /]/u threw exception SyntaxError: Invalid regular expression: unmatched ] or } bracket for Unicode pattern.
185
PASS /]/u threw exception SyntaxError: Invalid regular expression: unmatched ] or } bracket for Unicode pattern.
186
PASS /\5/u threw exception SyntaxError: Invalid regular expression: invalid backreference for Unicode pattern.
187
PASS /\01/u threw exception SyntaxError: Invalid regular expression: invalid octal escape for Unicode pattern.
188
PASS /[\23]/u threw exception SyntaxError: Invalid regular expression: invalid octal escape for Unicode pattern.
186
PASS /\c9/u threw exception SyntaxError: Invalid regular expression: invalid \c escape for Unicode pattern.
189
PASS /\c9/u threw exception SyntaxError: Invalid regular expression: invalid \c escape for Unicode pattern.
187
PASS r = new RegExp("\\-", "u") threw exception SyntaxError: Invalid regular expression: invalid escaped character for Unicode pattern.
190
PASS r = new RegExp("\\-", "u") threw exception SyntaxError: Invalid regular expression: invalid escaped character for Unicode pattern.
188
PASS r = new RegExp("\\a", "u") threw exception SyntaxError: Invalid regular expression: invalid escaped character for Unicode pattern.
191
PASS r = new RegExp("\\a", "u") threw exception SyntaxError: Invalid regular expression: invalid escaped character for Unicode pattern.
- a/LayoutTests/js/script-tests/regexp-unicode.js +3 lines
Lines 232-237 shouldThrow('r = new RegExp("\u{10405}{2147483648}", "u")', '"SyntaxError: Inval a/LayoutTests/js/script-tests/regexp-unicode.js_sec1
232
shouldThrow('/{/u', '"SyntaxError: Invalid regular expression: incomplete {} quantifier for Unicode pattern"');
232
shouldThrow('/{/u', '"SyntaxError: Invalid regular expression: incomplete {} quantifier for Unicode pattern"');
233
shouldThrow('/[a-\\d]/u', '"SyntaxError: Invalid regular expression: invalid range in character class for Unicode pattern"');
233
shouldThrow('/[a-\\d]/u', '"SyntaxError: Invalid regular expression: invalid range in character class for Unicode pattern"');
234
shouldThrow('/]/u', '"SyntaxError: Invalid regular expression: unmatched ] or } bracket for Unicode pattern"');
234
shouldThrow('/]/u', '"SyntaxError: Invalid regular expression: unmatched ] or } bracket for Unicode pattern"');
235
shouldThrow('/\\5/u', '"SyntaxError: Invalid regular expression: invalid backreference for Unicode pattern"');
236
shouldThrow('/\\01/u', '"SyntaxError: Invalid regular expression: invalid octal escape for Unicode pattern"');
237
shouldThrow('/[\\23]/u', '"SyntaxError: Invalid regular expression: invalid octal escape for Unicode pattern"');
235
shouldThrow('/\\c9/u', '"SyntaxError: Invalid regular expression: invalid \\\\c escape for Unicode pattern"');
238
shouldThrow('/\\c9/u', '"SyntaxError: Invalid regular expression: invalid \\\\c escape for Unicode pattern"');
236
239
237
var invalidEscapeException = "SyntaxError: Invalid regular expression: invalid escaped character for Unicode pattern";
240
var invalidEscapeException = "SyntaxError: Invalid regular expression: invalid escaped character for Unicode pattern";
- a/JSTests/ChangeLog +9 lines
Lines 1-3 a/JSTests/ChangeLog_sec1
1
2020-04-04  Alexey Shvayka  <shvaikalesh@gmail.com>
2
3
        Octal escapes should be max 3 digits and syntax errors in Unicode patterns
4
        https://bugs.webkit.org/show_bug.cgi?id=167067
5
6
        Reviewed by NOBODY (OOPS!).
7
8
        * test262/expectations.yaml: Mark 4 test cases as passing.
9
1
2020-04-03  Alexey Shvayka  <shvaikalesh@gmail.com>
10
2020-04-03  Alexey Shvayka  <shvaikalesh@gmail.com>
2
11
3
        Update test262 to commit 62b8fce38971
12
        Update test262 to commit 62b8fce38971
- a/JSTests/test262/expectations.yaml -6 lines
Lines 609-617 test/annexB/language/global-code/switch-dflt-global-skip-early-err-try.js: a/JSTests/test262/expectations.yaml_sec1
609
  default: 'Test262Error: An initialized binding is not created prior to evaluation Expected a ReferenceError to be thrown but no exception was thrown at all'
609
  default: 'Test262Error: An initialized binding is not created prior to evaluation Expected a ReferenceError to be thrown but no exception was thrown at all'
610
test/annexB/language/global-code/switch-dflt-global-skip-early-err.js:
610
test/annexB/language/global-code/switch-dflt-global-skip-early-err.js:
611
  default: "SyntaxError: Cannot declare a function that shadows a let/const/class/function variable 'f' in strict mode."
611
  default: "SyntaxError: Cannot declare a function that shadows a let/const/class/function variable 'f' in strict mode."
612
test/annexB/language/literals/regexp/legacy-octal-escape.js:
613
  default: "TypeError: null is not an object (evaluating '/\\0111/.exec('\\x091')[0]')"
614
  strict mode: "TypeError: null is not an object (evaluating '/\\0111/.exec('\\x091')[0]')"
615
test/annexB/language/statements/for-of/iterator-close-return-emulates-undefined-throws-when-called.js:
612
test/annexB/language/statements/for-of/iterator-close-return-emulates-undefined-throws-when-called.js:
616
  default: 'Test262Error: Expected a TypeError to be thrown but no exception was thrown at all'
613
  default: 'Test262Error: Expected a TypeError to be thrown but no exception was thrown at all'
617
  strict mode: 'Test262Error: Expected a TypeError to be thrown but no exception was thrown at all'
614
  strict mode: 'Test262Error: Expected a TypeError to be thrown but no exception was thrown at all'
Lines 1702-1710 test/built-ins/RegExp/prototype/unicode/cross-realm.js: a/JSTests/test262/expectations.yaml_sec2
1702
test/built-ins/RegExp/quantifier-integer-limit.js:
1699
test/built-ins/RegExp/quantifier-integer-limit.js:
1703
  default: 'SyntaxError: Invalid regular expression: number too large in {} quantifier'
1700
  default: 'SyntaxError: Invalid regular expression: number too large in {} quantifier'
1704
  strict mode: 'SyntaxError: Invalid regular expression: number too large in {} quantifier'
1701
  strict mode: 'SyntaxError: Invalid regular expression: number too large in {} quantifier'
1705
test/built-ins/RegExp/unicode_restricted_octal_escape.js:
1706
  default: 'Test262Error: RegExp("[\1]", "u"):  Expected a SyntaxError to be thrown but no exception was thrown at all'
1707
  strict mode: 'Test262Error: RegExp("[\1]", "u"):  Expected a SyntaxError to be thrown but no exception was thrown at all'
1708
test/built-ins/Set/proto-from-ctor-realm.js:
1702
test/built-ins/Set/proto-from-ctor-realm.js:
1709
  default: 'Test262Error: Expected SameValue(«[object Set]», «[object Set]») to be true'
1703
  default: 'Test262Error: Expected SameValue(«[object Set]», «[object Set]») to be true'
1710
  strict mode: 'Test262Error: Expected SameValue(«[object Set]», «[object Set]») to be true'
1704
  strict mode: 'Test262Error: Expected SameValue(«[object Set]», «[object Set]») to be true'

Return to Bug 167067