From e6570d67085125509347bbc3a5adfc2dae1462ba Mon Sep 17 00:00:00 2001 From: Kris Maglione Date: Sun, 6 Nov 2016 18:08:46 -0800 Subject: [PATCH] Bug 1303798: Correctly propagate addListener errors from WebRequest.jsm to extension. r=mixedpuppy MozReview-Commit-ID: BTTNaaAdBs5 --HG-- extra : rebase_source : 585e886fd44d689fea68e49b92e6bb1d29868924 --- toolkit/components/extensions/ExtensionUtils.jsm | 15 +++++++++++++-- .../mochitest/test_ext_webrequest_upload.html | 16 ++++++++++++---- toolkit/modules/addons/WebRequest.jsm | 6 +++++- 3 files changed, 30 insertions(+), 7 deletions(-) diff --git a/toolkit/components/extensions/ExtensionUtils.jsm b/toolkit/components/extensions/ExtensionUtils.jsm index ff377cb16435..4f1b7e229ac4 100644 --- a/toolkit/components/extensions/ExtensionUtils.jsm +++ b/toolkit/components/extensions/ExtensionUtils.jsm @@ -50,6 +50,12 @@ function getConsole() { XPCOMUtils.defineLazyGetter(this, "console", getConsole); +/** + * An Error subclass for which complete error messages are always passed + * to extensions, rather than being interpreted as an unknown error. + */ +class ExtensionError extends Error {} + function filterStack(error) { return String(error.stack).replace(/(^.*(Task\.jsm|Promise-backend\.js).*\n)+/gm, "\n"); } @@ -368,7 +374,7 @@ class BaseContext { return error; } let message; - if (instanceOf(error, "Object")) { + if (instanceOf(error, "Object") || error instanceof ExtensionError) { message = error.message; } else if (typeof error == "object" && this.principal.subsumes(Cu.getObjectPrincipal(error))) { @@ -1748,7 +1754,11 @@ class LocalAPIImplementation extends SchemaAPIInterface { } addListener(listener, args) { - this.pathObj[this.name].addListener.call(null, listener, ...args); + try { + this.pathObj[this.name].addListener.call(null, listener, ...args); + } catch (e) { + throw this.context.normalizeError(e); + } } hasListener(listener) { @@ -2236,6 +2246,7 @@ this.ExtensionUtils = { DefaultWeakMap, EventEmitter, EventManager, + ExtensionError, IconDetails, LocalAPIImplementation, LocaleData, diff --git a/toolkit/components/extensions/test/mochitest/test_ext_webrequest_upload.html b/toolkit/components/extensions/test/mochitest/test_ext_webrequest_upload.html index 669f1cb6819a..045a4fd8b9ff 100644 --- a/toolkit/components/extensions/test/mochitest/test_ext_webrequest_upload.html +++ b/toolkit/components/extensions/test/mochitest/test_ext_webrequest_upload.html @@ -72,10 +72,12 @@ function background() { "onCompleted": [{urls: [""]}, ["responseHeaders"]], }; + let requestBodySupported = true; + function onUpload(details) { let url = new URL(details.url); let upload = url.searchParams.get("upload"); - if (!upload) { + if (!upload || !requestBodySupported) { return; } let requestBody = details.requestBody; @@ -113,12 +115,18 @@ function background() { browser.webRequest[name].addListener( listener.bind(null, name), ...args); } catch (e) { + browser.test.assertTrue(/\brequestBody\b/.test(e.message), + "Request body is unsupported"); + // requestBody is disabled in release builds if (!/\brequestBody\b/.test(e.message)) { - args.pop(); - browser.webRequest[name].addListener( - listener.bind(null, name), ...args); + throw e; } + + requestBodySupported = false; + args.pop(); + browser.webRequest[name].addListener( + listener.bind(null, name), ...args); } } } diff --git a/toolkit/modules/addons/WebRequest.jsm b/toolkit/modules/addons/WebRequest.jsm index 89deefbae8c0..f2afdb3d542c 100644 --- a/toolkit/modules/addons/WebRequest.jsm +++ b/toolkit/modules/addons/WebRequest.jsm @@ -22,11 +22,15 @@ XPCOMUtils.defineLazyModuleGetter(this, "AppConstants", "resource://gre/modules/AppConstants.jsm"); XPCOMUtils.defineLazyModuleGetter(this, "BrowserUtils", "resource://gre/modules/BrowserUtils.jsm"); +XPCOMUtils.defineLazyModuleGetter(this, "ExtensionUtils", + "resource://gre/modules/ExtensionUtils.jsm"); XPCOMUtils.defineLazyModuleGetter(this, "WebRequestCommon", "resource://gre/modules/WebRequestCommon.jsm"); XPCOMUtils.defineLazyModuleGetter(this, "WebRequestUpload", "resource://gre/modules/WebRequestUpload.jsm"); +XPCOMUtils.defineLazyGetter(this, "ExtensionError", () => ExtensionUtils.ExtensionError); + function attachToChannel(channel, key, data) { if (channel instanceof Ci.nsIWritablePropertyBag2) { let wrapper = {wrappedJSObject: data}; @@ -80,7 +84,7 @@ function parseExtra(extra, allowed = []) { if (extra) { for (let ex of extra) { if (allowed.indexOf(ex) == -1) { - throw new Error(`Invalid option ${ex}`); + throw new ExtensionError(`Invalid option ${ex}`); } } }