@@ -169,6 +169,7 @@ struct AsyncFuzzTargetContext {
169169
170170 std::thread native_thread;
171171 Napi::Promise::Deferred deferred;
172+ Napi::Reference<Napi::Value> deferred_rejection;
172173 LibAflOptions options;
173174 std::unique_ptr<ScopedLibAflRuntime> runtime_guard;
174175 bool is_resolved = false ;
@@ -190,13 +191,12 @@ AsyncFuzzTargetContext *gActiveAsyncContext = nullptr;
190191AsyncTsfn gAsyncTsfn ;
191192JazzerLibAflFindingInfo gFindingInfo {};
192193
193- void RejectDeferredIfNeeded (AsyncFuzzTargetContext *context,
194+ void StoreDeferredRejection (AsyncFuzzTargetContext *context,
194195 const Napi::Value &error) {
195- if (context->is_resolved ) {
196+ if (! context->deferred_rejection . IsEmpty () ) {
196197 return ;
197198 }
198- context->deferred .Reject (error);
199- context->is_resolved = true ;
199+ context->deferred_rejection = Napi::Persistent (error);
200200}
201201
202202void SettleLibAflRun (Napi::Env env, Napi::Promise::Deferred &deferred,
@@ -243,13 +243,29 @@ void ReportAsyncFinding(AsyncFuzzTargetContext *context, Napi::Env env,
243243 const std::shared_ptr<AsyncExecutionState> &state,
244244 const Napi::Value &error,
245245 const std::vector<uint8_t > &input) {
246+ StoreDeferredRejection (context, error);
246247 if (TrySetExecutionStatus (state, kExecutionFinding )) {
247248 const auto artifact =
248249 WriteArtifact (context->options .artifact_prefix , " crash" , input.data (),
249250 input.size (), false );
250251 RecordFindingInfo (&gFindingInfo , artifact, DescribeJsError (env, error));
251252 }
252- RejectDeferredIfNeeded (context, error);
253+ }
254+
255+ void SettleAsyncLibAflRun (Napi::Env env, AsyncFuzzTargetContext *context) {
256+ if (context->is_resolved ) {
257+ return ;
258+ }
259+
260+ if (!context->deferred_rejection .IsEmpty ()) {
261+ context->is_resolved = true ;
262+ context->deferred .Reject (context->deferred_rejection .Value ());
263+ context->deferred_rejection .Reset ();
264+ return ;
265+ }
266+
267+ SettleLibAflRun (env, context->deferred , context->is_resolved ,
268+ context->run_status );
253269}
254270
255271void StartSyncWatchdog (SyncFuzzTargetContext *context) {
@@ -424,8 +440,6 @@ void CallJsFuzzCallback(Napi::Env env, Napi::Function js_fuzz_callback,
424440 try {
425441 if (context->sigints > 0 ) {
426442 TrySetExecutionStatus (state, kExecutionStop );
427- context->deferred .Resolve (env.Undefined ());
428- context->is_resolved = true ;
429443 return ;
430444 }
431445
@@ -522,10 +536,11 @@ void CallJsFuzzCallback(Napi::Env env, Napi::Function js_fuzz_callback,
522536 } catch (const Napi::Error &error) {
523537 ReportAsyncFinding (context, env, state, error.Value (), current_input);
524538 } catch (const std::exception &exception) {
525- TrySetExecutionStatus (state, kExecutionFatal );
526- auto message =
527- std::string (" Internal fuzzer error - " ).append (exception.what ());
528- RejectDeferredIfNeeded (context, Napi::Error::New (env, message).Value ());
539+ if (TrySetExecutionStatus (state, kExecutionFatal )) {
540+ auto message =
541+ std::string (" Internal fuzzer error - " ).append (exception.what ());
542+ StoreDeferredRejection (context, Napi::Error::New (env, message).Value ());
543+ }
529544 }
530545}
531546
@@ -673,8 +688,10 @@ Napi::Value StartLibAflAsync(const Napi::CallbackInfo &info) {
673688 info.Env (), info[0 ].As <Napi::Function>(), " LibAflAsyncAddon" , 0 , 1 ,
674689 context.get (),
675690 [](Napi::Env env, AsyncFinalizerDataType *, AsyncFuzzTargetContext *ctx) {
691+ Napi::HandleScope scope (env);
676692 ctx->native_thread .join ();
677- SettleLibAflRun (env, ctx->deferred , ctx->is_resolved , ctx->run_status );
693+ ctx->runtime_guard .reset ();
694+ SettleAsyncLibAflRun (env, ctx);
678695 delete ctx;
679696 });
680697
0 commit comments