$OpenBSD$ index 855c82c..21a05e6 100644 --- dom/bindings/DOMJSProxyHandler.cpp.orig Fri Feb 20 15:40:37 2015 +++ dom/bindings/DOMJSProxyHandler.cpp Fri Feb 20 15:40:37 2015 @@ -188,6 +188,16 @@ BaseDOMProxyHandler::getPropertyDescriptor(JSContext* cx, } bool +BaseDOMProxyHandler::getOwnPropertyDescriptor(JSContext* cx, + JS::Handle proxy, + JS::Handle id, + MutableHandle desc) +{ + return getOwnPropDescriptor(cx, proxy, id, /* ignoreNamedProps = */ false, + desc); +} + +bool DOMProxyHandler::defineProperty(JSContext* cx, JS::Handle proxy, JS::Handle id, MutableHandle desc, bool* defined) { @@ -225,7 +235,30 @@ DOMProxyHandler::set(JSContext *cx, Handle proxy, Handle r if (done) { return true; } - return mozilla::dom::BaseDOMProxyHandler::set(cx, proxy, receiver, id, strict, vp); + + // Make sure to ignore our named properties when checking for own + // property descriptors for a set. + JS::Rooted desc(cx); + if (!getOwnPropDescriptor(cx, proxy, id, /* ignoreNamedProps = */ true, + &desc)) { + return false; + } + bool descIsOwn = desc.object() != nullptr; + if (!desc.object()) { + // Don't just use getPropertyDescriptor, unlike BaseProxyHandler::set, + // because that would call getOwnPropertyDescriptor on ourselves. Instead, + // directly delegate to the proto, if any. + JS::Rooted proto(cx); + if (!js::GetObjectProto(cx, proxy, &proto)) { + return false; + } + if (proto && !JS_GetPropertyDescriptorById(cx, proto, id, &desc)) { + return false; + } + } + + return js::SetPropertyIgnoringNamedGetter(cx, this, proxy, receiver, id, + &desc, descIsOwn, strict, vp); } bool