Changeset 231939 in webkit


Ignore:
Timestamp:
May 17, 2018 7:59:31 PM (6 years ago)
Author:
msaboff@apple.com
Message:

We don't throw SyntaxErrors for runtime generated regular expressions with errors
https://bugs.webkit.org/show_bug.cgi?id=185755

Reviewed by Keith Miller.

JSTests:

New regression test.

  • stress/regexp-with-runtime-syntax-errors.js: Added.

(testThrowsSyntaxtError):
(fromExecWithBadUnicodeEscape):
(fromTestWithBadUnicodeProperty):
(fromSplitWithBadUnicodeIdentity):
(fromMatchWithBadUnicodeBackReference):
(fromReplaceWithBadUnicodeEscape):
(fromSearchWithBadUnicodeEscape):

Source/JavaScriptCore:

Added a new helper that creates the correct exception to throw for each type of error when
compiling a RegExp. Using that new helper, added missing checks for RegExp for the cases
where we create a new RegExp from an existing one. Also refactored other places that we
throw SyntaxErrors after a failed RegExp compile to use the new helper.

  • runtime/RegExp.h:
  • runtime/RegExpConstructor.cpp:

(JSC::regExpCreate):
(JSC::constructRegExp):

  • runtime/RegExpPrototype.cpp:

(JSC::regExpProtoFuncCompile):

  • yarr/YarrErrorCode.cpp:

(JSC::Yarr::errorToThrow):

  • yarr/YarrErrorCode.h:

LayoutTests:

Updated test and results from reporting a SyntaxError to an Out of memory error.

  • js/script-tests/stack-overflow-regexp.js:

(shouldThrow.recursiveCall):
(shouldThrow):
(recursiveCall):

  • js/stack-overflow-regexp-expected.txt:
Location:
trunk
Files:
1 added
12 edited

Legend:

Unmodified
Added
Removed
  • trunk/JSTests/ChangeLog

    r231886 r231939  
     12018-05-17  Michael Saboff  <msaboff@apple.com>
     2
     3        We don't throw SyntaxErrors for runtime generated regular expressions with errors
     4        https://bugs.webkit.org/show_bug.cgi?id=185755
     5
     6        Reviewed by Keith Miller.
     7
     8        New regression test.
     9
     10        * stress/regexp-with-runtime-syntax-errors.js: Added.
     11        (testThrowsSyntaxtError):
     12        (fromExecWithBadUnicodeEscape):
     13        (fromTestWithBadUnicodeProperty):
     14        (fromSplitWithBadUnicodeIdentity):
     15        (fromMatchWithBadUnicodeBackReference):
     16        (fromReplaceWithBadUnicodeEscape):
     17        (fromSearchWithBadUnicodeEscape):
     18
    1192018-05-16  Caio Lima  <ticaiolima@gmail.com>
    220
  • trunk/LayoutTests/ChangeLog

    r231937 r231939  
     12018-05-17  Michael Saboff  <msaboff@apple.com>
     2
     3        We don't throw SyntaxErrors for runtime generated regular expressions with errors
     4        https://bugs.webkit.org/show_bug.cgi?id=185755
     5
     6        Reviewed by Keith Miller.
     7
     8        Updated test and results from reporting a SyntaxError to an Out of memory error.
     9
     10        * js/script-tests/stack-overflow-regexp.js:
     11        (shouldThrow.recursiveCall):
     12        (shouldThrow):
     13        (recursiveCall):
     14        * js/stack-overflow-regexp-expected.txt:
     15
    1162018-05-17  Nan Wang  <n_wang@apple.com>
    217
  • trunk/LayoutTests/js/script-tests/stack-overflow-regexp.js

    r201412 r231939  
    22
    33// Base case.
    4 shouldThrow('new RegExp(Array(50000).join("(") + "a" + Array(50000).join(")"))', '"SyntaxError: Invalid regular expression: too many nested disjunctions"');
     4shouldThrow('new RegExp(Array(50000).join("(") + "a" + Array(50000).join(")"))', '"Error: Out of memory: Invalid regular expression: too many nested disjunctions"');
    55
    66{ // Verify that a deep JS stack does not help avoiding the error.
     
    88        if (!(depth % 10)) {
    99            debug("Creating RegExp at depth " + depth);
    10             shouldThrow('new RegExp(Array(50000).join("(") + "a" + Array(50000).join(")"))', '"SyntaxError: Invalid regular expression: too many nested disjunctions"');
     10            shouldThrow('new RegExp(Array(50000).join("(") + "a" + Array(50000).join(")"))', '"Error: Out of memory: Invalid regular expression: too many nested disjunctions"');
    1111        }
    1212        if (depth < 100) {
     
    2626        expression += ")(c))";
    2727    }
    28     shouldThrow('new RegExp(expression)', '"SyntaxError: Invalid regular expression: too many nested disjunctions"');
     28    shouldThrow('new RegExp(expression)', '"Error: Out of memory: Invalid regular expression: too many nested disjunctions"');
    2929}
  • trunk/LayoutTests/js/stack-overflow-regexp-expected.txt

    r201412 r231939  
    44
    55
    6 PASS new RegExp(Array(50000).join("(") + "a" + Array(50000).join(")")) threw exception SyntaxError: Invalid regular expression: too many nested disjunctions.
     6PASS new RegExp(Array(50000).join("(") + "a" + Array(50000).join(")")) threw exception Error: Out of memory: Invalid regular expression: too many nested disjunctions.
    77Creating RegExp at depth 0
    8 PASS new RegExp(Array(50000).join("(") + "a" + Array(50000).join(")")) threw exception SyntaxError: Invalid regular expression: too many nested disjunctions.
     8PASS new RegExp(Array(50000).join("(") + "a" + Array(50000).join(")")) threw exception Error: Out of memory: Invalid regular expression: too many nested disjunctions.
    99Creating RegExp at depth 10
    10 PASS new RegExp(Array(50000).join("(") + "a" + Array(50000).join(")")) threw exception SyntaxError: Invalid regular expression: too many nested disjunctions.
     10PASS new RegExp(Array(50000).join("(") + "a" + Array(50000).join(")")) threw exception Error: Out of memory: Invalid regular expression: too many nested disjunctions.
    1111Creating RegExp at depth 20
    12 PASS new RegExp(Array(50000).join("(") + "a" + Array(50000).join(")")) threw exception SyntaxError: Invalid regular expression: too many nested disjunctions.
     12PASS new RegExp(Array(50000).join("(") + "a" + Array(50000).join(")")) threw exception Error: Out of memory: Invalid regular expression: too many nested disjunctions.
    1313Creating RegExp at depth 30
    14 PASS new RegExp(Array(50000).join("(") + "a" + Array(50000).join(")")) threw exception SyntaxError: Invalid regular expression: too many nested disjunctions.
     14PASS new RegExp(Array(50000).join("(") + "a" + Array(50000).join(")")) threw exception Error: Out of memory: Invalid regular expression: too many nested disjunctions.
    1515Creating RegExp at depth 40
    16 PASS new RegExp(Array(50000).join("(") + "a" + Array(50000).join(")")) threw exception SyntaxError: Invalid regular expression: too many nested disjunctions.
     16PASS new RegExp(Array(50000).join("(") + "a" + Array(50000).join(")")) threw exception Error: Out of memory: Invalid regular expression: too many nested disjunctions.
    1717Creating RegExp at depth 50
    18 PASS new RegExp(Array(50000).join("(") + "a" + Array(50000).join(")")) threw exception SyntaxError: Invalid regular expression: too many nested disjunctions.
     18PASS new RegExp(Array(50000).join("(") + "a" + Array(50000).join(")")) threw exception Error: Out of memory: Invalid regular expression: too many nested disjunctions.
    1919Creating RegExp at depth 60
    20 PASS new RegExp(Array(50000).join("(") + "a" + Array(50000).join(")")) threw exception SyntaxError: Invalid regular expression: too many nested disjunctions.
     20PASS new RegExp(Array(50000).join("(") + "a" + Array(50000).join(")")) threw exception Error: Out of memory: Invalid regular expression: too many nested disjunctions.
    2121Creating RegExp at depth 70
    22 PASS new RegExp(Array(50000).join("(") + "a" + Array(50000).join(")")) threw exception SyntaxError: Invalid regular expression: too many nested disjunctions.
     22PASS new RegExp(Array(50000).join("(") + "a" + Array(50000).join(")")) threw exception Error: Out of memory: Invalid regular expression: too many nested disjunctions.
    2323Creating RegExp at depth 80
    24 PASS new RegExp(Array(50000).join("(") + "a" + Array(50000).join(")")) threw exception SyntaxError: Invalid regular expression: too many nested disjunctions.
     24PASS new RegExp(Array(50000).join("(") + "a" + Array(50000).join(")")) threw exception Error: Out of memory: Invalid regular expression: too many nested disjunctions.
    2525Creating RegExp at depth 90
    26 PASS new RegExp(Array(50000).join("(") + "a" + Array(50000).join(")")) threw exception SyntaxError: Invalid regular expression: too many nested disjunctions.
     26PASS new RegExp(Array(50000).join("(") + "a" + Array(50000).join(")")) threw exception Error: Out of memory: Invalid regular expression: too many nested disjunctions.
    2727Creating RegExp at depth 100
    28 PASS new RegExp(Array(50000).join("(") + "a" + Array(50000).join(")")) threw exception SyntaxError: Invalid regular expression: too many nested disjunctions.
    29 PASS new RegExp(expression) threw exception SyntaxError: Invalid regular expression: too many nested disjunctions.
     28PASS new RegExp(Array(50000).join("(") + "a" + Array(50000).join(")")) threw exception Error: Out of memory: Invalid regular expression: too many nested disjunctions.
     29PASS new RegExp(expression) threw exception Error: Out of memory: Invalid regular expression: too many nested disjunctions.
    3030PASS successfullyParsed is true
    3131
  • trunk/Source/JavaScriptCore/ChangeLog

    r231938 r231939  
     12018-05-17  Michael Saboff  <msaboff@apple.com>
     2
     3        We don't throw SyntaxErrors for runtime generated regular expressions with errors
     4        https://bugs.webkit.org/show_bug.cgi?id=185755
     5
     6        Reviewed by Keith Miller.
     7
     8        Added a new helper that creates the correct exception to throw for each type of error when
     9        compiling a RegExp.  Using that new helper, added missing checks for RegExp for the cases
     10        where we create a new RegExp from an existing one.  Also refactored other places that we
     11        throw SyntaxErrors after a failed RegExp compile to use the new helper.
     12
     13        * runtime/RegExp.h:
     14        * runtime/RegExpConstructor.cpp:
     15        (JSC::regExpCreate):
     16        (JSC::constructRegExp):
     17        * runtime/RegExpPrototype.cpp:
     18        (JSC::regExpProtoFuncCompile):
     19        * yarr/YarrErrorCode.cpp:
     20        (JSC::Yarr::errorToThrow):
     21        * yarr/YarrErrorCode.h:
     22
    1232018-05-17  Saam Barati  <sbarati@apple.com>
    224
  • trunk/Source/JavaScriptCore/runtime/Error.cpp

    r222473 r231939  
    354354}
    355355
     356JSObject* createOutOfMemoryError(ExecState* exec, const String& message)
     357{
     358   
     359    auto* error = createError(exec, makeString("Out of memory: ", message), nullptr);
     360    jsCast<ErrorInstance*>(error)->setOutOfMemoryError();
     361    return error;
     362}
     363
    356364
    357365const ClassInfo StrictModeTypeErrorFunction::s_info = { "Function", &Base::s_info, nullptr, nullptr, CREATE_METHOD_TABLE(StrictModeTypeErrorFunction) };
  • trunk/Source/JavaScriptCore/runtime/Error.h

    r230813 r231939  
    7272JS_EXPORT_PRIVATE JSObject* createURIError(ExecState*, const String&);
    7373JS_EXPORT_PRIVATE JSObject* createOutOfMemoryError(ExecState*);
     74JS_EXPORT_PRIVATE JSObject* createOutOfMemoryError(ExecState*, const String&);
    7475
    7576JS_EXPORT_PRIVATE JSObject* createError(ExecState*, ErrorType, const String&);
  • trunk/Source/JavaScriptCore/runtime/RegExp.h

    r228105 r231939  
    6363    bool isValid() const { return !Yarr::hasError(m_constructionErrorCode) && m_flags != InvalidFlags; }
    6464    const char* errorMessage() const { return Yarr::errorMessage(m_constructionErrorCode); }
     65    JSObject* errorToThrow(ExecState* exec) { return Yarr::errorToThrow(exec, m_constructionErrorCode); }
    6566
    6667    JS_EXPORT_PRIVATE int match(VM&, const String&, unsigned startOffset, Vector<int>& ovector);
  • trunk/Source/JavaScriptCore/runtime/RegExpConstructor.cpp

    r230369 r231939  
    244244    RegExp* regExp = RegExp::create(vm, pattern, flags);
    245245    if (!regExp->isValid())
    246         return throwException(exec, scope, createSyntaxError(exec, regExp->errorMessage()));
     246        return throwException(exec, scope, regExp->errorToThrow(exec));
    247247
    248248    Structure* structure = getRegExpStructure(exec, globalObject, newTarget);
     
    282282                return nullptr;
    283283            regExp = RegExp::create(vm, regExp->pattern(), flags);
     284
     285            if (!regExp->isValid())
     286                return throwException(exec, scope, regExp->errorToThrow(exec));
    284287        }
    285288
  • trunk/Source/JavaScriptCore/runtime/RegExpPrototype.cpp

    r231047 r231939  
    175175
    176176    if (!regExp->isValid())
    177         return throwVMError(exec, scope, createSyntaxError(exec, regExp->errorMessage()));
     177        return throwVMError(exec, scope, regExp->errorToThrow(exec));
    178178
    179179    thisRegExp->setRegExp(vm, regExp);
  • trunk/Source/JavaScriptCore/yarr/YarrErrorCode.cpp

    r226128 r231939  
    2626#include "config.h"
    2727#include "YarrErrorCode.h"
     28
     29#include "Error.h"
    2830
    2931namespace JSC { namespace Yarr {
     
    5961}
    6062
     63JSObject* errorToThrow(ExecState* exec, ErrorCode error)
     64{
     65    switch (error) {
     66    case ErrorCode::NoError:
     67        ASSERT_NOT_REACHED();
     68        return nullptr;
     69    case ErrorCode::PatternTooLarge:
     70    case ErrorCode::QuantifierOutOfOrder:
     71    case ErrorCode::QuantifierWithoutAtom:
     72    case ErrorCode::QuantifierTooLarge:
     73    case ErrorCode::MissingParentheses:
     74    case ErrorCode::ParenthesesUnmatched:
     75    case ErrorCode::ParenthesesTypeInvalid:
     76    case ErrorCode::InvalidGroupName:
     77    case ErrorCode::DuplicateGroupName:
     78    case ErrorCode::CharacterClassUnmatched:
     79    case ErrorCode::CharacterClassOutOfOrder:
     80    case ErrorCode::EscapeUnterminated:
     81    case ErrorCode::InvalidUnicodeEscape:
     82    case ErrorCode::InvalidBackreference:
     83    case ErrorCode::InvalidIdentityEscape:
     84    case ErrorCode::InvalidUnicodePropertyExpression:
     85    case ErrorCode::OffsetTooLarge:
     86    case ErrorCode::InvalidRegularExpressionFlags:
     87        return createSyntaxError(exec, errorMessage(error));
     88    case ErrorCode::TooManyDisjunctions:
     89        return createOutOfMemoryError(exec, errorMessage(error));
     90    }
     91
     92    ASSERT_NOT_REACHED();
     93    return nullptr;
     94}
     95
    6196} } // namespace JSC::Yarr
  • trunk/Source/JavaScriptCore/yarr/YarrErrorCode.h

    r226128 r231939  
    2626#pragma once
    2727
    28 namespace JSC { namespace Yarr {
     28namespace JSC {
     29
     30class ExecState;
     31class JSObject;
     32
     33namespace Yarr {
    2934
    3035enum class ErrorCode : unsigned {
     
    5661    return errorCode != ErrorCode::NoError;
    5762}
     63JS_EXPORT_PRIVATE JSObject* errorToThrow(ExecState*, ErrorCode);
    5864
    5965} } // namespace JSC::Yarr
Note: See TracChangeset for help on using the changeset viewer.