• 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 and might change at any time');
9
10  const { WASI } = require('wasi');
11  const wasmDir = path.join(__dirname, 'wasm');
12  const wasi = new WASI({
13    args: [],
14    env: process.env,
15    preopens: {
16      '/sandbox': process.argv[4],
17      '/tmp': process.argv[5],
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  })().then(common.mustCall());
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  const sandboxedTmp = path.join(tmpdir.path, 'tmp');
49
50  fs.mkdirSync(sandbox);
51  fs.mkdirSync(sandboxedDir);
52  fs.mkdirSync(sandboxedTmp);
53  fs.writeFileSync(sandboxedFile, 'hello from input.txt', 'utf8');
54  fs.writeFileSync(externalFile, 'this should be inaccessible', 'utf8');
55  fs.symlinkSync(path.join('.', 'input.txt'), sandboxedSymlink, 'file');
56  fs.symlinkSync(path.join('..', 'outside.txt'), escapingSymlink, 'file');
57  fs.symlinkSync(path.join('subdir', 'loop2'),
58                 loopSymlink1, 'file');
59  fs.symlinkSync(path.join('subdir', 'loop1'),
60                 loopSymlink2, 'file');
61
62  function runWASI(options) {
63    console.log('executing', options.test);
64    const opts = { env: { ...process.env, NODE_DEBUG_NATIVE: 'wasi' } };
65    const child = cp.spawnSync(process.execPath, [
66      __filename,
67      'wasi-child',
68      options.test,
69      sandbox,
70      sandboxedTmp,
71    ], opts);
72    console.log(child.stderr.toString());
73    assert.strictEqual(child.status, 0);
74    assert.strictEqual(child.signal, null);
75    assert.strictEqual(child.stdout.toString(), options.stdout || '');
76  }
77
78  runWASI({ test: 'create_symlink', stdout: 'hello from input.txt' });
79  runWASI({ test: 'follow_symlink', stdout: 'hello from input.txt' });
80  runWASI({ test: 'link' });
81  runWASI({ test: 'symlink_escape' });
82  runWASI({ test: 'symlink_loop' });
83}
84