Unsafe Names for HTML Form Controls

D

Dr J R Stockton

In comp.lang.javascript message <[email protected]>
I have written an article "Unsafe Names for HTML Form Controls".

A straightforward rule is that one should never choose for a name of any
sort any string which might be used for any purpose in a programmer-
visible interface of the system, whether as identifiers or as language
elements.

One method of doing this is to use non-English words (though I did once
read of a French Algol dialect in which the reserved words had been
translated).

Another can be to use unconventional capitalisation.

Another is to include one or more digits, though not 0 & 1 where they
may look like letters.

In any section on debugging, there should be mention of the possibility
of a newly-introduced name clashing with one in the same scope created
long ago. ISTR introducing a JavaScript/VBScript variable which matched
a pre-existing anchor.
 
R

RobG

I have written an article "Unsafe Names for HTML Form Controls".

<URL:http://jibbering.com/faq/names/>

I would appreciate any reviews, technical or otherwise.

I apologise in advance if these comments are late to the party, Google
Groups has been slow with updates lately. Comments below.


The use of colloquial terms like "clobber" are out of place in a
technical article, a better term would be “overwrite” or “replace”.

First sentence:

“An HTML FORM element...implements many interfaces, and has a rich
number of features”.

Would be better as:

“HTML FORM elements implement the HTMLFormElement Interface and have a
rich set of features”

Where the word HTMLFormElement is a link to the relevant part of the
DOM 2 HTML spec. The phrase “rich number” is inappropriate, “rich
set” is better.

<URL: http://www.w3.org/TR/DOM-Level-2-HTML/html.html#ID-40002357 >

Second sentence:

“...as properties to the FORM.”

might be better as properties *of* the FORM”

In the section “What kind of Collection is a Form”, I have serious
reservations about calling a form a collection. It isn’t, it a DOM
object with certain properties. You can't access the controls as
form, whereas you can use form.elements because its elements
property really is a collection.

The sentence:

“The FORM...provides direct access to the contained input elements”

Is misleading, a form has direct access to all named form controls,
not just input elements. Also, this point has been made earlier when
stating that references to named controls are added as properties of
the form. Further, the elements collection gives access to all
controls, not just the named ones.

I don’t think there should be any reference to the form as a
collection - since you can’t access the named properties by index, it
isn’t any kind of collection (mystery solved).

The “leak” example seems confusing. Why not simply state that once a
named property has been replaced by some other value, removing the
other value doesn’t restore the original. That behaviour is
consistent with javascript object properties and variables and
shouldn’t come as a big surprise.
 
D

David Mark

I have written an article "Unsafe Names for HTML Form Controls".

<URL:http://jibbering.com/faq/names/>

I would appreciate any reviews, technical or otherwise.

I had to read this sentence a couple of times:

"Accessing a form control as a FORM property is like accessing a FORM
element directly off the document."

If I get it, you are saying they are both non-standard shortcuts and
therefore bad. I certainly agree, but it took a bit to understand the
analogy.

I don't understand the "simple leak example" at all. I would flesh
out the explanation of that.

"Some browsers also have a tags property on the elements collection"

That is a new one on me. What does it do?

The section titled "The elements Collection is Live" is a quote and
reference to a Mozilla bug report. I see the connection, but it
doesn't seem to work as a section.

I recently noticed that all of the FAQ documents are loose HTML. I
imagine they have always been, but it seems silly to transition the
site forever.
 
D

dhtml

First off, thank you for the comments. I made changes to the index page
based on those. Removed 'clobber', added an example, and some text
qualifying the DOM 1 quote.

I did not agree with all of your feedback though. Comments interspersed.

First sentence:

“An HTML FORM element...implements many interfaces, and has a rich
number of features”.


By virtue of implementing the HTMLFormElement interface, they also
implement Node, Element, HTMLElement.

Most browsers are implementing EventTarget and ElementCSSInlineStyle.
Where the word HTMLFormElement is a link to the relevant part of the
DOM 2 HTML spec. The phrase “rich number” is inappropriate, “rich
set” is better.

