Changeset 242699 in webkit
- Timestamp:
- Mar 10, 2019, 11:20:53 PM (7 years ago)
- Location:
- trunk
- Files:
-
- 2 added
- 1 deleted
- 25 edited
-
JSTests/ChangeLog (modified) (1 diff)
-
JSTests/stress/regexp-syntax-error-invalid-flags.js (modified) (1 diff)
-
JSTests/stress/regress-161995.js (deleted)
-
JSTests/test262/expectations.yaml (modified) (1 diff)
-
Source/JavaScriptCore/CMakeLists.txt (modified) (1 diff)
-
Source/JavaScriptCore/ChangeLog (modified) (1 diff)
-
Source/JavaScriptCore/JavaScriptCore.xcodeproj/project.pbxproj (modified) (4 diffs)
-
Source/JavaScriptCore/Sources.txt (modified) (1 diff)
-
Source/JavaScriptCore/bytecompiler/NodesCodegen.cpp (modified) (2 diffs)
-
Source/JavaScriptCore/inspector/ContentSearchUtilities.cpp (modified) (2 diffs)
-
Source/JavaScriptCore/runtime/CachedTypes.cpp (modified) (4 diffs)
-
Source/JavaScriptCore/runtime/RegExp.cpp (modified) (5 diffs)
-
Source/JavaScriptCore/runtime/RegExp.h (modified) (5 diffs)
-
Source/JavaScriptCore/runtime/RegExpCache.cpp (modified) (2 diffs)
-
Source/JavaScriptCore/runtime/RegExpCache.h (modified) (2 diffs)
-
Source/JavaScriptCore/runtime/RegExpConstructor.cpp (modified) (5 diffs)
-
Source/JavaScriptCore/runtime/RegExpKey.h (modified) (4 diffs)
-
Source/JavaScriptCore/runtime/RegExpPrototype.cpp (modified) (3 diffs)
-
Source/JavaScriptCore/testRegExp.cpp (modified) (2 diffs)
-
Source/JavaScriptCore/yarr/RegularExpression.cpp (modified) (2 diffs)
-
Source/JavaScriptCore/yarr/YarrFlags.cpp (added)
-
Source/JavaScriptCore/yarr/YarrFlags.h (added)
-
Source/JavaScriptCore/yarr/YarrInterpreter.h (modified) (2 diffs)
-
Source/JavaScriptCore/yarr/YarrPattern.cpp (modified) (5 diffs)
-
Source/JavaScriptCore/yarr/YarrPattern.h (modified) (4 diffs)
-
Source/JavaScriptCore/yarr/YarrSyntaxChecker.cpp (modified) (2 diffs)
-
Source/WebCore/ChangeLog (modified) (1 diff)
-
Source/WebCore/bindings/js/SerializedScriptValue.cpp (modified) (3 diffs)
Legend:
- Unmodified
- Added
- Removed
-
trunk/JSTests/ChangeLog
r242667 r242699 1 2019-03-10 Ross Kirsling <ross.kirsling@sony.com> 2 3 Invalid flags in a RegExp literal should be an early SyntaxError 4 https://bugs.webkit.org/show_bug.cgi?id=195514 5 6 Reviewed by Darin Adler. 7 8 * test262/expectations.yaml: 9 Mark 4 test cases as passing. 10 11 * stress/regexp-syntax-error-invalid-flags.js: 12 * stress/regress-161995.js: Removed. 13 Update existing test, merging in an older test for the same behavior. 14 1 15 2019-03-08 Mark Lam <mark.lam@apple.com> 2 16 -
trunk/JSTests/stress/regexp-syntax-error-invalid-flags.js
r226209 r242699 1 function shouldThrow(func, errorMessage) { 2 var errorThrown = false; 3 var error = null; 1 function shouldThrowSyntaxError(script) { 2 let error; 4 3 try { 5 func();4 eval(script); 6 5 } catch (e) { 7 errorThrown = true;8 6 error = e; 9 7 } 10 if (!errorThrown) 8 9 if (!error) 11 10 throw new Error('not thrown'); 12 if (String(error) !== errorMessage)11 if (String(error) !== 'SyntaxError: Invalid regular expression: invalid flags') 13 12 throw new Error(`bad error: ${String(error)}`); 14 13 } 15 14 16 function test() 17 { 18 return /Hello/cocoa; 19 } 20 noInline(test); 21 22 for (var i = 0; i < 1e4; ++i) 23 shouldThrow(test, `SyntaxError: Invalid regular expression: invalid flags`); 15 shouldThrowSyntaxError('/Hello/cocoa'); 16 shouldThrowSyntaxError('/a/Z'); 17 shouldThrowSyntaxError('/./ii'); -
trunk/JSTests/test262/expectations.yaml
r240754 r242699 2397 2397 default: 'SyntaxError: No identifiers allowed directly after numeric literal' 2398 2398 strict mode: 'SyntaxError: No identifiers allowed directly after numeric literal' 2399 test/language/literals/regexp/early-err-bad-flag.js:2400 default: 'Test262: This statement should not be evaluated.'2401 strict mode: 'Test262: This statement should not be evaluated.'2402 test/language/literals/regexp/early-err-dup-flag.js:2403 default: 'Test262: This statement should not be evaluated.'2404 strict mode: 'Test262: This statement should not be evaluated.'2405 2399 test/language/literals/regexp/named-groups/invalid-dangling-groupname-2-u.js: 2406 2400 default: 'Test262: This statement should not be evaluated.' -
trunk/Source/JavaScriptCore/CMakeLists.txt
r242123 r242699 1001 1001 yarr/Yarr.h 1002 1002 yarr/YarrErrorCode.h 1003 yarr/YarrFlags.h 1003 1004 yarr/YarrInterpreter.h 1004 1005 yarr/YarrJIT.h -
trunk/Source/JavaScriptCore/ChangeLog
r242674 r242699 1 2019-03-10 Ross Kirsling <ross.kirsling@sony.com> 2 3 Invalid flags in a RegExp literal should be an early SyntaxError 4 https://bugs.webkit.org/show_bug.cgi?id=195514 5 6 Reviewed by Darin Adler. 7 8 Currently we're throwing a *runtime* SyntaxError; this should occur at parse time. 9 10 12.2.8.1 Static Semantics: Early Errors 11 PrimaryExpression : RegularExpressionLiteral 12 - It is a Syntax Error if BodyText of RegularExpressionLiteral cannot be recognized 13 using the goal symbol Pattern of the ECMAScript RegExp grammar specified in 21.2.1. 14 - It is a Syntax Error if FlagText of RegularExpressionLiteral contains any code points 15 other than "g", "i", "m", "s", "u", or "y", or if it contains the same code point more than once. 16 17 In fixing this, let's also move flag handling from runtime/ to yarr/. 18 19 * yarr/YarrSyntaxChecker.cpp: 20 (JSC::Yarr::checkSyntax): 21 Check flags before checking pattern. 22 23 * CMakeLists.txt: 24 * JavaScriptCore.xcodeproj/project.pbxproj: 25 * Sources.txt: 26 * bytecompiler/NodesCodegen.cpp: 27 (JSC::RegExpNode::emitBytecode): 28 * inspector/ContentSearchUtilities.cpp: 29 (Inspector::ContentSearchUtilities::findMagicComment): 30 * runtime/CachedTypes.cpp: 31 * runtime/RegExp.cpp: 32 (JSC::RegExp::RegExp): 33 (JSC::RegExp::createWithoutCaching): 34 (JSC::RegExp::create): 35 (JSC::regExpFlags): Deleted. 36 * runtime/RegExp.h: 37 * runtime/RegExpCache.cpp: 38 (JSC::RegExpCache::lookupOrCreate): 39 (JSC::RegExpCache::ensureEmptyRegExpSlow): 40 * runtime/RegExpCache.h: 41 * runtime/RegExpConstructor.cpp: 42 (JSC::toFlags): 43 (JSC::regExpCreate): 44 (JSC::constructRegExp): 45 * runtime/RegExpKey.h: 46 (JSC::RegExpKey::RegExpKey): 47 (WTF::HashTraits<JSC::RegExpKey>::constructDeletedValue): 48 (WTF::HashTraits<JSC::RegExpKey>::isDeletedValue): 49 (): Deleted. 50 * runtime/RegExpPrototype.cpp: 51 (JSC::regExpProtoFuncCompile): 52 * testRegExp.cpp: 53 (parseRegExpLine): 54 * yarr/RegularExpression.cpp: 55 (JSC::Yarr::RegularExpression::Private::compile): 56 * yarr/YarrFlags.cpp: Added. 57 (JSC::Yarr::parseFlags): 58 * yarr/YarrFlags.h: Added. 59 * yarr/YarrInterpreter.h: 60 (JSC::Yarr::BytecodePattern::ignoreCase const): 61 (JSC::Yarr::BytecodePattern::multiline const): 62 (JSC::Yarr::BytecodePattern::sticky const): 63 (JSC::Yarr::BytecodePattern::unicode const): 64 (JSC::Yarr::BytecodePattern::dotAll const): 65 * yarr/YarrPattern.cpp: 66 (JSC::Yarr::YarrPattern::compile): 67 (JSC::Yarr::YarrPattern::YarrPattern): 68 (JSC::Yarr::YarrPattern::dumpPattern): 69 * yarr/YarrPattern.h: 70 (JSC::Yarr::YarrPattern::global const): 71 (JSC::Yarr::YarrPattern::ignoreCase const): 72 (JSC::Yarr::YarrPattern::multiline const): 73 (JSC::Yarr::YarrPattern::sticky const): 74 (JSC::Yarr::YarrPattern::unicode const): 75 (JSC::Yarr::YarrPattern::dotAll const): 76 Move flag handling to Yarr and modernize API. 77 1 78 2019-03-09 Robin Morisset <rmorisset@apple.com> 2 79 -
trunk/Source/JavaScriptCore/JavaScriptCore.xcodeproj/project.pbxproj
r242252 r242699 1340 1340 A1D792FF1B43864B004516F5 /* IntlNumberFormatConstructor.h in Headers */ = {isa = PBXBuildFile; fileRef = A1D792F91B43864B004516F5 /* IntlNumberFormatConstructor.h */; }; 1341 1341 A1D793011B43864B004516F5 /* IntlNumberFormatPrototype.h in Headers */ = {isa = PBXBuildFile; fileRef = A1D792FB1B43864B004516F5 /* IntlNumberFormatPrototype.h */; }; 1342 A3FF9BC72234749100B1A9AB /* YarrFlags.h in Headers */ = {isa = PBXBuildFile; fileRef = A3FF9BC52234746600B1A9AB /* YarrFlags.h */; settings = {ATTRIBUTES = (Private, ); }; }; 1342 1343 A503FA1A188E0FB000110F14 /* JavaScriptCallFrame.h in Headers */ = {isa = PBXBuildFile; fileRef = A503FA14188E0FAF00110F14 /* JavaScriptCallFrame.h */; }; 1343 1344 A503FA1E188E0FB000110F14 /* JSJavaScriptCallFramePrototype.h in Headers */ = {isa = PBXBuildFile; fileRef = A503FA18188E0FB000110F14 /* JSJavaScriptCallFramePrototype.h */; }; … … 4087 4088 A1FE1EB01C2C537E00A289FF /* DatePrototype.js */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.javascript; path = DatePrototype.js; sourceTree = "<group>"; }; 4088 4089 A27958D7FA1142B0AC9E364D /* WasmContextInlines.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = WasmContextInlines.h; sourceTree = "<group>"; }; 4090 A3FF9BC52234746600B1A9AB /* YarrFlags.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = YarrFlags.h; path = yarr/YarrFlags.h; sourceTree = "<group>"; }; 4091 A3FF9BC62234746600B1A9AB /* YarrFlags.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = YarrFlags.cpp; path = yarr/YarrFlags.cpp; sourceTree = "<group>"; }; 4089 4092 A503FA13188E0FAF00110F14 /* JavaScriptCallFrame.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = JavaScriptCallFrame.cpp; sourceTree = "<group>"; }; 4090 4093 A503FA14188E0FAF00110F14 /* JavaScriptCallFrame.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = JavaScriptCallFrame.h; sourceTree = "<group>"; }; … … 7304 7307 E3282BB91FE930A300EDAF71 /* YarrErrorCode.cpp */, 7305 7308 E3282BBA1FE930A400EDAF71 /* YarrErrorCode.h */, 7309 A3FF9BC62234746600B1A9AB /* YarrFlags.cpp */, 7310 A3FF9BC52234746600B1A9AB /* YarrFlags.h */, 7306 7311 86704B7D12DBA33700A9FE7B /* YarrInterpreter.cpp */, 7307 7312 86704B7E12DBA33700A9FE7B /* YarrInterpreter.h */, … … 9897 9902 451539B912DC994500EF7AC4 /* Yarr.h in Headers */, 9898 9903 E3282BBB1FE930AF00EDAF71 /* YarrErrorCode.h in Headers */, 9904 A3FF9BC72234749100B1A9AB /* YarrFlags.h in Headers */, 9899 9905 86704B8512DBA33700A9FE7B /* YarrInterpreter.h in Headers */, 9900 9906 86704B8712DBA33700A9FE7B /* YarrJIT.h in Headers */, -
trunk/Source/JavaScriptCore/Sources.txt
r242123 r242699 1046 1046 yarr/YarrDisassembler.cpp 1047 1047 yarr/YarrErrorCode.cpp 1048 yarr/YarrFlags.cpp 1048 1049 yarr/YarrInterpreter.cpp 1049 1050 yarr/YarrJIT.cpp -
trunk/Source/JavaScriptCore/bytecompiler/NodesCodegen.cpp
r242591 r242699 42 42 #include "Parser.h" 43 43 #include "StackAlignment.h" 44 #include "YarrFlags.h" 44 45 #include <wtf/Assertions.h> 45 46 #include <wtf/Threading.h> … … 142 143 if (dst == generator.ignoredResult()) 143 144 return nullptr; 144 RegExp* regExp = RegExp::create(*generator.vm(), m_pattern.string(), regExpFlags(m_flags.string())); 145 146 auto flags = Yarr::parseFlags(m_flags.string()); 147 ASSERT(flags.hasValue()); 148 RegExp* regExp = RegExp::create(*generator.vm(), m_pattern.string(), flags.value()); 145 149 if (regExp->isValid()) 146 150 return generator.emitNewRegExp(generator.finalDestination(dst), regExp); 151 147 152 const char* messageCharacters = regExp->errorMessage(); 148 153 const Identifier& message = generator.parserArena().identifierArena().makeIdentifier(generator.vm(), bitwise_cast<const LChar*>(messageCharacters), strlen(messageCharacters)); -
trunk/Source/JavaScriptCore/inspector/ContentSearchUtilities.cpp
r233122 r242699 32 32 #include "RegularExpression.h" 33 33 #include "Yarr.h" 34 #include "YarrFlags.h" 34 35 #include "YarrInterpreter.h" 35 36 #include <wtf/BumpPointerAllocator.h> … … 168 169 169 170 JSC::Yarr::ErrorCode error { JSC::Yarr::ErrorCode::NoError }; 170 YarrPattern pattern(patternString, JSC:: RegExpFlags::FlagMultiline, error);171 YarrPattern pattern(patternString, JSC::Yarr::Flags::Multiline, error); 171 172 ASSERT(!hasError(error)); 172 173 BumpPointerAllocator regexAllocator; -
trunk/Source/JavaScriptCore/runtime/CachedTypes.cpp
r242605 r242699 29 29 #include "BytecodeCacheVersion.h" 30 30 #include "BytecodeLivenessAnalysis.h" 31 #include "JSCast.h"32 31 #include "JSImmutableButterfly.h" 33 32 #include "JSTemplateObjectDescriptor.h" … … 41 40 #include "UnlinkedProgramCodeBlock.h" 42 41 #include <wtf/FastMalloc.h> 43 #include <wtf/Forward.h>44 42 #include <wtf/Optional.h> 45 43 #include <wtf/UUID.h> … … 47 45 48 46 namespace JSC { 47 48 namespace Yarr { 49 enum class Flags : uint8_t; 50 } 49 51 50 52 template <typename T, typename = void> … … 1112 1114 private: 1113 1115 CachedString m_patternString; 1114 RegExpFlagsm_flags;1116 OptionSet<Yarr::Flags> m_flags; 1115 1117 }; 1116 1118 -
trunk/Source/JavaScriptCore/runtime/RegExp.cpp
r237763 r242699 29 29 #include "RegExpCache.h" 30 30 #include "RegExpInlines.h" 31 #include "Yarr.h"32 31 #include "YarrJIT.h" 33 32 #include <wtf/Assertions.h> … … 36 35 37 36 const ClassInfo RegExp::s_info = { "RegExp", nullptr, nullptr, nullptr, CREATE_METHOD_TABLE(RegExp) }; 38 39 RegExpFlags regExpFlags(const String& string)40 {41 RegExpFlags flags = NoFlags;42 43 for (unsigned i = 0; i < string.length(); ++i) {44 switch (string[i]) {45 case 'g':46 if (flags & FlagGlobal)47 return InvalidFlags;48 flags = static_cast<RegExpFlags>(flags | FlagGlobal);49 break;50 51 case 'i':52 if (flags & FlagIgnoreCase)53 return InvalidFlags;54 flags = static_cast<RegExpFlags>(flags | FlagIgnoreCase);55 break;56 57 case 'm':58 if (flags & FlagMultiline)59 return InvalidFlags;60 flags = static_cast<RegExpFlags>(flags | FlagMultiline);61 break;62 63 case 's':64 if (flags & FlagDotAll)65 return InvalidFlags;66 flags = static_cast<RegExpFlags>(flags | FlagDotAll);67 break;68 69 case 'u':70 if (flags & FlagUnicode)71 return InvalidFlags;72 flags = static_cast<RegExpFlags>(flags | FlagUnicode);73 break;74 75 case 'y':76 if (flags & FlagSticky)77 return InvalidFlags;78 flags = static_cast<RegExpFlags>(flags | FlagSticky);79 break;80 81 default:82 return InvalidFlags;83 }84 }85 86 return flags;87 }88 37 89 38 #if REGEXP_FUNC_TEST_DATA_GEN … … 211 160 #endif 212 161 213 RegExp::RegExp(VM& vm, const String& patternString, RegExpFlagsflags)162 RegExp::RegExp(VM& vm, const String& patternString, OptionSet<Yarr::Flags> flags) 214 163 : JSCell(vm, vm.regExpStructure.get()) 215 164 , m_patternString(patternString) 216 165 , m_flags(flags) 217 166 { 167 ASSERT(m_flags != Yarr::Flags::DeletedValue); 218 168 } 219 169 … … 250 200 } 251 201 252 RegExp* RegExp::createWithoutCaching(VM& vm, const String& patternString, RegExpFlagsflags)202 RegExp* RegExp::createWithoutCaching(VM& vm, const String& patternString, OptionSet<Yarr::Flags> flags) 253 203 { 254 204 RegExp* regExp = new (NotNull, allocateCell<RegExp>(vm.heap)) RegExp(vm, patternString, flags); … … 257 207 } 258 208 259 RegExp* RegExp::create(VM& vm, const String& patternString, RegExpFlagsflags)209 RegExp* RegExp::create(VM& vm, const String& patternString, OptionSet<Yarr::Flags> flags) 260 210 { 261 211 return vm.regExpCache()->lookupOrCreate(patternString, flags); -
trunk/Source/JavaScriptCore/runtime/RegExp.h
r240255 r242699 39 39 class VM; 40 40 41 JS_EXPORT_PRIVATE RegExpFlags regExpFlags(const String&);42 43 41 class RegExp final : public JSCell { 44 42 friend class CachedRegExp; … … 48 46 static const unsigned StructureFlags = Base::StructureFlags | StructureIsImmortal; 49 47 50 JS_EXPORT_PRIVATE static RegExp* create(VM&, const String& pattern, RegExpFlags);48 JS_EXPORT_PRIVATE static RegExp* create(VM&, const String& pattern, OptionSet<Yarr::Flags>); 51 49 static const bool needsDestruction = true; 52 50 static void destroy(JSCell*); … … 54 52 JS_EXPORT_PRIVATE static void dumpToStream(const JSCell*, PrintStream&); 55 53 56 bool global() const { return m_flags & FlagGlobal; }57 bool ignoreCase() const { return m_flags & FlagIgnoreCase; }58 bool multiline() const { return m_flags & FlagMultiline; }59 bool sticky() const { return m_flags & FlagSticky; }54 bool global() const { return m_flags.contains(Yarr::Flags::Global); } 55 bool ignoreCase() const { return m_flags.contains(Yarr::Flags::IgnoreCase); } 56 bool multiline() const { return m_flags.contains(Yarr::Flags::Multiline); } 57 bool sticky() const { return m_flags.contains(Yarr::Flags::Sticky); } 60 58 bool globalOrSticky() const { return global() || sticky(); } 61 bool unicode() const { return m_flags & FlagUnicode; }62 bool dotAll() const { return m_flags & FlagDotAll; }59 bool unicode() const { return m_flags.contains(Yarr::Flags::Unicode); } 60 bool dotAll() const { return m_flags.contains(Yarr::Flags::DotAll); } 63 61 64 62 const String& pattern() const { return m_patternString; } 65 63 66 bool isValid() const { return !Yarr::hasError(m_constructionErrorCode) && m_flags != InvalidFlags; }64 bool isValid() const { return !Yarr::hasError(m_constructionErrorCode); } 67 65 const char* errorMessage() const { return Yarr::errorMessage(m_constructionErrorCode); } 68 66 JSObject* errorToThrow(ExecState* exec) { return Yarr::errorToThrow(exec, m_constructionErrorCode); } … … 137 135 private: 138 136 friend class RegExpCache; 139 RegExp(VM&, const String&, RegExpFlags);137 RegExp(VM&, const String&, OptionSet<Yarr::Flags>); 140 138 141 static RegExp* createWithoutCaching(VM&, const String&, RegExpFlags);139 static RegExp* createWithoutCaching(VM&, const String&, OptionSet<Yarr::Flags>); 142 140 143 141 enum RegExpState : uint8_t { … … 162 160 String m_patternString; 163 161 RegExpState m_state { NotCompiled }; 164 RegExpFlagsm_flags;162 OptionSet<Yarr::Flags> m_flags; 165 163 ConcurrentJSLock m_lock; 166 164 Yarr::ErrorCode m_constructionErrorCode { Yarr::ErrorCode::NoError }; -
trunk/Source/JavaScriptCore/runtime/RegExpCache.cpp
r241640 r242699 36 36 namespace JSC { 37 37 38 RegExp* RegExpCache::lookupOrCreate(const String& patternString, RegExpFlagsflags)38 RegExp* RegExpCache::lookupOrCreate(const String& patternString, OptionSet<Yarr::Flags> flags) 39 39 { 40 40 RegExpKey key(flags, patternString); … … 59 59 RegExp* RegExpCache::ensureEmptyRegExpSlow(VM& vm) 60 60 { 61 RegExp* regExp = RegExp::create(vm, "", NoFlags);61 RegExp* regExp = RegExp::create(vm, "", { }); 62 62 m_emptyRegExp.set(vm, regExp); 63 63 return regExp; -
trunk/Source/JavaScriptCore/runtime/RegExpCache.h
r241640 r242699 37 37 namespace JSC { 38 38 39 namespace Yarr { 40 enum class Flags : uint8_t; 41 } 42 39 43 class RegExpCache : private WeakHandleOwner { 40 44 WTF_MAKE_FAST_ALLOCATED; … … 64 68 RegExp* ensureEmptyRegExpSlow(VM&); 65 69 66 RegExp* lookupOrCreate(const WTF::String& patternString, RegExpFlags);70 RegExp* lookupOrCreate(const WTF::String& patternString, OptionSet<Yarr::Flags>); 67 71 void addToStrongCache(RegExp*); 68 72 RegExpCacheMap m_weakCache; // Holds all regular expressions currently live. -
trunk/Source/JavaScriptCore/runtime/RegExpConstructor.cpp
r242650 r242699 25 25 #include "Error.h" 26 26 #include "GetterSetter.h" 27 #include "JSCInlines.h"28 27 #include "RegExpGlobalDataInlines.h" 29 28 #include "RegExpPrototype.h" 30 29 #include "StructureInlines.h" 30 #include "YarrFlags.h" 31 31 32 32 namespace JSC { … … 178 178 } 179 179 180 inline RegExpFlagstoFlags(ExecState* exec, JSValue flags)180 inline OptionSet<Yarr::Flags> toFlags(ExecState* exec, JSValue flags) 181 181 { 182 182 VM& vm = exec->vm(); … … 184 184 185 185 if (flags.isUndefined()) 186 return NoFlags; 187 JSString* flagsString = flags.toStringOrNull(exec); 188 EXCEPTION_ASSERT(!!scope.exception() == !flagsString); 189 if (UNLIKELY(!flagsString)) 190 return InvalidFlags; 191 192 RegExpFlags result = regExpFlags(flagsString->value(exec)); 193 RETURN_IF_EXCEPTION(scope, InvalidFlags); 194 if (result == InvalidFlags) 186 return { }; 187 188 auto result = Yarr::parseFlags(flags.toWTFString(exec)); 189 RETURN_IF_EXCEPTION(scope, { }); 190 if (!result) { 195 191 throwSyntaxError(exec, scope, "Invalid flags supplied to RegExp constructor."_s); 196 return result; 192 return { }; 193 } 194 195 return result.value(); 197 196 } 198 197 … … 205 204 RETURN_IF_EXCEPTION(scope, nullptr); 206 205 207 RegExpFlags flags = toFlags(exec, flagsArg); 208 EXCEPTION_ASSERT(!!scope.exception() == (flags == InvalidFlags)); 209 if (UNLIKELY(flags == InvalidFlags)) 210 return nullptr; 206 auto flags = toFlags(exec, flagsArg); 207 RETURN_IF_EXCEPTION(scope, nullptr); 211 208 212 209 RegExp* regExp = RegExp::create(vm, pattern, flags); … … 247 244 248 245 if (!flagsArg.isUndefined()) { 249 RegExpFlags flags = toFlags(exec, flagsArg); 250 EXCEPTION_ASSERT(!!scope.exception() == (flags == InvalidFlags)); 251 if (flags == InvalidFlags) 252 return nullptr; 246 auto flags = toFlags(exec, flagsArg); 247 RETURN_IF_EXCEPTION(scope, nullptr); 248 253 249 regExp = RegExp::create(vm, regExp->pattern(), flags); 254 255 250 if (UNLIKELY(!regExp->isValid())) { 256 251 throwException(exec, scope, regExp->errorToThrow(exec)); -
trunk/Source/JavaScriptCore/runtime/RegExpKey.h
r233621 r242699 28 28 #pragma once 29 29 30 #include "YarrFlags.h" 31 #include <wtf/OptionSet.h> 30 32 #include <wtf/text/StringHash.h> 31 #include <wtf/text/WTFString.h>32 33 33 34 namespace JSC { 34 35 35 enum RegExpFlags : int8_t {36 NoFlags = 0,37 FlagGlobal = 1,38 FlagIgnoreCase = 2,39 FlagMultiline = 4,40 FlagSticky = 8,41 FlagUnicode = 16,42 FlagDotAll = 32,43 InvalidFlags = 64,44 DeletedValueFlags = -145 };46 47 36 struct RegExpKey { 48 RegExpFlagsflagsValue;37 OptionSet<Yarr::Flags> flagsValue; 49 38 RefPtr<StringImpl> pattern; 50 39 51 40 RegExpKey() 52 : flagsValue(NoFlags)53 41 { 54 42 } 55 43 56 RegExpKey( RegExpFlagsflags)44 RegExpKey(OptionSet<Yarr::Flags> flags) 57 45 : flagsValue(flags) 58 46 { 59 47 } 60 48 61 RegExpKey( RegExpFlagsflags, const String& pattern)49 RegExpKey(OptionSet<Yarr::Flags> flags, const String& pattern) 62 50 : flagsValue(flags) 63 51 , pattern(pattern.impl()) … … 65 53 } 66 54 67 RegExpKey( RegExpFlagsflags, RefPtr<StringImpl>&& pattern)55 RegExpKey(OptionSet<Yarr::Flags> flags, RefPtr<StringImpl>&& pattern) 68 56 : flagsValue(flags) 69 57 , pattern(WTFMove(pattern)) … … 71 59 } 72 60 73 RegExpKey( RegExpFlagsflags, const RefPtr<StringImpl>& pattern)61 RegExpKey(OptionSet<Yarr::Flags> flags, const RefPtr<StringImpl>& pattern) 74 62 : flagsValue(flags) 75 63 , pattern(pattern) … … 108 96 template<> struct HashTraits<JSC::RegExpKey> : GenericHashTraits<JSC::RegExpKey> { 109 97 static const bool emptyValueIsZero = true; 110 static void constructDeletedValue(JSC::RegExpKey& slot) { slot.flagsValue = JSC:: DeletedValueFlags; }111 static bool isDeletedValue(const JSC::RegExpKey& value) { return value.flagsValue == JSC:: DeletedValueFlags; }98 static void constructDeletedValue(JSC::RegExpKey& slot) { slot.flagsValue = JSC::Yarr::Flags::DeletedValue; } 99 static bool isDeletedValue(const JSC::RegExpKey& value) { return value.flagsValue == JSC::Yarr::Flags::DeletedValue; } 112 100 }; 113 101 } // namespace WTF -
trunk/Source/JavaScriptCore/runtime/RegExpPrototype.cpp
r242650 r242699 30 30 #include "JSCJSValue.h" 31 31 #include "JSFunction.h" 32 #include "JSObject.h"33 32 #include "JSStringInlines.h" 34 33 #include "Lexer.h" 35 34 #include "ObjectPrototype.h" 36 #include "RegExp.h"37 35 #include "RegExpCache.h" 38 36 #include "RegExpObject.h" … … 40 38 #include "StringObject.h" 41 39 #include "StringRecursionChecker.h" 40 #include "YarrFlags.h" 42 41 #include <wtf/text/StringBuilder.h> 43 42 … … 150 149 RETURN_IF_EXCEPTION(scope, encodedJSValue()); 151 150 152 RegExpFlags flags = NoFlags; 153 if (!arg1.isUndefined()) { 154 flags = regExpFlags(arg1.toWTFString(exec)); 155 RETURN_IF_EXCEPTION(scope, encodedJSValue()); 156 if (flags == InvalidFlags) 157 return throwVMError(exec, scope, createSyntaxError(exec, "Invalid flags supplied to RegExp constructor."_s)); 158 } 159 regExp = RegExp::create(vm, pattern, flags); 151 auto flags = arg1.isUndefined() ? makeOptional(OptionSet<Yarr::Flags> { }) : Yarr::parseFlags(arg1.toWTFString(exec)); 152 RETURN_IF_EXCEPTION(scope, encodedJSValue()); 153 if (!flags) 154 return throwVMError(exec, scope, createSyntaxError(exec, "Invalid flags supplied to RegExp constructor."_s)); 155 156 regExp = RegExp::create(vm, pattern, flags.value()); 160 157 } 161 158 -
trunk/Source/JavaScriptCore/testRegExp.cpp
r240641 r242699 25 25 #include "JSCInlines.h" 26 26 #include "JSGlobalObject.h" 27 #include "YarrFlags.h" 27 28 #include <errno.h> 28 29 #include <stdio.h> … … 329 330 ++i; 330 331 331 RegExp* r = RegExp::create(vm, pattern.toString(), regExpFlags(line + i)); 332 auto flags = Yarr::parseFlags(line + i); 333 if (!flags) { 334 *regexpError = Yarr::errorMessage(Yarr::ErrorCode::InvalidRegularExpressionFlags); 335 return nullptr; 336 } 337 338 RegExp* r = RegExp::create(vm, pattern.toString(), flags.value()); 332 339 if (!r->isValid()) { 333 340 *regexpError = r->errorMessage(); 334 341 return nullptr; 335 342 } 343 336 344 return r; 337 345 } -
trunk/Source/JavaScriptCore/yarr/RegularExpression.cpp
r229363 r242699 30 30 31 31 #include "Yarr.h" 32 #include "YarrFlags.h" 32 33 #include "YarrInterpreter.h" 33 34 #include <wtf/Assertions.h> … … 56 57 std::unique_ptr<JSC::Yarr::BytecodePattern> compile(const String& patternString, TextCaseSensitivity caseSensitivity, MultilineMode multilineMode, UnicodeMode unicodeMode) 57 58 { 58 RegExpFlags flags = NoFlags;59 OptionSet<JSC::Yarr::Flags> flags; 59 60 60 61 if (caseSensitivity == TextCaseInsensitive) 61 flags = static_cast<RegExpFlags>(flags | FlagIgnoreCase);62 flags.add(Flags::IgnoreCase); 62 63 63 64 if (multilineMode == MultilineEnabled) 64 flags = static_cast<RegExpFlags>(flags | FlagMultiline);65 flags.add(Flags::Multiline); 65 66 66 67 if (unicodeMode == UnicodeAwareMode) 67 flags = static_cast<RegExpFlags>(flags | FlagUnicode);68 flags.add(Flags::Unicode); 68 69 69 70 JSC::Yarr::YarrPattern pattern(patternString, flags, m_constructionErrorCode); -
trunk/Source/JavaScriptCore/yarr/YarrInterpreter.h
r221160 r242699 27 27 28 28 #include "ConcurrentJSLock.h" 29 #include "YarrFlags.h" 29 30 #include "YarrPattern.h" 30 31 … … 368 369 size_t estimatedSizeInBytes() const { return m_body->estimatedSizeInBytes(); } 369 370 370 bool ignoreCase() const { return m_flags & FlagIgnoreCase; }371 bool multiline() const { return m_flags & FlagMultiline; }372 bool sticky() const { return m_flags & FlagSticky; }373 bool unicode() const { return m_flags & FlagUnicode; }374 bool dotAll() const { return m_flags & FlagDotAll; }371 bool ignoreCase() const { return m_flags.contains(Flags::IgnoreCase); } 372 bool multiline() const { return m_flags.contains(Flags::Multiline); } 373 bool sticky() const { return m_flags.contains(Flags::Sticky); } 374 bool unicode() const { return m_flags.contains(Flags::Unicode); } 375 bool dotAll() const { return m_flags.contains(Flags::DotAll); } 375 376 376 377 std::unique_ptr<ByteDisjunction> m_body; 377 RegExpFlagsm_flags;378 OptionSet<Flags> m_flags; 378 379 // Each BytecodePattern is associated with a RegExp, each RegExp is associated 379 380 // with a VM. Cache a pointer to out VM's m_regExpAllocator. -
trunk/Source/JavaScriptCore/yarr/YarrPattern.cpp
r240641 r242699 37 37 #include <wtf/Threading.h> 38 38 #include <wtf/Vector.h> 39 #include <wtf/text/WTFString.h>40 39 41 40 namespace JSC { namespace Yarr { … … 1111 1110 YarrPatternConstructor constructor(*this, stackLimit); 1112 1111 1113 if (m_flags == InvalidFlags)1114 return ErrorCode::InvalidRegularExpressionFlags;1115 1116 1112 { 1117 1113 ErrorCode error = parse(constructor, patternString, unicode()); … … 1153 1149 } 1154 1150 1155 YarrPattern::YarrPattern(const String& pattern, RegExpFlagsflags, ErrorCode& error, void* stackLimit)1151 YarrPattern::YarrPattern(const String& pattern, OptionSet<Flags> flags, ErrorCode& error, void* stackLimit) 1156 1152 : m_containsBackreferences(false) 1157 1153 , m_containsBOL(false) … … 1161 1157 , m_flags(flags) 1162 1158 { 1159 ASSERT(m_flags != Flags::DeletedValue); 1163 1160 error = compile(pattern, stackLimit); 1164 1161 } … … 1421 1418 dumpPatternString(out, patternString); 1422 1419 1423 if (m_flags != NoFlags) {1420 if (m_flags) { 1424 1421 bool printSeperator = false; 1425 1422 out.print(" ("); -
trunk/Source/JavaScriptCore/yarr/YarrPattern.h
r235882 r242699 27 27 #pragma once 28 28 29 #include "RegExpKey.h"30 29 #include "YarrErrorCode.h" 30 #include "YarrFlags.h" 31 31 #include "YarrUnicodeProperties.h" 32 32 #include <wtf/CheckedArithmetic.h> 33 33 #include <wtf/HashMap.h> 34 #include <wtf/OptionSet.h> 34 35 #include <wtf/PrintStream.h> 35 36 #include <wtf/Vector.h> 36 #include <wtf/text/ WTFString.h>37 #include <wtf/text/StringHash.h> 37 38 38 39 namespace JSC { namespace Yarr { … … 353 354 354 355 struct YarrPattern { 355 JS_EXPORT_PRIVATE YarrPattern(const String& pattern, RegExpFlags, ErrorCode&, void* stackLimit = nullptr);356 JS_EXPORT_PRIVATE YarrPattern(const String& pattern, OptionSet<Flags>, ErrorCode&, void* stackLimit = nullptr); 356 357 357 358 void resetForReparsing() … … 508 509 void dumpPattern(PrintStream& out, const String& pattern); 509 510 510 bool global() const { return m_flags & FlagGlobal; }511 bool ignoreCase() const { return m_flags & FlagIgnoreCase; }512 bool multiline() const { return m_flags & FlagMultiline; }513 bool sticky() const { return m_flags & FlagSticky; }514 bool unicode() const { return m_flags & FlagUnicode; }515 bool dotAll() const { return m_flags & FlagDotAll; }511 bool global() const { return m_flags.contains(Flags::Global); } 512 bool ignoreCase() const { return m_flags.contains(Flags::IgnoreCase); } 513 bool multiline() const { return m_flags.contains(Flags::Multiline); } 514 bool sticky() const { return m_flags.contains(Flags::Sticky); } 515 bool unicode() const { return m_flags.contains(Flags::Unicode); } 516 bool dotAll() const { return m_flags.contains(Flags::DotAll); } 516 517 517 518 bool m_containsBackreferences : 1; … … 520 521 bool m_hasCopiedParenSubexpressions : 1; 521 522 bool m_saveInitialStartValue : 1; 522 RegExpFlagsm_flags;523 OptionSet<Flags> m_flags; 523 524 unsigned m_numSubpatterns { 0 }; 524 525 unsigned m_maxBackReference { 0 }; -
trunk/Source/JavaScriptCore/yarr/YarrSyntaxChecker.cpp
r239427 r242699 27 27 #include "YarrSyntaxChecker.h" 28 28 29 #include "YarrFlags.h" 29 30 #include "YarrParser.h" 30 31 #include <wtf/Optional.h> 31 #include <wtf/text/WTFString.h>32 32 33 33 namespace JSC { namespace Yarr { … … 59 59 { 60 60 SyntaxChecker syntaxChecker; 61 return parse(syntaxChecker, pattern, flags.contains('u')); 61 62 auto parsedFlags = parseFlags(flags); 63 if (!parsedFlags) 64 return ErrorCode::InvalidRegularExpressionFlags; 65 66 return parse(syntaxChecker, pattern, parsedFlags->contains(Flags::Unicode)); 62 67 } 63 68 -
trunk/Source/WebCore/ChangeLog
r242696 r242699 1 2019-03-10 Ross Kirsling <ross.kirsling@sony.com> 2 3 Invalid flags in a RegExp literal should be an early SyntaxError 4 https://bugs.webkit.org/show_bug.cgi?id=195514 5 6 Reviewed by Darin Adler. 7 8 * bindings/js/SerializedScriptValue.cpp: 9 (WebCore::CloneDeserializer::readTerminal): 10 Consume YarrFlags. 11 1 12 2019-03-10 Tim Horton <timothy_horton@apple.com> 2 13 -
trunk/Source/WebCore/bindings/js/SerializedScriptValue.cpp
r239746 r242699 57 57 #include "WebCoreJSClientData.h" 58 58 #include <JavaScriptCore/APICast.h> 59 #include <JavaScriptCore/ArrayBuffer.h>60 59 #include <JavaScriptCore/BooleanObject.h> 61 60 #include <JavaScriptCore/CatchScope.h> … … 82 81 #include <JavaScriptCore/TypedArrays.h> 83 82 #include <JavaScriptCore/WasmModule.h> 83 #include <JavaScriptCore/YarrFlags.h> 84 84 #include <limits> 85 85 #include <wtf/MainThread.h> … … 2892 2892 if (!readStringData(flags)) 2893 2893 return JSValue(); 2894 RegExpFlags reFlags = regExpFlags(flags->string());2895 ASSERT(reFlags != InvalidFlags);2894 auto reFlags = Yarr::parseFlags(flags->string()); 2895 ASSERT(reFlags.hasValue()); 2896 2896 VM& vm = m_exec->vm(); 2897 RegExp* regExp = RegExp::create(vm, pattern->string(), reFlags );2897 RegExp* regExp = RegExp::create(vm, pattern->string(), reFlags.value()); 2898 2898 return RegExpObject::create(vm, m_globalObject->regExpStructure(), regExp); 2899 2899 }
Note:
See TracChangeset
for help on using the changeset viewer.