From 88db0108b14d58cf5d82ed7346f48f010feaaf0d Mon Sep 17 00:00:00 2001 From: wolfbeast Date: Thu, 7 Feb 2019 10:39:40 +0100 Subject: Align `instanceof` with the final ES6 spec. --- js/xpconnect/wrappers/WaiveXrayWrapper.cpp | 31 ++++++++++++++++++++++++++++++ 1 file changed, 31 insertions(+) (limited to 'js/xpconnect/wrappers/WaiveXrayWrapper.cpp') diff --git a/js/xpconnect/wrappers/WaiveXrayWrapper.cpp b/js/xpconnect/wrappers/WaiveXrayWrapper.cpp index 27c010d34..dca3daa58 100644 --- a/js/xpconnect/wrappers/WaiveXrayWrapper.cpp +++ b/js/xpconnect/wrappers/WaiveXrayWrapper.cpp @@ -87,6 +87,37 @@ WaiveXrayWrapper::nativeCall(JSContext* cx, JS::IsAcceptableThis test, WrapperFactory::WaiveXrayAndWrap(cx, args.rval()); } +bool +WaiveXrayWrapper::hasInstance(JSContext* cx, HandleObject wrapper, + MutableHandleValue v, bool* bp) const { + if (v.isObject() && WrapperFactory::IsXrayWrapper(&v.toObject())) { + // If |v| is an XrayWrapper and in the same compartment as the value + // wrapped by |wrapper|, then the Xrays of |v| would be waived upon + // calling CrossCompartmentWrapper::hasInstance. This may trigger + // getters and proxy traps of unwrapped |v|. To prevent that from + // happening, we exit early. + + // |wrapper| is the right operand of "instanceof", and must either be + // a function or an object with a @@hasInstance method. We are not going + // to call @@hasInstance, so only check whether it is a function. + // This check is here for consistency with usual "instanceof" behavior, + // which throws if the right operand is not a function. Without this + // check, the "instanceof" operator would return false and potentially + // hide errors in the code that uses the "instanceof" operator. + if (!JS::IsCallable(wrapper)) { + RootedValue wrapperv(cx, JS::ObjectValue(*wrapper)); + js::ReportIsNotFunction(cx, wrapperv); + return false; + } + + *bp = false; + return true; + } + + // Both |wrapper| and |v| have no Xrays here. + return CrossCompartmentWrapper::hasInstance(cx, wrapper, v, bp); +} + bool WaiveXrayWrapper::getPrototype(JSContext* cx, HandleObject wrapper, MutableHandleObject protop) const { -- cgit v1.2.3