mirror of
https://github.com/harttle/liquidjs.git
synced 2026-09-16 21:00:40 -07:00
fix(date): cap strftime widths and account padding in memoryLimit (#895)
* fix(date): cap strftime widths and account padding in memoryLimit - Clamp numeric strftime pad widths to MAX_STRFTIME_PAD (1024) - Export estimateStrftimePaddingMemory for the date filter to charge memoryLimit - Replace unbounded pad() concatenation loop with ch.repeat + single concat - Add regression tests for clamping and memoryLimit on huge %width directives Co-authored-by: Cursor <[email protected]> * fix(date): harden strftime memory accounting and document security model Move strftime memory charging into the same formatting path used for padding, enforce pre-allocation checks, and add regression tests for non-string date format PoCs. Add dedicated docs clarifying that memoryLimit is cooperative DoS mitigation and not strict heap isolation. Co-authored-by: Cursor <[email protected]> * docs(zh-cn): add security model docs for DoS limits Add a Chinese security-model tutorial and link it from the Chinese DoS guide to clarify that memoryLimit is cooperative accounting, list uncounted custom conversion cases, and recommend avoiding fully user-defined templates in online services. Co-authored-by: Cursor <[email protected]> * docs: consolidate DoS docs into security-model pages Merge DoS guidance into security-model docs in both English and Chinese, and remove the placeholder dos.md pages to avoid duplicate/redirect-only docs. Co-authored-by: Cursor <[email protected]> * docs: merge DoS details into security-model docs Move the detailed parseLimit/renderLimit/memoryLimit explanations and examples into the English and Chinese security-model pages so content from the removed dos pages is preserved. Co-authored-by: Cursor <[email protected]> * docs: reorganize security-model structure for clarity Restructure English and Chinese security-model docs into a consistent flow: security boundary, limits overview, per-limit details, and online service guidance. Co-authored-by: Cursor <[email protected]> * refactor(strftime): simplify %N width parsing logic Use regex-backed width assumptions to simplify %N width normalization and padding memory accounting while keeping behavior equivalent. Co-authored-by: Cursor <[email protected]> * refactor(strftime): rely on memoryLimit for width control Remove MAX_STRFTIME_PAD hard capping and rely on memoryLimit enforcement before padding allocation. Update strftime/date tests and security-model docs to match the new boundary and renderLimit caveats. Co-authored-by: Cursor <[email protected]> * fix(strftime): use add() once for padding, minimize churn - pad(): replace per-char loop with a single add(str, ch.repeat(n)) call. The earlier `probe[0] === ch` heuristic was wrong when ch happened to equal a leading char of 'probe' (e.g. ch === 'p'). - strftime.ts: revert unrelated typing/structural refactors so the diff contains only the memoryLimit threading and the %N memory charge. - docs: rewire the deleted dos.html sidebar entry to security-model.html (with localized labels) so the deleted page does not 404 from the sidebar. Co-authored-by: Cursor <[email protected]> --------- Co-authored-by: Cursor <[email protected]>
This commit is contained in:
@@ -204,6 +204,33 @@ describe('filters/date', function () {
|
||||
return test('{{ "1990-12-31T23:00:00Z" | date: "%Y-%m-%dT%H:%M:%S" }}', '1991-01-01T04:30:00', undefined, optsWithDateFormat)
|
||||
})
|
||||
})
|
||||
describe('strftime width / memoryLimit', () => {
|
||||
it('should charge memoryLimit for huge numeric strftime widths', () => {
|
||||
const liquid = new Liquid({ memoryLimit: 500 })
|
||||
expect(() => liquid.parseAndRenderSync('{{ d | date: f }}', { d: 'now', f: '%5000000d' }))
|
||||
.toThrow('memory alloc limit exceeded')
|
||||
})
|
||||
it('should charge memoryLimit for array format PoC', () => {
|
||||
const liquid = new Liquid({ memoryLimit: 50, renderLimit: 1e9 })
|
||||
expect(() => liquid.parseAndRenderSync('{{ d | date: f }}', { d: 'now', f: ['a'.repeat(2000000)] }))
|
||||
.toThrow('memory alloc limit exceeded')
|
||||
})
|
||||
it('should charge memoryLimit for object toString format PoC', () => {
|
||||
const liquid = new Liquid({ memoryLimit: 50, renderLimit: 1e9 })
|
||||
const huge = 'a'.repeat(2000000)
|
||||
const f = { toString: () => huge }
|
||||
expect(() => liquid.parseAndRenderSync('{{ d | date: f }}', { d: 'now', f }))
|
||||
.toThrow('memory alloc limit exceeded')
|
||||
})
|
||||
it('should honor numeric strftime pad width when memoryLimit allows', () => {
|
||||
const liquid = new Liquid({ memoryLimit: 1e7 })
|
||||
const out = liquid.parseAndRenderSync('{{ d | date: f }}', { d: 'now', f: '%5000d' })
|
||||
expect(out.length).toBe(5000)
|
||||
const tight = new Liquid({ memoryLimit: 100 })
|
||||
expect(() => tight.parseAndRenderSync('{{ d | date: f }}', { d: 'now', f: '%5000d' }))
|
||||
.toThrow('memory alloc limit exceeded')
|
||||
})
|
||||
})
|
||||
})
|
||||
describe('filters/date_to_xmlschema', function () {
|
||||
const liquid = new Liquid()
|
||||
|
||||
Reference in New Issue
Block a user