Skip to content

Commit ec33379

Browse files
davedoesdevmhdawson
authored andcommitted
Fix crash due to ObjectWrap copying CallbackInfo
PR-URL: #125 Reviewed-By: Anna Henningsen <[email protected]> Reviewed-By: Michael Dawson <[email protected]>
1 parent 749f1ac commit ec33379

File tree

7 files changed

+66
-2
lines changed

7 files changed

+66
-2
lines changed

napi-inl.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2288,7 +2288,7 @@ inline PropertyDescriptor::operator const napi_property_descriptor&() const {
22882288
////////////////////////////////////////////////////////////////////////////////
22892289

22902290
template <typename T>
2291-
inline ObjectWrap<T>::ObjectWrap(Napi::CallbackInfo callbackInfo) {
2291+
inline ObjectWrap<T>::ObjectWrap(const Napi::CallbackInfo& callbackInfo) {
22922292
napi_env env = callbackInfo.Env();
22932293
napi_value wrapper = callbackInfo.This();
22942294
napi_status status;

napi.h

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1125,6 +1125,10 @@ namespace Napi {
11251125
CallbackInfo(napi_env env, napi_callback_info info);
11261126
~CallbackInfo();
11271127

1128+
// Disallow copying to prevent multiple free of _dynamicArgs
1129+
CallbackInfo(CallbackInfo const &) = delete;
1130+
void operator=(CallbackInfo const &) = delete;
1131+
11281132
Napi::Env Env() const;
11291133
Value NewTarget() const;
11301134
bool IsConstructCall() const;
@@ -1279,7 +1283,7 @@ namespace Napi {
12791283
template <typename T>
12801284
class ObjectWrap : public Reference<Object> {
12811285
public:
1282-
ObjectWrap(CallbackInfo callbackInfo);
1286+
ObjectWrap(const CallbackInfo& callbackInfo);
12831287

12841288
static T* Unwrap(Object wrapper);
12851289

test/binding.cc

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ Object InitFunction(Env env);
1111
Object InitName(Env env);
1212
Object InitObject(Env env);
1313
Object InitTypedArray(Env env);
14+
Object InitObjectWrap(Env env);
1415

1516
void Init(Env env, Object exports, Object module) {
1617
exports.Set("arraybuffer", InitArrayBuffer(env));
@@ -22,6 +23,7 @@ void Init(Env env, Object exports, Object module) {
2223
exports.Set("name", InitName(env));
2324
exports.Set("object", InitObject(env));
2425
exports.Set("typedarray", InitTypedArray(env));
26+
exports.Set("objectwrap", InitObjectWrap(env));
2527
}
2628

2729
NODE_API_MODULE(addon, Init)

test/binding.gyp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@
1111
'name.cc',
1212
'object.cc',
1313
'typedarray.cc',
14+
'objectwrap.cc',
1415
],
1516
'include_dirs': ["<!@(node -p \"require('../').include\")"],
1617
'dependencies': ["<!(node -p \"require('../').gyp\")"],

test/index.js

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ let testModules = [
1010
'name',
1111
'object',
1212
'typedarray',
13+
'objectwrap'
1314
];
1415

1516
if (typeof global.gc === 'function') {

test/objectwrap.cc

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
#include <napi.h>
2+
3+
class Test : public Napi::ObjectWrap<Test> {
4+
public:
5+
Test(const Napi::CallbackInfo& info) :
6+
Napi::ObjectWrap<Test>(info) {
7+
}
8+
9+
void Set(const Napi::CallbackInfo& info) {
10+
value = info[0].As<Napi::Number>();
11+
}
12+
13+
Napi::Value Get(const Napi::CallbackInfo& info) {
14+
return Napi::Number::New(info.Env(), value);
15+
}
16+
17+
static void Initialize(Napi::Env env, Napi::Object exports) {
18+
exports.Set("Test", DefineClass(env, "Test", {
19+
InstanceMethod("test_set", &Test::Set),
20+
InstanceMethod("test_get", &Test::Get)
21+
}));
22+
}
23+
24+
private:
25+
uint32_t value;
26+
};
27+
28+
Napi::Object InitObjectWrap(Napi::Env env) {
29+
Napi::Object exports = Napi::Object::New(env);
30+
Test::Initialize(env, exports);
31+
return exports;
32+
}

test/objectwrap.js

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
'use strict';
2+
const buildType = process.config.target_defaults.default_configuration;
3+
const assert = require('assert');
4+
5+
test(require(`./build/${buildType}/binding.node`));
6+
test(require(`./build/${buildType}/binding_noexcept.node`));
7+
8+
function test(binding) {
9+
var Test = binding.objectwrap.Test;
10+
11+
function testSetGet(obj) {
12+
obj.test_set(90);
13+
assert.strictEqual(obj.test_get(), 90);
14+
}
15+
16+
function testObj(obj) {
17+
testSetGet(obj);
18+
}
19+
20+
testObj(new Test());
21+
testObj(new Test(1));
22+
testObj(new Test(1, 2, 3, 4, 5, 6));
23+
testObj(new Test(1, 2, 3, 4, 5, 6, 7));
24+
}

0 commit comments

Comments
 (0)