archives

« Bugzilla Issues Index

#1453 — Various Array.prototype tests try to assign to indexed properties


The following tests are invalid, because they try to assign to indexed properties on the global object. The global object does not implement the interfaces required for step 2.4 and 2.5 of http://dev.w3.org/2006/webapi/WebIDL/#defineownproperty to work. This bug was uncovered after we changed Firefox to follow the spec in https://bugzilla.mozilla.org/show_bug.cgi?id=828787. I haven't fully investigated all our failures yet, so there might be more tests with this problem.

15.4.4.14-1-17 Array.prototype.indexOf applied to the global object Fail
15.4.4.14-2-15 Array.prototype.indexOf - 'length' is property of the global object Fail
15.4.4.14-9-b-i-23 Array.prototype.indexOf - This object is the global object Fail
15.4.4.15-1-17 Array.prototype.lastIndexOf applied to the global object Fail
15.4.4.15-2-15 Array.prototype.lastIndexOf - 'length' is property of the global object Fail
15.4.4.15-8-b-i-23 Array.prototype.lastIndexOf - This object is the global object Fail
15.4.4.16-2-15 Array.prototype.every - 'length' is property of the global object Fail
15.4.4.16-7-c-i-23 Array.prototype.every - This object is an global object which contains index property Fail
15.4.4.17-2-15 Array.prototype.some - 'length' is property of the global object Fail
15.4.4.17-7-c-i-23 Array.prototype.some - This object is an global object which contains index property Fail
15.4.4.18-2-15 Array.prototype.forEach - 'length' is property of the global object Fail
15.4.4.18-7-c-i-23 Array.prototype.forEach - This object is an global object which contains index property Fail
15.4.4.19-8-c-i-23 Array.prototype.map - This object is the global object which contains index property Fail
15.4.4.20-2-15 Array.prototype.filter - 'length' is property of the global object Fail
15.4.4.20-9-c-i-23 Array.prototype.filter - This object is the global object which contains index property Fail
15.4.4.21-2-15 Array.prototype.reduce - 'length' is property of the global object Fail
15.4.4.21-8-b-iii-1-23 Array.prototype.reduce - This object is the global object which contains index property Fail
15.4.4.21-9-c-i-23 Array.prototype.reduce - This object is the global object which contains index property Fail
15.4.4.22-2-15 Array.prototype.reduceRight - 'length' is property of the global object Fail
15.4.4.22-8-b-iii-1-23 Array.prototype.reduceRight - This object is the global object which contains index property Fail
15.4.4.22-9-c-i-23 Array.prototype.reduceRight - This object is an global object which contains index property Fail


