Backed out changeset 713114c0331a (bug 1938707) by developer request CLOSED TREE
[gecko.git] / js / xpconnect / tests / unit / test_exportFunction.js
bloba7b2ca80564a00a0353b8f54799c2a786a5f8bb6
1 function run_test() {
2   var epsb = new Cu.Sandbox(["http://example.com", "http://example.org"], { wantExportHelpers: true });
3   var subsb = new Cu.Sandbox("http://example.com", { wantGlobalProperties: ["XMLHttpRequest"] });
4   var subsb2 = new Cu.Sandbox("http://example.com", { wantGlobalProperties: ["XMLHttpRequest"] });
5   var xorigsb = new Cu.Sandbox("http://test.com", { wantGlobalProperties: ["XMLHttpRequest"] });
7   epsb.subsb = subsb;
8   epsb.xorigsb = xorigsb;
9   epsb.ok = ok;
10   epsb.equal = equal;
11   subsb.ok = ok;
12   subsb.equal = equal;
14   // Exporting should work if prinicipal of the source sandbox
15   // subsumes the principal of the target sandbox.
16   Cu.evalInSandbox("(" + function() {
17     var wasCalled = false;
18     this.funToExport = function(expectedThis, a, obj, native, mixed, callback) {
19       equal(arguments.callee.length, 6);
20       equal(a, 42);
21       equal(obj, subsb.tobecloned);
22       equal(obj.cloned, "cloned");
23       equal(native, subsb.native);
24       equal(expectedThis, this);
25       equal(mixed.xrayed, subsb.xrayed);
26       equal(mixed.xrayed2, subsb.xrayed2);
27       if (typeof callback == 'function') {
28         equal(typeof subsb.callback, 'function');
29         equal(callback, subsb.callback);
30         callback();
31       }
32       wasCalled = true;
33     };
34     this.checkIfCalled = function() {
35       ok(wasCalled);
36       wasCalled = false;
37     }
38     exportFunction(funToExport, subsb, { defineAs: "imported", allowCallbacks: true });
39     exportFunction((x) => x, subsb, { defineAs: "echoAllowXO", allowCallbacks: true, allowCrossOriginArguments: true });
40   }.toSource() + ")()", epsb);
42   subsb.xrayed = Cu.evalInSandbox("(" + function () {
43       return new XMLHttpRequest();
44   }.toSource() + ")()", subsb2);
46   // Exported function should be able to be call from the
47   // target sandbox. Native arguments should be just wrapped
48   // every other argument should be cloned.
49   Cu.evalInSandbox("(" + function () {
50     native = new XMLHttpRequest();
51     xrayed2 = XPCNativeWrapper(new XMLHttpRequest());
52     mixed = { xrayed: xrayed, xrayed2: xrayed2 };
53     tobecloned = { cloned: "cloned" };
54     invokedCallback = false;
55     callback = function() { invokedCallback = true; };
56     imported(this, 42, tobecloned, native, mixed, callback);
57     equal(imported.length, 6);
58     ok(invokedCallback);
59   }.toSource() + ")()", subsb);
61   // Invoking an exported function with cross-origin arguments should throw.
62   subsb.xoNative = Cu.evalInSandbox('new XMLHttpRequest()', xorigsb);
63   try {
64     Cu.evalInSandbox('imported(this, xoNative)', subsb);
65     Assert.ok(false);
66   } catch (e) {
67     Assert.ok(/denied|insecure/.test(e));
68   }
70   // Callers can opt-out of the above.
71   subsb.xoNative = Cu.evalInSandbox('new XMLHttpRequest()', xorigsb);
72   try {
73     Assert.equal(Cu.evalInSandbox('echoAllowXO(xoNative)', subsb), subsb.xoNative);
74     Assert.ok(true);
75   } catch (e) {
76     Assert.ok(false);
77   }
79   // Apply should work and |this| should carry over appropriately.
80   Cu.evalInSandbox("(" + function() {
81     var someThis = {};
82     imported.apply(someThis, [someThis, 42, tobecloned, native, mixed]);
83   }.toSource() + ")()", subsb);
85   Cu.evalInSandbox("(" + function() {
86     checkIfCalled();
87   }.toSource() + ")()", epsb);
89   // Exporting should throw if principal of the source sandbox does
90   // not subsume the principal of the target.
91   Cu.evalInSandbox("(" + function() {
92     try{
93       exportFunction(function() {}, this.xorigsb, { defineAs: "denied" });
94       ok(false);
95     } catch (e) {
96       ok(e.toString().indexOf('Permission denied') > -1);
97     }
98   }.toSource() + ")()", epsb);
100   // Exporting should throw if the principal of the source sandbox does
101   // not subsume the principal of the function.
102   epsb.xo_function = new xorigsb.Function();
103   Cu.evalInSandbox("(" + function() {
104     try{
105       exportFunction(xo_function, this.subsb, { defineAs: "denied" });
106       ok(false);
107     } catch (e) {
108       dump('Exception: ' + e);
109       ok(e.toString().indexOf('Permission denied') > -1);
110     }
111   }.toSource() + ")()", epsb);
113   // Let's create an object in the target scope and add privileged
114   // function to it as a property.
115   Cu.evalInSandbox("(" + function() {
116     var newContentObject = createObjectIn(subsb, { defineAs: "importedObject" });
117     exportFunction(funToExport, newContentObject, { defineAs: "privMethod" });
118   }.toSource() + ")()", epsb);
120   Cu.evalInSandbox("(" + function () {
121     importedObject.privMethod(importedObject, 42, tobecloned, native, mixed);
122   }.toSource() + ")()", subsb);
124   Cu.evalInSandbox("(" + function() {
125     checkIfCalled();
126   }.toSource() + ")()", epsb);
128   // exportFunction and createObjectIn should be available from Cu too.
129   var newContentObject = Cu.createObjectIn(subsb, { defineAs: "importedObject2" });
130   var wasCalled = false;
131   Cu.exportFunction(function(arg) { wasCalled = arg.wasCalled; },
132                     newContentObject, { defineAs: "privMethod" });
134   Cu.evalInSandbox("(" + function () {
135     importedObject2.privMethod({wasCalled: true});
136   }.toSource() + ")()", subsb);
138   // 3rd argument of exportFunction should be optional.
139   Cu.evalInSandbox("(" + function() {
140     subsb.imported2 = exportFunction(funToExport, subsb);
141   }.toSource() + ")()", epsb);
143   Cu.evalInSandbox("(" + function () {
144     imported2(this, 42, tobecloned, native, mixed);
145   }.toSource() + ")()", subsb);
147   Cu.evalInSandbox("(" + function() {
148     checkIfCalled();
149   }.toSource() + ")()", epsb);
151   Assert.ok(wasCalled);