-
Notifications
You must be signed in to change notification settings - Fork 0
/
runtime_leaks.js
116 lines (102 loc) · 3.22 KB
/
runtime_leaks.js
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
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
const alterText = id => {
const node = document.getElementById(id);
node.innerText = node.innerText.replace("assuming no", "assuming yes");
};
const getConsoleAPICalledTest = (caseId, callback) => {
// Runtime.consoleAPICalled (Runtime.RemoteObject)
return async () => {
// Sample code here targeting isArrayLike from v8/src/inspector/value-mirror.cc
const a = {};
a.splice = () => null;
Object.defineProperty(a, "length", {
get: () => {
callback();
return 10 * caseId;
}
});
console.log(a);
};
};
const getExceptionThrownTest = (caseId, callback) => {
// Runtime.exceptionThrown (Runtime.ExceptionDetails)
return async () => {
// Sample code here targeting descriptionForError from v8/src/inspector/value-mirror.cc
const err = new Error("foo" + caseId);
Object.defineProperty(err, "stack", {
get: () => {
callback();
return "bar" + caseId;
},
});
throw err;
};
};
// Test 1
getConsoleAPICalledTest(1, () => { alterText("result1"); })();
// Test 2
getExceptionThrownTest(2, () => { alterText("result2"); })();
const wrapWithWorker = (caseId, test) => {
return async () => {
const payload = `
const caseId = ${caseId};
const callback = () => { postMessage("result${caseId}"); };
(${test().toString()})();
`;
const url = URL.createObjectURL(new Blob([payload], { type: "text/javascript" }));
const worker = new Worker(url);
worker.addEventListener('message', event => {
alterText(event.data);
});
};
};
// Test 3
wrapWithWorker(3, getConsoleAPICalledTest)();
// Test 4
wrapWithWorker(4, getExceptionThrownTest)();
const wrapWithSharedWorker = (caseId, test) => {
return async () => {
const payload = `
const p = new Promise(resolve => {
const caseId = ${caseId};
const callback = () => { resolve("result${caseId}"); };
(${test().toString()})();
});
onconnect = async event => {
event.ports[0].postMessage(await p);
};
`;
const url = `data:text/javascript;base64,${btoa(payload)}`;
const worker = new SharedWorker(url);
worker.port.start();
worker.port.addEventListener('message', event => {
alterText(event.data);
});
};
};
// Test 5
wrapWithSharedWorker(5, getConsoleAPICalledTest)();
// Test 6
wrapWithSharedWorker(6, getExceptionThrownTest)();
const wrapWithIframe = (caseId, test) => {
return async () => {
const payload = `
<script>
const caseId = ${caseId};
const callback = () => { parent.postMessage("result${caseId}", "*"); };
(${test().toString()})();
<\/script>
`;
const url = URL.createObjectURL(new Blob([payload], { type: "text/html" }));
addEventListener('message', event => {
if (event.data == `result${caseId}`)
alterText(event.data);
});
const iframe = document.createElement("iframe");
iframe.setAttribute("src", url);
document.body.appendChild(iframe);
};
};
// Test 7
wrapWithIframe(7, getConsoleAPICalledTest)();
// Test 8
wrapWithIframe(8, getExceptionThrownTest)();