From 98cdddd2d7d3f02389616f209bd0b5cfad4f71e4 Mon Sep 17 00:00:00 2001 From: George Raduta Date: Mon, 26 Oct 2026 16:56:32 +0100 Subject: [PATCH] Limit the size of the log content parsed to build the log snippet --- lib/public/utilities/formatting/formatLogSnippet.js | 8 +++++++- .../public/utilities/formatting/formatLogSnippet.test.js | 7 +++++++ 2 files changed, 14 insertions(+), 1 deletion(-) diff --git a/lib/public/utilities/formatting/formatLogSnippet.js b/lib/public/utilities/formatting/formatLogSnippet.js index d701a3d1cb..720099731c 100644 --- a/lib/public/utilities/formatting/formatLogSnippet.js +++ b/lib/public/utilities/formatting/formatLogSnippet.js @@ -13,6 +13,12 @@ const DEFAULT_MAX_LENGTH = 120; +/* + * Only the beginning of the content can end up in the snippet, so the rest is not parsed: the markdown stripping has a quadratic cost on + * long lines, which would freeze the overview for any log with a huge content + */ +const MAX_PARSED_LENGTH = 2000; + const CODE_PLACEHOLDER = '\u0000'; const CODE_PLACEHOLDER_REGEX = new RegExp(`${CODE_PLACEHOLDER}(\\d+)${CODE_PLACEHOLDER}`, 'g'); @@ -62,7 +68,7 @@ export const formatLogSnippet = (text, title = '', maxLength = DEFAULT_MAX_LENGT let inCodeFence = false; const lines = []; - for (const rawLine of String(text).split(/\r?\n|\\n/)) { + for (const rawLine of String(text).slice(0, MAX_PARSED_LENGTH).split(/\r?\n|\\n/)) { if (rawLine.trim().startsWith('```')) { inCodeFence = !inCodeFence; continue; diff --git a/test/lib/public/utilities/formatting/formatLogSnippet.test.js b/test/lib/public/utilities/formatting/formatLogSnippet.test.js index c28f6a5e02..f1af106063 100644 --- a/test/lib/public/utilities/formatting/formatLogSnippet.test.js +++ b/test/lib/public/utilities/formatting/formatLogSnippet.test.js @@ -58,6 +58,13 @@ module.exports = () => { expect(formatLogSnippet('Other\nRun 1 failed', 'Run 1 failed')).to.equal('Other Run 1 failed'); }); + it('should not take a long time to process a huge content', () => { + const start = Date.now(); + const snippet = formatLogSnippet(' __a b'.repeat(100000)); + expect(Date.now() - start).to.be.lessThan(500); + expect(snippet.length).to.be.lessThanOrEqual(120); + }); + it('should truncate on a word boundary with an ellipsis', () => { const snippet = formatLogSnippet('word '.repeat(50), '', 20); expect(snippet).to.equal('word word word…');