diff --git a/src/filters/html.ts b/src/filters/html.ts index c44ef92da..fb8096aef 100644 --- a/src/filters/html.ts +++ b/src/filters/html.ts @@ -42,28 +42,30 @@ export function newline_to_br (this: FilterImpl, v: string) { return str.replace(/\r?\n/gm, '
\n') } -// Linear-time strip via indexOf scan. A regex equivalent to the old -// /||<[\s\S]*?>|/g -// is O(n^2) on unclosed openers (JS regex has no atomic groups / memoization), -// so we cache "next known / position" across openers. +// '], [''], ['']] + const closes = [0, 0, 0] let out = '' let i = 0 - let scriptEnd = 0 - let styleEnd = 0 while (i < str.length) { const lt = str.indexOf('<', i) if (lt < 0) return out + str.slice(i) out += str.slice(i, lt) let end = -1 - if (str.startsWith('= 0 && scriptEnd < lt + 7) scriptEnd = str.indexOf('', lt + 7) - if (scriptEnd >= 0) end = scriptEnd + 9 - } else if (str.startsWith('= 0 && styleEnd < lt + 6) styleEnd = str.indexOf('', lt + 6) - if (styleEnd >= 0) end = styleEnd + 8 + for (let k = 0; k < blocks.length; k++) { + const [opener, closer] = blocks[k] + if (!str.startsWith(opener, lt)) continue + const from = lt + opener.length + if (closes[k] >= 0 && closes[k] < from) closes[k] = str.indexOf(closer, from) + if (closes[k] >= 0) end = closes[k] + closer.length + break } if (end < 0) end = str.indexOf('>', lt + 1) + 1 if (end <= 0) return out + str.slice(lt) diff --git a/test/integration/filters/html.spec.ts b/test/integration/filters/html.spec.ts index c4551dad4..e858420e0 100644 --- a/test/integration/filters/html.spec.ts +++ b/test/integration/filters/html.spec.ts @@ -57,6 +57,9 @@ describe('filters/html', function () { it('should strip multiline comments', function () { expect(liquid.parseAndRenderSync('{{""|strip_html}}')).toBe('') }) + it('should treat > inside comments as comment content (not a tag end)', function () { + expect(liquid.parseAndRenderSync('{{ "after" | strip_html }}')).toBe('after') + }) it('should strip all style tags and their contents', function () { return test('{{ "Ulysses?" | strip_html }}', 'Ulysses?')