diff options
Diffstat (limited to 'webkit/glue/plugins/plugin_list.cc')
-rw-r--r-- | webkit/glue/plugins/plugin_list.cc | 311 |
1 files changed, 234 insertions, 77 deletions
diff --git a/webkit/glue/plugins/plugin_list.cc b/webkit/glue/plugins/plugin_list.cc index b2a7634..4b3ce27 100644 --- a/webkit/glue/plugins/plugin_list.cc +++ b/webkit/glue/plugins/plugin_list.cc @@ -11,6 +11,7 @@ #include "base/logging.h" #include "base/string_split.h" #include "base/string_util.h" +#include "base/sys_string_conversions.h" #include "base/utf_string_conversions.h" #include "googleurl/src/gurl.h" #include "net/base/mime_util.h" @@ -23,12 +24,19 @@ namespace NPAPI { base::LazyInstance<PluginList> g_singleton(base::LINKER_INITIALIZED); +static LoadPluginsFromDiskHookFunc g_load_plugins_hook; + // static PluginList* PluginList::Singleton() { return g_singleton.Pointer(); } // static +void PluginList::SetPluginLoadHook(LoadPluginsFromDiskHookFunc hook) { + g_load_plugins_hook = hook; +} + +// static bool PluginList::DebugPluginLoading() { return CommandLine::ForCurrentProcess()->HasSwitch( switches::kDebugPluginLoading); @@ -108,9 +116,9 @@ bool PluginList::CreateWebPluginInfo(const PluginVersionInfo& pvi, WebPluginInfo* info) { std::vector<std::string> mime_types, file_extensions; std::vector<string16> descriptions; - SplitString(WideToUTF8(pvi.mime_types), '|', &mime_types); - SplitString(WideToUTF8(pvi.file_extensions), '|', &file_extensions); - SplitString(WideToUTF16(pvi.type_descriptions), '|', &descriptions); + base::SplitString(WideToUTF8(pvi.mime_types), '|', &mime_types); + base::SplitString(WideToUTF8(pvi.file_extensions), '|', &file_extensions); + base::SplitString(WideToUTF16(pvi.type_descriptions), '|', &descriptions); info->mime_types.clear(); @@ -130,7 +138,7 @@ bool PluginList::CreateWebPluginInfo(const PluginVersionInfo& pvi, WebPluginMimeType mime_type; mime_type.mime_type = StringToLowerASCII(mime_types[i]); if (file_extensions.size() > i) - SplitString(file_extensions[i], ',', &mime_type.file_extensions); + base::SplitString(file_extensions[i], ',', &mime_type.file_extensions); if (descriptions.size() > i) { mime_type.description = descriptions[i]; @@ -154,10 +162,21 @@ bool PluginList::CreateWebPluginInfo(const PluginVersionInfo& pvi, } PluginList::PluginList() - : plugins_loaded_(false), plugins_need_refresh_(false) { + : plugins_loaded_(false), + plugins_need_refresh_(false), + disable_outdated_plugins_(false) { PlatformInit(); } +bool PluginList::ShouldDisableGroup(const string16& group_name) { + AutoLock lock(lock_); + if (PluginGroup::IsPluginNameDisabledByPolicy(group_name)) { + disabled_groups_.insert(group_name); + return true; + } + return disabled_groups_.count(group_name) > 0; +} + void PluginList::LoadPlugins(bool refresh) { // Don't want to hold the lock while loading new plugins, so we don't block // other methods if they're called on other threads. @@ -177,6 +196,9 @@ void PluginList::LoadPlugins(bool refresh) { internal_plugins = internal_plugins_; } + if (g_load_plugins_hook) + g_load_plugins_hook(); + std::vector<WebPluginInfo> new_plugins; std::set<FilePath> visited_plugins; @@ -216,15 +238,37 @@ void PluginList::LoadPlugins(bool refresh) { if (webkit_glue::IsDefaultPluginEnabled()) LoadPlugin(FilePath(kDefaultPluginLibraryName), &new_plugins); + // Disable all of the plugins and plugin groups that are disabled by policy. + // There's currenly a bug that makes it impossible to correctly re-enable + // plugins or plugin-groups to their original, "pre-policy" state, so + // plugins and groups are only changed to a more "safe" state after a policy + // change, i.e. from enabled to disabled. See bug 54681. + PluginMap plugin_groups; + GetPluginGroups(&new_plugins, &plugin_groups); + for (PluginMap::const_iterator it = plugin_groups.begin(); + it != plugin_groups.end(); ++it) { + PluginGroup* group = it->second.get(); + string16 group_name = group->GetGroupName(); + if (ShouldDisableGroup(group_name)) { + it->second->Enable(false); + } + + if (disable_outdated_plugins_) { + group->DisableOutdatedPlugins(); + if (!group->Enabled()) { + AutoLock lock(lock_); + disabled_groups_.insert(group_name); + } + } + } + // Only update the data now since loading plugins can take a while. AutoLock lock(lock_); - // Go through and mark new plugins in the disabled list as, well, disabled. - for (std::vector<WebPluginInfo>::iterator it = new_plugins.begin(); - it != new_plugins.end(); - ++it) { - if (disabled_plugins_.find(it->path) != disabled_plugins_.end()) - it->enabled = false; + // Mark disabled plugins as such. + for (size_t i = 0; i < new_plugins.size(); ++i) { + if (disabled_plugins_.count(new_plugins[i].path)) + new_plugins[i].enabled = false; } plugins_ = new_plugins; @@ -263,65 +307,6 @@ void PluginList::LoadPlugin(const FilePath& path, plugins->push_back(plugin_info); } -bool PluginList::FindPlugin(const std::string& mime_type, - bool allow_wildcard, - WebPluginInfo* info) { - DCHECK(mime_type == StringToLowerASCII(mime_type)); - - LoadPlugins(false); - AutoLock lock(lock_); - for (size_t i = 0; i < plugins_.size(); ++i) { - if (plugins_[i].enabled && - SupportsType(plugins_[i], mime_type, allow_wildcard)) { - *info = plugins_[i]; - return true; - } - } - - return false; -} - -bool PluginList::FindDisabledPlugin(const std::string& mime_type, - bool allow_wildcard, - WebPluginInfo* info) { - DCHECK(mime_type == StringToLowerASCII(mime_type)); - - LoadPlugins(false); - AutoLock lock(lock_); - for (size_t i = 0; i < plugins_.size(); ++i) { - if (!plugins_[i].enabled && - SupportsType(plugins_[i], mime_type, allow_wildcard)) { - *info = plugins_[i]; - return true; - } - } - - return false; -} - -bool PluginList::FindPlugin(const GURL &url, - std::string* actual_mime_type, - WebPluginInfo* info) { - LoadPlugins(false); - AutoLock lock(lock_); - std::string path = url.path(); - std::string::size_type last_dot = path.rfind('.'); - if (last_dot == std::string::npos) - return false; - - std::string extension = StringToLowerASCII(std::string(path, last_dot+1)); - - for (size_t i = 0; i < plugins_.size(); ++i) { - if (plugins_[i].enabled && - SupportsExtension(plugins_[i], extension, actual_mime_type)) { - *info = plugins_[i]; - return true; - } - } - - return false; -} - bool PluginList::SupportsType(const WebPluginInfo& info, const std::string &mime_type, bool allow_wildcard) { @@ -380,20 +365,111 @@ void PluginList::GetEnabledPlugins(bool refresh, } } +void PluginList::GetPluginInfoArray(const GURL& url, + const std::string& mime_type, + bool allow_wildcard, + std::vector<WebPluginInfo>* info, + std::vector<std::string>* actual_mime_types) +{ + DCHECK(mime_type == StringToLowerASCII(mime_type)); + DCHECK(info); + + LoadPlugins(false); + AutoLock lock(lock_); + info->clear(); + if (actual_mime_types) + actual_mime_types->clear(); + + std::set<FilePath> visited_plugins; + + // Add in enabled plugins by mime type. + WebPluginInfo default_plugin; + for (size_t i = 0; i < plugins_.size(); ++i) { + if (plugins_[i].enabled && + SupportsType(plugins_[i], mime_type, allow_wildcard)) { + FilePath path = plugins_[i].path; + if (path.value() != kDefaultPluginLibraryName && + visited_plugins.insert(path).second) { + info->push_back(plugins_[i]); + if (actual_mime_types) + actual_mime_types->push_back(mime_type); + } + } + } + + // Add in enabled plugins by url. + std::string path = url.path(); + std::string::size_type last_dot = path.rfind('.'); + if (last_dot != std::string::npos) { + std::string extension = StringToLowerASCII(std::string(path, last_dot+1)); + std::string actual_mime_type; + for (size_t i = 0; i < plugins_.size(); ++i) { + if (plugins_[i].enabled && + SupportsExtension(plugins_[i], extension, &actual_mime_type)) { + FilePath path = plugins_[i].path; + if (path.value() != kDefaultPluginLibraryName && + visited_plugins.insert(path).second) { + info->push_back(plugins_[i]); + if (actual_mime_types) + actual_mime_types->push_back(actual_mime_type); + } + } + } + } + + // Add in disabled plugins by mime type. + for (size_t i = 0; i < plugins_.size(); ++i) { + if (!plugins_[i].enabled && + SupportsType(plugins_[i], mime_type, allow_wildcard)) { + FilePath path = plugins_[i].path; + if (path.value() != kDefaultPluginLibraryName && + visited_plugins.insert(path).second) { + info->push_back(plugins_[i]); + if (actual_mime_types) + actual_mime_types->push_back(mime_type); + } + } + } + + // Add the default plugin at the end if it supports the mime type given, + // and the default plugin is enabled. + if (!plugins_.empty() && webkit_glue::IsDefaultPluginEnabled()) { + const WebPluginInfo& default_info = plugins_.back(); + if (SupportsType(default_info, mime_type, allow_wildcard)) { + info->push_back(default_info); + if (actual_mime_types) + actual_mime_types->push_back(mime_type); + } + } +} + bool PluginList::GetPluginInfo(const GURL& url, const std::string& mime_type, bool allow_wildcard, WebPluginInfo* info, std::string* actual_mime_type) { - bool found = FindPlugin(mime_type, allow_wildcard, info); - if (!found || (info->path.value() == kDefaultPluginLibraryName)) { - if (FindPlugin(url, actual_mime_type, info) || - FindDisabledPlugin(mime_type, allow_wildcard, info)) { - found = true; + DCHECK(info); + std::vector<WebPluginInfo> info_list; + + // GetPluginInfoArray has slightly less work to do if we can pass + // NULL for the mime type list... + if (actual_mime_type) { + std::vector<std::string> mime_type_list; + GetPluginInfoArray( + url, mime_type, allow_wildcard, &info_list, &mime_type_list); + if (!info_list.empty()) { + *info = info_list[0]; + *actual_mime_type = mime_type_list[0]; + return true; + } + } else { + GetPluginInfoArray(url, mime_type, allow_wildcard, &info_list, NULL); + if (!info_list.empty()) { + *info = info_list[0]; + return true; } } - - return found; + return false; } bool PluginList::GetPluginInfoByPath(const FilePath& plugin_path, @@ -410,6 +486,47 @@ bool PluginList::GetPluginInfoByPath(const FilePath& plugin_path, return false; } +void PluginList::GetPluginGroups(bool load_if_necessary, + PluginMap* plugin_groups) { + if (load_if_necessary) + LoadPlugins(false); + + AutoLock lock(lock_); + GetPluginGroups(&plugins_, plugin_groups); +} + +// static +void PluginList::GetPluginGroups(const std::vector<WebPluginInfo>* plugins, + PluginMap* plugin_groups) { + plugin_groups->clear(); + // We first search for an existing group that matches our name, + // and only create a new group if we can't find any. + for (size_t i = 0; i < plugins->size(); ++i) { + const WebPluginInfo& web_plugin = (*plugins)[i]; + PluginGroup* group = PluginGroup::FindGroupMatchingPlugin( + *plugin_groups, web_plugin); + if (!group) { + group = PluginGroup::CopyOrCreatePluginGroup(web_plugin); + std::string identifier = group->identifier(); + // If the identifier is not unique, use the full path. This means that we + // probably won't be able to search for this group by identifier, but at + // least it's going to be in the set of plugin groups, and if there + // is already a plug-in with the same filename, it's probably going to + // handle the same MIME types (and it has a higher priority), so this one + // is not going to run anyway. + if (plugin_groups->find(identifier) != plugin_groups->end()) +#if defined(OS_POSIX) + identifier = web_plugin.path.value(); +#elif defined(OS_WIN) + identifier = base::SysWideToUTF8(web_plugin.path.value()); +#endif + DCHECK(plugin_groups->find(identifier) == plugin_groups->end()); + (*plugin_groups)[identifier] = linked_ptr<PluginGroup>(group); + } + group->AddPlugin(web_plugin, i); + } +} + bool PluginList::EnablePlugin(const FilePath& filename) { AutoLock lock(lock_); @@ -459,6 +576,46 @@ bool PluginList::DisablePlugin(const FilePath& filename) { return did_disable; } +bool PluginList::EnableGroup(bool enable, const string16& group_name) { + bool did_change = false; + { + AutoLock lock(lock_); + + std::set<string16>::iterator entry = disabled_groups_.find(group_name); + if (enable) { + if (entry == disabled_groups_.end()) + return did_change; // Early exit if group not in disabled list. + disabled_groups_.erase(entry); // Remove from disabled list. + } else { + if (entry != disabled_groups_.end()) + return did_change; // Early exit if group already in disabled list. + disabled_groups_.insert(group_name); + } + } + + PluginMap plugin_groups; + GetPluginGroups(false, &plugin_groups); + for (PluginMap::const_iterator it = plugin_groups.begin(); + it != plugin_groups.end(); ++it) { + if (it->second->GetGroupName() == group_name) { + if (it->second->Enabled() != enable) { + it->second->Enable(enable); + did_change = true; + break; + } + } + } + + return did_change; +} + +void PluginList::DisableOutdatedPluginGroups() { + disable_outdated_plugins_ = true; +} + +PluginList::~PluginList() { +} + void PluginList::Shutdown() { // TODO } |