Bug 516255 - Fix attributes on arguments[i]: index properties on arguments should be enumerable, configurable, and writable. r=dmandelin

This commit is contained in:
Jeff Walden 2010-08-11 23:27:40 -07:00
parent 6ec2024bd5
commit 154056d044
3 changed files with 110 additions and 11 deletions

View File

@ -596,8 +596,10 @@ args_resolve(JSContext *cx, JSObject *obj, jsid id, uintN flags,
*objp = NULL;
bool valid = false;
uintN attrs = JSPROP_SHARED;
if (JSID_IS_INT(id)) {
uint32 arg = uint32(JSID_TO_INT(id));
attrs = JSPROP_ENUMERATE | JSPROP_SHARED;
if (arg < obj->getArgsInitialLength() && !obj->getArgsElement(arg).isMagic(JS_ARGS_HOLE))
valid = true;
} else if (JSID_IS_ATOM(id, cx->runtime->atomState.lengthAtom)) {
@ -609,12 +611,8 @@ args_resolve(JSContext *cx, JSObject *obj, jsid id, uintN flags,
}
if (valid) {
/*
* XXX ECMA specs DontEnum even for indexed properties, contrary to
* other array-like objects.
*/
Value tmp = UndefinedValue();
if (!js_DefineProperty(cx, obj, id, &tmp, ArgGetter, ArgSetter, JSPROP_SHARED))
if (!js_DefineProperty(cx, obj, id, &tmp, ArgGetter, ArgSetter, attrs))
return JS_FALSE;
*objp = obj;
}
@ -713,8 +711,10 @@ strictargs_resolve(JSContext *cx, JSObject *obj, jsid id, uintN flags, JSObject
*objp = NULL;
bool valid = false;
uintN attrs = JSPROP_SHARED;
if (JSID_IS_INT(id)) {
uint32 arg = uint32(JSID_TO_INT(id));
attrs = JSPROP_SHARED | JSPROP_ENUMERATE;
if (arg < obj->getArgsInitialLength() && !obj->getArgsElement(arg).isMagic(JS_ARGS_HOLE))
valid = true;
} else if (JSID_IS_ATOM(id, cx->runtime->atomState.lengthAtom)) {
@ -746,13 +746,9 @@ strictargs_resolve(JSContext *cx, JSObject *obj, jsid id, uintN flags, JSObject
}
if (valid) {
/*
* XXX ECMA specs DontEnum even for indexed properties, contrary to
* other array-like objects.
*/
Value tmp = UndefinedValue();
if (!js_DefineProperty(cx, obj, id, &tmp, StrictArgGetter, StrictArgSetter, JSPROP_SHARED))
return JS_FALSE;
if (!js_DefineProperty(cx, obj, id, &tmp, StrictArgGetter, StrictArgSetter, attrs))
return false;
*objp = obj;
}
return true;

View File

@ -0,0 +1,102 @@
/*
* Any copyright is dedicated to the Public Domain.
* http://creativecommons.org/licenses/publicdomain/
*/
var gTestfile = 'arguments-property-attributes.js';
var BUGNUMBER = 516255;
var summary = "Attributes for properties of arguments objects";
print(BUGNUMBER + ": " + summary);
/**************
* BEGIN TEST *
**************/
// normal
function args() { return arguments; }
var a = args(0, 1);
var argProps = Object.getOwnPropertyNames(a).sort();
assertEq(argProps.indexOf("callee") >= 0, true);
assertEq(argProps.indexOf("0") >= 0, true);
assertEq(argProps.indexOf("1") >= 0, true);
assertEq(argProps.indexOf("length") >= 0, true);
var calleeDesc = Object.getOwnPropertyDescriptor(a, "callee");
assertEq(calleeDesc.value, args);
assertEq(calleeDesc.writable, true);
assertEq(calleeDesc.enumerable, false);
assertEq(calleeDesc.configurable, true);
var zeroDesc = Object.getOwnPropertyDescriptor(a, "0");
assertEq(zeroDesc.value, 0);
assertEq(zeroDesc.writable, true);
assertEq(zeroDesc.enumerable, true);
assertEq(zeroDesc.configurable, true);
var oneDesc = Object.getOwnPropertyDescriptor(a, "1");
assertEq(oneDesc.value, 1);
assertEq(oneDesc.writable, true);
assertEq(oneDesc.enumerable, true);
assertEq(oneDesc.configurable, true);
var lengthDesc = Object.getOwnPropertyDescriptor(a, "length");
assertEq(lengthDesc.value, 2);
assertEq(lengthDesc.writable, true);
assertEq(lengthDesc.enumerable, false);
assertEq(lengthDesc.configurable, true);
// strict
function strictArgs() { "use strict"; return arguments; }
var sa = strictArgs(0, 1);
var strictArgProps = Object.getOwnPropertyNames(sa).sort();
assertEq(strictArgProps.indexOf("callee") >= 0, true);
assertEq(strictArgProps.indexOf("caller") >= 0, true);
assertEq(strictArgProps.indexOf("0") >= 0, true);
assertEq(strictArgProps.indexOf("1") >= 0, true);
assertEq(strictArgProps.indexOf("length") >= 0, true);
var strictCalleeDesc = Object.getOwnPropertyDescriptor(sa, "callee");
assertEq(typeof strictCalleeDesc.get, "function");
assertEq(typeof strictCalleeDesc.set, "function");
assertEq(strictCalleeDesc.get, strictCalleeDesc.set);
assertEq(strictCalleeDesc.enumerable, false);
assertEq(strictCalleeDesc.configurable, false);
var strictCallerDesc = Object.getOwnPropertyDescriptor(sa, "caller");
assertEq(typeof strictCallerDesc.get, "function");
assertEq(typeof strictCallerDesc.set, "function");
assertEq(strictCallerDesc.get, strictCallerDesc.set);
assertEq(strictCallerDesc.enumerable, false);
assertEq(strictCallerDesc.configurable, false);
var strictZeroDesc = Object.getOwnPropertyDescriptor(sa, "0");
assertEq(strictZeroDesc.value, 0);
assertEq(strictZeroDesc.writable, true);
assertEq(strictZeroDesc.enumerable, true);
assertEq(strictZeroDesc.configurable, true);
var strictOneDesc = Object.getOwnPropertyDescriptor(sa, "1");
assertEq(strictOneDesc.value, 1);
assertEq(strictOneDesc.writable, true);
assertEq(strictOneDesc.enumerable, true);
assertEq(strictOneDesc.configurable, true);
var strictLengthDesc = Object.getOwnPropertyDescriptor(sa, "length");
assertEq(strictLengthDesc.value, 2);
assertEq(strictLengthDesc.writable, true);
assertEq(strictLengthDesc.enumerable, false);
assertEq(strictLengthDesc.configurable, true);
/******************************************************************************/
if (typeof reportCompare === "function")
reportCompare(true, true);
print("All tests passed!");

View File

@ -3,3 +3,4 @@ script 15.3.4.3-01.js
script arguments-caller-callee.js
script function-caller.js
script strict-arguments.js
script arguments-property-attributes.js