From 8db98b6172978b36d2756b502d23de708fbb7f4c Mon Sep 17 00:00:00 2001 From: Jon Parise Date: Thu, 14 Mar 2024 11:18:39 -0700 Subject: [PATCH] fix: escape backslashes in JSON formatter output Otherwise, our JSON-formatted ouput is not actually valid JSON when it is rendered with unescaped backslashes like ".+@.+\..+". Signed-off-by: Jon Parise --- formatters/json_formatter.js | 2 +- tests/formatters/json_formatter_tests.js | 27 ++++++++++++++++++++++++ 2 files changed, 28 insertions(+), 1 deletion(-) diff --git a/formatters/json_formatter.js b/formatters/json_formatter.js index 236ac156..79d16231 100644 --- a/formatters/json_formatter.js +++ b/formatters/json_formatter.js @@ -14,7 +14,7 @@ class JsonFormatter { * @returns {string} The formatted output */ static formatOutput(output, dryRun) { - return JSON.stringify(output) + return JSON.stringify(output).replace(/\\/g, '\\\\') } } diff --git a/tests/formatters/json_formatter_tests.js b/tests/formatters/json_formatter_tests.js index d10575db..ebbf6197 100644 --- a/tests/formatters/json_formatter_tests.js +++ b/tests/formatters/json_formatter_tests.js @@ -44,5 +44,32 @@ describe('formatters', () => { const successResult = jsonFormatter.formatOutput(result, false) expect(successResult).to.equal(expected) }) + it('escapes backslashes to produce valid JSON', () => { + const jsonFormatter = require('../../formatters/json_formatter') + + /** @type {import('../..').LintResult} */ + const result = { + passed: true, + errored: false, + results: [ + FormatResult.CreateLintOnly( + new RuleInfo('myrule', 'error', [], 'file-existence', {}), + new Result('Escaped: \\', [], true) + ) + ], + targets: { + language: new Result('No language?', [], false) + }, + params: { + targetDir: '.', + filterPaths: [], + ruleset: {} + } + } + const expected = + '{"passed":true,"errored":false,"results":[{"ruleInfo":{"name":"myrule","level":"error","where":[],"ruleType":"file-existence","ruleConfig":{}},"status":"PASSED","lintResult":{"message":"Escaped: \\\\\\\\","targets":[],"passed":true}}],"targets":{"language":{"message":"No language?","targets":[],"passed":false}},"params":{"targetDir":".","filterPaths":[],"ruleset":{}}}' + const successResult = jsonFormatter.formatOutput(result, false) + expect(successResult).to.equal(expected) + }) }) })