Bug 1473509 - store principal information with the URIs to avoid having to locate documents after the fact, r=mccr8
authorGijs Kruitbosch <gijskruitbosch@gmail.com>
Fri, 06 Jul 2018 17:27:17 +0100
changeset 425409 d8e6b69bc535861c0c6127f8d5b726714cd1eead
parent 425329 79197e2d630ab38e53971c7e9a5b028940a05b63
child 425410 c8abaff6bcae7ce99d31b2f6dbaac3452e0db1d7
push id34245
push userdluca@mozilla.com
push dateSat, 07 Jul 2018 10:29:39 +0000
treeherdermozilla-central@1df83f663c81 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersmccr8
bugs1473509
milestone63.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 1473509 - store principal information with the URIs to avoid having to locate documents after the fact, r=mccr8 The way we currently save resource URIs that we discovered by walking the document isn't guaranteed to be in-order with when we save the documents they came from. To deduce the correct principal to use to load these subresources, we need to store it with the resource in the map of URIs we work with. MozReview-Commit-ID: GNlNuS6TuVV
dom/webbrowserpersist/nsWebBrowserPersist.cpp
dom/webbrowserpersist/nsWebBrowserPersist.h
--- a/dom/webbrowserpersist/nsWebBrowserPersist.cpp
+++ b/dom/webbrowserpersist/nsWebBrowserPersist.cpp
@@ -78,33 +78,33 @@ struct nsWebBrowserPersist::WalkData
 };
 
 // Information about a DOM document
 struct nsWebBrowserPersist::DocData
 {
     nsCOMPtr<nsIURI> mBaseURI;
     nsCOMPtr<nsIWebBrowserPersistDocument> mDocument;
     nsCOMPtr<nsIURI> mFile;
-    nsCOMPtr<nsIPrincipal> mPrincipal;
     nsCString mCharset;
 };
 
 // Information about a URI
 struct nsWebBrowserPersist::URIData
 {
     bool mNeedsPersisting;
     bool mSaved;
     bool mIsSubFrame;
     bool mDataPathIsRelative;
     bool mNeedsFixup;
     nsString mFilename;
     nsString mSubFrameExt;
     nsCOMPtr<nsIURI> mFile;
     nsCOMPtr<nsIURI> mDataPath;
     nsCOMPtr<nsIURI> mRelativeDocumentURI;
+    nsCOMPtr<nsIPrincipal> mTriggeringPrincipal;
     nsCString mRelativePathToData;
     nsCString mCharset;
 
     nsresult GetLocalURI(nsIURI *targetBaseURI, nsCString& aSpecOut);
 };
 
 // Information about the output stream
 struct nsWebBrowserPersist::OutputData
@@ -599,22 +599,16 @@ nsWebBrowserPersist::SerializeNextFile()
             URIData *data = iter.UserData();
             if (data->mNeedsPersisting && !data->mSaved) {
                 urisToPersist++;
             }
         }
     }
 
     if (urisToPersist > 0) {
-        nsCOMPtr<nsIPrincipal> docPrincipal;
-        //XXXgijs I *think* this is already always true, but let's be sure.
-        MOZ_ASSERT(mDocList.Length() > 0,
-            "Should have the document for any walked URIs to persist!");
-        nsresult rv = mDocList.ElementAt(0)->mDocument->
-            GetPrincipal(getter_AddRefs(docPrincipal));
         NS_ENSURE_SUCCESS_VOID(rv);
         // Persist each file in the uri map. The document(s)
         // will be saved after the last one of these is saved.
         for (auto iter = mURIMap.Iter(); !iter.Done(); iter.Next()) {
             URIData *data = iter.UserData();
 
             if (!data->mNeedsPersisting || data->mSaved) {
                 continue;
@@ -632,17 +626,17 @@ 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, docPrincipal, 0, nullptr,
+            rv = SaveURIInternal(uri, data->mTriggeringPrincipal, 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;
             }
 
@@ -1709,35 +1703,35 @@ nsresult nsWebBrowserPersist::SaveDocume
         return NS_OK;
     }
 }
 
 NS_IMETHODIMP
 nsWebBrowserPersist::OnWalk::VisitResource(nsIWebBrowserPersistDocument* aDoc,
                                            const nsACString& aURI)
 {
-    return mParent->StoreURI(nsAutoCString(aURI).get());
+    return mParent->StoreURI(nsAutoCString(aURI).get(), aDoc);
 }
 
 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(), false, &data);
