mirror of
https://gitlab.winehq.org/wine/wine-gecko.git
synced 2024-09-13 09:24:08 -07:00
Bug 835698 - 'Pre-open() and send the fd for app process's application.zip'. r=jduell.
This commit is contained in:
parent
b5a78ecd74
commit
8aa8c1b752
@ -21,6 +21,7 @@
|
||||
#include "nsHTMLDNSPrefetch.h"
|
||||
#include "nsIAppsService.h"
|
||||
#include "nsEscape.h"
|
||||
#include "RemoteOpenFileParent.h"
|
||||
|
||||
using mozilla::dom::TabParent;
|
||||
using mozilla::net::PTCPSocketParent;
|
||||
@ -403,6 +404,14 @@ NeckoParent::AllocPRemoteOpenFile(const URIParams& aURI,
|
||||
return parent;
|
||||
}
|
||||
|
||||
bool
|
||||
NeckoParent::RecvPRemoteOpenFileConstructor(PRemoteOpenFileParent* aActor,
|
||||
const URIParams& aFileURI,
|
||||
PBrowserParent* aBrowser)
|
||||
{
|
||||
return static_cast<RemoteOpenFileParent*>(aActor)->OpenSendCloseDelete();
|
||||
}
|
||||
|
||||
bool
|
||||
NeckoParent::DeallocPRemoteOpenFile(PRemoteOpenFileParent* actor)
|
||||
{
|
||||
@ -428,4 +437,3 @@ NeckoParent::RecvCancelHTMLDNSPrefetch(const nsString& hostname,
|
||||
}
|
||||
|
||||
}} // mozilla::net
|
||||
|
||||
|
@ -69,10 +69,16 @@ protected:
|
||||
const bool& useSSL,
|
||||
const nsString& aBinaryType,
|
||||
PBrowserParent* aBrowser);
|
||||
virtual PRemoteOpenFileParent* AllocPRemoteOpenFile(
|
||||
const URIParams& fileuri,
|
||||
PBrowserParent* browser);
|
||||
virtual bool DeallocPRemoteOpenFile(PRemoteOpenFileParent* actor);
|
||||
|
||||
virtual PRemoteOpenFileParent* AllocPRemoteOpenFile(const URIParams& aFileURI,
|
||||
PBrowserParent* aBrowser)
|
||||
MOZ_OVERRIDE;
|
||||
virtual bool RecvPRemoteOpenFileConstructor(PRemoteOpenFileParent* aActor,
|
||||
const URIParams& aFileURI,
|
||||
PBrowserParent* aBrowser)
|
||||
MOZ_OVERRIDE;
|
||||
virtual bool DeallocPRemoteOpenFile(PRemoteOpenFileParent* aActor)
|
||||
MOZ_OVERRIDE;
|
||||
|
||||
virtual bool RecvPTCPSocketConstructor(PTCPSocketParent*,
|
||||
const nsString& aHost,
|
||||
|
@ -47,6 +47,8 @@ parent:
|
||||
PWebSocket(PBrowser browser, SerializedLoadContext loadContext);
|
||||
PTCPSocket(nsString host, uint16_t port, bool useSSL, nsString binaryType,
|
||||
nullable PBrowser browser);
|
||||
|
||||
// Request that the parent open a file.
|
||||
PRemoteOpenFile(URIParams fileuri, nullable PBrowser browser);
|
||||
|
||||
HTMLDNSPrefetch(nsString hostname, uint16_t flags);
|
||||
|
@ -18,18 +18,9 @@ protocol PRemoteOpenFile
|
||||
{
|
||||
manager PNecko;
|
||||
|
||||
parent:
|
||||
// Tell parent to open file. URI to open was passed and vetted for security in
|
||||
// IPDL constructor: see NeckoParent::AllocPRemoteOpenFile()
|
||||
AsyncOpenFile();
|
||||
|
||||
__delete__();
|
||||
|
||||
child:
|
||||
// Your file handle is ready, Sir...
|
||||
FileOpened(FileDescriptor fd);
|
||||
// Trying to send invalid fd crashes, so we need separate method for failure
|
||||
FileDidNotOpen();
|
||||
__delete__(FileDescriptor fd);
|
||||
};
|
||||
|
||||
|
||||
|
@ -186,11 +186,7 @@ RemoteOpenFileChild::AsyncRemoteFileOpen(int32_t aFlags,
|
||||
|
||||
gNeckoChild->SendPRemoteOpenFileConstructor(this, uri, mTabChild);
|
||||
|
||||
// Can't seem to reply from within IPDL Parent constructor, so send open as
|
||||
// separate message
|
||||
SendAsyncOpenFile();
|
||||
|
||||
// The chrome process now has a logical ref to us until we call Send__delete
|
||||
// The chrome process now has a logical ref to us until it calls Send__delete.
|
||||
AddIPDLReference();
|
||||
|
||||
mListener = aListener;
|
||||
@ -216,13 +212,13 @@ RemoteOpenFileChild::OnCachedFileDescriptor(const nsAString& aPath,
|
||||
}
|
||||
#endif
|
||||
|
||||
HandleFileDescriptorAndNotifyListener(aFD, /* aFromRecvFileOpened */ false);
|
||||
HandleFileDescriptorAndNotifyListener(aFD, /* aFromRecvDelete */ false);
|
||||
}
|
||||
|
||||
void
|
||||
RemoteOpenFileChild::HandleFileDescriptorAndNotifyListener(
|
||||
const FileDescriptor& aFD,
|
||||
bool aFromRecvFileOpened)
|
||||
bool aFromRecvDelete)
|
||||
{
|
||||
#if defined(XP_WIN) || defined(MOZ_WIDGET_COCOA)
|
||||
MOZ_NOT_REACHED("OS X and Windows shouldn't be doing IPDL here");
|
||||
@ -243,9 +239,11 @@ RemoteOpenFileChild::HandleFileDescriptorAndNotifyListener(
|
||||
nsRefPtr<TabChild> tabChild;
|
||||
mTabChild.swap(tabChild);
|
||||
|
||||
// If there is a pending callback and we're being called from IPDL then we
|
||||
// need to cancel it.
|
||||
if (tabChild && aFromRecvFileOpened) {
|
||||
// If RemoteOpenFile reply (Recv__delete__) for app's application.zip comes
|
||||
// back sooner than the parent-pushed fd (TabChild::RecvCacheFileDescriptor())
|
||||
// have TabChild cancel running callbacks, since we'll call them in
|
||||
// NotifyListener.
|
||||
if (tabChild && aFromRecvDelete) {
|
||||
nsString path;
|
||||
if (NS_FAILED(mFile->GetPath(path))) {
|
||||
MOZ_NOT_REACHED("Couldn't get path from file!");
|
||||
@ -285,33 +283,12 @@ RemoteOpenFileChild::NotifyListener(nsresult aResult)
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
bool
|
||||
RemoteOpenFileChild::RecvFileOpened(const FileDescriptor& aFD)
|
||||
RemoteOpenFileChild::Recv__delete__(const FileDescriptor& aFD)
|
||||
{
|
||||
#if defined(XP_WIN) || defined(MOZ_WIDGET_COCOA)
|
||||
NS_NOTREACHED("OS X and Windows shouldn't be doing IPDL here");
|
||||
#else
|
||||
HandleFileDescriptorAndNotifyListener(aFD, /* aFromRecvFileOpened */ true);
|
||||
|
||||
// This calls NeckoChild::DeallocPRemoteOpenFile(), which deletes |this| if
|
||||
// IPDL holds the last reference. Don't rely on |this| existing after here!
|
||||
Send__delete__(this);
|
||||
#endif
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool
|
||||
RemoteOpenFileChild::RecvFileDidNotOpen()
|
||||
{
|
||||
#if defined(XP_WIN) || defined(MOZ_WIDGET_COCOA)
|
||||
NS_NOTREACHED("OS X and Windows shouldn't be doing IPDL here");
|
||||
#else
|
||||
HandleFileDescriptorAndNotifyListener(FileDescriptor(),
|
||||
/* aFromRecvFileOpened */ true);
|
||||
|
||||
// This calls NeckoChild::DeallocPRemoteOpenFile(), which deletes |this| if
|
||||
// IPDL holds the last reference. Don't rely on |this| existing after here!
|
||||
Send__delete__(this);
|
||||
HandleFileDescriptorAndNotifyListener(aFD, /* aFromRecvDelete */ true);
|
||||
#endif
|
||||
|
||||
return true;
|
||||
|
@ -7,6 +7,7 @@
|
||||
#ifndef _RemoteOpenFileChild_h
|
||||
#define _RemoteOpenFileChild_h
|
||||
|
||||
#include "mozilla/Attributes.h"
|
||||
#include "mozilla/dom/TabChild.h"
|
||||
#include "mozilla/net/PRemoteOpenFileChild.h"
|
||||
#include "nsICachedFileDescriptorListener.h"
|
||||
@ -86,14 +87,13 @@ protected:
|
||||
AddRef();
|
||||
}
|
||||
|
||||
virtual bool RecvFileOpened(const FileDescriptor&);
|
||||
virtual bool RecvFileDidNotOpen();
|
||||
virtual bool Recv__delete__(const FileDescriptor&) MOZ_OVERRIDE;
|
||||
|
||||
virtual void OnCachedFileDescriptor(const nsAString& aPath,
|
||||
const FileDescriptor& aFD) MOZ_OVERRIDE;
|
||||
|
||||
void HandleFileDescriptorAndNotifyListener(const FileDescriptor&,
|
||||
bool aFromRecvFileOpened);
|
||||
bool aFromRecvDelete);
|
||||
|
||||
void NotifyListener(nsresult aResult);
|
||||
|
||||
|
@ -17,51 +17,42 @@
|
||||
namespace mozilla {
|
||||
namespace net {
|
||||
|
||||
RemoteOpenFileParent::RemoteOpenFileParent(nsIFileURL *aURI)
|
||||
: mURI(aURI)
|
||||
#if !defined(XP_WIN) && !defined(MOZ_WIDGET_COCOA)
|
||||
, mFd(-1)
|
||||
#endif
|
||||
{}
|
||||
|
||||
RemoteOpenFileParent::~RemoteOpenFileParent()
|
||||
{
|
||||
#if !defined(XP_WIN) && !defined(MOZ_WIDGET_COCOA)
|
||||
if (mFd != -1) {
|
||||
// close file handle now that other process has it open, else we'll leak
|
||||
// file handles in parent process
|
||||
close(mFd);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
bool
|
||||
RemoteOpenFileParent::RecvAsyncOpenFile()
|
||||
RemoteOpenFileParent::OpenSendCloseDelete()
|
||||
{
|
||||
#if defined(XP_WIN) || defined(MOZ_WIDGET_COCOA)
|
||||
NS_NOTREACHED("osX and Windows shouldn't be doing IPDL here");
|
||||
MOZ_NOT_REACHED("OS X and Windows shouldn't be doing IPDL here");
|
||||
#else
|
||||
|
||||
// TODO: make this async!
|
||||
|
||||
FileDescriptor fileDescriptor;
|
||||
|
||||
nsAutoCString path;
|
||||
nsresult rv = mURI->GetFilePath(path);
|
||||
NS_WARN_IF_FALSE(NS_SUCCEEDED(rv), "GetFilePath failed!");
|
||||
|
||||
NS_UnescapeURL(path);
|
||||
|
||||
if (NS_SUCCEEDED(rv)) {
|
||||
int fd = open(path.get(), O_RDONLY);
|
||||
if (fd != -1) {
|
||||
unused << SendFileOpened(FileDescriptor(fd));
|
||||
// file handle needs to stay open until it's shared with child (and IPDL
|
||||
// is async, so hasn't happened yet). Close in destructor.
|
||||
mFd = fd;
|
||||
return true;
|
||||
if (fd == -1) {
|
||||
printf_stderr("RemoteOpenFileParent: file '%s' was not found!\n",
|
||||
path.get());
|
||||
} else {
|
||||
fileDescriptor = FileDescriptor(fd);
|
||||
}
|
||||
}
|
||||
|
||||
// Note: sending an invalid file descriptor currently kills the child process:
|
||||
// but that's ok for our use case (failing to open application.jar).
|
||||
printf_stderr("RemoteOpenFileParent: file '%s' was not found!\n", path.get());
|
||||
unused << SendFileDidNotOpen();
|
||||
// Sending a potentially invalid file descriptor is just fine.
|
||||
unused << Send__delete__(this, fileDescriptor);
|
||||
|
||||
if (fileDescriptor.IsValid()) {
|
||||
// close file now that other process has it open, else we'll leak fds in the
|
||||
// parent process.
|
||||
close(fileDescriptor.PlatformHandle());
|
||||
}
|
||||
|
||||
#endif // OS_TYPE
|
||||
|
||||
return true;
|
||||
|
@ -18,18 +18,14 @@ namespace net {
|
||||
class RemoteOpenFileParent : public PRemoteOpenFileParent
|
||||
{
|
||||
public:
|
||||
RemoteOpenFileParent(nsIFileURL* aURI);
|
||||
RemoteOpenFileParent(nsIFileURL* aURI)
|
||||
: mURI(aURI)
|
||||
{}
|
||||
|
||||
~RemoteOpenFileParent();
|
||||
|
||||
virtual bool RecvAsyncOpenFile();
|
||||
bool OpenSendCloseDelete();
|
||||
|
||||
private:
|
||||
nsCOMPtr<nsIFileURL> mURI;
|
||||
|
||||
#if !defined(XP_WIN) && !defined(MOZ_WIDGET_COCOA)
|
||||
int mFd;
|
||||
#endif
|
||||
};
|
||||
|
||||
} // namespace net
|
||||
|
Loading…
Reference in New Issue
Block a user