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