From c46df1569b362bc52a1c3b08703ee967cbbf422b Mon Sep 17 00:00:00 2001 From: cjihrig Date: Sun, 22 Sep 2019 23:51:51 -0400 Subject: [PATCH] wasi: make preopen directories configurable --- lib/wasi.js | 19 ++++++++++--------- src/node_wasi.cc | 25 ++++++++++++++++++------- test/wasi/c/read_file.c | 3 ++- test/wasi/test-wasi.js | 9 ++++++++- test/wasi/wasm/read_file.wasm | Bin 34918 -> 34932 bytes 5 files changed, 38 insertions(+), 18 deletions(-) diff --git a/lib/wasi.js b/lib/wasi.js index 1ddf55a26b..620d0ee422 100644 --- a/lib/wasi.js +++ b/lib/wasi.js @@ -2,7 +2,7 @@ // TODO(cjihrig): Provide a mechanism to bind to WASM modules. 'use strict'; /* global WebAssembly */ -const { Array, ArrayPrototype } = primordials; +const { Array, ArrayPrototype, Object } = primordials; const { ERR_INVALID_ARG_TYPE } = require('internal/errors').codes; const { WASI: _WASI } = internalBinding('wasi'); const kSetMemory = Symbol('setMemory'); @@ -35,17 +35,18 @@ class WASI { throw new ERR_INVALID_ARG_TYPE('options.env', 'Object', env); } - if (preopens == null) { - preopens = null; - } else if (typeof preopens !== 'object') { + const preopenArray = []; + + if (typeof preopens === 'object' && preopens !== null) { + Object.keys(preopens).forEach((key) => { + preopenArray.push(String(key)); + preopenArray.push(String(preopens[key])); + }); + } else if (preopens !== undefined) { throw new ERR_INVALID_ARG_TYPE('options.preopens', 'Object', preopens); - } else { - // } - // TODO(cjihrig): Validate preopen object schema. - - const wrap = new _WASI(args, envPairs, preopens); + const wrap = new _WASI(args, envPairs, preopenArray); for (const prop in wrap) { wrap[prop] = wrap[prop].bind(wrap); diff --git a/src/node_wasi.cc b/src/node_wasi.cc index 9621b2d3ae..deb89e5d40 100644 --- a/src/node_wasi.cc +++ b/src/node_wasi.cc @@ -81,7 +81,7 @@ void WASI::New(const FunctionCallbackInfo& args) { CHECK_EQ(args.Length(), 3); CHECK(args[0]->IsArray()); CHECK(args[1]->IsArray()); - // CHECK(args[2]->IsArray()); + CHECK(args[2]->IsArray()); Environment* env = Environment::GetCurrent(args); Local context = env->context(); @@ -113,12 +113,23 @@ void WASI::New(const FunctionCallbackInfo& args) { } options.envp[envc] = nullptr; - // TODO(cjihrig): Process the preopens for real. - options.preopenc = 1; - options.preopens = - static_cast(calloc(1, sizeof(uvwasi_preopen_t))); - options.preopens[0].mapped_path = "/sandbox"; - options.preopens[0].real_path = "."; + Local preopens = args[2].As(); + CHECK_EQ(preopens->Length() % 2, 0); + options.preopenc = preopens->Length() / 2; + options.preopens = static_cast( + calloc(options.preopenc, sizeof(uvwasi_preopen_t))); + int index = 0; + for (uint32_t i = 0; i < preopens->Length(); i += 2) { + auto mapped = preopens->Get(context, i).ToLocalChecked(); + auto real = preopens->Get(context, i + 1).ToLocalChecked(); + CHECK(mapped->IsString()); + CHECK(real->IsString()); + node::Utf8Value mapped_path(env->isolate(), mapped); + node::Utf8Value real_path(env->isolate(), real); + options.preopens[index].mapped_path = strdup(*mapped_path); + options.preopens[index].real_path = strdup(*real_path); + index++; + } new WASI(env, args.This(), &options); diff --git a/test/wasi/c/read_file.c b/test/wasi/c/read_file.c index f744a63596..40023e29e2 100644 --- a/test/wasi/c/read_file.c +++ b/test/wasi/c/read_file.c @@ -7,7 +7,8 @@ int main() { char c = fgetc(file); while (c != EOF) { - assert(fputc(c, stdout) != EOF); + int wrote = fputc(c, stdout); + assert(wrote != EOF); c = fgetc(file); } } diff --git a/test/wasi/test-wasi.js b/test/wasi/test-wasi.js index 629ac937a9..339d25cd37 100644 --- a/test/wasi/test-wasi.js +++ b/test/wasi/test-wasi.js @@ -2,11 +2,18 @@ require('../common'); if (process.argv[2] === 'wasi-child') { + const fixtures = require('../common/fixtures'); const fs = require('fs'); const path = require('path'); const { WASI } = require('wasi'); const wasmDir = path.join(__dirname, 'wasm'); - const wasi = new WASI({ args: [], env: process.env }); + const wasi = new WASI({ + args: [], + env: process.env, + preopens: { + '/sandbox': fixtures.path('wasi') + } + }); const importObject = { wasi_unstable: wasi.wasiImport }; const modulePath = path.join(wasmDir, `${process.argv[3]}.wasm`); const buffer = fs.readFileSync(modulePath); diff --git a/test/wasi/wasm/read_file.wasm b/test/wasi/wasm/read_file.wasm index 68d2cd36a196b8261b9267776d8297a8ddcd6117..2b9db77d272618e47d8070f3515fdb8f84e97d78 100755 GIT binary patch delta 256 zcmaDhf$7TxrVVSE7@uuk$8?&Jv%XDaQH_9Ssc(ipmO#3d#aI8$fIo1ttX* zGbRQFCJiPAMO6h=MKuLkMRf%=1$B2t4M#>rO$7}F%|b;jCIb%o`SZ5j)Ja&p1@*|$qd{eBRLfH74!vGfUPo6P-9Xsuwr26Vc-T!@+cZQ z3Md)@U0{@@XslqY0#w$(pkTOJk4;65@zCaAo!d-|M>gy0H*qmO-@M7Pm67rFW((^H aHmv1E`6a27Z&f zM?qI$F~}?iZUrU{CJseC1wDZkV8itlm=yG_7}$9jxWRG~JcDtaL1eRhMW_G(Y^p(A