Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
25 changes: 25 additions & 0 deletions lib/liquid/tags/assign.rb
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,8 @@ module Liquid
# @liquid_syntax_keyword variable_name The name of the variable being created.
# @liquid_syntax_keyword value The value you want to assign to the variable.
class Assign < Tag
include ParserSwitching
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't think you need the include here because Tag already has it.


Syntax = /(#{VariableSignature}+)\s*=\s*(.*)\s*/om

# @api private
Expand All @@ -29,6 +31,10 @@ def self.raise_syntax_error(parse_context)

def initialize(tag_name, markup, parse_context)
super
parse_with_selected_parser(markup)
end

def lax_parse(markup)
if markup =~ Syntax
@to = Regexp.last_match(1)
@from = Variable.new(Regexp.last_match(2), parse_context)
Expand All @@ -37,6 +43,25 @@ def initialize(tag_name, markup, parse_context)
end
end

def strict_parse(markup)
lax_parse(markup)
end

def strict2_parse(markup)
unless markup =~ Syntax
self.class.raise_syntax_error(parse_context)
end

lhs = Regexp.last_match(1).strip
rhs = Regexp.last_match(2)

p = @parse_context.new_parser(lhs)
@to = p.consume(:id)
p.consume(:end_of_string)

@from = Variable.new(rhs, parse_context)
end

def render_to_output_buffer(context, output)
val = @from.render(context)
context.scopes.last[@to] = val
Expand Down
18 changes: 18 additions & 0 deletions lib/liquid/tags/capture.rb
Original file line number Diff line number Diff line change
Expand Up @@ -20,17 +20,35 @@ module Liquid
# @liquid_syntax_keyword variable The name of the variable being created.
# @liquid_syntax_keyword value The value you want to assign to the variable.
class Capture < Block
include ParserSwitching
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Same here


Syntax = /(#{VariableSignature}+)/o

attr_reader :to

def initialize(tag_name, markup, options)
super
parse_with_selected_parser(markup)
end

def lax_parse(markup)
if markup =~ Syntax
@to = Regexp.last_match(1)
else
raise SyntaxError, options[:locale].t("errors.syntax.capture")
end
end

def strict_parse(markup)
lax_parse(markup)
end

def strict2_parse(markup)
p = @parse_context.new_parser(markup.strip)
@to = p.consume(:id)
p.consume(:end_of_string)
end

def render_to_output_buffer(context, output)
context.resource_limits.with_capture do
capture_output = render(context)
Expand Down
40 changes: 40 additions & 0 deletions test/integration/assign_test.rb
Original file line number Diff line number Diff line change
Expand Up @@ -97,6 +97,46 @@ def test_assign_score_of_hash
assert_equal(12, assign_score_of('int' => 123, 'str' => 'abcd'))
end

def test_assign_with_valid_identifier_in_strict2
assert_template_result("hello", "{% assign my_var = 'hello' %}{{ my_var }}", error_mode: :strict2)
end

def test_assign_with_hyphen_in_strict2
assert_template_result("hello", "{% assign my-var = 'hello' %}{{ my-var }}", error_mode: :strict2)
end

def test_assign_rejects_parentheses_in_variable_name_in_strict2
assert_raises(Liquid::SyntaxError) do
Liquid::Template.parse("{% assign (a(b(c) = 1234 %}", error_mode: :strict2)
end
end

def test_assign_rejects_brackets_in_variable_name_in_strict2
assert_raises(Liquid::SyntaxError) do
Liquid::Template.parse("{% assign [x.y] = 'hello' %}", error_mode: :strict2)
end
end

def test_assign_rejects_dot_in_variable_name_in_strict2
assert_raises(Liquid::SyntaxError) do
Liquid::Template.parse("{% assign a.b = 'hello' %}", error_mode: :strict2)
end
end

def test_assign_rejects_numeric_variable_name_in_strict2
assert_raises(Liquid::SyntaxError) do
Liquid::Template.parse("{% assign 1abc = 'hello' %}", error_mode: :strict2)
end
end

def test_assign_allows_invalid_names_in_lax
assert_template_result("1234", "{% assign (a(b(c) = 1234 %}{{ self['(a(b(c)'] }}", error_mode: :lax)
end

def test_assign_with_filter_in_strict2
assert_template_result("HELLO", "{% assign my_var = 'hello' | upcase %}{{ my_var }}", error_mode: :strict2)
end

private

class ObjectWrapperDrop < Liquid::Drop
Expand Down
37 changes: 36 additions & 1 deletion test/integration/capture_test.rb
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,11 @@ class CaptureTest < Minitest::Test
include Liquid

def test_captures_block_content_in_variable
assert_template_result("test string", "{% capture 'var' %}test string{% endcapture %}{{var}}", {})
assert_template_result("test string", "{% capture var %}test string{% endcapture %}{{var}}", {})
end

def test_captures_block_content_in_quoted_variable_in_lax
assert_template_result("test string", "{% capture 'var' %}test string{% endcapture %}{{var}}", {}, error_mode: :lax)
end

def test_capture_with_hyphen_in_variable_name
Expand Down Expand Up @@ -49,4 +53,35 @@ def test_increment_assign_score_by_bytes_not_characters
t.render!
assert_equal(9, t.resource_limits.assign_score)
end

def test_capture_with_valid_identifier_in_strict2
assert_template_result("hello", "{% capture my_var %}hello{% endcapture %}{{ my_var }}", error_mode: :strict2)
end

def test_capture_with_hyphen_in_strict2
assert_template_result("hello", "{% capture my-var %}hello{% endcapture %}{{ my-var }}", error_mode: :strict2)
end

def test_capture_rejects_parentheses_in_variable_name_in_strict2
assert_raises(Liquid::SyntaxError) do
Liquid::Template.parse("{% capture (x[y %}hello{% endcapture %}", error_mode: :strict2)
end
end

def test_capture_rejects_dot_in_variable_name_in_strict2
assert_raises(Liquid::SyntaxError) do
Liquid::Template.parse("{% capture a.b %}hello{% endcapture %}", error_mode: :strict2)
end
end

def test_capture_rejects_numeric_variable_name_in_strict2
assert_raises(Liquid::SyntaxError) do
Liquid::Template.parse("{% capture 1abc %}hello{% endcapture %}", error_mode: :strict2)
end
end

def test_capture_allows_invalid_names_in_lax
t = Liquid::Template.parse("{% capture (x[y %}hello{% endcapture %}", error_mode: :lax)
assert_equal("(x[y", t.root.nodelist.first.to)
end
end
6 changes: 2 additions & 4 deletions test/integration/tags/cycle_tag_test.rb
Original file line number Diff line number Diff line change
Expand Up @@ -105,10 +105,8 @@ def test_cycle_tag_with_error_mode
error1 = assert_raises(Liquid::SyntaxError) { Template.parse(template1) }
error2 = assert_raises(Liquid::SyntaxError) { Template.parse(template2) }

expected_error = /Liquid syntax error: \[:dot, "."\] is not a valid expression/

assert_match(expected_error, error1.message)
assert_match(expected_error, error2.message)
assert_match(/Liquid syntax error:/, error1.message)
assert_match(/Liquid syntax error: \[:dot, "."\] is not a valid expression/, error2.message)
end
end

Expand Down
Loading