diff --git a/browser/base/content/browser.js b/browser/base/content/browser.js index 694b8389f..93966140c 100644 --- a/browser/base/content/browser.js +++ b/browser/base/content/browser.js @@ -2476,9 +2476,12 @@ function losslessDecodeURI(aURI) { // a sequence that survived decodeURI, i.e. one for: // ';', '/', '?', ':', '@', '&', '=', '+', '$', ',', '#' // (RFC 3987 section 3.2) - // 2. Re-encode whitespace so that it doesn't get eaten away - // by the location bar (bug 410726). - .replace(/%(?!3B|2F|3F|3A|40|26|3D|2B|24|2C|23)|[\r\n\t]/ig, + // 2. Re-encode select whitespace so that it doesn't get eaten + // away by the location bar (bug 410726). Re-encode all + // adjacent whitespace, to prevent spoofing attempts where + // invisible characters would push part of the URL to + // overflow the location bar (bug 1395508). + .replace(/%(?!3B|2F|3F|3A|40|26|3D|2B|24|2C|23)|[\r\n\t]|\s(?=\s)|\s$/ig, encodeURIComponent); } catch (e) {} diff --git a/docshell/base/nsDocShell.cpp b/docshell/base/nsDocShell.cpp index b9d4be58b..50a7f6c6e 100644 --- a/docshell/base/nsDocShell.cpp +++ b/docshell/base/nsDocShell.cpp @@ -6493,8 +6493,10 @@ nsDocShell::ScrollByPages(int32_t aNumPages) //***************************************************************************** NS_IMETHODIMP -nsDocShell::RefreshURI(nsIURI* aURI, int32_t aDelay, bool aRepeat, - bool aMetaRefresh) +nsDocShell::RefreshURI(nsIURI* aURI, + int32_t aDelay, bool aRepeat, + bool aMetaRefresh, + nsIPrincipal* aPrincipal) { NS_ENSURE_ARG(aURI); @@ -6529,6 +6531,7 @@ nsDocShell::RefreshURI(nsIURI* aURI, int32_t aDelay, bool aRepeat, nsCOMPtr dataRef = refreshTimer; // Get the ref count to 1 refreshTimer->mDocShell = this; + refreshTimer->mPrincipal = aPrincipal; refreshTimer->mURI = aURI; refreshTimer->mDelay = aDelay; refreshTimer->mRepeat = aRepeat; @@ -6560,7 +6563,8 @@ nsresult nsDocShell::ForceRefreshURIFromTimer(nsIURI* aURI, int32_t aDelay, bool aMetaRefresh, - nsITimer* aTimer) + nsITimer* aTimer, + nsIPrincipal* aPrincipal) { NS_PRECONDITION(aTimer, "Must have a timer here"); @@ -6578,7 +6582,7 @@ nsDocShell::ForceRefreshURIFromTimer(nsIURI* aURI, } } - return ForceRefreshURI(aURI, aDelay, aMetaRefresh); + return ForceRefreshURI(aURI, aDelay, aMetaRefresh, aPrincipal); } bool @@ -6608,7 +6612,7 @@ nsDocShell::DoAppRedirectIfNeeded(nsIURI* aURI, } NS_IMETHODIMP -nsDocShell::ForceRefreshURI(nsIURI* aURI, int32_t aDelay, bool aMetaRefresh) +nsDocShell::ForceRefreshURI(nsIURI* aURI, int32_t aDelay, bool aMetaRefresh, nsIPrincipal* aPrincipal) { NS_ENSURE_ARG(aURI); @@ -6656,11 +6660,18 @@ nsDocShell::ForceRefreshURI(nsIURI* aURI, int32_t aDelay, bool aMetaRefresh) loadInfo->SetLoadType(nsIDocShellLoadInfo::loadRefresh); } + // If the principal is null, the refresh will have a triggeringPrincipal + // derived from the referrer URI, or will be set to the system principal + // if there is no refererrer. See LoadURI() + if (aPrincipal) { + loadInfo->SetOwner(aPrincipal); // as called prior to bug 1286472 + } + /* * LoadURI(...) will cancel all refresh timers... This causes the * Timer and its refreshData instance to be released... */ - LoadURI(aURI, loadInfo, nsIWebNavigation::LOAD_FLAGS_NONE, true); + LoadURI(aURI, loadInfo, nsIWebNavigation::LOAD_FLAGS_DISALLOW_INHERIT_OWNER, true); // XXX: LOAD_FLAGS_DISALLOW_INHERIT_PRINCIPAL return NS_OK; } @@ -6896,7 +6907,7 @@ nsDocShell::SetupRefreshURIFromHeader(nsIURI* aBaseURI, return NS_ERROR_FAILURE; } - rv = RefreshURI(uri, seconds * 1000, false, true); + rv = RefreshURI(uri, seconds * 1000, false, true, aPrincipal); } } } @@ -12974,7 +12985,7 @@ nsRefreshTimer::Notify(nsITimer* aTimer) // Get the delay count to determine load type uint32_t delay = 0; aTimer->GetDelay(&delay); - mDocShell->ForceRefreshURIFromTimer(mURI, delay, mMetaRefresh, aTimer); + mDocShell->ForceRefreshURIFromTimer(mURI, delay, mMetaRefresh, aTimer, mPrincipal); } return NS_OK; } diff --git a/docshell/base/nsDocShell.h b/docshell/base/nsDocShell.h index 340f00793..6deb6947b 100644 --- a/docshell/base/nsDocShell.h +++ b/docshell/base/nsDocShell.h @@ -113,6 +113,7 @@ public: RefPtr mDocShell; nsCOMPtr mURI; + nsCOMPtr mPrincipal; int32_t mDelay; bool mRepeat; bool mMetaRefresh; @@ -244,7 +245,8 @@ public: // the timer involved out of mRefreshURIList if it's there. // aTimer must not be null. nsresult ForceRefreshURIFromTimer(nsIURI* aURI, int32_t aDelay, - bool aMetaRefresh, nsITimer* aTimer); + bool aMetaRefresh, nsITimer* aTimer, + nsIPrincipal* aPrincipal); friend class OnLinkClickEvent; diff --git a/docshell/base/nsIRefreshURI.idl b/docshell/base/nsIRefreshURI.idl index f872d8b7f..5abd829da 100644 --- a/docshell/base/nsIRefreshURI.idl +++ b/docshell/base/nsIRefreshURI.idl @@ -18,23 +18,35 @@ interface nsIRefreshURI : nsISupports { * queued and executed when the current load finishes. * * @param aUri The uri to refresh. + * @param aPrincipal The triggeringPrincipal for the refresh load + * May be null, in which case a principal will be built based on the + * referrer URI of the previous docshell load, or will use the system + * principal when there is no referrer. * @param aMillis The number of milliseconds to wait. * @param aRepeat Flag to indicate if the uri is to be * repeatedly refreshed every aMillis milliseconds. * @param aMetaRefresh Flag to indicate if this is a Meta refresh. */ - void refreshURI(in nsIURI aURI, in long aMillis, in boolean aRepeat, - in boolean aMetaRefresh); + void refreshURI(in nsIURI aURI, + in long aMillis, in boolean aRepeat, + in boolean aMetaRefresh, + [optional] in nsIPrincipal aPrincipal); /** * Loads a URI immediately as if it were a refresh. * * @param aURI The URI to refresh. + * @param aPrincipal The triggeringPrincipal for the refresh load + * May be null, in which case a principal will be built based on the + * referrer URI of the previous docshell load, or will use the system + * principal when there is no referrer. * @param aMillis The number of milliseconds by which this refresh would * be delayed if it were not being forced. * @param aMetaRefresh Flag to indicate if this is a meta refresh. */ - void forceRefreshURI(in nsIURI aURI, in long aMillis, in boolean aMetaRefresh); + void forceRefreshURI(in nsIURI aURI, + in long aMillis, in boolean aMetaRefresh, + [optional] in nsIPrincipal aPrincipal); /** * Checks the passed in channel to see if there is a refresh header, @@ -57,10 +69,15 @@ interface nsIRefreshURI : nsISupports { * the current page finishes loading. * * @param aBaseURI base URI to resolve refresh uri with. - * @param principal the associated principal + * @param aPrincipal The triggeringPrincipal for the refresh load + * May be null, in which case a principal will be built based on the + * referrer URI of the previous docshell load, or will use the system + * principal when there is no referrer. * @param aHeader The meta refresh header string. */ - void setupRefreshURIFromHeader(in nsIURI aBaseURI, in nsIPrincipal principal, in ACString aHeader); + void setupRefreshURIFromHeader(in nsIURI aBaseURI, + in nsIPrincipal principal, + in ACString aHeader); /** * Cancels all timer loads. diff --git a/gfx/thebes/gfxUserFontSet.h b/gfx/thebes/gfxUserFontSet.h index 081df4f2c..4687c939f 100644 --- a/gfx/thebes/gfxUserFontSet.h +++ b/gfx/thebes/gfxUserFontSet.h @@ -607,6 +607,10 @@ public: void GetFamilyNameAndURIForLogging(nsACString& aFamilyName, nsACString& aURI); +#ifdef DEBUG + gfxUserFontSet* GetUserFontSet() const { return mFontSet; } +#endif + protected: const uint8_t* SanitizeOpenTypeData(const uint8_t* aData, uint32_t aLength, diff --git a/layout/style/FontFace.cpp b/layout/style/FontFace.cpp index 1cf774059..9ae88417d 100644 --- a/layout/style/FontFace.cpp +++ b/layout/style/FontFace.cpp @@ -623,6 +623,11 @@ FontFace::SetUserFontEntry(gfxUserFontEntry* aEntry) if (mUserFontEntry) { mUserFontEntry->mFontFaces.AppendElement(this); + MOZ_ASSERT(mUserFontEntry->GetUserFontSet() == + mFontFaceSet->GetUserFontSet(), + "user font entry must be associated with the same user font set " + "as the FontFace"); + // Our newly assigned user font entry might be in the process of or // finished loading, so set our status accordingly. But only do so // if we're not going "backwards" in status, which could otherwise diff --git a/layout/style/FontFace.h b/layout/style/FontFace.h index 58072b6e5..d776a034e 100644 --- a/layout/style/FontFace.h +++ b/layout/style/FontFace.h @@ -90,6 +90,8 @@ public: void AddFontFaceSet(FontFaceSet* aFontFaceSet); void RemoveFontFaceSet(FontFaceSet* aFontFaceSet); + FontFaceSet* GetPrimaryFontFaceSet() const { return mFontFaceSet; } + /** * Gets the family name of the FontFace as a raw string (such as 'Times', as * opposed to GetFamily, which returns a CSS-escaped string, such as diff --git a/layout/style/FontFaceSet.cpp b/layout/style/FontFaceSet.cpp index b302c27c3..d7a6ccaca 100644 --- a/layout/style/FontFaceSet.cpp +++ b/layout/style/FontFaceSet.cpp @@ -953,7 +953,7 @@ FontFaceSet::InsertRuleFontFace(FontFace* aFontFace, SheetType aSheetType, mUserFontSet->AddUserFontEntry(fontfamily, entry); } -already_AddRefed +/* static */ already_AddRefed FontFaceSet::FindOrCreateUserFontEntryFromFontFace(FontFace* aFontFace) { nsAutoString fontfamily; @@ -967,11 +967,13 @@ FontFaceSet::FindOrCreateUserFontEntryFromFontFace(FontFace* aFontFace) SheetType::Doc); } -already_AddRefed +/* static */ already_AddRefed FontFaceSet::FindOrCreateUserFontEntryFromFontFace(const nsAString& aFamilyName, FontFace* aFontFace, SheetType aSheetType) { + FontFaceSet* set = aFontFace->GetPrimaryFontFaceSet(); + nsCSSValue val; nsCSSUnit unit; @@ -1099,7 +1101,7 @@ FontFaceSet::FindOrCreateUserFontEntryFromFontFace(const nsAString& aFamilyName, face->mSourceType = gfxFontFaceSrc::eSourceType_URL; face->mURI = val.GetURLValue(); face->mReferrer = val.GetURLStructValue()->mReferrer; - face->mReferrerPolicy = mDocument->GetReferrerPolicy(); + face->mReferrerPolicy = set->mDocument->GetReferrerPolicy(); face->mOriginPrincipal = val.GetURLStructValue()->mOriginPrincipal; NS_ASSERTION(face->mOriginPrincipal, "null origin principal in @font-face rule"); @@ -1160,11 +1162,11 @@ FontFaceSet::FindOrCreateUserFontEntryFromFontFace(const nsAString& aFamilyName, } RefPtr entry = - mUserFontSet->FindOrCreateUserFontEntry(aFamilyName, srcArray, weight, - stretch, italicStyle, - featureSettings, - languageOverride, - unicodeRanges); + set->mUserFontSet->FindOrCreateUserFontEntry(aFamilyName, srcArray, weight, + stretch, italicStyle, + featureSettings, + languageOverride, + unicodeRanges); return entry.forget(); } diff --git a/layout/style/FontFaceSet.h b/layout/style/FontFaceSet.h index 869e9b7cd..a18734368 100644 --- a/layout/style/FontFaceSet.h +++ b/layout/style/FontFaceSet.h @@ -122,7 +122,7 @@ public: * Finds an existing entry in the user font cache or creates a new user * font entry for the given FontFace object. */ - already_AddRefed + static already_AddRefed FindOrCreateUserFontEntryFromFontFace(FontFace* aFontFace); /** @@ -243,7 +243,7 @@ private: bool mLoadEventShouldFire; }; - already_AddRefed FindOrCreateUserFontEntryFromFontFace( + static already_AddRefed FindOrCreateUserFontEntryFromFontFace( const nsAString& aFamilyName, FontFace* aFontFace, SheetType aSheetType); diff --git a/layout/style/nsCSSParser.cpp b/layout/style/nsCSSParser.cpp index cb53785cd..61b2b5444 100644 --- a/layout/style/nsCSSParser.cpp +++ b/layout/style/nsCSSParser.cpp @@ -67,6 +67,7 @@ static bool sUnprefixingServiceGloballyWhitelisted; #endif static bool sMozGradientsEnabled; static bool sControlCharVisibility; +static bool sMozDocumentEnabledInContent; const uint32_t nsCSSProps::kParserVariantTable[eCSSProperty_COUNT_no_shorthands] = { @@ -3725,6 +3726,11 @@ CSSParserImpl::ParseMediaRule(RuleAppendFunc aAppendFunc, void* aData) bool CSSParserImpl::ParseMozDocumentRule(RuleAppendFunc aAppendFunc, void* aData) { + if (mParsingMode == css::eAuthorSheetFeatures && + !sMozDocumentEnabledInContent) { + return false; + } + css::DocumentRule::URL *urls = nullptr; css::DocumentRule::URL **next = &urls; @@ -16852,6 +16858,8 @@ nsCSSParser::Startup() "layout.css.prefixes.gradients"); Preferences::AddBoolVarCache(&sControlCharVisibility, "layout.css.control-characters.visible"); + Preferences::AddBoolVarCache(&sMozDocumentEnabledInContent, + "layout.css.moz-document.content.enabled"); } nsCSSParser::nsCSSParser(mozilla::css::Loader* aLoader, diff --git a/modules/libpref/init/all.js b/modules/libpref/init/all.js index 0acba78c1..6bc859de8 100644 --- a/modules/libpref/init/all.js +++ b/modules/libpref/init/all.js @@ -2230,6 +2230,9 @@ pref("layout.css.report_errors", true); // Should the :visited selector ever match (otherwise :link matches instead)? pref("layout.css.visited_links_enabled", true); +// Pref to control whether @-moz-document rules are enabled in content pages. +pref("layout.css.moz-document.content.enabled", true); // XXX: change in FPR6 + // Override DPI. A value of -1 means use the maximum of 96 and the system DPI. // A value of 0 means use the system DPI. A positive value is used as the DPI. // This sets the physical size of a device pixel and thus controls the diff --git a/netwerk/base/AutoClose.h b/netwerk/base/AutoClose.h index 79a6bda29..43ab27133 100644 --- a/netwerk/base/AutoClose.h +++ b/netwerk/base/AutoClose.h @@ -8,6 +8,7 @@ #define mozilla_net_AutoClose_h #include "nsCOMPtr.h" +#include "mozilla/Mutex.h" namespace mozilla { namespace net { @@ -18,49 +19,48 @@ template class AutoClose { public: - AutoClose() { } + AutoClose() : mMutex("net::AutoClose.mMutex") { } ~AutoClose(){ - Close(); + CloseAndRelease(); } - explicit operator bool() const + explicit operator bool() { + MutexAutoLock lock(mMutex); return mPtr; } already_AddRefed forget() { + MutexAutoLock lock(mMutex); return mPtr.forget(); } void takeOver(nsCOMPtr & rhs) { - Close(); - mPtr = rhs.forget(); - } - - void takeOver(AutoClose & rhs) - { - Close(); - mPtr = rhs.mPtr.forget(); + already_AddRefed other = rhs.forget(); + TakeOverInternal(&other); } void CloseAndRelease() { - Close(); - mPtr = nullptr; - } - - T* operator->() const MOZ_NO_ADDREF_RELEASE_ON_RETURN - { - return mPtr.operator->(); + TakeOverInternal(nullptr); } private: - void Close() + void TakeOverInternal(already_AddRefed *aOther) { - if (mPtr) { - mPtr->Close(); + nsCOMPtr ptr; + { + MutexAutoLock lock(mMutex); + ptr.swap(mPtr); + if (aOther) { + mPtr = *aOther; + } + } + + if (ptr) { + ptr->Close(); } } @@ -68,6 +68,7 @@ private: AutoClose(const AutoClose &) = delete; nsCOMPtr mPtr; + Mutex mMutex; }; } // namespace net diff --git a/netwerk/protocol/http/nsHttpChannel.cpp b/netwerk/protocol/http/nsHttpChannel.cpp index d372882e5..4d8ce5a8f 100644 --- a/netwerk/protocol/http/nsHttpChannel.cpp +++ b/netwerk/protocol/http/nsHttpChannel.cpp @@ -1096,8 +1096,9 @@ nsHttpChannel::CallOnStartRequest() LOG((" calling mListener->OnStartRequest\n")); if (mListener) { - MOZ_ASSERT(!mOnStartRequestCalled, - "We should not call OsStartRequest twice"); + NS_ASSERTION(!mOnStartRequestCalled, + "We should not call OsStartRequest twice"); + if (mOnStartRequestCalled) return NS_OK; rv = mListener->OnStartRequest(this, mListenerContext); mOnStartRequestCalled = true; if (NS_FAILED(rv)) diff --git a/startupcache/StartupCache.cpp b/startupcache/StartupCache.cpp index 5bd926245..eeaf6d229 100644 --- a/startupcache/StartupCache.cpp +++ b/startupcache/StartupCache.cpp @@ -738,6 +738,12 @@ StartupCacheWrapper* StartupCacheWrapper::gStartupCacheWrapper = nullptr; NS_IMPL_ISUPPORTS(StartupCacheWrapper, nsIStartupCache) +StartupCacheWrapper::~StartupCacheWrapper() +{ + MOZ_ASSERT(gStartupCacheWrapper == this); + gStartupCacheWrapper = nullptr; +} + StartupCacheWrapper* StartupCacheWrapper::GetSingleton() { if (!gStartupCacheWrapper) diff --git a/startupcache/StartupCache.h b/startupcache/StartupCache.h index cf874c3d1..3705fa7f8 100644 --- a/startupcache/StartupCache.h +++ b/startupcache/StartupCache.h @@ -214,7 +214,7 @@ class StartupCacheDebugOutputStream final class StartupCacheWrapper final : public nsIStartupCache { - ~StartupCacheWrapper() {} + ~StartupCacheWrapper(); NS_DECL_THREADSAFE_ISUPPORTS NS_DECL_NSISTARTUPCACHE diff --git a/toolkit/components/autocomplete/nsAutoCompleteController.cpp b/toolkit/components/autocomplete/nsAutoCompleteController.cpp index 6a5046360..a8c7ab474 100644 --- a/toolkit/components/autocomplete/nsAutoCompleteController.cpp +++ b/toolkit/components/autocomplete/nsAutoCompleteController.cpp @@ -1547,9 +1547,9 @@ nsAutoCompleteController::ProcessResult(int32_t aSearchIndex, nsIAutoCompleteRes if (mResults.IndexOf(aResult) == -1) { nsIAutoCompleteResult* oldResult = mResults.SafeObjectAt(aSearchIndex); if (oldResult) { - MOZ_ASSERT(false, "Passing new matches to OnSearchResult with a new " - "nsIAutoCompleteResult every time is deprecated, please " - "update the same result until the search is done"); + NS_ASSERTION(false, "Passing new matches to OnSearchResult with a new " + "nsIAutoCompleteResult every time is deprecated, please " + "update the same result until the search is done"); // Build a new nsIAutocompleteSimpleResult and merge results into it. RefPtr mergedResult = new nsAutoCompleteSimpleResult();