From 6fd54a2d018870cc5e0c6f2a393f9f6f257f9167 Mon Sep 17 00:00:00 2001 From: Josh Johnson Date: Mon, 6 Jul 2020 22:58:46 -0400 Subject: [PATCH 1/2] Add Failing Test --- src/test/extension.test.ts | 8 ++++++-- src/test/test-data/issue-293.formatted.xml | 6 ++++++ src/test/test-data/issue-293.unformatted.xml | 6 ++++++ 3 files changed, 18 insertions(+), 2 deletions(-) create mode 100644 src/test/test-data/issue-293.formatted.xml create mode 100644 src/test/test-data/issue-293.unformatted.xml diff --git a/src/test/extension.test.ts b/src/test/extension.test.ts index 640ec47..31f44e7 100644 --- a/src/test/extension.test.ts +++ b/src/test/extension.test.ts @@ -99,6 +99,10 @@ describe("V2XmlFormatter", () => { it("should handle mixed content as a child of another element", () => { testFormatter(xmlFormatter, options, "issue-257"); }); + + it("should not touch CDATA content", () => { + testFormatter(xmlFormatter, options, "issue-293"); + }); }); describe("#minifyXml(xml, options)", () => { @@ -130,7 +134,7 @@ function testFormatter(xmlFormatter: XmlFormatter, options: XmlFormattingOptions const actualFormattedXml = xmlFormatter.formatXml(unformattedXml, options).replace(/\r/g, ""); // tslint:disable-next-line - assert.ok((actualFormattedXml === expectedFormattedXml), `Actual formatted XML does not match expected formatted XML.\n\nACTUAL\n${actualFormattedXml.replace(/\s/, "~ws~")}\n\nEXPECTED\n${expectedFormattedXml.replace(/\s/, "~ws~")}`); + assert.ok((actualFormattedXml === expectedFormattedXml), `Actual formatted XML does not match expected formatted XML.\n\nACTUAL\n${actualFormattedXml.replace(/\s/g, "~ws~")}\n\nEXPECTED\n${expectedFormattedXml.replace(/\s/g, "~ws~")}`); } function testMinifier(xmlFormatter: XmlFormatter, options: XmlFormattingOptions, fileLabel: string): void { @@ -140,5 +144,5 @@ function testMinifier(xmlFormatter: XmlFormatter, options: XmlFormattingOptions, const actualMinifiedXml = xmlFormatter.minifyXml(unminifiedXml, options).replace(/\r/g, ""); // tslint:disable-next-line - assert.ok((actualMinifiedXml === expectedMinifiedXml), `Actual minified XML does not match expected minified XML.\n\nACTUAL\n${actualMinifiedXml.replace(/\s/, "~ws~")}\n\nEXPECTED\n${expectedMinifiedXml.replace(/\s/, "~ws~")}`); + assert.ok((actualMinifiedXml === expectedMinifiedXml), `Actual minified XML does not match expected minified XML.\n\nACTUAL\n${actualMinifiedXml.replace(/\s/g, "~ws~")}\n\nEXPECTED\n${expectedMinifiedXml.replace(/\s/g, "~ws~")}`); } diff --git a/src/test/test-data/issue-293.formatted.xml b/src/test/test-data/issue-293.formatted.xml new file mode 100644 index 0000000..f238eb5 --- /dev/null +++ b/src/test/test-data/issue-293.formatted.xml @@ -0,0 +1,6 @@ + + + + val +]]> + \ No newline at end of file diff --git a/src/test/test-data/issue-293.unformatted.xml b/src/test/test-data/issue-293.unformatted.xml new file mode 100644 index 0000000..f238eb5 --- /dev/null +++ b/src/test/test-data/issue-293.unformatted.xml @@ -0,0 +1,6 @@ + + + + val +]]> + \ No newline at end of file From 10619ee123373f3f138e02442ddbb7e342379edd Mon Sep 17 00:00:00 2001 From: Josh Johnson Date: Mon, 6 Jul 2020 23:13:40 -0400 Subject: [PATCH 2/2] Prevent CDATA Formatting fixes: #293 --- src/formatting/formatters/v2-xml-formatter.ts | 30 +++++++++---------- 1 file changed, 15 insertions(+), 15 deletions(-) diff --git a/src/formatting/formatters/v2-xml-formatter.ts b/src/formatting/formatters/v2-xml-formatter.ts index 8eed3d7..8b0fcbb 100644 --- a/src/formatting/formatters/v2-xml-formatter.ts +++ b/src/formatting/formatters/v2-xml-formatter.ts @@ -7,9 +7,9 @@ const MagicalStringOfWonders = "~::~MAAAGIC~::~"; /* tslint:disable no-use-before-declare */ export class V2XmlFormatter implements XmlFormatter { formatXml(xml: string, options: XmlFormattingOptions): string { - // this replaces all "<" brackets inside of comments to a magical string - // so the following minification steps don't mess with comment formatting - xml = this._sanitizeComments(xml); + // this replaces all "<" brackets inside of comments and CDATA to a magical string + // so the following minification steps don't mess with comment and CDATA formatting + xml = this._sanitizeCommentsAndCDATA(xml); // remove whitespace from between tags, except for line breaks xml = xml.replace(/>\s{0,} { @@ -25,7 +25,7 @@ export class V2XmlFormatter implements XmlFormatter { }); // the coast is clear - we can drop those "<" brackets back in - xml = this._unsanitizeComments(xml); + xml = this._unsanitizeCommentsAndCDATA(xml); let output = ""; @@ -298,9 +298,9 @@ export class V2XmlFormatter implements XmlFormatter { return text.replace(/[^\r\n\S]+$/, ""); } - private _sanitizeComments(xml: string): string { + private _sanitizeCommentsAndCDATA(xml: string): string { let output = ""; - let inComment = false; + let inCommentOrCDATA = false; for (let i = 0; i < xml.length; i++) { const cc = xml[i]; @@ -308,20 +308,20 @@ export class V2XmlFormatter implements XmlFormatter { const nnc = xml.charAt(i + 2); const pc = xml.charAt(i - 1); - if (!inComment && cc === "<" && nc === "!" && nnc === "-") { - inComment = true; - output += ""; + else if (inCommentOrCDATA && (cc === "-" && nc === "-" && nnc === ">") || (cc === "]" && nc === "]" && nnc === ">")) { + inCommentOrCDATA = false; + output += (cc === "-") ? "-->" : "]]>"; i += 2; } @@ -334,7 +334,7 @@ export class V2XmlFormatter implements XmlFormatter { return output; } - private _unsanitizeComments(xml: string): string { + private _unsanitizeCommentsAndCDATA(xml: string): string { return xml.replace(new RegExp(MagicalStringOfWonders, "g"), "<"); } }