Bug Summary

File:Volumes/Data/worker/Apple-iOS-26-Safer-CPP-Checks-EWS/build/Source/WebCore/loader/DocumentLoader.cpp
Warning:line 1782, column 11
Local variable 'resource' is uncounted and unsafe

Annotated Source Code

Press '?' to see keyboard shortcuts

clang -cc1 -cc1 -triple arm64-apple-ios26.2.0-simulator -O3 -Wundef-prefix=TARGET_OS_ -Werror=undef-prefix -Wdeprecated-objc-isa-usage -Werror=deprecated-objc-isa-usage -Werror=implicit-function-declaration -analyze -disable-free -clear-ast-before-backend -disable-llvm-verifier -discard-value-names -main-file-name UnifiedSource279.cpp -analyzer-checker=core -analyzer-checker=apiModeling -analyzer-checker=unix -analyzer-checker=osx -analyzer-checker=security.insecureAPI.decodeValueOfObjCType -analyzer-checker=deadcode -analyzer-checker=cplusplus -analyzer-checker=security.insecureAPI.UncheckedReturn -analyzer-checker=security.insecureAPI.getpw -analyzer-checker=security.insecureAPI.gets -analyzer-checker=security.insecureAPI.mktemp -analyzer-checker=security.insecureAPI.mkstemp -analyzer-checker=security.insecureAPI.vfork -analyzer-checker=nullability.NullPassedToNonnull -analyzer-checker=nullability.NullReturnedFromNonnull -analyzer-output plist -w -setup-static-analyzer -analyzer-config-compatibility-mode=true -mrelocation-model pic -pic-level 2 -mframe-pointer=non-leaf -ffp-contract=on -fno-rounding-math -target-sdk-version=26.2 -fdepfile-entry=/Applications/Xcode.app/Contents/Developer/Platforms/iPhoneSimulator.platform/Developer/SDKs/iPhoneSimulator26.2.sdk/SDKSettings.json -fcompatibility-qualified-id-block-type-checking -fvisibility-inlines-hidden-static-local-var -fno-modulemap-allow-subdirectory-search -fdefine-target-os-macros -enable-tlsdesc -target-cpu apple-m1 -target-feature +v8.4a -target-feature +aes -target-feature +altnzcv -target-feature +ccdp -target-feature +ccpp -target-feature +complxnum -target-feature +crc -target-feature +dotprod -target-feature +flagm -target-feature +fp-armv8 -target-feature +fp16fml -target-feature +fptoint -target-feature +fullfp16 -target-feature +jsconv -target-feature +lse -target-feature +neon -target-feature +pauth -target-feature +perfmon -target-feature +predres -target-feature +ras -target-feature +rcpc -target-feature +rdm -target-feature +sb -target-feature +sha2 -target-feature +sha3 -target-feature +specrestrict -target-feature +ssbs -target-abi darwinpcs -dwarf-ext-refs -fmodule-format=obj -debug-info-kind=standalone -dwarf-version=5 -debugger-tuning=lldb -fdebug-compilation-dir=/Volumes/Data/worker/Apple-iOS-26-Safer-CPP-Checks-EWS/build/Source/WebCore -target-linker-version 1230.1 -fcoverage-compilation-dir=/Volumes/Data/worker/Apple-iOS-26-Safer-CPP-Checks-EWS/build/Source/WebCore -resource-dir /Users/buildbot/Library/Developer/Toolchains/swift-webkit.xctoolchain/usr/lib/clang/21 -dependency-file /Volumes/Data/worker/Apple-iOS-26-Safer-CPP-Checks-EWS/build/scan-build-output/StaticAnalyzer/WebCore/WebCore/normal/arm64/UnifiedSource279.d -skip-unused-modulemap-deps -MT dependencies -isysroot /Applications/Xcode.app/Contents/Developer/Platforms/iPhoneSimulator.platform/Developer/SDKs/iPhoneSimulator26.2.sdk -iquote /Volumes/Data/worker/Apple-iOS-26-Safer-CPP-Checks-EWS/build/WebKitBuild/WebCore.build/Release-iphonesimulator/WebCore.build/WebCore-generated-files.hmap -iquote /Volumes/Data/worker/Apple-iOS-26-Safer-CPP-Checks-EWS/build/WebKitBuild/WebCore.build/Release-iphonesimulator/WebCore.build/WebCore-project-headers.hmap -isystem /Volumes/Data/worker/Apple-iOS-26-Safer-CPP-Checks-EWS/build/Source/WebCore/PAL/ThirdParty/dav1d/include -isystem /Volumes/Data/worker/Apple-iOS-26-Safer-CPP-Checks-EWS/build/WebKitBuild/Release-iphonesimulator/SDKAdditions/usr/include -iframework /Volumes/Data/worker/Apple-iOS-26-Safer-CPP-Checks-EWS/build/WebKitBuild/Release-iphonesimulator/SDKAdditions/System/Library/Frameworks -iframework /Volumes/Data/worker/Apple-iOS-26-Safer-CPP-Checks-EWS/build/WebKitLibraries/SDKs/iphonesimulator26.0-additions.sdk/System/Library/PrivateFrameworks -iframework /Applications/Xcode.app/Contents/Developer/Platforms/iPhoneSimulator.platform/Developer/SDKs/iPhoneSimulator26.2.sdk/System/Library/Frameworks -include-pch /Volumes/Data/worker/Apple-iOS-26-Safer-CPP-Checks-EWS/build/WebKitBuild/PrecompiledHeaders/SharedPrecompiledHeaders/11721353671419897710/WebCorePrefix.h.gch -D _LIBCPP_HARDENING_MODE=_LIBCPP_HARDENING_MODE_EXTENSIVE -D NDEBUG -D BUILDING_WEBKIT -D GL_SILENCE_DEPRECATION=1 -D GLES_SILENCE_DEPRECATION=1 -D __clang_analyzer__ -I /Volumes/Data/worker/Apple-iOS-26-Safer-CPP-Checks-EWS/build/WebKitBuild/WebCore.build/Release-iphonesimulator/WebCore.build/WebCore-own-target-headers.hmap -I /Volumes/Data/worker/Apple-iOS-26-Safer-CPP-Checks-EWS/build/WebKitBuild/WebCore.build/Release-iphonesimulator/WebCore.build/WebCore-all-target-headers.hmap -I /Volumes/Data/worker/Apple-iOS-26-Safer-CPP-Checks-EWS/build/WebKitBuild/Release-iphonesimulator/include -I PAL -I ForwardingHeaders -I /usr/include/libxslt -I /Applications/Xcode.app/Contents/Developer/Platforms/iPhoneSimulator.platform/Developer/SDKs/iPhoneSimulator26.2.sdk/usr/include/libxml2 -I /Volumes/Data/worker/Apple-iOS-26-Safer-CPP-Checks-EWS/build/WebKitBuild/Release-iphonesimulator/DerivedSources/WebCore -I /Volumes/Data/worker/Apple-iOS-26-Safer-CPP-Checks-EWS/build/WebKitBuild/Release-iphonesimulator/usr/local/include -I /Volumes/Data/worker/Apple-iOS-26-Safer-CPP-Checks-EWS/build/WebKitBuild/Release-iphonesimulator/usr/local/include/WebKitAdditions -I /Applications/Xcode.app/Contents/Developer/Platforms/iPhoneSimulator.platform/Developer/SDKs/iPhoneSimulator26.2.sdk/usr/local/include/WebKitAdditions -I /Volumes/Data/worker/Apple-iOS-26-Safer-CPP-Checks-EWS/build/WebKitBuild/Release-iphonesimulator/usr/local/include -I /Volumes/Data/worker/Apple-iOS-26-Safer-CPP-Checks-EWS/build/WebKitLibraries/SDKs/iphonesimulator26.0-additions.sdk/usr/local/include -I /Applications/Xcode.app/Contents/Developer/Platforms/iPhoneSimulator.platform/Developer/SDKs/iPhoneSimulator26.2.sdk/usr/local/include -I /Volumes/Data/worker/Apple-iOS-26-Safer-CPP-Checks-EWS/build/WebKitBuild/Release-iphonesimulator/usr/local/include/webrtc -I /Applications/Xcode.app/Contents/Developer/Platforms/iPhoneSimulator.platform/Developer/SDKs/iPhoneSimulator26.2.sdk/usr/local/include/webrtc -I /Volumes/Data/worker/Apple-iOS-26-Safer-CPP-Checks-EWS/build/WebKitBuild/Release-iphonesimulator/usr/local/include/webm -I /Applications/Xcode.app/Contents/Developer/Platforms/iPhoneSimulator.platform/Developer/SDKs/iPhoneSimulator26.2.sdk/usr/local/include/webm -I /Volumes/Data/worker/Apple-iOS-26-Safer-CPP-Checks-EWS/build/WebKitBuild/PAL.build/PAL.build/DerivedSources -I /Volumes/Data/worker/Apple-iOS-26-Safer-CPP-Checks-EWS/build/WebKitBuild/PAL.build/Release-iphonesimulator/PAL.build/DerivedSources -I /Volumes/Data/worker/Apple-iOS-26-Safer-CPP-Checks-EWS/build/Source/WebCore -I /Volumes/Data/worker/Apple-iOS-26-Safer-CPP-Checks-EWS/build/WebKitBuild/WebCore.build/Release-iphonesimulator/WebCore.build/DerivedSources-normal/arm64 -I /Volumes/Data/worker/Apple-iOS-26-Safer-CPP-Checks-EWS/build/WebKitBuild/WebCore.build/Release-iphonesimulator/WebCore.build/DerivedSources/arm64 -I /Volumes/Data/worker/Apple-iOS-26-Safer-CPP-Checks-EWS/build/WebKitBuild/WebCore.build/Release-iphonesimulator/WebCore.build/DerivedSources -F/Volumes/Data/worker/Apple-iOS-26-Safer-CPP-Checks-EWS/build/WebKitBuild/Release-iphonesimulator -F/Volumes/Data/worker/Apple-iOS-26-Safer-CPP-Checks-EWS/build/WebKitBuild/Release-iphonesimulator -I/usr/local/include -stdlib=libc++ -internal-isystem /Applications/Xcode.app/Contents/Developer/Platforms/iPhoneSimulator.platform/Developer/SDKs/iPhoneSimulator26.2.sdk/usr/include/c++/v1 -internal-isystem /Applications/Xcode.app/Contents/Developer/Platforms/iPhoneSimulator.platform/Developer/SDKs/iPhoneSimulator26.2.sdk/usr/local/include -internal-isystem /Users/buildbot/Library/Developer/Toolchains/swift-webkit.xctoolchain/usr/lib/clang/21/include -internal-externc-isystem /Applications/Xcode.app/Contents/Developer/Platforms/iPhoneSimulator.platform/Developer/SDKs/iPhoneSimulator26.2.sdk/usr/include -internal-iframework /Applications/Xcode.app/Contents/Developer/Platforms/iPhoneSimulator.platform/Developer/SDKs/iPhoneSimulator26.2.sdk/System/Library/Frameworks -internal-iframework /Applications/Xcode.app/Contents/Developer/Platforms/iPhoneSimulator.platform/Developer/SDKs/iPhoneSimulator26.2.sdk/System/Library/SubFrameworks -internal-iframework /Applications/Xcode.app/Contents/Developer/Platforms/iPhoneSimulator.platform/Developer/SDKs/iPhoneSimulator26.2.sdk/Library/Frameworks -Wno-trigraphs -Werror -Wno-missing-field-initializers -Wmissing-prototypes -Wunreachable-code -Wnon-virtual-dtor -Wno-overloaded-virtual -Wno-exit-time-destructors -Wno-missing-braces -Wparentheses -Wswitch -Wunused-function -Wno-unused-label -Wno-unused-parameter -Wunused-variable -Wunused-value -Wempty-body -Wuninitialized -Wno-unknown-pragmas -Wno-shadow -Wno-four-char-constants -Wno-conversion -Wconstant-conversion -Wint-conversion -Wbool-conversion -Wenum-conversion -Wno-float-conversion -Wnon-literal-null-conversion -Wobjc-literal-conversion -Wsign-compare -Wno-shorten-64-to-32 -Wnewline-eof -Wno-c++11-extensions -Wno-implicit-fallthrough -Wdeprecated-declarations -Winvalid-offsetof -Wno-sign-conversion -Winfinite-recursion -Wmove -Wcomma -Wblock-capture-autoreleasing -Wstrict-prototypes -Wrange-loop-analysis -Wno-semicolon-before-method-body -Wall -Wc99-designator -Wconditional-uninitialized -Wextra -Wdeprecated-enum-enum-conversion -Wdeprecated-enum-float-conversion -Wenum-float-conversion -Wfinal-dtor-non-final-class -Wformat=2 -Wmisleading-indentation -Wpointer-to-int-cast -Wreorder-init-list -Wundef -Wunused-but-set-variable -Wvla -Werror=unguarded-availability -Wno-elaborated-enum-base -Wcast-qual -Wchar-subscripts -Wextra-tokens -Winit-self -Wmissing-noreturn -Wpacked -Wpointer-arith -Wredundant-decls -Wwrite-strings -Wexit-time-destructors -Wglobal-constructors -Wtautological-compare -Wimplicit-fallthrough -Wvla -Wno-unknown-warning-option -Wliteral-conversion -Wthread-safety -Wno-profile-instr-out-of-date -Wno-profile-instr-unprofiled -Wno-backend-plugin -Wunsafe-buffer-usage -std=c++2b -fdeprecated-macro -ferror-limit 19 -fmacro-backtrace-limit=0 -fvisibility=hidden -fvisibility-inlines-hidden -stack-protector 1 -fblocks -fencode-extended-block-signature -fno-rtti -fregister-global-dtors-with-atexit -fgnuc-version=4.2.1 -fno-cxx-modules -fno-implicit-modules -fskip-odr-check-in-gmf -fpascal-strings -fmax-type-align=16 -fdiagnostics-show-note-include-stack -vectorize-loops -vectorize-slp -fsafe-buffer-usage-suggestions -analyzer-output=html -analyzer-config report-in-main-source-file=true -analyzer-config nullability:NoDiagnoseCallsToSystemHeaders=true -analyzer-checker optin.osx.cocoa.localizability.NonLocalizedStringChecker -analyzer-checker security.insecureAPI.UncheckedReturn -analyzer-checker security.insecureAPI.getpw -analyzer-checker security.insecureAPI.gets -analyzer-checker security.insecureAPI.mkstemp -analyzer-checker security.insecureAPI.mktemp -analyzer-disable-checker security.insecureAPI.rand -analyzer-disable-checker security.insecureAPI.strcpy -analyzer-checker security.insecureAPI.vfork -analyzer-disable-checker alpha,apiModeling,core,cplusplus,deadcode,debug,fuchsia,nullability,optin,osx,security,unix,webkit -analyzer-checker alpha.webkit.ForwardDeclChecker,alpha.webkit.MemoryUnsafeCastChecker,alpha.webkit.NoDeleteChecker,alpha.webkit.NoUncheckedPtrMemberChecker,alpha.webkit.NoUnretainedMemberChecker,alpha.webkit.RetainPtrCtorAdoptChecker,alpha.webkit.UncheckedCallArgsChecker,alpha.webkit.UncheckedLocalVarsChecker,alpha.webkit.UncountedCallArgsChecker,alpha.webkit.UncountedLocalVarsChecker,alpha.webkit.UnretainedCallArgsChecker,alpha.webkit.UnretainedLambdaCapturesChecker,alpha.webkit.UnretainedLocalVarsChecker,webkit.NoUncountedMemberChecker,webkit.RefCntblBaseVirtualDtor,webkit.UncountedLambdaCapturesChecker -analyzer-config max-nodes=10000000 -analyzer-config verbose-report-filename=true -fdwarf2-cfi-asm -o /Volumes/Data/worker/Apple-iOS-26-Safer-CPP-Checks-EWS/build/scan-build-output/StaticAnalyzer/WebCore/WebCore/normal/arm64/UnifiedSource279.plist -x c++ /Volumes/Data/worker/Apple-iOS-26-Safer-CPP-Checks-EWS/build/WebKitBuild/Release-iphonesimulator/DerivedSources/WebCore/unified-sources/UnifiedSource279.cpp
1/*
2 * Copyright (C) 2006-2026 Apple Inc. All rights reserved.
3 * Copyright (C) 2011 Google Inc. All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
8 *
9 * 1. Redistributions of source code must retain the above copyright
10 * notice, this list of conditions and the following disclaimer.
11 * 2. Redistributions in binary form must reproduce the above copyright
12 * notice, this list of conditions and the following disclaimer in the
13 * documentation and/or other materials provided with the distribution.
14 * 3. Neither the name of Apple Inc. ("Apple") nor the names of
15 * its contributors may be used to endorse or promote products derived
16 * from this software without specific prior written permission.
17 *
18 * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY
19 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
20 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
21 * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY
22 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
23 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
24 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
25 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
26 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
27 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
28 */
29
30#include "config.h"
31#include "DocumentLoader.h"
32
33#include "Archive.h"
34#include "ArchiveResourceCollection.h"
35#include "CachedPage.h"
36#include "CachedRawResource.h"
37#include "ContentExtensionError.h"
38#include "ContentRuleListResults.h"
39#include "ContentSecurityPolicy.h"
40#include "CrossOriginOpenerPolicy.h"
41#include "CustomHeaderFields.h"
42#include "DNS.h"
43#include "DeprecatedGlobalSettings.h"
44#include "DocumentInlines.h"
45#include "DocumentParser.h"
46#include "DocumentPrefetcher.h"
47#include "DocumentQuirks.h"
48#include "DocumentResourceLoader.h"
49#include "DocumentSecurityOrigin.h"
50#include "DocumentView.h"
51#include "DocumentWindow.h"
52#include "DocumentWriter.h"
53#include "ElementChildIteratorInlines.h"
54#include "Event.h"
55#include "EventNames.h"
56#include "ExtensionStyleSheets.h"
57#include "FormSubmission.h"
58#include "FrameInlines.h"
59#include "FrameLoader.h"
60#include "FrameTree.h"
61#include "HTMLFormElement.h"
62#include "HTMLFrameOwnerElement.h"
63#include "HTMLObjectElement.h"
64#include "HTTPHeaderNames.h"
65#include "HTTPParsers.h"
66#include "HTTPStatusCodes.h"
67#include "HistoryController.h"
68#include "HistoryItem.h"
69#include "IconLoader.h"
70#include "InspectorInstrumentation.h"
71#include "IntegrityPolicy.h"
72#include "LegacySchemeRegistry.h"
73#include "LinkIconCollector.h"
74#include "LinkIconType.h"
75#include "LoaderStrategy.h"
76#include "LocalDOMWindow.h"
77#include "LocalFrameInlines.h"
78#include "LocalFrameLoaderClient.h"
79#include "Logging.h"
80#include "MIMETypeRegistry.h"
81#include "MemoryCache.h"
82#include "MixedContentChecker.h"
83#include "NavigationNavigationType.h"
84#include "NavigationScheduler.h"
85#include "NetworkLoadMetrics.h"
86#include "NetworkStorageSession.h"
87#include "OriginAccessPatterns.h"
88#include "Page.h"
89#include "Performance.h"
90#include "PingLoader.h"
91#include "PlatformStrategies.h"
92#include "PolicyChecker.h"
93#include "ProgressTracker.h"
94#include "ResourceLoadObserver.h"
95#include "ResourceMonitor.h"
96#include "SWClientConnection.h"
97#include "ScriptableDocumentParser.h"
98#include "SecurityPolicy.h"
99#include "ServiceWorker.h"
100#include "ServiceWorkerClientData.h"
101#include "ServiceWorkerProvider.h"
102#include "Settings.h"
103#include "SubresourceLoader.h"
104#include "TextResourceDecoder.h"
105#include "UserContentProvider.h"
106#include "UserContentURLPattern.h"
107#include "ViolationReportType.h"
108#include <wtf/Assertions.h>
109#include <wtf/CompletionHandler.h>
110#include <wtf/NeverDestroyed.h>
111#include <wtf/Ref.h>
112#include <wtf/Scope.h>
113#include <wtf/text/CString.h>
114#include <wtf/text/MakeString.h>
115#include <wtf/text/WTFString.h>
116
117#if ENABLE(APPLICATION_MANIFEST)(defined 1 && 1)
118#include "ApplicationManifestLoader.h"
119#include "HTMLHeadElement.h"
120#include "HTMLLinkElement.h"
121#endif
122
123#if ENABLE(WEB_ARCHIVE)(defined 1 && 1) || ENABLE(MHTML)(defined 0 && 0)
124#include "ArchiveFactory.h"
125#endif
126
127#if ENABLE(CONTENT_FILTERING)(defined 1 && 1)
128#include "ContentFilter.h"
129#include "FrameLoadRequest.h"
130#include "ScriptController.h"
131#endif
132
133#if USE(QUICK_LOOK)(defined 1 && 1)
134#include "PreviewConverter.h"
135#include "QuickLook.h"
136#endif
137
138#if PLATFORM(COCOA)(defined 1 && 1)
139#include <wtf/cocoa/RuntimeApplicationChecksCocoa.h>
140#endif
141
142#define PAGE_ID (m_frame && m_frame->pageID() ? m_frame->pageID()->toUInt64() : 0)
143#define FRAME_ID (m_frame ? m_frame->frameID().toUInt64() : 0)
144#define IS_MAIN_FRAME (m_frame ? m_frame->isMainFrame() : false)
145#define DOCUMENTLOADER_RELEASE_LOG(fmt, ...)clang diagnostic push clang diagnostic ignored "-Wunknown-warning-option"
clang diagnostic ignored "-Wunsafe-buffer-usage" clang diagnostic
ignored "-Wunsafe-buffer-usage-in-libc-call" clang diagnostic
ignored "-Wunsafe-buffer-usage-in-format-attr-call" [[clang
::suppress]] __extension__({ os_log_t _log_tmp = (LogNetwork.
osLogChannel); os_log_type_t _type_tmp = (OS_LOG_TYPE_DEFAULT
); if (os_log_type_enabled(_log_tmp, _type_tmp)) { __extension__
({ clang diagnostic push clang diagnostic ignored "-Wvla" clang
diagnostic error "-Wformat" _Static_assert(__builtin_constant_p
("%p - [pageID=%" "ll" "u" ", frameID=%" "ll" "u" ", isMainFrame=%d] DocumentLoader::"
fmt), "format/label/description argument must be a string constant"
); __attribute__((section("__TEXT,__oslogstring,cstring_literals"
),internal_linkage)) static const char _os_fmt_str[] __asm("LOS_LOG39"
) = "%p - [pageID=%" "ll" "u" ", frameID=%" "ll" "u" ", isMainFrame=%d] DocumentLoader::"
fmt; uint8_t _Alignas(16) __attribute__((uninitialized)) _os_fmt_buf
[__builtin_os_log_format_buffer_size("%p - [pageID=%" "ll" "u"
", frameID=%" "ll" "u" ", isMainFrame=%d] DocumentLoader::" fmt
, this, PAGE_ID, FRAME_ID, IS_MAIN_FRAME, ...)]; _os_log_impl
(&__dso_handle, _log_tmp, _type_tmp, _os_fmt_str, (uint8_t
*)__builtin_os_log_format(_os_fmt_buf, "%p - [pageID=%" "ll"
"u" ", frameID=%" "ll" "u" ", isMainFrame=%d] DocumentLoader::"
fmt, this, PAGE_ID, FRAME_ID, IS_MAIN_FRAME, ...), (uint32_t
)sizeof(_os_fmt_buf)) clang diagnostic pop ; }); } }) clang diagnostic
pop
RELEASE_LOG(Network, "%p - [pageID=%" PRIu64 ", frameID=%" PRIu64 ", isMainFrame=%d] DocumentLoader::" fmt, this, PAGE_ID, FRAME_ID, IS_MAIN_FRAME, ##__VA_ARGS__)clang diagnostic push clang diagnostic ignored "-Wunknown-warning-option"
clang diagnostic ignored "-Wunsafe-buffer-usage" clang diagnostic
ignored "-Wunsafe-buffer-usage-in-libc-call" clang diagnostic
ignored "-Wunsafe-buffer-usage-in-format-attr-call" [[clang
::suppress]] __extension__({ os_log_t _log_tmp = (LogNetwork.
osLogChannel); os_log_type_t _type_tmp = (OS_LOG_TYPE_DEFAULT
); if (os_log_type_enabled(_log_tmp, _type_tmp)) { __extension__
({ clang diagnostic push clang diagnostic ignored "-Wvla" clang
diagnostic error "-Wformat" _Static_assert(__builtin_constant_p
("%p - [pageID=%" "ll" "u" ", frameID=%" "ll" "u" ", isMainFrame=%d] DocumentLoader::"
fmt), "format/label/description argument must be a string constant"
); __attribute__((section("__TEXT,__oslogstring,cstring_literals"
),internal_linkage)) static const char _os_fmt_str[] __asm("LOS_LOG40"
) = "%p - [pageID=%" "ll" "u" ", frameID=%" "ll" "u" ", isMainFrame=%d] DocumentLoader::"
fmt; uint8_t _Alignas(16) __attribute__((uninitialized)) _os_fmt_buf
[__builtin_os_log_format_buffer_size("%p - [pageID=%" "ll" "u"
", frameID=%" "ll" "u" ", isMainFrame=%d] DocumentLoader::" fmt
, this, PAGE_ID, FRAME_ID, IS_MAIN_FRAME, ##__VA_ARGS__)]; _os_log_impl
(&__dso_handle, _log_tmp, _type_tmp, _os_fmt_str, (uint8_t
*)__builtin_os_log_format(_os_fmt_buf, "%p - [pageID=%" "ll"
"u" ", frameID=%" "ll" "u" ", isMainFrame=%d] DocumentLoader::"
fmt, this, PAGE_ID, FRAME_ID, IS_MAIN_FRAME, ##__VA_ARGS__),
(uint32_t)sizeof(_os_fmt_buf)) clang diagnostic pop ; }); } }
) clang diagnostic pop
146#define DOCUMENTLOADER_RELEASE_LOG_FORWARDABLE(fmt, ...)do { if (auto& client = logClient()) client->fmt(PAGE_ID
, FRAME_ID, IS_MAIN_FRAME, ...); else clang diagnostic push clang
diagnostic ignored "-Wunknown-warning-option" clang diagnostic
ignored "-Wunsafe-buffer-usage" clang diagnostic ignored "-Wunsafe-buffer-usage-in-libc-call"
clang diagnostic ignored "-Wunsafe-buffer-usage-in-format-attr-call"
[[clang::suppress]] __extension__({ os_log_t _log_tmp = (LogNetwork
.osLogChannel); os_log_type_t _type_tmp = (OS_LOG_TYPE_DEFAULT
); if (os_log_type_enabled(_log_tmp, _type_tmp)) { __extension__
({ clang diagnostic push clang diagnostic ignored "-Wvla" clang
diagnostic error "-Wformat" _Static_assert(__builtin_constant_p
(MESSAGE_fmt), "format/label/description argument must be a string constant"
); __attribute__((section("__TEXT,__oslogstring,cstring_literals"
),internal_linkage)) static const char _os_fmt_str[] __asm("LOS_LOG41"
) = MESSAGE_fmt; uint8_t _Alignas(16) __attribute__((uninitialized
)) _os_fmt_buf[__builtin_os_log_format_buffer_size(MESSAGE_fmt
, WTF::safePrintfType(PAGE_ID) , WTF::safePrintfType(FRAME_ID
) , WTF::safePrintfType(IS_MAIN_FRAME) , WTF::safePrintfType(
...))]; _os_log_impl(&__dso_handle, _log_tmp, _type_tmp, _os_fmt_str
, (uint8_t *)__builtin_os_log_format(_os_fmt_buf, MESSAGE_fmt
, WTF::safePrintfType(PAGE_ID) , WTF::safePrintfType(FRAME_ID
) , WTF::safePrintfType(IS_MAIN_FRAME) , WTF::safePrintfType(
...)), (uint32_t)sizeof(_os_fmt_buf)) clang diagnostic pop ; }
); } }) clang diagnostic pop ; } while (0)
RELEASE_LOG_FORWARDABLE(Network, fmt, PAGE_ID, FRAME_ID, IS_MAIN_FRAME, ##__VA_ARGS__)do { if (auto& client = logClient()) client->fmt(PAGE_ID
, FRAME_ID, IS_MAIN_FRAME, ##__VA_ARGS__); else clang diagnostic
push clang diagnostic ignored "-Wunknown-warning-option" clang
diagnostic ignored "-Wunsafe-buffer-usage" clang diagnostic
ignored "-Wunsafe-buffer-usage-in-libc-call" clang diagnostic
ignored "-Wunsafe-buffer-usage-in-format-attr-call" [[clang
::suppress]] __extension__({ os_log_t _log_tmp = (LogNetwork.
osLogChannel); os_log_type_t _type_tmp = (OS_LOG_TYPE_DEFAULT
); if (os_log_type_enabled(_log_tmp, _type_tmp)) { __extension__
({ clang diagnostic push clang diagnostic ignored "-Wvla" clang
diagnostic error "-Wformat" _Static_assert(__builtin_constant_p
(MESSAGE_fmt), "format/label/description argument must be a string constant"
); __attribute__((section("__TEXT,__oslogstring,cstring_literals"
),internal_linkage)) static const char _os_fmt_str[] __asm("LOS_LOG42"
) = MESSAGE_fmt; uint8_t _Alignas(16) __attribute__((uninitialized
)) _os_fmt_buf[__builtin_os_log_format_buffer_size(MESSAGE_fmt
, WTF::safePrintfType(PAGE_ID) , WTF::safePrintfType(FRAME_ID
) , WTF::safePrintfType(IS_MAIN_FRAME) , WTF::safePrintfType(
##__VA_ARGS__))]; _os_log_impl(&__dso_handle, _log_tmp, _type_tmp
, _os_fmt_str, (uint8_t *)__builtin_os_log_format(_os_fmt_buf
, MESSAGE_fmt, WTF::safePrintfType(PAGE_ID) , WTF::safePrintfType
(FRAME_ID) , WTF::safePrintfType(IS_MAIN_FRAME) , WTF::safePrintfType
(##__VA_ARGS__)), (uint32_t)sizeof(_os_fmt_buf)) clang diagnostic
pop ; }); } }) clang diagnostic pop ; } while (0)
147
148namespace WebCore {
149
150#if ENABLE(CONTENT_FILTERING)(defined 1 && 1)
151static bool& NODELETE[[clang::annotate_type("webkit.nodelete")]] contentFilterInDocumentLoader()
152{
153 static bool filter = false;
154 RELEASE_ASSERT(isMainThread())do { if (__builtin_expect(!!(!(isMainThread())), 0)) do { WTF
::isIntegralOrPointerType(); compilerFenceForCrash(); WTFCrashWithInfo
(154, "/Volumes/Data/worker/Apple-iOS-26-Safer-CPP-Checks-EWS/build/Source/WebCore/loader/DocumentLoader.cpp"
, __PRETTY_FUNCTION__ ); } while (false); } while (0)
;
155 return filter;
156}
157#endif
158
159static void cancelAll(const ResourceLoaderMap& loaders)
160{
161 for (auto& loader : copyToVector(loaders))
162 loader->cancel();
163}
164
165static void setAllDefersLoading(const ResourceLoaderMap& loaders, bool defers)
166{
167 for (auto& loader : copyToVector(loaders))
168 loader->setDefersLoading(defers);
169}
170
171static HashMap<ScriptExecutionContextIdentifier, SingleThreadWeakPtr<DocumentLoader>>& NODELETE[[clang::annotate_type("webkit.nodelete")]] scriptExecutionContextIdentifierToLoaderMap()
172{
173 static MainThreadNeverDestroyed<HashMap<ScriptExecutionContextIdentifier, SingleThreadWeakPtr<DocumentLoader>>> map;
174 return map.get();
175}
176
177DocumentLoader* DocumentLoader::fromScriptExecutionContextIdentifier(ScriptExecutionContextIdentifier identifier)
178{
179 return scriptExecutionContextIdentifierToLoaderMap().get(identifier);
180}
181
182DEFINE_ALLOCATOR_WITH_HEAP_IDENTIFIER(DocumentLoader)struct MakeDebugHeapMallocedImplMacroSemicolonifierDocumentLoader
{ }
;
183
184DocumentLoader::DocumentLoader(ResourceRequest&& request, SubstituteData&& substituteData, ResourceRequest&& originalRequest)
185 : FrameDestructionObserver(nullptr)
186 , m_cachedResourceLoader(CachedResourceLoader::create(this))
187 , m_originalRequest(originalRequest.isNull() ? request : originalRequest)
188 , m_substituteData(WTF::move(substituteData))
189 , m_originalRequestCopy(originalRequest.isNull() ? request : WTF::move(originalRequest))
190 , m_request(WTF::move(request))
191 , m_substituteResourceDeliveryTimer(*this, &DocumentLoader::substituteResourceDeliveryTimerFired)
192 , m_originalSubstituteDataWasValid(substituteData.isValid())
193{
194}
195
196DocumentLoader::DocumentLoader(ResourceRequest&& request, SubstituteData&& substituteData)
197 : DocumentLoader(WTF::move(request), WTF::move(substituteData), { })
198{
199}
200
201FrameLoader* DocumentLoader::frameLoader() const
202{
203 if (!m_frame)
204 return nullptr;
205 return &m_frame->loader();
206}
207
208SubresourceLoader* DocumentLoader::mainResourceLoader() const
209{
210 if (!m_mainResource)
211 return nullptr;
212 return m_mainResource->loader();
213}
214
215DocumentLoader::~DocumentLoader()
216{
217 ASSERT(!m_frame || !isLoading() || frameLoader()->activeDocumentLoader() != this)((void)0);
218 ASSERT_WITH_MESSAGE(!m_waitingForContentPolicy, "The content policy callback should never outlive its DocumentLoader.")((void)0);
219 ASSERT_WITH_MESSAGE(!m_waitingForNavigationPolicy, "The navigation policy callback should never outlive its DocumentLoader.")((void)0);
220
221 m_cachedResourceLoader->clearDocumentLoader();
222 clearMainResource();
223
224 if (m_resultingClientId) {
225 ASSERT(scriptExecutionContextIdentifierToLoaderMap().contains(*m_resultingClientId))((void)0);
226 scriptExecutionContextIdentifierToLoaderMap().remove(*m_resultingClientId);
227 }
228
229 if (auto createdCallback = std::exchange(m_whenDocumentIsCreatedCallback, { }))
230 createdCallback(nullptr);
231}
232
233RefPtr<FragmentedSharedBuffer> DocumentLoader::mainResourceData() const
234{
235 if (m_substituteData.isValid())
236 return protect(m_substituteData.content())->copy();
237 if (m_mainResource)
238 return m_mainResource->resourceBuffer();
239 return nullptr;
240}
241
242Document* DocumentLoader::document() const
243{
244 if (m_frame && m_frame->loader().documentLoader() == this)
245 return m_frame->document();
246 return nullptr;
247}
248
249void DocumentLoader::replaceRequestURLForSameDocumentNavigation(const URL& url)
250{
251 m_originalRequestCopy.setURL(URL { url });
252 m_request.setURL(URL { url });
253}
254
255void DocumentLoader::setRequest(ResourceRequest&& req)
256{
257 // Replacing an unreachable URL with alternate content looks like a server-side
258 // redirect at this point, but we can replace a committed dataSource.
259 bool handlingUnreachableURL = false;
260 handlingUnreachableURL = m_substituteData.isValid() && !m_substituteData.failingURL().isEmpty();
261
262 bool shouldNotifyAboutProvisionalURLChange = false;
263 if (handlingUnreachableURL)
264 m_committed = false;
265 else if (isLoadingMainResource() && req.url() != m_request.url())
266 shouldNotifyAboutProvisionalURLChange = true;
267
268 // We should never be getting a redirect callback after the data
269 // source is committed, except in the unreachable URL case. It
270 // would be a WebFoundation bug if it sent a redirect callback after commit.
271 ASSERT(!m_committed)((void)0);
272
273 m_request = WTF::move(req);
274 if (shouldNotifyAboutProvisionalURLChange) {
275 // Logging for <rdar://problem/54830233>.
276 if (!frameLoader()->provisionalDocumentLoader())
277 DOCUMENTLOADER_RELEASE_LOG("DocumentLoader::setRequest: With no provisional document loader")clang diagnostic push clang diagnostic ignored "-Wunknown-warning-option"
clang diagnostic ignored "-Wunsafe-buffer-usage" clang diagnostic
ignored "-Wunsafe-buffer-usage-in-libc-call" clang diagnostic
ignored "-Wunsafe-buffer-usage-in-format-attr-call" [[clang
::suppress]] __extension__({ os_log_t _log_tmp = (LogNetwork.
osLogChannel); os_log_type_t _type_tmp = (OS_LOG_TYPE_DEFAULT
); if (os_log_type_enabled(_log_tmp, _type_tmp)) { __extension__
({ clang diagnostic push clang diagnostic ignored "-Wvla" clang
diagnostic error "-Wformat" _Static_assert(__builtin_constant_p
("%p - [pageID=%" "ll" "u" ", frameID=%" "ll" "u" ", isMainFrame=%d] DocumentLoader::"
"DocumentLoader::setRequest: With no provisional document loader"
), "format/label/description argument must be a string constant"
); __attribute__((section("__TEXT,__oslogstring,cstring_literals"
),internal_linkage)) static const char _os_fmt_str[] __asm("LOS_LOG43"
) = "%p - [pageID=%" "ll" "u" ", frameID=%" "ll" "u" ", isMainFrame=%d] DocumentLoader::"
"DocumentLoader::setRequest: With no provisional document loader"
; uint8_t _Alignas(16) __attribute__((uninitialized)) _os_fmt_buf
[__builtin_os_log_format_buffer_size("%p - [pageID=%" "ll" "u"
", frameID=%" "ll" "u" ", isMainFrame=%d] DocumentLoader::" "DocumentLoader::setRequest: With no provisional document loader"
, this, PAGE_ID, FRAME_ID, IS_MAIN_FRAME)]; _os_log_impl(&
__dso_handle, _log_tmp, _type_tmp, _os_fmt_str, (uint8_t *)__builtin_os_log_format
(_os_fmt_buf, "%p - [pageID=%" "ll" "u" ", frameID=%" "ll" "u"
", isMainFrame=%d] DocumentLoader::" "DocumentLoader::setRequest: With no provisional document loader"
, this, PAGE_ID, FRAME_ID, IS_MAIN_FRAME), (uint32_t)sizeof(_os_fmt_buf
)) clang diagnostic pop ; }); } }) clang diagnostic pop
;
278 protect(frameLoader()->client())->dispatchDidChangeProvisionalURL();
279 }
280}
281
282void DocumentLoader::setMainDocumentError(const ResourceError& error)
283{
284 if (!error.isNull())
285 DOCUMENTLOADER_RELEASE_LOG("setMainDocumentError: (type=%d, code=%d)", static_cast<int>(error.type()), error.errorCode())clang diagnostic push clang diagnostic ignored "-Wunknown-warning-option"
clang diagnostic ignored "-Wunsafe-buffer-usage" clang diagnostic
ignored "-Wunsafe-buffer-usage-in-libc-call" clang diagnostic
ignored "-Wunsafe-buffer-usage-in-format-attr-call" [[clang
::suppress]] __extension__({ os_log_t _log_tmp = (LogNetwork.
osLogChannel); os_log_type_t _type_tmp = (OS_LOG_TYPE_DEFAULT
); if (os_log_type_enabled(_log_tmp, _type_tmp)) { __extension__
({ clang diagnostic push clang diagnostic ignored "-Wvla" clang
diagnostic error "-Wformat" _Static_assert(__builtin_constant_p
("%p - [pageID=%" "ll" "u" ", frameID=%" "ll" "u" ", isMainFrame=%d] DocumentLoader::"
"setMainDocumentError: (type=%d, code=%d)"), "format/label/description argument must be a string constant"
); __attribute__((section("__TEXT,__oslogstring,cstring_literals"
),internal_linkage)) static const char _os_fmt_str[] __asm("LOS_LOG44"
) = "%p - [pageID=%" "ll" "u" ", frameID=%" "ll" "u" ", isMainFrame=%d] DocumentLoader::"
"setMainDocumentError: (type=%d, code=%d)"; uint8_t _Alignas
(16) __attribute__((uninitialized)) _os_fmt_buf[__builtin_os_log_format_buffer_size
("%p - [pageID=%" "ll" "u" ", frameID=%" "ll" "u" ", isMainFrame=%d] DocumentLoader::"
"setMainDocumentError: (type=%d, code=%d)", this, PAGE_ID, FRAME_ID
, IS_MAIN_FRAME, static_cast<int>(error.type()), error.
errorCode())]; _os_log_impl(&__dso_handle, _log_tmp, _type_tmp
, _os_fmt_str, (uint8_t *)__builtin_os_log_format(_os_fmt_buf
, "%p - [pageID=%" "ll" "u" ", frameID=%" "ll" "u" ", isMainFrame=%d] DocumentLoader::"
"setMainDocumentError: (type=%d, code=%d)", this, PAGE_ID, FRAME_ID
, IS_MAIN_FRAME, static_cast<int>(error.type()), error.
errorCode()), (uint32_t)sizeof(_os_fmt_buf)) clang diagnostic
pop ; }); } }) clang diagnostic pop
;
286
287 m_mainDocumentError = error;
288 protect(frameLoader()->client())->setMainDocumentError(this, error);
289}
290
291void DocumentLoader::mainReceivedError(const ResourceError& error, LoadWillContinueInAnotherProcess loadWillContinueInAnotherProcess)
292{
293 ASSERT(!error.isNull())((void)0);
294
295 if (auto createdCallback = std::exchange(m_whenDocumentIsCreatedCallback, { }))
296 createdCallback(nullptr);
297
298 if (!frameLoader())
299 return;
300
301 if (!error.isNull())
302 DOCUMENTLOADER_RELEASE_LOG("mainReceivedError: (type=%d, code=%d)", static_cast<int>(error.type()), error.errorCode())clang diagnostic push clang diagnostic ignored "-Wunknown-warning-option"
clang diagnostic ignored "-Wunsafe-buffer-usage" clang diagnostic
ignored "-Wunsafe-buffer-usage-in-libc-call" clang diagnostic
ignored "-Wunsafe-buffer-usage-in-format-attr-call" [[clang
::suppress]] __extension__({ os_log_t _log_tmp = (LogNetwork.
osLogChannel); os_log_type_t _type_tmp = (OS_LOG_TYPE_DEFAULT
); if (os_log_type_enabled(_log_tmp, _type_tmp)) { __extension__
({ clang diagnostic push clang diagnostic ignored "-Wvla" clang
diagnostic error "-Wformat" _Static_assert(__builtin_constant_p
("%p - [pageID=%" "ll" "u" ", frameID=%" "ll" "u" ", isMainFrame=%d] DocumentLoader::"
"mainReceivedError: (type=%d, code=%d)"), "format/label/description argument must be a string constant"
); __attribute__((section("__TEXT,__oslogstring,cstring_literals"
),internal_linkage)) static const char _os_fmt_str[] __asm("LOS_LOG45"
) = "%p - [pageID=%" "ll" "u" ", frameID=%" "ll" "u" ", isMainFrame=%d] DocumentLoader::"
"mainReceivedError: (type=%d, code=%d)"; uint8_t _Alignas(16
) __attribute__((uninitialized)) _os_fmt_buf[__builtin_os_log_format_buffer_size
("%p - [pageID=%" "ll" "u" ", frameID=%" "ll" "u" ", isMainFrame=%d] DocumentLoader::"
"mainReceivedError: (type=%d, code=%d)", this, PAGE_ID, FRAME_ID
, IS_MAIN_FRAME, static_cast<int>(error.type()), error.
errorCode())]; _os_log_impl(&__dso_handle, _log_tmp, _type_tmp
, _os_fmt_str, (uint8_t *)__builtin_os_log_format(_os_fmt_buf
, "%p - [pageID=%" "ll" "u" ", frameID=%" "ll" "u" ", isMainFrame=%d] DocumentLoader::"
"mainReceivedError: (type=%d, code=%d)", this, PAGE_ID, FRAME_ID
, IS_MAIN_FRAME, static_cast<int>(error.type()), error.
errorCode()), (uint32_t)sizeof(_os_fmt_buf)) clang diagnostic
pop ; }); } }) clang diagnostic pop
;
303
304 if (m_identifierForLoadWithoutResourceLoader) {
305 ASSERT(!mainResourceLoader())((void)0);
306 protect(frameLoader()->client())->dispatchDidFailLoading(this, *m_identifierForLoadWithoutResourceLoader, error);
307 }
308
309 // There is a bug in CFNetwork where callbacks can be dispatched even when loads are deferred.
310 // See <rdar://problem/6304600> for more details.
311#if !USE(CF)(defined 1 && 1)
312 ASSERT(!mainResourceLoader() || !mainResourceLoader()->defersLoading())((void)0);
313#endif
314
315 setMainDocumentError(error);
316 clearMainResourceLoader();
317 protect(frameLoader())->receivedMainResourceError(error, loadWillContinueInAnotherProcess);
318}
319
320void DocumentLoader::frameDestroyed()
321{
322 DOCUMENTLOADER_RELEASE_LOG("DocumentLoader::frameDestroyed: m_frame=%p", m_frame.get())clang diagnostic push clang diagnostic ignored "-Wunknown-warning-option"
clang diagnostic ignored "-Wunsafe-buffer-usage" clang diagnostic
ignored "-Wunsafe-buffer-usage-in-libc-call" clang diagnostic
ignored "-Wunsafe-buffer-usage-in-format-attr-call" [[clang
::suppress]] __extension__({ os_log_t _log_tmp = (LogNetwork.
osLogChannel); os_log_type_t _type_tmp = (OS_LOG_TYPE_DEFAULT
); if (os_log_type_enabled(_log_tmp, _type_tmp)) { __extension__
({ clang diagnostic push clang diagnostic ignored "-Wvla" clang
diagnostic error "-Wformat" _Static_assert(__builtin_constant_p
("%p - [pageID=%" "ll" "u" ", frameID=%" "ll" "u" ", isMainFrame=%d] DocumentLoader::"
"DocumentLoader::frameDestroyed: m_frame=%p"), "format/label/description argument must be a string constant"
); __attribute__((section("__TEXT,__oslogstring,cstring_literals"
),internal_linkage)) static const char _os_fmt_str[] __asm("LOS_LOG46"
) = "%p - [pageID=%" "ll" "u" ", frameID=%" "ll" "u" ", isMainFrame=%d] DocumentLoader::"
"DocumentLoader::frameDestroyed: m_frame=%p"; uint8_t _Alignas
(16) __attribute__((uninitialized)) _os_fmt_buf[__builtin_os_log_format_buffer_size
("%p - [pageID=%" "ll" "u" ", frameID=%" "ll" "u" ", isMainFrame=%d] DocumentLoader::"
"DocumentLoader::frameDestroyed: m_frame=%p", this, PAGE_ID,
FRAME_ID, IS_MAIN_FRAME, m_frame.get())]; _os_log_impl(&
__dso_handle, _log_tmp, _type_tmp, _os_fmt_str, (uint8_t *)__builtin_os_log_format
(_os_fmt_buf, "%p - [pageID=%" "ll" "u" ", frameID=%" "ll" "u"
", isMainFrame=%d] DocumentLoader::" "DocumentLoader::frameDestroyed: m_frame=%p"
, this, PAGE_ID, FRAME_ID, IS_MAIN_FRAME, m_frame.get()), (uint32_t
)sizeof(_os_fmt_buf)) clang diagnostic pop ; }); } }) clang diagnostic
pop
;
323 FrameDestructionObserver::frameDestroyed();
324}
325
326// Cancels the data source's pending loads. Conceptually, a data source only loads
327// one document at a time, but one document may have many related resources.
328// stopLoading will stop all loads initiated by the data source,
329// but not loads initiated by child frames' data sources -- that's the WebFrame's job.
330void DocumentLoader::stopLoading()
331{
332 DOCUMENTLOADER_RELEASE_LOG_FORWARDABLE(DOCUMENTLOADER_STOPLOADING)do { if (auto& client = logClient()) client->DOCUMENTLOADER_STOPLOADING
(PAGE_ID, FRAME_ID, IS_MAIN_FRAME); else clang diagnostic push
clang diagnostic ignored "-Wunknown-warning-option" clang diagnostic
ignored "-Wunsafe-buffer-usage" clang diagnostic ignored "-Wunsafe-buffer-usage-in-libc-call"
clang diagnostic ignored "-Wunsafe-buffer-usage-in-format-attr-call"
[[clang::suppress]] __extension__({ os_log_t _log_tmp = (LogNetwork
.osLogChannel); os_log_type_t _type_tmp = (OS_LOG_TYPE_DEFAULT
); if (os_log_type_enabled(_log_tmp, _type_tmp)) { __extension__
({ clang diagnostic push clang diagnostic ignored "-Wvla" clang
diagnostic error "-Wformat" _Static_assert(__builtin_constant_p
("[pageID=%" "ll" "u" ", frameID=%" "ll" "u" ", isMainFrame=%d] DocumentLoader::stopLoading"
), "format/label/description argument must be a string constant"
); __attribute__((section("__TEXT,__oslogstring,cstring_literals"
),internal_linkage)) static const char _os_fmt_str[] __asm("LOS_LOG47"
) = "[pageID=%" "ll" "u" ", frameID=%" "ll" "u" ", isMainFrame=%d] DocumentLoader::stopLoading"
; uint8_t _Alignas(16) __attribute__((uninitialized)) _os_fmt_buf
[__builtin_os_log_format_buffer_size("[pageID=%" "ll" "u" ", frameID=%"
"ll" "u" ", isMainFrame=%d] DocumentLoader::stopLoading", WTF
::safePrintfType(PAGE_ID) , WTF::safePrintfType(FRAME_ID) , WTF
::safePrintfType(IS_MAIN_FRAME))]; _os_log_impl(&__dso_handle
, _log_tmp, _type_tmp, _os_fmt_str, (uint8_t *)__builtin_os_log_format
(_os_fmt_buf, "[pageID=%" "ll" "u" ", frameID=%" "ll" "u" ", isMainFrame=%d] DocumentLoader::stopLoading"
, WTF::safePrintfType(PAGE_ID) , WTF::safePrintfType(FRAME_ID
) , WTF::safePrintfType(IS_MAIN_FRAME)), (uint32_t)sizeof(_os_fmt_buf
)) clang diagnostic pop ; }); } }) clang diagnostic pop ; } while
(0)
;
333
334 RefPtr frame = m_frame.get();
335 ASSERT(frame)((void)0);
336 if (!frame)
337 return;
338
339 Ref<DocumentLoader> protectedThis(*this);
340
341 // In some rare cases, calling FrameLoader::stopLoading could cause isLoading() to return false.
342 // (This can happen when there's a single XMLHttpRequest currently loading and stopLoading causes it
343 // to stop loading. Because of this, we need to save it so we don't return early.
344 bool loading = isLoading();
345
346 if (m_committed) {
347 // Attempt to stop the frame if the document loader is loading, or if it is done loading but
348 // still parsing. Failure to do so can cause a world leak.
349 RefPtr document = frame->document();
350 if (loading || document->parsing())
351 frame->loader().stopLoading(UnloadEventPolicy::None);
352 }
353
354 for (auto& callback : m_iconLoaders.values())
355 callback(nullptr);
356 m_iconLoaders.clear();
357 m_iconsPendingLoadDecision.clear();
358
359#if ENABLE(APPLICATION_MANIFEST)(defined 1 && 1)
360 m_applicationManifestLoader = nullptr;
361 m_finishedLoadingApplicationManifest = false;
362 notifyFinishedLoadingApplicationManifest();
363#endif
364
365 // Always cancel multipart loaders
366 cancelAll(m_multipartSubresourceLoaders);
367
368 if (RefPtr document = this->document())
369 document->suspendFontLoading();
370
371#if ENABLE(WEB_ARCHIVE)(defined 1 && 1) || ENABLE(MHTML)(defined 0 && 0)
372 clearArchiveResources();
373#endif
374
375 if (!loading) {
376 // If something above restarted loading we might run into mysterious crashes like
377 // https://bugs.webkit.org/show_bug.cgi?id=62764 and <rdar://problem/9328684>
378 ASSERT(!isLoading())((void)0);
379 return;
380 }
381
382 // We might run in to infinite recursion if we're stopping loading as the result of
383 // detaching from the frame, so break out of that recursion here.
384 // See <rdar://problem/9673866> for more details.
385 if (m_isStopping)
386 return;
387
388 m_isStopping = true;
389
390 // The frame may have been detached from this document by the onunload handler
391 if (RefPtr frameLoader = this->frameLoader()) {
392 DOCUMENTLOADER_RELEASE_LOG("stopLoading: canceling load")clang diagnostic push clang diagnostic ignored "-Wunknown-warning-option"
clang diagnostic ignored "-Wunsafe-buffer-usage" clang diagnostic
ignored "-Wunsafe-buffer-usage-in-libc-call" clang diagnostic
ignored "-Wunsafe-buffer-usage-in-format-attr-call" [[clang
::suppress]] __extension__({ os_log_t _log_tmp = (LogNetwork.
osLogChannel); os_log_type_t _type_tmp = (OS_LOG_TYPE_DEFAULT
); if (os_log_type_enabled(_log_tmp, _type_tmp)) { __extension__
({ clang diagnostic push clang diagnostic ignored "-Wvla" clang
diagnostic error "-Wformat" _Static_assert(__builtin_constant_p
("%p - [pageID=%" "ll" "u" ", frameID=%" "ll" "u" ", isMainFrame=%d] DocumentLoader::"
"stopLoading: canceling load"), "format/label/description argument must be a string constant"
); __attribute__((section("__TEXT,__oslogstring,cstring_literals"
),internal_linkage)) static const char _os_fmt_str[] __asm("LOS_LOG48"
) = "%p - [pageID=%" "ll" "u" ", frameID=%" "ll" "u" ", isMainFrame=%d] DocumentLoader::"
"stopLoading: canceling load"; uint8_t _Alignas(16) __attribute__
((uninitialized)) _os_fmt_buf[__builtin_os_log_format_buffer_size
("%p - [pageID=%" "ll" "u" ", frameID=%" "ll" "u" ", isMainFrame=%d] DocumentLoader::"
"stopLoading: canceling load", this, PAGE_ID, FRAME_ID, IS_MAIN_FRAME
)]; _os_log_impl(&__dso_handle, _log_tmp, _type_tmp, _os_fmt_str
, (uint8_t *)__builtin_os_log_format(_os_fmt_buf, "%p - [pageID=%"
"ll" "u" ", frameID=%" "ll" "u" ", isMainFrame=%d] DocumentLoader::"
"stopLoading: canceling load", this, PAGE_ID, FRAME_ID, IS_MAIN_FRAME
), (uint32_t)sizeof(_os_fmt_buf)) clang diagnostic pop ; }); }
}) clang diagnostic pop
;
393 if (isLoadingMainResource()) {
394 // Stop the main resource loader and let it send the cancelled message.
395 cancelMainResourceLoad(frameLoader->cancelledError(m_request));
396 } else if (!m_subresourceLoaders.isEmpty() || !m_plugInStreamLoaders.isEmpty()) {
397 // The main resource loader already finished loading. Set the cancelled error on the
398 // document and let the subresourceLoaders and pluginLoaders send individual cancelled messages below.
399 setMainDocumentError(frameLoader->cancelledError(m_request));
400 } else {
401 // If there are no resource loaders, we need to manufacture a cancelled message.
402 // (A back/forward navigation has no resource loaders because its resources are cached.)
403 mainReceivedError(frameLoader->cancelledError(m_request));
404 }
405 }
406
407 // We always need to explicitly cancel the Document's parser when stopping the load.
408 // Otherwise cancelling the parser while starting the next page load might result
409 // in unexpected side effects such as erroneous event dispatch. ( http://webkit.org/b/117112 )
410 if (RefPtr document = this->document())
411 document->cancelParsing();
412
413 stopLoadingSubresources();
414 stopLoadingPlugIns();
415
416 m_isStopping = false;
417}
418
419void DocumentLoader::commitIfReady()
420{
421 if (!m_committed) {
422 m_committed = true;
423 RefPtr protectedFrame { m_frame.get() };
424 protect(frameLoader())->commitProvisionalLoad();
425 }
426}
427
428bool DocumentLoader::isLoading() const
429{
430 // if (document() && document()->hasActiveParser())
431 // return true;
432 // FIXME: The above code should be enabled, but it seems to cause
433 // http/tests/security/feed-urls-from-remote.html to timeout on Mac WK1
434 // see http://webkit.org/b/110554 and http://webkit.org/b/110401
435
436 return isLoadingMainResource() || !m_subresourceLoaders.isEmpty() || !m_plugInStreamLoaders.isEmpty();
437}
438
439void DocumentLoader::notifyFinished(CachedResource& resource, const NetworkLoadMetrics& fetchMetrics, LoadWillContinueInAnotherProcess loadWillContinueInAnotherProcess)
440{
441 ASSERT(isMainThread())((void)0);
442#if ENABLE(CONTENT_FILTERING)(defined 1 && 1)
443 if (RefPtr contentFilter = m_contentFilter; contentFilter && !contentFilter->continueAfterNotifyFinished(resource))
444 return;
445#endif
446
447 Box<NetworkLoadMetrics> metrics;
448 if (RefPtr frameLoader = this->frameLoader()) {
449 if (auto prefetchedMetrics = frameLoader->documentPrefetcher().takePrefetchedResourceMetrics(url())) {
450 metrics = WTF::move(prefetchedMetrics);
451 metrics->fromPrefetch = true;
452 }
453 }
454 if (!metrics)
455 metrics = Box<NetworkLoadMetrics>::create(fetchMetrics);
456
457 if (RefPtr document = this->document()) {
458 if (RefPtr window = document->window())
459 protect(window->performance())->documentLoadFinished(*metrics);
460 }
461
462 ASSERT_UNUSED(resource, m_mainResource == &resource)((void)resource);
463 ASSERT(m_mainResource)((void)0);
464 if (!m_mainResource->errorOccurred() && !m_mainResource->wasCanceled()) {
465 finishedLoading();
466 return;
467 }
468
469 if (m_request.cachePolicy() == ResourceRequestCachePolicy::ReturnCacheDataDontLoad && !m_mainResource->wasCanceled()) {
470 protect(frameLoader())->retryAfterFailedCacheOnlyMainResourceLoad();
471 return;
472 }
473
474 if (!m_mainResource->resourceError().isNull())
475 DOCUMENTLOADER_RELEASE_LOG("notifyFinished: canceling load (type=%d, code=%d)", static_cast<int>(m_mainResource->resourceError().type()), m_mainResource->resourceError().errorCode())clang diagnostic push clang diagnostic ignored "-Wunknown-warning-option"
clang diagnostic ignored "-Wunsafe-buffer-usage" clang diagnostic
ignored "-Wunsafe-buffer-usage-in-libc-call" clang diagnostic
ignored "-Wunsafe-buffer-usage-in-format-attr-call" [[clang
::suppress]] __extension__({ os_log_t _log_tmp = (LogNetwork.
osLogChannel); os_log_type_t _type_tmp = (OS_LOG_TYPE_DEFAULT
); if (os_log_type_enabled(_log_tmp, _type_tmp)) { __extension__
({ clang diagnostic push clang diagnostic ignored "-Wvla" clang
diagnostic error "-Wformat" _Static_assert(__builtin_constant_p
("%p - [pageID=%" "ll" "u" ", frameID=%" "ll" "u" ", isMainFrame=%d] DocumentLoader::"
"notifyFinished: canceling load (type=%d, code=%d)"), "format/label/description argument must be a string constant"
); __attribute__((section("__TEXT,__oslogstring,cstring_literals"
),internal_linkage)) static const char _os_fmt_str[] __asm("LOS_LOG49"
) = "%p - [pageID=%" "ll" "u" ", frameID=%" "ll" "u" ", isMainFrame=%d] DocumentLoader::"
"notifyFinished: canceling load (type=%d, code=%d)"; uint8_t
_Alignas(16) __attribute__((uninitialized)) _os_fmt_buf[__builtin_os_log_format_buffer_size
("%p - [pageID=%" "ll" "u" ", frameID=%" "ll" "u" ", isMainFrame=%d] DocumentLoader::"
"notifyFinished: canceling load (type=%d, code=%d)", this, PAGE_ID
, FRAME_ID, IS_MAIN_FRAME, static_cast<int>(m_mainResource
->resourceError().type()), m_mainResource->resourceError
().errorCode())]; _os_log_impl(&__dso_handle, _log_tmp, _type_tmp
, _os_fmt_str, (uint8_t *)__builtin_os_log_format(_os_fmt_buf
, "%p - [pageID=%" "ll" "u" ", frameID=%" "ll" "u" ", isMainFrame=%d] DocumentLoader::"
"notifyFinished: canceling load (type=%d, code=%d)", this, PAGE_ID
, FRAME_ID, IS_MAIN_FRAME, static_cast<int>(m_mainResource
->resourceError().type()), m_mainResource->resourceError
().errorCode()), (uint32_t)sizeof(_os_fmt_buf)) clang diagnostic
pop ; }); } }) clang diagnostic pop
;
476
477 mainReceivedError(m_mainResource->resourceError(), loadWillContinueInAnotherProcess);
478}
479
480void DocumentLoader::finishedLoading()
481{
482 // There is a bug in CFNetwork where callbacks can be dispatched even when loads are deferred.
483 // See <rdar://problem/6304600> for more details.
484#if !USE(CF)(defined 1 && 1)
485 ASSERT(!m_frame->page()->defersLoading() || protect(frameLoader())->stateMachine().creatingInitialEmptyDocument() || InspectorInstrumentation::isDebuggerPaused(m_frame.get()))((void)0);
486#endif
487
488 Ref<DocumentLoader> protectedThis(*this);
489
490 if (m_identifierForLoadWithoutResourceLoader) {
491 // A didFinishLoading delegate might try to cancel the load (despite it
492 // being finished). Clear m_identifierForLoadWithoutResourceLoader
493 // before calling dispatchDidFinishLoading so that we don't later try to
494 // cancel the already-finished substitute load.
495 NetworkLoadMetrics emptyMetrics;
496 ResourceLoaderIdentifier identifier = *std::exchange(m_identifierForLoadWithoutResourceLoader, std::nullopt);
497 protect(frameLoader())->notifier().dispatchDidFinishLoading(this, identifier, emptyMetrics, nullptr);
498 }
499
500 maybeFinishLoadingMultipartContent();
501
502 timing().markEndTime();
503
504 commitIfReady();
505 RefPtr frameLoader = this->frameLoader();
506 if (!frameLoader)
507 return;
508
509 if (!maybeCreateArchive()) {
510 // If this is an empty document, it will not have actually been created yet. Commit dummy data so that
511 // DocumentWriter::begin() gets called and creates the Document.
512 if (!m_gotFirstByte)
513 commitData(SharedBuffer::create());
514
515 frameLoader = this->frameLoader();
516 if (!frameLoader)
517 return;
518 Ref frameLoaderClient = frameLoader->client();
519 frameLoaderClient->finishedLoading(this);
520 frameLoaderClient->loadStorageAccessQuirksIfNeeded();
521 }
522
523 m_writer.end();
524 if (!m_mainDocumentError.isNull())
525 return;
526 clearMainResourceLoader();
527
528 frameLoader = this->frameLoader();
529 if (!frameLoader)
530 return;
531 if (!frameLoader->stateMachine().creatingInitialEmptyDocument())
532 frameLoader->checkLoadComplete();
533}
534
535static bool isRedirectToGetAfterPost(const ResourceRequest& oldRequest, const ResourceRequest& newRequest)
536{
537 return oldRequest.httpMethod() == "POST"_s && newRequest.httpMethod() == "GET"_s;
538}
539
540bool DocumentLoader::isPostOrRedirectAfterPost(const ResourceRequest& newRequest, const ResourceResponse& redirectResponse)
541{
542 if (newRequest.httpMethod() == "POST"_s)
543 return true;
544
545 int status = redirectResponse.httpStatusCode();
546 if (((status >= 301 && status <= 303) || status == 307)
547 && m_originalRequest.httpMethod() == "POST"_s)
548 return true;
549
550 return false;
551}
552
553void DocumentLoader::handleSubstituteDataLoadNow()
554{
555 Ref protectedThis { *this };
556
557 if (m_substituteData.response().isRedirection()) {
558 auto newRequest = m_request.redirectedRequest(m_substituteData.response(), true);
559 auto substituteData = std::exchange(m_substituteData, { });
560 auto callback = [protectedThis, newRequest] (auto&& request) mutable {
561 if (request.isNull())
562 return;
563 protectedThis->loadMainResource(WTF::move(newRequest));
564 };
565 redirectReceived(WTF::move(newRequest), substituteData.response(), WTF::move(callback));
566 return;
567 }
568
569 ResourceResponse response = m_substituteData.response();
570 if (response.url().isEmpty())
571 response = ResourceResponse(URL { m_request.url() }, String { m_substituteData.mimeType() }, m_substituteData.content()->size(), String { m_substituteData.textEncoding() });
572
573#if ENABLE(CONTENT_EXTENSIONS)(defined 1 && 1)
574 RefPtr frame = m_frame.get();
575 RefPtr page = frame ? frame->page() : nullptr;
576 RefPtr userContentProvider = frame ? frame->userContentProvider() : nullptr;
577 if (page && userContentProvider) {
578 // We intentionally do nothing with the results of this call.
579 // We want the CSS to be loaded for us, but we ignore any attempt to block or upgrade the connection since there is no connection.
580 userContentProvider->processContentRuleListsForLoad(*page, response.url(), frame->isMainFrame() ? ContentExtensions::ResourceType::TopDocument : ContentExtensions::ResourceType::ChildDocument, *this);
581 }
582#endif
583
584 responseReceived(WTF::move(response), nullptr);
585}
586
587bool DocumentLoader::setControllingServiceWorkerRegistration(ServiceWorkerRegistrationData&& data)
588{
589 if (!m_loadingMainResource)
590 return false;
591
592 ASSERT(!m_gotFirstByte)((void)0);
593 m_serviceWorkerRegistrationData = makeUnique<ServiceWorkerRegistrationData>(WTF::move(data));
594 return true;
595}
596
597void DocumentLoader::matchRegistration(const URL& url, SWClientConnection::RegistrationCallback&& callback)
598{
599 bool shouldTryLoadingThroughServiceWorker = m_canUseServiceWorkers && !frameLoader()->isReloadingFromOrigin() && m_frame->page() && url.protocolIsInHTTPFamily();
600 if (!shouldTryLoadingThroughServiceWorker) {
601 callback(std::nullopt);
602 return;
603 }
604
605 RefPtr frame = m_frame.get();
606 auto origin = (!frame->isMainFrame() && frame->document()) ? protect(frame->document())->topOrigin().data() : SecurityOriginData::fromURL(url);
607 if (!protect(ServiceWorkerProvider::singleton().serviceWorkerConnection())->mayHaveServiceWorkerRegisteredForOrigin(origin)) {
608 callback(std::nullopt);
609 return;
610 }
611
612 Ref connection = ServiceWorkerProvider::singleton().serviceWorkerConnection();
613 connection->matchRegistration(WTF::move(origin), url, WTF::move(callback));
614}
615
616void DocumentLoader::redirectReceived(CachedResource& resource, ResourceRequest&& request, const ResourceResponse& redirectResponse, CompletionHandler<void(ResourceRequest&&)>&& completionHandler)
617{
618 ASSERT_UNUSED(resource, &resource == m_mainResource)((void)resource);
619 redirectReceived(WTF::move(request), redirectResponse, WTF::move(completionHandler));
620}
621
622void DocumentLoader::redirectReceived(ResourceRequest&& request, const ResourceResponse& redirectResponse, CompletionHandler<void(ResourceRequest&&)>&& completionHandler)
623{
624 if (m_serviceWorkerRegistrationData) {
625 m_serviceWorkerRegistrationData = { };
626 unregisterReservedServiceWorkerClient();
627 }
628
629 willSendRequest(WTF::move(request), redirectResponse, [completionHandler = WTF::move(completionHandler), protectedThis = Ref { *this }, this] (ResourceRequest&& request) mutable {
630 ASSERT(!m_substituteData.isValid())((void)0);
631 if (request.isNull() || !m_mainDocumentError.isNull() || !m_frame) {
632 completionHandler({ });
633 return;
634 }
635 completionHandler(WTF::move(request));
636 });
637}
638
639void DocumentLoader::willSendRequest(ResourceRequest&& newRequest, const ResourceResponse& redirectResponse, CompletionHandler<void(ResourceRequest&&)>&& completionHandler)
640{
641 // Note that there are no asserts here as there are for the other callbacks. This is due to the
642 // fact that this "callback" is sent when starting every load, and the state of callback
643 // deferrals plays less of a part in this function in preventing the bad behavior deferring
644 // callbacks is meant to prevent.
645 ASSERT(!newRequest.isNull())((void)0);
646
647 // Logging for <rdar://problem/54830233>.
648 if (!frameLoader() || !frameLoader()->provisionalDocumentLoader())
649 DOCUMENTLOADER_RELEASE_LOG("willSendRequest: With no provisional document loader")clang diagnostic push clang diagnostic ignored "-Wunknown-warning-option"
clang diagnostic ignored "-Wunsafe-buffer-usage" clang diagnostic
ignored "-Wunsafe-buffer-usage-in-libc-call" clang diagnostic
ignored "-Wunsafe-buffer-usage-in-format-attr-call" [[clang
::suppress]] __extension__({ os_log_t _log_tmp = (LogNetwork.
osLogChannel); os_log_type_t _type_tmp = (OS_LOG_TYPE_DEFAULT
); if (os_log_type_enabled(_log_tmp, _type_tmp)) { __extension__
({ clang diagnostic push clang diagnostic ignored "-Wvla" clang
diagnostic error "-Wformat" _Static_assert(__builtin_constant_p
("%p - [pageID=%" "ll" "u" ", frameID=%" "ll" "u" ", isMainFrame=%d] DocumentLoader::"
"willSendRequest: With no provisional document loader"), "format/label/description argument must be a string constant"
); __attribute__((section("__TEXT,__oslogstring,cstring_literals"
),internal_linkage)) static const char _os_fmt_str[] __asm("LOS_LOG50"
) = "%p - [pageID=%" "ll" "u" ", frameID=%" "ll" "u" ", isMainFrame=%d] DocumentLoader::"
"willSendRequest: With no provisional document loader"; uint8_t
_Alignas(16) __attribute__((uninitialized)) _os_fmt_buf[__builtin_os_log_format_buffer_size
("%p - [pageID=%" "ll" "u" ", frameID=%" "ll" "u" ", isMainFrame=%d] DocumentLoader::"
"willSendRequest: With no provisional document loader", this
, PAGE_ID, FRAME_ID, IS_MAIN_FRAME)]; _os_log_impl(&__dso_handle
, _log_tmp, _type_tmp, _os_fmt_str, (uint8_t *)__builtin_os_log_format
(_os_fmt_buf, "%p - [pageID=%" "ll" "u" ", frameID=%" "ll" "u"
", isMainFrame=%d] DocumentLoader::" "willSendRequest: With no provisional document loader"
, this, PAGE_ID, FRAME_ID, IS_MAIN_FRAME), (uint32_t)sizeof(_os_fmt_buf
)) clang diagnostic pop ; }); } }) clang diagnostic pop
;
650
651 bool didReceiveRedirectResponse = !redirectResponse.isNull();
652 if (!protect(frameLoader())->checkIfFormActionAllowedByCSP(newRequest.url(), didReceiveRedirectResponse, redirectResponse.url())) {
653 DOCUMENTLOADER_RELEASE_LOG("willSendRequest: canceling - form action not allowed by CSP")clang diagnostic push clang diagnostic ignored "-Wunknown-warning-option"
clang diagnostic ignored "-Wunsafe-buffer-usage" clang diagnostic
ignored "-Wunsafe-buffer-usage-in-libc-call" clang diagnostic
ignored "-Wunsafe-buffer-usage-in-format-attr-call" [[clang
::suppress]] __extension__({ os_log_t _log_tmp = (LogNetwork.
osLogChannel); os_log_type_t _type_tmp = (OS_LOG_TYPE_DEFAULT
); if (os_log_type_enabled(_log_tmp, _type_tmp)) { __extension__
({ clang diagnostic push clang diagnostic ignored "-Wvla" clang
diagnostic error "-Wformat" _Static_assert(__builtin_constant_p
("%p - [pageID=%" "ll" "u" ", frameID=%" "ll" "u" ", isMainFrame=%d] DocumentLoader::"
"willSendRequest: canceling - form action not allowed by CSP"
), "format/label/description argument must be a string constant"
); __attribute__((section("__TEXT,__oslogstring,cstring_literals"
),internal_linkage)) static const char _os_fmt_str[] __asm("LOS_LOG51"
) = "%p - [pageID=%" "ll" "u" ", frameID=%" "ll" "u" ", isMainFrame=%d] DocumentLoader::"
"willSendRequest: canceling - form action not allowed by CSP"
; uint8_t _Alignas(16) __attribute__((uninitialized)) _os_fmt_buf
[__builtin_os_log_format_buffer_size("%p - [pageID=%" "ll" "u"
", frameID=%" "ll" "u" ", isMainFrame=%d] DocumentLoader::" "willSendRequest: canceling - form action not allowed by CSP"
, this, PAGE_ID, FRAME_ID, IS_MAIN_FRAME)]; _os_log_impl(&
__dso_handle, _log_tmp, _type_tmp, _os_fmt_str, (uint8_t *)__builtin_os_log_format
(_os_fmt_buf, "%p - [pageID=%" "ll" "u" ", frameID=%" "ll" "u"
", isMainFrame=%d] DocumentLoader::" "willSendRequest: canceling - form action not allowed by CSP"
, this, PAGE_ID, FRAME_ID, IS_MAIN_FRAME), (uint32_t)sizeof(_os_fmt_buf
)) clang diagnostic pop ; }); } }) clang diagnostic pop
;
654 cancelMainResourceLoad(protect(frameLoader())->cancelledError(newRequest));
655 return completionHandler(WTF::move(newRequest));
656 }
657
658 RefPtr frame = m_frame.get();
659 if (auto requester = m_triggeringAction.requester(); requester && requester->documentIdentifier) {
660 if (RefPtr requestingDocument = Document::allDocumentsMap().get(requester->documentIdentifier); requestingDocument && requestingDocument->frame()) {
661 if (frame && requestingDocument->isNavigationBlockedByThirdPartyIFrameRedirectBlocking(*frame, newRequest.url())) {
662 DOCUMENTLOADER_RELEASE_LOG("willSendRequest: canceling - cross-site redirect of top frame triggered by third-party iframe")clang diagnostic push clang diagnostic ignored "-Wunknown-warning-option"
clang diagnostic ignored "-Wunsafe-buffer-usage" clang diagnostic
ignored "-Wunsafe-buffer-usage-in-libc-call" clang diagnostic
ignored "-Wunsafe-buffer-usage-in-format-attr-call" [[clang
::suppress]] __extension__({ os_log_t _log_tmp = (LogNetwork.
osLogChannel); os_log_type_t _type_tmp = (OS_LOG_TYPE_DEFAULT
); if (os_log_type_enabled(_log_tmp, _type_tmp)) { __extension__
({ clang diagnostic push clang diagnostic ignored "-Wvla" clang
diagnostic error "-Wformat" _Static_assert(__builtin_constant_p
("%p - [pageID=%" "ll" "u" ", frameID=%" "ll" "u" ", isMainFrame=%d] DocumentLoader::"
"willSendRequest: canceling - cross-site redirect of top frame triggered by third-party iframe"
), "format/label/description argument must be a string constant"
); __attribute__((section("__TEXT,__oslogstring,cstring_literals"
),internal_linkage)) static const char _os_fmt_str[] __asm("LOS_LOG52"
) = "%p - [pageID=%" "ll" "u" ", frameID=%" "ll" "u" ", isMainFrame=%d] DocumentLoader::"
"willSendRequest: canceling - cross-site redirect of top frame triggered by third-party iframe"
; uint8_t _Alignas(16) __attribute__((uninitialized)) _os_fmt_buf
[__builtin_os_log_format_buffer_size("%p - [pageID=%" "ll" "u"
", frameID=%" "ll" "u" ", isMainFrame=%d] DocumentLoader::" "willSendRequest: canceling - cross-site redirect of top frame triggered by third-party iframe"
, this, PAGE_ID, FRAME_ID, IS_MAIN_FRAME)]; _os_log_impl(&
__dso_handle, _log_tmp, _type_tmp, _os_fmt_str, (uint8_t *)__builtin_os_log_format
(_os_fmt_buf, "%p - [pageID=%" "ll" "u" ", frameID=%" "ll" "u"
", isMainFrame=%d] DocumentLoader::" "willSendRequest: canceling - cross-site redirect of top frame triggered by third-party iframe"
, this, PAGE_ID, FRAME_ID, IS_MAIN_FRAME), (uint32_t)sizeof(_os_fmt_buf
)) clang diagnostic pop ; }); } }) clang diagnostic pop
;
663 if (RefPtr document = frame->document()) {
664 auto message = makeString("Unsafe JavaScript attempt to initiate navigation for frame with URL '"_s
665 , document->url().string()
666 , "' from frame with URL '"_s
667 , requestingDocument->url().string()
668 , "'. The frame attempting navigation of the top-level window is cross-origin or untrusted and the user has never interacted with the frame."_s);
669 document->addConsoleMessage(MessageSource::Security, MessageLevel::Error, message);
670 }
671 cancelMainResourceLoad(protect(frameLoader())->cancelledError(newRequest));
672 return completionHandler(WTF::move(newRequest));
673 }
674 }
675 }
676
677 ASSERT(timing().startTime())((void)0);
678 if (didReceiveRedirectResponse) {
679 if (newRequest.url().protocolIsAbout() || newRequest.url().protocolIsData()) {
680 DOCUMENTLOADER_RELEASE_LOG("willSendRequest: canceling - redirecting URL scheme is not allowed")clang diagnostic push clang diagnostic ignored "-Wunknown-warning-option"
clang diagnostic ignored "-Wunsafe-buffer-usage" clang diagnostic
ignored "-Wunsafe-buffer-usage-in-libc-call" clang diagnostic
ignored "-Wunsafe-buffer-usage-in-format-attr-call" [[clang
::suppress]] __extension__({ os_log_t _log_tmp = (LogNetwork.
osLogChannel); os_log_type_t _type_tmp = (OS_LOG_TYPE_DEFAULT
); if (os_log_type_enabled(_log_tmp, _type_tmp)) { __extension__
({ clang diagnostic push clang diagnostic ignored "-Wvla" clang
diagnostic error "-Wformat" _Static_assert(__builtin_constant_p
("%p - [pageID=%" "ll" "u" ", frameID=%" "ll" "u" ", isMainFrame=%d] DocumentLoader::"
"willSendRequest: canceling - redirecting URL scheme is not allowed"
), "format/label/description argument must be a string constant"
); __attribute__((section("__TEXT,__oslogstring,cstring_literals"
),internal_linkage)) static const char _os_fmt_str[] __asm("LOS_LOG53"
) = "%p - [pageID=%" "ll" "u" ", frameID=%" "ll" "u" ", isMainFrame=%d] DocumentLoader::"
"willSendRequest: canceling - redirecting URL scheme is not allowed"
; uint8_t _Alignas(16) __attribute__((uninitialized)) _os_fmt_buf
[__builtin_os_log_format_buffer_size("%p - [pageID=%" "ll" "u"
", frameID=%" "ll" "u" ", isMainFrame=%d] DocumentLoader::" "willSendRequest: canceling - redirecting URL scheme is not allowed"
, this, PAGE_ID, FRAME_ID, IS_MAIN_FRAME)]; _os_log_impl(&
__dso_handle, _log_tmp, _type_tmp, _os_fmt_str, (uint8_t *)__builtin_os_log_format
(_os_fmt_buf, "%p - [pageID=%" "ll" "u" ", frameID=%" "ll" "u"
", isMainFrame=%d] DocumentLoader::" "willSendRequest: canceling - redirecting URL scheme is not allowed"
, this, PAGE_ID, FRAME_ID, IS_MAIN_FRAME), (uint32_t)sizeof(_os_fmt_buf
)) clang diagnostic pop ; }); } }) clang diagnostic pop
;
681 loadErrorDocument();
682 if (frame && frame->document())
683 protect(frame->document())->addConsoleMessage(MessageSource::Security, MessageLevel::Error, makeString("Not allowed to redirect to "_s, newRequest.url().stringCenterEllipsizedToLength(), " due to its scheme"_s));
684
685 if (RefPtr frameLoader = this->frameLoader())
686 cancelMainResourceLoad(frameLoader->blockedError(newRequest));
687 return completionHandler(WTF::move(newRequest));
688 }
689 // If the redirecting url is not allowed to display content from the target origin,
690 // then block the redirect.
691 Ref<SecurityOrigin> redirectingOrigin(SecurityOrigin::create(redirectResponse.url()));
692 if (!redirectingOrigin.get().canDisplay(newRequest.url(), OriginAccessPatternsForWebProcess::singleton())) {
693 DOCUMENTLOADER_RELEASE_LOG("willSendRequest: canceling - redirecting URL not allowed to display content from target")clang diagnostic push clang diagnostic ignored "-Wunknown-warning-option"
clang diagnostic ignored "-Wunsafe-buffer-usage" clang diagnostic
ignored "-Wunsafe-buffer-usage-in-libc-call" clang diagnostic
ignored "-Wunsafe-buffer-usage-in-format-attr-call" [[clang
::suppress]] __extension__({ os_log_t _log_tmp = (LogNetwork.
osLogChannel); os_log_type_t _type_tmp = (OS_LOG_TYPE_DEFAULT
); if (os_log_type_enabled(_log_tmp, _type_tmp)) { __extension__
({ clang diagnostic push clang diagnostic ignored "-Wvla" clang
diagnostic error "-Wformat" _Static_assert(__builtin_constant_p
("%p - [pageID=%" "ll" "u" ", frameID=%" "ll" "u" ", isMainFrame=%d] DocumentLoader::"
"willSendRequest: canceling - redirecting URL not allowed to display content from target"
), "format/label/description argument must be a string constant"
); __attribute__((section("__TEXT,__oslogstring,cstring_literals"
),internal_linkage)) static const char _os_fmt_str[] __asm("LOS_LOG54"
) = "%p - [pageID=%" "ll" "u" ", frameID=%" "ll" "u" ", isMainFrame=%d] DocumentLoader::"
"willSendRequest: canceling - redirecting URL not allowed to display content from target"
; uint8_t _Alignas(16) __attribute__((uninitialized)) _os_fmt_buf
[__builtin_os_log_format_buffer_size("%p - [pageID=%" "ll" "u"
", frameID=%" "ll" "u" ", isMainFrame=%d] DocumentLoader::" "willSendRequest: canceling - redirecting URL not allowed to display content from target"
, this, PAGE_ID, FRAME_ID, IS_MAIN_FRAME)]; _os_log_impl(&
__dso_handle, _log_tmp, _type_tmp, _os_fmt_str, (uint8_t *)__builtin_os_log_format
(_os_fmt_buf, "%p - [pageID=%" "ll" "u" ", frameID=%" "ll" "u"
", isMainFrame=%d] DocumentLoader::" "willSendRequest: canceling - redirecting URL not allowed to display content from target"
, this, PAGE_ID, FRAME_ID, IS_MAIN_FRAME), (uint32_t)sizeof(_os_fmt_buf
)) clang diagnostic pop ; }); } }) clang diagnostic pop
;
694 FrameLoader::reportLocalLoadFailed(frame.get(), newRequest.url().string());
695 cancelMainResourceLoad(protect(frameLoader())->cancelledError(newRequest));
696 return completionHandler(WTF::move(newRequest));
697 }
698 if (!ResourceLoader::isPortAllowed(newRequest.url())) {
699 DOCUMENTLOADER_RELEASE_LOG("willSendRequest: canceling - redirecting to a URL with a blocked port")clang diagnostic push clang diagnostic ignored "-Wunknown-warning-option"
clang diagnostic ignored "-Wunsafe-buffer-usage" clang diagnostic
ignored "-Wunsafe-buffer-usage-in-libc-call" clang diagnostic
ignored "-Wunsafe-buffer-usage-in-format-attr-call" [[clang
::suppress]] __extension__({ os_log_t _log_tmp = (LogNetwork.
osLogChannel); os_log_type_t _type_tmp = (OS_LOG_TYPE_DEFAULT
); if (os_log_type_enabled(_log_tmp, _type_tmp)) { __extension__
({ clang diagnostic push clang diagnostic ignored "-Wvla" clang
diagnostic error "-Wformat" _Static_assert(__builtin_constant_p
("%p - [pageID=%" "ll" "u" ", frameID=%" "ll" "u" ", isMainFrame=%d] DocumentLoader::"
"willSendRequest: canceling - redirecting to a URL with a blocked port"
), "format/label/description argument must be a string constant"
); __attribute__((section("__TEXT,__oslogstring,cstring_literals"
),internal_linkage)) static const char _os_fmt_str[] __asm("LOS_LOG55"
) = "%p - [pageID=%" "ll" "u" ", frameID=%" "ll" "u" ", isMainFrame=%d] DocumentLoader::"
"willSendRequest: canceling - redirecting to a URL with a blocked port"
; uint8_t _Alignas(16) __attribute__((uninitialized)) _os_fmt_buf
[__builtin_os_log_format_buffer_size("%p - [pageID=%" "ll" "u"
", frameID=%" "ll" "u" ", isMainFrame=%d] DocumentLoader::" "willSendRequest: canceling - redirecting to a URL with a blocked port"
, this, PAGE_ID, FRAME_ID, IS_MAIN_FRAME)]; _os_log_impl(&
__dso_handle, _log_tmp, _type_tmp, _os_fmt_str, (uint8_t *)__builtin_os_log_format
(_os_fmt_buf, "%p - [pageID=%" "ll" "u" ", frameID=%" "ll" "u"
", isMainFrame=%d] DocumentLoader::" "willSendRequest: canceling - redirecting to a URL with a blocked port"
, this, PAGE_ID, FRAME_ID, IS_MAIN_FRAME), (uint32_t)sizeof(_os_fmt_buf
)) clang diagnostic pop ; }); } }) clang diagnostic pop
;
700 if (frame)
701 FrameLoader::reportBlockedLoadFailed(*frame, newRequest.url());
702 cancelMainResourceLoad(protect(frameLoader())->blockedError(newRequest));
703 return completionHandler(WTF::move(newRequest));
704 }
705 if (isIPAddressDisallowed(newRequest.url())) {
706 DOCUMENTLOADER_RELEASE_LOG("willSendRequest: canceling - redirecting to a URL with a disallowed IP address")clang diagnostic push clang diagnostic ignored "-Wunknown-warning-option"
clang diagnostic ignored "-Wunsafe-buffer-usage" clang diagnostic
ignored "-Wunsafe-buffer-usage-in-libc-call" clang diagnostic
ignored "-Wunsafe-buffer-usage-in-format-attr-call" [[clang
::suppress]] __extension__({ os_log_t _log_tmp = (LogNetwork.
osLogChannel); os_log_type_t _type_tmp = (OS_LOG_TYPE_DEFAULT
); if (os_log_type_enabled(_log_tmp, _type_tmp)) { __extension__
({ clang diagnostic push clang diagnostic ignored "-Wvla" clang
diagnostic error "-Wformat" _Static_assert(__builtin_constant_p
("%p - [pageID=%" "ll" "u" ", frameID=%" "ll" "u" ", isMainFrame=%d] DocumentLoader::"
"willSendRequest: canceling - redirecting to a URL with a disallowed IP address"
), "format/label/description argument must be a string constant"
); __attribute__((section("__TEXT,__oslogstring,cstring_literals"
),internal_linkage)) static const char _os_fmt_str[] __asm("LOS_LOG56"
) = "%p - [pageID=%" "ll" "u" ", frameID=%" "ll" "u" ", isMainFrame=%d] DocumentLoader::"
"willSendRequest: canceling - redirecting to a URL with a disallowed IP address"
; uint8_t _Alignas(16) __attribute__((uninitialized)) _os_fmt_buf
[__builtin_os_log_format_buffer_size("%p - [pageID=%" "ll" "u"
", frameID=%" "ll" "u" ", isMainFrame=%d] DocumentLoader::" "willSendRequest: canceling - redirecting to a URL with a disallowed IP address"
, this, PAGE_ID, FRAME_ID, IS_MAIN_FRAME)]; _os_log_impl(&
__dso_handle, _log_tmp, _type_tmp, _os_fmt_str, (uint8_t *)__builtin_os_log_format
(_os_fmt_buf, "%p - [pageID=%" "ll" "u" ", frameID=%" "ll" "u"
", isMainFrame=%d] DocumentLoader::" "willSendRequest: canceling - redirecting to a URL with a disallowed IP address"
, this, PAGE_ID, FRAME_ID, IS_MAIN_FRAME), (uint32_t)sizeof(_os_fmt_buf
)) clang diagnostic pop ; }); } }) clang diagnostic pop
;
707 if (frame)
708 FrameLoader::reportBlockedLoadFailed(*frame, newRequest.url());
709 cancelMainResourceLoad(protect(frameLoader())->blockedError(newRequest));
710 return completionHandler(WTF::move(newRequest));
711 }
712 }
713
714 ASSERT(frame)((void)0);
715
716 RefPtr topFrame = frame->tree().top();
717
718 RefPtr document = frame->document();
719 ASSERT(document)((void)0);
720
721 // Update cookie policy base URL as URL changes, except for subframes, which use the
722 // URL of the main frame which doesn't change when we redirect.
723 if (frame->isMainFrame())
724 newRequest.setFirstPartyForCookies(newRequest.url());
725
726 FrameLoader::addSameSiteInfoToRequestIfNeeded(newRequest, document.get());
727
728 if (!didReceiveRedirectResponse)
729 protect(frameLoader()->client())->dispatchWillChangeDocument(document->url(), newRequest.url());
730
731 // If we're fielding a redirect in response to a POST, force a load from origin, since
732 // this is a common site technique to return to a page viewing some data that the POST
733 // just modified.
734 // Also, POST requests always load from origin, but this does not affect subresources.
735 if (newRequest.cachePolicy() == ResourceRequestCachePolicy::UseProtocolCachePolicy && isPostOrRedirectAfterPost(newRequest, redirectResponse))
736 newRequest.setCachePolicy(ResourceRequestCachePolicy::ReloadIgnoringCacheData);
737
738 if (isRedirectToGetAfterPost(m_request, newRequest))
739 newRequest.clearHTTPOrigin();
740
741 if (topFrame && topFrame != frame.get()) {
742 // We shouldn't check for mixed content against the current frame when navigating; we only need to be concerned with the ancestor frames.
743 RefPtr parentFrame = frame->tree().parent();
744 if (!parentFrame)
745 parentFrame = frameLoader()->client().provisionalParentFrame();
746
747 if (!parentFrame)
748 return completionHandler(WTF::move(newRequest));
749
750 if (MixedContentChecker::shouldBlockRequest(*parentFrame, newRequest.url())) {
751 cancelMainResourceLoad(protect(frameLoader())->cancelledError(newRequest));
752 return completionHandler(WTF::move(newRequest));
753 }
754 }
755
756 if (!newRequest.url().host().isEmpty() && SecurityOrigin::shouldIgnoreHost(newRequest.url())) {
757 auto url = newRequest.url();
758 url.removeHostAndPort();
759 newRequest.setURL(WTF::move(url));
760 }
761
762#if ENABLE(CONTENT_FILTERING)(defined 1 && 1)
763 if (RefPtr contentFilter = m_contentFilter; contentFilter && !contentFilter->continueAfterWillSendRequest(newRequest, redirectResponse))
764 return completionHandler(WTF::move(newRequest));
765#endif
766
767 setRequest(ResourceRequest { newRequest });
768
769 if (!didReceiveRedirectResponse)
770 return completionHandler(WTF::move(newRequest));
771
772 auto navigationPolicyCompletionHandler = [this, protectedThis = Ref { *this }, frame, completionHandler = WTF::move(completionHandler)] (ResourceRequest&& request, WeakPtr<FormSubmission>&&, NavigationPolicyDecision navigationPolicyDecision) mutable {
773 m_waitingForNavigationPolicy = false;
774 switch (navigationPolicyDecision) {
775 case NavigationPolicyDecision::IgnoreLoad:
776 case NavigationPolicyDecision::LoadWillContinueInAnotherProcess:
777 stopLoadingForPolicyChange(navigationPolicyDecision == NavigationPolicyDecision::LoadWillContinueInAnotherProcess ? LoadWillContinueInAnotherProcess::Yes : LoadWillContinueInAnotherProcess::No);
778 break;
779 case NavigationPolicyDecision::ContinueLoad:
780 break;
781 }
782
783 completionHandler(WTF::move(request));
784 };
785
786 ASSERT(!m_waitingForNavigationPolicy)((void)0);
787 m_waitingForNavigationPolicy = true;
788
789 // FIXME: Add a load type check.
790 auto& policyChecker = frameLoader()->policyChecker();
791 RELEASE_ASSERT(!isBackForwardLoadType(policyChecker.loadType()) || frame->loader().history().provisionalItem())do { if (__builtin_expect(!!(!(!isBackForwardLoadType(policyChecker
.loadType()) || frame->loader().history().provisionalItem(
))), 0)) do { WTF::isIntegralOrPointerType(); compilerFenceForCrash
(); WTFCrashWithInfo(791, "/Volumes/Data/worker/Apple-iOS-26-Safer-CPP-Checks-EWS/build/Source/WebCore/loader/DocumentLoader.cpp"
, __PRETTY_FUNCTION__ ); } while (false); } while (0)
;
792 policyChecker.checkNavigationPolicy(WTF::move(newRequest), redirectResponse, WTF::move(navigationPolicyCompletionHandler));
793}
794
795// https://html.spec.whatwg.org/multipage/browsing-the-web.html#process-a-navigate-fetch (Step 12.5.6)
796std::optional<CrossOriginOpenerPolicyEnforcementResult> DocumentLoader::doCrossOriginOpenerHandlingOfResponse(const ResourceResponse& response)
797{
798 // COOP only applies to top-level browsing contexts.
799 RefPtr frame = m_frame.get();
800 if (!frame->isMainFrame())
801 return std::nullopt;
802
803 RefPtr document = frame->document();
804 if (!document || !frame->document()->settings().crossOriginOpenerPolicyEnabled())
805 return std::nullopt;
806
807 URL openerURL;
808 if (RefPtr openerFrame = dynamicDowncast<LocalFrame>(frame->opener()))
809 openerURL = openerFrame->document() ? openerFrame->document()->url() : URL();
810
811 auto currentCoopEnforcementResult = CrossOriginOpenerPolicyEnforcementResult::from(document->url(), document->securityOrigin(), document->crossOriginOpenerPolicy(), m_triggeringAction.requester(), openerURL);
812
813 auto newCoopEnforcementResult = WebCore::doCrossOriginOpenerHandlingOfResponse(*document, response, m_triggeringAction.requester(), protect(contentSecurityPolicy()).get(), frame->effectiveSandboxFlags(), m_request.httpReferrer(), frameLoader()->stateMachine().isDisplayingInitialEmptyDocument(), currentCoopEnforcementResult);
814 if (!newCoopEnforcementResult) {
815 cancelMainResourceLoad(protect(frameLoader())->cancelledError(m_request));
816 return std::nullopt;
817 }
818
819 return newCoopEnforcementResult;
820}
821
822void DocumentLoader::setRedirectionAsSubstituteData(ResourceResponse&& response)
823{
824 ASSERT(response.isRedirection())((void)0);
825 m_substituteData = { SharedBuffer::create(), { }, WTF::move(response), SubstituteData::SessionHistoryVisibility::Visible };
826}
827
828bool DocumentLoader::tryLoadingSubstituteData()
829{
830 if (!m_substituteData.isValid() || !m_frame->page())
831 return false;
832
833 DOCUMENTLOADER_RELEASE_LOG("startLoadingMainResource: Returning substitute data")clang diagnostic push clang diagnostic ignored "-Wunknown-warning-option"
clang diagnostic ignored "-Wunsafe-buffer-usage" clang diagnostic
ignored "-Wunsafe-buffer-usage-in-libc-call" clang diagnostic
ignored "-Wunsafe-buffer-usage-in-format-attr-call" [[clang
::suppress]] __extension__({ os_log_t _log_tmp = (LogNetwork.
osLogChannel); os_log_type_t _type_tmp = (OS_LOG_TYPE_DEFAULT
); if (os_log_type_enabled(_log_tmp, _type_tmp)) { __extension__
({ clang diagnostic push clang diagnostic ignored "-Wvla" clang
diagnostic error "-Wformat" _Static_assert(__builtin_constant_p
("%p - [pageID=%" "ll" "u" ", frameID=%" "ll" "u" ", isMainFrame=%d] DocumentLoader::"
"startLoadingMainResource: Returning substitute data"), "format/label/description argument must be a string constant"
); __attribute__((section("__TEXT,__oslogstring,cstring_literals"
),internal_linkage)) static const char _os_fmt_str[] __asm("LOS_LOG57"
) = "%p - [pageID=%" "ll" "u" ", frameID=%" "ll" "u" ", isMainFrame=%d] DocumentLoader::"
"startLoadingMainResource: Returning substitute data"; uint8_t
_Alignas(16) __attribute__((uninitialized)) _os_fmt_buf[__builtin_os_log_format_buffer_size
("%p - [pageID=%" "ll" "u" ", frameID=%" "ll" "u" ", isMainFrame=%d] DocumentLoader::"
"startLoadingMainResource: Returning substitute data", this,
PAGE_ID, FRAME_ID, IS_MAIN_FRAME)]; _os_log_impl(&__dso_handle
, _log_tmp, _type_tmp, _os_fmt_str, (uint8_t *)__builtin_os_log_format
(_os_fmt_buf, "%p - [pageID=%" "ll" "u" ", frameID=%" "ll" "u"
", isMainFrame=%d] DocumentLoader::" "startLoadingMainResource: Returning substitute data"
, this, PAGE_ID, FRAME_ID, IS_MAIN_FRAME), (uint32_t)sizeof(_os_fmt_buf
)) clang diagnostic pop ; }); } }) clang diagnostic pop
;
834 m_identifierForLoadWithoutResourceLoader = ResourceLoaderIdentifier::generate();
835 protect(frameLoader())->notifier().assignIdentifierToInitialRequest(*m_identifierForLoadWithoutResourceLoader, this, m_request);
836 protect(frameLoader())->notifier().dispatchWillSendRequest(this, *m_identifierForLoadWithoutResourceLoader, m_request, ResourceResponse(), nullptr);
837
838 if (!m_deferMainResourceDataLoad || protect(frameLoader())->loadsSynchronously())
839 handleSubstituteDataLoadNow();
840 else {
841 auto loadData = [weakThis = WeakPtr { *this }] {
842 if (RefPtr protectedThis = weakThis.get())
843 protectedThis->handleSubstituteDataLoadNow();
844 };
845
846#if USE(COCOA_EVENT_LOOP)(defined 1 && 1)
847 RunLoop::dispatch(*m_frame->page()->scheduledRunLoopPairs(), WTF::move(loadData));
848#else
849 RunLoop::currentSingleton().dispatch(WTF::move(loadData));
850#endif
851 }
852
853 return true;
854}
855
856void DocumentLoader::stopLoadingAfterXFrameOptionsOrContentSecurityPolicyDenied(ResourceLoaderIdentifier identifier, const ResourceResponse& response)
857{
858 Ref<DocumentLoader> protectedThis { *this };
859 InspectorInstrumentation::continueAfterXFrameOptionsDenied(*protect(frame()), identifier, *this, response);
860
861 loadErrorDocument();
862
863 // The load event might have detached this frame. In that case, the load will already have been cancelled during detach.
864 if (RefPtr frameLoader = this->frameLoader())
865 cancelMainResourceLoad(frameLoader->cancelledError(m_request));
866}
867
868static URL microsoftTeamsRedirectURL()
869{
870 return URL { "https://www.microsoft.com/en-us/microsoft-365/microsoft-teams/"_str };
871}
872
873bool DocumentLoader::shouldClearContentSecurityPolicyForResponse(const ResourceResponse& response) const
874{
875 return response.httpHeaderField(HTTPHeaderName::ContentSecurityPolicy).isNull() && !m_isLoadingMultipartContent;
876}
877
878void DocumentLoader::responseReceived(const CachedResource& resource, const ResourceResponse& response, CompletionHandler<void()>&& completionHandler)
879{
880 ASSERT_UNUSED(resource, m_mainResource == &resource)((void)resource);
881
882 RefPtr frame = m_frame.get();
883 if (shouldClearContentSecurityPolicyForResponse(response))
884 m_contentSecurityPolicy = nullptr;
885 else {
886 // FIXME(294912): Clean up use of bare pointers for ReportingClient
887 ReportingClient* reportingClient = nullptr;
888 if (frame && frame->document())
889 reportingClient = frame->document();
890
891 if (!m_contentSecurityPolicy)
892 m_contentSecurityPolicy = makeUnique<ContentSecurityPolicy>(URL { response.url() }, nullptr, reportingClient);
893 protect(contentSecurityPolicy())->didReceiveHeaders(ContentSecurityPolicyResponseHeaders { response }, m_request.httpReferrer(), ContentSecurityPolicy::ReportParsingErrors::No);
894 }
895 if (frame && frame->document() && frame->document()->settings().crossOriginOpenerPolicyEnabled())
896 m_responseCOOP = obtainCrossOriginOpenerPolicy(response);
897
898 // https://w3c.github.io/webappsec-subresource-integrity/#parse-integrity-policy-headers
899 m_integrityPolicy = processIntegrityPolicy(response, HTTPHeaderName::IntegrityPolicy);
900 m_integrityPolicyReportOnly = processIntegrityPolicy(response, HTTPHeaderName::IntegrityPolicyReportOnly);
901
902 if (frame && frame->settings().clearSiteDataHTTPHeaderEnabled()) {
903 m_responseClearSiteDataValues = parseClearSiteDataHeader(response);
904 // https://wicg.github.io/nav-speculation/prefetch.html#clear-prefetch-cache
905 if (m_responseClearSiteDataValues.containsAny({ ClearSiteDataValue::Cache, ClearSiteDataValue::PrefetchCache })) {
906 Ref origin = SecurityOrigin::create(response.url());
907 frame->loader().documentPrefetcher().clearPrefetchedResourcesForOrigin(origin);
908 }
909 }
910
911 // FIXME(218779): Remove this quirk once microsoft.com completes their login flow redesign.
912 if (frame && frame->document()) {
913 Ref document = *frame->document();
914 if (Quirks::isMicrosoftTeamsRedirectURL(response.url())) {
915 auto firstPartyDomain = RegistrableDomain(response.url());
916 if (auto loginDomains = NetworkStorageSession::subResourceDomainsInNeedOfStorageAccessForFirstParty(firstPartyDomain)) {
917 if (!Quirks::hasStorageAccessForAllLoginDomains(*loginDomains, firstPartyDomain)) {
918 protect(frame->navigationScheduler())->scheduleRedirect(document, 0, microsoftTeamsRedirectURL(), IsMetaRefresh::No);
919 completionHandler();
920 return;
921 }
922 }
923 }
924 }
925
926 if (m_canUseServiceWorkers && response.source() == ResourceResponse::Source::MemoryCache) {
927 matchRegistration(response.url(), [this, protectedThis = Ref { *this }, response = ResourceResponse { response }, completionHandler = WTF::move(completionHandler)](auto&& registrationData) mutable {
928 if (!m_mainDocumentError.isNull() || !m_frame) {
929 completionHandler();
930 return;
931 }
932 if (registrationData)
933 m_serviceWorkerRegistrationData = makeUnique<ServiceWorkerRegistrationData>(WTF::move(*registrationData));
934 responseReceived(WTF::move(response), WTF::move(completionHandler));
935 });
936 return;
937 }
938 responseReceived(ResourceResponse { response }, WTF::move(completionHandler));
939}
940
941void DocumentLoader::responseReceived(ResourceResponse&& response, CompletionHandler<void()>&& completionHandler)
942{
943 ASSERT(response.certificateInfo())((void)0);
944 CompletionHandlerCallingScope completionHandlerCaller(WTF::move(completionHandler));
945
946#if ENABLE(CONTENT_FILTERING)(defined 1 && 1)
947 if (RefPtr contentFilter = m_contentFilter; contentFilter && !contentFilter->continueAfterResponseReceived(response))
948 return;
949#endif
950
951 Ref<DocumentLoader> protectedThis(*this);
952
953 ASSERT(m_identifierForLoadWithoutResourceLoader || m_mainResource)((void)0);
954 ResourceLoaderIdentifier identifier = m_identifierForLoadWithoutResourceLoader ? *m_identifierForLoadWithoutResourceLoader : *m_mainResource->resourceLoaderIdentifier();
955
956 if (m_substituteData.isValid() || !platformStrategies()->loaderStrategy()->havePerformedSecurityChecks(response)) {
957 auto url = response.url();
958 RefPtr frame = m_frame.get();
959 // FIXME(294912): Clean up use of bare pointers for ReportingClient
960 ReportingClient* reportingClient = nullptr;
961 if (frame && frame->document())
962 reportingClient = frame->document();
963 ContentSecurityPolicy contentSecurityPolicy(URL { url }, this, reportingClient);
964 contentSecurityPolicy.didReceiveHeaders(ContentSecurityPolicyResponseHeaders { response }, m_request.httpReferrer());
965 if (frame && !contentSecurityPolicy.allowFrameAncestors(*frame, url)) {
966 stopLoadingAfterXFrameOptionsOrContentSecurityPolicyDenied(identifier, response);
967 return;
968 }
969
970 if (frame && !contentSecurityPolicy.overridesXFrameOptions()) {
971 String frameOptions = response.httpHeaderFields().get(HTTPHeaderName::XFrameOptions);
972 if (!frameOptions.isNull()) {
973 if (protect(frameLoader())->shouldInterruptLoadForXFrameOptions(frameOptions, url, identifier)) {
974 auto message = makeString("Refused to display '"_s, url.stringCenterEllipsizedToLength(), "' in a frame because it set 'X-Frame-Options' to '"_s, frameOptions, "'."_s);
975 protect(frame->document())->addConsoleMessage(MessageSource::Security, MessageLevel::Error, message, identifier.toUInt64());
976 stopLoadingAfterXFrameOptionsOrContentSecurityPolicyDenied(identifier, response);
977 return;
978 }
979 }
980 }
981 }
982
983 // There is a bug in CFNetwork where callbacks can be dispatched even when loads are deferred.
984 // See <rdar://problem/6304600> for more details.
985#if !USE(CF)(defined 1 && 1)
986 ASSERT(!mainResourceLoader() || !mainResourceLoader()->defersLoading())((void)0);
987#endif
988
989 if (m_isLoadingMultipartContent) {
990 setupForMultipartReplace();
991 m_mainResource->clear();
992 } else if (response.isMultipart())
993 m_isLoadingMultipartContent = true;
994
995 m_response = WTF::move(response);
996
997 if (m_identifierForLoadWithoutResourceLoader) {
998 RefPtr frameLoader = this->frameLoader();
999 if (m_mainResource && m_mainResource->wasRedirected()) {
1000 ASSERT(m_mainResource->status() == CachedResource::Status::Cached)((void)0);
1001 if (frameLoader)
1002 protect(frameLoader->client())->dispatchDidReceiveServerRedirectForProvisionalLoad();
1003 }
1004 addResponse(m_response);
1005 if (frameLoader)
1006 frameLoader->notifier().dispatchDidReceiveResponse(this, *m_identifierForLoadWithoutResourceLoader, m_response, 0);
1007 }
1008
1009 ASSERT(!m_waitingForContentPolicy)((void)0);
1010 ASSERT(frameLoader())((void)0);
1011 m_waitingForContentPolicy = true;
1012
1013 // Always show content with valid substitute data.
1014 if (m_substituteData.isValid()) {
1015 continueAfterContentPolicy(PolicyAction::Use);
1016 return;
1017 }
1018
1019 RefPtr frame = m_frame.get();
1020#if ENABLE(FTPDIR)(defined 1 && 1)
1021 // Respect the hidden FTP Directory Listing pref so it can be tested even if the policy delegate might otherwise disallow it
1022 if (frame && frame->settings().forceFTPDirectoryListings() && m_response.mimeType() == "application/x-ftp-directory"_s) {
1023 continueAfterContentPolicy(PolicyAction::Use);
1024 return;
1025 }
1026#endif
1027
1028 if (!frame) {
1029 DOCUMENTLOADER_RELEASE_LOG("responseReceived by DocumentLoader with null frame")clang diagnostic push clang diagnostic ignored "-Wunknown-warning-option"
clang diagnostic ignored "-Wunsafe-buffer-usage" clang diagnostic
ignored "-Wunsafe-buffer-usage-in-libc-call" clang diagnostic
ignored "-Wunsafe-buffer-usage-in-format-attr-call" [[clang
::suppress]] __extension__({ os_log_t _log_tmp = (LogNetwork.
osLogChannel); os_log_type_t _type_tmp = (OS_LOG_TYPE_DEFAULT
); if (os_log_type_enabled(_log_tmp, _type_tmp)) { __extension__
({ clang diagnostic push clang diagnostic ignored "-Wvla" clang
diagnostic error "-Wformat" _Static_assert(__builtin_constant_p
("%p - [pageID=%" "ll" "u" ", frameID=%" "ll" "u" ", isMainFrame=%d] DocumentLoader::"
"responseReceived by DocumentLoader with null frame"), "format/label/description argument must be a string constant"
); __attribute__((section("__TEXT,__oslogstring,cstring_literals"
),internal_linkage)) static const char _os_fmt_str[] __asm("LOS_LOG58"
) = "%p - [pageID=%" "ll" "u" ", frameID=%" "ll" "u" ", isMainFrame=%d] DocumentLoader::"
"responseReceived by DocumentLoader with null frame"; uint8_t
_Alignas(16) __attribute__((uninitialized)) _os_fmt_buf[__builtin_os_log_format_buffer_size
("%p - [pageID=%" "ll" "u" ", frameID=%" "ll" "u" ", isMainFrame=%d] DocumentLoader::"
"responseReceived by DocumentLoader with null frame", this, PAGE_ID
, FRAME_ID, IS_MAIN_FRAME)]; _os_log_impl(&__dso_handle, _log_tmp
, _type_tmp, _os_fmt_str, (uint8_t *)__builtin_os_log_format(
_os_fmt_buf, "%p - [pageID=%" "ll" "u" ", frameID=%" "ll" "u"
", isMainFrame=%d] DocumentLoader::" "responseReceived by DocumentLoader with null frame"
, this, PAGE_ID, FRAME_ID, IS_MAIN_FRAME), (uint32_t)sizeof(_os_fmt_buf
)) clang diagnostic pop ; }); } }) clang diagnostic pop
;
1030 return;
1031 }
1032
1033 RefPtr<SubresourceLoader> mainResourceLoader = this->mainResourceLoader();
1034 if (mainResourceLoader)
1035 mainResourceLoader->markInAsyncResponsePolicyCheck();
1036
1037 protect(frameLoader())->checkContentPolicy(m_response, [this, protectedThis = Ref { *this }, mainResourceLoader = WTF::move(mainResourceLoader),
1038 completionHandler = completionHandlerCaller.release()] (PolicyAction policy) mutable {
1039 continueAfterContentPolicy(policy);
1040 if (mainResourceLoader)
1041 mainResourceLoader->didReceiveResponsePolicy();
1042 if (completionHandler)
1043 completionHandler();
1044 });
1045}
1046
1047// Prevent web archives from loading if
1048// 1) it is remote;
1049// 2) it is not the main frame;
1050// 3) it is not any of { loaded by clients; loaded by drag; reloaded from any of the previous two };
1051// because they can claim to be from any domain and thus avoid cross-domain security checks (4120255, 45524528, 47610130).
1052bool DocumentLoader::disallowWebArchive() const
1053{
1054 String mimeType = m_response.mimeType();
1055 if (mimeType.isNull() || !MIMETypeRegistry::isWebArchiveMIMEType(mimeType))
1056 return false;
1057
1058#if USE(QUICK_LOOK)(defined 1 && 1)
1059 if (isQuickLookPreviewURL(m_response.url()))
1060 return false;
1061#endif
1062
1063 if (m_substituteData.isValid())
1064 return false;
1065
1066 if (!LegacySchemeRegistry::shouldTreatURLSchemeAsLocal(m_request.url().protocol()))
1067 return true;
1068
1069#if ENABLE(WEB_ARCHIVE)(defined 1 && 1)
1070 // On purpose of maintaining existing tests.
1071 bool alwaysAllowLocalWebArchive = frame()->mainFrame().settings().alwaysAllowLocalWebarchive();
1072#else
1073 bool alwaysAllowLocalWebArchive { false };
1074#endif
1075 if (!frame() || (frame()->isMainFrame() && allowsWebArchiveForMainFrame()) || alwaysAllowLocalWebArchive)
1076 return false;
1077
1078 return true;
1079}
1080
1081// Prevent data URIs from loading as the main frame unless the result of user action.
1082bool DocumentLoader::disallowDataRequest() const
1083{
1084 if (!m_response.url().protocolIsData())
1085 return false;
1086
1087 if (!frame() || !frame()->isMainFrame() || allowsDataURLsForMainFrame() || frame()->settings().allowTopNavigationToDataURLs())
1088 return false;
1089
1090 if (RefPtr currentDocument = frame()->document()) {
1091 ResourceLoaderIdentifier identifier = m_identifierForLoadWithoutResourceLoader ? *m_identifierForLoadWithoutResourceLoader : *m_mainResource->resourceLoaderIdentifier();
1092 currentDocument->addConsoleMessage(MessageSource::Security, MessageLevel::Error, makeString("Not allowed to navigate top frame to data URL '"_s, m_response.url().stringCenterEllipsizedToLength(), "'."_s), identifier.toUInt64());
1093 }
1094 DOCUMENTLOADER_RELEASE_LOG("continueAfterContentPolicy: cannot show URL")clang diagnostic push clang diagnostic ignored "-Wunknown-warning-option"
clang diagnostic ignored "-Wunsafe-buffer-usage" clang diagnostic
ignored "-Wunsafe-buffer-usage-in-libc-call" clang diagnostic
ignored "-Wunsafe-buffer-usage-in-format-attr-call" [[clang
::suppress]] __extension__({ os_log_t _log_tmp = (LogNetwork.
osLogChannel); os_log_type_t _type_tmp = (OS_LOG_TYPE_DEFAULT
); if (os_log_type_enabled(_log_tmp, _type_tmp)) { __extension__
({ clang diagnostic push clang diagnostic ignored "-Wvla" clang
diagnostic error "-Wformat" _Static_assert(__builtin_constant_p
("%p - [pageID=%" "ll" "u" ", frameID=%" "ll" "u" ", isMainFrame=%d] DocumentLoader::"
"continueAfterContentPolicy: cannot show URL"), "format/label/description argument must be a string constant"
); __attribute__((section("__TEXT,__oslogstring,cstring_literals"
),internal_linkage)) static const char _os_fmt_str[] __asm("LOS_LOG59"
) = "%p - [pageID=%" "ll" "u" ", frameID=%" "ll" "u" ", isMainFrame=%d] DocumentLoader::"
"continueAfterContentPolicy: cannot show URL"; uint8_t _Alignas
(16) __attribute__((uninitialized)) _os_fmt_buf[__builtin_os_log_format_buffer_size
("%p - [pageID=%" "ll" "u" ", frameID=%" "ll" "u" ", isMainFrame=%d] DocumentLoader::"
"continueAfterContentPolicy: cannot show URL", this, PAGE_ID
, FRAME_ID, IS_MAIN_FRAME)]; _os_log_impl(&__dso_handle, _log_tmp
, _type_tmp, _os_fmt_str, (uint8_t *)__builtin_os_log_format(
_os_fmt_buf, "%p - [pageID=%" "ll" "u" ", frameID=%" "ll" "u"
", isMainFrame=%d] DocumentLoader::" "continueAfterContentPolicy: cannot show URL"
, this, PAGE_ID, FRAME_ID, IS_MAIN_FRAME), (uint32_t)sizeof(_os_fmt_buf
)) clang diagnostic pop ; }); } }) clang diagnostic pop
;
1095
1096 return true;
1097}
1098
1099void DocumentLoader::continueAfterContentPolicy(PolicyAction policy)
1100{
1101 ASSERT(m_waitingForContentPolicy)((void)0);
1102 m_waitingForContentPolicy = false;
1103 if (isStopping())
1104 return;
1105
1106 RefPtr frame = m_frame.get();
1107 if (!frame) {
1108 DOCUMENTLOADER_RELEASE_LOG("continueAfterContentPolicy: policyAction=%" PUBLIC_LOG_STRING " received by DocumentLoader with null frame", toString(policy).characters())clang diagnostic push clang diagnostic ignored "-Wunknown-warning-option"
clang diagnostic ignored "-Wunsafe-buffer-usage" clang diagnostic
ignored "-Wunsafe-buffer-usage-in-libc-call" clang diagnostic
ignored "-Wunsafe-buffer-usage-in-format-attr-call" [[clang
::suppress]] __extension__({ os_log_t _log_tmp = (LogNetwork.
osLogChannel); os_log_type_t _type_tmp = (OS_LOG_TYPE_DEFAULT
); if (os_log_type_enabled(_log_tmp, _type_tmp)) { __extension__
({ clang diagnostic push clang diagnostic ignored "-Wvla" clang
diagnostic error "-Wformat" _Static_assert(__builtin_constant_p
("%p - [pageID=%" "ll" "u" ", frameID=%" "ll" "u" ", isMainFrame=%d] DocumentLoader::"
"continueAfterContentPolicy: policyAction=%" "{public}s" " received by DocumentLoader with null frame"
), "format/label/description argument must be a string constant"
); __attribute__((section("__TEXT,__oslogstring,cstring_literals"
),internal_linkage)) static const char _os_fmt_str[] __asm("LOS_LOG60"
) = "%p - [pageID=%" "ll" "u" ", frameID=%" "ll" "u" ", isMainFrame=%d] DocumentLoader::"
"continueAfterContentPolicy: policyAction=%" "{public}s" " received by DocumentLoader with null frame"
; uint8_t _Alignas(16) __attribute__((uninitialized)) _os_fmt_buf
[__builtin_os_log_format_buffer_size("%p - [pageID=%" "ll" "u"
", frameID=%" "ll" "u" ", isMainFrame=%d] DocumentLoader::" "continueAfterContentPolicy: policyAction=%"
"{public}s" " received by DocumentLoader with null frame", this
, PAGE_ID, FRAME_ID, IS_MAIN_FRAME, toString(policy).characters
())]; _os_log_impl(&__dso_handle, _log_tmp, _type_tmp, _os_fmt_str
, (uint8_t *)__builtin_os_log_format(_os_fmt_buf, "%p - [pageID=%"
"ll" "u" ", frameID=%" "ll" "u" ", isMainFrame=%d] DocumentLoader::"
"continueAfterContentPolicy: policyAction=%" "{public}s" " received by DocumentLoader with null frame"
, this, PAGE_ID, FRAME_ID, IS_MAIN_FRAME, toString(policy).characters
()), (uint32_t)sizeof(_os_fmt_buf)) clang diagnostic pop ; })
; } }) clang diagnostic pop
;
1109 return;
1110 }
1111
1112 switch (policy) {
1113 case PolicyAction::Use: {
1114 if (!protect(frameLoader()->client())->canShowMIMEType(m_response.mimeType()) || disallowWebArchive() || disallowDataRequest()) {
1115 protect(frameLoader())->policyChecker().cannotShowMIMEType(m_response);
1116 // Check reachedTerminalState since the load may have already been canceled inside of _handleUnimplementablePolicyWithErrorCode::.
1117 stopLoadingForPolicyChange();
1118 return;
1119 }
1120 break;
1121 }
1122
1123 case PolicyAction::Download: {
1124 // m_mainResource can be null, e.g. when loading a substitute resource from application cache.
1125 if (!m_mainResource) {
1126 DOCUMENTLOADER_RELEASE_LOG("continueAfterContentPolicy: cannot show URL")clang diagnostic push clang diagnostic ignored "-Wunknown-warning-option"
clang diagnostic ignored "-Wunsafe-buffer-usage" clang diagnostic
ignored "-Wunsafe-buffer-usage-in-libc-call" clang diagnostic
ignored "-Wunsafe-buffer-usage-in-format-attr-call" [[clang
::suppress]] __extension__({ os_log_t _log_tmp = (LogNetwork.
osLogChannel); os_log_type_t _type_tmp = (OS_LOG_TYPE_DEFAULT
); if (os_log_type_enabled(_log_tmp, _type_tmp)) { __extension__
({ clang diagnostic push clang diagnostic ignored "-Wvla" clang
diagnostic error "-Wformat" _Static_assert(__builtin_constant_p
("%p - [pageID=%" "ll" "u" ", frameID=%" "ll" "u" ", isMainFrame=%d] DocumentLoader::"
"continueAfterContentPolicy: cannot show URL"), "format/label/description argument must be a string constant"
); __attribute__((section("__TEXT,__oslogstring,cstring_literals"
),internal_linkage)) static const char _os_fmt_str[] __asm("LOS_LOG61"
) = "%p - [pageID=%" "ll" "u" ", frameID=%" "ll" "u" ", isMainFrame=%d] DocumentLoader::"
"continueAfterContentPolicy: cannot show URL"; uint8_t _Alignas
(16) __attribute__((uninitialized)) _os_fmt_buf[__builtin_os_log_format_buffer_size
("%p - [pageID=%" "ll" "u" ", frameID=%" "ll" "u" ", isMainFrame=%d] DocumentLoader::"
"continueAfterContentPolicy: cannot show URL", this, PAGE_ID
, FRAME_ID, IS_MAIN_FRAME)]; _os_log_impl(&__dso_handle, _log_tmp
, _type_tmp, _os_fmt_str, (uint8_t *)__builtin_os_log_format(
_os_fmt_buf, "%p - [pageID=%" "ll" "u" ", frameID=%" "ll" "u"
", isMainFrame=%d] DocumentLoader::" "continueAfterContentPolicy: cannot show URL"
, this, PAGE_ID, FRAME_ID, IS_MAIN_FRAME), (uint32_t)sizeof(_os_fmt_buf
)) clang diagnostic pop ; }); } }) clang diagnostic pop
;
1127 mainReceivedError(platformStrategies()->loaderStrategy()->cannotShowURLError(m_request));
1128 return;
1129 }
1130
1131 if (RefPtr mainResourceLoader = this->mainResourceLoader())
1132 InspectorInstrumentation::continueWithPolicyDownload(*frame, *mainResourceLoader->identifier(), *this, m_response);
1133
1134 if (!frame->effectiveSandboxFlags().contains(SandboxFlag::Downloads)) {
1135 // When starting the request, we didn't know that it would result in download and not navigation. Now we know that main document URL didn't change.
1136 // Download may use this knowledge for purposes unrelated to cookies, notably for setting file quarantine data.
1137 protect(frameLoader())->setOriginalURLForDownloadRequest(m_request);
1138
1139 if (m_request.url().protocolIsData()) {
1140 // We decode data URL internally, there is no resource load to convert.
1141 protect(frameLoader()->client())->startDownload(m_request);
1142 } else
1143 protect(frameLoader()->client())->convertMainResourceLoadToDownload(this, m_request, m_response);
1144 } else if (RefPtr document = frame->document())
1145 document->addConsoleMessage(MessageSource::Security, MessageLevel::Error, "Not allowed to download due to sandboxing"_s);
1146
1147 // The main resource might be loading from the memory cache, or its loader might have gone missing.
1148 if (RefPtr loader = mainResourceLoader()) {
1149 loader->didFail(interruptedForPolicyChangeError());
1150 return;
1151 }
1152
1153 // We must stop loading even if there is no main resource loader. Otherwise, we might remain
1154 // the client of a CachedRawResource that will continue to send us data.
1155 stopLoadingForPolicyChange();
1156 return;
1157 }
1158 case PolicyAction::LoadWillContinueInAnotherProcess:
1159 ASSERT_NOT_REACHED()((void)0);
1160#if !ASSERT_ENABLED0
1161 [[fallthrough]];
1162#endif
1163 case PolicyAction::Ignore:
1164 if (RefPtr mainResourceLoader = this->mainResourceLoader())
1165 InspectorInstrumentation::continueWithPolicyIgnore(*frame, *mainResourceLoader->identifier(), *this, m_response);
1166 stopLoadingForPolicyChange();
1167 return;
1168 }
1169
1170 if (m_response.isInHTTPFamily()) {
1171 int status = m_response.httpStatusCode(); // Status may be zero when loading substitute data, in particular from a WebArchive.
1172 if (status) {
1173 if (status < httpStatus200OK || status >= httpStatus300MultipleChoices) {
1174 if (RefPtr owner = dynamicDowncast<HTMLObjectElement>(frame->ownerElement())) {
1175 owner->renderFallbackContent();
1176 // object elements are no longer rendered after we fallback, so don't
1177 // keep trying to process data from their load
1178 cancelMainResourceLoad(protect(frameLoader())->cancelledError(m_request));
1179 }
1180 } else if (status == httpStatus204NoContent || status == httpStatus205ResetContent) {
1181 // 204/205 responses should abort navigation without changing the document.
1182 stopLoadingForPolicyChange();
1183 return;
1184 }
1185 }
1186 }
1187
1188 if (!isStopping() && m_substituteData.isValid() && isLoadingMainResource()) {
1189 RefPtr content = m_substituteData.content();
1190 if (content && content->size()) {
1191 content->forEachSegmentAsSharedBuffer([&](auto&& buffer) {
1192 dataReceived(buffer);
1193 });
1194 }
1195 if (isLoadingMainResource())
1196 finishedLoading();
1197
1198 // Remove ourselves as a client of this CachedResource as we've decided to commit substitute data but the
1199 // load may keep going and be useful to other clients of the CachedResource. If we did not do this, we
1200 // may receive data later on even though this DocumentLoader has finished loading.
1201 clearMainResource();
1202 }
1203}
1204
1205void DocumentLoader::commitLoad(const SharedBuffer& data)
1206{
1207 // Both unloading the old page and parsing the new page may execute JavaScript which destroys the datasource
1208 // by starting a new load, so retain temporarily.
1209 RefPtr protectedFrame { m_frame.get() };
1210 Ref protectedThis { *this };
1211
1212 commitIfReady();
1213 RefPtr frameLoader = this->frameLoader();
1214 if (!frameLoader)
1215 return;
1216#if ENABLE(WEB_ARCHIVE)(defined 1 && 1) || ENABLE(MHTML)(defined 0 && 0)
1217 if (ArchiveFactory::isArchiveMIMEType(response().mimeType()))
1218 return;
1219#endif
1220 Ref client = frameLoader->client();
1221 client->committedLoad(this, data);
1222
1223 if (isMultipartReplacingLoad())
1224 client->didReplaceMultipartContent();
1225}
1226
1227ResourceError DocumentLoader::interruptedForPolicyChangeError() const
1228{
1229 if (!frameLoader()) {
1230 ResourceError error;
1231 error.setType(ResourceError::Type::Cancellation);
1232 return error;
1233 }
1234
1235 auto error = platformStrategies()->loaderStrategy()->interruptedForPolicyChangeError(request());
1236 error.setType(ResourceError::Type::Cancellation);
1237 return error;
1238}
1239
1240void DocumentLoader::stopLoadingForPolicyChange(LoadWillContinueInAnotherProcess loadWillContinueInAnotherProcess)
1241{
1242 cancelMainResourceLoad(interruptedForPolicyChangeError(), loadWillContinueInAnotherProcess);
1243}
1244
1245// https://w3c.github.io/ServiceWorker/#control-and-use-window-client
1246static inline bool shouldUseActiveServiceWorkerFromParent(const Document& document, const Document& parent)
1247{
1248 return !document.url().protocolIsInHTTPFamily() && !document.securityOrigin().isOpaque() && protect(parent.securityOrigin())->isSameOriginDomain(protect(document.securityOrigin()));
1249}
1250
1251#if ENABLE(CONTENT_EXTENSIONS)(defined 1 && 1)
1252static inline bool NODELETE[[clang::annotate_type("webkit.nodelete")]] shouldEnableResourceMonitor(const Frame& frame)
1253{
1254 if (frame.isMainFrame())
1255 return false;
1256
1257 return frame.settings().iFrameResourceMonitoringEnabled();
1258}
1259#endif
1260
1261void DocumentLoader::commitData(const SharedBuffer& data)
1262{
1263 if (!m_gotFirstByte) {
1264 m_gotFirstByte = true;
1265 bool hasBegun = m_writer.begin(documentURL(), false, nullptr, m_resultingClientId, &triggeringAction());
1266 if (!hasBegun)
1267 return;
1268
1269 m_writer.setDocumentWasLoadedAsPartOfNavigation();
1270
1271 RefPtr frame = m_frame.get();
1272 RefPtr documentOrNull = frame ? frame->document() : nullptr;
1273
1274 auto scope = makeScopeExit([this, protectedThis = Ref { *this }, documentOrNull] {
1275 if (auto createdCallback = std::exchange(m_whenDocumentIsCreatedCallback, { }))
1276 createdCallback(isInFinishedLoadingOfEmptyDocument() ? nullptr : documentOrNull.get());
1277 });
1278
1279 if (!documentOrNull)
1280 return;
1281 Ref document = *documentOrNull;
1282 ASSERT(frame)((void)0);
1283
1284#if ENABLE(CONTENT_EXTENSIONS)(defined 1 && 1)
1285 if (shouldEnableResourceMonitor(*frame)) {
1286 URL url = documentURL();
1287
1288 if (!url.isEmpty() && url.protocolIsInHTTPFamily())
1289 protect(document->resourceMonitor())->setDocumentURL(WTF::move(url));
1290 }
1291#endif
1292
1293 if (SecurityPolicy::allowSubstituteDataAccessToLocal() && m_originalSubstituteDataWasValid) {
1294 // If this document was loaded with substituteData, then the document can
1295 // load local resources. See https://bugs.webkit.org/show_bug.cgi?id=16756
1296 // and https://bugs.webkit.org/show_bug.cgi?id=19760 for further
1297 // discussion.
1298 protect(document->securityOrigin())->grantLoadLocalResources();
1299 }
1300
1301 if (protect(frameLoader())->stateMachine().creatingInitialEmptyDocument())
1302 return;
1303
1304#if ENABLE(WEB_ARCHIVE)(defined 1 && 1) || ENABLE(MHTML)(defined 0 && 0)
1305 if (RefPtr archive = m_archive; archive && archive->shouldOverrideBaseURL())
1306 document->setBaseURLOverride(archive->mainResource()->url());
1307#endif
1308 if (m_canUseServiceWorkers) {
1309 if (!document->securityOrigin().isOpaque()) {
1310 if (m_serviceWorkerRegistrationData && m_serviceWorkerRegistrationData->activeWorker) {
1311 document->setActiveServiceWorker(ServiceWorker::getOrCreate(document, WTF::move(m_serviceWorkerRegistrationData->activeWorker.value())));
1312 m_serviceWorkerRegistrationData = { };
1313 } else if (RefPtr parent = document->parentDocument()) {
1314 if (shouldUseActiveServiceWorkerFromParent(document, *parent))
1315 document->setActiveServiceWorker(parent->activeServiceWorker());
1316 }
1317 } else if (m_resultingClientId) {
1318 // In case document has an opaque origin, say due to sandboxing, we should have created a new context, let's create a new identifier instead.
1319 if (document->securityOrigin().isOpaque())
1320 document->createNewIdentifier();
1321 }
1322
1323 if (m_frame->document()->activeServiceWorker() || document->url().protocolIsInHTTPFamily() || (document->page() && document->page()->isServiceWorkerPage()) || (document->parentDocument() && shouldUseActiveServiceWorkerFromParent(document, *protect(document->parentDocument()))))
1324 document->setServiceWorkerConnection(&ServiceWorkerProvider::singleton().serviceWorkerConnection());
1325
1326 if (m_resultingClientId) {
1327 if (*m_resultingClientId != document->identifier())
1328 unregisterReservedServiceWorkerClient();
1329 scriptExecutionContextIdentifierToLoaderMap().remove(*m_resultingClientId);
1330 m_resultingClientId = std::nullopt;
1331 }
1332 }
1333 // Call receivedFirstData() exactly once per load. We should only reach this point multiple times
1334 // for multipart loads, and FrameLoader::isMultipartReplacing() will be true after the first time.
1335 if (!isMultipartReplacingLoad())
1336 protect(frameLoader())->receivedFirstData();
1337
1338 // The load could be canceled under receivedFirstData(), which makes delegate calls and even sometimes dispatches DOM events.
1339 if (!isLoading())
1340 return;
1341
1342 if (RefPtr window = document->window()) {
1343 window->prewarmLocalStorageIfNecessary();
1344
1345 if (m_mainResource) {
1346 auto* metrics = m_response.deprecatedNetworkLoadMetricsOrNull();
1347 NetworkLoadMetrics finalMetrics = metrics ? *metrics : NetworkLoadMetrics::emptyMetrics();
1348 auto source = m_response.source();
1349 finalMetrics.fromCache = source == ResourceResponse::Source::DiskCache
1350 || source == ResourceResponse::Source::DiskCacheAfterValidation
1351 || source == ResourceResponse::Source::MemoryCache
1352 || source == ResourceResponse::Source::MemoryCacheAfterValidation;
1353 if (RefPtr frameLoader = this->frameLoader())
1354 finalMetrics.fromPrefetch = frameLoader->documentPrefetcher().wasPrefetched(url());
1355 protect(window->performance())->addNavigationTiming(*this, document, *m_mainResource, timing(), finalMetrics);
1356 }
1357 }
1358
1359 DocumentWriter::IsEncodingUserChosen userChosen;
1360 String encoding;
1361 if (overrideEncoding().isNull()) {
1362 userChosen = DocumentWriter::IsEncodingUserChosen::No;
1363 encoding = response().textEncodingName();
1364#if ENABLE(WEB_ARCHIVE)(defined 1 && 1) || ENABLE(MHTML)(defined 0 && 0)
1365 if (RefPtr archive = m_archive; archive && archive->shouldUseMainResourceEncoding())
1366 encoding = archive->mainResource()->textEncoding();
1367#endif
1368 } else {
1369 userChosen = DocumentWriter::IsEncodingUserChosen::Yes;
1370 encoding = overrideEncoding();
1371 }
1372
1373 m_writer.setEncoding(encoding, userChosen);
1374 }
1375
1376#if ENABLE(CONTENT_EXTENSIONS)(defined 1 && 1)
1377 if (!m_pendingNamedContentExtensionStyleSheets.isEmpty() || !m_pendingContentExtensionDisplayNoneSelectors.isEmpty()) {
1378 CheckedRef extensionStyleSheets = protect(m_frame->document())->extensionStyleSheets();
1379 for (auto& pendingStyleSheet : m_pendingNamedContentExtensionStyleSheets)
1380 extensionStyleSheets->maybeAddContentExtensionSheet(pendingStyleSheet.key, Ref { pendingStyleSheet.value });
1381 for (auto& pendingSelectorEntry : m_pendingContentExtensionDisplayNoneSelectors) {
1382 for (const auto& pendingSelector : pendingSelectorEntry.value)
1383 extensionStyleSheets->addDisplayNoneSelector(pendingSelectorEntry.key, pendingSelector.first, pendingSelector.second);
1384 }
1385 m_pendingNamedContentExtensionStyleSheets.clear();
1386 m_pendingContentExtensionDisplayNoneSelectors.clear();
1387 }
1388#endif
1389
1390 ASSERT(m_frame->document()->parsing())((void)0);
1391 m_writer.addData(data);
1392}
1393
1394void DocumentLoader::dataReceived(CachedResource& resource, const SharedBuffer& buffer)
1395{
1396 ASSERT_UNUSED(resource, &resource == m_mainResource)((void)resource);
1397 dataReceived(buffer);
1398}
1399
1400void DocumentLoader::dataReceived(const SharedBuffer& buffer)
1401{
1402#if ENABLE(CONTENT_FILTERING)(defined 1 && 1)
1403 if (RefPtr contentFilter = m_contentFilter; contentFilter && !contentFilter->continueAfterDataReceived(buffer, ContentFilter::FromDocumentLoader::Yes))
1404 return;
1405#endif
1406
1407 ASSERT(!buffer.span().empty())((void)0);
1408 ASSERT(!m_response.isNull())((void)0);
1409
1410 // There is a bug in CFNetwork where callbacks can be dispatched even when loads are deferred.
1411 // See <rdar://problem/6304600> for more details.
1412#if !USE(CF)(defined 1 && 1)
1413 ASSERT(!mainResourceLoader() || !mainResourceLoader()->defersLoading())((void)0);
1414#endif
1415
1416 if (m_identifierForLoadWithoutResourceLoader)
1417 protect(frameLoader())->notifier().dispatchDidReceiveData(this, *m_identifierForLoadWithoutResourceLoader, &buffer, buffer.size(), -1);
1418
1419 if (!isMultipartReplacingLoad())
1420 commitLoad(buffer);
1421}
1422
1423void DocumentLoader::setupForMultipartReplace()
1424{
1425 if (!mainResourceData())
1426 return;
1427
1428 protect(frameLoader()->client())->willReplaceMultipartContent();
1429
1430 maybeFinishLoadingMultipartContent();
1431 maybeCreateArchive();
1432 m_writer.end();
1433 protect(frameLoader())->setMultipartReplacing();
1434 m_gotFirstByte = false;
1435
1436 unregisterReservedServiceWorkerClient();
1437 if (m_resultingClientId) {
1438 scriptExecutionContextIdentifierToLoaderMap().remove(*m_resultingClientId);
1439 m_resultingClientId = std::nullopt;
1440 }
1441
1442 stopLoadingSubresources();
1443 stopLoadingPlugIns();
1444#if ENABLE(WEB_ARCHIVE)(defined 1 && 1) || ENABLE(MHTML)(defined 0 && 0)
1445 clearArchiveResources();
1446#endif
1447}
1448
1449void DocumentLoader::checkLoadComplete()
1450{
1451 if (!m_frame || isLoading())
1452 return;
1453
1454 ASSERT(this == frameLoader()->activeDocumentLoader())((void)0);
1455 protect(protect(m_frame->document())->window())->finishedLoading();
1456}
1457
1458void DocumentLoader::applyPoliciesToSettings()
1459{
1460 if (!m_frame) {
1461 ASSERT_NOT_REACHED()((void)0);
1462 return;
1463 }
1464
1465 if (!m_frame->isMainFrame())
1466 return;
1467
1468#if ENABLE(MEDIA_SOURCE)(defined 1 && 1)
1469 m_frame->settings().setMediaSourceEnabled(m_mediaSourcePolicy == MediaSourcePolicy::Default ? Settings::platformDefaultMediaSourceEnabled() : m_mediaSourcePolicy == MediaSourcePolicy::Enable);
1470#endif
1471#if ENABLE(WEBKIT_OVERFLOW_SCROLLING_CSS_PROPERTY)(defined 1 && 1)
1472 if (m_legacyOverflowScrollingTouchPolicy == LegacyOverflowScrollingTouchPolicy::Disable)
1473 m_frame->settings().setLegacyOverflowScrollingTouchEnabled(false);
1474#endif
1475#if ENABLE(TEXT_AUTOSIZING)(defined 1 && 1)
1476 m_frame->settings().setIdempotentModeAutosizingOnlyHonorsPercentages(m_idempotentModeAutosizingOnlyHonorsPercentages);
1477#endif
1478
1479 if (m_pushAndNotificationsEnabledPolicy != PushAndNotificationsEnabledPolicy::UseGlobalPolicy) {
1480 bool enabled = m_pushAndNotificationsEnabledPolicy == PushAndNotificationsEnabledPolicy::Yes;
1481 m_frame->settings().setPushAPIEnabled(enabled);
1482#if ENABLE(NOTIFICATIONS)(defined 1 && 1)
1483 m_frame->settings().setNotificationsEnabled(enabled);
1484#endif
1485#if ENABLE(NOTIFICATION_EVENT)(defined 1 && 1)
1486 m_frame->settings().setNotificationEventEnabled(enabled);
1487#endif
1488#if PLATFORM(IOS)(defined 1 && 1)
1489 m_frame->settings().setAppBadgeEnabled(enabled);
1490#endif
1491 }
1492
1493 if (m_inlineMediaPlaybackPolicy != InlineMediaPlaybackPolicy::Default)
1494 m_frame->settings().setInlineMediaPlaybackRequiresPlaysInlineAttribute(m_inlineMediaPlaybackPolicy == InlineMediaPlaybackPolicy::RequiresPlaysInlineAttribute);
1495}
1496
1497ColorSchemePreference NODELETE[[clang::annotate_type("webkit.nodelete")]] DocumentLoader::colorSchemePreference() const
1498{
1499 return m_colorSchemePreference;
1500}
1501
1502void DocumentLoader::attachToFrame(LocalFrame& frame)
1503{
1504 if (m_frame == &frame)
1505 return;
1506
1507 ASSERT(!m_frame)((void)0);
1508 observeFrame(&frame);
1509 m_writer.setFrame(frame);
1510 attachToFrame();
1511
1512#if ASSERT_ENABLED0
1513 m_hasEverBeenAttached = true;
1514#endif
1515
1516 applyPoliciesToSettings();
1517}
1518
1519void DocumentLoader::attachToFrame()
1520{
1521 ASSERT(m_frame)((void)0);
1522 DOCUMENTLOADER_RELEASE_LOG_FORWARDABLE(DOCUMENTLOADER_ATTACHTOFRAME)do { if (auto& client = logClient()) client->DOCUMENTLOADER_ATTACHTOFRAME
(PAGE_ID, FRAME_ID, IS_MAIN_FRAME); else clang diagnostic push
clang diagnostic ignored "-Wunknown-warning-option" clang diagnostic
ignored "-Wunsafe-buffer-usage" clang diagnostic ignored "-Wunsafe-buffer-usage-in-libc-call"
clang diagnostic ignored "-Wunsafe-buffer-usage-in-format-attr-call"
[[clang::suppress]] __extension__({ os_log_t _log_tmp = (LogNetwork
.osLogChannel); os_log_type_t _type_tmp = (OS_LOG_TYPE_DEFAULT
); if (os_log_type_enabled(_log_tmp, _type_tmp)) { __extension__
({ clang diagnostic push clang diagnostic ignored "-Wvla" clang
diagnostic error "-Wformat" _Static_assert(__builtin_constant_p
("[pageID=%" "ll" "u" ", frameID=%" "ll" "u" ", isMainFrame=%d] DocumentLoader::attachToFrame"
), "format/label/description argument must be a string constant"
); __attribute__((section("__TEXT,__oslogstring,cstring_literals"
),internal_linkage)) static const char _os_fmt_str[] __asm("LOS_LOG62"
) = "[pageID=%" "ll" "u" ", frameID=%" "ll" "u" ", isMainFrame=%d] DocumentLoader::attachToFrame"
; uint8_t _Alignas(16) __attribute__((uninitialized)) _os_fmt_buf
[__builtin_os_log_format_buffer_size("[pageID=%" "ll" "u" ", frameID=%"
"ll" "u" ", isMainFrame=%d] DocumentLoader::attachToFrame", WTF
::safePrintfType(PAGE_ID) , WTF::safePrintfType(FRAME_ID) , WTF
::safePrintfType(IS_MAIN_FRAME))]; _os_log_impl(&__dso_handle
, _log_tmp, _type_tmp, _os_fmt_str, (uint8_t *)__builtin_os_log_format
(_os_fmt_buf, "[pageID=%" "ll" "u" ", frameID=%" "ll" "u" ", isMainFrame=%d] DocumentLoader::attachToFrame"
, WTF::safePrintfType(PAGE_ID) , WTF::safePrintfType(FRAME_ID
) , WTF::safePrintfType(IS_MAIN_FRAME)), (uint32_t)sizeof(_os_fmt_buf
)) clang diagnostic pop ; }); } }) clang diagnostic pop ; } while
(0)
;
1523}
1524
1525void DocumentLoader::detachFromFrame(LoadWillContinueInAnotherProcess loadWillContinueInAnotherProcess)
1526{
1527 DOCUMENTLOADER_RELEASE_LOG_FORWARDABLE(DOCUMENTLOADER_DETACHFROMFRAME)do { if (auto& client = logClient()) client->DOCUMENTLOADER_DETACHFROMFRAME
(PAGE_ID, FRAME_ID, IS_MAIN_FRAME); else clang diagnostic push
clang diagnostic ignored "-Wunknown-warning-option" clang diagnostic
ignored "-Wunsafe-buffer-usage" clang diagnostic ignored "-Wunsafe-buffer-usage-in-libc-call"
clang diagnostic ignored "-Wunsafe-buffer-usage-in-format-attr-call"
[[clang::suppress]] __extension__({ os_log_t _log_tmp = (LogNetwork
.osLogChannel); os_log_type_t _type_tmp = (OS_LOG_TYPE_DEFAULT
); if (os_log_type_enabled(_log_tmp, _type_tmp)) { __extension__
({ clang diagnostic push clang diagnostic ignored "-Wvla" clang
diagnostic error "-Wformat" _Static_assert(__builtin_constant_p
("[pageID=%" "ll" "u" ", frameID=%" "ll" "u" ", isMainFrame=%d] DocumentLoader::detachFromFrame"
), "format/label/description argument must be a string constant"
); __attribute__((section("__TEXT,__oslogstring,cstring_literals"
),internal_linkage)) static const char _os_fmt_str[] __asm("LOS_LOG63"
) = "[pageID=%" "ll" "u" ", frameID=%" "ll" "u" ", isMainFrame=%d] DocumentLoader::detachFromFrame"
; uint8_t _Alignas(16) __attribute__((uninitialized)) _os_fmt_buf
[__builtin_os_log_format_buffer_size("[pageID=%" "ll" "u" ", frameID=%"
"ll" "u" ", isMainFrame=%d] DocumentLoader::detachFromFrame"
, WTF::safePrintfType(PAGE_ID) , WTF::safePrintfType(FRAME_ID
) , WTF::safePrintfType(IS_MAIN_FRAME))]; _os_log_impl(&__dso_handle
, _log_tmp, _type_tmp, _os_fmt_str, (uint8_t *)__builtin_os_log_format
(_os_fmt_buf, "[pageID=%" "ll" "u" ", frameID=%" "ll" "u" ", isMainFrame=%d] DocumentLoader::detachFromFrame"
, WTF::safePrintfType(PAGE_ID) , WTF::safePrintfType(FRAME_ID
) , WTF::safePrintfType(IS_MAIN_FRAME)), (uint32_t)sizeof(_os_fmt_buf
)) clang diagnostic pop ; }); } }) clang diagnostic pop ; } while
(0)
;
1528
1529 RefPtr frame = m_frame.get();
1530#if ASSERT_ENABLED0
1531 if (m_hasEverBeenAttached)
1532 ASSERT_WITH_MESSAGE(frame, "detachFromFrame() is being called on a DocumentLoader twice without an attachToFrame() inbetween")((void)0);
1533 else
1534 ASSERT_WITH_MESSAGE(frame, "detachFromFrame() is being called on a DocumentLoader that has never attached to any Frame")((void)0);
1535#endif
1536 Ref protectedThis { *this };
1537
1538 // It never makes sense to have a document loader that is detached from its
1539 // frame have any loads active, so kill all the loads.
1540 stopLoading();
1541 if (m_mainResource && m_mainResource->hasClient(*this))
1542 m_mainResource->removeClient(*this);
1543#if ENABLE(CONTENT_FILTERING)(defined 1 && 1)
1544 if (RefPtr contentFilter = m_contentFilter)
1545 contentFilter->stopFilteringMainResource();
1546#endif
1547
1548 cancelPolicyCheckIfNeeded();
1549
1550 // cancelPolicyCheckIfNeeded can clear m_frame if the policy check
1551 // is stopped, resulting in a recursive call into this detachFromFrame.
1552 // If m_frame is nullptr after cancelPolicyCheckIfNeeded, our work is
1553 // already done so just return.
1554 frame = m_frame.get();
1555 if (!frame)
1556 return;
1557
1558 if (auto navigationID = std::exchange(m_navigationID, { }))
1559 frame->loader().client().documentLoaderDetached(*navigationID, loadWillContinueInAnotherProcess);
1560
1561 InspectorInstrumentation::loaderDetachedFromFrame(*frame, *this);
1562
1563 observeFrame(nullptr);
1564}
1565
1566void DocumentLoader::setNavigationID(NavigationIdentifier navigationID)
1567{
1568 m_navigationID = navigationID;
1569}
1570
1571void DocumentLoader::clearMainResourceLoader()
1572{
1573 m_loadingMainResource = false;
1574 m_isContinuingLoad = ShouldTreatAsContinuingLoad::No;
1575
1576 RefPtr frameLoader = this->frameLoader();
1577
1578 if (!frameLoader)
1579 return;
1580
1581 if (this == frameLoader->activeDocumentLoader())
1582 checkLoadComplete();
1583}
1584
1585#if ENABLE(APPLICATION_MANIFEST)(defined 1 && 1)
1586
1587void DocumentLoader::loadApplicationManifest(CompletionHandler<void(const std::optional<ApplicationManifest>&)>&& completionHandler)
1588{
1589 if (completionHandler)
1590 m_loadApplicationManifestCallbacks.append(WTF::move(completionHandler));
1591
1592 bool isLoading = !!m_applicationManifestLoader;
1593 auto notifyIfUnableToLoad = makeScopeExit([this, protectedThis = Ref { *this }, &isLoading] {
1594 if (!isLoading || m_finishedLoadingApplicationManifest)
1595 notifyFinishedLoadingApplicationManifest();
1596 });
1597
1598 if (isLoading)
1599 return;
1600
1601 RefPtr document = this->document();
1602 if (!document)
1603 return;
1604
1605 if (!document->isTopDocument())
1606 return;
1607
1608 if (document->url().isEmpty() || document->url().protocolIsAbout())
1609 return;
1610
1611 RefPtr head = document->head();
1612 if (!head)
1613 return;
1614
1615 URL manifestURL;
1616 bool useCredentials = false;
1617 for (Ref link : childrenOfType<HTMLLinkElement>(*head)) {
1618 if (!link->isApplicationManifest())
1619 continue;
1620
1621 auto href = link->href();
1622 if (href.isEmpty() || !href.isValid())
1623 continue;
1624
1625 if (!link->mediaAttributeMatches())
1626 continue;
1627
1628 manifestURL = href;
1629 useCredentials = equalLettersIgnoringASCIICase(link->attributeWithoutSynchronization(HTMLNames::crossoriginAttr), "use-credentials"_s);
1630 break;
1631 }
1632
1633 if (manifestURL.isEmpty() || !manifestURL.isValid())
1634 return;
1635
1636 Ref applicationManifestLoader = ApplicationManifestLoader::create(*this, manifestURL, useCredentials);
1637 m_applicationManifestLoader = applicationManifestLoader.copyRef();
1638
1639 isLoading = applicationManifestLoader->startLoading();
1640 if (!isLoading)
1641 m_finishedLoadingApplicationManifest = true;
1642}
1643
1644void DocumentLoader::finishedLoadingApplicationManifest(ApplicationManifestLoader& loader)
1645{
1646 ASSERT_UNUSED(loader, &loader == m_applicationManifestLoader.get())((void)loader);
1647
1648 // If the DocumentLoader has detached from its frame, all manifest loads should have already been canceled.
1649 ASSERT(m_frame)((void)0);
1650
1651 ASSERT(!m_finishedLoadingApplicationManifest)((void)0);
1652 m_finishedLoadingApplicationManifest = true;
1653
1654 notifyFinishedLoadingApplicationManifest();
1655}
1656
1657void DocumentLoader::notifyFinishedLoadingApplicationManifest()
1658{
1659 std::optional<ApplicationManifest> manifest = m_applicationManifestLoader ? Ref { *m_applicationManifestLoader }->processManifest() : std::nullopt;
1660 ASSERT_IMPLIES(manifest, m_finishedLoadingApplicationManifest)((void)0);
1661
1662 for (auto& callback : std::exchange(m_loadApplicationManifestCallbacks, { }))
1663 callback(manifest);
1664}
1665
1666#endif // ENABLE(APPLICATION_MANIFEST)
1667
1668bool DocumentLoader::isLoadingInAPISense() const
1669{
1670 // Once a frame has loaded, we no longer need to consider subresources,
1671 // but we still need to consider subframes.
1672 if (frameLoader()->state() != FrameState::Complete) {
1673 ASSERT(m_frame->document())((void)0);
1674 Ref document = *m_frame->document();
1675 if ((isLoadingMainResource() || !document->loadEventFinished()) && isLoading())
1676 return true;
1677 if (m_cachedResourceLoader->requestCount())
1678 return true;
1679 if (document->isDelayingLoadEvent())
1680 return true;
1681 if (document->processingLoadEvent())
1682 return true;
1683 if (document->hasActiveParser())
1684 return true;
1685 RefPtr scriptableParser = document->scriptableDocumentParser();
1686 if (scriptableParser && scriptableParser->hasScriptsWaitingForStylesheets())
1687 return true;
1688 }
1689 return protect(frameLoader())->subframeIsLoading();
1690}
1691
1692bool DocumentLoader::maybeCreateArchive()
1693{
1694#if !ENABLE(WEB_ARCHIVE)(defined 1 && 1) && !ENABLE(MHTML)(defined 0 && 0)
1695 return false;
1696#else
1697 // Give the archive machinery a crack at this document. If the MIME type is not an archive type, it will return 0.
1698 RefPtr archive = ArchiveFactory::create(m_response.url(), mainResourceData().get(), m_response.mimeType());
1699 m_archive = archive.copyRef();
1700 if (!archive)
1701 return false;
1702
1703 addAllArchiveResources(*archive);
1704 ASSERT(archive->mainResource())((void)0);
1705 Ref mainResource = *archive->mainResource();
1706 Ref parsedArchiveData = protect(mainResource->data())->makeContiguous();
1707 m_parsedArchiveData = parsedArchiveData.copyRef();
1708 m_writer.setMIMEType(mainResource->mimeType());
1709
1710 ASSERT(m_frame->document())((void)0);
1711 commitData(parsedArchiveData);
1712 return true;
1713#endif
1714}
1715
1716#if ENABLE(WEB_ARCHIVE)(defined 1 && 1) || ENABLE(MHTML)(defined 0 && 0)
1717
1718void DocumentLoader::setArchive(Ref<Archive>&& archive)
1719{
1720 m_archive = archive.copyRef();
1721 addAllArchiveResources(archive);
1722}
1723
1724void DocumentLoader::addAllArchiveResources(Archive& archive)
1725{
1726 if (!m_archiveResourceCollection)
1727 m_archiveResourceCollection = makeUnique<ArchiveResourceCollection>();
1728 m_archiveResourceCollection->addAllResources(archive);
1729}
1730
1731// FIXME: Adding a resource directly to a DocumentLoader/ArchiveResourceCollection seems like bad design, but is API some apps rely on.
1732// Can we change the design in a manner that will let us deprecate that API without reducing functionality of those apps?
1733void DocumentLoader::addArchiveResource(Ref<ArchiveResource>&& resource)
1734{
1735 if (!m_archiveResourceCollection)
1736 m_archiveResourceCollection = makeUnique<ArchiveResourceCollection>();
1737 m_archiveResourceCollection->addResource(WTF::move(resource));
1738}
1739
1740RefPtr<Archive> DocumentLoader::popArchiveForSubframe(const String& frameName, const URL& url)
1741{
1742 return m_archiveResourceCollection ? m_archiveResourceCollection->popSubframeArchive(frameName, url) : nullptr;
1743}
1744
1745void DocumentLoader::clearArchiveResources()
1746{
1747 m_archiveResourceCollection = nullptr;
1748 m_substituteResourceDeliveryTimer.stop();
1749}
1750
1751SharedBuffer* DocumentLoader::parsedArchiveData() const
1752{
1753 return m_parsedArchiveData;
1754}
1755
1756#endif // ENABLE(WEB_ARCHIVE) || ENABLE(MHTML)
1757
1758RefPtr<ArchiveResource> DocumentLoader::archiveResourceForURL(const URL& url) const
1759{
1760 if (!m_archiveResourceCollection)
1761 return nullptr;
1762 RefPtr resource = m_archiveResourceCollection->archiveResourceForURL(url);
1763 if (!resource || resource->shouldIgnoreWhenUnarchiving())
1764 return nullptr;
1765 return resource;
1766}
1767
1768RefPtr<ArchiveResource> DocumentLoader::mainResource() const
1769{
1770 RefPtr<FragmentedSharedBuffer> data = mainResourceData();
1771 if (!data)
1772 data = SharedBuffer::create();
1773 auto& response = this->response();
1774 return ArchiveResource::create(WTF::move(data), response.url(), response.mimeType(), response.textEncodingName(), frame()->tree().uniqueName());
1775}
1776
1777RefPtr<ArchiveResource> DocumentLoader::subresource(const URL& url) const
1778{
1779 if (!isCommitted())
1780 return nullptr;
1781
1782 auto* resource = m_cachedResourceLoader->cachedResource(url);
Local variable 'resource' is uncounted and unsafe
1783 if (!resource || !resource->isLoaded())
1784 return archiveResourceForURL(url);
1785
1786 if (resource->type() == CachedResource::Type::MainResource)
1787 return nullptr;
1788
1789 RefPtr data = resource->resourceBuffer();
1790 if (!data)
1791 return nullptr;
1792
1793 return ArchiveResource::create(data.get(), url, resource->response());
1794}
1795
1796Vector<Ref<ArchiveResource>> DocumentLoader::subresources() const
1797{
1798 if (!isCommitted())
1799 return { };
1800
1801 Vector<Ref<ArchiveResource>> subresources;
1802 for (auto& handle : m_cachedResourceLoader->allCachedResources().values()) {
1803 if (auto subresource = this->subresource(handle->url()))
1804 subresources.append(subresource.releaseNonNull());
1805 }
1806 return subresources;
1807}
1808
1809void DocumentLoader::deliverSubstituteResourcesAfterDelay()
1810{
1811 if (m_pendingSubstituteResources.isEmpty())
1812 return;
1813 ASSERT(m_frame)((void)0);
1814 ASSERT(m_frame->page())((void)0);
1815 if (m_frame->page()->defersLoading())
1816 return;
1817
1818 if (!m_substituteResourceDeliveryTimer.isActive())
1819 m_substituteResourceDeliveryTimer.startOneShot(0_s);
1820}
1821
1822void DocumentLoader::substituteResourceDeliveryTimerFired()
1823{
1824 if (m_pendingSubstituteResources.isEmpty())
1825 return;
1826 ASSERT(m_frame)((void)0);
1827 ASSERT(m_frame->page())((void)0);
1828 if (m_frame->page()->defersLoading())
1829 return;
1830
1831 auto pendingSubstituteResources = WTF::move(m_pendingSubstituteResources);
1832 for (auto& pendingSubstituteResource : pendingSubstituteResources) {
1833 auto& loader = pendingSubstituteResource.key;
1834 if (auto& resource = pendingSubstituteResource.value)
1835 resource->deliver(loader);
1836 else {
1837 // A null resource means that we should fail the load.
1838 // FIXME: Maybe we should use another error here - something like "not in cache".
1839 loader->didFail(loader->cannotShowURLError());
1840 }
1841 }
1842}
1843
1844#if ASSERT_ENABLED0
1845
1846bool DocumentLoader::isSubstituteLoadPending(ResourceLoader* loader) const
1847{
1848 return m_pendingSubstituteResources.contains(loader);
1849}
1850
1851#endif // ASSERT_ENABLED
1852
1853void DocumentLoader::cancelPendingSubstituteLoad(ResourceLoader* loader)
1854{
1855 if (m_pendingSubstituteResources.isEmpty())
1856 return;
1857 m_pendingSubstituteResources.remove(loader);
1858 if (m_pendingSubstituteResources.isEmpty())
1859 m_substituteResourceDeliveryTimer.stop();
1860}
1861
1862#if ENABLE(WEB_ARCHIVE)(defined 1 && 1) || ENABLE(MHTML)(defined 0 && 0)
1863
1864bool DocumentLoader::scheduleArchiveLoad(ResourceLoader& loader, const ResourceRequest& request)
1865{
1866 if (RefPtr resource = archiveResourceForURL(request.url())) {
1867 scheduleSubstituteResourceLoad(loader, *resource);
1868 return true;
1869 }
1870
1871 RefPtr archive = m_archive;
1872 if (!archive)
1873 return false;
1874
1875#if ENABLE(WEB_ARCHIVE)(defined 1 && 1)
1876 // The idea of WebArchiveDebugMode is that we should fail instead of trying to fetch from the network.
1877 // Returning true ensures the caller will not try to fetch from the network.
1878 if (m_frame->settings().webArchiveDebugModeEnabled() && responseMIMEType() == "application/x-webarchive"_s)
1879 return true;
1880#endif
1881
1882 // If we want to load from the archive only, then we should always return true so that the caller
1883 // does not try to fetch from the network.
1884 return archive->shouldLoadFromArchiveOnly();
1885}
1886
1887#endif
1888
1889void DocumentLoader::scheduleSubstituteResourceLoad(ResourceLoader& loader, SubstituteResource& resource)
1890{
1891 ASSERT(!loader.options().serviceWorkerRegistrationIdentifier)((void)0);
1892 m_pendingSubstituteResources.set(loader, &resource);
1893 deliverSubstituteResourcesAfterDelay();
1894}
1895
1896void DocumentLoader::scheduleCannotShowURLError(ResourceLoader& loader)
1897{
1898 m_pendingSubstituteResources.set(loader, nullptr);
1899 deliverSubstituteResourcesAfterDelay();
1900}
1901
1902void DocumentLoader::addResponse(const ResourceResponse& response)
1903{
1904 if (!m_stopRecordingResponses)
1905 m_responses.append(response);
1906}
1907
1908void DocumentLoader::stopRecordingResponses()
1909{
1910 m_stopRecordingResponses = true;
1911 m_responses.shrinkToFit();
1912}
1913
1914void DocumentLoader::setCustomHeaderFields(Vector<CustomHeaderFields>&& fields)
1915{
1916 m_customHeaderFields = WTF::move(fields);
1917}
1918
1919void DocumentLoader::setTitle(const StringWithDirection& title)
1920{
1921 if (m_pageTitle == title)
1922 return;
1923
1924 protect(frameLoader())->willChangeTitle(this);
1925 m_pageTitle = title;
1926 if (RefPtr frameLoader = this->frameLoader())
1927 frameLoader->didChangeTitle(this);
1928}
1929
1930URL DocumentLoader::urlForHistory() const
1931{
1932 // Return the URL to be used for history and B/F list.
1933 // Returns nil for WebDataProtocol URLs that aren't alternates
1934 // for unreachable URLs, because these can't be stored in history.
1935 if (m_substituteData.isValid() && m_substituteData.shouldRevealToSessionHistory() != SubstituteData::SessionHistoryVisibility::Visible)
1936 return unreachableURL();
1937
1938 return m_originalRequestCopy.url();
1939}
1940
1941bool DocumentLoader::urlForHistoryReflectsFailure() const
1942{
1943 return m_substituteData.isValid() || m_response.httpStatusCode() >= 400;
1944}
1945
1946URL DocumentLoader::documentURL() const
1947{
1948 URL url = substituteData().response().url();
1949#if ENABLE(WEB_ARCHIVE)(defined 1 && 1)
1950 if (RefPtr archive = m_archive; url.isEmpty() && archive && archive->shouldUseMainResourceURL())
1951 url = archive->mainResource()->url();
1952#endif
1953 if (url.isEmpty())
1954 url = m_request.url();
1955 if (url.isEmpty())
1956 url = m_response.url();
1957 return url;
1958}
1959
1960#if PLATFORM(IOS_FAMILY)(defined 1 && 1)
1961
1962// FIXME: This method seems to violate the encapsulation of this class.
1963void DocumentLoader::setResponseMIMEType(const String& responseMIMEType)
1964{
1965 m_response.setMimeType(String { responseMIMEType });
1966}
1967
1968#endif
1969
1970void DocumentLoader::setDefersLoading(bool defers)
1971{
1972 // Multiple frames may be loading the same main resource simultaneously. If deferral state changes,
1973 // each frame's DocumentLoader will try to send a setDefersLoading() to the same underlying ResourceLoader. Ensure only
1974 // the "owning" DocumentLoader does so, as setDefersLoading() is not resilient to setting the same value repeatedly.
1975 if (RefPtr loader = mainResourceLoader(); loader && loader->documentLoader() == this)
1976 loader->setDefersLoading(defers);
1977
1978 setAllDefersLoading(m_subresourceLoaders, defers);
1979 setAllDefersLoading(m_plugInStreamLoaders, defers);
1980 if (!defers)
1981 deliverSubstituteResourcesAfterDelay();
1982}
1983
1984void DocumentLoader::setMainResourceDataBufferingPolicy(DataBufferingPolicy dataBufferingPolicy)
1985{
1986 if (m_mainResource)
1987 m_mainResource->setDataBufferingPolicy(dataBufferingPolicy);
1988}
1989
1990void DocumentLoader::stopLoadingPlugIns()
1991{
1992 cancelAll(m_plugInStreamLoaders);
1993}
1994
1995void DocumentLoader::stopLoadingSubresources()
1996{
1997 for (auto& loader : copyToVector(m_subresourceLoaders)) {
1998 if (RefPtr cachedResource = loader->cachedResource()) {
1999 // Don't cancel loaders for prefetch resources, as they need to survive navigation.
2000 if (cachedResource->options().cachingPolicy == CachingPolicy::AllowCachingMainResourcePrefetch) {
2001 m_subresourceLoaders.remove(loader);
2002 continue;
2003 }
2004 }
2005 loader->cancel();
2006 }
2007 ASSERT(m_subresourceLoaders.isEmpty())((void)0);
2008}
2009
2010void DocumentLoader::addSubresourceLoader(SubresourceLoader& loader)
2011{
2012 // The main resource's underlying ResourceLoader will ask to be added here.
2013 // It is much simpler to handle special casing of main resource loads if we don't
2014 // let it be added. In the main resource load case, mainResourceLoader()
2015 // will still be null at this point, but m_gotFirstByte should be false here if and only
2016 // if we are just starting the main resource load.
2017 if (!m_gotFirstByte)
2018 return;
2019
2020 ASSERT(!m_subresourceLoaders.contains(&loader))((void)0);
2021 ASSERT(!mainResourceLoader() || mainResourceLoader() != &loader)((void)0);
2022
2023#if ASSERT_ENABLED0
2024 if (document()) {
2025 switch (document()->backForwardCacheState()) {
2026 case Document::NotInBackForwardCache:
2027 break;
2028 case Document::AboutToEnterBackForwardCache: {
2029 // A page about to enter the BackForwardCache should only be able to start ping loads.
2030 auto* cachedResource = loader.cachedResource();
2031 ASSERT(cachedResource && (CachedResource::shouldUsePingLoad(cachedResource->type()) || cachedResource->options().keepAlive))((void)0);
2032 break;
2033 }
2034 case Document::InBackForwardCache:
2035 // A page in the BackForwardCache should not be able to start loads.
2036 ASSERT_NOT_REACHED()((void)0);
2037 break;
2038 }
2039 }
2040#endif
2041
2042 m_subresourceLoaders.add(loader);
2043}
2044
2045void DocumentLoader::removeSubresourceLoader(LoadCompletionType type, SubresourceLoader& loader)
2046{
2047 if (!m_subresourceLoaders.remove(&loader))
2048 return;
2049 checkLoadComplete();
2050 if (RefPtr frame = m_frame.get())
2051 frame->loader().subresourceLoadDone(type);
2052}
2053
2054void DocumentLoader::addPlugInStreamLoader(ResourceLoader& loader)
2055{
2056 ASSERT(!m_plugInStreamLoaders.contains(&loader))((void)0);
2057
2058 m_plugInStreamLoaders.add(loader);
2059}
2060
2061void DocumentLoader::removePlugInStreamLoader(ResourceLoader& loader)
2062{
2063 ASSERT(m_plugInStreamLoaders.contains(&loader))((void)0);
2064
2065 m_plugInStreamLoaders.remove(&loader);
2066 checkLoadComplete();
2067}
2068
2069bool DocumentLoader::isMultipartReplacingLoad() const
2070{
2071 return isLoadingMultipartContent() && protect(frameLoader())->isMultipartReplacing();
2072}
2073
2074bool DocumentLoader::maybeLoadEmpty()
2075{
2076 bool shouldLoadEmpty = !m_substituteData.isValid() && (m_request.url().isEmpty() || LegacySchemeRegistry::shouldLoadURLSchemeAsEmptyDocument(m_request.url().protocol()));
2077 Ref frameLoaderClient = frameLoader()->client();
2078 if (!shouldLoadEmpty && !frameLoaderClient->representationExistsForURLScheme(m_request.url().protocol()))
2079 return false;
2080
2081 if (m_request.url().protocolIsAbout() && isHandledByAboutSchemeHandler())
2082 return false;
2083
2084 if (m_request.url().isEmpty() && !protect(frameLoader())->stateMachine().creatingInitialEmptyDocument()) {
2085 m_request.setURL(URL { aboutBlankURL() });
2086 if (isLoadingMainResource())
2087 frameLoaderClient->dispatchDidChangeProvisionalURL();
2088 }
2089
2090 String mimeType = shouldLoadEmpty ? textHTMLContentTypeAtom() : frameLoaderClient->generatedMIMETypeForURLScheme(m_request.url().protocol());
2091 m_response = ResourceResponse(URL { m_request.url() }, WTF::move(mimeType), 0, "UTF-8"_s);
2092
2093 bool isDisplayingInitialEmptyDocument = frameLoader()->stateMachine().isDisplayingInitialEmptyDocument();
2094 if (!isDisplayingInitialEmptyDocument) {
2095 if (auto coopEnforcementResult = doCrossOriginOpenerHandlingOfResponse(m_response)) {
2096 m_responseCOOP = coopEnforcementResult->crossOriginOpenerPolicy;
2097 if (coopEnforcementResult->needsBrowsingContextGroupSwitch)
2098 protect(frameLoader())->switchBrowsingContextsGroup();
2099 }
2100 }
2101
2102 SetForScope isInFinishedLoadingOfEmptyDocument { m_isInFinishedLoadingOfEmptyDocument, true };
2103 m_isInitialAboutBlank = isDisplayingInitialEmptyDocument;
2104 finishedLoading();
2105 return true;
2106}
2107
2108void DocumentLoader::loadErrorDocument()
2109{
2110 m_response = ResourceResponse(URL { m_request.url() }, String { textHTMLContentTypeAtom() }, 0, "UTF-8"_s);
2111 SetForScope isInFinishedLoadingOfEmptyDocument { m_isInFinishedLoadingOfEmptyDocument, true };
2112
2113 commitIfReady();
2114 if (!frameLoader())
2115 return;
2116
2117 commitData(SharedBuffer::create());
2118 m_frame->document()->enforceSandboxFlags(SandboxFlag::Origin);
2119 m_writer.end();
2120}
2121
2122static bool canUseServiceWorkers(LocalFrame* frame)
2123{
2124 return frame && frame->settings().serviceWorkersEnabled() && !is<HTMLPlugInElement>(frame->ownerElement());
2125}
2126
2127bool DocumentLoader::shouldCancelLoadingAboutURL(const URL& url) const
2128{
2129 if (!url.protocolIsAbout())
2130 return false;
2131
2132 if (url.isAboutBlank() || url.isAboutSrcDoc() || isHandledByAboutSchemeHandler())
2133 return false;
2134
2135 if (!url.hasOpaquePath())
2136 return false;
2137
2138#if PLATFORM(COCOA)(defined 1 && 1)
2139 if (!linkedOnOrAfterSDKWithBehavior(SDKAlignedBehavior::OnlyLoadWellKnownAboutURLs))
2140 return false;
2141#endif
2142
2143 return true;
2144}
2145
2146void DocumentLoader::startLoadingMainResource()
2147{
2148 RefPtr frame = m_frame.get();
2149 m_canUseServiceWorkers = canUseServiceWorkers(frame.get());
2150 m_mainDocumentError = ResourceError();
2151 timing().markStartTime();
2152 ASSERT(!m_mainResource)((void)0);
2153 ASSERT(!m_loadingMainResource)((void)0);
2154 m_loadingMainResource = true;
2155
2156 Ref<DocumentLoader> protectedThis(*this);
2157
2158 if (shouldCancelLoadingAboutURL(m_request.url())) {
2159 cancelMainResourceLoad(platformStrategies()->loaderStrategy()->cannotShowURLError(m_request));
2160 return;
2161 }
2162
2163 if (maybeLoadEmpty()) {
2164 DOCUMENTLOADER_RELEASE_LOG_FORWARDABLE(DOCUMENTLOADER_STARTLOADINGMAINRESOURCE_EMTPY_DOCUMENT)do { if (auto& client = logClient()) client->DOCUMENTLOADER_STARTLOADINGMAINRESOURCE_EMTPY_DOCUMENT
(PAGE_ID, FRAME_ID, IS_MAIN_FRAME); else clang diagnostic push
clang diagnostic ignored "-Wunknown-warning-option" clang diagnostic
ignored "-Wunsafe-buffer-usage" clang diagnostic ignored "-Wunsafe-buffer-usage-in-libc-call"
clang diagnostic ignored "-Wunsafe-buffer-usage-in-format-attr-call"
[[clang::suppress]] __extension__({ os_log_t _log_tmp = (LogNetwork
.osLogChannel); os_log_type_t _type_tmp = (OS_LOG_TYPE_DEFAULT
); if (os_log_type_enabled(_log_tmp, _type_tmp)) { __extension__
({ clang diagnostic push clang diagnostic ignored "-Wvla" clang
diagnostic error "-Wformat" _Static_assert(__builtin_constant_p
("[pageID=%" "ll" "u" ", frameID=%" "ll" "u" ", isMainFrame=%d] DocumentLoader::startLoadingMainResource: Returning empty document"
), "format/label/description argument must be a string constant"
); __attribute__((section("__TEXT,__oslogstring,cstring_literals"
),internal_linkage)) static const char _os_fmt_str[] __asm("LOS_LOG64"
) = "[pageID=%" "ll" "u" ", frameID=%" "ll" "u" ", isMainFrame=%d] DocumentLoader::startLoadingMainResource: Returning empty document"
; uint8_t _Alignas(16) __attribute__((uninitialized)) _os_fmt_buf
[__builtin_os_log_format_buffer_size("[pageID=%" "ll" "u" ", frameID=%"
"ll" "u" ", isMainFrame=%d] DocumentLoader::startLoadingMainResource: Returning empty document"
, WTF::safePrintfType(PAGE_ID) , WTF::safePrintfType(FRAME_ID
) , WTF::safePrintfType(IS_MAIN_FRAME))]; _os_log_impl(&__dso_handle
, _log_tmp, _type_tmp, _os_fmt_str, (uint8_t *)__builtin_os_log_format
(_os_fmt_buf, "[pageID=%" "ll" "u" ", frameID=%" "ll" "u" ", isMainFrame=%d] DocumentLoader::startLoadingMainResource: Returning empty document"
, WTF::safePrintfType(PAGE_ID) , WTF::safePrintfType(FRAME_ID
) , WTF::safePrintfType(IS_MAIN_FRAME)), (uint32_t)sizeof(_os_fmt_buf
)) clang diagnostic pop ; }); } }) clang diagnostic pop ; } while
(0)
;
2165 return;
2166 }
2167
2168#if ENABLE(CONTENT_FILTERING)(defined 1 && 1)
2169 // Always filter in WK1
2170 contentFilterInDocumentLoader() = frame && frame->view() && protect(frame->view())->platformWidget();
2171 if (contentFilterInDocumentLoader())
2172 m_contentFilter = !m_substituteData.isValid() ? ContentFilter::create(*this) : nullptr;
2173#endif
2174
2175 auto url = m_request.url();
2176 auto fragmentDirective = url.consumeFragmentDirective();
2177
2178 m_request.setURL(WTF::move(url), m_request.didFilterLinkDecoration());
2179 frame = m_frame.get();
2180 if (frame) {
2181 RefPtr page = frame->page();
2182 if (page)
2183 page->setMainFrameURLFragment(WTF::move(fragmentDirective));
2184 }
2185
2186 // Make sure we re-apply the user agent to the Document's ResourceRequest upon reload in case the embedding
2187 // application has changed it, by clearing the previous user agent value here and applying the new value in CachedResourceLoader.
2188 m_request.clearHTTPUserAgent();
2189
2190 ASSERT(timing().startTime())((void)0);
2191
2192 willSendRequest(ResourceRequest(m_request), ResourceResponse(), [this, protectedThis = Ref { *this }] (ResourceRequest&& request) mutable {
2193 request.setRequester(ResourceRequestRequester::Main);
2194
2195 m_request = request;
2196 // FIXME: Implement local URL interception by getting the service worker of the parent.
2197
2198 // willSendRequest() may lead to our Frame being detached or cancelling the load via nulling the ResourceRequest.
2199 if (!m_frame || m_request.isNull()) {
2200 DOCUMENTLOADER_RELEASE_LOG("startLoadingMainResource: Load canceled after willSendRequest")clang diagnostic push clang diagnostic ignored "-Wunknown-warning-option"
clang diagnostic ignored "-Wunsafe-buffer-usage" clang diagnostic
ignored "-Wunsafe-buffer-usage-in-libc-call" clang diagnostic
ignored "-Wunsafe-buffer-usage-in-format-attr-call" [[clang
::suppress]] __extension__({ os_log_t _log_tmp = (LogNetwork.
osLogChannel); os_log_type_t _type_tmp = (OS_LOG_TYPE_DEFAULT
); if (os_log_type_enabled(_log_tmp, _type_tmp)) { __extension__
({ clang diagnostic push clang diagnostic ignored "-Wvla" clang
diagnostic error "-Wformat" _Static_assert(__builtin_constant_p
("%p - [pageID=%" "ll" "u" ", frameID=%" "ll" "u" ", isMainFrame=%d] DocumentLoader::"
"startLoadingMainResource: Load canceled after willSendRequest"
), "format/label/description argument must be a string constant"
); __attribute__((section("__TEXT,__oslogstring,cstring_literals"
),internal_linkage)) static const char _os_fmt_str[] __asm("LOS_LOG65"
) = "%p - [pageID=%" "ll" "u" ", frameID=%" "ll" "u" ", isMainFrame=%d] DocumentLoader::"
"startLoadingMainResource: Load canceled after willSendRequest"
; uint8_t _Alignas(16) __attribute__((uninitialized)) _os_fmt_buf
[__builtin_os_log_format_buffer_size("%p - [pageID=%" "ll" "u"
", frameID=%" "ll" "u" ", isMainFrame=%d] DocumentLoader::" "startLoadingMainResource: Load canceled after willSendRequest"
, this, PAGE_ID, FRAME_ID, IS_MAIN_FRAME)]; _os_log_impl(&
__dso_handle, _log_tmp, _type_tmp, _os_fmt_str, (uint8_t *)__builtin_os_log_format
(_os_fmt_buf, "%p - [pageID=%" "ll" "u" ", frameID=%" "ll" "u"
", isMainFrame=%d] DocumentLoader::" "startLoadingMainResource: Load canceled after willSendRequest"
, this, PAGE_ID, FRAME_ID, IS_MAIN_FRAME), (uint32_t)sizeof(_os_fmt_buf
)) clang diagnostic pop ; }); } }) clang diagnostic pop
;
2201 return;
2202 }
2203
2204 // If this is a reload the cache layer might have made the previous request conditional. DocumentLoader can't handle 304 responses itself.
2205 request.makeUnconditional();
2206
2207 DOCUMENTLOADER_RELEASE_LOG_FORWARDABLE(DOCUMENTLOADER_STARTLOADINGMAINRESOURCE_STARTING_LOAD)do { if (auto& client = logClient()) client->DOCUMENTLOADER_STARTLOADINGMAINRESOURCE_STARTING_LOAD
(PAGE_ID, FRAME_ID, IS_MAIN_FRAME); else clang diagnostic push
clang diagnostic ignored "-Wunknown-warning-option" clang diagnostic
ignored "-Wunsafe-buffer-usage" clang diagnostic ignored "-Wunsafe-buffer-usage-in-libc-call"
clang diagnostic ignored "-Wunsafe-buffer-usage-in-format-attr-call"
[[clang::suppress]] __extension__({ os_log_t _log_tmp = (LogNetwork
.osLogChannel); os_log_type_t _type_tmp = (OS_LOG_TYPE_DEFAULT
); if (os_log_type_enabled(_log_tmp, _type_tmp)) { __extension__
({ clang diagnostic push clang diagnostic ignored "-Wvla" clang
diagnostic error "-Wformat" _Static_assert(__builtin_constant_p
("[pageID=%" "ll" "u" ", frameID=%" "ll" "u" ", isMainFrame=%d] DocumentLoader::startLoadingMainResource: Starting load"
), "format/label/description argument must be a string constant"
); __attribute__((section("__TEXT,__oslogstring,cstring_literals"
),internal_linkage)) static const char _os_fmt_str[] __asm("LOS_LOG66"
) = "[pageID=%" "ll" "u" ", frameID=%" "ll" "u" ", isMainFrame=%d] DocumentLoader::startLoadingMainResource: Starting load"
; uint8_t _Alignas(16) __attribute__((uninitialized)) _os_fmt_buf
[__builtin_os_log_format_buffer_size("[pageID=%" "ll" "u" ", frameID=%"
"ll" "u" ", isMainFrame=%d] DocumentLoader::startLoadingMainResource: Starting load"
, WTF::safePrintfType(PAGE_ID) , WTF::safePrintfType(FRAME_ID
) , WTF::safePrintfType(IS_MAIN_FRAME))]; _os_log_impl(&__dso_handle
, _log_tmp, _type_tmp, _os_fmt_str, (uint8_t *)__builtin_os_log_format
(_os_fmt_buf, "[pageID=%" "ll" "u" ", frameID=%" "ll" "u" ", isMainFrame=%d] DocumentLoader::startLoadingMainResource: Starting load"
, WTF::safePrintfType(PAGE_ID) , WTF::safePrintfType(FRAME_ID
) , WTF::safePrintfType(IS_MAIN_FRAME)), (uint32_t)sizeof(_os_fmt_buf
)) clang diagnostic pop ; }); } }) clang diagnostic pop ; } while
(0)
;
2208
2209 if (m_substituteData.isValid()) {
2210 auto url = request.url();
2211 matchRegistration(url, [request = WTF::move(request), protectedThis = Ref { *this }, this] (auto&& registrationData) mutable {
2212 if (!m_mainDocumentError.isNull()) {
2213 DOCUMENTLOADER_RELEASE_LOG("startLoadingMainResource callback: Load canceled because of main document error (type=%d, code=%d)", static_cast<int>(m_mainDocumentError.type()), m_mainDocumentError.errorCode())clang diagnostic push clang diagnostic ignored "-Wunknown-warning-option"
clang diagnostic ignored "-Wunsafe-buffer-usage" clang diagnostic
ignored "-Wunsafe-buffer-usage-in-libc-call" clang diagnostic
ignored "-Wunsafe-buffer-usage-in-format-attr-call" [[clang
::suppress]] __extension__({ os_log_t _log_tmp = (LogNetwork.
osLogChannel); os_log_type_t _type_tmp = (OS_LOG_TYPE_DEFAULT
); if (os_log_type_enabled(_log_tmp, _type_tmp)) { __extension__
({ clang diagnostic push clang diagnostic ignored "-Wvla" clang
diagnostic error "-Wformat" _Static_assert(__builtin_constant_p
("%p - [pageID=%" "ll" "u" ", frameID=%" "ll" "u" ", isMainFrame=%d] DocumentLoader::"
"startLoadingMainResource callback: Load canceled because of main document error (type=%d, code=%d)"
), "format/label/description argument must be a string constant"
); __attribute__((section("__TEXT,__oslogstring,cstring_literals"
),internal_linkage)) static const char _os_fmt_str[] __asm("LOS_LOG67"
) = "%p - [pageID=%" "ll" "u" ", frameID=%" "ll" "u" ", isMainFrame=%d] DocumentLoader::"
"startLoadingMainResource callback: Load canceled because of main document error (type=%d, code=%d)"
; uint8_t _Alignas(16) __attribute__((uninitialized)) _os_fmt_buf
[__builtin_os_log_format_buffer_size("%p - [pageID=%" "ll" "u"
", frameID=%" "ll" "u" ", isMainFrame=%d] DocumentLoader::" "startLoadingMainResource callback: Load canceled because of main document error (type=%d, code=%d)"
, this, PAGE_ID, FRAME_ID, IS_MAIN_FRAME, static_cast<int>
(m_mainDocumentError.type()), m_mainDocumentError.errorCode()
)]; _os_log_impl(&__dso_handle, _log_tmp, _type_tmp, _os_fmt_str
, (uint8_t *)__builtin_os_log_format(_os_fmt_buf, "%p - [pageID=%"
"ll" "u" ", frameID=%" "ll" "u" ", isMainFrame=%d] DocumentLoader::"
"startLoadingMainResource callback: Load canceled because of main document error (type=%d, code=%d)"
, this, PAGE_ID, FRAME_ID, IS_MAIN_FRAME, static_cast<int>
(m_mainDocumentError.type()), m_mainDocumentError.errorCode()
), (uint32_t)sizeof(_os_fmt_buf)) clang diagnostic pop ; }); }
}) clang diagnostic pop
;
2214 return;
2215 }
2216 if (!m_frame) {
2217 DOCUMENTLOADER_RELEASE_LOG("startLoadingMainResource callback: Load canceled because no frame")clang diagnostic push clang diagnostic ignored "-Wunknown-warning-option"
clang diagnostic ignored "-Wunsafe-buffer-usage" clang diagnostic
ignored "-Wunsafe-buffer-usage-in-libc-call" clang diagnostic
ignored "-Wunsafe-buffer-usage-in-format-attr-call" [[clang
::suppress]] __extension__({ os_log_t _log_tmp = (LogNetwork.
osLogChannel); os_log_type_t _type_tmp = (OS_LOG_TYPE_DEFAULT
); if (os_log_type_enabled(_log_tmp, _type_tmp)) { __extension__
({ clang diagnostic push clang diagnostic ignored "-Wvla" clang
diagnostic error "-Wformat" _Static_assert(__builtin_constant_p
("%p - [pageID=%" "ll" "u" ", frameID=%" "ll" "u" ", isMainFrame=%d] DocumentLoader::"
"startLoadingMainResource callback: Load canceled because no frame"
), "format/label/description argument must be a string constant"
); __attribute__((section("__TEXT,__oslogstring,cstring_literals"
),internal_linkage)) static const char _os_fmt_str[] __asm("LOS_LOG68"
) = "%p - [pageID=%" "ll" "u" ", frameID=%" "ll" "u" ", isMainFrame=%d] DocumentLoader::"
"startLoadingMainResource callback: Load canceled because no frame"
; uint8_t _Alignas(16) __attribute__((uninitialized)) _os_fmt_buf
[__builtin_os_log_format_buffer_size("%p - [pageID=%" "ll" "u"
", frameID=%" "ll" "u" ", isMainFrame=%d] DocumentLoader::" "startLoadingMainResource callback: Load canceled because no frame"
, this, PAGE_ID, FRAME_ID, IS_MAIN_FRAME)]; _os_log_impl(&
__dso_handle, _log_tmp, _type_tmp, _os_fmt_str, (uint8_t *)__builtin_os_log_format
(_os_fmt_buf, "%p - [pageID=%" "ll" "u" ", frameID=%" "ll" "u"
", isMainFrame=%d] DocumentLoader::" "startLoadingMainResource callback: Load canceled because no frame"
, this, PAGE_ID, FRAME_ID, IS_MAIN_FRAME), (uint32_t)sizeof(_os_fmt_buf
)) clang diagnostic pop ; }); } }) clang diagnostic pop
;
2218 return;
2219 }
2220
2221 if (registrationData)
2222 m_serviceWorkerRegistrationData = makeUnique<ServiceWorkerRegistrationData>(WTF::move(*registrationData));
2223 // Prefer existing substitute data (from WKWebView.loadData etc) over service worker fetch.
2224 if (this->tryLoadingSubstituteData()) {
2225 DOCUMENTLOADER_RELEASE_LOG("startLoadingMainResource callback: Load canceled because of substitute data")clang diagnostic push clang diagnostic ignored "-Wunknown-warning-option"
clang diagnostic ignored "-Wunsafe-buffer-usage" clang diagnostic
ignored "-Wunsafe-buffer-usage-in-libc-call" clang diagnostic
ignored "-Wunsafe-buffer-usage-in-format-attr-call" [[clang
::suppress]] __extension__({ os_log_t _log_tmp = (LogNetwork.
osLogChannel); os_log_type_t _type_tmp = (OS_LOG_TYPE_DEFAULT
); if (os_log_type_enabled(_log_tmp, _type_tmp)) { __extension__
({ clang diagnostic push clang diagnostic ignored "-Wvla" clang
diagnostic error "-Wformat" _Static_assert(__builtin_constant_p
("%p - [pageID=%" "ll" "u" ", frameID=%" "ll" "u" ", isMainFrame=%d] DocumentLoader::"
"startLoadingMainResource callback: Load canceled because of substitute data"
), "format/label/description argument must be a string constant"
); __attribute__((section("__TEXT,__oslogstring,cstring_literals"
),internal_linkage)) static const char _os_fmt_str[] __asm("LOS_LOG69"
) = "%p - [pageID=%" "ll" "u" ", frameID=%" "ll" "u" ", isMainFrame=%d] DocumentLoader::"
"startLoadingMainResource callback: Load canceled because of substitute data"
; uint8_t _Alignas(16) __attribute__((uninitialized)) _os_fmt_buf
[__builtin_os_log_format_buffer_size("%p - [pageID=%" "ll" "u"
", frameID=%" "ll" "u" ", isMainFrame=%d] DocumentLoader::" "startLoadingMainResource callback: Load canceled because of substitute data"
, this, PAGE_ID, FRAME_ID, IS_MAIN_FRAME)]; _os_log_impl(&
__dso_handle, _log_tmp, _type_tmp, _os_fmt_str, (uint8_t *)__builtin_os_log_format
(_os_fmt_buf, "%p - [pageID=%" "ll" "u" ", frameID=%" "ll" "u"
", isMainFrame=%d] DocumentLoader::" "startLoadingMainResource callback: Load canceled because of substitute data"
, this, PAGE_ID, FRAME_ID, IS_MAIN_FRAME), (uint32_t)sizeof(_os_fmt_buf
)) clang diagnostic pop ; }); } }) clang diagnostic pop
;
2226 return;
2227 }
2228
2229 this->loadMainResource(WTF::move(request));
2230 });
2231 return;
2232 }
2233 loadMainResource(WTF::move(request));
2234 });
2235}
2236
2237void DocumentLoader::unregisterReservedServiceWorkerClient()
2238{
2239 if (!m_resultingClientId)
2240 return;
2241
2242 if (RefPtr serviceWorkerConnection = ServiceWorkerProvider::singleton().existingServiceWorkerConnection())
2243 serviceWorkerConnection->unregisterServiceWorkerClient(*m_resultingClientId);
2244}
2245
2246void DocumentLoader::loadMainResource(ResourceRequest&& request)
2247{
2248 ResourceLoaderOptions mainResourceLoadOptions(
2249 SendCallbackPolicy::SendCallbacks,
2250 ContentSniffingPolicy::SniffContent,
2251 DataBufferingPolicy::BufferData,
2252 StoredCredentialsPolicy::Use,
2253 ClientCredentialPolicy::MayAskClientForCredentials,
2254 FetchOptions::Credentials::Include,
2255 SecurityCheckPolicy::SkipSecurityCheck,
2256 FetchOptions::Mode::Navigate,
2257 CertificateInfoPolicy::IncludeCertificateInfo,
2258 ContentSecurityPolicyImposition::SkipPolicyCheck,
2259 DefersLoadingPolicy::AllowDefersLoading,
2260 CachingPolicy::AllowCaching);
2261
2262 auto isSandboxingAllowingServiceWorkerFetchHandling = [](SandboxFlags flags) {
2263 return !(flags.contains(SandboxFlag::Origin)) && !(flags.contains(SandboxFlag::Scripts));
2264 };
2265
2266 RefPtr frame = m_frame.get();
2267 if (!m_canUseServiceWorkers || !isSandboxingAllowingServiceWorkerFetchHandling(frame->effectiveSandboxFlags()))
2268 mainResourceLoadOptions.serviceWorkersMode = ServiceWorkersMode::None;
2269 else {
2270 // The main navigation load will trigger the registration of the client.
2271 if (m_resultingClientId) {
2272 scriptExecutionContextIdentifierToLoaderMap().remove(*m_resultingClientId);
2273 unregisterReservedServiceWorkerClient();
2274 }
2275
2276 m_resultingClientId = ScriptExecutionContextIdentifier::generate();
2277 ASSERT(!scriptExecutionContextIdentifierToLoaderMap().contains(*m_resultingClientId))((void)0);
2278 scriptExecutionContextIdentifierToLoaderMap().add(*m_resultingClientId, *this);
2279 mainResourceLoadOptions.resultingClientIdentifier = m_resultingClientId->object();
2280 }
2281
2282 CachedResourceRequest mainResourceRequest(WTF::move(request), mainResourceLoadOptions);
2283 if (!frame->isMainFrame() && frame->document()) {
2284 // If we are loading the main resource of a subframe, use the cache partition of the main document.
2285 mainResourceRequest.setDomainForCachePartition(*protect(frame->document()));
2286 } else {
2287 if (protect(frameLoader())->frame().settings().storageBlockingPolicy() != StorageBlockingPolicy::BlockThirdParty)
2288 mainResourceRequest.setDomainForCachePartition(emptyString());
2289 else {
2290 auto origin = SecurityOrigin::create(mainResourceRequest.resourceRequest().url());
2291 mainResourceRequest.setDomainForCachePartition(origin->domainForCachePartition());
2292 }
2293 }
2294
2295 auto mainResourceOrError = m_cachedResourceLoader->requestMainResource(WTF::move(mainResourceRequest));
2296
2297 if (!mainResourceOrError) {
2298 // The frame may have gone away if this load was cancelled synchronously and this was the last pending load.
2299 // This is because we may have fired the load event in a parent frame.
2300 frame = m_frame.get();
2301 if (!frame) {
2302 DOCUMENTLOADER_RELEASE_LOG("loadMainResource: Unable to load main resource, frame has gone away")clang diagnostic push clang diagnostic ignored "-Wunknown-warning-option"
clang diagnostic ignored "-Wunsafe-buffer-usage" clang diagnostic
ignored "-Wunsafe-buffer-usage-in-libc-call" clang diagnostic
ignored "-Wunsafe-buffer-usage-in-format-attr-call" [[clang
::suppress]] __extension__({ os_log_t _log_tmp = (LogNetwork.
osLogChannel); os_log_type_t _type_tmp = (OS_LOG_TYPE_DEFAULT
); if (os_log_type_enabled(_log_tmp, _type_tmp)) { __extension__
({ clang diagnostic push clang diagnostic ignored "-Wvla" clang
diagnostic error "-Wformat" _Static_assert(__builtin_constant_p
("%p - [pageID=%" "ll" "u" ", frameID=%" "ll" "u" ", isMainFrame=%d] DocumentLoader::"
"loadMainResource: Unable to load main resource, frame has gone away"
), "format/label/description argument must be a string constant"
); __attribute__((section("__TEXT,__oslogstring,cstring_literals"
),internal_linkage)) static const char _os_fmt_str[] __asm("LOS_LOG70"
) = "%p - [pageID=%" "ll" "u" ", frameID=%" "ll" "u" ", isMainFrame=%d] DocumentLoader::"
"loadMainResource: Unable to load main resource, frame has gone away"
; uint8_t _Alignas(16) __attribute__((uninitialized)) _os_fmt_buf
[__builtin_os_log_format_buffer_size("%p - [pageID=%" "ll" "u"
", frameID=%" "ll" "u" ", isMainFrame=%d] DocumentLoader::" "loadMainResource: Unable to load main resource, frame has gone away"
, this, PAGE_ID, FRAME_ID, IS_MAIN_FRAME)]; _os_log_impl(&
__dso_handle, _log_tmp, _type_tmp, _os_fmt_str, (uint8_t *)__builtin_os_log_format
(_os_fmt_buf, "%p - [pageID=%" "ll" "u" ", frameID=%" "ll" "u"
", isMainFrame=%d] DocumentLoader::" "loadMainResource: Unable to load main resource, frame has gone away"
, this, PAGE_ID, FRAME_ID, IS_MAIN_FRAME), (uint32_t)sizeof(_os_fmt_buf
)) clang diagnostic pop ; }); } }) clang diagnostic pop
;
2303 return;
2304 }
2305
2306 if (!m_request.url().isValid()) {
2307 DOCUMENTLOADER_RELEASE_LOG("loadMainResource: Unable to load main resource, URL is invalid")clang diagnostic push clang diagnostic ignored "-Wunknown-warning-option"
clang diagnostic ignored "-Wunsafe-buffer-usage" clang diagnostic
ignored "-Wunsafe-buffer-usage-in-libc-call" clang diagnostic
ignored "-Wunsafe-buffer-usage-in-format-attr-call" [[clang
::suppress]] __extension__({ os_log_t _log_tmp = (LogNetwork.
osLogChannel); os_log_type_t _type_tmp = (OS_LOG_TYPE_DEFAULT
); if (os_log_type_enabled(_log_tmp, _type_tmp)) { __extension__
({ clang diagnostic push clang diagnostic ignored "-Wvla" clang
diagnostic error "-Wformat" _Static_assert(__builtin_constant_p
("%p - [pageID=%" "ll" "u" ", frameID=%" "ll" "u" ", isMainFrame=%d] DocumentLoader::"
"loadMainResource: Unable to load main resource, URL is invalid"
), "format/label/description argument must be a string constant"
); __attribute__((section("__TEXT,__oslogstring,cstring_literals"
),internal_linkage)) static const char _os_fmt_str[] __asm("LOS_LOG71"
) = "%p - [pageID=%" "ll" "u" ", frameID=%" "ll" "u" ", isMainFrame=%d] DocumentLoader::"
"loadMainResource: Unable to load main resource, URL is invalid"
; uint8_t _Alignas(16) __attribute__((uninitialized)) _os_fmt_buf
[__builtin_os_log_format_buffer_size("%p - [pageID=%" "ll" "u"
", frameID=%" "ll" "u" ", isMainFrame=%d] DocumentLoader::" "loadMainResource: Unable to load main resource, URL is invalid"
, this, PAGE_ID, FRAME_ID, IS_MAIN_FRAME)]; _os_log_impl(&
__dso_handle, _log_tmp, _type_tmp, _os_fmt_str, (uint8_t *)__builtin_os_log_format
(_os_fmt_buf, "%p - [pageID=%" "ll" "u" ", frameID=%" "ll" "u"
", isMainFrame=%d] DocumentLoader::" "loadMainResource: Unable to load main resource, URL is invalid"
, this, PAGE_ID, FRAME_ID, IS_MAIN_FRAME), (uint32_t)sizeof(_os_fmt_buf
)) clang diagnostic pop ; }); } }) clang diagnostic pop
;
2308 cancelMainResourceLoad(platformStrategies()->loaderStrategy()->cannotShowURLError(m_request));
2309 return;
2310 }
2311
2312 if (advancedPrivacyProtections().contains(AdvancedPrivacyProtections::HTTPSOnly)) {
2313 if (auto httpNavigationWithHTTPSOnlyError = platformStrategies()->loaderStrategy()->httpNavigationWithHTTPSOnlyError(m_request); mainResourceOrError.error().domain() == httpNavigationWithHTTPSOnlyError.domain()
2314 && mainResourceOrError.error().errorCode() == httpNavigationWithHTTPSOnlyError.errorCode()) {
2315 DOCUMENTLOADER_RELEASE_LOG("loadMainResource: Unable to load main resource, URL has HTTP scheme with HTTPSOnly enabled")clang diagnostic push clang diagnostic ignored "-Wunknown-warning-option"
clang diagnostic ignored "-Wunsafe-buffer-usage" clang diagnostic
ignored "-Wunsafe-buffer-usage-in-libc-call" clang diagnostic
ignored "-Wunsafe-buffer-usage-in-format-attr-call" [[clang
::suppress]] __extension__({ os_log_t _log_tmp = (LogNetwork.
osLogChannel); os_log_type_t _type_tmp = (OS_LOG_TYPE_DEFAULT
); if (os_log_type_enabled(_log_tmp, _type_tmp)) { __extension__
({ clang diagnostic push clang diagnostic ignored "-Wvla" clang
diagnostic error "-Wformat" _Static_assert(__builtin_constant_p
("%p - [pageID=%" "ll" "u" ", frameID=%" "ll" "u" ", isMainFrame=%d] DocumentLoader::"
"loadMainResource: Unable to load main resource, URL has HTTP scheme with HTTPSOnly enabled"
), "format/label/description argument must be a string constant"
); __attribute__((section("__TEXT,__oslogstring,cstring_literals"
),internal_linkage)) static const char _os_fmt_str[] __asm("LOS_LOG72"
) = "%p - [pageID=%" "ll" "u" ", frameID=%" "ll" "u" ", isMainFrame=%d] DocumentLoader::"
"loadMainResource: Unable to load main resource, URL has HTTP scheme with HTTPSOnly enabled"
; uint8_t _Alignas(16) __attribute__((uninitialized)) _os_fmt_buf
[__builtin_os_log_format_buffer_size("%p - [pageID=%" "ll" "u"
", frameID=%" "ll" "u" ", isMainFrame=%d] DocumentLoader::" "loadMainResource: Unable to load main resource, URL has HTTP scheme with HTTPSOnly enabled"
, this, PAGE_ID, FRAME_ID, IS_MAIN_FRAME)]; _os_log_impl(&
__dso_handle, _log_tmp, _type_tmp, _os_fmt_str, (uint8_t *)__builtin_os_log_format
(_os_fmt_buf, "%p - [pageID=%" "ll" "u" ", frameID=%" "ll" "u"
", isMainFrame=%d] DocumentLoader::" "loadMainResource: Unable to load main resource, URL has HTTP scheme with HTTPSOnly enabled"
, this, PAGE_ID, FRAME_ID, IS_MAIN_FRAME), (uint32_t)sizeof(_os_fmt_buf
)) clang diagnostic pop ; }); } }) clang diagnostic pop
;
2316 cancelMainResourceLoad(mainResourceOrError.error());
2317 return;
2318 }
2319 }
2320
2321 DOCUMENTLOADER_RELEASE_LOG("loadMainResource: Unable to load main resource, returning empty document")clang diagnostic push clang diagnostic ignored "-Wunknown-warning-option"
clang diagnostic ignored "-Wunsafe-buffer-usage" clang diagnostic
ignored "-Wunsafe-buffer-usage-in-libc-call" clang diagnostic
ignored "-Wunsafe-buffer-usage-in-format-attr-call" [[clang
::suppress]] __extension__({ os_log_t _log_tmp = (LogNetwork.
osLogChannel); os_log_type_t _type_tmp = (OS_LOG_TYPE_DEFAULT
); if (os_log_type_enabled(_log_tmp, _type_tmp)) { __extension__
({ clang diagnostic push clang diagnostic ignored "-Wvla" clang
diagnostic error "-Wformat" _Static_assert(__builtin_constant_p
("%p - [pageID=%" "ll" "u" ", frameID=%" "ll" "u" ", isMainFrame=%d] DocumentLoader::"
"loadMainResource: Unable to load main resource, returning empty document"
), "format/label/description argument must be a string constant"
); __attribute__((section("__TEXT,__oslogstring,cstring_literals"
),internal_linkage)) static const char _os_fmt_str[] __asm("LOS_LOG73"
) = "%p - [pageID=%" "ll" "u" ", frameID=%" "ll" "u" ", isMainFrame=%d] DocumentLoader::"
"loadMainResource: Unable to load main resource, returning empty document"
; uint8_t _Alignas(16) __attribute__((uninitialized)) _os_fmt_buf
[__builtin_os_log_format_buffer_size("%p - [pageID=%" "ll" "u"
", frameID=%" "ll" "u" ", isMainFrame=%d] DocumentLoader::" "loadMainResource: Unable to load main resource, returning empty document"
, this, PAGE_ID, FRAME_ID, IS_MAIN_FRAME)]; _os_log_impl(&
__dso_handle, _log_tmp, _type_tmp, _os_fmt_str, (uint8_t *)__builtin_os_log_format
(_os_fmt_buf, "%p - [pageID=%" "ll" "u" ", frameID=%" "ll" "u"
", isMainFrame=%d] DocumentLoader::" "loadMainResource: Unable to load main resource, returning empty document"
, this, PAGE_ID, FRAME_ID, IS_MAIN_FRAME), (uint32_t)sizeof(_os_fmt_buf
)) clang diagnostic pop ; }); } }) clang diagnostic pop
;
2322
2323 setRequest(ResourceRequest());
2324 maybeLoadEmpty();
2325 return;
2326 }
2327
2328 m_mainResource = mainResourceOrError.value();
2329
2330 ASSERT(frame)((void)0);
2331
2332#if ENABLE(CONTENT_EXTENSIONS)(defined 1 && 1)
2333 if (m_mainResource->errorOccurred() && frame->page() && m_mainResource->resourceError().domain() == ContentExtensions::WebKitContentBlockerDomain) {
2334 DOCUMENTLOADER_RELEASE_LOG("loadMainResource: Blocked by content blocker error")clang diagnostic push clang diagnostic ignored "-Wunknown-warning-option"
clang diagnostic ignored "-Wunsafe-buffer-usage" clang diagnostic
ignored "-Wunsafe-buffer-usage-in-libc-call" clang diagnostic
ignored "-Wunsafe-buffer-usage-in-format-attr-call" [[clang
::suppress]] __extension__({ os_log_t _log_tmp = (LogNetwork.
osLogChannel); os_log_type_t _type_tmp = (OS_LOG_TYPE_DEFAULT
); if (os_log_type_enabled(_log_tmp, _type_tmp)) { __extension__
({ clang diagnostic push clang diagnostic ignored "-Wvla" clang
diagnostic error "-Wformat" _Static_assert(__builtin_constant_p
("%p - [pageID=%" "ll" "u" ", frameID=%" "ll" "u" ", isMainFrame=%d] DocumentLoader::"
"loadMainResource: Blocked by content blocker error"), "format/label/description argument must be a string constant"
); __attribute__((section("__TEXT,__oslogstring,cstring_literals"
),internal_linkage)) static const char _os_fmt_str[] __asm("LOS_LOG74"
) = "%p - [pageID=%" "ll" "u" ", frameID=%" "ll" "u" ", isMainFrame=%d] DocumentLoader::"
"loadMainResource: Blocked by content blocker error"; uint8_t
_Alignas(16) __attribute__((uninitialized)) _os_fmt_buf[__builtin_os_log_format_buffer_size
("%p - [pageID=%" "ll" "u" ", frameID=%" "ll" "u" ", isMainFrame=%d] DocumentLoader::"
"loadMainResource: Blocked by content blocker error", this, PAGE_ID
, FRAME_ID, IS_MAIN_FRAME)]; _os_log_impl(&__dso_handle, _log_tmp
, _type_tmp, _os_fmt_str, (uint8_t *)__builtin_os_log_format(
_os_fmt_buf, "%p - [pageID=%" "ll" "u" ", frameID=%" "ll" "u"
", isMainFrame=%d] DocumentLoader::" "loadMainResource: Blocked by content blocker error"
, this, PAGE_ID, FRAME_ID, IS_MAIN_FRAME), (uint32_t)sizeof(_os_fmt_buf
)) clang diagnostic pop ; }); } }) clang diagnostic pop
;
2335 cancelMainResourceLoad(protect(frameLoader())->blockedByContentBlockerError(m_request));
2336 return;
2337 }
2338#endif
2339
2340 if (!mainResourceLoader()) {
2341 m_identifierForLoadWithoutResourceLoader = ResourceLoaderIdentifier::generate();
2342 protect(frameLoader())->notifier().assignIdentifierToInitialRequest(*m_identifierForLoadWithoutResourceLoader, this, mainResourceRequest.resourceRequest());
2343 protect(frameLoader())->notifier().dispatchWillSendRequest(this, *m_identifierForLoadWithoutResourceLoader, mainResourceRequest.resourceRequest(), ResourceResponse(), nullptr);
2344 }
2345
2346 becomeMainResourceClient();
2347
2348 // A bunch of headers are set when the underlying ResourceLoader is created, and m_request needs to include those.
2349 ResourceRequest updatedRequest = mainResourceLoader() ? mainResourceLoader()->originalRequest() : mainResourceRequest.resourceRequest();
2350 // If there was a fragment identifier on m_request, the cache will have stripped it. m_request should include
2351 // the fragment identifier, so add that back in.
2352 // Otherwise, if the main resource was loaded from a prefetch, we need to conserve the redirect URL here
2353 if (equalIgnoringFragmentIdentifier(m_request.url(), updatedRequest.url()) || (m_mainResource && m_mainResource->options().cachingPolicy == CachingPolicy::AllowCachingMainResourcePrefetch))
2354 updatedRequest.setURL(URL { m_request.url() });
2355 setRequest(WTF::move(updatedRequest));
2356}
2357
2358void DocumentLoader::cancelPolicyCheckIfNeeded()
2359{
2360 if (m_waitingForContentPolicy || m_waitingForNavigationPolicy) {
2361 RELEASE_ASSERT(frameLoader())do { if (__builtin_expect(!!(!(frameLoader())), 0)) do { WTF::
isIntegralOrPointerType(); compilerFenceForCrash(); WTFCrashWithInfo
(2361, "/Volumes/Data/worker/Apple-iOS-26-Safer-CPP-Checks-EWS/build/Source/WebCore/loader/DocumentLoader.cpp"
, __PRETTY_FUNCTION__ ); } while (false); } while (0)
;
2362 protect(frameLoader())->policyChecker().stopCheck();
2363 m_waitingForContentPolicy = false;
2364 m_waitingForNavigationPolicy = false;
2365 }
2366}
2367
2368void DocumentLoader::cancelMainResourceLoad(const ResourceError& resourceError, LoadWillContinueInAnotherProcess loadWillContinueInAnotherProcess)
2369{
2370 Ref<DocumentLoader> protectedThis(*this);
2371 ResourceError error = resourceError.isNull() ? protect(frameLoader())->cancelledError(m_request) : resourceError;
2372
2373 DOCUMENTLOADER_RELEASE_LOG("cancelMainResourceLoad: (type=%d, code=%d)", static_cast<int>(error.type()), error.errorCode())clang diagnostic push clang diagnostic ignored "-Wunknown-warning-option"
clang diagnostic ignored "-Wunsafe-buffer-usage" clang diagnostic
ignored "-Wunsafe-buffer-usage-in-libc-call" clang diagnostic
ignored "-Wunsafe-buffer-usage-in-format-attr-call" [[clang
::suppress]] __extension__({ os_log_t _log_tmp = (LogNetwork.
osLogChannel); os_log_type_t _type_tmp = (OS_LOG_TYPE_DEFAULT
); if (os_log_type_enabled(_log_tmp, _type_tmp)) { __extension__
({ clang diagnostic push clang diagnostic ignored "-Wvla" clang
diagnostic error "-Wformat" _Static_assert(__builtin_constant_p
("%p - [pageID=%" "ll" "u" ", frameID=%" "ll" "u" ", isMainFrame=%d] DocumentLoader::"
"cancelMainResourceLoad: (type=%d, code=%d)"), "format/label/description argument must be a string constant"
); __attribute__((section("__TEXT,__oslogstring,cstring_literals"
),internal_linkage)) static const char _os_fmt_str[] __asm("LOS_LOG75"
) = "%p - [pageID=%" "ll" "u" ", frameID=%" "ll" "u" ", isMainFrame=%d] DocumentLoader::"
"cancelMainResourceLoad: (type=%d, code=%d)"; uint8_t _Alignas
(16) __attribute__((uninitialized)) _os_fmt_buf[__builtin_os_log_format_buffer_size
("%p - [pageID=%" "ll" "u" ", frameID=%" "ll" "u" ", isMainFrame=%d] DocumentLoader::"
"cancelMainResourceLoad: (type=%d, code=%d)", this, PAGE_ID,
FRAME_ID, IS_MAIN_FRAME, static_cast<int>(error.type()
), error.errorCode())]; _os_log_impl(&__dso_handle, _log_tmp
, _type_tmp, _os_fmt_str, (uint8_t *)__builtin_os_log_format(
_os_fmt_buf, "%p - [pageID=%" "ll" "u" ", frameID=%" "ll" "u"
", isMainFrame=%d] DocumentLoader::" "cancelMainResourceLoad: (type=%d, code=%d)"
, this, PAGE_ID, FRAME_ID, IS_MAIN_FRAME, static_cast<int>
(error.type()), error.errorCode()), (uint32_t)sizeof(_os_fmt_buf
)) clang diagnostic pop ; }); } }) clang diagnostic pop
;
2374
2375 cancelPolicyCheckIfNeeded();
2376
2377 // Don't cancel loaders for prefetch resources, as they need to survive navigation.
2378 if (m_mainResource && m_mainResource->options().cachingPolicy == CachingPolicy::AllowCachingMainResourcePrefetch)
2379 return;
2380
2381 if (RefPtr loader = mainResourceLoader())
2382 loader->cancel(error, loadWillContinueInAnotherProcess);
2383
2384 clearMainResource();
2385
2386 mainReceivedError(error);
2387}
2388
2389void DocumentLoader::willContinueMainResourceLoadAfterRedirect(const ResourceRequest& newRequest)
2390{
2391 setRequest(ResourceRequest { newRequest });
2392}
2393
2394void DocumentLoader::clearMainResource()
2395{
2396 ASSERT(isMainThread())((void)0);
2397 if (m_mainResource && m_mainResource->hasClient(*this))
2398 m_mainResource->removeClient(*this);
2399#if ENABLE(CONTENT_FILTERING)(defined 1 && 1)
2400 if (RefPtr contentFilter = m_contentFilter)
2401 contentFilter->stopFilteringMainResource();
2402#endif
2403
2404 m_mainResource = nullptr;
2405 m_isContinuingLoad = ShouldTreatAsContinuingLoad::No;
2406
2407 unregisterReservedServiceWorkerClient();
2408}
2409
2410void DocumentLoader::subresourceLoaderFinishedLoadingOnePart(ResourceLoader& loader)
2411{
2412 if (!m_multipartSubresourceLoaders.add(loader).isNewEntry)
2413 ASSERT(!m_subresourceLoaders.contains(&loader))((void)0);
2414 else {
2415 ASSERT(m_subresourceLoaders.contains(&loader))((void)0);
2416 m_subresourceLoaders.remove(&loader);
2417 }
2418
2419 checkLoadComplete();
2420 if (m_frame)
2421 m_frame->loader().checkLoadComplete();
2422}
2423
2424void DocumentLoader::maybeFinishLoadingMultipartContent()
2425{
2426 if (!isMultipartReplacingLoad())
2427 return;
2428
2429 protect(frameLoader())->setupForMultipartReplace();
2430 m_committed = false;
2431 commitLoad(mainResourceData()->makeContiguous());
2432}
2433
2434void DocumentLoader::startIconLoading()
2435{
2436 static uint64_t nextIconCallbackID = 1;
2437
2438 RefPtr document = this->document();
2439 if (!document)
2440 return;
2441
2442 if (!m_frame->isMainFrame())
2443 return;
2444
2445 if (document->url().isEmpty() || document->url().protocolIsAbout())
2446 return;
2447
2448 m_linkIcons = LinkIconCollector { *document }.iconsOfTypes({ LinkIconType::Favicon, LinkIconType::TouchIcon, LinkIconType::TouchPrecomposedIcon });
2449
2450 auto findResult = m_linkIcons.findIf([](auto& icon) { return icon.type == LinkIconType::Favicon; });
2451 if (findResult == notFound && document->url().protocolIsInHTTPFamily())
2452 m_linkIcons.append({ document->completeURL("/favicon.ico"_s), LinkIconType::Favicon, String(), std::nullopt, { } });
2453
2454 if (!m_linkIcons.size())
2455 return;
2456
2457 auto iconDecisions = WTF::map(m_linkIcons, [&](auto& icon) -> std::pair<WebCore::LinkIcon&, uint64_t> {
2458 auto result = m_iconsPendingLoadDecision.add(nextIconCallbackID++, icon);
2459 return { icon, result.iterator->key };
2460 });
2461 m_frame->loader().client().getLoadDecisionForIcons(WTF::move(iconDecisions));
2462}
2463
2464void DocumentLoader::didGetLoadDecisionForIcon(bool decision, uint64_t loadIdentifier, CompletionHandler<void(FragmentedSharedBuffer*)>&& completionHandler)
2465{
2466 auto icon = m_iconsPendingLoadDecision.take(loadIdentifier);
2467
2468 // If the decision was not to load or this DocumentLoader is already detached, there is no load to perform.
2469 if (!decision || !m_frame)
2470 return completionHandler(nullptr);
2471
2472 // If the LinkIcon we just took is empty, then the DocumentLoader had all of its loaders stopped
2473 // while this icon load decision was pending.
2474 // In this case we need to notify the client that the icon finished loading with empty data.
2475 if (icon.url.isEmpty())
2476 return completionHandler(nullptr);
2477
2478 Ref iconLoader = IconLoader::create(*this, icon.url);
2479 m_iconLoaders.add(iconLoader, WTF::move(completionHandler));
2480
2481 iconLoader->startLoading();
2482}
2483
2484void DocumentLoader::finishedLoadingIcon(IconLoader& loader, FragmentedSharedBuffer* buffer)
2485{
2486 // If the DocumentLoader has detached from its frame, all icon loads should have already been cancelled.
2487 ASSERT(m_frame)((void)0);
2488
2489 if (auto callback = m_iconLoaders.take(&loader))
2490 callback(buffer);
2491}
2492
2493void DocumentLoader::dispatchOnloadEvents()
2494{
2495 m_wasOnloadDispatched = true;
2496}
2497
2498void DocumentLoader::setTriggeringAction(NavigationAction&& action)
2499{
2500 m_triggeringAction = WTF::move(action);
2501 m_triggeringAction.setShouldOpenExternalURLsPolicy(m_frame ? shouldOpenExternalURLsPolicyToPropagate() : m_shouldOpenExternalURLsPolicy);
2502}
2503
2504ShouldOpenExternalURLsPolicy DocumentLoader::shouldOpenExternalURLsPolicyToPropagate() const
2505{
2506 if (!m_frame)
2507 return ShouldOpenExternalURLsPolicy::ShouldNotAllow;
2508
2509 if (m_frame->isMainFrame())
2510 return m_shouldOpenExternalURLsPolicy;
2511
2512 if (RefPtr document = this->document(); document && document->isSameOriginAsTopDocument())
2513 return m_shouldOpenExternalURLsPolicy;
2514
2515 return ShouldOpenExternalURLsPolicy::ShouldNotAllow;
2516}
2517
2518// https://www.w3.org/TR/css-view-transitions-2/#navigation-can-trigger-a-cross-document-view-transition
2519CanTriggerCrossDocumentViewTransition DocumentLoader::navigationCanTriggerCrossDocumentViewTransition(Document& oldDocument, bool fromBackForwardCache)
2520{
2521 if (loadStartedDuringSwipeAnimation())
2522 return CanTriggerCrossDocumentViewTransition::No;
2523
2524 if (std::holds_alternative<Document::SkipTransition>(oldDocument.resolveViewTransitionRule()))
2525 return CanTriggerCrossDocumentViewTransition::No;
2526
2527 if (!m_triggeringAction.navigationAPIType() || *m_triggeringAction.navigationAPIType() == NavigationNavigationType::Reload)
2528 return CanTriggerCrossDocumentViewTransition::No;
2529
2530 Ref newOrigin = SecurityOrigin::create(documentURL());
2531 if (!newOrigin->isSameOriginAs(protect(oldDocument.securityOrigin())))
2532 return CanTriggerCrossDocumentViewTransition::No;
2533
2534 if (const auto* metrics = response().deprecatedNetworkLoadMetricsOrNull(); metrics && !fromBackForwardCache) {
2535 if (metrics->crossOriginRedirect())
2536 return CanTriggerCrossDocumentViewTransition::No;
2537 }
2538
2539 if (*m_triggeringAction.navigationAPIType() == NavigationNavigationType::Traverse)
2540 return CanTriggerCrossDocumentViewTransition::Yes;
2541
2542 if (isRequestFromClientOrUserInput())
2543 return CanTriggerCrossDocumentViewTransition::No;
2544
2545 return CanTriggerCrossDocumentViewTransition::Yes;
2546}
2547
2548void DocumentLoader::becomeMainResourceClient()
2549{
2550#if ENABLE(CONTENT_FILTERING)(defined 1 && 1)
2551 if (RefPtr contentFilter = m_contentFilter)
2552 contentFilter->startFilteringMainResource(*m_mainResource);
2553#endif
2554 m_mainResource->addClient(*this);
2555}
2556
2557#if ENABLE(CONTENT_EXTENSIONS)(defined 1 && 1)
2558void DocumentLoader::addPendingContentExtensionSheet(const String& identifier, StyleSheetContents& sheet)
2559{
2560 ASSERT(!m_gotFirstByte)((void)0);
2561 m_pendingNamedContentExtensionStyleSheets.set(identifier, sheet);
2562}
2563
2564void DocumentLoader::addPendingContentExtensionDisplayNoneSelector(const String& identifier, const String& selector, uint32_t selectorID)
2565{
2566 ASSERT(!m_gotFirstByte)((void)0);
2567 auto addResult = m_pendingContentExtensionDisplayNoneSelectors.add(identifier, Vector<std::pair<String, uint32_t>>());
2568 addResult.iterator->value.append(std::make_pair(selector, selectorID));
2569}
2570#endif
2571
2572#if USE(QUICK_LOOK)(defined 1 && 1)
2573
2574void DocumentLoader::previewResponseReceived(const CachedResource& resource, const ResourceResponse& response)
2575{
2576 ASSERT_UNUSED(resource, m_mainResource == &resource)((void)resource);
2577 m_response = response;
2578}
2579
2580void DocumentLoader::setPreviewConverter(RefPtr<PreviewConverter>&& previewConverter)
2581{
2582 m_previewConverter = WTF::move(previewConverter);
2583}
2584
2585PreviewConverter* DocumentLoader::previewConverter() const
2586{
2587 return m_previewConverter;
2588}
2589
2590#endif
2591
2592void DocumentLoader::addConsoleMessage(MessageSource messageSource, MessageLevel messageLevel, const String& message, unsigned long requestIdentifier)
2593{
2594 protect(protect(frame())->document())->addConsoleMessage(messageSource, messageLevel, message, requestIdentifier);
2595}
2596
2597void DocumentLoader::enqueueSecurityPolicyViolationEvent(SecurityPolicyViolationEventInit&& eventInit)
2598{
2599 protect(protect(frame())->document())->enqueueSecurityPolicyViolationEvent(WTF::move(eventInit));
2600}
2601
2602#if ENABLE(CONTENT_FILTERING)(defined 1 && 1)
2603void DocumentLoader::dataReceivedThroughContentFilter(const SharedBuffer& buffer)
2604{
2605 dataReceived(buffer);
2606}
2607
2608void DocumentLoader::cancelMainResourceLoadForContentFilter(const ResourceError& error)
2609{
2610 cancelMainResourceLoad(error);
2611}
2612
2613ResourceError DocumentLoader::contentFilterDidBlock(ContentFilterUnblockHandler&& unblockHandler, String&& unblockRequestDeniedScript)
2614{
2615 return handleContentFilterDidBlock(WTF::move(unblockHandler), WTF::move(unblockRequestDeniedScript));
2616}
2617
2618void DocumentLoader::handleProvisionalLoadFailureFromContentFilter(const URL& blockedPageURL, SubstituteData&& substituteData)
2619{
2620 protect(frameLoader())->load(FrameLoadRequest(*frame(), URL { blockedPageURL }, WTF::move(substituteData)));
2621}
2622
2623#if HAVE(WEBCONTENTRESTRICTIONS)(defined 1 && 1)
2624#if HAVE(WEBCONTENTRESTRICTIONS_PATH_SPI)(defined HAVE_WEBCONTENTRESTRICTIONS_PATH_SPI && HAVE_WEBCONTENTRESTRICTIONS_PATH_SPI
)
2625String DocumentLoader::webContentRestrictionsConfigurationPath() const
2626{
2627 return emptyString();
2628}
2629#endif
2630
2631URL DocumentLoader::mainDocumentURL() const
2632{
2633 RefPtr loaderFrame = frame();
2634 if (!loaderFrame)
2635 return { };
2636
2637 if (RefPtr origin = loaderFrame->mainFrame().frameDocumentSecurityOrigin())
2638 return origin->toURL();
2639
2640 return { };
2641}
2642#endif
2643#endif // ENABLE(CONTENT_FILTERING)
2644
2645#if ENABLE(CONTENT_FILTERING)(defined 1 && 1)
2646ResourceError DocumentLoader::handleContentFilterDidBlock(ContentFilterUnblockHandler&& unblockHandler, String&& unblockRequestDeniedScript)
2647{
2648 unblockHandler.setUnreachableURL(documentURL());
2649 if (!unblockRequestDeniedScript.isEmpty() && frame()) {
2650 unblockHandler.wrapWithDecisionHandler([scriptController = WeakPtr { frame()->script() }, script = WTF::move(unblockRequestDeniedScript).isolatedCopy()](bool unblocked) {
2651 if (!unblocked && scriptController) {
2652 // FIXME: This probably needs to figure out if the origin is considered tainted.
2653 scriptController->executeScriptIgnoringException(script, JSC::SourceTaintedOrigin::Untainted);
2654 }
2655 });
2656 }
2657 protect(frameLoader())->client().contentFilterDidBlockLoad(WTF::move(unblockHandler));
2658 auto error = protect(frameLoader())->blockedByContentFilterError(request());
2659
2660 m_blockedByContentFilter = true;
2661 m_blockedError = error;
2662
2663 return error;
2664}
2665
2666bool DocumentLoader::contentFilterWillHandleProvisionalLoadFailure(const ResourceError& error)
2667{
2668 if (RefPtr contentFilter = m_contentFilter; contentFilter && contentFilter->willHandleProvisionalLoadFailure(error))
2669 return true;
2670 if (contentFilterInDocumentLoader())
2671 return false;
2672 return m_blockedByContentFilter && m_blockedError.errorCode() == error.errorCode() && m_blockedError.domain() == error.domain();
2673}
2674
2675void DocumentLoader::contentFilterHandleProvisionalLoadFailure(const ResourceError& error)
2676{
2677 if (RefPtr contentFilter = m_contentFilter)
2678 contentFilter->handleProvisionalLoadFailure(error);
2679 if (contentFilterInDocumentLoader())
2680 return;
2681 handleProvisionalLoadFailureFromContentFilter(m_blockedPageURL, SubstituteData { m_substituteDataFromContentFilter });
2682}
2683
2684#endif // ENABLE(CONTENT_FILTERING)
2685
2686void DocumentLoader::setActiveContentRuleListActionPatterns(const HashMap<String, Vector<String>>& patterns)
2687{
2688 MemoryCompactRobinHoodHashMap<String, Vector<UserContentURLPattern>> parsedPatternMap;
2689
2690 for (auto& pair : patterns) {
2691 auto patternVector = WTF::compactMap(pair.value, [](auto& patternString) -> std::optional<UserContentURLPattern> {
2692 UserContentURLPattern parsedPattern(patternString);
2693 if (parsedPattern.isValid())
2694 return parsedPattern;
2695 return std::nullopt;
2696 });
2697 parsedPatternMap.set(pair.key, WTF::move(patternVector));
2698 }
2699
2700 m_activeContentRuleListActionPatterns = WTF::move(parsedPatternMap);
2701}
2702
2703bool DocumentLoader::allowsActiveContentRuleListActionsForURL(const String& contentRuleListIdentifier, const URL& url) const
2704{
2705 for (const auto& pattern : m_activeContentRuleListActionPatterns.get(contentRuleListIdentifier)) {
2706 if (pattern.matches(url))
2707 return true;
2708 }
2709 return false;
2710}
2711
2712void DocumentLoader::setHTTPSByDefaultMode(HTTPSByDefaultMode mode)
2713{
2714 if (mode == HTTPSByDefaultMode::Disabled) {
2715 if (m_advancedPrivacyProtections.contains(AdvancedPrivacyProtections::HTTPSOnly))
2716 m_httpsByDefaultMode = HTTPSByDefaultMode::UpgradeWithUserMediatedFallback;
2717 else if (m_advancedPrivacyProtections.contains(AdvancedPrivacyProtections::HTTPSFirst))
2718 m_httpsByDefaultMode = HTTPSByDefaultMode::UpgradeWithAutomaticFallback;
2719 } else
2720 m_httpsByDefaultMode = mode;
2721}
2722
2723void DocumentLoader::setPreferences(WebpagePreferences&& preferences)
2724{
2725 m_preferences = WTF::move(preferences);
2726}
2727
2728void DocumentLoader::whenDocumentIsCreated(Function<void(Document*)>&& callback)
2729{
2730 ASSERT(!m_canUseServiceWorkers || !!m_resultingClientId)((void)0);
2731
2732 if (auto previousCallback = std::exchange(m_whenDocumentIsCreatedCallback, { })) {
2733 callback = [previousCallback = WTF::move(previousCallback), newCallback = WTF::move(callback)] (auto* document) mutable {
2734 previousCallback(document);
2735 newCallback(document);
2736 };
2737 }
2738 m_whenDocumentIsCreatedCallback = WTF::move(callback);
2739}
2740
2741void DocumentLoader::setNewResultingClientId(ScriptExecutionContextIdentifier identifier)
2742{
2743 if (scriptExecutionContextIdentifierToLoaderMap().remove(*m_resultingClientId)) {
2744 m_resultingClientId = identifier;
2745 scriptExecutionContextIdentifierToLoaderMap().add(identifier, this);
2746 }
2747}
2748
2749std::unique_ptr<IntegrityPolicy> DocumentLoader::integrityPolicy()
2750{
2751 return WTF::move(m_integrityPolicy);
2752}
2753
2754std::unique_ptr<IntegrityPolicy> DocumentLoader::integrityPolicyReportOnly()
2755{
2756 return WTF::move(m_integrityPolicyReportOnly);
2757}
2758
2759} // namespace WebCore
2760
2761#undef PAGE_ID
2762#undef FRAME_ID
2763#undef IS_MAIN_FRAME