Skip to content

Commit

Permalink
src: return bool on object freeze and seal (nodejs#991)
Browse files Browse the repository at this point in the history
These operations can call into JavaScript by using Proxy handlers,
hence JavaScript exceptions might pending at the end of the operations.
  • Loading branch information
legendecas authored and Deepak Rajamohan committed Sep 23, 2021
1 parent 61236ef commit 5920f57
Show file tree
Hide file tree
Showing 5 changed files with 40 additions and 14 deletions.
10 changes: 6 additions & 4 deletions napi-inl.h
Original file line number Diff line number Diff line change
Expand Up @@ -1389,14 +1389,16 @@ inline void Object::AddFinalizer(Finalizer finalizeCallback,
}

#if NAPI_VERSION >= 8
inline void Object::Freeze() {
inline bool Object::Freeze() {
napi_status status = napi_object_freeze(_env, _value);
NAPI_THROW_IF_FAILED_VOID(_env, status);
NAPI_THROW_IF_FAILED(_env, status, false);
return true;
}

inline void Object::Seal() {
inline bool Object::Seal() {
napi_status status = napi_object_seal(_env, _value);
NAPI_THROW_IF_FAILED_VOID(_env, status);
NAPI_THROW_IF_FAILED(_env, status, false);
return true;
}
#endif // NAPI_VERSION >= 8

Expand Down
4 changes: 2 additions & 2 deletions napi.h
Original file line number Diff line number Diff line change
Expand Up @@ -773,8 +773,8 @@ namespace Napi {
T* data,
Hint* finalizeHint);
#if NAPI_VERSION >= 8
void Freeze();
void Seal();
bool Freeze();
bool Seal();
#endif // NAPI_VERSION >= 8
};

Expand Down
4 changes: 2 additions & 2 deletions test/common/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -76,7 +76,7 @@ exports.mustNotCall = function(msg) {
};

exports.runTest = async function(test, buildType) {
buildType = buildType || process.config.target_defaults.default_configuration;
buildType = buildType || process.config.target_defaults.default_configuration || 'Release';

const bindings = [
`../build/${buildType}/binding.node`,
Expand All @@ -90,7 +90,7 @@ exports.runTest = async function(test, buildType) {
}

exports.runTestWithBindingPath = async function(test, buildType) {
buildType = buildType || process.config.target_defaults.default_configuration;
buildType = buildType || process.config.target_defaults.default_configuration || 'Release';

const bindings = [
`../build/${buildType}/binding.node`,
Expand Down
8 changes: 4 additions & 4 deletions test/object/object_freeze_seal.cc
Original file line number Diff line number Diff line change
Expand Up @@ -4,14 +4,14 @@

using namespace Napi;

void Freeze(const CallbackInfo& info) {
Value Freeze(const CallbackInfo& info) {
Object obj = info[0].As<Object>();
obj.Freeze();
return Boolean::New(info.Env(), obj.Freeze());
}

void Seal(const CallbackInfo& info) {
Value Seal(const CallbackInfo& info) {
Object obj = info[0].As<Object>();
obj.Seal();
return Boolean::New(info.Env(), obj.Seal());
}

Object InitObjectFreezeSeal(Env env) {
Expand Down
28 changes: 26 additions & 2 deletions test/object/object_freeze_seal.js
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ module.exports = require('../common').runTest(test);
function test(binding) {
{
const obj = { x: 'a', y: 'b', z: 'c' };
binding.object_freeze_seal.freeze(obj);
assert.strictEqual(binding.object_freeze_seal.freeze(obj), true);
assert.strictEqual(Object.isFrozen(obj), true);
assert.throws(() => {
obj.x = 10;
Expand All @@ -20,9 +20,21 @@ function test(binding) {
}, /Cannot delete property 'x' of #<Object>/);
}

{
const obj = new Proxy({ x: 'a', y: 'b', z: 'c' }, {
preventExtensions() {
throw new Error('foo');
},
});

assert.throws(() => {
binding.object_freeze_seal.freeze(obj);
}, /foo/);
}

{
const obj = { x: 'a', y: 'b', z: 'c' };
binding.object_freeze_seal.seal(obj);
assert.strictEqual(binding.object_freeze_seal.seal(obj), true);
assert.strictEqual(Object.isSealed(obj), true);
assert.throws(() => {
obj.w = 'd';
Expand All @@ -34,4 +46,16 @@ function test(binding) {
// so this should not throw.
obj.x = 'd';
}

{
const obj = new Proxy({ x: 'a', y: 'b', z: 'c' }, {
preventExtensions() {
throw new Error('foo');
},
});

assert.throws(() => {
binding.object_freeze_seal.seal(obj);
}, /foo/);
}
}

0 comments on commit 5920f57

Please sign in to comment.