Changeset 232081 in webkit
- Timestamp:
- May 22, 2018 3:01:34 PM (6 years ago)
- Location:
- trunk/Source/WebCore
- Files:
-
- 7 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/Source/WebCore/ChangeLog
r232079 r232081 1 2018-05-22 Brent Fulgham <bfulgham@apple.com> 2 3 Avoid keeping FormState alive longer than necessary 4 https://bugs.webkit.org/show_bug.cgi?id=185877 5 <rdar://problem/39329219> 6 7 Reviewed by Ryosuke Niwa. 8 9 A number of crash fixes were done to prevent FormState objects from being 10 accessed after their relevant Frames had been destroyed. Unfortunately, this 11 could cause the FormState to persist after the owning Frame had been 12 destroyed, resulting in nullptr dereferences. 13 14 This patch does the following: 15 16 1. Changes to use WeakPtr's for FormState objects passed to completion handlers, 17 rather than RefPtr, since those completion handlers might fire as part of 18 the clean-up process during Frame destruction. This allows us to use the FormState 19 if they are still valid, but gracefully handle cases where a form submission 20 is cancelled in-flight. 21 2. Removes some extraneous WTFMove() calls being made on bare FormState pointers. 22 3. Changes the trap from Bug 183704 so that it only fires if the FormState object 23 is being retained more than once. 24 25 * loader/DocumentLoader.cpp: 26 (WebCore::DocumentLoader::willSendRequest): Update for new CompletionHandler 27 signature. 28 * loader/FormState.cpp: 29 (WebCore::FormState::willDetachPage): Revise trap to check for retain counts 30 above one. 31 * loader/FormState.h: 32 (WebCore::FormState::weakPtrFactory const): Added. 33 * loader/FrameLoader.cpp: 34 (WebCore::FrameLoader::loadFrameRequest): Revise to use WeakPtr for FormState 35 passed to the completion handler. 36 (WebCore::FrameLoader::loadURL): Update for new CompletionHandler signature. 37 (WebCore::FrameLoader::load): Ditto. 38 (WebCore::FrameLoader::loadWithDocumentLoader): Ditto. 39 (WebCore::FrameLoader::loadPostRequest): Ditto. 40 * loader/PolicyChecker.cpp: 41 (WebCore::PolicyChecker::checkNavigationPolicy): Revise to use WeakPtr for 42 FormState passed to the completion handler. Remove some extraneous WTFMove() 43 calls on bare pointers. 44 (WebCore::PolicyChecker::checkNewWindowPolicy): Ditto. 45 * loader/PolicyChecker.h: 46 1 47 2018-05-22 Sihui Liu <sihui_liu@apple.com> 2 48 -
trunk/Source/WebCore/loader/DocumentLoader.cpp
r232032 r232081 1 1 /* 2 * Copyright (C) 2006-201 7Apple Inc. All rights reserved.2 * Copyright (C) 2006-2018 Apple Inc. All rights reserved. 3 3 * Copyright (C) 2011 Google Inc. All rights reserved. 4 4 * … … 641 641 return completionHandler(WTFMove(newRequest)); 642 642 643 auto navigationPolicyCompletionHandler = [this, protectedThis = makeRef(*this), completionHandler = WTFMove(completionHandler)] (ResourceRequest&& request, FormState*, ShouldContinue shouldContinue) mutable {643 auto navigationPolicyCompletionHandler = [this, protectedThis = makeRef(*this), completionHandler = WTFMove(completionHandler)] (ResourceRequest&& request, WeakPtr<FormState>&&, ShouldContinue shouldContinue) mutable { 644 644 m_waitingForNavigationPolicy = false; 645 645 switch (shouldContinue) { -
trunk/Source/WebCore/loader/FormState.cpp
r229683 r232081 1 1 /* 2 * Copyright (C) 2006-201 7Apple Inc. All rights reserved.2 * Copyright (C) 2006-2018 Apple Inc. All rights reserved. 3 3 * 4 4 * Redistribution and use in source and binary forms, with or without … … 53 53 { 54 54 // Beartrap for <rdar://problem/37579354> 55 RELEASE_ASSERT _NOT_REACHED();55 RELEASE_ASSERT(hasOneRef()); 56 56 } 57 57 -
trunk/Source/WebCore/loader/FormState.h
r229683 r232081 1 1 /* 2 * Copyright (C) 2006-201 7Apple Inc. All rights reserved.2 * Copyright (C) 2006-2018 Apple Inc. All rights reserved. 3 3 * 4 4 * Redistribution and use in source and binary forms, with or without … … 30 30 31 31 #include "FrameDestructionObserver.h" 32 #include <wtf/WeakPtr.h> 32 33 #include <wtf/text/WTFString.h> 33 34 … … 50 51 FormSubmissionTrigger formSubmissionTrigger() const { return m_formSubmissionTrigger; } 51 52 53 auto& weakPtrFactory() const { return m_weakFactory; } 54 52 55 private: 53 56 FormState(HTMLFormElement&, StringPairVector&& textFieldValues, Document&, FormSubmissionTrigger); … … 58 61 Ref<Document> m_sourceDocument; 59 62 FormSubmissionTrigger m_formSubmissionTrigger; 63 WeakPtrFactory<FormState> m_weakFactory; 60 64 }; 61 65 -
trunk/Source/WebCore/loader/FrameLoader.cpp
r232019 r232081 1 1 /* 2 * Copyright (C) 2006-201 6Apple Inc. All rights reserved.2 * Copyright (C) 2006-2018 Apple Inc. All rights reserved. 3 3 * Copyright (C) 2008 Nokia Corporation and/or its subsidiary(-ies) 4 4 * Copyright (C) 2008, 2009 Torch Mobile Inc. All rights reserved. (http://www.torchmobile.com/) … … 1229 1229 loadType = FrameLoadType::Standard; 1230 1230 1231 auto completionHandler = [this, protectedFrame = makeRef(m_frame), formState = make RefPtr(formState), frameName = request.frameName()] {1231 auto completionHandler = [this, protectedFrame = makeRef(m_frame), formState = makeWeakPtr(formState), frameName = request.frameName()] { 1232 1232 // FIXME: It's possible this targetFrame will not be the same frame that was targeted by the actual 1233 1233 // load if frame names have changed. … … 1339 1339 if (!targetFrame && !frameName.isEmpty()) { 1340 1340 action = action.copyWithShouldOpenExternalURLsPolicy(shouldOpenExternalURLsPolicyToApply(m_frame, frameLoadRequest)); 1341 policyChecker().checkNewWindowPolicy(WTFMove(action), WTFMove(request), formState, frameName, [this, allowNavigationToInvalidURL, openerPolicy, completionHandler = completionHandlerCaller.release()] (const ResourceRequest& request, FormState*formState, const String& frameName, const NavigationAction& action, ShouldContinue shouldContinue) {1342 continueLoadAfterNewWindowPolicy(request, formState , frameName, action, shouldContinue, allowNavigationToInvalidURL, openerPolicy);1341 policyChecker().checkNewWindowPolicy(WTFMove(action), WTFMove(request), formState, frameName, [this, allowNavigationToInvalidURL, openerPolicy, completionHandler = completionHandlerCaller.release()] (const ResourceRequest& request, WeakPtr<FormState>&& formState, const String& frameName, const NavigationAction& action, ShouldContinue shouldContinue) { 1342 continueLoadAfterNewWindowPolicy(request, formState.get(), frameName, action, shouldContinue, allowNavigationToInvalidURL, openerPolicy); 1343 1343 completionHandler(); 1344 1344 }); … … 1359 1359 policyChecker().stopCheck(); 1360 1360 policyChecker().setLoadType(newLoadType); 1361 policyChecker().checkNavigationPolicy(WTFMove(request), false /* didReceiveRedirectResponse */, oldDocumentLoader.get(), formState, [this, protectedFrame = makeRef(m_frame)] (const ResourceRequest& request, FormState*, ShouldContinue shouldContinue) {1361 policyChecker().checkNavigationPolicy(WTFMove(request), false /* didReceiveRedirectResponse */, oldDocumentLoader.get(), formState, [this, protectedFrame = makeRef(m_frame)] (const ResourceRequest& request, WeakPtr<FormState>&&, ShouldContinue shouldContinue) { 1362 1362 continueFragmentScrollAfterNavigationPolicy(request, shouldContinue == ShouldContinue::Yes); 1363 1363 }, PolicyDecisionMode::Synchronous); … … 1415 1415 if (request.shouldCheckNewWindowPolicy()) { 1416 1416 NavigationAction action { request.requester(), request.resourceRequest(), InitiatedByMainFrame::Unknown, NavigationType::Other, request.shouldOpenExternalURLsPolicy() }; 1417 policyChecker().checkNewWindowPolicy(WTFMove(action), WTFMove(request.resourceRequest()), nullptr, request.frameName(), [this] (const ResourceRequest& request, FormState*formState, const String& frameName, const NavigationAction& action, ShouldContinue shouldContinue) {1418 continueLoadAfterNewWindowPolicy(request, formState , frameName, action, shouldContinue, AllowNavigationToInvalidURL::Yes, NewFrameOpenerPolicy::Suppress);1417 policyChecker().checkNewWindowPolicy(WTFMove(action), WTFMove(request.resourceRequest()), nullptr, request.frameName(), [this] (const ResourceRequest& request, WeakPtr<FormState>&& formState, const String& frameName, const NavigationAction& action, ShouldContinue shouldContinue) { 1418 continueLoadAfterNewWindowPolicy(request, formState.get(), frameName, action, shouldContinue, AllowNavigationToInvalidURL::Yes, NewFrameOpenerPolicy::Suppress); 1419 1419 }); 1420 1420 … … 1529 1529 oldDocumentLoader->setLastCheckedRequest(ResourceRequest()); 1530 1530 policyChecker().stopCheck(); 1531 policyChecker().checkNavigationPolicy(ResourceRequest(loader->request()), false /* didReceiveRedirectResponse */, oldDocumentLoader.get(), formState, [this, protectedFrame = makeRef(m_frame)] (const ResourceRequest& request, FormState*, ShouldContinue shouldContinue) {1531 policyChecker().checkNavigationPolicy(ResourceRequest(loader->request()), false /* didReceiveRedirectResponse */, oldDocumentLoader.get(), formState, [this, protectedFrame = makeRef(m_frame)] (const ResourceRequest& request, WeakPtr<FormState>&&, ShouldContinue shouldContinue) { 1532 1532 continueFragmentScrollAfterNavigationPolicy(request, shouldContinue == ShouldContinue::Yes); 1533 1533 }, PolicyDecisionMode::Synchronous); … … 1563 1563 } 1564 1564 1565 policyChecker().checkNavigationPolicy(ResourceRequest(loader->request()), false /* didReceiveRedirectResponse */, loader, formState, [this, protectedFrame = makeRef(m_frame), allowNavigationToInvalidURL, completionHandler = completionHandlerCaller.release()] (const ResourceRequest& request, FormState*formState, ShouldContinue shouldContinue) {1566 continueLoadAfterNavigationPolicy(request, formState , shouldContinue, allowNavigationToInvalidURL);1565 policyChecker().checkNavigationPolicy(ResourceRequest(loader->request()), false /* didReceiveRedirectResponse */, loader, formState, [this, protectedFrame = makeRef(m_frame), allowNavigationToInvalidURL, completionHandler = completionHandlerCaller.release()] (const ResourceRequest& request, WeakPtr<FormState>&& formState, ShouldContinue shouldContinue) { 1566 continueLoadAfterNavigationPolicy(request, formState.get(), shouldContinue, allowNavigationToInvalidURL); 1567 1567 completionHandler(); 1568 1568 }); … … 2857 2857 if (!frameName.isEmpty()) { 2858 2858 // The search for a target frame is done earlier in the case of form submission. 2859 if ( Frame* targetFrame = formState ? 0: findFrameForNavigation(frameName)) {2860 targetFrame->loader().loadWithNavigationAction(workingResourceRequest, action, lockHistory, loadType, WTFMove(formState), allowNavigationToInvalidURL, WTFMove(completionHandler));2859 if (auto* targetFrame = formState ? nullptr : findFrameForNavigation(frameName)) { 2860 targetFrame->loader().loadWithNavigationAction(workingResourceRequest, action, lockHistory, loadType, formState, allowNavigationToInvalidURL, WTFMove(completionHandler)); 2861 2861 return; 2862 2862 } 2863 2863 2864 policyChecker().checkNewWindowPolicy(WTFMove(action), WTFMove(workingResourceRequest), WTFMove(formState), frameName, [this, allowNavigationToInvalidURL, openerPolicy, completionHandler = WTFMove(completionHandler)] (const ResourceRequest& request, FormState*formState, const String& frameName, const NavigationAction& action, ShouldContinue shouldContinue) {2865 continueLoadAfterNewWindowPolicy(request, formState , frameName, action, shouldContinue, allowNavigationToInvalidURL, openerPolicy);2864 policyChecker().checkNewWindowPolicy(WTFMove(action), WTFMove(workingResourceRequest), formState, frameName, [this, allowNavigationToInvalidURL, openerPolicy, completionHandler = WTFMove(completionHandler)] (const ResourceRequest& request, WeakPtr<FormState>&& formState, const String& frameName, const NavigationAction& action, ShouldContinue shouldContinue) { 2865 continueLoadAfterNewWindowPolicy(request, formState.get(), frameName, action, shouldContinue, allowNavigationToInvalidURL, openerPolicy); 2866 2866 completionHandler(); 2867 2867 }); … … 2871 2871 // must grab this now, since this load may stop the previous load and clear this flag 2872 2872 bool isRedirect = m_quickRedirectComing; 2873 loadWithNavigationAction(workingResourceRequest, action, lockHistory, loadType, WTFMove(formState), allowNavigationToInvalidURL, [this, isRedirect, protectedFrame = makeRef(m_frame), completionHandler = WTFMove(completionHandler)] {2873 loadWithNavigationAction(workingResourceRequest, action, lockHistory, loadType, formState, allowNavigationToInvalidURL, [this, isRedirect, protectedFrame = makeRef(m_frame), completionHandler = WTFMove(completionHandler)] { 2874 2874 if (isRedirect) { 2875 2875 m_quickRedirectComing = false; -
trunk/Source/WebCore/loader/PolicyChecker.cpp
r231813 r232081 1 1 /* 2 * Copyright (C) 2006-201 6Apple Inc. All rights reserved.2 * Copyright (C) 2006-2018 Apple Inc. All rights reserved. 3 3 * Copyright (C) 2008 Nokia Corporation and/or its subsidiary(-ies) 4 4 * Copyright (C) 2008, 2009 Torch Mobile Inc. All rights reserved. (http://www.torchmobile.com/) … … 110 110 // This avoids confusion on the part of the client. 111 111 if (equalIgnoringHeaderFields(request, loader->lastCheckedRequest()) || (!request.isNull() && request.url().isEmpty())) { 112 function(ResourceRequest(request), nullptr, ShouldContinue::Yes);112 function(ResourceRequest(request), { }, ShouldContinue::Yes); 113 113 loader->setLastCheckedRequest(WTFMove(request)); 114 114 return; … … 125 125 if (isBackForwardLoadType(m_loadType)) 126 126 m_loadType = FrameLoadType::Reload; 127 function(WTFMove(request), nullptr, shouldContinue ? ShouldContinue::Yes : ShouldContinue::No);127 function(WTFMove(request), { }, shouldContinue ? ShouldContinue::Yes : ShouldContinue::No); 128 128 return; 129 129 } … … 135 135 m_frame.ownerElement()->dispatchEvent(Event::create(eventNames().loadEvent, false, false)); 136 136 } 137 function(WTFMove(request), nullptr, ShouldContinue::No);137 function(WTFMove(request), { }, ShouldContinue::No); 138 138 return; 139 139 } … … 148 148 // Always allow QuickLook-generated URLs based on the protocol scheme. 149 149 if (!request.isNull() && isQuickLookPreviewURL(request.url())) 150 return function(WTFMove(request), formState, ShouldContinue::Yes);150 return function(WTFMove(request), makeWeakPtr(formState), ShouldContinue::Yes); 151 151 #endif 152 152 … … 169 169 m_delegateIsDecidingNavigationPolicy = true; 170 170 String suggestedFilename = action.downloadAttribute().isEmpty() ? nullAtom() : action.downloadAttribute(); 171 m_frame.loader().client().dispatchDecidePolicyForNavigationAction(action, request, didReceiveRedirectResponse, formState, policyDecisionMode, [this, function = WTFMove(function), request = ResourceRequest(request), formState = make RefPtr(formState), suggestedFilename = WTFMove(suggestedFilename), blobURLLifetimeExtension = WTFMove(blobURLLifetimeExtension)](PolicyAction policyAction) mutable {171 m_frame.loader().client().dispatchDecidePolicyForNavigationAction(action, request, didReceiveRedirectResponse, formState, policyDecisionMode, [this, function = WTFMove(function), request = ResourceRequest(request), formState = makeWeakPtr(formState), suggestedFilename = WTFMove(suggestedFilename), blobURLLifetimeExtension = WTFMove(blobURLLifetimeExtension)](PolicyAction policyAction) mutable { 172 172 m_delegateIsDecidingNavigationPolicy = false; 173 173 … … 186 186 return function({ }, nullptr, ShouldContinue::No); 187 187 } 188 return function(WTFMove(request), formState.get(), ShouldContinue::Yes);188 return function(WTFMove(request), WTFMove(formState), ShouldContinue::Yes); 189 189 } 190 190 ASSERT_NOT_REACHED(); … … 202 202 auto blobURLLifetimeExtension = extendBlobURLLifetimeIfNecessary(request); 203 203 204 m_frame.loader().client().dispatchDecidePolicyForNewWindowAction(navigationAction, request, formState, frameName, [frame = makeRef(m_frame), request, formState = make RefPtr(formState), frameName, navigationAction, function = WTFMove(function), blobURLLifetimeExtension = WTFMove(blobURLLifetimeExtension)](PolicyAction policyAction) mutable {204 m_frame.loader().client().dispatchDecidePolicyForNewWindowAction(navigationAction, request, formState, frameName, [frame = makeRef(m_frame), request, formState = makeWeakPtr(formState), frameName, navigationAction, function = WTFMove(function), blobURLLifetimeExtension = WTFMove(blobURLLifetimeExtension)](PolicyAction policyAction) mutable { 205 205 switch (policyAction) { 206 206 case PolicyAction::Download: … … 214 214 RELEASE_ASSERT_NOT_REACHED(); 215 215 case PolicyAction::Use: 216 function(request, formState.get(), frameName, navigationAction, ShouldContinue::Yes);216 function(request, WTFMove(formState), frameName, navigationAction, ShouldContinue::Yes); 217 217 return; 218 218 } -
trunk/Source/WebCore/loader/PolicyChecker.h
r231714 r232081 1 1 /* 2 * Copyright (C) 2006-201 6Apple Inc. All rights reserved.2 * Copyright (C) 2006-2018 Apple Inc. All rights reserved. 3 3 * Copyright (C) 2008, 2009 Torch Mobile Inc. All rights reserved. (http://www.torchmobile.com/) 4 4 * … … 32 32 #include "FrameLoaderTypes.h" 33 33 #include "ResourceRequest.h" 34 #include <wtf/WeakPtr.h> 34 35 #include <wtf/text/WTFString.h> 35 36 … … 60 61 enum class PolicyDecisionMode { Synchronous, Asynchronous }; 61 62 62 using NewWindowPolicyDecisionFunction = CompletionHandler<void(const ResourceRequest&, FormState*, const String& frameName, const NavigationAction&, ShouldContinue)>;63 using NavigationPolicyDecisionFunction = CompletionHandler<void(ResourceRequest&&, FormState*, ShouldContinue)>;63 using NewWindowPolicyDecisionFunction = CompletionHandler<void(const ResourceRequest&, WeakPtr<FormState>&&, const String& frameName, const NavigationAction&, ShouldContinue)>; 64 using NavigationPolicyDecisionFunction = CompletionHandler<void(ResourceRequest&&, WeakPtr<FormState>&&, ShouldContinue)>; 64 65 65 66 class PolicyChecker {
Note: See TracChangeset
for help on using the changeset viewer.