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);
+};