Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

wasi: clean up options validation #31797

Closed
Closed
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
60 changes: 25 additions & 35 deletions lib/wasi.js
@@ -1,7 +1,6 @@
'use strict';
/* global WebAssembly */
const {
ArrayIsArray,
ArrayPrototypeMap,
ArrayPrototypePush,
FunctionPrototypeBind,
Expand All @@ -14,6 +13,11 @@ const {
ERR_WASI_ALREADY_STARTED
} = require('internal/errors').codes;
const { emitExperimentalWarning } = require('internal/util');
const {
validateArray,
validateBoolean,
validateObject,
} = require('internal/validators');
const { WASI: _WASI } = internalBinding('wasi');
const kExitCode = Symbol('exitCode');
const kSetMemory = Symbol('setMemory');
Expand All @@ -24,52 +28,39 @@ emitExperimentalWarning('WASI');

class WASI {
constructor(options = {}) {
if (options === null || typeof options !== 'object')
throw new ERR_INVALID_ARG_TYPE('options', 'object', options);

const { env, preopens, returnOnExit = false } = options;
let { args = [] } = options;
validateObject(options, 'options');

if (ArrayIsArray(args))
args = ArrayPrototypeMap(args, (arg) => { return String(arg); });
else
throw new ERR_INVALID_ARG_TYPE('options.args', 'Array', args);
if (options.args !== undefined)
validateArray(options.args, 'options.args');
const args = ArrayPrototypeMap(options.args || [], String);

const envPairs = [];

if (env !== null && typeof env === 'object') {
for (const key in env) {
const value = env[key];
const env = [];
if (options.env !== undefined) {
validateObject(options.env, 'options.env');
for (const [key, value] of ObjectEntries(options.env)) {
if (value !== undefined)
ArrayPrototypePush(envPairs, `${key}=${value}`);
ArrayPrototypePush(env, `${key}=${value}`);
}
} else if (env !== undefined) {
throw new ERR_INVALID_ARG_TYPE('options.env', 'Object', env);
}

const preopenArray = [];

if (typeof preopens === 'object' && preopens !== null) {
for (const [key, value] of ObjectEntries(preopens)) {
ArrayPrototypePush(preopenArray, String(key), String(value));
const preopens = [];
if (options.preopens !== undefined) {
validateObject(options.preopens, 'options.preopens');
for (const [key, value] of ObjectEntries(options.preopens)) {
ArrayPrototypePush(preopens, String(key), String(value));
}
} else if (preopens !== undefined) {
throw new ERR_INVALID_ARG_TYPE('options.preopens', 'Object', preopens);
}

if (typeof returnOnExit !== 'boolean') {
throw new ERR_INVALID_ARG_TYPE(
'options.returnOnExit', 'boolean', returnOnExit);
}

const wrap = new _WASI(args, envPairs, preopenArray);
const wrap = new _WASI(args, env, preopens);

for (const prop in wrap) {
wrap[prop] = FunctionPrototypeBind(wrap[prop], wrap);
}

if (returnOnExit) {
wrap.proc_exit = FunctionPrototypeBind(wasiReturnOnProcExit, this);
if (options.returnOnExit !== undefined) {
validateBoolean(options.returnOnExit, 'options.returnOnExit');
if (options.returnOnExit)
wrap.proc_exit = FunctionPrototypeBind(wasiReturnOnProcExit, this);
}

this[kSetMemory] = wrap._setMemory;
Expand All @@ -87,8 +78,7 @@ class WASI {

const exports = instance.exports;

if (exports === null || typeof exports !== 'object')
throw new ERR_INVALID_ARG_TYPE('instance.exports', 'Object', exports);
validateObject(exports, 'instance.exports');

const { memory } = exports;

Expand Down