Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Only use MethodLiteral in condition expressions #1300

Merged
merged 2 commits into from
Sep 25, 2020
Merged
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
22 changes: 20 additions & 2 deletions lib/liquid/condition.rb
Original file line number Diff line number Diff line change
Expand Up @@ -27,10 +27,28 @@ class Condition #:nodoc:
end,
}

class MethodLiteral
attr_reader :method_name, :to_s

def initialize(method_name, to_s)
@method_name = method_name
@to_s = to_s
end
end

@@method_literals = {
'blank' => MethodLiteral.new(:blank?, '').freeze,
'empty' => MethodLiteral.new(:empty?, '').freeze,
}

def self.operators
@@operators
end

def self.parse_expression(markup)
@@method_literals[markup] || Expression.parse(markup)
end

attr_reader :attachment, :child_condition
attr_accessor :left, :operator, :right

Expand Down Expand Up @@ -91,15 +109,15 @@ def inspect
private

def equal_variables(left, right)
if left.is_a?(Liquid::Expression::MethodLiteral)
if left.is_a?(MethodLiteral)
if right.respond_to?(left.method_name)
return right.send(left.method_name)
else
return nil
end
end

if right.is_a?(Liquid::Expression::MethodLiteral)
if right.is_a?(MethodLiteral)
if left.respond_to?(right.method_name)
return left.send(right.method_name)
else
Expand Down
17 changes: 2 additions & 15 deletions lib/liquid/expression.rb
Original file line number Diff line number Diff line change
Expand Up @@ -2,25 +2,12 @@

module Liquid
class Expression
class MethodLiteral
attr_reader :method_name, :to_s

def initialize(method_name, to_s)
@method_name = method_name
@to_s = to_s
end

def to_liquid
to_s
end
end

LITERALS = {
nil => nil, 'nil' => nil, 'null' => nil, '' => nil,
'true' => true,
'false' => false,
'blank' => MethodLiteral.new(:blank?, '').freeze,
'empty' => MethodLiteral.new(:empty?, '').freeze
'blank' => '',
'empty' => ''
}.freeze

SINGLE_QUOTED_STRING = /\A'(.*)'\z/m
Expand Down
2 changes: 1 addition & 1 deletion lib/liquid/tags/case.rb
Original file line number Diff line number Diff line change
Expand Up @@ -68,7 +68,7 @@ def record_when_condition(markup)

markup = Regexp.last_match(2)

block = Condition.new(@left, '==', Expression.parse(Regexp.last_match(1)))
block = Condition.new(@left, '==', Condition.parse_expression(Regexp.last_match(1)))
block.attach(body)
@blocks << block
end
Expand Down
12 changes: 8 additions & 4 deletions lib/liquid/tags/if.rb
Original file line number Diff line number Diff line change
Expand Up @@ -67,18 +67,22 @@ def push_block(tag, markup)
block.attach(new_body)
end

def parse_expression(markup)
Condition.parse_expression(markup)
end

def lax_parse(markup)
expressions = markup.scan(ExpressionsAndOperators)
raise SyntaxError, options[:locale].t("errors.syntax.if") unless expressions.pop =~ Syntax

condition = Condition.new(Expression.parse(Regexp.last_match(1)), Regexp.last_match(2), Expression.parse(Regexp.last_match(3)))
condition = Condition.new(parse_expression(Regexp.last_match(1)), Regexp.last_match(2), parse_expression(Regexp.last_match(3)))

until expressions.empty?
operator = expressions.pop.to_s.strip

raise SyntaxError, options[:locale].t("errors.syntax.if") unless expressions.pop.to_s =~ Syntax

new_condition = Condition.new(Expression.parse(Regexp.last_match(1)), Regexp.last_match(2), Expression.parse(Regexp.last_match(3)))
new_condition = Condition.new(parse_expression(Regexp.last_match(1)), Regexp.last_match(2), parse_expression(Regexp.last_match(3)))
raise SyntaxError, options[:locale].t("errors.syntax.if") unless BOOLEAN_OPERATORS.include?(operator)
new_condition.send(operator, condition)
condition = new_condition
Expand Down Expand Up @@ -106,9 +110,9 @@ def parse_binary_comparisons(p)
end

def parse_comparison(p)
a = Expression.parse(p.expression)
a = parse_expression(p.expression)
if (op = p.consume?(:comparison))
b = Expression.parse(p.expression)
b = parse_expression(p.expression)
Condition.new(a, op, b)
else
Condition.new(a)
Expand Down