@vscode/test-web 0.0.44 → 0.0.46

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/SECURITY.md ADDED
@@ -0,0 +1,41 @@
1
+ <!-- BEGIN MICROSOFT SECURITY.MD V0.0.8 BLOCK -->
2
+
3
+ ## Security
4
+
5
+ Microsoft takes the security of our software products and services seriously, which includes all source code repositories managed through our GitHub organizations, which include [Microsoft](https://github.com/microsoft), [Azure](https://github.com/Azure), [DotNet](https://github.com/dotnet), [AspNet](https://github.com/aspnet), [Xamarin](https://github.com/xamarin), and [our GitHub organizations](https://opensource.microsoft.com/).
6
+
7
+ If you believe you have found a security vulnerability in any Microsoft-owned repository that meets [Microsoft's definition of a security vulnerability](https://aka.ms/opensource/security/definition), please report it to us as described below.
8
+
9
+ ## Reporting Security Issues
10
+
11
+ **Please do not report security vulnerabilities through public GitHub issues.**
12
+
13
+ Instead, please report them to the Microsoft Security Response Center (MSRC) at [https://msrc.microsoft.com/create-report](https://aka.ms/opensource/security/create-report).
14
+
15
+ If you prefer to submit without logging in, send email to [secure@microsoft.com](mailto:secure@microsoft.com). If possible, encrypt your message with our PGP key; please download it from the [Microsoft Security Response Center PGP Key page](https://aka.ms/opensource/security/pgpkey).
16
+
17
+ You should receive a response within 24 hours. If for some reason you do not, please follow up via email to ensure we received your original message. Additional information can be found at [microsoft.com/msrc](https://aka.ms/opensource/security/msrc).
18
+
19
+ Please include the requested information listed below (as much as you can provide) to help us better understand the nature and scope of the possible issue:
20
+
21
+ * Type of issue (e.g. buffer overflow, SQL injection, cross-site scripting, etc.)
22
+ * Full paths of source file(s) related to the manifestation of the issue
23
+ * The location of the affected source code (tag/branch/commit or direct URL)
24
+ * Any special configuration required to reproduce the issue
25
+ * Step-by-step instructions to reproduce the issue
26
+ * Proof-of-concept or exploit code (if possible)
27
+ * Impact of the issue, including how an attacker might exploit the issue
28
+
29
+ This information will help us triage your report more quickly.
30
+
31
+ If you are reporting for a bug bounty, more complete reports can contribute to a higher bounty award. Please visit our [Microsoft Bug Bounty Program](https://aka.ms/opensource/security/bounty) page for more details about our active programs.
32
+
33
+ ## Preferred Languages
34
+
35
+ We prefer all communications to be in English.
36
+
37
+ ## Policy
38
+
39
+ Microsoft follows the principle of [Coordinated Vulnerability Disclosure](https://aka.ms/opensource/security/cvd).
40
+
41
+ <!-- END MICROSOFT SECURITY.MD BLOCK -->
@@ -475,21 +475,22 @@ const fsProvider_1 = __webpack_require__(3);
475
475
  const SCHEME = 'vscode-test-web';
476
476
  function activate(context) {
477
477
  const serverUri = context.extensionUri.with({ path: '/static/mount', query: undefined });
478
- const serverBackedRootDirectory = new ServerBackedDirectory(serverUri, '');
478
+ const serverBackedRootDirectory = new ServerBackedDirectory(serverUri, [], '');
479
479
  const disposable = vscode_1.workspace.registerFileSystemProvider(SCHEME, new fsProvider_1.MemFileSystemProvider(SCHEME, serverBackedRootDirectory));
480
480
  context.subscriptions.push(disposable);
481
481
  console.log(`vscode-test-web-support fs provider registers for ${SCHEME}, initial content from ${serverUri.toString(/*skipEncoding*/ true)}`);
482
482
  }
483
483
  exports.activate = activate;
484
484
  class ServerBackedFile {
485
- constructor(_serverUri, name) {
486
- this._serverUri = _serverUri;
485
+ constructor(_serverRoot, pathSegments, name) {
486
+ this._serverRoot = _serverRoot;
487
+ this.pathSegments = pathSegments;
487
488
  this.name = name;
488
489
  this.type = vscode_1.FileType.File;
489
490
  }
490
491
  get stats() {
491
492
  if (this._stats === undefined) {
492
- this._stats = getStats(this._serverUri);
493
+ this._stats = getStats(this._serverRoot, this.pathSegments);
493
494
  }
494
495
  return this._stats;
495
496
  }
@@ -498,7 +499,7 @@ class ServerBackedFile {
498
499
  }
499
500
  get content() {
500
501
  if (this._content === undefined) {
501
- this._content = getContent(this._serverUri);
502
+ this._content = getContent(this._serverRoot, this.pathSegments);
502
503
  }
503
504
  return this._content;
504
505
  }
@@ -507,14 +508,15 @@ class ServerBackedFile {
507
508
  }
508
509
  }
509
510
  class ServerBackedDirectory {
510
- constructor(_serverUri, name) {
511
- this._serverUri = _serverUri;
511
+ constructor(_serverRoot, pathSegments, name) {
512
+ this._serverRoot = _serverRoot;
513
+ this.pathSegments = pathSegments;
512
514
  this.name = name;
513
515
  this.type = vscode_1.FileType.Directory;
514
516
  }
515
517
  get stats() {
516
518
  if (this._stats === undefined) {
517
- this._stats = getStats(this._serverUri);
519
+ this._stats = getStats(this._serverRoot, this.pathSegments);
518
520
  }
519
521
  return this._stats;
520
522
  }
@@ -523,7 +525,7 @@ class ServerBackedDirectory {
523
525
  }
524
526
  get entries() {
525
527
  if (this._entries === undefined) {
526
- this._entries = getEntries(this._serverUri);
528
+ this._entries = getEntries(this._serverRoot, this.pathSegments);
527
529
  }
528
530
  return this._entries;
529
531
  }
@@ -539,8 +541,11 @@ function isEntry(e) {
539
541
  function isStat(e) {
540
542
  return e && (e.type === vscode_1.FileType.Directory || e.type === vscode_1.FileType.File) && typeof e.ctime === 'number' && typeof e.mtime === 'number' && typeof e.size === 'number';
541
543
  }
542
- async function getEntries(serverUri) {
543
- const url = serverUri.with({ query: 'readdir' }).toString(/*skipEncoding*/ true);
544
+ function getServerUri(serverRoot, pathSegments) {
545
+ return vscode_1.Uri.joinPath(serverRoot, ...pathSegments);
546
+ }
547
+ async function getEntries(serverRoot, pathSegments) {
548
+ const url = getServerUri(serverRoot, pathSegments).with({ query: 'readdir' }).toString(/*skipEncoding*/ true);
544
549
  const response = await (0, request_light_1.xhr)({ url });
545
550
  if (response.status === 200 && response.status <= 204) {
546
551
  try {
@@ -549,8 +554,8 @@ async function getEntries(serverUri) {
549
554
  const entries = new Map();
550
555
  for (const r of res) {
551
556
  if (isEntry(r)) {
552
- const childPath = vscode_1.Uri.joinPath(serverUri, r.name);
553
- const newEntry = r.type === vscode_1.FileType.Directory ? new ServerBackedDirectory(childPath, r.name) : new ServerBackedFile(childPath, r.name);
557
+ const newPathSegments = [...pathSegments, encodeURIComponent(r.name)];
558
+ const newEntry = r.type === vscode_1.FileType.Directory ? new ServerBackedDirectory(serverRoot, newPathSegments, r.name) : new ServerBackedFile(serverRoot, newPathSegments, r.name);
554
559
  entries.set(newEntry.name, newEntry);
555
560
  }
556
561
  }
@@ -567,7 +572,8 @@ async function getEntries(serverUri) {
567
572
  }
568
573
  return new Map();
569
574
  }
570
- async function getStats(serverUri) {
575
+ async function getStats(serverRoot, pathSegments) {
576
+ const serverUri = getServerUri(serverRoot, pathSegments);
571
577
  const url = serverUri.with({ query: 'stat' }).toString(/*skipEncoding*/ true);
572
578
  const response = await (0, request_light_1.xhr)({ url });
573
579
  if (response.status === 200 && response.status <= 204) {
@@ -579,7 +585,8 @@ async function getStats(serverUri) {
579
585
  }
580
586
  throw vscode_1.FileSystemError.FileNotFound(`Invalid server response for ${serverUri.toString(/*skipEncoding*/ true)}. Status ${response.status}.`);
581
587
  }
582
- async function getContent(serverUri) {
588
+ async function getContent(serverRoot, pathSegments) {
589
+ const serverUri = getServerUri(serverRoot, pathSegments);
583
590
  const response = await (0, request_light_1.xhr)({ url: serverUri.toString(/*skipEncoding*/ true) });
584
591
  if (response.status >= 200 && response.status <= 204) {
585
592
  return response.body;
@@ -35,11 +35,11 @@
35
35
  "package-web": "webpack --mode production --devtool hidden-source-map"
36
36
  },
37
37
  "devDependencies": {
38
- "@types/vscode": "^1.72.0",
39
- "@types/webpack-env": "^1.18.1",
40
- "ts-loader": "^9.4.3",
41
- "webpack": "^5.85.0",
42
- "webpack-cli": "^5.1.1",
38
+ "@types/vscode": "^1.81.0",
39
+ "@types/webpack-env": "^1.18.2",
40
+ "ts-loader": "^9.4.4",
41
+ "webpack": "^5.88.2",
42
+ "webpack-cli": "^5.1.4",
43
43
  "process": "^0.11.10",
44
44
  "path-browserify": "^1.0.1",
45
45
  "request-light": "^0.7.0",
package/out/index.js CHANGED
@@ -28,7 +28,7 @@ async function runTests(options) {
28
28
  extensionPaths: options.extensionPaths,
29
29
  extensionIds: options.extensionIds,
30
30
  coi: !!options.coi,
31
- esm: !!options.esm
31
+ esm: !!options.esm,
32
32
  };
33
33
  const host = options.host ?? 'localhost';
34
34
  const port = options.port ?? 3000;
@@ -76,7 +76,7 @@ async function getBuild(options) {
76
76
  if (options.vsCodeDevPath) {
77
77
  return {
78
78
  type: 'sources',
79
- location: options.vsCodeDevPath
79
+ location: options.vsCodeDevPath,
80
80
  };
81
81
  }
82
82
  const quality = options.quality || options.version;
@@ -94,7 +94,7 @@ async function open(options) {
94
94
  extensionPaths: options.extensionPaths,
95
95
  extensionIds: options.extensionIds,
96
96
  coi: !!options.coi,
97
- esm: !!options.esm
97
+ esm: !!options.esm,
98
98
  };
99
99
  const host = options.host ?? 'localhost';
100
100
  const port = options.port ?? 3000;
@@ -106,7 +106,7 @@ async function open(options) {
106
106
  dispose: () => {
107
107
  server.close();
108
108
  context?.browser()?.close();
109
- }
109
+ },
110
110
  };
111
111
  }
112
112
  exports.open = open;
@@ -143,7 +143,7 @@ async function openBrowser(endpoint, options, configPage) {
143
143
  }
144
144
  });
145
145
  });
146
- const page = context.pages()[0] ?? await context.newPage();
146
+ const page = context.pages()[0] ?? (await context.newPage());
147
147
  if (configPage) {
148
148
  await configPage(page, browser);
149
149
  }
@@ -160,7 +160,7 @@ async function openBrowser(endpoint, options, configPage) {
160
160
  }
161
161
  function validateStringOrUndefined(options, name) {
162
162
  const value = options[name];
163
- if (value === undefined || (typeof value === 'string')) {
163
+ if (value === undefined || typeof value === 'string') {
164
164
  return value;
165
165
  }
166
166
  console.log(`'${name}' needs to be a string value.`);
@@ -173,7 +173,7 @@ async function validatePathOrUndefined(options, name, isFile) {
173
173
  }
174
174
  function validateBooleanOrUndefined(options, name) {
175
175
  const value = options[name];
176
- if (value === undefined || (typeof value === 'boolean')) {
176
+ if (value === undefined || typeof value === 'boolean') {
177
177
  return value;
178
178
  }
179
179
  console.log(`'${name}' needs to be a boolean value.`);
@@ -199,7 +199,7 @@ function validateBrowserType(options) {
199
199
  if (options.browserType && options.browser) {
200
200
  console.log(`Ignoring browserType option '${options.browserType}' as browser option '${options.browser}' is set.`);
201
201
  }
202
- if ((typeof browserType === 'string') && ['chromium', 'firefox', 'webkit', 'none'].includes(browserType)) {
202
+ if (typeof browserType === 'string' && ['chromium', 'firefox', 'webkit', 'none'].includes(browserType)) {
203
203
  return browserType;
204
204
  }
205
205
  console.log(`Invalid browser option ${browserType}.`);
@@ -257,7 +257,7 @@ async function validateExtensionIds(extensionIds) {
257
257
  if (Array.isArray(extensionIds)) {
258
258
  const res = [];
259
259
  for (const extensionId of extensionIds) {
260
- const m = (typeof extensionId === 'string' && extensionId.match(EXTENSION_IDENTIFIER_PATTERN));
260
+ const m = typeof extensionId === 'string' && extensionId.match(EXTENSION_IDENTIFIER_PATTERN);
261
261
  if (m) {
262
262
  if (m[2]) {
263
263
  res.push({ id: m[1], preRelease: true });
@@ -282,13 +282,13 @@ async function validateExtensionIds(extensionIds) {
282
282
  async function validatePath(loc, isFile) {
283
283
  loc = path.resolve(loc);
284
284
  if (isFile) {
285
- if (!await (0, download_1.fileExists)(loc)) {
285
+ if (!(await (0, download_1.fileExists)(loc))) {
286
286
  console.log(`'${loc}' must be an existing file.`);
287
287
  process.exit(-1);
288
288
  }
289
289
  }
290
290
  else {
291
- if (!await (0, download_1.directoryExists)(loc)) {
291
+ if (!(await (0, download_1.directoryExists)(loc))) {
292
292
  console.log(`'${loc}' must be an existing folder.`);
293
293
  process.exit(-1);
294
294
  }
@@ -304,7 +304,7 @@ function validateQuality(quality, version, vsCodeDevPath) {
304
304
  console.log(`Sources folder is provided as input, quality is ignored.`);
305
305
  return undefined;
306
306
  }
307
- if (quality === undefined || ((typeof quality === 'string') && ['insiders', 'stable'].includes(quality))) {
307
+ if (quality === undefined || (typeof quality === 'string' && ['insiders', 'stable'].includes(quality))) {
308
308
  return quality;
309
309
  }
310
310
  if (version === 'sources') {
@@ -368,7 +368,7 @@ async function cliMain() {
368
368
  process.exit();
369
369
  }
370
370
  return true;
371
- }
371
+ },
372
372
  };
373
373
  const args = minimist(process.argv.slice(2), options);
374
374
  if (args.help) {
@@ -427,7 +427,7 @@ async function cliMain() {
427
427
  coi,
428
428
  host,
429
429
  port,
430
- testRunnerDataDir
430
+ testRunnerDataDir,
431
431
  }).catch(e => {
432
432
  console.log('Error running tests:', e);
433
433
  process.exit(1);
@@ -453,7 +453,7 @@ async function cliMain() {
453
453
  coi,
454
454
  host,
455
455
  port,
456
- testRunnerDataDir
456
+ testRunnerDataDir,
457
457
  });
458
458
  }
459
459
  }
package/out/server/app.js CHANGED
@@ -79,7 +79,7 @@ async function createApp(config) {
79
79
  console.log('Serving VS Code sources from ' + config.build.location);
80
80
  app.use(kmount('/static/sources', kstatic(config.build.location, serveOptions)));
81
81
  app.use(kmount('/static/sources', kstatic((0, path_1.join)(config.build.location, 'resources', 'server'), serveOptions))); // for manifest.json, favicon and code icons.
82
- // built-in extension are at 'extensions` as well as prebuilt extensions dowloaded from the marketplace
82
+ // built-in extension are at 'extensions` as well as prebuilt extensions downloaded from the marketplace
83
83
  app.use(kmount(`/static/sources/extensions`, kstatic((0, path_1.join)(config.build.location, extensions_1.prebuiltExtensionsLocation), serveOptions)));
84
84
  }
85
85
  (0, mounts_1.configureMounts)(config, app);
@@ -57,7 +57,7 @@ async function getScannedBuiltinExtensions(vsCodeDevLocation) {
57
57
  browserMain = browserMain + '.js';
58
58
  }
59
59
  const browserMainLocation = path.join(vsCodeDevLocation, 'extensions', ext.extensionPath, browserMain);
60
- if (!await (0, download_1.fileExists)(browserMainLocation)) {
60
+ if (!(await (0, download_1.fileExists)(browserMainLocation))) {
61
61
  console.log(`${browserMainLocation} not found. Make sure all extensions are compiled (use 'yarn watch-web').`);
62
62
  }
63
63
  }
@@ -27,14 +27,14 @@ function fileOps(mountPrefix, folderMountPath) {
27
27
  const router = new Router();
28
28
  router.get(`${mountPrefix}(/.*)?`, async (ctx, next) => {
29
29
  if (ctx.query.stat !== undefined) {
30
- const p = path.join(folderMountPath, ctx.path.substring(mountPrefix.length));
30
+ const p = path.join(folderMountPath, decodeURIComponent(ctx.path.substring(mountPrefix.length)));
31
31
  try {
32
32
  const stats = await fs_1.promises.stat(p);
33
33
  ctx.body = {
34
34
  type: getFileType(stats),
35
35
  ctime: stats.ctime.getTime(),
36
36
  mtime: stats.mtime.getTime(),
37
- size: stats.size
37
+ size: stats.size,
38
38
  };
39
39
  }
40
40
  catch (e) {
@@ -42,10 +42,10 @@ function fileOps(mountPrefix, folderMountPath) {
42
42
  }
43
43
  }
44
44
  else if (ctx.query.readdir !== undefined) {
45
- const p = path.join(folderMountPath, ctx.path.substring(mountPrefix.length));
45
+ const p = path.join(folderMountPath, decodeURIComponent(ctx.path.substring(mountPrefix.length)));
46
46
  try {
47
47
  const entries = await fs_1.promises.readdir(p, { withFileTypes: true });
48
- ctx.body = entries.map(d => ({ name: d.name, type: getFileType(d) }));
48
+ ctx.body = entries.map((d) => ({ name: d.name, type: getFileType(d) }));
49
49
  }
50
50
  catch (e) {
51
51
  ctx.body = { error: e.code };
@@ -31,7 +31,7 @@ class Workbench {
31
31
  WORKBENCH_AUTH_SESSION: '',
32
32
  WORKBENCH_WEB_BASE_URL: this.baseUrl,
33
33
  WORKBENCH_BUILTIN_EXTENSIONS: asJSON(this.builtInExtensions),
34
- WORKBENCH_MAIN: this.getMain()
34
+ WORKBENCH_MAIN: this.getMain(),
35
35
  };
36
36
  try {
37
37
  const workbenchTemplate = (await fs_1.promises.readFile(path.resolve(__dirname, `../../views/workbench${this.esm ? '-esm' : ''}.html`))).toString();
@@ -75,7 +75,7 @@ async function getWorkbenchOptions(ctx, config) {
75
75
  options.additionalBuiltinExtensions.push(...config.extensionIds);
76
76
  }
77
77
  if (config.extensionDevelopmentPath) {
78
- const developmentOptions = options.developmentOptions = {};
78
+ const developmentOptions = (options.developmentOptions = {});
79
79
  developmentOptions.extensions = await (0, extensions_1.scanForExtensions)(config.extensionDevelopmentPath, { scheme: ctx.protocol, authority: ctx.host, path: '/static/devextensions' });
80
80
  if (config.extensionTestsPath) {
81
81
  let relativePath = path.relative(config.extensionDevelopmentPath, config.extensionTestsPath);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@vscode/test-web",
3
- "version": "0.0.44",
3
+ "version": "0.0.46",
4
4
  "scripts": {
5
5
  "install-extensions": "yarn --cwd=fs-provider && yarn --cwd=sample",
6
6
  "compile": "tsc -p ./ && yarn compile-fs-provider",
@@ -30,28 +30,29 @@
30
30
  "koa-mount": "^4.0.0",
31
31
  "koa-static": "^5.0.0",
32
32
  "minimist": "^1.2.8",
33
- "playwright": "^1.34.3",
33
+ "playwright": "^1.38.1",
34
+ "@playwright/browser-chromium": "^1.38.1",
34
35
  "vscode-uri": "^3.0.7",
35
36
  "http-proxy-agent": "^7.0.0",
36
- "https-proxy-agent": "^7.0.0",
37
- "tar-fs": "^2.1.1",
37
+ "https-proxy-agent": "^7.0.2",
38
+ "tar-fs": "^3.0.4",
38
39
  "gunzip-maybe": "^1.4.2"
39
40
  },
40
41
  "devDependencies": {
41
- "@types/koa": "^2.13.6",
42
- "@types/koa-morgan": "^1.0.5",
43
- "@types/koa-mount": "^4.0.2",
42
+ "@types/koa": "^2.13.9",
43
+ "@types/koa-morgan": "^1.0.6",
44
+ "@types/koa-mount": "^4.0.3",
44
45
  "@types/koa-static": "^4.0.2",
45
- "@types/koa__router": "^12.0.0",
46
- "@types/minimist": "^1.2.2",
46
+ "@types/koa__router": "^12.0.1",
47
+ "@types/minimist": "^1.2.3",
47
48
  "@types/node": "16.x",
48
49
  "@types/gunzip-maybe": "^1.4.0",
49
- "@types/tar-fs": "^2.0.1",
50
- "@typescript-eslint/eslint-plugin": "^5.59.8",
51
- "@typescript-eslint/parser": "^5.59.8",
52
- "eslint": "^8.41.0",
50
+ "@types/tar-fs": "^2.0.2",
51
+ "@typescript-eslint/eslint-plugin": "^6.7.3",
52
+ "@typescript-eslint/parser": "^6.7.3",
53
+ "eslint": "^8.50.0",
53
54
  "eslint-plugin-header": "^3.1.1",
54
- "typescript": "^5.1.3"
55
+ "typescript": "^5.2.2"
55
56
  },
56
57
  "license": "MIT",
57
58
  "author": "Visual Studio Code Team",