11cb0ef41Sopenharmony_ci'use strict'; 21cb0ef41Sopenharmony_ciconst common = require('../common'); 31cb0ef41Sopenharmony_ciconst fs = require('fs'); 41cb0ef41Sopenharmony_ciconst path = require('path'); 51cb0ef41Sopenharmony_ci 61cb0ef41Sopenharmony_ciif (process.argv[2] === 'wasi-child') { 71cb0ef41Sopenharmony_ci common.expectWarning('ExperimentalWarning', 81cb0ef41Sopenharmony_ci 'WASI is an experimental feature and might change at any time'); 91cb0ef41Sopenharmony_ci 101cb0ef41Sopenharmony_ci const { WASI } = require('wasi'); 111cb0ef41Sopenharmony_ci const wasmDir = path.join(__dirname, 'wasm'); 121cb0ef41Sopenharmony_ci const wasi = new WASI({ 131cb0ef41Sopenharmony_ci args: [], 141cb0ef41Sopenharmony_ci env: process.env, 151cb0ef41Sopenharmony_ci preopens: { 161cb0ef41Sopenharmony_ci '/sandbox': process.argv[4], 171cb0ef41Sopenharmony_ci '/tmp': process.argv[5], 181cb0ef41Sopenharmony_ci }, 191cb0ef41Sopenharmony_ci }); 201cb0ef41Sopenharmony_ci const importObject = { wasi_snapshot_preview1: wasi.wasiImport }; 211cb0ef41Sopenharmony_ci const modulePath = path.join(wasmDir, `${process.argv[3]}.wasm`); 221cb0ef41Sopenharmony_ci const buffer = fs.readFileSync(modulePath); 231cb0ef41Sopenharmony_ci 241cb0ef41Sopenharmony_ci (async () => { 251cb0ef41Sopenharmony_ci const { instance } = await WebAssembly.instantiate(buffer, importObject); 261cb0ef41Sopenharmony_ci 271cb0ef41Sopenharmony_ci wasi.start(instance); 281cb0ef41Sopenharmony_ci })().then(common.mustCall()); 291cb0ef41Sopenharmony_ci} else { 301cb0ef41Sopenharmony_ci if (!common.canCreateSymLink()) { 311cb0ef41Sopenharmony_ci common.skip('insufficient privileges'); 321cb0ef41Sopenharmony_ci } 331cb0ef41Sopenharmony_ci 341cb0ef41Sopenharmony_ci const assert = require('assert'); 351cb0ef41Sopenharmony_ci const cp = require('child_process'); 361cb0ef41Sopenharmony_ci const tmpdir = require('../common/tmpdir'); 371cb0ef41Sopenharmony_ci 381cb0ef41Sopenharmony_ci // Setup the sandbox environment. 391cb0ef41Sopenharmony_ci tmpdir.refresh(); 401cb0ef41Sopenharmony_ci const sandbox = path.join(tmpdir.path, 'sandbox'); 411cb0ef41Sopenharmony_ci const sandboxedFile = path.join(sandbox, 'input.txt'); 421cb0ef41Sopenharmony_ci const externalFile = path.join(tmpdir.path, 'outside.txt'); 431cb0ef41Sopenharmony_ci const sandboxedDir = path.join(sandbox, 'subdir'); 441cb0ef41Sopenharmony_ci const sandboxedSymlink = path.join(sandboxedDir, 'input_link.txt'); 451cb0ef41Sopenharmony_ci const escapingSymlink = path.join(sandboxedDir, 'outside.txt'); 461cb0ef41Sopenharmony_ci const loopSymlink1 = path.join(sandboxedDir, 'loop1'); 471cb0ef41Sopenharmony_ci const loopSymlink2 = path.join(sandboxedDir, 'loop2'); 481cb0ef41Sopenharmony_ci const sandboxedTmp = path.join(tmpdir.path, 'tmp'); 491cb0ef41Sopenharmony_ci 501cb0ef41Sopenharmony_ci fs.mkdirSync(sandbox); 511cb0ef41Sopenharmony_ci fs.mkdirSync(sandboxedDir); 521cb0ef41Sopenharmony_ci fs.mkdirSync(sandboxedTmp); 531cb0ef41Sopenharmony_ci fs.writeFileSync(sandboxedFile, 'hello from input.txt', 'utf8'); 541cb0ef41Sopenharmony_ci fs.writeFileSync(externalFile, 'this should be inaccessible', 'utf8'); 551cb0ef41Sopenharmony_ci fs.symlinkSync(path.join('.', 'input.txt'), sandboxedSymlink, 'file'); 561cb0ef41Sopenharmony_ci fs.symlinkSync(path.join('..', 'outside.txt'), escapingSymlink, 'file'); 571cb0ef41Sopenharmony_ci fs.symlinkSync(path.join('subdir', 'loop2'), 581cb0ef41Sopenharmony_ci loopSymlink1, 'file'); 591cb0ef41Sopenharmony_ci fs.symlinkSync(path.join('subdir', 'loop1'), 601cb0ef41Sopenharmony_ci loopSymlink2, 'file'); 611cb0ef41Sopenharmony_ci 621cb0ef41Sopenharmony_ci function runWASI(options) { 631cb0ef41Sopenharmony_ci console.log('executing', options.test); 641cb0ef41Sopenharmony_ci const opts = { env: { ...process.env, NODE_DEBUG_NATIVE: 'wasi' } }; 651cb0ef41Sopenharmony_ci const child = cp.spawnSync(process.execPath, [ 661cb0ef41Sopenharmony_ci __filename, 671cb0ef41Sopenharmony_ci 'wasi-child', 681cb0ef41Sopenharmony_ci options.test, 691cb0ef41Sopenharmony_ci sandbox, 701cb0ef41Sopenharmony_ci sandboxedTmp, 711cb0ef41Sopenharmony_ci ], opts); 721cb0ef41Sopenharmony_ci console.log(child.stderr.toString()); 731cb0ef41Sopenharmony_ci assert.strictEqual(child.status, 0); 741cb0ef41Sopenharmony_ci assert.strictEqual(child.signal, null); 751cb0ef41Sopenharmony_ci assert.strictEqual(child.stdout.toString(), options.stdout || ''); 761cb0ef41Sopenharmony_ci } 771cb0ef41Sopenharmony_ci 781cb0ef41Sopenharmony_ci runWASI({ test: 'create_symlink', stdout: 'hello from input.txt' }); 791cb0ef41Sopenharmony_ci runWASI({ test: 'follow_symlink', stdout: 'hello from input.txt' }); 801cb0ef41Sopenharmony_ci runWASI({ test: 'link' }); 811cb0ef41Sopenharmony_ci runWASI({ test: 'symlink_escape' }); 821cb0ef41Sopenharmony_ci runWASI({ test: 'symlink_loop' }); 831cb0ef41Sopenharmony_ci} 84