diff --git a/dom/plugins/base/nsPluginsDirWin.cpp b/dom/plugins/base/nsPluginsDirWin.cpp index cf3eaa1d7bfd..114ef7e05e88 100644 --- a/dom/plugins/base/nsPluginsDirWin.cpp +++ b/dom/plugins/base/nsPluginsDirWin.cpp @@ -27,6 +27,41 @@ #include "nsIFile.h" #include "nsUnicharUtils.h" +#include +#define SHOCKWAVE_BASE_FILENAME L"np32dsw" +/** + * Determines whether or not SetDllDirectory should be called for this plugin. + * + * @param pluginFilePath The full path of the plugin file + * @return true if SetDllDirectory can be called for the plugin + */ +bool +ShouldProtectPluginCurrentDirectory(LPCWSTR pluginFilePath) +{ + LPCWSTR passedInFilename = PathFindFileName(pluginFilePath); + if (!passedInFilename) { + return true; + } + + // Somewhere in the middle of 11.6 version of Shockwave, naming of the DLL + // after its version number is introduced. + if (!wcsicmp(passedInFilename, SHOCKWAVE_BASE_FILENAME L".dll")) { + return false; + } + + // Shockwave versions before 1202122 will break if you call SetDllDirectory + const uint64_t kFixedShockwaveVersion = 1202122; + uint64_t version; + int found = swscanf(passedInFilename, SHOCKWAVE_BASE_FILENAME L"_%llu.dll", + &version); + if (found && version < kFixedShockwaveVersion) { + return false; + } + + // We always want to call SetDllDirectory otherwise + return true; +} + using namespace mozilla; /* Local helper functions */ @@ -245,17 +280,13 @@ nsresult nsPluginFile::LoadPlugin(PRLibrary **outLibrary) bool protectCurrentDirectory = true; - nsAutoString pluginFolderPath; - mPlugin->GetPath(pluginFolderPath); - - int32_t idx = pluginFolderPath.RFindChar('\\'); - if (kNotFound == idx) - return NS_ERROR_FILE_INVALID_PATH; - - if (Substring(pluginFolderPath, idx).LowerCaseEqualsLiteral("\\np32dsw.dll")) { - protectCurrentDirectory = false; - } + nsAutoString pluginFilePath; + mPlugin->GetPath(pluginFilePath); + protectCurrentDirectory = + ShouldProtectPluginCurrentDirectory(pluginFilePath.BeginReading()); + nsAutoString pluginFolderPath = pluginFilePath; + int32_t idx = pluginFilePath.RFindChar('\\'); pluginFolderPath.SetLength(idx); BOOL restoreOrigDir = FALSE; diff --git a/dom/plugins/ipc/PluginProcessChild.cpp b/dom/plugins/ipc/PluginProcessChild.cpp index 9649421a73be..0b64ad9d50fb 100644 --- a/dom/plugins/ipc/PluginProcessChild.cpp +++ b/dom/plugins/ipc/PluginProcessChild.cpp @@ -15,6 +15,7 @@ #ifdef XP_WIN #include +bool ShouldProtectPluginCurrentDirectory(LPCWSTR pluginFilePath); #endif using mozilla::ipc::IOThreadChild; @@ -37,6 +38,7 @@ std::size_t caseInsensitiveFind(std::string aHaystack, std::string aNeedle) { namespace mozilla { namespace plugins { + bool PluginProcessChild::Init() { @@ -102,21 +104,12 @@ PluginProcessChild::Init() CommandLine::ForCurrentProcess()->GetLooseValues(); NS_ABORT_IF_FALSE(values.size() >= 1, "not enough loose args"); - pluginFilename = WideToUTF8(values[0]); - - bool protectCurrentDirectory = true; - // Don't use SetDllDirectory for Shockwave Director - const std::string shockwaveDirectorPluginFilename("\\np32dsw.dll"); - std::size_t index = caseInsensitiveFind(pluginFilename, shockwaveDirectorPluginFilename); - if (index != std::string::npos && - index + shockwaveDirectorPluginFilename.length() == pluginFilename.length()) { - protectCurrentDirectory = false; - } - if (protectCurrentDirectory) { + if (ShouldProtectPluginCurrentDirectory(values[0].c_str())) { SanitizeEnvironmentVariables(); SetDllDirectory(L""); } + pluginFilename = WideToUTF8(values[0]); #else # error Sorry #endif