Skip to content

location.reference guard reports the wrong error, and the root-node case never reaches it #583

Description

@cjbarth

Summary

computeSignature() guards the before and after location actions with referenceNode.parentNode == null and throws `location.reference` refers to the root node (by default), so we can't insert `before` (src/signed-xml.ts:1041-1053). The check does not match the message:

  • For the root element the guard never fires. documentElement.parentNode is the Document (nodeType 9), not null, so the code proceeds to insertBefore and xmldom throws Hierarchy request error: Only one element can be added and only after doctype. The documented error is unreachable for the case it names.
  • The guard does fire for a parentless node such as an attribute, where the message is wrong: the reference did not refer to the root node.

Reproduction

const sig = new SignedXml({ privateKey, canonicalizationAlgorithm, signatureAlgorithm });
sig.addReference({ xpath: "/*", transforms: [canonicalizationAlgorithm], digestAlgorithm });

// Root element: reports xmldom's internal error, not ours.
sig.computeSignature("<root>trusted</root>", { location: { reference: "/*", action: "before" } });
// Hierarchy request error: Only one element can be added and only after doctype

// Attribute: hits our guard, with a message that does not describe the input.
sig.computeSignature('<root id="x">trusted</root>', { location: { reference: "//@id", action: "before" } });
// `location.reference` refers to the root node (by default), so we can't insert `before`

Both behave this way on master and on 6.1.2.

Suggested fix

Decide what each invalid location.reference should report, then make the checks say it:

  • Root element, or any child of the document node: throw the existing documented error instead of letting xmldom's Hierarchy request error escape.
  • A location.reference that does not select an element: reject it explicitly rather than reusing the root-node message.

Both change the error a caller observes for input that currently fails anyway, which is why this is filed against v7.0.

Context

Found while tracing the codecov/patch gap on #577: these two throw statements and their if branches are part of that PR's uncovered diff, because #577 moves the block. A test today could only pin the misleading message, so the guard should be fixed first.

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

    Type

    No type

    Projects

    No projects

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions