Diff
Modified: trunk/JSTests/ChangeLog (242698 => 242699)
--- trunk/JSTests/ChangeLog 2019-03-11 06:04:00 UTC (rev 242698)
+++ trunk/JSTests/ChangeLog 2019-03-11 06:20:53 UTC (rev 242699)
@@ -1,3 +1,17 @@
+2019-03-10 Ross Kirsling <[email protected]>
+
+ Invalid flags in a RegExp literal should be an early SyntaxError
+ https://bugs.webkit.org/show_bug.cgi?id=195514
+
+ Reviewed by Darin Adler.
+
+ * 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.
+
2019-03-08 Mark Lam <[email protected]>
Stack overflow crash in JSC::JSObject::hasInstance.
Modified: trunk/JSTests/stress/regexp-syntax-error-invalid-flags.js (242698 => 242699)
--- trunk/JSTests/stress/regexp-syntax-error-invalid-flags.js 2019-03-11 06:04:00 UTC (rev 242698)
+++ trunk/JSTests/stress/regexp-syntax-error-invalid-flags.js 2019-03-11 06:20:53 UTC (rev 242699)
@@ -1,23 +1,17 @@
-function shouldThrow(func, errorMessage) {
- var errorThrown = false;
- var error = null;
+function shouldThrowSyntaxError(script) {
+ let error;
try {
- func();
+ eval(script);
} catch (e) {
- errorThrown = true;
error = e;
}
- if (!errorThrown)
+
+ if (!error)
throw new Error('not thrown');
- if (String(error) !== errorMessage)
+ if (String(error) !== 'SyntaxError: Invalid regular _expression_: invalid flags')
throw new Error(`bad error: ${String(error)}`);
}
-function test()
-{
- return /Hello/cocoa;
-}
-noInline(test);
-
-for (var i = 0; i < 1e4; ++i)
- shouldThrow(test, `SyntaxError: Invalid regular _expression_: invalid flags`);
+shouldThrowSyntaxError('/Hello/cocoa');
+shouldThrowSyntaxError('/a/Z');
+shouldThrowSyntaxError('/./ii');
Deleted: trunk/JSTests/stress/regress-161995.js (242698 => 242699)
--- trunk/JSTests/stress/regress-161995.js 2019-03-11 06:04:00 UTC (rev 242698)
+++ trunk/JSTests/stress/regress-161995.js 2019-03-11 06:20:53 UTC (rev 242699)
@@ -1,14 +0,0 @@
-// Regression test for 161995.
-
-function testStatic()
-{
- return /a/Z;
-}
-
-try {
- testStatic();
- throw "Expected a SyntaxEerror for bad RegExp flags, but didn't get one.";
-} catch(e) {
- if (e != "SyntaxError: Invalid regular _expression_: invalid flags")
- throw "Incorrect exception for bad RegExp flags. Got: " + e;
-}
Modified: trunk/JSTests/test262/expectations.yaml (242698 => 242699)
--- trunk/JSTests/test262/expectations.yaml 2019-03-11 06:04:00 UTC (rev 242698)
+++ trunk/JSTests/test262/expectations.yaml 2019-03-11 06:20:53 UTC (rev 242699)
@@ -2396,12 +2396,6 @@
test/language/literals/numeric/numeric-separator-literal-sign-plus-dds-nsl-dd.js:
default: 'SyntaxError: No identifiers allowed directly after numeric literal'
strict mode: 'SyntaxError: No identifiers allowed directly after numeric literal'
-test/language/literals/regexp/early-err-bad-flag.js:
- default: 'Test262: This statement should not be evaluated.'
- strict mode: 'Test262: This statement should not be evaluated.'
-test/language/literals/regexp/early-err-dup-flag.js:
- default: 'Test262: This statement should not be evaluated.'
- strict mode: 'Test262: This statement should not be evaluated.'
test/language/literals/regexp/named-groups/invalid-dangling-groupname-2-u.js:
default: 'Test262: This statement should not be evaluated.'
strict mode: 'Test262: This statement should not be evaluated.'
Modified: trunk/Source/_javascript_Core/CMakeLists.txt (242698 => 242699)
--- trunk/Source/_javascript_Core/CMakeLists.txt 2019-03-11 06:04:00 UTC (rev 242698)
+++ trunk/Source/_javascript_Core/CMakeLists.txt 2019-03-11 06:20:53 UTC (rev 242699)
@@ -1000,6 +1000,7 @@
yarr/RegularExpression.h
yarr/Yarr.h
yarr/YarrErrorCode.h
+ yarr/YarrFlags.h
yarr/YarrInterpreter.h
yarr/YarrJIT.h
yarr/YarrParser.h
Modified: trunk/Source/_javascript_Core/ChangeLog (242698 => 242699)
--- trunk/Source/_javascript_Core/ChangeLog 2019-03-11 06:04:00 UTC (rev 242698)
+++ trunk/Source/_javascript_Core/ChangeLog 2019-03-11 06:20:53 UTC (rev 242699)
@@ -1,3 +1,80 @@
+2019-03-10 Ross Kirsling <[email protected]>
+
+ Invalid flags in a RegExp literal should be an early SyntaxError
+ https://bugs.webkit.org/show_bug.cgi?id=195514
+
+ Reviewed by Darin Adler.
+
+ 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:
+ * _javascript_Core.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.
+
2019-03-09 Robin Morisset <[email protected]>
Compilation can be shrunk by 8 bytes
Modified: trunk/Source/_javascript_Core/_javascript_Core.xcodeproj/project.pbxproj (242698 => 242699)
--- trunk/Source/_javascript_Core/_javascript_Core.xcodeproj/project.pbxproj 2019-03-11 06:04:00 UTC (rev 242698)
+++ trunk/Source/_javascript_Core/_javascript_Core.xcodeproj/project.pbxproj 2019-03-11 06:20:53 UTC (rev 242699)
@@ -1339,6 +1339,7 @@
A1D792FD1B43864B004516F5 /* IntlNumberFormat.h in Headers */ = {isa = PBXBuildFile; fileRef = A1D792F71B43864B004516F5 /* IntlNumberFormat.h */; };
A1D792FF1B43864B004516F5 /* IntlNumberFormatConstructor.h in Headers */ = {isa = PBXBuildFile; fileRef = A1D792F91B43864B004516F5 /* IntlNumberFormatConstructor.h */; };
A1D793011B43864B004516F5 /* IntlNumberFormatPrototype.h in Headers */ = {isa = PBXBuildFile; fileRef = A1D792FB1B43864B004516F5 /* IntlNumberFormatPrototype.h */; };
+ A3FF9BC72234749100B1A9AB /* YarrFlags.h in Headers */ = {isa = PBXBuildFile; fileRef = A3FF9BC52234746600B1A9AB /* YarrFlags.h */; settings = {ATTRIBUTES = (Private, ); }; };
A503FA1A188E0FB000110F14 /* _javascript_CallFrame.h in Headers */ = {isa = PBXBuildFile; fileRef = A503FA14188E0FAF00110F14 /* _javascript_CallFrame.h */; };
A503FA1E188E0FB000110F14 /* JSJavaScriptCallFramePrototype.h in Headers */ = {isa = PBXBuildFile; fileRef = A503FA18188E0FB000110F14 /* JSJavaScriptCallFramePrototype.h */; };
A503FA21188EFF6800110F14 /* ScriptBreakpoint.h in Headers */ = {isa = PBXBuildFile; fileRef = A503FA1F188EFF6800110F14 /* ScriptBreakpoint.h */; settings = {ATTRIBUTES = (Private, ); }; };
@@ -4086,6 +4087,8 @@
A1E0451B1C25B4B100BB663C /* StringPrototype.js */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode._javascript_; path = StringPrototype.js; sourceTree = "<group>"; };
A1FE1EB01C2C537E00A289FF /* DatePrototype.js */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode._javascript_; path = DatePrototype.js; sourceTree = "<group>"; };
A27958D7FA1142B0AC9E364D /* WasmContextInlines.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = WasmContextInlines.h; sourceTree = "<group>"; };
+ A3FF9BC52234746600B1A9AB /* YarrFlags.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = YarrFlags.h; path = yarr/YarrFlags.h; sourceTree = "<group>"; };
+ A3FF9BC62234746600B1A9AB /* YarrFlags.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = YarrFlags.cpp; path = yarr/YarrFlags.cpp; sourceTree = "<group>"; };
A503FA13188E0FAF00110F14 /* _javascript_CallFrame.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = _javascript_CallFrame.cpp; sourceTree = "<group>"; };
A503FA14188E0FAF00110F14 /* _javascript_CallFrame.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = _javascript_CallFrame.h; sourceTree = "<group>"; };
A503FA15188E0FB000110F14 /* JSJavaScriptCallFrame.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = JSJavaScriptCallFrame.cpp; sourceTree = "<group>"; };
@@ -7303,6 +7306,8 @@
65C6BEE021128C3B006849C3 /* YarrDisassembler.h */,
E3282BB91FE930A300EDAF71 /* YarrErrorCode.cpp */,
E3282BBA1FE930A400EDAF71 /* YarrErrorCode.h */,
+ A3FF9BC62234746600B1A9AB /* YarrFlags.cpp */,
+ A3FF9BC52234746600B1A9AB /* YarrFlags.h */,
86704B7D12DBA33700A9FE7B /* YarrInterpreter.cpp */,
86704B7E12DBA33700A9FE7B /* YarrInterpreter.h */,
86704B7F12DBA33700A9FE7B /* YarrJIT.cpp */,
@@ -9896,6 +9901,7 @@
9959E92E1BD17FA4001AA413 /* xxd.pl in Headers */,
451539B912DC994500EF7AC4 /* Yarr.h in Headers */,
E3282BBB1FE930AF00EDAF71 /* YarrErrorCode.h in Headers */,
+ A3FF9BC72234749100B1A9AB /* YarrFlags.h in Headers */,
86704B8512DBA33700A9FE7B /* YarrInterpreter.h in Headers */,
86704B8712DBA33700A9FE7B /* YarrJIT.h in Headers */,
86704B8812DBA33700A9FE7B /* YarrParser.h in Headers */,
Modified: trunk/Source/_javascript_Core/Sources.txt (242698 => 242699)
--- trunk/Source/_javascript_Core/Sources.txt 2019-03-11 06:04:00 UTC (rev 242698)
+++ trunk/Source/_javascript_Core/Sources.txt 2019-03-11 06:20:53 UTC (rev 242699)
@@ -1045,6 +1045,7 @@
yarr/YarrCanonicalizeUCS2.cpp
yarr/YarrDisassembler.cpp
yarr/YarrErrorCode.cpp
+yarr/YarrFlags.cpp
yarr/YarrInterpreter.cpp
yarr/YarrJIT.cpp
yarr/YarrPattern.cpp
Modified: trunk/Source/_javascript_Core/bytecompiler/NodesCodegen.cpp (242698 => 242699)
--- trunk/Source/_javascript_Core/bytecompiler/NodesCodegen.cpp 2019-03-11 06:04:00 UTC (rev 242698)
+++ trunk/Source/_javascript_Core/bytecompiler/NodesCodegen.cpp 2019-03-11 06:20:53 UTC (rev 242699)
@@ -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);
Modified: trunk/Source/_javascript_Core/inspector/ContentSearchUtilities.cpp (242698 => 242699)
--- trunk/Source/_javascript_Core/inspector/ContentSearchUtilities.cpp 2019-03-11 06:04:00 UTC (rev 242698)
+++ trunk/Source/_javascript_Core/inspector/ContentSearchUtilities.cpp 2019-03-11 06:20:53 UTC (rev 242699)
@@ -31,6 +31,7 @@
#include "RegularExpression.h"
#include "Yarr.h"
+#include "YarrFlags.h"
#include "YarrInterpreter.h"
#include <wtf/BumpPointerAllocator.h>
#include <wtf/StdLibExtras.h>
@@ -167,7 +168,7 @@
return String();
JSC::Yarr::ErrorCode error { JSC::Yarr::ErrorCode::NoError };
- YarrPattern pattern(patternString, JSC::RegExpFlags::FlagMultiline, error);
+ YarrPattern pattern(patternString, JSC::Yarr::Flags::Multiline, error);
ASSERT(!hasError(error));
BumpPointerAllocator regexAllocator;
auto bytecodePattern = byteCompile(pattern, ®exAllocator);
Modified: trunk/Source/_javascript_Core/runtime/CachedTypes.cpp (242698 => 242699)
--- trunk/Source/_javascript_Core/runtime/CachedTypes.cpp 2019-03-11 06:04:00 UTC (rev 242698)
+++ trunk/Source/_javascript_Core/runtime/CachedTypes.cpp 2019-03-11 06:20:53 UTC (rev 242699)
@@ -28,7 +28,6 @@
#include "BytecodeCacheVersion.h"
#include "BytecodeLivenessAnalysis.h"
-#include "JSCast.h"
#include "JSImmutableButterfly.h"
#include "JSTemplateObjectDescriptor.h"
#include "ScopedArgumentsTable.h"
@@ -40,7 +39,6 @@
#include "UnlinkedModuleProgramCodeBlock.h"
#include "UnlinkedProgramCodeBlock.h"
#include <wtf/FastMalloc.h>
-#include <wtf/Forward.h>
#include <wtf/Optional.h>
#include <wtf/UUID.h>
#include <wtf/text/AtomicStringImpl.h>
@@ -47,6 +45,10 @@
namespace JSC {
+namespace Yarr {
+enum class Flags : uint8_t;
+}
+
template <typename T, typename = void>
struct SourceTypeImpl {
using type = T;
@@ -1111,7 +1113,7 @@
private:
CachedString m_patternString;
- RegExpFlags m_flags;
+ OptionSet<Yarr::Flags> m_flags;
};
class CachedTemplateObjectDescriptor : public CachedObject<TemplateObjectDescriptor> {
Modified: trunk/Source/_javascript_Core/runtime/RegExp.cpp (242698 => 242699)
--- trunk/Source/_javascript_Core/runtime/RegExp.cpp 2019-03-11 06:04:00 UTC (rev 242698)
+++ trunk/Source/_javascript_Core/runtime/RegExp.cpp 2019-03-11 06:20:53 UTC (rev 242699)
@@ -28,7 +28,6 @@
#include "JSCInlines.h"
#include "RegExpCache.h"
#include "RegExpInlines.h"
-#include "Yarr.h"
#include "YarrJIT.h"
#include <wtf/Assertions.h>
@@ -36,56 +35,6 @@
const ClassInfo RegExp::s_info = { "RegExp", nullptr, nullptr, nullptr, CREATE_METHOD_TABLE(RegExp) };
-RegExpFlags regExpFlags(const String& string)
-{
- RegExpFlags flags = NoFlags;
-
- for (unsigned i = 0; i < string.length(); ++i) {
- switch (string[i]) {
- case 'g':
- if (flags & FlagGlobal)
- return InvalidFlags;
- flags = static_cast<RegExpFlags>(flags | FlagGlobal);
- break;
-
- case 'i':
- if (flags & FlagIgnoreCase)
- return InvalidFlags;
- flags = static_cast<RegExpFlags>(flags | FlagIgnoreCase);
- break;
-
- case 'm':
- if (flags & FlagMultiline)
- return InvalidFlags;
- flags = static_cast<RegExpFlags>(flags | FlagMultiline);
- break;
-
- case 's':
- if (flags & FlagDotAll)
- return InvalidFlags;
- flags = static_cast<RegExpFlags>(flags | FlagDotAll);
- break;
-
- case 'u':
- if (flags & FlagUnicode)
- return InvalidFlags;
- flags = static_cast<RegExpFlags>(flags | FlagUnicode);
- break;
-
- case 'y':
- if (flags & FlagSticky)
- return InvalidFlags;
- flags = static_cast<RegExpFlags>(flags | FlagSticky);
- break;
-
- default:
- return InvalidFlags;
- }
- }
-
- return flags;
-}
-
#if REGEXP_FUNC_TEST_DATA_GEN
const char* const RegExpFunctionalTestCollector::s_fileName = "/tmp/RegExpTestsData";
RegExpFunctionalTestCollector* RegExpFunctionalTestCollector::s_instance = 0;
@@ -210,11 +159,12 @@
}
#endif
-RegExp::RegExp(VM& vm, const String& patternString, RegExpFlags flags)
+RegExp::RegExp(VM& vm, const String& patternString, OptionSet<Yarr::Flags> flags)
: JSCell(vm, vm.regExpStructure.get())
, m_patternString(patternString)
, m_flags(flags)
{
+ ASSERT(m_flags != Yarr::Flags::DeletedValue);
}
void RegExp::finishCreation(VM& vm)
@@ -249,7 +199,7 @@
return Base::estimatedSize(cell, vm) + regexDataSize;
}
-RegExp* RegExp::createWithoutCaching(VM& vm, const String& patternString, RegExpFlags flags)
+RegExp* RegExp::createWithoutCaching(VM& vm, const String& patternString, OptionSet<Yarr::Flags> flags)
{
RegExp* regExp = new (NotNull, allocateCell<RegExp>(vm.heap)) RegExp(vm, patternString, flags);
regExp->finishCreation(vm);
@@ -256,7 +206,7 @@
return regExp;
}
-RegExp* RegExp::create(VM& vm, const String& patternString, RegExpFlags flags)
+RegExp* RegExp::create(VM& vm, const String& patternString, OptionSet<Yarr::Flags> flags)
{
return vm.regExpCache()->lookupOrCreate(patternString, flags);
}
Modified: trunk/Source/_javascript_Core/runtime/RegExp.h (242698 => 242699)
--- trunk/Source/_javascript_Core/runtime/RegExp.h 2019-03-11 06:04:00 UTC (rev 242698)
+++ trunk/Source/_javascript_Core/runtime/RegExp.h 2019-03-11 06:20:53 UTC (rev 242699)
@@ -38,8 +38,6 @@
struct RegExpRepresentation;
class VM;
-JS_EXPORT_PRIVATE RegExpFlags regExpFlags(const String&);
-
class RegExp final : public JSCell {
friend class CachedRegExp;
@@ -47,23 +45,23 @@
typedef JSCell Base;
static const unsigned StructureFlags = Base::StructureFlags | StructureIsImmortal;
- JS_EXPORT_PRIVATE static RegExp* create(VM&, const String& pattern, RegExpFlags);
+ JS_EXPORT_PRIVATE static RegExp* create(VM&, const String& pattern, OptionSet<Yarr::Flags>);
static const bool needsDestruction = true;
static void destroy(JSCell*);
static size_t estimatedSize(JSCell*, VM&);
JS_EXPORT_PRIVATE static void dumpToStream(const JSCell*, PrintStream&);
- bool global() const { return m_flags & FlagGlobal; }
- bool ignoreCase() const { return m_flags & FlagIgnoreCase; }
- bool multiline() const { return m_flags & FlagMultiline; }
- bool sticky() const { return m_flags & FlagSticky; }
+ bool global() const { return m_flags.contains(Yarr::Flags::Global); }
+ bool ignoreCase() const { return m_flags.contains(Yarr::Flags::IgnoreCase); }
+ bool multiline() const { return m_flags.contains(Yarr::Flags::Multiline); }
+ bool sticky() const { return m_flags.contains(Yarr::Flags::Sticky); }
bool globalOrSticky() const { return global() || sticky(); }
- bool unicode() const { return m_flags & FlagUnicode; }
- bool dotAll() const { return m_flags & FlagDotAll; }
+ bool unicode() const { return m_flags.contains(Yarr::Flags::Unicode); }
+ bool dotAll() const { return m_flags.contains(Yarr::Flags::DotAll); }
const String& pattern() const { return m_patternString; }
- bool isValid() const { return !Yarr::hasError(m_constructionErrorCode) && m_flags != InvalidFlags; }
+ bool isValid() const { return !Yarr::hasError(m_constructionErrorCode); }
const char* errorMessage() const { return Yarr::errorMessage(m_constructionErrorCode); }
JSObject* errorToThrow(ExecState* exec) { return Yarr::errorToThrow(exec, m_constructionErrorCode); }
void reset()
@@ -136,9 +134,9 @@
private:
friend class RegExpCache;
- RegExp(VM&, const String&, RegExpFlags);
+ RegExp(VM&, const String&, OptionSet<Yarr::Flags>);
- static RegExp* createWithoutCaching(VM&, const String&, RegExpFlags);
+ static RegExp* createWithoutCaching(VM&, const String&, OptionSet<Yarr::Flags>);
enum RegExpState : uint8_t {
ParseError,
@@ -161,7 +159,7 @@
String m_patternString;
RegExpState m_state { NotCompiled };
- RegExpFlags m_flags;
+ OptionSet<Yarr::Flags> m_flags;
ConcurrentJSLock m_lock;
Yarr::ErrorCode m_constructionErrorCode { Yarr::ErrorCode::NoError };
unsigned m_numSubpatterns { 0 };
Modified: trunk/Source/_javascript_Core/runtime/RegExpCache.cpp (242698 => 242699)
--- trunk/Source/_javascript_Core/runtime/RegExpCache.cpp 2019-03-11 06:04:00 UTC (rev 242698)
+++ trunk/Source/_javascript_Core/runtime/RegExpCache.cpp 2019-03-11 06:20:53 UTC (rev 242699)
@@ -35,7 +35,7 @@
namespace JSC {
-RegExp* RegExpCache::lookupOrCreate(const String& patternString, RegExpFlags flags)
+RegExp* RegExpCache::lookupOrCreate(const String& patternString, OptionSet<Yarr::Flags> flags)
{
RegExpKey key(flags, patternString);
if (RegExp* regExp = m_weakCache.get(key))
@@ -58,7 +58,7 @@
RegExp* RegExpCache::ensureEmptyRegExpSlow(VM& vm)
{
- RegExp* regExp = RegExp::create(vm, "", NoFlags);
+ RegExp* regExp = RegExp::create(vm, "", { });
m_emptyRegExp.set(vm, regExp);
return regExp;
}
Modified: trunk/Source/_javascript_Core/runtime/RegExpCache.h (242698 => 242699)
--- trunk/Source/_javascript_Core/runtime/RegExpCache.h 2019-03-11 06:04:00 UTC (rev 242698)
+++ trunk/Source/_javascript_Core/runtime/RegExpCache.h 2019-03-11 06:20:53 UTC (rev 242699)
@@ -36,6 +36,10 @@
namespace JSC {
+namespace Yarr {
+enum class Flags : uint8_t;
+}
+
class RegExpCache : private WeakHandleOwner {
WTF_MAKE_FAST_ALLOCATED;
@@ -63,7 +67,7 @@
RegExp* ensureEmptyRegExpSlow(VM&);
- RegExp* lookupOrCreate(const WTF::String& patternString, RegExpFlags);
+ RegExp* lookupOrCreate(const WTF::String& patternString, OptionSet<Yarr::Flags>);
void addToStrongCache(RegExp*);
RegExpCacheMap m_weakCache; // Holds all regular expressions currently live.
int m_nextEntryInStrongCache;
Modified: trunk/Source/_javascript_Core/runtime/RegExpConstructor.cpp (242698 => 242699)
--- trunk/Source/_javascript_Core/runtime/RegExpConstructor.cpp 2019-03-11 06:04:00 UTC (rev 242698)
+++ trunk/Source/_javascript_Core/runtime/RegExpConstructor.cpp 2019-03-11 06:20:53 UTC (rev 242699)
@@ -24,10 +24,10 @@
#include "Error.h"
#include "GetterSetter.h"
-#include "JSCInlines.h"
#include "RegExpGlobalDataInlines.h"
#include "RegExpPrototype.h"
#include "StructureInlines.h"
+#include "YarrFlags.h"
namespace JSC {
@@ -177,23 +177,22 @@
return structure;
}
-inline RegExpFlags toFlags(ExecState* exec, JSValue flags)
+inline OptionSet<Yarr::Flags> toFlags(ExecState* exec, JSValue flags)
{
VM& vm = exec->vm();
auto scope = DECLARE_THROW_SCOPE(vm);
if (flags.isUndefined())
- return NoFlags;
- JSString* flagsString = flags.toStringOrNull(exec);
- EXCEPTION_ASSERT(!!scope.exception() == !flagsString);
- if (UNLIKELY(!flagsString))
- return InvalidFlags;
+ return { };
+
+ auto result = Yarr::parseFlags(flags.toWTFString(exec));
+ RETURN_IF_EXCEPTION(scope, { });
+ if (!result) {
+ throwSyntaxError(exec, scope, "Invalid flags supplied to RegExp constructor."_s);
+ return { };
+ }
- RegExpFlags result = regExpFlags(flagsString->value(exec));
- RETURN_IF_EXCEPTION(scope, InvalidFlags);
- if (result == InvalidFlags)
- throwSyntaxError(exec, scope, "Invalid flags supplied to RegExp constructor."_s);
- return result;
+ return result.value();
}
static JSObject* regExpCreate(ExecState* exec, JSGlobalObject* globalObject, JSValue newTarget, JSValue patternArg, JSValue flagsArg)
@@ -204,10 +203,8 @@
String pattern = patternArg.isUndefined() ? emptyString() : patternArg.toWTFString(exec);
RETURN_IF_EXCEPTION(scope, nullptr);
- RegExpFlags flags = toFlags(exec, flagsArg);
- EXCEPTION_ASSERT(!!scope.exception() == (flags == InvalidFlags));
- if (UNLIKELY(flags == InvalidFlags))
- return nullptr;
+ auto flags = toFlags(exec, flagsArg);
+ RETURN_IF_EXCEPTION(scope, nullptr);
RegExp* regExp = RegExp::create(vm, pattern, flags);
if (UNLIKELY(!regExp->isValid())) {
@@ -246,12 +243,10 @@
RETURN_IF_EXCEPTION(scope, nullptr);
if (!flagsArg.isUndefined()) {
- RegExpFlags flags = toFlags(exec, flagsArg);
- EXCEPTION_ASSERT(!!scope.exception() == (flags == InvalidFlags));
- if (flags == InvalidFlags)
- return nullptr;
+ auto flags = toFlags(exec, flagsArg);
+ RETURN_IF_EXCEPTION(scope, nullptr);
+
regExp = RegExp::create(vm, regExp->pattern(), flags);
-
if (UNLIKELY(!regExp->isValid())) {
throwException(exec, scope, regExp->errorToThrow(exec));
return nullptr;
Modified: trunk/Source/_javascript_Core/runtime/RegExpKey.h (242698 => 242699)
--- trunk/Source/_javascript_Core/runtime/RegExpKey.h 2019-03-11 06:04:00 UTC (rev 242698)
+++ trunk/Source/_javascript_Core/runtime/RegExpKey.h 2019-03-11 06:20:53 UTC (rev 242699)
@@ -27,50 +27,38 @@
#pragma once
+#include "YarrFlags.h"
+#include <wtf/OptionSet.h>
#include <wtf/text/StringHash.h>
-#include <wtf/text/WTFString.h>
namespace JSC {
-enum RegExpFlags : int8_t {
- NoFlags = 0,
- FlagGlobal = 1,
- FlagIgnoreCase = 2,
- FlagMultiline = 4,
- FlagSticky = 8,
- FlagUnicode = 16,
- FlagDotAll = 32,
- InvalidFlags = 64,
- DeletedValueFlags = -1
-};
-
struct RegExpKey {
- RegExpFlags flagsValue;
+ OptionSet<Yarr::Flags> flagsValue;
RefPtr<StringImpl> pattern;
RegExpKey()
- : flagsValue(NoFlags)
{
}
- RegExpKey(RegExpFlags flags)
+ RegExpKey(OptionSet<Yarr::Flags> flags)
: flagsValue(flags)
{
}
- RegExpKey(RegExpFlags flags, const String& pattern)
+ RegExpKey(OptionSet<Yarr::Flags> flags, const String& pattern)
: flagsValue(flags)
, pattern(pattern.impl())
{
}
- RegExpKey(RegExpFlags flags, RefPtr<StringImpl>&& pattern)
+ RegExpKey(OptionSet<Yarr::Flags> flags, RefPtr<StringImpl>&& pattern)
: flagsValue(flags)
, pattern(WTFMove(pattern))
{
}
- RegExpKey(RegExpFlags flags, const RefPtr<StringImpl>& pattern)
+ RegExpKey(OptionSet<Yarr::Flags> flags, const RefPtr<StringImpl>& pattern)
: flagsValue(flags)
, pattern(pattern)
{
@@ -107,7 +95,7 @@
template<> struct HashTraits<JSC::RegExpKey> : GenericHashTraits<JSC::RegExpKey> {
static const bool emptyValueIsZero = true;
- static void constructDeletedValue(JSC::RegExpKey& slot) { slot.flagsValue = JSC::DeletedValueFlags; }
- static bool isDeletedValue(const JSC::RegExpKey& value) { return value.flagsValue == JSC::DeletedValueFlags; }
+ static void constructDeletedValue(JSC::RegExpKey& slot) { slot.flagsValue = JSC::Yarr::Flags::DeletedValue; }
+ static bool isDeletedValue(const JSC::RegExpKey& value) { return value.flagsValue == JSC::Yarr::Flags::DeletedValue; }
};
} // namespace WTF
Modified: trunk/Source/_javascript_Core/runtime/RegExpPrototype.cpp (242698 => 242699)
--- trunk/Source/_javascript_Core/runtime/RegExpPrototype.cpp 2019-03-11 06:04:00 UTC (rev 242698)
+++ trunk/Source/_javascript_Core/runtime/RegExpPrototype.cpp 2019-03-11 06:20:53 UTC (rev 242699)
@@ -29,16 +29,15 @@
#include "JSCInlines.h"
#include "JSCJSValue.h"
#include "JSFunction.h"
-#include "JSObject.h"
#include "JSStringInlines.h"
#include "Lexer.h"
#include "ObjectPrototype.h"
-#include "RegExp.h"
#include "RegExpCache.h"
#include "RegExpObject.h"
#include "RegExpObjectInlines.h"
#include "StringObject.h"
#include "StringRecursionChecker.h"
+#include "YarrFlags.h"
#include <wtf/text/StringBuilder.h>
namespace JSC {
@@ -149,14 +148,12 @@
String pattern = arg0.isUndefined() ? emptyString() : arg0.toWTFString(exec);
RETURN_IF_EXCEPTION(scope, encodedJSValue());
- RegExpFlags flags = NoFlags;
- if (!arg1.isUndefined()) {
- flags = regExpFlags(arg1.toWTFString(exec));
- RETURN_IF_EXCEPTION(scope, encodedJSValue());
- if (flags == InvalidFlags)
- return throwVMError(exec, scope, createSyntaxError(exec, "Invalid flags supplied to RegExp constructor."_s));
- }
- regExp = RegExp::create(vm, pattern, flags);
+ auto flags = arg1.isUndefined() ? makeOptional(OptionSet<Yarr::Flags> { }) : Yarr::parseFlags(arg1.toWTFString(exec));
+ RETURN_IF_EXCEPTION(scope, encodedJSValue());
+ if (!flags)
+ return throwVMError(exec, scope, createSyntaxError(exec, "Invalid flags supplied to RegExp constructor."_s));
+
+ regExp = RegExp::create(vm, pattern, flags.value());
}
if (!regExp->isValid())
Modified: trunk/Source/_javascript_Core/testRegExp.cpp (242698 => 242699)
--- trunk/Source/_javascript_Core/testRegExp.cpp 2019-03-11 06:04:00 UTC (rev 242698)
+++ trunk/Source/_javascript_Core/testRegExp.cpp 2019-03-11 06:20:53 UTC (rev 242699)
@@ -24,6 +24,7 @@
#include "InitializeThreading.h"
#include "JSCInlines.h"
#include "JSGlobalObject.h"
+#include "YarrFlags.h"
#include <errno.h>
#include <stdio.h>
#include <stdlib.h>
@@ -328,11 +329,18 @@
++i;
- RegExp* r = RegExp::create(vm, pattern.toString(), regExpFlags(line + i));
+ auto flags = Yarr::parseFlags(line + i);
+ if (!flags) {
+ *regexpError = Yarr::errorMessage(Yarr::ErrorCode::InvalidRegularExpressionFlags);
+ return nullptr;
+ }
+
+ RegExp* r = RegExp::create(vm, pattern.toString(), flags.value());
if (!r->isValid()) {
*regexpError = r->errorMessage();
return nullptr;
}
+
return r;
}
Modified: trunk/Source/_javascript_Core/yarr/RegularExpression.cpp (242698 => 242699)
--- trunk/Source/_javascript_Core/yarr/RegularExpression.cpp 2019-03-11 06:04:00 UTC (rev 242698)
+++ trunk/Source/_javascript_Core/yarr/RegularExpression.cpp 2019-03-11 06:20:53 UTC (rev 242699)
@@ -29,6 +29,7 @@
#include "RegularExpression.h"
#include "Yarr.h"
+#include "YarrFlags.h"
#include "YarrInterpreter.h"
#include <wtf/Assertions.h>
#include <wtf/BumpPointerAllocator.h>
@@ -55,16 +56,16 @@
std::unique_ptr<JSC::Yarr::BytecodePattern> compile(const String& patternString, TextCaseSensitivity caseSensitivity, MultilineMode multilineMode, UnicodeMode unicodeMode)
{
- RegExpFlags flags = NoFlags;
+ OptionSet<JSC::Yarr::Flags> flags;
if (caseSensitivity == TextCaseInsensitive)
- flags = static_cast<RegExpFlags>(flags | FlagIgnoreCase);
+ flags.add(Flags::IgnoreCase);
if (multilineMode == MultilineEnabled)
- flags = static_cast<RegExpFlags>(flags | FlagMultiline);
+ flags.add(Flags::Multiline);
if (unicodeMode == UnicodeAwareMode)
- flags = static_cast<RegExpFlags>(flags | FlagUnicode);
+ flags.add(Flags::Unicode);
JSC::Yarr::YarrPattern pattern(patternString, flags, m_constructionErrorCode);
if (JSC::Yarr::hasError(m_constructionErrorCode)) {
Added: trunk/Source/_javascript_Core/yarr/YarrFlags.cpp (0 => 242699)
--- trunk/Source/_javascript_Core/yarr/YarrFlags.cpp (rev 0)
+++ trunk/Source/_javascript_Core/yarr/YarrFlags.cpp 2019-03-11 06:20:53 UTC (rev 242699)
@@ -0,0 +1,83 @@
+/*
+ * Copyright (C) 2019 Sony Interactive Entertainment Inc.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "config.h"
+#include "YarrFlags.h"
+
+#include <wtf/OptionSet.h>
+#include <wtf/text/StringView.h>
+
+namespace JSC { namespace Yarr {
+
+Optional<OptionSet<Flags>> parseFlags(StringView string)
+{
+ OptionSet<Flags> flags;
+ for (auto character : string.codeUnits()) {
+ switch (character) {
+ case 'g':
+ if (flags.contains(Flags::Global))
+ return WTF::nullopt;
+ flags.add(Flags::Global);
+ break;
+
+ case 'i':
+ if (flags.contains(Flags::IgnoreCase))
+ return WTF::nullopt;
+ flags.add(Flags::IgnoreCase);
+ break;
+
+ case 'm':
+ if (flags.contains(Flags::Multiline))
+ return WTF::nullopt;
+ flags.add(Flags::Multiline);
+ break;
+
+ case 's':
+ if (flags.contains(Flags::DotAll))
+ return WTF::nullopt;
+ flags.add(Flags::DotAll);
+ break;
+
+ case 'u':
+ if (flags.contains(Flags::Unicode))
+ return WTF::nullopt;
+ flags.add(Flags::Unicode);
+ break;
+
+ case 'y':
+ if (flags.contains(Flags::Sticky))
+ return WTF::nullopt;
+ flags.add(Flags::Sticky);
+ break;
+
+ default:
+ return WTF::nullopt;
+ }
+ }
+
+ return makeOptional(flags);
+}
+
+} } // namespace JSC::Yarr
Added: trunk/Source/_javascript_Core/yarr/YarrFlags.h (0 => 242699)
--- trunk/Source/_javascript_Core/yarr/YarrFlags.h (rev 0)
+++ trunk/Source/_javascript_Core/yarr/YarrFlags.h 2019-03-11 06:20:53 UTC (rev 242699)
@@ -0,0 +1,45 @@
+/*
+ * Copyright (C) 2019 Sony Interactive Entertainment Inc.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#pragma once
+
+#include <wtf/Forward.h>
+#include <wtf/Optional.h>
+
+namespace JSC { namespace Yarr {
+
+enum class Flags : uint8_t {
+ Global = 1 << 0,
+ IgnoreCase = 1 << 1,
+ Multiline = 1 << 2,
+ Sticky = 1 << 3,
+ Unicode = 1 << 4,
+ DotAll = 1 << 5,
+ DeletedValue = 1 << 6
+};
+
+JS_EXPORT_PRIVATE Optional<OptionSet<Flags>> parseFlags(StringView);
+
+} } // namespace JSC::Yarr
Modified: trunk/Source/_javascript_Core/yarr/YarrInterpreter.h (242698 => 242699)
--- trunk/Source/_javascript_Core/yarr/YarrInterpreter.h 2019-03-11 06:04:00 UTC (rev 242698)
+++ trunk/Source/_javascript_Core/yarr/YarrInterpreter.h 2019-03-11 06:20:53 UTC (rev 242699)
@@ -26,6 +26,7 @@
#pragma once
#include "ConcurrentJSLock.h"
+#include "YarrFlags.h"
#include "YarrPattern.h"
namespace WTF {
@@ -367,14 +368,14 @@
size_t estimatedSizeInBytes() const { return m_body->estimatedSizeInBytes(); }
- bool ignoreCase() const { return m_flags & FlagIgnoreCase; }
- bool multiline() const { return m_flags & FlagMultiline; }
- bool sticky() const { return m_flags & FlagSticky; }
- bool unicode() const { return m_flags & FlagUnicode; }
- bool dotAll() const { return m_flags & FlagDotAll; }
+ bool ignoreCase() const { return m_flags.contains(Flags::IgnoreCase); }
+ bool multiline() const { return m_flags.contains(Flags::Multiline); }
+ bool sticky() const { return m_flags.contains(Flags::Sticky); }
+ bool unicode() const { return m_flags.contains(Flags::Unicode); }
+ bool dotAll() const { return m_flags.contains(Flags::DotAll); }
std::unique_ptr<ByteDisjunction> m_body;
- RegExpFlags m_flags;
+ OptionSet<Flags> m_flags;
// Each BytecodePattern is associated with a RegExp, each RegExp is associated
// with a VM. Cache a pointer to out VM's m_regExpAllocator.
BumpPointerAllocator* m_allocator;
Modified: trunk/Source/_javascript_Core/yarr/YarrPattern.cpp (242698 => 242699)
--- trunk/Source/_javascript_Core/yarr/YarrPattern.cpp 2019-03-11 06:04:00 UTC (rev 242698)
+++ trunk/Source/_javascript_Core/yarr/YarrPattern.cpp 2019-03-11 06:20:53 UTC (rev 242699)
@@ -36,7 +36,6 @@
#include <wtf/StackPointer.h>
#include <wtf/Threading.h>
#include <wtf/Vector.h>
-#include <wtf/text/WTFString.h>
namespace JSC { namespace Yarr {
@@ -1110,9 +1109,6 @@
{
YarrPatternConstructor constructor(*this, stackLimit);
- if (m_flags == InvalidFlags)
- return ErrorCode::InvalidRegularExpressionFlags;
-
{
ErrorCode error = parse(constructor, patternString, unicode());
if (hasError(error))
@@ -1152,7 +1148,7 @@
return ErrorCode::NoError;
}
-YarrPattern::YarrPattern(const String& pattern, RegExpFlags flags, ErrorCode& error, void* stackLimit)
+YarrPattern::YarrPattern(const String& pattern, OptionSet<Flags> flags, ErrorCode& error, void* stackLimit)
: m_containsBackreferences(false)
, m_containsBOL(false)
, m_containsUnsignedLengthPattern(false)
@@ -1160,6 +1156,7 @@
, m_saveInitialStartValue(false)
, m_flags(flags)
{
+ ASSERT(m_flags != Flags::DeletedValue);
error = compile(pattern, stackLimit);
}
@@ -1420,7 +1417,7 @@
out.print("RegExp pattern for ");
dumpPatternString(out, patternString);
- if (m_flags != NoFlags) {
+ if (m_flags) {
bool printSeperator = false;
out.print(" (");
if (global()) {
Modified: trunk/Source/_javascript_Core/yarr/YarrPattern.h (242698 => 242699)
--- trunk/Source/_javascript_Core/yarr/YarrPattern.h 2019-03-11 06:04:00 UTC (rev 242698)
+++ trunk/Source/_javascript_Core/yarr/YarrPattern.h 2019-03-11 06:20:53 UTC (rev 242699)
@@ -26,14 +26,15 @@
#pragma once
-#include "RegExpKey.h"
#include "YarrErrorCode.h"
+#include "YarrFlags.h"
#include "YarrUnicodeProperties.h"
#include <wtf/CheckedArithmetic.h>
#include <wtf/HashMap.h>
+#include <wtf/OptionSet.h>
#include <wtf/PrintStream.h>
#include <wtf/Vector.h>
-#include <wtf/text/WTFString.h>
+#include <wtf/text/StringHash.h>
namespace JSC { namespace Yarr {
@@ -352,7 +353,7 @@
struct YarrPattern {
- JS_EXPORT_PRIVATE YarrPattern(const String& pattern, RegExpFlags, ErrorCode&, void* stackLimit = nullptr);
+ JS_EXPORT_PRIVATE YarrPattern(const String& pattern, OptionSet<Flags>, ErrorCode&, void* stackLimit = nullptr);
void resetForReparsing()
{
@@ -507,12 +508,12 @@
void dumpPattern(const String& pattern);
void dumpPattern(PrintStream& out, const String& pattern);
- bool global() const { return m_flags & FlagGlobal; }
- bool ignoreCase() const { return m_flags & FlagIgnoreCase; }
- bool multiline() const { return m_flags & FlagMultiline; }
- bool sticky() const { return m_flags & FlagSticky; }
- bool unicode() const { return m_flags & FlagUnicode; }
- bool dotAll() const { return m_flags & FlagDotAll; }
+ bool global() const { return m_flags.contains(Flags::Global); }
+ bool ignoreCase() const { return m_flags.contains(Flags::IgnoreCase); }
+ bool multiline() const { return m_flags.contains(Flags::Multiline); }
+ bool sticky() const { return m_flags.contains(Flags::Sticky); }
+ bool unicode() const { return m_flags.contains(Flags::Unicode); }
+ bool dotAll() const { return m_flags.contains(Flags::DotAll); }
bool m_containsBackreferences : 1;
bool m_containsBOL : 1;
@@ -519,7 +520,7 @@
bool m_containsUnsignedLengthPattern : 1;
bool m_hasCopiedParenSubexpressions : 1;
bool m_saveInitialStartValue : 1;
- RegExpFlags m_flags;
+ OptionSet<Flags> m_flags;
unsigned m_numSubpatterns { 0 };
unsigned m_maxBackReference { 0 };
unsigned m_initialStartValueFrameLocation { 0 };
Modified: trunk/Source/_javascript_Core/yarr/YarrSyntaxChecker.cpp (242698 => 242699)
--- trunk/Source/_javascript_Core/yarr/YarrSyntaxChecker.cpp 2019-03-11 06:04:00 UTC (rev 242698)
+++ trunk/Source/_javascript_Core/yarr/YarrSyntaxChecker.cpp 2019-03-11 06:20:53 UTC (rev 242699)
@@ -26,9 +26,9 @@
#include "config.h"
#include "YarrSyntaxChecker.h"
+#include "YarrFlags.h"
#include "YarrParser.h"
#include <wtf/Optional.h>
-#include <wtf/text/WTFString.h>
namespace JSC { namespace Yarr {
@@ -58,7 +58,12 @@
ErrorCode checkSyntax(const String& pattern, const String& flags)
{
SyntaxChecker syntaxChecker;
- return parse(syntaxChecker, pattern, flags.contains('u'));
+
+ auto parsedFlags = parseFlags(flags);
+ if (!parsedFlags)
+ return ErrorCode::InvalidRegularExpressionFlags;
+
+ return parse(syntaxChecker, pattern, parsedFlags->contains(Flags::Unicode));
}
}} // JSC::Yarr
Modified: trunk/Source/WebCore/ChangeLog (242698 => 242699)
--- trunk/Source/WebCore/ChangeLog 2019-03-11 06:04:00 UTC (rev 242698)
+++ trunk/Source/WebCore/ChangeLog 2019-03-11 06:20:53 UTC (rev 242699)
@@ -1,3 +1,14 @@
+2019-03-10 Ross Kirsling <[email protected]>
+
+ Invalid flags in a RegExp literal should be an early SyntaxError
+ https://bugs.webkit.org/show_bug.cgi?id=195514
+
+ Reviewed by Darin Adler.
+
+ * bindings/js/SerializedScriptValue.cpp:
+ (WebCore::CloneDeserializer::readTerminal):
+ Consume YarrFlags.
+
2019-03-10 Tim Horton <[email protected]>
Add SPI to retrieve the set of text inputs in a given rect, and later focus one
Modified: trunk/Source/WebCore/bindings/js/SerializedScriptValue.cpp (242698 => 242699)
--- trunk/Source/WebCore/bindings/js/SerializedScriptValue.cpp 2019-03-11 06:04:00 UTC (rev 242698)
+++ trunk/Source/WebCore/bindings/js/SerializedScriptValue.cpp 2019-03-11 06:20:53 UTC (rev 242699)
@@ -56,7 +56,6 @@
#include "SharedBuffer.h"
#include "WebCoreJSClientData.h"
#include <_javascript_Core/APICast.h>
-#include <_javascript_Core/ArrayBuffer.h>
#include <_javascript_Core/BooleanObject.h>
#include <_javascript_Core/CatchScope.h>
#include <_javascript_Core/DateInstance.h>
@@ -81,6 +80,7 @@
#include <_javascript_Core/TypedArrayInlines.h>
#include <_javascript_Core/TypedArrays.h>
#include <_javascript_Core/WasmModule.h>
+#include <_javascript_Core/YarrFlags.h>
#include <limits>
#include <wtf/MainThread.h>
#include <wtf/RunLoop.h>
@@ -2891,10 +2891,10 @@
CachedStringRef flags;
if (!readStringData(flags))
return JSValue();
- RegExpFlags reFlags = regExpFlags(flags->string());
- ASSERT(reFlags != InvalidFlags);
+ auto reFlags = Yarr::parseFlags(flags->string());
+ ASSERT(reFlags.hasValue());
VM& vm = m_exec->vm();
- RegExp* regExp = RegExp::create(vm, pattern->string(), reFlags);
+ RegExp* regExp = RegExp::create(vm, pattern->string(), reFlags.value());
return RegExpObject::create(vm, m_globalObject->regExpStructure(), regExp);
}
case ObjectReferenceTag: {