Skip to content

Prefix collision issues in serialization algorithms #75

Open
@bwrrp

Description

@bwrrp

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.

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions