Invalid flags in a RegExp literal should be an early SyntaxError
https://bugs.webkit.org/show_bug.cgi?id=195514
Reviewed by Darin Adler.
JSTests:
* test262/expectations.yaml:
Mark 4 test cases as passing.
* stress/regexp-syntax-error-invalid-flags.js:
* stress/regress-161995.js: Removed.
Update existing test, merging in an older test for the same behavior.
Source/JavaScriptCore:
Currently we're throwing a *runtime* SyntaxError; this should occur at parse time.
12.2.8.1 Static Semantics: Early Errors
PrimaryExpression : RegularExpressionLiteral
- It is a Syntax Error if BodyText of RegularExpressionLiteral cannot be recognized
using the goal symbol Pattern of the ECMAScript RegExp grammar specified in 21.2.1.
- It is a Syntax Error if FlagText of RegularExpressionLiteral contains any code points
other than "g", "i", "m", "s", "u", or "y", or if it contains the same code point more than once.
In fixing this, let's also move flag handling from runtime/ to yarr/.
* yarr/YarrSyntaxChecker.cpp:
(JSC::Yarr::checkSyntax):
Check flags before checking pattern.
* CMakeLists.txt:
* JavaScriptCore.xcodeproj/project.pbxproj:
* Sources.txt:
* bytecompiler/NodesCodegen.cpp:
(JSC::RegExpNode::emitBytecode):
* inspector/ContentSearchUtilities.cpp:
(Inspector::ContentSearchUtilities::findMagicComment):
* runtime/CachedTypes.cpp:
* runtime/RegExp.cpp:
(JSC::RegExp::RegExp):
(JSC::RegExp::createWithoutCaching):
(JSC::RegExp::create):
(JSC::regExpFlags): Deleted.
* runtime/RegExp.h:
* runtime/RegExpCache.cpp:
(JSC::RegExpCache::lookupOrCreate):
(JSC::RegExpCache::ensureEmptyRegExpSlow):
* runtime/RegExpCache.h:
* runtime/RegExpConstructor.cpp:
(JSC::toFlags):
(JSC::regExpCreate):
(JSC::constructRegExp):
* runtime/RegExpKey.h:
(JSC::RegExpKey::RegExpKey):
(WTF::HashTraits<JSC::RegExpKey>::constructDeletedValue):
(WTF::HashTraits<JSC::RegExpKey>::isDeletedValue):
(): Deleted.
* runtime/RegExpPrototype.cpp:
(JSC::regExpProtoFuncCompile):
* testRegExp.cpp:
(parseRegExpLine):
* yarr/RegularExpression.cpp:
(JSC::Yarr::RegularExpression::Private::compile):
* yarr/YarrFlags.cpp: Added.
(JSC::Yarr::parseFlags):
* yarr/YarrFlags.h: Added.
* yarr/YarrInterpreter.h:
(JSC::Yarr::BytecodePattern::ignoreCase const):
(JSC::Yarr::BytecodePattern::multiline const):
(JSC::Yarr::BytecodePattern::sticky const):
(JSC::Yarr::BytecodePattern::unicode const):
(JSC::Yarr::BytecodePattern::dotAll const):
* yarr/YarrPattern.cpp:
(JSC::Yarr::YarrPattern::compile):
(JSC::Yarr::YarrPattern::YarrPattern):
(JSC::Yarr::YarrPattern::dumpPattern):
* yarr/YarrPattern.h:
(JSC::Yarr::YarrPattern::global const):
(JSC::Yarr::YarrPattern::ignoreCase const):
(JSC::Yarr::YarrPattern::multiline const):
(JSC::Yarr::YarrPattern::sticky const):
(JSC::Yarr::YarrPattern::unicode const):
(JSC::Yarr::YarrPattern::dotAll const):
Move flag handling to Yarr and modernize API.
Source/WebCore:
* bindings/js/SerializedScriptValue.cpp:
(WebCore::CloneDeserializer::readTerminal):
Consume YarrFlags.
git-svn-id: http://svn.webkit.org/repository/webkit/trunk@242699 268f45cc-cd09-0410-ab3c-d52691b4dbfc
diff --git a/Source/JavaScriptCore/bytecompiler/NodesCodegen.cpp b/Source/JavaScriptCore/bytecompiler/NodesCodegen.cpp
index df9dfd8..f07592b 100644
--- a/Source/JavaScriptCore/bytecompiler/NodesCodegen.cpp
+++ b/Source/JavaScriptCore/bytecompiler/NodesCodegen.cpp
@@ -41,6 +41,7 @@
#include "Lexer.h"
#include "Parser.h"
#include "StackAlignment.h"
+#include "YarrFlags.h"
#include <wtf/Assertions.h>
#include <wtf/Threading.h>
#include <wtf/text/StringBuilder.h>
@@ -141,9 +142,13 @@
{
if (dst == generator.ignoredResult())
return nullptr;
- RegExp* regExp = RegExp::create(*generator.vm(), m_pattern.string(), regExpFlags(m_flags.string()));
+
+ auto flags = Yarr::parseFlags(m_flags.string());
+ ASSERT(flags.hasValue());
+ RegExp* regExp = RegExp::create(*generator.vm(), m_pattern.string(), flags.value());
if (regExp->isValid())
return generator.emitNewRegExp(generator.finalDestination(dst), regExp);
+
const char* messageCharacters = regExp->errorMessage();
const Identifier& message = generator.parserArena().identifierArena().makeIdentifier(generator.vm(), bitwise_cast<const LChar*>(messageCharacters), strlen(messageCharacters));
generator.emitThrowStaticError(ErrorType::SyntaxError, message);