• 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      '/tmp': process.argv[5]
19    }
20  });
21  const importObject = { wasi_snapshot_preview1: wasi.wasiImport };
22  const modulePath = path.join(wasmDir, `${process.argv[3]}.wasm`);
23  const buffer = fs.readFileSync(modulePath);
24
25  (async () => {
26    const { instance } = await WebAssembly.instantiate(buffer, importObject);
27
28    wasi.start(instance);
29  })().then(common.mustCall());
30} else {
31  if (!common.canCreateSymLink()) {
32    common.skip('insufficient privileges');
33  }
34
35  const assert = require('assert');
36  const cp = require('child_process');
37  const tmpdir = require('../common/tmpdir');
38
39  // Setup the sandbox environment.
40  tmpdir.refresh();
41  const sandbox = path.join(tmpdir.path, 'sandbox');
42  const sandboxedFile = path.join(sandbox, 'input.txt');
43  const externalFile = path.join(tmpdir.path, 'outside.txt');
44  const sandboxedDir = path.join(sandbox, 'subdir');
45  const sandboxedSymlink = path.join(sandboxedDir, 'input_link.txt');
46  const escapingSymlink = path.join(sandboxedDir, 'outside.txt');
47  const loopSymlink1 = path.join(sandboxedDir, 'loop1');
48  const loopSymlink2 = path.join(sandboxedDir, 'loop2');
49  const sandboxedTmp = path.join(tmpdir.path, 'tmp');
50
51  fs.mkdirSync(sandbox);
52  fs.mkdirSync(sandboxedDir);
53  fs.mkdirSync(sandboxedTmp);
54  fs.writeFileSync(sandboxedFile, 'hello from input.txt', 'utf8');
55  fs.writeFileSync(externalFile, 'this should be inaccessible', 'utf8');
56  fs.symlinkSync(path.join('.', 'input.txt'), sandboxedSymlink, 'file');
57  fs.symlinkSync(path.join('..', 'outside.txt'), escapingSymlink, 'file');
58  fs.symlinkSync(path.join('subdir', 'loop2'),
59                 loopSymlink1, 'file');
60  fs.symlinkSync(path.join('subdir', 'loop1'),
61                 loopSymlink2, 'file');
62
63  function runWASI(options) {
64    console.log('executing', options.test);
65    const opts = { env: { ...process.env, NODE_DEBUG_NATIVE: 'wasi' } };
66    const child = cp.spawnSync(process.execPath, [
67      '--experimental-wasi-unstable-preview1',
68      '--experimental-wasm-bigint',
69      __filename,
70      'wasi-child',
71      options.test,
72      sandbox,
73      sandboxedTmp,
74    ], opts);
75    console.log(child.stderr.toString());
76    assert.strictEqual(child.status, 0);
77    assert.strictEqual(child.signal, null);
78    assert.strictEqual(child.stdout.toString(), options.stdout || '');
79  }
80
81  runWASI({ test: 'create_symlink', stdout: 'hello from input.txt' });
82  runWASI({ test: 'follow_symlink', stdout: 'hello from input.txt' });
83  runWASI({ test: 'link' });
84  runWASI({ test: 'symlink_escape' });
85  runWASI({ test: 'symlink_loop' });
86}
87