Bugfixes for recent PluginGroup refactoring.

BUG=66505
TEST=test_shell_tests: PluginGroupTest.*; manual: check that issues reported and screenshotted in bug 66505 no longer occur

Review URL: http://codereview.chromium.org/5918003

git-svn-id: svn://svn.chromium.org/chrome/trunk/src@69813 0039d316-1c4b-4281-b951-d872f2087c98
diff --git a/base/version.cc b/base/version.cc
index fe224eb..6ad0cbe 100644
--- a/base/version.cc
+++ b/base/version.cc
@@ -4,6 +4,8 @@
 
 #include "base/version.h"
 
+#include <algorithm>
+
 #include "base/logging.h"
 #include "base/string_number_conversions.h"
 #include "base/string_split.h"
@@ -32,6 +34,14 @@
 
 Version::~Version() {}
 
+Version* Version::Clone() const {
+  DCHECK(is_valid_);
+  Version* copy = new Version();
+  copy->components_ = components_;
+  copy->is_valid_ = true;
+  return copy;
+}
+
 bool Version::Equals(const Version& that) const {
   DCHECK(is_valid_);
   DCHECK(that.is_valid_);
diff --git a/base/version.h b/base/version.h
index 2b182bb..f034c03 100644
--- a/base/version.h
+++ b/base/version.h
@@ -27,6 +27,9 @@
 
   ~Version();
 
+  // Creates a copy of this version. Caller takes ownership.
+  Version* Clone() const;
+
   bool Equals(const Version& other) const;
 
   // Returns -1, 0, 1 for <, ==, >.
diff --git a/webkit/plugins/npapi/plugin_group.cc b/webkit/plugins/npapi/plugin_group.cc
index ec1b537..0460198 100644
--- a/webkit/plugins/npapi/plugin_group.cc
+++ b/webkit/plugins/npapi/plugin_group.cc
@@ -112,13 +112,10 @@
   description_ = other.description_;
   update_url_ = other.update_url_;
   enabled_ = other.enabled_;
-  for (size_t i = 0; i < other.version_ranges_.size(); ++i)
-    version_ranges_.push_back(other.version_ranges_[i]);
-  DCHECK_EQ(other.web_plugin_infos_.size(), other.web_plugin_positions_.size());
-  for (size_t i = 0; i < other.web_plugin_infos_.size(); ++i)
-    AddPlugin(other.web_plugin_infos_[i], other.web_plugin_positions_[i]);
-  if (!version_.get())
-    version_.reset(Version::GetVersionFromString("0"));
+  version_ranges_ = other.version_ranges_;
+  version_.reset(other.version_->Clone());
+  web_plugin_infos_ = other.web_plugin_infos_;
+  web_plugin_positions_ = other.web_plugin_positions_;
 }
 
 PluginGroup::PluginGroup(const PluginGroup& other) {
@@ -126,7 +123,6 @@
 }
 
 PluginGroup& PluginGroup::operator=(const PluginGroup& other) {
-  version_ranges_.clear();
   InitFrom(other);
   return *this;
 }
@@ -255,6 +251,10 @@
   UpdateActivePlugin(plugin);
 }
 
+bool PluginGroup::IsEmpty() const {
+  return web_plugin_infos_.empty();
+}
+
 string16 PluginGroup::GetGroupName() const {
   if (!group_name_.empty())
     return group_name_;
diff --git a/webkit/plugins/npapi/plugin_group.h b/webkit/plugins/npapi/plugin_group.h
index ae093ab..308fee7 100644
--- a/webkit/plugins/npapi/plugin_group.h
+++ b/webkit/plugins/npapi/plugin_group.h
@@ -104,6 +104,8 @@
   // plugin as given by PluginList so we can display its priority.
   void AddPlugin(const WebPluginInfo& plugin, int position);
 
+  bool IsEmpty() const;
+
   // Enables/disables this group. This enables/disables all plugins in the
   // group.
   void Enable(bool enable);
diff --git a/webkit/plugins/npapi/plugin_group_unittest.cc b/webkit/plugins/npapi/plugin_group_unittest.cc
index e82dc5a..3bda17c4 100644
--- a/webkit/plugins/npapi/plugin_group_unittest.cc
+++ b/webkit/plugins/npapi/plugin_group_unittest.cc
@@ -30,40 +30,40 @@
 };
 static const VersionRangeDefinition kPlugin34VersionRange[] = {
     { "0", "4", "3.0.44" },
-    { "4", "5", "4.0.44" }
+    { "4", "5", "" }
 };
 
 static const PluginGroupDefinition kPluginDef = {
-    "myplugin", "MyPlugin", "MyPlugin", kPluginVersionRange, 1,
-    "http://latest/" };
+    "myplugin", "MyPlugin", "MyPlugin", kPluginVersionRange,
+    arraysize(kPluginVersionRange), "http://latest/" };
 static const PluginGroupDefinition kPluginDef3 = {
-    "myplugin-3", "MyPlugin 3", "MyPlugin", kPlugin3VersionRange, 1,
-    "http://latest" };
+    "myplugin-3", "MyPlugin 3", "MyPlugin", kPlugin3VersionRange,
+    arraysize(kPlugin3VersionRange), "http://latest" };
 static const PluginGroupDefinition kPluginDef4 = {
-    "myplugin-4", "MyPlugin 4", "MyPlugin", kPlugin4VersionRange, 1,
-    "http://latest" };
+    "myplugin-4", "MyPlugin 4", "MyPlugin", kPlugin4VersionRange,
+    arraysize(kPlugin4VersionRange), "http://latest" };
 static const PluginGroupDefinition kPluginDef34 = {
-    "myplugin-34", "MyPlugin 3/4", "MyPlugin", kPlugin34VersionRange, 2,
-    "http://latest" };
+    "myplugin-34", "MyPlugin 3/4", "MyPlugin", kPlugin34VersionRange,
+    arraysize(kPlugin34VersionRange), "http://latest" };
 static const PluginGroupDefinition kPluginDefNotVulnerable = {
     "myplugin-latest", "MyPlugin", "MyPlugin", NULL, 0, "http://latest" };
 