<URL: http://www.w3.org/TR/DOM-Level-2-HTML/html.html#ID-40002357 >

Second sentence:

“...as properties to the FORM.”

"adds a property to the form" vs "adds a property from the form."

A property is added to the form, so I think the first one makes more sense.
might be better as properties *of* the FORM”

In the section “What kind of Collection is a Form”, I have serious
reservations about calling a form a collection. It isn’t, it a DOM
object with certain properties. You can't access the controls as
form, whereas you can use form.elements because its elements
property really is a collection.


It's right in the spec. you can hate it as much as I do and it will
still be there.

The elements can be accessed by index, as document.forms[0][0]. Just
don't expect them to be in the order they appear in the document.

The sentence:

“The FORM...provides direct access to the contained input elements”

Is misleading, a form has direct access to all named form controls,
not just input elements. Also, this point has been made earlier when
stating that references to named controls are added as properties of
the form. Further, the elements collection gives access to all
controls, not just the named ones.


The quote is from DOM 1.

http://www.w3.org/TR/2000/WD-DOM-Level-1-20000929/level-one-html.html#ID-40002357
I don’t think there should be any reference to the form as a
collection - since you can’t access the named properties by index, it
isn’t any kind of collection (mystery solved).

Not calling a form a collection because it doesn't allow access by index
is not a good argument. First of all, it isn't true.

The DOM specification says that a form encompasses behavior of a
collection. That is a true statement. Named properties are accessed by
name. Indexed properties, by index. That's two types of ways to index a
form control.

Second, a map, such as NamedNodeMap, can be a collection. Not all
collections are indexed.
The “leak” example seems confusing. Why not simply state that once a
named property has been replaced by some other value, removing the
other value doesn’t restore the original. That behaviour is
consistent with javascript object properties and variables and
shouldn’t come as a big surprise.

That is not the point I was trying to make. Hmm. The point is that when
a FORM control is removed, the property might still be on the form.

The phenomenon is demonstrated in the simple leak example:

http://jibbering.com/faq/names/simple-leak-form-input.html

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"
"http://www.w3.org/TR/html4/loose.dtd">
<html lang="en">
<head><title></title></head>
<body>
<form action=""><input name="foo"><input name="bar"></form>
<pre>
<script type="text/javascript">
document.forms[0].foo;
document.forms[0].elements.foo;

// Clear out form's HTML.
document.forms[0].innerHTML = "";
document.write('foo: ' + document.forms[0].foo+'<br>');
document.write('bar: '+document.forms[0].bar+'<br>');
document.write('elements.foo: '+document.forms[0].elements.foo);
</script>
</pre>
</body>
</html>

Firefox 3, Safari 3:
foo: [object HTMLInputElement]
bar: undefined
elements.foo: undefined


The result shows that after setting the forms innerHTML = "", the
property remains on the form.

Garrett
 
R

RobG

First off, thank you for the comments. I made changes to the index page
based on those. Removed 'clobber', added an example, and some text
qualifying the DOM 1 quote.

I did not agree with all of your feedback though. Comments interspersed.



By virtue of implementing the HTMLFormElement interface, they also
implement Node, Element, HTMLElement.

The article is about forms, so better to name the relevant interface
at least.

Most browsers are implementing EventTarget and ElementCSSInlineStyle.
Where the word HTMLFormElement is a link to the relevant part of the
DOM 2 HTML spec.  The phrase “rich number” is inappropriate, “rich
set” is better.

Second sentence:
“...as properties to the FORM.”

"adds a property to the form" vs "adds a property from the form."

A property is added to the form, so I think the first one makes more sense.
might be better as properties *of* the FORM”
In the section “What kind of Collection is a Form”, I have serious
reservations about calling a form a collection.  It isn’t, it a DOM
object with certain properties. You can't access the controls as
form, whereas you can use form.elements because its elements
property really is a collection.


It's right in the spec. you can hate it as much as I do and it will
still be there.

The elements can be accessed by index, as document.forms[0][0]. Just
don't expect them to be in the order they appear in the document.


