diff options
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> |