Skip to content

Commit

Permalink
src: fix use of Reference with typed arrays
Browse files Browse the repository at this point in the history
Fixes: #702

Previously calling Value() on a Reference for a TypedArray
that the enderlying object had been collected would result
in an error due to a failure in creating the return value.

Signed-off-by: Michael Dawson <[email protected]>

PR-URL: #726
Fixes: #702
Reviewed-By: Chengzhong Wu <[email protected]>
  • Loading branch information
mhdawson committed Jun 9, 2020
1 parent d463f02 commit 36e1af9
Show file tree
Hide file tree
Showing 6 changed files with 51 additions and 2 deletions.
10 changes: 8 additions & 2 deletions napi-inl.h
Original file line number Diff line number Diff line change
Expand Up @@ -1740,8 +1740,14 @@ inline TypedArrayOf<T>::TypedArrayOf() : TypedArray(), _data(nullptr) {
template <typename T>
inline TypedArrayOf<T>::TypedArrayOf(napi_env env, napi_value value)
: TypedArray(env, value), _data(nullptr) {
napi_status status = napi_get_typedarray_info(
_env, _value, &_type, &_length, reinterpret_cast<void**>(&_data), nullptr, nullptr);
napi_status status = napi_ok;
if (value != nullptr) {
status = napi_get_typedarray_info(
_env, _value, &_type, &_length, reinterpret_cast<void**>(&_data), nullptr, nullptr);
} else {
_type = TypedArrayTypeForPrimitiveType<T>();
_length = 0;
}
NAPI_THROW_IF_FAILED_VOID(_env, status);
}

Expand Down
2 changes: 2 additions & 0 deletions test/binding.cc
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,7 @@ Object InitObjectWrapConstructorException(Env env);
Object InitObjectWrapRemoveWrap(Env env);
Object InitObjectWrapMultipleInheritance(Env env);
Object InitObjectReference(Env env);
Object InitReference(Env env);
Object InitVersionManagement(Env env);
Object InitThunkingManual(Env env);

Expand Down Expand Up @@ -114,6 +115,7 @@ Object Init(Env env, Object exports) {
exports.Set("objectwrap_removewrap", InitObjectWrapRemoveWrap(env));
exports.Set("objectwrap_multiple_inheritance", InitObjectWrapMultipleInheritance(env));
exports.Set("objectreference", InitObjectReference(env));
exports.Set("reference", InitReference(env));
exports.Set("version_management", InitVersionManagement(env));
exports.Set("thunking_manual", InitThunkingManual(env));
return exports;
Expand Down
1 change: 1 addition & 0 deletions test/binding.gyp
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,7 @@
'objectwrap-removewrap.cc',
'objectwrap_multiple_inheritance.cc',
'objectreference.cc',
'reference.cc',
'version_management.cc',
'thunking_manual.cc',
],
Expand Down
1 change: 1 addition & 0 deletions test/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,7 @@ let testModules = [
'objectwrap-removewrap',
'objectwrap_multiple_inheritance',
'objectreference',
'reference',
'version_management'
];

Expand Down
24 changes: 24 additions & 0 deletions test/reference.cc
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
#include "napi.h"

using namespace Napi;

static Reference<Buffer<uint8_t>> weak;

void CreateWeakArray(const CallbackInfo& info) {
weak = Weak(Buffer<uint8_t>::New(info.Env(), 1));
weak.SuppressDestruct();
}

napi_value AccessWeakArrayEmpty(const CallbackInfo& info) {
Buffer<uint8_t> value = weak.Value();
return Napi::Boolean::New(info.Env(), value.IsEmpty());
}

Object InitReference(Env env) {
Object exports = Object::New(env);

exports["createWeakArray"] = Function::New(env, CreateWeakArray);
exports["accessWeakArrayEmpty"] = Function::New(env, AccessWeakArrayEmpty);

return exports;
}
15 changes: 15 additions & 0 deletions test/reference.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
'use strict';


const buildType = process.config.target_defaults.default_configuration;
const assert = require('assert');
const testUtil = require('./testUtil');

test(require(`./build/${buildType}/binding.node`));
test(require(`./build/${buildType}/binding_noexcept.node`));

function test(binding) {
binding.reference.createWeakArray();
global.gc();
assert.strictEqual(true, binding.reference.accessWeakArrayEmpty());
};

0 comments on commit 36e1af9

Please sign in to comment.