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 157008 400260c0b569f313ddd0399006e0973e7a2e73c7
parent 157001 1fda74e33e0610130db0e14f8812933f69143d81
child 157009 3d953e4170ce3252939264cf90746ce0e110230c
push idunknown
push userunknown
push dateunknown
reviewersjduell
bugs918090
milestone27.0a1
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