Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(607)

Side by Side Diff: content/common/plugin_list.cc

Issue 26541011: Return matching plug-ins in the sorted order (by version number). (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Use multiset Created 7 years, 1 month ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « content/common/plugin_list.h ('k') | content/common/plugin_list_unittest.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "content/common/plugin_list.h" 5 #include "content/common/plugin_list.h"
6 6
7 #include <algorithm> 7 #include <algorithm>
8 8
9 #include "base/command_line.h" 9 #include "base/command_line.h"
10 #include "base/lazy_instance.h" 10 #include "base/lazy_instance.h"
11 #include "base/logging.h" 11 #include "base/logging.h"
12 #include "base/strings/string_split.h" 12 #include "base/strings/string_split.h"
13 #include "base/strings/string_util.h" 13 #include "base/strings/string_util.h"
14 #include "base/strings/sys_string_conversions.h" 14 #include "base/strings/sys_string_conversions.h"
15 #include "base/strings/utf_string_conversions.h" 15 #include "base/strings/utf_string_conversions.h"
16 #include "base/version.h"
16 #include "content/public/common/content_switches.h" 17 #include "content/public/common/content_switches.h"
17 #include "net/base/mime_util.h" 18 #include "net/base/mime_util.h"
18 #include "url/gurl.h" 19 #include "url/gurl.h"
19 20
20 #if defined(OS_WIN) 21 #if defined(OS_WIN)
21 #include "content/common/plugin_constants_win.h" 22 #include "content/common/plugin_constants_win.h"
22 #endif 23 #endif
23 24
24 namespace content { 25 namespace content {
25 26
(...skipping 135 matching lines...) Expand 10 before | Expand all | Expand 10 after
161 mime_type.description.erase(ext); 162 mime_type.description.erase(ext);
162 } 163 }
163 } 164 }
164 165
165 parsed_mime_types->push_back(mime_type); 166 parsed_mime_types->push_back(mime_type);
166 } 167 }
167 168
168 return true; 169 return true;
169 } 170 }
170 171
172 bool PluginList::VersionComparator::operator()(const WebPluginInfo& lhs,
173 const WebPluginInfo& rhs) const {
174 Version lhs_version;
175 Version rhs_version;
176 WebPluginInfo::CreateVersionFromString(lhs.version, &lhs_version);
177 WebPluginInfo::CreateVersionFromString(rhs.version, &rhs_version);
178 if (!lhs_version.IsValid())
179 lhs_version = Version("0");
180 if (!rhs_version.IsValid())
181 rhs_version = Version("0");
182
183 return lhs_version.CompareTo(rhs_version) > 0;
184 }
185
171 PluginList::PluginList() 186 PluginList::PluginList()
172 : loading_state_(LOADING_STATE_NEEDS_REFRESH), 187 : loading_state_(LOADING_STATE_NEEDS_REFRESH),
173 plugins_discovery_disabled_(false) { 188 plugins_discovery_disabled_(false) {
174 } 189 }
175 190
176 void PluginList::LoadPlugins(bool include_npapi) { 191 void PluginList::LoadPlugins(bool include_npapi) {
177 { 192 {
178 base::AutoLock lock(lock_); 193 base::AutoLock lock(lock_);
179 if (loading_state_ == LOADING_STATE_UP_TO_DATE) 194 if (loading_state_ == LOADING_STATE_UP_TO_DATE)
180 return; 195 return;
(...skipping 134 matching lines...) Expand 10 before | Expand all | Expand 10 after
315 std::vector<WebPluginInfo>* info, 330 std::vector<WebPluginInfo>* info,
316 std::vector<std::string>* actual_mime_types) { 331 std::vector<std::string>* actual_mime_types) {
317 DCHECK(mime_type == StringToLowerASCII(mime_type)); 332 DCHECK(mime_type == StringToLowerASCII(mime_type));
318 DCHECK(info); 333 DCHECK(info);
319 334
320 if (!use_stale) 335 if (!use_stale)
321 LoadPlugins(include_npapi); 336 LoadPlugins(include_npapi);
322 base::AutoLock lock(lock_); 337 base::AutoLock lock(lock_);
323 if (use_stale) 338 if (use_stale)
324 *use_stale = (loading_state_ != LOADING_STATE_UP_TO_DATE); 339 *use_stale = (loading_state_ != LOADING_STATE_UP_TO_DATE);
325 info->clear();
326 if (actual_mime_types) 340 if (actual_mime_types)
327 actual_mime_types->clear(); 341 actual_mime_types->clear();
328 342
329 std::set<base::FilePath> visited_plugins; 343 std::set<base::FilePath> visited_plugins;
344 // Instead of pushing elements to |info| directly, we add it to
345 // |matched_plugins| first so that they are sorted by version number.
346 // Returning matched plugins in sorted order ensures that the first plugin
347 // that is tried is always the one with the latest version. This helps in the
348 // case when we have more than one plugin for given mime type. If we would
349 // pick the one that is older, we would decide to block it because it's
350 // outdated and wouldn't give the newer plugin a chance to run.
351 std::multiset<WebPluginInfo, VersionComparator> matched_plugins;
330 352
331 // Add in plugins by mime type. 353 // Add in plugins by mime type.
332 for (size_t i = 0; i < plugins_list_.size(); ++i) { 354 for (size_t i = 0; i < plugins_list_.size(); ++i) {
333 if (SupportsType(plugins_list_[i], mime_type, allow_wildcard)) { 355 if (SupportsType(plugins_list_[i], mime_type, allow_wildcard)) {
334 base::FilePath path = plugins_list_[i].path; 356 base::FilePath path = plugins_list_[i].path;
335 if (visited_plugins.insert(path).second) { 357 if (visited_plugins.insert(path).second) {
336 info->push_back(plugins_list_[i]); 358 matched_plugins.insert(plugins_list_[i]);
337 if (actual_mime_types) 359 if (actual_mime_types)
338 actual_mime_types->push_back(mime_type); 360 actual_mime_types->push_back(mime_type);
339 } 361 }
340 } 362 }
341 } 363 }
342 364
343 // Add in plugins by url. 365 // Add in plugins by url.
344 // We do not permit URL-sniff based plug-in MIME type overrides aside from 366 // We do not permit URL-sniff based plug-in MIME type overrides aside from
345 // the case where the "type" was initially missing. 367 // the case where the "type" was initially missing.
346 // We collected stats to determine this approach isn't a major compat issue, 368 // We collected stats to determine this approach isn't a major compat issue,
347 // and we defend against content confusion attacks in various cases, such 369 // and we defend against content confusion attacks in various cases, such
348 // as when the user doesn't have the Flash plug-in enabled. 370 // as when the user doesn't have the Flash plug-in enabled.
349 std::string path = url.path(); 371 std::string path = url.path();
350 std::string::size_type last_dot = path.rfind('.'); 372 std::string::size_type last_dot = path.rfind('.');
351 if (last_dot != std::string::npos && mime_type.empty()) { 373 if (last_dot != std::string::npos && mime_type.empty()) {
352 std::string extension = StringToLowerASCII(std::string(path, last_dot+1)); 374 std::string extension = StringToLowerASCII(std::string(path, last_dot+1));
353 std::string actual_mime_type; 375 std::string actual_mime_type;
354 for (size_t i = 0; i < plugins_list_.size(); ++i) { 376 for (size_t i = 0; i < plugins_list_.size(); ++i) {
355 if (SupportsExtension(plugins_list_[i], extension, &actual_mime_type)) { 377 if (SupportsExtension(plugins_list_[i], extension, &actual_mime_type)) {
356 base::FilePath path = plugins_list_[i].path; 378 base::FilePath path = plugins_list_[i].path;
357 if (visited_plugins.insert(path).second) { 379 if (visited_plugins.insert(path).second) {
358 info->push_back(plugins_list_[i]); 380 matched_plugins.insert(plugins_list_[i]);
359 if (actual_mime_types) 381 if (actual_mime_types)
360 actual_mime_types->push_back(actual_mime_type); 382 actual_mime_types->push_back(actual_mime_type);
361 } 383 }
362 } 384 }
363 } 385 }
364 } 386 }
387
388 // Assign in sorted order.
389 info->assign(matched_plugins.begin(), matched_plugins.end());
365 } 390 }
366 391
367 bool PluginList::SupportsType(const WebPluginInfo& plugin, 392 bool PluginList::SupportsType(const WebPluginInfo& plugin,
368 const std::string& mime_type, 393 const std::string& mime_type,
369 bool allow_wildcard) { 394 bool allow_wildcard) {
370 // Webkit will ask for a plugin to handle empty mime types. 395 // Webkit will ask for a plugin to handle empty mime types.
371 if (mime_type.empty()) 396 if (mime_type.empty())
372 return false; 397 return false;
373 398
374 for (size_t i = 0; i < plugin.mime_types.size(); ++i) { 399 for (size_t i = 0; i < plugin.mime_types.size(); ++i) {
(...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after
406 plugin_path); 431 plugin_path);
407 if (it != extra_plugin_paths_.end()) 432 if (it != extra_plugin_paths_.end())
408 extra_plugin_paths_.erase(it); 433 extra_plugin_paths_.erase(it);
409 } 434 }
410 435
411 PluginList::~PluginList() { 436 PluginList::~PluginList() {
412 } 437 }
413 438
414 439
415 } // namespace content 440 } // namespace content
OLDNEW
« no previous file with comments | « content/common/plugin_list.h ('k') | content/common/plugin_list_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698