diff --git a/NetFrontBrowserNX_OSSCopyright.txt b/NetFrontBrowserNX_OSSCopyright.txt index dbc371dd8..9f915eaf5 100644 --- a/NetFrontBrowserNX_OSSCopyright.txt +++ b/NetFrontBrowserNX_OSSCopyright.txt @@ -1,3 +1,3 @@ OSS Copyright of NetFront Browser NX -Copyright (c) 2015-2017 ACCESS CO., LTD. All rights reserved. +Copyright (c) 2015-2018 ACCESS CO., LTD. All rights reserved. Some files in this package were modified by ACCESS CO., LTD. diff --git a/WKC/WebCore/platform/network/WKC/SocketStreamHandle.h b/WKC/WebCore/platform/network/WKC/SocketStreamHandle.h index 6f18c29fb..5f222370a 100644 --- a/WKC/WebCore/platform/network/WKC/SocketStreamHandle.h +++ b/WKC/WebCore/platform/network/WKC/SocketStreamHandle.h @@ -66,8 +66,6 @@ namespace WebCore { }; int socketState() const { return m_socketState; } - bool isConstructed() const { return m_constructed; } - protected: virtual int platformSend(const char* data, int length); virtual void platformClose(); @@ -89,8 +87,6 @@ namespace WebCore { void progressTimerFired(); private: - bool m_constructed; - bool m_needClosing; bool m_clientCallingFromTimer; diff --git a/WKC/WebCore/platform/network/WKC/SocketStreamHandleWKC.cpp b/WKC/WebCore/platform/network/WKC/SocketStreamHandleWKC.cpp index 2a92a6010..90fba0ab2 100644 --- a/WKC/WebCore/platform/network/WKC/SocketStreamHandleWKC.cpp +++ b/WKC/WebCore/platform/network/WKC/SocketStreamHandleWKC.cpp @@ -64,7 +64,6 @@ namespace WebCore { SocketStreamHandle::SocketStreamHandle(const URL& url, SocketStreamHandleClient* client, NetworkingContext& networkingContext) : SocketStreamHandleBase(url, client) - , m_constructed(false) , m_clientCallingFromTimer(false) , m_needClosing(false) , m_socketState(None) @@ -283,10 +282,8 @@ void SocketStreamHandle::construct(void) m_socketState = Initialized; - m_constructed = true; - construct_end: - if (m_constructed && m_socketState == Initialized) { + if (m_socketState==Initialized) { if (m_client) m_client->willOpenSocketStream(this); } @@ -328,7 +325,7 @@ SocketStreamHandle::progressTimerFired() _LOG(Network, "SocketStreamHandle %p progressTimerFired", this); - if (!m_constructed || m_socketState == None) { + if (m_socketState==None) { if (m_client) { m_client->didFailSocketStream(this, SocketStreamError(-1)); m_client->didCloseSocketStream(this); @@ -470,7 +467,7 @@ int SocketStreamHandle::platformSend(const char* data, int len) { _LOG(Network, "SocketStreamHandle %p platformSend(%p, %d), state=%d", this, data, len, m_state); - if (!m_constructed || Open != m_state || !m_handle || !m_multiHandle || m_socket < 0) { + if (Open != m_state || !m_handle || !m_multiHandle || m_socket < 0) { if (m_client) m_client->didFailSocketStream(this, SocketStreamError(-1)); return -1; @@ -537,7 +534,7 @@ void SocketStreamHandle::platformClose() { _LOG(Network, "SocketStreamHandle %p platformClose()", this); - if (!m_constructed || !m_handle || !m_multiHandle) { + if (!m_handle || !m_multiHandle) { return; } diff --git a/WKC/WebKit/WKC/helpers/privates/WKCNode.cpp b/WKC/WebKit/WKC/helpers/privates/WKCNode.cpp index 6731872ff..3f0bbcb09 100644 --- a/WKC/WebKit/WKC/helpers/privates/WKCNode.cpp +++ b/WKC/WebKit/WKC/helpers/privates/WKCNode.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2011-2017 ACCESS CO., LTD. All rights reserved. + * Copyright (c) 2011-2018 ACCESS CO., LTD. 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 @@ -476,8 +476,16 @@ NodePrivate::isScrollableOverFlowBlockNode() const void NodePrivate::getNodeCompositeRect(WKCRect* rect, int tx, int ty) { + WebCore::RenderObject* renderer = m_webcore->renderer(); + if (!renderer) + return; + + WebCore::RenderStyle& style = renderer->style(); + bool isOverflowXHidden = (style.overflowX() == WebCore::OHIDDEN); + bool isOverflowYHidden = (style.overflowY() == WebCore::OHIDDEN); + WebCore::LayoutRect core_rect = WebCore::LayoutRect(rect->fX, rect->fY, rect->fWidth, rect->fHeight); - m_webcore->getNodeCompositeRect(&core_rect, tx, ty); + m_webcore->getNodeCompositeRect(&core_rect, isOverflowXHidden, isOverflowYHidden, tx, ty); rect->fX = core_rect.x(); rect->fY = core_rect.y(); rect->fWidth = core_rect.width(); diff --git a/WKC/WebKit/WKC/webkit/WKCVersion.h b/WKC/WebKit/WKC/webkit/WKCVersion.h index 305d46dd2..5f9bc42b5 100644 --- a/WKC/WebKit/WKC/webkit/WKCVersion.h +++ b/WKC/WebKit/WKC/webkit/WKCVersion.h @@ -29,7 +29,7 @@ #define WKC_VERSION_CHECK(major, minor, micro) \ (((major)*10000) + ((minor)*100) + (micro)) >= ((WKC_VERSION_MAJOR*10000) + (WKC_VERSION_MINOR*100) + (WKC_VERSION_MICRO)) -#define WKC_CUSTOMER_RELEASE_VERSION "0.8.9" +#define WKC_CUSTOMER_RELEASE_VERSION "0.9.3" #define WKC_WEBKIT_VERSION "601.6" diff --git a/WKC/WebKit/WKC/webkit/WKCWebView.cpp b/WKC/WebKit/WKC/webkit/WKCWebView.cpp index edd9efca2..9abf39615 100644 --- a/WKC/WebKit/WKC/webkit/WKCWebView.cpp +++ b/WKC/WebKit/WKC/webkit/WKCWebView.cpp @@ -1748,6 +1748,15 @@ WKCWebView::notifyMouseMoveTest(const WKCPoint& pos, WKC::MouseButton button, Mo result = notifyMouseMove(pos, button, modifiers); + renderer = targetNode->renderer(); + + if (!renderer) { + // Since the renderer has been deleted, there is a possibility that the appearance of the content has changed, + // but in this case, we do not consider it to be a change for a mouse over menu. + contentChanged = false; + goto exit; + } + renderer->frame().document()->updateStyleIfNeeded(); renderer = targetNode->renderer(); diff --git a/WKC/include/wkccairorename.h b/WKC/include/wkccairorename.h index 84a0b95d1..48888d24f 100644 --- a/WKC/include/wkccairorename.h +++ b/WKC/include/wkccairorename.h @@ -327,14 +327,14 @@ #define _cairo_image_surface_unmap_image wkc__cairo_image_surface_unmap_image #define _cairo_image_traps_compositor_get wkc__cairo_image_traps_compositor_get #define _cairo_init wkc__cairo_init +#define _cairo_int_96by64_32x64_divrem wkc__cairo_int_96by64_32x64_divrem +#define _cairo_int_surface_create_in_error wkc__cairo_int_surface_create_in_error #define _cairo_int128_cmp wkc__cairo_int128_cmp #define _cairo_int128_divrem wkc__cairo_int128_divrem #define _cairo_int128_lt wkc__cairo_int128_lt #define _cairo_int32_to_int128 wkc__cairo_int32_to_int128 #define _cairo_int64_to_int128 wkc__cairo_int64_to_int128 #define _cairo_int64x64_128_mul wkc__cairo_int64x64_128_mul -#define _cairo_int_96by64_32x64_divrem wkc__cairo_int_96by64_32x64_divrem -#define _cairo_int_surface_create_in_error wkc__cairo_int_surface_create_in_error #define _cairo_intern_string wkc__cairo_intern_string #define _cairo_intern_string_mutex wkc__cairo_intern_string_mutex #define _cairo_intern_string_reset_static_data wkc__cairo_intern_string_reset_static_data @@ -673,10 +673,10 @@ #define _cairo_time_from_s wkc__cairo_time_from_s #define _cairo_time_get wkc__cairo_time_get #define _cairo_time_to_s wkc__cairo_time_to_s -#define _cairo_tor22_scan_converter_add_polygon wkc__cairo_tor22_scan_converter_add_polygon -#define _cairo_tor22_scan_converter_create wkc__cairo_tor22_scan_converter_create #define _cairo_tor_scan_converter_add_polygon wkc__cairo_tor_scan_converter_add_polygon #define _cairo_tor_scan_converter_create wkc__cairo_tor_scan_converter_create +#define _cairo_tor22_scan_converter_add_polygon wkc__cairo_tor22_scan_converter_add_polygon +#define _cairo_tor22_scan_converter_create wkc__cairo_tor22_scan_converter_create #define _cairo_toy_font_face_mutex wkc__cairo_toy_font_face_mutex #define _cairo_toy_font_face_reset_static_data wkc__cairo_toy_font_face_reset_static_data #define _cairo_trapezoid_array_translate_and_scale wkc__cairo_trapezoid_array_translate_and_scale @@ -709,6 +709,7 @@ #define _cairo_twin_outlines wkc__cairo_twin_outlines #define _cairo_ucs4_to_utf16 wkc__cairo_ucs4_to_utf16 #define _cairo_ucs4_to_utf8 wkc__cairo_ucs4_to_utf8 +#define _cairo_uint_96by64_32x64_divrem wkc__cairo_uint_96by64_32x64_divrem #define _cairo_uint128_add wkc__cairo_uint128_add #define _cairo_uint128_cmp wkc__cairo_uint128_cmp #define _cairo_uint128_divrem wkc__cairo_uint128_divrem @@ -724,7 +725,6 @@ #define _cairo_uint32_to_uint128 wkc__cairo_uint32_to_uint128 #define _cairo_uint64_to_uint128 wkc__cairo_uint64_to_uint128 #define _cairo_uint64x64_128_mul wkc__cairo_uint64x64_128_mul -#define _cairo_uint_96by64_32x64_divrem wkc__cairo_uint_96by64_32x64_divrem #define _cairo_unbounded_rectangle wkc__cairo_unbounded_rectangle #define _cairo_unscaled_font_destroy wkc__cairo_unscaled_font_destroy #define _cairo_unscaled_font_init wkc__cairo_unscaled_font_init @@ -738,7 +738,6 @@ #define _cairo_user_font_face_backend wkc__cairo_user_font_face_backend #define _cairo_utf8_get_char_validated wkc__cairo_utf8_get_char_validated #define _cairo_utf8_to_ucs4 wkc__cairo_utf8_to_ucs4 -#define _cairo_utf8_to_utf16 wkc__cairo_utf8_to_utf16 #define _cairo_validate_text_clusters wkc__cairo_validate_text_clusters #define _do_cairo_gstate_backend_to_user wkc__do_cairo_gstate_backend_to_user #define _do_cairo_gstate_backend_to_user_distance wkc__do_cairo_gstate_backend_to_user_distance @@ -960,8 +959,8 @@ #define cairo_rel_curve_to wkc_cairo_rel_curve_to #define cairo_rel_line_to wkc_cairo_rel_line_to #define cairo_rel_move_to wkc_cairo_rel_move_to -#define cairo_resetVariables wkc_cairo_resetVariables #define cairo_reset_clip wkc_cairo_reset_clip +#define cairo_resetVariables wkc_cairo_resetVariables #define cairo_restore wkc_cairo_restore #define cairo_rotate wkc_cairo_rotate #define cairo_save wkc_cairo_save diff --git a/src/NX-NXFP2-a32/rocrt.AssemblyOffset.h b/src/NX-NXFP2-a32/rocrt.AssemblyOffset.h index a51cbc170..1b0c9ba9f 100644 --- a/src/NX-NXFP2-a32/rocrt.AssemblyOffset.h +++ b/src/NX-NXFP2-a32/rocrt.AssemblyOffset.h @@ -22,4 +22,4 @@ // NOLINT(build/header_guard) #define NN_ROCRT_MODULE_HEADER_VERSION 0x30444f4d // NOLINT(readability/define) -#define NN_ROCRT_ROMODULE_SIZE 0x5c // NOLINT(readability/define) +#define NN_ROCRT_ROMODULE_SIZE 0x64 // NOLINT(readability/define) diff --git a/src/NX-NXFP2-a64/rocrt.AssemblyOffset.h b/src/NX-NXFP2-a64/rocrt.AssemblyOffset.h index 0649d672a..b67969d74 100644 --- a/src/NX-NXFP2-a64/rocrt.AssemblyOffset.h +++ b/src/NX-NXFP2-a64/rocrt.AssemblyOffset.h @@ -22,4 +22,4 @@ // NOLINT(build/header_guard) #define NN_ROCRT_MODULE_HEADER_VERSION 0x30444f4d // NOLINT(readability/define) -#define NN_ROCRT_ROMODULE_SIZE 0xb8 // NOLINT(readability/define) +#define NN_ROCRT_ROMODULE_SIZE 0xc8 // NOLINT(readability/define) diff --git a/webkit/JavaScriptCore/ChangeLog b/webkit/JavaScriptCore/ChangeLog index 0c6e0f973..41240ec6b 100644 --- a/webkit/JavaScriptCore/ChangeLog +++ b/webkit/JavaScriptCore/ChangeLog @@ -1,3 +1,390 @@ +2018-04-03 Jason Marcell + + Cherry-pick r230101. rdar://problem/39155394 + + Out-of-bounds accesses due to a missing check for MAX_STORAGE_VECTOR_LENGTH in unshiftCountForAnyIndexingType + https://bugs.webkit.org/show_bug.cgi?id=183657 + JSTests: + + Reviewed by Keith Miller. + + * stress/large-unshift-splice.js: Added. + (make_contig_arr): + + Source/JavaScriptCore: + + + + Reviewed by Keith Miller. + + There was just a missing check in unshiftCountForIndexingType. + I've also replaced 'return false' by 'return true' in the case of an 'out-of-memory' exception, because 'return false' means 'please continue to the slow path', + and the slow path has an assert that there is no unhandled exception (line 360 of ArrayPrototype.cpp). + Finally, I made the assert in ensureLength a release assert as it would have caught this bug and prevented it from being a security risk. + + * runtime/ArrayPrototype.cpp: + (JSC::unshift): + * runtime/JSArray.cpp: + (JSC::JSArray::unshiftCountWithAnyIndexingType): + * runtime/JSObject.h: + (JSC::JSObject::ensureLength): + + git-svn-id: https://svn.webkit.org/repository/webkit/trunk@230101 268f45cc-cd09-0410-ab3c-d52691b4dbfc + + 2018-03-30 Robin Morisset + + Out-of-bounds accesses due to a missing check for MAX_STORAGE_VECTOR_LENGTH in unshiftCountForAnyIndexingType + https://bugs.webkit.org/show_bug.cgi?id=183657 + + + Reviewed by Keith Miller. + + There was just a missing check in unshiftCountForIndexingType. + I've also replaced 'return false' by 'return true' in the case of an 'out-of-memory' exception, because 'return false' means 'please continue to the slow path', + and the slow path has an assert that there is no unhandled exception (line 360 of ArrayPrototype.cpp). + Finally, I made the assert in ensureLength a release assert as it would have caught this bug and prevented it from being a security risk. + + * runtime/ArrayPrototype.cpp: + (JSC::unshift): + * runtime/JSArray.cpp: + (JSC::JSArray::unshiftCountWithAnyIndexingType): + * runtime/JSObject.h: + (JSC::JSObject::ensureLength): + +2018-04-03 Jason Marcell + + Cherry-pick r229850. rdar://problem/39155286 + + Race Condition in arrayProtoFuncReverse() causes wrong results or crash + https://bugs.webkit.org/show_bug.cgi?id=183901 + + Reviewed by Keith Miller. + + JSTests: + + New test. + + * stress/array-reverse-doesnt-clobber.js: Added. + (testArrayReverse): + (createArrayOfArrays): + (createArrayStorage): + + Source/JavaScriptCore: + + Added write barriers to ensure the reversed contents are properly marked. + + * runtime/ArrayPrototype.cpp: + (JSC::arrayProtoFuncReverse): + + + git-svn-id: https://svn.webkit.org/repository/webkit/trunk@229850 268f45cc-cd09-0410-ab3c-d52691b4dbfc + + 2018-03-22 Michael Saboff + + Race Condition in arrayProtoFuncReverse() causes wrong results or crash + https://bugs.webkit.org/show_bug.cgi?id=183901 + + Reviewed by Keith Miller. + + Added write barriers to ensure the reversed contents are properly marked. + + * runtime/ArrayPrototype.cpp: + (JSC::arrayProtoFuncReverse): + +2017-10-26 Mark Lam + + JSRopeString::RopeBuilder::append() should check for overflows. + https://bugs.webkit.org/show_bug.cgi?id=178385 + + + Reviewed by Saam Barati. + + 1. Made RopeString check for overflow like the Checked class does. + 2. Added a missing overflow check in objectProtoFuncToString(). + + * runtime/JSString.cpp: + (JSC::JSRopeString::RopeBuilder::expand): + (JSC::JSRopeString::RopeBuilder::expand): Deleted. + * runtime/JSString.h: + * runtime/ObjectPrototype.cpp: + (JSC::objectProtoFuncToString): + * runtime/Operations.h: + (JSC::jsStringFromRegisterArray): + (JSC::jsStringFromArguments): + +2018-01-27 Yusuke Suzuki + + DFG strength reduction fails to convert NumberToStringWithValidRadixConstant for 0 to constant '0' + https://bugs.webkit.org/show_bug.cgi?id=182213 + + Reviewed by Mark Lam. + + toStringWithRadixInternal is originally used for the slow path if the given value is larger than radix or negative. + As a result, it does not accept 0 correctly, and produces an empty string. Since DFGStrengthReductionPhase uses + this function, it accidentally converts NumberToStringWithValidRadixConstant(0, radix) to an empty string. + This patch fixes toStringWithRadixInternal to accept 0. This change fixes twitch.tv's issue. + + We also add a careful cast to avoid `-INT32_MIN`. It does not produce incorrect value in x86 in practice, + but it is UB, and a compiler may assume that the given value is never INT32_MIN and could do an incorrect optimization. + + * runtime/NumberPrototype.cpp: + (JSC::toStringWithRadixInternal): + +2018-01-23 Jason Marcell + + Cherry-pick r227424. rdar://problem/36791625 + + 2018-01-23 Filip Pizlo + + JSC should use a speculation fence on VM entry/exit + https://bugs.webkit.org/show_bug.cgi?id=181991 + + Reviewed by JF Bastien and Mark Lam. + + This adds a WTF::speculationFence on VM entry and exit. + + For a microbenchmark that just calls a native function (supplied via an Objective-C block) in a + tight loop from JS is a 0% regression on x86 and a 11% regression on ARM64. + + * runtime/JSLock.cpp: + (JSC::JSLock::didAcquireLock): + (JSC::JSLock::willReleaseLock): + +2018-01-16 Jason Marcell + + Cherry-pick r226895. rdar://problem/36568085 + + 2018-01-12 Joseph Pecoraro + + Web Inspector: Remove unnecessary raw pointer in InspectorConsoleAgent + https://bugs.webkit.org/show_bug.cgi?id=181579 + + + Reviewed by Brian Burg. + + * inspector/agents/InspectorConsoleAgent.h: + * inspector/agents/InspectorConsoleAgent.cpp: + (Inspector::InspectorConsoleAgent::clearMessages): + (Inspector::InspectorConsoleAgent::addConsoleMessage): + Switch from a raw pointer to m_consoleMessages.last(). + Also move the expiration check into the if block since it can only + happen inside here when the number of console messages changes. + + (Inspector::InspectorConsoleAgent::discardValues): + Also clear the expired message count when messages are cleared. + +2018-01-12 Jason Marcell + + Cherry-pick r226840. rdar://problem/36479468 + + 2018-01-11 Michael Saboff + + REGRESSION(226788): AppStore Crashed @ JavaScriptCore: JSC::MacroAssemblerARM64::pushToSaveImmediateWithoutTouchingRegisters + https://bugs.webkit.org/show_bug.cgi?id=181570 + + Reviewed by Keith Miller. + + * assembler/MacroAssemblerARM64.h: + (JSC::MacroAssemblerARM64::abortWithReason): + Reverting these functions to use dataTempRegister and memoryTempRegister as they are + JIT release asserts that will crash the program. + + (JSC::MacroAssemblerARM64::pushToSaveImmediateWithoutTouchingRegisters): + Changed this so that it invalidates any cached dataTmpRegister contents if temp register + caching is enabled. + +2018-01-11 Jason Marcell + + Cherry-pick r226788. rdar://problem/36450828 + + 2018-01-11 Michael Saboff + + Ensure there are no unsafe uses of MacroAssemblerARM64::dataTempRegister + https://bugs.webkit.org/show_bug.cgi?id=181512 + + Reviewed by Saam Barati. + + * assembler/MacroAssemblerARM64.h: + (JSC::MacroAssemblerARM64::abortWithReason): + (JSC::MacroAssemblerARM64::pushToSaveImmediateWithoutTouchingRegisters): + All current uses of dataTempRegister in these functions are safe, but it makes sense to + fix them in case they might be used elsewhere. + +2018-01-11 Jason Marcell + + Cherry-pick r226767. rdar://problem/36450818 + + 2018-01-11 Saam Barati + + Our for-in caching is wrong when we add indexed properties on things in the prototype chain + https://bugs.webkit.org/show_bug.cgi?id=181508 + + Reviewed by Yusuke Suzuki. + + Our for-in caching would cache structure chains that had prototypes with + indexed properties. Clearly this is wrong. This caching breaks when a prototype + adds new indexed properties. We would continue to enumerate the old cached + state of properties, and not include the new indexed properties. + + The old code used to prevent caching only if the base structure had + indexed properties. This patch extends it to prevent caching if the + base, or any structure in the prototype chain, has indexed properties. + + * runtime/Structure.cpp: + (JSC::Structure::canCachePropertyNameEnumerator const): + +2018-01-11 Jason Marcell + + Cherry-pick r226650. rdar://problem/36429150 + + 2018-01-09 Mark Lam + + ASSERTION FAILED: pair.second->m_type & PropertyNode::Getter + https://bugs.webkit.org/show_bug.cgi?id=181388 + + + Reviewed by Saam Barati. + + When there are duplicate setters or getters, we may end up overwriting a getter + with a setter, or vice versa. This patch adds tracking for getters/setters that + have been overwritten with duplicates and ignore them. + + * bytecompiler/NodesCodegen.cpp: + (JSC::PropertyListNode::emitBytecode): + * parser/NodeConstructors.h: + (JSC::PropertyNode::PropertyNode): + * parser/Nodes.h: + (JSC::PropertyNode::isOverriddenByDuplicate const): + (JSC::PropertyNode::setIsOverriddenByDuplicate): + +2018-01-09 Jason Marcell + + Cherry-pick r226672. rdar://problem/36397330 + + 2018-01-09 Keith Miller + + and32 with an Address source on ARM64 did not invalidate dataTempRegister + https://bugs.webkit.org/show_bug.cgi?id=181467 + + Reviewed by Michael Saboff. + + * assembler/MacroAssemblerARM64.h: + (JSC::MacroAssemblerARM64::and32): + +2017-12-01 Saam Barati + + Having a bad time needs to handle ArrayClass indexing type as well + https://bugs.webkit.org/show_bug.cgi?id=180274 + + + Reviewed by Keith Miller and Mark Lam. + + We need to make sure to transition ArrayClass to SlowPutArrayStorage as well. + Otherwise, we'll end up with the wrong Structure, which will lead us to not + adhere to the spec. The bug was that we were not considering ArrayClass inside + hasBrokenIndexing. This patch rewrites that function to automatically opt + in non-empty indexing types as broken, instead of having to opt out all + non-empty indexing types besides SlowPutArrayStorage. + + * runtime/IndexingType.h: + (JSC::hasSlowPutArrayStorage): + (JSC::shouldUseSlowPut): + * runtime/JSGlobalObject.cpp: + * runtime/JSObject.cpp: + (JSC::JSObject::switchToSlowPutArrayStorage): + +2016-11-14 Mark Lam + + RegExpObject::exec/match should handle errors gracefully. + https://bugs.webkit.org/show_bug.cgi?id=155145 + + + Reviewed by Keith Miller. + + 1. Added some missing exception checks to RegExpObject::execInline() and + RegExpObject::matchInline(). + 2. Updated related code to work with ExceptionScope verification requirements. + + * dfg/DFGOperations.cpp: + * runtime/RegExpObjectInlines.h: + (JSC::RegExpObject::execInline): + (JSC::RegExpObject::matchInline): + * runtime/RegExpPrototype.cpp: + (JSC::regExpProtoFuncTestFast): + (JSC::regExpProtoFuncExec): + (JSC::regExpProtoFuncMatchFast): + +2016-03-07 Filip Pizlo + + RegExp.prototype.exec() should call into Yarr at most once + https://bugs.webkit.org/show_bug.cgi?id=155139 + + Reviewed by Saam Barati. + + For apparently no good reason, RegExp.prototype.match() was calling into Yarr twice, almost + as if it was hoping that the non-matching case was so common that it was best to have the + matching case do the work all over again. + + This is a 4% speed-up on Octane/regexp. It's also a matter of common sense: we should not be + in the business of presuming whether someone's match will succeed or fail. The increased + cost of running Yarr twice is so much larger than whatever savings we were getting from + running a match-only regexp that this is just not a good overall deal for the engine. + + Also, it's interesting that we are seeing a 4% speed-up on regexp despite the fact that a + majority (almost a supermajority, I think) of calls into RegExp.prototype.match() are failed + matches. So, this change is a 4% speed-up despite being a slow down on the common case. That + tells you just how bad the old behavior was on the uncommon case. + + * runtime/MatchResult.h: + (MatchResult::MatchResult): + (MatchResult::failed): + (MatchResult::operator bool): + * runtime/RegExpCachedResult.cpp: + (JSC::RegExpCachedResult::lastResult): + * runtime/RegExpConstructor.h: + (JSC::RegExpConstructor::setMultiline): + (JSC::RegExpConstructor::multiline): + (JSC::RegExpConstructor::performMatch): + (JSC::RegExpConstructor::recordMatch): + * runtime/RegExpMatchesArray.cpp: + (JSC::createRegExpMatchesArray): + (JSC::createEmptyRegExpMatchesArray): + (JSC::createStructureImpl): + * runtime/RegExpMatchesArray.h: + (JSC::createRegExpMatchesArray): + * runtime/RegExpObject.cpp: + (JSC::RegExpObject::put): + (JSC::getLastIndexAsUnsigned): + (JSC::RegExpObject::exec): + (JSC::RegExpObject::match): + * runtime/RegExpObject.h: + (JSC::RegExpObject::getLastIndex): + (JSC::RegExpObject::test): + * runtime/StringPrototype.cpp: + (JSC::stringProtoFuncMatch): + +2016-10-21 Caitlin Potter + + [JSC] don't crash when arguments to `new Function()` produce unexpected AST + https://bugs.webkit.org/show_bug.cgi?id=163748 + + Reviewed by Mark Lam. + + The ASSERT(statement); and ASSERT(funcDecl); lines are removed, replaced with blocks + to report a generic Parser error message. These lines are only possible to be reached + if the input string produced an unexpected AST, which previously could be used to crash + the process via ASSERT failure. + + The node type assertions are left in the tree, as it should be impossible for a top-level + `{` to produce anything other than a Block node. If the node turns out not to be a Block, + it indicates that the (C++) caller of this function (E.g in FunctionConstructor.cpp), is + doing something incorrect. Similarly, it should be impossible for the `funcDecl` node to + be anything other than a function declaration given the conventions of the caller of this + function. + + * runtime/CodeCache.cpp: + (JSC::CodeCache::getFunctionExecutableFromGlobalCode): + 2016-02-02 Caitlin Potter JSSymbolTableObject::deleteProperty() crashes deleting Symbols diff --git a/webkit/JavaScriptCore/assembler/MacroAssemblerARM64.h b/webkit/JavaScriptCore/assembler/MacroAssemblerARM64.h index d4fdc2206..542c9f842 100644 --- a/webkit/JavaScriptCore/assembler/MacroAssemblerARM64.h +++ b/webkit/JavaScriptCore/assembler/MacroAssemblerARM64.h @@ -335,7 +335,7 @@ class MacroAssemblerARM64 : public AbstractMacroAssembler @@ -474,11 +474,16 @@ RegisterID* PropertyListNode::emitBytecode(BytecodeGenerator& generator, Registe // Duplicates are possible. GetterSetterPair pair(node, static_cast(nullptr)); GetterSetterMap::AddResult result = map.add(node->name()->impl(), pair); + auto& resultPair = result.iterator->value; if (!result.isNewEntry) { - if (result.iterator->value.first->m_type == node->m_type) - result.iterator->value.first = node; - else - result.iterator->value.second = node; + if (resultPair.first->m_type == node->m_type) { + resultPair.first->setIsOverriddenByDuplicate(); + resultPair.first = node; + } else { + if (resultPair.second) + resultPair.second->setIsOverriddenByDuplicate(); + resultPair.second = node; + } } } @@ -514,7 +519,7 @@ RegisterID* PropertyListNode::emitBytecode(BytecodeGenerator& generator, Registe GetterSetterPair& pair = it->value; // Was this already generated as a part of its partner? - if (pair.second == node) + if (pair.second == node || node->isOverriddenByDuplicate()) continue; // Generate the paired node now. diff --git a/webkit/JavaScriptCore/inspector/agents/InspectorConsoleAgent.cpp b/webkit/JavaScriptCore/inspector/agents/InspectorConsoleAgent.cpp index a9c3c4bef..dc94feef5 100644 --- a/webkit/JavaScriptCore/inspector/agents/InspectorConsoleAgent.cpp +++ b/webkit/JavaScriptCore/inspector/agents/InspectorConsoleAgent.cpp @@ -46,7 +46,6 @@ static const int expireConsoleMessagesStep = 10; InspectorConsoleAgent::InspectorConsoleAgent(InjectedScriptManager* injectedScriptManager) : InspectorAgentBase(ASCIILiteral("Console")) , m_injectedScriptManager(injectedScriptManager) - , m_previousMessage(nullptr) , m_expiredConsoleMessageCount(0) , m_enabled(false) { @@ -74,6 +73,7 @@ void InspectorConsoleAgent::willDestroyFrontendAndBackend(DisconnectReason) void InspectorConsoleAgent::discardValues() { m_consoleMessages.clear(); + m_expiredConsoleMessageCount = 0; } void InspectorConsoleAgent::enable(ErrorString&) @@ -105,7 +105,6 @@ void InspectorConsoleAgent::clearMessages(ErrorString&) { m_consoleMessages.clear(); m_expiredConsoleMessageCount = 0; - m_previousMessage = nullptr; m_injectedScriptManager->releaseObjectGroup(ASCIILiteral("console")); @@ -209,20 +208,21 @@ void InspectorConsoleAgent::addConsoleMessage(std::unique_ptr co ASSERT(m_injectedScriptManager->inspectorEnvironment().developerExtrasEnabled()); ASSERT_ARG(consoleMessage, consoleMessage); - if (m_previousMessage && !isGroupMessage(m_previousMessage->type()) && m_previousMessage->isEqual(consoleMessage.get())) { - m_previousMessage->incrementCount(); + ConsoleMessage* previousMessage = m_consoleMessages.isEmpty() ? nullptr : m_consoleMessages.last().get(); + if (previousMessage && !isGroupMessage(previousMessage->type()) && previousMessage->isEqual(consoleMessage.get())) { + previousMessage->incrementCount(); if (m_frontendDispatcher && m_enabled) - m_previousMessage->updateRepeatCountInConsole(m_frontendDispatcher.get()); + previousMessage->updateRepeatCountInConsole(m_frontendDispatcher.get()); } else { - m_previousMessage = consoleMessage.get(); + ConsoleMessage* newMessage = consoleMessage.get(); m_consoleMessages.append(WTF::move(consoleMessage)); if (m_frontendDispatcher && m_enabled) - m_previousMessage->addToFrontend(m_frontendDispatcher.get(), m_injectedScriptManager, true); - } + newMessage->addToFrontend(m_frontendDispatcher.get(), m_injectedScriptManager, true); - if (!m_frontendDispatcher && m_consoleMessages.size() >= maximumConsoleMessages) { - m_expiredConsoleMessageCount += expireConsoleMessagesStep; - m_consoleMessages.remove(0, expireConsoleMessagesStep); + if (!m_frontendDispatcher && m_consoleMessages.size() >= maximumConsoleMessages) { + m_expiredConsoleMessageCount += expireConsoleMessagesStep; + m_consoleMessages.remove(0, expireConsoleMessagesStep); + } } } diff --git a/webkit/JavaScriptCore/inspector/agents/InspectorConsoleAgent.h b/webkit/JavaScriptCore/inspector/agents/InspectorConsoleAgent.h index b57590119..52c9c048f 100644 --- a/webkit/JavaScriptCore/inspector/agents/InspectorConsoleAgent.h +++ b/webkit/JavaScriptCore/inspector/agents/InspectorConsoleAgent.h @@ -84,7 +84,6 @@ class JS_EXPORT_PRIVATE InspectorConsoleAgent : public InspectorAgentBase, publi InjectedScriptManager* m_injectedScriptManager; std::unique_ptr m_frontendDispatcher; RefPtr m_backendDispatcher; - ConsoleMessage* m_previousMessage; Vector> m_consoleMessages; int m_expiredConsoleMessageCount; HashMap m_counts; diff --git a/webkit/JavaScriptCore/parser/NodeConstructors.h b/webkit/JavaScriptCore/parser/NodeConstructors.h index b497e3515..c68301eb8 100644 --- a/webkit/JavaScriptCore/parser/NodeConstructors.h +++ b/webkit/JavaScriptCore/parser/NodeConstructors.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2009, 2013 Apple Inc. All rights reserved. + * Copyright (C) 2009-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 @@ -223,6 +223,7 @@ namespace JSC { , m_type(type) , m_needsSuperBinding(superBinding == SuperBinding::Needed) , m_putType(putType) + , m_isOverriddenByDuplicate(false) { } @@ -233,6 +234,7 @@ namespace JSC { , m_type(type) , m_needsSuperBinding(false) , m_putType(putType) + , m_isOverriddenByDuplicate(false) { } diff --git a/webkit/JavaScriptCore/parser/Nodes.h b/webkit/JavaScriptCore/parser/Nodes.h index 79c1cae40..949fd8b3e 100644 --- a/webkit/JavaScriptCore/parser/Nodes.h +++ b/webkit/JavaScriptCore/parser/Nodes.h @@ -1,7 +1,7 @@ /* * Copyright (C) 1999-2000 Harri Porten (porten@kde.org) * Copyright (C) 2001 Peter Kelly (pmk@post.com) - * Copyright (C) 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2013, 2015 Apple Inc. All rights reserved. + * Copyright (C) 2003-2018 Apple Inc. All rights reserved. * Copyright (C) 2007 Cameron Zwarich (cwzwarich@uwaterloo.ca) * Copyright (C) 2007 Maks Orlovich * Copyright (C) 2007 Eric Seidel @@ -594,6 +594,8 @@ namespace JSC { Type type() const { return static_cast(m_type); } bool needsSuperBinding() const { return m_needsSuperBinding; } + bool isOverriddenByDuplicate() const { return m_isOverriddenByDuplicate; } + void setIsOverriddenByDuplicate() { m_isOverriddenByDuplicate = true; } PutType putType() const { return static_cast(m_putType); } private: @@ -604,6 +606,7 @@ namespace JSC { unsigned m_type : 5; unsigned m_needsSuperBinding : 1; unsigned m_putType : 1; + unsigned m_isOverriddenByDuplicate : 1; }; class PropertyListNode : public ExpressionNode { diff --git a/webkit/JavaScriptCore/runtime/ArrayPrototype.cpp b/webkit/JavaScriptCore/runtime/ArrayPrototype.cpp index 77c20bedb..33b13ebac 100644 --- a/webkit/JavaScriptCore/runtime/ArrayPrototype.cpp +++ b/webkit/JavaScriptCore/runtime/ArrayPrototype.cpp @@ -302,7 +302,7 @@ void unshift(ExecState* exec, JSObject* thisObj, unsigned header, unsigned curre RELEASE_ASSERT(currentCount <= (length - header)); // Guard against overflow. - if (count > (UINT_MAX - length)) { + if (count > UINT_MAX - length) { throwOutOfMemoryError(exec); return; } @@ -626,6 +626,8 @@ EncodedJSValue JSC_HOST_CALL arrayProtoFuncPush(ExecState* exec) EncodedJSValue JSC_HOST_CALL arrayProtoFuncReverse(ExecState* exec) { + VM& vm = exec->vm(); + JSObject* thisObject = exec->thisValue().toThis(exec, StrictMode).toObject(exec); unsigned length = getLength(exec, thisObject); @@ -642,6 +644,8 @@ EncodedJSValue JSC_HOST_CALL arrayProtoFuncReverse(ExecState* exec) if (containsHole(data, length) && holesMustForwardToPrototype(*exec, thisObject)) break; std::reverse(data, data + length); + if (!hasInt32(thisObject->indexingType())) + vm.heap.writeBarrier(thisObject); return JSValue::encode(thisObject); } case ALL_DOUBLE_INDEXING_TYPES: { @@ -662,6 +666,7 @@ EncodedJSValue JSC_HOST_CALL arrayProtoFuncReverse(ExecState* exec) break; auto data = storage.vector().data(); std::reverse(data, data + length); + vm.heap.writeBarrier(thisObject); return JSValue::encode(thisObject); } } diff --git a/webkit/JavaScriptCore/runtime/CodeCache.cpp b/webkit/JavaScriptCore/runtime/CodeCache.cpp index a4076111f..b64d22e3d 100644 --- a/webkit/JavaScriptCore/runtime/CodeCache.cpp +++ b/webkit/JavaScriptCore/runtime/CodeCache.cpp @@ -154,16 +154,20 @@ UnlinkedFunctionExecutable* CodeCache::getFunctionExecutableFromGlobalCode(VM& v // This function assumes an input string that would result in a single function declaration. StatementNode* statement = program->singleStatement(); - ASSERT(statement); + if (UNLIKELY(!statement)) { + JSToken token; + error = ParserError(ParserError::SyntaxError, ParserError::SyntaxErrorIrrecoverable, token, "Parser error", -1); + return nullptr; + } ASSERT(statement->isBlock()); - if (!statement || !statement->isBlock()) - return nullptr; StatementNode* funcDecl = static_cast(statement)->singleStatement(); - ASSERT(funcDecl); + if (UNLIKELY(!funcDecl)) { + JSToken token; + error = ParserError(ParserError::SyntaxError, ParserError::SyntaxErrorIrrecoverable, token, "Parser error", -1); + return nullptr; + } ASSERT(funcDecl->isFuncDeclNode()); - if (!funcDecl || !funcDecl->isFuncDeclNode()) - return nullptr; FunctionBodyNode* body = static_cast(funcDecl)->body(); ASSERT(body); diff --git a/webkit/JavaScriptCore/runtime/IndexingType.h b/webkit/JavaScriptCore/runtime/IndexingType.h index c7bcb118a..e98fabda0 100644 --- a/webkit/JavaScriptCore/runtime/IndexingType.h +++ b/webkit/JavaScriptCore/runtime/IndexingType.h @@ -147,11 +147,16 @@ static inline bool hasAnyArrayStorage(IndexingType indexingType) return static_cast(indexingType & IndexingShapeMask) >= ArrayStorageShape; } -static inline bool shouldUseSlowPut(IndexingType indexingType) +static inline bool hasSlowPutArrayStorage(IndexingType indexingType) { return (indexingType & IndexingShapeMask) == SlowPutArrayStorageShape; } +static inline bool shouldUseSlowPut(IndexingType indexingType) +{ + return hasSlowPutArrayStorage(indexingType); +} + inline IndexingType indexingTypeForValue(JSValue value) { if (value.isInt32()) diff --git a/webkit/JavaScriptCore/runtime/JSArray.cpp b/webkit/JavaScriptCore/runtime/JSArray.cpp index f0c328348..34e96b095 100644 --- a/webkit/JavaScriptCore/runtime/JSArray.cpp +++ b/webkit/JavaScriptCore/runtime/JSArray.cpp @@ -1026,9 +1026,12 @@ bool JSArray::unshiftCountWithAnyIndexingType(ExecState* exec, unsigned startInd if (oldLength - startIndex >= MIN_SPARSE_ARRAY_INDEX) return unshiftCountWithArrayStorage(exec, startIndex, count, ensureArrayStorage(exec->vm())); + if (oldLength + count > MAX_STORAGE_VECTOR_LENGTH) + return false; + if (!ensureLength(exec->vm(), oldLength + count)) { throwOutOfMemoryError(exec); - return false; + return true; } // We have to check for holes before we start moving things around so that we don't get halfway @@ -1061,9 +1064,12 @@ bool JSArray::unshiftCountWithAnyIndexingType(ExecState* exec, unsigned startInd if (oldLength - startIndex >= MIN_SPARSE_ARRAY_INDEX) return unshiftCountWithArrayStorage(exec, startIndex, count, ensureArrayStorage(exec->vm())); + if (oldLength + count > MAX_STORAGE_VECTOR_LENGTH) + return false; + if (!ensureLength(exec->vm(), oldLength + count)) { throwOutOfMemoryError(exec); - return false; + return true; } // We have to check for holes before we start moving things around so that we don't get halfway diff --git a/webkit/JavaScriptCore/runtime/JSGlobalObject.cpp b/webkit/JavaScriptCore/runtime/JSGlobalObject.cpp index 205804e96..acc9236aa 100644 --- a/webkit/JavaScriptCore/runtime/JSGlobalObject.cpp +++ b/webkit/JavaScriptCore/runtime/JSGlobalObject.cpp @@ -641,11 +641,8 @@ ObjectsWithBrokenIndexingFinder::ObjectsWithBrokenIndexingFinder( inline bool hasBrokenIndexing(JSObject* object) { - // This will change if we have more indexing types. IndexingType type = object->indexingType(); - // This could be made obviously more efficient, but isn't made so right now, because - // we expect this to be an unlikely slow path anyway. - return hasUndecided(type) || hasInt32(type) || hasDouble(type) || hasContiguous(type) || hasArrayStorage(type); + return type && !hasSlowPutArrayStorage(type); } inline void ObjectsWithBrokenIndexingFinder::visit(JSCell* cell) diff --git a/webkit/JavaScriptCore/runtime/JSLock.cpp b/webkit/JavaScriptCore/runtime/JSLock.cpp index 8c34c23a3..9bacdd0ee 100644 --- a/webkit/JavaScriptCore/runtime/JSLock.cpp +++ b/webkit/JavaScriptCore/runtime/JSLock.cpp @@ -142,6 +142,8 @@ void JSLock::lock(intptr_t lockCount) void JSLock::didAcquireLock() { + WTF::speculationFence(); + // FIXME: What should happen to the per-thread identifier table if we don't have a VM? if (!m_vm) return; @@ -188,6 +190,8 @@ void JSLock::unlock(intptr_t unlockCount) void JSLock::willReleaseLock() { + WTF::speculationFence(); + if (m_vm) { m_vm->heap.releaseDelayedReleasedObjects(); m_vm->setStackPointerAtVMEntry(nullptr); diff --git a/webkit/JavaScriptCore/runtime/JSObject.cpp b/webkit/JavaScriptCore/runtime/JSObject.cpp index ed07b56ea..2bd71cb1d 100644 --- a/webkit/JavaScriptCore/runtime/JSObject.cpp +++ b/webkit/JavaScriptCore/runtime/JSObject.cpp @@ -1151,6 +1151,14 @@ ArrayStorage* JSObject::ensureArrayStorageExistsAndEnterDictionaryIndexingMode(V void JSObject::switchToSlowPutArrayStorage(VM& vm) { switch (indexingType()) { + case ArrayClass: + ensureArrayStorage(vm); + RELEASE_ASSERT(hasAnyArrayStorage(indexingType())); + if (hasSlowPutArrayStorage(indexingType())) + return; + switchToSlowPutArrayStorage(vm); + break; + case ALL_UNDECIDED_INDEXING_TYPES: convertUndecidedToArrayStorage(vm, AllocateSlowPutArrayStorage); break; diff --git a/webkit/JavaScriptCore/runtime/JSObject.h b/webkit/JavaScriptCore/runtime/JSObject.h index ac7b13bea..97d0e3375 100644 --- a/webkit/JavaScriptCore/runtime/JSObject.h +++ b/webkit/JavaScriptCore/runtime/JSObject.h @@ -821,7 +821,7 @@ class JSObject : public JSCell { // the array is contiguous. bool WARN_UNUSED_RETURN ensureLength(VM& vm, unsigned length) { - ASSERT(length <= MAX_STORAGE_VECTOR_LENGTH); + RELEASE_ASSERT(length <= MAX_STORAGE_VECTOR_LENGTH); ASSERT(hasContiguous(indexingType()) || hasInt32(indexingType()) || hasDouble(indexingType()) || hasUndecided(indexingType())); if (m_butterfly.get()->vectorLength() < length) { diff --git a/webkit/JavaScriptCore/runtime/JSString.cpp b/webkit/JavaScriptCore/runtime/JSString.cpp index ae510a009..deca9dfbd 100644 --- a/webkit/JavaScriptCore/runtime/JSString.cpp +++ b/webkit/JavaScriptCore/runtime/JSString.cpp @@ -35,11 +35,12 @@ namespace JSC { const ClassInfo JSString::s_info = { "string", 0, 0, CREATE_METHOD_TABLE(JSString) }; -void JSRopeString::RopeBuilder::expand() +template<> +void JSRopeString::RopeBuilder::expand() { + RELEASE_ASSERT(!this->hasOverflowed()); ASSERT(m_index == JSRopeString::s_maxInternalRopeLength); JSString* jsString = m_jsString; - RELEASE_ASSERT(jsString); m_jsString = jsStringBuilder(&m_vm); m_index = 0; append(jsString); diff --git a/webkit/JavaScriptCore/runtime/JSString.h b/webkit/JavaScriptCore/runtime/JSString.h index c70e31bb5..08ec226c0 100644 --- a/webkit/JavaScriptCore/runtime/JSString.h +++ b/webkit/JavaScriptCore/runtime/JSString.h @@ -30,6 +30,7 @@ #include "PropertySlot.h" #include "Structure.h" #include +#include #include namespace JSC { @@ -242,7 +243,8 @@ class JSRopeString final : public JSString { friend JSRopeString* jsStringBuilder(VM*); public: - class RopeBuilder { + template + class RopeBuilder : public OverflowHandler { public: RopeBuilder(VM& vm) : m_vm(vm) @@ -253,10 +255,12 @@ class JSRopeString final : public JSString { bool append(JSString* jsString) { + if (UNLIKELY(this->hasOverflowed())) + return false; if (m_index == JSRopeString::s_maxInternalRopeLength) expand(); if (static_cast(m_jsString->length() + jsString->length()) < 0) { - m_jsString = nullptr; + this->overflowed(); return false; } m_jsString->append(m_vm, m_index++, jsString); @@ -265,13 +269,17 @@ class JSRopeString final : public JSString { JSRopeString* release() { - RELEASE_ASSERT(m_jsString); + RELEASE_ASSERT(!this->hasOverflowed()); JSRopeString* tmp = m_jsString; - m_jsString = 0; + m_jsString = nullptr; return tmp; } - unsigned length() const { return m_jsString->m_length; } + unsigned length() const + { + ASSERT(!this->hasOverflowed()); + return m_jsString->length(); + } private: void expand(); diff --git a/webkit/JavaScriptCore/runtime/MatchResult.h b/webkit/JavaScriptCore/runtime/MatchResult.h index d87c8516b..9689a5c18 100644 --- a/webkit/JavaScriptCore/runtime/MatchResult.h +++ b/webkit/JavaScriptCore/runtime/MatchResult.h @@ -28,7 +28,13 @@ typedef uint64_t EncodedMatchResult; -struct MatchResult { +struct MatchResult { + MatchResult() + : start(WTF::notFound) + , end(0) + { + } + ALWAYS_INLINE MatchResult(size_t start, size_t end) : start(start) , end(end) @@ -51,10 +57,10 @@ struct MatchResult { ALWAYS_INLINE static MatchResult failed() { - return MatchResult(WTF::notFound, 0); + return MatchResult(); } - ALWAYS_INLINE operator bool() + ALWAYS_INLINE explicit operator bool() const { return start != WTF::notFound; } diff --git a/webkit/JavaScriptCore/runtime/NumberPrototype.cpp b/webkit/JavaScriptCore/runtime/NumberPrototype.cpp index 65c6b6c25..56b3b5769 100644 --- a/webkit/JavaScriptCore/runtime/NumberPrototype.cpp +++ b/webkit/JavaScriptCore/runtime/NumberPrototype.cpp @@ -1,4 +1,4 @@ -/* +/* * Copyright (C) 1999-2000,2003 Harri Porten (porten@kde.org) * Copyright (C) 2007, 2008, 2011 Apple Inc. All rights reserved. * @@ -350,15 +350,17 @@ static String toStringWithRadix(int32_t number, unsigned radix) uint32_t positiveNumber = number; if (number < 0) { negative = true; - positiveNumber = -number; + positiveNumber = static_cast(-static_cast(number)); } - while (positiveNumber) { + // Always loop at least once, to emit at least '0'. + do { uint32_t index = positiveNumber % radix; ASSERT(index < sizeof(radixDigits)); *--p = static_cast(radixDigits[index]); positiveNumber /= radix; - } + } while (positiveNumber); + if (negative) *--p = '-'; diff --git a/webkit/JavaScriptCore/runtime/ObjectPrototype.cpp b/webkit/JavaScriptCore/runtime/ObjectPrototype.cpp index 0fe34ccff..305233526 100644 --- a/webkit/JavaScriptCore/runtime/ObjectPrototype.cpp +++ b/webkit/JavaScriptCore/runtime/ObjectPrototype.cpp @@ -246,10 +246,13 @@ EncodedJSValue JSC_HOST_CALL objectProtoFuncToString(ExecState* exec) JSValue stringTag = thisObject->get(exec, exec->propertyNames().toStringTagSymbol); if (stringTag.isString()) { - JSRopeString::RopeBuilder ropeBuilder(vm); + JSRopeString::RopeBuilder ropeBuilder(vm); ropeBuilder.append(vm.smallStrings.objectStringStart()); ropeBuilder.append(jsCast(stringTag)); ropeBuilder.append(vm.smallStrings.singleCharacterString(']')); + if(ropeBuilder.hasOverflowed()) + return JSValue::encode(throwOutOfMemoryError(exec)); + return JSValue::encode(ropeBuilder.release()); } diff --git a/webkit/JavaScriptCore/runtime/Operations.h b/webkit/JavaScriptCore/runtime/Operations.h index 057f59471..69c0cedf9 100644 --- a/webkit/JavaScriptCore/runtime/Operations.h +++ b/webkit/JavaScriptCore/runtime/Operations.h @@ -77,7 +77,7 @@ ALWAYS_INLINE JSValue jsString(ExecState* exec, const String& u1, const String& ALWAYS_INLINE JSValue jsStringFromRegisterArray(ExecState* exec, Register* strings, unsigned count) { VM* vm = &exec->vm(); - JSRopeString::RopeBuilder ropeBuilder(*vm); + JSRopeString::RopeBuilder ropeBuilder(*vm); for (unsigned i = 0; i < count; ++i) { JSValue v = strings[-static_cast(i)].jsValue(); @@ -91,7 +91,7 @@ ALWAYS_INLINE JSValue jsStringFromRegisterArray(ExecState* exec, Register* strin ALWAYS_INLINE JSValue jsStringFromArguments(ExecState* exec, JSValue thisValue) { VM* vm = &exec->vm(); - JSRopeString::RopeBuilder ropeBuilder(*vm); + JSRopeString::RopeBuilder ropeBuilder(*vm); ropeBuilder.append(thisValue.toString(exec)); for (unsigned i = 0; i < exec->argumentCount(); ++i) { diff --git a/webkit/JavaScriptCore/runtime/RegExpObject.cpp b/webkit/JavaScriptCore/runtime/RegExpObject.cpp index 7a31a57e1..065731346 100644 --- a/webkit/JavaScriptCore/runtime/RegExpObject.cpp +++ b/webkit/JavaScriptCore/runtime/RegExpObject.cpp @@ -173,6 +173,8 @@ MatchResult RegExpObject::match(ExecState* exec, JSString* string) RegExpConstructor* regExpConstructor = exec->lexicalGlobalObject()->regExpConstructor(); String input = string->value(exec); VM& vm = exec->vm(); + if (UNLIKELY(vm.exception())) + return MatchResult(); if (!regExp->global()) return regExpConstructor->performMatch(vm, regExp, string, input, 0); diff --git a/webkit/JavaScriptCore/runtime/RegExpObject.h b/webkit/JavaScriptCore/runtime/RegExpObject.h index a1f571d9f..7d38c4895 100644 --- a/webkit/JavaScriptCore/runtime/RegExpObject.h +++ b/webkit/JavaScriptCore/runtime/RegExpObject.h @@ -61,7 +61,7 @@ class RegExpObject : public JSNonFinalObject { return m_lastIndex.get(); } - bool test(ExecState* exec, JSString* string) { return match(exec, string); } + bool test(ExecState* exec, JSString* string) { return !!match(exec, string); } JSValue exec(ExecState*, JSString*); static bool getOwnPropertySlot(JSObject*, ExecState*, PropertyName, PropertySlot&); diff --git a/webkit/JavaScriptCore/runtime/StringPrototype.cpp b/webkit/JavaScriptCore/runtime/StringPrototype.cpp index 8c7796613..2dd4d8aba 100644 --- a/webkit/JavaScriptCore/runtime/StringPrototype.cpp +++ b/webkit/JavaScriptCore/runtime/StringPrototype.cpp @@ -745,7 +745,7 @@ EncodedJSValue JSC_HOST_CALL stringProtoFuncRepeat(ExecState* exec) return JSValue::encode(repeatCharacter(exec, character, repeatCount)); } - JSRopeString::RopeBuilder ropeBuilder(vm); + JSRopeString::RopeBuilder ropeBuilder(vm); for (unsigned i = 0; i < repeatCount; ++i) { if (!ropeBuilder.append(string)) return JSValue::encode(throwOutOfMemoryError(exec)); diff --git a/webkit/JavaScriptCore/runtime/Structure.cpp b/webkit/JavaScriptCore/runtime/Structure.cpp index 8363c961b..a05cff9d5 100644 --- a/webkit/JavaScriptCore/runtime/Structure.cpp +++ b/webkit/JavaScriptCore/runtime/Structure.cpp @@ -1250,13 +1250,17 @@ JSPropertyNameEnumerator* Structure::cachedPropertyNameEnumerator() const bool Structure::canCachePropertyNameEnumerator() const { - if (isDictionary()) - return false; - - if (hasIndexedProperties(indexingType())) - return false; + auto canCache = [](const Structure* structure) { + if (structure->isDictionary()) + return false; + if (hasIndexedProperties(structure->indexingType())) + return false; + if (structure->typeInfo().overridesGetPropertyNames()) + return false; + return true; + }; - if (typeInfo().overridesGetPropertyNames()) + if (!canCache(this)) return false; StructureChain* structureChain = m_cachedPrototypeChain.get(); @@ -1264,12 +1268,13 @@ bool Structure::canCachePropertyNameEnumerator() const WriteBarrier* structure = structureChain->head(); while (true) { if (!structure->get()) - break; - if (structure->get()->typeInfo().overridesGetPropertyNames()) + return true; + if (!canCache(structure->get())) return false; structure++; } + ASSERT_NOT_REACHED(); return true; } diff --git a/webkit/WTF/ChangeLog b/webkit/WTF/ChangeLog index b3d57107e..231d302a4 100644 --- a/webkit/WTF/ChangeLog +++ b/webkit/WTF/ChangeLog @@ -1,3 +1,48 @@ +2017-09-30 Antti Koivisto + + Add makeWeakPtr for easier WeakPtr construction + https://bugs.webkit.org/show_bug.cgi?id=177706 + + Reviewed by Sam Weinig. + + Standalone makeWeakPtr() returns a WeakPtr of the same type as the argument. + + For this to work the argument type needs to expose a (possibly base type) WeakPtrFactory + as a public weakPtrFactory() member function. + + * wtf/WeakPtr.h: + (WTF::WeakPtr::operator-> const): + (WTF::WeakPtr::operator* const): Also add operator*. + (WTF::makeWeakPtr): + +2017-10-26 Mark Lam + + JSRopeString::RopeBuilder::append() should check for overflows. + https://bugs.webkit.org/show_bug.cgi?id=178385 + + + Reviewed by Saam Barati. + + * wtf/CheckedArithmetic.h: + +2018-01-23 Jason Marcell + + Cherry-pick r227424. rdar://problem/36791625 + + 2018-01-23 Filip Pizlo + + JSC should use a speculation fence on VM entry/exit + https://bugs.webkit.org/show_bug.cgi?id=181991 + + Reviewed by JF Bastien and Mark Lam. + + Implement speculationFence as lfence on x86 and isb on ARM64. I'm not sure if isb is + appropriate for all ARM64's. + + * wtf/Atomics.h: + (WTF::speculationFence): + (WTF::x86_lfence): + 2017-10-09 Tim Horton Disable INPUT_TYPE_COLOR in FeatureDefines.h diff --git a/webkit/WTF/wtf/Atomics.h b/webkit/WTF/wtf/Atomics.h index b14395968..49e99cd08 100644 --- a/webkit/WTF/wtf/Atomics.h +++ b/webkit/WTF/wtf/Atomics.h @@ -279,9 +279,17 @@ inline void storeLoadFence() { armV7_dmb(); } inline void storeStoreFence() { armV7_dmb_st(); } inline void memoryBarrierAfterLock() { armV7_dmb(); } inline void memoryBarrierBeforeUnlock() { armV7_dmb(); } +inline void speculationFence() { armV7_dmb(); } #elif CPU(X86) || CPU(X86_64) +inline void x86_lfence() +{ +#if !OS(WINDOWS) && !OS(WINDOWS_WKC) + asm volatile("lfence" ::: "memory"); +#endif +} + inline void x86_mfence() { #if OS(WINDOWS) || OS(WINDOWS_WKC) @@ -301,6 +309,7 @@ inline void storeLoadFence() { x86_mfence(); } inline void storeStoreFence() { compilerFence(); } inline void memoryBarrierAfterLock() { compilerFence(); } inline void memoryBarrierBeforeUnlock() { compilerFence(); } +inline void speculationFence() { x86_lfence(); } #else @@ -310,6 +319,7 @@ inline void storeLoadFence() { compilerFence(); } inline void storeStoreFence() { compilerFence(); } inline void memoryBarrierAfterLock() { compilerFence(); } inline void memoryBarrierBeforeUnlock() { compilerFence(); } +inline void speculationFence() { } // Probably not strong enough. #endif diff --git a/webkit/WTF/wtf/CheckedArithmetic.h b/webkit/WTF/wtf/CheckedArithmetic.h index 6cc45b329..e6a05239a 100644 --- a/webkit/WTF/wtf/CheckedArithmetic.h +++ b/webkit/WTF/wtf/CheckedArithmetic.h @@ -789,7 +789,6 @@ template bool sumOverflows(Args... args) using WTF::Checked; using WTF::CheckedState; -using WTF::RecordOverflow; using WTF::CheckedInt8; using WTF::CheckedUint8; using WTF::CheckedInt16; @@ -799,6 +798,8 @@ using WTF::CheckedUint32; using WTF::CheckedInt64; using WTF::CheckedUint64; using WTF::CheckedSize; +using WTF::CrashOnOverflow; +using WTF::RecordOverflow; using WTF::checkedSum; using WTF::sumOverflows; diff --git a/webkit/WTF/wtf/WeakPtr.h b/webkit/WTF/wtf/WeakPtr.h index a947cc68c..edff379c1 100644 --- a/webkit/WTF/wtf/WeakPtr.h +++ b/webkit/WTF/wtf/WeakPtr.h @@ -101,7 +101,8 @@ class WeakPtr { WeakPtr& operator=(const WeakPtr& o) { m_ref = o.m_ref.copyRef(); return *this; } WeakPtr& operator=(std::nullptr_t) { m_ref = WeakReference::create(nullptr); return *this; } - T* operator->() const { return m_ref->get(); } + T* operator->() const { return get(); } + T& operator*() const { return *get(); } void clear() { m_ref = WeakReference::create(nullptr); } diff --git a/webkit/WebCore/ChangeLog b/webkit/WebCore/ChangeLog index 88a3b18fc..519df1f87 100644 --- a/webkit/WebCore/ChangeLog +++ b/webkit/WebCore/ChangeLog @@ -1,3 +1,736 @@ +2017-12-11 Zalan Bujtas + + FloatingObjects/FloatingObject classes should hold weak references to renderers + https://bugs.webkit.org/show_bug.cgi?id=180627 + + + Reviewed by Antti Koivisto. + + * rendering/FloatingObjects.cpp: + (WebCore::FloatingObject::FloatingObject): + (WebCore::ComputeFloatOffsetAdapter::ComputeFloatOffsetAdapter): + (WebCore::ComputeFloatOffsetForFloatLayoutAdapter::ComputeFloatOffsetForFloatLayoutAdapter): + (WebCore::ComputeFloatOffsetForLineLayoutAdapter::ComputeFloatOffsetForLineLayoutAdapter): + (WebCore::FindNextFloatLogicalBottomAdapter::FindNextFloatLogicalBottomAdapter): + (WebCore::FindNextFloatLogicalBottomAdapter::collectIfNeeded): + (WebCore::FloatingObjects::findNextFloatLogicalBottomBelow): + (WebCore::FloatingObjects::findNextFloatLogicalBottomBelowForBlock): + (WebCore::FloatingObjects::FloatingObjects): + (WebCore::FloatingObjects::clearLineBoxTreePointers): + (WebCore::FloatingObjects::logicalLeftOffsetForPositioningFloat): + (WebCore::FloatingObjects::logicalRightOffsetForPositioningFloat): + (WebCore::FloatingObjects::logicalLeftOffset): + (WebCore::FloatingObjects::logicalRightOffset): + (WebCore::ComputeFloatOffsetForFloatLayoutAdapter::updateOffsetIfNeeded): + (WebCore::ComputeFloatOffsetForFloatLayoutAdapter::updateOffsetIfNeeded): + (WebCore::ComputeFloatOffsetForFloatLayoutAdapter::heightRemaining const): + (WebCore::ComputeFloatOffsetAdapter::collectIfNeeded): + (WebCore::ComputeFloatOffsetForLineLayoutAdapter::updateOffsetIfNeeded): + (WebCore::ComputeFloatOffsetForLineLayoutAdapter::updateOffsetIfNeeded): + * rendering/FloatingObjects.h: + (WebCore::FloatingObject::renderer const): + (WebCore::FloatingObjects::renderer const): + +2018-03-09 Nan Wang + + AX: AOM: More accessibility events support + https://bugs.webkit.org/show_bug.cgi?id=183023 + + + Reviewed by Chris Fleizach. + + The test is crashing when we call updateBackingStore when + the AXObjectCache object is gone. Added a check to fix that. + + Modified the test by using the right format of setTimeout and extended the delay. + + * accessibility/AccessibilityObject.cpp: + (WebCore::AccessibilityObject::updateBackingStore): + +2018-02-19 Fujii Hironori + + null m_lastNodeInserted dereference at ReplaceSelectionCommand::InsertedNodes::lastLeafInserted + https://bugs.webkit.org/show_bug.cgi?id=161947 + + Reviewed by Ryosuke Niwa. + + InsertedNodes happened to be empty if the inserted nodes were + removed. Add more checks if InsertedNodes is empty. + + No new tests (Covered by existing tests). + + * editing/ReplaceSelectionCommand.cpp: + (WebCore::ReplaceSelectionCommand::doApply): Return early if InsertedNodes becomes empty. + * editing/ReplaceSelectionCommand.h: + (WebCore::ReplaceSelectionCommand::InsertedNodes::isEmpty): New method. + (WebCore::ReplaceSelectionCommand::InsertedNodes::lastLeafInserted const): + Assert m_lastNodeInserted is not null. + (WebCore::ReplaceSelectionCommand::InsertedNodes::pastLastLeaf const): Ditto. + +2018-02-13 Chris Dumez + + REGRESSION (r228299): Broke reader mode in Safari + https://bugs.webkit.org/show_bug.cgi?id=182697 + + + Reviewed by Ryosuke Niwa. + + Rework the fix for r228299 to be more targeted. I moved the policy check + cencelation from FrameLoader::stopLoading() to NavigationScheduler::schedule() + when a pending load is cancelled by another load. I have verified that the + sites fixed by r228299 still work with this more limited change. However, + reader mode is now working again. + + The issue seems to be that we tell CFNetwork to continue with the load after + receiving the response, even if the client has not responded to the + decidePolicyForNavigationResponse delegate yet. As a result, CFNetwork sends + us the resource data and we may commit the provisional load before receiving + the policy response from the client. When the provisional load is committed, + we call FrameLoader::stopLoading() which after r228299 cancelled pending + policy checks. Because we did not wait for the policy check response to + commit the load, we would cancel it which would make the load fail. + + The real fix here would be to make not tell CFNetwork to continue until after + we've received the policy delegate response. However, this is a larger and + riskier change at this point. I will follow-up on this issue. + + Covered by new API test. + + * loader/FrameLoader.cpp: + (WebCore::FrameLoader::stopLoading): + * loader/NavigationScheduler.cpp: + (WebCore::NavigationScheduler::schedule): + +2018-05-08 Jason Marcell + + Cherry-pick r231236. rdar://problem/40050705 + + Source/WebCore: + Prevent Debug ASSERT when changing forms + https://bugs.webkit.org/show_bug.cgi?id=185173 + + + Reviewed by Ryosuke Niwa. + + Form submission could trigger a debug assertion during validation when + a form is changed during an input submission. Fix this by cleaning up + the event handling logic and make it more consistent with modern WebKit + coding style. + + Test: fast/forms/form-submission-crash-3.html + + * html/HTMLButtonElement.cpp: + (WebCore::HTMLButtonElement::defaultEventHandler): Make sure layout runs before + attempting to perform event handling. + * html/HTMLFormElement.cpp: + (WebCore::HTMLFormElement::reportValidity): Ditto. + (WebCore::HTMLFormElement::validateInteractively): Remove call to perform layout here, + since we expect this to happen earlier in the layout pass. Add an assertion that the + tree is not dirty. + * html/ImageInputType.cpp: + (WebCore::ImageInputType::handleDOMActivateEvent): Make sure layout runs before + attempting to perform event handling. + * html/SubmitInputType.cpp: + (WebCore::SubmitInputType::handleDOMActivateEvent): Ditto. + + LayoutTests: + Prevent assertion when changing forms + https://bugs.webkit.org/show_bug.cgi?id=185173 + + + Reviewed by Ryosuke Niwa. + + * fast/forms/form-submission-crash-3-expected.txt: Added. + * fast/forms/form-submission-crash-3.html: Added. + + git-svn-id: https://svn.webkit.org/repository/webkit/trunk@231236 268f45cc-cd09-0410-ab3c-d52691b4dbfc + + 2018-05-01 Brent Fulgham + + Prevent Debug ASSERT when changing forms + https://bugs.webkit.org/show_bug.cgi?id=185173 + + + Reviewed by Ryosuke Niwa. + + Form submission could trigger a debug assertion during validation when + a form is changed during an input submission. Fix this by cleaning up + the event handling logic and make it more consistent with modern WebKit + coding style. + + Test: fast/forms/form-submission-crash-3.html + + * html/HTMLButtonElement.cpp: + (WebCore::HTMLButtonElement::defaultEventHandler): Make sure layout runs before + attempting to perform event handling. + * html/HTMLFormElement.cpp: + (WebCore::HTMLFormElement::reportValidity): Ditto. + (WebCore::HTMLFormElement::validateInteractively): Remove call to perform layout here, + since we expect this to happen earlier in the layout pass. Add an assertion that the + tree is not dirty. + * html/ImageInputType.cpp: + (WebCore::ImageInputType::handleDOMActivateEvent): Make sure layout runs before + attempting to perform event handling. + * html/SubmitInputType.cpp: + (WebCore::SubmitInputType::handleDOMActivateEvent): Ditto. + +2018-04-03 Jason Marcell + + Cherry-pick r230052. rdar://problem/39155251 + + WebSocket cookie incorrectly stored + https://bugs.webkit.org/show_bug.cgi?id=184100 + + + Reviewed by Brent Fulgham. + + Source/WebCore: + + A cookie received in a WebSocket response should be stored with respect to the + origin of the WebSocket server in order for it to be sent in a subsequent request. + + Also removed a FIXME about implementing support for the long since + deprecated Set-Cookie2 header. + + Test: http/tests/websocket/tests/hybi/websocket-cookie-overwrite-behavior.html + + * Modules/websockets/WebSocketChannel.cpp: + (WebCore::WebSocketChannel::processBuffer): + * Modules/websockets/WebSocketHandshake.h: + + LayoutTests: + + * http/tests/websocket/tests/hybi/cookie_wsh.py: Added. Downloaded from + . + (_add_set_cookie): + (web_socket_do_extra_handshake): + (web_socket_transfer_data): + * http/tests/websocket/tests/hybi/websocket-cookie-overwrite-behavior-expected.txt: Added. + * http/tests/websocket/tests/hybi/websocket-cookie-overwrite-behavior.html: Added. + + git-svn-id: https://svn.webkit.org/repository/webkit/trunk@230052 268f45cc-cd09-0410-ab3c-d52691b4dbfc + + 2018-03-28 Daniel Bates + + WebSocket cookie incorrectly stored + https://bugs.webkit.org/show_bug.cgi?id=184100 + + + Reviewed by Brent Fulgham. + + A cookie received in a WebSocket response should be stored with respect to the + origin of the WebSocket server in order for it to be sent in a subsequent request. + + Also removed a FIXME about implementing support for the long since + deprecated Set-Cookie2 header. + + Test: http/tests/websocket/tests/hybi/websocket-cookie-overwrite-behavior.html + + * Modules/websockets/WebSocketChannel.cpp: + (WebCore::WebSocketChannel::processBuffer): + * Modules/websockets/WebSocketHandshake.h: + +2018-04-03 Jason Marcell + + Cherry-pick r230063. rdar://problem/39155049 + + The SVGAnimatedProperty wrappers have to be detached from the referenced values before the SVGAnimatedType is deleted + https://bugs.webkit.org/show_bug.cgi?id=183972 + + Reviewed by Daniel Bates. + + If the SVGAnimatedType is a list type, e.g. SVGLengthListValues, the wrappers + of the animated properties have to be detached from the items in the list + before it's deleted. + + * svg/SVGAnimateElementBase.cpp: + (WebCore::SVGAnimateElementBase::clearAnimatedType): + + + git-svn-id: https://svn.webkit.org/repository/webkit/trunk@230063 268f45cc-cd09-0410-ab3c-d52691b4dbfc + + 2018-03-28 Said Abou-Hallawa + + The SVGAnimatedProperty wrappers have to be detached from the referenced values before the SVGAnimatedType is deleted + https://bugs.webkit.org/show_bug.cgi?id=183972 + + Reviewed by Daniel Bates. + + If the SVGAnimatedType is a list type, e.g. SVGLengthListValues, the wrappers + of the animated properties have to be detached from the items in the list + before it's deleted. + + * svg/SVGAnimateElementBase.cpp: + (WebCore::SVGAnimateElementBase::clearAnimatedType): + +2018-03-20 Jason Marcell + + Cherry-pick r229505. rdar://problem/38651624 + + 2018-03-09 Zalan Bujtas + + Turn off offset*/scroll* optimization for input elements with shadow content + https://bugs.webkit.org/show_bug.cgi?id=182383 + + + Reviewed by Antti Koivisto. + + We normally ensure clean tree before calling offsetHeight/Width, scrollHeight/Width. + In certain cases (see updateLayoutIfDimensionsOutOfDate() for details), it's okay to return + the previously computed values even when some part of the tree is dirty. + In case of shadow content, updateLayoutIfDimensionsOutOfDate() might return false (no need to layout) + for the root, while true (needs layout) for the shadow content. + This could confuse the caller (Element::scrollWidth/Height etc) and lead to incorrect result. + + Test: fast/forms/scrollheight-with-mutation-crash.html + + * dom/Document.cpp: + (WebCore::Document::updateLayoutIfDimensionsOutOfDate): + +2018-02-20 Jason Marcell + + Cherry-pick r228585. rdar://problem/37697677 + + 2018-02-16 Antti Koivisto + + Assert in mixed blend animation + https://bugs.webkit.org/show_bug.cgi?id=182887 + + + Reviewed by Zalan Bujtas. + + Test: fast/css/calc-mixed-blend-crash.html + + * platform/CalculationValue.cpp: + (WebCore::CalcExpressionBlendLength::CalcExpressionBlendLength): + + Fix mismatch between the type test and the value used. + +2018-02-14 Jason Marcell + + Cherry-pick r228476. rdar://problem/37549893 + + 2018-02-14 Dean Jackson + + CrashTracer: com.apple.WebKit.WebContent at com.apple.WebCore: WebCore::HTMLPlugInImageElement::didAddUserAgentShadowRoot + 618 + https://bugs.webkit.org/show_bug.cgi?id=182798 + + + Reviewed by Eric Carlson. + + Speculative fix for a crash in HTMLPlugInImageElement::didAddUserAgentShadowRoot. + The guess is that the m_swapRendererTimer is set, and the display state changes to + something that does not require a shadow root, but before the timer fires. + Fix this by ensuring that the timer is reset on every display state change. + + * html/HTMLPlugInElement.cpp: + (WebCore::HTMLPlugInElement::setDisplayState): Guard for sets that wouldn't + actually change value, and make sure we always reset the timer. + +2018-02-13 Jason Marcell + + Cherry-pick r228299. rdar://problem/37518837 + + 2018-02-08 Chris Dumez + + Form submission after navigation fails when decidePolicyForNavigationAction is async + https://bugs.webkit.org/show_bug.cgi?id=182412 + + + Reviewed by Alex Christensen. + + When the form is submitted and schedules the load in an iframe that is already loading, + FrameLoader::stopLoading() is called as expected. However, because policy checks can + now be asynchronous, stopLoading() also needs to stop pending policy checks. Otherwise, + continueLoadAfterNavigationPolicy() gets called for a cancelled load and we're in trouble + because the FrameLoader was reused for another load since then. + + Test: http/tests/navigation/sync-form-submit-iframe.html + + * loader/FrameLoader.cpp: + (WebCore::FrameLoader::stopLoading): + +2018-01-29 Antti Koivisto + + CalcExpressionBlendLength::evaluate hits stack limit + https://bugs.webkit.org/show_bug.cgi?id=182243 + + Reviewed by Zalan Bujtas. + + Speculative fix to prevent nesting of CalcExpressionBlendLength. + + No test, don't know how to make one. + + * platform/CalculationValue.cpp: + (WebCore::CalcExpressionBlendLength::CalcExpressionBlendLength): + + CalcExpressionBlendLength is only used in Length values of animated style. Normally such styles are not used + as input for further blending but there are some paths where this could in principle happen. Repeated + application (for each animation frame) could construct CalcExpressionBlendLength expression that blows + the stack when evaluated. + + Speculatively fix by flattening any nesting. + + * platform/CalculationValue.h: + (WebCore::CalcExpressionBlendLength::CalcExpressionBlendLength): Deleted. +2018-01-30 Jason Marcell + + Cherry-pick r227697. rdar://problem/37019483 + + 2018-01-26 Simon Fraser + + REGRESSiON (r226492): Crash under Element::absoluteEventBounds() on a SVGPathElement which has not been laid out yet + https://bugs.webkit.org/show_bug.cgi?id=182185 + rdar://problem/36836262 + + Reviewed by Zalan Bujtas. + + Document::absoluteRegionForEventTargets() can fire when layout is dirty, and SVGPathElement's path() can be null if it + hasn't been laid out yet. So protect against a null path in getBBox(). + + Not easily testable because internals.nonFastScrollableRects() forces layout, and the crash depends on the timing of + absoluteRegionForEventTargets(). + + * svg/SVGPathElement.cpp: + (WebCore::SVGPathElement::getBBox): + +2018-01-06 Simon Fraser + + Possible crash computing event regions + https://bugs.webkit.org/show_bug.cgi?id=181368 + rdar://problem/34847081 + + Reviewed by Zalan Bujtas. + + Don't trigger layout in Element::absoluteEventHandlerBounds(), since this can run arbirary script + which might delete elements or re-enter Document::absoluteRegionForEventTargets(). + + It's OK to not trigger layout, because if layout is dirty, the next layout will update event regions again. + + Add a LayoutDisallowedScope to check that Document::absoluteRegionForEventTargets() doesn't + trigger layout, and move the check for LayoutDisallowedScope::isLayoutAllowed() from Document::updateLayout() + to LayoutContext::layout(), since some layouts don't happen via the former (e.g. the one being removed here). + + The test checks that the assertion does not fire. I was not able to get a reliable test for any crash. + + Test: fast/events/event-handler-regions-layout.html + + * dom/Document.cpp: + (WebCore::Document::updateLayout): + (WebCore::Document::absoluteRegionForEventTargets): + * dom/Element.cpp: + (WebCore::Element::absoluteEventHandlerBounds): + * page/LayoutContext.cpp: + (WebCore::LayoutContext::layout): + * rendering/LayoutDisallowedScope.h: Move the #ifdefs around to avoid defining the enum twice. + (WebCore::LayoutDisallowedScope::LayoutDisallowedScope): + (WebCore::LayoutDisallowedScope::isLayoutAllowed): + +2018-01-25 Jason Marcell + + Cherry-pick r227578. rdar://problem/36873356 + + 2018-01-24 Chris Dumez + + close() operation should not be exposed inside a ServiceWorkerGlobalScope + https://bugs.webkit.org/show_bug.cgi?id=182057 + + Reviewed by Youenn Fablet. + + Move close() from WorkerGlobalScope to DedicatedWorkerGlobalScope as per: + - https://html.spec.whatwg.org/multipage/workers.html#dedicatedworkerglobalscope + + This change to the specification was made to avoid exposing this deprecated + features to service workers (which are new). + + No new tests, rebaselined existing test. + + * workers/DedicatedWorkerGlobalScope.idl: + * workers/WorkerGlobalScope.idl: + + +2018-01-25 Jason Marcell + + Cherry-pick r227567. rdar://problem/36873353 + + 2018-01-24 Daniel Bates + + [CSP] Check policy for targeted windows when navigating to a JavaScript URL + https://bugs.webkit.org/show_bug.cgi?id=182018 + + + Reviewed by Brent Fulgham. + + Move the CSP check to be earlier in the function. + + Test: http/tests/security/contentSecurityPolicy/window-open-javascript-url-with-target-blocked.html + + * loader/FrameLoader.cpp: + (WebCore::createWindow): + +2018-01-24 Jason Marcell + + Cherry-pick r227531. rdar://problem/36830355 + + 2018-01-24 Youenn Fablet + + Fetch response should copy its url from the request if null + https://bugs.webkit.org/show_bug.cgi?id=182048 + Reviewed by Chris Dumez. + + No change of behavior. + + * loader/DocumentLoader.cpp: + (WebCore::DocumentLoader::responseReceived): Add assertion to check that the response URL is not null. + +2018-01-19 Ryosuke Niwa + + Release assertion in canExecuteScript when executing scripts during page cache restore + https://bugs.webkit.org/show_bug.cgi?id=181902 + + Reviewed by Antti Koivisto. + + The crash was caused by an erroneous instantiation of ScriptDisallowedScope::InMainThread in CachedPage::restore. + It can execute arbitrary scripts since CachedFrame::open can update style, layout, and evaluate media queries. + + This is fine because there is no way to put this page back into a page cache until the load is commited via + FrameLoader::commitProvisionalLoad is invoked later which only happens after CachedPage::restore had exited. + + Also added a release assert to make sure this condition holds. + + Tests: fast/history/page-cache-execute-script-during-restore.html + fast/history/page-cache-navigate-during-restore.html + + * history/CachedPage.cpp: + (WebCore::CachedPageRestorationScope::CachedPageRestorationScope): Added. + (WebCore::CachedPageRestorationScope::~CachedPageRestorationScope): Added. + (WebCore::CachedPage::restore): Don't instantiate ScriptDisallowedScope::InMainThread. Set isRestoringCachedPage + on the cached pate to release-assert that there won't be any attempt to put this very page back into the cache. + * history/PageCache.cpp: + (WebCore::canCachePage): Added a release assert to make sure the page which is in the process of being restored + from the page cache is not put into the page cache. + * page/Page.h: + (WebCore::Page::setIsRestoringCachedPage): Added. + (WebCore::Page::isRestoringCachedPage const): Added. + +2018-01-21 Jer Noble + + REGRESSION (macOS 10.13.2): imported/w3c/web-platform-tests/media-source/mediasource-* LayoutTests failing + https://bugs.webkit.org/show_bug.cgi?id=181891 + + Reviewed by Eric Carlson. + + In macOS 10.13.2, CoreMedia changed the definition of CMSampleBufferGetDuration() to return + the presentation duration rather than the decode duration. For media streams where those two + durations are identical (or at least, closely similar), this isn't a problem. But the media + file used in the WPT tests have an unusual frame cadence: decode durations go {3000, 1, 5999, + 1, 5999,...} and presentation durations go {3000, 2999, 3000, 2999}. This caused one check in + the "Coded Frame Processing" algorithm to begin failing, where it checks that the delta + between the last sample's decode time and the new decode time is no more than 2x as far as + the last sample's duration. That's not a problem as long as the "duration" is the "decode + duration" and the samples are all adjacent. Once the "duration" is "presentation duration", + all the assumptions in the algorithm are invalidated. In the WPT test case, the delta between + decode times is 5999, and 2 * the presentation duration is 5998, causing all samples up to + the next sync sample to be dropped. + + To work around this change in behavior, we'll adopt the same technique used by Mozilla's MSE + implementation, which was done for similar reasons. Rather than track the "last frame duration", + we'll record the "greatest frame duration", and use actual decode timestamps to derive this + duration. The "greatest frame duration" field will be reset at the same times as "last frame + duration", and will be used only in the part of the algorithm that checks for large decode + timestamp gaps. + + * Modules/mediasource/SourceBuffer.cpp: + (WebCore::SourceBuffer::TrackBuffer::TrackBuffer): + (WebCore::SourceBuffer::resetParserState): + (WebCore::SourceBuffer::sourceBufferPrivateDidReceiveSample): + +2018-01-16 Jason Marcell + + Cherry-pick r227000. rdar://problem/36567987 + + 2018-01-16 Simon Fraser + + Text looks bad on some CSS spec pages + https://bugs.webkit.org/show_bug.cgi?id=181700 + rdar://problem/36552107 + + Reviewed by Tim Horton. + + When making new tiles in a TileController, we failed to set their "supports antialiased layer text" + setting, so tile caches could end up with a mixture of layers that do and do not support + antialiased layer text. + + No tests because the tiled drawing tests don't dump out tiles inside of tile caches. + + * platform/graphics/ca/TileController.cpp: + (WebCore::TileController::createTileLayer): + +2015-10-05 Jiewen Tan + + Fix null pointer dereference in WebSocket::connect() + https://bugs.webkit.org/show_bug.cgi?id=149311 + + + Reviewed by Chris Dumez. + + This is a merge of Blink r187441, + https://codereview.chromium.org/785933005 + + Test: http/tests/websocket/construct-in-detached-frame.html + + * Modules/websockets/WebSocket.cpp: + (WebCore::WebSocket::connect): + Call function implemented below instead of duplicating the code. + * page/ContentSecurityPolicy.cpp: + (WebCore::ContentSecurityPolicy::shouldBypassMainWorldContentSecurityPolicy): + * page/ContentSecurityPolicy.h: + Factor the logic to check shouldBypassMainWorldContentSecurityPolicy into + a function in this class. Check Frame pointers are not null before getting + shouldBypassMainWorldContentSecurityPolicy via those pointers. + * page/EventSource.cpp: + (WebCore::EventSource::create): + This got fixed as a bonus. + * xml/XMLHttpRequest.cpp: + (WebCore::XMLHttpRequest::open): + This got fixed as a bonus too. + +2018-01-16 Jason Marcell + + Cherry-pick r226951. rdar://problem/36568098 + + 2018-01-15 Youenn Fablet + + RealtimeMediaSource should be ThreadSafeRefCounted + https://bugs.webkit.org/show_bug.cgi?id=181649 + + Reviewed by Eric Carlson. + + Difficult to write a test as this is really racy. + RealtimeIncomingVideoSourceCocoa::OnFrame is taking a reference on a background thread + to send a task to the main thread. + This requires it to be thread safe ref counted. + + * platform/mediastream/RealtimeMediaSource.h: + +2018-01-16 Jason Marcell + + Cherry-pick r226929. rdar://problem/36567962 + + 2018-01-12 Alex Christensen + + History state should be updated during client redirects with asynchronous policy decisions + https://bugs.webkit.org/show_bug.cgi?id=181358 + + + Reviewed by Andy Estes. + + When decidePolicyForNavigationAction is responded to asynchronously during a client redirect, + HistoryController::updateForRedirectWithLockedBackForwardList does not update the history because + the document loader has not been marked as a client redirect because the FrameLoader only looks + at its provisional document loader to mark it as a client redirect. When decidePolicyForNavigationAction + is responded to asynchronously, though, the FrameLoader's provisional document loader has moved to + its policy document loader. To get both asynchronous and synchronous cases, let's just mark the document + loader as a client redirect whether it's the provisional or policy document loader. + + Covered by a new API test. + + * loader/FrameLoader.cpp: + (WebCore::FrameLoader::loadURL): + (WebCore::FrameLoader::loadPostRequest): + +2018-01-16 Jason Marcell + + Cherry-pick r226908. rdar://problem/36568060 + + 2018-01-12 Dean Jackson + + drawElements should be invalid if vertexAttrib0 doesn't have data + https://bugs.webkit.org/show_bug.cgi?id=181609 + + + Reviewed by Antoine Quint. + + If a vertex attribute has been enabled, but no data provided, then + draw validation should fail. + + Test: fast/canvas/webgl/drawElements-empty-vertex-data.html + + * html/canvas/WebGLRenderingContextBase.cpp: + (WebCore::WebGLRenderingContextBase::validateVertexAttributes): If there were + never any data in the vertex buffer, then we incorrectly compared with 0. + +2018-01-11 Jason Marcell + + Cherry-pick r226653. rdar://problem/36429147 + + 2018-01-09 Antti Koivisto + + Blank page except for inner iframes because pending stylesheets cause style.isNotFinal() to be true + https://bugs.webkit.org/show_bug.cgi?id=180940 + + + Reviewed by Darin Adler. + + Test: http/tests/local/loading-stylesheet-import-remove.html + + If a referencing a stylesheet containing an @import that was still loading was removed + from the document, the loading state was never cleared. For head stylesheets this blocked + rendering permanently. + + Test reduction by Justin Ridgewell. + + * html/HTMLLinkElement.cpp: + (WebCore::HTMLLinkElement::removedFromAncestor): + + Test if the stylesheet it loading before clearing the pointer. + +2018-01-06 Simon Fraser + + Crash under RenderLayer::scrollTo() with marquee + https://bugs.webkit.org/show_bug.cgi?id=181349 + rdar://problem/36190168 + + Reviewed by Zalan Bujtas. + + Don't call updateWidgetPositions() synchonously during RenderLayer scrolling, because it + can run arbitrary script which may trigger destruction of this RenderLayer. + + Instead, queue up updateWidgetPositions() on a zero-delay timer. + + Under some circumstances this may allow a paint to occur before the widgets have been + updated (which could be fixed with a more invasive change), but in practice I saw no + painting issues with plug-ins or iframes inside overflow scroll, in WebKit or LegacyWebKit. + + Test: fast/scrolling/marquee-scroll-crash.html + + * page/FrameView.cpp: + (WebCore::FrameView::FrameView): + (WebCore::FrameView::updateWidgetPositions): + (WebCore::FrameView::scheduleUpdateWidgetPositions): + (WebCore::FrameView::updateWidgetPositionsTimerFired): + * page/FrameView.h: + * rendering/RenderLayer.cpp: + (WebCore::RenderLayer::scrollTo): + +2017-12-01 Zalan Bujtas + + Nullptr deref in WebCore::RenderTableCaption::containingBlockLogicalWidthForContent + https://bugs.webkit.org/show_bug.cgi?id=180251 + + + Reviewed by Simon Fraser. + + containingBlockLogicalWidthForContent should check whether the renderer is actually + attached to the tree. + + Test: fast/table/caption-crash-when-layer-backed.html + + * rendering/RenderBoxModelObject.cpp: + (WebCore::RenderBoxModelObject::containingBlockLogicalWidthForContent const): + * rendering/RenderTableCaption.h: + (WebCore::RenderTableCaption::containingBlockLogicalWidthForContent const): + 2017-10-27 Daniel Bates Only allow non-mixed content protected subresources to ask for credentials diff --git a/webkit/WebCore/Modules/mediasource/SourceBuffer.cpp b/webkit/WebCore/Modules/mediasource/SourceBuffer.cpp index aa3423274..cbd274949 100644 --- a/webkit/WebCore/Modules/mediasource/SourceBuffer.cpp +++ b/webkit/WebCore/Modules/mediasource/SourceBuffer.cpp @@ -111,6 +111,7 @@ struct SourceBuffer::TrackBuffer { public: #endif MediaTime lastDecodeTimestamp; + MediaTime greatestDecodeDuration; MediaTime lastFrameDuration; MediaTime highestPresentationTimestamp; MediaTime lastEnqueuedPresentationTime; @@ -124,6 +125,7 @@ struct SourceBuffer::TrackBuffer { TrackBuffer() : lastDecodeTimestamp(MediaTime::invalidTime()) + , greatestDecodeDuration(MediaTime::invalidTime()) , lastFrameDuration(MediaTime::invalidTime()) , highestPresentationTimestamp(MediaTime::invalidTime()) , lastEnqueuedPresentationTime(MediaTime::invalidTime()) @@ -348,6 +350,7 @@ void SourceBuffer::resetParserState() // 5. Set the need random access point flag on all track buffers to true. for (auto& trackBufferPair : m_trackBufferMap.values()) { trackBufferPair.lastDecodeTimestamp = MediaTime::invalidTime(); + trackBufferPair.greatestDecodeDuration = MediaTime::invalidTime(); trackBufferPair.lastFrameDuration = MediaTime::invalidTime(); trackBufferPair.highestPresentationTimestamp = MediaTime::invalidTime(); trackBufferPair.needRandomAccessFlag = true; @@ -1672,7 +1675,7 @@ void SourceBuffer::sourceBufferPrivateDidReceiveSample(SourceBufferPrivate*, Pas // ↳ If last decode timestamp for track buffer is set and the difference between decode timestamp and // last decode timestamp is greater than 2 times last frame duration: if (trackBuffer.lastDecodeTimestamp.isValid() && (decodeTimestamp < trackBuffer.lastDecodeTimestamp - || abs(decodeTimestamp - trackBuffer.lastDecodeTimestamp) > (trackBuffer.lastFrameDuration * 2))) { + || (trackBuffer.greatestDecodeDuration.isValid() && abs(decodeTimestamp - trackBuffer.lastDecodeTimestamp) >(trackBuffer.greatestDecodeDuration * 2)))) { // 1.6.1: if (m_mode == segmentsKeyword()) { @@ -1689,6 +1692,7 @@ void SourceBuffer::sourceBufferPrivateDidReceiveSample(SourceBufferPrivate*, Pas // 1.6.2 Unset the last decode timestamp on all track buffers. trackBuffer.lastDecodeTimestamp = MediaTime::invalidTime(); // 1.6.3 Unset the last frame duration on all track buffers. + trackBuffer.greatestDecodeDuration = MediaTime::invalidTime(); trackBuffer.lastFrameDuration = MediaTime::invalidTime(); // 1.6.4 Unset the highest presentation timestamp on all track buffers. trackBuffer.highestPresentationTimestamp = MediaTime::invalidTime(); @@ -1882,6 +1886,14 @@ void SourceBuffer::sourceBufferPrivateDidReceiveSample(SourceBufferPrivate*, Pas trackBuffer.decodeQueue.insert(DecodeOrderSampleMap::MapType::value_type(decodeKey, sample)); } + // NOTE: the spec considers "Coded Frame Duration" to be the presentation duration, but this is not necessarily equal + // to the decoded duration. When comparing deltas between decode timestamps, the decode duration, not the presentation. + if (trackBuffer.lastDecodeTimestamp.isValid()) { + MediaTime lastDecodeDuration = decodeTimestamp - trackBuffer.lastDecodeTimestamp; + if (lastDecodeDuration > trackBuffer.greatestDecodeDuration) + trackBuffer.greatestDecodeDuration = lastDecodeDuration; + } + // 1.18 Set last decode timestamp for track buffer to decode timestamp. trackBuffer.lastDecodeTimestamp = decodeTimestamp; diff --git a/webkit/WebCore/Modules/websockets/ThreadableWebSocketChannel.h b/webkit/WebCore/Modules/websockets/ThreadableWebSocketChannel.h index 16190e467..86b4cd420 100644 --- a/webkit/WebCore/Modules/websockets/ThreadableWebSocketChannel.h +++ b/webkit/WebCore/Modules/websockets/ThreadableWebSocketChannel.h @@ -79,10 +79,6 @@ class ThreadableWebSocketChannel { virtual void suspend() = 0; virtual void resume() = 0; -#if PLATFORM(WKC) - virtual bool isConstructed() const { return true; } -#endif - void ref() { refThreadableWebSocketChannel(); } void deref() { derefThreadableWebSocketChannel(); } diff --git a/webkit/WebCore/Modules/websockets/WebSocket.cpp b/webkit/WebCore/Modules/websockets/WebSocket.cpp index dcf42f397..e05da034f 100644 --- a/webkit/WebCore/Modules/websockets/WebSocket.cpp +++ b/webkit/WebCore/Modules/websockets/WebSocket.cpp @@ -239,11 +239,7 @@ void WebSocket::connect(const String& url, const Vector& protocols, Exce } // FIXME: Convert this to check the isolated world's Content Security Policy once webkit.org/b/104520 is solved. - bool shouldBypassMainWorldContentSecurityPolicy = false; - if (is(*scriptExecutionContext())) { - Document& document = downcast(*scriptExecutionContext()); - shouldBypassMainWorldContentSecurityPolicy = document.frame()->script().shouldBypassMainWorldContentSecurityPolicy(); - } + bool shouldBypassMainWorldContentSecurityPolicy = ContentSecurityPolicy::shouldBypassMainWorldContentSecurityPolicy(*scriptExecutionContext()); if (!scriptExecutionContext()->contentSecurityPolicy()->allowConnectToSource(m_url, shouldBypassMainWorldContentSecurityPolicy)) { m_state = CLOSED; @@ -302,13 +298,6 @@ void WebSocket::connect(const String& url, const Vector& protocols, Exce protocolString = joinStrings(protocols, subProtocolSeperator()); m_channel->connect(m_url, protocolString); -#if PLATFORM(WKC) - if (!m_channel->isConstructed()) { - m_state = CLOSED; - ec = QUOTA_EXCEEDED_ERR; - return; - } -#endif ActiveDOMObject::setPendingActivity(this); } diff --git a/webkit/WebCore/Modules/websockets/WebSocketChannel.cpp b/webkit/WebCore/Modules/websockets/WebSocketChannel.cpp index 79f01699e..f420912bf 100644 --- a/webkit/WebCore/Modules/websockets/WebSocketChannel.cpp +++ b/webkit/WebCore/Modules/websockets/WebSocketChannel.cpp @@ -254,14 +254,6 @@ void WebSocketChannel::resume() m_resumeTimer.startOneShot(0); } -#if PLATFORM(WKC) -bool WebSocketChannel::isConstructed() const -{ - return m_handle->isConstructed(); -} -#endif - - void WebSocketChannel::willOpenSocketStream(SocketStreamHandle*) { LOG(Network, "WebSocketChannel %p willOpenSocketStream()", this); @@ -451,13 +443,11 @@ bool WebSocketChannel::processBuffer() if (m_handshake->mode() == WebSocketHandshake::Connected) { if (m_identifier) InspectorInstrumentation::didReceiveWebSocketHandshakeResponse(m_document, m_identifier, m_handshake->serverHandshakeResponse()); - if (!m_handshake->serverSetCookie().isEmpty()) { - if (cookiesEnabled(m_document)) { - // Exception (for sandboxed documents) ignored. - m_document->setCookie(m_handshake->serverSetCookie(), IGNORE_EXCEPTION); - } + String serverSetCookie = m_handshake->serverSetCookie(); + if (!serverSetCookie.isEmpty()) { + if (m_document && cookiesEnabled(m_document)) + setCookies(m_document, m_handshake->httpURLForAuthenticationAndCookies(), serverSetCookie); } - // FIXME: handle set-cookie2. LOG(Network, "WebSocketChannel %p Connected", this); skipBuffer(headerLength); m_client->didConnect(); diff --git a/webkit/WebCore/Modules/websockets/WebSocketChannel.h b/webkit/WebCore/Modules/websockets/WebSocketChannel.h index 2fe2956dc..96f3f7911 100644 --- a/webkit/WebCore/Modules/websockets/WebSocketChannel.h +++ b/webkit/WebCore/Modules/websockets/WebSocketChannel.h @@ -75,9 +75,6 @@ class WebSocketChannel : public RefCounted, public SocketStrea virtual void close(int code, const String& reason) override; // Start closing handshake. virtual void fail(const String& reason) override; virtual void disconnect() override; -#if PLATFORM(WKC) - virtual bool isConstructed() const override; -#endif virtual void suspend() override; virtual void resume() override; diff --git a/webkit/WebCore/Modules/websockets/WebSocketHandshake.h b/webkit/WebCore/Modules/websockets/WebSocketHandshake.h index 0d5900b88..80740b087 100644 --- a/webkit/WebCore/Modules/websockets/WebSocketHandshake.h +++ b/webkit/WebCore/Modules/websockets/WebSocketHandshake.h @@ -55,6 +55,7 @@ class WebSocketHandshake { const URL& url() const; void setURL(const URL&); + URL httpURLForAuthenticationAndCookies() const; const String host() const; const String& clientProtocol() const; @@ -90,7 +91,6 @@ class WebSocketHandshake { static String getExpectedWebSocketAccept(const String& secWebSocketKey); private: - URL httpURLForAuthenticationAndCookies() const; int readStatusLine(const char* header, size_t headerLength, int& statusCode, String& statusText); diff --git a/webkit/WebCore/accessibility/AccessibilityObject.cpp b/webkit/WebCore/accessibility/AccessibilityObject.cpp index ea85202c0..92c97482b 100644 --- a/webkit/WebCore/accessibility/AccessibilityObject.cpp +++ b/webkit/WebCore/accessibility/AccessibilityObject.cpp @@ -1598,6 +1598,9 @@ unsigned AccessibilityObject::doAXLineForIndex(unsigned index) #if HAVE(ACCESSIBILITY) void AccessibilityObject::updateBackingStore() { + if (!axObjectCache()) + return; + // Updating the layout may delete this object. RefPtr protector(this); diff --git a/webkit/WebCore/css/CSSFilterImageValue.cpp b/webkit/WebCore/css/CSSFilterImageValue.cpp index 297fbc873..fbd041d91 100644 --- a/webkit/WebCore/css/CSSFilterImageValue.cpp +++ b/webkit/WebCore/css/CSSFilterImageValue.cpp @@ -133,7 +133,13 @@ PassRefPtr CSSFilterImageValue::image(RenderElement* renderer, const Floa return Image::nullImage(); filterRenderer->apply(); +#if PLATFORM(WKC) + ImageBuffer* sourceImage = filterRenderer->output(); + if (sourceImage) + m_generatedImage = sourceImage->copyImage(); +#else m_generatedImage = filterRenderer->output()->copyImage(); +#endif return m_generatedImage.release(); } diff --git a/webkit/WebCore/dom/Document.cpp b/webkit/WebCore/dom/Document.cpp index 902117ec7..adfa0f535 100644 --- a/webkit/WebCore/dom/Document.cpp +++ b/webkit/WebCore/dom/Document.cpp @@ -1982,6 +1982,10 @@ bool Document::updateLayoutIfDimensionsOutOfDate(Element& element, DimensionsChe requireFullLayout = true; } + // Turn off this optimization for input elements with shadow content. + if (is(element)) + requireFullLayout = true; + bool isVertical = renderer && !renderer->isHorizontalWritingMode(); bool checkingLogicalWidth = ((dimensionsCheck & WidthDimensionsCheck) && !isVertical) || ((dimensionsCheck & HeightDimensionsCheck) && isVertical); bool checkingLogicalHeight = ((dimensionsCheck & HeightDimensionsCheck) && !isVertical) || ((dimensionsCheck & WidthDimensionsCheck) && isVertical); diff --git a/webkit/WebCore/dom/Element.cpp b/webkit/WebCore/dom/Element.cpp index c0239f300..b54e1fa66 100644 --- a/webkit/WebCore/dom/Element.cpp +++ b/webkit/WebCore/dom/Element.cpp @@ -1047,9 +1047,6 @@ LayoutRect Element::absoluteEventHandlerBounds(bool& includesFixedPositionElemen if (!frameView) return LayoutRect(); - if (frameView->needsLayout()) - frameView->layout(); - return absoluteEventBoundsOfElementAndDescendants(includesFixedPositionElements); } diff --git a/webkit/WebCore/dom/Node.cpp b/webkit/WebCore/dom/Node.cpp index b969e9a5c..1ccdb9ac9 100644 --- a/webkit/WebCore/dom/Node.cpp +++ b/webkit/WebCore/dom/Node.cpp @@ -780,22 +780,49 @@ LayoutRect Node::renderRect(bool* isReplaced) #if PLATFORM(WKC) // FIXME: Move this function to Element. -void Node::getNodeCompositeRect(LayoutRect* rects, int tx, int ty) +void Node::getNodeCompositeRect(LayoutRect* rects, bool isOverflowXHidden, bool isOverflowYHidden, int tx, int ty) { if (!isElementNode() || isSVGElement()) return; + if (isOverflowXHidden && isOverflowYHidden) + return; + for (Element* element = ElementTraversal::firstWithin((Element &)*this); element; element = ElementTraversal::nextSibling(*element)) { RenderObject* o = element->renderer(); if (o) { IntRect rect = o->absoluteBoundingBoxRect(true); if (!rect.isEmpty() && !(rect.x() < 0 || rect.y() < 0)) { if (element->firstChild()) { - element->getNodeCompositeRect(rects, tx, ty); + bool x = (o->style().overflowX() == OHIDDEN); + bool y = (o->style().overflowY() == OHIDDEN); + element->getNodeCompositeRect(rects, (isOverflowXHidden | x), (isOverflowYHidden | y), tx, ty); } rect.move(-tx,-ty); - LayoutRect lr(rect.x(), rect.y(), rect.width(), rect.height()); - rects->unite(enclosingIntRect(lr)); + if (!isOverflowXHidden && !isOverflowYHidden) { + LayoutRect lr(rect.x(), rect.y(), rect.width(), rect.height()); + rects->unite(enclosingIntRect(lr)); + } else if (!isOverflowXHidden) { + if (rects->isEmpty()) { + rects->setX(rect.x()); + rects->setWidth(rect.width()); + } else { + LayoutUnit newX = std::min(rects->x(), LayoutUnit(rect.x())); + LayoutUnit newMaxX = std::max(rects->maxX(), LayoutUnit(rect.maxX())); + rects->setX(newX); + rects->setWidth(newMaxX - newX); + } + } else if (!isOverflowYHidden) { + if (rects->isEmpty()) { + rects->setY(rect.y()); + rects->setHeight(rect.height()); + } else { + LayoutUnit newY = std::min(rects->y(), LayoutUnit(rect.y())); + LayoutUnit newMaxY = std::max(rects->maxY(), LayoutUnit(rect.maxY())); + rects->setY(newY); + rects->setHeight(newMaxY - newY); + } + } } } } diff --git a/webkit/WebCore/dom/Node.h b/webkit/WebCore/dom/Node.h index 7ed56b6f7..c17d0e180 100644 --- a/webkit/WebCore/dom/Node.h +++ b/webkit/WebCore/dom/Node.h @@ -265,7 +265,7 @@ class Node : public EventTarget, public ScriptWrappable { #if PLATFORM(WKC) bool isScrollableOverFlowBlockNode() const; - void getNodeCompositeRect(LayoutRect* rects, int tx = 0, int ty = 0); + void getNodeCompositeRect(LayoutRect* rects, bool isOverflowXHidden, bool isOverflowYHidden, int tx = 0, int ty = 0); #endif bool isDocumentNode() const; diff --git a/webkit/WebCore/editing/ReplaceSelectionCommand.cpp b/webkit/WebCore/editing/ReplaceSelectionCommand.cpp index 6d171ad45..a75cfb338 100644 --- a/webkit/WebCore/editing/ReplaceSelectionCommand.cpp +++ b/webkit/WebCore/editing/ReplaceSelectionCommand.cpp @@ -1188,13 +1188,17 @@ void ReplaceSelectionCommand::doApply() node = next; } + if (insertedNodes.isEmpty()) + return; removeUnrenderedTextNodesAtEnds(insertedNodes); if (!handledStyleSpans) handleStyleSpans(insertedNodes); // Mutation events (bug 20161) may have already removed the inserted content - if (!insertedNodes.firstNodeInserted() || !insertedNodes.firstNodeInserted()->inDocument()) + if (insertedNodes.isEmpty()) + return; + if (!insertedNodes.firstNodeInserted()->inDocument()) return; VisiblePosition startOfInsertedContent = firstPositionInOrBeforeNode(insertedNodes.firstNodeInserted()); @@ -1215,8 +1219,12 @@ void ReplaceSelectionCommand::doApply() } makeInsertedContentRoundTrippableWithHTMLTreeBuilder(insertedNodes); + if (insertedNodes.isEmpty()) + return; removeRedundantStylesAndKeepStyleSpanInline(insertedNodes); + if (insertedNodes.isEmpty()) + return; if (m_sanitizeFragment) applyCommandToComposite(SimplifyMarkupCommand::create(document(), insertedNodes.firstNodeInserted(), insertedNodes.pastLastLeaf())); diff --git a/webkit/WebCore/editing/ReplaceSelectionCommand.h b/webkit/WebCore/editing/ReplaceSelectionCommand.h index 73620fd23..b6c2c190f 100644 --- a/webkit/WebCore/editing/ReplaceSelectionCommand.h +++ b/webkit/WebCore/editing/ReplaceSelectionCommand.h @@ -65,15 +65,17 @@ class ReplaceSelectionCommand : public CompositeEditCommand { void willRemoveNode(Node*); void didReplaceNode(Node*, Node* newNode); + bool isEmpty() { return !m_firstNodeInserted; } Node* firstNodeInserted() const { return m_firstNodeInserted.get(); } - Node* lastLeafInserted() const { return m_lastNodeInserted->lastDescendant(); } + Node* lastLeafInserted() const + { + ASSERT(m_lastNodeInserted); + return m_lastNodeInserted->lastDescendant(); + } Node* pastLastLeaf() const { - if (m_lastNodeInserted) { - ASSERT(lastLeafInserted()); - return NodeTraversal::next(*lastLeafInserted()); - } - return nullptr; + ASSERT(m_lastNodeInserted); + return NodeTraversal::next(*lastLeafInserted()); } private: diff --git a/webkit/WebCore/history/CachedPage.cpp b/webkit/WebCore/history/CachedPage.cpp index 0773d771a..a00849b73 100644 --- a/webkit/WebCore/history/CachedPage.cpp +++ b/webkit/WebCore/history/CachedPage.cpp @@ -98,20 +98,32 @@ static void firePageShowAndPopStateEvents(Page& page) } } +class CachedPageRestorationScope { +public: + CachedPageRestorationScope(Page& page) + : m_page(page) + { + m_page.setIsRestoringCachedPage(true); + } + + ~CachedPageRestorationScope() + { + m_page.setIsRestoringCachedPage(false); + } + +private: + Page& m_page; +}; + void CachedPage::restore(Page& page) { ASSERT(m_cachedMainFrame); ASSERT(m_cachedMainFrame->view()->frame().isMainFrame()); ASSERT(!page.subframeCount()); - { - // Do not dispatch DOM events as their JavaScript listeners could cause the page to be put - // into the page cache before we have finished restoring it from the page cache. - NoEventDispatchAssertion noEventDispatchAssertion; + CachedPageRestorationScope restorationScope(page); + m_cachedMainFrame->open(); - m_cachedMainFrame->open(); - } - // Restore the focus appearance for the focused element. // FIXME: Right now we don't support pages w/ frames in the b/f cache. This may need to be tweaked when we add support for that. Document* focusedDocument = page.focusController().focusedOrMainFrame().document(); diff --git a/webkit/WebCore/history/PageCache.cpp b/webkit/WebCore/history/PageCache.cpp index 0c2ce5b34..87bb7e54d 100644 --- a/webkit/WebCore/history/PageCache.cpp +++ b/webkit/WebCore/history/PageCache.cpp @@ -189,6 +189,8 @@ static bool canCacheFrame(Frame& frame, DiagnosticLoggingClient& diagnosticLoggi static bool canCachePage(Page& page) { + RELEASE_ASSERT(!page.isRestoringCachedPage()); + unsigned indentLevel = 0; PCLOG("--------\n Determining if page can be cached:"); diff --git a/webkit/WebCore/html/HTMLAnchorElement.cpp b/webkit/WebCore/html/HTMLAnchorElement.cpp index 22ecb6953..06d49c50f 100644 --- a/webkit/WebCore/html/HTMLAnchorElement.cpp +++ b/webkit/WebCore/html/HTMLAnchorElement.cpp @@ -131,9 +131,14 @@ static bool hasNonEmptyBox(RenderBoxModelObject* renderer) Node* node = static_cast(renderer)->node(); if (!node) return false; + if (!node->renderer()) + return false; ASSERT(is(*node)); + RenderStyle& style = node->renderer()->style(); + bool isOverflowXHidden = (style.overflowX() == OHIDDEN); + bool isOverflowYHidden = (style.overflowY() == OHIDDEN); LayoutRect rect; - node->getNodeCompositeRect(&rect); + node->getNodeCompositeRect(&rect, isOverflowXHidden, isOverflowYHidden); if (!rect.isEmpty()) return true; #endif diff --git a/webkit/WebCore/html/HTMLButtonElement.cpp b/webkit/WebCore/html/HTMLButtonElement.cpp index c03ca5ca1..e71e44d18 100644 --- a/webkit/WebCore/html/HTMLButtonElement.cpp +++ b/webkit/WebCore/html/HTMLButtonElement.cpp @@ -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 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 { @@ -110,15 +111,25 @@ void HTMLButtonElement::parseAttribute(const QualifiedName& name, const AtomicSt 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) { + TemporaryChange activatedSubmitState(m_isActivatedSubmit, true); + currentForm->prepareForSubmission(event); + } + + if (m_type == RESET) + currentForm->reset(); + } + + if (m_type == SUBMIT || m_type == RESET) + event->setDefaultHandled(); } } diff --git a/webkit/WebCore/html/HTMLFormElement.cpp b/webkit/WebCore/html/HTMLFormElement.cpp index ce8cdbd1d..252a8f34e 100644 --- a/webkit/WebCore/html/HTMLFormElement.cpp +++ b/webkit/WebCore/html/HTMLFormElement.cpp @@ -245,9 +245,9 @@ bool HTMLFormElement::validateInteractively(Event* event) // 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 protect(*this); diff --git a/webkit/WebCore/html/HTMLLinkElement.cpp b/webkit/WebCore/html/HTMLLinkElement.cpp index ea88f76f3..31582cb1f 100644 --- a/webkit/WebCore/html/HTMLLinkElement.cpp +++ b/webkit/WebCore/html/HTMLLinkElement.cpp @@ -309,10 +309,12 @@ void HTMLLinkElement::removedFrom(ContainerNode& insertionPoint) } document().styleSheetCollection().removeStyleSheetCandidateNode(*this); + bool wasLoading = styleSheetIsLoading(); + if (m_sheet) clearSheet(); - if (styleSheetIsLoading()) + if (wasLoading) removePendingSheet(RemovePendingSheetNotifyLater); if (document().hasLivingRenderTree()) diff --git a/webkit/WebCore/html/HTMLPlugInElement.cpp b/webkit/WebCore/html/HTMLPlugInElement.cpp index 7859d63c4..b3d8eb44b 100644 --- a/webkit/WebCore/html/HTMLPlugInElement.cpp +++ b/webkit/WebCore/html/HTMLPlugInElement.cpp @@ -312,9 +312,13 @@ void HTMLPlugInElement::swapRendererTimerFired() void HTMLPlugInElement::setDisplayState(DisplayState state) { + if (state == m_displayState) + return; + m_displayState = state; - if ((state == DisplayingSnapshot || displayState() == PreparingPluginReplacement) && !m_swapRendererTimer.isActive()) + m_swapRendererTimer.stop(); + if ((state == DisplayingSnapshot || displayState() == PreparingPluginReplacement)) m_swapRendererTimer.startOneShot(0); } diff --git a/webkit/WebCore/html/ImageInputType.cpp b/webkit/WebCore/html/ImageInputType.cpp index 1234440be..7e286f432 100644 --- a/webkit/WebCore/html/ImageInputType.cpp +++ b/webkit/WebCore/html/ImageInputType.cpp @@ -84,6 +84,9 @@ void ImageInputType::handleDOMActivateEvent(Event* event) Ref element(this->element()); if (element->isDisabledFormControl() || !element->form()) return; + + Ref protectedForm(*element->form()); + element->setActivatedSubmit(true); m_clickLocation = IntPoint(); @@ -96,7 +99,13 @@ void ImageInputType::handleDOMActivateEvent(Event* event) } } - element->form()->prepareForSubmission(event); // Event handlers can run. + // Update layout before processing form actions in case the style changes + // the Form or button relationships. + element->document().updateLayoutIgnorePendingStylesheets(); + + if (auto currentForm = element->form()) + currentForm->prepareForSubmission(event); // Event handlers can run. + element->setActivatedSubmit(false); event->setDefaultHandled(); } diff --git a/webkit/WebCore/html/SubmitInputType.cpp b/webkit/WebCore/html/SubmitInputType.cpp index 1d0b72ed9..ab4af4b83 100644 --- a/webkit/WebCore/html/SubmitInputType.cpp +++ b/webkit/WebCore/html/SubmitInputType.cpp @@ -64,8 +64,16 @@ void SubmitInputType::handleDOMActivateEvent(Event* event) Ref element(this->element()); if (element->isDisabledFormControl() || !element->form()) return; + + Ref protectedForm(*element->form()); + + // Update layout before processing form actions in case the style changes + // the Form or button relationships. + element->document().updateLayoutIgnorePendingStylesheets(); + element->setActivatedSubmit(true); - element->form()->prepareForSubmission(event); // Event handlers can run. + if (auto currentForm = element->form()) + currentForm->prepareForSubmission(event); // Event handlers can run. element->setActivatedSubmit(false); event->setDefaultHandled(); } diff --git a/webkit/WebCore/html/canvas/WebGLRenderingContextBase.cpp b/webkit/WebCore/html/canvas/WebGLRenderingContextBase.cpp index c047c1721..823f5a092 100644 --- a/webkit/WebCore/html/canvas/WebGLRenderingContextBase.cpp +++ b/webkit/WebCore/html/canvas/WebGLRenderingContextBase.cpp @@ -1724,6 +1724,8 @@ bool WebGLRenderingContextBase::validateVertexAttributes(unsigned elementCount, // For the last element, we will only touch the data for the // element and nothing beyond it. int bytesRemaining = static_cast(state.bufferBinding->byteLength() - state.offset); + if (bytesRemaining <= 0) + return false; unsigned numElements = 0; ASSERT(state.stride > 0); if (bytesRemaining >= state.bytesPerElement) diff --git a/webkit/WebCore/loader/DocumentLoader.cpp b/webkit/WebCore/loader/DocumentLoader.cpp index 77735ac49..c213a7c78 100644 --- a/webkit/WebCore/loader/DocumentLoader.cpp +++ b/webkit/WebCore/loader/DocumentLoader.cpp @@ -681,6 +681,7 @@ void DocumentLoader::responseReceived(CachedResource* resource, const ResourceRe } else if (response.isMultipart()) m_isLoadingMultipartContent = true; + ASSERT(!response.url().isNull()); m_response = response; if (m_identifierForLoadWithoutResourceLoader) { diff --git a/webkit/WebCore/loader/FrameLoader.cpp b/webkit/WebCore/loader/FrameLoader.cpp index b5fa879a7..dd9f5ad69 100644 --- a/webkit/WebCore/loader/FrameLoader.cpp +++ b/webkit/WebCore/loader/FrameLoader.cpp @@ -1300,6 +1300,8 @@ void FrameLoader::loadURL(const FrameLoadRequest& frameLoadRequest, const String m_quickRedirectComing = false; if (m_provisionalDocumentLoader) m_provisionalDocumentLoader->setIsClientRedirect(true); + else if (m_policyDocumentLoader) + m_policyDocumentLoader->setIsClientRedirect(true); } else if (sameURL && newLoadType != FrameLoadType::Reload && newLoadType != FrameLoadType::ReloadFromOrigin) { // Example of this case are sites that reload the same URL with a different cookie // driving the generated content, or a master frame with links that drive a target @@ -2781,6 +2783,8 @@ void FrameLoader::loadPostRequest(const FrameLoadRequest& request, const String& m_quickRedirectComing = false; if (m_provisionalDocumentLoader) m_provisionalDocumentLoader->setIsClientRedirect(true); + else if (m_policyDocumentLoader) + m_policyDocumentLoader->setIsClientRedirect(true); } } @@ -3660,6 +3664,10 @@ RefPtr createWindow(Frame& openerFrame, Frame& lookupFrame, const FrameLo created = false; + // FIXME: Provide line number information with respect to the opener's document. + if (protocolIsJavaScript(request.resourceRequest().url()) && !openerFrame.document()->contentSecurityPolicy()->allowJavaScriptURLs(openerFrame.document()->url(), { })) + return nullptr; + if (!request.frameName().isEmpty() && request.frameName() != "_blank") { if (RefPtr frame = lookupFrame.loader().findFrameForNavigation(request.frameName(), openerFrame.document())) { if (request.frameName() != "_self") { @@ -3677,10 +3685,6 @@ RefPtr createWindow(Frame& openerFrame, Frame& lookupFrame, const FrameLo return nullptr; } - // FIXME: Provide line number information with respect to the opener's document. - if (protocolIsJavaScript(request.resourceRequest().url()) && !openerFrame.document()->contentSecurityPolicy()->allowJavaScriptURLs(openerFrame.document()->url(), { })) - return nullptr; - // FIXME: Setting the referrer should be the caller's responsibility. FrameLoadRequest requestWithReferrer = request; String referrer = SecurityPolicy::generateReferrerHeader(openerFrame.document()->referrerPolicy(), request.resourceRequest().url(), openerFrame.loader().outgoingReferrer()); diff --git a/webkit/WebCore/loader/NavigationScheduler.cpp b/webkit/WebCore/loader/NavigationScheduler.cpp index fbc16008e..e53865c21 100644 --- a/webkit/WebCore/loader/NavigationScheduler.cpp +++ b/webkit/WebCore/loader/NavigationScheduler.cpp @@ -47,6 +47,7 @@ #include "HistoryItem.h" #include "InspectorInstrumentation.h" #include "Page.h" +#include "PolicyChecker.h" #include "ScriptController.h" #include "Settings.h" #include "UserGestureIndicator.h" @@ -533,6 +534,7 @@ void NavigationScheduler::schedule(std::unique_ptr redirect if (redirect->wasDuringLoad()) { if (DocumentLoader* provisionalDocumentLoader = m_frame.loader().provisionalDocumentLoader()) provisionalDocumentLoader->stopLoading(); + m_frame.loader().policyChecker().stopCheck(); m_frame.loader().stopLoading(UnloadEventPolicyUnloadAndPageHide); } diff --git a/webkit/WebCore/page/ContentSecurityPolicy.cpp b/webkit/WebCore/page/ContentSecurityPolicy.cpp index 53a6155b1..871828ed1 100644 --- a/webkit/WebCore/page/ContentSecurityPolicy.cpp +++ b/webkit/WebCore/page/ContentSecurityPolicy.cpp @@ -37,6 +37,7 @@ #include "PingLoader.h" #include "RuntimeEnabledFeatures.h" #include "SchemeRegistry.h" +#include "ScriptController.h" #include "ScriptState.h" #include "SecurityOrigin.h" #include "SecurityPolicyViolationEvent.h" @@ -1789,4 +1790,14 @@ bool ContentSecurityPolicy::experimentalFeaturesEnabled() const #endif } +bool ContentSecurityPolicy::shouldBypassMainWorldContentSecurityPolicy(ScriptExecutionContext& context) +{ + if (is(context)) { + auto& document = downcast(context); + return document.frame() && document.frame()->script().shouldBypassMainWorldContentSecurityPolicy(); + } + + return false; +} + } diff --git a/webkit/WebCore/page/ContentSecurityPolicy.h b/webkit/WebCore/page/ContentSecurityPolicy.h index dc3c95103..cedf1e23f 100644 --- a/webkit/WebCore/page/ContentSecurityPolicy.h +++ b/webkit/WebCore/page/ContentSecurityPolicy.h @@ -130,6 +130,7 @@ class ContentSecurityPolicy { String evalDisabledErrorMessage() const; bool experimentalFeaturesEnabled() const; + static bool shouldBypassMainWorldContentSecurityPolicy(ScriptExecutionContext&); private: void logToConsole(const String& message, const String& contextURL = String(), const WTF::OrdinalNumber& contextLine = WTF::OrdinalNumber::beforeFirst(), JSC::ExecState* = nullptr) const; diff --git a/webkit/WebCore/page/EventSource.cpp b/webkit/WebCore/page/EventSource.cpp index be2767695..5947667bf 100644 --- a/webkit/WebCore/page/EventSource.cpp +++ b/webkit/WebCore/page/EventSource.cpp @@ -86,11 +86,7 @@ RefPtr EventSource::create(ScriptExecutionContext& context, const S } // FIXME: Convert this to check the isolated world's Content Security Policy once webkit.org/b/104520 is solved. - bool shouldBypassMainWorldContentSecurityPolicy = false; - if (is(context)) { - Document& document = downcast(context); - shouldBypassMainWorldContentSecurityPolicy = document.frame()->script().shouldBypassMainWorldContentSecurityPolicy(); - } + bool shouldBypassMainWorldContentSecurityPolicy = ContentSecurityPolicy::shouldBypassMainWorldContentSecurityPolicy(context); if (!context.contentSecurityPolicy()->allowConnectToSource(fullURL, shouldBypassMainWorldContentSecurityPolicy)) { // FIXME: Should this be throwing an exception? ec = SECURITY_ERR; diff --git a/webkit/WebCore/page/FrameView.cpp b/webkit/WebCore/page/FrameView.cpp index 8e94799b9..9fbf19dd7 100644 --- a/webkit/WebCore/page/FrameView.cpp +++ b/webkit/WebCore/page/FrameView.cpp @@ -173,6 +173,7 @@ FrameView::FrameView(Frame& frame) , m_inSynchronousPostLayout(false) , m_postLayoutTasksTimer(*this, &FrameView::postLayoutTimerFired) , m_updateEmbeddedObjectsTimer(*this, &FrameView::updateEmbeddedObjectsTimerFired) + , m_updateWidgetPositionsTimer(*this, &FrameView::updateWidgetPositionsTimerFired) , m_isTransparent(false) , m_baseBackgroundColor(Color::white) , m_mediaType("screen") @@ -4903,6 +4904,7 @@ static Vector> collectAndProtectWidgets(const HashSet& s void FrameView::updateWidgetPositions() { + m_updateWidgetPositionsTimer.stop(); // updateWidgetPosition() can possibly cause layout to be re-entered (via plug-ins running // scripts in response to NPP_SetWindow, for example), so we need to keep the Widgets // alive during enumeration. @@ -4914,6 +4916,17 @@ void FrameView::updateWidgetPositions() } } +void FrameView::scheduleUpdateWidgetPositions() +{ + if (!m_updateWidgetPositionsTimer.isActive()) + m_updateWidgetPositionsTimer.startOneShot(0); +} + +void FrameView::updateWidgetPositionsTimerFired() +{ + updateWidgetPositions(); +} + void FrameView::notifyWidgets(WidgetNotification notification) { for (auto& widget : collectAndProtectWidgets(m_widgetsInRenderTree)) diff --git a/webkit/WebCore/page/FrameView.h b/webkit/WebCore/page/FrameView.h index deb09e7e5..ba1329570 100644 --- a/webkit/WebCore/page/FrameView.h +++ b/webkit/WebCore/page/FrameView.h @@ -534,6 +534,8 @@ class FrameView final : public ScrollView { void setHasFlippedBlockRenderers(bool b) { m_hasFlippedBlockRenderers = b; } void updateWidgetPositions(); + void scheduleUpdateWidgetPositions(); + void didAddWidgetToRenderTree(Widget&); void willRemoveWidgetFromRenderTree(Widget&); @@ -674,6 +676,9 @@ class FrameView final : public ScrollView { void updateEmbeddedObjectsTimerFired(); bool updateEmbeddedObjects(); void updateEmbeddedObject(RenderEmbeddedObject&); + + void updateWidgetPositionsTimerFired(); + void scrollToAnchor(); #if PLATFORM(WKC) public: @@ -739,6 +744,8 @@ class FrameView final : public ScrollView { unsigned m_nestedLayoutCount; Timer m_postLayoutTasksTimer; Timer m_updateEmbeddedObjectsTimer; + Timer m_updateWidgetPositionsTimer; + bool m_firstLayoutCallbackPending; bool m_firstLayout; diff --git a/webkit/WebCore/page/Page.h b/webkit/WebCore/page/Page.h index a6fbcbd8c..1d8838be6 100644 --- a/webkit/WebCore/page/Page.h +++ b/webkit/WebCore/page/Page.h @@ -321,6 +321,9 @@ class Page : public Supplementable { void setIsClosing() { m_isClosing = true; } bool isClosing() const { return m_isClosing; } + void setIsRestoringCachedPage(bool value) { m_isRestoringCachedPage = value; } + bool isRestoringCachedPage() const { return m_isRestoringCachedPage; } + void addViewStateChangeObserver(ViewStateChangeObserver&); void removeViewStateChangeObserver(ViewStateChangeObserver&); @@ -638,6 +641,7 @@ class Page : public Supplementable { SessionID m_sessionID; bool m_isClosing; + bool m_isRestoringCachedPage{ false }; bool m_shouldTabSuspend { false }; Timer m_tabSuspensionTimer; diff --git a/webkit/WebCore/page/SpatialNavigation.cpp b/webkit/WebCore/page/SpatialNavigation.cpp index ae9ee07ac..79ad48a91 100644 --- a/webkit/WebCore/page/SpatialNavigation.cpp +++ b/webkit/WebCore/page/SpatialNavigation.cpp @@ -897,7 +897,10 @@ bool hasOffscreenRect(Node* node, FocusDirection direction) #if PLATFORM(WKC) LayoutRect rect = render->absoluteClippedOverflowRect(); if (node->hasTagName(HTMLNames::aTag) && node->firstChild()) { - node->getNodeCompositeRect(&rect); + RenderStyle& style = render->style(); + bool isOverflowXHidden = (style.overflowX() == OHIDDEN); + bool isOverflowYHidden = (style.overflowY() == OHIDDEN); + node->getNodeCompositeRect(&rect, isOverflowXHidden, isOverflowYHidden); } #else LayoutRect rect(render->absoluteClippedOverflowRect()); @@ -1222,7 +1225,10 @@ LayoutRect nodeRectInAbsoluteCoordinates(Node* node, bool ignoreBorder) if (RenderObject* renderer = node->renderer()) { rect = renderer->absoluteBoundingBoxRect(true); if (node->hasTagName(HTMLNames::aTag) && node->firstChild()) { - node->getNodeCompositeRect(&rect); + RenderStyle& style = renderer->style(); + bool isOverflowXHidden = (style.overflowX() == OHIDDEN); + bool isOverflowYHidden = (style.overflowY() == OHIDDEN); + node->getNodeCompositeRect(&rect, isOverflowXHidden, isOverflowYHidden); } rect = rectToAbsoluteCoordinates(node->document().frame(), rect); } diff --git a/webkit/WebCore/platform/CalculationValue.cpp b/webkit/WebCore/platform/CalculationValue.cpp index 64c0cac74..3bc3c3a68 100644 --- a/webkit/WebCore/platform/CalculationValue.cpp +++ b/webkit/WebCore/platform/CalculationValue.cpp @@ -96,6 +96,20 @@ bool CalcExpressionLength::operator==(const CalcExpressionNode& other) const return other.type() == CalcExpressionNodeLength && *this == toCalcExpressionLength(other); } +CalcExpressionBlendLength::CalcExpressionBlendLength(Length from, Length to, float progress) + : CalcExpressionNode(CalcExpressionNodeBlendLength) + , m_from(from) + , m_to(to) + , m_progress(progress) +{ + // Flatten nesting of CalcExpressionBlendLength as a speculative fix for rdar://problem/30533005. + // CalcExpressionBlendLength is only used as a result of animation and they don't nest in normal cases. + if (m_from.isCalculated() && m_from.calculationValue().expression().type() == CalcExpressionNodeBlendLength) + m_from = toCalcExpressionBlendLength(m_from.calculationValue().expression()).from(); + if (m_to.isCalculated() && m_to.calculationValue().expression().type() == CalcExpressionNodeBlendLength) + m_to = toCalcExpressionBlendLength(m_to.calculationValue().expression()).to(); +} + float CalcExpressionBlendLength::evaluate(float maxValue) const { return (1.0f - m_progress) * floatValueForLength(m_from, maxValue) + m_progress * floatValueForLength(m_to, maxValue); diff --git a/webkit/WebCore/platform/CalculationValue.h b/webkit/WebCore/platform/CalculationValue.h index b228a4ac6..5f46d0877 100644 --- a/webkit/WebCore/platform/CalculationValue.h +++ b/webkit/WebCore/platform/CalculationValue.h @@ -218,14 +218,6 @@ inline const CalcExpressionBinaryOperation& toCalcExpressionBinaryOperation(cons return static_cast(value); } -inline CalcExpressionBlendLength::CalcExpressionBlendLength(Length from, Length to, float progress) - : CalcExpressionNode(CalcExpressionNodeBlendLength) - , m_from(from) - , m_to(to) - , m_progress(progress) -{ -} - inline bool operator==(const CalcExpressionBlendLength& a, const CalcExpressionBlendLength& b) { return a.progress() == b.progress() && a.from() == b.from() && a.to() == b.to(); diff --git a/webkit/WebCore/platform/graphics/ca/TileController.cpp b/webkit/WebCore/platform/graphics/ca/TileController.cpp index e8075d283..c701575ed 100644 --- a/webkit/WebCore/platform/graphics/ca/TileController.cpp +++ b/webkit/WebCore/platform/graphics/ca/TileController.cpp @@ -587,6 +587,7 @@ RefPtr TileController::createTileLayer(const IntRect& tileRect, layer->setContentsScale(m_deviceScaleFactor * temporaryScaleFactor); layer->setAcceleratesDrawing(m_acceleratesDrawing); + layer->setSupportsSubpixelAntialiasedText(m_supportsSubpixelAntialiasedText); layer->setNeedsDisplay(); diff --git a/webkit/WebCore/platform/graphics/filters/FEBlend.cpp b/webkit/WebCore/platform/graphics/filters/FEBlend.cpp index c14f60fc6..612ba2ed4 100644 --- a/webkit/WebCore/platform/graphics/filters/FEBlend.cpp +++ b/webkit/WebCore/platform/graphics/filters/FEBlend.cpp @@ -72,8 +72,15 @@ void FEBlend::platformApplySoftware() ImageBuffer* imageBuffer = in->asImageBuffer(); ImageBuffer* imageBuffer2 = in2->asImageBuffer(); +#if PLATFORM(WKC) + if (!imageBuffer) + return; + if (!imageBuffer2) + return; +#else ASSERT(imageBuffer); ASSERT(imageBuffer2); +#endif filterContext->drawImageBuffer(imageBuffer2, ColorSpaceDeviceRGB, drawingRegionOfInputImage(in2->absolutePaintRect())); filterContext->drawImageBuffer(imageBuffer, ColorSpaceDeviceRGB, drawingRegionOfInputImage(in->absolutePaintRect()), IntRect(IntPoint(), imageBuffer->logicalSize()), ImagePaintingOptions(CompositeSourceOver, m_mode)); diff --git a/webkit/WebCore/platform/graphics/filters/FEColorMatrix.cpp b/webkit/WebCore/platform/graphics/filters/FEColorMatrix.cpp index 152822647..3c831d24c 100644 --- a/webkit/WebCore/platform/graphics/filters/FEColorMatrix.cpp +++ b/webkit/WebCore/platform/graphics/filters/FEColorMatrix.cpp @@ -147,7 +147,13 @@ void FEColorMatrix::platformApplySoftware() if (!resultImage) return; +#if PLATFORM(WKC) + ImageBuffer* sourceImage = in->asImageBuffer(); + if (sourceImage) + resultImage->context()->drawImageBuffer(sourceImage, ColorSpaceDeviceRGB, drawingRegionOfInputImage(in->absolutePaintRect())); +#else resultImage->context()->drawImageBuffer(in->asImageBuffer(), ColorSpaceDeviceRGB, drawingRegionOfInputImage(in->absolutePaintRect())); +#endif IntRect imageRect(IntPoint(), resultImage->logicalSize()); RefPtr pixelArray = resultImage->getUnmultipliedImageData(imageRect); diff --git a/webkit/WebCore/platform/graphics/filters/FEComposite.cpp b/webkit/WebCore/platform/graphics/filters/FEComposite.cpp index 30a90eb77..692934c48 100644 --- a/webkit/WebCore/platform/graphics/filters/FEComposite.cpp +++ b/webkit/WebCore/platform/graphics/filters/FEComposite.cpp @@ -278,8 +278,15 @@ void FEComposite::platformApplySoftware() ImageBuffer* imageBuffer = in->asImageBuffer(); ImageBuffer* imageBuffer2 = in2->asImageBuffer(); +#if PLATFORM(WKC) + if (!imageBuffer) + return; + if (!imageBuffer2) + return; +#else ASSERT(imageBuffer); ASSERT(imageBuffer2); +#endif switch (m_type) { case FECOMPOSITE_OPERATOR_OVER: diff --git a/webkit/WebCore/platform/graphics/filters/FEMerge.cpp b/webkit/WebCore/platform/graphics/filters/FEMerge.cpp index 26b932acf..40326b1e2 100644 --- a/webkit/WebCore/platform/graphics/filters/FEMerge.cpp +++ b/webkit/WebCore/platform/graphics/filters/FEMerge.cpp @@ -50,7 +50,13 @@ void FEMerge::platformApplySoftware() GraphicsContext* filterContext = resultImage->context(); for (unsigned i = 0; i < size; ++i) { FilterEffect* in = inputEffect(i); +#if PLATFORM(WKC) + ImageBuffer* sourceImage = in->asImageBuffer(); + if (sourceImage) + filterContext->drawImageBuffer(sourceImage, ColorSpaceDeviceRGB, drawingRegionOfInputImage(in->absolutePaintRect())); +#else filterContext->drawImageBuffer(in->asImageBuffer(), ColorSpaceDeviceRGB, drawingRegionOfInputImage(in->absolutePaintRect())); +#endif } } diff --git a/webkit/WebCore/platform/graphics/filters/FEOffset.cpp b/webkit/WebCore/platform/graphics/filters/FEOffset.cpp index a44c21d6a..162fbf039 100644 --- a/webkit/WebCore/platform/graphics/filters/FEOffset.cpp +++ b/webkit/WebCore/platform/graphics/filters/FEOffset.cpp @@ -87,7 +87,13 @@ void FEOffset::platformApplySoftware() FloatRect drawingRegion = drawingRegionOfInputImage(in->absolutePaintRect()); Filter& filter = this->filter(); drawingRegion.move(filter.applyHorizontalScale(m_dx), filter.applyVerticalScale(m_dy)); +#if PLATFORM(WKC) + ImageBuffer* sourceImage = in->asImageBuffer(); + if (sourceImage) + resultImage->context()->drawImageBuffer(sourceImage, ColorSpaceDeviceRGB, drawingRegion); +#else resultImage->context()->drawImageBuffer(in->asImageBuffer(), ColorSpaceDeviceRGB, drawingRegion); +#endif } void FEOffset::dump() diff --git a/webkit/WebCore/platform/graphics/filters/FETile.cpp b/webkit/WebCore/platform/graphics/filters/FETile.cpp index 8d3172d98..b9bf3b89e 100644 --- a/webkit/WebCore/platform/graphics/filters/FETile.cpp +++ b/webkit/WebCore/platform/graphics/filters/FETile.cpp @@ -69,7 +69,13 @@ void FETile::platformApplySoftware() GraphicsContext* tileImageContext = tileImage->context(); tileImageContext->translate(-inMaxEffectLocation.x(), -inMaxEffectLocation.y()); +#if PLATFORM(WKC) + ImageBuffer* sourceImage = in->asImageBuffer(); + if (sourceImage) + tileImageContext->drawImageBuffer(sourceImage, ColorSpaceDeviceRGB, in->absolutePaintRect().location()); +#else tileImageContext->drawImageBuffer(in->asImageBuffer(), ColorSpaceDeviceRGB, in->absolutePaintRect().location()); +#endif auto tileImageCopy = tileImage->copyImage(CopyBackingStore); if (!tileImageCopy) diff --git a/webkit/WebCore/platform/graphics/filters/FilterEffect.cpp b/webkit/WebCore/platform/graphics/filters/FilterEffect.cpp index ba63cd93f..154b6941c 100644 --- a/webkit/WebCore/platform/graphics/filters/FilterEffect.cpp +++ b/webkit/WebCore/platform/graphics/filters/FilterEffect.cpp @@ -573,7 +573,13 @@ void FilterEffect::transformResultColorSpace(ColorSpace dstColorSpace) // FIXME: We can avoid this potentially unnecessary ImageBuffer conversion by adding // color space transform support for the {pre,un}multiplied arrays. +#if PLATFORM(WKC) + ImageBuffer* sourceImage = asImageBuffer(); + if (sourceImage) + sourceImage->transformColorSpace(m_resultColorSpace, dstColorSpace); +#else asImageBuffer()->transformColorSpace(m_resultColorSpace, dstColorSpace); +#endif #if ENABLE(OPENCL) } diff --git a/webkit/WebCore/platform/graphics/filters/SourceAlpha.cpp b/webkit/WebCore/platform/graphics/filters/SourceAlpha.cpp index 3a7a50284..19775b629 100644 --- a/webkit/WebCore/platform/graphics/filters/SourceAlpha.cpp +++ b/webkit/WebCore/platform/graphics/filters/SourceAlpha.cpp @@ -54,7 +54,12 @@ void SourceAlpha::platformApplySoftware() GraphicsContext* filterContext = resultImage->context(); ImageBuffer* imageBuffer = inputEffect(0)->asImageBuffer(); +#if PLATFORM(WKC) + if (!imageBuffer) + return; +#else ASSERT(imageBuffer); +#endif FloatRect imageRect(FloatPoint(), absolutePaintRect().size()); filterContext->fillRect(imageRect, Color::black, ColorSpaceDeviceRGB); diff --git a/webkit/WebCore/platform/mediastream/RealtimeMediaSource.h b/webkit/WebCore/platform/mediastream/RealtimeMediaSource.h index 3beff453d..5d22f94d8 100644 --- a/webkit/WebCore/platform/mediastream/RealtimeMediaSource.h +++ b/webkit/WebCore/platform/mediastream/RealtimeMediaSource.h @@ -38,7 +38,7 @@ #include "MediaConstraints.h" #include "RealtimeMediaSourceCapabilities.h" -#include +#include #include #include @@ -49,7 +49,7 @@ class MediaConstraints; class MediaStreamPrivate; class RealtimeMediaSourceStates; -class RealtimeMediaSource : public RefCounted { +class RealtimeMediaSource : public ThreadSafeRefCounted { public: class Observer { public: diff --git a/webkit/WebCore/rendering/FilterEffectRenderer.cpp b/webkit/WebCore/rendering/FilterEffectRenderer.cpp index 3cf8bcfcb..7c1732766 100644 --- a/webkit/WebCore/rendering/FilterEffectRenderer.cpp +++ b/webkit/WebCore/rendering/FilterEffectRenderer.cpp @@ -430,8 +430,15 @@ void FilterEffectRendererHelper::applyFilterEffect(GraphicsContext* destinationC LayoutRect destRect = filter->outputRect(); destRect.move(m_paintOffset.x(), m_paintOffset.y()); +#if PLATFORM(WKC) + ImageBuffer* sourceImage = filter->output(); + if (sourceImage) + destinationContext->drawImageBuffer(sourceImage, m_renderLayer->renderer().style().colorSpace(), + snapRectToDevicePixels(destRect, m_renderLayer->renderer().document().deviceScaleFactor())); +#else destinationContext->drawImageBuffer(filter->output(), m_renderLayer->renderer().style().colorSpace(), snapRectToDevicePixels(destRect, m_renderLayer->renderer().document().deviceScaleFactor())); +#endif filter->clearIntermediateResults(); } diff --git a/webkit/WebCore/rendering/FloatingObjects.cpp b/webkit/WebCore/rendering/FloatingObjects.cpp index 8e1af95da..fe797a964 100644 --- a/webkit/WebCore/rendering/FloatingObjects.cpp +++ b/webkit/WebCore/rendering/FloatingObjects.cpp @@ -42,7 +42,7 @@ struct SameSizeAsFloatingObject { COMPILE_ASSERT(sizeof(FloatingObject) == sizeof(SameSizeAsFloatingObject), FloatingObject_should_stay_small); FloatingObject::FloatingObject(RenderBox& renderer) - : m_renderer(renderer) + : m_renderer(renderer.createWeakPtr()) , m_originatingLine(nullptr) , m_paginationStrut(0) , m_shouldPaint(true) @@ -61,7 +61,7 @@ FloatingObject::FloatingObject(RenderBox& renderer) } FloatingObject::FloatingObject(RenderBox& renderer, Type type, const LayoutRect& frameRect, bool shouldPaint, bool isDescendant) - : m_renderer(renderer) + : m_renderer(renderer.createWeakPtr()) , m_originatingLine(nullptr) , m_frameRect(frameRect) , m_paginationStrut(0) @@ -126,8 +126,8 @@ class ComputeFloatOffsetAdapter { public: typedef FloatingObjectInterval IntervalType; - ComputeFloatOffsetAdapter(const RenderBlockFlow& renderer, LayoutUnit lineTop, LayoutUnit lineBottom, LayoutUnit offset) - : m_renderer(renderer) + ComputeFloatOffsetAdapter(RenderBlockFlow& renderer, LayoutUnit lineTop, LayoutUnit lineBottom, LayoutUnit offset) + : m_renderer(renderer.createWeakPtr()) , m_lineTop(lineTop) , m_lineBottom(lineBottom) , m_offset(offset) @@ -146,7 +146,7 @@ class ComputeFloatOffsetAdapter { protected: virtual bool updateOffsetIfNeeded(const FloatingObject&) = 0; - const RenderBlockFlow& m_renderer; + WeakPtr m_renderer; LayoutUnit m_lineTop; LayoutUnit m_lineBottom; LayoutUnit m_offset; @@ -156,7 +156,7 @@ class ComputeFloatOffsetAdapter { template class ComputeFloatOffsetForFloatLayoutAdapter : public ComputeFloatOffsetAdapter { public: - ComputeFloatOffsetForFloatLayoutAdapter(const RenderBlockFlow& renderer, LayoutUnit lineTop, LayoutUnit lineBottom, LayoutUnit offset) + ComputeFloatOffsetForFloatLayoutAdapter(RenderBlockFlow& renderer, LayoutUnit lineTop, LayoutUnit lineBottom, LayoutUnit offset) : ComputeFloatOffsetAdapter(renderer, lineTop, lineBottom, offset) { } @@ -172,7 +172,7 @@ class ComputeFloatOffsetForFloatLayoutAdapter : public ComputeFloatOffsetAdapter template class ComputeFloatOffsetForLineLayoutAdapter : public ComputeFloatOffsetAdapter { public: - ComputeFloatOffsetForLineLayoutAdapter(const RenderBlockFlow& renderer, LayoutUnit lineTop, LayoutUnit lineBottom, LayoutUnit offset) + ComputeFloatOffsetForLineLayoutAdapter(RenderBlockFlow& renderer, LayoutUnit lineTop, LayoutUnit lineBottom, LayoutUnit offset) : ComputeFloatOffsetAdapter(renderer, lineTop, lineBottom, offset) { } @@ -190,8 +190,8 @@ class FindNextFloatLogicalBottomAdapter { public: typedef FloatingObjectInterval IntervalType; - FindNextFloatLogicalBottomAdapter(const RenderBlockFlow& renderer, LayoutUnit belowLogicalHeight) - : m_renderer(renderer) + FindNextFloatLogicalBottomAdapter(RenderBlockFlow& renderer, LayoutUnit belowLogicalHeight) + : m_renderer(renderer.createWeakPtr()) , m_belowLogicalHeight(belowLogicalHeight) , m_aboveLogicalHeight(LayoutUnit::max()) , m_nextLogicalBottom(LayoutUnit::max()) @@ -207,7 +207,7 @@ class FindNextFloatLogicalBottomAdapter { LayoutUnit nextShapeLogicalBottom() { return m_nextShapeLogicalBottom == LayoutUnit::max() ? nextLogicalBottom() : m_nextShapeLogicalBottom; } private: - const RenderBlockFlow& m_renderer; + WeakPtr m_renderer; LayoutUnit m_belowLogicalHeight; LayoutUnit m_aboveLogicalHeight; LayoutUnit m_nextLogicalBottom; @@ -222,15 +222,15 @@ inline void FindNextFloatLogicalBottomAdapter::collectIfNeeded(const IntervalTyp // All the objects returned from the tree should be already placed. ASSERT(floatingObject->isPlaced()); - ASSERT(rangesIntersect(m_renderer.logicalTopForFloat(floatingObject), m_renderer.logicalBottomForFloat(floatingObject), m_belowLogicalHeight, m_aboveLogicalHeight)); + ASSERT(rangesIntersect(m_renderer->logicalTopForFloat(floatingObject), m_renderer->logicalBottomForFloat(floatingObject), m_belowLogicalHeight, m_aboveLogicalHeight)); - LayoutUnit floatBottom = m_renderer.logicalBottomForFloat(floatingObject); + LayoutUnit floatBottom = m_renderer->logicalBottomForFloat(floatingObject); if (m_nextLogicalBottom < floatBottom) return; #if ENABLE(CSS_SHAPES) if (ShapeOutsideInfo* shapeOutside = floatingObject->renderer().shapeOutsideInfo()) { - LayoutUnit shapeBottom = m_renderer.logicalTopForFloat(floatingObject) + m_renderer.marginBeforeForChild(floatingObject->renderer()) + shapeOutside->shapeLogicalBottom(); + LayoutUnit shapeBottom = m_renderer->logicalTopForFloat(floatingObject) + m_renderer->marginBeforeForChild(floatingObject->renderer()) + shapeOutside->shapeLogicalBottom(); // Use the shapeBottom unless it extends outside of the margin box, in which case it is clipped. m_nextShapeLogicalBottom = std::min(shapeBottom, floatBottom); } else @@ -241,7 +241,7 @@ inline void FindNextFloatLogicalBottomAdapter::collectIfNeeded(const IntervalTyp LayoutUnit FloatingObjects::findNextFloatLogicalBottomBelow(LayoutUnit logicalHeight) { - FindNextFloatLogicalBottomAdapter adapter(m_renderer, logicalHeight); + FindNextFloatLogicalBottomAdapter adapter(renderer(), logicalHeight); if (const FloatingObjectTree* placedFloatsTree = this->placedFloatsTree()) placedFloatsTree->allOverlapsWithAdapter(adapter); @@ -250,7 +250,7 @@ LayoutUnit FloatingObjects::findNextFloatLogicalBottomBelow(LayoutUnit logicalHe LayoutUnit FloatingObjects::findNextFloatLogicalBottomBelowForBlock(LayoutUnit logicalHeight) { - FindNextFloatLogicalBottomAdapter adapter(m_renderer, logicalHeight); + FindNextFloatLogicalBottomAdapter adapter(renderer(), logicalHeight); if (const FloatingObjectTree* placedFloatsTree = this->placedFloatsTree()) placedFloatsTree->allOverlapsWithAdapter(adapter); @@ -261,7 +261,7 @@ FloatingObjects::FloatingObjects(const RenderBlockFlow& renderer) : m_leftObjectsCount(0) , m_rightObjectsCount(0) , m_horizontalWritingMode(renderer.isHorizontalWritingMode()) - , m_renderer(renderer) + , m_renderer((const_cast(renderer)).createWeakPtr()) { } @@ -273,7 +273,7 @@ void FloatingObjects::clearLineBoxTreePointers() { // Clear references to originating lines, since the lines are being deleted for (auto it = m_set.begin(), end = m_set.end(); it != end; ++it) { - ASSERT(!((*it)->originatingLine()) || &((*it)->originatingLine()->renderer()) == &m_renderer); + ASSERT(!((*it)->originatingLine()) || &((*it)->originatingLine()->renderer()) == &renderer()); (*it)->setOriginatingLine(0); } } @@ -396,7 +396,7 @@ inline const FloatingObjectTree* FloatingObjects::placedFloatsTree() LayoutUnit FloatingObjects::logicalLeftOffsetForPositioningFloat(LayoutUnit fixedOffset, LayoutUnit logicalTop, LayoutUnit *heightRemaining) { - ComputeFloatOffsetForFloatLayoutAdapter adapter(m_renderer, logicalTop, logicalTop, fixedOffset); + ComputeFloatOffsetForFloatLayoutAdapter adapter(renderer(), logicalTop, logicalTop, fixedOffset); if (const FloatingObjectTree* placedFloatsTree = this->placedFloatsTree()) placedFloatsTree->allOverlapsWithAdapter(adapter); @@ -408,7 +408,7 @@ LayoutUnit FloatingObjects::logicalLeftOffsetForPositioningFloat(LayoutUnit fixe LayoutUnit FloatingObjects::logicalRightOffsetForPositioningFloat(LayoutUnit fixedOffset, LayoutUnit logicalTop, LayoutUnit *heightRemaining) { - ComputeFloatOffsetForFloatLayoutAdapter adapter(m_renderer, logicalTop, logicalTop, fixedOffset); + ComputeFloatOffsetForFloatLayoutAdapter adapter(renderer(), logicalTop, logicalTop, fixedOffset); if (const FloatingObjectTree* placedFloatsTree = this->placedFloatsTree()) placedFloatsTree->allOverlapsWithAdapter(adapter); @@ -420,7 +420,7 @@ LayoutUnit FloatingObjects::logicalRightOffsetForPositioningFloat(LayoutUnit fix LayoutUnit FloatingObjects::logicalLeftOffset(LayoutUnit fixedOffset, LayoutUnit logicalTop, LayoutUnit logicalHeight) { - ComputeFloatOffsetForLineLayoutAdapter adapter(m_renderer, logicalTop, logicalTop + logicalHeight, fixedOffset); + ComputeFloatOffsetForLineLayoutAdapter adapter(renderer(), logicalTop, logicalTop + logicalHeight, fixedOffset); if (const FloatingObjectTree* placedFloatsTree = this->placedFloatsTree()) placedFloatsTree->allOverlapsWithAdapter(adapter); @@ -429,7 +429,7 @@ LayoutUnit FloatingObjects::logicalLeftOffset(LayoutUnit fixedOffset, LayoutUnit LayoutUnit FloatingObjects::logicalRightOffset(LayoutUnit fixedOffset, LayoutUnit logicalTop, LayoutUnit logicalHeight) { - ComputeFloatOffsetForLineLayoutAdapter adapter(m_renderer, logicalTop, logicalTop + logicalHeight, fixedOffset); + ComputeFloatOffsetForLineLayoutAdapter adapter(renderer(), logicalTop, logicalTop + logicalHeight, fixedOffset); if (const FloatingObjectTree* placedFloatsTree = this->placedFloatsTree()) placedFloatsTree->allOverlapsWithAdapter(adapter); @@ -439,7 +439,7 @@ LayoutUnit FloatingObjects::logicalRightOffset(LayoutUnit fixedOffset, LayoutUni template<> inline bool ComputeFloatOffsetForFloatLayoutAdapter::updateOffsetIfNeeded(const FloatingObject& floatingObject) { - LayoutUnit logicalRight = m_renderer.logicalRightForFloat(&floatingObject); + LayoutUnit logicalRight = m_renderer->logicalRightForFloat(&floatingObject); if (logicalRight > m_offset) { m_offset = logicalRight; return true; @@ -450,7 +450,7 @@ inline bool ComputeFloatOffsetForFloatLayoutAdapter:: template<> inline bool ComputeFloatOffsetForFloatLayoutAdapter::updateOffsetIfNeeded(const FloatingObject& floatingObject) { - LayoutUnit logicalLeft = m_renderer.logicalLeftForFloat(&floatingObject); + LayoutUnit logicalLeft = m_renderer->logicalLeftForFloat(&floatingObject); if (logicalLeft < m_offset) { m_offset = logicalLeft; return true; @@ -461,7 +461,7 @@ inline bool ComputeFloatOffsetForFloatLayoutAdapter: template LayoutUnit ComputeFloatOffsetForFloatLayoutAdapter::heightRemaining() const { - return this->m_outermostFloat ? this->m_renderer.logicalBottomForFloat(this->m_outermostFloat) - this->m_lineTop : LayoutUnit::fromPixel(1); + return this->m_outermostFloat ? this->m_renderer->logicalBottomForFloat(this->m_outermostFloat) - this->m_lineTop : LayoutUnit::fromPixel(1); } template @@ -474,9 +474,9 @@ inline void ComputeFloatOffsetAdapter::collectIfNeeded(const Int // All the objects returned from the tree should be already placed. ASSERT(floatingObject->isPlaced()); #if !PLATFORM(WKC) - ASSERT(rangesIntersect(m_renderer.logicalTopForFloat(floatingObject), m_renderer.logicalBottomForFloat(floatingObject), m_lineTop, m_lineBottom)); + ASSERT(rangesIntersect(m_renderer->logicalTopForFloat(floatingObject), m_renderer->logicalBottomForFloat(floatingObject), m_lineTop, m_lineBottom)); #else - if (!rangesIntersect(m_renderer.logicalTopForFloat(floatingObject), m_renderer.logicalBottomForFloat(floatingObject), m_lineTop, m_lineBottom)) + if (!rangesIntersect(m_renderer->logicalTopForFloat(floatingObject), m_renderer->logicalBottomForFloat(floatingObject), m_lineTop, m_lineBottom)) return; #endif @@ -488,10 +488,10 @@ inline void ComputeFloatOffsetAdapter::collectIfNeeded(const Int template<> inline bool ComputeFloatOffsetForLineLayoutAdapter::updateOffsetIfNeeded(const FloatingObject& floatingObject) { - LayoutUnit logicalRight = m_renderer.logicalRightForFloat(&floatingObject); + LayoutUnit logicalRight = m_renderer->logicalRightForFloat(&floatingObject); #if ENABLE(CSS_SHAPES) if (ShapeOutsideInfo* shapeOutside = floatingObject.renderer().shapeOutsideInfo()) { - ShapeOutsideDeltas shapeDeltas = shapeOutside->computeDeltasForContainingBlockLine(m_renderer, floatingObject, m_lineTop, m_lineBottom - m_lineTop); + ShapeOutsideDeltas shapeDeltas = shapeOutside->computeDeltasForContainingBlockLine(*m_renderer, floatingObject, m_lineTop, m_lineBottom - m_lineTop); if (!shapeDeltas.lineOverlapsShape()) return false; @@ -509,10 +509,10 @@ inline bool ComputeFloatOffsetForLineLayoutAdapter::u template<> inline bool ComputeFloatOffsetForLineLayoutAdapter::updateOffsetIfNeeded(const FloatingObject& floatingObject) { - LayoutUnit logicalLeft = m_renderer.logicalLeftForFloat(&floatingObject); + LayoutUnit logicalLeft = m_renderer->logicalLeftForFloat(&floatingObject); #if ENABLE(CSS_SHAPES) if (ShapeOutsideInfo* shapeOutside = floatingObject.renderer().shapeOutsideInfo()) { - ShapeOutsideDeltas shapeDeltas = shapeOutside->computeDeltasForContainingBlockLine(m_renderer, floatingObject, m_lineTop, m_lineBottom - m_lineTop); + ShapeOutsideDeltas shapeDeltas = shapeOutside->computeDeltasForContainingBlockLine(*m_renderer, floatingObject, m_lineTop, m_lineBottom - m_lineTop); if (!shapeDeltas.lineOverlapsShape()) return false; diff --git a/webkit/WebCore/rendering/FloatingObjects.h b/webkit/WebCore/rendering/FloatingObjects.h index 1f574ae56..fb217d37c 100644 --- a/webkit/WebCore/rendering/FloatingObjects.h +++ b/webkit/WebCore/rendering/FloatingObjects.h @@ -47,7 +47,7 @@ class FloatingObject { FloatingObject(RenderBox&, Type, const LayoutRect&, bool shouldPaint, bool isDescendant); Type type() const { return static_cast(m_type); } - RenderBox& renderer() const { return m_renderer; } + RenderBox& renderer() const { return *m_renderer; } bool isPlaced() const { return m_isPlaced; } void setIsPlaced(bool placed = true) { m_isPlaced = placed; } @@ -85,7 +85,7 @@ class FloatingObject { void setOriginatingLine(RootInlineBox* line) { m_originatingLine = line; } private: - RenderBox& m_renderer; + WeakPtr m_renderer; RootInlineBox* m_originatingLine; LayoutRect m_frameRect; LayoutUnit m_paginationStrut; @@ -149,6 +149,7 @@ class FloatingObjects { LayoutUnit findNextFloatLogicalBottomBelowForBlock(LayoutUnit logicalHeight); private: + RenderBlockFlow& renderer() const { return *m_renderer; } void computePlacedFloatsTree(); const FloatingObjectTree* placedFloatsTree(); void increaseObjectsCount(FloatingObject::Type); @@ -160,7 +161,7 @@ class FloatingObjects { unsigned m_leftObjectsCount; unsigned m_rightObjectsCount; bool m_horizontalWritingMode; - const RenderBlockFlow& m_renderer; + WeakPtr m_renderer; }; #ifndef NDEBUG diff --git a/webkit/WebCore/rendering/RenderBlockFlow.cpp b/webkit/WebCore/rendering/RenderBlockFlow.cpp index 7e9e98340..09469ced0 100644 --- a/webkit/WebCore/rendering/RenderBlockFlow.cpp +++ b/webkit/WebCore/rendering/RenderBlockFlow.cpp @@ -104,6 +104,9 @@ RenderBlockFlow::RenderBlockFlow(Element& element, Ref&& style) , m_widthForTextAutosizing(-1) , m_lineCountForTextAutosizing(NOT_SET) #endif +#if PLATFORM(WKC) + , m_weakFactory(this) +#endif { setChildrenInline(true); } @@ -114,6 +117,9 @@ RenderBlockFlow::RenderBlockFlow(Document& document, Ref&& style) , m_widthForTextAutosizing(-1) , m_lineCountForTextAutosizing(NOT_SET) #endif +#if PLATFORM(WKC) + , m_weakFactory(this) +#endif { setChildrenInline(true); } diff --git a/webkit/WebCore/rendering/RenderBlockFlow.h b/webkit/WebCore/rendering/RenderBlockFlow.h index 5a616b284..ba17ae0e0 100644 --- a/webkit/WebCore/rendering/RenderBlockFlow.h +++ b/webkit/WebCore/rendering/RenderBlockFlow.h @@ -623,6 +623,10 @@ class RenderBlockFlow : public RenderBlock { } #endif +#if PLATFORM(WKC) + WeakPtr createWeakPtr() { return m_weakFactory.createWeakPtr(); } +#endif + protected: std::unique_ptr m_floatingObjects; std::unique_ptr m_rareBlockFlowData; @@ -631,6 +635,11 @@ class RenderBlockFlow : public RenderBlock { friend class LineBreaker; friend class LineWidth; // Needs to know FloatingObject + +#if PLATFORM(WKC) +private: + WeakPtrFactory m_weakFactory; +#endif }; inline bool RenderElement::isRenderNamedFlowFragmentContainer() const diff --git a/webkit/WebCore/rendering/RenderBox.cpp b/webkit/WebCore/rendering/RenderBox.cpp index ba70efea6..60f1a8251 100644 --- a/webkit/WebCore/rendering/RenderBox.cpp +++ b/webkit/WebCore/rendering/RenderBox.cpp @@ -79,7 +79,11 @@ struct SameSizeAsRenderBox : public RenderBoxModelObject { LayoutRect frameRect; LayoutBoxExtent marginBox; LayoutUnit preferredLogicalWidths[2]; +#if PLATFORM(WKC) + void* pointers[3]; +#else void* pointers[2]; +#endif }; COMPILE_ASSERT(sizeof(RenderBox) == sizeof(SameSizeAsRenderBox), RenderBox_should_stay_small); @@ -134,6 +138,9 @@ RenderBox::RenderBox(Element& element, Ref&& style, unsigned baseTy , m_minPreferredLogicalWidth(-1) , m_maxPreferredLogicalWidth(-1) , m_inlineBoxWrapper(nullptr) +#if PLATFORM(WKC) + , m_weakFactory(this) +#endif { setIsBox(); } @@ -143,6 +150,9 @@ RenderBox::RenderBox(Document& document, Ref&& style, unsigned base , m_minPreferredLogicalWidth(-1) , m_maxPreferredLogicalWidth(-1) , m_inlineBoxWrapper(nullptr) +#if PLATFORM(WKC) + , m_weakFactory(this) +#endif { setIsBox(); } diff --git a/webkit/WebCore/rendering/RenderBox.h b/webkit/WebCore/rendering/RenderBox.h index ad546331e..001f948d4 100644 --- a/webkit/WebCore/rendering/RenderBox.h +++ b/webkit/WebCore/rendering/RenderBox.h @@ -641,6 +641,10 @@ class RenderBox : public RenderBoxModelObject { const RenderBox* findEnclosingScrollableContainer() const; +#if PLATFORM(WKC) + WeakPtr createWeakPtr() { return m_weakFactory.createWeakPtr(); } +#endif + protected: RenderBox(Element&, Ref&&, unsigned baseTypeFlags); RenderBox(Document&, Ref&&, unsigned baseTypeFlags); @@ -763,6 +767,7 @@ class RenderBox : public RenderBoxModelObject { static bool s_hadOverflowClip; #else WKC_DEFINE_GLOBAL_CLASS_OBJ_ENTRY(bool, s_hadOverflowClip); + WeakPtrFactory m_weakFactory; #endif }; diff --git a/webkit/WebCore/rendering/RenderBoxModelObject.cpp b/webkit/WebCore/rendering/RenderBoxModelObject.cpp index fd9f60f2b..37e1b6027 100644 --- a/webkit/WebCore/rendering/RenderBoxModelObject.cpp +++ b/webkit/WebCore/rendering/RenderBoxModelObject.cpp @@ -2448,7 +2448,9 @@ void RenderBoxModelObject::paintBoxShadow(const PaintInfo& info, const LayoutRec LayoutUnit RenderBoxModelObject::containingBlockLogicalWidthForContent() const { - return containingBlock()->availableLogicalWidth(); + if (auto* containingBlock = this->containingBlock()) + return containingBlock->availableLogicalWidth(); + return { }; } RenderBoxModelObject* RenderBoxModelObject::continuation() const diff --git a/webkit/WebCore/rendering/RenderLayer.cpp b/webkit/WebCore/rendering/RenderLayer.cpp index 0bb898926..f4ba60bc7 100644 --- a/webkit/WebCore/rendering/RenderLayer.cpp +++ b/webkit/WebCore/rendering/RenderLayer.cpp @@ -2457,7 +2457,7 @@ void RenderLayer::scrollTo(int x, int y) #if ENABLE(DASHBOARD_SUPPORT) view.frameView().updateAnnotatedRegions(); #endif - view.frameView().updateWidgetPositions(); + view.frameView().scheduleUpdateWidgetPositions(); if (!m_updatingMarqueePosition) { // Avoid updating compositing layers if, higher on the stack, we're already updating layer diff --git a/webkit/WebCore/rendering/RenderTableCaption.h b/webkit/WebCore/rendering/RenderTableCaption.h index ee614262a..a26216075 100644 --- a/webkit/WebCore/rendering/RenderTableCaption.h +++ b/webkit/WebCore/rendering/RenderTableCaption.h @@ -33,7 +33,7 @@ class RenderTableCaption final : public RenderBlockFlow { Element& element() const { return downcast(nodeForNonAnonymous()); } - virtual LayoutUnit containingBlockLogicalWidthForContent() const override { return containingBlock()->logicalWidth(); } + virtual LayoutUnit containingBlockLogicalWidthForContent() const override; private: virtual bool isTableCaption() const override { return true; } @@ -44,6 +44,13 @@ class RenderTableCaption final : public RenderBlockFlow { RenderTable* table() const; }; +inline LayoutUnit RenderTableCaption::containingBlockLogicalWidthForContent() const +{ + if (auto* containingBlock = this->containingBlock()) + return containingBlock->logicalWidth(); + return { }; +} + } // namespace WebCore SPECIALIZE_TYPE_TRAITS_RENDER_OBJECT(RenderTableCaption, isTableCaption()) diff --git a/webkit/WebCore/svg/SVGAnimateElementBase.cpp b/webkit/WebCore/svg/SVGAnimateElementBase.cpp index 9f0b85016..703c7d06f 100644 --- a/webkit/WebCore/svg/SVGAnimateElementBase.cpp +++ b/webkit/WebCore/svg/SVGAnimateElementBase.cpp @@ -305,6 +305,11 @@ void SVGAnimateElementBase::clearAnimatedType(SVGElement* targetElement) if (!m_animatedType) return; + // If the SVGAnimatedType is a list type, e.g. SVGLengthListValues, the wrappers of the + // animated properties have to be detached from the items in the list before it's deleted. + if (!m_animatedProperties.isEmpty()) + m_animator->animValWillChange(m_animatedProperties); + if (!targetElement) { m_animatedType = nullptr; return; diff --git a/webkit/WebCore/svg/SVGPathElement.cpp b/webkit/WebCore/svg/SVGPathElement.cpp index c95744939..356360b78 100644 --- a/webkit/WebCore/svg/SVGPathElement.cpp +++ b/webkit/WebCore/svg/SVGPathElement.cpp @@ -401,9 +401,11 @@ FloatRect SVGPathElement::getBBox(StyleUpdateStrategy styleUpdateStrategy) RenderSVGPath* renderer = downcast(this->renderer()); - // FIXME: Eventually we should support getBBox for detached elements. - if (!renderer) - return FloatRect(); + // FIXME: Eventually we should support getBBox for detached elements. + // FIXME: If the path is null it means we're calling getBBox() before laying out this element, + // which is an error. + if (!renderer || !renderer->hasPath()) + return { }; return renderer->path().boundingRect(); } diff --git a/webkit/WebCore/workers/DedicatedWorkerGlobalScope.idl b/webkit/WebCore/workers/DedicatedWorkerGlobalScope.idl index 01f3739cb..066cdfec4 100644 --- a/webkit/WebCore/workers/DedicatedWorkerGlobalScope.idl +++ b/webkit/WebCore/workers/DedicatedWorkerGlobalScope.idl @@ -41,6 +41,8 @@ [RaisesException] void postMessage(DOMString message, optional MessagePort messagePort); #endif + void close(); + attribute EventHandler onmessage; }; diff --git a/webkit/WebCore/workers/WorkerGlobalScope.idl b/webkit/WebCore/workers/WorkerGlobalScope.idl index c704c89a9..13c20b76d 100644 --- a/webkit/WebCore/workers/WorkerGlobalScope.idl +++ b/webkit/WebCore/workers/WorkerGlobalScope.idl @@ -37,7 +37,6 @@ readonly attribute WorkerGlobalScope self; #endif readonly attribute WorkerLocation location; - void close(); attribute EventHandler onerror; attribute EventHandler onoffline; diff --git a/webkit/WebCore/xml/XMLHttpRequest.cpp b/webkit/WebCore/xml/XMLHttpRequest.cpp index d79e50d33..129fb165e 100644 --- a/webkit/WebCore/xml/XMLHttpRequest.cpp +++ b/webkit/WebCore/xml/XMLHttpRequest.cpp @@ -503,12 +503,7 @@ void XMLHttpRequest::open(const String& method, const URL& url, bool async, Exce } // FIXME: Convert this to check the isolated world's Content Security Policy once webkit.org/b/104520 is solved. - bool shouldBypassMainWorldContentSecurityPolicy = false; - if (is(*scriptExecutionContext())) { - Document& document = downcast(*scriptExecutionContext()); - if (document.frame()) - shouldBypassMainWorldContentSecurityPolicy = document.frame()->script().shouldBypassMainWorldContentSecurityPolicy(); - } + bool shouldBypassMainWorldContentSecurityPolicy = ContentSecurityPolicy::shouldBypassMainWorldContentSecurityPolicy(*scriptExecutionContext()); if (!scriptExecutionContext()->contentSecurityPolicy()->allowConnectToSource(url, shouldBypassMainWorldContentSecurityPolicy)) { // FIXME: Should this be throwing an exception? ec = SECURITY_ERR;