-// name, path, version, desc, mime_types, enabled.
+// name, path, version, desc.
 static WebPluginInfo kPlugin2043 = WebPluginInfo(
-    ASCIIToUTF16("MyPlugin"), ASCIIToUTF16("2.0.43"),
-    ASCIIToUTF16("MyPlugin version 2.0.43"));
+    ASCIIToUTF16("MyPlugin"), FilePath(FILE_PATH_LITERAL("myplugin.so.2.0.43")),
+    ASCIIToUTF16("2.0.43"), ASCIIToUTF16("MyPlugin version 2.0.43"));
 static WebPluginInfo kPlugin3043 = WebPluginInfo(
-    ASCIIToUTF16("MyPlugin"), ASCIIToUTF16("3.0.43"),
-    ASCIIToUTF16("MyPlugin version 3.0.43"));
+    ASCIIToUTF16("MyPlugin"), FilePath(FILE_PATH_LITERAL("myplugin.so.3.0.43")),
+    ASCIIToUTF16("3.0.43"), ASCIIToUTF16("MyPlugin version 3.0.43"));
 static WebPluginInfo kPlugin3044 = WebPluginInfo(
-    ASCIIToUTF16("MyPlugin"), ASCIIToUTF16("3.0.44"),
-    ASCIIToUTF16("MyPlugin version 3.0.44"));
+    ASCIIToUTF16("MyPlugin"), FilePath(FILE_PATH_LITERAL("myplugin.so.3.0.44")),
+    ASCIIToUTF16("3.0.44"), ASCIIToUTF16("MyPlugin version 3.0.44"));
 static WebPluginInfo kPlugin3045 = WebPluginInfo(
-    ASCIIToUTF16("MyPlugin"), ASCIIToUTF16("3.0.45"),
-    ASCIIToUTF16("MyPlugin version 3.0.45"));
+    ASCIIToUTF16("MyPlugin"), FilePath(FILE_PATH_LITERAL("myplugin.so.3.0.45")),
+     ASCIIToUTF16("3.0.45"), ASCIIToUTF16("MyPlugin version 3.0.45"));
 static WebPluginInfo kPlugin4043 = WebPluginInfo(
-    ASCIIToUTF16("MyPlugin"), ASCIIToUTF16("4.0.43"),
-    ASCIIToUTF16("MyPlugin version 4.0.43"));
+    ASCIIToUTF16("MyPlugin"), FilePath(FILE_PATH_LITERAL("myplugin.so.4.0.43")),
+     ASCIIToUTF16("4.0.43"), ASCIIToUTF16("MyPlugin version 4.0.43"));
 
 class PluginGroupTest : public testing::Test {
  public:
@@ -110,8 +110,9 @@
   string16 desc3043(ASCIIToUTF16("MyPlugin version 3.0.43"));
   string16 desc3045(ASCIIToUTF16("MyPlugin version 3.0.45"));
 
-  PluginGroupDefinition plugindefs[] = { kPluginDef3, kPluginDef34 };
-  for (size_t i = 0; i < 2; ++i) {
+  PluginGroupDefinition plugindefs[] =
+      { kPluginDef, kPluginDef3, kPluginDef34 };
+  for (size_t i = 0; i < arraysize(plugindefs); ++i) {
     WebPluginInfo plugin3043(kPlugin3043);
     WebPluginInfo plugin3045(kPlugin3045);
     {
@@ -200,7 +201,8 @@
 
   for (size_t i = 0; i < arraysize(versions); i++) {
     const WebPluginInfo plugin = WebPluginInfo(
-        ASCIIToUTF16("Blah Plugin"), ASCIIToUTF16(versions[i][0]), string16());
+        ASCIIToUTF16("Blah Plugin"), FilePath(FILE_PATH_LITERAL("blahfile")),
+        ASCIIToUTF16(versions[i][0]), string16());
     scoped_ptr<PluginGroup> group(PluginGroupTest::CreatePluginGroup(plugin));
     EXPECT_TRUE(group->Match(plugin));
     group->AddPlugin(plugin, 0);
@@ -224,5 +226,43 @@
       ASCIIToUTF16("Google Earth")));
 }
 
+TEST(PluginGroupTest, IsVulnerable) {
+  // Adobe Reader 10
+  VersionRangeDefinition adobe_reader_version_range[] = {
+      { "10", "11", "" },
+      { "9", "10", "9.4.1" },
+      { "0", "9", "8.2.5" }
+  };
+  PluginGroupDefinition adobe_reader_plugin_def = {
+      "adobe-reader", "Adobe Reader", "Adobe Acrobat",
+      adobe_reader_version_range, arraysize(adobe_reader_version_range),
+      "http://get.adobe.com/reader/" };
+  WebPluginInfo adobe_reader_plugin(ASCIIToUTF16("Adobe Reader"),
+                                    FilePath(FILE_PATH_LITERAL("/reader.so")),
+                                    ASCIIToUTF16("10.0.0.396"),
+                                    ASCIIToUTF16("adobe reader 10"));
+  scoped_ptr<PluginGroup> group(PluginGroupTest::CreatePluginGroup(
+      adobe_reader_plugin_def));
+  group->AddPlugin(adobe_reader_plugin, 0);
+  PluginGroup group_copy(*group);  // Exercise the copy constructor.
+  EXPECT_FALSE(group_copy.IsVulnerable());
+
+  // Silverlight 4
+  VersionRangeDefinition silverlight_version_range[] = {
+      { "0", "4", "3.0.50106.0" },
+      { "4", "5", "" }
+  };
+  PluginGroupDefinition silverlight_plugin_def = {
+      "silverlight", "Silverlight", "Silverlight", silverlight_version_range,
+      arraysize(silverlight_version_range),
+      "http://www.microsoft.com/getsilverlight/" };
+  WebPluginInfo silverlight_plugin(ASCIIToUTF16("Silverlight"),
+                                   FilePath(FILE_PATH_LITERAL("/silver.so")),
+                                   ASCIIToUTF16("4.0.50917.0"),
+                                   ASCIIToUTF16("silverlight 4"));
+  group.reset(PluginGroupTest::CreatePluginGroup(silverlight_plugin_def));
+  group->AddPlugin(silverlight_plugin, 0);
+  EXPECT_FALSE(PluginGroup(*group).IsVulnerable());
+}
 }  // namespace npapi
 }  // namespace webkit