(In reply to comment #0)
> The following tests are invalid, because they try to assign to indexed
> properties on the global object. The global object does not implement the
> interfaces required for step 2.4 and 2.5 of
> http://dev.w3.org/2006/webapi/WebIDL/#defineownproperty to work.
That's irrelevant for Test262 which only cares about ECMAScript conformance (not WebIDL conformance).
What's of interest here is what the internal methods of the global objects, like [[Get]] and [[HasProperty]] are.

I read the following:
# 15.1
"The values of the [[Prototype]] and [[Class]] internal properties of the global object are implementation-dependent."

This suggests that the behavior in the tests is implementation dependent so I agree these tests are invalid. However, note that these tests could pass even if assigning indexed properties if for instance, the global object had the [[Get]] and [[HasProperty]] (etc.) defined in section 8.12

I believe indeed, pretty much all tests playing with properties of the global object beyond the standards one should be removed from the test suite.


Sounds like a WebIDL bug to me.

The characteristics of the ECMAScript global object is defined in ES5.1 http://ecma-international.org/ecma-262/5.1/#sec-15.1

While section 15.1 one states various requirements concerning the global object, there is not stated requirement or permission in that would permit restricting the global object from having property keys that are numeric strings.

So, according the the ECMAScript specification assigning index properties to the global object is should work.

These are valid tests. Look to me like they have done their job and found an implementation bug.


(In reply to comment #2)
> The characteristics of the ECMAScript global object is defined in ES5.1
> http://ecma-international.org/ecma-262/5.1/#sec-15.1
>
> While section 15.1 one states various requirements concerning the global
> object, there is not stated requirement or permission in that would permit
> restricting the global object from having property keys that are numeric
> strings.
A custom [[Class]] suggests being allowed to have custom internal properties, doesn't it?


(In reply to comment #1)
>
> What's of interest here is what the internal methods of the global objects,
> like [[Get]] and [[HasProperty]] are.
>
> I read the following:
> # 15.1
> "The values of the [[Prototype]] and [[Class]] internal properties of the
> global object are implementation-dependent."

The above sentence means exactly what it says and nothing more. The value of the [[Prototype]] internal property controls the effect of proto climbing by [[Put]]. In theory setting an appropriate prototype object could call all [[Put]]'s of index properties to fail, but only if that object observably exposed via [[GetOwnProperty]] all possible index property keys as non-writable.

[[Class]] has non-thing at all to do with property access.

>
> This suggests that the behavior in the tests is implementation dependent so I
> agree these tests are invalid.

I don't read it that way, and I don't write it to be interpreted that way. It may be arguably reasonable for WebIDL to be restricting index properties on the objects that it exclusively controls. But the global object is a shared resource that is defined by ECMAScript and extended by WebIDL. Section 15.1 gives permission for WebIDL to add properties to the global object. I don't that it is reasonable for WebIDL to restrict its properties. Also note that while 15.1 allows the host to define properties and set the [[Class]] and [[Prototype]] internal properties, there is nothing that says that the global object is a "host object".

However, note that these tests could pass even
> if assigning indexed properties if for instance, the global object had the
> [[Get]] and [[HasProperty]] (etc.) defined in section 8.12
>
> I believe indeed, pretty much all tests playing with properties of the global
> object beyond the standards one should be removed from the test suite.

Not, it is valid for ES code to manipulate properties of the global object in many was, that capability needs to be tested.


(In reply to comment #3)
> (In reply to comment #2)
> > The characteristics of the ECMAScript global object is defined in ES5.1
> > http://ecma-international.org/ecma-262/5.1/#sec-15.1
> >
> > While section 15.1 one states various requirements concerning the global
> > object, there is not stated requirement or permission in that would permit
> > restricting the global object from having property keys that are numeric
> > strings.
> A custom [[Class]] suggests being allowed to have custom internal properties,
> doesn't it?

No, it means that Object.prototype.toString will print the value provided by [[Class]] and it potentially affects the path taken by anything in the ES spec. that explicitly tests for a specific [[Class]] value.

[[Class]] has nothing directly to do with internal properties (and internal properties have nothing to do with regular properties). The only connection between [[Class]] and internal properties is that the ES spec. says that certain object that have a specific [[Class]] value also have specific internal properties (and also that host objects may not assign those [[class]] values to host objects). Hence the spec. algorithms can infer the presence of certain spec defined internal properties based upon the presence of the corresponding [[Class]] values. The spec. does not give any meaning (other that the toString effect) to new host assigned [[Class]] values.


(In reply to comment #4)
> Section 15.1 gives permission for WebIDL to add properties to the global
> object. I don't that it is reasonable for WebIDL to restrict its properties.

Let's suppose that's true. ECMAScript allows additional properties beyond those in the standard. This includes numeric properties, and it implicitly includes a "length" property. Now take a look at 15.4.4.14-1-7's test, just for example:

function testcase() {
try {
var oldLen = fnGlobalObject().length;
fnGlobalObject()[1] = true;
fnGlobalObject().length = 2;
return Array.prototype.indexOf.call(fnGlobalObject(), true) === 1;
} finally {
delete fnGlobalObject()[1];
fnGlobalObject().length = oldLen;
}
}
runTestCase(testcase);

What is to prevent a conforming implementation from implementing a global object whose "length" property is a non-configurable getter/setter pair, where both getter and setter throw a TypeError on call? Or the same for the "1" property? Per section 16, it is explicitly permitted to provide additional properties such as these, beyond those described in ECMAScript. In such an implementation, shouldn't the test above fail, despite there being no spec-compliance error in the implementation?

Given section 16, I don't think test262 tests can reasonably test the behavior of any non-standard property, when ECMAScript itself imposes no limitations on the behavior of that non-standard property. Thus these tests should be considered invalid.


By that same logic, would most of the tests in Chapter 15 be invalid because they assume, for example, that there is not a non-configurable getter/setter pair on Object.prototype named "prop"?

function testcase() {
var proto = {};
Object.defineProperty(proto, "prop", {
value: 11,
configurable: false
});
var Con = function () { };
Con.prototype = proto;

var obj = new Con();

Object.defineProperties(obj, {
prop: {
value: 12,
configurable: true
}
});

return dataPropertyAttributesAreCorrect(obj, "prop", 12, false, false, true);

}
runTestCase(testcase);

I think we have to make some assumptions about the extensions runtimes are likely to make, otherwise it seems impossible to write almost any tests at all.


(In reply to comment #7)
> I think we have to make some assumptions about the extensions runtimes are
> likely to make, otherwise it seems impossible to write almost any tests at all.

That's fair enough, as far as tests touching the global object goes. But I think we need some ground rules about what tests should be allowed to touch on the global object. Standard-defined properties are obviously okay to touch. But anything beyond that, that might reasonably be used in an implementation, I think we shouldn't. "length" and indexed properties of any sort, I would argue, clearly fit that requirement. There are all sorts of reasons an implementation might define indexed properties (either statically or dynamically, even if the latter is "technically" not okay) on the global, as I think the browser case makes clear.

I care much less about the "prop" case, but I think it's reasonable to say we'll just change the test to use a different name whenever such conflicts arise in practice, at the request of anyone implementing or embedding the language.


(FWIW my specific example above is bad because it won't break in the presence of a getter/setter pair on prototype, but there are a number of tests that will because they assume you can assign to some property on an object to create that property).

(In reply to comment #8)
> I think it's reasonable to say
> we'll just change the test to use a different name whenever such conflicts
> arise in practice, at the request of anyone implementing or embedding the
> language.

I agree that we can change up the tests when implementers have extended the language in some way that cause tests to break. This particular circumstance is interesting, though, because there is no way to change the tests for the behavior of Array built-ins on the global object that I am aware of. The tests have to be removed. I understand this isn't a key interoperability scenario but it still doesn't sit well with me to pull out a bunch of tests that do validate ECMAScript but are invalid in a particular host because of extensions they've made.

An alternative that I don't necessarily like is to allow tests to specify a list of host environments that they will not run in...


(In reply to comment #9)
> it still doesn't sit well with me to pull out a bunch of tests that do validate
> ECMAScript but are invalid in a particular host

(Note that "particular host" should in time become "all browser hosts", if WebIDL remains as it is. [And not to digress as far as this bug database is concerned, but I think it should.])

> because of extensions they've made.

It doesn't a whole lot with me, either. But this is the global object, "broken" in oh so many ways in the browser, at the moment the most important ECMAScript embedding. I think we grind our teeth and just roll with it.

> An alternative that I don't necessarily like is to allow tests to specify a
> list of host environments that they will not run in...

Yeah, that seems unsustainable to me in the face of sufficient numbers of implementations, and I hope getting more implementations is a goal of the language (or at least not something we're willing to put stumbling blocks in the way of).


(In reply to comment #6)
> (In reply to comment #4)
> > Section 15.1 gives permission for WebIDL to add properties to the global
> > object. I don't that it is reasonable for WebIDL to restrict its properties.
>
> Let's suppose that's true. ECMAScript allows additional properties beyond
> those in the standard. This includes numeric properties, and it implicitly
> includes a "length" property. Now take a look at 15.4.4.14-1-7's test, just
> for example:
>

Fair enough. The array methods are generic but we have not guarantee that that any non-array object (including the global object) is actually sufficiently "array-like" that these sort of test will work for them. On that basis, perhaps they should ultimately be removed.

But, in the meantime, they have done their intended job and caught an attempt by WebIDL to require something that is inconsistent with the intent of the ES spec.

It sounds to me like the first thing we need to do before we can eliminates these tests is add tests to make sure that integer numeric valued string property keys can be added to the global object.

And to account for Jeff's point about a "length" property, the section 16 permission about adding properties probably needs to be refined for ES6. At the very least it probably needs to say that an host or implementation may not add array index properties and "length" to Object.prototype. Probably also for the global object.


Allen, Window objects have array index properties and a length property and have for almost 20 years now. Web content rather depends on them existing. So requiring the non-existence of such properties on the global is a non-starter, unfortunately.

I don't like it any more than you do, and wish people hadn't implemented Window this way back in the mid-90s. But they did, and here we are.


You'd also need to rope in every object along the global object's prototype chain, if you wanted to prohibit indexes and length. I agree with bz that this is not a feasible change to make in browsers.

And for what it's worth, I don't agree that restricting indexed proeprties or adding a length property here is "inconsistent with the intent of the ES spec". I don't think there's much that talks to "intent" in ECMAScript, except in rare NOTEs. (I kind of wish there were more -- get the tribal knowledge into the open so everyone can consider it -- but I understand why that's usually not the case.) I'm not aware of one that might be applicable here.


(In reply to comment #12)
> Allen, Window objects have array index properties and a length property and
> have for almost 20 years now. Web content rather depends on them existing. So
> requiring the non-existence of such properties on the global is a non-starter,
> unfortunately.
>
> I don't like it any more than you do, and wish people hadn't implemented Window
> this way back in the mid-90s. But they did, and here we are.

Right, I didn't realized the Window has always had a length and indexed properties. The problem with the tests listed for this bug isn't that the array methods such as indexof won't work when the global object is the browser Window object. The problem is that the setup for the tests assume that you can do stuff like:
fnGlobalObject()[1] = true;
fnGlobalObject().length = 2;

as part of the setup for the test. The above fails because (I believe) the window.length property preexists and is not assignable and window does not permit creation array-index expando properties outside its "length" range.

If we are going to test these array methods on the browser global object, we need to do the setup for the tests in a way that works in a browser (eg, creating a some subframes of window).

> Web content rather depends on them existing. So
> requiring the non-existence of such properties on the global is a non-starter,
> unfortunately.

Actually, I don't think web content depends upon them being own properties of the window object. If they were defined as accessor properties on the window object's prototype (I believe "length" is already defined that way) then the above setup could be done as:
Object.defineProperty(fnGlobalObject,1,{value:true,configurable: true,writable:true});
Object.defineProperty(fnGlobalObject,"length",{value:2,configurable: true,writable:true});

and things would work. There may be an issue that WebIDL allows such own over-rides of "length" but not of array-indexed properties.


That's true. Putting all that stuff on the prototype is probably web-compatible if it really becomes necessary. It would make the length inconsistent with other properties on Window (iirc people had agreed that for Window specifically WebIDL attributes should become own properties) and would make indexed access on window inconsistent with other objects... Worth bringing up on public-script-coord to see what people think.


This makes Firefox look bad. Is there any timeline when this is going to be fixed?