Bug 1184333 - Handle UTF8 paths as input for GMP loading. r=bobowen

This commit is contained in:
Chris Pearce 2015-07-17 11:09:49 +12:00
Родитель 730e6e237a
Коммит c629cf3789
4 изменённых файлов: 62 добавлений и 20 удалений

Просмотреть файл

@ -51,6 +51,13 @@ extern PRLogModuleInfo* GetGMPLog();
namespace gmp { namespace gmp {
static bool
FileExists(nsIFile* aFile)
{
bool exists = false;
return aFile && NS_SUCCEEDED(aFile->Exists(&exists)) && exists;
}
GMPChild::GMPChild() GMPChild::GMPChild()
: mAsyncShutdown(nullptr) : mAsyncShutdown(nullptr)
, mGMPMessageLoop(MessageLoop::current()) , mGMPMessageLoop(MessageLoop::current())
@ -269,7 +276,7 @@ GMPChild::Init(const std::string& aPluginPath,
#endif #endif
mPluginPath = aPluginPath; mPluginPath = aPluginPath;
mVoucherPath = aVoucherPath; mSandboxVoucherPath = aVoucherPath;
return true; return true;
} }
@ -323,6 +330,7 @@ GMPChild::PreLoadLibraries(const std::string& aPluginPath)
std::ifstream stream; std::ifstream stream;
#ifdef _MSC_VER #ifdef _MSC_VER
// Must use UTF16 for Windows for paths for non-Latin characters.
stream.open(static_cast<const wchar_t*>(path.get())); stream.open(static_cast<const wchar_t*>(path.get()));
#else #else
stream.open(NS_ConvertUTF16toUTF8(path).get()); stream.open(NS_ConvertUTF16toUTF8(path).get());
@ -363,7 +371,7 @@ GMPChild::PreLoadLibraries(const std::string& aPluginPath)
#endif #endif
bool bool
GMPChild::GetLibPath(nsACString& aOutLibPath) GMPChild::GetUTF8LibPath(nsACString& aOutLibPath)
{ {
#if defined(XP_MACOSX) && defined(MOZ_GMP_SANDBOX) #if defined(XP_MACOSX) && defined(MOZ_GMP_SANDBOX)
nsAutoCString pluginDirectoryPath, pluginFilePath; nsAutoCString pluginDirectoryPath, pluginFilePath;
@ -377,7 +385,17 @@ GMPChild::GetLibPath(nsACString& aOutLibPath)
if (!GetPluginFile(mPluginPath, libFile)) { if (!GetPluginFile(mPluginPath, libFile)) {
return false; return false;
} }
return NS_SUCCEEDED(libFile->GetNativePath(aOutLibPath));
if (!FileExists(libFile)) {
NS_WARNING("Can't find GMP library file!");
return false;
}
nsAutoString path;
libFile->GetPath(path);
aOutLibPath = NS_ConvertUTF16toUTF8(path);
return true;
#endif #endif
} }
@ -389,11 +407,14 @@ GMPChild::RecvStartPlugin()
#if defined(XP_WIN) #if defined(XP_WIN)
PreLoadLibraries(mPluginPath); PreLoadLibraries(mPluginPath);
#endif #endif
PreLoadPluginVoucher(mPluginPath); if (!PreLoadPluginVoucher(mPluginPath)) {
NS_WARNING("Plugin voucher failed to load!");
return false;
}
PreLoadSandboxVoucher(); PreLoadSandboxVoucher();
nsCString libPath; nsCString libPath;
if (!GetLibPath(libPath)) { if (!GetUTF8LibPath(libPath)) {
return false; return false;
} }
@ -613,11 +634,20 @@ GMPChild::PreLoadPluginVoucher(const std::string& aPluginPath)
nsCOMPtr<nsIFile> voucherFile; nsCOMPtr<nsIFile> voucherFile;
GetPluginVoucherFile(aPluginPath, voucherFile); GetPluginVoucherFile(aPluginPath, voucherFile);
if (!FileExists(voucherFile)) {
return true;
}
nsString path; nsString path;
voucherFile->GetPath(path); voucherFile->GetPath(path);
std::ifstream stream; std::ifstream stream;
#ifdef _MSC_VER
// Must use UTF16 for Windows for paths for non-Latin characters.
stream.open(static_cast<const wchar_t*>(path.get()), std::ios::binary);
#else
stream.open(NS_ConvertUTF16toUTF8(path).get(), std::ios::binary); stream.open(NS_ConvertUTF16toUTF8(path).get(), std::ios::binary);
#endif
if (!stream.good()) { if (!stream.good()) {
return false; return false;
} }
@ -646,7 +676,15 @@ void
GMPChild::PreLoadSandboxVoucher() GMPChild::PreLoadSandboxVoucher()
{ {
std::ifstream stream; std::ifstream stream;
stream.open(mVoucherPath.c_str(), std::ios::binary); #ifdef _MSC_VER
// Must use UTF16 for Windows for paths for non-Latin characters.
nsDependentCString utf8Path(mSandboxVoucherPath.c_str(),
mSandboxVoucherPath.size());
NS_ConvertUTF8toUTF16 utf16Path(utf8Path);
stream.open(static_cast<const wchar_t*>(utf16Path.get()), std::ios::binary);
#else
stream.open(mSandboxVoucherPath.c_str(), std::ios::binary);
#endif
if (!stream.good()) { if (!stream.good()) {
NS_WARNING("PreLoadSandboxVoucher can't find sandbox voucher file!"); NS_WARNING("PreLoadSandboxVoucher can't find sandbox voucher file!");
return; return;

Просмотреть файл

@ -53,7 +53,7 @@ private:
bool PreLoadPluginVoucher(const std::string& aPluginPath); bool PreLoadPluginVoucher(const std::string& aPluginPath);
void PreLoadSandboxVoucher(); void PreLoadSandboxVoucher();
bool GetLibPath(nsACString& aOutLibPath); bool GetUTF8LibPath(nsACString& aOutLibPath);
virtual bool RecvSetNodeId(const nsCString& aNodeId) override; virtual bool RecvSetNodeId(const nsCString& aNodeId) override;
virtual bool RecvStartPlugin() override; virtual bool RecvStartPlugin() override;
@ -88,7 +88,7 @@ private:
MessageLoop* mGMPMessageLoop; MessageLoop* mGMPMessageLoop;
std::string mPluginPath; std::string mPluginPath;
std::string mVoucherPath; std::string mSandboxVoucherPath;
std::string mNodeId; std::string mNodeId;
GMPLoader* mGMPLoader; GMPLoader* mGMPLoader;
nsTArray<uint8_t> mPluginVoucher; nsTArray<uint8_t> mPluginVoucher;

Просмотреть файл

@ -10,6 +10,7 @@
#include "gmp-entrypoints.h" #include "gmp-entrypoints.h"
#include "prlink.h" #include "prlink.h"
#include "prenv.h" #include "prenv.h"
#include "nsAutoPtr.h"
#include <string> #include <string>
@ -69,8 +70,8 @@ public:
{} {}
virtual ~GMPLoaderImpl() {} virtual ~GMPLoaderImpl() {}
virtual bool Load(const char* aLibPath, virtual bool Load(const char* aUTF8LibPath,
uint32_t aLibPathLen, uint32_t aUTF8LibPathLen,
char* aOriginSalt, char* aOriginSalt,
uint32_t aOriginSaltLen, uint32_t aOriginSaltLen,
const GMPPlatformAPI* aPlatformAPI) override; const GMPPlatformAPI* aPlatformAPI) override;
@ -133,8 +134,8 @@ GetStackAfterCurrentFrame(uint8_t** aOutTop, uint8_t** aOutBottom)
#endif #endif
bool bool
GMPLoaderImpl::Load(const char* aLibPath, GMPLoaderImpl::Load(const char* aUTF8LibPath,
uint32_t aLibPathLen, uint32_t aUTF8LibPathLen,
char* aOriginSalt, char* aOriginSalt,
uint32_t aOriginSaltLen, uint32_t aOriginSaltLen,
const GMPPlatformAPI* aPlatformAPI) const GMPPlatformAPI* aPlatformAPI)
@ -200,14 +201,13 @@ GMPLoaderImpl::Load(const char* aLibPath,
// loader will attempt to create an activation context which will fail because // loader will attempt to create an activation context which will fail because
// of the sandbox. If we create an activation context before we start the // of the sandbox. If we create an activation context before we start the
// sandbox then this one will get picked up by the DLL loader. // sandbox then this one will get picked up by the DLL loader.
int pathLen = MultiByteToWideChar(CP_ACP, 0, aLibPath, -1, nullptr, 0); int pathLen = MultiByteToWideChar(CP_UTF8, 0, aUTF8LibPath, -1, nullptr, 0);
if (pathLen == 0) { if (pathLen == 0) {
return false; return false;
} }
wchar_t* widePath = new wchar_t[pathLen]; nsAutoArrayPtr<wchar_t> widePath(new wchar_t[pathLen]);
if (MultiByteToWideChar(CP_ACP, 0, aLibPath, -1, widePath, pathLen) == 0) { if (MultiByteToWideChar(CP_UTF8, 0, aUTF8LibPath, -1, widePath, pathLen) == 0) {
delete[] widePath;
return false; return false;
} }
@ -216,20 +216,24 @@ GMPLoaderImpl::Load(const char* aLibPath,
actCtx.lpSource = widePath; actCtx.lpSource = widePath;
actCtx.lpResourceName = ISOLATIONAWARE_MANIFEST_RESOURCE_ID; actCtx.lpResourceName = ISOLATIONAWARE_MANIFEST_RESOURCE_ID;
ScopedActCtxHandle actCtxHandle(CreateActCtx(&actCtx)); ScopedActCtxHandle actCtxHandle(CreateActCtx(&actCtx));
delete[] widePath;
#endif #endif
// Start the sandbox now that we've generated the device bound node id. // Start the sandbox now that we've generated the device bound node id.
// This must happen after the node id is bound to the device id, as // This must happen after the node id is bound to the device id, as
// generating the device id requires privileges. // generating the device id requires privileges.
if (mSandboxStarter && !mSandboxStarter->Start(aLibPath)) { if (mSandboxStarter && !mSandboxStarter->Start(aUTF8LibPath)) {
return false; return false;
} }
// Load the GMP. // Load the GMP.
PRLibSpec libSpec; PRLibSpec libSpec;
libSpec.value.pathname = aLibPath; #ifdef XP_WIN
libSpec.value.pathname_u = widePath;
libSpec.type = PR_LibSpec_PathnameU;
#else
libSpec.value.pathname = aUTF8LibPath;
libSpec.type = PR_LibSpec_Pathname; libSpec.type = PR_LibSpec_Pathname;
#endif
mLib = PR_LoadLibraryWithFlags(libSpec, 0); mLib = PR_LoadLibraryWithFlags(libSpec, 0);
if (!mLib) { if (!mLib) {
return false; return false;

Просмотреть файл

@ -52,7 +52,7 @@ public:
// Calculates the device-bound node id, then activates the sandbox, // Calculates the device-bound node id, then activates the sandbox,
// then loads the GMP library and (if applicable) passes the bound node id // then loads the GMP library and (if applicable) passes the bound node id
// to the GMP. // to the GMP.
virtual bool Load(const char* aLibPath, virtual bool Load(const char* aUTF8LibPath,
uint32_t aLibPathLen, uint32_t aLibPathLen,
char* aOriginSalt, char* aOriginSalt,
uint32_t aOriginSaltLen, uint32_t aOriginSaltLen,