From 133d95e61892e304af8763b6df1412af5a87f32d Mon Sep 17 00:00:00 2001 From: Johannes Rieken Date: Fri, 11 Sep 2020 17:59:23 +0200 Subject: [PATCH] adopt new amd loader with support for TrustedScriptURL, add typings for TrustedTypesFactory et al, https://github.com/microsoft/vscode/issues/106396 --- src/typings/trustedTypes.d.ts | 36 +++++++++++++++ src/vs/base/worker/workerMain.ts | 3 +- .../code/browser/workbench/workbench-dev.html | 1 + src/vs/code/browser/workbench/workbench.html | 1 + src/vs/loader.js | 45 +++++++++++++++++++ .../worker/extensionHostWorkerMain.ts | 3 +- 6 files changed, 87 insertions(+), 2 deletions(-) create mode 100644 src/typings/trustedTypes.d.ts diff --git a/src/typings/trustedTypes.d.ts b/src/typings/trustedTypes.d.ts new file mode 100644 index 00000000000..feb4af29184 --- /dev/null +++ b/src/typings/trustedTypes.d.ts @@ -0,0 +1,36 @@ +/*--------------------------------------------------------------------------------------------- + * Copyright (c) Microsoft Corporation. All rights reserved. + * Licensed under the MIT License. See License.txt in the project root for license information. + *--------------------------------------------------------------------------------------------*/ + +// see https://w3c.github.io/webappsec-trusted-types/dist/spec/ +// this isn't complete nor 100% correct + +type TrustedHTML = string & object; +type TrustedScript = string; +type TrustedScriptURL = string; + +interface TrustedTypePolicyOptions { + createHTML?: (value: string) => string + createScript?: (value: string) => string + createScriptURL?: (value: string) => string +} + +interface TrustedTypePolicy { + readonly name: string; + createHTML(input: string, ...more: any[]): TrustedHTML + createScript(input: string, ...more: any[]): TrustedScript + createScriptURL(input: string, ...more: any[]): TrustedScriptURL +} + +interface TrustedTypePolicyFactory { + createPolicy(policyName: string, object: TrustedTypePolicyOptions): TrustedTypePolicy; +} + +interface Window { + trustedTypes: TrustedTypePolicyFactory | undefined; +} + +interface WorkerGlobalScope { + trustedTypes: TrustedTypePolicyFactory | undefined; +} diff --git a/src/vs/base/worker/workerMain.ts b/src/vs/base/worker/workerMain.ts index 22bc88f1c00..71c6724e984 100644 --- a/src/vs/base/worker/workerMain.ts +++ b/src/vs/base/worker/workerMain.ts @@ -14,7 +14,8 @@ require.config({ baseUrl: monacoBaseUrl, - catchError: true + catchError: true, + createTrustedScriptURL: (value: string) => value, }); let loadCode = function (moduleId: string) { diff --git a/src/vs/code/browser/workbench/workbench-dev.html b/src/vs/code/browser/workbench/workbench-dev.html index 8cf808998eb..0142bb7f53d 100644 --- a/src/vs/code/browser/workbench/workbench-dev.html +++ b/src/vs/code/browser/workbench/workbench-dev.html @@ -33,6 +33,7 @@ self.require = { baseUrl: `${window.location.origin}/static/out`, recordStats: true, + createTrustedScriptURL: value => value, paths: { 'vscode-textmate': `${window.location.origin}/static/remote/web/node_modules/vscode-textmate/release/main`, 'vscode-oniguruma': `${window.location.origin}/static/remote/web/node_modules/vscode-oniguruma/release/main`, diff --git a/src/vs/code/browser/workbench/workbench.html b/src/vs/code/browser/workbench/workbench.html index 38535768348..d56e3fdd36a 100644 --- a/src/vs/code/browser/workbench/workbench.html +++ b/src/vs/code/browser/workbench/workbench.html @@ -31,6 +31,7 @@ self.require = { baseUrl: `${window.location.origin}/static/out`, recordStats: true, + createTrustedScriptURL: value => value, paths: { 'vscode-textmate': `${window.location.origin}/static/node_modules/vscode-textmate/release/main`, 'vscode-oniguruma': `${window.location.origin}/static/node_modules/vscode-oniguruma/release/main`, diff --git a/src/vs/loader.js b/src/vs/loader.js index 5da6a16b13e..3b71c723592 100644 --- a/src/vs/loader.js +++ b/src/vs/loader.js @@ -618,8 +618,37 @@ var AMDLoader; }; return OnlyOnceScriptLoader; }()); + var trustedTypesPolyfill = new /** @class */(function () { + function class_1() { + } + class_1.prototype.installIfNeeded = function () { + if (typeof globalThis.trustedTypes !== 'undefined') { + return; // already defined + } + var _defaultRules = { + createHTML: function () { throw new Error('Policy\'s TrustedTypePolicyOptions did not specify a \'createHTML\' member'); }, + createScript: function () { throw new Error('Policy\'s TrustedTypePolicyOptions did not specify a \'createScript\' member'); }, + createScriptURL: function () { throw new Error('Policy\'s TrustedTypePolicyOptions did not specify a \'createScriptURL\' member'); }, + }; + globalThis.trustedTypes = { + createPolicy: function (name, rules) { + var _a, _b, _c; + return { + name: name, + createHTML: (_a = rules.createHTML) !== null && _a !== void 0 ? _a : _defaultRules.createHTML, + createScript: (_b = rules.createScript) !== null && _b !== void 0 ? _b : _defaultRules.createScript, + createScriptURL: (_c = rules.createScriptURL) !== null && _c !== void 0 ? _c : _defaultRules.createScriptURL, + }; + } + }; + }; + return class_1; + }()); + //#endregion var BrowserScriptLoader = /** @class */ (function () { function BrowserScriptLoader() { + // polyfill trustedTypes-support if missing + trustedTypesPolyfill.installIfNeeded(); } /** * Attach load / error listeners to a script element and remove them when either one has fired. @@ -662,6 +691,13 @@ var AMDLoader; script.setAttribute('async', 'async'); script.setAttribute('type', 'text/javascript'); this.attachListeners(script, callback, errorback); + var createTrustedScriptURL = moduleManager.getConfig().getOptionsLiteral().createTrustedScriptURL; + if (createTrustedScriptURL) { + if (!this.scriptSourceURLPolicy) { + this.scriptSourceURLPolicy = trustedTypes.createPolicy('amdLoader', { createScriptURL: createTrustedScriptURL }); + } + scriptSrc = this.scriptSourceURLPolicy.createScriptURL(scriptSrc); + } script.setAttribute('src', scriptSrc); // Propagate CSP nonce to dynamically created script tag. var cspNonce = moduleManager.getConfig().getOptionsLiteral().cspNonce; @@ -675,8 +711,17 @@ var AMDLoader; }()); var WorkerScriptLoader = /** @class */ (function () { function WorkerScriptLoader() { + // polyfill trustedTypes-support if missing + trustedTypesPolyfill.installIfNeeded(); } WorkerScriptLoader.prototype.load = function (moduleManager, scriptSrc, callback, errorback) { + var createTrustedScriptURL = moduleManager.getConfig().getOptionsLiteral().createTrustedScriptURL; + if (createTrustedScriptURL) { + if (!this.scriptSourceURLPolicy) { + this.scriptSourceURLPolicy = trustedTypes.createPolicy('amdLoader', { createScriptURL: createTrustedScriptURL }); + } + scriptSrc = this.scriptSourceURLPolicy.createScriptURL(scriptSrc); + } try { importScripts(scriptSrc); callback(); diff --git a/src/vs/workbench/services/extensions/worker/extensionHostWorkerMain.ts b/src/vs/workbench/services/extensions/worker/extensionHostWorkerMain.ts index 79455414c06..b39a5cbb9ea 100644 --- a/src/vs/workbench/services/extensions/worker/extensionHostWorkerMain.ts +++ b/src/vs/workbench/services/extensions/worker/extensionHostWorkerMain.ts @@ -14,7 +14,8 @@ require.config({ baseUrl: monacoBaseUrl, - catchError: true + catchError: true, + createTrustedScriptURL: (value: string) => value }); require(['vs/workbench/services/extensions/worker/extensionHostWorker'], () => { }, err => console.error(err));