Layout Test fast/events/beforeunload-dom-manipulation-crash.html is crashing
[WebKit-https.git] / Source / WebCore / loader / FrameLoader.h
1 /*
2  * Copyright (C) 2006-2016 Apple Inc. All rights reserved.
3  * Copyright (C) 2008, 2009 Torch Mobile Inc. All rights reserved. (http://www.torchmobile.com/)
4  * Copyright (C) Research In Motion Limited 2009. All rights reserved.
5  * Copyright (C) 2011 Google Inc. All rights reserved.
6  *
7  * Redistribution and use in source and binary forms, with or without
8  * modification, are permitted provided that the following conditions
9  * are met:
10  *
11  * 1.  Redistributions of source code must retain the above copyright
12  *     notice, this list of conditions and the following disclaimer. 
13  * 2.  Redistributions in binary form must reproduce the above copyright
14  *     notice, this list of conditions and the following disclaimer in the
15  *     documentation and/or other materials provided with the distribution. 
16  * 3.  Neither the name of Apple Inc. ("Apple") nor the names of
17  *     its contributors may be used to endorse or promote products derived
18  *     from this software without specific prior written permission. 
19  *
20  * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY
21  * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
22  * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
23  * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY
24  * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
25  * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
26  * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
27  * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
28  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
29  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
30  */
31
32 #pragma once
33
34 #include "CachePolicy.h"
35 #include "FrameLoaderStateMachine.h"
36 #include "FrameLoaderTypes.h"
37 #include "LayoutMilestones.h"
38 #include "MixedContentChecker.h"
39 #include "ReferrerPolicy.h"
40 #include "ResourceLoadNotifier.h"
41 #include "ResourceLoaderOptions.h"
42 #include "ResourceRequestBase.h"
43 #include "SecurityContext.h"
44 #include "StoredCredentialsPolicy.h"
45 #include "Timer.h"
46 #include <wtf/Forward.h>
47 #include <wtf/HashSet.h>
48 #include <wtf/OptionSet.h>
49 #include <wtf/Optional.h>
50
51 namespace WebCore {
52
53 class Archive;
54 class CachedFrame;
55 class CachedFrameBase;
56 class CachedPage;
57 class CachedResource;
58 class Chrome;
59 class DOMWrapperWorld;
60 class Document;
61 class DocumentLoader;
62 class Event;
63 class FormState;
64 class FormSubmission;
65 class FrameLoadRequest;
66 class FrameLoaderClient;
67 class FrameNetworkingContext;
68 class HistoryController;
69 class HistoryItem;
70 class NavigationAction;
71 class NetworkingContext;
72 class Page;
73 class PolicyChecker;
74 class ResourceError;
75 class ResourceRequest;
76 class ResourceResponse;
77 class SerializedScriptValue;
78 class SharedBuffer;
79 class SubframeLoader;
80 class SubstituteData;
81
82 struct WindowFeatures;
83
84 WEBCORE_EXPORT bool isBackForwardLoadType(FrameLoadType);
85 WEBCORE_EXPORT bool isReload(FrameLoadType);
86
87 using ContentPolicyDecisionFunction = WTF::Function<void(PolicyAction)>;
88
89 class FrameLoader {
90     WTF_MAKE_NONCOPYABLE(FrameLoader);
91 public:
92     FrameLoader(Frame&, FrameLoaderClient&);
93     ~FrameLoader();
94
95     WEBCORE_EXPORT void init();
96     void initForSynthesizedDocument(const URL&);
97
98     Frame& frame() const { return m_frame; }
99
100     PolicyChecker& policyChecker() const { return *m_policyChecker; }
101     HistoryController& history() const { return *m_history; }
102     ResourceLoadNotifier& notifier() const { return m_notifier; }
103     SubframeLoader& subframeLoader() const { return *m_subframeLoader; }
104     MixedContentChecker& mixedContentChecker() const { return m_mixedContentChecker; }
105
106     void setupForReplace();
107
108     // FIXME: These are all functions which start loads. We have too many.
109     WEBCORE_EXPORT void loadURLIntoChildFrame(const URL&, const String& referer, Frame*);
110     WEBCORE_EXPORT void loadFrameRequest(FrameLoadRequest&&, Event*, FormState*); // Called by submitForm, calls loadPostRequest and loadURL.
111
112     WEBCORE_EXPORT void load(FrameLoadRequest&&);
113
114 #if ENABLE(WEB_ARCHIVE) || ENABLE(MHTML)
115     WEBCORE_EXPORT void loadArchive(Ref<Archive>&&);
116 #endif
117     unsigned long loadResourceSynchronously(const ResourceRequest&, StoredCredentialsPolicy, ClientCredentialPolicy, ResourceError&, ResourceResponse&, RefPtr<SharedBuffer>& data);
118
119     void changeLocation(FrameLoadRequest&&);
120     WEBCORE_EXPORT void urlSelected(const URL&, const String& target, Event*, LockHistory, LockBackForwardList, ShouldSendReferrer, ShouldOpenExternalURLsPolicy, std::optional<NewFrameOpenerPolicy> = std::nullopt, const AtomicString& downloadAttribute = nullAtom());
121     void submitForm(Ref<FormSubmission>&&);
122
123     WEBCORE_EXPORT void reload(OptionSet<ReloadOption> = { });
124     WEBCORE_EXPORT void reloadWithOverrideEncoding(const String& overrideEncoding);
125
126     void open(CachedFrameBase&);
127     void loadItem(HistoryItem&, FrameLoadType);
128     HistoryItem* requestedHistoryItem() const { return m_requestedHistoryItem.get(); }
129
130     void retryAfterFailedCacheOnlyMainResourceLoad();
131
132     static void reportLocalLoadFailed(Frame*, const String& url);
133     static void reportBlockedPortFailed(Frame*, const String& url);
134
135     // FIXME: These are all functions which stop loads. We have too many.
136     WEBCORE_EXPORT void stopAllLoaders(ClearProvisionalItemPolicy = ShouldClearProvisionalItem);
137     WEBCORE_EXPORT void stopForUserCancel(bool deferCheckLoadComplete = false);
138     void stop();
139     void stopLoading(UnloadEventPolicy);
140     bool closeURL();
141     void cancelAndClear();
142     // FIXME: clear() is trying to do too many things. We should break it down into smaller functions (ideally with fewer raw Boolean parameters).
143     void clear(Document* newDocument, bool clearWindowProperties = true, bool clearScriptObjects = true, bool clearFrameView = true);
144
145     bool isLoading() const;
146     WEBCORE_EXPORT bool frameHasLoaded() const;
147
148     WEBCORE_EXPORT int numPendingOrLoadingRequests(bool recurse) const;
149
150     ReferrerPolicy effectiveReferrerPolicy() const;
151     String referrer() const;
152     WEBCORE_EXPORT String outgoingReferrer() const;
153     String outgoingOrigin() const;
154
155     WEBCORE_EXPORT DocumentLoader* activeDocumentLoader() const;
156     DocumentLoader* documentLoader() const { return m_documentLoader.get(); }
157     DocumentLoader* policyDocumentLoader() const { return m_policyDocumentLoader.get(); }
158     DocumentLoader* provisionalDocumentLoader() const { return m_provisionalDocumentLoader.get(); }
159     FrameState state() const { return m_state; }
160
161     void setShouldReportResourceTimingToParentFrame(bool value) { m_shouldReportResourceTimingToParentFrame = value; }
162     bool shouldReportResourceTimingToParentFrame() { return m_shouldReportResourceTimingToParentFrame; };
163     
164 #if PLATFORM(IOS)
165     RetainPtr<CFDictionaryRef> connectionProperties(ResourceLoader*);
166 #endif
167     const ResourceRequest& originalRequest() const;
168     const ResourceRequest& initialRequest() const;
169     void receivedMainResourceError(const ResourceError&);
170
171     bool willLoadMediaElementURL(URL&);
172
173     void handleFallbackContent();
174
175     WEBCORE_EXPORT ResourceError cancelledError(const ResourceRequest&) const;
176     WEBCORE_EXPORT ResourceError blockedByContentBlockerError(const ResourceRequest&) const;
177     ResourceError blockedError(const ResourceRequest&) const;
178 #if ENABLE(CONTENT_FILTERING)
179     ResourceError blockedByContentFilterError(const ResourceRequest&) const;
180 #endif
181
182     bool isHostedByObjectElement() const;
183
184     bool isReplacing() const;
185     void setReplacing();
186     bool subframeIsLoading() const;
187     void willChangeTitle(DocumentLoader*);
188     void didChangeTitle(DocumentLoader*);
189
190     bool shouldTreatURLAsSrcdocDocument(const URL&) const;
191
192     WEBCORE_EXPORT FrameLoadType loadType() const;
193
194     CachePolicy subresourceCachePolicy(const URL&) const;
195
196     void didReachLayoutMilestone(LayoutMilestones);
197     void didFirstLayout();
198
199     void loadedResourceFromMemoryCache(CachedResource&, ResourceRequest& newRequest, ResourceError&);
200     void tellClientAboutPastMemoryCacheLoads();
201
202     void checkLoadComplete();
203     WEBCORE_EXPORT void detachFromParent();
204     void detachViewsAndDocumentLoader();
205
206     void addExtraFieldsToSubresourceRequest(ResourceRequest&);
207     void addExtraFieldsToMainResourceRequest(ResourceRequest&);
208     
209     static void addHTTPOriginIfNeeded(ResourceRequest&, const String& origin);
210     static void addHTTPUpgradeInsecureRequestsIfNeeded(ResourceRequest&);
211
212     FrameLoaderClient& client() const { return m_client; }
213
214     void setDefersLoading(bool);
215
216     void checkContentPolicy(const ResourceResponse&, ContentPolicyDecisionFunction&&);
217
218     void didExplicitOpen();
219
220     // Callbacks from DocumentWriter
221     void didBeginDocument(bool dispatchWindowObjectAvailable);
222
223     void receivedFirstData();
224
225     void dispatchOnloadEvents();
226     String userAgent(const URL&) const;
227
228     void dispatchDidClearWindowObjectInWorld(DOMWrapperWorld&);
229     void dispatchDidClearWindowObjectsInAllWorlds();
230
231     // The following sandbox flags will be forced, regardless of changes to
232     // the sandbox attribute of any parent frames.
233     void forceSandboxFlags(SandboxFlags flags) { m_forcedSandboxFlags |= flags; }
234     SandboxFlags effectiveSandboxFlags() const;
235
236     bool checkIfFormActionAllowedByCSP(const URL&, bool didReceiveRedirectResponse) const;
237
238     WEBCORE_EXPORT Frame* opener();
239     WEBCORE_EXPORT void setOpener(Frame*);
240
241     void resetMultipleFormSubmissionProtection();
242
243     void checkCallImplicitClose();
244
245     void frameDetached();
246
247     void setOutgoingReferrer(const URL&);
248
249     void loadDone();
250     void finishedParsing();
251     void checkCompleted();
252
253     WEBCORE_EXPORT bool isComplete() const;
254
255     void commitProvisionalLoad();
256
257     void setLoadsSynchronously(bool loadsSynchronously) { m_loadsSynchronously = loadsSynchronously; }
258     bool loadsSynchronously() const { return m_loadsSynchronously; }
259
260     FrameLoaderStateMachine& stateMachine() { return m_stateMachine; }
261
262     WEBCORE_EXPORT Frame* findFrameForNavigation(const AtomicString& name, Document* activeDocument = nullptr);
263
264     void applyUserAgentIfNeeded(ResourceRequest&);
265
266     bool shouldInterruptLoadForXFrameOptions(const String&, const URL&, unsigned long requestIdentifier);
267
268     void completed();
269     bool allAncestorsAreComplete() const; // including this
270     void clientRedirected(const URL&, double delay, double fireDate, LockBackForwardList);
271     void clientRedirectCancelledOrFinished(bool cancelWithLoadInProgress);
272
273     WEBCORE_EXPORT void setOriginalURLForDownloadRequest(ResourceRequest&);
274
275     bool quickRedirectComing() const { return m_quickRedirectComing; }
276
277     WEBCORE_EXPORT bool shouldClose();
278     
279     void started();
280
281     enum class PageDismissalType { None, BeforeUnload, PageHide, Unload };
282     PageDismissalType pageDismissalEventBeingDispatched() const { return m_pageDismissalEventBeingDispatched; }
283
284     WEBCORE_EXPORT NetworkingContext* networkingContext() const;
285
286     void loadProgressingStatusChanged();
287
288     const URL& previousURL() const { return m_previousURL; }
289
290     void forcePageTransitionIfNeeded();
291
292     void setOverrideCachePolicyForTesting(ResourceRequestCachePolicy policy) { m_overrideCachePolicyForTesting = policy; }
293     void setOverrideResourceLoadPriorityForTesting(ResourceLoadPriority priority) { m_overrideResourceLoadPriorityForTesting = priority; }
294     void setStrictRawResourceValidationPolicyDisabledForTesting(bool disabled) { m_isStrictRawResourceValidationPolicyDisabledForTesting = disabled; }
295     bool isStrictRawResourceValidationPolicyDisabledForTesting() { return m_isStrictRawResourceValidationPolicyDisabledForTesting; }
296
297     WEBCORE_EXPORT void clearTestingOverrides();
298
299     const URL& provisionalLoadErrorBeingHandledURL() const { return m_provisionalLoadErrorBeingHandledURL; }
300     void setProvisionalLoadErrorBeingHandledURL(const URL& url) { m_provisionalLoadErrorBeingHandledURL = url; }
301
302     bool isAlwaysOnLoggingAllowed() const;
303     bool shouldSuppressTextInputFromEditing() const;
304     bool isReloadingFromOrigin() const { return m_loadType == FrameLoadType::ReloadFromOrigin; }
305
306 private:
307     enum FormSubmissionCacheLoadPolicy {
308         MayAttemptCacheOnlyLoadForFormSubmissionItem,
309         MayNotAttemptCacheOnlyLoadForFormSubmissionItem
310     };
311
312     bool allChildrenAreComplete() const; // immediate children, not all descendants
313
314     void checkTimerFired();
315
316     void loadSameDocumentItem(HistoryItem&);
317     void loadDifferentDocumentItem(HistoryItem&, FrameLoadType, FormSubmissionCacheLoadPolicy);
318
319     void loadProvisionalItemFromCachedPage();
320
321     void updateFirstPartyForCookies();
322     void setFirstPartyForCookies(const URL&);
323
324     void addExtraFieldsToRequest(ResourceRequest&, FrameLoadType, bool isMainResource);
325     ResourceRequestCachePolicy defaultRequestCachingPolicy(const ResourceRequest&, FrameLoadType, bool isMainResource);
326
327     void clearProvisionalLoad();
328     void transitionToCommitted(CachedPage*);
329     void frameLoadCompleted();
330
331     SubstituteData defaultSubstituteDataForURL(const URL&);
332
333     bool dispatchBeforeUnloadEvent(Chrome&, FrameLoader* frameLoaderBeingNavigated);
334     void dispatchUnloadEvents(UnloadEventPolicy);
335
336     void continueLoadAfterNavigationPolicy(const ResourceRequest&, FormState*, bool shouldContinue, AllowNavigationToInvalidURL);
337     void continueLoadAfterNewWindowPolicy(const ResourceRequest&, FormState*, const String& frameName, const NavigationAction&, bool shouldContinue, AllowNavigationToInvalidURL, NewFrameOpenerPolicy);
338     void continueFragmentScrollAfterNavigationPolicy(const ResourceRequest&, bool shouldContinue);
339
340     bool shouldPerformFragmentNavigation(bool isFormSubmission, const String& httpMethod, FrameLoadType, const URL&);
341     void scrollToFragmentWithParentBoundary(const URL&, bool isNewNavigation = true);
342
343     void checkLoadCompleteForThisFrame();
344
345     void setDocumentLoader(DocumentLoader*);
346     void setPolicyDocumentLoader(DocumentLoader*);
347     void setProvisionalDocumentLoader(DocumentLoader*);
348
349     void setState(FrameState);
350
351     void closeOldDataSources();
352     void willRestoreFromCachedPage();
353
354     bool shouldReloadToHandleUnreachableURL(DocumentLoader*);
355
356     void dispatchDidCommitLoad(std::optional<HasInsecureContent> initialHasInsecureContent);
357
358     void urlSelected(FrameLoadRequest&&, Event*);
359
360     void loadWithDocumentLoader(DocumentLoader*, FrameLoadType, FormState*, AllowNavigationToInvalidURL); // Calls continueLoadAfterNavigationPolicy
361     void load(DocumentLoader*); // Calls loadWithDocumentLoader
362
363     void loadWithNavigationAction(const ResourceRequest&, const NavigationAction&, LockHistory, FrameLoadType, FormState*, AllowNavigationToInvalidURL); // Calls loadWithDocumentLoader
364
365     void loadPostRequest(FrameLoadRequest&&, const String& referrer, FrameLoadType, Event*, FormState*);
366     void loadURL(FrameLoadRequest&&, const String& referrer, FrameLoadType, Event*, FormState*);
367
368     bool shouldReload(const URL& currentURL, const URL& destinationURL);
369
370     void requestFromDelegate(ResourceRequest&, unsigned long& identifier, ResourceError&);
371
372     WEBCORE_EXPORT void detachChildren();
373     void closeAndRemoveChild(Frame&);
374
375     void loadInSameDocument(const URL&, SerializedScriptValue* stateObject, bool isNewNavigation);
376
377     void prepareForLoadStart();
378     void provisionalLoadStarted();
379
380     void willTransitionToCommitted();
381     bool didOpenURL();
382
383     void scheduleCheckCompleted();
384     void scheduleCheckLoadComplete();
385     void startCheckCompleteTimer();
386
387     bool shouldTreatURLAsSameAsCurrent(const URL&) const;
388
389     void dispatchGlobalObjectAvailableInAllWorlds();
390
391     bool isNavigationAllowed() const;
392     bool isStopLoadingAllowed() const;
393
394     Frame& m_frame;
395     FrameLoaderClient& m_client;
396
397     const std::unique_ptr<PolicyChecker> m_policyChecker;
398     const std::unique_ptr<HistoryController> m_history;
399     mutable ResourceLoadNotifier m_notifier;
400     const std::unique_ptr<SubframeLoader> m_subframeLoader;
401     mutable FrameLoaderStateMachine m_stateMachine;
402     mutable MixedContentChecker m_mixedContentChecker;
403
404     class FrameProgressTracker;
405     std::unique_ptr<FrameProgressTracker> m_progressTracker;
406
407     FrameState m_state;
408     FrameLoadType m_loadType;
409
410     // Document loaders for the three phases of frame loading. Note that while 
411     // a new request is being loaded, the old document loader may still be referenced.
412     // E.g. while a new request is in the "policy" state, the old document loader may
413     // be consulted in particular as it makes sense to imply certain settings on the new loader.
414     RefPtr<DocumentLoader> m_documentLoader;
415     RefPtr<DocumentLoader> m_provisionalDocumentLoader;
416     RefPtr<DocumentLoader> m_policyDocumentLoader;
417
418     URL m_provisionalLoadErrorBeingHandledURL;
419
420     bool m_quickRedirectComing;
421     bool m_sentRedirectNotification;
422     bool m_inStopAllLoaders;
423     bool m_shouldReportResourceTimingToParentFrame { true };
424
425     String m_outgoingReferrer;
426
427     bool m_isExecutingJavaScriptFormAction;
428
429     bool m_didCallImplicitClose;
430     bool m_wasUnloadEventEmitted;
431
432     PageDismissalType m_pageDismissalEventBeingDispatched { PageDismissalType::None };
433     bool m_isComplete;
434
435     RefPtr<SerializedScriptValue> m_pendingStateObject;
436
437     bool m_needsClear;
438
439     URL m_submittedFormURL;
440
441     Timer m_checkTimer;
442     bool m_shouldCallCheckCompleted;
443     bool m_shouldCallCheckLoadComplete;
444
445     Frame* m_opener;
446     HashSet<Frame*> m_openedFrames;
447
448     bool m_loadingFromCachedPage;
449
450     bool m_currentNavigationHasShownBeforeUnloadConfirmPanel;
451
452     bool m_loadsSynchronously;
453
454     SandboxFlags m_forcedSandboxFlags;
455
456     RefPtr<FrameNetworkingContext> m_networkingContext;
457
458     std::optional<ResourceRequestCachePolicy> m_overrideCachePolicyForTesting;
459     std::optional<ResourceLoadPriority> m_overrideResourceLoadPriorityForTesting;
460     bool m_isStrictRawResourceValidationPolicyDisabledForTesting { false };
461
462     URL m_previousURL;
463     RefPtr<HistoryItem> m_requestedHistoryItem;
464 };
465
466 // This function is called by createWindow() in JSDOMWindowBase.cpp, for example, for
467 // modal dialog creation.  The lookupFrame is for looking up the frame name in case
468 // the frame name references a frame different from the openerFrame, e.g. when it is
469 // "_self" or "_parent".
470 //
471 // FIXME: Consider making this function part of an appropriate class (not FrameLoader)
472 // and moving it to a more appropriate location.
473 RefPtr<Frame> createWindow(Frame& openerFrame, Frame& lookupFrame, FrameLoadRequest&&, const WindowFeatures&, bool& created);
474
475 } // namespace WebCore