Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(165)

Unified Diff: chrome/renderer/resources/extensions/schema_generated_bindings.js

Issue 9403006: Extensions: run "custom bindings" v8-extensions in content scripts. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: final comments Created 8 years, 10 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « chrome/renderer/extensions/schema_generated_bindings.cc ('k') | no next file » | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: chrome/renderer/resources/extensions/schema_generated_bindings.js
diff --git a/chrome/renderer/resources/extensions/schema_generated_bindings.js b/chrome/renderer/resources/extensions/schema_generated_bindings.js
index df126906ea7050abd57103c9fb40392d055c07ae..ae53c857b5be7cb2045454eb086189783326c920 100644
--- a/chrome/renderer/resources/extensions/schema_generated_bindings.js
+++ b/chrome/renderer/resources/extensions/schema_generated_bindings.js
@@ -404,32 +404,34 @@ var chrome = chrome || {};
});
}
+ // Returns whether access to the content of a schema should be denied,
+ // based on the presence of "unprivileged" and whether this is an
+ // extension process (versus e.g. a content script).
+ function isSchemaAccessAllowed(itemSchema) {
+ return isExtensionProcess ||
+ apiDef.unprivileged ||
+ itemSchema.unprivileged;
+ }
+
// Adds a getter that throws an access denied error to object |module|
// for property |name|.
- //
- // Returns true if the getter was necessary (access is disallowed), or
- // false otherwise.
- function addUnprivilegedAccessGetter(module, name, allowUnprivileged) {
- if (allowUnprivileged || isExtensionProcess)
- return false;
-
+ function addUnprivilegedAccessGetter(module, name) {
module.__defineGetter__(name, function() {
throw new Error(
'"' + name + '" can only be used in extension processes. See ' +
'the content scripts documentation for more details.');
});
- return true;
}
// Setup Functions.
if (apiDef.functions) {
apiDef.functions.forEach(function(functionDef) {
+ if (functionDef.name in module)
+ return;
if (!isSchemaNodeSupported(functionDef, platform, manifestVersion))
return;
-
- if (functionDef.name in module ||
- addUnprivilegedAccessGetter(module, functionDef.name,
- functionDef.unprivileged)) {
+ if (!isSchemaAccessAllowed(functionDef)) {
+ addUnprivilegedAccessGetter(module, functionDef.name);
return;
}
@@ -469,12 +471,12 @@ var chrome = chrome || {};
// Setup Events
if (apiDef.events) {
apiDef.events.forEach(function(eventDef) {
+ if (eventDef.name in module)
+ return;
if (!isSchemaNodeSupported(eventDef, platform, manifestVersion))
return;
-
- if (eventDef.name in module ||
- addUnprivilegedAccessGetter(module, eventDef.name,
- eventDef.unprivileged)) {
+ if (!isSchemaAccessAllowed(eventDef)) {
+ addUnprivilegedAccessGetter(module, eventDef.name);
return;
}
@@ -491,66 +493,59 @@ var chrome = chrome || {};
});
}
- function addProperties(m, def) {
- // Parse any values defined for properties.
- if (def.properties) {
- forEach(def.properties, function(prop, property) {
- if (!isSchemaNodeSupported(property, platform, manifestVersion))
- return;
+ function addProperties(m, parentDef) {
+ var properties = parentDef.properties;
+ if (!properties)
+ return;
- if (prop in m ||
- addUnprivilegedAccessGetter(m, prop, property.unprivileged)) {
- return;
- }
+ forEach(properties, function(propertyName, propertyDef) {
+ if (propertyName in m)
+ return;
+ if (!isSchemaNodeSupported(propertyDef, platform, manifestVersion))
+ return;
+ if (!isSchemaAccessAllowed(propertyDef)) {
+ addUnprivilegedAccessGetter(m, propertyName);
+ return;
+ }
- var value = property.value;
- if (value) {
- if (property.type === 'integer') {
- value = parseInt(value);
- } else if (property.type === 'boolean') {
- value = value === "true";
- } else if (property["$ref"]) {
- var constructor = customTypes[property["$ref"]];
- if (!constructor)
- throw new Error("No custom binding for " + property["$ref"]);
- var args = value;
- // For an object property, |value| is an array of constructor
- // arguments, but we want to pass the arguments directly
- // (i.e. not as an array), so we have to fake calling |new| on
- // the constructor.
- value = { __proto__: constructor.prototype };
- constructor.apply(value, args);
- // Recursively add properties.
- addProperties(value, property);
- } else if (property.type === 'object') {
- // Recursively add properties.
- addProperties(value, property);
- } else if (property.type !== 'string') {
- throw "NOT IMPLEMENTED (extension_api.json error): Cannot " +
- "parse values for type \"" + property.type + "\"";
- }
- }
- if (value) {
- m[prop] = value;
+ var value = propertyDef.value;
+ if (value) {
+ if (propertyDef.type === 'integer') {
+ value = parseInt(value);
+ } else if (propertyDef.type === 'boolean') {
+ value = value === "true";
+ } else if (propertyDef["$ref"]) {
+ var constructor = customTypes[propertyDef["$ref"]];
+ if (!constructor)
+ throw new Error("No custom binding for " + propertyDef["$ref"]);
+ var args = value;
+ // For an object propertyDef, |value| is an array of constructor
+ // arguments, but we want to pass the arguments directly
+ // (i.e. not as an array), so we have to fake calling |new| on
+ // the constructor.
+ value = { __proto__: constructor.prototype };
+ constructor.apply(value, args);
+ // Recursively add properties.
+ addProperties(value, propertyDef);
+ } else if (propertyDef.type === 'object') {
+ // Recursively add properties.
+ addProperties(value, propertyDef);
+ } else if (propertyDef.type !== 'string') {
+ throw "NOT IMPLEMENTED (extension_api.json error): Cannot " +
+ "parse values for type \"" + propertyDef.type + "\"";
}
- });
- }
+ }
+ if (value) {
+ m[propertyName] = value;
+ }
+ });
}
addProperties(module, apiDef);
});
- // TODO(aa): The rest of the crap below this really needs to be factored out
- // with a clean API boundary. Right now it is too soupy for me to feel
- // comfortable running in content scripts. What if people are just
- // overwriting random APIs? That would bypass our content script access
- // checks.
- if (!isExtensionProcess)
- return;
-
- // TODO(kalman/aa): "The rest of this crap..." comment above. Only run the
- // custom hooks in extension processes, to maintain current behaviour. We
- // should fix this this with a smaller hammer.
+ // Run the non-declarative custom hooks after all the schemas have been
+ // generated, in case hooks depend on other APIs being available.
apiDefinitions.forEach(function(apiDef) {
if (!isSchemaNodeSupported(apiDef, platform, manifestVersion))
return;
@@ -570,7 +565,7 @@ var chrome = chrome || {};
}, extensionId);
});
- // TOOD(mihaip): remove this alias once the webstore stops calling
+ // TODO(mihaip): remove this alias once the webstore stops calling
// beginInstallWithManifest2.
// See http://crbug.com/100242
if (chrome.webstorePrivate) {
« no previous file with comments | « chrome/renderer/extensions/schema_generated_bindings.cc ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698