Bug 918090 - Let NeckoParent get the app:// uri when remoting file opening. r=jduell
authorFabrice Desré <fabrice@mozilla.com>
Wed, 18 Sep 2013 16:55:56 -0700
changeset 148379 400260c0b569f313ddd0399006e0973e7a2e73c7
parent 148372 1fda74e33e0610130db0e14f8812933f69143d81
child 148380 3d953e4170ce3252939264cf90746ce0e110230c
push id25342
push useremorley@mozilla.com
push dateTue, 24 Sep 2013 14:39:36 +0000
treeherdermozilla-central@57d160eda301 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersjduell
bugs918090
milestone27.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 918090 - Let NeckoParent get the app:// uri when remoting file opening. r=jduell
modules/libjar/nsJARChannel.cpp
netwerk/ipc/NeckoChild.cpp
netwerk/ipc/NeckoChild.h
netwerk/ipc/NeckoParent.cpp
netwerk/ipc/NeckoParent.h
netwerk/ipc/PNecko.ipdl
netwerk/ipc/RemoteOpenFileChild.cpp
netwerk/ipc/RemoteOpenFileChild.h
--- a/modules/libjar/nsJARChannel.cpp
+++ b/modules/libjar/nsJARChannel.cpp
@@ -344,17 +344,17 @@ nsJARChannel::LookupFile()
     }
     // if we're in child process and have special "remoteopenfile:://" scheme,
     // create special nsIFile that gets file handle from parent when opened.
     if (!mJarFile && !gJarHandler->IsMainProcess()) {
         nsAutoCString scheme;
         rv = mJarBaseURI->GetScheme(scheme);
         if (NS_SUCCEEDED(rv) && scheme.EqualsLiteral("remoteopenfile")) {
             nsRefPtr<RemoteOpenFileChild> remoteFile = new RemoteOpenFileChild();
-            rv = remoteFile->Init(mJarBaseURI);
+            rv = remoteFile->Init(mJarBaseURI, mAppURI);
             NS_ENSURE_SUCCESS(rv, rv);
             mJarFile = remoteFile;
 
             nsIZipReaderCache *jarCache = gJarHandler->JarCache();
             if (jarCache) {
                 bool cached = false;
                 rv = jarCache->IsCached(mJarFile, &cached);
                 if (NS_SUCCEEDED(rv) && cached) {
--- a/netwerk/ipc/NeckoChild.cpp
+++ b/netwerk/ipc/NeckoChild.cpp
@@ -184,17 +184,17 @@ bool
 NeckoChild::DeallocPTCPServerSocketChild(PTCPServerSocketChild* child)
 {
   TCPServerSocketChild* p = static_cast<TCPServerSocketChild*>(child);
   p->ReleaseIPDLReference();
   return true;
 }
 
 PRemoteOpenFileChild*
-NeckoChild::AllocPRemoteOpenFileChild(const URIParams&)
+NeckoChild::AllocPRemoteOpenFileChild(const URIParams&, const OptionalURIParams&)
 {
   // We don't allocate here: instead we always use IPDL constructor that takes
   // an existing RemoteOpenFileChild
   NS_NOTREACHED("AllocPRemoteOpenFileChild should not be called on child");
   return nullptr;
 }
 
 bool
--- a/netwerk/ipc/NeckoChild.h
+++ b/netwerk/ipc/NeckoChild.h
@@ -42,17 +42,18 @@ protected:
   virtual PWebSocketChild* AllocPWebSocketChild(PBrowserChild*, const SerializedLoadContext&);
   virtual bool DeallocPWebSocketChild(PWebSocketChild*);
   virtual PTCPSocketChild* AllocPTCPSocketChild();
   virtual bool DeallocPTCPSocketChild(PTCPSocketChild*);
   virtual PTCPServerSocketChild* AllocPTCPServerSocketChild(const uint16_t& aLocalPort,
                                                        const uint16_t& aBacklog,
                                                        const nsString& aBinaryType);
   virtual bool DeallocPTCPServerSocketChild(PTCPServerSocketChild*);
-  virtual PRemoteOpenFileChild* AllocPRemoteOpenFileChild(const URIParams&);
+  virtual PRemoteOpenFileChild* AllocPRemoteOpenFileChild(const URIParams&,
+                                                          const OptionalURIParams&);
   virtual bool DeallocPRemoteOpenFileChild(PRemoteOpenFileChild*);
 };
 
 /**
  * Reference to the PNecko Child protocol.
  * Null if this is not a content process.
  */
 extern PNeckoChild *gNeckoChild;
--- a/netwerk/ipc/NeckoParent.cpp
+++ b/netwerk/ipc/NeckoParent.cpp
@@ -343,17 +343,18 @@ bool
 NeckoParent::DeallocPTCPServerSocketParent(PTCPServerSocketParent* actor)
 {
   TCPServerSocketParent* p = static_cast<TCPServerSocketParent*>(actor);
    p->ReleaseIPDLReference();
   return true;
 }
 
 PRemoteOpenFileParent*
-NeckoParent::AllocPRemoteOpenFileParent(const URIParams& aURI)
+NeckoParent::AllocPRemoteOpenFileParent(const URIParams& aURI,
+                                        const OptionalURIParams& aAppURI)
 {
   nsCOMPtr<nsIURI> uri = DeserializeURI(aURI);
   nsCOMPtr<nsIFileURL> fileURL = do_QueryInterface(uri);
   if (!fileURL) {
     return nullptr;
   }
 
   // security checks
@@ -442,30 +443,31 @@ NeckoParent::AllocPRemoteOpenFileParent(
       }
       nsPrintfCString mustMatch("%s/%s/application.zip",
                                 NS_LossyConvertUTF16toASCII(basePath).get(),
                                 NS_LossyConvertUTF16toASCII(uuid).get());
       if (!requestedPath.Equals(mustMatch)) {
         printf_stderr("NeckoParent::AllocPRemoteOpenFile: "
                       "FATAL error: app without webapps-manage permission is "
                       "requesting file '%s' but is only allowed to open its "
-                      "own application.zip: KILLING CHILD PROCESS\n",
-                      requestedPath.get());
+                      "own application.zip at %s: KILLING CHILD PROCESS\n",
+                      requestedPath.get(), mustMatch.get());
         return nullptr;
       }
     }
   }
 
   RemoteOpenFileParent* parent = new RemoteOpenFileParent(fileURL);
   return parent;
 }
 
 bool
 NeckoParent::RecvPRemoteOpenFileConstructor(PRemoteOpenFileParent* aActor,
-                                            const URIParams& aFileURI)
+                                            const URIParams& aFileURI,
+                                            const OptionalURIParams& aAppURI)
 {
   return static_cast<RemoteOpenFileParent*>(aActor)->OpenSendCloseDelete();
 }
 
 bool
 NeckoParent::DeallocPRemoteOpenFileParent(PRemoteOpenFileParent* actor)
 {
   delete actor;
--- a/netwerk/ipc/NeckoParent.h
+++ b/netwerk/ipc/NeckoParent.h
@@ -83,20 +83,22 @@ protected:
                       const SerializedLoadContext& aSerialized,
                       const FTPChannelCreationArgs& aOpenArgs);
   virtual bool DeallocPFTPChannelParent(PFTPChannelParent*);
   virtual PWebSocketParent* AllocPWebSocketParent(PBrowserParent* browser,
                                                   const SerializedLoadContext& aSerialized);
   virtual bool DeallocPWebSocketParent(PWebSocketParent*);
   virtual PTCPSocketParent* AllocPTCPSocketParent();
 
