diff -Nru webkit2gtk-2.20.3/debian/changelog webkit2gtk-2.20.5/debian/changelog --- webkit2gtk-2.20.3/debian/changelog 2018-06-14 16:58:08.000000000 +0000 +++ webkit2gtk-2.20.5/debian/changelog 2018-08-15 11:45:42.000000000 +0000 @@ -1,3 +1,14 @@ +webkit2gtk (2.20.5-0ubuntu0.18.04.1) bionic-security; urgency=medium + + * Updated to 2.20.5 to fix security issues. + - CVE-2018-4246, CVE-2018-4261, CVE-2018-4262, CVE-2018-4263, + CVE-2018-4264, CVE-2018-4265, CVE-2018-4266, CVE-2018-4267, + CVE-2018-4270, CVE-2018-4272, CVE-2018-4273, CVE-2018-4278, + CVE-2018-4284, CVE-2018-12911 + * debian/patches/fix-ftbfs-m68k.patch: refreshed with new version. + + -- Marc Deslauriers Wed, 15 Aug 2018 07:45:42 -0400 + webkit2gtk (2.20.3-0ubuntu0.18.04.1) bionic-security; urgency=medium * Updated to 2.20.3 to fix security issues. diff -Nru webkit2gtk-2.20.3/debian/patches/fix-ftbfs-m68k.patch webkit2gtk-2.20.5/debian/patches/fix-ftbfs-m68k.patch --- webkit2gtk-2.20.3/debian/patches/fix-ftbfs-m68k.patch 2018-04-10 18:34:42.000000000 +0000 +++ webkit2gtk-2.20.5/debian/patches/fix-ftbfs-m68k.patch 2018-08-13 07:52:34.000000000 +0000 @@ -96,6 +96,18 @@ struct SameSizeAsRenderStyle { void* dataRefs[7]; +@@ -81,7 +85,11 @@ struct SameSizeAsRenderStyle { + #endif + }; + ++#if defined(__m68k__) ++static_assert(sizeof(RenderStyle) <= sizeof(SameSizeAsRenderStyle), "RenderStyle should stay small"); ++#else + static_assert(sizeof(RenderStyle) == sizeof(SameSizeAsRenderStyle), "RenderStyle should stay small"); ++#endif + + RenderStyle& RenderStyle::defaultStyle() + { Index: webkitgtk/Source/WebCore/rendering/style/StyleBoxData.cpp =================================================================== --- webkitgtk.orig/Source/WebCore/rendering/style/StyleBoxData.cpp diff -Nru webkit2gtk-2.20.3/Documentation/webkit2gtk-4.0/html/index.html webkit2gtk-2.20.5/Documentation/webkit2gtk-4.0/html/index.html --- webkit2gtk-2.20.3/Documentation/webkit2gtk-4.0/html/index.html 2018-06-11 11:49:14.000000000 +0000 +++ webkit2gtk-2.20.5/Documentation/webkit2gtk-4.0/html/index.html 2018-08-13 07:13:21.000000000 +0000 @@ -14,7 +14,7 @@
-

for WebKit2GTK+ 2.20.3

+

for WebKit2GTK+ 2.20.5


diff -Nru webkit2gtk-2.20.3/Documentation/webkit2gtk-4.0/html/webkit2gtk-4.0-WebKitVersion.html webkit2gtk-2.20.5/Documentation/webkit2gtk-4.0/html/webkit2gtk-4.0-WebKitVersion.html --- webkit2gtk-2.20.3/Documentation/webkit2gtk-4.0/html/webkit2gtk-4.0-WebKitVersion.html 2018-06-11 11:49:14.000000000 +0000 +++ webkit2gtk-2.20.5/Documentation/webkit2gtk-4.0/html/webkit2gtk-4.0-WebKitVersion.html 2018-08-13 07:13:21.000000000 +0000 @@ -213,7 +213,7 @@

WEBKIT_MICRO_VERSION

-
#define WEBKIT_MICRO_VERSION (3)
+
#define WEBKIT_MICRO_VERSION (5)
 

Like webkit_get_micro_version(), but from the headers used at application compile time, rather than from the library linked diff -Nru webkit2gtk-2.20.3/Documentation/webkitdomgtk-4.0/html/index.html webkit2gtk-2.20.5/Documentation/webkitdomgtk-4.0/html/index.html --- webkit2gtk-2.20.3/Documentation/webkitdomgtk-4.0/html/index.html 2018-06-11 11:48:54.000000000 +0000 +++ webkit2gtk-2.20.5/Documentation/webkitdomgtk-4.0/html/index.html 2018-08-13 07:13:00.000000000 +0000 @@ -14,7 +14,7 @@

-

for WebKitDOMGTK+ 2.20.3

+

for WebKitDOMGTK+ 2.20.5


diff -Nru webkit2gtk-2.20.3/NEWS webkit2gtk-2.20.5/NEWS --- webkit2gtk-2.20.3/NEWS 2018-06-11 11:48:04.000000000 +0000 +++ webkit2gtk-2.20.5/NEWS 2018-08-13 06:51:10.000000000 +0000 @@ -1,4 +1,23 @@ ================== +WebKitGTK+ 2.20.5 +================== + +What's new in WebKitGTK+ 2.20.5? + + - Fix rendering artifacts in some web sites due to a bug introduced in 2.20.4. + +================== +WebKitGTK+ 2.20.4 +================== + +What's new in WebKitGTK+ 2.20.4? + + - Fix a crash when leaving accelerated compositing mode. + - Fix non-deterministic build failure due to missing JavaScriptCore/JSContextRef.h. + - Security fixes: CVE-2018-4261, CVE-2018-4262, CVE-2018-4263, CVE-2018-4264, CVE-2018-4265, CVE-2018-4266, + CVE-2018-4267, CVE-2018-4270, CVE-2018-4272, CVE-2018-4273, CVE-2018-4278, CVE-2018-4284. + +================== WebKitGTK+ 2.20.3 ================== diff -Nru webkit2gtk-2.20.3/Source/cmake/OptionsGTK.cmake webkit2gtk-2.20.5/Source/cmake/OptionsGTK.cmake --- webkit2gtk-2.20.3/Source/cmake/OptionsGTK.cmake 2018-06-11 11:40:23.000000000 +0000 +++ webkit2gtk-2.20.5/Source/cmake/OptionsGTK.cmake 2018-08-13 06:49:32.000000000 +0000 @@ -1,11 +1,11 @@ include(GNUInstallDirs) include(VersioningUtils) -SET_PROJECT_VERSION(2 20 3) +SET_PROJECT_VERSION(2 20 5) set(WEBKITGTK_API_VERSION 4.0) -CALCULATE_LIBRARY_VERSIONS_FROM_LIBTOOL_TRIPLE(WEBKIT 65 3 28) -CALCULATE_LIBRARY_VERSIONS_FROM_LIBTOOL_TRIPLE(JAVASCRIPTCORE 25 11 7) +CALCULATE_LIBRARY_VERSIONS_FROM_LIBTOOL_TRIPLE(WEBKIT 65 5 28) +CALCULATE_LIBRARY_VERSIONS_FROM_LIBTOOL_TRIPLE(JAVASCRIPTCORE 25 13 7) # These are shared variables, but we special case their definition so that we can use the # CMAKE_INSTALL_* variables that are populated by the GNUInstallDirs macro. diff -Nru webkit2gtk-2.20.3/Source/JavaScriptCore/builtins/BuiltinNames.h webkit2gtk-2.20.5/Source/JavaScriptCore/builtins/BuiltinNames.h --- webkit2gtk-2.20.3/Source/JavaScriptCore/builtins/BuiltinNames.h 2018-02-19 07:45:14.000000000 +0000 +++ webkit2gtk-2.20.5/Source/JavaScriptCore/builtins/BuiltinNames.h 2018-06-14 06:01:36.000000000 +0000 @@ -83,6 +83,7 @@ macro(typedArrayGetOriginalConstructor) \ macro(typedArraySubarrayCreate) \ macro(BuiltinLog) \ + macro(BuiltinDescribe) \ macro(homeObject) \ macro(templateRegistryKey) \ macro(enqueueJob) \ diff -Nru webkit2gtk-2.20.3/Source/JavaScriptCore/bytecode/CodeBlock.cpp webkit2gtk-2.20.5/Source/JavaScriptCore/bytecode/CodeBlock.cpp --- webkit2gtk-2.20.3/Source/JavaScriptCore/bytecode/CodeBlock.cpp 2018-06-11 10:29:22.000000000 +0000 +++ webkit2gtk-2.20.5/Source/JavaScriptCore/bytecode/CodeBlock.cpp 2018-07-31 08:51:45.000000000 +0000 @@ -1241,9 +1241,7 @@ for (size_t size = propertyAccessInstructions.size(), i = 0; i < size; ++i) { Instruction* curInstruction = &instructions()[propertyAccessInstructions[i]]; switch (Interpreter::getOpcodeID(curInstruction[0])) { - case op_get_by_id: - case op_get_by_id_proto_load: - case op_get_by_id_unset: { + case op_get_by_id: { StructureID oldStructureID = curInstruction[4].u.structureID; if (!oldStructureID || Heap::isMarked(vm.heap.structureIDTable().get(oldStructureID))) break; @@ -1282,6 +1280,8 @@ // We need to add optimizations for op_resolve_scope_for_hoisting_func_decl_in_eval to do link time scope resolution. case op_resolve_scope_for_hoisting_func_decl_in_eval: break; + case op_get_by_id_proto_load: + case op_get_by_id_unset: case op_get_array_length: break; case op_to_this: @@ -1339,8 +1339,27 @@ // We can't just remove all the sets when we clear the caches since we might have created a watchpoint set // then cleared the cache without GCing in between. - m_llintGetByIdWatchpointMap.removeIf([](const StructureWatchpointMap::KeyValuePairType& pair) -> bool { - return !Heap::isMarked(pair.key); + m_llintGetByIdWatchpointMap.removeIf([&] (const StructureWatchpointMap::KeyValuePairType& pair) -> bool { + auto clear = [&] () { + Instruction* instruction = std::get<1>(pair.key); + OpcodeID opcode = Interpreter::getOpcodeID(*instruction); + if (opcode == op_get_by_id_proto_load || opcode == op_get_by_id_unset) { + if (Options::verboseOSR()) + dataLogF("Clearing LLInt property access.\n"); + clearLLIntGetByIdCache(instruction); + } + return true; + }; + + if (!Heap::isMarked(std::get<0>(pair.key))) + return clear(); + + for (const LLIntPrototypeLoadAdaptiveStructureWatchpoint* watchpoint : pair.value) { + if (!watchpoint->key().isStillLive()) + return clear(); + } + + return false; }); for (unsigned i = 0; i < m_llintCallLinkInfos.size(); ++i) { diff -Nru webkit2gtk-2.20.3/Source/JavaScriptCore/bytecode/CodeBlock.h webkit2gtk-2.20.5/Source/JavaScriptCore/bytecode/CodeBlock.h --- webkit2gtk-2.20.3/Source/JavaScriptCore/bytecode/CodeBlock.h 2018-02-20 10:12:21.000000000 +0000 +++ webkit2gtk-2.20.5/Source/JavaScriptCore/bytecode/CodeBlock.h 2018-07-31 08:51:45.000000000 +0000 @@ -625,7 +625,7 @@ return m_llintExecuteCounter; } - typedef HashMap> StructureWatchpointMap; + typedef HashMap, Bag> StructureWatchpointMap; StructureWatchpointMap& llintGetByIdWatchpointMap() { return m_llintGetByIdWatchpointMap; } // Functions for controlling when tiered compilation kicks in. This diff -Nru webkit2gtk-2.20.3/Source/JavaScriptCore/bytecode/LLIntPrototypeLoadAdaptiveStructureWatchpoint.h webkit2gtk-2.20.5/Source/JavaScriptCore/bytecode/LLIntPrototypeLoadAdaptiveStructureWatchpoint.h --- webkit2gtk-2.20.3/Source/JavaScriptCore/bytecode/LLIntPrototypeLoadAdaptiveStructureWatchpoint.h 2018-02-19 07:45:14.000000000 +0000 +++ webkit2gtk-2.20.5/Source/JavaScriptCore/bytecode/LLIntPrototypeLoadAdaptiveStructureWatchpoint.h 2018-07-31 08:51:37.000000000 +0000 @@ -33,16 +33,19 @@ class LLIntPrototypeLoadAdaptiveStructureWatchpoint : public Watchpoint { public: + LLIntPrototypeLoadAdaptiveStructureWatchpoint() = default; LLIntPrototypeLoadAdaptiveStructureWatchpoint(const ObjectPropertyCondition&, Instruction*); void install(); + const ObjectPropertyCondition& key() const { return m_key; } + protected: void fireInternal(const FireDetail&) override; private: ObjectPropertyCondition m_key; - Instruction* m_getByIdInstruction; + Instruction* m_getByIdInstruction { nullptr }; }; } // namespace JSC diff -Nru webkit2gtk-2.20.3/Source/JavaScriptCore/bytecode/ObjectPropertyConditionSet.h webkit2gtk-2.20.5/Source/JavaScriptCore/bytecode/ObjectPropertyConditionSet.h --- webkit2gtk-2.20.3/Source/JavaScriptCore/bytecode/ObjectPropertyConditionSet.h 2018-02-19 07:45:14.000000000 +0000 +++ webkit2gtk-2.20.5/Source/JavaScriptCore/bytecode/ObjectPropertyConditionSet.h 2018-07-31 08:51:45.000000000 +0000 @@ -67,7 +67,8 @@ } bool isValidAndWatchable() const; - + + size_t size() const { return m_data ? m_data->vector.size() : 0; } bool isEmpty() const { return !m_data; diff -Nru webkit2gtk-2.20.3/Source/JavaScriptCore/bytecode/Watchpoint.cpp webkit2gtk-2.20.5/Source/JavaScriptCore/bytecode/Watchpoint.cpp --- webkit2gtk-2.20.3/Source/JavaScriptCore/bytecode/Watchpoint.cpp 2018-02-19 07:45:14.000000000 +0000 +++ webkit2gtk-2.20.5/Source/JavaScriptCore/bytecode/Watchpoint.cpp 2018-07-31 07:50:44.000000000 +0000 @@ -92,6 +92,16 @@ WTF::storeStoreFence(); } +void WatchpointSet::fireAllSlow(VM&, DeferredWatchpointFire* deferredWatchpoints) +{ + ASSERT(state() == IsWatched); + + WTF::storeStoreFence(); + deferredWatchpoints->takeWatchpointsToFire(this); + m_state = IsInvalidated; // Do after moving watchpoints to deferredWatchpoints so deferredWatchpoints gets our current state. + WTF::storeStoreFence(); +} + void WatchpointSet::fireAllSlow(VM& vm, const char* reason) { fireAllSlow(vm, StringFireDetail(reason)); @@ -133,6 +143,15 @@ } } +void WatchpointSet::take(WatchpointSet* other) +{ + ASSERT(state() == ClearWatchpoint); + m_set.takeFrom(other->m_set); + m_setIsNotEmpty = other->m_setIsNotEmpty; + m_state = other->m_state; + other->m_setIsNotEmpty = false; +} + void InlineWatchpointSet::add(Watchpoint* watchpoint) { inflate()->add(watchpoint); @@ -159,5 +178,28 @@ fat()->deref(); } +DeferredWatchpointFire::DeferredWatchpointFire(VM& vm) + : m_vm(vm) + , m_watchpointsToFire(ClearWatchpoint) +{ +} + +DeferredWatchpointFire::~DeferredWatchpointFire() +{ +} + +void DeferredWatchpointFire::fireAll() +{ + if (m_watchpointsToFire.state() == IsWatched) + m_watchpointsToFire.fireAll(m_vm, *this); +} + +void DeferredWatchpointFire::takeWatchpointsToFire(WatchpointSet* watchpointsToFire) +{ + ASSERT(m_watchpointsToFire.state() == ClearWatchpoint); + ASSERT(watchpointsToFire->state() == IsWatched); + m_watchpointsToFire.take(watchpointsToFire); +} + } // namespace JSC diff -Nru webkit2gtk-2.20.3/Source/JavaScriptCore/bytecode/Watchpoint.h webkit2gtk-2.20.5/Source/JavaScriptCore/bytecode/Watchpoint.h --- webkit2gtk-2.20.3/Source/JavaScriptCore/bytecode/Watchpoint.h 2018-02-19 07:45:14.000000000 +0000 +++ webkit2gtk-2.20.5/Source/JavaScriptCore/bytecode/Watchpoint.h 2018-07-31 08:51:45.000000000 +0000 @@ -68,9 +68,7 @@ WTF_MAKE_NONCOPYABLE(Watchpoint); WTF_MAKE_FAST_ALLOCATED; public: - Watchpoint() - { - } + Watchpoint() = default; virtual ~Watchpoint(); @@ -89,10 +87,12 @@ }; class InlineWatchpointSet; +class DeferredWatchpointFire; class VM; class WatchpointSet : public ThreadSafeRefCounted { friend class LLIntOffsetsExtractor; + friend class DeferredWatchpointFire; public: JS_EXPORT_PRIVATE WatchpointSet(WatchpointState); @@ -159,6 +159,13 @@ fireAllSlow(vm, detail); } + void fireAll(VM& vm, DeferredWatchpointFire* deferredWatchpoints) + { + if (LIKELY(m_state != IsWatched)) + return; + fireAllSlow(vm, deferredWatchpoints); + } + void fireAll(VM& vm, const char* reason) { if (LIKELY(m_state != IsWatched)) @@ -201,10 +208,12 @@ int8_t* addressOfSetIsNotEmpty() { return &m_setIsNotEmpty; } JS_EXPORT_PRIVATE void fireAllSlow(VM&, const FireDetail&); // Call only if you've checked isWatched. + JS_EXPORT_PRIVATE void fireAllSlow(VM&, DeferredWatchpointFire* deferredWatchpoints); JS_EXPORT_PRIVATE void fireAllSlow(VM&, const char* reason); // Ditto. private: void fireAllWatchpoints(VM&, const FireDetail&); + void take(WatchpointSet* other); friend class InlineWatchpointSet; @@ -308,6 +317,18 @@ WTF::storeStoreFence(); } + void fireAll(VM& vm, DeferredWatchpointFire* deferred) + { + if (isFat()) { + fat()->fireAll(vm, deferred); + return; + } + if (decodeState(m_data) == ClearWatchpoint) + return; + m_data = encodeState(IsInvalidated); + WTF::storeStoreFence(); + } + void invalidate(VM& vm, const FireDetail& detail) { if (isFat()) @@ -435,4 +456,19 @@ uintptr_t m_data; }; +class DeferredWatchpointFire : public FireDetail { + WTF_MAKE_NONCOPYABLE(DeferredWatchpointFire); +public: + JS_EXPORT_PRIVATE DeferredWatchpointFire(VM&); + JS_EXPORT_PRIVATE ~DeferredWatchpointFire(); + + JS_EXPORT_PRIVATE void takeWatchpointsToFire(WatchpointSet*); + JS_EXPORT_PRIVATE void fireAll(); + + void dump(PrintStream& out) const override = 0; +private: + VM& m_vm; + WatchpointSet m_watchpointsToFire; +}; + } // namespace JSC diff -Nru webkit2gtk-2.20.3/Source/JavaScriptCore/bytecompiler/BytecodeGenerator.cpp webkit2gtk-2.20.5/Source/JavaScriptCore/bytecompiler/BytecodeGenerator.cpp --- webkit2gtk-2.20.3/Source/JavaScriptCore/bytecompiler/BytecodeGenerator.cpp 2018-06-11 10:29:22.000000000 +0000 +++ webkit2gtk-2.20.5/Source/JavaScriptCore/bytecompiler/BytecodeGenerator.cpp 2018-07-31 08:50:25.000000000 +0000 @@ -1,5 +1,5 @@ /* - * Copyright (C) 2008-2017 Apple Inc. All rights reserved. + * Copyright (C) 2008-2018 Apple Inc. All rights reserved. * Copyright (C) 2008 Cameron Zwarich * Copyright (C) 2012 Igalia, S.L. * @@ -3114,6 +3114,16 @@ } } +void BytecodeGenerator::preserveTDZStack(BytecodeGenerator::PreservedTDZStack& preservedStack) +{ + preservedStack.m_preservedTDZStack = m_TDZStack; +} + +void BytecodeGenerator::restoreTDZStack(const BytecodeGenerator::PreservedTDZStack& preservedStack) +{ + m_TDZStack = preservedStack.m_preservedTDZStack; +} + RegisterID* BytecodeGenerator::emitNewObject(RegisterID* dst) { size_t begin = instructions().size(); diff -Nru webkit2gtk-2.20.3/Source/JavaScriptCore/bytecompiler/BytecodeGenerator.h webkit2gtk-2.20.5/Source/JavaScriptCore/bytecompiler/BytecodeGenerator.h --- webkit2gtk-2.20.3/Source/JavaScriptCore/bytecompiler/BytecodeGenerator.h 2018-06-11 10:29:22.000000000 +0000 +++ webkit2gtk-2.20.5/Source/JavaScriptCore/bytecompiler/BytecodeGenerator.h 2018-07-31 08:50:25.000000000 +0000 @@ -1,5 +1,5 @@ /* - * Copyright (C) 2008-2017 Apple Inc. All rights reserved. + * Copyright (C) 2008-2018 Apple Inc. All rights reserved. * Copyright (C) 2008 Cameron Zwarich * Copyright (C) 2012 Igalia, S.L. * @@ -1090,6 +1090,13 @@ void initializeArrowFunctionContextScopeIfNeeded(SymbolTable* functionSymbolTable = nullptr, bool canReuseLexicalEnvironment = false); bool needsDerivedConstructorInArrowFunctionLexicalEnvironment(); + enum class TDZNecessityLevel { + NotNeeded, + Optimize, + DoNotOptimize + }; + typedef HashMap, TDZNecessityLevel, IdentifierRepHash> TDZMap; + public: JSString* addStringConstant(const Identifier&); JSValue addBigIntConstant(const Identifier&, uint8_t radix); @@ -1099,6 +1106,15 @@ RegisterID* emitThrowExpressionTooDeepException(); + class PreservedTDZStack { + private: + Vector m_preservedTDZStack; + friend class BytecodeGenerator; + }; + + void preserveTDZStack(PreservedTDZStack&); + void restoreTDZStack(const PreservedTDZStack&); + private: Vector m_instructions; @@ -1111,12 +1127,7 @@ int m_symbolTableConstantIndex; }; Vector m_lexicalScopeStack; - enum class TDZNecessityLevel { - NotNeeded, - Optimize, - DoNotOptimize - }; - typedef HashMap, TDZNecessityLevel, IdentifierRepHash> TDZMap; + Vector m_TDZStack; std::optional m_varScopeLexicalScopeStackIndex; void pushTDZVariables(const VariableEnvironment&, TDZCheckOptimization, TDZRequirement); diff -Nru webkit2gtk-2.20.3/Source/JavaScriptCore/bytecompiler/NodesCodegen.cpp webkit2gtk-2.20.5/Source/JavaScriptCore/bytecompiler/NodesCodegen.cpp --- webkit2gtk-2.20.3/Source/JavaScriptCore/bytecompiler/NodesCodegen.cpp 2018-06-11 10:29:22.000000000 +0000 +++ webkit2gtk-2.20.5/Source/JavaScriptCore/bytecompiler/NodesCodegen.cpp 2018-07-31 08:50:25.000000000 +0000 @@ -3006,6 +3006,9 @@ enumerator = generator.emitGetPropertyEnumerator(generator.newTemporary(), base.get()); + BytecodeGenerator::PreservedTDZStack preservedTDZStack; + generator.preserveTDZStack(preservedTDZStack); + // Indexed property loop. { Ref scope = generator.newLabelScope(LabelScope::Loop); @@ -3045,6 +3048,7 @@ generator.emitJump(end.get()); generator.emitLabel(loopEnd.get()); } + generator.restoreTDZStack(preservedTDZStack); // Structure property loop. { @@ -3085,6 +3089,7 @@ generator.emitJump(end.get()); generator.emitLabel(loopEnd.get()); } + generator.restoreTDZStack(preservedTDZStack); // Generic property loop. { diff -Nru webkit2gtk-2.20.3/Source/JavaScriptCore/CMakeLists.txt webkit2gtk-2.20.5/Source/JavaScriptCore/CMakeLists.txt --- webkit2gtk-2.20.3/Source/JavaScriptCore/CMakeLists.txt 2018-06-11 09:01:08.000000000 +0000 +++ webkit2gtk-2.20.5/Source/JavaScriptCore/CMakeLists.txt 2018-07-31 05:57:41.000000000 +0000 @@ -247,6 +247,7 @@ ${DERIVED_SOURCES_JAVASCRIPTCORE_DIR}/LLIntDesiredOffsets.h ${DERIVED_SOURCES_JAVASCRIPTCORE_DIR}/Bytecodes.h ${DERIVED_SOURCES_JAVASCRIPTCORE_DIR}/BytecodeStructs.h ) target_link_libraries(LLIntOffsetsExtractor WTF) +add_dependencies(LLIntOffsetsExtractor JavaScriptCoreForwardingHeaders) # The build system will execute asm.rb every time LLIntOffsetsExtractor's mtime is newer than # LLIntAssembly.h's mtime. The problem we have here is: asm.rb has some built-in optimization diff -Nru webkit2gtk-2.20.3/Source/JavaScriptCore/dfg/DFGAbstractInterpreterInlines.h webkit2gtk-2.20.5/Source/JavaScriptCore/dfg/DFGAbstractInterpreterInlines.h --- webkit2gtk-2.20.3/Source/JavaScriptCore/dfg/DFGAbstractInterpreterInlines.h 2018-06-11 10:29:22.000000000 +0000 +++ webkit2gtk-2.20.5/Source/JavaScriptCore/dfg/DFGAbstractInterpreterInlines.h 2018-07-31 06:57:14.000000000 +0000 @@ -1967,11 +1967,9 @@ case RegExpExec: case RegExpExecNonGlobalOrSticky: if (node->op() == RegExpExec) { - if (node->child2().useKind() == RegExpObjectUse - && node->child3().useKind() == StringUse) { - // This doesn't clobber the world since there are no conversions to perform. - } else - clobberWorld(node->origin.semantic, clobberLimit); + // Even if we've proven known input types as RegExpObject and String, + // accessing lastIndex is effectful if it's a global regexp. + clobberWorld(node->origin.semantic, clobberLimit); } if (JSValue globalObjectValue = forNode(node->child1()).m_value) { @@ -1991,11 +1989,9 @@ break; case RegExpTest: - if (node->child2().useKind() == RegExpObjectUse - && node->child3().useKind() == StringUse) { - // This doesn't clobber the world since there are no conversions to perform. - } else - clobberWorld(node->origin.semantic, clobberLimit); + // Even if we've proven known input types as RegExpObject and String, + // accessing lastIndex is effectful if it's a global regexp. + clobberWorld(node->origin.semantic, clobberLimit); forNode(node).setType(SpecBoolean); break; diff -Nru webkit2gtk-2.20.3/Source/JavaScriptCore/dfg/DFGClobberize.h webkit2gtk-2.20.5/Source/JavaScriptCore/dfg/DFGClobberize.h --- webkit2gtk-2.20.3/Source/JavaScriptCore/dfg/DFGClobberize.h 2018-06-11 10:29:22.000000000 +0000 +++ webkit2gtk-2.20.5/Source/JavaScriptCore/dfg/DFGClobberize.h 2018-07-31 06:57:14.000000000 +0000 @@ -1488,19 +1488,19 @@ case RegExpExec: case RegExpTest: - case RegExpMatchFast: - if (node->child2().useKind() == RegExpObjectUse - && node->child3().useKind() == StringUse) { - read(RegExpState); - read(RegExpObject_lastIndex); - write(RegExpState); - write(RegExpObject_lastIndex); - return; - } + // Even if we've proven known input types as RegExpObject and String, + // accessing lastIndex is effectful if it's a global regexp. read(World); write(Heap); return; + case RegExpMatchFast: + read(RegExpState); + read(RegExpObject_lastIndex); + write(RegExpState); + write(RegExpObject_lastIndex); + return; + case RegExpExecNonGlobalOrSticky: read(RegExpState); write(RegExpState); diff -Nru webkit2gtk-2.20.3/Source/JavaScriptCore/ftl/FTLLowerDFGToB3.cpp webkit2gtk-2.20.5/Source/JavaScriptCore/ftl/FTLLowerDFGToB3.cpp --- webkit2gtk-2.20.3/Source/JavaScriptCore/ftl/FTLLowerDFGToB3.cpp 2018-06-11 10:29:22.000000000 +0000 +++ webkit2gtk-2.20.5/Source/JavaScriptCore/ftl/FTLLowerDFGToB3.cpp 2018-07-31 06:46:57.000000000 +0000 @@ -5274,7 +5274,7 @@ LValue arrayLength = lowInt32(m_node->child1()); LBasicBlock loopStart = m_out.newBlock(); JSGlobalObject* globalObject = m_graph.globalObjectFor(m_node->origin.semantic); - RegisteredStructure structure = m_graph.registerStructure(globalObject->restParameterStructure()); + RegisteredStructure structure = m_graph.registerStructure(globalObject->originalRestParameterStructure()); ArrayValues arrayValues = allocateUninitializedContiguousJSArray(arrayLength, structure); LValue array = arrayValues.array; LValue butterfly = arrayValues.butterfly; diff -Nru webkit2gtk-2.20.3/Source/JavaScriptCore/inspector/remote/glib/RemoteInspectorUtils.cpp webkit2gtk-2.20.5/Source/JavaScriptCore/inspector/remote/glib/RemoteInspectorUtils.cpp --- webkit2gtk-2.20.3/Source/JavaScriptCore/inspector/remote/glib/RemoteInspectorUtils.cpp 2018-06-11 08:16:31.000000000 +0000 +++ webkit2gtk-2.20.5/Source/JavaScriptCore/inspector/remote/glib/RemoteInspectorUtils.cpp 2018-07-31 05:57:41.000000000 +0000 @@ -32,11 +32,7 @@ #include #include -#if PLATFORM(GTK) -#define INSPECTOR_BACKEND_COMMANDS_PATH "/org/webkitgtk/inspector/UserInterface/Protocol/InspectorBackendCommands.js" -#elif PLATFORM(WPE) -#define INSPECTOR_BACKEND_COMMANDS_PATH "/org/wpe/inspector/UserInterface/Protocol/InspectorBackendCommands.js" -#endif +#define INSPECTOR_BACKEND_COMMANDS_PATH "/org/webkit/inspector/UserInterface/Protocol/InspectorBackendCommands.js" namespace Inspector { diff -Nru webkit2gtk-2.20.3/Source/JavaScriptCore/llint/LLIntSlowPaths.cpp webkit2gtk-2.20.5/Source/JavaScriptCore/llint/LLIntSlowPaths.cpp --- webkit2gtk-2.20.3/Source/JavaScriptCore/llint/LLIntSlowPaths.cpp 2018-06-11 10:29:22.000000000 +0000 +++ webkit2gtk-2.20.5/Source/JavaScriptCore/llint/LLIntSlowPaths.cpp 2018-07-31 08:51:45.000000000 +0000 @@ -671,15 +671,18 @@ PropertyOffset offset = invalidOffset; CodeBlock::StructureWatchpointMap& watchpointMap = codeBlock->llintGetByIdWatchpointMap(); - auto result = watchpointMap.add(structure, Bag()); + Bag watchpoints; for (ObjectPropertyCondition condition : conditions) { if (!condition.isWatchable()) return; if (condition.condition().kind() == PropertyCondition::Presence) offset = condition.condition().offset(); - result.iterator->value.add(condition, pc)->install(); + watchpoints.add(condition, pc)->install(); } + ASSERT((offset == invalidOffset) == slot.isUnset()); + auto result = watchpointMap.add(std::make_tuple(structure, pc), WTFMove(watchpoints)); + ASSERT_UNUSED(result, result.isNewEntry); ConcurrentJSLocker locker(codeBlock->m_lock); diff -Nru webkit2gtk-2.20.3/Source/JavaScriptCore/runtime/CommonSlowPaths.h webkit2gtk-2.20.5/Source/JavaScriptCore/runtime/CommonSlowPaths.h --- webkit2gtk-2.20.3/Source/JavaScriptCore/runtime/CommonSlowPaths.h 2018-02-26 08:10:27.000000000 +0000 +++ webkit2gtk-2.20.5/Source/JavaScriptCore/runtime/CommonSlowPaths.h 2018-07-31 05:57:41.000000000 +0000 @@ -158,7 +158,7 @@ scope->structure()->didCachePropertyReplacement(vm, slot.cachedOffset()); ConcurrentJSLocker locker(codeBlock->m_lock); - pc[5].u.structure.set(vm, codeBlock, scope->structure()); + pc[5].u.structure.set(vm, codeBlock, scope->structure(vm)); pc[6].u.operand = slot.cachedOffset(); } } diff -Nru webkit2gtk-2.20.3/Source/JavaScriptCore/runtime/JSFunction.cpp webkit2gtk-2.20.5/Source/JavaScriptCore/runtime/JSFunction.cpp --- webkit2gtk-2.20.3/Source/JavaScriptCore/runtime/JSFunction.cpp 2018-02-26 09:44:56.000000000 +0000 +++ webkit2gtk-2.20.5/Source/JavaScriptCore/runtime/JSFunction.cpp 2018-06-14 06:01:43.000000000 +0000 @@ -364,9 +364,34 @@ // Firefox returns null for native code callers, so we match that behavior. if (function->isHostOrBuiltinFunction()) return JSValue::encode(jsNull()); - if (!function->jsExecutable()->isStrictMode()) - return JSValue::encode(caller); - return JSValue::encode(throwTypeError(exec, scope, ASCIILiteral("Function.caller used to retrieve strict caller"))); + SourceParseMode parseMode = function->jsExecutable()->parseMode(); + switch (parseMode) { + case SourceParseMode::GeneratorBodyMode: + case SourceParseMode::AsyncGeneratorBodyMode: + return JSValue::encode(throwTypeError(exec, scope, ASCIILiteral("Function.caller used to retrieve generator body"))); + case SourceParseMode::AsyncFunctionBodyMode: + case SourceParseMode::AsyncArrowFunctionBodyMode: + return JSValue::encode(throwTypeError(exec, scope, ASCIILiteral("Function.caller used to retrieve async function body"))); + case SourceParseMode::NormalFunctionMode: + case SourceParseMode::GeneratorWrapperFunctionMode: + case SourceParseMode::GetterMode: + case SourceParseMode::SetterMode: + case SourceParseMode::MethodMode: + case SourceParseMode::ArrowFunctionMode: + case SourceParseMode::AsyncFunctionMode: + case SourceParseMode::AsyncMethodMode: + case SourceParseMode::AsyncArrowFunctionMode: + case SourceParseMode::ProgramMode: + case SourceParseMode::ModuleAnalyzeMode: + case SourceParseMode::ModuleEvaluateMode: + case SourceParseMode::AsyncGeneratorWrapperFunctionMode: + case SourceParseMode::AsyncGeneratorWrapperMethodMode: + case SourceParseMode::GeneratorWrapperMethodMode: + if (!function->jsExecutable()->isStrictMode()) + return JSValue::encode(caller); + return JSValue::encode(throwTypeError(exec, scope, ASCIILiteral("Function.caller used to retrieve strict caller"))); + } + RELEASE_ASSERT_NOT_REACHED(); } bool JSFunction::getOwnPropertySlot(JSObject* object, ExecState* exec, PropertyName propertyName, PropertySlot& slot) diff -Nru webkit2gtk-2.20.3/Source/JavaScriptCore/runtime/JSGlobalObject.cpp webkit2gtk-2.20.5/Source/JavaScriptCore/runtime/JSGlobalObject.cpp --- webkit2gtk-2.20.3/Source/JavaScriptCore/runtime/JSGlobalObject.cpp 2018-06-11 08:16:31.000000000 +0000 +++ webkit2gtk-2.20.5/Source/JavaScriptCore/runtime/JSGlobalObject.cpp 2018-06-14 06:01:43.000000000 +0000 @@ -773,6 +773,7 @@ putDirectWithoutTransition(vm, vm.propertyNames->Loader, m_moduleLoader.get(), static_cast(PropertyAttribute::DontEnum)); JSFunction* builtinLog = JSFunction::create(vm, this, 1, vm.propertyNames->emptyIdentifier.string(), globalFuncBuiltinLog); + JSFunction* builtinDescribe = JSFunction::create(vm, this, 1, vm.propertyNames->emptyIdentifier.string(), globalFuncBuiltinDescribe); JSFunction* privateFuncAbs = JSFunction::create(vm, this, 0, String(), mathProtoFuncAbs, AbsIntrinsic); JSFunction* privateFuncFloor = JSFunction::create(vm, this, 0, String(), mathProtoFuncFloor, FloorIntrinsic); @@ -863,6 +864,7 @@ GlobalPropertyInfo(vm.propertyNames->builtinNames().hasInstanceBoundFunctionPrivateName(), privateFuncHasInstanceBoundFunction, PropertyAttribute::DontEnum | PropertyAttribute::DontDelete | PropertyAttribute::ReadOnly), GlobalPropertyInfo(vm.propertyNames->builtinNames().instanceOfPrivateName(), privateFuncInstanceOf, PropertyAttribute::DontEnum | PropertyAttribute::DontDelete | PropertyAttribute::ReadOnly), GlobalPropertyInfo(vm.propertyNames->builtinNames().BuiltinLogPrivateName(), builtinLog, PropertyAttribute::DontEnum | PropertyAttribute::DontDelete | PropertyAttribute::ReadOnly), + GlobalPropertyInfo(vm.propertyNames->builtinNames().BuiltinDescribePrivateName(), builtinDescribe, PropertyAttribute::DontEnum | PropertyAttribute::DontDelete | PropertyAttribute::ReadOnly), GlobalPropertyInfo(vm.propertyNames->builtinNames().NumberPrivateName(), numberConstructor, PropertyAttribute::DontEnum | PropertyAttribute::DontDelete | PropertyAttribute::ReadOnly), GlobalPropertyInfo(vm.propertyNames->builtinNames().RegExpPrivateName(), m_regExpConstructor.get(), PropertyAttribute::DontEnum | PropertyAttribute::DontDelete | PropertyAttribute::ReadOnly), GlobalPropertyInfo(vm.propertyNames->builtinNames().StringPrivateName(), stringConstructor, PropertyAttribute::DontEnum | PropertyAttribute::DontDelete | PropertyAttribute::ReadOnly), diff -Nru webkit2gtk-2.20.3/Source/JavaScriptCore/runtime/JSGlobalObjectFunctions.cpp webkit2gtk-2.20.5/Source/JavaScriptCore/runtime/JSGlobalObjectFunctions.cpp --- webkit2gtk-2.20.3/Source/JavaScriptCore/runtime/JSGlobalObjectFunctions.cpp 2018-02-19 07:45:17.000000000 +0000 +++ webkit2gtk-2.20.5/Source/JavaScriptCore/runtime/JSGlobalObjectFunctions.cpp 2018-06-14 06:01:36.000000000 +0000 @@ -774,6 +774,11 @@ return JSValue::encode(jsUndefined()); } +EncodedJSValue JSC_HOST_CALL globalFuncBuiltinDescribe(ExecState* exec) +{ + return JSValue::encode(jsString(exec, toString(exec->argument(0)))); +} + EncodedJSValue JSC_HOST_CALL globalFuncImportModule(ExecState* exec) { VM& vm = exec->vm(); diff -Nru webkit2gtk-2.20.3/Source/JavaScriptCore/runtime/JSGlobalObjectFunctions.h webkit2gtk-2.20.5/Source/JavaScriptCore/runtime/JSGlobalObjectFunctions.h --- webkit2gtk-2.20.3/Source/JavaScriptCore/runtime/JSGlobalObjectFunctions.h 2018-02-19 07:45:17.000000000 +0000 +++ webkit2gtk-2.20.5/Source/JavaScriptCore/runtime/JSGlobalObjectFunctions.h 2018-06-14 06:01:36.000000000 +0000 @@ -52,6 +52,7 @@ EncodedJSValue JSC_HOST_CALL globalFuncProtoSetter(ExecState*); EncodedJSValue JSC_HOST_CALL globalFuncHostPromiseRejectionTracker(ExecState*); EncodedJSValue JSC_HOST_CALL globalFuncBuiltinLog(ExecState*); +EncodedJSValue JSC_HOST_CALL globalFuncBuiltinDescribe(ExecState*); EncodedJSValue JSC_HOST_CALL globalFuncImportModule(ExecState*); EncodedJSValue JSC_HOST_CALL globalFuncPropertyIsEnumerable(ExecState*); diff -Nru webkit2gtk-2.20.3/Source/JavaScriptCore/runtime/JSGlobalObject.h webkit2gtk-2.20.5/Source/JavaScriptCore/runtime/JSGlobalObject.h --- webkit2gtk-2.20.3/Source/JavaScriptCore/runtime/JSGlobalObject.h 2018-04-10 07:33:13.000000000 +0000 +++ webkit2gtk-2.20.5/Source/JavaScriptCore/runtime/JSGlobalObject.h 2018-07-31 06:46:57.000000000 +0000 @@ -667,6 +667,7 @@ Structure* proxyRevokeStructure() const { return m_proxyRevokeStructure.get(); } Structure* moduleLoaderStructure() const { return m_moduleLoaderStructure.get(); } Structure* restParameterStructure() const { return arrayStructureForIndexingTypeDuringAllocation(ArrayWithContiguous); } + Structure* originalRestParameterStructure() const { return originalArrayStructureForIndexingType(ArrayWithContiguous); } #if ENABLE(WEBASSEMBLY) Structure* webAssemblyModuleRecordStructure() const { return m_webAssemblyModuleRecordStructure.get(); } Structure* webAssemblyFunctionStructure() const { return m_webAssemblyFunctionStructure.get(); } diff -Nru webkit2gtk-2.20.3/Source/JavaScriptCore/runtime/JSObject.cpp webkit2gtk-2.20.5/Source/JavaScriptCore/runtime/JSObject.cpp --- webkit2gtk-2.20.3/Source/JavaScriptCore/runtime/JSObject.cpp 2018-02-20 08:57:42.000000000 +0000 +++ webkit2gtk-2.20.5/Source/JavaScriptCore/runtime/JSObject.cpp 2018-07-31 07:50:49.000000000 +0000 @@ -1652,7 +1652,7 @@ prototype.asCell()->didBecomePrototype(); if (structure(vm)->hasMonoProto()) { - DeferredStructureTransitionWatchpointFire deferred; + DeferredStructureTransitionWatchpointFire deferred(vm, structure(vm)); Structure* newStructure = Structure::changePrototypeTransition(vm, structure(vm), prototype, deferred); setStructure(vm, newStructure); } else @@ -3543,7 +3543,7 @@ void JSObject::convertToDictionary(VM& vm) { - DeferredStructureTransitionWatchpointFire deferredWatchpointFire; + DeferredStructureTransitionWatchpointFire deferredWatchpointFire(vm, structure(vm)); setStructure( vm, Structure::toCacheableDictionaryTransition(vm, structure(vm), &deferredWatchpointFire)); } diff -Nru webkit2gtk-2.20.3/Source/JavaScriptCore/runtime/JSObjectInlines.h webkit2gtk-2.20.5/Source/JavaScriptCore/runtime/JSObjectInlines.h --- webkit2gtk-2.20.3/Source/JavaScriptCore/runtime/JSObjectInlines.h 2018-06-11 10:29:22.000000000 +0000 +++ webkit2gtk-2.20.5/Source/JavaScriptCore/runtime/JSObjectInlines.h 2018-07-31 07:50:49.000000000 +0000 @@ -287,12 +287,13 @@ putDirect(vm, offset, value); structure->didReplaceProperty(offset); - slot.setExistingProperty(this, offset); if ((attributes & PropertyAttribute::Accessor) != (currentAttributes & PropertyAttribute::Accessor) || (attributes & PropertyAttribute::CustomAccessor) != (currentAttributes & PropertyAttribute::CustomAccessor)) { ASSERT(!(attributes & PropertyAttribute::ReadOnly)); setStructure(vm, Structure::attributeChangeTransition(vm, structure, propertyName, attributes)); - } + } else + slot.setExistingProperty(this, offset); + return true; } @@ -344,13 +345,14 @@ vm, propertyName, value, slot.context() == PutPropertySlot::PutById); } - slot.setExistingProperty(this, offset); putDirect(vm, offset, value); if ((attributes & PropertyAttribute::Accessor) != (currentAttributes & PropertyAttribute::Accessor) || (attributes & PropertyAttribute::CustomAccessor) != (currentAttributes & PropertyAttribute::CustomAccessor)) { ASSERT(!(attributes & PropertyAttribute::ReadOnly)); setStructure(vm, Structure::attributeChangeTransition(vm, structure, propertyName, attributes)); - } + } else + slot.setExistingProperty(this, offset); + return true; } @@ -360,7 +362,7 @@ // We want the structure transition watchpoint to fire after this object has switched // structure. This allows adaptive watchpoints to observe if the new structure is the one // we want. - DeferredStructureTransitionWatchpointFire deferredWatchpointFire; + DeferredStructureTransitionWatchpointFire deferredWatchpointFire(vm, structure); newStructure = Structure::addNewPropertyTransition( vm, structure, propertyName, attributes, offset, slot.context(), &deferredWatchpointFire); diff -Nru webkit2gtk-2.20.3/Source/JavaScriptCore/runtime/StringConstructor.cpp webkit2gtk-2.20.5/Source/JavaScriptCore/runtime/StringConstructor.cpp --- webkit2gtk-2.20.3/Source/JavaScriptCore/runtime/StringConstructor.cpp 2018-05-07 09:20:30.000000000 +0000 +++ webkit2gtk-2.20.5/Source/JavaScriptCore/runtime/StringConstructor.cpp 2018-07-31 06:29:58.000000000 +0000 @@ -77,9 +77,9 @@ unsigned length = exec->argumentCount(); if (LIKELY(length == 1)) { - unsigned code = exec->uncheckedArgument(0).toUInt32(exec); - RETURN_IF_EXCEPTION(scope, encodedJSValue()); scope.release(); + unsigned code = exec->uncheckedArgument(0).toUInt32(exec); + // Not checking for an exception here is ok because jsSingleCharacterString will just fetch an unused string if there's an exception. return JSValue::encode(jsSingleCharacterString(exec, code)); } diff -Nru webkit2gtk-2.20.3/Source/JavaScriptCore/runtime/Structure.cpp webkit2gtk-2.20.5/Source/JavaScriptCore/runtime/Structure.cpp --- webkit2gtk-2.20.3/Source/JavaScriptCore/runtime/Structure.cpp 2018-02-19 07:45:17.000000000 +0000 +++ webkit2gtk-2.20.5/Source/JavaScriptCore/runtime/Structure.cpp 2018-07-31 07:50:49.000000000 +0000 @@ -1035,22 +1035,20 @@ out.print("Structure transition from ", *m_structure); } -DeferredStructureTransitionWatchpointFire::DeferredStructureTransitionWatchpointFire() - : m_structure(nullptr) +DeferredStructureTransitionWatchpointFire::DeferredStructureTransitionWatchpointFire(VM& vm, Structure* structure) + : DeferredWatchpointFire(vm) + , m_structure(structure) { } DeferredStructureTransitionWatchpointFire::~DeferredStructureTransitionWatchpointFire() { - if (m_structure) - m_structure->transitionWatchpointSet().fireAll(*m_structure->vm(), StructureFireDetail(m_structure)); + fireAll(); } -void DeferredStructureTransitionWatchpointFire::add(const Structure* structure) +void DeferredStructureTransitionWatchpointFire::dump(PrintStream& out) const { - RELEASE_ASSERT(!m_structure); - RELEASE_ASSERT(structure); - m_structure = structure; + out.print("Structure transition from ", *m_structure); } void Structure::didTransitionFromThisStructure(DeferredStructureTransitionWatchpointFire* deferred) const @@ -1060,10 +1058,11 @@ // unwise to watch it. if (m_transitionWatchpointSet.isBeingWatched()) const_cast(this)->setTransitionWatchpointIsLikelyToBeFired(true); - - if (deferred) - deferred->add(this); - else + + if (deferred) { + ASSERT(deferred->structure() == this); + m_transitionWatchpointSet.fireAll(*vm(), deferred); + } else m_transitionWatchpointSet.fireAll(*vm(), StructureFireDetail(this)); } diff -Nru webkit2gtk-2.20.3/Source/JavaScriptCore/runtime/Structure.h webkit2gtk-2.20.5/Source/JavaScriptCore/runtime/Structure.h --- webkit2gtk-2.20.3/Source/JavaScriptCore/runtime/Structure.h 2018-02-20 10:12:21.000000000 +0000 +++ webkit2gtk-2.20.5/Source/JavaScriptCore/runtime/Structure.h 2018-07-31 07:50:49.000000000 +0000 @@ -110,14 +110,16 @@ const Structure* m_structure; }; -class DeferredStructureTransitionWatchpointFire { +class DeferredStructureTransitionWatchpointFire : public DeferredWatchpointFire { WTF_MAKE_NONCOPYABLE(DeferredStructureTransitionWatchpointFire); public: - JS_EXPORT_PRIVATE DeferredStructureTransitionWatchpointFire(); + JS_EXPORT_PRIVATE DeferredStructureTransitionWatchpointFire(VM&, Structure*); JS_EXPORT_PRIVATE ~DeferredStructureTransitionWatchpointFire(); - void add(const Structure*); - + void dump(PrintStream& out) const override; + + const Structure* structure() const { return m_structure; } + private: const Structure* m_structure; }; diff -Nru webkit2gtk-2.20.3/Source/ThirdParty/xdgmime/src/xdgmimecache.c webkit2gtk-2.20.5/Source/ThirdParty/xdgmime/src/xdgmimecache.c --- webkit2gtk-2.20.3/Source/ThirdParty/xdgmime/src/xdgmimecache.c 2018-02-19 07:45:20.000000000 +0000 +++ webkit2gtk-2.20.5/Source/ThirdParty/xdgmime/src/xdgmimecache.c 2018-07-31 09:10:34.000000000 +0000 @@ -1038,6 +1038,9 @@ xdg_uint32_t child_offset; int i; + assert (*n >= 0); + assert (depth >= 0); + if (*n >= n_globs) return FALSE; @@ -1046,7 +1049,7 @@ xdg_uint32_t mime_offset = GET_UINT32 (cache->buffer, offset + 4); if (strcasecmp (cache->buffer + mime_offset, mime) == 0) { - globs[*n] = malloc (depth * sizeof (char)); + globs[*n] = malloc ((depth + 1) * sizeof (char)); for (i = 0; i < depth; i++) globs[*n][depth - i - 1] = prefix[i]; globs[*n][depth] = '\0'; diff -Nru webkit2gtk-2.20.3/Source/ThirdParty/xdgmime/src/xdgmimeglob.c webkit2gtk-2.20.5/Source/ThirdParty/xdgmime/src/xdgmimeglob.c --- webkit2gtk-2.20.3/Source/ThirdParty/xdgmime/src/xdgmimeglob.c 2018-02-19 07:45:20.000000000 +0000 +++ webkit2gtk-2.20.5/Source/ThirdParty/xdgmime/src/xdgmimeglob.c 2018-07-31 09:10:22.000000000 +0000 @@ -484,6 +484,9 @@ xdg_unichar_t *prefix, int depth) { + assert (*n >= 0); + assert (depth >= 0); + if (*n >= n_globs) return FALSE; @@ -495,7 +498,7 @@ { int i; - globs[*n] = malloc (depth * sizeof (char)); + globs[*n] = malloc ((depth + 1) * sizeof (char)); for (i = 0; i < depth; i++) globs[*n][depth - i - 1] = prefix[i]; globs[*n][depth] = '\0'; diff -Nru webkit2gtk-2.20.3/Source/WebCore/html/BaseButtonInputType.cpp webkit2gtk-2.20.5/Source/WebCore/html/BaseButtonInputType.cpp --- webkit2gtk-2.20.3/Source/WebCore/html/BaseButtonInputType.cpp 2018-02-19 07:45:32.000000000 +0000 +++ webkit2gtk-2.20.5/Source/WebCore/html/BaseButtonInputType.cpp 2018-07-31 07:02:08.000000000 +0000 @@ -1,6 +1,6 @@ /* * Copyright (C) 2010 Google Inc. All rights reserved. - * Copyright (C) 2011 Apple Inc. All rights reserved. + * Copyright (C) 2011-2018 Apple Inc. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are @@ -53,7 +53,8 @@ RenderPtr BaseButtonInputType::createInputRenderer(RenderStyle&& style) { - return createRenderer(element(), WTFMove(style)); + ASSERT(element()); + return createRenderer(*element(), WTFMove(style)); } bool BaseButtonInputType::storesValueSeparateFromAttribute() @@ -63,7 +64,8 @@ void BaseButtonInputType::setValue(const String& sanitizedValue, bool, TextFieldEventBehavior) { - element().setAttributeWithoutSynchronization(valueAttr, sanitizedValue); + ASSERT(element()); + element()->setAttributeWithoutSynchronization(valueAttr, sanitizedValue); } } // namespace WebCore diff -Nru webkit2gtk-2.20.3/Source/WebCore/html/BaseCheckableInputType.cpp webkit2gtk-2.20.5/Source/WebCore/html/BaseCheckableInputType.cpp --- webkit2gtk-2.20.3/Source/WebCore/html/BaseCheckableInputType.cpp 2018-02-19 07:45:32.000000000 +0000 +++ webkit2gtk-2.20.5/Source/WebCore/html/BaseCheckableInputType.cpp 2018-07-31 07:02:08.000000000 +0000 @@ -1,6 +1,6 @@ /* * Copyright (C) 2010 Google Inc. All rights reserved. - * Copyright (C) 2011 Apple Inc. All rights reserved. + * Copyright (C) 2011-2018 Apple Inc. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are @@ -45,19 +45,22 @@ FormControlState BaseCheckableInputType::saveFormControlState() const { - return { element().checked() ? ASCIILiteral("on") : ASCIILiteral("off") }; + ASSERT(element()); + return { element()->checked() ? ASCIILiteral("on") : ASCIILiteral("off") }; } void BaseCheckableInputType::restoreFormControlState(const FormControlState& state) { - element().setChecked(state[0] == "on"); + ASSERT(element()); + element()->setChecked(state[0] == "on"); } bool BaseCheckableInputType::appendFormData(DOMFormData& formData, bool) const { - if (!element().checked()) + ASSERT(element()); + if (!element()->checked()) return false; - formData.append(element().name(), element().value()); + formData.append(element()->name(), element()->value()); return true; } @@ -65,7 +68,8 @@ { const String& key = event.keyIdentifier(); if (key == "U+0020") { - element().setActive(true, true); + ASSERT(element()); + element()->setActive(true, true); // No setDefaultHandled(), because IE dispatches a keypress in this case // and the caller will only dispatch a keypress if we don't call setDefaultHandled(). } @@ -89,7 +93,8 @@ { InputType::accessKeyAction(sendMouseEvents); - element().dispatchSimulatedClick(0, sendMouseEvents ? SendMouseUpDownEvents : SendNoEvents); + ASSERT(element()); + element()->dispatchSimulatedClick(0, sendMouseEvents ? SendMouseUpDownEvents : SendNoEvents); } String BaseCheckableInputType::fallbackValue() const @@ -105,7 +110,8 @@ void BaseCheckableInputType::setValue(const String& sanitizedValue, bool, TextFieldEventBehavior) { - element().setAttributeWithoutSynchronization(valueAttr, sanitizedValue); + ASSERT(element()); + element()->setAttributeWithoutSynchronization(valueAttr, sanitizedValue); } bool BaseCheckableInputType::isCheckable() diff -Nru webkit2gtk-2.20.3/Source/WebCore/html/BaseClickableWithKeyInputType.cpp webkit2gtk-2.20.5/Source/WebCore/html/BaseClickableWithKeyInputType.cpp --- webkit2gtk-2.20.3/Source/WebCore/html/BaseClickableWithKeyInputType.cpp 2018-02-19 07:45:32.000000000 +0000 +++ webkit2gtk-2.20.5/Source/WebCore/html/BaseClickableWithKeyInputType.cpp 2018-07-31 07:02:08.000000000 +0000 @@ -1,6 +1,6 @@ /* * Copyright (C) 2010, 2012 Google Inc. All rights reserved. - * Copyright (C) 2011 Apple Inc. All rights reserved. + * Copyright (C) 2011-2018 Apple Inc. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are @@ -80,12 +80,14 @@ void BaseClickableWithKeyInputType::handleKeydownEvent(KeyboardEvent& event) { - handleKeydownEvent(element(), event); + ASSERT(element()); + handleKeydownEvent(*element(), event); } void BaseClickableWithKeyInputType::handleKeypressEvent(KeyboardEvent& event) { - handleKeypressEvent(element(), event); + ASSERT(element()); + handleKeypressEvent(*element(), event); } void BaseClickableWithKeyInputType::handleKeyupEvent(KeyboardEvent& event) @@ -96,7 +98,8 @@ void BaseClickableWithKeyInputType::accessKeyAction(bool sendMouseEvents) { InputType::accessKeyAction(sendMouseEvents); - accessKeyAction(element(), sendMouseEvents); + ASSERT(element()); + accessKeyAction(*element(), sendMouseEvents); } } // namespace WebCore diff -Nru webkit2gtk-2.20.3/Source/WebCore/html/BaseDateAndTimeInputType.cpp webkit2gtk-2.20.5/Source/WebCore/html/BaseDateAndTimeInputType.cpp --- webkit2gtk-2.20.3/Source/WebCore/html/BaseDateAndTimeInputType.cpp 2018-03-05 09:46:43.000000000 +0000 +++ webkit2gtk-2.20.5/Source/WebCore/html/BaseDateAndTimeInputType.cpp 2018-07-31 07:07:39.000000000 +0000 @@ -98,7 +98,8 @@ void BaseDateAndTimeInputType::minOrMaxAttributeChanged() { - element().invalidateStyleForSubtree(); + if (auto* element = this->element()) + element->invalidateStyleForSubtree(); } Decimal BaseDateAndTimeInputType::parseToNumber(const String& source, const Decimal& defaultValue) const diff -Nru webkit2gtk-2.20.3/Source/WebCore/html/BaseTextInputType.cpp webkit2gtk-2.20.5/Source/WebCore/html/BaseTextInputType.cpp --- webkit2gtk-2.20.3/Source/WebCore/html/BaseTextInputType.cpp 2018-02-19 11:04:38.000000000 +0000 +++ webkit2gtk-2.20.5/Source/WebCore/html/BaseTextInputType.cpp 2018-07-31 07:09:05.000000000 +0000 @@ -3,6 +3,7 @@ * * Copyright (C) 2009 Michelangelo De Simone * Copyright (C) 2010 Google Inc. All rights reserved. + * Copyright (C) 2018 Apple Inc. All rights reserved. * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Library General Public @@ -39,7 +40,8 @@ bool BaseTextInputType::patternMismatch(const String& value) const { - const AtomicString& rawPattern = element().attributeWithoutSynchronization(patternAttr); + ASSERT(element()); + const AtomicString& rawPattern = element()->attributeWithoutSynchronization(patternAttr); if (rawPattern.isNull() || value.isEmpty() || !JSC::Yarr::RegularExpression(rawPattern).isValid()) return false; String pattern = "^(?:" + rawPattern + ")$"; diff -Nru webkit2gtk-2.20.3/Source/WebCore/html/canvas/WebGLRenderingContextBase.cpp webkit2gtk-2.20.5/Source/WebCore/html/canvas/WebGLRenderingContextBase.cpp --- webkit2gtk-2.20.3/Source/WebCore/html/canvas/WebGLRenderingContextBase.cpp 2018-02-19 11:04:38.000000000 +0000 +++ webkit2gtk-2.20.5/Source/WebCore/html/canvas/WebGLRenderingContextBase.cpp 2018-07-31 07:38:00.000000000 +0000 @@ -5746,6 +5746,8 @@ if (m_context->getError() != GraphicsContext3D::NO_ERROR) { // We were unable to create a buffer. m_vertexAttrib0UsedBefore = false; + m_vertexAttrib0BufferSize = 0; + m_forceAttrib0BufferRefill = true; return std::nullopt; } m_vertexAttrib0BufferSize = bufferDataSize; diff -Nru webkit2gtk-2.20.3/Source/WebCore/html/canvas/WebGLRenderingContextBase.h webkit2gtk-2.20.5/Source/WebCore/html/canvas/WebGLRenderingContextBase.h --- webkit2gtk-2.20.3/Source/WebCore/html/canvas/WebGLRenderingContextBase.h 2018-02-19 11:04:38.000000000 +0000 +++ webkit2gtk-2.20.5/Source/WebCore/html/canvas/WebGLRenderingContextBase.h 2018-07-31 07:38:00.000000000 +0000 @@ -488,10 +488,10 @@ Vector m_vertexAttribValue; unsigned m_maxVertexAttribs; RefPtr m_vertexAttrib0Buffer; - long m_vertexAttrib0BufferSize; + long m_vertexAttrib0BufferSize { 0 }; GC3Dfloat m_vertexAttrib0BufferValue[4]; - bool m_forceAttrib0BufferRefill; - bool m_vertexAttrib0UsedBefore; + bool m_forceAttrib0BufferRefill { true }; + bool m_vertexAttrib0UsedBefore { false }; RefPtr m_currentProgram; RefPtr m_framebufferBinding; diff -Nru webkit2gtk-2.20.3/Source/WebCore/html/CheckboxInputType.cpp webkit2gtk-2.20.5/Source/WebCore/html/CheckboxInputType.cpp --- webkit2gtk-2.20.3/Source/WebCore/html/CheckboxInputType.cpp 2018-02-19 07:45:32.000000000 +0000 +++ webkit2gtk-2.20.5/Source/WebCore/html/CheckboxInputType.cpp 2018-07-31 07:02:08.000000000 +0000 @@ -1,6 +1,6 @@ /* * Copyright (C) 2010 Google Inc. All rights reserved. - * Copyright (C) 2011 Apple Inc. All rights reserved. + * Copyright (C) 2011-2018 Apple Inc. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are @@ -46,7 +46,8 @@ bool CheckboxInputType::valueMissing(const String&) const { - return element().isRequired() && !element().checked(); + ASSERT(element()); + return element()->isRequired() && !element()->checked(); } String CheckboxInputType::valueMissingText() const @@ -64,23 +65,26 @@ void CheckboxInputType::willDispatchClick(InputElementClickState& state) { + ASSERT(element()); + // An event handler can use preventDefault or "return false" to reverse the checking we do here. // The InputElementClickState object contains what we need to undo what we did here in didDispatchClick. - state.checked = element().checked(); - state.indeterminate = element().indeterminate(); + state.checked = element()->checked(); + state.indeterminate = element()->indeterminate(); if (state.indeterminate) - element().setIndeterminate(false); + element()->setIndeterminate(false); - element().setChecked(!state.checked, DispatchChangeEvent); + element()->setChecked(!state.checked, DispatchChangeEvent); } void CheckboxInputType::didDispatchClick(Event& event, const InputElementClickState& state) { if (event.defaultPrevented() || event.defaultHandled()) { - element().setIndeterminate(state.indeterminate); - element().setChecked(state.checked); + ASSERT(element()); + element()->setIndeterminate(state.indeterminate); + element()->setChecked(state.checked); } // The work we did in willDispatchClick was default handling. @@ -99,7 +103,8 @@ bool CheckboxInputType::shouldAppearIndeterminate() const { - return element().indeterminate(); + ASSERT(element()); + return element()->indeterminate(); } } // namespace WebCore diff -Nru webkit2gtk-2.20.3/Source/WebCore/html/ColorInputType.cpp webkit2gtk-2.20.5/Source/WebCore/html/ColorInputType.cpp --- webkit2gtk-2.20.3/Source/WebCore/html/ColorInputType.cpp 2018-02-19 07:45:32.000000000 +0000 +++ webkit2gtk-2.20.5/Source/WebCore/html/ColorInputType.cpp 2018-07-31 07:02:15.000000000 +0000 @@ -1,6 +1,6 @@ /* * Copyright (C) 2010 Google Inc. All rights reserved. - * Copyright (C) 2015-2017 Apple Inc. All rights reserved. + * Copyright (C) 2015-2018 Apple Inc. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are @@ -111,20 +111,22 @@ Color ColorInputType::valueAsColor() const { - return parseSimpleColorValue(element().value()).value(); + ASSERT(element()); + return parseSimpleColorValue(element()->value()).value(); } void ColorInputType::createShadowSubtree() { - ASSERT(element().shadowRoot()); + ASSERT(element()); + ASSERT(element()->shadowRoot()); - Document& document = element().document(); + Document& document = element()->document(); auto wrapperElement = HTMLDivElement::create(document); wrapperElement->setPseudo(AtomicString("-webkit-color-swatch-wrapper", AtomicString::ConstructFromLiteral)); auto colorSwatch = HTMLDivElement::create(document); colorSwatch->setPseudo(AtomicString("-webkit-color-swatch", AtomicString::ConstructFromLiteral)); wrapperElement->appendChild(colorSwatch); - element().userAgentShadowRoot()->appendChild(wrapperElement); + element()->userAgentShadowRoot()->appendChild(wrapperElement); updateColorSwatch(); } @@ -143,7 +145,8 @@ void ColorInputType::handleDOMActivateEvent(Event& event) { - if (element().isDisabledFormControl() || !element().renderer()) + ASSERT(element()); + if (element()->isDisabledFormControl() || !element()->renderer()) return; if (!UserGestureIndicator::processingUserGesture()) @@ -181,12 +184,13 @@ void ColorInputType::didChooseColor(const Color& color) { - if (element().isDisabledFormControl() || color == valueAsColor()) + ASSERT(element()); + if (element()->isDisabledFormControl() || color == valueAsColor()) return; EventQueueScope scope; - element().setValueFromRenderer(color.serialized()); + element()->setValueFromRenderer(color.serialized()); updateColorSwatch(); - element().dispatchFormControlChangeEvent(); + element()->dispatchFormControlChangeEvent(); } void ColorInputType::didEndChooser() @@ -206,12 +210,14 @@ if (!colorSwatch) return; - colorSwatch->setInlineStyleProperty(CSSPropertyBackgroundColor, element().value(), false); + ASSERT(element()); + colorSwatch->setInlineStyleProperty(CSSPropertyBackgroundColor, element()->value(), false); } HTMLElement* ColorInputType::shadowColorSwatch() const { - RefPtr shadow = element().userAgentShadowRoot(); + ASSERT(element()); + RefPtr shadow = element()->userAgentShadowRoot(); if (!shadow) return nullptr; @@ -224,9 +230,10 @@ IntRect ColorInputType::elementRectRelativeToRootView() const { - if (!element().renderer()) + ASSERT(element()); + if (!element()->renderer()) return IntRect(); - return element().document().view()->contentsToRootView(element().renderer()->absoluteBoundingBoxRect()); + return element()->document().view()->contentsToRootView(element()->renderer()->absoluteBoundingBoxRect()); } Color ColorInputType::currentColor() @@ -237,7 +244,8 @@ bool ColorInputType::shouldShowSuggestions() const { #if ENABLE(DATALIST_ELEMENT) - return element().hasAttributeWithoutSynchronization(listAttr); + ASSERT(element()); + return element()->hasAttributeWithoutSynchronization(listAttr); #else return false; #endif @@ -247,7 +255,8 @@ { Vector suggestions; #if ENABLE(DATALIST_ELEMENT) - if (auto dataList = element().dataList()) { + ASSERT(element()); + if (auto dataList = element()->dataList()) { Ref options = dataList->options(); unsigned length = options->length(); suggestions.reserveInitialCapacity(length); diff -Nru webkit2gtk-2.20.3/Source/WebCore/html/EmailInputType.cpp webkit2gtk-2.20.5/Source/WebCore/html/EmailInputType.cpp --- webkit2gtk-2.20.3/Source/WebCore/html/EmailInputType.cpp 2018-02-19 11:04:38.000000000 +0000 +++ webkit2gtk-2.20.5/Source/WebCore/html/EmailInputType.cpp 2018-07-31 07:02:08.000000000 +0000 @@ -3,6 +3,7 @@ * * Copyright (C) 2009 Michelangelo De Simone * Copyright (C) 2010 Google Inc. All rights reserved. + * Copyright (C) 2018 Apple Inc. All rights reserved. * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Library General Public @@ -58,9 +59,10 @@ bool EmailInputType::typeMismatchFor(const String& value) const { + ASSERT(element()); if (value.isEmpty()) return false; - if (!element().multiple()) + if (!element()->multiple()) return !isValidEmailAddress(value); Vector addresses; value.split(',', true, addresses); @@ -73,12 +75,14 @@ bool EmailInputType::typeMismatch() const { - return typeMismatchFor(element().value()); + ASSERT(element()); + return typeMismatchFor(element()->value()); } String EmailInputType::typeMismatchText() const { - return element().multiple() ? validationMessageTypeMismatchForMultipleEmailText() : validationMessageTypeMismatchForEmailText(); + ASSERT(element()); + return element()->multiple() ? validationMessageTypeMismatchForMultipleEmailText() : validationMessageTypeMismatchForEmailText(); } bool EmailInputType::isEmailField() const @@ -94,7 +98,8 @@ String EmailInputType::sanitizeValue(const String& proposedValue) const { String noLineBreakValue = proposedValue.removeCharacters(isHTMLLineBreak); - if (!element().multiple()) + ASSERT(element()); + if (!element()->multiple()) return stripLeadingAndTrailingHTMLSpaces(noLineBreakValue); Vector addresses; noLineBreakValue.split(',', true, addresses); diff -Nru webkit2gtk-2.20.3/Source/WebCore/html/FileInputType.cpp webkit2gtk-2.20.5/Source/WebCore/html/FileInputType.cpp --- webkit2gtk-2.20.3/Source/WebCore/html/FileInputType.cpp 2018-02-19 07:45:32.000000000 +0000 +++ webkit2gtk-2.20.5/Source/WebCore/html/FileInputType.cpp 2018-07-31 07:10:27.000000000 +0000 @@ -151,10 +151,11 @@ bool FileInputType::appendFormData(DOMFormData& formData, bool multipart) const { - auto fileList = makeRefPtr(element().files()); + ASSERT(element()); + auto fileList = makeRefPtr(element()->files()); ASSERT(fileList); - auto name = element().name(); + auto name = element()->name(); if (!multipart) { // Send only the basenames. @@ -184,17 +185,20 @@ bool FileInputType::valueMissing(const String& value) const { - return element().isRequired() && value.isEmpty(); + ASSERT(element()); + return element()->isRequired() && value.isEmpty(); } String FileInputType::valueMissingText() const { - return element().multiple() ? validationMessageValueMissingForMultipleFileText() : validationMessageValueMissingForFileText(); + ASSERT(element()); + return element()->multiple() ? validationMessageValueMissingForMultipleFileText() : validationMessageValueMissingForFileText(); } void FileInputType::handleDOMActivateEvent(Event& event) { - auto& input = element(); + ASSERT(element()); + auto& input = *element(); if (input.isDisabledFormControl()) return; @@ -221,7 +225,8 @@ RenderPtr FileInputType::createInputRenderer(RenderStyle&& style) { - return createRenderer(element(), WTFMove(style)); + ASSERT(element()); + return createRenderer(*element(), WTFMove(style)); } bool FileInputType::canSetStringValue() const @@ -265,7 +270,8 @@ // FIXME: Should we clear the file list, or replace it with a new empty one here? This is observable from JavaScript through custom properties. m_fileList->clear(); m_icon = nullptr; - element().invalidateStyleForSubtree(); + ASSERT(element()); + element()->invalidateStyleForSubtree(); } bool FileInputType::isFileUpload() const @@ -275,32 +281,33 @@ void FileInputType::createShadowSubtree() { - ASSERT(element().shadowRoot()); - element().userAgentShadowRoot()->appendChild(element().multiple() ? UploadButtonElement::createForMultiple(element().document()): UploadButtonElement::create(element().document())); + ASSERT(element()); + ASSERT(element()->shadowRoot()); + element()->userAgentShadowRoot()->appendChild(element()->multiple() ? UploadButtonElement::createForMultiple(element()->document()): UploadButtonElement::create(element()->document())); } void FileInputType::disabledAttributeChanged() { - ASSERT(element().shadowRoot()); + ASSERT(element()); + ASSERT(element()->shadowRoot()); - auto root = element().userAgentShadowRoot(); + auto root = element()->userAgentShadowRoot(); if (!root) return; if (auto button = makeRefPtr(childrenOfType(*root).first())) - button->setBooleanAttribute(disabledAttr, element().isDisabledFormControl()); + button->setBooleanAttribute(disabledAttr, element()->isDisabledFormControl()); } void FileInputType::multipleAttributeChanged() { - ASSERT(element().shadowRoot()); - - auto root = element().userAgentShadowRoot(); - if (!root) - return; - - if (auto button = makeRefPtr(childrenOfType(*root).first())) - button->setValue(element().multiple() ? fileButtonChooseMultipleFilesLabel() : fileButtonChooseFileLabel()); + if (auto* element = this->element()) { + ASSERT(element->shadowRoot()); + if (auto root = element->userAgentShadowRoot()) { + if (auto button = makeRefPtr(childrenOfType(*root).first())) + button->setValue(element->multiple() ? fileButtonChooseMultipleFilesLabel() : fileButtonChooseFileLabel()); + } + } } void FileInputType::requestIcon(const Vector& paths) @@ -337,7 +344,8 @@ { if (!RuntimeEnabledFeatures::sharedFeatures().directoryUploadEnabled()) return false; - return element().hasAttributeWithoutSynchronization(webkitdirectoryAttr); + ASSERT(element()); + return element()->hasAttributeWithoutSynchronization(webkitdirectoryAttr); } void FileInputType::setFiles(RefPtr&& files) @@ -350,7 +358,8 @@ if (!files) return; - Ref input(element()); + ASSERT(element()); + Ref protectedInputElement(*element()); unsigned length = files->length(); @@ -368,8 +377,8 @@ m_fileList = files.releaseNonNull(); - input->setFormControlValueMatchesRenderer(true); - input->updateValidity(); + protectedInputElement->setFormControlValueMatchesRenderer(true); + protectedInputElement->updateValidity(); if (shouldRequestIcon == RequestIcon::Yes) { Vector paths; @@ -379,15 +388,15 @@ requestIcon(paths); } - if (input->renderer()) - input->renderer()->repaint(); + if (protectedInputElement->renderer()) + protectedInputElement->renderer()->repaint(); if (pathsChanged) { // This call may cause destruction of this instance. // input instance is safe since it is ref-counted. - input->dispatchChangeEvent(); + protectedInputElement->dispatchChangeEvent(); } - input->setChangedSinceLastFormControlChangeEvent(false); + protectedInputElement->setChangedSinceLastFormControlChangeEvent(false); } void FileInputType::filesChosen(const Vector& paths, const String& displayString, Icon* icon) @@ -420,8 +429,9 @@ return; m_icon = WTFMove(icon); - if (element().renderer()) - element().renderer()->repaint(); + ASSERT(element()); + if (auto* renderer = element()->renderer()) + renderer->repaint(); } #if ENABLE(DRAG_SUPPORT) @@ -431,7 +441,8 @@ if (paths.isEmpty()) return false; - if (element().hasAttributeWithoutSynchronization(multipleAttr)) { + ASSERT(element()); + if (element()->hasAttributeWithoutSynchronization(multipleAttr)) { Vector files; files.reserveInitialCapacity(paths.size()); for (auto& path : paths) @@ -454,7 +465,8 @@ { unsigned listSize = m_fileList->length(); if (!listSize) { - if (element().multiple()) + ASSERT(element()); + if (element()->multiple()) return fileButtonNoFilesSelectedLabel(); return fileButtonNoFileSelectedLabel(); } diff -Nru webkit2gtk-2.20.3/Source/WebCore/html/HiddenInputType.cpp webkit2gtk-2.20.5/Source/WebCore/html/HiddenInputType.cpp --- webkit2gtk-2.20.3/Source/WebCore/html/HiddenInputType.cpp 2018-02-19 07:45:32.000000000 +0000 +++ webkit2gtk-2.20.5/Source/WebCore/html/HiddenInputType.cpp 2018-07-31 07:02:08.000000000 +0000 @@ -52,12 +52,14 @@ { // valueAttributeWasUpdatedAfterParsing() never be true for form controls create by createElement() or cloneNode(). // It's OK for now because we restore values only to form controls created by parsing. - return element().valueAttributeWasUpdatedAfterParsing() ? FormControlState { { element().value() } } : FormControlState { }; + ASSERT(element()); + return element()->valueAttributeWasUpdatedAfterParsing() ? FormControlState { { element()->value() } } : FormControlState { }; } void HiddenInputType::restoreFormControlState(const FormControlState& state) { - element().setAttributeWithoutSynchronization(valueAttr, state[0]); + ASSERT(element()); + element()->setAttributeWithoutSynchronization(valueAttr, state[0]); } bool HiddenInputType::supportsValidation() const @@ -87,7 +89,8 @@ void HiddenInputType::setValue(const String& sanitizedValue, bool, TextFieldEventBehavior) { - element().setAttributeWithoutSynchronization(valueAttr, sanitizedValue); + ASSERT(element()); + element()->setAttributeWithoutSynchronization(valueAttr, sanitizedValue); } bool HiddenInputType::isHiddenType() const @@ -97,7 +100,8 @@ bool HiddenInputType::appendFormData(DOMFormData& formData, bool isMultipartForm) const { - auto name = element().name(); + ASSERT(element()); + auto name = element()->name(); if (equalIgnoringASCIICase(name, "_charset_")) { formData.append(name, String { formData.encoding().name() }); diff -Nru webkit2gtk-2.20.3/Source/WebCore/html/HTMLButtonElement.cpp webkit2gtk-2.20.5/Source/WebCore/html/HTMLButtonElement.cpp --- webkit2gtk-2.20.3/Source/WebCore/html/HTMLButtonElement.cpp 2018-02-19 07:45:32.000000000 +0000 +++ webkit2gtk-2.20.5/Source/WebCore/html/HTMLButtonElement.cpp 2018-07-31 06:59:28.000000000 +0000 @@ -2,7 +2,7 @@ * Copyright (C) 1999 Lars Knoll (knoll@kde.org) * (C) 1999 Antti Koivisto (koivisto@kde.org) * (C) 2001 Dirk Mueller (mueller@kde.org) - * Copyright (C) 2004, 2005, 2006, 2007, 2010, 2016 Apple Inc. All rights reserved. + * Copyright (C) 2004-2018 Apple Inc. All rights reserved. * (C) 2006 Alexey Proskuryakov (ap@nypop.com) * Copyright (C) 2007 Samuel Weinig (sam@webkit.org) * @@ -32,6 +32,7 @@ #include "HTMLNames.h" #include "KeyboardEvent.h" #include "RenderButton.h" +#include #include namespace WebCore { @@ -115,15 +116,25 @@ void HTMLButtonElement::defaultEventHandler(Event& event) { if (event.type() == eventNames().DOMActivateEvent && !isDisabledFormControl()) { - if (form() && m_type == SUBMIT) { - m_isActivatedSubmit = true; - form()->prepareForSubmission(event); - event.setDefaultHandled(); - m_isActivatedSubmit = false; // Do this in case submission was canceled. - } - if (form() && m_type == RESET) { - form()->reset(); - event.setDefaultHandled(); + RefPtr protectedForm(form()); + + if (protectedForm) { + // Update layout before processing form actions in case the style changes + // the Form or button relationships. + document().updateLayoutIgnorePendingStylesheets(); + + if (auto currentForm = form()) { + if (m_type == SUBMIT) { + SetForScope activatedSubmitState(m_isActivatedSubmit, true); + currentForm->prepareForSubmission(event); + } + + if (m_type == RESET) + currentForm->reset(); + } + + if (m_type == SUBMIT || m_type == RESET) + event.setDefaultHandled(); } } diff -Nru webkit2gtk-2.20.3/Source/WebCore/html/HTMLFormElement.cpp webkit2gtk-2.20.5/Source/WebCore/html/HTMLFormElement.cpp --- webkit2gtk-2.20.3/Source/WebCore/html/HTMLFormElement.cpp 2018-02-19 07:45:32.000000000 +0000 +++ webkit2gtk-2.20.5/Source/WebCore/html/HTMLFormElement.cpp 2018-07-31 06:58:42.000000000 +0000 @@ -219,9 +219,9 @@ // Because the form has invalid controls, we abort the form submission and // show a validation message on a focusable form control. - // Needs to update layout now because we'd like to call isFocusable(), which - // has !renderer()->needsLayout() assertion. - document().updateLayoutIgnorePendingStylesheets(); + // Make sure layout is up-to-date in case we call isFocusable() (which + // has !renderer()->needsLayout() assertion). + ASSERT(!document().view() || !document().view()->needsLayout()); Ref protectedThis(*this); @@ -740,6 +740,12 @@ bool HTMLFormElement::reportValidity() { + Ref protectedThis(*this); + + // Update layout before processing form actions in case the style changes + // the Form or button relationships. + document().updateLayoutIgnorePendingStylesheets(); + return validateInteractively(); } diff -Nru webkit2gtk-2.20.3/Source/WebCore/html/HTMLInputElement.cpp webkit2gtk-2.20.5/Source/WebCore/html/HTMLInputElement.cpp --- webkit2gtk-2.20.3/Source/WebCore/html/HTMLInputElement.cpp 2018-04-09 10:48:00.000000000 +0000 +++ webkit2gtk-2.20.5/Source/WebCore/html/HTMLInputElement.cpp 2018-07-31 07:01:38.000000000 +0000 @@ -97,7 +97,6 @@ HTMLInputElement::HTMLInputElement(const QualifiedName& tagName, Document& document, HTMLFormElement* form, bool createdByParser) : HTMLTextFormControlElement(tagName, document, form) , m_size(defaultSize) - , m_maxResults(-1) , m_isChecked(false) , m_reflectsCheckedAttribute(true) , m_isIndeterminate(false) @@ -120,10 +119,12 @@ , m_hasTouchEventHandler(false) #endif , m_isSpellcheckDisabledExceptTextReplacement(false) +{ // m_inputType is lazily created when constructed by the parser to avoid constructing unnecessarily a text inputType and // its shadow subtree, just to destroy them when the |type| attribute gets set by the parser to something else than 'text'. - , m_inputType(createdByParser ? nullptr : InputType::createText(*this)) -{ + if (!createdByParser) + m_inputType = InputType::createText(*this); + ASSERT(hasTagName(inputTag)); setHasCustomStyleResolveCallbacks(); } @@ -146,7 +147,8 @@ void HTMLInputElement::didAddUserAgentShadowRoot(ShadowRoot&) { - m_inputType->createShadowSubtree(); + Ref protectedInputType(*m_inputType); + protectedInputType->createShadowSubtree(); updateInnerTextElementEditability(); } @@ -612,7 +614,8 @@ void HTMLInputElement::accessKeyAction(bool sendMouseEvents) { - m_inputType->accessKeyAction(sendMouseEvents); + Ref protectedInputType(*m_inputType); + protectedInputType->accessKeyAction(sendMouseEvents); } bool HTMLInputElement::isPresentationAttribute(const QualifiedName& name) const @@ -669,6 +672,7 @@ void HTMLInputElement::parseAttribute(const QualifiedName& name, const AtomicString& value) { ASSERT(m_inputType); + Ref protectedInputType(*m_inputType); if (name == nameAttr) { removeFromRadioButtonGroup(); @@ -876,6 +880,7 @@ bool HTMLInputElement::appendFormData(DOMFormData& formData, bool multipart) { + Ref protectedInputType(*m_inputType); return m_inputType->isFormDataAppendable() && m_inputType->appendFormData(formData, multipart); } diff -Nru webkit2gtk-2.20.3/Source/WebCore/html/HTMLInputElement.h webkit2gtk-2.20.5/Source/WebCore/html/HTMLInputElement.h --- webkit2gtk-2.20.3/Source/WebCore/html/HTMLInputElement.h 2018-02-19 07:45:32.000000000 +0000 +++ webkit2gtk-2.20.5/Source/WebCore/html/HTMLInputElement.h 2018-07-31 07:02:15.000000000 +0000 @@ -28,6 +28,7 @@ #include "HTMLTextFormControlElement.h" #include "StepRange.h" #include +#include #if PLATFORM(IOS) #include "DateComponents.h" @@ -341,6 +342,8 @@ ExceptionOr setSelectionRangeForBindings(int start, int end, const String& direction); + auto& weakPtrFactory() const { return m_weakFactory; } + protected: HTMLInputElement(const QualifiedName&, Document&, HTMLFormElement*, bool createdByParser); @@ -446,7 +449,7 @@ AtomicString m_name; String m_valueIfDirty; unsigned m_size; - short m_maxResults; + short m_maxResults { -1 }; bool m_isChecked : 1; bool m_reflectsCheckedAttribute : 1; bool m_isIndeterminate : 1; @@ -469,7 +472,7 @@ bool m_hasTouchEventHandler : 1; #endif bool m_isSpellcheckDisabledExceptTextReplacement : 1; - std::unique_ptr m_inputType; + RefPtr m_inputType; // The ImageLoader must be owned by this element because the loader code assumes // that it lives as long as its owning element lives. If we move the loader into // the ImageInput object we may delete the loader while this element lives on. @@ -477,6 +480,7 @@ #if ENABLE(DATALIST_ELEMENT) std::unique_ptr m_listAttributeTargetObserver; #endif + WeakPtrFactory m_weakFactory; }; } diff -Nru webkit2gtk-2.20.3/Source/WebCore/html/ImageInputType.cpp webkit2gtk-2.20.5/Source/WebCore/html/ImageInputType.cpp --- webkit2gtk-2.20.3/Source/WebCore/html/ImageInputType.cpp 2018-02-19 07:45:32.000000000 +0000 +++ webkit2gtk-2.20.5/Source/WebCore/html/ImageInputType.cpp 2018-07-31 07:13:12.000000000 +0000 @@ -56,10 +56,11 @@ bool ImageInputType::appendFormData(DOMFormData& formData, bool) const { - if (!element().isActivatedSubmit()) + ASSERT(element()); + if (!element()->isActivatedSubmit()) return false; - auto& name = element().name(); + auto& name = element()->name(); if (name.isEmpty()) { formData.append(ASCIILiteral("x"), String::number(m_clickLocation.x())); formData.append(ASCIILiteral("y"), String::number(m_clickLocation.y())); @@ -69,7 +70,7 @@ formData.append(makeString(name, ".x"), String::number(m_clickLocation.x())); formData.append(makeString(name, ".y"), String::number(m_clickLocation.y())); - auto value = element().value(); + auto value = element()->value(); if (!value.isEmpty()) formData.append(name, value); @@ -83,10 +84,14 @@ void ImageInputType::handleDOMActivateEvent(Event& event) { - Ref element(this->element()); - if (element->isDisabledFormControl() || !element->form()) + ASSERT(element()); + Ref protectedElement(*element()); + if (protectedElement->isDisabledFormControl() || !protectedElement->form()) return; - element->setActivatedSubmit(true); + + Ref protectedForm(*protectedElement->form()); + + protectedElement->setActivatedSubmit(true); m_clickLocation = IntPoint(); if (event.underlyingEvent()) { @@ -98,42 +103,49 @@ } } - element->form()->prepareForSubmission(event); // Event handlers can run. - element->setActivatedSubmit(false); + // Update layout before processing form actions in case the style changes + // the Form or button relationships. + protectedElement->document().updateLayoutIgnorePendingStylesheets(); + + if (auto currentForm = protectedElement->form()) + currentForm->prepareForSubmission(event); // Event handlers can run. + + protectedElement->setActivatedSubmit(false); event.setDefaultHandled(); } RenderPtr ImageInputType::createInputRenderer(RenderStyle&& style) { - return createRenderer(element(), WTFMove(style)); + ASSERT(element()); + return createRenderer(*element(), WTFMove(style)); } void ImageInputType::altAttributeChanged() { - if (!is(element().renderer())) - return; - - auto* renderer = downcast(element().renderer()); - if (!renderer) - return; - renderer->updateAltText(); + if (auto* element = this->element()) { + auto* renderer = element->renderer(); + if (is(renderer)) + downcast(*renderer).updateAltText(); + } } void ImageInputType::srcAttributeChanged() { - if (!element().renderer()) - return; - element().ensureImageLoader().updateFromElementIgnoringPreviousError(); + if (auto* element = this->element()) { + if (element->renderer()) + element->ensureImageLoader().updateFromElementIgnoringPreviousError(); + } } void ImageInputType::attach() { BaseButtonInputType::attach(); - HTMLImageLoader& imageLoader = element().ensureImageLoader(); + ASSERT(element()); + HTMLImageLoader& imageLoader = element()->ensureImageLoader(); imageLoader.updateFromElement(); - auto* renderer = downcast(element().renderer()); + auto* renderer = downcast(element()->renderer()); if (!renderer) return; @@ -176,7 +188,8 @@ unsigned ImageInputType::height() const { - Ref element(this->element()); + ASSERT(element()); + Ref element(*this->element()); element->document().updateLayout(); @@ -197,7 +210,8 @@ unsigned ImageInputType::width() const { - Ref element(this->element()); + ASSERT(element()); + Ref element(*this->element()); element->document().updateLayout(); diff -Nru webkit2gtk-2.20.3/Source/WebCore/html/InputType.cpp webkit2gtk-2.20.5/Source/WebCore/html/InputType.cpp --- webkit2gtk-2.20.3/Source/WebCore/html/InputType.cpp 2018-02-19 07:45:32.000000000 +0000 +++ webkit2gtk-2.20.5/Source/WebCore/html/InputType.cpp 2018-07-31 07:02:15.000000000 +0000 @@ -2,7 +2,7 @@ * Copyright (C) 1999 Lars Knoll (knoll@kde.org) * (C) 1999 Antti Koivisto (koivisto@kde.org) * (C) 2001 Dirk Mueller (mueller@kde.org) - * Copyright (C) 2004-2017 Apple Inc. All rights reserved. + * Copyright (C) 2004-2018 Apple Inc. All rights reserved. * (C) 2006 Alexey Proskuryakov (ap@nypop.com) * Copyright (C) 2007 Samuel Weinig (sam@webkit.org) * Copyright (C) 2009, 2010, 2011, 2012 Google Inc. All rights reserved. @@ -85,13 +85,13 @@ typedef bool (RuntimeEnabledFeatures::*InputTypeConditionalFunction)() const; typedef const AtomicString& (*InputTypeNameFunction)(); -typedef std::unique_ptr (*InputTypeFactoryFunction)(HTMLInputElement&); +typedef Ref (*InputTypeFactoryFunction)(HTMLInputElement&); typedef HashMap InputTypeFactoryMap; template -static std::unique_ptr createInputType(HTMLInputElement& element) +static Ref createInputType(HTMLInputElement& element) { - return std::make_unique(element); + return adoptRef(*new T(element)); } static InputTypeFactoryMap createInputTypeFactoryMap() @@ -149,19 +149,19 @@ return map; } -std::unique_ptr InputType::create(HTMLInputElement& element, const AtomicString& typeName) +Ref InputType::create(HTMLInputElement& element, const AtomicString& typeName) { if (!typeName.isEmpty()) { static const auto factoryMap = makeNeverDestroyed(createInputTypeFactoryMap()); if (auto factory = factoryMap.get().get(typeName)) return factory(element); } - return std::make_unique(element); + return adoptRef(*new TextInputType(element)); } -std::unique_ptr InputType::createText(HTMLInputElement& element) +Ref InputType::createText(HTMLInputElement& element) { - return std::make_unique(element); + return adoptRef(*new TextInputType(element)); } InputType::~InputType() = default; @@ -193,27 +193,31 @@ FormControlState InputType::saveFormControlState() const { - auto currentValue = element().value(); - if (currentValue == element().defaultValue()) + ASSERT(element()); + auto currentValue = element()->value(); + if (currentValue == element()->defaultValue()) return { }; return { { currentValue } }; } void InputType::restoreFormControlState(const FormControlState& state) { - element().setValue(state[0]); + ASSERT(element()); + element()->setValue(state[0]); } bool InputType::isFormDataAppendable() const { + ASSERT(element()); // There is no form data unless there's a name for non-image types. - return !element().name().isEmpty(); + return !element()->name().isEmpty(); } bool InputType::appendFormData(DOMFormData& formData, bool) const { + ASSERT(element()); // Always successful. - formData.append(element().name(), element().value()); + formData.append(element()->name(), element()->value()); return true; } @@ -319,7 +323,8 @@ bool InputType::sizeShouldIncludeDecoration(int, int& preferredSize) const { - preferredSize = element().size(); + ASSERT(element()); + preferredSize = element()->size(); return false; } @@ -390,7 +395,8 @@ String InputType::validationMessage() const { - String value = element().value(); + ASSERT(element()); + String value = element()->value(); // The order of the following checks is meaningful. e.g. We'd like to show the // badInput message even if the control has other validation errors. @@ -406,11 +412,11 @@ if (patternMismatch(value)) return validationMessagePatternMismatchText(); - if (element().tooShort()) - return validationMessageTooShortText(numGraphemeClusters(value), element().minLength()); + if (element()->tooShort()) + return validationMessageTooShortText(numGraphemeClusters(value), element()->minLength()); - if (element().tooLong()) - return validationMessageTooLongText(numGraphemeClusters(value), element().effectiveMaxLength()); + if (element()->tooLong()) + return validationMessageTooLongText(numGraphemeClusters(value), element()->effectiveMaxLength()); if (!isSteppable()) return emptyString(); @@ -480,12 +486,14 @@ RenderPtr InputType::createInputRenderer(RenderStyle&& style) { - return RenderPtr(RenderElement::createFor(element(), WTFMove(style))); + ASSERT(element()); + return RenderPtr(RenderElement::createFor(*element(), WTFMove(style))); } void InputType::blur() { - element().defaultBlur(); + ASSERT(element()); + element()->defaultBlur(); } void InputType::createShadowSubtree() @@ -494,7 +502,8 @@ void InputType::destroyShadowSubtree() { - RefPtr root = element().userAgentShadowRoot(); + ASSERT(element()); + RefPtr root = element()->userAgentShadowRoot(); if (!root) return; @@ -533,14 +542,16 @@ void InputType::dispatchSimulatedClickIfActive(KeyboardEvent& event) const { - if (element().active()) - element().dispatchSimulatedClick(&event); + ASSERT(element()); + if (element()->active()) + element()->dispatchSimulatedClick(&event); event.setDefaultHandled(); } Chrome* InputType::chrome() const { - if (Page* page = element().document().page()) + ASSERT(element()); + if (Page* page = element()->document().page()) return &page->chrome(); return nullptr; } @@ -557,12 +568,14 @@ bool InputType::isKeyboardFocusable(KeyboardEvent& event) const { - return !element().isReadOnly() && element().isTextFormControlKeyboardFocusable(event); + ASSERT(element()); + return !element()->isReadOnly() && element()->isTextFormControlKeyboardFocusable(event); } bool InputType::isMouseFocusable() const { - return element().isTextFormControlMouseFocusable(); + ASSERT(element()); + return element()->isTextFormControlMouseFocusable(); } bool InputType::shouldUseInputMethod() const @@ -580,7 +593,8 @@ void InputType::accessKeyAction(bool) { - element().focus(false); + ASSERT(element()); + element()->focus(false); } void InputType::addSearchResult() @@ -671,17 +685,20 @@ void InputType::setValue(const String& sanitizedValue, bool valueChanged, TextFieldEventBehavior eventBehavior) { - element().setValueInternal(sanitizedValue, eventBehavior); - element().invalidateStyleForSubtree(); + ASSERT(element()); + element()->setValueInternal(sanitizedValue, eventBehavior); + element()->invalidateStyleForSubtree(); if (!valueChanged) return; + switch (eventBehavior) { case DispatchChangeEvent: - element().dispatchFormControlChangeEvent(); + element()->dispatchFormControlChangeEvent(); break; case DispatchInputAndChangeEvent: - element().dispatchFormControlInputEvent(); - element().dispatchFormControlChangeEvent(); + element()->dispatchFormControlInputEvent(); + if (auto element = this->element()) + element->dispatchFormControlChangeEvent(); break; case DispatchNoEvent: break; @@ -708,7 +725,8 @@ String InputType::visibleValue() const { - return element().value(); + ASSERT(element()); + return element()->value(); } bool InputType::isEmptyValue() const @@ -984,7 +1002,8 @@ if (!stepRange.hasStep()) return Exception { InvalidStateError }; - const Decimal current = parseToNumberOrNaN(element().value()); + ASSERT(element()); + const Decimal current = parseToNumberOrNaN(element()->value()); if (!current.isFinite()) return Exception { InvalidStateError }; Decimal newValue = current + stepRange.step() * count; @@ -997,7 +1016,7 @@ if (newValue < stepRange.minimum()) newValue = stepRange.minimum(); - if (!equalLettersIgnoringASCIICase(element().attributeWithoutSynchronization(stepAttr), "any")) + if (!equalLettersIgnoringASCIICase(element()->attributeWithoutSynchronization(stepAttr), "any")) newValue = stepRange.alignValueForStep(current, newValue); if (newValue - stepRange.maximum() > acceptableErrorValue) @@ -1009,8 +1028,8 @@ if (result.hasException()) return result; - if (AXObjectCache* cache = element().document().existingAXObjectCache()) - cache->postNotification(&element(), AXObjectCache::AXValueChanged); + if (AXObjectCache* cache = element()->document().existingAXObjectCache()) + cache->postNotification(element(), AXObjectCache::AXValueChanged); return result; } @@ -1097,7 +1116,8 @@ else sign = 0; - String currentStringValue = element().value(); + ASSERT(element()); + String currentStringValue = element()->value(); Decimal current = parseToNumberOrNaN(currentStringValue); if (!current.isFinite()) { current = defaultValueForStepUp(); @@ -1111,7 +1131,7 @@ if ((sign > 0 && current < stepRange.minimum()) || (sign < 0 && current > stepRange.maximum())) setValueAsDecimal(sign > 0 ? stepRange.minimum() : stepRange.maximum(), DispatchInputAndChangeEvent); else { - if (stepMismatch(element().value())) { + if (stepMismatch(element()->value())) { ASSERT(!step.isZero()); const Decimal base = stepRange.stepBase(); Decimal newValue; diff -Nru webkit2gtk-2.20.3/Source/WebCore/html/InputType.h webkit2gtk-2.20.5/Source/WebCore/html/InputType.h --- webkit2gtk-2.20.3/Source/WebCore/html/InputType.h 2018-02-19 07:45:32.000000000 +0000 +++ webkit2gtk-2.20.5/Source/WebCore/html/InputType.h 2018-07-31 07:02:15.000000000 +0000 @@ -1,6 +1,6 @@ /* * Copyright (C) 2010 Google Inc. All rights reserved. - * Copyright (C) 2011-2017 Apple Inc. All rights reserved. + * Copyright (C) 2011-2018 Apple Inc. All rights reserved. * Copyright (C) 2012 Samsung Electronics. All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -37,6 +37,7 @@ #include "StepRange.h" #include #include +#include #include #if PLATFORM(IOS) @@ -68,12 +69,12 @@ // An InputType object represents the type-specific part of an HTMLInputElement. // Do not expose instances of InputType and classes derived from it to classes // other than HTMLInputElement. -class InputType { +class InputType : public RefCounted { WTF_MAKE_FAST_ALLOCATED; public: - static std::unique_ptr create(HTMLInputElement&, const AtomicString&); - static std::unique_ptr createText(HTMLInputElement&); + static Ref create(HTMLInputElement&, const AtomicString&); + static Ref createText(HTMLInputElement&); virtual ~InputType(); static bool themeSupportsDataListUI(InputType*); @@ -309,8 +310,9 @@ virtual String displayString() const; protected: - explicit InputType(HTMLInputElement& element) : m_element(element) { } - HTMLInputElement& element() const { return m_element; } + explicit InputType(HTMLInputElement& element) + : m_element(makeWeakPtr(element)) { } + HTMLInputElement* element() const { return m_element.get(); } Chrome* chrome() const; Decimal parseToNumberOrNaN(const String&) const; @@ -319,7 +321,7 @@ ExceptionOr applyStep(int count, AnyStepHandling, TextFieldEventBehavior); // Raw pointer because the HTMLInputElement object owns this InputType object. - HTMLInputElement& m_element; + WeakPtr m_element; }; } // namespace WebCore diff -Nru webkit2gtk-2.20.3/Source/WebCore/html/NumberInputType.cpp webkit2gtk-2.20.5/Source/WebCore/html/NumberInputType.cpp --- webkit2gtk-2.20.3/Source/WebCore/html/NumberInputType.cpp 2018-02-19 07:45:32.000000000 +0000 +++ webkit2gtk-2.20.5/Source/WebCore/html/NumberInputType.cpp 2018-07-31 07:16:29.000000000 +0000 @@ -93,14 +93,16 @@ void NumberInputType::setValue(const String& sanitizedValue, bool valueChanged, TextFieldEventBehavior eventBehavior) { - if (!valueChanged && sanitizedValue.isEmpty() && !element().innerTextValue().isEmpty()) + ASSERT(element()); + if (!valueChanged && sanitizedValue.isEmpty() && !element()->innerTextValue().isEmpty()) updateInnerTextValue(); TextFieldInputType::setValue(sanitizedValue, valueChanged, eventBehavior); } double NumberInputType::valueAsDouble() const { - return parseToDoubleForNumberType(element().value()); + ASSERT(element()); + return parseToDoubleForNumberType(element()->value()); } ExceptionOr NumberInputType::setValueAsDouble(double newValue, TextFieldEventBehavior eventBehavior) const @@ -109,7 +111,8 @@ const double floatMax = std::numeric_limits::max(); if (newValue < -floatMax || newValue > floatMax) return Exception { InvalidStateError }; - element().setValue(serializeForNumberType(newValue), eventBehavior); + ASSERT(element()); + element()->setValue(serializeForNumberType(newValue), eventBehavior); return { }; } @@ -119,7 +122,8 @@ const Decimal floatMax = Decimal::fromDouble(std::numeric_limits::max()); if (newValue < -floatMax || newValue > floatMax) return Exception { InvalidStateError }; - element().setValue(serializeForNumberType(newValue), eventBehavior); + ASSERT(element()); + element()->setValue(serializeForNumberType(newValue), eventBehavior); return { }; } @@ -130,17 +134,20 @@ bool NumberInputType::typeMismatch() const { - ASSERT(!typeMismatchFor(element().value())); + ASSERT(element()); + ASSERT(!typeMismatchFor(element()->value())); return false; } StepRange NumberInputType::createStepRange(AnyStepHandling anyStepHandling) const { static NeverDestroyed stepDescription(numberDefaultStep, numberDefaultStepBase, numberStepScaleFactor); - const Decimal stepBase = parseToDecimalForNumberType(element().attributeWithoutSynchronization(minAttr), numberDefaultStepBase); + + ASSERT(element()); + const Decimal stepBase = parseToDecimalForNumberType(element()->attributeWithoutSynchronization(minAttr), numberDefaultStepBase); // FIXME: We should use numeric_limits::max for number input type. const Decimal floatMax = Decimal::fromDouble(std::numeric_limits::max()); - const Element& element = this->element(); + const Element& element = *this->element(); RangeLimitations rangeLimitations = RangeLimitations::Invalid; auto extractBound = [&] (const QualifiedName& attributeName, const Decimal& defaultValue) -> Decimal { @@ -163,15 +170,16 @@ { preferredSize = defaultSize; - auto& stepString = element().attributeWithoutSynchronization(stepAttr); + ASSERT(element()); + auto& stepString = element()->attributeWithoutSynchronization(stepAttr); if (equalLettersIgnoringASCIICase(stepString, "any")) return false; - const Decimal minimum = parseToDecimalForNumberType(element().attributeWithoutSynchronization(minAttr)); + const Decimal minimum = parseToDecimalForNumberType(element()->attributeWithoutSynchronization(minAttr)); if (!minimum.isFinite()) return false; - const Decimal maximum = parseToDecimalForNumberType(element().attributeWithoutSynchronization(maxAttr)); + const Decimal maximum = parseToDecimalForNumberType(element()->attributeWithoutSynchronization(maxAttr)); if (!maximum.isFinite()) return false; @@ -187,8 +195,10 @@ float NumberInputType::decorationWidth() const { + ASSERT(element()); + float width = 0; - RefPtr spinButton = element().innerSpinButtonElement(); + RefPtr spinButton = element()->innerSpinButtonElement(); if (RenderBox* spinRenderer = spinButton ? spinButton->renderBox() : 0) { width += spinRenderer->borderAndPaddingLogicalWidth(); // Since the width of spinRenderer is not calculated yet, spinRenderer->logicalWidth() returns 0. @@ -234,12 +244,14 @@ // We don't localize scientific notations. if (proposedValue.find(isE) != notFound) return proposedValue; - return element().locale().convertToLocalizedNumber(proposedValue); + ASSERT(element()); + return element()->locale().convertToLocalizedNumber(proposedValue); } String NumberInputType::visibleValue() const { - return localizeValue(element().value()); + ASSERT(element()); + return localizeValue(element()->value()); } String NumberInputType::convertFromVisibleValue(const String& visibleValue) const @@ -249,7 +261,8 @@ // We don't localize scientific notations. if (visibleValue.find(isE) != notFound) return visibleValue; - return element().locale().convertFromLocalizedNumber(visibleValue); + ASSERT(element()); + return element()->locale().convertFromLocalizedNumber(visibleValue); } String NumberInputType::sanitizeValue(const String& proposedValue) const @@ -261,7 +274,8 @@ bool NumberInputType::hasBadInput() const { - String standardValue = convertFromVisibleValue(element().innerTextValue()); + ASSERT(element()); + String standardValue = convertFromVisibleValue(element()->innerTextValue()); return !standardValue.isEmpty() && !std::isfinite(parseToDoubleForNumberType(standardValue)); } @@ -282,19 +296,21 @@ void NumberInputType::minOrMaxAttributeChanged() { - InputType::minOrMaxAttributeChanged(); - HTMLInputElement& element = this->element(); - element.invalidateStyleForSubtree(); - if (RenderObject* renderer = element.renderer()) - renderer->setNeedsLayoutAndPrefWidthsRecalc(); + if (auto* element = this->element()) { + element->invalidateStyleForSubtree(); + if (auto* renderer = element->renderer()) + renderer->setNeedsLayoutAndPrefWidthsRecalc(); + } } void NumberInputType::stepAttributeChanged() { InputType::stepAttributeChanged(); - if (element().renderer()) - element().renderer()->setNeedsLayoutAndPrefWidthsRecalc(); + if (auto* element = this->element()) { + if (auto* renderer = element->renderer()) + renderer->setNeedsLayoutAndPrefWidthsRecalc(); + } } } // namespace WebCore diff -Nru webkit2gtk-2.20.3/Source/WebCore/html/RadioInputType.cpp webkit2gtk-2.20.5/Source/WebCore/html/RadioInputType.cpp --- webkit2gtk-2.20.3/Source/WebCore/html/RadioInputType.cpp 2018-02-19 07:45:32.000000000 +0000 +++ webkit2gtk-2.20.5/Source/WebCore/html/RadioInputType.cpp 2018-07-31 07:02:15.000000000 +0000 @@ -1,5 +1,5 @@ /* - * Copyright (C) 2005, 2011, 2016 Apple Inc. All rights reserved. + * Copyright (C) 2005-2018 Apple Inc. All rights reserved. * Copyright (C) 2010 Google Inc. All rights reserved. * * This library is free software; you can redistribute it and/or @@ -44,7 +44,8 @@ bool RadioInputType::valueMissing(const String&) const { - return element().isInRequiredRadioButtonGroup() && !element().checkedRadioButtonForGroup(); + ASSERT(element()); + return element()->isInRequiredRadioButtonGroup() && !element()->checkedRadioButtonForGroup(); } String RadioInputType::valueMissingText() const @@ -66,18 +67,19 @@ if (key != "Up" && key != "Down" && key != "Left" && key != "Right") return; + ASSERT(element()); // Left and up mean "previous radio button". // Right and down mean "next radio button". // Tested in WinIE, and even for RTL, left still means previous radio button (and so moves // to the right). Seems strange, but we'll match it. // However, when using Spatial Navigation, we need to be able to navigate without changing the selection. - if (isSpatialNavigationEnabled(element().document().frame())) + if (isSpatialNavigationEnabled(element()->document().frame())) return; bool forward = (key == "Down" || key == "Right"); // We can only stay within the form's children if the form hasn't been demoted to a leaf because // of malformed HTML. - RefPtr node = &element(); + RefPtr node = element(); while ((node = (forward ? NodeTraversal::next(*node) : NodeTraversal::previous(*node)))) { // Once we encounter a form element, we know we're through. if (is(*node)) @@ -86,10 +88,10 @@ if (!is(*node)) continue; RefPtr inputElement = downcast(node.get()); - if (inputElement->form() != element().form()) + if (inputElement->form() != element()->form()) break; - if (inputElement->isRadioButton() && inputElement->name() == element().name() && inputElement->isFocusable()) { - element().document().setFocusedElement(inputElement.get()); + if (inputElement->isRadioButton() && inputElement->name() == element()->name() && inputElement->isFocusable()) { + element()->document().setFocusedElement(inputElement.get()); inputElement->dispatchSimulatedClick(&event, SendNoEvents, DoNotShowPressedLook); event.setDefaultHandled(); return; @@ -102,9 +104,11 @@ const String& key = event.keyIdentifier(); if (key != "U+0020") return; + + ASSERT(element()); // If an unselected radio is tabbed into (because the entire group has nothing // checked, or because of some explicit .focus() call), then allow space to check it. - if (element().checked()) + if (element()->checked()) return; dispatchSimulatedClickIfActive(event); } @@ -114,32 +118,35 @@ if (!InputType::isKeyboardFocusable(event)) return false; + ASSERT(element()); // When using Spatial Navigation, every radio button should be focusable. - if (isSpatialNavigationEnabled(element().document().frame())) + if (isSpatialNavigationEnabled(element()->document().frame())) return true; // Never allow keyboard tabbing to leave you in the same radio group. Always // skip any other elements in the group. - RefPtr currentFocusedNode = element().document().focusedElement(); + RefPtr currentFocusedNode = element()->document().focusedElement(); if (is(currentFocusedNode)) { HTMLInputElement& focusedInput = downcast(*currentFocusedNode); - if (focusedInput.isRadioButton() && focusedInput.form() == element().form() && focusedInput.name() == element().name()) + if (focusedInput.isRadioButton() && focusedInput.form() == element()->form() && focusedInput.name() == element()->name()) return false; } // Allow keyboard focus if we're checked or if nothing in the group is checked. - return element().checked() || !element().checkedRadioButtonForGroup(); + return element()->checked() || !element()->checkedRadioButtonForGroup(); } bool RadioInputType::shouldSendChangeEventAfterCheckedChanged() { // Don't send a change event for a radio button that's getting unchecked. // This was done to match the behavior of other browsers. - return element().checked(); + ASSERT(element()); + return element()->checked(); } void RadioInputType::willDispatchClick(InputElementClickState& state) { + ASSERT(element()); // An event handler can use preventDefault or "return false" to reverse the selection we do here. // The InputElementClickState object contains what we need to undo what we did here in didDispatchClick. @@ -147,10 +154,10 @@ // Therefore if nothing is currently selected, we won't allow the upcoming action to be "undone", since // we want some object in the radio group to actually get selected. - state.checked = element().checked(); - state.checkedRadioButton = element().checkedRadioButtonForGroup(); + state.checked = element()->checked(); + state.checkedRadioButton = element()->checkedRadioButtonForGroup(); - element().setChecked(true, DispatchChangeEvent); + element()->setChecked(true, DispatchChangeEvent); } void RadioInputType::didDispatchClick(Event& event, const InputElementClickState& state) @@ -159,7 +166,8 @@ // Restore the original selected radio button if possible. // Make sure it is still a radio button and only do the restoration if it still belongs to our group. auto& button = state.checkedRadioButton; - if (button && button->isRadioButton() && button->form() == element().form() && button->name() == element().name()) + ASSERT(element()); + if (button && button->isRadioButton() && button->form() == element()->form() && button->name() == element()->name()) button->setChecked(true); } @@ -174,7 +182,8 @@ bool RadioInputType::matchesIndeterminatePseudoClass() const { - const HTMLInputElement& element = this->element(); + ASSERT(element()); + const HTMLInputElement& element = *this->element(); if (const RadioButtonGroups* radioButtonGroups = element.radioButtonGroups()) return !radioButtonGroups->hasCheckedButton(&element); return !element.checked(); diff -Nru webkit2gtk-2.20.3/Source/WebCore/html/RangeInputType.cpp webkit2gtk-2.20.5/Source/WebCore/html/RangeInputType.cpp --- webkit2gtk-2.20.3/Source/WebCore/html/RangeInputType.cpp 2018-02-19 07:45:32.000000000 +0000 +++ webkit2gtk-2.20.5/Source/WebCore/html/RangeInputType.cpp 2018-07-31 07:16:04.000000000 +0000 @@ -92,12 +92,14 @@ double RangeInputType::valueAsDouble() const { - return parseToDoubleForNumberType(element().value()); + ASSERT(element()); + return parseToDoubleForNumberType(element()->value()); } ExceptionOr RangeInputType::setValueAsDecimal(const Decimal& newValue, TextFieldEventBehavior eventBehavior) const { - element().setValue(serialize(newValue), eventBehavior); + ASSERT(element()); + element()->setValue(serialize(newValue), eventBehavior); return { }; } @@ -115,16 +117,17 @@ { static NeverDestroyed stepDescription(rangeDefaultStep, rangeDefaultStepBase, rangeStepScaleFactor); - const Decimal minimum = parseToNumber(element().attributeWithoutSynchronization(minAttr), rangeDefaultMinimum); - const Decimal maximum = ensureMaximum(parseToNumber(element().attributeWithoutSynchronization(maxAttr), rangeDefaultMaximum), minimum, rangeDefaultMaximum); + ASSERT(element()); + const Decimal minimum = parseToNumber(element()->attributeWithoutSynchronization(minAttr), rangeDefaultMinimum); + const Decimal maximum = ensureMaximum(parseToNumber(element()->attributeWithoutSynchronization(maxAttr), rangeDefaultMaximum), minimum, rangeDefaultMaximum); - const AtomicString& precisionValue = element().attributeWithoutSynchronization(precisionAttr); + const AtomicString& precisionValue = element()->attributeWithoutSynchronization(precisionAttr); if (!precisionValue.isNull()) { const Decimal step = equalLettersIgnoringASCIICase(precisionValue, "float") ? Decimal::nan() : 1; return StepRange(minimum, RangeLimitations::Valid, minimum, maximum, step, stepDescription); } - const Decimal step = StepRange::parseStep(anyStepHandling, stepDescription, element().attributeWithoutSynchronization(stepAttr)); + const Decimal step = StepRange::parseStep(anyStepHandling, stepDescription, element()->attributeWithoutSynchronization(stepAttr)); return StepRange(minimum, RangeLimitations::Valid, minimum, maximum, step, stepDescription); } @@ -137,14 +140,15 @@ void RangeInputType::handleMouseDownEvent(MouseEvent& event) { - if (element().isDisabledFormControl()) + ASSERT(element()); + if (element()->isDisabledFormControl()) return; if (event.button() != LeftButton || !is(event.target())) return; - ASSERT(element().shadowRoot()); + ASSERT(element()->shadowRoot()); auto& targetNode = downcast(*event.target()); - if (&targetNode != &element() && !targetNode.isDescendantOf(element().userAgentShadowRoot().get())) + if (&targetNode != element() && !targetNode.isDescendantOf(element()->userAgentShadowRoot().get())) return; auto& thumb = typedSliderThumbElement(); if (&targetNode == &thumb) @@ -160,7 +164,8 @@ #if PLATFORM(IOS) typedSliderThumbElement().handleTouchEvent(event); #elif ENABLE(TOUCH_SLIDER) - if (element().isDisabledFormControl()) + ASSERT(element()); + if (element()->isDisabledFormControl()) return; if (event.type() == eventNames().touchendEvent) { @@ -193,12 +198,13 @@ void RangeInputType::handleKeydownEvent(KeyboardEvent& event) { - if (element().isDisabledFormControl()) + ASSERT(element()); + if (element()->isDisabledFormControl()) return; const String& key = event.keyIdentifier(); - const Decimal current = parseToNumberOrNaN(element().value()); + const Decimal current = parseToNumberOrNaN(element()->value()); ASSERT(current.isFinite()); StepRange stepRange(createStepRange(RejectAny)); @@ -206,12 +212,12 @@ // FIXME: We can't use stepUp() for the step value "any". So, we increase // or decrease the value by 1/100 of the value range. Is it reasonable? - const Decimal step = equalLettersIgnoringASCIICase(element().attributeWithoutSynchronization(stepAttr), "any") ? (stepRange.maximum() - stepRange.minimum()) / 100 : stepRange.step(); + const Decimal step = equalLettersIgnoringASCIICase(element()->attributeWithoutSynchronization(stepAttr), "any") ? (stepRange.maximum() - stepRange.minimum()) / 100 : stepRange.step(); const Decimal bigStep = std::max((stepRange.maximum() - stepRange.minimum()) / 10, step); bool isVertical = false; - if (element().renderer()) { - ControlPart part = element().renderer()->style().appearance(); + if (auto* renderer = element()->renderer()) { + ControlPart part = renderer->style().appearance(); isVertical = part == SliderVerticalPart || part == MediaVolumeSliderPart; } @@ -241,8 +247,8 @@ EventQueueScope scope; setValueAsDecimal(newValue, DispatchInputAndChangeEvent); - if (AXObjectCache* cache = element().document().existingAXObjectCache()) - cache->postNotification(&element(), AXObjectCache::AXValueChanged); + if (AXObjectCache* cache = element()->document().existingAXObjectCache()) + cache->postNotification(element(), AXObjectCache::AXValueChanged); } event.setDefaultHandled(); @@ -250,25 +256,27 @@ void RangeInputType::createShadowSubtree() { - ASSERT(element().userAgentShadowRoot()); + ASSERT(element()); + ASSERT(element()->userAgentShadowRoot()); - Document& document = element().document(); + Document& document = element()->document(); auto track = HTMLDivElement::create(document); track->setPseudo(AtomicString("-webkit-slider-runnable-track", AtomicString::ConstructFromLiteral)); track->appendChild(SliderThumbElement::create(document)); auto container = SliderContainerElement::create(document); container->appendChild(track); - element().userAgentShadowRoot()->appendChild(container); + element()->userAgentShadowRoot()->appendChild(container); } HTMLElement* RangeInputType::sliderTrackElement() const { - ASSERT(element().userAgentShadowRoot()); - ASSERT(element().userAgentShadowRoot()->firstChild()); // container - ASSERT(element().userAgentShadowRoot()->firstChild()->isHTMLElement()); - ASSERT(element().userAgentShadowRoot()->firstChild()->firstChild()); // track + ASSERT(element()); + ASSERT(element()->userAgentShadowRoot()); + ASSERT(element()->userAgentShadowRoot()->firstChild()); // container + ASSERT(element()->userAgentShadowRoot()->firstChild()->isHTMLElement()); + ASSERT(element()->userAgentShadowRoot()->firstChild()->firstChild()); // track - RefPtr root = element().userAgentShadowRoot(); + RefPtr root = element()->userAgentShadowRoot(); if (!root) return nullptr; @@ -294,7 +302,8 @@ RenderPtr RangeInputType::createInputRenderer(RenderStyle&& style) { - return createRenderer(element(), WTFMove(style)); + ASSERT(element()); + return createRenderer(*element(), WTFMove(style)); } Decimal RangeInputType::parseToNumber(const String& src, const Decimal& defaultValue) const @@ -314,7 +323,8 @@ { InputType::accessKeyAction(sendMouseEvents); - element().dispatchSimulatedClick(0, sendMouseEvents ? SendMouseUpDownEvents : SendNoEvents); + ASSERT(element()); + element()->dispatchSimulatedClick(0, sendMouseEvents ? SendMouseUpDownEvents : SendNoEvents); } void RangeInputType::minOrMaxAttributeChanged() @@ -322,9 +332,10 @@ InputType::minOrMaxAttributeChanged(); // Sanitize the value. - if (element().hasDirtyValue()) - element().setValue(element().value()); - + if (auto* element = this->element()) { + if (element->hasDirtyValue()) + element->setValue(element->value()); + } typedSliderThumbElement().setPositionFromValue(); } @@ -335,8 +346,10 @@ if (!valueChanged) return; - if (eventBehavior == DispatchNoEvent) - element().setTextAsOfLastFormControlChangeEvent(value); + if (eventBehavior == DispatchNoEvent) { + ASSERT(element()); + element()->setTextAsOfLastFormControlChangeEvent(value); + } typedSliderThumbElement().setPositionFromValue(); } @@ -373,7 +386,8 @@ return; m_tickMarkValues.clear(); m_tickMarkValuesDirty = false; - auto dataList = element().dataList(); + ASSERT(element()); + auto dataList = element()->dataList(); if (!dataList) return; Ref options = dataList->options(); @@ -382,7 +396,7 @@ RefPtr node = options->item(i); HTMLOptionElement& optionElement = downcast(*node); String optionValue = optionElement.value(); - if (!element().isValidValue(optionValue)) + if (!element()->isValidValue(optionValue)) continue; m_tickMarkValues.append(parseToNumber(optionValue, Decimal::nan())); } diff -Nru webkit2gtk-2.20.3/Source/WebCore/html/ResetInputType.cpp webkit2gtk-2.20.5/Source/WebCore/html/ResetInputType.cpp --- webkit2gtk-2.20.3/Source/WebCore/html/ResetInputType.cpp 2018-02-19 07:45:32.000000000 +0000 +++ webkit2gtk-2.20.5/Source/WebCore/html/ResetInputType.cpp 2018-07-31 07:02:08.000000000 +0000 @@ -52,9 +52,10 @@ void ResetInputType::handleDOMActivateEvent(Event& event) { - if (element().isDisabledFormControl() || !element().form()) + ASSERT(element()); + if (element()->isDisabledFormControl() || !element()->form()) return; - element().form()->reset(); + element()->form()->reset(); event.setDefaultHandled(); } diff -Nru webkit2gtk-2.20.3/Source/WebCore/html/SearchInputType.cpp webkit2gtk-2.20.5/Source/WebCore/html/SearchInputType.cpp --- webkit2gtk-2.20.3/Source/WebCore/html/SearchInputType.cpp 2018-02-19 07:45:32.000000000 +0000 +++ webkit2gtk-2.20.5/Source/WebCore/html/SearchInputType.cpp 2018-07-31 07:17:18.000000000 +0000 @@ -60,8 +60,9 @@ // Normally we've got the correct renderer by the time we get here. However when the input type changes // we don't update the associated renderers until after the next tree update, so we could actually end up here // with a mismatched renderer (e.g. through form submission). - if (is(element().renderer())) - downcast(*element().renderer()).addSearchResult(); + ASSERT(element()); + if (is(element()->renderer())) + downcast(*element()->renderer()).addSearchResult(); #endif } @@ -77,13 +78,16 @@ void SearchInputType::maxResultsAttributeChanged() { - if (m_resultsButton) - updateResultButtonPseudoType(*m_resultsButton, element().maxResults()); + if (m_resultsButton) { + if (auto* element = this->element()) + updateResultButtonPseudoType(*m_resultsButton, element->maxResults()); + } } RenderPtr SearchInputType::createInputRenderer(RenderStyle&& style) { - return createRenderer(element(), WTFMove(style)); + ASSERT(element()); + return createRenderer(*element(), WTFMove(style)); } const AtomicString& SearchInputType::formControlType() const @@ -112,11 +116,12 @@ ASSERT(container); ASSERT(textWrapper); - m_resultsButton = SearchFieldResultsButtonElement::create(element().document()); - updateResultButtonPseudoType(*m_resultsButton, element().maxResults()); + ASSERT(element()); + m_resultsButton = SearchFieldResultsButtonElement::create(element()->document()); + updateResultButtonPseudoType(*m_resultsButton, element()->maxResults()); container->insertBefore(*m_resultsButton, textWrapper.get()); - m_cancelButton = SearchFieldCancelButtonElement::create(element().document()); + m_cancelButton = SearchFieldCancelButtonElement::create(element()->document()); container->insertBefore(*m_cancelButton, textWrapper->nextSibling()); } @@ -132,16 +137,17 @@ void SearchInputType::handleKeydownEvent(KeyboardEvent& event) { - if (element().isDisabledOrReadOnly()) { + ASSERT(element()); + if (element()->isDisabledOrReadOnly()) { TextFieldInputType::handleKeydownEvent(event); return; } const String& key = event.keyIdentifier(); if (key == "U+001B") { - Ref input(this->element()); - input->setValueForUser(emptyString()); - input->onSearch(); + Ref protectedInputElement(*element()); + protectedInputElement->setValueForUser(emptyString()); + protectedInputElement->onSearch(); event.setDefaultHandled(); return; } @@ -157,8 +163,9 @@ void SearchInputType::startSearchEventTimer() { - ASSERT(element().renderer()); - unsigned length = element().innerTextValue().length(); + ASSERT(element()); + ASSERT(element()->renderer()); + unsigned length = element()->innerTextValue().length(); if (!length) { m_searchEventTimer.startOneShot(0_ms); @@ -177,18 +184,21 @@ void SearchInputType::searchEventTimerFired() { - element().onSearch(); + ASSERT(element()); + element()->onSearch(); } bool SearchInputType::searchEventsShouldBeDispatched() const { - return element().hasAttributeWithoutSynchronization(incrementalAttr); + ASSERT(element()); + return element()->hasAttributeWithoutSynchronization(incrementalAttr); } void SearchInputType::didSetValueByUserEdit() { - if (m_cancelButton && is(element().renderer())) - downcast(*element().renderer()).updateCancelButtonVisibility(); + ASSERT(element()); + if (m_cancelButton && is(element()->renderer())) + downcast(*element()->renderer()).updateCancelButtonVisibility(); // If the incremental attribute is set, then dispatch the search event if (searchEventsShouldBeDispatched()) startSearchEventTimer(); @@ -198,7 +208,8 @@ bool SearchInputType::sizeShouldIncludeDecoration(int, int& preferredSize) const { - preferredSize = element().size(); + ASSERT(element()); + preferredSize = element()->size(); return true; } diff -Nru webkit2gtk-2.20.3/Source/WebCore/html/SubmitInputType.cpp webkit2gtk-2.20.5/Source/WebCore/html/SubmitInputType.cpp --- webkit2gtk-2.20.3/Source/WebCore/html/SubmitInputType.cpp 2018-02-19 07:45:32.000000000 +0000 +++ webkit2gtk-2.20.5/Source/WebCore/html/SubmitInputType.cpp 2018-07-31 07:02:08.000000000 +0000 @@ -48,9 +48,10 @@ bool SubmitInputType::appendFormData(DOMFormData& formData, bool) const { - if (!element().isActivatedSubmit()) + ASSERT(element()); + if (!element()->isActivatedSubmit()) return false; - formData.append(element().name(), element().valueWithDefault()); + formData.append(element()->name(), element()->valueWithDefault()); return true; } @@ -61,12 +62,21 @@ void SubmitInputType::handleDOMActivateEvent(Event& event) { - Ref element(this->element()); - if (element->isDisabledFormControl() || !element->form()) + ASSERT(element()); + Ref protectedElement(*element()); + if (protectedElement->isDisabledFormControl() || !protectedElement->form()) return; - element->setActivatedSubmit(true); - element->form()->prepareForSubmission(event); // Event handlers can run. - element->setActivatedSubmit(false); + + Ref protectedForm(*protectedElement->form()); + + // Update layout before processing form actions in case the style changes + // the Form or button relationships. + protectedElement->document().updateLayoutIgnorePendingStylesheets(); + + protectedElement->setActivatedSubmit(true); + if (auto currentForm = protectedElement->form()) + currentForm->prepareForSubmission(event); // Event handlers can run. + protectedElement->setActivatedSubmit(false); event.setDefaultHandled(); } diff -Nru webkit2gtk-2.20.3/Source/WebCore/html/TextFieldInputType.cpp webkit2gtk-2.20.5/Source/WebCore/html/TextFieldInputType.cpp --- webkit2gtk-2.20.3/Source/WebCore/html/TextFieldInputType.cpp 2018-02-19 07:45:32.000000000 +0000 +++ webkit2gtk-2.20.5/Source/WebCore/html/TextFieldInputType.cpp 2018-07-31 07:18:06.000000000 +0000 @@ -75,16 +75,18 @@ bool TextFieldInputType::isKeyboardFocusable(KeyboardEvent&) const { + ASSERT(element()); #if PLATFORM(IOS) - if (element().isReadOnly()) + if (element()->isReadOnly()) return false; #endif - return element().isTextFormControlFocusable(); + return element()->isTextFormControlFocusable(); } bool TextFieldInputType::isMouseFocusable() const { - return element().isTextFormControlFocusable(); + ASSERT(element()); + return element()->isTextFormControlFocusable(); } bool TextFieldInputType::isTextField() const @@ -106,14 +108,17 @@ bool TextFieldInputType::valueMissing(const String& value) const { - return element().isRequired() && value.isEmpty(); + ASSERT(element()); + return element()->isRequired() && value.isEmpty(); } void TextFieldInputType::setValue(const String& sanitizedValue, bool valueChanged, TextFieldEventBehavior eventBehavior) { + ASSERT(element()); + // Grab this input element to keep reference even if JS event handler // changes input type. - Ref input(element()); + Ref input(*element()); // We don't ask InputType::setValue to dispatch events because // TextFieldInputType dispatches events different way from InputType. @@ -158,17 +163,19 @@ void TextFieldInputType::handleKeydownEvent(KeyboardEvent& event) { - if (!element().focused()) + ASSERT(element()); + if (!element()->focused()) return; - RefPtr frame = element().document().frame(); - if (!frame || !frame->editor().doTextFieldCommandFromEvent(&element(), &event)) + RefPtr frame = element()->document().frame(); + if (!frame || !frame->editor().doTextFieldCommandFromEvent(element(), &event)) return; event.setDefaultHandled(); } void TextFieldInputType::handleKeydownEventForSpinButton(KeyboardEvent& event) { - if (element().isDisabledOrReadOnly()) + ASSERT(element()); + if (element()->isDisabledOrReadOnly()) return; const String& key = event.keyIdentifier(); if (key == "Up") @@ -192,13 +199,16 @@ bool isBlurEvent = event.type() == eventNames().blurEvent; if (isFocusEvent || isBlurEvent) capsLockStateMayHaveChanged(); - if (event.isMouseEvent() || isFocusEvent || isBlurEvent) - element().forwardEvent(event); + if (event.isMouseEvent() || isFocusEvent || isBlurEvent) { + ASSERT(element()); + element()->forwardEvent(event); + } } void TextFieldInputType::elementDidBlur() { - auto* renderer = element().renderer(); + ASSERT(element()); + auto* renderer = element()->renderer(); if (!renderer) return; @@ -217,15 +227,17 @@ void TextFieldInputType::handleFocusEvent(Node* oldFocusedNode, FocusDirection) { - ASSERT_UNUSED(oldFocusedNode, oldFocusedNode != &element()); - if (RefPtr frame = element().document().frame()) - frame->editor().textFieldDidBeginEditing(&element()); + ASSERT(element()); + ASSERT_UNUSED(oldFocusedNode, oldFocusedNode != element()); + if (RefPtr frame = element()->document().frame()) + frame->editor().textFieldDidBeginEditing(element()); } void TextFieldInputType::handleBlurEvent() { InputType::handleBlurEvent(); - element().endEditing(); + ASSERT(element()); + element()->endEditing(); } bool TextFieldInputType::shouldSubmitImplicitly(Event& event) @@ -236,7 +248,8 @@ RenderPtr TextFieldInputType::createInputRenderer(RenderStyle&& style) { - return createRenderer(element(), WTFMove(style)); + ASSERT(element()); + return createRenderer(*element(), WTFMove(style)); } bool TextFieldInputType::needsContainer() const @@ -246,17 +259,20 @@ bool TextFieldInputType::shouldHaveSpinButton() const { - return RenderTheme::singleton().shouldHaveSpinButton(element()); + ASSERT(element()); + return RenderTheme::singleton().shouldHaveSpinButton(*element()); } bool TextFieldInputType::shouldHaveCapsLockIndicator() const { - return RenderTheme::singleton().shouldHaveCapsLockIndicator(element()); + ASSERT(element()); + return RenderTheme::singleton().shouldHaveCapsLockIndicator(*element()); } void TextFieldInputType::createShadowSubtree() { - ASSERT(element().shadowRoot()); + ASSERT(element()); + ASSERT(element()->shadowRoot()); ASSERT(!m_innerText); ASSERT(!m_innerBlock); @@ -264,7 +280,7 @@ ASSERT(!m_capsLockIndicator); ASSERT(!m_autoFillButton); - Document& document = element().document(); + Document& document = element()->document(); bool shouldHaveSpinButton = this->shouldHaveSpinButton(); bool shouldHaveCapsLockIndicator = this->shouldHaveCapsLockIndicator(); bool createsContainer = shouldHaveSpinButton || shouldHaveCapsLockIndicator || needsContainer(); @@ -272,7 +288,7 @@ m_innerText = TextControlInnerTextElement::create(document); if (!createsContainer) { - element().userAgentShadowRoot()->appendChild(*m_innerText); + element()->userAgentShadowRoot()->appendChild(*m_innerText); updatePlaceholderText(); return; } @@ -350,8 +366,10 @@ void TextFieldInputType::attributeChanged(const QualifiedName& attributeName) { - if (attributeName == valueAttr || attributeName == placeholderAttr) - updateInnerTextValue(); + if (attributeName == valueAttr || attributeName == placeholderAttr) { + if (element()) + updateInnerTextValue(); + } } void TextFieldInputType::disabledAttributeChanged() @@ -474,12 +492,13 @@ void TextFieldInputType::handleBeforeTextInsertedEvent(BeforeTextInsertedEvent& event) { + ASSERT(element()); // Make sure that the text to be inserted will not violate the maxLength. // We use RenderTextControlSingleLine::text() instead of InputElement::value() // because they can be mismatched by sanitizeValue() in // HTMLInputElement::subtreeHasChanged() in some cases. - String innerText = element().innerTextValue(); + String innerText = element()->innerTextValue(); unsigned oldLength = numGraphemeClusters(innerText); // selectionLength represents the selection length of this text field to be @@ -488,18 +507,18 @@ // selection length. The selection is the source of text drag-and-drop in // that case, and nothing in the text field will be removed. unsigned selectionLength = 0; - if (element().focused()) { - ASSERT(enclosingTextFormControl(element().document().frame()->selection().selection().start()) == &element()); - int selectionStart = element().selectionStart(); - ASSERT(selectionStart <= element().selectionEnd()); - int selectionCodeUnitCount = element().selectionEnd() - selectionStart; + if (element()->focused()) { + ASSERT(enclosingTextFormControl(element()->document().frame()->selection().selection().start()) == element()); + int selectionStart = element()->selectionStart(); + ASSERT(selectionStart <= element()->selectionEnd()); + int selectionCodeUnitCount = element()->selectionEnd() - selectionStart; selectionLength = selectionCodeUnitCount ? numGraphemeClusters(StringView(innerText).substring(selectionStart, selectionCodeUnitCount)) : 0; } ASSERT(oldLength >= selectionLength); // Selected characters will be removed by the next text event. unsigned baseLength = oldLength - selectionLength; - unsigned maxLength = isTextType() ? element().effectiveMaxLength() : HTMLInputElement::maxEffectiveLength; + unsigned maxLength = isTextType() ? element()->effectiveMaxLength() : HTMLInputElement::maxEffectiveLength; unsigned appendableLength = maxLength > baseLength ? maxLength - baseLength : 0; // Truncate the inserted text to avoid violating the maxLength and other constraints. @@ -523,7 +542,8 @@ { if (!supportsPlaceholder()) return; - String placeholderText = element().strippedPlaceholder(); + ASSERT(element()); + String placeholderText = element()->strippedPlaceholder(); if (placeholderText.isEmpty()) { if (m_placeholder) { m_placeholder->parentNode()->removeChild(*m_placeholder); @@ -532,8 +552,8 @@ return; } if (!m_placeholder) { - m_placeholder = TextControlPlaceholderElement::create(element().document()); - element().userAgentShadowRoot()->insertBefore(*m_placeholder, m_container ? m_container.get() : innerTextElement().get()); + m_placeholder = TextControlPlaceholderElement::create(element()->document()); + element()->userAgentShadowRoot()->insertBefore(*m_placeholder, m_container ? m_container.get() : innerTextElement().get()); } m_placeholder->setInnerText(placeholderText); } @@ -541,9 +561,10 @@ bool TextFieldInputType::appendFormData(DOMFormData& formData, bool multipart) const { InputType::appendFormData(formData, multipart); - auto& dirnameAttrValue = element().attributeWithoutSynchronization(dirnameAttr); + ASSERT(element()); + auto& dirnameAttrValue = element()->attributeWithoutSynchronization(dirnameAttr); if (!dirnameAttrValue.isNull()) - formData.append(dirnameAttrValue, element().directionForFormData()); + formData.append(dirnameAttrValue, element()->directionForFormData()); return true; } @@ -554,7 +575,8 @@ void TextFieldInputType::subtreeHasChanged() { - element().setChangedSinceLastFormControlChangeEvent(true); + ASSERT(element()); + element()->setChangedSinceLastFormControlChangeEvent(true); // We don't need to call sanitizeUserInputValue() function here because // HTMLInputElement::handleBeforeTextInsertedEvent() has already called @@ -566,23 +588,24 @@ // user input in order to retain parity between what's in the model and // what's on the screen. Otherwise, we retain the sanitization process for // backward compatibility. https://bugs.webkit.org/show_bug.cgi?id=150346 - String innerText = convertFromVisibleValue(element().innerTextValue()); + String innerText = convertFromVisibleValue(element()->innerTextValue()); if (!supportsSelectionAPI()) innerText = sanitizeValue(innerText); - element().setValueFromRenderer(innerText); - element().updatePlaceholderVisibility(); + element()->setValueFromRenderer(innerText); + element()->updatePlaceholderVisibility(); // Recalc for :invalid change. - element().invalidateStyleForSubtree(); + element()->invalidateStyleForSubtree(); didSetValueByUserEdit(); } void TextFieldInputType::didSetValueByUserEdit() { - if (!element().focused()) + ASSERT(element()); + if (!element()->focused()) return; - if (RefPtr frame = element().document().frame()) - frame->editor().textDidChangeInTextField(&element()); + if (RefPtr frame = element()->document().frame()) + frame->editor().textDidChangeInTextField(element()); } void TextFieldInputType::spinButtonStepDown() @@ -597,40 +620,45 @@ void TextFieldInputType::updateInnerTextValue() { - if (!element().formControlValueMatchesRenderer()) { + ASSERT(element()); + if (!element()->formControlValueMatchesRenderer()) { // Update the renderer value if the formControlValueMatchesRenderer() flag is false. // It protects an unacceptable renderer value from being overwritten with the DOM value. - element().setInnerTextValue(visibleValue()); - element().updatePlaceholderVisibility(); + element()->setInnerTextValue(visibleValue()); + element()->updatePlaceholderVisibility(); } } void TextFieldInputType::focusAndSelectSpinButtonOwner() { - Ref input(element()); + ASSERT(element()); + Ref input(*element()); input->focus(); input->select(); } bool TextFieldInputType::shouldSpinButtonRespondToMouseEvents() { - return !element().isDisabledOrReadOnly(); + ASSERT(element()); + return !element()->isDisabledOrReadOnly(); } bool TextFieldInputType::shouldSpinButtonRespondToWheelEvents() { - return shouldSpinButtonRespondToMouseEvents() && element().focused(); + ASSERT(element()); + return shouldSpinButtonRespondToMouseEvents() && element()->focused(); } bool TextFieldInputType::shouldDrawCapsLockIndicator() const { - if (element().document().focusedElement() != &element()) + ASSERT(element()); + if (element()->document().focusedElement() != element()) return false; - if (element().isDisabledOrReadOnly()) + if (element()->isDisabledOrReadOnly()) return false; - RefPtr frame = element().document().frame(); + RefPtr frame = element()->document().frame(); if (!frame) return false; @@ -651,30 +679,33 @@ bool TextFieldInputType::shouldDrawAutoFillButton() const { - return !element().isDisabledOrReadOnly() && element().autoFillButtonType() != AutoFillButtonType::None; + ASSERT(element()); + return !element()->isDisabledOrReadOnly() && element()->autoFillButtonType() != AutoFillButtonType::None; } void TextFieldInputType::autoFillButtonElementWasClicked() { - Page* page = element().document().page(); + ASSERT(element()); + Page* page = element()->document().page(); if (!page) return; - page->chrome().client().handleAutoFillButtonClick(element()); + page->chrome().client().handleAutoFillButtonClick(*element()); } void TextFieldInputType::createContainer() { ASSERT(!m_container); + ASSERT(element()); - m_container = TextControlInnerContainer::create(element().document()); + m_container = TextControlInnerContainer::create(element()->document()); m_container->setPseudo(AtomicString("-webkit-textfield-decoration-container", AtomicString::ConstructFromLiteral)); - m_innerBlock = TextControlInnerElement::create(element().document()); + m_innerBlock = TextControlInnerElement::create(element()->document()); m_innerBlock->appendChild(*m_innerText); m_container->appendChild(*m_innerBlock); - element().userAgentShadowRoot()->appendChild(*m_container); + element()->userAgentShadowRoot()->appendChild(*m_container); } void TextFieldInputType::createAutoFillButton(AutoFillButtonType autoFillButtonType) @@ -684,7 +715,8 @@ if (autoFillButtonType == AutoFillButtonType::None) return; - m_autoFillButton = AutoFillButtonElement::create(element().document(), *this); + ASSERT(element()); + m_autoFillButton = AutoFillButtonElement::create(element()->document(), *this); m_autoFillButton->setPseudo(autoFillButtonTypeToAutoFillButtonPseudoClassName(autoFillButtonType)); m_autoFillButton->setAttributeWithoutSynchronization(roleAttr, AtomicString("button", AtomicString::ConstructFromLiteral)); m_autoFillButton->setAttributeWithoutSynchronization(aria_labelAttr, autoFillButtonTypeToAccessibilityLabel(autoFillButtonType)); @@ -698,7 +730,8 @@ if (!m_container) createContainer(); - AutoFillButtonType autoFillButtonType = element().autoFillButtonType(); + ASSERT(element()); + AutoFillButtonType autoFillButtonType = element()->autoFillButtonType(); if (!m_autoFillButton) createAutoFillButton(autoFillButtonType); diff -Nru webkit2gtk-2.20.3/Source/WebCore/html/URLInputType.cpp webkit2gtk-2.20.5/Source/WebCore/html/URLInputType.cpp --- webkit2gtk-2.20.3/Source/WebCore/html/URLInputType.cpp 2018-02-19 07:45:32.000000000 +0000 +++ webkit2gtk-2.20.5/Source/WebCore/html/URLInputType.cpp 2018-07-31 07:02:08.000000000 +0000 @@ -1,5 +1,6 @@ /* * Copyright (C) 2010 Google Inc. All rights reserved. + * Copyright (C) 2018 Apple Inc. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are @@ -51,7 +52,8 @@ bool URLInputType::typeMismatch() const { - return typeMismatchFor(element().value()); + ASSERT(element()); + return typeMismatchFor(element()->value()); } String URLInputType::typeMismatchText() const diff -Nru webkit2gtk-2.20.3/Source/WebCore/Modules/webaudio/AudioContext.cpp webkit2gtk-2.20.5/Source/WebCore/Modules/webaudio/AudioContext.cpp --- webkit2gtk-2.20.3/Source/WebCore/Modules/webaudio/AudioContext.cpp 2018-02-19 11:04:38.000000000 +0000 +++ webkit2gtk-2.20.5/Source/WebCore/Modules/webaudio/AudioContext.cpp 2018-07-31 07:46:52.000000000 +0000 @@ -393,6 +393,17 @@ } } +bool AudioContext::wouldTaintOrigin(const URL& url) const +{ + if (url.protocolIsData()) + return false; + + if (auto* document = this->document()) + return !document->securityOrigin().canRequest(url); + + return false; +} + ExceptionOr> AudioContext::createBuffer(unsigned numberOfChannels, size_t numberOfFrames, float sampleRate) { auto audioBuffer = AudioBuffer::create(numberOfChannels, numberOfFrames, sampleRate); diff -Nru webkit2gtk-2.20.3/Source/WebCore/Modules/webaudio/AudioContext.h webkit2gtk-2.20.5/Source/WebCore/Modules/webaudio/AudioContext.h --- webkit2gtk-2.20.3/Source/WebCore/Modules/webaudio/AudioContext.h 2018-02-19 11:04:38.000000000 +0000 +++ webkit2gtk-2.20.5/Source/WebCore/Modules/webaudio/AudioContext.h 2018-07-31 07:46:52.000000000 +0000 @@ -71,6 +71,7 @@ class PannerNode; class PeriodicWave; class ScriptProcessorNode; +class URL; class WaveShaperNode; // AudioContext is the cornerstone of the web audio API and all AudioNodes are created from it. @@ -118,6 +119,8 @@ enum class State { Suspended, Running, Interrupted, Closed }; State state() const; + bool wouldTaintOrigin(const URL&) const; + // The AudioNode create methods are called on the main thread (from JavaScript). Ref createBufferSource(); #if ENABLE(VIDEO) diff -Nru webkit2gtk-2.20.3/Source/WebCore/Modules/webaudio/MediaElementAudioSourceNode.cpp webkit2gtk-2.20.5/Source/WebCore/Modules/webaudio/MediaElementAudioSourceNode.cpp --- webkit2gtk-2.20.3/Source/WebCore/Modules/webaudio/MediaElementAudioSourceNode.cpp 2018-02-19 07:45:31.000000000 +0000 +++ webkit2gtk-2.20.5/Source/WebCore/Modules/webaudio/MediaElementAudioSourceNode.cpp 2018-07-31 07:49:11.000000000 +0000 @@ -67,6 +67,8 @@ void MediaElementAudioSourceNode::setFormat(size_t numberOfChannels, float sourceSampleRate) { + m_muted = wouldTaintOrigin(); + if (numberOfChannels != m_sourceNumberOfChannels || sourceSampleRate != m_sourceSampleRate) { if (!numberOfChannels || numberOfChannels > AudioContext::maxNumberOfChannels() || sourceSampleRate < minSampleRate || sourceSampleRate > maxSampleRate) { // process() will generate silence for these uninitialized values. @@ -100,11 +102,22 @@ } } +bool MediaElementAudioSourceNode::wouldTaintOrigin() +{ + if (!m_mediaElement->hasSingleSecurityOrigin()) + return true; + + if (m_mediaElement->player() && m_mediaElement->player()->didPassCORSAccessCheck()) + return false; + + return context().wouldTaintOrigin(m_mediaElement->currentSrc()); +} + void MediaElementAudioSourceNode::process(size_t numberOfFrames) { AudioBus* outputBus = output(0)->bus(); - if (!m_sourceNumberOfChannels || !m_sourceSampleRate) { + if (m_muted || !m_sourceNumberOfChannels || !m_sourceSampleRate) { outputBus->zero(); return; } diff -Nru webkit2gtk-2.20.3/Source/WebCore/Modules/webaudio/MediaElementAudioSourceNode.h webkit2gtk-2.20.5/Source/WebCore/Modules/webaudio/MediaElementAudioSourceNode.h --- webkit2gtk-2.20.3/Source/WebCore/Modules/webaudio/MediaElementAudioSourceNode.h 2018-02-19 07:45:31.000000000 +0000 +++ webkit2gtk-2.20.5/Source/WebCore/Modules/webaudio/MediaElementAudioSourceNode.h 2018-07-31 07:46:45.000000000 +0000 @@ -51,7 +51,7 @@ // AudioSourceProviderClient void setFormat(size_t numberOfChannels, float sampleRate) override; - + void lock(); void unlock(); @@ -64,11 +64,14 @@ // As an audio source, we will never propagate silence. bool propagatesSilence() const override { return false; } + bool wouldTaintOrigin(); + Ref m_mediaElement; Lock m_processMutex; unsigned m_sourceNumberOfChannels; double m_sourceSampleRate; + bool m_muted { false }; std::unique_ptr m_multiChannelResampler; }; diff -Nru webkit2gtk-2.20.3/Source/WebCore/platform/graphics/texmap/coordinated/CoordinatedGraphicsLayer.cpp webkit2gtk-2.20.5/Source/WebCore/platform/graphics/texmap/coordinated/CoordinatedGraphicsLayer.cpp --- webkit2gtk-2.20.3/Source/WebCore/platform/graphics/texmap/coordinated/CoordinatedGraphicsLayer.cpp 2018-05-07 09:13:02.000000000 +0000 +++ webkit2gtk-2.20.5/Source/WebCore/platform/graphics/texmap/coordinated/CoordinatedGraphicsLayer.cpp 2018-07-31 09:11:43.000000000 +0000 @@ -171,24 +171,28 @@ void CoordinatedGraphicsLayer::addChild(GraphicsLayer* layer) { GraphicsLayer::addChild(layer); + downcast(*layer).setCoordinatorIncludingSubLayersIfNeeded(m_coordinator); didChangeChildren(); } void CoordinatedGraphicsLayer::addChildAtIndex(GraphicsLayer* layer, int index) { GraphicsLayer::addChildAtIndex(layer, index); + downcast(*layer).setCoordinatorIncludingSubLayersIfNeeded(m_coordinator); didChangeChildren(); } void CoordinatedGraphicsLayer::addChildAbove(GraphicsLayer* layer, GraphicsLayer* sibling) { GraphicsLayer::addChildAbove(layer, sibling); + downcast(*layer).setCoordinatorIncludingSubLayersIfNeeded(m_coordinator); didChangeChildren(); } void CoordinatedGraphicsLayer::addChildBelow(GraphicsLayer* layer, GraphicsLayer* sibling) { GraphicsLayer::addChildBelow(layer, sibling); + downcast(*layer).setCoordinatorIncludingSubLayersIfNeeded(m_coordinator); didChangeChildren(); } @@ -197,6 +201,7 @@ bool ok = GraphicsLayer::replaceChild(oldChild, newChild); if (!ok) return false; + downcast(*newChild).setCoordinatorIncludingSubLayersIfNeeded(m_coordinator); didChangeChildren(); return true; } @@ -1017,6 +1022,33 @@ m_coordinator = coordinator; } +void CoordinatedGraphicsLayer::setCoordinatorIncludingSubLayersIfNeeded(CoordinatedGraphicsLayerClient* coordinator) +{ + if (m_coordinator == coordinator) + return; + + // If the coordinators are different it means that we are attaching a layer that was created by a different + // CompositingCoordinator than the current one. This happens because the layer was taken out of the tree + // and then added back after AC was disabled and enabled again. We need to set the new coordinator to the + // layer and its children. + // + // During each layer flush, the state stores the values that have changed since the previous one, and these + // are updated once in the scene. When adding CoordinatedGraphicsLayers back to the tree, the fields that + // are not updated during the next flush won't be sent to the scene, so they won't be updated there and the + // rendering will fail. + // + // For example the drawsContent flag. This is set when the layer is created and is not updated anymore (unless + // the content changes). When the layer is added back to the tree, the state won't reflect any change in the + // flag value, so the scene won't update it and the layer won't be rendered. + // + // We need to update here the layer changeMask so the scene gets all the current values. + m_layerState.changeMask = UINT_MAX; + + coordinator->attachLayer(this); + for (auto& child : children()) + downcast(*child).setCoordinatorIncludingSubLayersIfNeeded(coordinator); +} + void CoordinatedGraphicsLayer::setNeedsVisibleRectAdjustment() { if (shouldHaveBackingStore()) @@ -1108,8 +1140,7 @@ bool CoordinatedGraphicsLayer::shouldHaveBackingStore() const { - return drawsContent() && contentsAreVisible() && !m_size.isEmpty() - && (!!opacity() || m_animations.hasActiveAnimationsOfType(AnimatedPropertyOpacity)); + return drawsContent() && contentsAreVisible() && !m_size.isEmpty(); } bool CoordinatedGraphicsLayer::selfOrAncestorHasActiveTransformAnimation() const diff -Nru webkit2gtk-2.20.3/Source/WebCore/platform/graphics/texmap/coordinated/CoordinatedGraphicsLayer.h webkit2gtk-2.20.5/Source/WebCore/platform/graphics/texmap/coordinated/CoordinatedGraphicsLayer.h --- webkit2gtk-2.20.3/Source/WebCore/platform/graphics/texmap/coordinated/CoordinatedGraphicsLayer.h 2018-02-19 07:45:32.000000000 +0000 +++ webkit2gtk-2.20.5/Source/WebCore/platform/graphics/texmap/coordinated/CoordinatedGraphicsLayer.h 2018-07-31 09:22:15.000000000 +0000 @@ -52,6 +52,7 @@ virtual FloatRect visibleContentsRect() const = 0; virtual Ref createImageBackingIfNeeded(Image&) = 0; virtual void detachLayer(CoordinatedGraphicsLayer*) = 0; + virtual void attachLayer(CoordinatedGraphicsLayer*) = 0; virtual Ref getCoordinatedBuffer(const IntSize&, Nicosia::Buffer::Flags, uint32_t&, IntRect&) = 0; virtual Nicosia::PaintingEngine& paintingEngine() = 0; @@ -138,6 +139,7 @@ void removeTile(uint32_t tileID) override; void setCoordinator(CoordinatedGraphicsLayerClient*); + void setCoordinatorIncludingSubLayersIfNeeded(CoordinatedGraphicsLayerClient*); void setNeedsVisibleRectAdjustment(); void purgeBackingStores(); diff -Nru webkit2gtk-2.20.3/Source/WebCore/platform/graphics/texmap/TextureMapperLayer.h webkit2gtk-2.20.5/Source/WebCore/platform/graphics/texmap/TextureMapperLayer.h --- webkit2gtk-2.20.3/Source/WebCore/platform/graphics/texmap/TextureMapperLayer.h 2018-05-07 09:47:43.000000000 +0000 +++ webkit2gtk-2.20.5/Source/WebCore/platform/graphics/texmap/TextureMapperLayer.h 2018-07-31 05:57:41.000000000 +0000 @@ -117,7 +117,6 @@ void setRepaintCount(int); void setContentsLayer(TextureMapperPlatformLayer*); void setAnimations(const TextureMapperAnimations&); - const TextureMapperAnimations& animations() const { return m_animations; } void setFixedToViewport(bool); bool fixedToViewport() const { return m_fixedToViewport; } void setBackingStore(RefPtr&&); diff -Nru webkit2gtk-2.20.3/Source/WebCore/platform/ScrollView.h webkit2gtk-2.20.5/Source/WebCore/platform/ScrollView.h --- webkit2gtk-2.20.3/Source/WebCore/platform/ScrollView.h 2018-02-19 07:45:32.000000000 +0000 +++ webkit2gtk-2.20.5/Source/WebCore/platform/ScrollView.h 2018-07-31 07:24:32.000000000 +0000 @@ -1,5 +1,5 @@ /* - * Copyright (C) 2004-2017 Apple Inc. All rights reserved. + * Copyright (C) 2004-2018 Apple Inc. All rights reserved. * Copyright (C) 2009 Holger Hans Peter Freyther * * Redistribution and use in source and binary forms, with or without @@ -33,6 +33,7 @@ #include "ScrollTypes.h" #include "Widget.h" #include +#include #if PLATFORM(IOS) @@ -371,6 +372,8 @@ void setAllowsUnclampedScrollPositionForTesting(bool allowsUnclampedScrollPosition) { m_allowsUnclampedScrollPosition = allowsUnclampedScrollPosition; } bool allowsUnclampedScrollPosition() const { return m_allowsUnclampedScrollPosition; } + auto& weakPtrFactory() const { return m_weakPtrFactory; } + protected: ScrollView(); @@ -457,6 +460,8 @@ IntPoint m_panScrollIconPoint; + WeakPtrFactory m_weakPtrFactory; + bool m_horizontalScrollbarLock { false }; bool m_verticalScrollbarLock { false }; diff -Nru webkit2gtk-2.20.3/Source/WebCore/platform/Widget.cpp webkit2gtk-2.20.5/Source/WebCore/platform/Widget.cpp --- webkit2gtk-2.20.3/Source/WebCore/platform/Widget.cpp 2018-02-19 07:45:32.000000000 +0000 +++ webkit2gtk-2.20.5/Source/WebCore/platform/Widget.cpp 2018-07-31 07:24:32.000000000 +0000 @@ -1,5 +1,5 @@ /* - * Copyright (C) 2004, 2005, 2006, 2010 Apple Inc. All rights reserved. + * Copyright (C) 2004-2018 Apple Inc. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions @@ -34,7 +34,6 @@ void Widget::init(PlatformWidget widget) { - m_parent = 0; m_selfVisible = false; m_parentVisible = false; m_widget = widget; @@ -47,7 +46,7 @@ ASSERT(!view || !m_parent); if (!view || !view->isVisible()) setParentVisible(false); - m_parent = view; + m_parent = view ? makeWeakPtr(*view) : nullptr; if (view && view->isVisible()) setParentVisible(true); } diff -Nru webkit2gtk-2.20.3/Source/WebCore/platform/Widget.h webkit2gtk-2.20.5/Source/WebCore/platform/Widget.h --- webkit2gtk-2.20.3/Source/WebCore/platform/Widget.h 2018-02-19 07:45:32.000000000 +0000 +++ webkit2gtk-2.20.5/Source/WebCore/platform/Widget.h 2018-07-31 07:24:32.000000000 +0000 @@ -1,5 +1,5 @@ /* - * Copyright (C) 2004-2016 Apple Inc. All rights reserved. + * Copyright (C) 2004-2018 Apple Inc. All rights reserved. * Copyright (C) 2008 Collabora Ltd. All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -140,7 +140,7 @@ WEBCORE_EXPORT void removeFromParent(); WEBCORE_EXPORT virtual void setParent(ScrollView* view); - ScrollView* parent() const { return m_parent; } + ScrollView* parent() const { return m_parent.get(); } FrameView* root() const; virtual void handleEvent(Event&) { } @@ -204,7 +204,7 @@ static IntPoint convertFromContainingWindowToRoot(const Widget* rootWidget, const IntPoint&); private: - ScrollView* m_parent; + WeakPtr m_parent; #if !PLATFORM(COCOA) PlatformWidget m_widget; #else diff -Nru webkit2gtk-2.20.3/Source/WebKit/Shared/CoordinatedGraphics/CoordinatedGraphicsScene.cpp webkit2gtk-2.20.5/Source/WebKit/Shared/CoordinatedGraphics/CoordinatedGraphicsScene.cpp --- webkit2gtk-2.20.3/Source/WebKit/Shared/CoordinatedGraphics/CoordinatedGraphicsScene.cpp 2018-05-07 09:16:13.000000000 +0000 +++ webkit2gtk-2.20.5/Source/WebKit/Shared/CoordinatedGraphics/CoordinatedGraphicsScene.cpp 2018-07-31 05:57:41.000000000 +0000 @@ -61,8 +61,7 @@ static bool layerShouldHaveBackingStore(TextureMapperLayer* layer) { - return layer->drawsContent() && layer->contentsAreVisible() && !layer->size().isEmpty() - && (!!layer->opacity() || layer->animations().hasActiveAnimationsOfType(AnimatedPropertyOpacity)); + return layer->drawsContent() && layer->contentsAreVisible() && !layer->size().isEmpty(); } CoordinatedGraphicsScene::CoordinatedGraphicsScene(CoordinatedGraphicsSceneClient* client) diff -Nru webkit2gtk-2.20.3/Source/WebKit/UIProcess/gtk/WebInspectorProxyGtk.cpp webkit2gtk-2.20.5/Source/WebKit/UIProcess/gtk/WebInspectorProxyGtk.cpp --- webkit2gtk-2.20.3/Source/WebKit/UIProcess/gtk/WebInspectorProxyGtk.cpp 2018-03-12 09:09:01.000000000 +0000 +++ webkit2gtk-2.20.5/Source/WebKit/UIProcess/gtk/WebInspectorProxyGtk.cpp 2018-07-31 05:57:41.000000000 +0000 @@ -338,17 +338,17 @@ String WebInspectorProxy::inspectorPageURL() { - return String("resource:///org/webkitgtk/inspector/UserInterface/Main.html"); + return String("resource:///org/webkit/inspector/UserInterface/Main.html"); } String WebInspectorProxy::inspectorTestPageURL() { - return String("resource:///org/webkitgtk/inspector/UserInterface/Test.html"); + return String("resource:///org/webkit/inspector/UserInterface/Test.html"); } String WebInspectorProxy::inspectorBaseURL() { - return String("resource:///org/webkitgtk/inspector/UserInterface/"); + return String("resource:///org/webkit/inspector/UserInterface/"); } unsigned WebInspectorProxy::platformInspectedWindowHeight() diff -Nru webkit2gtk-2.20.3/Source/WebKit/WebProcess/WebPage/CoordinatedGraphics/CompositingCoordinator.cpp webkit2gtk-2.20.5/Source/WebKit/WebProcess/WebPage/CoordinatedGraphics/CompositingCoordinator.cpp --- webkit2gtk-2.20.3/Source/WebKit/WebProcess/WebPage/CoordinatedGraphics/CompositingCoordinator.cpp 2018-02-20 06:53:53.000000000 +0000 +++ webkit2gtk-2.20.5/Source/WebKit/WebProcess/WebPage/CoordinatedGraphics/CompositingCoordinator.cpp 2018-07-31 09:13:37.000000000 +0000 @@ -354,6 +354,15 @@ notifyFlushRequired(layer); } +void CompositingCoordinator::attachLayer(CoordinatedGraphicsLayer* layer) +{ + layer->setCoordinator(this); + m_registeredLayers.add(layer->id(), layer); + m_state.layersToCreate.append(layer->id()); + layer->setNeedsVisibleRectAdjustment(); + notifyFlushRequired(layer); +} + void CompositingCoordinator::commitScrollOffset(uint32_t layerID, const WebCore::IntSize& offset) { if (auto* layer = m_registeredLayers.get(layerID)) diff -Nru webkit2gtk-2.20.3/Source/WebKit/WebProcess/WebPage/CoordinatedGraphics/CompositingCoordinator.h webkit2gtk-2.20.5/Source/WebKit/WebProcess/WebPage/CoordinatedGraphics/CompositingCoordinator.h --- webkit2gtk-2.20.3/Source/WebKit/WebProcess/WebPage/CoordinatedGraphics/CompositingCoordinator.h 2018-02-19 07:45:33.000000000 +0000 +++ webkit2gtk-2.20.5/Source/WebKit/WebProcess/WebPage/CoordinatedGraphics/CompositingCoordinator.h 2018-07-31 09:22:39.000000000 +0000 @@ -117,6 +117,7 @@ WebCore::FloatRect visibleContentsRect() const override; Ref createImageBackingIfNeeded(WebCore::Image&) override; void detachLayer(WebCore::CoordinatedGraphicsLayer*) override; + void attachLayer(WebCore::CoordinatedGraphicsLayer*) override; Ref getCoordinatedBuffer(const WebCore::IntSize&, Nicosia::Buffer::Flags, uint32_t&, WebCore::IntRect&) override; Nicosia::PaintingEngine& paintingEngine() override; void syncLayerState(WebCore::CoordinatedLayerID, WebCore::CoordinatedGraphicsLayerState&) override; diff -Nru webkit2gtk-2.20.3/Source/WebKit/WebProcess/WebPage/gtk/WebInspectorUIGtk.cpp webkit2gtk-2.20.5/Source/WebKit/WebProcess/WebPage/gtk/WebInspectorUIGtk.cpp --- webkit2gtk-2.20.3/Source/WebKit/WebProcess/WebPage/gtk/WebInspectorUIGtk.cpp 2018-02-19 07:45:33.000000000 +0000 +++ webkit2gtk-2.20.5/Source/WebKit/WebProcess/WebPage/gtk/WebInspectorUIGtk.cpp 2018-07-31 05:57:41.000000000 +0000 @@ -41,12 +41,12 @@ String WebInspectorUI::localizedStringsURL() { - return String("resource:///org/webkitgtk/inspector/Localizations/en.lproj/localizedStrings.js"); + return String("resource:///org/webkit/inspector/Localizations/en.lproj/localizedStrings.js"); } String RemoteWebInspectorUI::localizedStringsURL() { - return String("resource:///org/webkitgtk/inspector/Localizations/en.lproj/localizedStrings.js"); + return String("resource:///org/webkit/inspector/Localizations/en.lproj/localizedStrings.js"); } } // namespace WebKit diff -Nru webkit2gtk-2.20.3/Source/WTF/wtf/Bag.h webkit2gtk-2.20.5/Source/WTF/wtf/Bag.h --- webkit2gtk-2.20.3/Source/WTF/wtf/Bag.h 2018-02-19 07:45:30.000000000 +0000 +++ webkit2gtk-2.20.5/Source/WTF/wtf/Bag.h 2018-07-31 08:51:37.000000000 +0000 @@ -138,13 +138,21 @@ result.m_node = unwrappedHead(); return result; } - - iterator end() { return iterator(); } + + const iterator begin() const + { + iterator result; + result.m_node = unwrappedHead(); + return result; + } + + + iterator end() const { return iterator(); } bool isEmpty() const { return !m_head; } private: - Node* unwrappedHead() { return PtrTraits::unwrap(m_head); } + Node* unwrappedHead() const { return PtrTraits::unwrap(m_head); } typename PtrTraits::StorageType m_head { nullptr }; }; diff -Nru webkit2gtk-2.20.3/Source/WTF/wtf/text/StringBuilderJSON.cpp webkit2gtk-2.20.5/Source/WTF/wtf/text/StringBuilderJSON.cpp --- webkit2gtk-2.20.3/Source/WTF/wtf/text/StringBuilderJSON.cpp 2018-04-09 12:38:17.000000000 +0000 +++ webkit2gtk-2.20.5/Source/WTF/wtf/text/StringBuilderJSON.cpp 2018-07-31 06:42:55.000000000 +0000 @@ -91,6 +91,10 @@ // https://bugs.webkit.org/show_bug.cgi?id=176086 allocationSize = std::max(allocationSize, roundUpToPowerOfTwo(allocationSize)); + // Allocating this much will definitely fail. + if (allocationSize >= 0x80000000) + return false; + if (is8Bit() && !string.is8Bit()) allocateBufferUpConvert(m_bufferCharacters8, allocationSize); else diff -Nru webkit2gtk-2.20.3/Tools/glib/generate-inspector-gresource-manifest.py webkit2gtk-2.20.5/Tools/glib/generate-inspector-gresource-manifest.py --- webkit2gtk-2.20.3/Tools/glib/generate-inspector-gresource-manifest.py 2018-02-19 07:45:33.000000000 +0000 +++ webkit2gtk-2.20.5/Tools/glib/generate-inspector-gresource-manifest.py 2018-07-31 05:57:41.000000000 +0000 @@ -67,7 +67,7 @@ args.output.write(\ """ - + """) for filename in get_filenames(args.input):