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 +4 -4
- data/lib/liquid/condition.rb +54 -11
- data/lib/liquid/drop.rb +1 -1
- data/lib/liquid/expression.rb +1 -1
- data/lib/liquid/i18n.rb +1 -1
- data/lib/liquid/resource_limits.rb +22 -5
- data/lib/liquid/standardfilters.rb +17 -0
- data/lib/liquid/tags/case.rb +1 -1
- data/lib/liquid/tokenizer.rb +1 -1
- data/lib/liquid/utils.rb +3 -1
- data/lib/liquid/variable_lookup.rb +5 -0
- data/lib/liquid/version.rb +1 -1
- metadata +2 -2
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: ede4a234547978b59f059b4a2939bfb3c91092952c45ef8616f7874c2f9902e3
|
|
4
|
+
data.tar.gz: 4f489720f234a848498a390a76ba89e97bfa6b5d8c708ac9b6de293748ce6dd3
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: c0417cca5aece94bb341d38ba6e20deac2437fa453e926c296b6725858a35e845f25c548d1ddb364c675223667284ee088cf1fe76c151ef905b70cda08b977d3
|
|
7
|
+
data.tar.gz: ec169349a4b973bc11d5f52a2f4f20e7467eaecae1521cdec014b9e42f2de2cc955b1789f44e0249db95f9d8fc5d7659fed6897c699753f8f4111ce16c742b36
|
data/lib/liquid/condition.rb
CHANGED
|
@@ -113,22 +113,65 @@ module Liquid
|
|
|
113
113
|
|
|
114
114
|
def equal_variables(left, right)
|
|
115
115
|
if left.is_a?(MethodLiteral)
|
|
116
|
-
|
|
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
|
-
|
|
125
|
-
|
|
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
|
-
|
|
141
|
+
false
|
|
128
142
|
end
|
|
129
143
|
end
|
|
144
|
+
end
|
|
130
145
|
|
|
131
|
-
|
|
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
|
-
"
|
|
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
data/lib/liquid/expression.rb
CHANGED
|
@@ -55,7 +55,7 @@ module Liquid
|
|
|
55
55
|
end
|
|
56
56
|
|
|
57
57
|
def inner_parse(markup, ss, cache)
|
|
58
|
-
if
|
|
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
|
-
|
|
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,
|
|
6
|
-
|
|
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
|
|
10
|
-
@render_score_limit
|
|
11
|
-
@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
|
|
data/lib/liquid/tags/case.rb
CHANGED
|
@@ -118,7 +118,7 @@ module Liquid
|
|
|
118
118
|
parser = @parse_context.new_parser(markup)
|
|
119
119
|
|
|
120
120
|
loop do
|
|
121
|
-
expr =
|
|
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
|
data/lib/liquid/tokenizer.rb
CHANGED
|
@@ -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 &&
|
|
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
|
|
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
|
data/lib/liquid/version.rb
CHANGED
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.
|
|
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:
|
|
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: []
|