This commit is contained in:
@@ -0,0 +1,123 @@
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<meta http-equiv="Content-Security-Policy" content="
|
||||
default-src 'none';
|
||||
child-src 'self' data: blob:;
|
||||
script-src 'self' 'unsafe-eval' 'sha256-75NYUUvf+5++1WbfCZOV3PSWxBhONpaxwx+mkOFRv/Y=' https:;
|
||||
connect-src 'self' https: wss: http://localhost:* http://127.0.0.1:* ws://localhost:* ws://127.0.0.1:*;"/>
|
||||
</head>
|
||||
<body>
|
||||
<script>
|
||||
(function () {
|
||||
const searchParams = new URL(document.location.href).searchParams;
|
||||
const vscodeWebWorkerExtHostId = searchParams.get('vscodeWebWorkerExtHostId') || '';
|
||||
const name = searchParams.get('debugged') ? 'DebugWorkerExtensionHost' : 'WorkerExtensionHost';
|
||||
const parentOrigin = searchParams.get('parentOrigin') || window.origin;
|
||||
const salt = searchParams.get('salt');
|
||||
|
||||
(async function () {
|
||||
const hostnameValidationMarker = 'v--';
|
||||
const hostname = location.hostname;
|
||||
if (!hostname.startsWith(hostnameValidationMarker)) {
|
||||
// validation not requested
|
||||
return start();
|
||||
}
|
||||
if (!crypto.subtle) {
|
||||
// cannot validate, not running in a secure context
|
||||
return sendError(new Error(`Cannot validate in current context!`));
|
||||
}
|
||||
|
||||
// Here the `parentOriginHash()` function from `src/vs/base/browser/iframe.ts` is inlined
|
||||
// compute a sha-256 composed of `parentOrigin` and `salt` converted to base 32
|
||||
/** @type {string} */
|
||||
let parentOriginHash;
|
||||
try {
|
||||
const strData = JSON.stringify({ parentOrigin, salt });
|
||||
const encoder = new TextEncoder();
|
||||
const arrData = encoder.encode(strData);
|
||||
const hash = await crypto.subtle.digest('sha-256', arrData);
|
||||
const hashArray = Array.from(new Uint8Array(hash));
|
||||
const hashHex = hashArray.map(b => b.toString(16).padStart(2, '0')).join('');
|
||||
// sha256 has 256 bits, so we need at most ceil(lg(2^256-1)/lg(32)) = 52 chars to represent it in base 32
|
||||
parentOriginHash = BigInt(`0x${hashHex}`).toString(32).padStart(52, '0');
|
||||
} catch (err) {
|
||||
return sendError(err instanceof Error ? err : new Error(String(err)));
|
||||
}
|
||||
|
||||
const requiredSubdomain = `${hostnameValidationMarker}${parentOriginHash}.`;
|
||||
if (hostname.substring(0, requiredSubdomain.length) === requiredSubdomain) {
|
||||
// validation succeeded!
|
||||
return start();
|
||||
}
|
||||
|
||||
return sendError(new Error(`Expected '${requiredSubdomain}' as subdomain!`));
|
||||
})();
|
||||
|
||||
function sendError(error) {
|
||||
window.parent.postMessage({
|
||||
vscodeWebWorkerExtHostId,
|
||||
error: {
|
||||
name: error ? error.name : '',
|
||||
message: error ? error.message : '',
|
||||
stack: error ? error.stack : []
|
||||
}
|
||||
}, '*');
|
||||
}
|
||||
|
||||
function start() {
|
||||
try {
|
||||
let workerUrl = '../../../../base/worker/workerMain.js';
|
||||
if (globalThis.crossOriginIsolated) {
|
||||
workerUrl += '?vscode-coi=2'; // COEP
|
||||
}
|
||||
|
||||
const worker = new Worker(workerUrl, { name });
|
||||
worker.postMessage('vs/workbench/api/worker/extensionHostWorker');
|
||||
const nestedWorkers = new Map();
|
||||
|
||||
worker.onmessage = (event) => {
|
||||
const { data } = event;
|
||||
|
||||
if (data?.type === '_newWorker') {
|
||||
const { id, port, url, options } = data;
|
||||
const newWorker = new Worker(url, options);
|
||||
newWorker.postMessage(port, [port]);
|
||||
newWorker.onerror = console.error.bind(console);
|
||||
nestedWorkers.set(id, newWorker);
|
||||
|
||||
} else if (data?.type === '_terminateWorker') {
|
||||
const { id } = data;
|
||||
if (nestedWorkers.has(id)) {
|
||||
nestedWorkers.get(id).terminate();
|
||||
nestedWorkers.delete(id);
|
||||
}
|
||||
} else {
|
||||
worker.onerror = console.error.bind(console);
|
||||
window.parent.postMessage({
|
||||
vscodeWebWorkerExtHostId,
|
||||
data
|
||||
}, parentOrigin, [data]);
|
||||
}
|
||||
};
|
||||
|
||||
worker.onerror = (event) => {
|
||||
console.error(event.message, event.error);
|
||||
sendError(event.error);
|
||||
};
|
||||
|
||||
self.onmessage = (event) => {
|
||||
if (event.origin !== parentOrigin) {
|
||||
return;
|
||||
}
|
||||
worker.postMessage(event.data, event.ports);
|
||||
};
|
||||
} catch (err) {
|
||||
console.error(err);
|
||||
sendError(err);
|
||||
}
|
||||
}
|
||||
})();
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
Reference in New Issue
Block a user