mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-11-24 21:31:04 +00:00
Bug 1041731 - Unforgeable Xrayed methods aren't getting cached on the holder. r=bholley.
--HG-- extra : rebase_source : 9e86ba2d864e6894cc10722ddaf83ded41d88e42
This commit is contained in:
parent
a5dc9951ad
commit
63152eee22
@ -970,6 +970,7 @@ static bool
|
||||
XrayResolveUnforgeableProperty(JSContext* cx, JS::Handle<JSObject*> wrapper,
|
||||
JS::Handle<JSObject*> obj, JS::Handle<jsid> id,
|
||||
JS::MutableHandle<JSPropertyDescriptor> desc,
|
||||
bool& cacheOnHolder,
|
||||
const NativeProperties* nativeProperties);
|
||||
|
||||
static bool
|
||||
@ -977,13 +978,17 @@ XrayResolveNativeProperty(JSContext* cx, JS::Handle<JSObject*> wrapper,
|
||||
const NativePropertyHooks* nativePropertyHooks,
|
||||
DOMObjectType type, JS::Handle<JSObject*> obj,
|
||||
JS::Handle<jsid> id,
|
||||
JS::MutableHandle<JSPropertyDescriptor> desc);
|
||||
JS::MutableHandle<JSPropertyDescriptor> desc,
|
||||
bool& cacheOnHolder);
|
||||
|
||||
bool
|
||||
XrayResolveOwnProperty(JSContext* cx, JS::Handle<JSObject*> wrapper,
|
||||
JS::Handle<JSObject*> obj, JS::Handle<jsid> id,
|
||||
JS::MutableHandle<JSPropertyDescriptor> desc)
|
||||
JS::MutableHandle<JSPropertyDescriptor> desc,
|
||||
bool& cacheOnHolder)
|
||||
{
|
||||
cacheOnHolder = false;
|
||||
|
||||
DOMObjectType type;
|
||||
const NativePropertyHooks *nativePropertyHooks =
|
||||
GetNativePropertyHooks(cx, obj, type);
|
||||
@ -992,20 +997,20 @@ XrayResolveOwnProperty(JSContext* cx, JS::Handle<JSObject*> wrapper,
|
||||
// For prototype objects and interface objects, just return their
|
||||
// normal set of properties.
|
||||
return XrayResolveNativeProperty(cx, wrapper, nativePropertyHooks, type,
|
||||
obj, id, desc);
|
||||
obj, id, desc, cacheOnHolder);
|
||||
}
|
||||
|
||||
// Check for unforgeable properties before doing mResolveOwnProperty weirdness
|
||||
const NativePropertiesHolder& nativeProperties =
|
||||
nativePropertyHooks->mNativeProperties;
|
||||
if (!XrayResolveUnforgeableProperty(cx, wrapper, obj, id, desc,
|
||||
if (!XrayResolveUnforgeableProperty(cx, wrapper, obj, id, desc, cacheOnHolder,
|
||||
nativeProperties.regular)) {
|
||||
return false;
|
||||
}
|
||||
if (desc.object()) {
|
||||
return true;
|
||||
}
|
||||
if (!XrayResolveUnforgeableProperty(cx, wrapper, obj, id, desc,
|
||||
if (!XrayResolveUnforgeableProperty(cx, wrapper, obj, id, desc, cacheOnHolder,
|
||||
nativeProperties.chromeOnly)) {
|
||||
return false;
|
||||
}
|
||||
@ -1021,7 +1026,8 @@ static bool
|
||||
XrayResolveAttribute(JSContext* cx, JS::Handle<JSObject*> wrapper,
|
||||
JS::Handle<JSObject*> obj, JS::Handle<jsid> id,
|
||||
const Prefable<const JSPropertySpec>* attributes, jsid* attributeIds,
|
||||
const JSPropertySpec* attributeSpecs, JS::MutableHandle<JSPropertyDescriptor> desc)
|
||||
const JSPropertySpec* attributeSpecs, JS::MutableHandle<JSPropertyDescriptor> desc,
|
||||
bool& cacheOnHolder)
|
||||
{
|
||||
for (; attributes->specs; ++attributes) {
|
||||
if (attributes->isEnabled(cx, obj)) {
|
||||
@ -1030,6 +1036,8 @@ XrayResolveAttribute(JSContext* cx, JS::Handle<JSObject*> wrapper,
|
||||
size_t i = attributes->specs - attributeSpecs;
|
||||
for ( ; attributeIds[i] != JSID_VOID; ++i) {
|
||||
if (id == attributeIds[i]) {
|
||||
cacheOnHolder = true;
|
||||
|
||||
const JSPropertySpec& attrSpec = attributeSpecs[i];
|
||||
// Because of centralization, we need to make sure we fault in the
|
||||
// JitInfos as well. At present, until the JSAPI changes, the easiest
|
||||
@ -1073,7 +1081,8 @@ XrayResolveMethod(JSContext* cx, JS::Handle<JSObject*> wrapper,
|
||||
const Prefable<const JSFunctionSpec>* methods,
|
||||
jsid* methodIds,
|
||||
const JSFunctionSpec* methodSpecs,
|
||||
JS::MutableHandle<JSPropertyDescriptor> desc)
|
||||
JS::MutableHandle<JSPropertyDescriptor> desc,
|
||||
bool& cacheOnHolder)
|
||||
{
|
||||
const Prefable<const JSFunctionSpec>* method;
|
||||
for (method = methods; method->specs; ++method) {
|
||||
@ -1083,6 +1092,8 @@ XrayResolveMethod(JSContext* cx, JS::Handle<JSObject*> wrapper,
|
||||
size_t i = method->specs - methodSpecs;
|
||||
for ( ; methodIds[i] != JSID_VOID; ++i) {
|
||||
if (id == methodIds[i]) {
|
||||
cacheOnHolder = true;
|
||||
|
||||
const JSFunctionSpec& methodSpec = methodSpecs[i];
|
||||
JSFunction *fun;
|
||||
if (methodSpec.selfHostedName) {
|
||||
@ -1117,6 +1128,7 @@ XrayResolveMethod(JSContext* cx, JS::Handle<JSObject*> wrapper,
|
||||
XrayResolveUnforgeableProperty(JSContext* cx, JS::Handle<JSObject*> wrapper,
|
||||
JS::Handle<JSObject*> obj, JS::Handle<jsid> id,
|
||||
JS::MutableHandle<JSPropertyDescriptor> desc,
|
||||
bool& cacheOnHolder,
|
||||
const NativeProperties* nativeProperties)
|
||||
{
|
||||
if (!nativeProperties) {
|
||||
@ -1128,7 +1140,7 @@ XrayResolveUnforgeableProperty(JSContext* cx, JS::Handle<JSObject*> wrapper,
|
||||
nativeProperties->unforgeableAttributes,
|
||||
nativeProperties->unforgeableAttributeIds,
|
||||
nativeProperties->unforgeableAttributeSpecs,
|
||||
desc)) {
|
||||
desc, cacheOnHolder)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
@ -1142,7 +1154,7 @@ XrayResolveUnforgeableProperty(JSContext* cx, JS::Handle<JSObject*> wrapper,
|
||||
nativeProperties->unforgeableMethods,
|
||||
nativeProperties->unforgeableMethodIds,
|
||||
nativeProperties->unforgeableMethodSpecs,
|
||||
desc)) {
|
||||
desc, cacheOnHolder)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
@ -1157,7 +1169,8 @@ XrayResolveUnforgeableProperty(JSContext* cx, JS::Handle<JSObject*> wrapper,
|
||||
static bool
|
||||
XrayResolveProperty(JSContext* cx, JS::Handle<JSObject*> wrapper,
|
||||
JS::Handle<JSObject*> obj, JS::Handle<jsid> id,
|
||||
JS::MutableHandle<JSPropertyDescriptor> desc, DOMObjectType type,
|
||||
JS::MutableHandle<JSPropertyDescriptor> desc,
|
||||
bool& cacheOnHolder, DOMObjectType type,
|
||||
const NativeProperties* nativeProperties)
|
||||
{
|
||||
const Prefable<const JSFunctionSpec>* methods;
|
||||
@ -1174,7 +1187,7 @@ XrayResolveProperty(JSContext* cx, JS::Handle<JSObject*> wrapper,
|
||||
}
|
||||
if (methods) {
|
||||
if (!XrayResolveMethod(cx, wrapper, obj, id, methods, methodIds,
|
||||
methodSpecs, desc)) {
|
||||
methodSpecs, desc, cacheOnHolder)) {
|
||||
return false;
|
||||
}
|
||||
if (desc.object()) {
|
||||
@ -1187,7 +1200,8 @@ XrayResolveProperty(JSContext* cx, JS::Handle<JSObject*> wrapper,
|
||||
if (!XrayResolveAttribute(cx, wrapper, obj, id,
|
||||
nativeProperties->staticAttributes,
|
||||
nativeProperties->staticAttributeIds,
|
||||
nativeProperties->staticAttributeSpecs, desc)) {
|
||||
nativeProperties->staticAttributeSpecs, desc,
|
||||
cacheOnHolder)) {
|
||||
return false;
|
||||
}
|
||||
if (desc.object()) {
|
||||
@ -1199,7 +1213,8 @@ XrayResolveProperty(JSContext* cx, JS::Handle<JSObject*> wrapper,
|
||||
if (!XrayResolveAttribute(cx, wrapper, obj, id,
|
||||
nativeProperties->attributes,
|
||||
nativeProperties->attributeIds,
|
||||
nativeProperties->attributeSpecs, desc)) {
|
||||
nativeProperties->attributeSpecs, desc,
|
||||
cacheOnHolder)) {
|
||||
return false;
|
||||
}
|
||||
if (desc.object()) {
|
||||
@ -1217,6 +1232,8 @@ XrayResolveProperty(JSContext* cx, JS::Handle<JSObject*> wrapper,
|
||||
size_t i = constant->specs - nativeProperties->constantSpecs;
|
||||
for ( ; nativeProperties->constantIds[i] != JSID_VOID; ++i) {
|
||||
if (id == nativeProperties->constantIds[i]) {
|
||||
cacheOnHolder = true;
|
||||
|
||||
desc.setAttributes(JSPROP_ENUMERATE | JSPROP_READONLY | JSPROP_PERMANENT);
|
||||
desc.object().set(wrapper);
|
||||
desc.value().set(nativeProperties->constantSpecs[i].value);
|
||||
@ -1234,7 +1251,8 @@ static bool
|
||||
ResolvePrototypeOrConstructor(JSContext* cx, JS::Handle<JSObject*> wrapper,
|
||||
JS::Handle<JSObject*> obj,
|
||||
size_t protoAndIfaceCacheIndex, unsigned attrs,
|
||||
JS::MutableHandle<JSPropertyDescriptor> desc)
|
||||
JS::MutableHandle<JSPropertyDescriptor> desc,
|
||||
bool cacheOnHolder)
|
||||
{
|
||||
JS::Rooted<JSObject*> global(cx, js::GetGlobalForObjectCrossCompartment(obj));
|
||||
{
|
||||
@ -1245,6 +1263,9 @@ ResolvePrototypeOrConstructor(JSContext* cx, JS::Handle<JSObject*> wrapper,
|
||||
if (!protoOrIface) {
|
||||
return false;
|
||||
}
|
||||
|
||||
cacheOnHolder = true;
|
||||
|
||||
desc.object().set(wrapper);
|
||||
desc.setAttributes(attrs);
|
||||
desc.setGetter(JS_PropertyStub);
|
||||
@ -1259,28 +1280,29 @@ XrayResolveNativeProperty(JSContext* cx, JS::Handle<JSObject*> wrapper,
|
||||
const NativePropertyHooks* nativePropertyHooks,
|
||||
DOMObjectType type, JS::Handle<JSObject*> obj,
|
||||
JS::Handle<jsid> id,
|
||||
JS::MutableHandle<JSPropertyDescriptor> desc)
|
||||
JS::MutableHandle<JSPropertyDescriptor> desc,
|
||||
bool& cacheOnHolder)
|
||||
{
|
||||
if (type == eInterface && IdEquals(id, "prototype")) {
|
||||
return nativePropertyHooks->mPrototypeID == prototypes::id::_ID_Count ||
|
||||
ResolvePrototypeOrConstructor(cx, wrapper, obj,
|
||||
nativePropertyHooks->mPrototypeID,
|
||||
JSPROP_PERMANENT | JSPROP_READONLY,
|
||||
desc);
|
||||
desc, cacheOnHolder);
|
||||
}
|
||||
|
||||
if (type == eInterfacePrototype && IdEquals(id, "constructor")) {
|
||||
return nativePropertyHooks->mConstructorID == constructors::id::_ID_Count ||
|
||||
ResolvePrototypeOrConstructor(cx, wrapper, obj,
|
||||
nativePropertyHooks->mConstructorID,
|
||||
0, desc);
|
||||
0, desc, cacheOnHolder);
|
||||
}
|
||||
|
||||
const NativePropertiesHolder& nativeProperties =
|
||||
nativePropertyHooks->mNativeProperties;
|
||||
|
||||
if (nativeProperties.regular &&
|
||||
!XrayResolveProperty(cx, wrapper, obj, id, desc, type,
|
||||
!XrayResolveProperty(cx, wrapper, obj, id, desc, cacheOnHolder, type,
|
||||
nativeProperties.regular)) {
|
||||
return false;
|
||||
}
|
||||
@ -1288,7 +1310,7 @@ XrayResolveNativeProperty(JSContext* cx, JS::Handle<JSObject*> wrapper,
|
||||
if (!desc.object() &&
|
||||
nativeProperties.chromeOnly &&
|
||||
xpc::AccessCheck::isChrome(js::GetObjectCompartment(wrapper)) &&
|
||||
!XrayResolveProperty(cx, wrapper, obj, id, desc, type,
|
||||
!XrayResolveProperty(cx, wrapper, obj, id, desc, cacheOnHolder, type,
|
||||
nativeProperties.chromeOnly)) {
|
||||
return false;
|
||||
}
|
||||
@ -1299,8 +1321,11 @@ XrayResolveNativeProperty(JSContext* cx, JS::Handle<JSObject*> wrapper,
|
||||
bool
|
||||
XrayResolveNativeProperty(JSContext* cx, JS::Handle<JSObject*> wrapper,
|
||||
JS::Handle<JSObject*> obj,
|
||||
JS::Handle<jsid> id, JS::MutableHandle<JSPropertyDescriptor> desc)
|
||||
JS::Handle<jsid> id, JS::MutableHandle<JSPropertyDescriptor> desc,
|
||||
bool& cacheOnHolder)
|
||||
{
|
||||
cacheOnHolder = false;
|
||||
|
||||
DOMObjectType type;
|
||||
const NativePropertyHooks* nativePropertyHooks =
|
||||
GetNativePropertyHooks(cx, obj, type);
|
||||
@ -1314,7 +1339,7 @@ XrayResolveNativeProperty(JSContext* cx, JS::Handle<JSObject*> wrapper,
|
||||
if (type == eInterfacePrototype) {
|
||||
do {
|
||||
if (!XrayResolveNativeProperty(cx, wrapper, nativePropertyHooks, type,
|
||||
obj, id, desc)) {
|
||||
obj, id, desc, cacheOnHolder)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
@ -1327,7 +1352,7 @@ XrayResolveNativeProperty(JSContext* cx, JS::Handle<JSObject*> wrapper,
|
||||
}
|
||||
|
||||
return XrayResolveNativeProperty(cx, wrapper, nativePropertyHooks, type, obj,
|
||||
id, desc);
|
||||
id, desc, cacheOnHolder);
|
||||
}
|
||||
|
||||
bool
|
||||
@ -1666,7 +1691,8 @@ NativeToString(JSContext* cx, JS::Handle<JSObject*> wrapper,
|
||||
toStringDesc.value().set(JS::UndefinedValue());
|
||||
JS::Rooted<jsid> id(cx,
|
||||
nsXPConnect::GetRuntimeInstance()->GetStringID(XPCJSRuntime::IDX_TO_STRING));
|
||||
if (!XrayResolveNativeProperty(cx, wrapper, obj, id, &toStringDesc)) {
|
||||
bool unused;
|
||||
if (!XrayResolveNativeProperty(cx, wrapper, obj, id, &toStringDesc, unused)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
|
@ -2301,7 +2301,8 @@ bool
|
||||
XrayResolveOwnProperty(JSContext* cx, JS::Handle<JSObject*> wrapper,
|
||||
JS::Handle<JSObject*> obj,
|
||||
JS::Handle<jsid> id,
|
||||
JS::MutableHandle<JSPropertyDescriptor> desc);
|
||||
JS::MutableHandle<JSPropertyDescriptor> desc,
|
||||
bool& cacheOnHolder);
|
||||
|
||||
/**
|
||||
* This resolves operations, attributes and constants of the interfaces for obj.
|
||||
@ -2313,7 +2314,8 @@ XrayResolveOwnProperty(JSContext* cx, JS::Handle<JSObject*> wrapper,
|
||||
bool
|
||||
XrayResolveNativeProperty(JSContext* cx, JS::Handle<JSObject*> wrapper,
|
||||
JS::Handle<JSObject*> obj,
|
||||
JS::Handle<jsid> id, JS::MutableHandle<JSPropertyDescriptor> desc);
|
||||
JS::Handle<jsid> id, JS::MutableHandle<JSPropertyDescriptor> desc,
|
||||
bool& cacheOnHolder);
|
||||
|
||||
/**
|
||||
* Define a property on obj through an Xray wrapper.
|
||||
|
@ -4,3 +4,4 @@
|
||||
[test_bug775543.html]
|
||||
[test_document_location_set_via_xray.html]
|
||||
[test_proxies_via_xray.html]
|
||||
[test_document_location_via_xray_cached.html]
|
||||
|
@ -0,0 +1,36 @@
|
||||
<!DOCTYPE HTML>
|
||||
<html>
|
||||
<!--
|
||||
https://bugzilla.mozilla.org/show_bug.cgi?id=1041731
|
||||
-->
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<title>Test for Bug 1041731</title>
|
||||
<script type="application/javascript" src="chrome://mochikit/content/tests/SimpleTest/SimpleTest.js"></script>
|
||||
<link rel="stylesheet" type="text/css" href="chrome://mochikit/content/tests/SimpleTest/test.css"/>
|
||||
</head>
|
||||
<body>
|
||||
<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=1041731">Mozilla Bug 1041731</a>
|
||||
<p id="display"></p>
|
||||
<div id="content" style="display: none">
|
||||
<iframe id="t" src="http://example.org/tests/dom/bindings/test/file_document_location_set_via_xray.html"></iframe>
|
||||
</div>
|
||||
<pre id="test">
|
||||
<script type="application/javascript">
|
||||
|
||||
/** Test for Bug 1041731 **/
|
||||
|
||||
function test()
|
||||
{
|
||||
var loc = document.getElementById("t").contentWindow.document.location;
|
||||
ise(loc.toString, loc.toString, "Unforgeable method on the Xray should be cached");
|
||||
SimpleTest.finish();
|
||||
}
|
||||
|
||||
SimpleTest.waitForExplicitFinish();
|
||||
addLoadEvent(test);
|
||||
|
||||
</script>
|
||||
</pre>
|
||||
</body>
|
||||
</html>
|
@ -2060,8 +2060,9 @@ DOMXrayTraits::resolveNativeProperty(JSContext *cx, HandleObject wrapper,
|
||||
HandleObject holder, HandleId id,
|
||||
MutableHandle<JSPropertyDescriptor> desc)
|
||||
{
|
||||
bool unused;
|
||||
RootedObject obj(cx, getTargetObject(wrapper));
|
||||
if (!XrayResolveNativeProperty(cx, wrapper, obj, id, desc))
|
||||
if (!XrayResolveNativeProperty(cx, wrapper, obj, id, desc, unused))
|
||||
return false;
|
||||
|
||||
MOZ_ASSERT(!desc.object() || desc.object() == wrapper, "What did we resolve this on?");
|
||||
@ -2102,13 +2103,26 @@ DOMXrayTraits::resolveOwnProperty(JSContext *cx, const Wrapper &jsWrapper, Handl
|
||||
}
|
||||
}
|
||||
|
||||
if (!JS_GetPropertyDescriptorById(cx, holder, id, desc))
|
||||
return false;
|
||||
if (desc.object()) {
|
||||
desc.object().set(wrapper);
|
||||
return true;
|
||||
}
|
||||
|
||||
RootedObject obj(cx, getTargetObject(wrapper));
|
||||
if (!XrayResolveOwnProperty(cx, wrapper, obj, id, desc))
|
||||
bool cacheOnHolder;
|
||||
if (!XrayResolveOwnProperty(cx, wrapper, obj, id, desc, cacheOnHolder))
|
||||
return false;
|
||||
|
||||
MOZ_ASSERT(!desc.object() || desc.object() == wrapper, "What did we resolve this on?");
|
||||
|
||||
return true;
|
||||
if (!desc.object() || !cacheOnHolder)
|
||||
return true;
|
||||
|
||||
return JS_DefinePropertyById(cx, holder, id, desc.value(), desc.attributes(),
|
||||
desc.getter(), desc.setter()) &&
|
||||
JS_GetPropertyDescriptorById(cx, holder, id, desc);
|
||||
}
|
||||
|
||||
bool
|
||||
|
Loading…
Reference in New Issue
Block a user