From ab8e2b892e118b69426a9f7573eb3b07340ef6bd Mon Sep 17 00:00:00 2001 From: Mikael Selander Date: Thu, 14 Apr 2022 08:42:35 +0200 Subject: [PATCH] fix: remove invalid xml characters in junit reporter output (fix #1144) (#1145) --- packages/vitest/src/node/reporters/junit.ts | 38 ++++++++++++++++--- test/reporters/src/data.ts | 8 ++++ .../__snapshots__/reporters.spec.ts.snap | 18 +++++++++ 3 files changed, 58 insertions(+), 6 deletions(-) diff --git a/packages/vitest/src/node/reporters/junit.ts b/packages/vitest/src/node/reporters/junit.ts index 9643e341781a..681b4dfef12a 100644 --- a/packages/vitest/src/node/reporters/junit.ts +++ b/packages/vitest/src/node/reporters/junit.ts @@ -23,13 +23,39 @@ function flattenTasks(task: Task, baseName = ''): Task[] { } } +// https://gist.github.com/john-doherty/b9195065884cdbfd2017a4756e6409cc +function removeInvalidXMLCharacters(value: any, removeDiscouragedChars: boolean): string { + // eslint-disable-next-line no-control-regex + let regex = /((?:[\0-\x08\x0B\f\x0E-\x1F\uFFFD\uFFFE\uFFFF]|[\uD800-\uDBFF](?![\uDC00-\uDFFF])|(?:[^\uD800-\uDBFF]|^)[\uDC00-\uDFFF]))/g + value = String(value || '').replace(regex, '') + + if (removeDiscouragedChars) { + // remove everything discouraged by XML 1.0 specifications + regex = new RegExp( + '([\\x7F-\\x84]|[\\x86-\\x9F]|[\\uFDD0-\\uFDEF]|(?:\\uD83F[\\uDFFE\\uDFFF])|(?:\\uD87F[\\uDF' + + 'FE\\uDFFF])|(?:\\uD8BF[\\uDFFE\\uDFFF])|(?:\\uD8FF[\\uDFFE\\uDFFF])|(?:\\uD93F[\\uDFFE\\uD' + + 'FFF])|(?:\\uD97F[\\uDFFE\\uDFFF])|(?:\\uD9BF[\\uDFFE\\uDFFF])|(?:\\uD9FF[\\uDFFE\\uDFFF])' + + '|(?:\\uDA3F[\\uDFFE\\uDFFF])|(?:\\uDA7F[\\uDFFE\\uDFFF])|(?:\\uDABF[\\uDFFE\\uDFFF])|(?:\\' + + 'uDAFF[\\uDFFE\\uDFFF])|(?:\\uDB3F[\\uDFFE\\uDFFF])|(?:\\uDB7F[\\uDFFE\\uDFFF])|(?:\\uDBBF' + + '[\\uDFFE\\uDFFF])|(?:\\uDBFF[\\uDFFE\\uDFFF])(?:[\\0-\\t\\x0B\\f\\x0E-\\u2027\\u202A-\\uD7FF\\' + + 'uE000-\\uFFFF]|[\\uD800-\\uDBFF][\\uDC00-\\uDFFF]|[\\uD800-\\uDBFF](?![\\uDC00-\\uDFFF])|' + + '(?:[^\\uD800-\\uDBFF]|^)[\\uDC00-\\uDFFF]))', 'g') + + value = value.replace(regex, '') + } + + return value +} + function escapeXML(value: any): string { - return String(value) - .replace(/&/g, '&') - .replace(/"/g, '"') - .replace(/'/g, ''') - .replace(//g, '>') + return removeInvalidXMLCharacters( + String(value) + .replace(/&/g, '&') + .replace(/"/g, '"') + .replace(/'/g, ''') + .replace(//g, '>'), + true) } function getDuration(task: Task): string | undefined { diff --git a/test/reporters/src/data.ts b/test/reporters/src/data.ts index a5003c07197b..03f9e0451c1c 100644 --- a/test/reporters/src/data.ts +++ b/test/reporters/src/data.ts @@ -142,6 +142,14 @@ const tasks: Task[] = [ fails: undefined, file, result: { state: 'pass', duration: 0.1923508644104004 }, + logs: [ + { + content: 'error', + type: 'stderr', + time: 1642587001759, + size: 15, + }, + ], }, ] diff --git a/test/reporters/tests/__snapshots__/reporters.spec.ts.snap b/test/reporters/tests/__snapshots__/reporters.spec.ts.snap index 5e31568012c8..6083083da594 100644 --- a/test/reporters/tests/__snapshots__/reporters.spec.ts.snap +++ b/test/reporters/tests/__snapshots__/reporters.spec.ts.snap @@ -24,6 +24,9 @@ AssertionError: expected 2.23606797749979 to equal 2 + +[33merror[39m + @@ -54,6 +57,9 @@ AssertionError: expected 2.23606797749979 to equal 2 + +[33merror[39m + @@ -89,6 +95,9 @@ AssertionError: expected 2.23606797749979 to equal 2 + +[33merror[39m + @@ -124,6 +133,9 @@ AssertionError: expected 2.23606797749979 to equal 2 + +[33merror[39m + @@ -159,6 +171,9 @@ AssertionError: expected 2.23606797749979 to equal 2 + +[33merror[39m + @@ -194,6 +209,9 @@ AssertionError: expected 2.23606797749979 to equal 2 + +[33merror[39m +