From 0113b2715df393afaa761bf82cbc4f5182d39dac Mon Sep 17 00:00:00 2001 From: Moonchild Date: Wed, 2 Apr 2025 12:50:14 +0200 Subject: [PATCH] [DOM] Check state before compiling/transforming. --- dom/webidl/XSLTProcessor.webidl | 2 + dom/xslt/xslt/txMozillaXSLTProcessor.cpp | 54 ++++++++++++++++++++++-- dom/xslt/xslt/txMozillaXSLTProcessor.h | 21 +++++++-- 3 files changed, 70 insertions(+), 7 deletions(-) diff --git a/dom/webidl/XSLTProcessor.webidl b/dom/webidl/XSLTProcessor.webidl index 276e1b3fa3..d2eccca036 100644 --- a/dom/webidl/XSLTProcessor.webidl +++ b/dom/webidl/XSLTProcessor.webidl @@ -85,11 +85,13 @@ interface XSLTProcessor { * the processor use the default-value for all parameters as specified in * the stylesheet. */ + [Throws] void clearParameters(); /** * Remove all parameters and stylesheets from this nsIXSLTProcessor. */ + [Throws] void reset(); /** diff --git a/dom/xslt/xslt/txMozillaXSLTProcessor.cpp b/dom/xslt/xslt/txMozillaXSLTProcessor.cpp index 867bc53392..46ca2a279b 100644 --- a/dom/xslt/xslt/txMozillaXSLTProcessor.cpp +++ b/dom/xslt/xslt/txMozillaXSLTProcessor.cpp @@ -7,6 +7,7 @@ #include "nsContentCID.h" #include "nsError.h" #include "nsIChannel.h" +#include "mozilla/AutoRestore.h" #include "mozilla/dom/Element.h" #include "nsIDOMElement.h" #include "nsIDOMText.h" @@ -570,6 +571,8 @@ public: NS_IMETHOD Run() override { + MOZ_RELEASE_ASSERT(mProcessor->mState == + txMozillaXSLTProcessor::State::None); mProcessor->TransformToDoc(nullptr, false); return NS_OK; } @@ -604,6 +607,12 @@ txMozillaXSLTProcessor::ImportStylesheet(nsIDOMNode *aStyle) NS_ENSURE_TRUE(!mStylesheetDocument && !mStylesheet, NS_ERROR_NOT_IMPLEMENTED); + if (mState != State::None) { + return NS_ERROR_DOM_INVALID_STATE_ERR; + } + mozilla::AutoRestore restore(mState); + mState = State::Compiling; + // Reset mCompileResult when importing. mCompileResult = NS_OK; @@ -650,9 +659,17 @@ txMozillaXSLTProcessor::TransformToDocument(nsIDOMNode *aSource, return NS_ERROR_DOM_SECURITY_ERR; } + if (mState != State::None) { + return NS_ERROR_DOM_INVALID_STATE_ERR; + } + nsresult rv = ensureStylesheet(); NS_ENSURE_SUCCESS(rv, rv); + MOZ_RELEASE_ASSERT(mState == State::None); + mozilla::AutoRestore restore(mState); + mState = State::Transforming; + mSource = do_QueryInterface(aSource); return TransformToDoc(aResult, true); @@ -729,9 +746,17 @@ txMozillaXSLTProcessor::TransformToFragment(nsIDOMNode *aSource, return NS_ERROR_DOM_SECURITY_ERR; } + if (mState != State::None) { + return NS_ERROR_DOM_INVALID_STATE_ERR; + } + nsresult rv = ensureStylesheet(); NS_ENSURE_SUCCESS(rv, rv); + MOZ_RELEASE_ASSERT(mState == State::None); + mozilla::AutoRestore restore(mState); + mState = State::Transforming; + nsAutoPtr sourceNode(txXPathNativeNode::createXPathNode(aSource)); if (!sourceNode) { return NS_ERROR_OUT_OF_MEMORY; @@ -767,6 +792,9 @@ txMozillaXSLTProcessor::SetParameter(const nsAString & aNamespaceURI, nsIVariant *aValue) { NS_ENSURE_ARG(aValue); + if (mState != State::None) { + return NS_ERROR_DOM_INVALID_STATE_ERR; + } nsCOMPtr value = aValue; @@ -990,6 +1018,10 @@ NS_IMETHODIMP txMozillaXSLTProcessor::RemoveParameter(const nsAString& aNamespaceURI, const nsAString& aLocalName) { + if (mState != State::None) { + return NS_ERROR_DOM_INVALID_STATE_ERR; + } + int32_t nsId = kNameSpaceID_Unknown; nsresult rv = nsContentUtils::NameSpaceManager()-> RegisterNameSpace(aNamespaceURI, nsId); @@ -1004,6 +1036,10 @@ txMozillaXSLTProcessor::RemoveParameter(const nsAString& aNamespaceURI, NS_IMETHODIMP txMozillaXSLTProcessor::ClearParameters() { + if (mState != State::None) { + return NS_ERROR_DOM_INVALID_STATE_ERR; + } + mVariables.clear(); return NS_OK; @@ -1012,6 +1048,10 @@ txMozillaXSLTProcessor::ClearParameters() NS_IMETHODIMP txMozillaXSLTProcessor::Reset() { + if (mState != State::None) { + return NS_ERROR_DOM_INVALID_STATE_ERR; + } + if (mStylesheetDocument) { mStylesheetDocument->RemoveMutationObserver(this); } @@ -1215,6 +1255,12 @@ txMozillaXSLTProcessor::notifyError() nsresult txMozillaXSLTProcessor::ensureStylesheet() { + if (mState != State::None) { + return NS_ERROR_DOM_INVALID_STATE_ERR; + } + mozilla::AutoRestore restore(mState); + mState = State::Compiling; + if (mStylesheet) { return NS_OK; } @@ -1311,10 +1357,10 @@ txMozillaXSLTProcessor::Constructor(const GlobalObject& aGlobal, } void -txMozillaXSLTProcessor::ImportStylesheet(nsINode& stylesheet, +txMozillaXSLTProcessor::ImportStylesheet(nsINode& aStylesheet, mozilla::ErrorResult& aRv) { - aRv = ImportStylesheet(stylesheet.AsDOMNode()); + aRv = ImportStylesheet(aStylesheet.AsDOMNode()); } already_AddRefed @@ -1333,11 +1379,11 @@ txMozillaXSLTProcessor::TransformToFragment(nsINode& source, } already_AddRefed -txMozillaXSLTProcessor::TransformToDocument(nsINode& source, +txMozillaXSLTProcessor::TransformToDocument(nsINode& aSource, mozilla::ErrorResult& aRv) { nsCOMPtr document; - aRv = TransformToDocument(source.AsDOMNode(), getter_AddRefs(document)); + aRv = TransformToDocument(aSource.AsDOMNode(), getter_AddRefs(document)); nsCOMPtr domDoc = do_QueryInterface(document); return domDoc.forget(); } diff --git a/dom/xslt/xslt/txMozillaXSLTProcessor.h b/dom/xslt/xslt/txMozillaXSLTProcessor.h index fc76585f2d..2072de6c06 100644 --- a/dom/xslt/xslt/txMozillaXSLTProcessor.h +++ b/dom/xslt/xslt/txMozillaXSLTProcessor.h @@ -110,12 +110,12 @@ public: Constructor(const mozilla::dom::GlobalObject& aGlobal, mozilla::ErrorResult& aRv); - void ImportStylesheet(nsINode& stylesheet, + void ImportStylesheet(nsINode& aStylesheet, mozilla::ErrorResult& aRv); already_AddRefed - TransformToFragment(nsINode& source, nsIDocument& docVal, mozilla::ErrorResult& aRv); + TransformToFragment(nsINode& source, nsIDocument& docVal, mozilla::ErrorResult& aRv); already_AddRefed - TransformToDocument(nsINode& source, mozilla::ErrorResult& aRv); + TransformToDocument(nsINode& aSource, mozilla::ErrorResult& aRv); void SetParameter(JSContext* aCx, const nsAString& aNamespaceURI, @@ -131,6 +131,12 @@ public: { aRv = RemoveParameter(aNamespaceURI, aLocalName); } + void ClearParameters(mozilla::ErrorResult& aRv) { + aRv = ClearParameters(); + }; + void Reset(mozilla::ErrorResult& aRv) { + aRv = Reset(); + }; uint32_t Flags() { @@ -160,6 +166,8 @@ public: static void Shutdown(); private: + friend class nsTransformBlockerEvent; + explicit txMozillaXSLTProcessor(nsISupports* aOwner); /** * Default destructor for txMozillaXSLTProcessor @@ -186,6 +194,13 @@ private: RefPtr mRecycler; uint32_t mFlags; + + enum class State { + None, + Compiling, + Transforming, + }; + State mState = State::None; }; extern nsresult TX_LoadSheet(nsIURI* aUri, txMozillaXSLTProcessor* aProcessor,