From d93a96f2d579bca5d66d3742b7e581e5ab1224d1 Mon Sep 17 00:00:00 2001 From: Taylor Woll Date: Wed, 24 Oct 2018 17:32:34 -0700 Subject: [PATCH] chakrashim: fix CheckSignature to look up the prototype chain --- deps/chakrashim/src/v8signature.cc | 26 +++++++++++++++++++++----- 1 file changed, 21 insertions(+), 5 deletions(-) diff --git a/deps/chakrashim/src/v8signature.cc b/deps/chakrashim/src/v8signature.cc index fa637e32839..9b439ecaa0b 100644 --- a/deps/chakrashim/src/v8signature.cc +++ b/deps/chakrashim/src/v8signature.cc @@ -39,16 +39,32 @@ Local AccessorSignature::New( return reinterpret_cast(*receiver); } +bool InstanceOfButNotPrototypeObject(JsValueRef instance, + JsValueRef constructor) { + if (!jsrt::InstanceOf(instance, constructor)) { + return false; + } + + JsValueRef constructorProp; + JsValueRef prototypeProp; + if (jsrt::GetProperty(instance, "constructor", &constructorProp) == + JsNoError && + jsrt::GetProperty(constructorProp, "prototype", &prototypeProp) == + JsNoError && + prototypeProp == instance) { + return false; + } + + return true; +} + bool Utils::CheckSignature(Local receiver, Local thisPointer, Local* holder) { *holder = thisPointer; - Local receiverInstanceTemplate = receiver->InstanceTemplate(); - - // v8 signature check walks hidden prototype chain to find holder. Chakra - // doesn't support hidden prototypes. Just check the receiver itself. - bool matched = Utils::IsInstanceOf(*thisPointer, *receiverInstanceTemplate); + bool matched = + InstanceOfButNotPrototypeObject(*thisPointer, *receiver->GetFunction()); if (!matched) { const char txt[] = "Illegal invocation";