Auto merge of #13017 - nox:wrong-receiver, r=Ms2ger

Pass the receiver to get_property_on_prototype (fixes #11600)

<!-- Reviewable:start -->
This change is [<img src="https://reviewable.io/review_button.svg" height="34" align="absmiddle" alt="Reviewable"/>](https://reviewable.io/reviews/servo/servo/13017)
<!-- Reviewable:end -->
This commit is contained in:
bors-servo 2016-08-25 11:49:54 -05:00 committed by GitHub
commit 160d15670e
3 changed files with 60 additions and 48 deletions

View file

@ -4724,10 +4724,17 @@ class CGDOMJSProxyHandler_getOwnPropertyDescriptor(CGAbstractExternMethod):
# Once we start supporting OverrideBuiltins we need to make # Once we start supporting OverrideBuiltins we need to make
# ResolveOwnProperty or EnumerateOwnProperties filter out named # ResolveOwnProperty or EnumerateOwnProperties filter out named
# properties that shadow prototype properties. # properties that shadow prototype properties.
namedGet = ("\n" + namedGet = """
"if RUST_JSID_IS_STRING(id) && !has_property_on_prototype(cx, proxy, id) {\n" + if RUST_JSID_IS_STRING(id) {
CGIndenter(CGProxyNamedGetter(self.descriptor, templateValues)).define() + "\n" + let mut has_on_proto = false;
"}\n") if !has_property_on_prototype(cx, proxy, id, &mut has_on_proto) {
return false;
}
if !has_on_proto {
%s
}
}
""" % CGIndenter(CGProxyNamedGetter(self.descriptor, templateValues), 8).define()
else: else:
namedGet = "" namedGet = ""
@ -4952,12 +4959,20 @@ class CGDOMJSProxyHandler_hasOwn(CGAbstractExternMethod):
namedGetter = self.descriptor.operations['NamedGetter'] namedGetter = self.descriptor.operations['NamedGetter']
if namedGetter: if namedGetter:
named = ("if RUST_JSID_IS_STRING(id) && !has_property_on_prototype(cx, proxy, id) {\n" + named = """\
CGIndenter(CGProxyNamedGetter(self.descriptor)).define() + "\n" + if RUST_JSID_IS_STRING(id) {
" *bp = found;\n" let mut has_on_proto = false;
" return true;\n" if !has_property_on_prototype(cx, proxy, id, &mut has_on_proto) {
"}\n" + return false;
"\n") }
if !has_on_proto {
%s
*bp = found;
return true;
}
}
""" % CGIndenter(CGProxyNamedGetter(self.descriptor), 8).define()
else: else:
named = "" named = ""
@ -5035,7 +5050,7 @@ if !expando.is_null() {
%s %s
let mut found = false; let mut found = false;
if !get_property_on_prototype(cx, proxy, id, &mut found, vp) { if !get_property_on_prototype(cx, proxy, receiver, id, &mut found, vp) {
return false; return false;
} }

View file

@ -29,7 +29,7 @@ use js::jsapi::{JS_GetProperty, JS_GetPrototype, JS_GetReservedSlot, JS_HasPrope
use js::jsapi::{JS_HasPropertyById, JS_IsExceptionPending, JS_IsGlobalObject}; use js::jsapi::{JS_HasPropertyById, JS_IsExceptionPending, JS_IsGlobalObject};
use js::jsapi::{JS_ResolveStandardClass, JS_SetProperty, ToWindowProxyIfWindow}; use js::jsapi::{JS_ResolveStandardClass, JS_SetProperty, ToWindowProxyIfWindow};
use js::jsapi::{JS_StringHasLatin1Chars, MutableHandleValue, ObjectOpResult}; use js::jsapi::{JS_StringHasLatin1Chars, MutableHandleValue, ObjectOpResult};
use js::jsval::{JSVal, ObjectValue, UndefinedValue}; use js::jsval::{JSVal, UndefinedValue};
use js::rust::{GCMethods, ToString}; use js::rust::{GCMethods, ToString};
use libc; use libc;
use std::ffi::CString; use std::ffi::CString;
@ -127,14 +127,13 @@ pub type ProtoOrIfaceArray = [*mut JSObject; PROTO_OR_IFACE_LENGTH];
/// set to true and `*vp` to the value, otherwise `*found` is set to false. /// set to true and `*vp` to the value, otherwise `*found` is set to false.
/// ///
/// Returns false on JSAPI failure. /// Returns false on JSAPI failure.
pub fn get_property_on_prototype(cx: *mut JSContext, pub unsafe fn get_property_on_prototype(cx: *mut JSContext,
proxy: HandleObject, proxy: HandleObject,
receiver: HandleValue,
id: HandleId, id: HandleId,
found: *mut bool, found: *mut bool,
vp: MutableHandleValue) vp: MutableHandleValue)
-> bool { -> bool {
unsafe {
// let proto = GetObjectProto(proxy);
rooted!(in(cx) let mut proto = ptr::null_mut()); rooted!(in(cx) let mut proto = ptr::null_mut());
if !JS_GetPrototype(cx, proxy, proto.handle_mut()) || proto.is_null() { if !JS_GetPrototype(cx, proxy, proto.handle_mut()) || proto.is_null() {
*found = false; *found = false;
@ -150,9 +149,7 @@ pub fn get_property_on_prototype(cx: *mut JSContext,
return true; return true;
} }
rooted!(in(cx) let receiver = ObjectValue(&*proxy.get())); JS_ForwardGetPropertyTo(cx, proto.handle(), id, receiver, vp)
JS_ForwardGetPropertyTo(cx, proto.handle(), id, receiver.handle(), vp)
}
} }
/// Get an array index from the given `jsid`. Returns `None` if the given /// Get an array index from the given `jsid`. Returns `None` if the given
@ -285,12 +282,17 @@ pub fn set_dictionary_property(cx: *mut JSContext,
} }
/// Returns whether `proxy` has a property `id` on its prototype. /// Returns whether `proxy` has a property `id` on its prototype.
pub fn has_property_on_prototype(cx: *mut JSContext, proxy: HandleObject, id: HandleId) -> bool { pub unsafe fn has_property_on_prototype(cx: *mut JSContext,
// MOZ_ASSERT(js::IsProxy(proxy) && js::GetProxyHandler(proxy) == handler); proxy: HandleObject,
let mut found = false; id: HandleId,
!get_property_on_prototype(cx, proxy, id, &mut found, unsafe { found: &mut bool)
MutableHandleValue::from_marked_location(ptr::null_mut()) -> bool {
}) || found rooted!(in(cx) let mut proto = ptr::null_mut());
if !JS_GetPrototype(cx, proxy, proto.handle_mut()) {
return false;
}
assert!(!proto.is_null());
JS_HasPropertyById(cx, proto.handle(), id, found)
} }
/// Drop the resources held by reserved slots of a global object /// Drop the resources held by reserved slots of a global object

View file

@ -1,5 +0,0 @@
[HTMLCollection-as-proto-length-get-throws.html]
type: testharness
[HTMLcollection as a prototype should not allow getting .length on the base object]
expected: FAIL