blob: 3ea6bd21b4245e67de0c19af4aad424b9391fbd9 (
plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
|
/**
* Any copyright is dedicated to the Public Domain.
* http://creativecommons.org/publicdomain/zero/1.0/
*/
/**
* Test repeatedly setting values that are just under the LocalStorage quota
* limit without yielding control flow in order to verify that the write
* optimizer is present / works. If there was no write optimizer present, the
* IPC message size limit would be exceeded, resulting in a crash.
*/
add_task(async function testSteps() {
const globalLimitKB = 5 * 1024;
// 18 and more iterations would produce an IPC message with size greater than
// 256 MB if write optimizer was not present. This number was determined
// experimentally by running the test with disabled write optimizer.
const numberOfIterations = 18;
const randomStringBlockSize = 65536;
// We need to use a random string because LS internally tries to compress
// values.
function getRandomString(size) {
let crypto = this.window ? this.window.crypto : this.crypto;
let decoder = new TextDecoder("ISO-8859-2");
function getRandomStringBlock(array) {
crypto.getRandomValues(array);
return decoder.decode(array);
}
let string = "";
let quotient = size / randomStringBlockSize;
if (quotient) {
let array = new Uint8Array(randomStringBlockSize);
for (let i = 1; i <= quotient; i++) {
string += getRandomStringBlock(array);
}
}
let remainder = size % randomStringBlockSize;
if (remainder) {
let array = new Uint8Array(remainder);
string += getRandomStringBlock(array);
}
return string;
}
const data = {};
data.key = "foo";
data.value = getRandomString(
globalLimitKB * 1024 -
data.key.length -
numberOfIterations.toString().length
);
info("Setting pref");
// By disabling snapshot reusing, we guarantee that the snapshot will be
// checkpointed once control returns to the event loop.
if (this.window) {
await SpecialPowers.pushPrefEnv({
set: [["dom.storage.snapshot_reusing", false]],
});
} else {
Services.prefs.setBoolPref("dom.storage.snapshot_reusing", false);
}
info("Getting storage");
let storage = getLocalStorage();
info("Adding/updating item");
for (var i = 0; i < numberOfIterations; i++) {
storage.setItem(data.key, data.value + i);
}
info("Returning to event loop");
await returnToEventLoop();
ok(!storage.hasSnapshot, "Snapshot successfully finished");
});
|