зеркало из https://github.com/mozilla/gecko-dev.git
Bug 590057: Add support for loading plugins of a different architecture than the host browser on Mac OS X. r=cjones a=blocking-b7
This commit is contained in:
Родитель
1fa97831bc
Коммит
5c84bcf9f6
|
@ -40,6 +40,8 @@
|
|||
#include "mozilla/plugins/PluginProcessParent.h"
|
||||
|
||||
#include "base/string_util.h"
|
||||
#include "base/process_util.h"
|
||||
|
||||
#include "mozilla/ipc/BrowserProcessSubThread.h"
|
||||
#include "mozilla/plugins/PluginMessageUtils.h"
|
||||
|
||||
|
@ -49,6 +51,7 @@ using std::string;
|
|||
using mozilla::ipc::BrowserProcessSubThread;
|
||||
using mozilla::ipc::GeckoChildProcessHost;
|
||||
using mozilla::plugins::PluginProcessParent;
|
||||
using base::ProcessArchitecture;
|
||||
|
||||
template<>
|
||||
struct RunnableMethodTraits<PluginProcessParent>
|
||||
|
@ -70,9 +73,42 @@ PluginProcessParent::~PluginProcessParent()
|
|||
bool
|
||||
PluginProcessParent::Launch(PRInt32 timeoutMs)
|
||||
{
|
||||
ProcessArchitecture currentArchitecture = base::GetCurrentProcessArchitecture();
|
||||
uint32 containerArchitectures = GetSupportedArchitecturesForProcessType(GeckoProcessType_Plugin);
|
||||
|
||||
uint32 pluginLibArchitectures = currentArchitecture;
|
||||
#ifdef XP_MACOSX
|
||||
nsresult rv = GetArchitecturesForBinary(mPluginFilePath.c_str(), &pluginLibArchitectures);
|
||||
if (NS_FAILED(rv)) {
|
||||
// If the call failed just assume that we want the current architecture.
|
||||
pluginLibArchitectures = currentArchitecture;
|
||||
}
|
||||
#endif
|
||||
|
||||
ProcessArchitecture selectedArchitecture = currentArchitecture;
|
||||
if (!(pluginLibArchitectures & containerArchitectures & currentArchitecture)) {
|
||||
// Prefererence in order: x86_64, i386, PPC. The only particularly important thing
|
||||
// about this order is that we'll prefer 64-bit architectures first.
|
||||
if (base::PROCESS_ARCH_X86_64 & pluginLibArchitectures & containerArchitectures) {
|
||||
selectedArchitecture = base::PROCESS_ARCH_X86_64;
|
||||
}
|
||||
else if (base::PROCESS_ARCH_I386 & pluginLibArchitectures & containerArchitectures) {
|
||||
selectedArchitecture = base::PROCESS_ARCH_I386;
|
||||
}
|
||||
else if (base::PROCESS_ARCH_PPC & pluginLibArchitectures & containerArchitectures) {
|
||||
selectedArchitecture = base::PROCESS_ARCH_PPC;
|
||||
}
|
||||
else if (base::PROCESS_ARCH_ARM & pluginLibArchitectures & containerArchitectures) {
|
||||
selectedArchitecture = base::PROCESS_ARCH_ARM;
|
||||
}
|
||||
else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
vector<string> args;
|
||||
args.push_back(MungePluginDsoPath(mPluginFilePath));
|
||||
return SyncLaunch(args, timeoutMs);
|
||||
return SyncLaunch(args, timeoutMs, selectedArchitecture);
|
||||
}
|
||||
|
||||
void
|
||||
|
|
|
@ -57,6 +57,29 @@ struct kinfo_proc;
|
|||
|
||||
namespace base {
|
||||
|
||||
// These can be used in a 32-bit bitmask.
|
||||
enum ProcessArchitecture {
|
||||
PROCESS_ARCH_I386 = 0x1,
|
||||
PROCESS_ARCH_X86_64 = 0x2,
|
||||
PROCESS_ARCH_PPC = 0x4,
|
||||
PROCESS_ARCH_ARM = 0x8
|
||||
};
|
||||
|
||||
static ProcessArchitecture GetCurrentProcessArchitecture()
|
||||
{
|
||||
base::ProcessArchitecture currentArchitecture;
|
||||
#if defined(ARCH_CPU_X86)
|
||||
currentArchitecture = base::PROCESS_ARCH_I386;
|
||||
#elif defined(ARCH_CPU_X86_64)
|
||||
currentArchitecture = base::PROCESS_ARCH_X86_64;
|
||||
#elif defined(ARCH_CPU_PPC)
|
||||
currentArchitecture = base::PROCESS_ARCH_PPC;
|
||||
#elif defined(ARCH_CPU_ARMEL)
|
||||
currentArchitecture = base::PROCESS_ARCH_ARM;
|
||||
#endif
|
||||
return currentArchitecture;
|
||||
}
|
||||
|
||||
// A minimalistic but hopefully cross-platform set of exit codes.
|
||||
// Do not change the enumeration values or you will break third-party
|
||||
// installers.
|
||||
|
@ -140,7 +163,8 @@ typedef std::map<std::string, std::string> environment_map;
|
|||
bool LaunchApp(const std::vector<std::string>& argv,
|
||||
const file_handle_mapping_vector& fds_to_remap,
|
||||
const environment_map& env_vars_to_set,
|
||||
bool wait, ProcessHandle* process_handle);
|
||||
bool wait, ProcessHandle* process_handle,
|
||||
ProcessArchitecture arch=GetCurrentProcessArchitecture());
|
||||
#endif
|
||||
|
||||
// Executes the application specified by cl. This function delegates to one
|
||||
|
|
|
@ -46,7 +46,8 @@ bool LaunchApp(const std::vector<std::string>& argv,
|
|||
#if defined(CHROMIUM_MOZILLA_BUILD)
|
||||
const environment_map& env_vars_to_set,
|
||||
#endif
|
||||
bool wait, ProcessHandle* process_handle) {
|
||||
bool wait, ProcessHandle* process_handle,
|
||||
ProcessArchitecture arch) {
|
||||
pid_t pid = fork();
|
||||
if (pid < 0)
|
||||
return false;
|
||||
|
|
|
@ -22,6 +22,14 @@
|
|||
|
||||
namespace base {
|
||||
|
||||
void FreeEnvVarsArray(char* array[], int length)
|
||||
{
|
||||
for (int i = 0; i < length; i++) {
|
||||
free(array[i]);
|
||||
}
|
||||
delete[] array;
|
||||
}
|
||||
|
||||
bool LaunchApp(const std::vector<std::string>& argv,
|
||||
const file_handle_mapping_vector& fds_to_remap,
|
||||
bool wait, ProcessHandle* process_handle) {
|
||||
|
@ -32,7 +40,8 @@ bool LaunchApp(const std::vector<std::string>& argv,
|
|||
bool LaunchApp(const std::vector<std::string>& argv,
|
||||
const file_handle_mapping_vector& fds_to_remap,
|
||||
const environment_map& env_vars_to_set,
|
||||
bool wait, ProcessHandle* process_handle) {
|
||||
bool wait, ProcessHandle* process_handle,
|
||||
ProcessArchitecture arch) {
|
||||
bool retval = true;
|
||||
|
||||
char* argv_copy[argv.size() + 1];
|
||||
|
@ -75,10 +84,7 @@ bool LaunchApp(const std::vector<std::string>& argv,
|
|||
|
||||
posix_spawn_file_actions_t file_actions;
|
||||
if (posix_spawn_file_actions_init(&file_actions) != 0) {
|
||||
for(int j = 0; j < varsLen; j++) {
|
||||
free(vars[j]);
|
||||
}
|
||||
delete[] vars;
|
||||
FreeEnvVarsArray(vars, varsLen);
|
||||
return false;
|
||||
}
|
||||
|
||||
|
@ -97,30 +103,59 @@ bool LaunchApp(const std::vector<std::string>& argv,
|
|||
} else {
|
||||
if (posix_spawn_file_actions_adddup2(&file_actions, src_fd, dest_fd) != 0) {
|
||||
posix_spawn_file_actions_destroy(&file_actions);
|
||||
for(int j = 0; j < varsLen; j++) {
|
||||
free(vars[j]);
|
||||
}
|
||||
delete[] vars;
|
||||
FreeEnvVarsArray(vars, varsLen);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Set up the CPU preference array.
|
||||
cpu_type_t cpu_types[1];
|
||||
switch (arch) {
|
||||
case PROCESS_ARCH_I386:
|
||||
cpu_types[0] = CPU_TYPE_X86;
|
||||
break;
|
||||
case PROCESS_ARCH_X86_64:
|
||||
cpu_types[0] = CPU_TYPE_X86_64;
|
||||
break;
|
||||
case PROCESS_ARCH_PPC:
|
||||
cpu_types[0] = CPU_TYPE_POWERPC;
|
||||
default:
|
||||
cpu_types[0] = CPU_TYPE_ANY;
|
||||
break;
|
||||
}
|
||||
|
||||
// Initialize spawn attributes.
|
||||
posix_spawnattr_t spawnattr;
|
||||
if (posix_spawnattr_init(&spawnattr) != 0) {
|
||||
FreeEnvVarsArray(vars, varsLen);
|
||||
return false;
|
||||
}
|
||||
|
||||
// Set spawn attributes.
|
||||
size_t attr_count = 1;
|
||||
size_t attr_ocount = 0;
|
||||
if (posix_spawnattr_setbinpref_np(&spawnattr, attr_count, cpu_types, &attr_ocount) != 0 ||
|
||||
attr_ocount != attr_count) {
|
||||
FreeEnvVarsArray(vars, varsLen);
|
||||
posix_spawnattr_destroy(&spawnattr);
|
||||
return false;
|
||||
}
|
||||
|
||||
int pid = 0;
|
||||
int spawn_succeeded = (posix_spawnp(&pid,
|
||||
argv_copy[0],
|
||||
&file_actions,
|
||||
NULL,
|
||||
&spawnattr,
|
||||
argv_copy,
|
||||
vars) == 0);
|
||||
|
||||
for(int j = 0; j < varsLen; j++) {
|
||||
free(vars[j]);
|
||||
}
|
||||
delete[] vars;
|
||||
FreeEnvVarsArray(vars, varsLen);
|
||||
|
||||
posix_spawn_file_actions_destroy(&file_actions);
|
||||
|
||||
posix_spawnattr_destroy(&spawnattr);
|
||||
|
||||
bool process_handle_valid = pid > 0;
|
||||
if (!spawn_succeeded || !process_handle_valid) {
|
||||
retval = false;
|
||||
|
|
|
@ -46,6 +46,7 @@
|
|||
#ifdef XP_MACOSX
|
||||
#include "chrome/common/mach_ipc_mac.h"
|
||||
#include "base/rand_util.h"
|
||||
#include "nsILocalFileMac.h"
|
||||
#endif
|
||||
|
||||
#include "prprf.h"
|
||||
|
@ -119,6 +120,122 @@ GeckoChildProcessHost::~GeckoChildProcessHost()
|
|||
#endif
|
||||
}
|
||||
|
||||
void GetPathToBinary(FilePath& exePath)
|
||||
{
|
||||
#if defined(OS_WIN)
|
||||
exePath = FilePath::FromWStringHack(CommandLine::ForCurrentProcess()->program());
|
||||
exePath = exePath.DirName();
|
||||
exePath = exePath.AppendASCII(MOZ_CHILD_PROCESS_NAME);
|
||||
#elif defined(OS_POSIX)
|
||||
nsCOMPtr<nsIProperties> directoryService(do_GetService(NS_DIRECTORY_SERVICE_CONTRACTID));
|
||||
nsCOMPtr<nsIFile> greDir;
|
||||
nsresult rv = directoryService->Get(NS_GRE_DIR, NS_GET_IID(nsIFile), getter_AddRefs(greDir));
|
||||
if (NS_SUCCEEDED(rv)) {
|
||||
nsCString path;
|
||||
greDir->GetNativePath(path);
|
||||
exePath = FilePath(path.get());
|
||||
}
|
||||
else {
|
||||
exePath = FilePath(CommandLine::ForCurrentProcess()->argv()[0]);
|
||||
exePath = exePath.DirName();
|
||||
}
|
||||
|
||||
#ifdef OS_MACOSX
|
||||
// We need to use an App Bundle on OS X so that we can hide
|
||||
// the dock icon. See Bug 557225
|
||||
exePath = exePath.AppendASCII(MOZ_CHILD_PROCESS_BUNDLE);
|
||||
#endif
|
||||
|
||||
exePath = exePath.AppendASCII(MOZ_CHILD_PROCESS_NAME);
|
||||
#endif
|
||||
}
|
||||
|
||||
#ifdef XP_MACOSX
|
||||
class AutoCFTypeObject {
|
||||
public:
|
||||
AutoCFTypeObject(CFTypeRef object)
|
||||
{
|
||||
mObject = object;
|
||||
}
|
||||
~AutoCFTypeObject()
|
||||
{
|
||||
::CFRelease(mObject);
|
||||
}
|
||||
private:
|
||||
CFTypeRef mObject;
|
||||
};
|
||||
#endif
|
||||
|
||||
nsresult GeckoChildProcessHost::GetArchitecturesForBinary(const char *path, uint32 *result)
|
||||
{
|
||||
*result = 0;
|
||||
|
||||
#ifdef XP_MACOSX
|
||||
CFURLRef url = ::CFURLCreateFromFileSystemRepresentation(kCFAllocatorDefault,
|
||||
(const UInt8*)path,
|
||||
strlen(path),
|
||||
false);
|
||||
if (!url) {
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
AutoCFTypeObject autoPluginContainerURL(url);
|
||||
|
||||
CFArrayRef pluginContainerArchs = ::CFBundleCopyExecutableArchitecturesForURL(url);
|
||||
if (!pluginContainerArchs) {
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
AutoCFTypeObject autoPluginContainerArchs(pluginContainerArchs);
|
||||
|
||||
CFIndex pluginArchCount = ::CFArrayGetCount(pluginContainerArchs);
|
||||
for (CFIndex i = 0; i < pluginArchCount; i++) {
|
||||
CFNumberRef currentArch = static_cast<CFNumberRef>(::CFArrayGetValueAtIndex(pluginContainerArchs, i));
|
||||
int currentArchInt = 0;
|
||||
if (!::CFNumberGetValue(currentArch, kCFNumberIntType, ¤tArchInt)) {
|
||||
continue;
|
||||
}
|
||||
switch (currentArchInt) {
|
||||
case kCFBundleExecutableArchitectureI386:
|
||||
*result |= base::PROCESS_ARCH_I386;
|
||||
break;
|
||||
case kCFBundleExecutableArchitectureX86_64:
|
||||
*result |= base::PROCESS_ARCH_X86_64;
|
||||
break;
|
||||
case kCFBundleExecutableArchitecturePPC:
|
||||
*result |= base::PROCESS_ARCH_PPC;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return (*result ? NS_OK : NS_ERROR_FAILURE);
|
||||
#else
|
||||
return NS_ERROR_NOT_IMPLEMENTED;
|
||||
#endif
|
||||
}
|
||||
|
||||
uint32 GeckoChildProcessHost::GetSupportedArchitecturesForProcessType(GeckoProcessType type)
|
||||
{
|
||||
#ifdef XP_MACOSX
|
||||
if (type == GeckoProcessType_Plugin) {
|
||||
// Cache this, it shouldn't ever change.
|
||||
static uint32 pluginContainerArchs = 0;
|
||||
if (pluginContainerArchs == 0) {
|
||||
FilePath exePath;
|
||||
GetPathToBinary(exePath);
|
||||
nsresult rv = GetArchitecturesForBinary(exePath.value().c_str(), &pluginContainerArchs);
|
||||
NS_ASSERTION(NS_SUCCEEDED(rv) && pluginContainerArchs != 0, "Getting architecture of plugin container failed!");
|
||||
if (NS_FAILED(rv) || pluginContainerArchs == 0) {
|
||||
pluginContainerArchs = base::GetCurrentProcessArchitecture();
|
||||
}
|
||||
}
|
||||
return pluginContainerArchs;
|
||||
}
|
||||
#endif
|
||||
|
||||
return base::GetCurrentProcessArchitecture();
|
||||
}
|
||||
|
||||
#ifdef XP_WIN
|
||||
void GeckoChildProcessHost::InitWindowsGroupID()
|
||||
{
|
||||
|
@ -143,7 +260,7 @@ void GeckoChildProcessHost::InitWindowsGroupID()
|
|||
#endif
|
||||
|
||||
bool
|
||||
GeckoChildProcessHost::SyncLaunch(std::vector<std::string> aExtraOpts, int aTimeoutMs)
|
||||
GeckoChildProcessHost::SyncLaunch(std::vector<std::string> aExtraOpts, int aTimeoutMs, base::ProcessArchitecture arch)
|
||||
{
|
||||
#ifdef XP_WIN
|
||||
InitWindowsGroupID();
|
||||
|
@ -157,7 +274,7 @@ GeckoChildProcessHost::SyncLaunch(std::vector<std::string> aExtraOpts, int aTime
|
|||
ioLoop->PostTask(FROM_HERE,
|
||||
NewRunnableMethod(this,
|
||||
&GeckoChildProcessHost::PerformAsyncLaunch,
|
||||
aExtraOpts));
|
||||
aExtraOpts, arch));
|
||||
// NB: this uses a different mechanism than the chromium parent
|
||||
// class.
|
||||
MonitorAutoEnter mon(mMonitor);
|
||||
|
@ -194,7 +311,7 @@ GeckoChildProcessHost::AsyncLaunch(std::vector<std::string> aExtraOpts)
|
|||
ioLoop->PostTask(FROM_HERE,
|
||||
NewRunnableMethod(this,
|
||||
&GeckoChildProcessHost::PerformAsyncLaunch,
|
||||
aExtraOpts));
|
||||
aExtraOpts, base::GetCurrentProcessArchitecture()));
|
||||
|
||||
// This may look like the sync launch wait, but we only delay as
|
||||
// long as it takes to create the channel.
|
||||
|
@ -217,7 +334,7 @@ GeckoChildProcessHost::InitializeChannel()
|
|||
}
|
||||
|
||||
bool
|
||||
GeckoChildProcessHost::PerformAsyncLaunch(std::vector<std::string> aExtraOpts)
|
||||
GeckoChildProcessHost::PerformAsyncLaunch(std::vector<std::string> aExtraOpts, base::ProcessArchitecture arch)
|
||||
{
|
||||
// FIXME/cjones: make this work from non-IO threads, too
|
||||
|
||||
|
@ -246,18 +363,14 @@ GeckoChildProcessHost::PerformAsyncLaunch(std::vector<std::string> aExtraOpts)
|
|||
// and passing wstrings from one config to the other is unsafe. So
|
||||
// we split the logic here.
|
||||
|
||||
FilePath exePath;
|
||||
#if defined(OS_LINUX) || defined(OS_MACOSX)
|
||||
base::environment_map newEnvVars;
|
||||
#endif
|
||||
|
||||
nsCOMPtr<nsIProperties> directoryService(do_GetService(NS_DIRECTORY_SERVICE_CONTRACTID));
|
||||
nsCOMPtr<nsIFile> greDir;
|
||||
nsresult rv = directoryService->Get(NS_GRE_DIR, NS_GET_IID(nsIFile), getter_AddRefs(greDir));
|
||||
if (NS_SUCCEEDED(rv)) {
|
||||
nsCString path;
|
||||
greDir->GetNativePath(path);
|
||||
exePath = FilePath(path.get());
|
||||
#ifdef OS_LINUX
|
||||
#ifdef ANDROID
|
||||
path += "/lib";
|
||||
|
@ -267,18 +380,10 @@ GeckoChildProcessHost::PerformAsyncLaunch(std::vector<std::string> aExtraOpts)
|
|||
newEnvVars["DYLD_LIBRARY_PATH"] = path.get();
|
||||
#endif
|
||||
}
|
||||
else {
|
||||
exePath = FilePath(CommandLine::ForCurrentProcess()->argv()[0]);
|
||||
exePath = exePath.DirName();
|
||||
}
|
||||
|
||||
#ifdef OS_MACOSX
|
||||
// We need to use an App Bundle on OS X so that we can hide
|
||||
// the dock icon. See Bug 557225
|
||||
exePath = exePath.AppendASCII(MOZ_CHILD_PROCESS_BUNDLE);
|
||||
#endif
|
||||
|
||||
exePath = exePath.AppendASCII(MOZ_CHILD_PROCESS_NAME);
|
||||
FilePath exePath;
|
||||
GetPathToBinary(exePath);
|
||||
|
||||
#ifdef ANDROID
|
||||
// The java wrapper unpacks this for us but can't make it executable
|
||||
|
@ -350,7 +455,7 @@ GeckoChildProcessHost::PerformAsyncLaunch(std::vector<std::string> aExtraOpts)
|
|||
#if defined(OS_LINUX) || defined(OS_MACOSX)
|
||||
newEnvVars,
|
||||
#endif
|
||||
false, &process);
|
||||
false, &process, arch);
|
||||
|
||||
#ifdef XP_MACOSX
|
||||
// Wait for the child process to send us its 'task_t' data.
|
||||
|
@ -394,11 +499,8 @@ GeckoChildProcessHost::PerformAsyncLaunch(std::vector<std::string> aExtraOpts)
|
|||
//--------------------------------------------------
|
||||
#elif defined(OS_WIN)
|
||||
|
||||
FilePath exePath =
|
||||
FilePath::FromWStringHack(CommandLine::ForCurrentProcess()->program());
|
||||
exePath = exePath.DirName();
|
||||
|
||||
exePath = exePath.AppendASCII(MOZ_CHILD_PROCESS_NAME);
|
||||
FilePath exePath;
|
||||
GetPathToBinary(exePath);
|
||||
|
||||
CommandLine cmdLine(exePath.ToWStringHack());
|
||||
cmdLine.AppendSwitchWithValue(switches::kProcessChannelID, channel_id());
|
||||
|
|
|
@ -64,9 +64,16 @@ public:
|
|||
|
||||
~GeckoChildProcessHost();
|
||||
|
||||
bool SyncLaunch(std::vector<std::string> aExtraOpts=std::vector<std::string>(), int32 timeoutMs=0);
|
||||
static nsresult GetArchitecturesForBinary(const char *path, uint32 *result);
|
||||
|
||||
static uint32 GetSupportedArchitecturesForProcessType(GeckoProcessType type);
|
||||
|
||||
bool SyncLaunch(std::vector<std::string> aExtraOpts=std::vector<std::string>(),
|
||||
int32 timeoutMs=0,
|
||||
base::ProcessArchitecture arch=base::GetCurrentProcessArchitecture());
|
||||
bool AsyncLaunch(std::vector<std::string> aExtraOpts=std::vector<std::string>());
|
||||
bool PerformAsyncLaunch(std::vector<std::string> aExtraOpts=std::vector<std::string>());
|
||||
bool PerformAsyncLaunch(std::vector<std::string> aExtraOpts=std::vector<std::string>(),
|
||||
base::ProcessArchitecture arch=base::GetCurrentProcessArchitecture());
|
||||
|
||||
virtual void OnChannelConnected(int32 peer_pid);
|
||||
virtual void OnMessageReceived(const IPC::Message& aMsg);
|
||||
|
|
|
@ -45,6 +45,11 @@
|
|||
by Patrick C. Beard.
|
||||
*/
|
||||
|
||||
#ifdef MOZ_IPC
|
||||
#include "GeckoChildProcessHost.h"
|
||||
#include "base/process_util.h"
|
||||
#endif
|
||||
|
||||
#include "prlink.h"
|
||||
#include "prnetdb.h"
|
||||
#include "nsXPCOM.h"
|
||||
|
@ -103,13 +108,13 @@ static nsresult toCFURLRef(nsIFile* file, CFURLRef& outURL)
|
|||
|
||||
PRBool nsPluginsDir::IsPluginFile(nsIFile* file)
|
||||
{
|
||||
nsCString temp;
|
||||
file->GetNativeLeafName(temp);
|
||||
nsCString fileName;
|
||||
file->GetNativeLeafName(fileName);
|
||||
/*
|
||||
* Don't load the VDP fake plugin, to avoid tripping a bad bug in OS X
|
||||
* 10.5.3 (see bug 436575).
|
||||
*/
|
||||
if (!strcmp(temp.get(), "VerifiedDownloadPlugin.plugin")) {
|
||||
if (!strcmp(fileName.get(), "VerifiedDownloadPlugin.plugin")) {
|
||||
NS_WARNING("Preventing load of VerifiedDownloadPlugin.plugin (see bug 436575)");
|
||||
return PR_FALSE;
|
||||
}
|
||||
|
@ -125,7 +130,27 @@ PRBool nsPluginsDir::IsPluginFile(nsIFile* file)
|
|||
UInt32 packageType, packageCreator;
|
||||
::CFBundleGetPackageInfo(pluginBundle, &packageType, &packageCreator);
|
||||
if (packageType == 'BRPL' || packageType == 'IEPL' || packageType == 'NSPL') {
|
||||
#ifdef MOZ_IPC
|
||||
// Get path to plugin as a C string.
|
||||
char executablePath[PATH_MAX];
|
||||
executablePath[0] = '\0';
|
||||
if (!::CFURLGetFileSystemRepresentation(pluginURL, true, (UInt8*)&executablePath, PATH_MAX)) {
|
||||
executablePath[0] = '\0';
|
||||
}
|
||||
|
||||
uint32 pluginLibArchitectures;
|
||||
nsresult rv = mozilla::ipc::GeckoChildProcessHost::GetArchitecturesForBinary(executablePath, &pluginLibArchitectures);
|
||||
if (NS_FAILED(rv)) {
|
||||
return PR_FALSE;
|
||||
}
|
||||
|
||||
uint32 containerArchitectures = mozilla::ipc::GeckoChildProcessHost::GetSupportedArchitecturesForProcessType(GeckoProcessType_Plugin);
|
||||
|
||||
// Consider the plugin architecture valid if there is any overlap in the masks.
|
||||
isPluginFile = !!(containerArchitectures & pluginLibArchitectures);
|
||||
#else
|
||||
isPluginFile = !!::CFBundlePreflightExecutable(pluginBundle, NULL);
|
||||
#endif
|
||||
}
|
||||
::CFRelease(pluginBundle);
|
||||
}
|
||||
|
|
Загрузка…
Ссылка в новой задаче