Bugger me, in all these years I've never accessed a form control that
way. I actually tried a test and stuffed it up, but see now that it
can be done. All the same, it doesn't make it a collection any more
than a collection is an Array because of being able to access its
properties by index.

Collections are defined in the DOM HTML spec, I don't see
HTMLFormElement defined as one.


Then that spec is missleading too for the same reason - form controls
are no restricted to input elements (unless in DOM 1 access really was
restricted to input elements). You may note that the DOM 2 HTML spec
has ammended that phrase with "...contained form controls" instead.


Not calling a form a collection because it doesn't allow access by index
is not a good argument. First of all, it isn't true.

Noted, but doesn't change my mind. :)

The DOM specification says that a form encompasses behavior of a
collection. That is a true statement. Named properties are accessed by
name. Indexed properties, by index. That's two types of ways to index a
form control.

It also has a self adjusting, read-only length property related to the
number of controls in the form, but doesn't seem to implement the
HTMLCollection's item or namedItem methods (in Firefox 3 at least).

So it is fair to say that it has some of the properties of a
collection, just like it's fair to say a collection is *like* an
Array, but that doesn't make it one.

Second, a map, such as NamedNodeMap, can be a collection. Not all
collections are indexed.

NamedNodeMap is in the DOM Core spec, not the HTML spec which defines
HTMLCollection. I think if you are going to introduce the term
"collection" as a generic term, you should define what you mean by it
and make clear that you aren't referring to the set of objects defined
by the DOM 2 HTML spec that implement the HTMLCollection interface.
That is not the point I was trying to make. Hmm. The point is that when
a FORM control is removed, the property might still be on the form.

Then better to say that. You can also remove controls using
removeChild rather than innerHTML[1] and your example still works.
Perhaps the form has multiple references to the control and removing
one of them doesn't remove the others.

1. I think using DOM methods makes for a better example, otherwise
it's easy to blame innerHTML for unexpected behaviour 'cos it's not a
standard and has known cross-browswer differences.
 
R

Richard Cornford

On Oct 28, 3:36 am, David Mark wrote:
"Some browsers also have a tags property on the elements
collection"

That is a new one on me. What does it do?
<snip>

The - tags - property is a method of the collection objects. It takes
a string value representing a tag name as its argument and returns a
collection/array of all the elements in its collection that have a
corresponding tag name. (Here 'collection' means the pre-DOM
collections, so - elementRef.children - has a - tags - method but -
elementRef.childNodes - does not (pre-DOM collections that were
formalised in the HTML DOM retained their - tags - methods for back-
compatibility))

The - tags - method was used to provide fall-back on IE 4 for -
getElementsByTagName -because wherever you could have otherwise used -
elementRef.getElementsByTagName(tagNameString); - on IE 4 you could
use elementRef.all.tags(tagNameString); - (the - all - collection of
elements containing all decedents so the subset of a particular type
was equivalent to the DOM method's result (though I don't recall
whether order or 'live-ness' were equivalent).

Richard.
 
D

David Mark

On Oct 28, 3:36 am, David Mark wrote:



<snip>

The - tags - property is a method of the collection objects. It takes
a string value representing a tag name as its argument and returns a
collection/array of all the elements in its collection that have a
corresponding tag name. (Here 'collection' means the pre-DOM
collections, so - elementRef.children - has a - tags - method but -
elementRef.childNodes - does not (pre-DOM collections that were
formalised in the HTML DOM retained their - tags - methods for back-
compatibility))

Oh that. I thought that was just for the "all" collections.
The - tags - method was used to provide fall-back on IE 4 for -
getElementsByTagName -because wherever you could have otherwise used -

Right. I use it for just that.
elementRef.getElementsByTagName(tagNameString); - on IE 4 you could
use elementRef.all.tags(tagNameString); - (the - all - collection of
elements containing all decedents so the subset of a particular type
was equivalent to the DOM method's result (though I don't recall
whether order or 'live-ness' were equivalent).

I don't remember either. Order is the same, IIRC.
 
D

dhtml

Richard said:
You probably won't agree with mine either, but we will have to wait as
it will be a while before i have time to write them all down.

I'll try to get to these comments over the weekend.

