From 1eed2637265f1f0a8b2bc3fd2b073cec3ff4f1ad Mon Sep 17 00:00:00 2001 From: Jason Ginchereau Date: Wed, 31 May 2017 10:39:26 -0700 Subject: [PATCH] Handle prototype chain insertions --- src/node_api_jsrt.cc | 21 ++++++++++++++------- 1 file changed, 14 insertions(+), 7 deletions(-) diff --git a/src/node_api_jsrt.cc b/src/node_api_jsrt.cc index 17a0bfd2e42..a7b12ae89f0 100644 --- a/src/node_api_jsrt.cc +++ b/src/node_api_jsrt.cc @@ -1375,15 +1375,22 @@ napi_status napi_wrap(napi_env env, napi_status napi_unwrap(napi_env env, napi_value js_object, void** result) { JsValueRef value = reinterpret_cast(js_object); - // A wrapper value's prototype should be an external value. - JsValueRef external; - CHECK_JSRT(JsGetPrototype(value, &external)); + // Search the object's prototype chain for the wrapper with external data. + // Usually the wrapper would be the first in the chain, but it is OK for + // other objects to be inserted in the prototype chain. + JsValueRef wrapper = value; + bool hasExternalData = false; + do { + CHECK_JSRT(JsGetPrototype(wrapper, &wrapper)); + if (wrapper == nullptr) { + return napi_invalid_arg; + } + CHECK_JSRT(JsHasExternalData(wrapper, &hasExternalData)); + } while (!hasExternalData); jsrtimpl::ExternalData* externalData; - if (external == nullptr || JsNoError != - JsGetExternalData(external, reinterpret_cast(&externalData))) { - externalData = nullptr; - } + CHECK_JSRT(JsGetExternalData( + wrapper, reinterpret_cast(&externalData))); *result = (externalData != nullptr ? externalData->Data() : nullptr);