Skip to content

Commit

Permalink
Escape according to Canonical XML 1.0.
Browse files Browse the repository at this point in the history
See <http://www.w3.org/TR/2000/WD-xml-c14n-20000119.html#charescaping>.

First and foremost, this change allows adding linefeeds, tabs and
carriage returns to attribute values.  This was not possible before,
since such characters did not get escaped and without escaping a
conforming XML reader will replace them by blanks. [1]

While at it, this change escapes attribute values according to the
Canonical XML 1.0 specification.  In particular, in attribute values
greater-than no longer gets escaped.

[1] http://www.w3.org/TR/2004/REC-xml-20040204/#AVNormalize
  • Loading branch information
jscheid committed Nov 13, 2014
1 parent d50c58c commit 4b20998
Show file tree
Hide file tree
Showing 2 changed files with 17 additions and 4 deletions.
9 changes: 8 additions & 1 deletion lib/xml-writer.js
Expand Up @@ -254,7 +254,14 @@ XMLWriter.prototype = {
if (!this.tags && !this.comment && !this.pi && !this.cdata) return this;
if (this.attributes && this.attribute) {
++this.texts;
this.write(content.replace(/&/g, '&amp;').replace(/</g, '&lt;').replace(/>/g, '&gt;').replace(/"/g, '&quot;'));
this.write(content
.replace(/&/g, '&amp;')
.replace(/</g, '&lt;')
.replace(/"/g, '&quot;')
.replace(/\t/g, '&#x9;')
.replace(/\n/g, '&#xA;')
.replace(/\r/g, '&#xD;')
);
return this;
} else if (this.attributes && !this.attribute) {
this.endAttributes();
Expand Down
12 changes: 9 additions & 3 deletions test/attributes.js
Expand Up @@ -46,14 +46,14 @@ exports['t05'] = function (test) {
test.equal(this.xw.toString(), '<tag key1=""><tag>value</tag></tag>');
test.done();
};
exports['t06'] = function (test) {
exports['t06a'] = function (test) {
this.xw.startElement('tag').writeAttribute('key', 'value').endElement();
test.equal(this.xw.toString(), '<tag key="value"/>');
test.done();
};
exports['t06'] = function (test) {
exports['t06b'] = function (test) {
this.xw.startElement('tag').writeAttribute('key', '"< & >"').endElement();
test.equal(this.xw.toString(), '<tag key="&quot;&lt; &amp; &gt;&quot;"/>');
test.equal(this.xw.toString(), '<tag key="&quot;&lt; &amp; >&quot;"/>');
test.done();
};
exports['t07'] = function (test) {
Expand All @@ -64,3 +64,9 @@ exports['t07'] = function (test) {
test.equal(this.xw.toString(), '<tag/>');
test.done();
};
exports['t08'] = function (test) {
this.xw.startElement('tag');
this.xw.writeAttribute('key1', '\t\n\r');
test.equal(this.xw.toString(), '<tag key1="&#x9;&#xA;&#xD;"/>');
test.done();
};

0 comments on commit 4b20998

Please sign in to comment.