From 78acdb77ee7c9b4403bc955a40517f5b0a642ba9 Mon Sep 17 00:00:00 2001 From: Jordan Santell Date: Wed, 11 Feb 2015 16:15:00 -0500 Subject: [PATCH] Bug 1130901 - Export patched methods in call-watcher actor with Cu.exportFunctions so that Function.prototype methods can be called without permission errors. r=vp --- .../devtools/webaudioeditor/test/browser.ini | 25 ++++++++---------- .../test/browser_callwatcher-01.js | 26 +++++++++++++++++++ .../webaudioeditor/test/doc_bug_1130901.html | 22 ++++++++++++++++ .../devtools/server/actors/call-watcher.js | 21 ++++++++------- toolkit/devtools/server/actors/webaudio.js | 17 ++++++------ 5 files changed, 78 insertions(+), 33 deletions(-) create mode 100644 browser/devtools/webaudioeditor/test/browser_callwatcher-01.js create mode 100644 browser/devtools/webaudioeditor/test/doc_bug_1130901.html diff --git a/browser/devtools/webaudioeditor/test/browser.ini b/browser/devtools/webaudioeditor/test/browser.ini index 4090858f844f..69afc93ec23c 100644 --- a/browser/devtools/webaudioeditor/test/browser.ini +++ b/browser/devtools/webaudioeditor/test/browser.ini @@ -12,6 +12,7 @@ support-files = doc_iframe-context.html doc_automation.html doc_bug_1125817.html + doc_bug_1130901.html 440hz_sine.ogg head.js @@ -29,21 +30,17 @@ skip-if = true # bug 1092571 [browser_audionode-actor-get-automation-data-01.js] [browser_audionode-actor-get-automation-data-02.js] [browser_audionode-actor-get-automation-data-03.js] +[browser_callwatcher-01.js] [browser_webaudio-actor-simple.js] [browser_webaudio-actor-destroy-node.js] [browser_webaudio-actor-connect-param.js] [browser_webaudio-actor-automation-event.js] -[browser_wa_destroy-node-01.js] - -[browser_wa_first-run.js] -[browser_wa_reset-01.js] -[browser_wa_reset-02.js] -[browser_wa_reset-03.js] -[browser_wa_reset-04.js] -[browser_wa_navigate.js] +[browser_wa_automation-view-01.js] +[browser_wa_automation-view-02.js] [browser_wa_controller-01.js] - +[browser_wa_destroy-node-01.js] +[browser_wa_first-run.js] [browser_wa_graph-click.js] [browser_wa_graph-markers.js] [browser_wa_graph-render-01.js] @@ -54,11 +51,10 @@ skip-if = true # bug 1092571 skip-if = true # bug 1092571 [browser_wa_graph-selected.js] [browser_wa_graph-zoom.js] - [browser_wa_inspector.js] [browser_wa_inspector-toggle.js] [browser_wa_inspector-bypass-01.js] - +[browser_wa_navigate.js] [browser_wa_properties-view.js] [browser_wa_properties-view-edit-01.js] skip-if = true # bug 1010423 @@ -67,6 +63,7 @@ skip-if = true # bug 1010423 [browser_wa_properties-view-media-nodes.js] [browser_wa_properties-view-params.js] [browser_wa_properties-view-params-objects.js] - -[browser_wa_automation-view-01.js] -[browser_wa_automation-view-02.js] +[browser_wa_reset-01.js] +[browser_wa_reset-02.js] +[browser_wa_reset-03.js] +[browser_wa_reset-04.js] diff --git a/browser/devtools/webaudioeditor/test/browser_callwatcher-01.js b/browser/devtools/webaudioeditor/test/browser_callwatcher-01.js new file mode 100644 index 000000000000..a3dc801c6264 --- /dev/null +++ b/browser/devtools/webaudioeditor/test/browser_callwatcher-01.js @@ -0,0 +1,26 @@ +/* Any copyright is dedicated to the Public Domain. + http://creativecommons.org/publicdomain/zero/1.0/ */ + +/** + * Bug 1130901 + * Tests to ensure that calling call/apply on methods wrapped + * via CallWatcher do not throw a security permissions error: + * "Error: Permission denied to access property 'call'" + */ + +const BUG_1130901_URL = EXAMPLE_URL + "doc_bug_1130901.html"; + +add_task(function*() { + let { target, panel } = yield initWebAudioEditor(BUG_1130901_URL); + let { panelWin } = panel; + let { gFront, $, $$, EVENTS, gAudioNodes } = panelWin; + + reload(target); + + yield waitForGraphRendered(panelWin, 3, 0); + + ok(true, "Successfully created a node from AudioContext via `call`."); + ok(true, "Successfully created a node from AudioContext via `apply`."); + + yield teardown(target); +}); diff --git a/browser/devtools/webaudioeditor/test/doc_bug_1130901.html b/browser/devtools/webaudioeditor/test/doc_bug_1130901.html new file mode 100644 index 000000000000..1ce1ebf5514a --- /dev/null +++ b/browser/devtools/webaudioeditor/test/doc_bug_1130901.html @@ -0,0 +1,22 @@ + + + + + + + Web Audio Editor test page + + + + + + + + diff --git a/toolkit/devtools/server/actors/call-watcher.js b/toolkit/devtools/server/actors/call-watcher.js index 990858480d73..e1207e4441f1 100644 --- a/toolkit/devtools/server/actors/call-watcher.js +++ b/toolkit/devtools/server/actors/call-watcher.js @@ -416,17 +416,18 @@ let CallWatcherActor = exports.CallWatcherActor = protocol.ActorClass({ // the arguments array is inaccessible to it. Get Xrays back. let originalFunc = Cu.unwaiveXrays(target[name]); - Object.defineProperty(target, name, { - value: function(...args) { - let result = Cu.waiveXrays(originalFunc.apply(this, args)); + Cu.exportFunction(function(...args) { + let result = Cu.waiveXrays(originalFunc.apply(this, args)); - if (self._recording) { - let stack = getStack(name); - let type = CallWatcherFront.METHOD_FUNCTION; - callback(unwrappedWindow, global, this, type, name, stack, args, result); - } - return result; - }, + if (self._recording) { + let stack = getStack(name); + let type = CallWatcherFront.METHOD_FUNCTION; + callback(unwrappedWindow, global, this, type, name, stack, args, result); + } + return result; + }, target, { defineAs: name }); + + Object.defineProperty(target, name, { configurable: descriptor.configurable, enumerable: descriptor.enumerable, writable: true diff --git a/toolkit/devtools/server/actors/webaudio.js b/toolkit/devtools/server/actors/webaudio.js index b17db9ea1f0e..c3eb646eb775 100644 --- a/toolkit/devtools/server/actors/webaudio.js +++ b/toolkit/devtools/server/actors/webaudio.js @@ -523,24 +523,23 @@ let AudioNodeActor = exports.AudioNodeActor = protocol.ActorClass({ // double-casting will only occur when starting from `addAutomationEvent`, // which is only used in tests. let param = XPCNativeWrapper.unwrap(node[paramName]); + let contentGlobal = Cu.getGlobalForObject(param); + let contentArgs = Cu.cloneInto(args, contentGlobal); // If calling `setValueCurveAtTime`, the first argument // is a Float32Array, which won't be able to be serialized // over the protocol. Cast a normal array to a Float32Array here. if (eventName === "setValueCurveAtTime") { - let contentGlobal = Cu.getGlobalForObject(param); - // Since we cannot iterate over and modify the actual Float32Array - // in the content, we'll have to pass in an array to the constructor - // from the same context, since we can iterate over non-TypedArrays. - let contentArray = copyInto(new contentGlobal.Array(), args[0]); - // Create a Float32Array from the content, seeding with an array // from the same scope. - let curve = new contentGlobal.Float32Array(contentArray); - args[0] = curve; + let curve = new contentGlobal.Float32Array(contentArgs[0]); + contentArgs[0] = curve; } - param[eventName].apply(param, args); + // Apply the args back from the content scope, which is necessary + // due to the method wrapping changing in bug 1130901 to be exported + // directly to the content scope. + param[eventName].apply(param, contentArgs); } catch (e) { return constructError(e); }