Enforce new id format (hex str of sha-1)

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

git-svn-id: svn://svn.chromium.org/chrome/trunk/src@10529 0039d316-1c4b-4281-b951-d872f2087c98
diff --git a/chrome/browser/extensions/extension.cc b/chrome/browser/extensions/extension.cc
index 9efdd37..348cc13 100644
--- a/chrome/browser/extensions/extension.cc
+++ b/chrome/browser/extensions/extension.cc
@@ -69,6 +69,8 @@
 const char* Extension::kInvalidPluginsDirError =
     "Invalid value for 'plugins_dir'.";
 
+const int Extension::kIdSize = 20;  // SHA1 (160 bits) == 20 bytes
+
 const std::string Extension::VersionString() const {
   return version_->GetString();
 }
@@ -172,19 +174,11 @@
     *error = kInvalidIdError;
     return false;
   }
-  // Verify that the id is legal.  This test is basically verifying that it
-  // is ASCII and doesn't have any path components in it.
-  // TODO(erikkay): verify the actual id format - it will be more restrictive
-  // than this.  Perhaps just a hex string?
-  if (!IsStringASCII(id_)) {
-    *error = kInvalidIdError;
-    return false;
-  }
-  FilePath id_path;
-  id_path = id_path.AppendASCII(id_);
-  if ((id_path.value() == FilePath::kCurrentDirectory) ||
-      (id_path.value() == FilePath::kParentDirectory) ||
-      !(id_path.BaseName() == id_path)) {
+
+  // Verify that the id is legal.  The id is a hex string of the SHA-1 hash of
+  // the public key.
+  std::vector<uint8> id_bytes;
+  if (!HexStringToBytes(id_, &id_bytes) || id_bytes.size() != kIdSize) {
     *error = kInvalidIdError;
     return false;
   }
diff --git a/chrome/browser/extensions/extension.h b/chrome/browser/extensions/extension.h
index 39e5fff..48833d45 100644
--- a/chrome/browser/extensions/extension.h
+++ b/chrome/browser/extensions/extension.h
@@ -64,6 +64,9 @@
   static const char* kInvalidZipHashError;
   static const char* kInvalidPluginsDirError;
 
+  // The number of bytes in a legal id.
+  static const int kIdSize;
+
   // Creates an absolute url to a resource inside an extension. The
   // |extension_url| argument should be the url() from an Extension object. The
   // |relative_path| can be untrusted user input. The returned URL will either
diff --git a/chrome/browser/extensions/extensions_service_unittest.cc b/chrome/browser/extensions/extensions_service_unittest.cc
index 62df67c..a49399d 100644
--- a/chrome/browser/extensions/extensions_service_unittest.cc
+++ b/chrome/browser/extensions/extensions_service_unittest.cc
@@ -110,11 +110,15 @@
         scoped_refptr<ExtensionsServiceFrontendInterface>(this));
     message_loop_.RunAllPending();
     if (should_succeed) {
-      EXPECT_EQ(1u, installed_.size());
+      EXPECT_EQ(1u, installed_.size()) << path.value();
       EXPECT_EQ(0u, errors_.size()) << path.value();
+      for (std::vector<std::string>::iterator err = errors_.begin();
+        err != errors_.end(); ++err) {
+        LOG(ERROR) << *err;
+      }
     } else {
-      EXPECT_EQ(0u, installed_.size());
-      EXPECT_EQ(1u, errors_.size());
+      EXPECT_EQ(0u, installed_.size()) << path.value();
+      EXPECT_EQ(1u, errors_.size()) << path.value();
     }
     installed_.clear();
     errors_.clear();
@@ -148,9 +152,14 @@
       scoped_refptr<ExtensionsServiceFrontendInterface>(frontend.get()));
   frontend->GetMessageLoop()->RunAllPending();
 
+  std::vector<std::string>* errors = frontend->errors();
+  for (std::vector<std::string>::iterator err = errors->begin();
+    err != errors->end(); ++err) {
+    LOG(ERROR) << *err;
+  }
   ASSERT_EQ(3u, frontend->extensions()->size());
 
-  EXPECT_EQ(std::string("com.google.myextension1"),
+  EXPECT_EQ(std::string("00123456789ABCDEF0123456789ABCDEF0123456"),
             frontend->extensions()->at(0)->id());
   EXPECT_EQ(std::string("My extension 1"),
             frontend->extensions()->at(0)->name());
@@ -172,7 +181,7 @@
   EXPECT_EQ(extension->path().AppendASCII("script2.js").value(),
             scripts[1].path().value());
 
-  EXPECT_EQ(std::string("com.google.myextension2"),
+  EXPECT_EQ(std::string("10123456789ABCDEF0123456789ABCDEF0123456"),
             frontend->extensions()->at(1)->id());
   EXPECT_EQ(std::string("My extension 2"),
             frontend->extensions()->at(1)->name());
@@ -182,7 +191,7 @@
             frontend->extensions()->at(1)->plugins_dir().value());
   ASSERT_EQ(0u, frontend->extensions()->at(1)->content_scripts().size());
 
-  EXPECT_EQ(std::string("com.google.myextension3"),
+  EXPECT_EQ(std::string("20123456789ABCDEF0123456789ABCDEF0123456"),
             frontend->extensions()->at(2)->id());
   EXPECT_EQ(std::string("My extension 3"),
             frontend->extensions()->at(2)->name());
@@ -212,18 +221,19 @@
 
   EXPECT_TRUE(MatchPattern(frontend->errors()->at(0),
       std::string("Could not load extension from '*'. * ") +
-      JSONReader::kBadRootElementType));
+      JSONReader::kBadRootElementType)) << frontend->errors()->at(0);
 
   EXPECT_TRUE(MatchPattern(frontend->errors()->at(1),
       std::string("Could not load extension from '*'. ") +
-      Extension::kInvalidJsListError));
+      Extension::kInvalidJsListError)) << frontend->errors()->at(1);
 
   EXPECT_TRUE(MatchPattern(frontend->errors()->at(2),
       std::string("Could not load extension from '*'. ") +
-      Extension::kInvalidManifestError));
+      Extension::kInvalidManifestError)) << frontend->errors()->at(2);
 
   EXPECT_TRUE(MatchPattern(frontend->errors()->at(3),
-      "Could not load extension from '*'. Could not read '*' file."));
+      "Could not load extension from '*'. Could not read '*' file.")) <<
+      frontend->errors()->at(3);
 };
 
 // Test installing extensions.