-  virtual PRemoteOpenFileParent* AllocPRemoteOpenFileParent(const URIParams& aFileURI)
+  virtual PRemoteOpenFileParent* AllocPRemoteOpenFileParent(const URIParams& aFileURI,
+                                                            const OptionalURIParams& aAppURI)
                                                             MOZ_OVERRIDE;
   virtual bool RecvPRemoteOpenFileConstructor(PRemoteOpenFileParent* aActor,
-                                              const URIParams& aFileURI)
+                                              const URIParams& aFileURI,
+                                              const OptionalURIParams& aAppURI)
                                               MOZ_OVERRIDE;
   virtual bool DeallocPRemoteOpenFileParent(PRemoteOpenFileParent* aActor)
                                             MOZ_OVERRIDE;
 
   virtual bool DeallocPTCPSocketParent(PTCPSocketParent*);
   virtual PTCPServerSocketParent* AllocPTCPServerSocketParent(const uint16_t& aLocalPort,
                                                         const uint16_t& aBacklog,
                                                         const nsString& aBinaryType);
--- a/netwerk/ipc/PNecko.ipdl
+++ b/netwerk/ipc/PNecko.ipdl
@@ -49,17 +49,17 @@ parent:
                SerializedLoadContext loadContext,
                HttpChannelCreationArgs args);
   PWyciwygChannel();
   PFTPChannel(PBrowser browser, SerializedLoadContext loadContext,
               FTPChannelCreationArgs args);
 
   PWebSocket(PBrowser browser, SerializedLoadContext loadContext);
   PTCPServerSocket(uint16_t localPort, uint16_t backlog, nsString binaryType);
-  PRemoteOpenFile(URIParams fileuri);
+  PRemoteOpenFile(URIParams fileuri, OptionalURIParams appuri);
 
   HTMLDNSPrefetch(nsString hostname, uint16_t flags);
   CancelHTMLDNSPrefetch(nsString hostname, uint16_t flags, nsresult reason);
 
 both:
   PTCPSocket();
 };
 