In the section “What kind of Collection is a Form”, I have
serious reservations about calling a form a collection. It
isn’t, it a DOM object with certain properties. You can't
access the controls as form, whereas you can use
form.elements because its elements property really is
a collection.


It's right in the spec.


No it is not.


spec says it is:

http://www.w3.org/TR/DOM-Level-2-HTML/html.html#ID-40002357

| The FORM element encompasses behavior similar to a collection and
| an element.


And we can see that a form control can be referenced right off the form:-

document.forms[0][0]

If something has behavior of a collection, then it can be called a
collection. Not an "HTMLCollection" but some sort of collection that is
vaguely described by the spec.

of course that's not the only thing a form is. It's also an EventTarget
in most modern browsers.

The quote is from DOM 1.

http://www.w3.org/TR/2000/WD-DOM-Level-1-20000929/level-one-html.html#ID-40002357



Not calling a form a collection because it doesn't allow access by
index is not a good argument. First of all, it isn't true.

The DOM specification says that a form encompasses behavior of a
collection.

You are reading more into the text than it actually says. In the spec,
the ECMAScript bindings documents make assertions about the mapping of
bracket notation property accessors to collection interface methods. No
such assertions are made about the HTMLFormElement interface, and it
also has no methods that could be mapped to the property accessors. Thus
there is no DOM specified behaviour for - formElement[0] - or -
formElement['someName'] -.


You seem to interpret that as the property accessors map to either item
or namedItem method. But we can see that when using a string as a
property, the indexed element is returned.


But neither are defined in the (ECMAScript bindings for) the specification.

I really don't think I'm reading more into the spec. This is what it says:-

| Functions of objects that implement the HTMLCollection interface:
|
| item(index)
| This *function* returns an object that implements the Node
| interface.
| The index parameter is a Number.
| 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.
| namedItem(name)
| This function returns an object that implements the Node
| interface.
| The name parameter is a String.
| 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.

Where the spec says "Note: This *object* can also be dereferenced using
square bracket notation (e.g. obj[1])", that does define how property
accessors work on a form, even though they defined it wrong.

The square bracket property accessors do not do type checking. Not on
native objects and not when used on DOM elements. The Expression is
converted to a string.

That's why I pointed out:
http://jibbering.com/faq/names/extra_props.html#StandardWrong

And the example shows that
document.forms[0]["0"] is the same as document.forms[0][0];

There is no equivalent of "namedItem" being called. It doesn't work that
way.

<snip>

