Unsafe Names for HTML Form Controls

Extra Properties: FORM Elements

Named Properties

A browser may add a property to the either the FORM or elements collection for each named (or id'd) element. Alternatively, the same browser may implement a specialized [[Get]] method to find the property.

The way to tell if an object has a property is to use the in operator.

   

Behavior varies between browsers, and between FORM and elements. When named properties exist, they usually appear to have the attributes ReadOnly, DontDelete.

Indexed Properties

Browsers also either add indexed properties to the collection or form or implement a specialized [[Get]] method to find the property. As with named properties, most browsers will actually add the property to the collection.

   

Mozilla seems to be the only browser that implements a specialized [[Get]].

Standard

The elements collection is an HTMLCollection that provides a standard way to access form controls.

Web IDL [WebIDL] lumps these behaviors into the terms: [[NameGetter]] and [[IndexGetter]]. Not all browsers have a specialized [[Get]] to retrieve named elements; the ones that do (Mozilla) don't always use it for every collection, so the term is a bit of a misnomer.

We can see the influence Java programmers had in the DOM 2 ECMAScript bindings [DOM2], which falsely states:

Objects that implement the HTMLCollection interface: ...

Note: This object can also be dereferenced using square bracket notation (e.g. obj[1]). Dereferencing with an integer index is equivalent to invoking the item function with that index.

...

Note: This object can also be dereferenced using square bracket notation (e.g. obj["foo"]). Dereferencing using a string index is equivalent to invoking the namedItem function with that index.

Property Access Operators

Contrary to what the [DOM 1] specification states, the [ ] property access operator does not perform a typecheck. In ECMAScript, property access is performed with obj[ Expression ] or obj . Identifier.

Property Access on a Form

When the named or indexed property is added to the form, there is no call to item or namedItem. The specification is wrong.

When the property access operator is used, the Expression is converted to a string with the internal ToString. The internal ToString method calls the object's toString property if it is an object or, if toString is not an object, the valueOf property is to be called (though results vary).

Property Access on a Form Example

The following example shows that with form[ Expression ], the Expression, an ObjectLiteral, results in an Object. This object's toString method is called by the internal [[ToString]].

 

The property access operator results in a call to the object's toString property and the resulting primitive value is converted to the string value "0".

Had the authors of the DOM specification ECMAScript bindings written some tests, they could have learned how this basic feature of property access works in ECMAScript.

Accessing form controls from the elements collection reduces ambiguity in the code. Control names that may conflict with the collection's properties are limited to: length, item, namedItem, tags. The names document, and window are still unsafe.

Accessing form controls from the elements collection is safe. There are fewer conflicting names and, unlike form-as-a-collection, elements is a live representation.

Table of Contents