Bug 1182543 - Use channel->ascynOpen2 in dom/plugins/base/nsPluginHost.cpp - simplifications in instanceowner (r=sicking)
authorChristoph Kerschbaumer <mozilla@christophkerschbaumer.com>
Tue, 04 Aug 2015 20:06:03 -0700
changeset 256273 401e10fc988b0127bcec58bfca4199c17f4896e1
parent 256272 22458d00ae2503f59fd8f92e18950fa39f3c7e0e
child 256274 9776adf990a4072f2236e06397bf73118a539219
push id29171
push usercbook@mozilla.com
push dateWed, 05 Aug 2015 11:13:29 +0000
treeherdermozilla-central@b12a261ee32e [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewerssicking
bugs1182543
milestone42.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 1182543 - Use channel->ascynOpen2 in dom/plugins/base/nsPluginHost.cpp - simplifications in instanceowner (r=sicking)
dom/plugins/base/nsIPluginInstanceOwner.idl
dom/plugins/base/nsNPAPIPluginStreamListener.cpp
dom/plugins/base/nsPluginHost.cpp
dom/plugins/base/nsPluginHost.h
dom/plugins/base/nsPluginInstanceOwner.cpp
dom/plugins/base/nsPluginInstanceOwner.h
--- a/dom/plugins/base/nsIPluginInstanceOwner.idl
+++ b/dom/plugins/base/nsIPluginInstanceOwner.idl
@@ -21,17 +21,17 @@ enum nsPluginTagType {
   nsPluginTagType_Applet
 };
 %}
 
 [ptr] native nsNPAPIPluginInstancePtr(nsNPAPIPluginInstance);
 
 // Do not make this interface scriptable, because the virtual functions in C++
 // blocks will make script call the wrong functions.