That would depend on how you defined a collection (the DOM specification
doesn't).

Right.

The term 'collection', in this context, comes from early Netscape
browser documentation, and was also adopted by Microsoft to describe
corresponding structures/objects. The HTML DOM formalises (most of)
those 'collection' objects as the HTMLCollection interface, but a
NamedNodeMap is not an HTMLCollection.

Right. Its a collection in the general sense. For example, a
java.util.Map is part of the "Collections Framework". Granted, we're not
talking about Java, but in the general sense of the word "collection" a
map fits the description.
 
D

dhtml

I don't have IE here, but in Opera:-
javascript:document.write(document.body.childNodes.tags);document.close();

Result:
Opera
function tags() { [native code] }


For a more complete example, we can see on the form.elements collection:-

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"
"http://www.w3.org/TR/html4/loose.dtd">
<html lang="en">
<head>
<title>elements-tags.html</title>
</head>
<body>
<form action="">
</form>
<script type="text/javascript">
document.write(document.forms[0].elements.tags);
</script>

</body>
</html>


Opera, Safari:-
function tags() { [native code] }

I don't have IE here and I'm too busy at work to check this.

Garrett
 
R

Richard Cornford

I'll try to get to these comments over the weekend.

As it looks like it will be unlikely that I will have time to write
them before Monday it will be interesting to see how you do that.
In the section “What kind of Collection is a Form”, I have
serious reservations about calling a form a collection. It
isn’t, it a DOM object with certain properties. You can't
access the controls as form, whereas you can use
form.elements because its elements property really is
a collection.
It's right in the spec.

No it is not.

spec says it is:


No it dosn't.
http://www.w3.org/TR/DOM-Level-2-HTML/html.html#ID-40002357

| The FORM element encompasses behavior similar to a collection
| and an element.

Being a collection would be a recognisable absolute state, while being
similar to a collection is at best ambiguous. Having a - length -
property that dynamically reflects the number of form controls
contained in a form is being similar, not having any form control
retrieval methods represents not being the same as a collection.
And we can see that a form control can be referenced right off
the form:-

document.forms[0][0]

Yes, but as a product of facilitating back-compatibility rather than
as a result of the W2C DOM specification.
If something has behavior of a collection,

The DOM specification does not provide it with the behaviour of a
collection, just some (one) of the properties of a collection.
then it can be called a collection.

The representations of FORM Element in web browsers certainly can be
called 'collections', but that is because there were collections
before there was a W3C DOM standard for them.
Not an "HTMLCollection" but some sort of collection that is
vaguely described by the spec.

Specifications are not in the business of vaguely describing things.
If they don't specify something then it is not part of the
specification, and the form elements are not specified as having any
form control retrieval methods.
of course that's not the only thing a form is. It's also an
EventTarget in most modern browsers.

Except IE (7 and 8 reasonably qualify as 'modern', as 'modern' only
suggest chronological criteria (most lists of "modern" browsers
includes IE 6, but excludes the much more recent Opera 7)).
You are reading more into the text than it actually says. In
the spec, the ECMAScript bindings documents make assertions
about the mapping of bracket notation property accessors to
collection interface methods. No such assertions are made
about the HTMLFormElement interface, and it also has no
methods that could be mapped to the property accessors. Thus
there is no DOM specified behaviour for - formElement[0]
- or - formElement['someName'] -.

You seem to interpret that as the property accessors map to
either item or namedItem method.

That is what the ECMAScript bindings say they must do for the
HTMLCollection interface.
But we can see that when using a string as a
property, the indexed element is returned.

The initial nature of the value of the expression used in a bracket
notation property accessor is irrelevant as they are always type-
converted into strings in property accessor algorithm. The ECMAScript
bindings for the DOM don't get any say in that, they can only suggest
that (like the Array [[Put]] method) some action is taken based on the
value (characters in) of that string.
But neither are defined in the (ECMAScript bindings for) the
specification.

I really don't think I'm reading more into the spec. This is what it says:-

| Functions of objects that implement the HTMLCollection interface:
|
| item(index)
| This *function* returns an object that implements the Node
| interface.
| The index parameter is a Number.
| 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.
| namedItem(name)
| This function returns an object that implements the Node
| interface.
| The name parameter is a String.
| 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.

Where the spec says "Note: This *object* can also be dereferenced
using square bracket notation (e.g. obj[1])", that does define how
property accessors work on a form,

No it does not. That section is (as it clearly sates) is about the
HTMLCollection interface. At no point in the spec does it say that
object implementing the HTMLFormElement interface also implement the
HTMLCollection interface. So, as I have already pointed out, the
HTMLFormElement interface has no methods for form control retrieval
and no mapping of those methods to bracket notation property accessors
(obviously without the former the latter would not be possible).
even though they defined it wrong.

The square bracket property accessors do not do type checking.
Not on native objects and not when used on DOM elements. The
Expression is converted to a string.
And the example shows that
document.forms[0]["0"] is the same as document.forms[0][0];

As the ECMAScript specification requires it to be.
There is no equivalent of "namedItem" being called. It doesn't
work that way.

How it works does not influence the meaning of the specification. If
accessing form controls by indexing the objects implementing the
HTMLFormElement interface were specified there would have to be method
in the interface to do that retrieval, and a mapping of property
accessors to those method in the ECMAScript bindings. These things
are absent from the specification, and so the ability to reference
form controls as properties of implementing the HTMLFormElement
interface is not specified.

It is not what can be done that is being disputed here, but only
whether the ability to do it is specified; it is not.
Right. Its a collection in the general sense. For example, a
java.util.Map is part of the "Collections Framework". Granted,
we're not talking about Java, but in the general sense of the
word "collection" a map fits the description.

We can talk about Java in this context because the HTML DOM Java
bindings are also pertinent when considering intentions regarding the
HTMLFormElement interface. Java has no equivalent of bracket notation
property accessors so when it accesses a collection it has to use
methods. The Java bindings for HTMLCollection have those methods (as
do NodeList, etc.), but the bindings for HTMLFormElement do not. It is
hardly reasonable to assert that a specification framed in IDL and
provided with bindings for ECMAScript and Java should only be
referring only to ECMAScript implementations when saying "encompasses
behaviour similar to a collection", and as an interpretation of that
text that suggests the HTMLFormElement be a collection is contradicted
by the omissions in the Java bindings (in addition to the ECMAScript
bindings) it becomes necessary to read the text as having another
intended meaning.

Ricahrd.
 
D

dhtml

Richard said:
Being a collection would be a recognisable absolute state, while being
similar to a collection is at best ambiguous. Having a - length -
property that dynamically reflects the number of form controls
contained in a form is being similar, not having any form control
retrieval methods represents not being the same as a collection.

The spec says:-
It provides direct access to the contained input elements as well as the
attributes of the FORM element.

Being similar to a collection is not descriptive enough (vague). The
length property is not significant to being similar to a collection.

A collection is, in the general sense of the word, an object that holds
other objects, either indexed or keyed. Describing a form element as
being similar to a collection, first and foremost, solely on the basis
that it has a length property would be misplaced.

It would be shorter to say that the form has length property, however,
the length property is not that significant to warrant placement as the
first sentence in the under the heading HTMLFormElement. In fact, the
length property defined below that.
http://www.w3.org/TR/DOM-Level-2-HTML/html.html#ID-40002357

I think the authors intentionally left out defining "direct access". I
think they were aware of browsers allowing named controls being
accessible directly off the form but couldn't specify that in IDL.


Specifications are not in the business of vaguely describing things.

Similar to a collection sounds vague to me. You said ambiguous, but I
think vague is more appropriate.
But we can see that when using a string as a
property, the indexed element is returned.

The initial nature of the value of the expression used in a bracket
notation property accessor is irrelevant as they are always type-
converted into strings in property accessor algorithm. The ECMAScript
bindings for the DOM don't get any say in that, they can only suggest
that (like the Array [[Put]] method) some action is taken based on the
value (characters in) of that string.

[snip]
The square bracket property accessors do not do type checking.
Not on native objects and not when used on DOM elements. The
Expression is converted to a string.

And that is stated in the article:-

| 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.
....
| When the property access operator is used, the Expression is converted
| to a string with the internal ToString.

I've also mentioned on the html mailing lists:
http://lists.whatwg.org/pipermail/whatwg-whatwg.org/2008-August/015684.html
http://lists.w3.org/Archives/Public/public-html/2008Jul/0169.html
And the example shows that
document.forms[0]["0"] is the same as document.forms[0][0];

As the ECMAScript specification requires it to be.

That is how property access works. But that is not what DOM 0 says.
We can talk about Java in this context because the HTML DOM Java
bindings are also pertinent when considering intentions regarding the
HTMLFormElement interface. Java has no equivalent of bracket notation
property accessors so when it accesses a collection it has to use
methods. The Java bindings for HTMLCollection have those methods (as
do NodeList, etc.), but the bindings for HTMLFormElement do not. It is
hardly reasonable to assert that a specification framed in IDL and
provided with bindings for ECMAScript and Java should only be
referring only to ECMAScript implementations when saying "encompasses
behaviour similar to a collection", and as an interpretation of that
text that suggests the HTMLFormElement be a collection is contradicted
by the omissions in the Java bindings (in addition to the ECMAScript
bindings) it becomes necessary to read the text as having another
intended meaning.

I've updated pages 1, 2, and the conclusion. Accessing controls directly
off the FORM is non-standard. A FORM is not an HTMLCollection, but it
acts like a collection in a non-standard way. Web forms 2.0 is trying to
standardize the behavior.

Looking forward to more comments.

Garrett
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,755
Messages
2,569,534
Members
45,007
Latest member
obedient dusk

Latest Threads

Top