Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Error thrown when resetting the default namespace to null on a prefixed element #48

Open
bwrrp opened this issue Mar 22, 2019 · 4 comments · May be fixed by #49
Open

Error thrown when resetting the default namespace to null on a prefixed element #48

bwrrp opened this issue Mar 22, 2019 · 4 comments · May be fixed by #49

Comments

@bwrrp
Copy link

bwrrp commented Mar 22, 2019

Consider the following code, run on an empty XML document:

const root = document.appendChild(document.createElementNS('ns_root', 'root'));
const child = root.appendChild(document.createElementNS('ns_child', 'p:child'));
child.setAttributeNS('http://www.w3.org/2000/xmlns/', 'xmlns', '');
const grandChild = child.appendChild(document.createElementNS(null, 'grandchild'));

Which produces the following DOM (whitespace added for clarity):

<root xmlns="ns_root">
  <p:child xmlns:p="ns_child" xmlns="">
    <grandchild/>
  </p:child>
</root>

If we now run the serialization algorithms as specified, with the require-well-formed flag set (as would be the case in root.outerHTML, for instance), an exception is thrown at step 3.5.2.3. of "serializing an element's attributes":

If the require well-formed flag is set (its value is true), and the value of attr's value attribute is the empty string, then throw an exception; namespace prefix declarations cannot be used to undeclare a namespace (use a default namespace declaration instead).

The error message seems to suggest that this check is intended only for prefix declarations, and indeed something like xmlns:pre="" would have been invalid. However, setting the default namespace back to null should be allowed. In the example given, an explicit declaration on child would be preferable to having an automatically generated xmlns="" on grandchild, especially in cases where there would be many grandchild nodes.

It seems that the condition for this error should have included a check whether attr's prefix attribute is not null. Note that both default namespace declaration attributes and prefix declaration attributes are specified to be in the XMLNS namespace, even though the former does not have a prefix (this is the only case of an unprefixed attribute having a non-null namespace).

Note that this case is only hit for an xmlns="" declaration on an element that is itself prefixed, in a namespace other than the inherited default. If the element itself is unprefixed it would itself be in the null namespace. This would cause its own serialization generating the declaration and the ignore namespace definition attribute flag being set for the call to serialize its attributes, which in turn would cause the algorithm to skip the attribute earlier at step 3.5.2.1. (second bullet point).

Testing the above example in Firefox and Chrome shows that root.outerHTML returns the expected serialization (minus the whitespace) and does not throw the error.

Please let me know if it would be appreciated if I submit a PR (here and/or on the WPT repo?). It looks like the last one was flagged as I'm not a W3C member.

@annevk
Copy link
Member

annevk commented Mar 22, 2019

@bwrrp additional WPT coverage would be terrific. Patching this standard too, but as you can tell from your previous PR there's no active maintenance at the moment so it might linger around for a while until it gets applied. (I'll look into that a bit.)

bwrrp added a commit to bwrrp/wpt that referenced this issue Mar 22, 2019
This adds a DOM parsing test for the case where the default namespace is
reset on a prefixed element. If implemented according to the spec,
serialization with the `require-well-formed` flag set should throw. The
error message seems to suggest that this check was intended only for
prefix declarations, and indeed something like xmlns:pre="" would have
been invalid. However, setting the default namespace back to null should
be allowed, and from initial testing at least Firefox and Chrome seem to
agree and do not throw.
@bwrrp
Copy link
Author

bwrrp commented Mar 22, 2019

I've added the example as a WPT test case in web-platform-tests/wpt#16025.

bwrrp added a commit to bwrrp/DOM-Parsing that referenced this issue Mar 22, 2019
…medness

At this point, the declaration may either be a prefix declaration or a
default namespace declaration. While prefix declarations for the null
namespace are not valid, it is allowed to reset the default namespace
this way.

Fixes w3c#48
@annevk
Copy link
Member

annevk commented Mar 22, 2019

Now that you wrote that test, I'm reminded of #47, so perhaps the test isn't needed after all as we added a very similar one already.

@bwrrp bwrrp linked a pull request Mar 22, 2019 that will close this issue
@bwrrp
Copy link
Author

bwrrp commented Mar 22, 2019

Ah yes, I saw that one. Looking at the tests in the linked PR it looks like they do not cover the case where the element having the xmlns="" declaration has a prefix (and is therefore not affected by this declaration, which now only applies to its children). In serialization, this causes the ignore namespace definition attribute flag to be set, which means the algorithm will skip the declaration before reaching the branch that throws the error mentioned here.

wmfgerrit pushed a commit to wikimedia/mediawiki-libs-Dodo that referenced this issue Jul 3, 2021
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging a pull request may close this issue.

3 participants