diff --git a/webkit/plugins/npapi/plugin_list.cc b/webkit/plugins/npapi/plugin_list.cc
index a92373e6..a54a122d 100644
--- a/webkit/plugins/npapi/plugin_list.cc
+++ b/webkit/plugins/npapi/plugin_list.cc
@@ -615,7 +615,8 @@
   plugin_groups->clear();
   for (PluginGroup::PluginMap::const_iterator it = plugin_groups_.begin();
        it != plugin_groups_.end(); ++it) {
-    plugin_groups->push_back(*it->second);
+    if (!it->second->IsEmpty())
+      plugin_groups->push_back(*it->second);
   }
 }
 
diff --git a/webkit/plugins/npapi/webplugininfo.cc b/webkit/plugins/npapi/webplugininfo.cc
index c0559530..cd5a19f 100644
--- a/webkit/plugins/npapi/webplugininfo.cc
+++ b/webkit/plugins/npapi/webplugininfo.cc
@@ -35,10 +35,11 @@
 }
 
 WebPluginInfo::WebPluginInfo(const string16& fake_name,
+                             const FilePath& fake_path,
                              const string16& fake_version,
                              const string16& fake_desc)
     : name(fake_name),
-      path(),
+      path(fake_path),
       version(fake_version),
       desc(fake_desc),
       mime_types(),
diff --git a/webkit/plugins/npapi/webplugininfo.h b/webkit/plugins/npapi/webplugininfo.h
index 6b9f240..859665c1 100644
--- a/webkit/plugins/npapi/webplugininfo.h
+++ b/webkit/plugins/npapi/webplugininfo.h
@@ -38,6 +38,7 @@
 
   // Special constructor only used during unit testing:
   WebPluginInfo(const string16& fake_name,
+                const FilePath& fake_path,
                 const string16& fake_version,
                 const string16& fake_desc);