Bug 764315 - Trigger reification for QuickStubbed accessors in SpecialPowers wrappers before calling Object.getOwnPropertyDescriptor. r=mrbkap

This commit is contained in:
Bobby Holley 2012-06-18 15:43:00 +02:00
parent 4127f77199
commit c2dbe5e980
2 changed files with 29 additions and 3 deletions

View File

@ -90,6 +90,21 @@ function isXrayWrapper(x) {
}
}
function callGetOwnPropertyDescriptor(obj, name) {
// Quickstubbed getters and setters are propertyOps, and don't get reified
// until someone calls __lookupGetter__ or __lookupSetter__ on them (note
// that there are special version of those functions for quickstubs, so
// apply()ing Object.prototype.__lookupGetter__ isn't good enough). Try to
// trigger reification before calling Object.getOwnPropertyDescriptor.
//
// See bug 764315.
try {
obj.__lookupGetter__(name);
obj.__lookupSetter__(name);
} catch(e) { }
return Object.getOwnPropertyDescriptor(obj, name);
}
// We can't call apply() directy on Xray-wrapped functions, so we have to be
// clever.
function doApply(fun, invocant, args) {
@ -226,7 +241,7 @@ SpecialPowersHandler.prototype.doGetPropertyDescriptor = function(name, own) {
//
// This one is easy, thanks to Object.getOwnPropertyDescriptor().
if (own)
desc = Object.getOwnPropertyDescriptor(obj, name);
desc = callGetOwnPropertyDescriptor(obj, name);
// Case 2: Not own, not Xray-wrapped.
//
@ -236,7 +251,7 @@ SpecialPowersHandler.prototype.doGetPropertyDescriptor = function(name, own) {
// NB: Make sure to check this.wrappedObject here, rather than obj, because
// we may have waived Xray on obj above.
else if (!isXrayWrapper(this.wrappedObject))
desc = crawlProtoChain(obj, function(o) {return Object.getOwnPropertyDescriptor(o, name);});
desc = crawlProtoChain(obj, function(o) {return callGetOwnPropertyDescriptor(o, name);});
// Case 3: Not own, Xray-wrapped.
//

View File

@ -8,7 +8,7 @@
<body onload="starttest();">
<div id="content" style="display: none">
<canvas id="testcanvas" width="200" height="200">
</div>
<pre id="test">
<script class="testbody" type="text/javascript">
@ -128,6 +128,17 @@ function starttest(){
var WrappedConstructor = SpecialPowers.wrap(TestConstructor);
is((new WrappedConstructor()).foo, 2, "JS constructors work properly when wrapped");
// Try messing around with QuickStubbed getters/setters and make sure the wrapper deals.
var ctx = SpecialPowers.wrap(document).getElementById('testcanvas').getContext('2d');
var pixels = ctx.getImageData(0,0,1,1);
try {
pixels.data;
ok(true, "Didn't throw getting quickstubbed accessor prop from proto");
}
catch (e) {
ok(false, "Threw while getting quickstubbed accessor prop from proto");
}
// Check functions that return null.
var returnsNull = function() { return null; }
is(SpecialPowers.wrap(returnsNull)(), null, "Should be able to handle functions that return null.");