-[uuid(8ff5f46e-96fa-4905-a75c-35aac30bdcee)]
+[uuid(518e7465-e1bc-4490-a30e-0ba9d791aaa8)]
 interface nsIPluginInstanceOwner : nsISupports
 {
   /**
    * Let the owner know what its instance is
    */
   void setInstance(in nsNPAPIPluginInstancePtr aInstance);
 
   /**
@@ -61,17 +61,18 @@ interface nsIPluginInstanceOwner : nsISu
   /**
    * Called when there is a valid target so that the proper
    * frame can be updated with new content. will not be called
    * with nullptr aTarget.
    */
   NS_IMETHOD
   GetURL(const char *aURL, const char *aTarget, 
          nsIInputStream *aPostStream,
-         void *aHeadersData, uint32_t aHeadersDataLen) = 0;
+         void *aHeadersData, uint32_t aHeadersDataLen,
+         bool aDoCheckLoadURIChecks) = 0;
 %}
 
   /**
    * Get the associated document.
    */
   readonly attribute nsIDocument document;
 
   /**
--- a/dom/plugins/base/nsNPAPIPluginStreamListener.cpp
+++ b/dom/plugins/base/nsNPAPIPluginStreamListener.cpp
@@ -85,18 +85,17 @@ nsPluginStreamToFile::Flush()
 }
 
 NS_IMETHODIMP
 nsPluginStreamToFile::Write(const char* aBuf, uint32_t aCount,
                             uint32_t *aWriteCount)
 {
   mOutputStream->Write(aBuf, aCount, aWriteCount);
   mOutputStream->Flush();
-  mOwner->GetURL(mFileURL.get(), mTarget, nullptr, nullptr, 0);
-  
+  mOwner->GetURL(mFileURL.get(), mTarget, nullptr, nullptr, 0, false);
   return NS_OK;
 }
 
 NS_IMETHODIMP
 nsPluginStreamToFile::WriteFrom(nsIInputStream *inStr, uint32_t count,
                                 uint32_t *_retval)
 {
   NS_NOTREACHED("WriteFrom");
@@ -117,17 +116,17 @@ nsPluginStreamToFile::IsNonBlocking(bool
   *aNonBlocking = false;
   return NS_OK;
 }
 
 NS_IMETHODIMP
 nsPluginStreamToFile::Close(void)
 {
   mOutputStream->Close();
-  mOwner->GetURL(mFileURL.get(), mTarget, nullptr, nullptr, 0);
+  mOwner->GetURL(mFileURL.get(), mTarget, nullptr, nullptr, 0, false);
   return NS_OK;
 }
 
 // nsNPAPIPluginStreamListener Methods
 
 NS_IMPL_ISUPPORTS(nsNPAPIPluginStreamListener,
                   nsITimerCallback, nsIHTTPHeaderListener)
 
--- a/dom/plugins/base/nsPluginHost.cpp
+++ b/dom/plugins/base/nsPluginHost.cpp
@@ -83,17 +83,16 @@
 #include "nsPluginDirServiceProvider.h"
 
 #include "nsUnicharUtils.h"
 #include "nsPluginManifestLineReader.h"
 
 #include "nsIWeakReferenceUtils.h"
 #include "nsIPresShell.h"
 #include "nsPluginNativeWindow.h"
-#include "nsIScriptSecurityManager.h"
 #include "nsIContentPolicy.h"
 #include "nsContentPolicyUtils.h"
 #include "mozilla/TimeStamp.h"
 #include "mozilla/Telemetry.h"
 #include "nsIImageLoadingContent.h"
 #include "mozilla/Preferences.h"
 #include "nsVersionComparator.h"
 #include "nsNullPrincipal.h"
@@ -511,42 +510,34 @@ nsresult nsPluginHost::GetURLWithHeaders
                                          const char* altHost,
                                          const char* referrer,
                                          bool forceJSEnabled,
                                          uint32_t getHeadersLength,
                                          const char* getHeaders)
 {
   // we can only send a stream back to the plugin (as specified by a
   // null target) if we also have a nsNPAPIPluginStreamListener to talk to
-  if (!target && !streamListener)
+  if (!target && !streamListener) {
     return NS_ERROR_ILLEGAL_VALUE;
+  }
 
   nsresult rv = NS_OK;
 
   if (target) {
-    rv = DoURLLoadSecurityCheck(pluginInst, url);
-    NS_ENSURE_SUCCESS(rv, rv);
-
     nsRefPtr<nsPluginInstanceOwner> owner = pluginInst->GetOwner();
     if (owner) {
-      if ((0 == PL_strcmp(target, "newwindow")) ||
-          (0 == PL_strcmp(target, "_new")))
-        target = "_blank";
-      else if (0 == PL_strcmp(target, "_current"))
-        target = "_self";
-
-      rv = owner->GetURL(url, target, nullptr, nullptr, 0);
+      rv = owner->GetURL(url, target, nullptr, nullptr, 0, true);
     }
   }
 
-  if (streamListener)
+  if (streamListener) {
     rv = NewPluginURLStream(NS_ConvertUTF8toUTF16(url), pluginInst,
                             streamListener, nullptr,
                             getHeaders, getHeadersLength);
-
+  }
   return rv;
 }
 
 nsresult nsPluginHost::PostURL(nsISupports* pluginInst,
                                const char* url,
                                uint32_t postDataLen,
                                const char* postData,
                                bool isFile,
@@ -604,38 +595,29 @@ nsresult nsPluginHost::PostURL(nsISuppor
     // data allocated by ParsePostBufferToFixHeaders() is managed and
     // freed by the string stream.
     postDataLen = newDataToPostLen;
     sis->AdoptData(dataToPost, postDataLen);
     postStream = sis;
   }
 
   if (target) {
-    rv = DoURLLoadSecurityCheck(instance, url);
-    NS_ENSURE_SUCCESS(rv, rv);
-
     nsRefPtr<nsPluginInstanceOwner> owner = instance->GetOwner();
     if (owner) {
-      if ((0 == PL_strcmp(target, "newwindow")) ||
-          (0 == PL_strcmp(target, "_new"))) {
-        target = "_blank";
-      } else if (0 == PL_strcmp(target, "_current")) {
-        target = "_self";
-      }
       rv = owner->GetURL(url, target, postStream,
-                         (void*)postHeaders, postHeadersLength);
+                         (void*)postHeaders, postHeadersLength, true);
     }
   }
 
   // if we don't have a target, just create a stream.
-  if (streamListener)
+  if (streamListener) {
     rv = NewPluginURLStream(NS_ConvertUTF8toUTF16(url), instance,
                             streamListener,
                             postStream, postHeaders, postHeadersLength);
-
+  }
   return rv;
 }
 
 /* This method queries the prefs for proxy information.
  * It has been tested and is known to work in the following three cases
  * when no proxy host or port is specified
  * when only the proxy host is specified
  * when only the proxy port is specified
@@ -3526,55 +3508,16 @@ nsresult nsPluginHost::NewPluginURLStrea
     }
   }
   rv = channel->AsyncOpen2(listenerPeer);
   if (NS_SUCCEEDED(rv))
     listenerPeer->TrackRequest(channel);
   return rv;
 }
 
-// Called by GetURL and PostURL
-nsresult
-nsPluginHost::DoURLLoadSecurityCheck(nsNPAPIPluginInstance *aInstance,
-                                     const char* aURL)
-{
-  if (!aURL || *aURL == '\0')
-    return NS_OK;
-
-  // get the base URI for the plugin element
-  nsRefPtr<nsPluginInstanceOwner> owner = aInstance->GetOwner();
-  if (!owner)
-    return NS_ERROR_FAILURE;
-
-  nsCOMPtr<nsIURI> baseURI = owner->GetBaseURI();
-  if (!baseURI)
-    return NS_ERROR_FAILURE;
-
-  // Create an absolute URL for the target in case the target is relative
-  nsCOMPtr<nsIURI> targetURL;
-  NS_NewURI(getter_AddRefs(targetURL), aURL, baseURI);
-  if (!targetURL)
-    return NS_ERROR_FAILURE;
-
-  nsCOMPtr<nsIDocument> doc;
-  owner->GetDocument(getter_AddRefs(doc));
-  if (!doc)
-    return NS_ERROR_FAILURE;
-
-  nsresult rv;
-  nsCOMPtr<nsIScriptSecurityManager> secMan(
-    do_GetService(NS_SCRIPTSECURITYMANAGER_CONTRACTID, &rv));
-  if (NS_FAILED(rv))
-    return rv;
-
-  return secMan->CheckLoadURIWithPrincipal(doc->NodePrincipal(), targetURL,
-                                           nsIScriptSecurityManager::STANDARD);
-
-}
-
 nsresult
 nsPluginHost::AddHeadersToChannel(const char *aHeadersData,
                                   uint32_t aHeadersDataLen,
                                   nsIChannel *aGenericChannel)
 {
   nsresult rv = NS_OK;
 
   nsCOMPtr<nsIHttpChannel> aChannel = do_QueryInterface(aGenericChannel);
--- a/dom/plugins/base/nsPluginHost.h
+++ b/dom/plugins/base/nsPluginHost.h
@@ -176,20 +176,16 @@ public:
                     nsNPAPIPluginStreamListener* streamListener = nullptr,
                     const char* altHost = nullptr,
                     const char* referrer = nullptr,
                     bool forceJSEnabled = false,
                     uint32_t getHeadersLength = 0,
                     const char* getHeaders = nullptr);
 
   nsresult
-  DoURLLoadSecurityCheck(nsNPAPIPluginInstance *aInstance,
-                         const char* aURL);
-
-  nsresult
   AddHeadersToChannel(const char *aHeadersData, uint32_t aHeadersDataLen,
                       nsIChannel *aGenericChannel);
 
   static nsresult GetPluginTempDir(nsIFile **aDir);
 
   // Helper that checks if a type is whitelisted in plugin.allowed_types.
   // Always returns true if plugin.allowed_types is not set
   static bool IsTypeWhitelisted(const char *aType);
--- a/dom/plugins/base/nsPluginInstanceOwner.cpp
+++ b/dom/plugins/base/nsPluginInstanceOwner.cpp
@@ -39,16 +39,17 @@ using mozilla::DefaultXDisplay;
 #include "nsIAppShell.h"
 #include "nsIDOMHTMLAppletElement.h"
 #include "nsIObjectLoadingContent.h"
 #include "nsObjectLoadingContent.h"
 #include "nsAttrName.h"
 #include "nsIFocusManager.h"
 #include "nsFocusManager.h"
 #include "nsIDOMDragEvent.h"
+#include "nsIScriptSecurityManager.h"
 #include "nsIScrollableFrame.h"
 #include "nsIDocShell.h"
 #include "ImageContainer.h"
 #include "nsIDOMHTMLCollection.h"
 #include "GLContext.h"
 #include "EGLUtils.h"
 #include "nsIContentInlines.h"
 #include "mozilla/MiscEvents.h"
@@ -475,17 +476,18 @@ nsresult nsPluginInstanceOwner::GetInsta
   NS_IF_ADDREF(*aInstance);
   return NS_OK;
 }
 
 NS_IMETHODIMP nsPluginInstanceOwner::GetURL(const char *aURL,
                                             const char *aTarget,
                                             nsIInputStream *aPostStream,
                                             void *aHeadersData,
-                                            uint32_t aHeadersDataLen)
+                                            uint32_t aHeadersDataLen,
+                                            bool aDoCheckLoadURIChecks)
 {
   nsCOMPtr<nsIContent> content = do_QueryReferent(mContent);
   if (!content) {
     return NS_ERROR_NULL_POINTER;
   }
 
   if (content->IsEditable()) {
     return NS_OK;
@@ -507,27 +509,45 @@ NS_IMETHODIMP nsPluginInstanceOwner::Get
   }
 
   // the container of the pres context will give us the link handler
   nsCOMPtr<nsISupports> container = presContext->GetContainerWeak();
   NS_ENSURE_TRUE(container,NS_ERROR_FAILURE);
   nsCOMPtr<nsILinkHandler> lh = do_QueryInterface(container);
   NS_ENSURE_TRUE(lh, NS_ERROR_FAILURE);
 
-  nsAutoString  unitarget;
-  unitarget.AssignASCII(aTarget); // XXX could this be nonascii?
+  nsAutoString unitarget;
+  if ((0 == PL_strcmp(aTarget, "newwindow")) ||
+      (0 == PL_strcmp(aTarget, "_new"))) {
+    unitarget.AssignASCII("_blank");
+  }
+  else if (0 == PL_strcmp(aTarget, "_current")) {
+    unitarget.AssignASCII("_self");
+  }
+  else {
+    unitarget.AssignASCII(aTarget); // XXX could this be nonascii?
+  }
 
   nsCOMPtr<nsIURI> baseURI = GetBaseURI();
 
   // Create an absolute URL
   nsCOMPtr<nsIURI> uri;
   nsresult rv = NS_NewURI(getter_AddRefs(uri), aURL, baseURI);
-
   NS_ENSURE_SUCCESS(rv, NS_ERROR_FAILURE);
 
+  if (aDoCheckLoadURIChecks) {
+    nsCOMPtr<nsIScriptSecurityManager> secMan(
+      do_GetService(NS_SCRIPTSECURITYMANAGER_CONTRACTID, &rv));
+    NS_ENSURE_TRUE(secMan, NS_ERROR_FAILURE);
+
+    rv = secMan->CheckLoadURIWithPrincipal(content->NodePrincipal(), uri,
+                                           nsIScriptSecurityManager::STANDARD);
+    NS_ENSURE_SUCCESS(rv, rv);
+  }
+
   nsCOMPtr<nsIInputStream> headersDataStream;
   if (aPostStream && aHeadersData) {
     if (!aHeadersDataLen)
       return NS_ERROR_UNEXPECTED;
 
     nsCOMPtr<nsIStringInputStream> sis = do_CreateInstance("@mozilla.org/io/string-input-stream;1");
     if (!sis)
       return NS_ERROR_OUT_OF_MEMORY;
--- a/dom/plugins/base/nsPluginInstanceOwner.h
+++ b/dom/plugins/base/nsPluginInstanceOwner.h
@@ -56,17 +56,18 @@ public:
   nsPluginInstanceOwner();
   
   NS_DECL_ISUPPORTS
   NS_DECL_NSIPLUGININSTANCEOWNER
   NS_DECL_NSIPRIVACYTRANSITIONOBSERVER
   
   NS_IMETHOD GetURL(const char *aURL, const char *aTarget,
                     nsIInputStream *aPostStream, 
-                    void *aHeadersData, uint32_t aHeadersDataLen) override;
+                    void *aHeadersData, uint32_t aHeadersDataLen,
+                    bool aDoCheckLoadURIChecks) override;
   
   NPBool     ConvertPoint(double sourceX, double sourceY, NPCoordinateSpace sourceSpace,
                           double *destX, double *destY, NPCoordinateSpace destSpace) override;
   
   /**
    * Get the type of the HTML tag that was used ot instantiate this
    * plugin.  Currently supported tags are EMBED, OBJECT and APPLET.
    */