Bug 1505989 - pass around actual content policy types so they work even when using 'save page as', r=ckerschb
authorGijs Kruitbosch <gijskruitbosch@gmail.com>
Fri, 09 Nov 2018 14:48:11 +0000
changeset 445869 7e613710a9e121e1b903866148b3513ef312a47b
parent 445868 c52a3f7f06ad32032bf355cc4a3ac698832112a5
child 445870 2255173f959f40c0fc4f37981426dd22ddb96e8d
push id35027
push userrmaries@mozilla.com
push dateMon, 12 Nov 2018 17:18:42 +0000
treeherdermozilla-central@ea56fcfdbf72 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersckerschb
bugs1505989
milestone65.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Bug 1505989 - pass around actual content policy types so they work even when using 'save page as', r=ckerschb Depends on D11412 Differential Revision: https://phabricator.services.mozilla.com/D11413
dom/webbrowserpersist/PWebBrowserPersistResources.ipdl
dom/webbrowserpersist/WebBrowserPersistLocalDocument.cpp
dom/webbrowserpersist/WebBrowserPersistResourcesChild.cpp
dom/webbrowserpersist/WebBrowserPersistResourcesChild.h
dom/webbrowserpersist/WebBrowserPersistResourcesParent.cpp
dom/webbrowserpersist/WebBrowserPersistResourcesParent.h
dom/webbrowserpersist/nsIWebBrowserPersistDocument.idl
dom/webbrowserpersist/nsWebBrowserPersist.cpp
dom/webbrowserpersist/nsWebBrowserPersist.h
--- a/dom/webbrowserpersist/PWebBrowserPersistResources.ipdl
+++ b/dom/webbrowserpersist/PWebBrowserPersistResources.ipdl
@@ -7,17 +7,17 @@ include protocol PWebBrowserPersistDocum
 
 namespace mozilla {
 
 // == nsIWebBrowserPersistResourceVisitor
 protocol PWebBrowserPersistResources {
   manager PWebBrowserPersistDocument;
 
 parent:
-  async VisitResource(nsCString aURI);
+  async VisitResource(nsCString aURI, uint32_t aContentPolicyType);
 
   // The actor sent here is in the START state; the parent-side
   // receiver will have to wait for it to enter the MAIN state
   // before exposing it with a visitDocument call.
   async VisitDocument(PWebBrowserPersistDocument aSubDocument);
 
   // This reflects the endVisit method.
   async __delete__(nsresult aStatus);
--- a/dom/webbrowserpersist/WebBrowserPersistLocalDocument.cpp
+++ b/dom/webbrowserpersist/WebBrowserPersistLocalDocument.cpp
@@ -261,19 +261,20 @@ private:
     // The number of DocumentDone calls after which EndVisit will be
     // called on the visitor.  Counts the main document if it's still
     // being walked and any outstanding asynchronous subdocument
     // StartPersistence calls.
     size_t mOutstandingDocuments;
     // Collects the status parameters to DocumentDone calls.
     nsresult mEndStatus;
 
-    nsresult OnWalkURI(const nsACString& aURISpec);
-    nsresult OnWalkURI(nsIURI* aURI);
+    nsresult OnWalkURI(const nsACString& aURISpec, nsContentPolicyType aContentPolicyType);
+    nsresult OnWalkURI(nsIURI* aURI, nsContentPolicyType aContentPolicyType);
     nsresult OnWalkAttribute(Element* aElement,
+                             nsContentPolicyType aContentPolicyType,
                              const char* aAttribute,
                              const char* aNamespaceURI = "");
     nsresult OnWalkSubframe(nsINode* aNode);
 
     ~ResourceReader();
 
     using IWBP = nsIWebBrowserPersist;
 };
@@ -347,46 +348,46 @@ ResourceReader::OnDocumentReady(nsIWebBr
 NS_IMETHODIMP
 ResourceReader::OnError(nsresult aFailure)
 {
     DocumentDone(aFailure);
     return NS_OK;
 }
 
 nsresult
-ResourceReader::OnWalkURI(nsIURI* aURI)
+ResourceReader::OnWalkURI(nsIURI* aURI, nsContentPolicyType aContentPolicyType)
 {
     // Test if this URI should be persisted. By default
     // we should assume the URI  is persistable.
     bool doNotPersistURI;
     nsresult rv = NS_URIChainHasFlags(aURI,
                                       nsIProtocolHandler::URI_NON_PERSISTABLE,
                                       &doNotPersistURI);
     if (NS_SUCCEEDED(rv) && doNotPersistURI) {
         return NS_OK;
     }
 
     nsAutoCString stringURI;
     rv = aURI->GetSpec(stringURI);
     NS_ENSURE_SUCCESS(rv, rv);
-    return mVisitor->VisitResource(mParent, stringURI);
+    return mVisitor->VisitResource(mParent, stringURI, aContentPolicyType);
 }
 
 nsresult
-ResourceReader::OnWalkURI(const nsACString& aURISpec)
+ResourceReader::OnWalkURI(const nsACString& aURISpec, nsContentPolicyType aContentPolicyType)
 {
     nsresult rv;
     nsCOMPtr<nsIURI> uri;
 
     rv = NS_NewURI(getter_AddRefs(uri),
                    aURISpec,
                    mParent->GetCharacterSet(),
                    mCurrentBaseURI);
     NS_ENSURE_SUCCESS(rv, rv);
-    return OnWalkURI(uri);
+    return OnWalkURI(uri, aContentPolicyType);
 }
 
 static void
 ExtractAttribute(Element* aElement,
                  const char* aAttribute,
                  const char* aNamespaceURI,
                  nsCString&  aValue)
 {
@@ -404,25 +405,26 @@ ExtractAttribute(Element* aElement,
         CopyUTF16toUTF8(value, aValue);
     } else {
         aValue.Truncate();
     }
 }
 
 nsresult
 ResourceReader::OnWalkAttribute(Element* aElement,
+                                nsContentPolicyType aContentPolicyType,
                                 const char* aAttribute,
                                 const char* aNamespaceURI)
 {
     nsAutoCString uriSpec;
     ExtractAttribute(aElement, aAttribute, aNamespaceURI, uriSpec);
     if (uriSpec.IsEmpty()) {
         return NS_OK;
     }
-    return OnWalkURI(uriSpec);
+    return OnWalkURI(uriSpec, aContentPolicyType);
 }
 
 static nsresult
 GetXMLStyleSheetLink(dom::ProcessingInstruction *aPI, nsAString &aHref)
 {
     nsAutoString data;
     aPI->GetData(data);
 
@@ -436,71 +438,71 @@ ResourceReader::OnWalkDOMNode(nsINode* a
     // Fixup xml-stylesheet processing instructions
     if (auto nodeAsPI = dom::ProcessingInstruction::FromNode(aNode)) {
         nsAutoString target;
         nodeAsPI->GetTarget(target);
         if (target.EqualsLiteral("xml-stylesheet")) {
             nsAutoString href;
             GetXMLStyleSheetLink(nodeAsPI, href);
             if (!href.IsEmpty()) {
-                return OnWalkURI(NS_ConvertUTF16toUTF8(href));
+                return OnWalkURI(NS_ConvertUTF16toUTF8(href), nsIContentPolicy::TYPE_STYLESHEET);
             }
         }
         return NS_OK;
     }
 
     // Test the node to see if it's an image, frame, iframe, css, js
     if (aNode->IsHTMLElement(nsGkAtoms::img)) {
-        return OnWalkAttribute(aNode->AsElement(), "src");
+        return OnWalkAttribute(aNode->AsElement(), nsIContentPolicy::TYPE_IMAGE, "src");
     }
 
     if (aNode->IsSVGElement(nsGkAtoms::img)) {
-        return OnWalkAttribute(aNode->AsElement(), "href",
+        return OnWalkAttribute(aNode->AsElement(), nsIContentPolicy::TYPE_IMAGE, "href",
                                "http://www.w3.org/1999/xlink");
     }
 
     if (aNode->IsAnyOfHTMLElements(nsGkAtoms::audio, nsGkAtoms::video)) {
-        return OnWalkAttribute(aNode->AsElement(), "src");
+        return OnWalkAttribute(aNode->AsElement(), nsIContentPolicy::TYPE_MEDIA, "src");
     }
 
     if (aNode->IsHTMLElement(nsGkAtoms::source)) {
-        return OnWalkAttribute(aNode->AsElement(), "src");
+        return OnWalkAttribute(aNode->AsElement(), nsIContentPolicy::TYPE_MEDIA, "src");
     }
 
     if (aNode->IsHTMLElement(nsGkAtoms::body)) {
-        return OnWalkAttribute(aNode->AsElement(), "background");
+        return OnWalkAttribute(aNode->AsElement(), nsIContentPolicy::TYPE_IMAGE, "background");
     }
 
     if (aNode->IsHTMLElement(nsGkAtoms::table)) {
-        return OnWalkAttribute(aNode->AsElement(), "background");
+        return OnWalkAttribute(aNode->AsElement(), nsIContentPolicy::TYPE_IMAGE, "background");
     }
 
     if (aNode->IsHTMLElement(nsGkAtoms::tr)) {
-        return OnWalkAttribute(aNode->AsElement(), "background");
+        return OnWalkAttribute(aNode->AsElement(), nsIContentPolicy::TYPE_IMAGE, "background");
     }
 
     if (aNode->IsAnyOfHTMLElements(nsGkAtoms::td, nsGkAtoms::th)) {
-        return OnWalkAttribute(aNode->AsElement(), "background");
+        return OnWalkAttribute(aNode->AsElement(), nsIContentPolicy::TYPE_IMAGE, "background");
     }
 
     if (aNode->IsHTMLElement(nsGkAtoms::script)) {
-        return OnWalkAttribute(aNode->AsElement(), "src");
+        return OnWalkAttribute(aNode->AsElement(), nsIContentPolicy::TYPE_SCRIPT, "src");
     }
 
     if (aNode->IsSVGElement(nsGkAtoms::script)) {
-        return OnWalkAttribute(aNode->AsElement(), "href",
+        return OnWalkAttribute(aNode->AsElement(), nsIContentPolicy::TYPE_SCRIPT, "href",
                                "http://www.w3.org/1999/xlink");
     }
 
     if (aNode->IsHTMLElement(nsGkAtoms::embed)) {
-        return OnWalkAttribute(aNode->AsElement(), "src");
+        return OnWalkAttribute(aNode->AsElement(), nsIContentPolicy::TYPE_OBJECT, "src");
     }
 
     if (aNode->IsHTMLElement(nsGkAtoms::object)) {
-        return OnWalkAttribute(aNode->AsElement(), "data");
+        return OnWalkAttribute(aNode->AsElement(), nsIContentPolicy::TYPE_OBJECT, "data");
     }
 
     if (auto nodeAsLink = dom::HTMLLinkElement::FromNode(aNode)) {
         // Test if the link has a rel value indicating it to be a stylesheet
         nsAutoString linkRel;
         nodeAsLink->GetRel(linkRel);
         if (!linkRel.IsEmpty()) {
             nsReadingIterator<char16_t> start;
@@ -521,17 +523,17 @@ ResourceReader::OnWalkDOMNode(nsINode* a
                 nsReadingIterator<char16_t> startWord = current;
                 do {
                     ++current;
                 } while (current != end && !nsCRT::IsAsciiSpace(*current));
 
                 // Store the link for fix up if it says "stylesheet"
                 if (Substring(startWord, current)
                         .LowerCaseEqualsLiteral("stylesheet")) {
-                    OnWalkAttribute(aNode->AsElement(), "href");
+                    OnWalkAttribute(aNode->AsElement(), nsIContentPolicy::TYPE_STYLESHEET, "href");
                     return NS_OK;
                 }
                 if (current == end) {
                     break;
                 }
             }
         }
         return NS_OK;
@@ -543,17 +545,17 @@ ResourceReader::OnWalkDOMNode(nsINode* a
 
     if (aNode->IsHTMLElement(nsGkAtoms::iframe) &&
         !(mPersistFlags & IWBP::PERSIST_FLAGS_IGNORE_IFRAMES)) {
         return OnWalkSubframe(aNode);
     }
 
     auto nodeAsInput = dom::HTMLInputElement::FromNode(aNode);
     if (nodeAsInput) {
-        return OnWalkAttribute(aNode->AsElement(), "src");
+        return OnWalkAttribute(aNode->AsElement(), nsIContentPolicy::TYPE_IMAGE, "src");
     }
 
     return NS_OK;
 }
 
 // Helper class for node rewriting in writeContent().
 class PersistNodeFixup final : public nsIDocumentEncoderNodeFixup {
 public:
--- a/dom/webbrowserpersist/WebBrowserPersistResourcesChild.cpp
+++ b/dom/webbrowserpersist/WebBrowserPersistResourcesChild.cpp
@@ -17,20 +17,21 @@ NS_IMPL_ISUPPORTS(WebBrowserPersistResou
 WebBrowserPersistResourcesChild::WebBrowserPersistResourcesChild()
 {
 }
 
 WebBrowserPersistResourcesChild::~WebBrowserPersistResourcesChild() = default;
 
 NS_IMETHODIMP
 WebBrowserPersistResourcesChild::VisitResource(nsIWebBrowserPersistDocument *aDocument,
-                                               const nsACString& aURI)
+                                               const nsACString& aURI,
+                                               nsContentPolicyType aContentPolicyType)
 {
     nsCString copiedURI(aURI); // Yay, XPIDL/IPDL mismatch.
-    SendVisitResource(copiedURI);
+    SendVisitResource(copiedURI, aContentPolicyType);
     return NS_OK;
 }
 
 NS_IMETHODIMP
 WebBrowserPersistResourcesChild::VisitDocument(nsIWebBrowserPersistDocument* aDocument,
                                                nsIWebBrowserPersistDocument* aSubDocument)
 {
     auto* subActor = new WebBrowserPersistDocumentChild();
--- a/dom/webbrowserpersist/WebBrowserPersistResourcesChild.h
+++ b/dom/webbrowserpersist/WebBrowserPersistResourcesChild.h
@@ -5,16 +5,17 @@
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 #ifndef WebBrowserPersistResourcesChild_h__
 #define WebBrowserPersistResourcesChild_h__
 
 #include "mozilla/PWebBrowserPersistResourcesChild.h"
 
 #include "nsIWebBrowserPersistDocument.h"
+#include "nsIContentPolicy.h"
 
 namespace mozilla {
 
 class WebBrowserPersistResourcesChild final
     : public PWebBrowserPersistResourcesChild
     , public nsIWebBrowserPersistResourceVisitor
 {
 public:
--- a/dom/webbrowserpersist/WebBrowserPersistResourcesParent.cpp
+++ b/dom/webbrowserpersist/WebBrowserPersistResourcesParent.cpp
@@ -47,19 +47,19 @@ mozilla::ipc::IPCResult
 WebBrowserPersistResourcesParent::Recv__delete__(const nsresult& aStatus)
 {
     mVisitor->EndVisit(mDocument, aStatus);
     mVisitor = nullptr;
     return IPC_OK();
 }
 
 mozilla::ipc::IPCResult
-WebBrowserPersistResourcesParent::RecvVisitResource(const nsCString& aURI)
+WebBrowserPersistResourcesParent::RecvVisitResource(const nsCString& aURI, const nsContentPolicyType& aContentPolicyType)
 {
-    mVisitor->VisitResource(mDocument, aURI);
+    mVisitor->VisitResource(mDocument, aURI, aContentPolicyType);
     return IPC_OK();
 }
 
 mozilla::ipc::IPCResult
 WebBrowserPersistResourcesParent::RecvVisitDocument(PWebBrowserPersistDocumentParent* aSubDocument)
 {
     // Don't expose the subdocument to the visitor until it's ready
     // (until the actor isn't in START state).
--- a/dom/webbrowserpersist/WebBrowserPersistResourcesParent.h
+++ b/dom/webbrowserpersist/WebBrowserPersistResourcesParent.h
@@ -7,29 +7,30 @@
 #ifndef WebBrowserPersistResourcesParent_h__
 #define WebBrowserPersistResourcesParent_h__
 
 #include "mozilla/PWebBrowserPersistResourcesParent.h"
 
 #include "WebBrowserPersistDocumentParent.h"
 #include "nsCOMPtr.h"
 #include "nsIWebBrowserPersistDocument.h"
+#include "nsIContentPolicy.h"
 
 namespace mozilla {
 
 class WebBrowserPersistResourcesParent final
     : public PWebBrowserPersistResourcesParent
     , public nsIWebBrowserPersistDocumentReceiver
 {
 public:
     WebBrowserPersistResourcesParent(nsIWebBrowserPersistDocument* aDocument,
                                      nsIWebBrowserPersistResourceVisitor* aVisitor);
 
     virtual mozilla::ipc::IPCResult
-    RecvVisitResource(const nsCString& aURI) override;
+    RecvVisitResource(const nsCString& aURI, const nsContentPolicyType& aContentPolicyType) override;
 
     virtual mozilla::ipc::IPCResult
     RecvVisitDocument(PWebBrowserPersistDocumentParent* aSubDocument) override;
 
     virtual mozilla::ipc::IPCResult
     Recv__delete__(const nsresult& aStatus) override;
 
     virtual void
--- a/dom/webbrowserpersist/nsIWebBrowserPersistDocument.idl
+++ b/dom/webbrowserpersist/nsIWebBrowserPersistDocument.idl
@@ -1,15 +1,16 @@
 /* -*- Mode: IDL; indent-tabs-mode: nil; c-basic-offset: 2 -*-
  *
  * This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 #include "nsISupports.idl"
+#include "nsIContentPolicy.idl"
 
 interface nsIInputStream;
 interface nsIOutputStream;
 interface nsIPrincipal;
 interface nsITabParent;
 interface nsIWebBrowserPersistResourceVisitor;
 interface nsIWebBrowserPersistWriteCompletion;
 
@@ -129,19 +130,21 @@ interface nsIWebBrowserPersistDocument :
 interface nsIWebBrowserPersistResourceVisitor : nsISupports
 {
   /**
    * Indicates a resource that is not a document; e.g., an image, script,
    * or stylesheet.
    *
    * @param aDocument   The document containing the reference.
    * @param aURI        The absolute URI spec for the referenced resource.
+   * @param aContentPolicyType The type of resource.
    */
   void visitResource(in nsIWebBrowserPersistDocument aDocument,
-                     in AUTF8String aURI);
+                     in AUTF8String aURI,
+                     in nsContentPolicyType aContentPolicyType);
   /**
    * Indicates a subdocument resource; e.g., a frame or iframe.
    *
    * @param aDocument     The document containing the reference.
    * @param aSubDocument  The referenced document.
    */
   void visitDocument(in nsIWebBrowserPersistDocument aDocument,
                      in nsIWebBrowserPersistDocument aSubDocument);
--- a/dom/webbrowserpersist/nsWebBrowserPersist.cpp
+++ b/dom/webbrowserpersist/nsWebBrowserPersist.cpp
@@ -95,16 +95,17 @@ struct nsWebBrowserPersist::URIData
     bool mDataPathIsRelative;
     bool mNeedsFixup;
     nsString mFilename;
     nsString mSubFrameExt;
     nsCOMPtr<nsIURI> mFile;
     nsCOMPtr<nsIURI> mDataPath;
     nsCOMPtr<nsIURI> mRelativeDocumentURI;
     nsCOMPtr<nsIPrincipal> mTriggeringPrincipal;
+    nsContentPolicyType mContentPolicyType;
     nsCString mRelativePathToData;
     nsCString mCharset;
 
     nsresult GetLocalURI(nsIURI *targetBaseURI, nsCString& aSpecOut);
 };
 
 // Information about the output stream
 struct nsWebBrowserPersist::OutputData
@@ -437,17 +438,18 @@ NS_IMETHODIMP nsWebBrowserPersist::SaveP
 
     nsCOMPtr<nsIURI> fileAsURI;
     nsresult rv;
     rv = GetValidURIFromObject(aFile, getter_AddRefs(fileAsURI));
     NS_ENSURE_SUCCESS(rv, NS_ERROR_INVALID_ARG);
 
     // SaveURI doesn't like broken uris.
     mPersistFlags |= PERSIST_FLAGS_FAIL_ON_BROKEN_LINKS;
-    rv = SaveURIInternal(aURI, aPrincipal, aCacheKey,
+    rv = SaveURIInternal(aURI, aPrincipal,
+                         nsIContentPolicy::TYPE_SAVEAS_DOWNLOAD, aCacheKey,
                          aReferrer, aReferrerPolicy,
                          aPostData, aExtraHeaders, fileAsURI,
                          false, aIsPrivate);
     return NS_FAILED(rv) ? rv : NS_OK;
 }
 
 NS_IMETHODIMP nsWebBrowserPersist::SaveChannel(
     nsIChannel *aChannel, nsISupports *aFile)
@@ -626,17 +628,18 @@ nsWebBrowserPersist::SerializeNextFile()
             nsCOMPtr<nsIURI> fileAsURI = data->mDataPath;
             rv = AppendPathToURI(fileAsURI, data->mFilename, fileAsURI);
             if (NS_WARN_IF(NS_FAILED(rv))) {
                 break;
             }
 
             // The Referrer Policy doesn't matter here since the referrer is
             // nullptr.
-            rv = SaveURIInternal(uri, data->mTriggeringPrincipal, 0, nullptr,
+            rv = SaveURIInternal(uri, data->mTriggeringPrincipal,
+                                 data->mContentPolicyType, 0, nullptr,
                                  mozilla::net::RP_Unset, nullptr, nullptr,
                                  fileAsURI, true, mIsPrivate);
             // If SaveURIInternal fails, then it will have called EndDownload,
             // which means that |data| is no longer valid memory. We MUST bail.
             if (NS_WARN_IF(NS_FAILED(rv))) {
                 break;
             }
 
@@ -1324,16 +1327,17 @@ nsWebBrowserPersist::AppendPathToURI(nsI
 
     return NS_MutateURI(aURI)
              .SetPathQueryRef(newPath)
              .Finalize(aOutURI);
 }
 
 nsresult nsWebBrowserPersist::SaveURIInternal(
     nsIURI *aURI, nsIPrincipal* aTriggeringPrincipal,
+    nsContentPolicyType aContentPolicyType,
     uint32_t aCacheKey, nsIURI *aReferrer,
     uint32_t aReferrerPolicy, nsIInputStream *aPostData,
     const char *aExtraHeaders, nsIURI *aFile,
     bool aCalcFileExt, bool aIsPrivate)
 {
     NS_ENSURE_ARG_POINTER(aURI);
     NS_ENSURE_ARG_POINTER(aFile);
     NS_ENSURE_ARG_POINTER(aTriggeringPrincipal);
@@ -1701,30 +1705,31 @@ nsresult nsWebBrowserPersist::SaveDocume
         // Not walking DOMs, so go directly to serialization.
         SerializeNextFile();
         return NS_OK;
     }
 }
 
 NS_IMETHODIMP
 nsWebBrowserPersist::OnWalk::VisitResource(nsIWebBrowserPersistDocument* aDoc,
-                                           const nsACString& aURI)
+                                           const nsACString& aURI,
+                                           nsContentPolicyType aContentPolicyType)
 {
-    return mParent->StoreURI(nsAutoCString(aURI).get(), aDoc);
+    return mParent->StoreURI(nsAutoCString(aURI).get(), aDoc, aContentPolicyType);
 }
 
 NS_IMETHODIMP
 nsWebBrowserPersist::OnWalk::VisitDocument(nsIWebBrowserPersistDocument* aDoc,
                                              nsIWebBrowserPersistDocument* aSubDoc)
 {
     URIData* data = nullptr;
     nsAutoCString uriSpec;
     nsresult rv = aSubDoc->GetDocumentURI(uriSpec);
     NS_ENSURE_SUCCESS(rv, rv);
-    rv = mParent->StoreURI(uriSpec.get(), aDoc, false, &data);
+    rv = mParent->StoreURI(uriSpec.get(), aDoc, nsIContentPolicy::TYPE_SUBDOCUMENT, false, &data);
     NS_ENSURE_SUCCESS(rv, rv);
     if (!data) {
         // If the URI scheme isn't persistable, then don't persist.
         return NS_OK;
     }
     data->mIsSubFrame = true;
     return mParent->SaveSubframeContent(aSubDoc, aDoc, uriSpec, data);
 }
@@ -2456,33 +2461,35 @@ nsWebBrowserPersist::CalcTotalProgress()
         mTotalCurrentProgress = 10000;
         mTotalMaxProgress = 10000;
     }
 }
 
 nsresult
 nsWebBrowserPersist::StoreURI(
     const char *aURI, nsIWebBrowserPersistDocument *aDoc,
+    nsContentPolicyType aContentPolicyType,
     bool aNeedsPersisting, URIData **aData)
 {
     NS_ENSURE_ARG_POINTER(aURI);
 
     nsCOMPtr<nsIURI> uri;
     nsresult rv = NS_NewURI(getter_AddRefs(uri),
                             nsDependentCString(aURI),
                             mCurrentCharset.get(),
                             mCurrentBaseURI);
     NS_ENSURE_SUCCESS(rv, rv);
 
-    return StoreURI(uri, aDoc, aNeedsPersisting, aData);
+    return StoreURI(uri, aDoc, aContentPolicyType, aNeedsPersisting, aData);
 }
 
 nsresult
 nsWebBrowserPersist::StoreURI(
     nsIURI *aURI, nsIWebBrowserPersistDocument *aDoc,
+    nsContentPolicyType aContentPolicyType,
     bool aNeedsPersisting, URIData **aData)
 {
     NS_ENSURE_ARG_POINTER(aURI);
     if (aData)
     {
         *aData = nullptr;
     }
 
@@ -2498,17 +2505,17 @@ nsWebBrowserPersist::StoreURI(
     }
 
     if (doNotPersistURI)
     {
         return NS_OK;
     }
 
     URIData *data = nullptr;
-    MakeAndStoreLocalFilenameInURIMap(aURI, aDoc, aNeedsPersisting, &data);
+    MakeAndStoreLocalFilenameInURIMap(aURI, aDoc, aContentPolicyType, aNeedsPersisting, &data);
     if (aData)
     {
         *aData = data;
     }
 
     return NS_OK;
 }
 
@@ -2661,17 +2668,24 @@ nsWebBrowserPersist::SaveSubframeContent
     // of frames that are not documents, e.g. images.
     if (DocumentEncoderExists(contentType.get())) {
         auto toWalk = mozilla::MakeUnique<WalkData>();
         toWalk->mDocument = aFrameContent;
         toWalk->mFile = frameURI;
         toWalk->mDataPath = frameDataURI;
         mWalkStack.AppendElement(std::move(toWalk));
     } else {
-        rv = StoreURI(aURISpec.get(), aParentDocument);
+        nsContentPolicyType policyType = nsIContentPolicy::TYPE_OTHER;
+        if (StringBeginsWith(contentType, NS_LITERAL_CSTRING("image/"))) {
+          policyType = nsIContentPolicy::TYPE_IMAGE;
+        } else if (StringBeginsWith(contentType, NS_LITERAL_CSTRING("audio/")) ||
+                   StringBeginsWith(contentType, NS_LITERAL_CSTRING("video/"))) {
+          policyType = nsIContentPolicy::TYPE_MEDIA;
+        }
+        rv = StoreURI(aURISpec.get(), aParentDocument, policyType);
     }
     NS_ENSURE_SUCCESS(rv, rv);
 
     // Store the updated uri to the frame
     aData->mFile = frameURI;
     aData->mSubFrameExt.Truncate(); // we already put this in frameURI
 
     return NS_OK;
@@ -2695,17 +2709,18 @@ nsWebBrowserPersist::CreateChannelFromUR
     NS_ENSURE_SUCCESS(rv, rv);
     return NS_OK;
 }
 
 
 // we store the current location as the key (absolutized version of domnode's attribute's value)
 nsresult
 nsWebBrowserPersist::MakeAndStoreLocalFilenameInURIMap(
-    nsIURI *aURI, nsIWebBrowserPersistDocument *aDoc, bool aNeedsPersisting, URIData **aData)
+    nsIURI *aURI, nsIWebBrowserPersistDocument *aDoc, nsContentPolicyType aContentPolicyType,
+    bool aNeedsPersisting, URIData **aData)
 {
     NS_ENSURE_ARG_POINTER(aURI);
 
     nsAutoCString spec;
     nsresult rv = aURI->GetSpec(spec);
     NS_ENSURE_SUCCESS(rv, NS_ERROR_FAILURE);
 
     // Create a sensibly named filename for the URI and store in the URI map
@@ -2727,16 +2742,17 @@ nsWebBrowserPersist::MakeAndStoreLocalFi
     nsString filename;
     rv = MakeFilenameFromURI(aURI, filename);
     NS_ENSURE_SUCCESS(rv, NS_ERROR_FAILURE);
 
     // Store the file name
     data = new URIData;
     NS_ENSURE_TRUE(data, NS_ERROR_OUT_OF_MEMORY);
 
+    data->mContentPolicyType = aContentPolicyType;
     data->mNeedsPersisting = aNeedsPersisting;
     data->mNeedsFixup = true;
     data->mFilename = filename;
     data->mSaved = false;
     data->mIsSubFrame = false;
     data->mDataPath = mCurrentDataPath;
     data->mDataPathIsRelative = mCurrentDataPathIsRelative;
     data->mRelativePathToData = mCurrentRelativePathToData;
--- a/dom/webbrowserpersist/nsWebBrowserPersist.h
+++ b/dom/webbrowserpersist/nsWebBrowserPersist.h
@@ -15,16 +15,17 @@
 #include "nsIStreamListener.h"
 #include "nsIOutputStream.h"
 #include "nsIInputStream.h"
 #include "nsIChannel.h"
 #include "nsIDocumentEncoder.h"
 #include "nsITransport.h"
 #include "nsIProgressEventSink.h"
 #include "nsIFile.h"
+#include "nsIContentPolicy.h"
 #include "nsIWebProgressListener2.h"
 #include "nsIWebBrowserPersist.h"
 #include "nsIWebBrowserPersistDocument.h"
 
 #include "mozilla/UniquePtr.h"
 #include "nsClassHashtable.h"
 #include "nsHashKeys.h"
 #include "nsTArray.h"
@@ -52,16 +53,17 @@ public:
     NS_DECL_NSISTREAMLISTENER
     NS_DECL_NSIPROGRESSEVENTSINK
 
 // Private members
 private:
     virtual ~nsWebBrowserPersist();
     nsresult SaveURIInternal(
         nsIURI *aURI, nsIPrincipal* aTriggeringPrincipal,
+        nsContentPolicyType aContentPolicyType,
         uint32_t aCacheKey, nsIURI *aReferrer,
         uint32_t aReferrerPolicy, nsIInputStream *aPostData,
         const char *aExtraHeaders, nsIURI *aFile,
         bool aCalcFileExt, bool aIsPrivate);
     nsresult SaveChannelInternal(
         nsIChannel *aChannel, nsIURI *aFile, bool aCalcFileExt);
     nsresult SaveDocumentInternal(
         nsIWebBrowserPersistDocument *aDocument,
@@ -88,17 +90,18 @@ private:
 
     nsresult SaveDocumentDeferred(mozilla::UniquePtr<WalkData>&& aData);
     void Cleanup();
     void CleanupLocalFiles();
     nsresult GetValidURIFromObject(nsISupports *aObject, nsIURI **aURI) const;
     static nsresult GetLocalFileFromURI(nsIURI *aURI, nsIFile **aLocalFile);
     static nsresult AppendPathToURI(nsIURI *aURI, const nsAString & aPath, nsCOMPtr<nsIURI>& aOutURI);
     nsresult MakeAndStoreLocalFilenameInURIMap(
-        nsIURI *aURI, nsIWebBrowserPersistDocument *aDoc, bool aNeedsPersisting, URIData **aData);
+        nsIURI *aURI, nsIWebBrowserPersistDocument *aDoc, 
+        nsContentPolicyType aContentPolicyType, bool aNeedsPersisting, URIData **aData);
     nsresult MakeOutputStream(
         nsIURI *aFile, nsIOutputStream **aOutputStream);
     nsresult MakeOutputStreamFromFile(
         nsIFile *aFile, nsIOutputStream **aOutputStream);
     nsresult MakeOutputStreamFromURI(nsIURI *aURI, nsIOutputStream  **aOutStream);
     nsresult CreateChannelFromURI(nsIURI *aURI, nsIChannel **aChannel);
     nsresult StartUpload(nsIStorageStream *aOutStream, nsIURI *aDestinationURI,
         const nsACString &aContentType);
@@ -108,21 +111,23 @@ private:
                                        nsIURI *aOriginalURIWithExtension,
                                        nsCOMPtr<nsIURI>& aOutURI);
     nsresult CalculateUniqueFilename(nsIURI *aURI, nsCOMPtr<nsIURI>& aOutURI);
     nsresult MakeFilenameFromURI(
         nsIURI *aURI, nsString &aFilename);
     nsresult StoreURI(
         const char *aURI,
         nsIWebBrowserPersistDocument *aDoc,
+        nsContentPolicyType aContentPolicyType,
         bool aNeedsPersisting = true,
         URIData **aData = nullptr);
     nsresult StoreURI(
         nsIURI *aURI,
         nsIWebBrowserPersistDocument *aDoc,
+        nsContentPolicyType aContentPolicyType,
         bool aNeedsPersisting = true,
         URIData **aData = nullptr);
     bool DocumentEncoderExists(const char *aContentType);
 
     nsresult SaveSubframeContent(
         nsIWebBrowserPersistDocument *aFrameContent,
         nsIWebBrowserPersistDocument *aParentDocument,
         const nsCString& aURISpec,