Thu, 15 Jan 2015 15:59:08 +0100
Implement a real Private Browsing Mode condition by changing the API/ABI;
This solves Tor bug #9701, complying with disk avoidance documented in
https://www.torproject.org/projects/torbrowser/design/#disk-avoidance.
1 /* This Source Code Form is subject to the terms of the Mozilla Public
2 * License, v. 2.0. If a copy of the MPL was not distributed with this
3 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
5 const xpcom = require("sdk/platform/xpcom");
6 const { Cc, Ci, Cm, Cr } = require("chrome");
7 const { isCIDRegistered } = Cm.QueryInterface(Ci.nsIComponentRegistrar);
8 const { Class } = require("sdk/core/heritage");
9 const { Loader } = require("sdk/test/loader");
11 exports['test Unknown implements nsISupports'] = function(assert) {
12 let actual = xpcom.Unknown();
13 assert.equal(actual.QueryInterface(Ci.nsISupports),
14 actual,
15 'component implements nsISupports');
16 };
18 exports['test implement xpcom interfaces'] = function(assert) {
19 let WeakReference = Class({
20 extends: xpcom.Unknown,
21 interfaces: [ 'nsIWeakReference' ],
22 QueryReferent: function() {}
23 });
24 let weakReference = WeakReference()
26 assert.equal(weakReference.QueryInterface(Ci.nsISupports),
27 weakReference,
28 'component implements nsISupports');
29 assert.equal(weakReference.QueryInterface(Ci.nsIWeakReference),
30 weakReference,
31 'component implements specified interface');
33 assert.throws(function() {
34 component.QueryInterface(Ci.nsIObserver);
35 }, "component does not implements interface");
37 let Observer = Class({
38 extends: WeakReference,
39 interfaces: [ 'nsIObserver', 'nsIRequestObserver' ],
40 observe: function() {},
41 onStartRequest: function() {},
42 onStopRequest: function() {}
43 });
44 let observer = Observer()
46 assert.equal(observer.QueryInterface(Ci.nsISupports),
47 observer,
48 'derived component implements nsISupports');
49 assert.equal(observer.QueryInterface(Ci.nsIWeakReference),
50 observer,
51 'derived component implements supers interface');
52 assert.equal(observer.QueryInterface(Ci.nsIObserver),
53 observer.QueryInterface(Ci.nsIRequestObserver),
54 'derived component implements specified interfaces');
55 };
57 exports['test implement factory without contract'] = function(assert) {
58 let actual = xpcom.Factory({
59 get wrappedJSObject() this,
60 });
62 assert.ok(isCIDRegistered(actual.id), 'factory is regiseterd');
63 xpcom.unregister(actual);
64 assert.ok(!isCIDRegistered(actual.id), 'factory is unregistered');
65 };
67 exports['test implement xpcom factory'] = function(assert) {
68 let Component = Class({
69 extends: xpcom.Unknown,
70 interfaces: [ 'nsIObserver' ],
71 get wrappedJSObject() this,
72 observe: function() {}
73 });
75 let factory = xpcom.Factory({
76 register: false,
77 contract: '@jetpack/test/factory;1',
78 Component: Component
79 });
81 assert.ok(!isCIDRegistered(factory.id), 'factory is not registered');
82 xpcom.register(factory);
83 assert.ok(isCIDRegistered(factory.id), 'factory is registered');
85 let actual = Cc[factory.contract].createInstance(Ci.nsIObserver);
87 assert.ok(actual.wrappedJSObject instanceof Component,
88 "createInstance returnes wrapped factory instances");
90 assert.notEqual(Cc[factory.contract].createInstance(Ci.nsIObserver),
91 Cc[factory.contract].createInstance(Ci.nsIObserver),
92 "createInstance returns new instance each time");
93 };
95 exports['test implement xpcom service'] = function(assert) {
96 let actual = xpcom.Service({
97 contract: '@jetpack/test/service;1',
98 register: false,
99 Component: Class({
100 extends: xpcom.Unknown,
101 interfaces: [ 'nsIObserver'],
102 get wrappedJSObject() this,
103 observe: function() {},
104 name: 'my-service'
105 })
106 });
108 assert.ok(!isCIDRegistered(actual.id), 'component is not registered');
109 xpcom.register(actual);
110 assert.ok(isCIDRegistered(actual.id), 'service is regiseterd');
111 assert.ok(Cc[actual.contract].getService(Ci.nsIObserver).observe,
112 'service can be accessed via get service');
113 assert.equal(Cc[actual.contract].getService(Ci.nsIObserver).wrappedJSObject,
114 actual.component,
115 'wrappedJSObject is an actual component');
116 xpcom.unregister(actual);
117 assert.ok(!isCIDRegistered(actual.id), 'service is unregistered');
118 };
121 function testRegister(assert, text) {
123 const service = xpcom.Service({
124 description: 'test about:boop page',
125 contract: '@mozilla.org/network/protocol/about;1?what=boop',
126 register: false,
127 Component: Class({
128 extends: xpcom.Unknown,
129 get wrappedJSObject() this,
130 interfaces: [ 'nsIAboutModule' ],
131 newChannel : function(aURI) {
132 var ios = Cc["@mozilla.org/network/io-service;1"].
133 getService(Ci.nsIIOService);
135 var channel = ios.newChannel(
136 "data:text/plain;charset=utf-8," + text,
137 null,
138 null
139 );
141 channel.originalURI = aURI;
142 return channel;
143 },
144 getURIFlags: function(aURI) {
145 return Ci.nsIAboutModule.ALLOW_SCRIPT;
146 }
147 })
148 });
150 xpcom.register(service);
152 assert.equal(isCIDRegistered(service.id), true);
154 var aboutFactory = xpcom.factoryByContract(service.contract);
155 var about = aboutFactory.createInstance(Ci.nsIAboutModule);
157 var ios = Cc["@mozilla.org/network/io-service;1"].
158 getService(Ci.nsIIOService);
159 assert.equal(
160 about.getURIFlags(ios.newURI("http://foo.com", null, null)),
161 Ci.nsIAboutModule.ALLOW_SCRIPT
162 );
164 var aboutURI = ios.newURI("about:boop", null, null);
165 var channel = ios.newChannelFromURI(aboutURI);
166 var iStream = channel.open();
167 var siStream = Cc['@mozilla.org/scriptableinputstream;1']
168 .createInstance(Ci.nsIScriptableInputStream);
169 siStream.init(iStream);
170 var data = new String();
171 data += siStream.read(-1);
172 siStream.close();
173 iStream.close();
174 assert.equal(data, text);
176 xpcom.unregister(service);
177 assert.equal(isCIDRegistered(service.id), false);
178 }
180 exports["test register"] = function(assert) {
181 testRegister(assert, "hai2u");
182 };
184 exports["test re-register"] = function(assert) {
185 testRegister(assert, "hai2u again");
186 };
188 exports["test unload"] = function(assert) {
189 let loader = Loader(module);
190 let sbxpcom = loader.require("sdk/platform/xpcom");
192 let auto = sbxpcom.Factory({
193 contract: "@mozilla.org/test/auto-unload;1",
194 description: "test auto",
195 name: "auto"
196 });
198 let manual = sbxpcom.Factory({
199 contract: "@mozilla.org/test/manual-unload;1",
200 description: "test manual",
201 register: false,
202 unregister: false,
203 name: "manual"
204 });
206 assert.equal(isCIDRegistered(auto.id), true, 'component registered');
207 assert.equal(isCIDRegistered(manual.id), false, 'component not registered');
209 sbxpcom.register(manual)
210 assert.equal(isCIDRegistered(manual.id), true,
211 'component was automatically registered on first instance');
212 loader.unload();
214 assert.equal(isCIDRegistered(auto.id), false,
215 'component was atumatically unregistered on unload');
216 assert.equal(isCIDRegistered(manual.id), true,
217 'component was not automatically unregistered on unload');
218 sbxpcom.unregister(manual);
219 assert.equal(isCIDRegistered(manual.id), false,
220 'component was manually unregistered on unload');
221 };
223 require("test").run(exports);