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

Side by Side Diff: extensions/renderer/resources/binding.js

Issue 482603002: Unify logic of stack trace generation for extension errors (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Add $Error and $String.indexOf to safe builtins Created 6 years, 4 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 unified diff | Download patch
OLDNEW
1 // Copyright 2014 The Chromium Authors. All rights reserved. 1 // Copyright 2014 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 var Event = require('event_bindings').Event; 5 var Event = require('event_bindings').Event;
6 var forEach = require('utils').forEach; 6 var forEach = require('utils').forEach;
7 var GetAvailability = requireNative('v8_context').GetAvailability; 7 var GetAvailability = requireNative('v8_context').GetAvailability;
8 var getExtensionStackTrace = 8 var getExtensionStackTrace =
9 require('uncaught_exception_handler').getExtensionStackTrace; 9 require('uncaught_exception_handler').getExtensionStackTrace;
10 var lastError = require('lastError'); 10 var lastError = require('lastError');
(...skipping 28 matching lines...) Expand all
39 // than throwing Errors. 39 // than throwing Errors.
40 APIFunctions.prototype.registerUnavailable = function(apiName) { 40 APIFunctions.prototype.registerUnavailable = function(apiName) {
41 this.unavailableApiFunctions_[apiName] = apiName; 41 this.unavailableApiFunctions_[apiName] = apiName;
42 }; 42 };
43 43
44 APIFunctions.prototype.setHook_ = 44 APIFunctions.prototype.setHook_ =
45 function(apiName, propertyName, customizedFunction) { 45 function(apiName, propertyName, customizedFunction) {
46 if ($Object.hasOwnProperty(this.unavailableApiFunctions_, apiName)) 46 if ($Object.hasOwnProperty(this.unavailableApiFunctions_, apiName))
47 return; 47 return;
48 if (!$Object.hasOwnProperty(this.apiFunctions_, apiName)) 48 if (!$Object.hasOwnProperty(this.apiFunctions_, apiName))
49 throw new Error('Tried to set hook for unknown API "' + apiName + '"'); 49 throw new $Error.self(
50 'Tried to set hook for unknown API "' + apiName + '"');
50 this.apiFunctions_[apiName][propertyName] = customizedFunction; 51 this.apiFunctions_[apiName][propertyName] = customizedFunction;
51 }; 52 };
52 53
53 APIFunctions.prototype.setHandleRequest = 54 APIFunctions.prototype.setHandleRequest =
54 function(apiName, customizedFunction) { 55 function(apiName, customizedFunction) {
55 var prefix = this.namespace; 56 var prefix = this.namespace;
56 return this.setHook_(apiName, 'handleRequest', 57 return this.setHook_(apiName, 'handleRequest',
57 function() { 58 function() {
58 var ret = $Function.apply(customizedFunction, this, arguments); 59 var ret = $Function.apply(customizedFunction, this, arguments);
59 // Logs API calls to the Activity Log if it doesn't go through an 60 // Logs API calls to the Activity Log if it doesn't go through an
(...skipping 69 matching lines...) Expand 10 before | Expand all | Expand 10 after
129 for (var i = 0; i < platforms.length; i++) { 130 for (var i = 0; i < platforms.length; i++) {
130 if ($RegExp.test(platforms[i][0], navigator.appVersion)) { 131 if ($RegExp.test(platforms[i][0], navigator.appVersion)) {
131 return platforms[i][1]; 132 return platforms[i][1];
132 } 133 }
133 } 134 }
134 return "unknown"; 135 return "unknown";
135 } 136 }
136 137
137 function isPlatformSupported(schemaNode, platform) { 138 function isPlatformSupported(schemaNode, platform) {
138 return !schemaNode.platforms || 139 return !schemaNode.platforms ||
139 schemaNode.platforms.indexOf(platform) > -1; 140 $Array.indexOf(schemaNode.platforms, platform) > -1;
140 } 141 }
141 142
142 function isManifestVersionSupported(schemaNode, manifestVersion) { 143 function isManifestVersionSupported(schemaNode, manifestVersion) {
143 return !schemaNode.maximumManifestVersion || 144 return !schemaNode.maximumManifestVersion ||
144 manifestVersion <= schemaNode.maximumManifestVersion; 145 manifestVersion <= schemaNode.maximumManifestVersion;
145 } 146 }
146 147
147 function isSchemaNodeSupported(schemaNode, platform, manifestVersion) { 148 function isSchemaNodeSupported(schemaNode, platform, manifestVersion) {
148 return isPlatformSupported(schemaNode, platform) && 149 return isPlatformSupported(schemaNode, platform) &&
149 isManifestVersionSupported(schemaNode, manifestVersion); 150 isManifestVersionSupported(schemaNode, manifestVersion);
(...skipping 131 matching lines...) Expand 10 before | Expand all | Expand 10 after
281 function isSchemaAccessAllowed(itemSchema) { 282 function isSchemaAccessAllowed(itemSchema) {
282 return (contextType == 'BLESSED_EXTENSION') || 283 return (contextType == 'BLESSED_EXTENSION') ||
283 schema.unprivileged || 284 schema.unprivileged ||
284 itemSchema.unprivileged; 285 itemSchema.unprivileged;
285 }; 286 };
286 287
287 // Setup Functions. 288 // Setup Functions.
288 if (schema.functions) { 289 if (schema.functions) {
289 $Array.forEach(schema.functions, function(functionDef) { 290 $Array.forEach(schema.functions, function(functionDef) {
290 if (functionDef.name in mod) { 291 if (functionDef.name in mod) {
291 throw new Error('Function ' + functionDef.name + 292 throw new $Error.self('Function ' + functionDef.name +
292 ' already defined in ' + schema.namespace); 293 ' already defined in ' + schema.namespace);
293 } 294 }
294 295
295 if (!isSchemaNodeSupported(functionDef, platform, manifestVersion)) { 296 if (!isSchemaNodeSupported(functionDef, platform, manifestVersion)) {
296 this.apiFunctions_.registerUnavailable(functionDef.name); 297 this.apiFunctions_.registerUnavailable(functionDef.name);
297 return; 298 return;
298 } 299 }
299 300
300 var apiFunction = {}; 301 var apiFunction = {};
301 apiFunction.definition = functionDef; 302 apiFunction.definition = functionDef;
302 apiFunction.name = schema.namespace + '.' + functionDef.name; 303 apiFunction.name = schema.namespace + '.' + functionDef.name;
303 304
304 if (!GetAvailability(apiFunction.name).is_available || 305 if (!GetAvailability(apiFunction.name).is_available ||
305 (checkUnprivileged && !isSchemaAccessAllowed(functionDef))) { 306 (checkUnprivileged && !isSchemaAccessAllowed(functionDef))) {
306 this.apiFunctions_.registerUnavailable(functionDef.name); 307 this.apiFunctions_.registerUnavailable(functionDef.name);
307 return; 308 return;
308 } 309 }
309 310
310 // TODO(aa): It would be best to run this in a unit test, but in order 311 // TODO(aa): It would be best to run this in a unit test, but in order
311 // to do that we would need to better factor this code so that it 312 // to do that we would need to better factor this code so that it
312 // doesn't depend on so much v8::Extension machinery. 313 // doesn't depend on so much v8::Extension machinery.
313 if (logging.DCHECK_IS_ON() && 314 if (logging.DCHECK_IS_ON() &&
314 schemaUtils.isFunctionSignatureAmbiguous(apiFunction.definition)) { 315 schemaUtils.isFunctionSignatureAmbiguous(apiFunction.definition)) {
315 throw new Error( 316 throw new $Error.self(
316 apiFunction.name + ' has ambiguous optional arguments. ' + 317 apiFunction.name + ' has ambiguous optional arguments. ' +
317 'To implement custom disambiguation logic, add ' + 318 'To implement custom disambiguation logic, add ' +
318 '"allowAmbiguousOptionalArguments" to the function\'s schema.'); 319 '"allowAmbiguousOptionalArguments" to the function\'s schema.');
319 } 320 }
320 321
321 this.apiFunctions_.register(functionDef.name, apiFunction); 322 this.apiFunctions_.register(functionDef.name, apiFunction);
322 323
323 mod[functionDef.name] = $Function.bind(function() { 324 mod[functionDef.name] = $Function.bind(function() {
324 var args = $Array.slice(arguments); 325 var args = $Array.slice(arguments);
325 if (this.updateArgumentsPreValidate) 326 if (this.updateArgumentsPreValidate)
(...skipping 26 matching lines...) Expand all
352 schemaUtils.validate([retval], [this.definition.returns]); 353 schemaUtils.validate([retval], [this.definition.returns]);
353 return retval; 354 return retval;
354 }, apiFunction); 355 }, apiFunction);
355 }, this); 356 }, this);
356 } 357 }
357 358
358 // Setup Events 359 // Setup Events
359 if (schema.events) { 360 if (schema.events) {
360 $Array.forEach(schema.events, function(eventDef) { 361 $Array.forEach(schema.events, function(eventDef) {
361 if (eventDef.name in mod) { 362 if (eventDef.name in mod) {
362 throw new Error('Event ' + eventDef.name + 363 throw new $Error.self('Event ' + eventDef.name +
363 ' already defined in ' + schema.namespace); 364 ' already defined in ' + schema.namespace);
not at google - send to devlin 2014/08/19 16:45:54 Fix indentation.
364 } 365 }
365 if (!isSchemaNodeSupported(eventDef, platform, manifestVersion)) 366 if (!isSchemaNodeSupported(eventDef, platform, manifestVersion))
366 return; 367 return;
367 368
368 var eventName = schema.namespace + "." + eventDef.name; 369 var eventName = schema.namespace + "." + eventDef.name;
369 if (!GetAvailability(eventName).is_available || 370 if (!GetAvailability(eventName).is_available ||
370 (checkUnprivileged && !isSchemaAccessAllowed(eventDef))) { 371 (checkUnprivileged && !isSchemaAccessAllowed(eventDef))) {
371 return; 372 return;
372 } 373 }
373 374
(...skipping 49 matching lines...) Expand 10 before | Expand all | Expand 10 after
423 // not as an array), so we have to fake calling |new| on the 424 // not as an array), so we have to fake calling |new| on the
424 // constructor. 425 // constructor.
425 value = { __proto__: constructor.prototype }; 426 value = { __proto__: constructor.prototype };
426 $Function.apply(constructor, value, args); 427 $Function.apply(constructor, value, args);
427 // Recursively add properties. 428 // Recursively add properties.
428 addProperties(value, propertyDef); 429 addProperties(value, propertyDef);
429 } else if (type === 'object') { 430 } else if (type === 'object') {
430 // Recursively add properties. 431 // Recursively add properties.
431 addProperties(value, propertyDef); 432 addProperties(value, propertyDef);
432 } else if (type !== 'string') { 433 } else if (type !== 'string') {
433 throw new Error('NOT IMPLEMENTED (extension_api.json error): ' + 434 throw new $Error.self(
435 'NOT IMPLEMENTED (extension_api.json error): ' +
434 'Cannot parse values for type "' + type + '"'); 436 'Cannot parse values for type "' + type + '"');
435 } 437 }
436 m[propertyName] = value; 438 m[propertyName] = value;
437 } 439 }
438 }); 440 });
439 }; 441 };
440 442
441 addProperties(mod, schema); 443 addProperties(mod, schema);
442 444
443 // This generate() call is considered successful if any functions, 445 // This generate() call is considered successful if any functions,
(...skipping 28 matching lines...) Expand all
472 availability.message); 474 availability.message);
473 return; 475 return;
474 } 476 }
475 477
476 this.runHooks_(mod); 478 this.runHooks_(mod);
477 return mod; 479 return mod;
478 } 480 }
479 }; 481 };
480 482
481 exports.Binding = Binding; 483 exports.Binding = Binding;
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698