Bug Summary

File:root/firefox-clang/dom/prototype/PrototypeDocumentContentSink.cpp
Warning:line 763, column 7
Value stored to 'rv' is never read

Annotated Source Code

Press '?' to see keyboard shortcuts

clang -cc1 -cc1 -triple x86_64-pc-linux-gnu -O2 -analyze -disable-free -clear-ast-before-backend -disable-llvm-verifier -discard-value-names -main-file-name PrototypeDocumentContentSink.cpp -analyzer-checker=core -analyzer-checker=apiModeling -analyzer-checker=unix -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 -fhalf-no-semantic-interposition -mframe-pointer=all -relaxed-aliasing -ffp-contract=off -fno-rounding-math -mconstructor-aliases -funwind-tables=2 -target-cpu x86-64 -tune-cpu generic -debugger-tuning=gdb -fdebug-compilation-dir=/root/firefox-clang/obj-x86_64-pc-linux-gnu/dom/prototype -fcoverage-compilation-dir=/root/firefox-clang/obj-x86_64-pc-linux-gnu/dom/prototype -resource-dir /usr/lib/llvm-23/lib/clang/23 -include /root/firefox-clang/config/gcc_hidden.h -include /root/firefox-clang/obj-x86_64-pc-linux-gnu/mozilla-config.h -I /root/firefox-clang/obj-x86_64-pc-linux-gnu/dist/stl_wrappers -D _GLIBCXX_ASSERTIONS=1 -I /root/firefox-clang/obj-x86_64-pc-linux-gnu/dist/system_wrappers -U _FORTIFY_SOURCE -D _FORTIFY_SOURCE=2 -D DEBUG=1 -D MOZ_HAS_MOZGLUE -D MOZILLA_INTERNAL_API -D IMPL_LIBXUL -D MOZ_SUPPORT_LEAKCHECKING -D STATIC_EXPORTABLE_JS_API -I /root/firefox-clang/dom/prototype -I /root/firefox-clang/obj-x86_64-pc-linux-gnu/dom/prototype -I /root/firefox-clang/dom/base -I /root/firefox-clang/dom/xul -I /root/firefox-clang/obj-x86_64-pc-linux-gnu/dist/include -I /root/firefox-clang/obj-x86_64-pc-linux-gnu/dist/include/nspr -I /root/firefox-clang/obj-x86_64-pc-linux-gnu/dist/include/nss -D MOZILLA_CLIENT -internal-isystem /usr/lib/gcc/x86_64-linux-gnu/16/../../../../include/c++/16 -internal-isystem /usr/lib/gcc/x86_64-linux-gnu/16/../../../../include/x86_64-linux-gnu/c++/16 -internal-isystem /usr/lib/gcc/x86_64-linux-gnu/16/../../../../include/c++/16/backward -internal-isystem /usr/lib/llvm-23/lib/clang/23/include -internal-isystem /usr/local/include -internal-isystem /usr/lib/gcc/x86_64-linux-gnu/16/../../../../x86_64-linux-gnu/include -internal-externc-isystem /usr/include/x86_64-linux-gnu -internal-externc-isystem /include -internal-externc-isystem /usr/include -Wno-error=pessimizing-move -Wno-error=large-by-value-copy=128 -Wno-error=implicit-int-float-conversion -Wno-error=thread-safety-analysis -Wno-error=tautological-type-limit-compare -Wno-invalid-offsetof -Wno-range-loop-analysis -Wno-deprecated-anon-enum-enum-conversion -Wno-deprecated-enum-enum-conversion -Wno-inline-new-delete -Wno-error=deprecated-declarations -Wno-error=array-bounds -Wno-error=free-nonheap-object -Wno-error=atomic-alignment -Wno-error=deprecated-builtins -Wno-psabi -Wno-error=builtin-macro-redefined -Wno-vla-cxx-extension -Wno-unknown-warning-option -Wno-character-conversion -std=gnu++20 -fdeprecated-macro -ferror-limit 19 -fstrict-flex-arrays=1 -stack-protector 2 -fstack-clash-protection -ftrivial-auto-var-init=pattern -fno-rtti -fgnuc-version=4.2.1 -fno-implicit-modules -fskip-odr-check-in-gmf -fno-sized-deallocation -fno-aligned-allocation -fdiagnostics-absolute-paths -vectorize-loops -vectorize-slp -analyzer-checker optin.performance.Padding -analyzer-output=html -analyzer-config stable-report-filename=true -mllvm -dwarf-linkage-names=Abstract -faddrsig -fdwarf2-cfi-asm -o /tmp/scan-build-2026-10-03-101356-1532927-1 -x c++ /root/firefox-clang/dom/prototype/PrototypeDocumentContentSink.cpp
1/* This Source Code Form is subject to the terms of the Mozilla Public
2 * License, v. 2.0. If a copy of the MPL was not distributed with this
3 * file, You can obtain one at https://mozilla.org/MPL/2.0/. */
4
5#include "mozilla/dom/PrototypeDocumentContentSink.h"
6
7#include "js/CompilationAndEvaluation.h"
8#include "js/Utility.h" // JS::FreePolicy
9#include "js/experimental/JSStencil.h"
10#include "mozAutoDocUpdate.h"
11#include "mozilla/CycleCollectedJSContext.h"
12#include "mozilla/LoadInfo.h"
13#include "mozilla/Logging.h"
14#include "mozilla/PresShell.h"
15#include "mozilla/ProfilerLabels.h"
16#include "mozilla/RefPtr.h"
17#include "mozilla/StyleSheetInlines.h"
18#include "mozilla/Try.h"
19#include "mozilla/css/Loader.h"
20#include "mozilla/dom/AutoEntryScript.h"
21#include "mozilla/dom/CDATASection.h"
22#include "mozilla/dom/Comment.h"
23#include "mozilla/dom/Document.h"
24#include "mozilla/dom/DocumentType.h"
25#include "mozilla/dom/Element.h"
26#include "mozilla/dom/HTMLTemplateElement.h"
27#include "mozilla/dom/PolicyContainer.h"
28#include "mozilla/dom/ProcessingInstruction.h"
29#include "mozilla/dom/ScriptLoader.h"
30#include "mozilla/dom/XMLStylesheetProcessingInstruction.h"
31#include "mozilla/dom/nsCSPUtils.h"
32#include "nsCOMPtr.h"
33#include "nsCRT.h"
34#include "nsContentCreatorFunctions.h"
35#include "nsContentPolicyUtils.h"
36#include "nsContentUtils.h"
37#include "nsDocElementCreatedNotificationRunner.h"
38#include "nsError.h"
39#include "nsGkAtoms.h"
40#include "nsHTMLParts.h"
41#include "nsHtml5SVGLoadDispatcher.h"
42#include "nsIChannel.h"
43#include "nsIContent.h"
44#include "nsIContentPolicy.h"
45#include "nsIParser.h"
46#include "nsIScriptContext.h"
47#include "nsIScriptElement.h"
48#include "nsIScriptError.h"
49#include "nsIScriptGlobalObject.h"
50#include "nsIURI.h"
51#include "nsMimeTypes.h"
52#include "nsNameSpaceManager.h"
53#include "nsNetUtil.h"
54#include "nsNodeInfoManager.h"
55#include "nsReadableUtils.h"
56#include "nsRect.h"
57#include "nsTextNode.h"
58#include "nsUnicharUtils.h"
59#include "nsXULElement.h"
60#include "nsXULPrototypeCache.h"
61#include "prtime.h"
62
63using namespace mozilla;
64using namespace mozilla::dom;
65
66LazyLogModule PrototypeDocumentContentSink::gLog("PrototypeDocument");
67
68nsresult NS_NewPrototypeDocumentContentSink(nsIContentSink** aResult,
69 Document* aDoc, nsIURI* aURI,
70 nsISupports* aContainer,
71 nsIChannel* aChannel) {
72 MOZ_ASSERT(nullptr != aResult, "null ptr")do { static_assert( mozilla::detail::AssertionConditionType<
decltype(nullptr != aResult)>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(nullptr != aResult))), 0))) {
do { } while (false); MOZ_ReportAssertionFailure("nullptr != aResult"
" (" "null ptr" ")", "/root/firefox-clang/dom/prototype/PrototypeDocumentContentSink.cpp"
, 72); AnnotateMozCrashReason("MOZ_ASSERT" "(" "nullptr != aResult"
") (" "null ptr" ")"); do { MOZ_CrashSequence(__null, 72); __attribute__
((nomerge)) ::abort(); } while (false); } } while (false)
;
73 if (nullptr == aResult) {
74 return NS_ERROR_NULL_POINTER;
75 }
76 RefPtr<PrototypeDocumentContentSink> it = new PrototypeDocumentContentSink();
77
78 nsresult rv = it->Init(aDoc, aURI, aContainer, aChannel);
79 NS_ENSURE_SUCCESS(rv, rv)do { nsresult __rv = rv; if (((bool)(__builtin_expect(!!(NS_FAILED_impl
(__rv)), 0)))) { const char* name = mozilla::GetStaticErrorName
(__rv); mozilla::SmprintfPointer msg = mozilla::Smprintf( "NS_ENSURE_SUCCESS(%s, %s) failed with "
"result 0x%" "X" "%s%s%s", "rv", "rv", static_cast<uint32_t
>(__rv), name ? " (" : "", name ? name : "", name ? ")" : ""
); NS_DebugBreak(NS_DEBUG_WARNING, msg.get(), nullptr, "/root/firefox-clang/dom/prototype/PrototypeDocumentContentSink.cpp"
, 79); return rv; } } while (false)
;
80
81 it.forget(aResult);
82 return NS_OK;
83}
84
85namespace mozilla::dom {
86
87PrototypeDocumentContentSink::PrototypeDocumentContentSink()
88 : mNextSrcLoadWaiter(nullptr),
89 mCurrentScriptProto(nullptr),
90 mOffThreadCompiling(false),
91 mStillWalking(false),
92 mPendingSheets(0) {}
93
94PrototypeDocumentContentSink::~PrototypeDocumentContentSink() {
95 NS_ASSERTION(do { if (!(mNextSrcLoadWaiter == nullptr)) { NS_DebugBreak(NS_DEBUG_ASSERTION
, "unreferenced document still waiting for script source to load?"
, "mNextSrcLoadWaiter == nullptr", "/root/firefox-clang/dom/prototype/PrototypeDocumentContentSink.cpp"
, 97); MOZ_PretendNoReturn(); } } while (0)
96 mNextSrcLoadWaiter == nullptr,do { if (!(mNextSrcLoadWaiter == nullptr)) { NS_DebugBreak(NS_DEBUG_ASSERTION
, "unreferenced document still waiting for script source to load?"
, "mNextSrcLoadWaiter == nullptr", "/root/firefox-clang/dom/prototype/PrototypeDocumentContentSink.cpp"
, 97); MOZ_PretendNoReturn(); } } while (0)
97 "unreferenced document still waiting for script source to load?")do { if (!(mNextSrcLoadWaiter == nullptr)) { NS_DebugBreak(NS_DEBUG_ASSERTION
, "unreferenced document still waiting for script source to load?"
, "mNextSrcLoadWaiter == nullptr", "/root/firefox-clang/dom/prototype/PrototypeDocumentContentSink.cpp"
, 97); MOZ_PretendNoReturn(); } } while (0)
;
98}
99
100nsresult PrototypeDocumentContentSink::Init(Document* aDoc, nsIURI* aURI,
101 nsISupports* aContainer,
102 nsIChannel* aChannel) {
103 MOZ_ASSERT(aDoc, "null ptr")do { static_assert( mozilla::detail::AssertionConditionType<
decltype(aDoc)>::isValid, "invalid assertion condition"); if
((__builtin_expect(!!(!(!!(aDoc))), 0))) { do { } while (false
); MOZ_ReportAssertionFailure("aDoc" " (" "null ptr" ")", "/root/firefox-clang/dom/prototype/PrototypeDocumentContentSink.cpp"
, 103); AnnotateMozCrashReason("MOZ_ASSERT" "(" "aDoc" ") (" "null ptr"
")"); do { MOZ_CrashSequence(__null, 103); __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
104 MOZ_ASSERT(aURI, "null ptr")do { static_assert( mozilla::detail::AssertionConditionType<
decltype(aURI)>::isValid, "invalid assertion condition"); if
((__builtin_expect(!!(!(!!(aURI))), 0))) { do { } while (false
); MOZ_ReportAssertionFailure("aURI" " (" "null ptr" ")", "/root/firefox-clang/dom/prototype/PrototypeDocumentContentSink.cpp"
, 104); AnnotateMozCrashReason("MOZ_ASSERT" "(" "aURI" ") (" "null ptr"
")"); do { MOZ_CrashSequence(__null, 104); __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
105
106 mDocument = aDoc;
107
108 mDocument->SetDelayFrameLoaderInitialization(true);
109 mDocument->SetMayStartLayout(false);
110
111 // Get the URI. this should match the uri used for the OnNewURI call in
112 // nsDocShell::CreateDocumentViewer.
113 nsresult rv = NS_GetFinalChannelURI(aChannel, getter_AddRefs(mDocumentURI));
114 NS_ENSURE_SUCCESS(rv, rv)do { nsresult __rv = rv; if (((bool)(__builtin_expect(!!(NS_FAILED_impl
(__rv)), 0)))) { const char* name = mozilla::GetStaticErrorName
(__rv); mozilla::SmprintfPointer msg = mozilla::Smprintf( "NS_ENSURE_SUCCESS(%s, %s) failed with "
"result 0x%" "X" "%s%s%s", "rv", "rv", static_cast<uint32_t
>(__rv), name ? " (" : "", name ? name : "", name ? ")" : ""
); NS_DebugBreak(NS_DEBUG_WARNING, msg.get(), nullptr, "/root/firefox-clang/dom/prototype/PrototypeDocumentContentSink.cpp"
, 114); return rv; } } while (false)
;
115
116 mScriptLoader = mDocument->GetScriptLoader();
117
118 return NS_OK;
119}
120
121NS_IMPL_CYCLE_COLLECTION(PrototypeDocumentContentSink, mParser, mDocumentURI,PrototypeDocumentContentSink::cycleCollection PrototypeDocumentContentSink
::_cycleCollectorGlobal; void PrototypeDocumentContentSink::cycleCollection
::Unlink(void* p) { PrototypeDocumentContentSink* tmp = DowncastCCParticipant
<PrototypeDocumentContentSink>(p); ImplCycleCollectionUnlink
(tmp->mParser); ImplCycleCollectionUnlink(tmp->mDocumentURI
); ImplCycleCollectionUnlink(tmp->mDocument); ImplCycleCollectionUnlink
(tmp->mScriptLoader); ImplCycleCollectionUnlink(tmp->mContextStack
); ImplCycleCollectionUnlink(tmp->mCurrentPrototype); (void
)tmp; } nsresult PrototypeDocumentContentSink::cycleCollection
::TraverseNative( void* p, nsCycleCollectionTraversalCallback
& cb) { PrototypeDocumentContentSink* tmp = DowncastCCParticipant
<PrototypeDocumentContentSink>(p); cb.DescribeRefCountedNode
(tmp->mRefCnt.get(), "PrototypeDocumentContentSink"); ImplCycleCollectionTraverse
(cb, tmp->mParser, "mParser", 0); ImplCycleCollectionTraverse
(cb, tmp->mDocumentURI, "mDocumentURI", 0); ImplCycleCollectionTraverse
(cb, tmp->mDocument, "mDocument", 0); ImplCycleCollectionTraverse
(cb, tmp->mScriptLoader, "mScriptLoader", 0); ImplCycleCollectionTraverse
(cb, tmp->mContextStack, "mContextStack", 0); ImplCycleCollectionTraverse
(cb, tmp->mCurrentPrototype, "mCurrentPrototype", 0); (void
)tmp; return NS_OK; }
122 mDocument, mScriptLoader, mContextStack,PrototypeDocumentContentSink::cycleCollection PrototypeDocumentContentSink
::_cycleCollectorGlobal; void PrototypeDocumentContentSink::cycleCollection
::Unlink(void* p) { PrototypeDocumentContentSink* tmp = DowncastCCParticipant
<PrototypeDocumentContentSink>(p); ImplCycleCollectionUnlink
(tmp->mParser); ImplCycleCollectionUnlink(tmp->mDocumentURI
); ImplCycleCollectionUnlink(tmp->mDocument); ImplCycleCollectionUnlink
(tmp->mScriptLoader); ImplCycleCollectionUnlink(tmp->mContextStack
); ImplCycleCollectionUnlink(tmp->mCurrentPrototype); (void
)tmp; } nsresult PrototypeDocumentContentSink::cycleCollection
::TraverseNative( void* p, nsCycleCollectionTraversalCallback
& cb) { PrototypeDocumentContentSink* tmp = DowncastCCParticipant
<PrototypeDocumentContentSink>(p); cb.DescribeRefCountedNode
(tmp->mRefCnt.get(), "PrototypeDocumentContentSink"); ImplCycleCollectionTraverse
(cb, tmp->mParser, "mParser", 0); ImplCycleCollectionTraverse
(cb, tmp->mDocumentURI, "mDocumentURI", 0); ImplCycleCollectionTraverse
(cb, tmp->mDocument, "mDocument", 0); ImplCycleCollectionTraverse
(cb, tmp->mScriptLoader, "mScriptLoader", 0); ImplCycleCollectionTraverse
(cb, tmp->mContextStack, "mContextStack", 0); ImplCycleCollectionTraverse
(cb, tmp->mCurrentPrototype, "mCurrentPrototype", 0); (void
)tmp; return NS_OK; }
123 mCurrentPrototype)PrototypeDocumentContentSink::cycleCollection PrototypeDocumentContentSink
::_cycleCollectorGlobal; void PrototypeDocumentContentSink::cycleCollection
::Unlink(void* p) { PrototypeDocumentContentSink* tmp = DowncastCCParticipant
<PrototypeDocumentContentSink>(p); ImplCycleCollectionUnlink
(tmp->mParser); ImplCycleCollectionUnlink(tmp->mDocumentURI
); ImplCycleCollectionUnlink(tmp->mDocument); ImplCycleCollectionUnlink
(tmp->mScriptLoader); ImplCycleCollectionUnlink(tmp->mContextStack
); ImplCycleCollectionUnlink(tmp->mCurrentPrototype); (void
)tmp; } nsresult PrototypeDocumentContentSink::cycleCollection
::TraverseNative( void* p, nsCycleCollectionTraversalCallback
& cb) { PrototypeDocumentContentSink* tmp = DowncastCCParticipant
<PrototypeDocumentContentSink>(p); cb.DescribeRefCountedNode
(tmp->mRefCnt.get(), "PrototypeDocumentContentSink"); ImplCycleCollectionTraverse
(cb, tmp->mParser, "mParser", 0); ImplCycleCollectionTraverse
(cb, tmp->mDocumentURI, "mDocumentURI", 0); ImplCycleCollectionTraverse
(cb, tmp->mDocument, "mDocument", 0); ImplCycleCollectionTraverse
(cb, tmp->mScriptLoader, "mScriptLoader", 0); ImplCycleCollectionTraverse
(cb, tmp->mContextStack, "mContextStack", 0); ImplCycleCollectionTraverse
(cb, tmp->mCurrentPrototype, "mCurrentPrototype", 0); (void
)tmp; return NS_OK; }
124
125NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(PrototypeDocumentContentSink)nsresult PrototypeDocumentContentSink::QueryInterface(const nsIID
& aIID, void** aInstancePtr) { do { if (!(aInstancePtr)) {
NS_DebugBreak(NS_DEBUG_ASSERTION, "QueryInterface requires a non-NULL destination!"
, "aInstancePtr", "/root/firefox-clang/dom/prototype/PrototypeDocumentContentSink.cpp"
, 125); MOZ_PretendNoReturn(); } } while (0); nsISupports* foundInterface
; if (TopThreeWordsEquals( aIID, (nsXPCOMCycleCollectionParticipant
::kIID), (nsCycleCollectionISupports::kIID)) && (LowWordEquals
(aIID, (nsXPCOMCycleCollectionParticipant::kIID)) || LowWordEquals
(aIID, (nsCycleCollectionISupports::kIID)))) { if (LowWordEquals
(aIID, (nsXPCOMCycleCollectionParticipant::kIID))) { *aInstancePtr
= PrototypeDocumentContentSink::cycleCollection::GetParticipant
(); return NS_OK; } if (LowWordEquals(aIID, (nsCycleCollectionISupports
::kIID))) { *aInstancePtr = PrototypeDocumentContentSink::cycleCollection
::Upcast(this); return NS_OK; } foundInterface = nullptr; } else
126 NS_INTERFACE_MAP_ENTRY_AMBIGUOUS(nsISupports, nsIContentSink)if (aIID.Equals(mozilla::detail::kImplementedIID<std::remove_reference_t
<decltype(*this)>, nsISupports>)) foundInterface = static_cast
<nsISupports*>(static_cast<nsIContentSink*>(this)
); else
127 NS_INTERFACE_MAP_ENTRY(nsIContentSink)if (aIID.Equals(mozilla::detail::kImplementedIID<std::remove_reference_t
<decltype(*this)>, nsIContentSink>)) foundInterface =
static_cast<nsIContentSink*>(this); else
128 NS_INTERFACE_MAP_ENTRY(nsIStreamLoaderObserver)if (aIID.Equals(mozilla::detail::kImplementedIID<std::remove_reference_t
<decltype(*this)>, nsIStreamLoaderObserver>)) foundInterface
= static_cast<nsIStreamLoaderObserver*>(this); else
129 NS_INTERFACE_MAP_ENTRY(nsICSSLoaderObserver)if (aIID.Equals(mozilla::detail::kImplementedIID<std::remove_reference_t
<decltype(*this)>, nsICSSLoaderObserver>)) foundInterface
= static_cast<nsICSSLoaderObserver*>(this); else
130 NS_INTERFACE_MAP_ENTRY(nsIOffThreadScriptReceiver)if (aIID.Equals(mozilla::detail::kImplementedIID<std::remove_reference_t
<decltype(*this)>, nsIOffThreadScriptReceiver>)) foundInterface
= static_cast<nsIOffThreadScriptReceiver*>(this); else
131NS_INTERFACE_MAP_ENDfoundInterface = 0; nsresult status; if (!foundInterface) { do
{ static_assert( mozilla::detail::AssertionConditionType<
decltype(!aIID.Equals((nsISupports::kIID)))>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(!aIID.Equals((nsISupports::kIID
))))), 0))) { do { } while (false); MOZ_ReportAssertionFailure
("!aIID.Equals((nsISupports::kIID))", "/root/firefox-clang/dom/prototype/PrototypeDocumentContentSink.cpp"
, 131); AnnotateMozCrashReason("MOZ_ASSERT" "(" "!aIID.Equals((nsISupports::kIID))"
")"); do { MOZ_CrashSequence(__null, 131); __attribute__((nomerge
)) ::abort(); } while (false); } } while (false); status = NS_NOINTERFACE
; } else { (foundInterface)->AddRef(); status = NS_OK; } *
aInstancePtr = foundInterface; return status; }
132
133NS_IMPL_CYCLE_COLLECTING_ADDREF(PrototypeDocumentContentSink)MozExternalRefCountType PrototypeDocumentContentSink::AddRef(
void) { static_assert(!std::is_destructible_v<PrototypeDocumentContentSink
>, "Reference-counted class " "PrototypeDocumentContentSink"
" should not have a public destructor. " "Make this class's destructor non-public"
); do { static_assert( mozilla::detail::AssertionConditionType
<decltype(int32_t(mRefCnt) >= 0)>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(int32_t(mRefCnt) >= 0))),
0))) { do { } while (false); MOZ_ReportAssertionFailure("int32_t(mRefCnt) >= 0"
" (" "illegal refcnt" ")", "/root/firefox-clang/dom/prototype/PrototypeDocumentContentSink.cpp"
, 133); AnnotateMozCrashReason("MOZ_ASSERT" "(" "int32_t(mRefCnt) >= 0"
") (" "illegal refcnt" ")"); do { MOZ_CrashSequence(__null, 133
); __attribute__((nomerge)) ::abort(); } while (false); } } while
(false); _mOwningThread.AssertOwnership("PrototypeDocumentContentSink"
" not thread-safe"); nsISupports* base = PrototypeDocumentContentSink
::cycleCollection::Upcast(this); nsrefcnt count = mRefCnt.incr
(base); NS_LogAddRef((this), (count), ("PrototypeDocumentContentSink"
), (uint32_t)(sizeof(*this))); return count; }
134NS_IMPL_CYCLE_COLLECTING_RELEASE(PrototypeDocumentContentSink)MozExternalRefCountType PrototypeDocumentContentSink::Release
(void) { do { static_assert( mozilla::detail::AssertionConditionType
<decltype(int32_t(mRefCnt) > 0)>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(int32_t(mRefCnt) > 0))), 0
))) { do { } while (false); MOZ_ReportAssertionFailure("int32_t(mRefCnt) > 0"
" (" "dup release" ")", "/root/firefox-clang/dom/prototype/PrototypeDocumentContentSink.cpp"
, 134); AnnotateMozCrashReason("MOZ_ASSERT" "(" "int32_t(mRefCnt) > 0"
") (" "dup release" ")"); do { MOZ_CrashSequence(__null, 134
); __attribute__((nomerge)) ::abort(); } while (false); } } while
(false); _mOwningThread.AssertOwnership("PrototypeDocumentContentSink"
" not thread-safe"); nsISupports* base = PrototypeDocumentContentSink
::cycleCollection::Upcast(this); nsrefcnt count = mRefCnt.decr
(base); if (count == 0) { NS_CycleCollectableHasRefCntZero();
} NS_LogRelease((this), (count), ("PrototypeDocumentContentSink"
)); return count; } void PrototypeDocumentContentSink::DeleteCycleCollectable
(void) { delete (this); }
135
136//----------------------------------------------------------------------
137//
138// nsIContentSink interface
139//
140
141void PrototypeDocumentContentSink::SetDocumentCharset(
142 NotNull<const Encoding*> aEncoding) {
143 if (mDocument) {
144 mDocument->SetDocumentCharacterSet(aEncoding);
145 }
146}
147
148nsISupports* PrototypeDocumentContentSink::GetTarget() {
149 return ToSupports(mDocument);
150}
151
152bool PrototypeDocumentContentSink::IsScriptExecuting() {
153 if (!mScriptLoader) {
154 MOZ_ASSERT(false, "Can't load prototype docs as data")do { static_assert( mozilla::detail::AssertionConditionType<
decltype(false)>::isValid, "invalid assertion condition");
if ((__builtin_expect(!!(!(!!(false))), 0))) { do { } while (
false); MOZ_ReportAssertionFailure("false" " (" "Can't load prototype docs as data"
")", "/root/firefox-clang/dom/prototype/PrototypeDocumentContentSink.cpp"
, 154); AnnotateMozCrashReason("MOZ_ASSERT" "(" "false" ") ("
"Can't load prototype docs as data" ")"); do { MOZ_CrashSequence
(__null, 154); __attribute__((nomerge)) ::abort(); } while (false
); } } while (false)
;
155 return false;
156 }
157 return !!mScriptLoader->GetCurrentScript();
158}
159
160NS_IMETHODIMPnsresult
161PrototypeDocumentContentSink::SetParser(nsParserBase* aParser) {
162 MOZ_ASSERT(aParser, "Should have a parser here!")do { static_assert( mozilla::detail::AssertionConditionType<
decltype(aParser)>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(aParser))), 0))) { do { } while
(false); MOZ_ReportAssertionFailure("aParser" " (" "Should have a parser here!"
")", "/root/firefox-clang/dom/prototype/PrototypeDocumentContentSink.cpp"
, 162); AnnotateMozCrashReason("MOZ_ASSERT" "(" "aParser" ") ("
"Should have a parser here!" ")"); do { MOZ_CrashSequence(__null
, 162); __attribute__((nomerge)) ::abort(); } while (false); }
} while (false)
;
163 mParser = aParser;
164 return NS_OK;
165}
166
167nsIParser* PrototypeDocumentContentSink::GetParser() {
168 return static_cast<nsIParser*>(mParser.get());
169}
170
171void PrototypeDocumentContentSink::ContinueInterruptedParsingIfEnabled() {
172 if (mParser && mParser->IsParserEnabled()) {
173 GetParser()->ContinueInterruptedParsing();
174 }
175}
176
177void PrototypeDocumentContentSink::ContinueInterruptedParsingAsync() {
178 nsCOMPtr<nsIRunnable> ev = NewRunnableMethod(
179 "PrototypeDocumentContentSink::ContinueInterruptedParsingIfEnabled", this,
180 &PrototypeDocumentContentSink::ContinueInterruptedParsingIfEnabled);
181 mDocument->Dispatch(ev.forget());
182}
183
184//----------------------------------------------------------------------
185//
186// PrototypeDocumentContentSink::ContextStack
187//
188
189PrototypeDocumentContentSink::ContextStack::ContextStack()
190 : mTop(nullptr), mDepth(0) {}
191
192PrototypeDocumentContentSink::ContextStack::~ContextStack() { Clear(); }
193
194void PrototypeDocumentContentSink::ContextStack::Traverse(
195 nsCycleCollectionTraversalCallback& aCallback, const char* aName,
196 uint32_t aFlags) {
197 aFlags |= CycleCollectionEdgeNameArrayFlag;
198 Entry* current = mTop;
199 while (current) {
200 CycleCollectionNoteChild(aCallback, current->mElement, aName, aFlags);
201 current = current->mNext;
202 }
203}
204
205void PrototypeDocumentContentSink::ContextStack::Clear() {
206 while (mTop) {
207 Entry* doomed = mTop;
208 mTop = mTop->mNext;
209 NS_IF_RELEASE(doomed->mElement)do { if (doomed->mElement) { (doomed->mElement)->Release
(); (doomed->mElement) = 0; } } while (0)
;
210 delete doomed;
211 }
212 mDepth = 0;
213}
214
215nsresult PrototypeDocumentContentSink::ContextStack::Push(
216 nsXULPrototypeElement* aPrototype, nsIContent* aElement) {
217 Entry* entry = new Entry;
218 entry->mPrototype = aPrototype;
219 entry->mElement = aElement;
220 NS_IF_ADDREF(entry->mElement)ns_if_addref(entry->mElement);
221 entry->mIndex = 0;
222
223 entry->mNext = mTop;
224 mTop = entry;
225
226 ++mDepth;
227 return NS_OK;
228}
229
230nsresult PrototypeDocumentContentSink::ContextStack::Pop() {
231 if (mDepth == 0) return NS_ERROR_UNEXPECTED;
232
233 Entry* doomed = mTop;
234 mTop = mTop->mNext;
235 --mDepth;
236
237 NS_IF_RELEASE(doomed->mElement)do { if (doomed->mElement) { (doomed->mElement)->Release
(); (doomed->mElement) = 0; } } while (0)
;
238 delete doomed;
239 return NS_OK;
240}
241
242nsresult PrototypeDocumentContentSink::ContextStack::Peek(
243 nsXULPrototypeElement** aPrototype, nsIContent** aElement,
244 int32_t* aIndex) {
245 if (mDepth == 0) return NS_ERROR_UNEXPECTED;
246
247 *aPrototype = mTop->mPrototype;
248 *aElement = mTop->mElement;
249 NS_IF_ADDREF(*aElement)ns_if_addref(*aElement);
250 *aIndex = mTop->mIndex;
251
252 return NS_OK;
253}
254
255nsresult PrototypeDocumentContentSink::ContextStack::SetTopIndex(
256 int32_t aIndex) {
257 if (mDepth == 0) return NS_ERROR_UNEXPECTED;
258
259 mTop->mIndex = aIndex;
260 return NS_OK;
261}
262
263//----------------------------------------------------------------------
264//
265// Content model walking routines
266//
267
268nsresult PrototypeDocumentContentSink::OnPrototypeLoadDone(
269 nsXULPrototypeDocument* aPrototype) {
270 mCurrentPrototype = aPrototype;
271 mDocument->SetPrototypeDocument(aPrototype);
272
273 nsresult rv = PrepareToWalk();
274 NS_ENSURE_SUCCESS(rv, rv)do { nsresult __rv = rv; if (((bool)(__builtin_expect(!!(NS_FAILED_impl
(__rv)), 0)))) { const char* name = mozilla::GetStaticErrorName
(__rv); mozilla::SmprintfPointer msg = mozilla::Smprintf( "NS_ENSURE_SUCCESS(%s, %s) failed with "
"result 0x%" "X" "%s%s%s", "rv", "rv", static_cast<uint32_t
>(__rv), name ? " (" : "", name ? name : "", name ? ")" : ""
); NS_DebugBreak(NS_DEBUG_WARNING, msg.get(), nullptr, "/root/firefox-clang/dom/prototype/PrototypeDocumentContentSink.cpp"
, 274); return rv; } } while (false)
;
275
276 rv = ResumeWalk();
277
278 return rv;
279}
280
281nsresult PrototypeDocumentContentSink::PrepareToWalk() {
282 MOZ_ASSERT(mCurrentPrototype)do { static_assert( mozilla::detail::AssertionConditionType<
decltype(mCurrentPrototype)>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(mCurrentPrototype))), 0))) {
do { } while (false); MOZ_ReportAssertionFailure("mCurrentPrototype"
, "/root/firefox-clang/dom/prototype/PrototypeDocumentContentSink.cpp"
, 282); AnnotateMozCrashReason("MOZ_ASSERT" "(" "mCurrentPrototype"
")"); do { MOZ_CrashSequence(__null, 282); __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
283 nsresult rv;
284
285 mStillWalking = true;
286
287 // Notify document that the load is beginning
288 mDocument->BeginLoad();
289 MOZ_ASSERT(!mDocument->HasChildren())do { static_assert( mozilla::detail::AssertionConditionType<
decltype(!mDocument->HasChildren())>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(!mDocument->HasChildren()
))), 0))) { do { } while (false); MOZ_ReportAssertionFailure(
"!mDocument->HasChildren()", "/root/firefox-clang/dom/prototype/PrototypeDocumentContentSink.cpp"
, 289); AnnotateMozCrashReason("MOZ_ASSERT" "(" "!mDocument->HasChildren()"
")"); do { MOZ_CrashSequence(__null, 289); __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
290
291 // Get the prototype's root element and initialize the context
292 // stack for the prototype walk.
293 nsXULPrototypeElement* proto = mCurrentPrototype->GetRootElement();
294
295 if (!proto) {
296 if (MOZ_LOG_TEST(gLog, LogLevel::Error)(__builtin_expect(!!(mozilla::detail::log_test(gLog, LogLevel
::Error)), 0))
) {
297 nsCOMPtr<nsIURI> url = mCurrentPrototype->GetURI();
298
299 nsAutoCString urlspec;
300 rv = url->GetSpec(urlspec);
301 if (NS_FAILED(rv)((bool)(__builtin_expect(!!(NS_FAILED_impl(rv)), 0)))) return rv;
302
303 MOZ_LOG(gLog, LogLevel::Error,do { const ::mozilla::LogModule* moz_real_module = gLog; if (
(__builtin_expect(!!(mozilla::detail::log_test(moz_real_module
, LogLevel::Error)), 0))) { mozilla::detail::log_print(moz_real_module
, LogLevel::Error, "prototype: error parsing '%s'", urlspec.get
()); } } while (0)
304 ("prototype: error parsing '%s'", urlspec.get()))do { const ::mozilla::LogModule* moz_real_module = gLog; if (
(__builtin_expect(!!(mozilla::detail::log_test(moz_real_module
, LogLevel::Error)), 0))) { mozilla::detail::log_print(moz_real_module
, LogLevel::Error, "prototype: error parsing '%s'", urlspec.get
()); } } while (0)
;
305 }
306
307 return NS_OK;
308 }
309
310 const nsTArray<RefPtr<nsXULPrototypePI> >& processingInstructions =
311 mCurrentPrototype->GetProcessingInstructions();
312
313 uint32_t total = processingInstructions.Length();
314 for (uint32_t i = 0; i < total; ++i) {
315 rv = CreateAndInsertPI(processingInstructions[i], mDocument,
316 /* aInProlog */ true);
317 if (NS_FAILED(rv)((bool)(__builtin_expect(!!(NS_FAILED_impl(rv)), 0)))) return rv;
318 }
319
320 // Do one-time initialization.
321 RefPtr<Element> root;
322
323 // Add the root element
324 rv = CreateElementFromPrototype(proto, getter_AddRefs(root), nullptr);
325 if (NS_FAILED(rv)((bool)(__builtin_expect(!!(NS_FAILED_impl(rv)), 0)))) return rv;
326
327 ErrorResult error;
328 mDocument->AppendChildTo(root, false, error);
329 if (error.Failed()) {
330 return error.StealNSResult();
331 }
332
333 // TODO(emilio): Should this really notify? We don't notify of appends anyhow,
334 // and we just appended the root so no styles can possibly depend on it.
335 mDocument->UpdateDocumentStates(DocumentState::RTL_LOCALE, true);
336
337 nsContentUtils::AddScriptRunner(
338 MakeAndAddRef<nsDocElementCreatedNotificationRunner>(mDocument));
339
340 // There'd better not be anything on the context stack at this
341 // point! This is the basis case for our "induction" in
342 // ResumeWalk(), below, which'll assume that there's always a
343 // content element on the context stack if we're in the document.
344 NS_ASSERTION(mContextStack.Depth() == 0,do { if (!(mContextStack.Depth() == 0)) { NS_DebugBreak(NS_DEBUG_ASSERTION
, "something's on the context stack already", "mContextStack.Depth() == 0"
, "/root/firefox-clang/dom/prototype/PrototypeDocumentContentSink.cpp"
, 345); MOZ_PretendNoReturn(); } } while (0)
345 "something's on the context stack already")do { if (!(mContextStack.Depth() == 0)) { NS_DebugBreak(NS_DEBUG_ASSERTION
, "something's on the context stack already", "mContextStack.Depth() == 0"
, "/root/firefox-clang/dom/prototype/PrototypeDocumentContentSink.cpp"
, 345); MOZ_PretendNoReturn(); } } while (0)
;
346 if (mContextStack.Depth() != 0) return NS_ERROR_UNEXPECTED;
347
348 rv = mContextStack.Push(proto, root);
349 if (NS_FAILED(rv)((bool)(__builtin_expect(!!(NS_FAILED_impl(rv)), 0)))) return rv;
350
351 return NS_OK;
352}
353
354nsresult PrototypeDocumentContentSink::CreateAndInsertPI(
355 const nsXULPrototypePI* aProtoPI, nsINode* aParent, bool aInProlog) {
356 MOZ_ASSERT(aProtoPI, "null ptr")do { static_assert( mozilla::detail::AssertionConditionType<
decltype(aProtoPI)>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(aProtoPI))), 0))) { do { } while
(false); MOZ_ReportAssertionFailure("aProtoPI" " (" "null ptr"
")", "/root/firefox-clang/dom/prototype/PrototypeDocumentContentSink.cpp"
, 356); AnnotateMozCrashReason("MOZ_ASSERT" "(" "aProtoPI" ") ("
"null ptr" ")"); do { MOZ_CrashSequence(__null, 356); __attribute__
((nomerge)) ::abort(); } while (false); } } while (false)
;
357 MOZ_ASSERT(aParent, "null ptr")do { static_assert( mozilla::detail::AssertionConditionType<
decltype(aParent)>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(aParent))), 0))) { do { } while
(false); MOZ_ReportAssertionFailure("aParent" " (" "null ptr"
")", "/root/firefox-clang/dom/prototype/PrototypeDocumentContentSink.cpp"
, 357); AnnotateMozCrashReason("MOZ_ASSERT" "(" "aParent" ") ("
"null ptr" ")"); do { MOZ_CrashSequence(__null, 357); __attribute__
((nomerge)) ::abort(); } while (false); } } while (false)
;
358
359 RefPtr<ProcessingInstruction> node = NS_NewXMLProcessingInstruction(
360 aParent->NodeInfoManager(), aProtoPI->mTarget, aProtoPI->mData);
361
362 nsresult rv;
363 if (aProtoPI->mTarget.EqualsLiteral("xml-stylesheet")) {
364 MOZ_ASSERT(LinkStyle::FromNode(*node),do { static_assert( mozilla::detail::AssertionConditionType<
decltype(LinkStyle::FromNode(*node))>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(LinkStyle::FromNode(*node)))
), 0))) { do { } while (false); MOZ_ReportAssertionFailure("LinkStyle::FromNode(*node)"
" (" "XML Stylesheet node does not implement LinkStyle!" ")"
, "/root/firefox-clang/dom/prototype/PrototypeDocumentContentSink.cpp"
, 365); AnnotateMozCrashReason("MOZ_ASSERT" "(" "LinkStyle::FromNode(*node)"
") (" "XML Stylesheet node does not implement LinkStyle!" ")"
); do { MOZ_CrashSequence(__null, 365); __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
365 "XML Stylesheet node does not implement LinkStyle!")do { static_assert( mozilla::detail::AssertionConditionType<
decltype(LinkStyle::FromNode(*node))>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(LinkStyle::FromNode(*node)))
), 0))) { do { } while (false); MOZ_ReportAssertionFailure("LinkStyle::FromNode(*node)"
" (" "XML Stylesheet node does not implement LinkStyle!" ")"
, "/root/firefox-clang/dom/prototype/PrototypeDocumentContentSink.cpp"
, 365); AnnotateMozCrashReason("MOZ_ASSERT" "(" "LinkStyle::FromNode(*node)"
") (" "XML Stylesheet node does not implement LinkStyle!" ")"
); do { MOZ_CrashSequence(__null, 365); __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
366 auto* pi = static_cast<XMLStylesheetProcessingInstruction*>(node.get());
367 rv = InsertXMLStylesheetPI(aProtoPI, aParent, pi);
368 } else {
369 // Handles the special <?csp ?> PI, which will be handled before
370 // creating any element with potential inline style or scripts.
371 if (aInProlog && aProtoPI->mTarget.EqualsLiteral("csp")) {
372 CSP_ApplyMetaCSPToDoc(*aParent->OwnerDoc(), aProtoPI->mData);
373 }
374
375 // No special processing, just add the PI to the document.
376 ErrorResult error;
377 aParent->AppendChildTo(node->AsContent(), false, error);
378 rv = error.StealNSResult();
379 }
380
381 return rv;
382}
383
384nsresult PrototypeDocumentContentSink::InsertXMLStylesheetPI(
385 const nsXULPrototypePI* aProtoPI, nsINode* aParent,
386 XMLStylesheetProcessingInstruction* aPINode) {
387 // We want to be notified when the style sheet finishes loading, so
388 // disable style sheet loading for now.
389 aPINode->DisableUpdates();
390 aPINode->OverrideBaseURI(mCurrentPrototype->GetURI());
391
392 ErrorResult rv;
393 aParent->AppendChildTo(aPINode, false, rv);
394 if (rv.Failed()) {
395 return rv.StealNSResult();
396 }
397
398 // load the stylesheet if necessary, passing ourselves as
399 // nsICSSObserver
400 auto result = aPINode->EnableUpdatesAndUpdateStyleSheet(this);
401 if (result.isErr()) {
402 // Ignore errors from UpdateStyleSheet; we don't want failure to
403 // do that to break the XUL document load. But do propagate out
404 // NS_ERROR_OUT_OF_MEMORY.
405 if (result.unwrapErr() == NS_ERROR_OUT_OF_MEMORY) {
406 return result.unwrapErr();
407 }
408 return NS_OK;
409 }
410
411 auto update = result.unwrap();
412 if (update.ShouldBlock()) {
413 ++mPendingSheets;
414 }
415
416 return NS_OK;
417}
418
419void PrototypeDocumentContentSink::CloseElement(Element* aElement) {
420 if (nsIContent::RequiresDoneAddingChildren(
421 aElement->NodeInfo()->NamespaceID(),
422 aElement->NodeInfo()->NameAtom())) {
423 nsAutoScriptBlocker scriptBlocker;
424 aElement->DoneAddingChildren(false);
425 }
426
427 if (auto* linkStyle = LinkStyle::FromNode(*aElement)) {
428 auto result = linkStyle->EnableUpdatesAndUpdateStyleSheet(this);
429 if (result.isOk() && result.unwrap().ShouldBlock()) {
430 ++mPendingSheets;
431 }
432 return;
433 }
434
435 // See bug 370111 and bug 1495946. We don't cache module scripts in the
436 // prototype cache, so we need to do this for the script to be properly
437 // processed.
438 if (aElement->IsHTMLElement(nsGkAtoms::script) ||
439 aElement->IsSVGElement(nsGkAtoms::script)) {
440 nsCOMPtr<nsIScriptElement> sele = do_QueryInterface(aElement);
441 MOZ_ASSERT(sele, "Node didn't QI to script.")do { static_assert( mozilla::detail::AssertionConditionType<
decltype(sele)>::isValid, "invalid assertion condition"); if
((__builtin_expect(!!(!(!!(sele))), 0))) { do { } while (false
); MOZ_ReportAssertionFailure("sele" " (" "Node didn't QI to script."
")", "/root/firefox-clang/dom/prototype/PrototypeDocumentContentSink.cpp"
, 441); AnnotateMozCrashReason("MOZ_ASSERT" "(" "sele" ") (" "Node didn't QI to script."
")"); do { MOZ_CrashSequence(__null, 441); __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
442 if (sele->GetScriptIsModule()) {
443 // https://html.spec.whatwg.org/#parsing-main-incdata
444 // An end tag whose tag name is "script"
445 // - If the active speculative HTML parser is null and the JavaScript
446 // execution context stack is empty, then perform a microtask checkpoint.
447 {
448 nsAutoMicroTask mt;
449 }
450 sele->AttemptToExecute(nullptr /* aParser */);
451 }
452 }
453}
454
455nsresult PrototypeDocumentContentSink::ResumeWalk() {
456 nsresult rv = ResumeWalkInternal();
457 if (NS_FAILED(rv)((bool)(__builtin_expect(!!(NS_FAILED_impl(rv)), 0)))) {
458 nsContentUtils::ReportToConsoleNonLocalized(
459 u"Failed to load document from prototype document."_ns,
460 nsIScriptError::errorFlag, "Prototype Document"_ns, mDocument,
461 SourceLocation{mDocumentURI.get()});
462 }
463 return rv;
464}
465
466nsresult PrototypeDocumentContentSink::ResumeWalkInternal() {
467 MOZ_ASSERT(mStillWalking)do { static_assert( mozilla::detail::AssertionConditionType<
decltype(mStillWalking)>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(mStillWalking))), 0))) { do {
} while (false); MOZ_ReportAssertionFailure("mStillWalking",
"/root/firefox-clang/dom/prototype/PrototypeDocumentContentSink.cpp"
, 467); AnnotateMozCrashReason("MOZ_ASSERT" "(" "mStillWalking"
")"); do { MOZ_CrashSequence(__null, 467); __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
468 // Walk the prototype and build the delegate content model. The
469 // walk is performed in a top-down, left-to-right fashion. That
470 // is, a parent is built before any of its children; a node is
471 // only built after all of its siblings to the left are fully
472 // constructed.
473 //
474 // It is interruptable so that transcluded documents (e.g.,
475 // <html:script src="..." />) can be properly re-loaded if the
476 // cached copy of the document becomes stale.
477 nsresult rv;
478 nsCOMPtr<nsIURI> docURI =
479 mCurrentPrototype ? mCurrentPrototype->GetURI() : nullptr;
480
481 while (true) {
482 // Begin (or resume) walking the current prototype.
483
484 while (mContextStack.Depth() > 0) {
485 // Look at the top of the stack to determine what we're
486 // currently working on.
487 // This will always be a node already constructed and
488 // inserted to the actual document.
489 nsXULPrototypeElement* proto;
490 nsCOMPtr<nsIContent> element;
491 nsCOMPtr<nsIContent> nodeToPushTo;
492 int32_t indx; // all children of proto before indx (not
493 // inclusive) have already been constructed
494 rv = mContextStack.Peek(&proto, getter_AddRefs(element), &indx);
495 if (NS_FAILED(rv)((bool)(__builtin_expect(!!(NS_FAILED_impl(rv)), 0)))) return rv;
496
497 if (indx >= (int32_t)proto->mChildren.Length()) {
498 if (element) {
499 // We've processed all of the prototype's children.
500 CloseElement(element->AsElement());
501 }
502 // Now pop the context stack back up to the parent
503 // element and continue the prototype walk.
504 mContextStack.Pop();
505 continue;
506 }
507
508 nodeToPushTo = element;
509 // For template elements append the content to the template's document
510 // fragment.
511 if (auto* templateElement = HTMLTemplateElement::FromNode(element)) {
512 nodeToPushTo = templateElement->Content();
513 }
514
515 // Grab the next child, and advance the current context stack
516 // to the next sibling to our right.
517 nsXULPrototypeNode* childproto = proto->mChildren[indx];
518 mContextStack.SetTopIndex(++indx);
519
520 switch (childproto->mType) {
521 case nsXULPrototypeNode::eType_Element: {
522 // An 'element', which may contain more content.
523 auto* protoele = static_cast<nsXULPrototypeElement*>(childproto);
524
525 RefPtr<Element> child;
526 MOZ_TRY(CreateElementFromPrototype(protoele, getter_AddRefs(child),__extension__({ auto mozTryVarTempResult = ::mozilla::ToResult
(CreateElementFromPrototype(protoele, getter_AddRefs(child), nodeToPushTo
)); if ((__builtin_expect(!!(mozTryVarTempResult.isErr()), 0)
)) { return mozTryVarTempResult.propagateErr(); } mozTryVarTempResult
.unwrap(); })
527 nodeToPushTo))__extension__({ auto mozTryVarTempResult = ::mozilla::ToResult
(CreateElementFromPrototype(protoele, getter_AddRefs(child), nodeToPushTo
)); if ((__builtin_expect(!!(mozTryVarTempResult.isErr()), 0)
)) { return mozTryVarTempResult.propagateErr(); } mozTryVarTempResult
.unwrap(); })
;
528
529 if (auto* linkStyle = LinkStyle::FromNode(*child)) {
530 linkStyle->DisableUpdates();
531 }
532
533 // ...and append it to the content model.
534 ErrorResult error;
535 nodeToPushTo->AppendChildTo(child, false, error);
536 if (error.Failed()) {
537 return error.StealNSResult();
538 }
539
540 if (nsIContent::RequiresDoneCreatingElement(
541 protoele->mNodeInfo->NamespaceID(),
542 protoele->mNodeInfo->NameAtom())) {
543 child->DoneCreatingElement();
544 }
545
546 // If it has children, push the element onto the context
547 // stack and begin to process them.
548 if (protoele->mChildren.Length() > 0) {
549 rv = mContextStack.Push(protoele, child);
550 if (NS_FAILED(rv)((bool)(__builtin_expect(!!(NS_FAILED_impl(rv)), 0)))) return rv;
551 } else {
552 // If there are no children, close the element immediately.
553 CloseElement(child);
554 }
555 } break;
556
557 case nsXULPrototypeNode::eType_Script: {
558 // A script reference. Execute the script immediately;
559 // this may have side effects in the content model.
560 auto* scriptproto = static_cast<nsXULPrototypeScript*>(childproto);
561 if (scriptproto->mSrcURI) {
562 // A transcluded script reference; this may
563 // "block" our prototype walk if the script isn't
564 // cached, or the cached copy of the script is
565 // stale and must be reloaded.
566 bool blocked;
567 rv = LoadScript(scriptproto, &blocked);
568 // If the script cannot be loaded, just keep going!
569
570 if (NS_SUCCEEDED(rv)((bool)(__builtin_expect(!!(!NS_FAILED_impl(rv)), 1))) && blocked) return NS_OK;
571 } else if (scriptproto->HasStencil()) {
572 // An inline script
573 rv = ExecuteScript(scriptproto);
574 if (NS_FAILED(rv)((bool)(__builtin_expect(!!(NS_FAILED_impl(rv)), 0)))) return rv;
575 }
576 } break;
577
578 case nsXULPrototypeNode::eType_Text: {
579 nsNodeInfoManager* nim = nodeToPushTo->NodeInfo()->NodeInfoManager();
580 // A simple text node.
581 RefPtr<nsTextNode> text = new (nim) nsTextNode(nim);
582
583 auto* textproto = static_cast<nsXULPrototypeText*>(childproto);
584 text->SetText(textproto->mValue, false);
585
586 ErrorResult error;
587 nodeToPushTo->AppendChildTo(text, false, error);
588 if (error.Failed()) {
589 return error.StealNSResult();
590 }
591 } break;
592
593 case nsXULPrototypeNode::eType_PI: {
594 auto* piProto = static_cast<nsXULPrototypePI*>(childproto);
595
596 // <?xml-stylesheet?> and <?csp?> don't have an effect
597 // outside the prolog, issue a warning.
598
599 if (piProto->mTarget.EqualsLiteral("xml-stylesheet") ||
600 piProto->mTarget.EqualsLiteral("csp")) {
601 AutoTArray<nsString, 1> params = {piProto->mTarget};
602
603 nsContentUtils::ReportToConsole(
604 nsIScriptError::warningFlag, "XUL Document"_ns, nullptr,
605 PropertiesFile::XUL_PROPERTIES, "PINotInProlog2", params,
606 SourceLocation(docURI.get()));
607 }
608
609 if (nsIContent* parent = element.get()) {
610 // an inline script could have removed the root element
611 rv = CreateAndInsertPI(piProto, parent, /* aInProlog */ false);
612 NS_ENSURE_SUCCESS(rv, rv)do { nsresult __rv = rv; if (((bool)(__builtin_expect(!!(NS_FAILED_impl
(__rv)), 0)))) { const char* name = mozilla::GetStaticErrorName
(__rv); mozilla::SmprintfPointer msg = mozilla::Smprintf( "NS_ENSURE_SUCCESS(%s, %s) failed with "
"result 0x%" "X" "%s%s%s", "rv", "rv", static_cast<uint32_t
>(__rv), name ? " (" : "", name ? name : "", name ? ")" : ""
); NS_DebugBreak(NS_DEBUG_WARNING, msg.get(), nullptr, "/root/firefox-clang/dom/prototype/PrototypeDocumentContentSink.cpp"
, 612); return rv; } } while (false)
;
613 }
614 } break;
615
616 default:
617 MOZ_ASSERT_UNREACHABLE("Unexpected nsXULPrototypeNode::Type")do { static_assert( mozilla::detail::AssertionConditionType<
decltype(false)>::isValid, "invalid assertion condition");
if ((__builtin_expect(!!(!(!!(false))), 0))) { do { } while (
false); MOZ_ReportAssertionFailure("false" " (" "MOZ_ASSERT_UNREACHABLE: "
"Unexpected nsXULPrototypeNode::Type" ")", "/root/firefox-clang/dom/prototype/PrototypeDocumentContentSink.cpp"
, 617); AnnotateMozCrashReason("MOZ_ASSERT" "(" "false" ") ("
"MOZ_ASSERT_UNREACHABLE: " "Unexpected nsXULPrototypeNode::Type"
")"); do { MOZ_CrashSequence(__null, 617); __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
618 }
619 }
620
621 // Once we get here, the context stack will have been
622 // depleted. That means that the entire prototype has been
623 // walked and content has been constructed.
624 break;
625 }
626
627 mStillWalking = false;
628 return MaybeDoneWalking();
629}
630
631void PrototypeDocumentContentSink::InitialTranslationCompleted() {
632 MaybeDoneWalking();
633}
634
635nsresult PrototypeDocumentContentSink::MaybeDoneWalking() {
636 if (mPendingSheets > 0 || mStillWalking) {
637 return NS_OK;
638 }
639
640 if (mDocument->HasPendingInitialTranslation()) {
641 mDocument->OnParsingCompleted();
642 return NS_OK;
643 }
644
645 return DoneWalking();
646}
647
648nsresult PrototypeDocumentContentSink::DoneWalking() {
649 MOZ_ASSERT(mPendingSheets == 0, "there are sheets to be loaded")do { static_assert( mozilla::detail::AssertionConditionType<
decltype(mPendingSheets == 0)>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(mPendingSheets == 0))), 0)))
{ do { } while (false); MOZ_ReportAssertionFailure("mPendingSheets == 0"
" (" "there are sheets to be loaded" ")", "/root/firefox-clang/dom/prototype/PrototypeDocumentContentSink.cpp"
, 649); AnnotateMozCrashReason("MOZ_ASSERT" "(" "mPendingSheets == 0"
") (" "there are sheets to be loaded" ")"); do { MOZ_CrashSequence
(__null, 649); __attribute__((nomerge)) ::abort(); } while (false
); } } while (false)
;
650 MOZ_ASSERT(!mStillWalking, "walk not done")do { static_assert( mozilla::detail::AssertionConditionType<
decltype(!mStillWalking)>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(!mStillWalking))), 0))) { do
{ } while (false); MOZ_ReportAssertionFailure("!mStillWalking"
" (" "walk not done" ")", "/root/firefox-clang/dom/prototype/PrototypeDocumentContentSink.cpp"
, 650); AnnotateMozCrashReason("MOZ_ASSERT" "(" "!mStillWalking"
") (" "walk not done" ")"); do { MOZ_CrashSequence(__null, 650
); __attribute__((nomerge)) ::abort(); } while (false); } } while
(false)
;
651 MOZ_ASSERT(!mDocument->HasPendingInitialTranslation(), "translation pending")do { static_assert( mozilla::detail::AssertionConditionType<
decltype(!mDocument->HasPendingInitialTranslation())>::
isValid, "invalid assertion condition"); if ((__builtin_expect
(!!(!(!!(!mDocument->HasPendingInitialTranslation()))), 0)
)) { do { } while (false); MOZ_ReportAssertionFailure("!mDocument->HasPendingInitialTranslation()"
" (" "translation pending" ")", "/root/firefox-clang/dom/prototype/PrototypeDocumentContentSink.cpp"
, 651); AnnotateMozCrashReason("MOZ_ASSERT" "(" "!mDocument->HasPendingInitialTranslation()"
") (" "translation pending" ")"); do { MOZ_CrashSequence(__null
, 651); __attribute__((nomerge)) ::abort(); } while (false); }
} while (false)
;
652
653 if (const RefPtr<Document> doc = mDocument) {
654 MOZ_ASSERT(doc->GetReadyStateEnum() == Document::READYSTATE_LOADING,do { static_assert( mozilla::detail::AssertionConditionType<
decltype(doc->GetReadyStateEnum() == Document::READYSTATE_LOADING
)>::isValid, "invalid assertion condition"); if ((__builtin_expect
(!!(!(!!(doc->GetReadyStateEnum() == Document::READYSTATE_LOADING
))), 0))) { do { } while (false); MOZ_ReportAssertionFailure(
"doc->GetReadyStateEnum() == Document::READYSTATE_LOADING"
" (" "Bad readyState" ")", "/root/firefox-clang/dom/prototype/PrototypeDocumentContentSink.cpp"
, 655); AnnotateMozCrashReason("MOZ_ASSERT" "(" "doc->GetReadyStateEnum() == Document::READYSTATE_LOADING"
") (" "Bad readyState" ")"); do { MOZ_CrashSequence(__null, 655
); __attribute__((nomerge)) ::abort(); } while (false); } } while
(false)
655 "Bad readyState")do { static_assert( mozilla::detail::AssertionConditionType<
decltype(doc->GetReadyStateEnum() == Document::READYSTATE_LOADING
)>::isValid, "invalid assertion condition"); if ((__builtin_expect
(!!(!(!!(doc->GetReadyStateEnum() == Document::READYSTATE_LOADING
))), 0))) { do { } while (false); MOZ_ReportAssertionFailure(
"doc->GetReadyStateEnum() == Document::READYSTATE_LOADING"
" (" "Bad readyState" ")", "/root/firefox-clang/dom/prototype/PrototypeDocumentContentSink.cpp"
, 655); AnnotateMozCrashReason("MOZ_ASSERT" "(" "doc->GetReadyStateEnum() == Document::READYSTATE_LOADING"
") (" "Bad readyState" ")"); do { MOZ_CrashSequence(__null, 655
); __attribute__((nomerge)) ::abort(); } while (false); } } while
(false)
;
656 doc->SetReadyStateInternal(Document::READYSTATE_INTERACTIVE);
657 doc->NotifyPossibleTitleChange(false);
658
659 nsContentUtils::DispatchEventOnlyToChrome(doc, doc,
660 u"MozBeforeInitialXULLayout"_ns,
661 CanBubble::eYes, Cancelable::eNo);
662 }
663
664 if (const RefPtr<ScriptLoader> scriptLoader = mScriptLoader) {
665 scriptLoader->ParsingComplete(false);
666 scriptLoader->DeferCheckpointReached();
667 }
668
669 StartLayout();
670
671 if (mDocumentURI->SchemeIs("chrome") &&
672 nsXULPrototypeCache::GetInstance()->IsEnabled()) {
673 bool isCachedOnDisk;
674 nsXULPrototypeCache::GetInstance()->HasPrototype(mDocumentURI,
675 &isCachedOnDisk);
676 if (!isCachedOnDisk) {
677 if (!mDocument->GetDocumentElement() ||
678 (mDocument->GetDocumentElement()->NodeInfo()->Equals(
679 nsGkAtoms::parsererror) &&
680 mDocument->GetDocumentElement()->NodeInfo()->NamespaceEquals(
681 nsDependentAtomString(nsGkAtoms::nsuri_parsererror)))) {
682 nsXULPrototypeCache::GetInstance()->RemovePrototype(mDocumentURI);
683 } else {
684 nsXULPrototypeCache::GetInstance()->WritePrototype(mCurrentPrototype);
685 }
686 }
687 }
688
689 mDocument->SetDelayFrameLoaderInitialization(false);
690 RefPtr<Document> doc = mDocument;
691 doc->MaybeInitializeFinalizeFrameLoaders();
692
693 // If the document we are loading has a reference or it is a
694 // frameset document, disable the scroll bars on the views.
695
696 doc->SetScrollToRef(mDocument->GetDocumentURI());
697
698 doc->EndLoad(/* aFireDOMContentLoadedSync = */ true);
699
700 return NS_OK;
701}
702
703void PrototypeDocumentContentSink::StartLayout() {
704 AUTO_PROFILER_LABEL_DYNAMIC_NSCSTRING(mozilla::Maybe<nsAutoCString> autoCStr; mozilla::Maybe<
mozilla::AutoProfilerLabel> raiiObjectNsCString; if (profiler_is_active
()) { autoCStr.emplace(mDocumentURI->GetSpecOrDefault()); raiiObjectNsCString
.emplace("PrototypeDocumentContentSink::StartLayout", autoCStr
->get(), JS::ProfilingCategoryPair::LAYOUT); }
705 "PrototypeDocumentContentSink::StartLayout", LAYOUT,mozilla::Maybe<nsAutoCString> autoCStr; mozilla::Maybe<
mozilla::AutoProfilerLabel> raiiObjectNsCString; if (profiler_is_active
()) { autoCStr.emplace(mDocumentURI->GetSpecOrDefault()); raiiObjectNsCString
.emplace("PrototypeDocumentContentSink::StartLayout", autoCStr
->get(), JS::ProfilingCategoryPair::LAYOUT); }
706 mDocumentURI->GetSpecOrDefault())mozilla::Maybe<nsAutoCString> autoCStr; mozilla::Maybe<
mozilla::AutoProfilerLabel> raiiObjectNsCString; if (profiler_is_active
()) { autoCStr.emplace(mDocumentURI->GetSpecOrDefault()); raiiObjectNsCString
.emplace("PrototypeDocumentContentSink::StartLayout", autoCStr
->get(), JS::ProfilingCategoryPair::LAYOUT); }
;
707 mDocument->SetMayStartLayout(true);
708 RefPtr<PresShell> presShell = mDocument->GetPresShell();
709 if (presShell && !presShell->DidInitialize()) {
710 nsresult rv = presShell->Initialize();
711 if (NS_FAILED(rv)((bool)(__builtin_expect(!!(NS_FAILED_impl(rv)), 0)))) {
712 return;
713 }
714 }
715}
716
717NS_IMETHODIMPnsresult
718PrototypeDocumentContentSink::StyleSheetLoaded(StyleSheet* aSheet,
719 bool aWasDeferred,
720 nsresult aStatus) {
721 if (!aWasDeferred) {
722 // Don't care about when alternate sheets finish loading
723 MOZ_ASSERT(mPendingSheets > 0, "Unexpected StyleSheetLoaded notification")do { static_assert( mozilla::detail::AssertionConditionType<
decltype(mPendingSheets > 0)>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(mPendingSheets > 0))), 0)
)) { do { } while (false); MOZ_ReportAssertionFailure("mPendingSheets > 0"
" (" "Unexpected StyleSheetLoaded notification" ")", "/root/firefox-clang/dom/prototype/PrototypeDocumentContentSink.cpp"
, 723); AnnotateMozCrashReason("MOZ_ASSERT" "(" "mPendingSheets > 0"
") (" "Unexpected StyleSheetLoaded notification" ")"); do { MOZ_CrashSequence
(__null, 723); __attribute__((nomerge)) ::abort(); } while (false
); } } while (false)
;
724
725 --mPendingSheets;
726
727 return MaybeDoneWalking();
728 }
729
730 return NS_OK;
731}
732
733nsresult PrototypeDocumentContentSink::LoadScript(
734 nsXULPrototypeScript* aScriptProto, bool* aBlock) {
735 // Load a transcluded script
736 nsresult rv;
737
738 bool isChromeDoc = mDocumentURI->SchemeIs("chrome");
739
740 if (isChromeDoc && aScriptProto->HasStencil()) {
741 rv = ExecuteScript(aScriptProto);
742
743 // Ignore return value from execution, and don't block
744 *aBlock = false;
745 return NS_OK;
746 }
747
748 // Try the XUL script cache, in case two XUL documents source the same
749 // .js file (e.g., strres.js from navigator.xul and utilityOverlay.xul).
750 // XXXbe the cache relies on aScriptProto's GC root!
751 bool useXULCache = nsXULPrototypeCache::GetInstance()->IsEnabled();
752
753 if (isChromeDoc && useXULCache) {
754 RefPtr<JS::Stencil> newStencil =
755 nsXULPrototypeCache::GetInstance()->GetStencil(aScriptProto->mSrcURI);
756 if (newStencil) {
757 // The script language for a proto must remain constant - we
758 // can't just change it for this unexpected language.
759 aScriptProto->Set(newStencil);
760 }
761
762 if (aScriptProto->HasStencil()) {
763 rv = ExecuteScript(aScriptProto);
Value stored to 'rv' is never read
764
765 // Ignore return value from execution, and don't block
766 *aBlock = false;
767 return NS_OK;
768 }
769 }
770
771 // Release stencil from FastLoad since we decided against using them
772 aScriptProto->Set(nullptr);
773
774 // Set the current script prototype so that OnStreamComplete can report
775 // the right file if there are errors in the script.
776 NS_ASSERTION(!mCurrentScriptProto,do { if (!(!mCurrentScriptProto)) { NS_DebugBreak(NS_DEBUG_ASSERTION
, "still loading a script when starting another load?", "!mCurrentScriptProto"
, "/root/firefox-clang/dom/prototype/PrototypeDocumentContentSink.cpp"
, 777); MOZ_PretendNoReturn(); } } while (0)
777 "still loading a script when starting another load?")do { if (!(!mCurrentScriptProto)) { NS_DebugBreak(NS_DEBUG_ASSERTION
, "still loading a script when starting another load?", "!mCurrentScriptProto"
, "/root/firefox-clang/dom/prototype/PrototypeDocumentContentSink.cpp"
, 777); MOZ_PretendNoReturn(); } } while (0)
;
778 mCurrentScriptProto = aScriptProto;
779
780 if (isChromeDoc && aScriptProto->mSrcLoading) {
781 // Another document load has started, which is still in progress.
782 // Remember to ResumeWalk this document when the load completes.
783 mNextSrcLoadWaiter = aScriptProto->mSrcLoadWaiters;
784 aScriptProto->mSrcLoadWaiters = this;
785 NS_ADDREF_THIS()AddRef();
786 } else {
787 nsCOMPtr<nsILoadGroup> group =
788 mDocument
789 ->GetDocumentLoadGroup(); // found in
790 // mozilla::dom::Document::SetScriptGlobalObject
791
792 // Note: the loader will keep itself alive while it's loading.
793 nsCOMPtr<nsIStreamLoader> loader;
794 rv = NS_NewStreamLoader(
795 getter_AddRefs(loader), aScriptProto->mSrcURI,
796 this, // aObserver
797 mDocument, // aRequestingContext
798 nsILoadInfo::SEC_REQUIRE_SAME_ORIGIN_INHERITS_SEC_CONTEXT,
799 nsIContentPolicy::TYPE_INTERNAL_SCRIPT, group);
800
801 if (NS_FAILED(rv)((bool)(__builtin_expect(!!(NS_FAILED_impl(rv)), 0)))) {
802 mCurrentScriptProto = nullptr;
803 return rv;
804 }
805
806 aScriptProto->mSrcLoading = true;
807 }
808
809 // Block until OnStreamComplete resumes us.
810 *aBlock = true;
811 return NS_OK;
812}
813
814NS_IMETHODIMPnsresult
815PrototypeDocumentContentSink::OnStreamComplete(nsIStreamLoader* aLoader,
816 nsISupports* context,
817 nsresult aStatus,
818 uint32_t stringLen,
819 const uint8_t* string) {
820 nsCOMPtr<nsIRequest> request;
821 aLoader->GetRequest(getter_AddRefs(request));
822 nsCOMPtr<nsIChannel> channel = do_QueryInterface(request);
823
824#ifdef DEBUG1
825 // print a load error on bad status
826 if (NS_FAILED(aStatus)((bool)(__builtin_expect(!!(NS_FAILED_impl(aStatus)), 0)))) {
827 if (channel) {
828 nsCOMPtr<nsIURI> uri;
829 channel->GetURI(getter_AddRefs(uri));
830 if (uri) {
831 printf("Failed to load %s\n", uri->GetSpecOrDefault().get());
832 }
833 }
834 }
835#endif
836
837 // This is the completion routine that will be called when a
838 // transcluded script completes. Compile and execute the script
839 // if the load was successful, then continue building content
840 // from the prototype.
841 nsresult rv = aStatus;
842
843 NS_ASSERTION(mCurrentScriptProto && mCurrentScriptProto->mSrcLoading,do { if (!(mCurrentScriptProto && mCurrentScriptProto
->mSrcLoading)) { NS_DebugBreak(NS_DEBUG_ASSERTION, "script source not loading on unichar stream complete?"
, "mCurrentScriptProto && mCurrentScriptProto->mSrcLoading"
, "/root/firefox-clang/dom/prototype/PrototypeDocumentContentSink.cpp"
, 844); MOZ_PretendNoReturn(); } } while (0)
844 "script source not loading on unichar stream complete?")do { if (!(mCurrentScriptProto && mCurrentScriptProto
->mSrcLoading)) { NS_DebugBreak(NS_DEBUG_ASSERTION, "script source not loading on unichar stream complete?"
, "mCurrentScriptProto && mCurrentScriptProto->mSrcLoading"
, "/root/firefox-clang/dom/prototype/PrototypeDocumentContentSink.cpp"
, 844); MOZ_PretendNoReturn(); } } while (0)
;
845 if (!mCurrentScriptProto) {
846 // XXX Wallpaper for bug 270042
847 return NS_OK;
848 }
849
850 if (NS_SUCCEEDED(aStatus)((bool)(__builtin_expect(!!(!NS_FAILED_impl(aStatus)), 1)))) {
851 // If the including document is a FastLoad document, and we're
852 // compiling an out-of-line script (one with src=...), then we must
853 // be writing a new FastLoad file. If we were reading this script
854 // from the FastLoad file, XULContentSinkImpl::OpenScript (over in
855 // nsXULContentSink.cpp) would have already deserialized a non-null
856 // script->mStencil, causing control flow at the top of LoadScript
857 // not to reach here.
858 nsCOMPtr<nsIURI> uri = mCurrentScriptProto->mSrcURI;
859
860 // XXX should also check nsIHttpChannel::requestSucceeded
861
862 MOZ_ASSERT(!mOffThreadCompiling,do { static_assert( mozilla::detail::AssertionConditionType<
decltype(!mOffThreadCompiling)>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(!mOffThreadCompiling))), 0))
) { do { } while (false); MOZ_ReportAssertionFailure("!mOffThreadCompiling"
" (" "PrototypeDocument can't load multiple scripts at once"
")", "/root/firefox-clang/dom/prototype/PrototypeDocumentContentSink.cpp"
, 863); AnnotateMozCrashReason("MOZ_ASSERT" "(" "!mOffThreadCompiling"
") (" "PrototypeDocument can't load multiple scripts at once"
")"); do { MOZ_CrashSequence(__null, 863); __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
863 "PrototypeDocument can't load multiple scripts at once")do { static_assert( mozilla::detail::AssertionConditionType<
decltype(!mOffThreadCompiling)>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(!mOffThreadCompiling))), 0))
) { do { } while (false); MOZ_ReportAssertionFailure("!mOffThreadCompiling"
" (" "PrototypeDocument can't load multiple scripts at once"
")", "/root/firefox-clang/dom/prototype/PrototypeDocumentContentSink.cpp"
, 863); AnnotateMozCrashReason("MOZ_ASSERT" "(" "!mOffThreadCompiling"
") (" "PrototypeDocument can't load multiple scripts at once"
")"); do { MOZ_CrashSequence(__null, 863); __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
864
865 UniquePtr<Utf8Unit[], JS::FreePolicy> units;
866 size_t unitsLength = 0;
867
868 rv = ScriptLoader::ConvertToUTF8(channel, string, stringLen, u""_ns,
869 mDocument, units, unitsLength);
870 if (NS_SUCCEEDED(rv)((bool)(__builtin_expect(!!(!NS_FAILED_impl(rv)), 1)))) {
871 rv = mCurrentScriptProto->CompileMaybeOffThread(
872 std::move(units), unitsLength, uri, 1, mDocument, this);
873 if (NS_SUCCEEDED(rv)((bool)(__builtin_expect(!!(!NS_FAILED_impl(rv)), 1))) && !mCurrentScriptProto->HasStencil()) {
874 mOffThreadCompiling = true;
875 mDocument->BlockOnload();
876 return NS_OK;
877 }
878 }
879 }
880
881 return OnScriptCompileComplete(mCurrentScriptProto->GetStencil(), rv);
882}
883
884NS_IMETHODIMPnsresult
885PrototypeDocumentContentSink::OnScriptCompileComplete(JS::Stencil* aStencil,
886 nsresult aStatus) {
887 // The mCurrentScriptProto may have been cleared out by another
888 // PrototypeDocumentContentSink.
889 if (!mCurrentScriptProto) {
890 return NS_OK;
891 }
892
893 // When compiling off thread the script will not have been attached to the
894 // script proto yet.
895 if (aStencil && !mCurrentScriptProto->HasStencil()) {
896 mCurrentScriptProto->Set(aStencil);
897 }
898
899 // Allow load events to be fired once off thread compilation finishes.
900 if (mOffThreadCompiling) {
901 mOffThreadCompiling = false;
902 mDocument->UnblockOnload(false);
903 }
904
905 // Clear mCurrentScriptProto now, but save it first for use below in
906 // the execute code, and in the while loop that resumes walks of other
907 // documents that raced to load this script.
908 nsXULPrototypeScript* scriptProto = mCurrentScriptProto;
909 mCurrentScriptProto = nullptr;
910
911 // Clear the prototype's loading flag before executing the script or
912 // resuming document walks, in case any of those control flows starts a
913 // new script load.
914 scriptProto->mSrcLoading = false;
915
916 nsresult rv = aStatus;
917 if (NS_SUCCEEDED(rv)((bool)(__builtin_expect(!!(!NS_FAILED_impl(rv)), 1)))) {
918 rv = ExecuteScript(scriptProto);
919
920 // If the XUL cache is enabled, save the script object there in
921 // case different XUL documents source the same script.
922 //
923 // But don't save the script in the cache unless the master XUL
924 // document URL is a chrome: URL. It is valid for a URL such as
925 // about:config to translate into a master document URL, whose
926 // prototype document nodes -- including prototype scripts that
927 // hold GC roots protecting their mJSObject pointers -- are not
928 // cached in the XUL prototype cache. See StartDocumentLoad,
929 // the fillXULCache logic.
930 //
931 // A document such as about:config is free to load a script via
932 // a URL such as chrome://global/content/config.js, and we must
933 // not cache that script object without a prototype cache entry
934 // containing a companion nsXULPrototypeScript node that owns a
935 // GC root protecting the script object. Otherwise, the script
936 // cache entry will dangle once the uncached prototype document
937 // is released when its owning document is unloaded.
938 //
939 // (See http://bugzilla.mozilla.org/show_bug.cgi?id=98207 for
940 // the true crime story.)
941 bool useXULCache = nsXULPrototypeCache::GetInstance()->IsEnabled();
942
943 if (useXULCache && mDocumentURI->SchemeIs("chrome") &&
944 scriptProto->HasStencil()) {
945 nsXULPrototypeCache::GetInstance()->PutStencil(scriptProto->mSrcURI,
946 scriptProto->GetStencil());
947 }
948 // ignore any evaluation errors
949 }
950
951 rv = ResumeWalk();
952
953 // Load a pointer to the prototype-script's list of documents who
954 // raced to load the same script
955 PrototypeDocumentContentSink** docp = &scriptProto->mSrcLoadWaiters;
956
957 // Resume walking other documents that waited for this one's load, first
958 // executing the script we just compiled, in each doc's script context
959 PrototypeDocumentContentSink* doc;
960 while ((doc = *docp) != nullptr) {
961 NS_ASSERTION(doc->mCurrentScriptProto == scriptProto,do { if (!(doc->mCurrentScriptProto == scriptProto)) { NS_DebugBreak
(NS_DEBUG_ASSERTION, "waiting for wrong script to load?", "doc->mCurrentScriptProto == scriptProto"
, "/root/firefox-clang/dom/prototype/PrototypeDocumentContentSink.cpp"
, 962); MOZ_PretendNoReturn(); } } while (0)
962 "waiting for wrong script to load?")do { if (!(doc->mCurrentScriptProto == scriptProto)) { NS_DebugBreak
(NS_DEBUG_ASSERTION, "waiting for wrong script to load?", "doc->mCurrentScriptProto == scriptProto"
, "/root/firefox-clang/dom/prototype/PrototypeDocumentContentSink.cpp"
, 962); MOZ_PretendNoReturn(); } } while (0)
;
963 doc->mCurrentScriptProto = nullptr;
964
965 // Unlink doc from scriptProto's list before executing and resuming
966 *docp = doc->mNextSrcLoadWaiter;
967 doc->mNextSrcLoadWaiter = nullptr;
968
969 if (aStatus == NS_BINDING_ABORTED && !scriptProto->HasStencil()) {
970 // If the previous doc load was aborted, we want to try loading
971 // again for the next doc. Otherwise, one abort would lead to all
972 // subsequent waiting docs to abort as well.
973 bool block = false;
974 doc->LoadScript(scriptProto, &block);
975 NS_RELEASE(doc)do { (doc)->Release(); (doc) = 0; } while (0);
976 return rv;
977 }
978
979 // Execute only if we loaded and compiled successfully, then resume
980 if (NS_SUCCEEDED(aStatus)((bool)(__builtin_expect(!!(!NS_FAILED_impl(aStatus)), 1))) && scriptProto->HasStencil()) {
981 doc->ExecuteScript(scriptProto);
982 }
983 doc->ResumeWalk();
984 NS_RELEASE(doc)do { (doc)->Release(); (doc) = 0; } while (0);
985 }
986
987 return rv;
988}
989
990nsresult PrototypeDocumentContentSink::ExecuteScript(
991 nsXULPrototypeScript* aScript) {
992 MOZ_ASSERT(aScript != nullptr, "null ptr")do { static_assert( mozilla::detail::AssertionConditionType<
decltype(aScript != nullptr)>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(aScript != nullptr))), 0))) {
do { } while (false); MOZ_ReportAssertionFailure("aScript != nullptr"
" (" "null ptr" ")", "/root/firefox-clang/dom/prototype/PrototypeDocumentContentSink.cpp"
, 992); AnnotateMozCrashReason("MOZ_ASSERT" "(" "aScript != nullptr"
") (" "null ptr" ")"); do { MOZ_CrashSequence(__null, 992); __attribute__
((nomerge)) ::abort(); } while (false); } } while (false)
;
993 NS_ENSURE_TRUE(aScript, NS_ERROR_NULL_POINTER)do { if ((__builtin_expect(!!(!(aScript)), 0))) { NS_DebugBreak
(NS_DEBUG_WARNING, "NS_ENSURE_TRUE(" "aScript" ") failed", nullptr
, "/root/firefox-clang/dom/prototype/PrototypeDocumentContentSink.cpp"
, 993); return NS_ERROR_NULL_POINTER; } } while (false)
;
994
995 nsIScriptGlobalObject* scriptGlobalObject;
996 bool aHasHadScriptHandlingObject;
997 scriptGlobalObject =
998 mDocument->GetScriptHandlingObject(aHasHadScriptHandlingObject);
999
1000 NS_ENSURE_TRUE(scriptGlobalObject, NS_ERROR_NOT_INITIALIZED)do { if ((__builtin_expect(!!(!(scriptGlobalObject)), 0))) { NS_DebugBreak
(NS_DEBUG_WARNING, "NS_ENSURE_TRUE(" "scriptGlobalObject" ") failed"
, nullptr, "/root/firefox-clang/dom/prototype/PrototypeDocumentContentSink.cpp"
, 1000); return NS_ERROR_NOT_INITIALIZED; } } while (false)
;
1001
1002 nsresult rv;
1003 rv = scriptGlobalObject->EnsureScriptEnvironment();
1004 NS_ENSURE_SUCCESS(rv, rv)do { nsresult __rv = rv; if (((bool)(__builtin_expect(!!(NS_FAILED_impl
(__rv)), 0)))) { const char* name = mozilla::GetStaticErrorName
(__rv); mozilla::SmprintfPointer msg = mozilla::Smprintf( "NS_ENSURE_SUCCESS(%s, %s) failed with "
"result 0x%" "X" "%s%s%s", "rv", "rv", static_cast<uint32_t
>(__rv), name ? " (" : "", name ? name : "", name ? ")" : ""
); NS_DebugBreak(NS_DEBUG_WARNING, msg.get(), nullptr, "/root/firefox-clang/dom/prototype/PrototypeDocumentContentSink.cpp"
, 1004); return rv; } } while (false)
;
1005
1006 // Execute the precompiled script with the given version
1007 nsAutoMicroTask mt;
1008
1009 // We're about to run script via JS_ExecuteScript, so we need an
1010 // AutoEntryScript. This is Gecko specific and not in any spec.
1011 AutoEntryScript aes(scriptGlobalObject, "precompiled XUL <script> element");
1012 JSContext* cx = aes.cx();
1013
1014 JS::Rooted<JSScript*> scriptObject(cx);
1015 rv = aScript->InstantiateScript(cx, &scriptObject);
1016 NS_ENSURE_SUCCESS(rv, rv)do { nsresult __rv = rv; if (((bool)(__builtin_expect(!!(NS_FAILED_impl
(__rv)), 0)))) { const char* name = mozilla::GetStaticErrorName
(__rv); mozilla::SmprintfPointer msg = mozilla::Smprintf( "NS_ENSURE_SUCCESS(%s, %s) failed with "
"result 0x%" "X" "%s%s%s", "rv", "rv", static_cast<uint32_t
>(__rv), name ? " (" : "", name ? name : "", name ? ")" : ""
); NS_DebugBreak(NS_DEBUG_WARNING, msg.get(), nullptr, "/root/firefox-clang/dom/prototype/PrototypeDocumentContentSink.cpp"
, 1016); return rv; } } while (false)
;
1017
1018 JS::Rooted<JSObject*> global(cx, JS::CurrentGlobalOrNull(cx));
1019 NS_ENSURE_TRUE(xpc::Scriptability::Get(global).Allowed(), NS_OK)do { if ((__builtin_expect(!!(!(xpc::Scriptability::Get(global
).Allowed())), 0))) { NS_DebugBreak(NS_DEBUG_WARNING, "NS_ENSURE_TRUE("
"xpc::Scriptability::Get(global).Allowed()" ") failed", nullptr
, "/root/firefox-clang/dom/prototype/PrototypeDocumentContentSink.cpp"
, 1019); return NS_OK; } } while (false)
;
1020
1021 if (!aScript->mOutOfLine) {
1022 // Check if CSP allows loading of inline scripts.
1023 if (nsCOMPtr<nsIContentSecurityPolicy> csp =
1024 PolicyContainer::GetCSP(mDocument->GetPolicyContainer())) {
1025 nsAutoJSString content;
1026 JS::Rooted<JSString*> decompiled(cx,
1027 JS_DecompileScript(cx, scriptObject));
1028 if (NS_WARN_IF(!decompiled || !content.init(cx, decompiled))NS_warn_if_impl(!decompiled || !content.init(cx, decompiled),
"!decompiled || !content.init(cx, decompiled)", "/root/firefox-clang/dom/prototype/PrototypeDocumentContentSink.cpp"
, 1028)
) {
1029 JS_ClearPendingException(cx);
1030 }
1031
1032 bool allowInlineScript = false;
1033 rv = csp->GetAllowsInline(
1034 nsIContentSecurityPolicy::SCRIPT_SRC_ELEM_DIRECTIVE,
1035 /* aHasUnsafeHash */ false, /* aNonce */ u""_ns,
1036 /* aParserCreated */ true,
1037 /* aTriggeringElement */ nullptr,
1038 /* nsICSPEventListener */ nullptr,
1039 /* aContentOfPseudoScript */ content, aScript->mLineNo,
1040 /* aColumnNumber */ 0, &allowInlineScript);
1041 if (NS_FAILED(rv)((bool)(__builtin_expect(!!(NS_FAILED_impl(rv)), 0))) || !allowInlineScript) {
1042 return NS_OK;
1043 }
1044 }
1045 }
1046
1047 // On failure, ~AutoScriptEntry will handle exceptions, so
1048 // there is no need to manually check the return value.
1049 JS::Rooted<JS::Value> rval(cx);
1050 (void)JS_ExecuteScript(cx, scriptObject, &rval);
1051
1052 return NS_OK;
1053}
1054
1055nsresult PrototypeDocumentContentSink::CreateElementFromPrototype(
1056 nsXULPrototypeElement* aPrototype, Element** aResult, nsIContent* aParent) {
1057 // Create a content model element from a prototype element.
1058 MOZ_ASSERT(aPrototype, "null ptr")do { static_assert( mozilla::detail::AssertionConditionType<
decltype(aPrototype)>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(aPrototype))), 0))) { do { }
while (false); MOZ_ReportAssertionFailure("aPrototype" " (" "null ptr"
")", "/root/firefox-clang/dom/prototype/PrototypeDocumentContentSink.cpp"
, 1058); AnnotateMozCrashReason("MOZ_ASSERT" "(" "aPrototype"
") (" "null ptr" ")"); do { MOZ_CrashSequence(__null, 1058);
__attribute__((nomerge)) ::abort(); } while (false); } } while
(false)
;
1059 if (!aPrototype) return NS_ERROR_NULL_POINTER;
1060
1061 *aResult = nullptr;
1062 nsresult rv = NS_OK;
1063
1064 if (MOZ_LOG_TEST(gLog, LogLevel::Debug)(__builtin_expect(!!(mozilla::detail::log_test(gLog, LogLevel
::Debug)), 0))
) {
1065 MOZ_LOG(do { const ::mozilla::LogModule* moz_real_module = gLog; if (
(__builtin_expect(!!(mozilla::detail::log_test(moz_real_module
, LogLevel::Debug)), 0))) { mozilla::detail::log_print(moz_real_module
, LogLevel::Debug, "prototype: creating <%s> from prototype"
, NS_ConvertUTF16toUTF8(aPrototype->mNodeInfo->QualifiedName
()).get()); } } while (0)
1066 gLog, LogLevel::Debug,do { const ::mozilla::LogModule* moz_real_module = gLog; if (
(__builtin_expect(!!(mozilla::detail::log_test(moz_real_module
, LogLevel::Debug)), 0))) { mozilla::detail::log_print(moz_real_module
, LogLevel::Debug, "prototype: creating <%s> from prototype"
, NS_ConvertUTF16toUTF8(aPrototype->mNodeInfo->QualifiedName
()).get()); } } while (0)
1067 ("prototype: creating <%s> from prototype",do { const ::mozilla::LogModule* moz_real_module = gLog; if (
(__builtin_expect(!!(mozilla::detail::log_test(moz_real_module
, LogLevel::Debug)), 0))) { mozilla::detail::log_print(moz_real_module
, LogLevel::Debug, "prototype: creating <%s> from prototype"
, NS_ConvertUTF16toUTF8(aPrototype->mNodeInfo->QualifiedName
()).get()); } } while (0)
1068 NS_ConvertUTF16toUTF8(aPrototype->mNodeInfo->QualifiedName()).get()))do { const ::mozilla::LogModule* moz_real_module = gLog; if (
(__builtin_expect(!!(mozilla::detail::log_test(moz_real_module
, LogLevel::Debug)), 0))) { mozilla::detail::log_print(moz_real_module
, LogLevel::Debug, "prototype: creating <%s> from prototype"
, NS_ConvertUTF16toUTF8(aPrototype->mNodeInfo->QualifiedName
()).get()); } } while (0)
;
1069 }
1070
1071 RefPtr<Element> result;
1072
1073 Document* doc = aParent ? aParent->OwnerDoc() : mDocument.get();
1074 if (aPrototype->mNodeInfo->NamespaceEquals(kNameSpaceID_XUL8)) {
1075 const bool isRoot = !aParent;
1076 // If it's a XUL element, it'll be lightweight until somebody
1077 // monkeys with it.
1078 result = nsXULElement::CreateFromPrototype(aPrototype, doc, isRoot);
1079 if (!result) {
1080 return NS_ERROR_OUT_OF_MEMORY;
1081 }
1082 } else {
1083 // If it's not a XUL element, it's gonna be heavyweight no matter
1084 // what. So we need to copy everything out of the prototype
1085 // into the element. Get a nodeinfo from our nodeinfo manager
1086 // for this node.
1087 RefPtr<NodeInfo> newNodeInfo = doc->NodeInfoManager()->GetNodeInfo(
1088 aPrototype->mNodeInfo->NameAtom(),
1089 aPrototype->mNodeInfo->GetPrefixAtom(),
1090 aPrototype->mNodeInfo->NamespaceID(), nsINode::ELEMENT_NODE);
1091 if (!newNodeInfo) {
1092 return NS_ERROR_OUT_OF_MEMORY;
1093 }
1094 const bool isScript =
1095 newNodeInfo->Equals(nsGkAtoms::script, kNameSpaceID_XHTML3) ||
1096 newNodeInfo->Equals(nsGkAtoms::script, kNameSpaceID_SVG9);
1097 if (aPrototype->mIsAtom &&
1098 newNodeInfo->NamespaceID() == kNameSpaceID_XHTML3) {
1099 rv = NS_NewHTMLElement(getter_AddRefs(result), newNodeInfo.forget(),
1100 FROM_PARSER_NETWORK, aPrototype->mIsAtom);
1101 } else {
1102 rv = NS_NewElement(getter_AddRefs(result), newNodeInfo.forget(),
1103 FROM_PARSER_NETWORK);
1104 }
1105 if (NS_FAILED(rv)((bool)(__builtin_expect(!!(NS_FAILED_impl(rv)), 0)))) return rv;
1106
1107 rv = AddAttributes(aPrototype, result);
1108 if (NS_FAILED(rv)((bool)(__builtin_expect(!!(NS_FAILED_impl(rv)), 0)))) return rv;
1109
1110 if (isScript) {
1111 nsCOMPtr<nsIScriptElement> sele = do_QueryInterface(result);
1112 MOZ_ASSERT(sele, "Node didn't QI to script.")do { static_assert( mozilla::detail::AssertionConditionType<
decltype(sele)>::isValid, "invalid assertion condition"); if
((__builtin_expect(!!(!(!!(sele))), 0))) { do { } while (false
); MOZ_ReportAssertionFailure("sele" " (" "Node didn't QI to script."
")", "/root/firefox-clang/dom/prototype/PrototypeDocumentContentSink.cpp"
, 1112); AnnotateMozCrashReason("MOZ_ASSERT" "(" "sele" ") ("
"Node didn't QI to script." ")"); do { MOZ_CrashSequence(__null
, 1112); __attribute__((nomerge)) ::abort(); } while (false);
} } while (false)
;
1113 sele->FreezeExecutionAttrs(doc);
1114 }
1115 }
1116
1117 // FIXME(bug 1627474): Is this right if this is inside an <html:template>?
1118 if (result->HasAttr(nsGkAtoms::datal10nid)) {
1119 mDocument->mL10nProtoElements.InsertOrUpdate(result, RefPtr{aPrototype});
1120 result->SetElementCreatedFromPrototypeAndHasUnmodifiedL10n();
1121 }
1122 result.forget(aResult);
1123 return NS_OK;
1124}
1125
1126nsresult PrototypeDocumentContentSink::AddAttributes(
1127 nsXULPrototypeElement* aPrototype, Element* aElement) {
1128 nsresult rv;
1129
1130 for (size_t i = 0; i < aPrototype->mAttributes.Length(); ++i) {
1131 nsXULPrototypeAttribute* protoattr = &(aPrototype->mAttributes[i]);
1132 nsAutoString valueStr;
1133 protoattr->mValue.ToString(valueStr);
1134
1135 rv = aElement->SetAttr(protoattr->mName.NamespaceID(),
1136 protoattr->mName.LocalName(),
1137 protoattr->mName.GetPrefix(), valueStr, false);
1138 if (NS_FAILED(rv)((bool)(__builtin_expect(!!(NS_FAILED_impl(rv)), 0)))) return rv;
1139 }
1140
1141 return NS_OK;
1142}
1143
1144} // namespace mozilla::dom