Bug 464754 - nsIContentPolicy.shouldLoad() called without context for scripts. r/sr=bz a=beltzner
authorBlake Kaplan <mrbkap@gmail.com>
Wed, 19 Nov 2008 02:05:05 -0500
changeset 21823 9a453249ca6c
parent 21822 964ca72afb55
child 21824 0cd41f599080
push id3698
push userrflint@ryanflint.com
push dateWed, 19 Nov 2008 07:05:58 +0000
treeherdermozilla-central@9a453249ca6c [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersbeltzner
bugs464754
milestone1.9.1b2pre
Bug 464754 - nsIContentPolicy.shouldLoad() called without context for scripts. r/sr=bz a=beltzner
content/base/src/nsScriptLoader.cpp
content/base/src/nsScriptLoader.h
--- a/content/base/src/nsScriptLoader.cpp
+++ b/content/base/src/nsScriptLoader.cpp
@@ -191,41 +191,57 @@ IsScriptEventHandler(nsIScriptElement *a
 
     return PR_TRUE;
   }
 
   return PR_FALSE;
 }
 
 nsresult
+nsScriptLoader::CheckContentPolicy(nsScriptLoadRequest *aRequest,
+                                   nsISupports *aContext,
+                                   const nsAString &aType)
+{
+  PRInt16 shouldLoad = nsIContentPolicy::ACCEPT;
+  nsresult rv = NS_CheckContentLoadPolicy(nsIContentPolicy::TYPE_SCRIPT,
+                                          aRequest->mURI,
+                                          mDocument->NodePrincipal(),
+                                          aContext,
+                                          NS_LossyConvertUTF16toASCII(aType),
+                                          nsnull,    //extra
+                                          &shouldLoad,
+                                          nsContentUtils::GetContentPolicy(),
+                                          nsContentUtils::GetSecurityManager());
+  if (NS_FAILED(rv) || NS_CP_REJECTED(shouldLoad)) {
+    if (NS_FAILED(rv) || shouldLoad != nsIContentPolicy::REJECT_TYPE) {
+      return NS_ERROR_CONTENT_BLOCKED;
+    }
+    return NS_ERROR_CONTENT_BLOCKED_SHOW_ALT;
+  }
+
+  return NS_OK;
+}
+
+nsresult
 nsScriptLoader::StartLoad(nsScriptLoadRequest *aRequest, const nsAString &aType)
 {
   // Check that the containing page is allowed to load this URI.
   nsresult rv = nsContentUtils::GetSecurityManager()->
     CheckLoadURIWithPrincipal(mDocument->NodePrincipal(), aRequest->mURI,
                               nsIScriptSecurityManager::ALLOW_CHROME);
 
   NS_ENSURE_SUCCESS(rv, rv);
 
   // After the security manager, the content-policy stuff gets a veto
-  PRInt16 shouldLoad = nsIContentPolicy::ACCEPT;
-  rv = NS_CheckContentLoadPolicy(nsIContentPolicy::TYPE_SCRIPT,
-                                 aRequest->mURI,
-                                 mDocument->NodePrincipal(),
-                                 aRequest->mElement,
-                                 NS_LossyConvertUTF16toASCII(aType),
-                                 nsnull,    //extra
-                                 &shouldLoad,
-                                 nsContentUtils::GetContentPolicy(),
-                                 nsContentUtils::GetSecurityManager());
-  if (NS_FAILED(rv) || NS_CP_REJECTED(shouldLoad)) {
-    if (NS_FAILED(rv) || shouldLoad != nsIContentPolicy::REJECT_TYPE) {
-      return NS_ERROR_CONTENT_BLOCKED;
-    }
-    return NS_ERROR_CONTENT_BLOCKED_SHOW_ALT;
+  nsISupports *context = aRequest->mElement.get()
+                         ? static_cast<nsISupports *>(aRequest->mElement.get())
+                         : static_cast<nsISupports *>(mDocument);
+  rv = CheckContentPolicy(aRequest, context, aType);
+  if (NS_FAILED(rv)) {
+    return rv;
   }
 
   nsCOMPtr<nsILoadGroup> loadGroup = mDocument->GetDocumentLoadGroup();
   nsCOMPtr<nsIStreamLoader> loader;
 
   nsCOMPtr<nsPIDOMWindow> window(do_QueryInterface(mDocument->GetScriptGlobalObject()));
   nsIDocShell *docshell = window->GetDocShell();
 
@@ -458,16 +474,22 @@ nsScriptLoader::ProcessScriptElement(nsI
       mPreloads.IndexOf(scriptURI.get(), 0, PreloadURIComparator());
     if (i != nsTArray<PreloadInfo>::NoIndex) {
       request = mPreloads[i].mRequest;
       request->mElement = aElement;
       request->mJSVersion = version;
       request->mDefer = mDeferEnabled && aElement->GetScriptDeferred();
       mPreloads.RemoveElementAt(i);
 
+      rv = CheckContentPolicy(request, aElement, type);
+      if (NS_FAILED(rv)) {
+        // Note, we're dropping our last ref to request here.
+        return rv;
+      }
+
       if (!request->mLoading && !request->mDefer && !hadPendingRequests &&
             ReadyToExecuteScripts() && nsContentUtils::IsSafeToRunScript()) {
         return ProcessRequest(request);
       }
 
       // Not done loading yet. Move into the real requests queue and wait.
       mRequests.AppendObject(request);
 
--- a/content/base/src/nsScriptLoader.h
+++ b/content/base/src/nsScriptLoader.h
@@ -212,16 +212,23 @@ public:
    * @param aCharset The charset parameter for the script.
    * @param aType The type parameter for the script.
    */
   virtual void PreloadURI(nsIURI *aURI, const nsAString &aCharset,
                           const nsAString &aType);
 
 protected:
   /**
+   * Helper function to check the content policy for a given request.
+   */
+  nsresult CheckContentPolicy(nsScriptLoadRequest *aRequest,
+                              nsISupports *aContext,
+                              const nsAString &aType);
+
+  /**
    * Start a load for aRequest's URI.
    */
   nsresult StartLoad(nsScriptLoadRequest *aRequest, const nsAString &aType);
 
   /**
    * Process any pending requests asyncronously (i.e. off an event) if there
    * are any. Note that this is a no-op if there aren't any currently pending
    * requests.