--- a/netwerk/ipc/RemoteOpenFileChild.cpp
+++ b/netwerk/ipc/RemoteOpenFileChild.cpp
@@ -70,16 +70,19 @@ NS_IMPL_ISUPPORTS3(RemoteOpenFileChild,
 RemoteOpenFileChild::RemoteOpenFileChild(const RemoteOpenFileChild& other)
   : mTabChild(other.mTabChild)
   , mNSPRFileDesc(other.mNSPRFileDesc)
   , mAsyncOpenCalled(other.mAsyncOpenCalled)
   , mNSPROpenCalled(other.mNSPROpenCalled)
 {
   // Note: don't clone mListener or we'll have a refcount leak.
   other.mURI->Clone(getter_AddRefs(mURI));
+  if (other.mAppURI) {
+    other.mAppURI->Clone(getter_AddRefs(mAppURI));
+  }
   other.mFile->Clone(getter_AddRefs(mFile));
 }
 
 RemoteOpenFileChild::~RemoteOpenFileChild()
 {
   if (mListener) {
     NotifyListener(NS_ERROR_UNEXPECTED);
   }
@@ -88,22 +91,26 @@ RemoteOpenFileChild::~RemoteOpenFileChil
     // If we handed out fd we shouldn't have pointer to it any more.
     MOZ_ASSERT(!mNSPROpenCalled);
     // PR_Close both closes the file and deallocates the PRFileDesc
     PR_Close(mNSPRFileDesc);
   }
 }
 
 nsresult
-RemoteOpenFileChild::Init(nsIURI* aRemoteOpenUri)
+RemoteOpenFileChild::Init(nsIURI* aRemoteOpenUri, nsIURI* aAppUri)
 {
   if (!aRemoteOpenUri) {
     return NS_ERROR_INVALID_ARG;
   }
 
+  if (aAppUri) {
+    aAppUri->Clone(getter_AddRefs(mAppURI));
+  }
+
   nsAutoCString scheme;
   nsresult rv = aRemoteOpenUri->GetScheme(scheme);
   NS_ENSURE_SUCCESS(rv, rv);
 
   if (!scheme.EqualsLiteral("remoteopenfile")) {
     return NS_ERROR_INVALID_ARG;
   }
 
@@ -178,18 +185,20 @@ RemoteOpenFileChild::AsyncRemoteFileOpen
       // The file descriptor was found in the cache and OnCachedFileDescriptor()
       // will be called with it.
       return NS_OK;
     }
   }
 
   URIParams uri;
   SerializeURI(mURI, uri);
+  OptionalURIParams appUri;
+  SerializeURI(mAppURI, appUri);
 
-  gNeckoChild->SendPRemoteOpenFileConstructor(this, uri);
+  gNeckoChild->SendPRemoteOpenFileConstructor(this, uri, appUri);
 
   // The chrome process now has a logical ref to us until it calls Send__delete.
   AddIPDLReference();
 
   mListener = aListener;
   mAsyncOpenCalled = true;
   return NS_OK;
 #endif
--- a/netwerk/ipc/RemoteOpenFileChild.h
+++ b/netwerk/ipc/RemoteOpenFileChild.h
@@ -58,18 +58,19 @@ public:
   {}
 
   virtual ~RemoteOpenFileChild();
 
   NS_DECL_THREADSAFE_ISUPPORTS
   NS_DECL_NSIFILE
   NS_DECL_NSIHASHABLE
 
-  // URI must be scheme 'remoteopenfile://': otherwise looks like a file:// uri.
-  nsresult Init(nsIURI* aRemoteOpenUri);
+  // aRemoteOpenUri must be scheme 'remoteopenfile://': otherwise looks like
+  // a file:// uri.
+  nsresult Init(nsIURI* aRemoteOpenUri, nsIURI* aAppUri);
 
   // Send message to parent to tell it to open file handle for file.
   // TabChild is required, for IPC security.
   // Note: currently only PR_RDONLY is supported for 'flags'
   nsresult AsyncRemoteFileOpen(int32_t aFlags,
                                nsIRemoteOpenFileListener* aListener,
                                nsITabChild* aTabChild);
 
@@ -95,16 +96,17 @@ protected:
   void HandleFileDescriptorAndNotifyListener(const FileDescriptor&,
                                              bool aFromRecvDelete);
 
   void NotifyListener(nsresult aResult);
 
   // regular nsIFile object, that we forward most calls to.
   nsCOMPtr<nsIFile> mFile;
   nsCOMPtr<nsIURI> mURI;
+  nsCOMPtr<nsIURI> mAppURI;
   nsCOMPtr<nsIRemoteOpenFileListener> mListener;
   nsRefPtr<TabChild> mTabChild;
   PRFileDesc* mNSPRFileDesc;
   bool mAsyncOpenCalled;
   bool mNSPROpenCalled;
 };
 
 } // namespace net