summaryrefslogtreecommitdiffstats
path: root/chrome/renderer/extensions
diff options
context:
space:
mode:
Diffstat (limited to 'chrome/renderer/extensions')
-rw-r--r--chrome/renderer/extensions/contextMenus_custom_bindings.cc38
-rw-r--r--chrome/renderer/extensions/contextMenus_custom_bindings.h24
-rw-r--r--chrome/renderer/extensions/custom_bindings_util.cc70
-rw-r--r--chrome/renderer/extensions/custom_bindings_util.h44
-rw-r--r--chrome/renderer/extensions/extension_dispatcher.cc55
-rw-r--r--chrome/renderer/extensions/extension_dispatcher.h6
-rw-r--r--chrome/renderer/extensions/schema_generated_bindings.cc10
7 files changed, 221 insertions, 26 deletions
diff --git a/chrome/renderer/extensions/contextMenus_custom_bindings.cc b/chrome/renderer/extensions/contextMenus_custom_bindings.cc
new file mode 100644
index 0000000..a1b5049
--- /dev/null
+++ b/chrome/renderer/extensions/contextMenus_custom_bindings.cc
@@ -0,0 +1,38 @@
+// Copyright (c) 2012 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/renderer/extensions/contextMenus_custom_bindings.h"
+
+#include "grit/renderer_resources.h"
+#include "v8/include/v8.h"
+
+namespace extensions {
+
+ContextMenusCustomBindings::ContextMenusCustomBindings(
+ int dependency_count,
+ const char** dependencies)
+ : ChromeV8Extension(
+ "extensions/contextMenus_custom_bindings.js",
+ IDR_CONTEXTMENUS_CUSTOM_BINDINGS_JS,
+ dependency_count,
+ dependencies,
+ NULL) {}
+
+static v8::Handle<v8::Value> GetNextContextMenuId(const v8::Arguments& args) {
+ // Note: this works because contextMenus.create() only works in the
+ // extension process. If that API is opened up to content scripts, this
+ // will need to change. See crbug.com/77023
+ static int next_context_menu_id = 1;
+ return v8::Integer::New(next_context_menu_id++);
+}
+
+v8::Handle<v8::FunctionTemplate> ContextMenusCustomBindings::GetNativeFunction(
+ v8::Handle<v8::String> name) {
+ if (name->Equals(v8::String::New("GetNextContextMenuId")))
+ return v8::FunctionTemplate::New(GetNextContextMenuId);
+
+ return ChromeV8Extension::GetNativeFunction(name);
+}
+
+} // extensions
diff --git a/chrome/renderer/extensions/contextMenus_custom_bindings.h b/chrome/renderer/extensions/contextMenus_custom_bindings.h
new file mode 100644
index 0000000..8acd2bd
--- /dev/null
+++ b/chrome/renderer/extensions/contextMenus_custom_bindings.h
@@ -0,0 +1,24 @@
+// Copyright (c) 2012 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_RENDERER_EXTENSIONS_CONTEXTMENUS_CUSTOM_BINDINGS_H_
+#define CHROME_RENDERER_EXTENSIONS_CONTEXTMENUS_CUSTOM_BINDINGS_H_
+#pragma once
+
+#include "chrome/renderer/extensions/chrome_v8_extension.h"
+
+namespace extensions {
+
+// Implements custom bindings for the contextMenus API.
+class ContextMenusCustomBindings : public ChromeV8Extension {
+ public:
+ ContextMenusCustomBindings(int dependency_count, const char** dependencies);
+
+ virtual v8::Handle<v8::FunctionTemplate> GetNativeFunction(
+ v8::Handle<v8::String> name) OVERRIDE;
+};
+
+} // extensions
+
+#endif // CHROME_RENDERER_EXTENSIONS_CONTEXTMENUS_CUSTOM_BINDINGS_H_
diff --git a/chrome/renderer/extensions/custom_bindings_util.cc b/chrome/renderer/extensions/custom_bindings_util.cc
new file mode 100644
index 0000000..c17740f
--- /dev/null
+++ b/chrome/renderer/extensions/custom_bindings_util.cc
@@ -0,0 +1,70 @@
+// Copyright (c) 2012 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/renderer/extensions/custom_bindings_util.h"
+
+#include <map>
+
+#include "base/string_util.h"
+#include "chrome/common/extensions/extension.h"
+#include "chrome/renderer/extensions/chrome_v8_extension.h"
+#include "chrome/renderer/extensions/contextMenus_custom_bindings.h"
+#include "base/logging.h"
+#include "grit/renderer_resources.h"
+#include "v8/include/v8.h"
+
+namespace extensions {
+
+namespace custom_bindings_util {
+
+std::vector<v8::Extension*> GetAll() {
+ static const char* kDependencies[] = {
+ "extensions/schema_generated_bindings.js",
+ };
+ static const size_t kDependencyCount = arraysize(kDependencies);
+
+ std::vector<v8::Extension*> result;
+
+ result.push_back(
+ new ContextMenusCustomBindings(kDependencyCount, kDependencies));
+
+ return result;
+}
+
+// Extracts the name of an API from the name of the V8 extension which contains
+// custom bindings for it (see kCustomBindingNames).
+std::string GetAPIName(const std::string& v8_extension_name) {
+ // Extract the name of the API from the v8 extension name.
+ // This is "${api_name}" in "extensions/${api_name}_custom_bindings.js".
+ std::string prefix = "extensions/";
+ const bool kCaseSensitive = true;
+ if (!StartsWithASCII(v8_extension_name, prefix, kCaseSensitive))
+ return "";
+
+ std::string suffix = "_custom_bindings.js";
+ if (!EndsWith(v8_extension_name, suffix, kCaseSensitive))
+ return "";
+
+ return v8_extension_name.substr(
+ prefix.size(),
+ v8_extension_name.size() - prefix.size() - suffix.size());
+}
+
+bool AllowAPIInjection(const std::string& api_name,
+ const Extension& extension) {
+ CHECK(api_name != "");
+
+ // As in ExtensionAPI::GetSchemasForExtension, we need to allow any bindings
+ // for an API that the extension *might* have permission to use.
+ if (!extension.required_permission_set()->HasAnyAccessToAPI(api_name) &&
+ !extension.optional_permission_set()->HasAnyAccessToAPI(api_name)) {
+ return false;
+ }
+
+ return true;
+}
+
+} // namespace custom_bindings_util
+
+} // namespace extensions
diff --git a/chrome/renderer/extensions/custom_bindings_util.h b/chrome/renderer/extensions/custom_bindings_util.h
new file mode 100644
index 0000000..9832386
--- /dev/null
+++ b/chrome/renderer/extensions/custom_bindings_util.h
@@ -0,0 +1,44 @@
+// Copyright (c) 2012 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_RENDERER_EXTENSIONS_CUSTOM_BINDINGS_UTIL_H_
+#define CHROME_RENDERER_EXTENSIONS_CUSTOM_BINDINGS_UTIL_H_
+#pragma once
+
+#include <string>
+#include <vector>
+
+#include "chrome/renderer/extensions/chrome_v8_extension.h"
+
+class Extension;
+
+namespace v8 {
+class Extension;
+}
+
+namespace extensions {
+
+// Utilities for managing the set of V8 extensions for extension API custom
+// bindings.
+namespace custom_bindings_util {
+
+// Creates V8 extensions for all custom bindings.
+std::vector<v8::Extension*> GetAll();
+
+// Extracts the name of an API from the name of the V8 extension which contains
+// custom bindings for it.
+// Returns an empty string if the extension is not for a custom binding.
+std::string GetAPIName(const std::string& v8_extension_name);
+
+// Returns whether the custom binding for an API should be allowed to run for
+// |extension|. This is based on whether the extension has any permission
+// (required or optional) for that API.
+bool AllowAPIInjection(const std::string& api_name,
+ const Extension& extension);
+
+} // namespace custom_bindings_util
+
+} // namespace extensions
+
+#endif // CHROME_RENDERER_EXTENSIONS_CUSTOM_BINDINGS_UTIL_H_
diff --git a/chrome/renderer/extensions/extension_dispatcher.cc b/chrome/renderer/extensions/extension_dispatcher.cc
index 13a0655..b1663cd 100644
--- a/chrome/renderer/extensions/extension_dispatcher.cc
+++ b/chrome/renderer/extensions/extension_dispatcher.cc
@@ -1,4 +1,4 @@
-// Copyright (c) 2011 The Chromium Authors. All rights reserved.
+// Copyright (c) 2012 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.
@@ -16,6 +16,7 @@
#include "chrome/renderer/extensions/chrome_v8_context.h"
#include "chrome/renderer/extensions/chrome_v8_extension.h"
#include "chrome/renderer/extensions/chrome_webstore_bindings.h"
+#include "chrome/renderer/extensions/custom_bindings_util.h"
#include "chrome/renderer/extensions/event_bindings.h"
#include "chrome/renderer/extensions/extension_groups.h"
#include "chrome/renderer/extensions/file_browser_private_bindings.h"
@@ -39,8 +40,8 @@ static const int64 kInitialExtensionIdleHandlerDelayMs = 5*1000;
static const int64 kMaxExtensionIdleHandlerDelayMs = 5*60*1000;
}
-using extensions::MiscellaneousBindings;
-using extensions::SchemaGeneratedBindings;
+using namespace extensions;
+
using WebKit::WebDataSource;
using WebKit::WebDocument;
using WebKit::WebFrame;
@@ -115,6 +116,12 @@ void ExtensionDispatcher::WebKitInitialized() {
RegisterExtension(new ChromeV8Extension(
"extensions/apitest.js", IDR_EXTENSION_APITEST_JS, NULL), true);
+ std::vector<v8::Extension*> custom_bindings = custom_bindings_util::GetAll();
+ for (std::vector<v8::Extension*>::iterator it = custom_bindings.begin();
+ it != custom_bindings.end(); ++it) {
+ RegisterExtension(*it, true);
+ }
+
// Initialize host permissions for any extensions that were activated before
// WebKit was initialized.
for (std::set<std::string>::iterator iter = active_extension_ids_.begin();
@@ -286,6 +293,21 @@ bool ExtensionDispatcher::AllowScriptExtension(
extensions_.ExtensionBindingsAllowed(ExtensionURLInfo(
frame->document().securityOrigin(),
UserScriptSlave::GetDataSourceURLForFrame(frame)))) {
+ // If the extension is a custom API binding, only allow if the extension
+ // has permission to use the API.
+ std::string custom_binding_api_name =
+ custom_bindings_util::GetAPIName(v8_extension_name);
+ if (!custom_binding_api_name.empty()) {
+ const Extension* extension =
+ extensions_.GetByID(GetExtensionID(frame, world_id));
+ // TODO(kalman): there appears to be a race condition, particularly hit
+ // on windows tests, causing this check to fail. It should be a check.
+ if (!extension)
+ return true;
+ return custom_bindings_util::AllowAPIInjection(
+ custom_binding_api_name, *extension);
+ }
+
return true;
}
@@ -294,19 +316,8 @@ bool ExtensionDispatcher::AllowScriptExtension(
void ExtensionDispatcher::DidCreateScriptContext(
WebFrame* frame, v8::Handle<v8::Context> v8_context, int world_id) {
- std::string extension_id;
- if (!test_extension_id_.empty()) {
- extension_id = test_extension_id_;
- } else if (world_id != 0) {
- extension_id = user_script_slave_->GetExtensionIdForIsolatedWorld(world_id);
- } else {
- GURL frame_url = UserScriptSlave::GetDataSourceURLForFrame(frame);
- extension_id = extensions_.GetExtensionOrAppIDByURL(
- ExtensionURLInfo(frame->document().securityOrigin(), frame_url));
- }
-
ChromeV8Context* context =
- new ChromeV8Context(v8_context, frame, extension_id);
+ new ChromeV8Context(v8_context, frame, GetExtensionID(frame, world_id));
v8_context_set_.Add(context);
context->DispatchOnLoadEvent(
@@ -316,6 +327,20 @@ void ExtensionDispatcher::DidCreateScriptContext(
VLOG(1) << "Num tracked contexts: " << v8_context_set_.size();
}
+std::string ExtensionDispatcher::GetExtensionID(WebFrame* frame, int world_id) {
+ if (!test_extension_id_.empty()) {
+ return test_extension_id_;
+ } else if (world_id != 0) {
+ // Isolated worlds (content script).
+ return user_script_slave_->GetExtensionIdForIsolatedWorld(world_id);
+ } else {
+ // Extension pages (chrome-extension:// URLs).
+ GURL frame_url = UserScriptSlave::GetDataSourceURLForFrame(frame);
+ return extensions_.GetExtensionOrAppIDByURL(
+ ExtensionURLInfo(frame->document().securityOrigin(), frame_url));
+ }
+}
+
void ExtensionDispatcher::WillReleaseScriptContext(
WebFrame* frame, v8::Handle<v8::Context> v8_context, int world_id) {
ChromeV8Context* context = v8_context_set_.GetByV8Context(v8_context);
diff --git a/chrome/renderer/extensions/extension_dispatcher.h b/chrome/renderer/extensions/extension_dispatcher.h
index ea48e03..9796430 100644
--- a/chrome/renderer/extensions/extension_dispatcher.h
+++ b/chrome/renderer/extensions/extension_dispatcher.h
@@ -1,4 +1,4 @@
-// Copyright (c) 2011 The Chromium Authors. All rights reserved.
+// Copyright (c) 2012 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.
@@ -137,6 +137,10 @@ class ExtensionDispatcher : public content::RenderProcessObserver {
const Extension* extension,
const URLPatternSet& origins);
+ // Finds the extension ID for the current context. This is determined from
+ // |world_id| if it's non-zero, or the URL in |frame| if it is.
+ std::string GetExtensionID(WebKit::WebFrame* frame, int world_id);
+
// True if this renderer is running extensions.
bool is_extension_process_;
diff --git a/chrome/renderer/extensions/schema_generated_bindings.cc b/chrome/renderer/extensions/schema_generated_bindings.cc
index baf484c..bd6fd47 100644
--- a/chrome/renderer/extensions/schema_generated_bindings.cc
+++ b/chrome/renderer/extensions/schema_generated_bindings.cc
@@ -195,8 +195,6 @@ class ExtensionImpl : public ChromeV8Extension {
return v8::FunctionTemplate::New(GetNextRequestId);
} else if (name->Equals(v8::String::New("OpenChannelToTab"))) {
return v8::FunctionTemplate::New(OpenChannelToTab);
- } else if (name->Equals(v8::String::New("GetNextContextMenuId"))) {
- return v8::FunctionTemplate::New(GetNextContextMenuId);
} else if (name->Equals(v8::String::New("GetNextSocketEventId"))) {
return v8::FunctionTemplate::New(GetNextSocketEventId);
} else if (name->Equals(v8::String::New("GetNextTtsEventId"))) {
@@ -477,14 +475,6 @@ class ExtensionImpl : public ChromeV8Extension {
return v8::Undefined();
}
- static v8::Handle<v8::Value> GetNextContextMenuId(const v8::Arguments& args) {
- // Note: this works because contextMenus.create() only works in the
- // extension process. If that API is opened up to content scripts, this
- // will need to change. See crbug.com/77023
- static int next_context_menu_id = 1;
- return v8::Integer::New(next_context_menu_id++);
- }
-
static v8::Handle<v8::Value> GetNextTtsEventId(const v8::Arguments& args) {
// Note: this works because the TTS API only works in the
// extension process, not content scripts.