⚠ Archived content — this site is no longer maintained.   Current WebKit documentation is at docs.webkit.org.

Changeset 259546 in webkit


Ignore:
Timestamp:
Apr 5, 2020, 1:12:54 AM (6 years ago)
Author:
Alexey Shvayka
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/JavaScriptCore:

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:
Location:
trunk
Files:
10 edited

Legend:

Unmodified
Added
Removed
  • trunk/JSTests/ChangeLog

    r259536 r259546  
     12020-04-05  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 Ross Kirsling.
     7
     8        * test262/expectations.yaml: Mark 4 test cases as passing.
     9
    1102020-04-04  Alexey Shvayka  <shvaikalesh@gmail.com>
    211
  • trunk/JSTests/test262/expectations.yaml

    r259536 r259546  
    610610test/annexB/language/global-code/switch-dflt-global-skip-early-err.js:
    611611  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]')"
    615612test/annexB/language/statements/for-of/iterator-close-return-emulates-undefined-throws-when-called.js:
    616613  default: 'Test262Error: Expected a TypeError to be thrown but no exception was thrown at all'
     
    17031700  default: 'SyntaxError: Invalid regular expression: number too large in {} quantifier'
    17041701  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'
    17081702test/built-ins/Set/proto-from-ctor-realm.js:
    17091703  default: 'Test262Error: Expected SameValue(«[object Set]», «[object Set]») to be true'
  • trunk/LayoutTests/ChangeLog

    r259542 r259546  
     12020-04-05  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 Ross Kirsling.
     7
     8        * fast/regex/script-tests/pcre-test-1.js:
     9        * js/regexp-unicode-expected.txt:
     10        * js/script-tests/regexp-unicode.js:
     11
    1122020-04-04  Lauro Moura  <lmoura@igalia.com>
    213
  • trunk/LayoutTests/fast/regex/script-tests/pcre-test-1.js

    r217408 r259546  
    995995
    996996var regex64 = /abc\0def\00pqr\000xyz\0000AB/;
    997 var input0 = "abc\0def\0pqr\0xyz\0AB";
    998 var results = ["abc\0def\0pqr\0xyz\0AB"];
     997var input0 = "abc\0def\0pqr\0xyz\0" + "0AB";
     998var results = ["abc\0def\0pqr\0xyz\0" + "0AB"];
    999999shouldBe('regex64.exec(input0);', 'results');
    1000 var input1 = "abc456 abc\0def\0pqr\0xyz\0ABCDE";
    1001 var results = ["abc\0def\0pqr\0xyz\0AB"];
     1000var input1 = "abc456 abc\0def\0pqr\0xyz\0" + "0ABCDE";
     1001var results = ["abc\0def\0pqr\0xyz\0" + "0AB"];
    10021002shouldBe('regex64.exec(input1);', 'results');
    10031003
  • trunk/LayoutTests/js/regexp-unicode-expected.txt

    r259262 r259546  
    184184PASS /[a-\d]/u threw exception SyntaxError: Invalid regular expression: invalid range in character class for Unicode pattern.
    185185PASS /]/u threw exception SyntaxError: Invalid regular expression: unmatched ] or } bracket for Unicode pattern.
     186PASS /\5/u threw exception SyntaxError: Invalid regular expression: invalid backreference for Unicode pattern.
     187PASS /\01/u threw exception SyntaxError: Invalid regular expression: invalid octal escape for Unicode pattern.
     188PASS /[\23]/u threw exception SyntaxError: Invalid regular expression: invalid octal escape for Unicode pattern.
    186189PASS /\c9/u threw exception SyntaxError: Invalid regular expression: invalid \c escape for Unicode pattern.
    187190PASS r = new RegExp("\\-", "u") threw exception SyntaxError: Invalid regular expression: invalid escaped character for Unicode pattern.
  • trunk/LayoutTests/js/script-tests/regexp-unicode.js

    r259262 r259546  
    233233shouldThrow('/[a-\\d]/u', '"SyntaxError: Invalid regular expression: invalid range in character class for Unicode pattern"');
    234234shouldThrow('/]/u', '"SyntaxError: Invalid regular expression: unmatched ] or } bracket for Unicode pattern"');
     235shouldThrow('/\\5/u', '"SyntaxError: Invalid regular expression: invalid backreference for Unicode pattern"');
     236shouldThrow('/\\01/u', '"SyntaxError: Invalid regular expression: invalid octal escape for Unicode pattern"');
     237shouldThrow('/[\\23]/u', '"SyntaxError: Invalid regular expression: invalid octal escape for Unicode pattern"');
    235238shouldThrow('/\\c9/u', '"SyntaxError: Invalid regular expression: invalid \\\\c escape for Unicode pattern"');
    236239
  • trunk/Source/JavaScriptCore/ChangeLog

    r259545 r259546  
     12020-04-05  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 Ross Kirsling.
     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
    1262020-04-04  Keith Miller  <keith_miller@apple.com>
    227
  • trunk/Source/JavaScriptCore/yarr/YarrErrorCode.cpp

    r259262 r259546  
    5757        REGEXP_ERROR_PREFIX "invalid \\k<> named backreference",                    // InvalidNamedBackReference
    5858        REGEXP_ERROR_PREFIX "invalid escaped character for Unicode pattern",        // InvalidIdentityEscape
     59        REGEXP_ERROR_PREFIX "invalid octal escape for Unicode pattern",             // InvalidOctalEscape
    5960        REGEXP_ERROR_PREFIX "invalid \\c escape for Unicode pattern",               // InvalidControlLetterEscape
    6061        REGEXP_ERROR_PREFIX "invalid property expression",                          // InvalidUnicodePropertyExpression
     
    9394    case ErrorCode::InvalidNamedBackReference:
    9495    case ErrorCode::InvalidIdentityEscape:
     96    case ErrorCode::InvalidOctalEscape:
    9597    case ErrorCode::InvalidControlLetterEscape:
    9698    case ErrorCode::InvalidUnicodePropertyExpression:
  • trunk/Source/JavaScriptCore/yarr/YarrErrorCode.h

    r259262 r259546  
    5656    InvalidNamedBackReference,
    5757    InvalidIdentityEscape,
     58    InvalidOctalEscape,
    5859    InvalidControlLetterEscape,
    5960    InvalidUnicodePropertyExpression,
  • trunk/Source/JavaScriptCore/yarr/YarrParser.h

    r259262 r259546  
    323323            break;
    324324
     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
    325342        // DecimalEscape
    326343        case '1':
     
    333350        case '8':
    334351        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.
    336353            // First, try to parse this as backreference.
    337354            if (!inCharacterClass) {
     
    346363
    347364                restoreState(state);
    348             }
    349 
    350             // Not a backreference, and not octal. Just a number.
    351             if (peek() >= '8') {
    352                 delegate.atomPatternCharacter(consume());
    353                 break;
    354             }
    355 
    356             // Fall-through to handle this as an octal escape.
    357             FALLTHROUGH;
    358         }
    359 
    360         // Octal escape
    361         case '0':
    362             delegate.atomPatternCharacter(consumeOctal());
    363             break;
     365                if (m_isUnicode) {
     366                    m_errorCode = ErrorCode::InvalidBackreference;
     367                    break;
     368                }
     369            }
     370
     371            if (m_isUnicode) {
     372                m_errorCode = ErrorCode::InvalidOctalEscape;
     373                break;
     374            }
     375
     376            delegate.atomPatternCharacter(peek() < '8' ? consumeOctal(3) : consume());
     377            break;
     378        }
    364379
    365380        // ControlEscape
     
    10671082    }
    10681083
    1069     unsigned consumeOctal()
    1070     {
    1071         ASSERT(WTF::isASCIIOctalDigit(peek()));
    1072 
    1073         unsigned n = consumeDigit();
    1074         while (n < 32 && !atEndOfPattern() && WTF::isASCIIOctalDigit(peek()))
    1075             n = n * 8 + consumeDigit();
    1076         return n;
     1084    // https://tc39.es/ecma262/#prod-annexB-LegacyOctalEscapeSequence
     1085    unsigned consumeOctal(unsigned count)
     1086    {
     1087        unsigned octal = 0;
     1088        while (count-- && octal < 32 && !atEndOfPattern() && WTF::isASCIIOctalDigit(peek()))
     1089            octal = octal * 8 + consumeDigit();
     1090        return octal;
    10771091    }
    10781092
Note: See TracChangeset for help on using the changeset viewer.