From 9b82cb15843923ae2cd6ad8f3bff0da8240f17b6 Mon Sep 17 00:00:00 2001 From: Zack Weinberg Date: Tue, 13 Oct 2015 17:43:16 -0400 Subject: [PATCH] Bug 1035091 part 1: change CSS parser and loader APIs to distinguish UA, user, and author sheets instead of just UA vs everyone else. r=heycam --HG-- extra : rebase_source : a8a5a27db01306d1de58974ebb4d06d29d4b72b0 --- dom/base/nsDocument.cpp | 32 ++++++++++--- dom/base/nsTreeSanitizer.cpp | 3 +- dom/svg/SVGDocument.cpp | 4 +- editor/libeditor/nsHTMLEditor.cpp | 3 +- layout/base/nsStyleSheetService.cpp | 55 +++++++++++++++++------ layout/style/CSSStyleSheet.cpp | 9 ++-- layout/style/Loader.cpp | 57 +++++++++++++++--------- layout/style/Loader.h | 49 +++++++++++++++----- layout/style/nsCSSParser.cpp | 44 ++++++++++++------ layout/style/nsCSSParser.h | 8 ++-- layout/style/nsLayoutStylesheetCache.cpp | 49 ++++++++++---------- layout/style/nsLayoutStylesheetCache.h | 11 +++-- 12 files changed, 221 insertions(+), 103 deletions(-) diff --git a/dom/base/nsDocument.cpp b/dom/base/nsDocument.cpp index fc378131c167..1ae96d223c71 100644 --- a/dom/base/nsDocument.cpp +++ b/dom/base/nsDocument.cpp @@ -4405,7 +4405,8 @@ FindSheet(const nsCOMArray& aSheets, nsIURI* aSheetURI) } nsresult -nsDocument::LoadAdditionalStyleSheet(additionalSheetType aType, nsIURI* aSheetURI) +nsDocument::LoadAdditionalStyleSheet(additionalSheetType aType, + nsIURI* aSheetURI) { NS_PRECONDITION(aSheetURI, "null arg"); @@ -4414,11 +4415,29 @@ nsDocument::LoadAdditionalStyleSheet(additionalSheetType aType, nsIURI* aSheetUR return NS_ERROR_INVALID_ARG; // Loading the sheet sync. - nsRefPtr loader = new mozilla::css::Loader(); + nsRefPtr loader = new css::Loader(); + + css::SheetParsingMode parsingMode; + switch (aType) { + case nsIDocument::eAgentSheet: + parsingMode = css::eAgentSheetFeatures; + break; + + case nsIDocument::eUserSheet: + parsingMode = css::eUserSheetFeatures; + break; + + case nsIDocument::eAuthorSheet: + parsingMode = css::eAuthorSheetFeatures; + break; + + default: + MOZ_CRASH("impossible value for aType"); + } nsRefPtr sheet; - nsresult rv = loader->LoadSheetSync(aSheetURI, aType == eAgentSheet, - true, getter_AddRefs(sheet)); + nsresult rv = loader->LoadSheetSync(aSheetURI, parsingMode, true, + getter_AddRefs(sheet)); NS_ENSURE_SUCCESS(rv, rv); sheet->SetOwningDocument(this); @@ -9905,7 +9924,10 @@ nsresult nsDocument::LoadChromeSheetSync(nsIURI* uri, bool isAgentSheet, CSSStyleSheet** sheet) { - return CSSLoader()->LoadSheetSync(uri, isAgentSheet, isAgentSheet, sheet); + css::SheetParsingMode mode = + isAgentSheet ? css::eAgentSheetFeatures + : css::eAuthorSheetFeatures; + return CSSLoader()->LoadSheetSync(uri, mode, isAgentSheet, sheet); } class nsDelayedEventDispatcher : public nsRunnable diff --git a/dom/base/nsTreeSanitizer.cpp b/dom/base/nsTreeSanitizer.cpp index e9502bdd2566..7164a3e08210 100644 --- a/dom/base/nsTreeSanitizer.cpp +++ b/dom/base/nsTreeSanitizer.cpp @@ -1098,7 +1098,8 @@ nsTreeSanitizer::SanitizeStyleSheet(const nsAString& aOriginal, // Create the CSS parser, and parse the CSS text. nsCSSParser parser(nullptr, sheet); rv = parser.ParseSheet(aOriginal, aDocument->GetDocumentURI(), aBaseURI, - aDocument->NodePrincipal(), 0, false); + aDocument->NodePrincipal(), 0, + mozilla::css::eAuthorSheetFeatures); NS_ENSURE_SUCCESS(rv, true); // Mark the sheet as complete. MOZ_ASSERT(!sheet->IsModified(), diff --git a/dom/svg/SVGDocument.cpp b/dom/svg/SVGDocument.cpp index 913f90338270..7270ca183a6f 100644 --- a/dom/svg/SVGDocument.cpp +++ b/dom/svg/SVGDocument.cpp @@ -148,7 +148,9 @@ SVGDocument::EnsureNonSVGUserAgentStyleSheetsLoaded() NS_NewURI(getter_AddRefs(uri), spec); if (uri) { nsRefPtr cssSheet; - cssLoader->LoadSheetSync(uri, true, true, getter_AddRefs(cssSheet)); + cssLoader->LoadSheetSync(uri, + mozilla::css::eAgentSheetFeatures, + true, getter_AddRefs(cssSheet)); if (cssSheet) { EnsureOnDemandBuiltInUASheet(cssSheet); } diff --git a/editor/libeditor/nsHTMLEditor.cpp b/editor/libeditor/nsHTMLEditor.cpp index c169c38f6cc2..1afb7f7b6509 100644 --- a/editor/libeditor/nsHTMLEditor.cpp +++ b/editor/libeditor/nsHTMLEditor.cpp @@ -2843,7 +2843,8 @@ nsHTMLEditor::AddOverrideStyleSheet(const nsAString& aURL) nsRefPtr sheet; // Editor override style sheets may want to style Gecko anonymous boxes rv = ps->GetDocument()->CSSLoader()-> - LoadSheetSync(uaURI, true, true, getter_AddRefs(sheet)); + LoadSheetSync(uaURI, mozilla::css::eAgentSheetFeatures, true, + getter_AddRefs(sheet)); // Synchronous loads should ALWAYS return completed NS_ENSURE_TRUE(sheet, NS_ERROR_NULL_POINTER); diff --git a/layout/base/nsStyleSheetService.cpp b/layout/base/nsStyleSheetService.cpp index f85227ee9298..36d50bde609a 100644 --- a/layout/base/nsStyleSheetService.cpp +++ b/layout/base/nsStyleSheetService.cpp @@ -180,17 +180,32 @@ nsresult nsStyleSheetService::LoadAndRegisterSheetInternal(nsIURI *aSheetURI, uint32_t aSheetType) { - NS_ENSURE_ARG(aSheetType == AGENT_SHEET || - aSheetType == USER_SHEET || - aSheetType == AUTHOR_SHEET); NS_ENSURE_ARG_POINTER(aSheetURI); + css::SheetParsingMode parsingMode; + switch (aSheetType) { + case AGENT_SHEET: + parsingMode = css::eAgentSheetFeatures; + break; + + case USER_SHEET: + parsingMode = css::eUserSheetFeatures; + break; + + case AUTHOR_SHEET: + parsingMode = css::eAuthorSheetFeatures; + break; + + default: + NS_WARNING("invalid sheet type argument"); + return NS_ERROR_INVALID_ARG; + } + nsRefPtr loader = new css::Loader(); nsRefPtr sheet; - // Allow UA sheets, but not user sheets, to use unsafe rules - nsresult rv = loader->LoadSheetSync(aSheetURI, aSheetType == AGENT_SHEET, - true, getter_AddRefs(sheet)); + nsresult rv = loader->LoadSheetSync(aSheetURI, parsingMode, true, + getter_AddRefs(sheet)); NS_ENSURE_SUCCESS(rv, rv); if (!mSheets[aSheetType].AppendObject(sheet)) { @@ -219,18 +234,32 @@ NS_IMETHODIMP nsStyleSheetService::PreloadSheet(nsIURI *aSheetURI, uint32_t aSheetType, nsIDOMStyleSheet **aSheet) { - NS_ENSURE_ARG(aSheetType == AGENT_SHEET || - aSheetType == USER_SHEET || - aSheetType == AUTHOR_SHEET); - NS_ENSURE_ARG_POINTER(aSheetURI); NS_PRECONDITION(aSheet, "Null out param"); + NS_ENSURE_ARG_POINTER(aSheetURI); + css::SheetParsingMode parsingMode; + switch (aSheetType) { + case AGENT_SHEET: + parsingMode = css::eAgentSheetFeatures; + break; + + case USER_SHEET: + parsingMode = css::eUserSheetFeatures; + break; + + case AUTHOR_SHEET: + parsingMode = css::eAuthorSheetFeatures; + break; + + default: + NS_WARNING("invalid sheet type argument"); + return NS_ERROR_INVALID_ARG; + } nsRefPtr loader = new css::Loader(); - // Allow UA sheets, but not user sheets, to use unsafe rules nsRefPtr sheet; - nsresult rv = loader->LoadSheetSync(aSheetURI, aSheetType == AGENT_SHEET, - true, getter_AddRefs(sheet)); + nsresult rv = loader->LoadSheetSync(aSheetURI, parsingMode, true, + getter_AddRefs(sheet)); NS_ENSURE_SUCCESS(rv, rv); sheet.forget(aSheet); return NS_OK; diff --git a/layout/style/CSSStyleSheet.cpp b/layout/style/CSSStyleSheet.cpp index 36db0ff3b8f4..c556ea1de6f8 100644 --- a/layout/style/CSSStyleSheet.cpp +++ b/layout/style/CSSStyleSheet.cpp @@ -2331,8 +2331,11 @@ CSSStyleSheet::ReparseSheet(const nsAString& aInput) mInner->mFirstChild = nullptr; mInner->mNameSpaceMap = nullptr; - // allow unsafe rules if the style sheet's principal is the system principal - bool allowUnsafeRules = nsContentUtils::IsSystemPrincipal(mInner->mPrincipal); + // allow agent features if the style sheet's principal is the system principal + css::SheetParsingMode parsingMode = + nsContentUtils::IsSystemPrincipal(mInner->mPrincipal) + ? css::eAgentSheetFeatures + : css::eAuthorSheetFeatures; uint32_t lineNumber = 1; if (mOwningNode) { @@ -2345,7 +2348,7 @@ CSSStyleSheet::ReparseSheet(const nsAString& aInput) nsCSSParser parser(loader, this); nsresult rv = parser.ParseSheet(aInput, mInner->mSheetURI, mInner->mBaseURI, mInner->mPrincipal, lineNumber, - allowUnsafeRules, &reusableSheets); + parsingMode, &reusableSheets); DidDirty(); // we are always 'dirty' here since we always remove rules first NS_ENSURE_SUCCESS(rv, rv); diff --git a/layout/style/Loader.cpp b/layout/style/Loader.cpp index 488b07b9aa34..53b49c3d1769 100644 --- a/layout/style/Loader.cpp +++ b/layout/style/Loader.cpp @@ -104,6 +104,12 @@ namespace css { * Data needed to properly load a stylesheet * *********************************************/ +static_assert(eAuthorSheetFeatures == 0 && + eUserSheetFeatures == 1 && + eAgentSheetFeatures == 2, + "sheet parsing mode constants won't fit " + "in SheetLoadData::mParsingMode"); + class SheetLoadData final : public nsIRunnable, public nsIUnicharStreamLoaderObserver, public nsIThreadObserver @@ -137,7 +143,7 @@ public: nsIURI* aURI, CSSStyleSheet* aSheet, bool aSyncLoad, - bool aAllowUnsafeRules, + SheetParsingMode aParsingMode, bool aUseSystemPrincipal, const nsCString& aCharset, nsICSSLoaderObserver* aObserver, @@ -215,9 +221,12 @@ public: // created. bool mWasAlternate : 1; - // mAllowUnsafeRules is true if we should allow unsafe rules to be parsed - // in the loaded sheet. - bool mAllowUnsafeRules : 1; + // mParsingMode controls access to nonstandard style constructs that + // are not safe for use on the public Web but necessary in UA sheets + // and/or useful in user sheets. The only values stored in this + // field are 0, 1, and 2; three bits are allocated to avoid issues + // should the enum type be signed. + SheetParsingMode mParsingMode : 3; // mUseSystemPrincipal is true if the system principal should be used for // this sheet, no matter what the channel principal is. Only true for sync @@ -333,7 +342,7 @@ SheetLoadData::SheetLoadData(Loader* aLoader, mIsCancelled(false), mMustNotify(false), mWasAlternate(aIsAlternate), - mAllowUnsafeRules(false), + mParsingMode(eAuthorSheetFeatures), mUseSystemPrincipal(false), mSheetAlreadyComplete(false), mOwningElement(aOwningElement), @@ -364,7 +373,7 @@ SheetLoadData::SheetLoadData(Loader* aLoader, mIsCancelled(false), mMustNotify(false), mWasAlternate(false), - mAllowUnsafeRules(false), + mParsingMode(eAuthorSheetFeatures), mUseSystemPrincipal(false), mSheetAlreadyComplete(false), mOwningElement(nullptr), @@ -376,7 +385,7 @@ SheetLoadData::SheetLoadData(Loader* aLoader, if (mParentData) { mSyncLoad = mParentData->mSyncLoad; mIsNonDocumentSheet = mParentData->mIsNonDocumentSheet; - mAllowUnsafeRules = mParentData->mAllowUnsafeRules; + mParsingMode = mParentData->mParsingMode; mUseSystemPrincipal = mParentData->mUseSystemPrincipal; ++(mParentData->mPendingChildren); } @@ -389,7 +398,7 @@ SheetLoadData::SheetLoadData(Loader* aLoader, nsIURI* aURI, CSSStyleSheet* aSheet, bool aSyncLoad, - bool aAllowUnsafeRules, + SheetParsingMode aParsingMode, bool aUseSystemPrincipal, const nsCString& aCharset, nsICSSLoaderObserver* aObserver, @@ -407,7 +416,7 @@ SheetLoadData::SheetLoadData(Loader* aLoader, mIsCancelled(false), mMustNotify(false), mWasAlternate(false), - mAllowUnsafeRules(aAllowUnsafeRules), + mParsingMode(aParsingMode), mUseSystemPrincipal(aUseSystemPrincipal), mSheetAlreadyComplete(false), mOwningElement(nullptr), @@ -417,6 +426,10 @@ SheetLoadData::SheetLoadData(Loader* aLoader, mCharsetHint(aCharset) { NS_PRECONDITION(mLoader, "Must have a loader!"); + NS_PRECONDITION(aParsingMode == eAuthorSheetFeatures || + aParsingMode == eUserSheetFeatures || + aParsingMode == eAgentSheetFeatures, + "Unrecognized sheet parsing mode"); NS_POSTCONDITION(!mUseSystemPrincipal || mSyncLoad, "Shouldn't use system principal for async loads"); @@ -1779,7 +1792,7 @@ Loader::ParseSheet(const nsAString& aInput, nsresult rv = parser.ParseSheet(aInput, sheetURI, baseURI, aLoadData->mSheet->Principal(), aLoadData->mLineNumber, - aLoadData->mAllowUnsafeRules); + aLoadData->mParsingMode); mParsingDatas.RemoveElementAt(mParsingDatas.Length() - 1); if (NS_FAILED(rv)) { @@ -2293,14 +2306,16 @@ Loader::LoadChildSheet(CSSStyleSheet* aParentSheet, } nsresult -Loader::LoadSheetSync(nsIURI* aURL, bool aAllowUnsafeRules, +Loader::LoadSheetSync(nsIURI* aURL, + SheetParsingMode aParsingMode, bool aUseSystemPrincipal, CSSStyleSheet** aSheet) { LOG(("css::Loader::LoadSheetSync")); - return InternalLoadNonDocumentSheet(aURL, false, aAllowUnsafeRules, - aUseSystemPrincipal, nullptr, - EmptyCString(), aSheet, nullptr); + return InternalLoadNonDocumentSheet(aURL, + false, aParsingMode, aUseSystemPrincipal, + nullptr, EmptyCString(), + aSheet, nullptr); } nsresult @@ -2312,7 +2327,8 @@ Loader::LoadSheet(nsIURI* aURL, { LOG(("css::Loader::LoadSheet(aURL, aObserver, aSheet) api call")); NS_PRECONDITION(aSheet, "aSheet is null"); - return InternalLoadNonDocumentSheet(aURL, false, false, false, + return InternalLoadNonDocumentSheet(aURL, + false, eAuthorSheetFeatures, false, aOriginPrincipal, aCharset, aSheet, aObserver); } @@ -2328,16 +2344,17 @@ Loader::LoadSheet(nsIURI* aURL, const nsAString& aIntegrity) { LOG(("css::Loader::LoadSheet(aURL, aObserver) api call")); - return InternalLoadNonDocumentSheet(aURL, aIsPreload, false, false, + return InternalLoadNonDocumentSheet(aURL, + aIsPreload, eAuthorSheetFeatures, false, aOriginPrincipal, aCharset, - nullptr, aObserver, aCORSMode, - aReferrerPolicy, aIntegrity); + nullptr, aObserver, + aCORSMode, aReferrerPolicy, aIntegrity); } nsresult Loader::InternalLoadNonDocumentSheet(nsIURI* aURL, bool aIsPreload, - bool aAllowUnsafeRules, + SheetParsingMode aParsingMode, bool aUseSystemPrincipal, nsIPrincipal* aOriginPrincipal, const nsCString& aCharset, @@ -2394,7 +2411,7 @@ Loader::InternalLoadNonDocumentSheet(nsIURI* aURL, } SheetLoadData* data = - new SheetLoadData(this, aURL, sheet, syncLoad, aAllowUnsafeRules, + new SheetLoadData(this, aURL, sheet, syncLoad, aParsingMode, aUseSystemPrincipal, aCharset, aObserver, aOriginPrincipal, mDocument); diff --git a/layout/style/Loader.h b/layout/style/Loader.h index 6da5285e8157..0e81d4ccc6f8 100644 --- a/layout/style/Loader.h +++ b/layout/style/Loader.h @@ -183,6 +183,33 @@ enum StyleSheetState { eSheetComplete }; +/** + * Enum defining the mode in which a sheet is to be parsed. This is + * usually, but not always, the same as the cascade level at which the + * sheet will apply (see nsStyleSet.h). Most of the Loader APIs only + * support loading of author sheets. + * + * Author sheets are the normal case: styles embedded in or linked + * from HTML pages. They are also the most restricted. + * + * User sheets can do anything author sheets can do, and also get + * access to a few CSS extensions that are not yet suitable for + * exposure on the public Web, but are very useful for expressing + * user style overrides, such as @-moz-document rules. + * + * Agent sheets have access to all author- and user-sheet features + * plus more extensions that are necessary for internal use but, + * again, not yet suitable for exposure on the public Web. Some of + * these are outright unsafe to expose; in particular, incorrect + * styling of anonymous box pseudo-elements can violate layout + * invariants. + */ +enum SheetParsingMode { + eAuthorSheetFeatures = 0, + eUserSheetFeatures, + eAgentSheetFeatures +}; + class Loader final { typedef mozilla::net::ReferrerPolicy ReferrerPolicy; @@ -300,13 +327,8 @@ public: * method can be used to load sheets not associated with a document. * * @param aURL the URL of the sheet to load - * @param aEnableUnsafeRules whether unsafe rules are enabled for this - * sheet load - * Unsafe rules are rules that can violate key Gecko invariants if misused. - * In particular, most anonymous box pseudoelements must be very carefully - * styled or we will have severe problems. Therefore unsafe rules should - * never be enabled for stylesheets controlled by untrusted sites; preferably - * unsafe rules should only be enabled for agent sheets. + * @param aParsingMode the mode in which to parse the sheet + * (see comments at enum SheetParsingMode, above). * @param aUseSystemPrincipal if true, give the resulting sheet the system * principal no matter where it's being loaded from. * @param [out] aSheet the loaded, complete sheet. @@ -319,22 +341,25 @@ public: * whether the data could be parsed as CSS and doesn't indicate anything * about the status of child sheets of the returned sheet. */ - nsresult LoadSheetSync(nsIURI* aURL, bool aEnableUnsafeRules, + nsresult LoadSheetSync(nsIURI* aURL, + SheetParsingMode aParsingMode, bool aUseSystemPrincipal, CSSStyleSheet** aSheet); /** - * As above, but aUseSystemPrincipal and aEnableUnsafeRules are assumed false. + * As above, but defaults aParsingMode to eAuthorSheetFeatures and + * aUseSystemPrincipal to false. */ nsresult LoadSheetSync(nsIURI* aURL, CSSStyleSheet** aSheet) { - return LoadSheetSync(aURL, false, false, aSheet); + return LoadSheetSync(aURL, eAuthorSheetFeatures, false, aSheet); } /** * Asynchronously load the stylesheet at aURL. If a successful result is * returned, aObserver is guaranteed to be notified asynchronously once the * sheet is loaded and marked complete. This method can be used to load - * sheets not associated with a document. + * sheets not associated with a document. This method cannot be used to + * load user or agent sheets. * * @param aURL the URL of the sheet to load * @param aOriginPrincipal the principal to use for security checks. This @@ -495,7 +520,7 @@ private: nsresult InternalLoadNonDocumentSheet(nsIURI* aURL, bool aIsPreload, - bool aAllowUnsafeRules, + SheetParsingMode aParsingMode, bool aUseSystemPrincipal, nsIPrincipal* aOriginPrincipal, const nsCString& aCharset, diff --git a/layout/style/nsCSSParser.cpp b/layout/style/nsCSSParser.cpp index b460e73c56b5..826b6951caf0 100644 --- a/layout/style/nsCSSParser.cpp +++ b/layout/style/nsCSSParser.cpp @@ -107,6 +107,12 @@ struct CSSParserInputState { bool mHavePushBack; }; +static_assert(eAuthorSheetFeatures == 0 && + eUserSheetFeatures == 1 && + eAgentSheetFeatures == 2, + "sheet parsing mode constants won't fit " + "in CSSParserImpl::mParsingMode"); + // Your basic top-down recursive descent style parser // The exposed methods and members of this class are precisely those // needed by nsCSSParser, far below. @@ -131,7 +137,7 @@ public: nsIURI* aBaseURI, nsIPrincipal* aSheetPrincipal, uint32_t aLineNumber, - bool aAllowUnsafeRules, + SheetParsingMode aParsingMode, LoaderReusableStyleSheets* aReusableSheets); nsresult ParseStyleAttribute(const nsAString& aAttributeValue, @@ -316,12 +322,20 @@ public: uint32_t aLineNumber, uint32_t aLineOffset); + bool AgentRulesEnabled() const { + return mParsingMode == eAgentSheetFeatures; + } + bool UserRulesEnabled() const { + return mParsingMode == eAgentSheetFeatures || + mParsingMode == eUserSheetFeatures; + } + nsCSSProps::EnabledState PropertyEnabledState() const { static_assert(nsCSSProps::eEnabledForAllContent == 0, "nsCSSProps::eEnabledForAllContent should be zero for " "this bitfield to work"); nsCSSProps::EnabledState enabledState = nsCSSProps::eEnabledForAllContent; - if (mUnsafeRulesEnabled) { + if (AgentRulesEnabled()) { enabledState |= nsCSSProps::eEnabledInUASheets; } if (mIsChrome) { @@ -1215,8 +1229,12 @@ protected: // True when the unitless length quirk applies. bool mUnitlessLengthQuirk : 1; - // True if unsafe rules should be allowed - bool mUnsafeRulesEnabled : 1; + // Controls access to nonstandard style constructs that are not safe + // for use on the public Web but necessary in UA sheets and/or + // useful in user sheets. The only values stored in this field are + // 0, 1, and 2; three bits are allocated to avoid issues should the + // enum type be signed. + SheetParsingMode mParsingMode : 3; // True if we are in parsing rules for the chrome. bool mIsChrome : 1; @@ -1346,7 +1364,7 @@ CSSParserImpl::CSSParserImpl() mNavQuirkMode(false), mHashlessColorQuirk(false), mUnitlessLengthQuirk(false), - mUnsafeRulesEnabled(false), + mParsingMode(eAuthorSheetFeatures), mIsChrome(false), mViewportUnitsEnabled(true), mHTMLMediaMode(false), @@ -1453,7 +1471,7 @@ CSSParserImpl::ParseSheet(const nsAString& aInput, nsIURI* aBaseURI, nsIPrincipal* aSheetPrincipal, uint32_t aLineNumber, - bool aAllowUnsafeRules, + SheetParsingMode aParsingMode, LoaderReusableStyleSheets* aReusableSheets) { NS_PRECONDITION(aSheetPrincipal, "Must have principal here!"); @@ -1499,7 +1517,7 @@ CSSParserImpl::ParseSheet(const nsAString& aInput, mSection = eCSSSection_Charset; // sheet is empty, any rules are fair } - mUnsafeRulesEnabled = aAllowUnsafeRules; + mParsingMode = aParsingMode; mIsChrome = nsContentUtils::IsSystemPrincipal(aSheetPrincipal); mReusableSheets = aReusableSheets; @@ -1524,7 +1542,7 @@ CSSParserImpl::ParseSheet(const nsAString& aInput, } ReleaseScanner(); - mUnsafeRulesEnabled = false; + mParsingMode = eAuthorSheetFeatures; mIsChrome = false; mReusableSheets = nullptr; @@ -5604,7 +5622,7 @@ CSSParserImpl::ParsePseudoSelector(int32_t& aDataMask, bool pseudoClassIsUserAction = nsCSSPseudoClasses::IsUserActionPseudoClass(pseudoClassType); - if (!mUnsafeRulesEnabled && + if (!AgentRulesEnabled() && ((pseudoElementType < nsCSSPseudoElements::ePseudo_PseudoElementCount && nsCSSPseudoElements::PseudoElementIsUASheetOnly(pseudoElementType)) || (pseudoClassType != nsCSSPseudoClasses::ePseudoClass_NotPseudoClass && @@ -5640,10 +5658,10 @@ CSSParserImpl::ParsePseudoSelector(int32_t& aDataMask, bool isPseudoElement = (pseudoElementType < nsCSSPseudoElements::ePseudo_PseudoElementCount); // anonymous boxes are only allowed if they're the tree boxes or we have - // enabled unsafe rules + // enabled agent rules bool isAnonBox = isTreePseudo || (pseudoElementType == nsCSSPseudoElements::ePseudo_AnonBox && - mUnsafeRulesEnabled); + AgentRulesEnabled()); bool isPseudoClass = (pseudoClassType != nsCSSPseudoClasses::ePseudoClass_NotPseudoClass); @@ -15820,12 +15838,12 @@ nsCSSParser::ParseSheet(const nsAString& aInput, nsIURI* aBaseURI, nsIPrincipal* aSheetPrincipal, uint32_t aLineNumber, - bool aAllowUnsafeRules, + SheetParsingMode aParsingMode, LoaderReusableStyleSheets* aReusableSheets) { return static_cast(mImpl)-> ParseSheet(aInput, aSheetURI, aBaseURI, aSheetPrincipal, aLineNumber, - aAllowUnsafeRules, aReusableSheets); + aParsingMode, aReusableSheets); } nsresult diff --git a/layout/style/nsCSSParser.h b/layout/style/nsCSSParser.h index a4e18a2de88e..f23958100fd5 100644 --- a/layout/style/nsCSSParser.h +++ b/layout/style/nsCSSParser.h @@ -9,6 +9,7 @@ #define nsCSSParser_h___ #include "mozilla/Attributes.h" +#include "mozilla/css/Loader.h" #include "nsCSSProperty.h" #include "nsCSSScanner.h" @@ -32,8 +33,6 @@ class CSSVariableValues; namespace css { class Rule; class Declaration; -class Loader; -class LoaderReusableStyleSheets; class StyleRule; } // namespace css } // namespace mozilla @@ -78,8 +77,7 @@ public: * @param aSheetPrincipal the principal of the stylesheet. This must match * the principal of the sheet passed to SetStyleSheet. * @param aLineNumber the line number of the first line of the sheet. - * @param aAllowUnsafeRules see aEnableUnsafeRules in - * mozilla::css::Loader::LoadSheetSync + * @param aParsingMode see SheetParsingMode in css/Loader.h * @param aReusableSheets style sheets that can be reused by an @import. * This can be nullptr. */ @@ -88,7 +86,7 @@ public: nsIURI* aBaseURI, nsIPrincipal* aSheetPrincipal, uint32_t aLineNumber, - bool aAllowUnsafeRules, + mozilla::css::SheetParsingMode aParsingMode, mozilla::css::LoaderReusableStyleSheets* aReusableSheets = nullptr); diff --git a/layout/style/nsLayoutStylesheetCache.cpp b/layout/style/nsLayoutStylesheetCache.cpp index fdf054eb5c79..2692a3a84ade 100644 --- a/layout/style/nsLayoutStylesheetCache.cpp +++ b/layout/style/nsLayoutStylesheetCache.cpp @@ -30,6 +30,7 @@ #endif using namespace mozilla; +using namespace mozilla::css; static bool sNumberControlEnabled; @@ -70,7 +71,7 @@ nsLayoutStylesheetCache::ScrollbarsSheet() if (!gStyleCache->mScrollbarsSheet) { // Scrollbars don't need access to unsafe rules LoadSheetURL("chrome://global/skin/scrollbars.css", - gStyleCache->mScrollbarsSheet, false); + gStyleCache->mScrollbarsSheet, eAuthorSheetFeatures); } return gStyleCache->mScrollbarsSheet; @@ -84,7 +85,7 @@ nsLayoutStylesheetCache::FormsSheet() if (!gStyleCache->mFormsSheet) { // forms.css needs access to unsafe rules LoadSheetURL("resource://gre-resources/forms.css", - gStyleCache->mFormsSheet, true); + gStyleCache->mFormsSheet, eAgentSheetFeatures); } return gStyleCache->mFormsSheet; @@ -101,7 +102,7 @@ nsLayoutStylesheetCache::NumberControlSheet() if (!gStyleCache->mNumberControlSheet) { LoadSheetURL("resource://gre-resources/number-control.css", - gStyleCache->mNumberControlSheet, true); + gStyleCache->mNumberControlSheet, eAgentSheetFeatures); } return gStyleCache->mNumberControlSheet; @@ -128,7 +129,7 @@ nsLayoutStylesheetCache::UASheet() if (!gStyleCache->mUASheet) { LoadSheetURL("resource://gre-resources/ua.css", - gStyleCache->mUASheet, true); + gStyleCache->mUASheet, eAgentSheetFeatures); } return gStyleCache->mUASheet; @@ -141,7 +142,7 @@ nsLayoutStylesheetCache::HTMLSheet() if (!gStyleCache->mHTMLSheet) { LoadSheetURL("resource://gre-resources/html.css", - gStyleCache->mHTMLSheet, true); + gStyleCache->mHTMLSheet, eAgentSheetFeatures); } return gStyleCache->mHTMLSheet; @@ -182,7 +183,7 @@ nsLayoutStylesheetCache::MathMLSheet() if (!gStyleCache->mMathMLSheet) { LoadSheetURL("resource://gre-resources/mathml.css", - gStyleCache->mMathMLSheet, true); + gStyleCache->mMathMLSheet, eAgentSheetFeatures); } return gStyleCache->mMathMLSheet; @@ -209,7 +210,7 @@ nsLayoutStylesheetCache::NoScriptSheet() #else "resource://gre-resources/noscript.css", #endif - gStyleCache->mNoScriptSheet, true); + gStyleCache->mNoScriptSheet, eAgentSheetFeatures); } return gStyleCache->mNoScriptSheet; @@ -229,7 +230,7 @@ nsLayoutStylesheetCache::NoFramesSheet() #else "resource://gre-resources/noframes.css", #endif - gStyleCache->mNoFramesSheet, true); + gStyleCache->mNoFramesSheet, eAgentSheetFeatures); } return gStyleCache->mNoFramesSheet; @@ -268,7 +269,7 @@ nsLayoutStylesheetCache::ContentEditableSheet() if (!gStyleCache->mContentEditableSheet) { LoadSheetURL("resource://gre/res/contenteditable.css", - gStyleCache->mContentEditableSheet, true); + gStyleCache->mContentEditableSheet, eAgentSheetFeatures); } return gStyleCache->mContentEditableSheet; @@ -281,7 +282,7 @@ nsLayoutStylesheetCache::DesignModeSheet() if (!gStyleCache->mDesignModeSheet) { LoadSheetURL("resource://gre/res/designmode.css", - gStyleCache->mDesignModeSheet, true); + gStyleCache->mDesignModeSheet, eAgentSheetFeatures); } return gStyleCache->mDesignModeSheet; @@ -359,15 +360,15 @@ nsLayoutStylesheetCache::nsLayoutStylesheetCache() // And make sure that we load our UA sheets. No need to do this // per-profile, since they're profile-invariant. LoadSheetURL("resource://gre-resources/counterstyles.css", - mCounterStylesSheet, true); + mCounterStylesSheet, eAgentSheetFeatures); LoadSheetURL("chrome://global/content/minimal-xul.css", - mMinimalXULSheet, true); + mMinimalXULSheet, eAgentSheetFeatures); LoadSheetURL("resource://gre-resources/quirk.css", - mQuirkSheet, true); + mQuirkSheet, eAgentSheetFeatures); LoadSheetURL("resource://gre/res/svg.css", - mSVGSheet, true); + mSVGSheet, eAgentSheetFeatures); LoadSheetURL("chrome://global/content/xul.css", - mXULSheet, true); + mXULSheet, eAgentSheetFeatures); // The remaining sheets are created on-demand do to their use being rarer // (which helps save memory for Firefox OS apps) or because they need to @@ -434,25 +435,27 @@ nsLayoutStylesheetCache::InitFromProfile() contentFile->Append(NS_LITERAL_STRING("userContent.css")); chromeFile->Append(NS_LITERAL_STRING("userChrome.css")); - LoadSheetFile(contentFile, mUserContentSheet); - LoadSheetFile(chromeFile, mUserChromeSheet); + LoadSheetFile(contentFile, mUserContentSheet, eUserSheetFeatures); + LoadSheetFile(chromeFile, mUserChromeSheet, eUserSheetFeatures); } /* static */ void nsLayoutStylesheetCache::LoadSheetURL(const char* aURL, nsRefPtr& aSheet, - bool aEnableUnsafeRules) + SheetParsingMode aParsingMode) { nsCOMPtr uri; NS_NewURI(getter_AddRefs(uri), aURL); - LoadSheet(uri, aSheet, aEnableUnsafeRules); + LoadSheet(uri, aSheet, aParsingMode); if (!aSheet) { NS_ERROR(nsPrintfCString("Could not load %s", aURL).get()); } } void -nsLayoutStylesheetCache::LoadSheetFile(nsIFile* aFile, nsRefPtr& aSheet) +nsLayoutStylesheetCache::LoadSheetFile(nsIFile* aFile, + nsRefPtr& aSheet, + SheetParsingMode aParsingMode) { bool exists = false; aFile->Exists(&exists); @@ -462,7 +465,7 @@ nsLayoutStylesheetCache::LoadSheetFile(nsIFile* aFile, nsRefPtr& nsCOMPtr uri; NS_NewFileURI(getter_AddRefs(uri), aFile); - LoadSheet(uri, aSheet, false); + LoadSheet(uri, aSheet, aParsingMode); } #ifdef MOZ_CRASHREPORTER @@ -719,7 +722,7 @@ ErrorLoadingBuiltinSheet(nsIURI* aURI, const char* aMsg) void nsLayoutStylesheetCache::LoadSheet(nsIURI* aURI, nsRefPtr& aSheet, - bool aEnableUnsafeRules) + SheetParsingMode aParsingMode) { if (!aURI) { ErrorLoadingBuiltinSheet(aURI, "null URI"); @@ -736,7 +739,7 @@ nsLayoutStylesheetCache::LoadSheet(nsIURI* aURI, } - nsresult rv = gCSSLoader->LoadSheetSync(aURI, aEnableUnsafeRules, true, + nsresult rv = gCSSLoader->LoadSheetSync(aURI, aParsingMode, true, getter_AddRefs(aSheet)); if (NS_FAILED(rv)) { ErrorLoadingBuiltinSheet(aURI, diff --git a/layout/style/nsLayoutStylesheetCache.h b/layout/style/nsLayoutStylesheetCache.h index 5d9beb8f90c8..f18271b3860d 100644 --- a/layout/style/nsLayoutStylesheetCache.h +++ b/layout/style/nsLayoutStylesheetCache.h @@ -13,15 +13,13 @@ #include "mozilla/Attributes.h" #include "mozilla/MemoryReporting.h" #include "mozilla/StaticPtr.h" +#include "mozilla/css/Loader.h" class nsIFile; class nsIURI; namespace mozilla { class CSSStyleSheet; -namespace css { -class Loader; -} // namespace css } // namespace mozilla class nsLayoutStylesheetCache final @@ -69,11 +67,12 @@ private: void InitMemoryReporter(); static void LoadSheetURL(const char* aURL, nsRefPtr& aSheet, - bool aEnableUnsafeRules); + mozilla::css::SheetParsingMode aParsingMode); static void LoadSheetFile(nsIFile* aFile, - nsRefPtr& aSheet); + nsRefPtr& aSheet, + mozilla::css::SheetParsingMode aParsingMode); static void LoadSheet(nsIURI* aURI, nsRefPtr& aSheet, - bool aEnableUnsafeRules); + mozilla::css::SheetParsingMode aParsingMode); static void InvalidateSheet(nsRefPtr& aSheet); static void DependentPrefChanged(const char* aPref, void* aData); void BuildPreferenceSheet(nsRefPtr& aSheet,