Skip to content

Commit

Permalink
wasi: throw on failed uvwasi_init()
Browse files Browse the repository at this point in the history
Prior to this commit, if uvwasi_init() failed in any way, Node
would abort due to a failed CHECK_EQ(). This commit changes
that behavior to a thrown exception.

PR-URL: #31076
Fixes: #30878
Reviewed-By: Jiawen Geng <technicalcute@gmail.com>
Reviewed-By: Anna Henningsen <anna@addaleax.net>
Reviewed-By: James M Snell <jasnell@gmail.com>
Reviewed-By: Chengzhong Wu <legendecas@gmail.com>
Reviewed-By: Rich Trott <rtrott@gmail.com>
  • Loading branch information
cjihrig committed Dec 26, 2019
1 parent 6e20674 commit 208453e
Show file tree
Hide file tree
Showing 2 changed files with 48 additions and 1 deletion.
44 changes: 43 additions & 1 deletion src/node_wasi.cc
Original file line number Diff line number Diff line change
Expand Up @@ -74,22 +74,64 @@ using v8::ArrayBuffer;
using v8::BackingStore;
using v8::BigInt;
using v8::Context;
using v8::Exception;
using v8::FunctionCallbackInfo;
using v8::FunctionTemplate;
using v8::Integer;
using v8::Isolate;
using v8::Local;
using v8::MaybeLocal;
using v8::Object;
using v8::String;
using v8::Uint32;
using v8::Value;


static MaybeLocal<Value> WASIException(Local<Context> context,
int errorno,
const char* syscall) {
Isolate* isolate = context->GetIsolate();
Environment* env = Environment::GetCurrent(context);
CHECK_NOT_NULL(env);
const char* err_name = uvwasi_embedder_err_code_to_string(errorno);
Local<String> js_code = OneByteString(isolate, err_name);
Local<String> js_syscall = OneByteString(isolate, syscall);
Local<String> js_msg = js_code;
js_msg =
String::Concat(isolate, js_msg, FIXED_ONE_BYTE_STRING(isolate, ", "));
js_msg = String::Concat(isolate, js_msg, js_syscall);
Local<Object> e =
Exception::Error(js_msg)->ToObject(context)
.ToLocalChecked();

if (e->Set(context,
env->errno_string(),
Integer::New(isolate, errorno)).IsNothing() ||
e->Set(context, env->code_string(), js_code).IsNothing() ||
e->Set(context, env->syscall_string(), js_syscall).IsNothing()) {
return MaybeLocal<Value>();
}

return e;
}


WASI::WASI(Environment* env,
Local<Object> object,
uvwasi_options_t* options) : BaseObject(env, object) {
MakeWeak();
alloc_info_ = MakeAllocator();
options->allocator = &alloc_info_;
CHECK_EQ(uvwasi_init(&uvw_, options), UVWASI_ESUCCESS);
int err = uvwasi_init(&uvw_, options);
if (err != UVWASI_ESUCCESS) {
Local<Context> context = env->context();
MaybeLocal<Value> exception = WASIException(context, err, "uvwasi_init");

if (exception.IsEmpty())
return;

context->GetIsolate()->ThrowException(exception.ToLocalChecked());
}
}


Expand Down
5 changes: 5 additions & 0 deletions test/wasi/test-wasi-options-validation.js
Original file line number Diff line number Diff line change
Expand Up @@ -26,3 +26,8 @@ assert.throws(() => { new WASI({ preopens: 'fhqwhgads' }); },
assert.throws(() => { new WASI(value); },
{ code: 'ERR_INVALID_ARG_TYPE' });
});

// Verify that exceptions thrown from the binding layer are handled.
assert.throws(() => {
new WASI({ preopens: { '/sandbox': '__/not/real/path' } });
}, { code: 'UVWASI_ENOENT', message: /uvwasi_init/ });

0 comments on commit 208453e

Please sign in to comment.