• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1'use strict';
2const common = require('../common');
3const fs = require('fs');
4const path = require('path');
5
6if (process.argv[2] === 'wasi-child') {
7  common.expectWarning('ExperimentalWarning',
8                       'WASI is an experimental feature. This feature could ' +
9                       'change at any time');
10
11  const { WASI } = require('wasi');
12  const wasmDir = path.join(__dirname, 'wasm');
13  const wasi = new WASI({
14    args: [],
15    env: process.env,
16    preopens: {
17      '/sandbox': process.argv[4]
18    }
19  });
20  const importObject = { wasi_snapshot_preview1: wasi.wasiImport };
21  const modulePath = path.join(wasmDir, `${process.argv[3]}.wasm`);
22  const buffer = fs.readFileSync(modulePath);
23
24  (async () => {
25    const { instance } = await WebAssembly.instantiate(buffer, importObject);
26
27    wasi.start(instance);
28  })();
29} else {
30  if (!common.canCreateSymLink()) {
31    common.skip('insufficient privileges');
32  }
33
34  const assert = require('assert');
35  const cp = require('child_process');
36  const tmpdir = require('../common/tmpdir');
37
38  // Setup the sandbox environment.
39  tmpdir.refresh();
40  const sandbox = path.join(tmpdir.path, 'sandbox');
41  const sandboxedFile = path.join(sandbox, 'input.txt');
42  const externalFile = path.join(tmpdir.path, 'outside.txt');
43  const sandboxedDir = path.join(sandbox, 'subdir');
44  const sandboxedSymlink = path.join(sandboxedDir, 'input_link.txt');
45  const escapingSymlink = path.join(sandboxedDir, 'outside.txt');
46  const loopSymlink1 = path.join(sandboxedDir, 'loop1');
47  const loopSymlink2 = path.join(sandboxedDir, 'loop2');
48
49  fs.mkdirSync(sandbox);
50  fs.mkdirSync(sandboxedDir);
51  fs.writeFileSync(sandboxedFile, 'hello from input.txt', 'utf8');
52  fs.writeFileSync(externalFile, 'this should be inaccessible', 'utf8');
53  fs.symlinkSync(path.join('.', 'input.txt'), sandboxedSymlink, 'file');
54  fs.symlinkSync(path.join('..', 'outside.txt'), escapingSymlink, 'file');
55  fs.symlinkSync(path.join('subdir', 'loop2'),
56                 loopSymlink1, 'file');
57  fs.symlinkSync(path.join('subdir', 'loop1'),
58                 loopSymlink2, 'file');
59
60  function runWASI(options) {
61    console.log('executing', options.test);
62    const opts = { env: { ...process.env, NODE_DEBUG_NATIVE: 'wasi' } };
63    const child = cp.spawnSync(process.execPath, [
64      '--experimental-wasi-unstable-preview1',
65      '--experimental-wasm-bigint',
66      __filename,
67      'wasi-child',
68      options.test,
69      sandbox
70    ], opts);
71    console.log(child.stderr.toString());
72    assert.strictEqual(child.status, 0);
73    assert.strictEqual(child.signal, null);
74    assert.strictEqual(child.stdout.toString(), options.stdout || '');
75  }
76
77  runWASI({ test: 'create_symlink', stdout: 'hello from input.txt' });
78  runWASI({ test: 'follow_symlink', stdout: 'hello from input.txt' });
79  runWASI({ test: 'symlink_escape' });
80  runWASI({ test: 'symlink_loop' });
81}
82