diff options
Diffstat (limited to 'js/xpconnect/wrappers/WaiveXrayWrapper.cpp')
-rw-r--r-- | js/xpconnect/wrappers/WaiveXrayWrapper.cpp | 31 |
1 files changed, 31 insertions, 0 deletions
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 @@ -88,6 +88,37 @@ WaiveXrayWrapper::nativeCall(JSContext* cx, JS::IsAcceptableThis test, } 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 { return CrossCompartmentWrapper::getPrototype(cx, wrapper, protop) && |