summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--chrome/browser/extensions/extension.cc36
-rw-r--r--chrome/browser/extensions/extension.h8
-rwxr-xr-xchrome/browser/extensions/extension_content_script_inject_unittest.cc62
-rw-r--r--chrome/browser/extensions/extension_ui_unittest.cc2
-rw-r--r--chrome/browser/extensions/extension_unittest.cc61
-rwxr-xr-xchrome/browser/extensions/extension_view_unittest.cc63
-rw-r--r--chrome/browser/extensions/extensions_service.cc24
-rw-r--r--chrome/browser/extensions/extensions_service.h2
-rwxr-xr-xchrome/browser/extensions/test_extension_loader.cc63
-rwxr-xr-xchrome/browser/extensions/test_extension_loader.h35
-rw-r--r--chrome/chrome.gyp4
-rw-r--r--chrome/common/extensions/user_script.cc6
-rw-r--r--chrome/common/extensions/user_script.h9
-rw-r--r--chrome/renderer/resources/extension_process_bindings.js6
-rw-r--r--chrome/renderer/user_script_slave.cc35
-rwxr-xr-xchrome/test/data/extensions/content_script_inject/js_test.js33
-rwxr-xr-xchrome/test/data/extensions/content_script_inject/manifest.json21
-rw-r--r--chrome/test/data/extensions/content_script_inject/script1.css10
-rwxr-xr-xchrome/test/data/extensions/content_script_inject/script1a.js7
-rwxr-xr-xchrome/test/data/extensions/content_script_inject/script1b.js27
-rwxr-xr-xchrome/test/data/extensions/content_script_inject/script2.js12
-rw-r--r--chrome/test/data/extensions/content_script_inject/script3.js31
-rwxr-xr-xchrome/test/data/extensions/content_script_inject_page.html10
-rw-r--r--chrome/test/data/purify/unit_tests.exe_MLK.txt56
-rw-r--r--chrome/test/data/purify/unit_tests.exe_UMR.txt92
-rw-r--r--chrome/test/unit/unittests.vcproj12
26 files changed, 595 insertions, 132 deletions
diff --git a/chrome/browser/extensions/extension.cc b/chrome/browser/extensions/extension.cc
index d8ab403..1aeaeaa 100644
--- a/chrome/browser/extensions/extension.cc
+++ b/chrome/browser/extensions/extension.cc
@@ -103,21 +103,6 @@ Extension::Extension(const Extension& rhs)
theme_paths_(rhs.theme_paths_) {
}
-const GURL& Extension::url() {
- if (!extension_url_.is_valid())
- extension_url_ = GURL(std::string(chrome::kExtensionScheme) +
- chrome::kStandardSchemeSeparator + id_ + "/");
-
- return extension_url_;
-}
-
-void Extension::set_id(const std::string& id) {
- id_ = id;
-
- // Reset url_ so that it gets reinitialized next time.
- extension_url_ = GURL();
-}
-
const std::string Extension::VersionString() const {
return version_->GetString();
}
@@ -335,10 +320,9 @@ bool Extension::LoadUserScriptHelper(const DictionaryValue* content_script,
return true;
}
-bool Extension::InitFromValue(const DictionaryValue& source,
+bool Extension::InitFromValue(const DictionaryValue& source, bool require_id,
std::string* error) {
- // Initialize id. The ID is not required here because we don't require IDs for
- // extensions used with --load-extension.
+ // Initialize id.
if (source.HasKey(kIdKey)) {
if (!source.GetString(kIdKey, &id_)) {
*error = kInvalidIdError;
@@ -356,8 +340,23 @@ bool Extension::InitFromValue(const DictionaryValue& source,
*error = kInvalidIdError;
return false;
}
+ } else if (require_id) {
+ *error = kInvalidIdError;
+ return false;
+ } else {
+ // Generate a random ID
+ static int counter = 0;
+ id_ = StringPrintf("%x", counter);
+ ++counter;
+
+ // pad the string out to 40 chars with zeroes.
+ id_.insert(0, 40 - id_.length(), '0');
}
+ // Initialize the URL.
+ extension_url_ = GURL(std::string(chrome::kExtensionScheme) +
+ chrome::kStandardSchemeSeparator + id_ + "/");
+
// Initialize version.
std::string version_str;
if (!source.GetString(kVersionKey, &version_str)) {
@@ -457,6 +456,7 @@ bool Extension::InitFromValue(const DictionaryValue& source,
UserScript script;
if (!LoadUserScriptHelper(content_script, i, error, &script))
return false; // Failed to parse script context definition
+ script.set_extension_id(id());
content_scripts_.push_back(script);
}
}
diff --git a/chrome/browser/extensions/extension.h b/chrome/browser/extensions/extension.h
index 5c3d9b8f..2f59115 100644
--- a/chrome/browser/extensions/extension.h
+++ b/chrome/browser/extensions/extension.h
@@ -100,7 +100,10 @@ class Extension {
}
// Initialize the extension from a parsed manifest.
- bool InitFromValue(const DictionaryValue& value, std::string* error);
+ // If |require_id| is true, will return an error if the "id" key is missing
+ // from the value.
+ bool InitFromValue(const DictionaryValue& value, bool require_id,
+ std::string* error);
// Returns an absolute path to a resource inside of an extension if the
// extension has a theme defined with the given |resource_id|. Otherwise
@@ -110,9 +113,8 @@ class Extension {
FilePath GetThemeResourcePath(const int resource_id);
const FilePath& path() const { return path_; }
- const GURL& url();
+ const GURL& url() const { return extension_url_; }
const std::string& id() const { return id_; }
- void set_id(const std::string& id);
const Version* version() const { return version_.get(); }
// String representation of the version number.
const std::string VersionString() const;
diff --git a/chrome/browser/extensions/extension_content_script_inject_unittest.cc b/chrome/browser/extensions/extension_content_script_inject_unittest.cc
new file mode 100755
index 0000000..750176b
--- /dev/null
+++ b/chrome/browser/extensions/extension_content_script_inject_unittest.cc
@@ -0,0 +1,62 @@
+// Copyright (c) 2009 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "chrome/browser/browser.h"
+#include "chrome/browser/extensions/extension_error_reporter.h"
+#include "chrome/browser/extensions/test_extension_loader.h"
+#include "chrome/common/chrome_paths.h"
+#include "chrome/test/in_process_browser_test.h"
+#include "chrome/test/ui_test_utils.h"
+#include "net/base/net_util.h"
+
+namespace {
+
+// The extension we're using as our test case.
+const char* kExtensionId = "00123456789abcdef0123456789abcdef0123456";
+
+} // namespace
+
+class ExtensionContentScriptInjectTest : public InProcessBrowserTest {
+ public:
+ virtual void SetUp() {
+ // Initialize the error reporter here, otherwise BrowserMain will create it
+ // with the wrong MessageLoop.
+ ExtensionErrorReporter::Init(false);
+
+ InProcessBrowserTest::SetUp();
+ }
+};
+
+// Tests that an extension's user script gets injected into content.
+IN_PROC_BROWSER_TEST_F(ExtensionContentScriptInjectTest, Simple) {
+ // Get the path to our extension.
+ FilePath extension_path;
+ ASSERT_TRUE(PathService::Get(chrome::DIR_TEST_DATA, &extension_path));
+ extension_path = extension_path.AppendASCII("extensions").
+ AppendASCII("content_script_inject");
+ ASSERT_TRUE(file_util::DirectoryExists(extension_path)); // sanity check
+
+ // Load it.
+ TestExtensionLoader loader(browser()->profile());
+ Extension* extension = loader.Load(kExtensionId, extension_path);
+ ASSERT_TRUE(extension);
+
+ // Get the file URL to our test page.
+ FilePath test_page_path;
+ ASSERT_TRUE(PathService::Get(chrome::DIR_TEST_DATA, &test_page_path));
+ test_page_path = test_page_path.AppendASCII("extensions").
+ AppendASCII("content_script_inject_page.html");
+ ASSERT_TRUE(file_util::PathExists(test_page_path)); // sanity check
+ GURL test_page_url = net::FilePathToFileURL(test_page_path);
+
+ ui_test_utils::NavigateToURL(browser(), test_page_url);
+ TabContents* tabContents = browser()->GetSelectedTabContents();
+
+ // The injected user script will set the page title upon execution.
+ const char kExpectedTitle[] =
+ "testScriptFilesRunInSameContext,testContentInteraction,"
+ "testCSSWasInjected,testCannotSeeOtherContentScriptGlobals,"
+ "testRunAtDocumentStart,testGotLoadEvents,";
+ EXPECT_EQ(ASCIIToUTF16(kExpectedTitle), tabContents->GetTitle());
+}
diff --git a/chrome/browser/extensions/extension_ui_unittest.cc b/chrome/browser/extensions/extension_ui_unittest.cc
index 0e24832..c3dbbb0 100644
--- a/chrome/browser/extensions/extension_ui_unittest.cc
+++ b/chrome/browser/extensions/extension_ui_unittest.cc
@@ -39,7 +39,7 @@ namespace {
scoped_ptr<DictionaryValue> extension_data(DeserializeJSONTestData(
manifest_path, &error));
EXPECT_EQ("", error);
- EXPECT_TRUE(extension.InitFromValue(*extension_data, &error));
+ EXPECT_TRUE(extension.InitFromValue(*extension_data, true, &error));
EXPECT_EQ("", error);
scoped_ptr<DictionaryValue>expected_output_data(DeserializeJSONTestData(
diff --git a/chrome/browser/extensions/extension_unittest.cc b/chrome/browser/extensions/extension_unittest.cc
index 5cde5ca..f160117 100644
--- a/chrome/browser/extensions/extension_unittest.cc
+++ b/chrome/browser/extensions/extension_unittest.cc
@@ -38,47 +38,52 @@ TEST(ExtensionTest, InitFromValueInvalid) {
static_cast<DictionaryValue*>(serializer.Deserialize(&error)));
ASSERT_TRUE(valid_value.get());
ASSERT_EQ("", error);
- ASSERT_TRUE(extension.InitFromValue(*valid_value, &error));
+ ASSERT_TRUE(extension.InitFromValue(*valid_value, true, &error));
ASSERT_EQ("", error);
scoped_ptr<DictionaryValue> input_value;
// Test missing and invalid ids
input_value.reset(static_cast<DictionaryValue*>(valid_value->DeepCopy()));
+ input_value->Remove(Extension::kIdKey, NULL);
+ EXPECT_FALSE(extension.InitFromValue(*input_value, true, &error));
+ EXPECT_EQ(Extension::kInvalidIdError, error);
+
+ input_value.reset(static_cast<DictionaryValue*>(valid_value->DeepCopy()));
input_value->SetInteger(Extension::kIdKey, 42);
- EXPECT_FALSE(extension.InitFromValue(*input_value, &error));
+ EXPECT_FALSE(extension.InitFromValue(*input_value, true, &error));
EXPECT_EQ(Extension::kInvalidIdError, error);
// Test missing and invalid versions
input_value.reset(static_cast<DictionaryValue*>(valid_value->DeepCopy()));
input_value->Remove(Extension::kVersionKey, NULL);
- EXPECT_FALSE(extension.InitFromValue(*input_value, &error));
+ EXPECT_FALSE(extension.InitFromValue(*input_value, true, &error));
EXPECT_EQ(Extension::kInvalidVersionError, error);
input_value->SetInteger(Extension::kVersionKey, 42);
- EXPECT_FALSE(extension.InitFromValue(*input_value, &error));
+ EXPECT_FALSE(extension.InitFromValue(*input_value, true, &error));
EXPECT_EQ(Extension::kInvalidVersionError, error);
// Test missing and invalid names
input_value.reset(static_cast<DictionaryValue*>(valid_value->DeepCopy()));
input_value->Remove(Extension::kNameKey, NULL);
- EXPECT_FALSE(extension.InitFromValue(*input_value, &error));
+ EXPECT_FALSE(extension.InitFromValue(*input_value, true, &error));
EXPECT_EQ(Extension::kInvalidNameError, error);
input_value->SetInteger(Extension::kNameKey, 42);
- EXPECT_FALSE(extension.InitFromValue(*input_value, &error));
+ EXPECT_FALSE(extension.InitFromValue(*input_value, true, &error));
EXPECT_EQ(Extension::kInvalidNameError, error);
// Test invalid description
input_value.reset(static_cast<DictionaryValue*>(valid_value->DeepCopy()));
input_value->SetInteger(Extension::kDescriptionKey, 42);
- EXPECT_FALSE(extension.InitFromValue(*input_value, &error));
+ EXPECT_FALSE(extension.InitFromValue(*input_value, true, &error));
EXPECT_EQ(Extension::kInvalidDescriptionError, error);
// Test invalid user scripts list
input_value.reset(static_cast<DictionaryValue*>(valid_value->DeepCopy()));
input_value->SetInteger(Extension::kContentScriptsKey, 42);
- EXPECT_FALSE(extension.InitFromValue(*input_value, &error));
+ EXPECT_FALSE(extension.InitFromValue(*input_value, true, &error));
EXPECT_EQ(Extension::kInvalidContentScriptsListError, error);
// Test invalid user script item
@@ -87,7 +92,7 @@ TEST(ExtensionTest, InitFromValueInvalid) {
input_value->GetList(Extension::kContentScriptsKey, &content_scripts);
ASSERT_FALSE(NULL == content_scripts);
content_scripts->Set(0, Value::CreateIntegerValue(42));
- EXPECT_FALSE(extension.InitFromValue(*input_value, &error));
+ EXPECT_FALSE(extension.InitFromValue(*input_value, true, &error));
EXPECT_TRUE(MatchPattern(error, Extension::kInvalidContentScriptError));
// Test missing and invalid matches array
@@ -96,21 +101,21 @@ TEST(ExtensionTest, InitFromValueInvalid) {
DictionaryValue* user_script = NULL;
content_scripts->GetDictionary(0, &user_script);
user_script->Remove(Extension::kMatchesKey, NULL);
- EXPECT_FALSE(extension.InitFromValue(*input_value, &error));
+ EXPECT_FALSE(extension.InitFromValue(*input_value, true, &error));
EXPECT_TRUE(MatchPattern(error, Extension::kInvalidMatchesError));
user_script->Set(Extension::kMatchesKey, Value::CreateIntegerValue(42));
- EXPECT_FALSE(extension.InitFromValue(*input_value, &error));
+ EXPECT_FALSE(extension.InitFromValue(*input_value, true, &error));
EXPECT_TRUE(MatchPattern(error, Extension::kInvalidMatchesError));
ListValue* matches = new ListValue;
user_script->Set(Extension::kMatchesKey, matches);
- EXPECT_FALSE(extension.InitFromValue(*input_value, &error));
+ EXPECT_FALSE(extension.InitFromValue(*input_value, true, &error));
EXPECT_TRUE(MatchPattern(error, Extension::kInvalidMatchCountError));
// Test invalid match element
matches->Set(0, Value::CreateIntegerValue(42));
- EXPECT_FALSE(extension.InitFromValue(*input_value, &error));
+ EXPECT_FALSE(extension.InitFromValue(*input_value, true, &error));
EXPECT_TRUE(MatchPattern(error, Extension::kInvalidMatchError));
// Test missing and invalid files array
@@ -119,52 +124,52 @@ TEST(ExtensionTest, InitFromValueInvalid) {
content_scripts->GetDictionary(0, &user_script);
user_script->Remove(Extension::kJsKey, NULL);
user_script->Remove(Extension::kCssKey, NULL);
- EXPECT_FALSE(extension.InitFromValue(*input_value, &error));
+ EXPECT_FALSE(extension.InitFromValue(*input_value, true, &error));
EXPECT_TRUE(MatchPattern(error, Extension::kMissingFileError));
user_script->Set(Extension::kJsKey, Value::CreateIntegerValue(42));
- EXPECT_FALSE(extension.InitFromValue(*input_value, &error));
+ EXPECT_FALSE(extension.InitFromValue(*input_value, true, &error));
EXPECT_TRUE(MatchPattern(error, Extension::kInvalidJsListError));
user_script->Set(Extension::kCssKey, new ListValue);
user_script->Set(Extension::kJsKey, new ListValue);
- EXPECT_FALSE(extension.InitFromValue(*input_value, &error));
+ EXPECT_FALSE(extension.InitFromValue(*input_value, true, &error));
EXPECT_TRUE(MatchPattern(error, Extension::kMissingFileError));
user_script->Remove(Extension::kCssKey, NULL);
ListValue* files = new ListValue;
user_script->Set(Extension::kJsKey, files);
- EXPECT_FALSE(extension.InitFromValue(*input_value, &error));
+ EXPECT_FALSE(extension.InitFromValue(*input_value, true, &error));
EXPECT_TRUE(MatchPattern(error, Extension::kMissingFileError));
// Test invalid file element
files->Set(0, Value::CreateIntegerValue(42));
- EXPECT_FALSE(extension.InitFromValue(*input_value, &error));
+ EXPECT_FALSE(extension.InitFromValue(*input_value, true, &error));
EXPECT_TRUE(MatchPattern(error, Extension::kInvalidJsError));
user_script->Remove(Extension::kJsKey, NULL);
// Test the css element
user_script->Set(Extension::kCssKey, Value::CreateIntegerValue(42));
- EXPECT_FALSE(extension.InitFromValue(*input_value, &error));
+ EXPECT_FALSE(extension.InitFromValue(*input_value, true, &error));
EXPECT_TRUE(MatchPattern(error, Extension::kInvalidCssListError));
// Test invalid file element
ListValue* css_files = new ListValue;
user_script->Set(Extension::kCssKey, css_files);
css_files->Set(0, Value::CreateIntegerValue(42));
- EXPECT_FALSE(extension.InitFromValue(*input_value, &error));
+ EXPECT_FALSE(extension.InitFromValue(*input_value, true, &error));
EXPECT_TRUE(MatchPattern(error, Extension::kInvalidCssError));
// Test missing and invalid permissions array
input_value.reset(static_cast<DictionaryValue*>(valid_value->DeepCopy()));
- EXPECT_TRUE(extension.InitFromValue(*input_value, &error));
+ EXPECT_TRUE(extension.InitFromValue(*input_value, true, &error));
ListValue* permissions = NULL;
input_value->GetList(Extension::kPermissionsKey, &permissions);
ASSERT_FALSE(NULL == permissions);
permissions = new ListValue;
input_value->Set(Extension::kPermissionsKey, permissions);
- EXPECT_TRUE(extension.InitFromValue(*input_value, &error));
+ EXPECT_TRUE(extension.InitFromValue(*input_value, true, &error));
const std::vector<std::string>* error_vector =
ExtensionErrorReporter::GetInstance()->GetErrors();
const std::string log_error = error_vector->at(error_vector->size() - 1);
@@ -172,24 +177,24 @@ TEST(ExtensionTest, InitFromValueInvalid) {
Extension::kInvalidPermissionCountWarning));
input_value->Set(Extension::kPermissionsKey, Value::CreateIntegerValue(9));
- EXPECT_FALSE(extension.InitFromValue(*input_value, &error));
+ EXPECT_FALSE(extension.InitFromValue(*input_value, true, &error));
EXPECT_TRUE(MatchPattern(error, Extension::kInvalidPermissionsError));
input_value.reset(static_cast<DictionaryValue*>(valid_value->DeepCopy()));
input_value->GetList(Extension::kPermissionsKey, &permissions);
permissions->Set(0, Value::CreateIntegerValue(24));
- EXPECT_FALSE(extension.InitFromValue(*input_value, &error));
+ EXPECT_FALSE(extension.InitFromValue(*input_value, true, &error));
EXPECT_TRUE(MatchPattern(error, Extension::kInvalidPermissionError));
permissions->Set(0, Value::CreateStringValue("www.google.com"));
- EXPECT_FALSE(extension.InitFromValue(*input_value, &error));
+ EXPECT_FALSE(extension.InitFromValue(*input_value, true, &error));
EXPECT_TRUE(MatchPattern(error, Extension::kInvalidPermissionError));
// Test permissions scheme.
input_value.reset(static_cast<DictionaryValue*>(valid_value->DeepCopy()));
input_value->GetList(Extension::kPermissionsKey, &permissions);
permissions->Set(0, Value::CreateStringValue("file:///C:/foo.txt"));
- EXPECT_FALSE(extension.InitFromValue(*input_value, &error));
+ EXPECT_FALSE(extension.InitFromValue(*input_value, true, &error));
EXPECT_TRUE(MatchPattern(error, Extension::kInvalidPermissionSchemeError));
}
@@ -209,7 +214,7 @@ TEST(ExtensionTest, InitFromValueValid) {
input_value.SetString(Extension::kVersionKey, "1.0.0.0");
input_value.SetString(Extension::kNameKey, "my extension");
- EXPECT_TRUE(extension.InitFromValue(input_value, &error));
+ EXPECT_TRUE(extension.InitFromValue(input_value, true, &error));
EXPECT_EQ("", error);
EXPECT_EQ("00123456789abcdef0123456789abcdef0123456", extension.id());
EXPECT_EQ("1.0.0.0", extension.VersionString());
@@ -231,7 +236,7 @@ TEST(ExtensionTest, GetResourceURLAndPath) {
"00123456789ABCDEF0123456789ABCDEF0123456");
input_value.SetString(Extension::kVersionKey, "1.0.0.0");
input_value.SetString(Extension::kNameKey, "my extension");
- EXPECT_TRUE(extension.InitFromValue(input_value, NULL));
+ EXPECT_TRUE(extension.InitFromValue(input_value, true, NULL));
EXPECT_EQ(extension.url().spec() + "bar/baz.js",
Extension::GetResourceURL(extension.url(), "bar/baz.js").spec());
diff --git a/chrome/browser/extensions/extension_view_unittest.cc b/chrome/browser/extensions/extension_view_unittest.cc
index 4cdb91c..69a1fb9 100755
--- a/chrome/browser/extensions/extension_view_unittest.cc
+++ b/chrome/browser/extensions/extension_view_unittest.cc
@@ -2,16 +2,14 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
-#include "base/message_loop.h"
#include "base/ref_counted.h"
#include "chrome/browser/browser.h"
#include "chrome/browser/renderer_host/render_view_host.h"
-#include "chrome/browser/profile.h"
#include "chrome/browser/extensions/extension_error_reporter.h"
#include "chrome/browser/extensions/extension_view.h"
#include "chrome/browser/extensions/extensions_service.h"
+#include "chrome/browser/extensions/test_extension_loader.h"
#include "chrome/common/chrome_paths.h"
-#include "chrome/common/notification_service.h"
#include "chrome/test/in_process_browser_test.h"
#include "chrome/test/ui_test_utils.h"
@@ -21,12 +19,11 @@ namespace {
// up.
const int kAlertTimeoutMs = 20000;
-// How long to wait for the extension to load before giving up.
-const int kLoadTimeoutMs = 10000;
-
// The extension we're using as our test case.
const char* kExtensionId = "00123456789abcdef0123456789abcdef0123456";
+}; // namespace
+
// This class starts up an extension process and waits until it tries to put
// up a javascript alert.
class MockExtensionView : public ExtensionView {
@@ -60,44 +57,6 @@ class MockExtensionView : public ExtensionView {
bool got_message_;
};
-// This class waits for a specific extension to be loaded.
-class ExtensionLoadedObserver : public NotificationObserver {
- public:
- explicit ExtensionLoadedObserver() : extension_(NULL) {
- registrar_.Add(this, NotificationType::EXTENSIONS_LOADED,
- NotificationService::AllSources());
- }
-
- Extension* WaitForExtension() {
- MessageLoop::current()->PostDelayedTask(FROM_HERE,
- new MessageLoop::QuitTask, kLoadTimeoutMs);
- ui_test_utils::RunMessageLoop();
- return extension_;
- }
-
- private:
- virtual void Observe(NotificationType type, const NotificationSource& source,
- const NotificationDetails& details) {
- if (type == NotificationType::EXTENSIONS_LOADED) {
- ExtensionList* extensions = Details<ExtensionList>(details).ptr();
- for (size_t i = 0; i < (*extensions).size(); i++) {
- if ((*extensions)[i]->id() == kExtensionId) {
- extension_ = (*extensions)[i];
- MessageLoopForUI::current()->Quit();
- break;
- }
- }
- } else {
- NOTREACHED();
- }
- }
-
- NotificationRegistrar registrar_;
- Extension* extension_;
-};
-
-} // namespace
-
class ExtensionViewTest : public InProcessBrowserTest {
public:
virtual void SetUp() {
@@ -115,10 +74,6 @@ class ExtensionViewTest : public InProcessBrowserTest {
// Tests that ExtensionView starts an extension process and runs the script
// contained in the extension's "index.html" file.
IN_PROC_BROWSER_TEST_F(ExtensionViewTest, Index) {
- // Create an observer first to be sure we have the notification registered
- // before it's sent.
- ExtensionLoadedObserver observer;
-
// Get the path to our extension.
FilePath path;
ASSERT_TRUE(PathService::Get(chrome::DIR_TEST_DATA, &path));
@@ -126,17 +81,13 @@ IN_PROC_BROWSER_TEST_F(ExtensionViewTest, Index) {
AppendASCII("good").AppendASCII("extension1").AppendASCII("1");
ASSERT_TRUE(file_util::DirectoryExists(path)); // sanity check
- // Load it.
- Profile* profile = browser()->profile();
- profile->GetExtensionsService()->Init();
- profile->GetExtensionsService()->LoadExtension(path);
-
- // Now wait for it to load, and grab a pointer to it.
- Extension* extension = observer.WaitForExtension();
+ // Wait for the extension to load and grab a pointer to it.
+ TestExtensionLoader loader(browser()->profile());
+ Extension* extension = loader.Load(kExtensionId, path);
ASSERT_TRUE(extension);
GURL url = Extension::GetResourceURL(extension->url(), "toolstrip1.html");
// Start the extension process and wait for it to show a javascript alert.
- MockExtensionView view(extension, url, profile);
+ MockExtensionView view(extension, url, browser()->profile());
EXPECT_TRUE(view.got_message());
}
diff --git a/chrome/browser/extensions/extensions_service.cc b/chrome/browser/extensions/extensions_service.cc
index 5c836d0..942d23c 100644
--- a/chrome/browser/extensions/extensions_service.cc
+++ b/chrome/browser/extensions/extensions_service.cc
@@ -258,18 +258,9 @@ void ExtensionsServiceBackend::LoadSingleExtension(
LOG(INFO) << "Loading single extension from " <<
WideToASCII(extension_path.BaseName().ToWStringHack());
- Extension* extension = LoadExtension(extension_path);
+ Extension* extension = LoadExtension(extension_path,
+ false); // don't require ID
if (extension) {
- if (extension->id().empty()) {
- // Generate an ID
- static int counter = 0;
- std::string id = StringPrintf("%x", counter);
- ++counter;
-
- // pad the string out to 40 chars with zeroes.
- id.insert(0, 40 - id.length(), '0');
- extension->set_id(id);
- }
ExtensionList* extensions = new ExtensionList;
extensions->push_back(extension);
ReportExtensionsLoaded(extensions);
@@ -290,11 +281,12 @@ Extension* ExtensionsServiceBackend::LoadExtensionCurrentVersion(
WideToASCII(extension_path.BaseName().ToWStringHack()) <<
" version: " << version_str;
- return LoadExtension(extension_path.AppendASCII(version_str));
+ return LoadExtension(extension_path.AppendASCII(version_str),
+ true); // require id
}
Extension* ExtensionsServiceBackend::LoadExtension(
- const FilePath& extension_path) {
+ const FilePath& extension_path, bool require_id) {
FilePath manifest_path =
extension_path.AppendASCII(Extension::kManifestFilename);
if (!file_util::PathExists(manifest_path)) {
@@ -317,7 +309,7 @@ Extension* ExtensionsServiceBackend::LoadExtension(
scoped_ptr<Extension> extension(new Extension(extension_path));
if (!extension->InitFromValue(*static_cast<DictionaryValue*>(root.get()),
- &error)) {
+ require_id, &error)) {
ReportExtensionLoadError(extension_path, error);
return NULL;
}
@@ -638,7 +630,9 @@ bool ExtensionsServiceBackend::InstallOrUpdateExtension(
DictionaryValue* dict = manifest.get();
Extension extension;
std::string error;
- if (!extension.InitFromValue(*dict, &error)) {
+ if (!extension.InitFromValue(*dict,
+ true, // require ID
+ &error)) {
ReportExtensionInstallError(source_file,
"Invalid extension manifest.");
return false;
diff --git a/chrome/browser/extensions/extensions_service.h b/chrome/browser/extensions/extensions_service.h
index 5c08685..64d2e55 100644
--- a/chrome/browser/extensions/extensions_service.h
+++ b/chrome/browser/extensions/extensions_service.h
@@ -141,7 +141,7 @@ class ExtensionsServiceBackend
private:
// Load a single extension from |extension_path|, the top directory of
// a specific extension where its manifest file lives.
- Extension* LoadExtension(const FilePath& extension_path);
+ Extension* LoadExtension(const FilePath& extension_path, bool require_id);
// Load a single extension from |extension_path|, the top directory of
// a versioned extension where its Current Version file lives.
diff --git a/chrome/browser/extensions/test_extension_loader.cc b/chrome/browser/extensions/test_extension_loader.cc
new file mode 100755
index 0000000..d8bacb7
--- /dev/null
+++ b/chrome/browser/extensions/test_extension_loader.cc
@@ -0,0 +1,63 @@
+// Copyright (c) 2009 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "chrome/browser/extensions/test_extension_loader.h"
+
+#include "base/file_path.h"
+#include "base/message_loop.h"
+#include "chrome/browser/profile.h"
+#include "chrome/browser/extensions/extensions_service.h"
+#include "chrome/common/notification_service.h"
+#include "chrome/test/ui_test_utils.h"
+
+namespace {
+
+// How long to wait for the extension to load before giving up.
+const int kLoadTimeoutMs = 5000;
+
+} // namespace
+
+TestExtensionLoader::TestExtensionLoader(Profile* profile)
+ : profile_(profile),
+ extension_(NULL) {
+ registrar_.Add(this, NotificationType::EXTENSIONS_LOADED,
+ NotificationService::AllSources());
+
+ profile_->GetExtensionsService()->Init();
+ DCHECK(profile_->GetExtensionsService()->extensions()->empty());
+}
+
+Extension* TestExtensionLoader::Load(const char* extension_id,
+ const FilePath& path) {
+ loading_extension_id_ = extension_id;
+
+ // Load the extension.
+ profile_->GetExtensionsService()->LoadExtension(path);
+
+ // Wait for the load to complete. Stick a QuitTask into the message loop
+ // with the timeout so it will exit if the extension never loads.
+ extension_ = NULL;
+ MessageLoop::current()->PostDelayedTask(FROM_HERE,
+ new MessageLoop::QuitTask, kLoadTimeoutMs);
+ ui_test_utils::RunMessageLoop();
+
+ return extension_;
+}
+
+void TestExtensionLoader::Observe(NotificationType type,
+ const NotificationSource& source,
+ const NotificationDetails& details) {
+ if (type == NotificationType::EXTENSIONS_LOADED) {
+ ExtensionList* extensions = Details<ExtensionList>(details).ptr();
+ for (size_t i = 0; i < (*extensions).size(); ++i) {
+ if ((*extensions)[i]->id() == loading_extension_id_) {
+ extension_ = (*extensions)[i];
+ MessageLoopForUI::current()->Quit();
+ break;
+ }
+ }
+ } else {
+ NOTREACHED();
+ }
+}
diff --git a/chrome/browser/extensions/test_extension_loader.h b/chrome/browser/extensions/test_extension_loader.h
new file mode 100755
index 0000000..4fb74d9
--- /dev/null
+++ b/chrome/browser/extensions/test_extension_loader.h
@@ -0,0 +1,35 @@
+// Copyright (c) 2009 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef CHROME_BROWSER_EXTENSIONS_TEST_EXTENSION_LOADER_H_
+#define CHROME_BROWSER_EXTENSIONS_TEST_EXTENSION_LOADER_H_
+
+#include "chrome/browser/extensions/extension.h"
+#include "chrome/common/notification_observer.h"
+#include "chrome/common/notification_registrar.h"
+
+class Extension;
+class FilePath;
+class Profile;
+
+class TestExtensionLoader : public NotificationObserver {
+ public:
+ explicit TestExtensionLoader(Profile* profile);
+
+ Extension* Load(const char* extension_id, const FilePath& path);
+
+ virtual void Observe(NotificationType type,
+ const NotificationSource& source,
+ const NotificationDetails& details);
+
+ private:
+ Profile* profile_;
+ Extension* extension_;
+ NotificationRegistrar registrar_;
+ std::string loading_extension_id_;
+
+ DISALLOW_COPY_AND_ASSIGN(TestExtensionLoader);
+};
+
+#endif // CHROME_BROWSER_EXTENSIONS_TEST_EXTENSION_LOADER_H_
diff --git a/chrome/chrome.gyp b/chrome/chrome.gyp
index df1d4b8..cf3a9c3 100644
--- a/chrome/chrome.gyp
+++ b/chrome/chrome.gyp
@@ -2092,9 +2092,11 @@
'browser/download/download_manager_unittest.cc',
'browser/download/download_request_manager_unittest.cc',
'browser/download/save_package_unittest.cc',
+ 'browser/extensions/extension_content_script_inject_unittest.cc',
'browser/extensions/extension_ui_unittest.cc',
'browser/extensions/extension_unittest.cc',
'browser/extensions/extensions_service_unittest.cc',
+ 'browser/extensions/test_extension_loader.cc',
'browser/extensions/user_script_master_unittest.cc',
'browser/google_url_tracker_unittest.cc',
'browser/gtk/tabs/tab_renderer_gtk_unittest.cc',
@@ -2271,6 +2273,8 @@
'browser/bookmarks/bookmark_folder_tree_model_unittest.cc',
'browser/bookmarks/bookmark_table_model_unittest.cc',
'browser/browser_commands_unittest.cc',
+ 'browser/extensions/extension_content_script_inject_unittest.cc',
+ 'browser/extensions/test_extension_loader.cc',
'browser/extensions/user_script_master_unittest.cc',
'browser/importer/firefox_importer_unittest.cc',
'browser/importer/importer_unittest.cc',
diff --git a/chrome/common/extensions/user_script.cc b/chrome/common/extensions/user_script.cc
index 69fe5f4..abe9280 100644
--- a/chrome/common/extensions/user_script.cc
+++ b/chrome/common/extensions/user_script.cc
@@ -40,6 +40,9 @@ void UserScript::Pickle(::Pickle* pickle) const {
// Write the run location.
pickle->WriteInt(run_location());
+ // Write the extension id.
+ pickle->WriteString(extension_id());
+
// Write globs.
pickle->WriteSize(globs_.size());
for (std::vector<std::string>::const_iterator glob = globs_.begin();
@@ -76,6 +79,9 @@ void UserScript::Unpickle(const ::Pickle& pickle, void** iter) {
CHECK(run_location >= 0 && run_location < RUN_LOCATION_LAST);
run_location_ = static_cast<RunLocation>(run_location);
+ // Read the extension ID.
+ CHECK(pickle.ReadString(iter, &extension_id_));
+
// Read globs.
size_t num_globs = 0;
CHECK(pickle.ReadSize(iter, &num_globs));
diff --git a/chrome/common/extensions/user_script.h b/chrome/common/extensions/user_script.h
index 1a8d6df..070ead3 100644
--- a/chrome/common/extensions/user_script.h
+++ b/chrome/common/extensions/user_script.h
@@ -111,6 +111,11 @@ class UserScript {
FileList& css_scripts() { return css_scripts_; }
const FileList& css_scripts() const { return css_scripts_; }
+ const std::string& extension_id() const { return extension_id_; }
+ void set_extension_id(const std::string& id) { extension_id_ = id; }
+
+ bool is_standalone() { return extension_id_.empty(); }
+
// Returns true if the script should be applied to the specified URL, false
// otherwise.
bool MatchesUrl(const GURL& url);
@@ -141,6 +146,10 @@ class UserScript {
// List of css scripts defined in content_scripts
FileList css_scripts_;
+
+ // The ID of the extension this script is a part of, if any. Can be empty if
+ // the script is a "standlone" user script.
+ std::string extension_id_;
};
typedef std::vector<UserScript> UserScriptList;
diff --git a/chrome/renderer/resources/extension_process_bindings.js b/chrome/renderer/resources/extension_process_bindings.js
index b109a76..221f3fd 100644
--- a/chrome/renderer/resources/extension_process_bindings.js
+++ b/chrome/renderer/resources/extension_process_bindings.js
@@ -9,9 +9,9 @@ var chromium;
// We shouldn't be receiving evil JSON unless the browser is owned, but just
// to be safe, we sanitize it. This regex mania was borrowed from json2,
// from json.org.
- if (!/^[\],:{}\s]*$/.test(
- str.replace(/\\(?:["\\\/bfnrt]|u[0-9a-fA-F]{4})/g, '@').
- replace(/"[^"\\\n\r]*"|true|false|null|-?\d+(?:\.\d*)?(?:[eE][+\-]?\d+)?/g, ']').
+ if (!/^[\],:{}\s]*$/.test(
+ str.replace(/\\(?:["\\\/bfnrt]|u[0-9a-fA-F]{4})/g, '@').
+ replace(/"[^"\\\n\r]*"|true|false|null|-?\d+(?:\.\d*)?(?:[eE][+\-]?\d+)?/g, ']').
replace(/(?:^|:|,)(?:\s*\[)+/g, '')))
throw new Error("Unexpected characters in incoming JSON response.");
diff --git a/chrome/renderer/user_script_slave.cc b/chrome/renderer/user_script_slave.cc
index aedc345..bd5a988 100644
--- a/chrome/renderer/user_script_slave.cc
+++ b/chrome/renderer/user_script_slave.cc
@@ -25,6 +25,8 @@ using WebKit::WebString;
static const char kUserScriptHead[] = "(function (unsafeWindow) {\n";
static const char kUserScriptTail[] = "\n})(window);";
+static const char kInitSelf[] = "chromium.self = new chromium.Extension('%s')";
+
UserScriptSlave::UserScriptSlave()
: shared_memory_(NULL),
script_deleter_(&scripts_),
@@ -110,8 +112,8 @@ bool UserScriptSlave::InjectScripts(WebFrame* frame,
PerfTimer timer;
int num_matched = 0;
- std::vector<WebScriptSource> sources;
for (size_t i = 0; i < scripts_.size(); ++i) {
+ std::vector<WebScriptSource> sources;
UserScript* script = scripts_[i];
if (!script->MatchesUrl(frame->GetURL()))
continue; // This frame doesn't match the script url pattern, skip it.
@@ -127,16 +129,35 @@ bool UserScriptSlave::InjectScripts(WebFrame* frame,
if (script->run_location() == location) {
for (size_t j = 0; j < script->js_scripts().size(); ++j) {
UserScript::File &file = script->js_scripts()[j];
+ std::string content = file.GetContent().as_string();
+
+ // We add this dumb function wrapper for standalone user script to
+ // emulate what Greasemonkey does.
+ if (script->is_standalone()) {
+ content.insert(0, kUserScriptHead);
+ content += kUserScriptTail;
+ }
sources.push_back(WebScriptSource(
- WebString::fromUTF8(file.GetContent()), file.url()));
+ WebString::fromUTF8(content.c_str(), content.length()),
+ file.url()));
}
}
- }
- if (!sources.empty()) {
- sources.insert(
- sources.begin(), WebScriptSource(WebString::fromUTF8(api_js_)));
- frame->ExecuteScriptInNewContext(&sources.front(), sources.size());
+ if (!sources.empty()) {
+ if (script->is_standalone()) {
+ // For standalone scripts, we try to emulate the Greasemonkey API.
+ sources.insert(sources.begin(),
+ WebScriptSource(WebString::fromUTF8(api_js_.as_string())));
+ } else {
+ // Setup chromium.self to contain an Extension object with the correct
+ // ID.
+ sources.insert(sources.begin(),
+ WebScriptSource(WebString::fromUTF8(
+ StringPrintf(kInitSelf, script->extension_id().c_str()))));
+ }
+
+ frame->ExecuteScriptInNewContext(&sources.front(), sources.size());
+ }
}
// Log debug info.
diff --git a/chrome/test/data/extensions/content_script_inject/js_test.js b/chrome/test/data/extensions/content_script_inject/js_test.js
new file mode 100755
index 0000000..87a0930
--- /dev/null
+++ b/chrome/test/data/extensions/content_script_inject/js_test.js
@@ -0,0 +1,33 @@
+// Copyright (c) 2009 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// A quick and dirty JavaScript test runner.
+
+function assert(truth) {
+ if (!truth) {
+ throw new Error('Assertion failed');
+ }
+}
+
+function runAllTests() {
+ // If there was already an error, do nothing. We don't want to muddy
+ // up the results.
+ if (document.title.indexOf("Error: ") == 0) {
+ return;
+ }
+
+ for (var propName in window) {
+ if (typeof window[propName] == "function" &&
+ propName.indexOf("test") == 0) {
+ try {
+ window[propName]();
+ document.title += propName + ",";
+ } catch (e) {
+ // We use document.title to communicate results back to the browser.
+ document.title = "Error: " + propName + ': ' + e.message;
+ return;
+ }
+ }
+ }
+}
diff --git a/chrome/test/data/extensions/content_script_inject/manifest.json b/chrome/test/data/extensions/content_script_inject/manifest.json
new file mode 100755
index 0000000..8214fb6
--- /dev/null
+++ b/chrome/test/data/extensions/content_script_inject/manifest.json
@@ -0,0 +1,21 @@
+{
+ "id": "00123456789ABCDEF0123456789ABCDEF0123456",
+ "version": "1.0.0.0",
+ "name": "User script inject",
+ "content_scripts": [
+ {
+ "matches": ["file://*/content_script_inject_page.html"],
+ "css": ["script1.css"],
+ "js": ["js_test.js", "script1a.js", "script1b.js"]
+ },
+ {
+ "matches": ["file://*/content_script_inject_page.html"],
+ "js": ["js_test.js", "script2.js"]
+ },
+ {
+ "matches": ["file://*/content_script_inject_page.html"],
+ "js": ["js_test.js", "script3.js"],
+ "run_at": "document_start"
+ }
+ ]
+}
diff --git a/chrome/test/data/extensions/content_script_inject/script1.css b/chrome/test/data/extensions/content_script_inject/script1.css
new file mode 100644
index 0000000..521b501b
--- /dev/null
+++ b/chrome/test/data/extensions/content_script_inject/script1.css
@@ -0,0 +1,10 @@
+/*
+Copyright (c) 2006-2009 The Chromium Authors. All rights reserved.
+Use of this source code is governed by a BSD-style license that can be
+found in the LICENSE file.
+*/
+
+/* script1b.js tests that this rule was applied. */
+body {
+ background:red;
+}
diff --git a/chrome/test/data/extensions/content_script_inject/script1a.js b/chrome/test/data/extensions/content_script_inject/script1a.js
new file mode 100755
index 0000000..87f4f55
--- /dev/null
+++ b/chrome/test/data/extensions/content_script_inject/script1a.js
@@ -0,0 +1,7 @@
+// Copyright (c) 2009 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// create a global variable. script1b.js tests to make sure it is visible and
+// script2.js tests to make sure it is not.
+var script1_var = 1;
diff --git a/chrome/test/data/extensions/content_script_inject/script1b.js b/chrome/test/data/extensions/content_script_inject/script1b.js
new file mode 100755
index 0000000..8e7e102
--- /dev/null
+++ b/chrome/test/data/extensions/content_script_inject/script1b.js
@@ -0,0 +1,27 @@
+// Copyright (c) 2009 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// This tests that we are running in the same global context as script1a.js.
+function testScriptFilesRunInSameContext() {
+ assert(script1_var === 1);
+}
+
+// This tests that our relationship to content is working correctly.
+// a) We should not see content globals in our global scope.
+// b) We should have a contentWindow object that looks like a DOM Window.
+// c) We should be able to access content globals via contentWindow.
+function testContentInteraction() {
+ assert(typeof content_var == "undefined");
+ assert(typeof contentWindow != "undefined");
+ assert(contentWindow.location.href.match(/content_script_inject_page.html$/));
+ assert(contentWindow.content_var == "hello");
+}
+
+// Test that our css in script1.css was injected successfully.
+function testCSSWasInjected() {
+ assert(document.defaultView.getComputedStyle(
+ document.body, null)["background-color"] == "rgb(255, 0, 0)");
+}
+
+runAllTests();
diff --git a/chrome/test/data/extensions/content_script_inject/script2.js b/chrome/test/data/extensions/content_script_inject/script2.js
new file mode 100755
index 0000000..9133afa2
--- /dev/null
+++ b/chrome/test/data/extensions/content_script_inject/script2.js
@@ -0,0 +1,12 @@
+// Copyright (c) 2009 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Tests that we cannot see global variables defined in other content scripts.
+// This var was defined in script1a.js. We run each content script in a separate
+// context, so we shouldn't see globals across them.
+function testCannotSeeOtherContentScriptGlobals() {
+ assert(typeof script1_var == "undefined");
+}
+
+runAllTests();
diff --git a/chrome/test/data/extensions/content_script_inject/script3.js b/chrome/test/data/extensions/content_script_inject/script3.js
new file mode 100644
index 0000000..15bc225
--- /dev/null
+++ b/chrome/test/data/extensions/content_script_inject/script3.js
@@ -0,0 +1,31 @@
+// Copyright (c) 2009 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+var gotDOMContentLoadedEvent = false;
+
+// Test that at parse time, we have the document element.
+// This basically tests that we don't get injected too early (before there is
+// a document element).
+var hasDocumentElement = (document.documentElement.tagName == "HTML");
+
+// TODO(aa): We would like to add more tests here verifying that we aren't
+// injected too late. For example, we could test that there are zero child
+// nodes to the documentElement, but unfortunately run_at:document_start is
+// currently buggy and doesn't guarantee that.
+
+window.addEventListener("DOMContentLoaded", function() {
+ gotDOMContentLoadedEvent = true;
+}, false);
+
+// Don't run tests until onload so that we can test that DOMContentLoaded and
+// onload happen after this script runs.
+window.addEventListener("load", runAllTests, false);
+
+function testRunAtDocumentStart() {
+ assert(hasDocumentElement);
+}
+
+function testGotLoadEvents() {
+ assert(gotDOMContentLoadedEvent);
+}
diff --git a/chrome/test/data/extensions/content_script_inject_page.html b/chrome/test/data/extensions/content_script_inject_page.html
new file mode 100755
index 0000000..4412e19
--- /dev/null
+++ b/chrome/test/data/extensions/content_script_inject_page.html
@@ -0,0 +1,10 @@
+<html>
+<head>
+<title></title>
+<script>
+var content_var = "hello";
+</script>
+</head>
+<body>
+</body>
+</html>
diff --git a/chrome/test/data/purify/unit_tests.exe_MLK.txt b/chrome/test/data/purify/unit_tests.exe_MLK.txt
index e69de29..ba64753 100644
--- a/chrome/test/data/purify/unit_tests.exe_MLK.txt
+++ b/chrome/test/data/purify/unit_tests.exe_MLK.txt
@@ -0,0 +1,56 @@
+c:\program files\microsoft visual studio 8\vc\include\xmemory.
+Alloc Location
+ ...
+ chrome/browser/renderer_host/renderer_security_policy.cc RendererSecurityPolicy::SecurityState::GrantScheme(basic_string::std const&)
+ chrome/browser/renderer_host/renderer_security_policy.cc RendererSecurityPolicy::GrantRequestURL(int,GURL const&)
+ chrome/browser/renderer_host/render_view_host.cc RenderViewHost::NavigateToEntry(NavigationEntry const&,bool)
+ chrome/browser/tab_contents/web_contents.cc WebContents::NavigateToPendingEntry(bool)
+ chrome/browser/tab_contents/navigation_controller.cc NavigationController::NavigateToPendingEntry(bool)
+ chrome/browser/tab_contents/navigation_controller.cc NavigationController::LoadEntry(NavigationEntry *)
+ chrome/browser/tab_contents/navigation_controller.cc NavigationController::LoadURL(GURL const&,GURL const&,UINT)
+ chrome/browser/browser.cc Browser::OpenURLFromTab(TabContents *,GURL const&,GURL const&,WindowOpenDisposition,UINT)
+ chrome/test/ui_test_utils.cc ui_test_utils::NavigateToURL(Browser *,GURL const&)
+ chrome/browser/extensions/extension_content_script_inject_unittest.cc ExtensionContentScriptInjectTest_Simple_Test::RunTestOnMainThread(void)
+ chrome/test/in_process_browser_test.cc InProcessBrowserTest::RunTestOnMainThreadLoop(void)
+ base/tuple.h ?DispatchToMethod@VInProcessBrowserTest@@P81@AEXXZ@@YAXPAVInProcessBrowserTest@@P80@AEXXZABUTuple0@@@Z
+ ^^^
+
+RendererSecurityPolicy::Add(int) [unit_tests.exe]
+Alloc Location
+ ...
+ chrome/browser/renderer_host/renderer_security_policy.cc RendererSecurityPolicy::Add(int)
+ chrome/browser/renderer_host/browser_render_process_host.cc BrowserRenderProcessHost::Init(void)
+ chrome/browser/renderer_host/render_view_host.cc RenderViewHost::CreateRenderView(void)
+ chrome/browser/tab_contents/web_contents.cc WebContents::CreateRenderViewForRenderManager(RenderViewHost *)
+ chrome/browser/tab_contents/render_view_host_manager.cc RenderViewHostManager::Navigate(NavigationEntry const&)
+ chrome/browser/tab_contents/web_contents.cc WebContents::NavigateToPendingEntry(bool)
+ chrome/browser/tab_contents/navigation_controller.cc NavigationController::NavigateToPendingEntry(bool)
+ chrome/browser/tab_contents/navigation_controller.cc NavigationController::LoadEntry(NavigationEntry *)
+ chrome/browser/tab_contents/navigation_controller.cc NavigationController::LoadURL(GURL const&,GURL const&,UINT)
+ chrome/browser/browser.cc Browser::CreateTabContentsForURL(GURL const&,GURL const&,Profile *,UINT,bool,SiteInstance *)const
+ chrome/browser/browser.cc Browser::AddTabWithURL(GURL const&,GURL const&,UINT,bool,SiteInstance *)
+ chrome/test/in_process_browser_test.cc InProcessBrowserTest::CreateBrowser(Profile *)
+ chrome/test/in_process_browser_test.cc InProcessBrowserTest::RunTestOnMainThreadLoop(void)
+ base/tuple.h ?DispatchToMethod@VInProcessBrowserTest@@P81@AEXXZ@@YAXPAVInProcessBrowserTest@@P80@AEXXZABUTuple0@@@Z
+ ^^^
+
+c:\program files\microsoft visual studio 8\vc\include\xmemory.
+Alloc Location
+ ...
+ chrome/browser/renderer_host/renderer_security_policy.cc RendererSecurityPolicy::SecurityState::SecurityState(void)
+ chrome/browser/renderer_host/renderer_security_policy.cc RendererSecurityPolicy::Add(int)
+ chrome/browser/renderer_host/browser_render_process_host.cc BrowserRenderProcessHost::Init(void)
+ chrome/browser/renderer_host/render_view_host.cc RenderViewHost::CreateRenderView(void)
+ chrome/browser/tab_contents/web_contents.cc WebContents::CreateRenderViewForRenderManager(RenderViewHost *)
+ chrome/browser/tab_contents/render_view_host_manager.cc RenderViewHostManager::Navigate(NavigationEntry const&)
+ chrome/browser/tab_contents/web_contents.cc WebContents::NavigateToPendingEntry(bool)
+ chrome/browser/tab_contents/navigation_controller.cc NavigationController::NavigateToPendingEntry(bool)
+ chrome/browser/tab_contents/navigation_controller.cc NavigationController::LoadEntry(NavigationEntry *)
+ chrome/browser/tab_contents/navigation_controller.cc NavigationController::LoadURL(GURL const&,GURL const&,UINT)
+ chrome/browser/browser.cc Browser::CreateTabContentsForURL(GURL const&,GURL const&,Profile *,UINT,bool,SiteInstance *)const
+ chrome/browser/browser.cc Browser::AddTabWithURL(GURL const&,GURL const&,UINT,bool,SiteInstance *)
+ chrome/test/in_process_browser_test.cc InProcessBrowserTest::CreateBrowser(Profile *)
+ chrome/test/in_process_browser_test.cc InProcessBrowserTest::RunTestOnMainThreadLoop(void)
+ base/tuple.h ?DispatchToMethod@VInProcessBrowserTest@@P81@AEXXZ@@YAXPAVInProcessBrowserTest@@P80@AEXXZABUTuple0@@@Z
+ ^^^
+ \ No newline at end of file
diff --git a/chrome/test/data/purify/unit_tests.exe_UMR.txt b/chrome/test/data/purify/unit_tests.exe_UMR.txt
index e69de29..87dd20c 100644
--- a/chrome/test/data/purify/unit_tests.exe_UMR.txt
+++ b/chrome/test/data/purify/unit_tests.exe_UMR.txt
@@ -0,0 +1,92 @@
+Uninitialized memory read in AutocompleteEditViewWin::SetSelectionRange(_charrange const&)
+Error Location
+ chrome/browser/autocomplete/autocomplete_edit_view_win.h AutocompleteEditViewWin::SetSelectionRange(_charrange const&)
+ chrome/browser/autocomplete/autocomplete_edit_view_win.cc AutocompleteEditViewWin::EmphasizeURLComponents(void)
+ chrome/browser/autocomplete/autocomplete_edit_view_win.cc AutocompleteEditViewWin::TextChanged(void)
+ chrome/browser/autocomplete/autocomplete_edit_view_win.cc AutocompleteEditViewWin::RevertAll(void)
+ chrome/browser/autocomplete/autocomplete_edit_view_win.cc AutocompleteEditViewWin::Update(TabContents const*)
+ chrome/browser/views/location_bar_view.cc LocationBarView::Update(TabContents const*)
+ chrome/browser/views/toolbar_view.cc BrowserToolbarView::Update(TabContents *,bool)
+ chrome/browser/views/frame/browser_view.cc BrowserView::UpdateToolbar(TabContents *,bool)
+ chrome/browser/browser.cc Browser::UpdateToolbar(bool)
+ chrome/browser/browser.cc Browser::ScheduleUIUpdate(TabContents const*,UINT)
+ chrome/browser/browser.cc Browser::OpenURLFromTab(TabContents *,GURL const&,GURL const&,WindowOpenDisposition,UINT)
+ chrome/test/ui_test_utils.cc ui_test_utils::NavigateToURL(Browser *,GURL const&)
+ chrome/browser/extensions/extension_content_script_inject_unittest.cc ExtensionContentScriptInjectTest_Simple_Test::RunTestOnMainThread(void)
+ chrome/test/in_process_browser_test.cc InProcessBrowserTest::RunTestOnMainThreadLoop(void)
+ base/tuple.h ?DispatchToMethod@VInProcessBrowserTest@@P81@AEXXZ@@YAXPAVInProcessBrowserTest@@P80@AEXXZABUTuple0@@@Z
+ ^^^
+
+Uninitialized memory read in AutocompleteEditViewWin::SetSelectionRange(_charrange const&)
+Error Location
+ chrome/browser/autocomplete/autocomplete_edit_view_win.h AutocompleteEditViewWin::SetSelectionRange(_charrange const&)
+ chrome/browser/autocomplete/autocomplete_edit_view_win.cc AutocompleteEditViewWin::EmphasizeURLComponents(void)
+ chrome/browser/autocomplete/autocomplete_edit_view_win.cc AutocompleteEditViewWin::TextChanged(void)
+ chrome/browser/autocomplete/autocomplete_edit_view_win.cc AutocompleteEditViewWin::RevertAll(void)
+ chrome/browser/autocomplete/autocomplete_edit_view_win.cc AutocompleteEditViewWin::Update(TabContents const*)
+ chrome/browser/views/location_bar_view.cc LocationBarView::Update(TabContents const*)
+ chrome/browser/views/toolbar_view.cc BrowserToolbarView::Update(TabContents *,bool)
+ chrome/browser/views/frame/browser_view.cc BrowserView::UpdateToolbar(TabContents *,bool)
+ chrome/browser/browser.cc Browser::UpdateToolbar(bool)
+ chrome/browser/browser.cc Browser::TabSelectedAt(TabContents *,TabContents *,int,bool)
+ chrome/browser/tabs/tab_strip_model.cc TabStripModel::ChangeSelectedContentsFrom(TabContents *,int,bool)
+ chrome/browser/tabs/tab_strip_model.cc TabStripModel::InsertTabContentsAt(int,TabContents *,bool,bool)
+ chrome/browser/tabs/tab_strip_model.cc TabStripModel::AddTabContents(TabContents *,int,UINT,bool)
+ chrome/browser/browser.cc Browser::AddTabWithURL(GURL const&,GURL const&,UINT,bool,SiteInstance *)
+ chrome/test/in_process_browser_test.cc InProcessBrowserTest::CreateBrowser(Profile *)
+ chrome/test/in_process_browser_test.cc InProcessBrowserTest::RunTestOnMainThreadLoop(void)
+ base/tuple.h ?DispatchToMethod@VInProcessBrowserTest@@P81@AEXXZ@@YAXPAVInProcessBrowserTest@@P80@AEXXZABUTuple0@@@Z
+ ^^^
+
+Uninitialized memory read in AutocompleteEditViewWin::SetSelectionRange(_charrange const&)
+Error Location
+ chrome/browser/autocomplete/autocomplete_edit_view_win.h AutocompleteEditViewWin::SetSelectionRange(_charrange const&)
+ chrome/browser/autocomplete/autocomplete_edit_view_win.cc AutocompleteEditViewWin::EmphasizeURLComponents(void)
+ chrome/browser/autocomplete/autocomplete_edit_view_win.cc AutocompleteEditViewWin::TextChanged(void)
+ chrome/browser/autocomplete/autocomplete_edit_view_win.cc AutocompleteEditViewWin::RevertAll(void)
+ chrome/browser/autocomplete/autocomplete_edit_view_win.cc AutocompleteEditViewWin::Update(TabContents const*)
+ chrome/browser/views/location_bar_view.cc LocationBarView::Update(TabContents const*)
+ chrome/browser/views/toolbar_view.cc BrowserToolbarView::Update(TabContents *,bool)
+ chrome/browser/views/frame/browser_view.cc BrowserView::UpdateToolbar(TabContents *,bool)
+ chrome/browser/views/frame/browser_view.cc BrowserView::TabSelectedAt(TabContents *,TabContents *,int,bool)
+ chrome/browser/tabs/tab_strip_model.cc TabStripModel::ChangeSelectedContentsFrom(TabContents *,int,bool)
+ chrome/browser/tabs/tab_strip_model.cc TabStripModel::InsertTabContentsAt(int,TabContents *,bool,bool)
+ chrome/browser/tabs/tab_strip_model.cc TabStripModel::AddTabContents(TabContents *,int,UINT,bool)
+ chrome/browser/browser.cc Browser::AddTabWithURL(GURL const&,GURL const&,UINT,bool,SiteInstance *)
+ chrome/test/in_process_browser_test.cc InProcessBrowserTest::CreateBrowser(Profile *)
+ chrome/test/in_process_browser_test.cc InProcessBrowserTest::RunTestOnMainThreadLoop(void)
+ base/tuple.h ?DispatchToMethod@VInProcessBrowserTest@@P81@AEXXZ@@YAXPAVInProcessBrowserTest@@P80@AEXXZABUTuple0@@@Z
+ ^^^
+
+Uninitialized memory read in AutocompleteEditViewWin::SetSelectionRange(_charrange const&)
+Error Location
+ chrome/browser/autocomplete/autocomplete_edit_view_win.h AutocompleteEditViewWin::SetSelectionRange(_charrange const&)
+ chrome/browser/autocomplete/autocomplete_edit_view_win.cc AutocompleteEditViewWin::EmphasizeURLComponents(void)
+ chrome/browser/autocomplete/autocomplete_edit_view_win.cc AutocompleteEditViewWin::TextChanged(void)
+ chrome/browser/autocomplete/autocomplete_edit_view_win.cc AutocompleteEditViewWin::RevertAll(void)
+ chrome/browser/autocomplete/autocomplete_edit_view_win.cc AutocompleteEditViewWin::Update(TabContents const*)
+ chrome/browser/views/location_bar_view.cc LocationBarView::Update(TabContents const*)
+ chrome/browser/views/location_bar_view.cc LocationBarView::Init(void)
+ chrome/browser/views/toolbar_view.cc BrowserToolbarView::CreateCenterStack(Profile *)
+ chrome/browser/views/toolbar_view.cc BrowserToolbarView::Init(Profile *)
+ chrome/browser/views/frame/browser_view.cc BrowserView::Init(void)
+ chrome/browser/views/frame/browser_view.cc BrowserView::ViewHierarchyChanged(bool,View::views *,View::views *)
+ chrome/views/view.cc views::View::ViewHierarchyChangedImpl(bool,bool,View::views *,View::views *)
+ chrome/views/view.cc views::View::PropagateAddNotifications(View::views *,View::views *)
+ chrome/views/view.cc views::View::AddChildView(int,View::views *,bool)
+ chrome/views/view.cc views::View::AddChildView(int,View::views *)
+ chrome/views/window/non_client_view.cc views::NonClientView::ViewHierarchyChanged(bool,View::views *,View::views *)
+ chrome/views/view.cc views::View::ViewHierarchyChangedImpl(bool,bool,View::views *,View::views *)
+ chrome/views/view.cc views::View::PropagateAddNotifications(View::views *,View::views *)
+ chrome/views/view.cc views::View::AddChildView(int,View::views *,bool)
+ chrome/views/view.cc views::View::AddChildView(View::views *)
+ chrome/views/widget/widget_win.cc views::WidgetWin::SetContentsView(View::views *)
+ chrome/views/window/window_win.cc views::WindowWin::Init(HWND__ *,Rect::gfx const&)
+ chrome/browser/views/frame/browser_frame.cc BrowserFrame::Init(void)
+ chrome/browser/views/frame/browser_view.cc BrowserWindow::CreateBrowserWindow(Browser *)
+ chrome/browser/browser.cc Browser::CreateBrowserWindow(void)
+ chrome/browser/browser.cc Browser::Create(Profile *)
+ chrome/test/in_process_browser_test.cc InProcessBrowserTest::CreateBrowser(Profile *)
+ chrome/test/in_process_browser_test.cc InProcessBrowserTest::RunTestOnMainThreadLoop(void)
+ base/tuple.h ?DispatchToMethod@VInProcessBrowserTest@@P81@AEXXZ@@YAXPAVInProcessBrowserTest@@P80@AEXXZABUTuple0@@@Z
+ ^^^
diff --git a/chrome/test/unit/unittests.vcproj b/chrome/test/unit/unittests.vcproj
index 947f797..4a5d3cd 100644
--- a/chrome/test/unit/unittests.vcproj
+++ b/chrome/test/unit/unittests.vcproj
@@ -476,6 +476,10 @@
>
</File>
<File
+ RelativePath="..\..\browser\extensions\extension_content_script_inject_unittest.cc"
+ >
+ </File>
+ <File
RelativePath="..\..\browser\extensions\extension_ui_unittest.cc"
>
</File>
@@ -704,6 +708,14 @@
>
</File>
<File
+ RelativePath="..\..\browser\extensions\test_extension_loader.cc"
+ >
+ </File>
+ <File
+ RelativePath="..\..\browser\extensions\test_extension_loader.h"
+ >
+ </File>
+ <File
RelativePath="..\..\browser\history\text_database_manager_unittest.cc"
>
</File>