diff options
author | jam@chromium.org <jam@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2009-01-12 19:43:44 +0000 |
---|---|---|
committer | jam@chromium.org <jam@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2009-01-12 19:43:44 +0000 |
commit | b734450b86e9d6bd7a07b381c119ca91803ae46b (patch) | |
tree | 5099af8aa485c96af0c487e434bca5a0212f424e /webkit/glue/plugins/plugin_list.cc | |
parent | 64a02b8056c86576428022859baadbb9a7b929f1 (diff) | |
download | chromium_src-b734450b86e9d6bd7a07b381c119ca91803ae46b.zip chromium_src-b734450b86e9d6bd7a07b381c119ca91803ae46b.tar.gz chromium_src-b734450b86e9d6bd7a07b381c119ca91803ae46b.tar.bz2 |
Get rid of lowercasing plugin filenames in order to determine if two paths point to the same plugin. Check plugin versions and load the latest version if multiple versions are found.I've also refactored and cleaned PluginList so that it doesn't depend on PluginLib, which only made sense a long time ago when plugins were loaded in process. Now PluginLib will only be loaded in the plugin process (and not in the browser process as well).
Review URL: http://codereview.chromium.org/17451
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@7888 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'webkit/glue/plugins/plugin_list.cc')
-rw-r--r-- | webkit/glue/plugins/plugin_list.cc | 232 |
1 files changed, 133 insertions, 99 deletions
diff --git a/webkit/glue/plugins/plugin_list.cc b/webkit/glue/plugins/plugin_list.cc index f969874..b4b3dcb 100644 --- a/webkit/glue/plugins/plugin_list.cc +++ b/webkit/glue/plugins/plugin_list.cc @@ -17,10 +17,11 @@ #include "base/string_util.h" #include "base/sys_string_conversions.h" #include "base/time.h" +#include "net/base/mime_util.h" #include "webkit/activex_shim/activex_shared.h" +#include "webkit/glue/plugins/plugin_lib.h" #include "webkit/glue/webkit_glue.h" #include "webkit/glue/webplugin.h" -#include "webkit/glue/plugins/plugin_lib.h" #include "googleurl/src/gurl.h" using base::TimeDelta; @@ -42,10 +43,10 @@ static const TCHAR kRegistryPath[] = _T("Path"); static const TCHAR kRegistryMozillaPlugins[] = _T("SOFTWARE\\MozillaPlugins"); static const TCHAR kRegistryFirefoxInstalled[] = _T("SOFTWARE\\Mozilla\\Mozilla Firefox"); -static const TCHAR kMozillaActiveXPlugin[] = _T("npmozax.dll"); -static const TCHAR kNewWMPPlugin[] = _T("np-mswmp.dll"); -static const TCHAR kOldWMPPlugin[] = _T("npdsplay.dll"); -static const TCHAR kYahooApplicationStatePlugin[] = _T("npystate.dll"); +static const char kMozillaActiveXPlugin[] = "npmozax.dll"; +static const char kNewWMPPlugin[] = "np-mswmp.dll"; +static const char kOldWMPPlugin[] = "npdsplay.dll"; +static const char kYahooApplicationStatePlugin[] = "npystate.dll"; static const TCHAR kRegistryJava[] = _T("Software\\JavaSoft\\Java Runtime Environment"); static const TCHAR kRegistryBrowserJavaVersion[] = _T("BrowserJavaVersion"); @@ -80,10 +81,6 @@ PluginList::PluginList() : !command_line.HasSwitch(kNoNativeActiveXShimSwitch); } -PluginList::~PluginList() { - plugins_.clear(); -} - void PluginList::LoadPlugins(bool refresh) { if (plugins_loaded_ && !refresh) return; @@ -122,9 +119,11 @@ void PluginList::LoadPlugins(bool refresh) { LoadWindowsMediaPlugins(); if (webkit_glue::IsDefaultPluginEnabled()) { - scoped_refptr<PluginLib> default_plugin = PluginLib::CreatePluginLib( - FilePath(kDefaultPluginLibraryName)); - plugins_.push_back(default_plugin); + WebPluginInfo info; + if (PluginLib::ReadWebPluginInfo(FilePath(kDefaultPluginLibraryName), + &info)) { + plugins_[WideToUTF8(kDefaultPluginLibraryName)] = info; + } } TimeTicks end_time = TimeTicks::Now(); @@ -155,15 +154,42 @@ void PluginList::LoadPlugins(const FilePath &path) { FindClose(find_handle); } + +// Compares Windows style version strings (i.e. 1,2,3,4). Returns true if b's +// version is newer than a's, or false if it's equal or older. +bool IsNewerVersion(const std::wstring& a, const std::wstring& b) { + std::vector<std::wstring> a_ver, b_ver; + SplitString(a, ',', &a_ver); + SplitString(b, ',', &b_ver); + if (a_ver.size() != b_ver.size()) + return false; + for (size_t i = 0; i < a_ver.size(); i++) { + int cur_a = StringToInt(a_ver[i]); + int cur_b = StringToInt(b_ver[i]); + if (cur_a > cur_b) + return false; + if (cur_a < cur_b) + return true; + } + return false; +} + void PluginList::LoadPlugin(const FilePath &path) { - if (!ShouldLoadPlugin(path.BaseName())) + WebPluginInfo plugin_info; + if (!PluginLib::ReadWebPluginInfo(path, &plugin_info)) return; - scoped_refptr<PluginLib> new_plugin = PluginLib::CreatePluginLib(path); - if (!new_plugin.get()) + // Canonicalize names on Windows in case different versions of the plugin + // have different case in the version string. + std::string filename_lc = StringToLowerASCII(plugin_info.filename); + if (!ShouldLoadPlugin(filename_lc)) return; - const WebPluginInfo& plugin_info = new_plugin->plugin_info(); + PluginMap::const_iterator iter = plugins_.find(filename_lc); + if (iter != plugins_.end() && + !IsNewerVersion(iter->second.version, plugin_info.version)) + return; // The loaded version is newer. + for (size_t i = 0; i < plugin_info.mime_types.size(); ++i) { // TODO: don't load global handlers for now. // WebKit hands to the Plugin before it tries @@ -172,50 +198,41 @@ void PluginList::LoadPlugin(const FilePath &path) { if (mime_type == "*" ) { #ifndef NDEBUG // Make an exception for NPSPY. - if (plugin_info.file.value().find(L"npspy.dll") != std::wstring::npos) { - // Put it at the beginning so it's used before the real plugin. - plugins_.insert(plugins_.begin(), new_plugin.get()); - } + if (filename_lc == "npspy.dll") + break; #endif - continue; - } - - if (!SupportsType(mime_type)) { - plugins_.push_back(new_plugin); return; } } + + plugins_[filename_lc] = plugin_info; } -bool PluginList::ShouldLoadPlugin(const FilePath& filename) { - // Canonicalize names. - std::wstring filename_lc = StringToLowerASCII(filename.value()); - +bool PluginList::ShouldLoadPlugin(const std::string& filename) { // Depends on XPCOM. - if (filename_lc == kMozillaActiveXPlugin) + if (filename == kMozillaActiveXPlugin) return false; // Disable the yahoo application state plugin as it crashes the plugin // process on return from NPObjectStub::OnInvoke. Please refer to // http://b/issue?id=1372124 for more information. - if (filename_lc == kYahooApplicationStatePlugin) + if (filename == kYahooApplicationStatePlugin) return false; // We will use activex shim to handle embeded wmp media. if (use_internal_activex_shim_) { - if (filename_lc == kNewWMPPlugin || filename_lc == kOldWMPPlugin) + if (filename == kNewWMPPlugin || filename == kOldWMPPlugin) return false; } else { // If both the new and old WMP plugins exist, only load the new one. - if (filename_lc == kNewWMPPlugin) { + if (filename == kNewWMPPlugin) { if (dont_load_new_wmp_) return false; - int old_plugin = FindPluginFile(kOldWMPPlugin); - if (old_plugin != -1) - plugins_.erase(plugins_.begin() + old_plugin); - } else if (filename_lc == kOldWMPPlugin) { - if (FindPluginFile(kNewWMPPlugin) != -1) + if (plugins_.find(kOldWMPPlugin) != plugins_.end()) + plugins_.erase(kOldWMPPlugin); + } else if (filename == kOldWMPPlugin) { + if (plugins_.find(kOldWMPPlugin) != plugins_.end()) return false; } } @@ -224,73 +241,94 @@ bool PluginList::ShouldLoadPlugin(const FilePath& filename) { } void PluginList::LoadInternalPlugins() { - if (use_internal_activex_shim_) { - scoped_refptr<PluginLib> new_plugin = PluginLib::CreatePluginLib( - FilePath(kActiveXShimFileName)); - plugins_.push_back(new_plugin); - - new_plugin = PluginLib::CreatePluginLib( - FilePath(kActivexShimFileNameForMediaPlayer)); - plugins_.push_back(new_plugin); - } -} + if (!use_internal_activex_shim_) + return; -int PluginList::FindPluginFile(const std::wstring& filename) { - std::string filename_narrow = WideToASCII(filename); - for (size_t i = 0; i < plugins_.size(); ++i) { - if (LowerCaseEqualsASCII( - plugins_[i]->plugin_info().file.BaseName().value(), - filename_narrow.c_str())) { - return static_cast<int>(i); - } + WebPluginInfo info; + if (PluginLib::ReadWebPluginInfo(FilePath(kActiveXShimFileName), + &info)) { + plugins_[WideToUTF8(kActiveXShimFileName)] = info; } - return -1; -} + if (PluginLib::ReadWebPluginInfo(FilePath(kActivexShimFileNameForMediaPlayer), + &info)) { + plugins_[WideToUTF8(kActivexShimFileNameForMediaPlayer)] = info; + } +} -PluginLib* PluginList::FindPlugin(const std::string& mime_type, - const std::string& clsid, - bool allow_wildcard) { +bool PluginList::FindPlugin(const std::string& mime_type, + const std::string& clsid, + bool allow_wildcard, + WebPluginInfo* info) { DCHECK(mime_type == StringToLowerASCII(mime_type)); - for (size_t idx = 0; idx < plugins_.size(); ++idx) { - if (plugins_[idx]->SupportsType(mime_type, allow_wildcard)) { - if (!clsid.empty() && - plugins_[idx]->plugin_info().file.value() == kActiveXShimFileName) { + PluginMap::const_iterator default_iter = plugins_.end(); + for (PluginMap::const_iterator iter = plugins_.begin(); + iter != plugins_.end(); ++iter) { + if (SupportsType(iter->second, mime_type, allow_wildcard)) { + if (iter->second.path.value() == kDefaultPluginLibraryName) { + // Only use the default plugin if it's the only one that's found. + default_iter = iter; + continue; + } + + if (!clsid.empty() && iter->second.path.value() == kActiveXShimFileName) { // Special handling for ActiveX shim. If ActiveX is not installed, we // should use the default plugin to show the installation UI. if (!activex_shim::IsActiveXInstalled(clsid)) continue; } - return plugins_[idx]; + *info = iter->second; + return true; } } - return NULL; + if (default_iter != plugins_.end()) { + *info = default_iter->second; + return true; + } + + return false; } -PluginLib* PluginList::FindPlugin(const GURL &url, std::string* actual_mime_type) { +bool PluginList::FindPlugin(const GURL &url, std::string* actual_mime_type, + WebPluginInfo* info) { std::wstring path = base::SysNativeMBToWide(url.path()); std::wstring extension_wide = file_util::GetFileExtensionFromPath(path); if (extension_wide.empty()) - return NULL; + return false; std::string extension = StringToLowerASCII(base::SysWideToNativeMB(extension_wide)); - for (size_t idx = 0; idx < plugins_.size(); ++idx) { - if (SupportsExtension(plugins_[idx]->plugin_info(), extension, actual_mime_type)) { - return plugins_[idx]; + for (PluginMap::const_iterator iter = plugins_.begin(); + iter != plugins_.end(); ++iter) { + if (SupportsExtension(iter->second, extension, actual_mime_type)) { + *info = iter->second; + return true; } } - return NULL; + return false; } -bool PluginList::SupportsType(const std::string &mime_type) { - DCHECK(mime_type == StringToLowerASCII(mime_type)); - bool allow_wildcard = true; - return (FindPlugin(mime_type, "", allow_wildcard ) != 0); +bool PluginList::SupportsType(const WebPluginInfo& info, + const std::string &mime_type, + bool allow_wildcard) { + // Webkit will ask for a plugin to handle empty mime types. + if (mime_type.empty()) + return false; + + for (size_t i = 0; i < info.mime_types.size(); ++i) { + const WebPluginMimeType& mime_info = info.mime_types[i]; + if (net::MatchesMimeType(mime_info.mime_type, mime_type)) { + if (!allow_wildcard && mime_info.mime_type == "*") { + continue; + } + return true; + } + } + return false; } bool PluginList::SupportsExtension(const WebPluginInfo& info, @@ -315,9 +353,12 @@ bool PluginList::GetPlugins(bool refresh, std::vector<WebPluginInfo>* plugins) { if (refresh) LoadPlugins(true); + int i = 0; plugins->resize(plugins_.size()); - for (size_t i = 0; i < plugins->size(); ++i) - (*plugins)[i] = plugins_[i]->plugin_info(); + for (PluginMap::const_iterator iter = plugins_.begin(); + iter != plugins_.end(); ++iter) { + (*plugins)[i++] = iter->second; + } return true; } @@ -328,32 +369,25 @@ bool PluginList::GetPluginInfo(const GURL& url, bool allow_wildcard, WebPluginInfo* info, std::string* actual_mime_type) { - scoped_refptr<PluginLib> plugin = FindPlugin(mime_type, clsid, - allow_wildcard); - - if (plugin.get() == NULL || - (plugin->plugin_info().file.value() == kDefaultPluginLibraryName - && clsid.empty())) { - scoped_refptr<PluginLib> default_plugin = plugin; - plugin = FindPlugin(url, actual_mime_type); - // url matches may not return the default plugin if no match is found. - if (plugin.get() == NULL && default_plugin.get() != NULL) - plugin = default_plugin; + bool found = FindPlugin(mime_type, clsid, allow_wildcard, info); + if (!found || + (info->path.value() == kDefaultPluginLibraryName && clsid.empty())) { + WebPluginInfo info2; + if (FindPlugin(url, actual_mime_type, &info2)) { + found = true; + *info = info2; + } } - if (plugin.get() == NULL) - return false; - - *info = plugin->plugin_info(); - return true; + return found; } bool PluginList::GetPluginInfoByPath(const FilePath& plugin_path, WebPluginInfo* info) { - for (size_t i = 0; i < plugins_.size(); ++i) { - if (wcsicmp(plugins_[i]->plugin_info().file.value().c_str(), - plugin_path.value().c_str()) == 0) { - *info = plugins_[i]->plugin_info(); + for (PluginMap::const_iterator iter = plugins_.begin(); + iter != plugins_.end(); ++iter) { + if (iter->second.path == plugin_path) { + *info = iter->second; return true; } } |