liquid 5.11.0 → 5.12.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 88705bb2e645a541fb76afe0a59c727429aaae33824103fb94178b5edbbda54e
4
- data.tar.gz: 5982801da2e3431575b2e32edfd0f46a3371b1c74060dc8936470df75c27c630
3
+ metadata.gz: ede4a234547978b59f059b4a2939bfb3c91092952c45ef8616f7874c2f9902e3
4
+ data.tar.gz: 4f489720f234a848498a390a76ba89e97bfa6b5d8c708ac9b6de293748ce6dd3
5
5
  SHA512:
6
- metadata.gz: 9c8ddeba605175a534a658c96dc749624ce78171f3df420011b3ac0f525301b29dac63b452e07081a8355f231e4643ee49a087daf0bcf0bb550bf07726c17228
7
- data.tar.gz: 150dce06c67bc6aa2efddf094e6b2b745b58503436fcfa8784f0f1d88f2d8447f2b8a025915745a5b0b31109b3a8e0887b552e7a7279ff3cb123182ae4188543
6
+ metadata.gz: c0417cca5aece94bb341d38ba6e20deac2437fa453e926c296b6725858a35e845f25c548d1ddb364c675223667284ee088cf1fe76c151ef905b70cda08b977d3
7
+ data.tar.gz: ec169349a4b973bc11d5f52a2f4f20e7467eaecae1521cdec014b9e42f2de2cc955b1789f44e0249db95f9d8fc5d7659fed6897c699753f8f4111ce16c742b36
@@ -113,22 +113,65 @@ module Liquid
113
113
 
114
114
  def equal_variables(left, right)
115
115
  if left.is_a?(MethodLiteral)
116
- if right.respond_to?(left.method_name)
117
- return right.send(left.method_name)
118
- else
119
- return nil
120
- end
116
+ return call_method_literal(left, right)
121
117
  end
122
118
 
123
119
  if right.is_a?(MethodLiteral)
124
- if left.respond_to?(right.method_name)
125
- return left.send(right.method_name)
120
+ return call_method_literal(right, left)
121
+ end
122
+
123
+ left == right
124
+ end
125
+
126
+ def call_method_literal(literal, value)
127
+ method_name = literal.method_name
128
+
129
+ # If the object responds to the method (e.g., ActiveSupport is loaded), use it
130
+ if value.respond_to?(method_name)
131
+ value.send(method_name)
132
+ else
133
+ # Emulate ActiveSupport's blank?/empty? to make Liquid invariant
134
+ # to whether ActiveSupport is loaded or not
135
+ case method_name
136
+ when :blank?
137
+ liquid_blank?(value)
138
+ when :empty?
139
+ liquid_empty?(value)
126
140
  else
127
- return nil
141
+ false
128
142
  end
129
143
  end
144
+ end
130
145
 
131
- left == right
146
+ # Implement blank? semantics matching ActiveSupport
147
+ # blank? returns true for nil, false, empty strings, whitespace-only strings,
148
+ # empty arrays, and empty hashes
149
+ def liquid_blank?(value)
150
+ case value
151
+ when NilClass, FalseClass
152
+ true
153
+ when TrueClass, Numeric
154
+ false
155
+ when String
156
+ # Blank if empty or whitespace only (matches ActiveSupport)
157
+ value.empty? || value.match?(/\A\s*\z/)
158
+ when Array, Hash
159
+ value.empty?
160
+ else
161
+ # Fall back to empty? if available, otherwise false
162
+ value.respond_to?(:empty?) ? value.empty? : false
163
+ end
164
+ end
165
+
166
+ # Implement empty? semantics
167
+ # Note: nil is NOT empty. empty? checks if a collection has zero elements.
168
+ def liquid_empty?(value)
169
+ case value
170
+ when String, Array, Hash
171
+ value.empty?
172
+ else
173
+ value.respond_to?(:empty?) ? value.empty? : false
174
+ end
132
175
  end
133
176
 
134
177
  def interpret_condition(left, right, op, context)
@@ -154,8 +197,8 @@ module Liquid
154
197
  end
155
198
 
156
199
  def deprecated_default_context
157
- warn("DEPRECATION WARNING: Condition#evaluate without a context argument is deprecated" \
158
- " and will be removed from Liquid 6.0.0.")
200
+ warn("DEPRECATION WARNING: Condition#evaluate without a context argument is deprecated " \
201
+ "and will be removed from Liquid 6.0.0.")
159
202
  Context.new
