From a31e7ff30822b6fc81c584ce4b13951e4d81458b Mon Sep 17 00:00:00 2001 From: zhangsn <398816613@qq.com> Date: Sun, 9 Jul 2023 02:11:24 +0800 Subject: [PATCH] Fix issue in case when namespace has no prefix (#329) --- lib/c14n-canonicalization.js | 2 +- lib/signed-xml.js | 34 ++++++++++++++-------------- test/c14n-non-exclusive-unit-test.js | 26 +++++++++++++++++++++ 3 files changed, 44 insertions(+), 18 deletions(-) diff --git a/lib/c14n-canonicalization.js b/lib/c14n-canonicalization.js index 0e4ba696..6dffac48 100644 --- a/lib/c14n-canonicalization.js +++ b/lib/c14n-canonicalization.js @@ -167,7 +167,7 @@ C14nCanonicalization.prototype.renderNs = function ( } p = nsListToRender[a]; - res.push(" xmlns:", p.prefix, '="', p.namespaceURI, '"'); + res.push(" xmlns", p.prefix ? ":" + p.prefix : "", '="', p.namespaceURI, '"'); } return { rendered: res.join(""), newDefaultNs: newDefaultNs }; diff --git a/lib/signed-xml.js b/lib/signed-xml.js index 7d26d726..ac3dd51f 100644 --- a/lib/signed-xml.js +++ b/lib/signed-xml.js @@ -212,21 +212,10 @@ function findAncestorNs(doc, docSubsetXpath, namespaceResolver) { // Remove namespaces which are already declared in the subset with the same prefix var returningNs = []; - var subsetAttributes = docSubset[0].attributes; - for (var j = 0; j < ancestorNsWithoutDuplicate.length; j++) { - var isUnique = true; - for (var k = 0; k < subsetAttributes.length; k++) { - var nodeName = subsetAttributes[k].nodeName; - if (nodeName.search(/^xmlns:/) === -1) continue; - var prefix = nodeName.replace(/^xmlns:/, ""); - if (ancestorNsWithoutDuplicate[j].prefix === prefix) { - isUnique = false; - break; - } - } - - if (isUnique) { - returningNs.push(ancestorNsWithoutDuplicate[j]); + const subsetNsPrefix = findNSPrefix(docSubset[0]); + for (const ancestorNs of ancestorNsWithoutDuplicate) { + if (ancestorNs.prefix !== subsetNsPrefix) { + returningNs.push(ancestorNs); } } @@ -247,9 +236,9 @@ function collectAncestorNamespaces(node, nsArray) { if (parent.attributes && parent.attributes.length > 0) { for (var i = 0; i < parent.attributes.length; i++) { var attr = parent.attributes[i]; - if (attr && attr.nodeName && attr.nodeName.search(/^xmlns:/) !== -1) { + if (attr && attr.nodeName && attr.nodeName.search(/^xmlns:?/) !== -1) { nsArray.push({ - prefix: attr.nodeName.replace(/^xmlns:/, ""), + prefix: attr.nodeName.replace(/^xmlns:?/, ""), namespaceURI: attr.nodeValue, }); } @@ -259,6 +248,17 @@ function collectAncestorNamespaces(node, nsArray) { return collectAncestorNamespaces(parent, nsArray); } +function findNSPrefix(subset) { + const subsetAttributes = subset.attributes; + for (let k = 0; k < subsetAttributes.length; k++) { + const nodeName = subsetAttributes[k].nodeName; + if (nodeName.search(/^xmlns:?/) !== -1) { + return nodeName.replace(/^xmlns:?/, ""); + } + } + return subset.prefix || ""; +} + /** * Xml signature implementation * diff --git a/test/c14n-non-exclusive-unit-test.js b/test/c14n-non-exclusive-unit-test.js index cdf47e9b..0273b939 100644 --- a/test/c14n-non-exclusive-unit-test.js +++ b/test/c14n-non-exclusive-unit-test.js @@ -95,6 +95,23 @@ exports[ test_findAncestorNs(test, xml, xpath, expected); }; +exports["findAncestorNs: Should not find namespace when both has no prefix"] = function (test) { + var xml = ""; + var xpath = "//*[local-name()='child2']"; + var expected = []; + + test_findAncestorNs(xml, xpath, expected); +}; + +exports["findAncestorNs: Should find namespace without prefix"] = function (test) { + var xml = + ""; + var xpath = "//*[local-name()='child2']"; + var expected = [{ prefix: "", namespaceURI: "bbb" }]; + + test_findAncestorNs(xml, xpath, expected); +}; + exports["findAncestorNs: Ignores namespace declared in the target xpath node"] = function (test) { var xml = ""; var xpath = "/root/child1/child2"; @@ -197,3 +214,12 @@ exports["C14n: Don't declare an attribute's namespace prefix if in scope from pa test_C14nCanonicalization(test, xml, xpath, expected); }; + +exports["C14n: should not has colon when parent namespace has no prefix"] = function (test) { + var xml = + ""; + var xpath = "//*[local-name()='child3']"; + var expected = ''; + + test_C14nCanonicalization(test, xml, xpath, expected); +};