From f0c785ec5190f1c99f0576a17d62ffbd19a74670 Mon Sep 17 00:00:00 2001 From: Jochen Delabie Date: Thu, 29 Oct 2026 16:53:06 +0100 Subject: [PATCH] Escape backslashes in CI summary table cells A backslash before a pipe in an error message turned the escaped \| into \\|, so the pipe split the Markdown table. Fixes code scanning alert #4 (js/incomplete-sanitization). --- src/utils/ci_summary.ts | 3 ++- tests/utils/ci_summary.test.ts | 15 +++++++++++++++ 2 files changed, 17 insertions(+), 1 deletion(-) diff --git a/src/utils/ci_summary.ts b/src/utils/ci_summary.ts index 9ae8606..34f9fd7 100644 --- a/src/utils/ci_summary.ts +++ b/src/utils/ci_summary.ts @@ -71,7 +71,8 @@ function failuresOf(output: JsonOutput): Failure[] { /** One line, no table-breaking pipes, bounded length. */ function cell(text: string, max = 200): string { - const flat = text.replace(/\s+/g, ' ').replace(/\|/g, '\\|').trim(); + // Backslashes too: otherwise an input `\|` becomes `\\|` and the pipe breaks the table. + const flat = text.replace(/\s+/g, ' ').replace(/[\\|]/g, '\\$&').trim(); return flat.length > max ? `${flat.slice(0, max - 1)}…` : flat; } diff --git a/tests/utils/ci_summary.test.ts b/tests/utils/ci_summary.test.ts index e54c464..57635fe 100644 --- a/tests/utils/ci_summary.test.ts +++ b/tests/utils/ci_summary.test.ts @@ -84,6 +84,21 @@ describe('renderMarkdown', () => { expect(md).not.toContain('search on'); }); + test('a backslash before a pipe cannot unescape it and break the table', () => { + const md = renderMarkdown({ + ...maestro, + runs: [ + { + ...maestro.runs[0], + flows: [ + flow(2, 'checkout', false, { errors: ['path C:\\tmp\\| x'] }), + ], + }, + ], + }); + expect(md).toContain('| path C:\\\\tmp\\\\\\| x |'); + }); + test('a passed Espresso run without flows', () => { const md = renderMarkdown(espresso); expect(md).toContain('### TestingBot Espresso: ✅ passed');