michael@0: function run_test() { michael@0: var Cu = Components.utils; michael@0: var epsb = new Cu.Sandbox(["http://example.com", "http://example.org"], { wantExportHelpers: true }); michael@0: var subsb = new Cu.Sandbox("http://example.com", { wantGlobalProperties: ["XMLHttpRequest"] }); michael@0: var subsb2 = new Cu.Sandbox("http://example.com", { wantGlobalProperties: ["XMLHttpRequest"] }); michael@0: var xorigsb = new Cu.Sandbox("http://test.com"); michael@0: michael@0: epsb.subsb = subsb; michael@0: epsb.xorigsb = xorigsb; michael@0: epsb.do_check_true = do_check_true; michael@0: epsb.do_check_eq = do_check_eq; michael@0: epsb.do_check_neq = do_check_neq; michael@0: michael@0: // Exporting should work if prinicipal of the source sandbox michael@0: // subsumes the principal of the target sandbox. michael@0: Cu.evalInSandbox("(" + function() { michael@0: Object.prototype.protoProp = "common"; michael@0: var wasCalled = false; michael@0: var _this = this; michael@0: this.funToExport = function(a, obj, native, mixed) { michael@0: do_check_eq(a, 42); michael@0: do_check_neq(obj, subsb.tobecloned); michael@0: do_check_eq(obj.cloned, "cloned"); michael@0: do_check_eq(obj.protoProp, "common"); michael@0: do_check_eq(native, subsb.native); michael@0: do_check_eq(_this, this); michael@0: do_check_eq(mixed.xrayed, subsb.xrayed); michael@0: do_check_eq(mixed.xrayed2, subsb.xrayed2); michael@0: wasCalled = true; michael@0: }; michael@0: this.checkIfCalled = function() { michael@0: do_check_true(wasCalled); michael@0: wasCalled = false; michael@0: } michael@0: exportFunction(funToExport, subsb, { defineAs: "imported" }); michael@0: }.toSource() + ")()", epsb); michael@0: michael@0: subsb.xrayed = Cu.evalInSandbox("(" + function () { michael@0: return new XMLHttpRequest(); michael@0: }.toSource() + ")()", subsb2); michael@0: michael@0: // Exported function should be able to be call from the michael@0: // target sandbox. Native arguments should be just wrapped michael@0: // every other argument should be cloned. michael@0: Cu.evalInSandbox("(" + function () { michael@0: native = new XMLHttpRequest(); michael@0: xrayed2 = XPCNativeWrapper(new XMLHttpRequest()); michael@0: mixed = { xrayed: xrayed, xrayed2: xrayed2 }; michael@0: tobecloned = { cloned: "cloned" }; michael@0: imported(42,tobecloned, native, mixed); michael@0: }.toSource() + ")()", subsb); michael@0: michael@0: // Apply should work but the |this| argument should not be michael@0: // possible to be changed. michael@0: Cu.evalInSandbox("(" + function() { michael@0: imported.apply("something", [42, tobecloned, native, mixed]); michael@0: }.toSource() + ")()", subsb); michael@0: michael@0: Cu.evalInSandbox("(" + function() { michael@0: checkIfCalled(); michael@0: }.toSource() + ")()", epsb); michael@0: michael@0: // Exporting should throw if princpal of the source sandbox does michael@0: // not subsume the principal of the target. michael@0: Cu.evalInSandbox("(" + function() { michael@0: try{ michael@0: exportFunction(function() {}, this.xorigsb, { defineAs: "denied" }); michael@0: do_check_true(false); michael@0: } catch (e) { michael@0: do_check_true(e.toString().indexOf('Permission denied') > -1); michael@0: } michael@0: }.toSource() + ")()", epsb); michael@0: michael@0: // Let's create an object in the target scope and add privileged michael@0: // function to it as a property. michael@0: Cu.evalInSandbox("(" + function() { michael@0: var newContentObject = createObjectIn(subsb, { defineAs: "importedObject" }); michael@0: exportFunction(funToExport, newContentObject, { defineAs: "privMethod" }); michael@0: }.toSource() + ")()", epsb); michael@0: michael@0: Cu.evalInSandbox("(" + function () { michael@0: importedObject.privMethod(42, tobecloned, native, mixed); michael@0: }.toSource() + ")()", subsb); michael@0: michael@0: Cu.evalInSandbox("(" + function() { michael@0: checkIfCalled(); michael@0: }.toSource() + ")()", epsb); michael@0: michael@0: // exportFunction and createObjectIn should be available from Cu too. michael@0: var newContentObject = Cu.createObjectIn(subsb, { defineAs: "importedObject2" }); michael@0: var wasCalled = false; michael@0: Cu.exportFunction(function(arg) { wasCalled = arg.wasCalled; }, michael@0: newContentObject, { defineAs: "privMethod" }); michael@0: michael@0: Cu.evalInSandbox("(" + function () { michael@0: importedObject2.privMethod({wasCalled: true}); michael@0: }.toSource() + ")()", subsb); michael@0: michael@0: // 3rd argument of exportFunction should be optional. michael@0: Cu.evalInSandbox("(" + function() { michael@0: subsb.imported2 = exportFunction(funToExport, subsb); michael@0: }.toSource() + ")()", epsb); michael@0: michael@0: Cu.evalInSandbox("(" + function () { michael@0: imported2(42, tobecloned, native, mixed); michael@0: }.toSource() + ")()", subsb); michael@0: michael@0: Cu.evalInSandbox("(" + function() { michael@0: checkIfCalled(); michael@0: }.toSource() + ")()", epsb); michael@0: michael@0: do_check_true(wasCalled, true); michael@0: }