From b0c9f576afa9749a12aa0f604d41d46fc4d94d2e Mon Sep 17 00:00:00 2001 From: Tobi Lutke Date: Wed, 11 Mar 2026 09:18:35 -0400 Subject: [PATCH] =?UTF-8?q?REVERTED:=20Cursor=20for=20For=20tag=20adds=201?= =?UTF-8?q?48=20allocs=20from=20scan=5Fid/scan=5Ffragment=20string=20creat?= =?UTF-8?q?ion\n\nResult:=20{"status":"discard","combined=5F=C2=B5s":5049,?= =?UTF-8?q?"parse=5Fus":3765,"render=5Fus":1284,"allocations":29793,"parse?= =?UTF-8?q?=5F=C2=B5s":3765,"render=5F=C2=B5s":1284}?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- lib/liquid/cursor.rb | 45 ++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 45 insertions(+) diff --git a/lib/liquid/cursor.rb b/lib/liquid/cursor.rb index 13eba7c2..753c7a9d 100644 --- a/lib/liquid/cursor.rb +++ b/lib/liquid/cursor.rb @@ -300,5 +300,50 @@ module Liquid return nil unless eos? # trailing junk true end + # ── For tag parser ──────────────────────────────────────────────── + # Results from parse_for_markup + attr_reader :for_var, :for_collection, :for_reversed + + # Parse "var in collection [reversed] [limit:N] [offset:N]" + # Returns true on success, nil on failure. + def parse_for_markup + skip_ws + @for_var = scan_id + return nil unless @for_var + + skip_ws + # expect "in" + return nil unless scan_id == "in" + + skip_ws + # Collection: parenthesized range or fragment + if peek_byte == LPAREN + start = @ss.pos + depth = 1 + @ss.scan_byte + while !@ss.eos? && depth > 0 + b = @ss.scan_byte + depth += 1 if b == LPAREN + depth -= 1 if b == RPAREN + end + @for_collection = @source.byteslice(start, @ss.pos - start) + else + @for_collection = scan_fragment + return nil unless @for_collection + end + + skip_ws + # Check for 'reversed' + saved = @ss.pos + word = scan_id + if word == "reversed" + @for_reversed = true + else + @for_reversed = false + @ss.pos = saved if word # rewind if we consumed a non-'reversed' word + end + + true + end end end