160
203
  end
161
204
 
data/lib/liquid/drop.rb CHANGED
@@ -31,7 +31,7 @@ module Liquid
31
31
 
32
32
  # Catch all for the method
33
33
  def liquid_method_missing(method)
34
- return nil unless @context&.strict_variables
34
+ return unless @context&.strict_variables
35
35
  raise Liquid::UndefinedDropMethod, "undefined method #{method}"
36
36
  end
37
37
 
@@ -55,7 +55,7 @@ module Liquid
55
55
  end
56
56
 
57
57
  def inner_parse(markup, ss, cache)
58
- if (markup.start_with?("(") && markup.end_with?(")")) && markup =~ RANGES_REGEX
58
+ if markup.start_with?("(") && markup.end_with?(")") && markup =~ RANGES_REGEX
59
59
  return RangeLookup.parse(
60
60
  Regexp.last_match(1),
61
61
  Regexp.last_match(2),
data/lib/liquid/i18n.rb CHANGED
@@ -28,7 +28,7 @@ module Liquid
28
28
  def interpolate(name, vars)
29
29
  name.gsub(/%\{(\w+)\}/) do
30
30
  # raise TranslationError, "Undefined key #{$1} for interpolation in translation #{name}" unless vars[$1.to_sym]
31
- (vars[Regexp.last_match(1).to_sym]).to_s
31
+ vars[Regexp.last_match(1).to_sym].to_s
32
32
  end
33
33
  end
34
34
 
@@ -2,24 +2,39 @@
2
2
 
3
3
  module Liquid
4
4
  class ResourceLimits
5
- attr_accessor :render_length_limit, :render_score_limit, :assign_score_limit
6
- attr_reader :render_score, :assign_score
5
+ attr_accessor :render_length_limit,
6
+ :render_score_limit,
7
+ :assign_score_limit,
8
+ :cumulative_render_score_limit,
9
+ :cumulative_assign_score_limit
10
+ attr_reader :render_score,
11
+ :assign_score,
12
+ :cumulative_render_score,
13
+ :cumulative_assign_score
7
14
 
8
15
  def initialize(limits)
9
- @render_length_limit = limits[:render_length_limit]
10
- @render_score_limit = limits[:render_score_limit]
11
- @assign_score_limit = limits[:assign_score_limit]
16
+ @render_length_limit = limits[:render_length_limit]
17
+ @render_score_limit = limits[:render_score_limit]
18
+ @assign_score_limit = limits[:assign_score_limit]
19
+ @cumulative_render_score_limit = limits[:cumulative_render_score_limit]
20
+ @cumulative_assign_score_limit = limits[:cumulative_assign_score_limit]
21
+ @cumulative_render_score = 0
22
+ @cumulative_assign_score = 0
12
23
  reset
13
24
  end
14
25
 
15
26
  def increment_render_score(amount)
16
27
  @render_score += amount
28
+ @cumulative_render_score += amount
17
29
  raise_limits_reached if @render_score_limit && @render_score > @render_score_limit
30
+ raise_limits_reached if @cumulative_render_score_limit && @cumulative_render_score > @cumulative_render_score_limit
18
31
  end
19
32
 
20
33
  def increment_assign_score(amount)
21
34
  @assign_score += amount
35
+ @cumulative_assign_score += amount
22
36
  raise_limits_reached if @assign_score_limit && @assign_score > @assign_score_limit
37
+ raise_limits_reached if @cumulative_assign_score_limit && @cumulative_assign_score > @cumulative_assign_score_limit
23
38
  end
24
39
 
25
40
  # update either render_length or assign_score based on whether or not the writes are captured
@@ -47,6 +62,8 @@ module Liquid
47
62
  @reached_limit = false
48
63
  @last_capture_length = nil
49
64
  @render_score = @assign_score = 0
65
+ raise_limits_reached if @cumulative_render_score_limit && @cumulative_render_score > @cumulative_render_score_limit
66
+ raise_limits_reached if @cumulative_assign_score_limit && @cumulative_assign_score > @cumulative_assign_score_limit
50
67
  end
51
68
 
52
69
  def with_capture
@@ -293,6 +293,19 @@ module Liquid
293
293
  input.split(pattern)
294
294
  end
295
295
 
296
+ # @liquid_public_docs
297
+ # @liquid_type filter
298
+ # @liquid_category string
299
+ # @liquid_summary
300
+ # Removes leading and trailing whitespace and collapses consecutive whitespace to a single space.
301
+ # @liquid_syntax string | squish
302
+ # @liquid_return [string]
303
+ def squish(input)
304
+ return if input.nil?
305
+
306
+ Utils.to_s(input).strip.gsub(/\s+/, ' ')
307
+ end
308
+
296
309
  # @liquid_public_docs
297
310
  # @liquid_type filter
298
311
  # @liquid_category string
@@ -768,6 +781,8 @@ module Liquid
768
781
  # @liquid_syntax array | first
769
782
  # @liquid_return [untyped]
770
783
  def first(array)
784
+ # ActiveSupport returns "" for empty strings, not nil
785
+ return array[0] || "" if array.is_a?(String)
771
786
  array.first if array.respond_to?(:first)
772
787
  end
773
788
 
@@ -779,6 +794,8 @@ module Liquid
779
794
  # @liquid_syntax array | last
780
795
  # @liquid_return [untyped]
781
796
  def last(array)
797
+ # ActiveSupport returns "" for empty strings, not nil
798
+ return array[-1] || "" if array.is_a?(String)
782
799
  array.last if array.respond_to?(:last)
783
800
  end
784
801
 
@@ -118,7 +118,7 @@ module Liquid
118
118
  parser = @parse_context.new_parser(markup)
119
119
 
120
120
  loop do
121
- expr = safe_parse_expression(parser)
121
+ expr = Condition.parse_expression(parse_context, parser.expression, safe: true)
122
122
  block = Condition.new(@left, '==', expr)
123
123
  block.attach(body)
124
124
  @blocks << block
@@ -117,7 +117,7 @@ module Liquid
117
117
  byte_a = byte_b = @ss.scan_byte
118
118
 
119
119
  while byte_b
120
- byte_a = @ss.scan_byte while byte_a && (byte_a != CLOSE_CURLEY && byte_a != OPEN_CURLEY)
120
+ byte_a = @ss.scan_byte while byte_a && byte_a != CLOSE_CURLEY && byte_a != OPEN_CURLEY
121
121
 
122
122
  break unless byte_a
123
123
 
data/lib/liquid/utils.rb CHANGED
@@ -69,7 +69,7 @@ module Liquid
69
69
  return obj if obj.respond_to?(:strftime)
70
70
 
71
71
  if obj.is_a?(String)
72
- return nil if obj.empty?
72
+ return if obj.empty?
73
73
  obj = obj.downcase
74
74
  end
75
75
 
@@ -95,6 +95,8 @@ module Liquid
95
95
 
96
96
  def self.to_s(obj, seen = {})
97
97
  case obj
98
+ when BigDecimal
99
+ obj.to_s("F")
98
100
  when Hash
99
101
  # If the custom hash implementation overrides `#to_s`, use their
100
102
  # custom implementation. Otherwise we use Liquid's default
@@ -70,6 +70,11 @@ module Liquid
70
70
  elsif lookup_command?(i) && object.respond_to?(key)
71
71
  object = object.send(key).to_liquid
72
72
 
73
+ # Handle string first/last like ActiveSupport does (returns first/last character)
74
+ # ActiveSupport returns "" for empty strings, not nil
75
+ elsif lookup_command?(i) && object.is_a?(String) && (key == "first" || key == "last")
76
+ object = key == "first" ? (object[0] || "") : (object[-1] || "")
77
+
73
78
  # No key was present with the desired value and it wasn't one of the directly supported
74
79
  # keywords either. The only thing we got left is to return nil or
75
80
  # raise an exception if `strict_variables` option is set to true
@@ -2,5 +2,5 @@
2
2
  # frozen_string_literal: true
3
3
 
4
4
  module Liquid
5
- VERSION = "5.11.0"
5
+ VERSION = "5.12.0"
6
6
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: liquid
3
3
  version: !ruby/object:Gem::Version
4
- version: 5.11.0
4
+ version: 5.12.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Tobias Lütke
@@ -159,7 +159,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
159
159
  - !ruby/object:Gem::Version
160
160
  version: 1.3.7
161
161
  requirements: []
162
- rubygems_version: 3.7.2
162
+ rubygems_version: 4.0.8
163
163
  specification_version: 4
164
164
  summary: A secure, non-evaling end user template engine with aesthetic markup.
165
165
  test_files: []