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

Prefix collision issues in serialization algorithms #75

Open
bwrrp opened this issue Oct 17, 2023 · 1 comment
Open

Prefix collision issues in serialization algorithms #75

bwrrp opened this issue Oct 17, 2023 · 1 comment

Comments

@bwrrp
Copy link

bwrrp commented Oct 17, 2023

While revisiting the XML serialization spec I found a few more bugs in it that can lead to serialization issues:

prefix redeclaration confusion

const root = document.appendChild(document.createElementNS('ns1', 'pre:root'));
const child = root.appendChild(document.createElementNS('ns2', 'pre:child'));
child.appendChild(document.createElementNS('ns1', 'grandChild'));

This currently results in grandChild being assigned the pre prefix without redeclaring it, which places it in ns2 instead of ns1.

Firefox assigns a new a0 prefix to child here to avoid this. Chrome redeclares the pre prefix on grandChild back to ns2.

Chrome's behavior seems to more closely match the author's intent in that it preserves all prefixes as specified. To match that, the algorithm should likely keep track of the prefix to namespace mapping in addition to the currently tracked inverse mapping, and use that to check if the prefix it wants to use needs to be redeclared.

generated prefix collisions

const root = document.appendChild(document.createElementNS('ns1', 'ns1:root'));
root.setAttributeNS('ns2', 'attr', 'value');

This currently results in two declarations for the ns1 prefix on the root element, one for ns1 produced as part of serializing the element, one for ns2 produced for the generated prefix ns1. That is not well-formed.

Firefox and Chrome both assigns a new prefix to attr here to fix this. In Firefox the prefix is a0, Chrome uses ns2.

To fix, the "generate a prefix" algorithm should probably check whether the prefix it intends to generate isn't declared already. If there is an existing local declaration for the prefix, it can loop to try a higher prefix index, matching Chrome's behavior.

@bwrrp
Copy link
Author

bwrrp commented Oct 18, 2023

Apologies, the second issue seems to have been reported already as #44, although the repro steps here are simpler. I did not find mention of the first issue elsewhere.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant