Bug 1425843 - Pass correct referrer and referrer policy when fetching modules r=smaug
authorJon Coppeard <jcoppeard@mozilla.com>
Tue, 19 Dec 2017 15:30:49 +0000
changeset 396844 fd6d8af1cda716d5dd7f876384d4af9898efe2f7
parent 396843 8e6356ea82b27a29aad6a0eea2bfa850dc4fd893
child 396845 e8318c6db1a0e470f75b71284bb9623c5d5119ec
push id98380
push userjcoppeard@mozilla.com
push dateTue, 19 Dec 2017 15:45:30 +0000
treeherdermozilla-inbound@e8318c6db1a0 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewerssmaug
bugs1425843
milestone59.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 1425843 - Pass correct referrer and referrer policy when fetching modules r=smaug
dom/script/ModuleLoadRequest.cpp
dom/script/ModuleLoadRequest.h
dom/script/ScriptLoadRequest.cpp
dom/script/ScriptLoadRequest.h
dom/script/ScriptLoader.cpp
dom/script/ScriptLoader.h
testing/web-platform/meta/html/semantics/scripting-1/the-script-element/module/referrer-no-referrer.sub.html.ini
testing/web-platform/meta/html/semantics/scripting-1/the-script-element/module/referrer-origin-when-cross-origin.sub.html.ini
testing/web-platform/meta/html/semantics/scripting-1/the-script-element/module/referrer-origin.sub.html.ini
testing/web-platform/meta/html/semantics/scripting-1/the-script-element/module/referrer-same-origin.sub.html.ini
testing/web-platform/meta/html/semantics/scripting-1/the-script-element/module/referrer-unsafe-url.sub.html.ini
--- a/dom/script/ModuleLoadRequest.cpp
+++ b/dom/script/ModuleLoadRequest.cpp
@@ -27,47 +27,52 @@ NS_IMPL_CYCLE_COLLECTION_INHERITED(Modul
 NS_IMPL_ADDREF_INHERITED(ModuleLoadRequest, ScriptLoadRequest)
 NS_IMPL_RELEASE_INHERITED(ModuleLoadRequest, ScriptLoadRequest)
 
 ModuleLoadRequest::ModuleLoadRequest(nsIURI* aURI,
                                      nsIScriptElement* aElement,
                                      ValidJSVersion aValidJSVersion,
                                      CORSMode aCORSMode,
                                      const SRIMetadata& aIntegrity,
+                                     nsIURI* aReferrer,
+                                     mozilla::net::ReferrerPolicy aReferrerPolicy,
                                      ScriptLoader* aLoader)
   : ScriptLoadRequest(ScriptKind::Module,
                       aURI,
                       aElement,
                       aValidJSVersion,
                       aCORSMode,
-                      aIntegrity),
+                      aIntegrity,
+                      aReferrer,
+                      aReferrerPolicy),
     mIsTopLevel(true),
     mLoader(aLoader),
     mVisitedSet(new VisitedURLSet())
 {
   mVisitedSet->PutEntry(aURI);
 }
 
 ModuleLoadRequest::ModuleLoadRequest(nsIURI* aURI,
                                      ModuleLoadRequest* aParent)
   : ScriptLoadRequest(ScriptKind::Module,
                       aURI,
                       aParent->mElement,
                       aParent->mValidJSVersion,
                       aParent->mCORSMode,
-                      aParent->mIntegrity),
+                      aParent->mIntegrity,
+                      aParent->mURI,
+                      aParent->mReferrerPolicy),
     mIsTopLevel(false),
     mLoader(aParent->mLoader),
     mVisitedSet(aParent->mVisitedSet)
 {
   MOZ_ASSERT(mVisitedSet->Contains(aURI));
 
   mTriggeringPrincipal = aParent->mTriggeringPrincipal;
   mIsInline = false;
-  mReferrerPolicy = aParent->mReferrerPolicy;
 }
 
 void
 ModuleLoadRequest::Cancel()
 {
   ScriptLoadRequest::Cancel();
   mModuleScript = nullptr;
   mProgress = ScriptLoadRequest::Progress::Ready;
--- a/dom/script/ModuleLoadRequest.h
+++ b/dom/script/ModuleLoadRequest.h
@@ -43,16 +43,18 @@ public:
   NS_DECL_CYCLE_COLLECTION_CLASS_INHERITED(ModuleLoadRequest, ScriptLoadRequest)
 
   // Create a top-level module load request.
   ModuleLoadRequest(nsIURI* aURI,
                     nsIScriptElement* aElement,
                     ValidJSVersion aValidJSVersion,
                     CORSMode aCORSMode,
                     const SRIMetadata& aIntegrity,
+                    nsIURI* aReferrer,
+                    mozilla::net::ReferrerPolicy,
                     ScriptLoader* aLoader);
 
   // Create a module load request for an imported module.
   ModuleLoadRequest(nsIURI* aURI,
                     ModuleLoadRequest* aParent);
 
   bool IsTopLevel() const
   {
--- a/dom/script/ScriptLoadRequest.cpp
+++ b/dom/script/ScriptLoadRequest.cpp
@@ -38,17 +38,19 @@ NS_IMPL_CYCLE_COLLECTION_TRACE_BEGIN(Scr
   NS_IMPL_CYCLE_COLLECTION_TRACE_JS_MEMBER_CALLBACK(mScript)
 NS_IMPL_CYCLE_COLLECTION_TRACE_END
 
 ScriptLoadRequest::ScriptLoadRequest(ScriptKind aKind,
                                      nsIURI* aURI,
                                      nsIScriptElement* aElement,
                                      ValidJSVersion aValidJSVersion,
                                      mozilla::CORSMode aCORSMode,
-                                     const mozilla::dom::SRIMetadata& aIntegrity)
+                                     const mozilla::dom::SRIMetadata& aIntegrity,
+                                     nsIURI* aReferrer,
+                                     mozilla::net::ReferrerPolicy aReferrerPolicy)
   : mKind(aKind)
   , mElement(aElement)
   , mScriptFromHead(false)
   , mProgress(Progress::Loading)
   , mDataType(DataType::Unknown)
   , mIsInline(true)
   , mHasSourceMapURL(false)
   , mIsDefer(false)
@@ -64,17 +66,18 @@ ScriptLoadRequest::ScriptLoadRequest(Scr
   , mScriptText()
   , mScriptBytecode()
   , mBytecodeOffset(0)
   , mValidJSVersion(aValidJSVersion)
   , mURI(aURI)
   , mLineNo(1)
   , mCORSMode(aCORSMode)
   , mIntegrity(aIntegrity)
-  , mReferrerPolicy(mozilla::net::RP_Unset)
+  , mReferrer(aReferrer)
+  , mReferrerPolicy(aReferrerPolicy)
 {
 }
 
 ScriptLoadRequest::~ScriptLoadRequest()
 {
   // We should always clean up any off-thread script parsing resources.
   MOZ_ASSERT(!mOffThreadToken);
 
--- a/dom/script/ScriptLoadRequest.h
+++ b/dom/script/ScriptLoadRequest.h
@@ -51,17 +51,19 @@ protected:
   virtual ~ScriptLoadRequest();
 
 public:
   ScriptLoadRequest(ScriptKind aKind,
                     nsIURI* aURI,
                     nsIScriptElement* aElement,
                     ValidJSVersion aValidJSVersion,
                     mozilla::CORSMode aCORSMode,
-                    const mozilla::dom::SRIMetadata &aIntegrity);
+                    const mozilla::dom::SRIMetadata &aIntegrity,
+                    nsIURI* aReferrer,
+                    mozilla::net::ReferrerPolicy aReferrerPolicy);
 
   NS_DECL_CYCLE_COLLECTING_ISUPPORTS
   NS_DECL_CYCLE_COLLECTION_SCRIPT_HOLDER_CLASS(ScriptLoadRequest)
 
   bool IsModuleRequest() const
   {
     return mKind == ScriptKind::Module;
   }
@@ -189,17 +191,18 @@ public:
   ValidJSVersion mValidJSVersion;
   const nsCOMPtr<nsIURI> mURI;
   nsCOMPtr<nsIPrincipal> mTriggeringPrincipal;
   nsCOMPtr<nsIPrincipal> mOriginPrincipal;
   nsAutoCString mURL;     // Keep the URI's filename alive during off thread parsing.
   int32_t mLineNo;
   const mozilla::CORSMode mCORSMode;
   const mozilla::dom::SRIMetadata mIntegrity;
-  mozilla::net::ReferrerPolicy mReferrerPolicy;
+  const nsCOMPtr<nsIURI> mReferrer;
+  const mozilla::net::ReferrerPolicy mReferrerPolicy;
 
   // Holds the Cache information, which is used to register the bytecode
   // on the cache entry, such that we can load it the next time.
   nsCOMPtr<nsICacheInfoChannel> mCacheInfo;
 };
 
 class ScriptLoadRequestList : private mozilla::LinkedList<ScriptLoadRequest>
 {
--- a/dom/script/ScriptLoader.cpp
+++ b/dom/script/ScriptLoader.cpp
@@ -1100,17 +1100,17 @@ ScriptLoader::StartLoad(ScriptLoadReques
 
   nsCOMPtr<nsIHttpChannel> httpChannel(do_QueryInterface(channel));
   if (httpChannel) {
     // HTTP content negotation has little value in this context.
     rv = httpChannel->SetRequestHeader(NS_LITERAL_CSTRING("Accept"),
                                        NS_LITERAL_CSTRING("*/*"),
                                        false);
     MOZ_ASSERT(NS_SUCCEEDED(rv));
-    rv = httpChannel->SetReferrerWithPolicy(mDocument->GetDocumentURI(),
+    rv = httpChannel->SetReferrerWithPolicy(aRequest->mReferrer,
                                             aRequest->mReferrerPolicy);
     MOZ_ASSERT(NS_SUCCEEDED(rv));
 
     nsCOMPtr<nsIHttpChannelInternal> internalChannel(do_QueryInterface(httpChannel));
     if (internalChannel) {
       rv = internalChannel->SetIntegrityMetadata(aRequest->mIntegrity.GetIntegrityString());
       MOZ_ASSERT(NS_SUCCEEDED(rv));
     }
@@ -1258,29 +1258,33 @@ CSPAllowsInlineScript(nsIScriptElement* 
 }
 
 ScriptLoadRequest*
 ScriptLoader::CreateLoadRequest(ScriptKind aKind,
                                 nsIURI* aURI,
                                 nsIScriptElement* aElement,
                                 ValidJSVersion aValidJSVersion,
                                 CORSMode aCORSMode,
-                                const SRIMetadata& aIntegrity)
+                                const SRIMetadata& aIntegrity,
+                                mozilla::net::ReferrerPolicy aReferrerPolicy)
 {
+  nsIURI* referrer = mDocument->GetDocumentURI();
+
   if (aKind == ScriptKind::Classic) {
     ScriptLoadRequest* slr = new ScriptLoadRequest(aKind, aURI, aElement,
-                                 aValidJSVersion, aCORSMode, aIntegrity);
+                                                   aValidJSVersion, aCORSMode, aIntegrity,
+                                                   referrer, aReferrerPolicy);
 
     LOG(("ScriptLoader %p creates ScriptLoadRequest %p", this, slr));
     return slr;
   }
 
   MOZ_ASSERT(aKind == ScriptKind::Module);
   return new ModuleLoadRequest(aURI, aElement, aValidJSVersion, aCORSMode,
-                               aIntegrity, this);
+                               aIntegrity, referrer, aReferrerPolicy, this);
 }
 
 bool
 ScriptLoader::ProcessScriptElement(nsIScriptElement* aElement)
 {
   // We need a document to evaluate scripts.
   NS_ENSURE_TRUE(mDocument, false);
 
@@ -1336,30 +1340,30 @@ ScriptLoader::ProcessScriptElement(nsISc
       scriptContent->IsHTMLElement() &&
       scriptContent->HasAttr(kNameSpaceID_None, nsGkAtoms::nomodule)) {
     return false;
   }
 
   // Step 15. and later in the HTML5 spec
   nsresult rv = NS_OK;
   RefPtr<ScriptLoadRequest> request;
+  mozilla::net::ReferrerPolicy ourRefPolicy = mDocument->GetReferrerPolicy();
   if (aElement->GetScriptExternal()) {
     // external script
     nsCOMPtr<nsIURI> scriptURI = aElement->GetScriptURI();
     if (!scriptURI) {
       // Asynchronously report the failure to create a URI object
       NS_DispatchToCurrentThread(
         NewRunnableMethod("nsIScriptElement::FireErrorEvent",
                           aElement,
                           &nsIScriptElement::FireErrorEvent));
       return false;
     }
 
     // Double-check that the preload matches what we're asked to load now.
-    mozilla::net::ReferrerPolicy ourRefPolicy = mDocument->GetReferrerPolicy();
     CORSMode ourCORSMode = aElement->GetCORSMode();
     nsTArray<PreloadInfo>::index_type i =
       mPreloads.IndexOf(scriptURI.get(), 0, PreloadURIComparator());
     if (i != nsTArray<PreloadInfo>::NoIndex) {
       // preloaded
       // note that a script-inserted script can steal a preload!
       request = mPreloads[i].mRequest;
       request->mElement = aElement;
@@ -1409,20 +1413,20 @@ ScriptLoader::ProcessScriptElement(nsISc
       }
 
       nsCOMPtr<nsIPrincipal> principal = aElement->GetScriptURITriggeringPrincipal();
       if (!principal) {
         principal = scriptContent->NodePrincipal();
       }
 
       request = CreateLoadRequest(scriptKind, scriptURI, aElement,
-                                  validJSVersion, ourCORSMode, sriMetadata);
+                                  validJSVersion, ourCORSMode, sriMetadata,
+                                  ourRefPolicy);
       request->mTriggeringPrincipal = Move(principal);
       request->mIsInline = false;
-      request->mReferrerPolicy = ourRefPolicy;
       // keep request->mScriptFromHead to false so we don't treat non preloaded
       // scripts as blockers for full page load. See bug 792438.
 
       rv = StartLoad(request);
       if (NS_FAILED(rv)) {
         const char* message;
         bool isScript = scriptKind == ScriptKind::Classic;
         if (rv == NS_ERROR_MALFORMED_URI) {
@@ -1554,20 +1558,21 @@ ScriptLoader::ProcessScriptElement(nsISc
     return false;
   }
 
   // Does CSP allow this inline script to run?
   if (!CSPAllowsInlineScript(aElement, mDocument)) {
     return false;
   }
 
-  // Inline scripts ignore ther CORS mode and are always CORS_NONE
+  // Inline scripts ignore ther CORS mode and are always CORS_NONE.
   request = CreateLoadRequest(scriptKind, mDocument->GetDocumentURI(), aElement,
                               validJSVersion, CORS_NONE,
-                              SRIMetadata()); // SRI doesn't apply
+                              SRIMetadata(), // SRI doesn't apply
+                              ourRefPolicy);
   request->mValidJSVersion = validJSVersion;
   request->mIsInline = true;
   request->mTriggeringPrincipal = mDocument->NodePrincipal();
   request->mLineNo = aElement->GetScriptLineNumber();
   request->mProgress = ScriptLoadRequest::Progress::Loading_Source;
   request->mDataType = ScriptLoadRequest::DataType::Source;
   TRACE_FOR_TEST_BOOL(request->mElement, "scriptloader_load_source");
   CollectScriptTelemetry(nullptr, request);
@@ -3150,20 +3155,20 @@ ScriptLoader::PreloadURI(nsIURI* aURI, c
     if (mDocument->GetDocumentURI()) {
       mDocument->GetDocumentURI()->GetAsciiSpec(sourceUri);
     }
     SRICheck::IntegrityMetadata(aIntegrity, sourceUri, mReporter, &sriMetadata);
   }
 
   RefPtr<ScriptLoadRequest> request =
     CreateLoadRequest(ScriptKind::Classic, aURI, nullptr, ValidJSVersion::Valid,
-                      Element::StringToCORSMode(aCrossOrigin), sriMetadata);
+                      Element::StringToCORSMode(aCrossOrigin), sriMetadata,
+                      aReferrerPolicy);
   request->mTriggeringPrincipal = mDocument->NodePrincipal();
   request->mIsInline = false;
-  request->mReferrerPolicy = aReferrerPolicy;
   request->mScriptFromHead = aScriptFromHead;
   request->mPreloadAsAsync = aAsync;
   request->mPreloadAsDefer = aDefer;
 
   nsresult rv = StartLoad(request);
   if (NS_FAILED(rv)) {
     return;
   }
--- a/dom/script/ScriptLoader.h
+++ b/dom/script/ScriptLoader.h
@@ -339,17 +339,18 @@ public:
 private:
   virtual ~ScriptLoader();
 
   ScriptLoadRequest* CreateLoadRequest(ScriptKind aKind,
                                        nsIURI* aURI,
                                        nsIScriptElement* aElement,
                                        ValidJSVersion aValidJSVersion,
                                        mozilla::CORSMode aCORSMode,
-                                       const mozilla::dom::SRIMetadata& aIntegrity);
+                                       const mozilla::dom::SRIMetadata& aIntegrity,
+                                       mozilla::net::ReferrerPolicy aReferrerPolicy);
 
   /**
    * Unblocks the creator parser of the parser-blocking scripts.
    */
   void UnblockParser(ScriptLoadRequest* aParserBlockingRequest);
 
   /**
    * Asynchronously resumes the creator parser of the parser-blocking scripts.
deleted file mode 100644
--- a/testing/web-platform/meta/html/semantics/scripting-1/the-script-element/module/referrer-no-referrer.sub.html.ini
+++ /dev/null
@@ -1,16 +0,0 @@
-[referrer-no-referrer.sub.html]
-  [Importing a same-origin top-level script with the no-referrer policy.]
-    expected: FAIL
-
-  [Importing a remote-origin top-level script with the no-referrer policy.]
-    expected: FAIL
-
-  [Importing a same-origin descendant script from a same-origin top-level script with the no-referrer policy.]
-    expected: FAIL
-
-  [Importing a remote-origin descendant script from a same-origin top-level script with the no-referrer policy.]
-    expected: FAIL
-
-  [Importing a remote-origin descendant script from a remote-origin top-level script with the no-referrer policy.]
-    expected: FAIL
-
deleted file mode 100644
--- a/testing/web-platform/meta/html/semantics/scripting-1/the-script-element/module/referrer-origin-when-cross-origin.sub.html.ini
+++ /dev/null
@@ -1,13 +0,0 @@
-[referrer-origin-when-cross-origin.sub.html]
-  [Importing a remote-origin top-level script with the origin-when-cross-origin policy.]
-    expected: FAIL
-
-  [Importing a same-origin descendant script from a same-origin top-level script with the origin-when-cross-origin policy.]
-    expected: FAIL
-
-  [Importing a remote-origin descendant script from a same-origin top-level script with the origin-when-cross-origin policy.]
-    expected: FAIL
-
-  [Importing a remote-origin descendant script from a remote-origin top-level script with the origin-when-cross-origin policy.]
-    expected: FAIL
-
deleted file mode 100644
--- a/testing/web-platform/meta/html/semantics/scripting-1/the-script-element/module/referrer-origin.sub.html.ini
+++ /dev/null
@@ -1,16 +0,0 @@
-[referrer-origin.sub.html]
-  [Importing a same-origin top-level script with the origin policy.]
-    expected: FAIL
-
-  [Importing a remote-origin top-level script with the origin policy.]
-    expected: FAIL
-
-  [Importing a same-origin descendant script from a same-origin top-level script with the origin policy.]
-    expected: FAIL
-
-  [Importing a remote-origin descendant script from a same-origin top-level script with the origin policy.]
-    expected: FAIL
-
-  [Importing a remote-origin descendant script from a remote-origin top-level script with the origin policy.]
-    expected: FAIL
-
deleted file mode 100644
--- a/testing/web-platform/meta/html/semantics/scripting-1/the-script-element/module/referrer-same-origin.sub.html.ini
+++ /dev/null
@@ -1,13 +0,0 @@
-[referrer-same-origin.sub.html]
-  [Importing a remote-origin top-level script with the same-origin policy.]
-    expected: FAIL
-
-  [Importing a same-origin descendant script from a same-origin top-level script with the same-origin policy.]
-    expected: FAIL
-
-  [Importing a remote-origin descendant script from a same-origin top-level script with the same-origin policy.]
-    expected: FAIL
-
-  [Importing a remote-origin descendant script from a remote-origin top-level script with the same-origin policy.]
-    expected: FAIL
-
deleted file mode 100644
--- a/testing/web-platform/meta/html/semantics/scripting-1/the-script-element/module/referrer-unsafe-url.sub.html.ini
+++ /dev/null
@@ -1,10 +0,0 @@
-[referrer-unsafe-url.sub.html]
-  [Importing a same-origin descendant script from a same-origin top-level script with the unsafe-url policy.]
-    expected: FAIL
-
-  [Importing a remote-origin descendant script from a same-origin top-level script with the unsafe-url policy.]
-    expected: FAIL
-
-  [Importing a remote-origin descendant script from a remote-origin top-level script with the unsafe-url policy.]
-    expected: FAIL
-