On Thu, Oct 23, 2008 at 5:33 PM, Dave Cridland <[EMAIL PROTECTED]> wrote:
>
> My personal view is that stream termination is not really acceptable, but 
> sometimes implementors have little choice, and that the next easiest to 
> implement is to essentially ignore undeclared prefixes, treating them as if 
> they were an unknown URI.

It really depends on which way you are trying to go with the XMPP
standard. Servers are only able to handle and forward documents which
are not namespace-well-formed because they are not conforming with the
XML names spec. XMPP has historical baggage that makes it really
difficult to use off-the-shelf parsers for server implementations and
be close to efficient - things like stanza namespace URIs changing
from jabber:client to jabber:server based on context make it hard to
use off-the-shelf DOM. To be fair to the original creators of Jabber
(and I suppose to myself), namespaces work differently than originally
envisioned. Today DTDs have all but been forgotten, but when XML names
was originally written the expectation of use by a DTD was something
like this:

<!DOCTYPE A [
<!ELEMENT A >
<!ATTLIST A
    xmlns CDATA #REQUIRED "urn:foo"
    xmlns:bar CDATA #REQUIRED "urn:bar"
    bar:name CDATA #OPTIONAL>
]>

As in, namespaces are used to combine specifications into a new
specification, not as an inclusion and extension mechanism. Of course
the original thoughts were all but abandoned by the time XML Schema
was created.
Anyway the question is, will the spec try to actually be conforming in
the future? Is the idea to move away from 'attributes and element
names with special meanings' and firmly into the realm of xml names?
Or to say 'you can try to be conforming with xml names, but keep in
mind there are servers out there which use regexp rather than an XML
parser, and you will be expected to work with them'.

>
> 2) Why we might want to let servers forward "Bad XMLNS":
>
> As stated above, the status quo is that some servers do forward XML without 
> checking that every prefix used is declared.
>
> There are advantages in doing so, indeed, since an XML stream can be split 
> into stanzas, and the outer element of the stanza examined, without doing 
> more than a relatively simple, non-destructive, lex of a buffer.
>
> This seems to give people some confusion, so forgive me while I explain this 
> in detail.
>
> In other words, a server starts off with a string:
>
> "<message to='[EMAIL PROTECTED]' type='headline'><!-- A comment containing a 
> < --><![CDATA[ A CDATA section, perhaps with < or > in ]]><foo/></message>"
>
> By iterating through the string, character by character (or, more likely, 
> octet by octet, since it's equivalent in UTF-8 for these purposes), and 
> maintaining a very small amount of fixed state irrespective of the "depth" of 
> the XML, we can find the end of the element.

What if the server receives non-well-formed XML?

There are plenty of client (and probably server) implementations which
do something similar to this, but they do it because off-the-shelf
tools generally do not expect you to parse an XML fragment rather than
an XML document.

Really at a minimum your XML-parsing state machine needs a stack of
element names and a temporary dictionary of attribute names (to detect
<foo bar='1' bar='2' />)

>
> If servers were unconditionally mandated to check each and every prefix in 
> incoming streams, then servers would be forced to build an allocated lookup 
> table for prefixes. This lookup table needs to be adjusted potentially on 
> every element - with every opening tag, new prefixes can be defined - and 
> these affect the tag they're declared in, so we must handle cases such as:
>
> "<foo:element bar:attr='false' xmlns:foo='l' xmlns:bar='k'>"
>
> Which essentially nessecitates a three-phase parse, first finding the 
> possibly prefixed names and attributes, then gathering XML namespace 
> declarations, then finally resolving each prefix. At the closing tag, of 
> course, we need to locate every prefix declaration now leaving scope, and 
> remove it from our lookup.

It necessitates a symbol table; a stack of namespace prefix
declarations. Since you already have the requirement for the attribute
name dictionary, you don't need to use two passes on the data in order
to validate this; build the attribute dictionary by qname, scan it to
build the symbol table, and then double-check the attributes to make
sure you don't have <foo xmlns:a='1' xmlns:b='1' a:bar='1' b:bar='2'
/>.

> And what for?

So that you use XML correctly, and can do productive things rather
than dealing with DoS vectors. To give an example, ATOM's biggest
benefit over RSS is that it requires XML well-formedness.

Look, it really sucks sometimes that a XMPP connection is an XML
document. There are hacks to make this more efficient, and there are
hacks to do XMPP with off-the-shelf XML tools. Deciding to ignore that
it is XML altogether and just counting angle brackets is not a fix,
and is just not going to play well if you are dealing with anything
other than sanitized input.

You can put most off-the-shelf tools in an XML namespace ignorant
mode, but it still comes to a decision - does XMPP use attributes with
funny names that start with 'xmlns:' and happens to conflict with XML
names, or is it meant to be XML names compliant with some bad legacy
software out there that server authors might want to cope with. The
middle ground is a world of pain.

-DW

Reply via email to