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: nodejs#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 <michael_dawson@ca.ibm.com>
  • Loading branch information
mhdawson committed May 13, 2020
1 parent 45cb1d9 commit 8385d0c
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 @@ -54,6 +54,7 @@ Object InitObjectWrap(Env env);
Object InitObjectWrapConstructorException(Env env);
Object InitObjectWrapRemoveWrap(Env env);
Object InitObjectReference(Env env);
Object InitReference(Env env);
Object InitVersionManagement(Env env);
Object InitThunkingManual(Env env);

Expand Down Expand Up @@ -112,6 +113,7 @@ Object Init(Env env, Object exports) {
InitObjectWrapConstructorException(env));
exports.Set("objectwrap_removewrap", InitObjectWrapRemoveWrap(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 @@ -46,6 +46,7 @@
'objectwrap_constructor_exception.cc',
'objectwrap-removewrap.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 @@ -54,6 +54,7 @@ let testModules = [
'objectwrap_constructor_exception',
'objectwrap-removewrap',
'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 8385d0c

Please sign in to comment.