Sat, 03 Jan 2015 20:18:00 +0100
Conditionally enable double key logic according to:
private browsing mode or privacy.thirdparty.isolate preference and
implement in GetCookieStringCommon and FindCookie where it counts...
With some reservations of how to convince FindCookie users to test
condition and pass a nullptr when disabling double key logic.
1 const Cu = Components.utils;
2 Cu.import("resource://gre/modules/Services.jsm");
3 let tempScope = {};
4 Cu.import("resource://gre/modules/devtools/dbg-client.jsm", tempScope);
5 Cu.import("resource://gre/modules/devtools/dbg-server.jsm", tempScope);
6 Cu.import("resource://gre/modules/Promise.jsm", tempScope);
7 let {DebuggerServer, DebuggerClient, Promise} = tempScope;
8 tempScope = null;
10 const {StorageFront} = require("devtools/server/actors/storage");
11 let gFront, gWindow;
13 const beforeReload = {
14 cookies: {
15 "test1.example.org": ["c1", "cs2", "c3", "uc1"],
16 "sectest1.example.org": ["uc1", "cs2"]
17 },
18 localStorage: {
19 "http://test1.example.org": ["ls1", "ls2"],
20 "http://sectest1.example.org": ["iframe-u-ls1"]
21 },
22 sessionStorage: {
23 "http://test1.example.org": ["ss1"],
24 "http://sectest1.example.org": ["iframe-u-ss1", "iframe-u-ss2"]
25 },
26 indexedDB: {
27 "http://test1.example.org": [
28 JSON.stringify(["idb1", "obj1"]),
29 JSON.stringify(["idb1", "obj2"]),
30 JSON.stringify(["idb2", "obj3"]),
31 ],
32 "http://sectest1.example.org": []
33 }
34 };
36 function finishTests(client) {
37 // Cleanup so that indexed db created from this test do not interfere next ones
39 /**
40 * This method iterates over iframes in a window and clears the indexed db
41 * created by this test.
42 */
43 let clearIDB = (w, i, c) => {
44 if (w[i] && w[i].clear) {
45 w[i].clearIterator = w[i].clear(() => clearIDB(w, i + 1, c));
46 w[i].clearIterator.next();
47 }
48 else if (w[i] && w[i + 1]) {
49 clearIDB(w, i + 1, c);
50 }
51 else {
52 c();
53 }
54 };
56 let closeConnection = () => {
57 // Forcing GC/CC to get rid of docshells and windows created by this test.
58 forceCollections();
59 client.close(() => {
60 forceCollections();
61 DebuggerServer.destroy();
62 forceCollections();
63 gFront = gWindow = DebuggerClient = DebuggerServer = null;
64 finish();
65 });
66 }
67 gWindow.clearIterator = gWindow.clear(() => {
68 clearIDB(gWindow, 0, closeConnection);
69 });
70 gWindow.clearIterator.next();
71 }
73 function testStores(data, client) {
74 testWindowsBeforeReload(data);
75 testReload().then(() =>
76 testAddIframe()).then(() =>
77 testRemoveIframe()).then(() =>
78 finishTests(client));
79 }
81 function testWindowsBeforeReload(data) {
82 for (let storageType in beforeReload) {
83 ok(data[storageType], storageType + " storage actor is present");
84 is(Object.keys(data[storageType].hosts).length,
85 Object.keys(beforeReload[storageType]).length,
86 "Number of hosts for " + storageType + "match");
87 for (let host in beforeReload[storageType]) {
88 ok(data[storageType].hosts[host], "Host " + host + " is present");
89 }
90 }
91 }
93 function markOutMatched(toBeEmptied, data, deleted) {
94 if (!Object.keys(toBeEmptied).length) {
95 info("Object empty")
96 return;
97 }
98 ok(Object.keys(data).length,
99 "Atleast some storage types should be present in deleted");
100 for (let storageType in toBeEmptied) {
101 if (!data[storageType]) {
102 continue;
103 }
104 info("Testing for " + storageType);
105 for (let host in data[storageType]) {
106 ok(toBeEmptied[storageType][host], "Host " + host + " found");
107 if (!deleted) {
108 for (let item of data[storageType][host]) {
109 let index = toBeEmptied[storageType][host].indexOf(item);
110 ok(index > -1, "Item found - " + item);
111 if (index > -1) {
112 toBeEmptied[storageType][host].splice(index, 1);
113 }
114 }
115 if (!toBeEmptied[storageType][host].length) {
116 delete toBeEmptied[storageType][host];
117 }
118 }
119 else {
120 delete toBeEmptied[storageType][host];
121 }
122 }
123 if (!Object.keys(toBeEmptied[storageType]).length) {
124 delete toBeEmptied[storageType];
125 }
126 }
127 }
129 function testReload() {
130 info("Testing if reload works properly");
132 let shouldBeEmptyFirst = Cu.cloneInto(beforeReload, {});
133 let shouldBeEmptyLast = Cu.cloneInto(beforeReload, {});
134 let reloaded = Promise.defer();
136 let onStoresUpdate = data => {
137 info("in stores update of testReload");
138 // This might be second time stores update is happening, in which case,
139 // data.deleted will be null.
140 // OR.. This might be the first time on a super slow machine where both
141 // data.deleted and data.added is missing in the first update.
142 if (data.deleted) {
143 markOutMatched(shouldBeEmptyFirst, data.deleted, true);
144 }
146 if (!Object.keys(shouldBeEmptyFirst).length) {
147 info("shouldBeEmptyFirst is empty now");
148 }
150 // stores-update call might not have data.added for the first time on slow
151 // machines, in which case, data.added will be null
152 if (data.added) {
153 markOutMatched(shouldBeEmptyLast, data.added);
154 }
156 if (!Object.keys(shouldBeEmptyLast).length) {
157 info("Everything to be received is received.");
158 endTestReloaded();
159 }
160 };
162 let endTestReloaded = () => {
163 gFront.off("stores-update", onStoresUpdate);
164 reloaded.resolve();
165 };
167 gFront.on("stores-update", onStoresUpdate);
169 content.location.reload();
170 return reloaded.promise;
171 }
173 function testAddIframe() {
174 info("Testing if new iframe addition works properly");
175 let reloaded = Promise.defer();
177 let shouldBeEmpty = {
178 localStorage: {
179 "https://sectest1.example.org": ["iframe-s-ls1"]
180 },
181 sessionStorage: {
182 "https://sectest1.example.org": ["iframe-s-ss1"]
183 },
184 cookies: {
185 "sectest1.example.org": ["sc1"]
186 },
187 indexedDB: {
188 // empty because indexed db creation happens after the page load, so at
189 // the time of window-ready, there was no indexed db present.
190 "https://sectest1.example.org": []
191 }
192 };
194 let onStoresUpdate = data => {
195 info("checking if the hosts list is correct for this iframe addition");
197 markOutMatched(shouldBeEmpty, data.added);
199 ok(!data.changed || !data.changed.cookies ||
200 !data.changed.cookies["https://sectest1.example.org"],
201 "Nothing got changed for cookies");
202 ok(!data.changed || !data.changed.localStorage ||
203 !data.changed.localStorage["https://sectest1.example.org"],
204 "Nothing got changed for local storage");
205 ok(!data.changed || !data.changed.sessionStorage ||
206 !data.changed.sessionStorage["https://sectest1.example.org"],
207 "Nothing got changed for session storage");
208 ok(!data.changed || !data.changed.indexedDB ||
209 !data.changed.indexedDB["https://sectest1.example.org"],
210 "Nothing got changed for indexed db");
212 ok(!data.deleted || !data.deleted.cookies ||
213 !data.deleted.cookies["https://sectest1.example.org"],
214 "Nothing got deleted for cookies");
215 ok(!data.deleted || !data.deleted.localStorage ||
216 !data.deleted.localStorage["https://sectest1.example.org"],
217 "Nothing got deleted for local storage");
218 ok(!data.deleted || !data.deleted.sessionStorage ||
219 !data.deleted.sessionStorage["https://sectest1.example.org"],
220 "Nothing got deleted for session storage");
221 ok(!data.deleted || !data.deleted.indexedDB ||
222 !data.deleted.indexedDB["https://sectest1.example.org"],
223 "Nothing got deleted for indexed db");
225 if (!Object.keys(shouldBeEmpty).length) {
226 info("Everything to be received is received.");
227 endTestReloaded();
228 }
229 };
231 let endTestReloaded = () => {
232 gFront.off("stores-update", onStoresUpdate);
233 reloaded.resolve();
234 };
236 gFront.on("stores-update", onStoresUpdate);
238 let iframe = content.document.createElement("iframe");
239 iframe.src = ALT_DOMAIN_SECURED + "storage-secured-iframe.html";
240 content.document.querySelector("body").appendChild(iframe);
241 return reloaded.promise;
242 }
244 function testRemoveIframe() {
245 info("Testing if iframe removal works properly");
246 let reloaded = Promise.defer();
248 let shouldBeEmpty = {
249 localStorage: {
250 "http://sectest1.example.org": []
251 },
252 sessionStorage: {
253 "http://sectest1.example.org": []
254 }
255 };
257 let onStoresUpdate = data => {
258 info("checking if the hosts list is correct for this iframe deletion");
260 markOutMatched(shouldBeEmpty, data.deleted, true);
262 ok(!data.deleted.cookies || !data.deleted.cookies["sectest1.example.org"],
263 "Nothing got deleted for Cookies as the same hostname is still present");
265 ok(!data.changed || !data.changed.cookies ||
266 !data.changed.cookies["http://sectest1.example.org"],
267 "Nothing got changed for cookies");
268 ok(!data.changed || !data.changed.localStorage ||
269 !data.changed.localStorage["http://sectest1.example.org"],
270 "Nothing got changed for local storage");
271 ok(!data.changed || !data.changed.sessionStorage ||
272 !data.changed.sessionStorage["http://sectest1.example.org"],
273 "Nothing got changed for session storage");
275 ok(!data.added || !data.added.cookies ||
276 !data.added.cookies["http://sectest1.example.org"],
277 "Nothing got added for cookies");
278 ok(!data.added || !data.added.localStorage ||
279 !data.added.localStorage["http://sectest1.example.org"],
280 "Nothing got added for local storage");
281 ok(!data.added || !data.added.sessionStorage ||
282 !data.added.sessionStorage["http://sectest1.example.org"],
283 "Nothing got added for session storage");
285 if (!Object.keys(shouldBeEmpty).length) {
286 info("Everything to be received is received.");
287 endTestReloaded();
288 }
289 };
291 let endTestReloaded = () => {
292 gFront.off("stores-update", onStoresUpdate);
293 reloaded.resolve();
294 };
296 gFront.on("stores-update", onStoresUpdate);
298 for (let iframe of content.document.querySelectorAll("iframe")) {
299 if (iframe.src.startsWith("http:")) {
300 iframe.remove();
301 break;
302 }
303 }
304 return reloaded.promise;
305 }
307 function test() {
308 waitForExplicitFinish();
309 addTab(MAIN_DOMAIN + "storage-dynamic-windows.html", function(doc) {
310 try {
311 // Sometimes debugger server does not get destroyed correctly by previous
312 // tests.
313 DebuggerServer.destroy();
314 } catch (ex) { }
315 DebuggerServer.init(function () { return true; });
316 DebuggerServer.addBrowserActors();
318 let createConnection = () => {
319 let client = new DebuggerClient(DebuggerServer.connectPipe());
320 client.connect(function onConnect() {
321 client.listTabs(function onListTabs(aResponse) {
322 let form = aResponse.tabs[aResponse.selected];
323 gFront = StorageFront(client, form);
325 gFront.listStores().then(data => testStores(data, client));
326 });
327 });
328 };
330 /**
331 * This method iterates over iframes in a window and setups the indexed db
332 * required for this test.
333 */
334 let setupIDBInFrames = (w, i, c) => {
335 if (w[i] && w[i].idbGenerator) {
336 w[i].setupIDB = w[i].idbGenerator(() => setupIDBInFrames(w, i + 1, c));
337 w[i].setupIDB.next();
338 }
339 else if (w[i] && w[i + 1]) {
340 setupIDBInFrames(w, i + 1, c);
341 }
342 else {
343 c();
344 }
345 };
346 // Setup the indexed db in main window.
347 gWindow = doc.defaultView.wrappedJSObject;
348 gWindow.setupIDB = gWindow.idbGenerator(() => {
349 setupIDBInFrames(gWindow, 0, createConnection);
350 });
351 gWindow.setupIDB.next();
352 });
353 }