diff options
author | asargent@chromium.org <asargent@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2009-11-13 22:22:55 +0000 |
---|---|---|
committer | asargent@chromium.org <asargent@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2009-11-13 22:22:55 +0000 |
commit | 1307901f3bb5ab694530551f05e3898596acd854 (patch) | |
tree | 8a47789504223edce1995ee19afba3dcb7426f93 /chrome/renderer | |
parent | 95ff808aa05c3de690fed32e92a940a6877cd3ed (diff) | |
download | chromium_src-1307901f3bb5ab694530551f05e3898596acd854.zip chromium_src-1307901f3bb5ab694530551f05e3898596acd854.tar.gz chromium_src-1307901f3bb5ab694530551f05e3898596acd854.tar.bz2 |
Add stub functions for chrome.* APIs in content scripts.
Most of the extensions API is not supported in content scripts for security
purposes. Instead the typical pattern is to use messaging between content
scripts and a background page which executes them on behalf of the script.
This is not immediately obvious to many extension developers, so this
change adds an error message to help them better understand what's going on.
BUG=26128
TEST=Try writing a content script that uses some of the extensions API stuff
in chrome.tabs, chrome.windows, etc. You should see errors in the console
telling you that it isn't supported in content scripts.
Review URL: http://codereview.chromium.org/366024
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@31958 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'chrome/renderer')
-rw-r--r-- | chrome/renderer/resources/extension_process_bindings.js | 8 | ||||
-rw-r--r-- | chrome/renderer/resources/renderer_extension_bindings.js | 50 | ||||
-rw-r--r-- | chrome/renderer/user_script_slave.cc | 3 |
3 files changed, 57 insertions, 4 deletions
diff --git a/chrome/renderer/resources/extension_process_bindings.js b/chrome/renderer/resources/extension_process_bindings.js index 85b65ea..2dbf7b4 100644 --- a/chrome/renderer/resources/extension_process_bindings.js +++ b/chrome/renderer/resources/extension_process_bindings.js @@ -272,7 +272,7 @@ var chrome = chrome || {}; } chromeHidden.onLoad.addListener(function (extensionId) { - chrome.initExtension(extensionId); + chrome.initExtension(extensionId, false); // |apiFunctions| is a hash of name -> object that stores the // name & definition of the apiFunction. Custom handling of api functions @@ -317,7 +317,7 @@ var chrome = chrome || {}; module[functionDef.name] = bind(apiFunction, function() { chromeHidden.validate(arguments, this.definition.parameters); - + var retval; if (this.handleRequest) retval = this.handleRequest.apply(this, arguments); @@ -498,6 +498,10 @@ var chrome = chrome || {}; setIconCommon(details, this.name, this.definition.parameters); }; + if (chrome.test) { + chrome.test.getApiDefinitions = GetExtensionAPIDefinition; + } + setupBrowserActionEvent(extensionId); setupPageActionEvents(extensionId); setupToolstripEvents(GetRenderViewId()); diff --git a/chrome/renderer/resources/renderer_extension_bindings.js b/chrome/renderer/resources/renderer_extension_bindings.js index 718c414..5e28537 100644 --- a/chrome/renderer/resources/renderer_extension_bindings.js +++ b/chrome/renderer/resources/renderer_extension_bindings.js @@ -141,7 +141,7 @@ var chrome = chrome || {}; // This function is called on context initialization for both content scripts // and extension contexts. - chrome.initExtension = function(extensionId) { + chrome.initExtension = function(extensionId, warnOnPrivilegedApiAccess) { delete chrome.initExtension; chromeHidden.extensionId = extensionId; @@ -200,5 +200,53 @@ var chrome = chrome || {}; chrome.extension.getURL = function(path) { return "chrome-extension://" + extensionId + "/" + path; }; + + if (warnOnPrivilegedApiAccess) { + setupApiStubs(); + } + } + + var notSupportedSuffix = " is not supported in content scripts. " + + "See the content scripts documentation for more details."; + + // Setup to throw an error message when trying to access |name| on the chrome + // object. The |name| can be a dot-separated path. + function createStub(name) { + var module = chrome; + var parts = name.split("."); + for (var i = 0; i < parts.length - 1; i++) { + var nextPart = parts[i]; + // Make sure an object at the path so far is defined. + module[nextPart] = module[nextPart] || {}; + module = module[nextPart]; + } + var finalPart = parts[parts.length-1]; + module.__defineGetter__(finalPart, function() { + throw new Error("chrome." + name + notSupportedSuffix); + }); } + + // Sets up stubs to throw a better error message for the common case of + // developers trying to call extension API's that aren't allowed to be + // called from content scripts. + function setupApiStubs() { + // TODO(asargent) It would be nice to eventually generate this + // programmatically from extension_api.json (there is already a browser test + // that should prevent it from getting stale). + var privileged = [ + // Entire namespaces. + "bookmarks", "browserAction", "devtools", "experimental.extension", + "experimental.history", "experimental.popup", "i18n", "pageAction", + "pageActions", "tabs", "test", "toolstrip", "windows", + + // Functions/events/properties within the extension namespace. + "extension.getBackgroundPage", "extension.getExtensionTabs", + "extension.getToolstrips", "extension.getViews", "extension.lastError", + "extension.onConnectExternal", "extension.onRequestExternal" + ]; + for (var i = 0; i < privileged.length; i++) { + createStub(privileged[i]); + } + } + })(); diff --git a/chrome/renderer/user_script_slave.cc b/chrome/renderer/user_script_slave.cc index 6aafd4a..c91e566 100644 --- a/chrome/renderer/user_script_slave.cc +++ b/chrome/renderer/user_script_slave.cc @@ -28,7 +28,8 @@ static const char kUserScriptTail[] = "\n})(window);"; // Sets up the chrome.extension module. This may be run multiple times per // context, but the init method deletes itself after the first time. static const char kInitExtension[] = - "if (chrome.initExtension) chrome.initExtension('%s');"; + "if (chrome.initExtension) chrome.initExtension('%s', true);"; + int UserScriptSlave::GetIsolatedWorldId(const std::string& extension_id) { typedef std::map<std::string, int> IsolatedWorldMap; |