Skip to content

Commit 36e1af9

Browse files
committed
src: fix use of Reference with typed arrays
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]>
1 parent d463f02 commit 36e1af9

File tree

6 files changed

+51
-2
lines changed

6 files changed

+51
-2
lines changed

napi-inl.h

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1740,8 +1740,14 @@ inline TypedArrayOf<T>::TypedArrayOf() : TypedArray(), _data(nullptr) {
17401740
template <typename T>
17411741
inline TypedArrayOf<T>::TypedArrayOf(napi_env env, napi_value value)
17421742
: TypedArray(env, value), _data(nullptr) {
1743-
napi_status status = napi_get_typedarray_info(
1744-
_env, _value, &_type, &_length, reinterpret_cast<void**>(&_data), nullptr, nullptr);
1743+
napi_status status = napi_ok;
1744+
if (value != nullptr) {
1745+
status = napi_get_typedarray_info(
1746+
_env, _value, &_type, &_length, reinterpret_cast<void**>(&_data), nullptr, nullptr);
1747+
} else {
1748+
_type = TypedArrayTypeForPrimitiveType<T>();
1749+
_length = 0;
1750+
}
17451751
NAPI_THROW_IF_FAILED_VOID(_env, status);
17461752
}
17471753

test/binding.cc

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -55,6 +55,7 @@ Object InitObjectWrapConstructorException(Env env);
5555
Object InitObjectWrapRemoveWrap(Env env);
5656
Object InitObjectWrapMultipleInheritance(Env env);
5757
Object InitObjectReference(Env env);
58+
Object InitReference(Env env);
5859
Object InitVersionManagement(Env env);
5960
Object InitThunkingManual(Env env);
6061

@@ -114,6 +115,7 @@ Object Init(Env env, Object exports) {
114115
exports.Set("objectwrap_removewrap", InitObjectWrapRemoveWrap(env));
115116
exports.Set("objectwrap_multiple_inheritance", InitObjectWrapMultipleInheritance(env));
116117
exports.Set("objectreference", InitObjectReference(env));
118+
exports.Set("reference", InitReference(env));
117119
exports.Set("version_management", InitVersionManagement(env));
118120
exports.Set("thunking_manual", InitThunkingManual(env));
119121
return exports;

test/binding.gyp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,7 @@
4747
'objectwrap-removewrap.cc',
4848
'objectwrap_multiple_inheritance.cc',
4949
'objectreference.cc',
50+
'reference.cc',
5051
'version_management.cc',
5152
'thunking_manual.cc',
5253
],

test/index.js

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -55,6 +55,7 @@ let testModules = [
5555
'objectwrap-removewrap',
5656
'objectwrap_multiple_inheritance',
5757
'objectreference',
58+
'reference',
5859
'version_management'
5960
];
6061

test/reference.cc

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
#include "napi.h"
2+
3+
using namespace Napi;
4+
5+
static Reference<Buffer<uint8_t>> weak;
6+
7+
void CreateWeakArray(const CallbackInfo& info) {
8+
weak = Weak(Buffer<uint8_t>::New(info.Env(), 1));
9+
weak.SuppressDestruct();
10+
}
11+
12+
napi_value AccessWeakArrayEmpty(const CallbackInfo& info) {
13+
Buffer<uint8_t> value = weak.Value();
14+
return Napi::Boolean::New(info.Env(), value.IsEmpty());
15+
}
16+
17+
Object InitReference(Env env) {
18+
Object exports = Object::New(env);
19+
20+
exports["createWeakArray"] = Function::New(env, CreateWeakArray);
21+
exports["accessWeakArrayEmpty"] = Function::New(env, AccessWeakArrayEmpty);
22+
23+
return exports;
24+
}

test/reference.js

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
'use strict';
2+
3+
4+
const buildType = process.config.target_defaults.default_configuration;
5+
const assert = require('assert');
6+
const testUtil = require('./testUtil');
7+
8+
test(require(`./build/${buildType}/binding.node`));
9+
test(require(`./build/${buildType}/binding_noexcept.node`));
10+
11+
function test(binding) {
12+
binding.reference.createWeakArray();
13+
global.gc();
14+
assert.strictEqual(true, binding.reference.accessWeakArrayEmpty());
15+
};

0 commit comments

Comments
 (0)