diff --git a/dom/base/ChromeUtils.cpp b/dom/base/ChromeUtils.cpp index 37ca77ff7b5a..93ba6abfa706 100644 --- a/dom/base/ChromeUtils.cpp +++ b/dom/base/ChromeUtils.cpp @@ -1617,8 +1617,7 @@ void ChromeUtils::ClearResourceCache(GlobalObject&, Maybe chrome = aChrome.WasPassed() ? Some(aChrome.Value()) : Nothing(); SharedStyleSheetCache::Clear(chrome); SharedScriptCache::Clear(chrome); - imgLoader::PrivateBrowsingLoader()->ClearCache(chrome); - imgLoader::NormalLoader()->ClearCache(chrome); + imgLoader::ClearCache(Nothing(), chrome); } #define PROCTYPE_TO_WEBIDL_CASE(_procType, _webidl) \ diff --git a/dom/ipc/ContentChild.cpp b/dom/ipc/ContentChild.cpp index 22952b81b3bc..efc5e8b9c9f3 100644 --- a/dom/ipc/ContentChild.cpp +++ b/dom/ipc/ContentChild.cpp @@ -2106,35 +2106,13 @@ mozilla::ipc::IPCResult ContentChild::RecvClearScriptCache( return IPC_OK(); } -mozilla::ipc::IPCResult ContentChild::RecvClearImageCacheFromPrincipal( - nsIPrincipal* aPrincipal) { - imgLoader* loader; - if (aPrincipal->OriginAttributesRef().IsPrivateBrowsing()) { - loader = imgLoader::PrivateBrowsingLoader(); - } else { - loader = imgLoader::NormalLoader(); - } - - loader->RemoveEntriesInternal(Some(aPrincipal), Nothing(), Nothing()); - return IPC_OK(); -} - -mozilla::ipc::IPCResult ContentChild::RecvClearImageCacheFromSite( - const nsCString& aSchemelessSite, const OriginAttributesPattern& aPattern) { - imgLoader::NormalLoader()->RemoveEntriesInternal( - Nothing(), Some(aSchemelessSite), Some(aPattern)); - imgLoader::PrivateBrowsingLoader()->RemoveEntriesInternal( - Nothing(), Some(aSchemelessSite), Some(aPattern)); - - return IPC_OK(); -} - mozilla::ipc::IPCResult ContentChild::RecvClearImageCache( - const bool& privateLoader, const mozilla::Maybe& chrome) { - imgLoader* loader = privateLoader ? imgLoader::PrivateBrowsingLoader() - : imgLoader::NormalLoader(); - - loader->ClearCache(chrome); + const Maybe& aPrivateLoader, const Maybe& aChrome, + const Maybe>& aPrincipal, + const Maybe& aSchemelessSite, + const Maybe& aPattern) { + imgLoader::ClearCache(aPrincipal, aChrome, aPrincipal, aSchemelessSite, + aPattern); return IPC_OK(); } diff --git a/dom/ipc/ContentChild.h b/dom/ipc/ContentChild.h index e0284d464cad..0c06aa8580e3 100644 --- a/dom/ipc/ContentChild.h +++ b/dom/ipc/ContentChild.h @@ -256,13 +256,11 @@ class ContentChild final : public PContentChild, const Maybe& aSchemelessSite, const Maybe& aPattern); - mozilla::ipc::IPCResult RecvClearImageCacheFromPrincipal( - nsIPrincipal* aPrincipal); - mozilla::ipc::IPCResult RecvClearImageCacheFromSite( - const nsCString& aSchemelessSite, - const OriginAttributesPattern& aPattern); - mozilla::ipc::IPCResult RecvClearImageCache(const bool& privateLoader, - const Maybe& chrome); + mozilla::ipc::IPCResult RecvClearImageCache( + const Maybe& aPrivateLoader, const Maybe& aChrome, + const Maybe>& aPrincipal, + const Maybe& aSchemelessSite, + const Maybe& aPattern); PRemoteSpellcheckEngineChild* AllocPRemoteSpellcheckEngineChild(); diff --git a/dom/ipc/PContent.ipdl b/dom/ipc/PContent.ipdl index 74561b063aae..24fb69679f33 100644 --- a/dom/ipc/PContent.ipdl +++ b/dom/ipc/PContent.ipdl @@ -654,11 +654,11 @@ child: OverrideMapping[] overrides, nsCString locale, bool reset); async RegisterChromeItem(ChromeRegistryItem item); - async ClearImageCacheFromPrincipal(nullable nsIPrincipal aPrincipal); - - async ClearImageCacheFromSite(nsCString aSchemelessSite, OriginAttributesPattern aPattern); - - async ClearImageCache(bool privateLoader, bool? chrome); + async ClearImageCache(bool? privateLoader, + bool? aChrome, + nullable nsIPrincipal? aPrincipal, + nsCString? aSchemelessSite, + OriginAttributesPattern? aPattern); async ClearStyleSheetCache(bool? aChrome, nullable nsIPrincipal? aPrincipal, diff --git a/image/imgLoader.cpp b/image/imgLoader.cpp index 5f7437f31b6b..820990d7fc85 100644 --- a/image/imgLoader.cpp +++ b/image/imgLoader.cpp @@ -1372,17 +1372,28 @@ imgLoader::Observe(nsISupports* aSubject, const char* aTopic, } NS_IMETHODIMP -imgLoader::ClearCache(JS::Handle chrome) { - return ClearCache(chrome.isBoolean() ? Some(chrome.toBoolean()) : Nothing()); -} +imgLoader::ClearCache(JS::Handle aChrome) { + nsresult rv = NS_OK; -nsresult imgLoader::ClearCache(mozilla::Maybe chrome) { + Maybe chrome = + aChrome.isBoolean() ? Some(aChrome.toBoolean()) : Nothing(); if (XRE_IsParentProcess()) { bool privateLoader = this == gPrivateBrowsingLoader; - for (auto* cp : ContentParent::AllProcesses(ContentParent::eLive)) { - Unused << cp->SendClearImageCache(privateLoader, chrome); + rv = ClearCache(Some(privateLoader), chrome, Nothing(), Nothing(), + Nothing()); + + if (this == gNormalLoader || this == gPrivateBrowsingLoader) { + return rv; } + + // NOTE: There can be other loaders created with + // Cc["@mozilla.org/image/loader;1"].createInstance(Ci.imgILoader). + // If ClearCache is called on them, the above static ClearCache + // doesn't handle it, and ClearImageCache needs to be called on + // the current instance. + // The favicon handling and some tests can create such loaders. } + ClearOptions options; if (chrome) { if (*chrome) { @@ -1391,7 +1402,74 @@ nsresult imgLoader::ClearCache(mozilla::Maybe chrome) { options += ClearOption::ContentOnly; } } - return ClearImageCache(options); + nsresult rv2 = ClearImageCache(options); + + if (NS_FAILED(rv)) { + return rv; + } + return rv2; +} + +/*static */ +nsresult imgLoader::ClearCache( + mozilla::Maybe aPrivateLoader /* = mozilla::Nothing() */, + mozilla::Maybe aChrome /* = mozilla::Nothing() */, + const mozilla::Maybe>& + aPrincipal /* = mozilla::Nothing() */, + const mozilla::Maybe& aSchemelessSite /* = mozilla::Nothing() */, + const mozilla::Maybe& + aPattern /* = mozilla::Nothing() */) { + if (XRE_IsParentProcess()) { + for (auto* cp : ContentParent::AllProcesses(ContentParent::eLive)) { + Unused << cp->SendClearImageCache(aPrivateLoader, aChrome, aPrincipal, + aSchemelessSite, aPattern); + } + } + + if (aPrincipal) { + imgLoader* loader; + if ((*aPrincipal)->OriginAttributesRef().IsPrivateBrowsing()) { + loader = imgLoader::PrivateBrowsingLoader(); + } else { + loader = imgLoader::NormalLoader(); + } + + loader->RemoveEntriesInternal(aPrincipal, Nothing(), Nothing()); + return NS_OK; + } + + if (aSchemelessSite) { + if (!aPrivateLoader || !*aPrivateLoader) { + nsresult rv = imgLoader::NormalLoader()->RemoveEntriesInternal( + Nothing(), aSchemelessSite, aPattern); + NS_ENSURE_SUCCESS(rv, rv); + } + if (!aPrivateLoader || *aPrivateLoader) { + nsresult rv = imgLoader::PrivateBrowsingLoader()->RemoveEntriesInternal( + Nothing(), aSchemelessSite, aPattern); + NS_ENSURE_SUCCESS(rv, rv); + } + return NS_OK; + } + + ClearOptions options; + if (aChrome) { + if (*aChrome) { + options += ClearOption::ChromeOnly; + } else { + options += ClearOption::ContentOnly; + } + } + + if (!aPrivateLoader || !*aPrivateLoader) { + nsresult rv = imgLoader::NormalLoader()->ClearImageCache(options); + NS_ENSURE_SUCCESS(rv, rv); + } + if (!aPrivateLoader || *aPrivateLoader) { + nsresult rv = imgLoader::PrivateBrowsingLoader()->ClearImageCache(options); + NS_ENSURE_SUCCESS(rv, rv); + } + return NS_OK; } NS_IMETHODIMP @@ -1400,18 +1478,8 @@ imgLoader::RemoveEntriesFromPrincipalInAllProcesses(nsIPrincipal* aPrincipal) { return NS_ERROR_NOT_AVAILABLE; } - for (auto* cp : ContentParent::AllProcesses(ContentParent::eLive)) { - Unused << cp->SendClearImageCacheFromPrincipal(aPrincipal); - } - - imgLoader* loader; - if (aPrincipal->OriginAttributesRef().IsPrivateBrowsing()) { - loader = imgLoader::PrivateBrowsingLoader(); - } else { - loader = imgLoader::NormalLoader(); - } - - return loader->RemoveEntriesInternal(Some(aPrincipal), Nothing(), Nothing()); + nsCOMPtr principal = aPrincipal; + return ClearCache(Nothing(), Nothing(), Some(principal)); } NS_IMETHODIMP @@ -1428,12 +1496,8 @@ imgLoader::RemoveEntriesFromSiteInAllProcesses( return NS_ERROR_INVALID_ARG; } - for (auto* cp : ContentParent::AllProcesses(ContentParent::eLive)) { - Unused << cp->SendClearImageCacheFromSite(aSchemelessSite, pattern); - } - - return RemoveEntriesInternal(Nothing(), Some(nsCString(aSchemelessSite)), - Some(pattern)); + return ClearCache(Nothing(), Nothing(), Nothing(), + Some(nsCString(aSchemelessSite)), Some(pattern)); } nsresult imgLoader::RemoveEntriesInternal( diff --git a/image/imgLoader.h b/image/imgLoader.h index 47e7643d49ef..bc6e1a641f15 100644 --- a/image/imgLoader.h +++ b/image/imgLoader.h @@ -244,7 +244,40 @@ class imgLoader final : public imgILoader, imgLoader(); nsresult Init(); - nsresult ClearCache(mozilla::Maybe chrome); + /** + * Clear cache that matches the specified filters. + * If called on the parent process, clear cache from all processes. + * If called in the content process, clear cache within the process. + * + * @param aPrivateLoader + * If specified and true, clear private loader. + * If specified and false, clear normal loader. + * If not specified, clear both loaders. + * Has no effect with aPrincipal. + * @param aChrome + * If specified and true, clear chrome cache. + * If specified and false, clear content cache. + * If not specified, clear both. + * Has no effect with aPrincipal or aSchemelessSite. + * @param aPrincipal + * If specified, clear cache from the same origin and the same + * originAttributes of the passed principal. + * Exclusive with aSchemelessSite. + * @param aSchemelessSite + * If specified, clear cache which match the the given site. + * If this is specified, aPattern should also be specified. + * Exclusive with aPrincipal. + * @param aPattern + * The pattern used with aSchemelessSite. + */ + static nsresult ClearCache( + mozilla::Maybe aPrivateLoader = mozilla::Nothing(), + mozilla::Maybe aChrome = mozilla::Nothing(), + const mozilla::Maybe>& aPrincipal = + mozilla::Nothing(), + const mozilla::Maybe& aSchemelessSite = mozilla::Nothing(), + const mozilla::Maybe& aPattern = + mozilla::Nothing()); bool IsImageAvailable(nsIURI*, nsIPrincipal* aTriggeringPrincipal, mozilla::CORSMode, mozilla::dom::Document*);