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) + }) }) })