Commit Graph
213 Commits
Author SHA1 Message Date
Yang JunandCursor b405733cdb 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]>
2026-05-10 13:34:37 +08:00
Yang JunandCursor 56b14d8a2d 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]>
2026-05-09 01:37:27 +08:00
Yang JunandCursor 29be7546e6 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]>
2026-05-08 21:00:43 +08:00
5b9c346908 fix: enforce renderLimit for empty renderTemplates calls (#894)
renderLimit was only checked inside the per-template loop, so
renderTemplates([], ...) skipped it. Empty {% for %} and {% tablerow %}
bodies call that path once per iteration (tablerow still does emitter
work for <tr>/<td>), bypassing the documented time budget. Check the
limiter at renderTemplates entry before the loop.

Add regression tests for empty for-body and empty tablerow-body.

Co-authored-by: Cursor <[email protected]>
2026-05-07 23:03:43 +08:00
dbbf628803 fix: propagate ownPropertyOnly into Context.spawn() for {% render %} (#893)
Child contexts from spawn() re-derived ownPropertyOnly from Liquid opts
only, dropping per-render RenderOptions overrides. That broke the contract
that parseAndRender(..., { ownPropertyOnly: true }) locks down a single
render, including partials loaded via {% render %}.

Add regression test matching prototype-chain leak PoC.

Co-authored-by: Cursor <[email protected]>
2026-05-03 22:35:31 +08:00
26ea2856c7 fix: strip html newline tags (#892)
* docs: add @talboren as financial contributor

* fix(strip_html): match tags that span newlines inside angle brackets

Co-authored-by: Cursor <[email protected]>

---------

Co-authored-by: Cursor <[email protected]>
2026-05-03 21:36:09 +08:00
Vladimir FilonovandGitHub 1c816d4fc3 feat: add sha256 and hmac_sha256 filters for cryptographic operations (#889) 2026-05-03 12:03:26 +08:00
TalandGitHub 0ee6dbb511 fix(filters): support Buffer input in base64_encode to prevent binary data corruption (#881)
* fix: support Buffer input in base64_encode filter

When binary data (e.g. images, PDFs) is passed through the template
context as a Node.js Buffer, the base64_encode filter would call
stringify() on it first, which internally does String(value). This
triggers Buffer.toString() with the default 'utf-8' encoding, which
is a lossy conversion for non-UTF-8 byte sequences — invalid bytes
get replaced with U+FFFD, permanently destroying the original data.

The fix checks for Buffer.isBuffer() before stringify, and calls
buffer.toString('base64') directly, bypassing the lossy UTF-8
intermediate step. String inputs continue through the existing path
unchanged.

Made-with: Cursor

* fix: handle Buffer in filter layer to fix browser build

Move Buffer handling from base64-impl.ts (which gets swapped for the
browser impl at build time) into base64.ts (the filter layer). This
avoids a type error during the browser rollup build where the browser
impl only accepts string.

Also guard Buffer.isBuffer() with typeof Buffer !== 'undefined' for
safety in browser environments.

Made-with: Cursor
2026-04-23 21:30:58 +08:00
Yang JunandGitHub e2311dfd6e fix: nested block for layout (#883) 2026-04-19 23:41:35 +08:00
Timmy BraunandGitHub 1cdf10b57d fix: rounding negative away from zero when half (#873) 2026-04-08 00:52:35 +08:00
Timmy BraunandGitHub 4f9a49988a fix: null date should return empty (#868) (#872) 2026-04-08 00:10:33 +08:00
Yang JunandGitHub f41c1fc02f fix: enforce root containment for renderFile/parseFile lookups (#870)
Made-with: Cursor
2026-04-07 23:18:53 +08:00
Yang JunandGitHub e743da0020 fix: sort and sort_natural filters bypass ownPropertyOnly (#869)
Use _getFromScope for property access in sort/sort_natural filters to respect the ownPropertyOnly security option, preventing prototype chain traversal that could leak sensitive inherited properties.

Also extract shared sortBy helper, add orderedCompare with nil handling consistent with caseInsensitiveCompare and Ruby Liquid.

Made-with: Cursor
2026-04-07 21:01:20 +08:00
Joe CottamandGitHub 0ad2b11ab1 fix: handle undefined replacement argument in replace filter (#864) 2026-03-26 01:18:40 +08:00
Loo Rong JieandGitHub 955b7971c0 Support having new line and other whitespace after include filename (#834) 2025-11-11 13:58:12 +08:00
Omri RosnerandGitHub 86fc135d9e feat(filters): Add base64_encode and base64_decode filters for Shopify compatibility (#828)
* feat(filters): add base64 encode and decode

* fix: use Object.defineProperty for cross-platform btoa/atob mocking

* docs(filters): update docs

* docs(filters): update version
2025-10-27 22:40:31 +08:00
Yang JunandGitHub e8e502c585 fix: math filters coerce invalid string to 0, #813 (#819) 2025-10-06 18:31:43 +08:00
Yang JunandGitHub 025c40f0f2 fix: block.super with strictVariables, #806 (#807) 2025-05-15 01:47:57 +08:00
Bruno CarvalhoandGitHub 0deb93eeae feat: add find_index, has, and reject filters (#799)
* feat: add find_index, has, and reject filters

* Minor tweaks

* Change semantics of jekyllStyle, add more tests

* Some docs improvements
2025-02-23 22:57:17 +08:00
HarttleandJun Yang a490a70da1 fix: consistent range syntax parsing, #791 2025-01-19 17:58:00 +08:00
HarttleandJun Yang a5070af3e4 fix: context for group_by_exp/where_exp/find_exp, #790 2025-01-19 17:53:25 +08:00
Jun YangandGitHub 25ef104446 fix: enumerate plain objects in where/where_exp, #785 (#788) 2025-01-04 23:41:25 +08:00
HarttleandJun Yang 59cf3c08db fix: preserveTimezones support for RFC2822 date, #784 2025-01-04 22:46:07 +08:00
HarttleandJun Yang 5f1a4cfdc9 fix: break/continue stops whole template, #783 2025-01-04 22:15:39 +08:00
JamesandGitHub 3492ff63f4 feat: static variable analysis (#770)
* feat: static variable analysis

* Accept any iterable from `children`, `arguments`, etc.

* Test analysis of standard tags

* Use `TagToken.tokenizer` instead of creating a new one

* Test analysis of netsted tags

* Group variables by their root value

* Test analysis of nested globals and locals

* Analyze included and rendered templates WIP

* Use existing tokenizer when constructing `Hash`

* Improve test coverage

* Analyze variables from `layout` and `block` tags

* Test analysis of Jekyll style includes

* Handle variables that start with a nested variable

* Async analysis

* Test non-standard tag end to end

* Implement convenience analysis methods on the `Liquid` class

* More analysis convenience methods

* Accept string or template array

* Draft static analysis docs

* Deduplicate variables names

* Fix isolated scope global variable map

* Coerce variables to strings instead of extending String

* Private map instead of extending Map

* Fix e2e test

* Tentatively implement analysis of aliased variables

* Fix nested variable segments array

* Update docs sidebar
2024-12-28 21:35:28 +08:00
HarttleandJun Yang 35a84421a6 feat: size, first, last support arraylike objects, #781 2024-12-28 16:10:06 +08:00
HarttleandJun Yang e3ef574674 fix: inconsistent continue behaviour, fixes #779 2024-12-22 16:32:08 +08:00
HarttleandJun Yang 9107eb1b93 feat: support Jekyll style where, #768 2024-11-17 21:33:38 +08:00
Yang Jun 0b195b21eb test: case for "." path handling 2024-11-12 23:59:40 +08:00
Jun YangandGitHub e941378535 docs: add internal types in apidoc (#734)
* docs: add internal types in apidoc

* chore: downgrade package-lock version for NodeJS 14

* test: test case when performance uses Date.now
2024-08-17 00:55:24 +08:00
Jun YangandGitHub e4aeb023fd feat: locale support for date filter, #567 (#723) 2024-07-22 00:39:44 +08:00
Yang Jun e443068cb9 feat: DoS prevention, #250 2024-07-09 22:51:11 +08:00
Harttle df27ac6947 feat: support in-memory template mapping, inspired by @jg-rp #714 2024-07-08 02:25:25 +08:00
Harttle 22b5a12333 fix: report error for malformed else/elsif/endif/endfor, #713 2024-07-05 01:23:33 +08:00
Jun YangandGitHub 3b5627b040 feat: support catching all errors, #220 (#710) 2024-06-17 22:48:57 +08:00
a0ea372764 docs: fix some spelling (#708)
* spelling: according

Signed-off-by: Josh Soref <[email protected]>

* spelling: asynchronously

Signed-off-by: Josh Soref <[email protected]>

* spelling: background

Signed-off-by: Josh Soref <[email protected]>

* spelling: camel

Signed-off-by: Josh Soref <[email protected]>

* spelling: cannot

Signed-off-by: Josh Soref <[email protected]>

* spelling: case-sensitive

Signed-off-by: Josh Soref <[email protected]>

* spelling: comparison

Signed-off-by: Josh Soref <[email protected]>

* spelling: demos

Signed-off-by: Josh Soref <[email protected]>

* spelling: forloop

Signed-off-by: Josh Soref <[email protected]>

* spelling: formatters

Signed-off-by: Josh Soref <[email protected]>

* spelling: github

Signed-off-by: Josh Soref <[email protected]>

* spelling: guidelines

Signed-off-by: Josh Soref <[email protected]>

* spelling: hashes

Signed-off-by: Josh Soref <[email protected]>

* spelling: https

Signed-off-by: Josh Soref <[email protected]>

* spelling: javascript

Signed-off-by: Josh Soref <[email protected]>

* spelling: keep

Signed-off-by: Josh Soref <[email protected]>

* spelling: natural

Signed-off-by: Josh Soref <[email protected]>

* spelling: neither

Signed-off-by: Josh Soref <[email protected]>

* spelling: no longer

Signed-off-by: Josh Soref <[email protected]>

* spelling: nonexistent

Signed-off-by: Josh Soref <[email protected]>

* spelling: output

Signed-off-by: Josh Soref <[email protected]>

* spelling: polymorphism

Signed-off-by: Josh Soref <[email protected]>

* spelling: precache

Signed-off-by: Josh Soref <[email protected]>

* spelling: programmatically

Signed-off-by: Josh Soref <[email protected]>

* spelling: punctuation

Signed-off-by: Josh Soref <[email protected]>

* spelling: registration

Signed-off-by: Josh Soref <[email protected]>

* spelling: rendered

Signed-off-by: Josh Soref <[email protected]>

* spelling: synchronously

Signed-off-by: Josh Soref <[email protected]>

* spelling: thrown

Signed-off-by: Josh Soref <[email protected]>

* spelling: trimmed

Signed-off-by: Josh Soref <[email protected]>

* spelling: unbalanced

Signed-off-by: Josh Soref <[email protected]>

* chore: use example.com

* chore: fix reference for sidebar.registration

---------

Signed-off-by: Josh Soref <[email protected]>
Co-authored-by: Harttle <[email protected]>
2024-06-17 17:19:46 +08:00
Adam TannerandGitHub a7da93ff0f fix: use drop valueOf when evaluated as condition (#705) 2024-06-05 08:28:21 +08:00
55e144a029 fix: isComparable full interface check (#701)
* Improve isComparable function to ensure full Comparable interface implementation

* Deleted trailing commas

---------

Co-authored-by: Guillermo Casal Caro <[email protected]>
2024-05-24 10:35:49 +08:00
0983f2c420 fix: allow liquidMethodMissing to return any supported value type (#698)
* fix: allow liquidMethodMissing to return any supported value type

* Update src/drop/drop.ts

Co-authored-by: Jun Yang <[email protected]>

---------

Co-authored-by: Jun Yang <[email protected]>
2024-05-22 12:35:46 +08:00
Yang Jun 47ddc1193b feat: slugify filter from Jekyll, #443 2024-05-13 23:54:07 +08:00
Yang Jun 50253a98ca feat: array_to_sentence_string and number_of_words filters from Jekyll, #443 2024-05-13 00:38:52 +08:00
Yang Jun b12eb8ab4b feat: escape filters from Jekyll, #443 2024-05-12 15:05:36 +08:00
Yang Jun 4955e75be7 feat: date filters from Jekyll 2024-05-09 23:37:27 +08:00
Yang Jun 842b45c96a feat: jsonify, inspect, to_integer, normalize_whitespace filters 2024-05-06 21:10:27 +08:00
Yang JunandJun Yang 2b630353c4 fix: case/when array equality, #673 2024-04-28 23:17:01 +08:00
Yang JunandJun Yang 8c7cef9f95 feat: introduce where_exp filter from Jekyll 2024-04-28 23:17:01 +08:00
Max MedveandGitHub 490ff4309c fix: Allow lenientIf for multiple operands (issue #682) (#683)
* allow `lenientIf` for multiple operands

* update tests
2024-04-21 16:04:38 +08:00
Yang JunandJun Yang e09657c52b fix: allow %Z for TimezoneDate, update docs accordingly #684 2024-04-21 15:57:43 +08:00
Jun Yang 2b713b721d feat: group_by/group_by_exp/find/find_exp from Jekyll, #443 2024-04-14 19:34:07 +08:00
Jun Yang 258780e9a8 feat: pop/shift/unshift filters from Jekyll 2024-04-14 19:34:07 +08:00