mirror of
https://github.com/harttle/liquidjs.git
synced 2026-09-16 12:50:38 -07:00
refactor(strip_html): drop position cache, delete dead blocks from Set
Once `indexOf(closer, X)` returns -1, all subsequent searches (with monotonically increasing start) also return -1. So tracking absence is enough; storing positions is unnecessary. Make `blocks` a Set and delete a kind once its closer is known absent — no parallel `dead` bookkeeping. Use Jest's per-test timeout for the ReDoS regressions instead of manual Date.now() bookkeeping. Co-authored-by: Cursor <[email protected]>
This commit is contained in:
@@ -88,29 +88,21 @@ describe('DoS related', function () {
|
||||
describe('strip_html ReDoS', () => {
|
||||
// Regression for O(n^2) backtracking on unclosed `<script` / `<style` openers.
|
||||
// The previous regex stalled the event loop for ~10s on 350KB of `'<script'.repeat`.
|
||||
// The per-test timeout below caps total time; an O(n^2) regression would blow it.
|
||||
it('should handle many unclosed <script openers in linear time', () => {
|
||||
const liquid = new Liquid()
|
||||
const payload = '<script'.repeat(50000)
|
||||
const t0 = Date.now()
|
||||
const out = liquid.parseAndRenderSync('{{ x | strip_html }}', { x: payload })
|
||||
expect(Date.now() - t0).toBeLessThan(1000)
|
||||
expect(out).toBe(payload)
|
||||
})
|
||||
expect(liquid.parseAndRenderSync('{{ x | strip_html }}', { x: payload })).toBe(payload)
|
||||
}, 1000)
|
||||
it('should handle many unclosed <style openers in linear time', () => {
|
||||
const liquid = new Liquid()
|
||||
const payload = '<style'.repeat(50000)
|
||||
const t0 = Date.now()
|
||||
const out = liquid.parseAndRenderSync('{{ x | strip_html }}', { x: payload })
|
||||
expect(Date.now() - t0).toBeLessThan(1000)
|
||||
expect(out).toBe(payload)
|
||||
})
|
||||
expect(liquid.parseAndRenderSync('{{ x | strip_html }}', { x: payload })).toBe(payload)
|
||||
}, 1000)
|
||||
it('should handle <script openers that have > but no </script> in linear time', () => {
|
||||
const liquid = new Liquid()
|
||||
const payload = '<script>foo'.repeat(50000)
|
||||
const t0 = Date.now()
|
||||
const out = liquid.parseAndRenderSync('{{ x | strip_html }}', { x: payload })
|
||||
expect(Date.now() - t0).toBeLessThan(1000)
|
||||
expect(out).toBe('foo'.repeat(50000))
|
||||
})
|
||||
expect(liquid.parseAndRenderSync('{{ x | strip_html }}', { x: payload })).toBe('foo'.repeat(50000))
|
||||
}, 1000)
|
||||
})
|
||||
})
|
||||
|
||||
Reference in New Issue
Block a user