fix(filters): return empty for out-of-range slice begin or negative length (#928)

Ruby/Shopify `slice` returns nil (rendered as an empty string or array) when
the begin offset falls outside the negative range or when the length is
negative. liquidjs forwarded the adjusted indices straight to
Array/String.prototype.slice, whose own negative-index handling produced
non-empty, incorrect output:

  {{ "hello" | slice: -10, 2 }}  => "he"   (expected "")
  {{ "Liquid" | slice: 1, -2 }}  => "iqui" (expected "")

Guard the adjusted begin and the length before slicing.
This commit is contained in:
spokodev
2026-07-09 22:41:46 +08:00
committed by GitHub
parent 7ab49f999a
commit f9a1316d16
2 changed files with 4 additions and 0 deletions
+1
View File
@@ -114,6 +114,7 @@ export function slice<T> (this: FilterImpl, v: T[] | string, begin: number, leng
if (isNil(v)) return []
if (!isArray(v)) v = stringify(v)
begin = begin < 0 ? v.length + begin : begin
if (begin < 0 || length < 0) return isArray(v) ? [] : ''
this.context.memoryLimit.use(length)
return isArray(v)
? Array.prototype.slice.call(v, begin, begin + length)
+3
View File
@@ -288,6 +288,9 @@ describe('filters/array', function () {
it('should slice substr by -2,2', () => test('{{ "abc" | slice: -2, 2 }}', 'bc'))
it('should support array', () => test('{{ "1,2,3,4" | split: "," | slice: 1,2 | join }}', '2 3'))
it('should return empty array for nil value', () => test('{{ nil | slice: 0 }}', ''))
it('should return empty when begin is out of negative range', () => test('{{ "hello" | slice: -10, 2 }}', ''))
it('should return empty when length is negative', () => test('{{ "Liquid" | slice: 1, -2 }}', ''))
it('should return empty array when begin is out of negative range', () => test('{{ "1,2,3,4,5" | split: "," | slice: -10, 2 | join: "," }}', ''))
})
describe('sort', function () {
it('should support sort', function () {