Skip to content
This repository was archived by the owner on Oct 15, 2020. It is now read-only.

Commit 9ab193b

Browse files
committed
n-api: update napi_wrap error behavior
The `napi_wrap` function is expected to return an error if a wrapped object is passed to it. A given object can only be wrapped once. PR-URL: #336 Reviewed-By: Kunal Pathak <kunal.pathak@microsoft.com>
1 parent cbfb520 commit 9ab193b

File tree

1 file changed

+32
-12
lines changed

1 file changed

+32
-12
lines changed

src/node_api_jsrt.cc

Lines changed: 32 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -288,6 +288,31 @@ JsNameValueFromPropertyDescriptor(const napi_property_descriptor* p,
288288
}
289289
return napi_ok;
290290
}
291+
292+
inline napi_status FindWrapper(JsValueRef obj, JsValueRef* result) {
293+
// Search the object's prototype chain for the wrapper with external data.
294+
// Usually the wrapper would be the first in the chain, but it is OK for
295+
// other objects to be inserted in the prototype chain.
296+
JsValueRef wrapper = obj;
297+
bool hasExternalData = false;
298+
299+
JsValueRef nullValue = JS_INVALID_REFERENCE;
300+
CHECK_JSRT(JsGetNullValue(&nullValue));
301+
302+
do {
303+
CHECK_JSRT(JsGetPrototype(wrapper, &wrapper));
304+
if (wrapper == JS_INVALID_REFERENCE || wrapper == nullValue) {
305+
*result = JS_INVALID_REFERENCE;
306+
return napi_ok;
307+
}
308+
309+
CHECK_JSRT(JsHasExternalData(wrapper, &hasExternalData));
310+
} while (!hasExternalData);
311+
312+
*result = wrapper;
313+
return napi_ok;
314+
}
315+
291316
} // end of namespace jsrtimpl
292317

293318
// Intercepts the Node-V8 module registration callback. Converts parameters
@@ -1351,6 +1376,10 @@ napi_status napi_wrap(napi_env env,
13511376
napi_ref* result) {
13521377
JsValueRef value = reinterpret_cast<JsValueRef>(js_object);
13531378

1379+
JsValueRef wrapper = JS_INVALID_REFERENCE;
1380+
CHECK_NAPI(jsrtimpl::FindWrapper(value, &wrapper));
1381+
RETURN_STATUS_IF_FALSE(wrapper == JS_INVALID_REFERENCE, napi_invalid_arg);
1382+
13541383
jsrtimpl::ExternalData* externalData = new jsrtimpl::ExternalData(
13551384
env, native_object, finalize_cb, finalize_hint);
13561385
if (externalData == nullptr) return napi_set_last_error(napi_generic_failure);
@@ -1376,18 +1405,9 @@ napi_status napi_wrap(napi_env env,
13761405
napi_status napi_unwrap(napi_env env, napi_value js_object, void** result) {
13771406
JsValueRef value = reinterpret_cast<JsValueRef>(js_object);
13781407

1379-
// Search the object's prototype chain for the wrapper with external data.
1380-
// Usually the wrapper would be the first in the chain, but it is OK for
1381-
// other objects to be inserted in the prototype chain.
1382-
JsValueRef wrapper = value;
1383-
bool hasExternalData = false;
1384-
do {
1385-
CHECK_JSRT(JsGetPrototype(wrapper, &wrapper));
1386-
if (wrapper == JS_INVALID_REFERENCE) {
1387-
return napi_invalid_arg;
1388-
}
1389-
CHECK_JSRT(JsHasExternalData(wrapper, &hasExternalData));
1390-
} while (!hasExternalData);
1408+
JsValueRef wrapper = JS_INVALID_REFERENCE;
1409+
CHECK_NAPI(jsrtimpl::FindWrapper(value, &wrapper));
1410+
RETURN_STATUS_IF_FALSE(wrapper != JS_INVALID_REFERENCE, napi_invalid_arg);
13911411

13921412
jsrtimpl::ExternalData* externalData;
13931413
CHECK_JSRT(JsGetExternalData(

0 commit comments

Comments
 (0)