Skip to content

Commit

Permalink
handle the case where the reference is not deleted in its destructor
Browse files Browse the repository at this point in the history
  • Loading branch information
Gabriel Schulhof committed Feb 11, 2021
1 parent 68dccb1 commit 55cfe37
Show file tree
Hide file tree
Showing 3 changed files with 30 additions and 7 deletions.
4 changes: 2 additions & 2 deletions src/js_native_api_v8.cc
Original file line number Diff line number Diff line change
Expand Up @@ -281,10 +281,10 @@ class RefBase : protected Finalizer, RefTracker {
// this is safe because if a request to delete the reference
// is made in the finalize_callback it will defer deletion
// to this block and set _delete_self to true
_finalize_ran = true;

if (_delete_self || is_env_teardown) {
Delete(this);
} else {
_finalize_ran = true;
}
}

Expand Down
3 changes: 2 additions & 1 deletion test/js-native-api/test_reference_double_free/test.js
Original file line number Diff line number Diff line change
Expand Up @@ -7,4 +7,5 @@ const { buildType } = require('../../common');

const addon = require(`./build/${buildType}/test_reference_double_free`);

{ new addon.MyObject(); }
{ new addon.MyObject(true); }
{ new addon.MyObject(false); }
Original file line number Diff line number Diff line change
Expand Up @@ -2,19 +2,41 @@
#include <js_native_api.h>
#include "../common.h"

static size_t g_call_count = 0;

static void Destructor(napi_env env, void* data, void* nothing) {
napi_ref* ref = data;
NODE_API_CALL_RETURN_VOID(env, napi_delete_reference(env, *ref));
free(ref);
}

static void NoDeleteDestructor(napi_env env, void* data, void* hint) {
napi_ref* ref = data;
size_t* call_count = hint;

// This destructor must be called exactly once.
if ((*call_count) > 0) abort();
*call_count = ((*call_count) + 1);
free(ref);
}

static napi_value New(napi_env env, napi_callback_info info) {
size_t argc = 0;
napi_value js_this;
size_t argc = 1;
napi_value js_this, js_delete;
bool delete;
napi_ref* ref = malloc(sizeof(*ref));

NODE_API_CALL(env, napi_get_cb_info(env, info, &argc, NULL, &js_this, NULL));
NODE_API_CALL(env, napi_wrap(env, js_this, ref, Destructor, NULL, ref));
NODE_API_CALL(env,
napi_get_cb_info(env, info, &argc, &js_delete, &js_this, NULL));
NODE_API_CALL(env, napi_get_value_bool(env, js_delete, &delete));

if (delete) {
NODE_API_CALL(env,
napi_wrap(env, js_this, ref, Destructor, NULL, ref));
} else {
NODE_API_CALL(env,
napi_wrap(env, js_this, ref, NoDeleteDestructor, &g_call_count, ref));
}
NODE_API_CALL(env, napi_reference_ref(env, *ref, NULL));

return js_this;
Expand Down

0 comments on commit 55cfe37

Please sign in to comment.