+    rv = mParent->StoreURI(uriSpec.get(), aDoc, 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, uriSpec, data);
+    return mParent->SaveSubframeContent(aSubDoc, aDoc, uriSpec, data);
 }
 
 
 NS_IMETHODIMP
 nsWebBrowserPersist::OnWalk::EndVisit(nsIWebBrowserPersistDocument* aDoc,
                                       nsresult aStatus)
 {
     if (NS_FAILED(aStatus)) {
@@ -2461,33 +2455,35 @@ nsWebBrowserPersist::CalcTotalProgress()
         // No output streams so we must be complete
         mTotalCurrentProgress = 10000;
         mTotalMaxProgress = 10000;
     }
 }
 
 nsresult
 nsWebBrowserPersist::StoreURI(
-    const char *aURI, bool aNeedsPersisting, URIData **aData)
+    const char *aURI, nsIWebBrowserPersistDocument *aDoc,
+    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, aNeedsPersisting, aData);
+    return StoreURI(uri, aDoc, aNeedsPersisting, aData);
 }
 
 nsresult
 nsWebBrowserPersist::StoreURI(
-    nsIURI *aURI, bool aNeedsPersisting, URIData **aData)
+    nsIURI *aURI, nsIWebBrowserPersistDocument *aDoc,
+    bool aNeedsPersisting, URIData **aData)
 {
     NS_ENSURE_ARG_POINTER(aURI);
     if (aData)
     {
         *aData = nullptr;
     }
 
     // Test if this URI should be persisted. By default
@@ -2502,17 +2498,17 @@ nsWebBrowserPersist::StoreURI(
     }
 
     if (doNotPersistURI)
     {
         return NS_OK;
     }
 
     URIData *data = nullptr;
-    MakeAndStoreLocalFilenameInURIMap(aURI, aNeedsPersisting, &data);
+    MakeAndStoreLocalFilenameInURIMap(aURI, aDoc, aNeedsPersisting, &data);
     if (aData)
     {
         *aData = data;
     }
 
     return NS_OK;
 }
 
@@ -2607,16 +2603,17 @@ nsWebBrowserPersist::DocumentEncoderExis
         }
     }
     return false;
 }
 
 nsresult
 nsWebBrowserPersist::SaveSubframeContent(
     nsIWebBrowserPersistDocument *aFrameContent,
+    nsIWebBrowserPersistDocument *aParentDocument,
     const nsCString& aURISpec,
     URIData *aData)
 {
     NS_ENSURE_ARG_POINTER(aData);
 
     // Extract the content type for the frame's contents.
     nsAutoCString contentType;
     nsresult rv = aFrameContent->GetContentType(contentType);
@@ -2680,17 +2677,17 @@ 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());
+        rv = StoreURI(aURISpec.get(), aParentDocument);
     }
     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;
@@ -2714,17 +2711,17 @@ 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, bool aNeedsPersisting, URIData **aData)
+    nsIURI *aURI, nsIWebBrowserPersistDocument *aDoc, 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
@@ -2757,16 +2754,18 @@ nsWebBrowserPersist::MakeAndStoreLocalFi
     data->mSaved = false;
     data->mIsSubFrame = false;
     data->mDataPath = mCurrentDataPath;
     data->mDataPathIsRelative = mCurrentDataPathIsRelative;
     data->mRelativePathToData = mCurrentRelativePathToData;
     data->mRelativeDocumentURI = mTargetBaseURI;
     data->mCharset = mCurrentCharset;
 
+    aDoc->GetPrincipal(getter_AddRefs(data->mTriggeringPrincipal));
+
     if (aNeedsPersisting)
         mCurrentThingsToPersist++;
 
     mURIMap.Put(spec, data);
     if (aData)
     {
         *aData = data;
     }
--- a/dom/webbrowserpersist/nsWebBrowserPersist.h
+++ b/dom/webbrowserpersist/nsWebBrowserPersist.h
@@ -89,17 +89,17 @@ 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, bool aNeedsPersisting, URIData **aData);
+        nsIURI *aURI, nsIWebBrowserPersistDocument *aDoc, 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,26 +108,29 @@ private:
     nsresult CalculateAndAppendFileExt(nsIURI *aURI, nsIChannel *aChannel,
                                        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,
         bool aNeedsPersisting = true,
         URIData **aData = nullptr);
     nsresult StoreURI(
         nsIURI *aURI,
+        nsIWebBrowserPersistDocument *aDoc,
         bool aNeedsPersisting = true,
         URIData **aData = nullptr);
     bool DocumentEncoderExists(const char *aContentType);
 
     nsresult SaveSubframeContent(
         nsIWebBrowserPersistDocument *aFrameContent,
+        nsIWebBrowserPersistDocument *aParentDocument,
         const nsCString& aURISpec,
         URIData *aData);
     nsresult SendErrorStatusChange(
         bool aIsReadError, nsresult aResult, nsIRequest *aRequest, nsIURI *aURI);
 
     nsresult FixRedirectedChannelEntry(nsIChannel *aNewChannel);
 
     void EndDownload(nsresult aResult);