Skip to content

Commit a31e7ff

Browse files
authored
Fix issue in case when namespace has no prefix (#329)
1 parent be17c06 commit a31e7ff

File tree

3 files changed

+44
-18
lines changed

3 files changed

+44
-18
lines changed

lib/c14n-canonicalization.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -167,7 +167,7 @@ C14nCanonicalization.prototype.renderNs = function (
167167
}
168168

169169
p = nsListToRender[a];
170-
res.push(" xmlns:", p.prefix, '="', p.namespaceURI, '"');
170+
res.push(" xmlns", p.prefix ? ":" + p.prefix : "", '="', p.namespaceURI, '"');
171171
}
172172

173173
return { rendered: res.join(""), newDefaultNs: newDefaultNs };

lib/signed-xml.js

Lines changed: 17 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -212,21 +212,10 @@ function findAncestorNs(doc, docSubsetXpath, namespaceResolver) {
212212

213213
// Remove namespaces which are already declared in the subset with the same prefix
214214
var returningNs = [];
215-
var subsetAttributes = docSubset[0].attributes;
216-
for (var j = 0; j < ancestorNsWithoutDuplicate.length; j++) {
217-
var isUnique = true;
218-
for (var k = 0; k < subsetAttributes.length; k++) {
219-
var nodeName = subsetAttributes[k].nodeName;
220-
if (nodeName.search(/^xmlns:/) === -1) continue;
221-
var prefix = nodeName.replace(/^xmlns:/, "");
222-
if (ancestorNsWithoutDuplicate[j].prefix === prefix) {
223-
isUnique = false;
224-
break;
225-
}
226-
}
227-
228-
if (isUnique) {
229-
returningNs.push(ancestorNsWithoutDuplicate[j]);
215+
const subsetNsPrefix = findNSPrefix(docSubset[0]);
216+
for (const ancestorNs of ancestorNsWithoutDuplicate) {
217+
if (ancestorNs.prefix !== subsetNsPrefix) {
218+
returningNs.push(ancestorNs);
230219
}
231220
}
232221

@@ -247,9 +236,9 @@ function collectAncestorNamespaces(node, nsArray) {
247236
if (parent.attributes && parent.attributes.length > 0) {
248237
for (var i = 0; i < parent.attributes.length; i++) {
249238
var attr = parent.attributes[i];
250-
if (attr && attr.nodeName && attr.nodeName.search(/^xmlns:/) !== -1) {
239+
if (attr && attr.nodeName && attr.nodeName.search(/^xmlns:?/) !== -1) {
251240
nsArray.push({
252-
prefix: attr.nodeName.replace(/^xmlns:/, ""),
241+
prefix: attr.nodeName.replace(/^xmlns:?/, ""),
253242
namespaceURI: attr.nodeValue,
254243
});
255244
}
@@ -259,6 +248,17 @@ function collectAncestorNamespaces(node, nsArray) {
259248
return collectAncestorNamespaces(parent, nsArray);
260249
}
261250

251+
function findNSPrefix(subset) {
252+
const subsetAttributes = subset.attributes;
253+
for (let k = 0; k < subsetAttributes.length; k++) {
254+
const nodeName = subsetAttributes[k].nodeName;
255+
if (nodeName.search(/^xmlns:?/) !== -1) {
256+
return nodeName.replace(/^xmlns:?/, "");
257+
}
258+
}
259+
return subset.prefix || "";
260+
}
261+
262262
/**
263263
* Xml signature implementation
264264
*

test/c14n-non-exclusive-unit-test.js

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -95,6 +95,23 @@ exports[
9595
test_findAncestorNs(test, xml, xpath, expected);
9696
};
9797

98+
exports["findAncestorNs: Should not find namespace when both has no prefix"] = function (test) {
99+
var xml = "<root xmlns='bbb'><child1><child2 xmlns='ddd'></child2></child1></root>";
100+
var xpath = "//*[local-name()='child2']";
101+
var expected = [];
102+
103+
test_findAncestorNs(xml, xpath, expected);
104+
};
105+
106+
exports["findAncestorNs: Should find namespace without prefix"] = function (test) {
107+
var xml =
108+
"<root xmlns='bbb'><child1><ds:child2 xmlns:ds='ddd'><ds:child3></ds:child3></ds:child2></child1></root>";
109+
var xpath = "//*[local-name()='child2']";
110+
var expected = [{ prefix: "", namespaceURI: "bbb" }];
111+
112+
test_findAncestorNs(xml, xpath, expected);
113+
};
114+
98115
exports["findAncestorNs: Ignores namespace declared in the target xpath node"] = function (test) {
99116
var xml = "<root xmlns:aaa='bbb'><child1><child2 xmlns:ccc='ddd'></child2></child1></root>";
100117
var xpath = "/root/child1/child2";
@@ -197,3 +214,12 @@ exports["C14n: Don't declare an attribute's namespace prefix if in scope from pa
197214

198215
test_C14nCanonicalization(test, xml, xpath, expected);
199216
};
217+
218+
exports["C14n: should not has colon when parent namespace has no prefix"] = function (test) {
219+
var xml =
220+
"<root xmlns='bbb'><child1><cc:child2 xmlns:cc='ddd'><cc:child3></cc:child3></cc:child2></child1></root>";
221+
var xpath = "//*[local-name()='child3']";
222+
var expected = '<cc:child3 xmlns="bbb" xmlns:cc="ddd"></cc:child3>';
223+
224+
test_C14nCanonicalization(test, xml, xpath, expected);
225+
};

0 commit comments

Comments
 (0)