mirror of
https://github.com/kemko/liquid.git
synced 2026-01-02 00:05:42 +03:00
Compare commits
3 Commits
sort-numer
...
lax-parse-
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
0e25e5d5e8 | ||
|
|
77bdccf5ec | ||
|
|
87e3234b58 |
@@ -3,7 +3,7 @@ module Liquid
|
|||||||
def parse_with_selected_parser(markup)
|
def parse_with_selected_parser(markup)
|
||||||
case parse_context.error_mode
|
case parse_context.error_mode
|
||||||
when :strict then strict_parse_with_error_context(markup)
|
when :strict then strict_parse_with_error_context(markup)
|
||||||
when :lax then lax_parse(markup)
|
when :lax, :lax_warn then lax_parse(markup)
|
||||||
when :warn
|
when :warn
|
||||||
begin
|
begin
|
||||||
return strict_parse_with_error_context(markup)
|
return strict_parse_with_error_context(markup)
|
||||||
|
|||||||
@@ -10,7 +10,16 @@ module Liquid
|
|||||||
# {{ user | link }}
|
# {{ user | link }}
|
||||||
#
|
#
|
||||||
class Variable
|
class Variable
|
||||||
FilterParser = /(?:\s+|#{QuotedFragment}|#{ArgumentSeparator})+/o
|
capture_ignored_variable_prefix = /([\s,\|'"]+?)??/
|
||||||
|
capture_expression = /(#{QuotedFragment})/o
|
||||||
|
capture_ignored_filter_prefix = /([^\|]+?)??/
|
||||||
|
capture_filters = /(#{FilterSeparator}.*)/o
|
||||||
|
VariableSyntax = /\A\s*#{capture_ignored_variable_prefix}\s*#{capture_expression}\s*(?:#{capture_ignored_filter_prefix}\s*#{capture_filters})?\z/om
|
||||||
|
|
||||||
|
capture_lax_separator = /(['"\|]+?)/
|
||||||
|
capture_filter = /((?:\s+|#{QuotedFragment}|#{ArgumentSeparator})+)/o
|
||||||
|
FilterParser = /\s*(?:#{FilterSeparator}|#{capture_lax_separator})\s*#{capture_filter}/o
|
||||||
|
|
||||||
attr_accessor :filters, :name, :line_number
|
attr_accessor :filters, :name, :line_number
|
||||||
attr_reader :parse_context
|
attr_reader :parse_context
|
||||||
alias_method :options, :parse_context
|
alias_method :options, :parse_context
|
||||||
@@ -35,16 +44,19 @@ module Liquid
|
|||||||
|
|
||||||
def lax_parse(markup)
|
def lax_parse(markup)
|
||||||
@filters = []
|
@filters = []
|
||||||
return unless markup =~ /(#{QuotedFragment})(.*)/om
|
return unless markup =~ VariableSyntax
|
||||||
|
|
||||||
name_markup = $1
|
add_syntax_warning("variable prefixed with ignored characters: #{$1.inspect}") if $1
|
||||||
filter_markup = $2
|
name_markup = $2
|
||||||
|
add_syntax_warning("variable filter separator prefixed with ignored characters: #{$3.inspect}") if $3
|
||||||
|
filters_markup = $4
|
||||||
@name = Expression.parse(name_markup)
|
@name = Expression.parse(name_markup)
|
||||||
if filter_markup =~ /#{FilterSeparator}\s*(.*)/om
|
if filters_markup
|
||||||
filters = $1.scan(FilterParser)
|
filters_markup.scan(FilterParser) do |lax_sep, f|
|
||||||
filters.each do |f|
|
add_syntax_warning("unterminated quote or multiple pipe characters used as a filter separator: #{lax_sep.inspect}") if lax_sep
|
||||||
next unless f =~ /\w+/
|
next unless f =~ /\A\s*(\W+)??(\w+)/
|
||||||
filtername = Regexp.last_match(0)
|
add_syntax_warning("ignored characters before filter name: #{$1.inspect}") if $1
|
||||||
|
filtername = $2
|
||||||
filterargs = f.scan(/(?:#{FilterArgumentSeparator}|#{ArgumentSeparator})\s*((?:\w+\s*\:\s*)?#{QuotedFragment})/o).flatten
|
filterargs = f.scan(/(?:#{FilterArgumentSeparator}|#{ArgumentSeparator})\s*((?:\w+\s*\:\s*)?#{QuotedFragment})/o).flatten
|
||||||
@filters << parse_filter_expressions(filtername, filterargs)
|
@filters << parse_filter_expressions(filtername, filterargs)
|
||||||
end
|
end
|
||||||
@@ -81,6 +93,13 @@ module Liquid
|
|||||||
|
|
||||||
private
|
private
|
||||||
|
|
||||||
|
def add_syntax_warning(warning)
|
||||||
|
return unless parse_context.error_mode == :lax_warn
|
||||||
|
error = SyntaxError.new(warning)
|
||||||
|
error.line_number = parse_context.line_number
|
||||||
|
parse_context.warnings << error
|
||||||
|
end
|
||||||
|
|
||||||
def parse_filter_expressions(filter_name, unparsed_args)
|
def parse_filter_expressions(filter_name, unparsed_args)
|
||||||
filter_args = []
|
filter_args = []
|
||||||
keyword_args = {}
|
keyword_args = {}
|
||||||
|
|||||||
@@ -89,4 +89,32 @@ class VariableTest < Minitest::Test
|
|||||||
def test_multiline_variable
|
def test_multiline_variable
|
||||||
assert_equal 'worked', Template.parse("{{\ntest\n}}").render!('test' => 'worked')
|
assert_equal 'worked', Template.parse("{{\ntest\n}}").render!('test' => 'worked')
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def test_lax_warnings_for_variable_ignored_prefix
|
||||||
|
ignored_chars = %(|,'")
|
||||||
|
template = Liquid::Template.parse("{{ #{ignored_chars}test }}", error_mode: :lax_warn)
|
||||||
|
assert_equal "works", template.render!('test' => 'works')
|
||||||
|
assert_equal [Liquid::SyntaxError.new("variable prefixed with ignored characters: #{ignored_chars.inspect}")], template.warnings
|
||||||
|
end
|
||||||
|
|
||||||
|
def test_lax_warnings_for_ignored_variable_filter_prefix
|
||||||
|
ignored_chars = ",wat? lax!"
|
||||||
|
template = Liquid::Template.parse("{{ test#{ignored_chars} | noop }}", error_mode: :lax_warn)
|
||||||
|
assert_equal "works", template.render!('test' => 'works')
|
||||||
|
assert_equal [Liquid::SyntaxError.new("variable filter separator prefixed with ignored characters: #{ignored_chars.inspect}")], template.warnings
|
||||||
|
end
|
||||||
|
|
||||||
|
def test_lax_warnings_for_weird_filter_chars
|
||||||
|
template = Liquid::Template.parse("{{ test | upcase \" prepend: 'it ' || append: ' surprisingly' }}", error_mode: :lax_warn)
|
||||||
|
assert_equal "it WORKS surprisingly", template.render!('test' => 'works')
|
||||||
|
expected_warnings = ['"', '||'].map{ |sep| Liquid::SyntaxError.new("unterminated quote or multiple pipe characters used as a filter separator: #{sep.inspect}") }
|
||||||
|
assert_equal expected_warnings, template.warnings
|
||||||
|
end
|
||||||
|
|
||||||
|
def test_lax_warnings_for_ignored_filter_name_prefix
|
||||||
|
ignored_chars = "'': '"
|
||||||
|
template = Liquid::Template.parse("{{ test | '': 'prepend ' }}", error_mode: :lax_warn)
|
||||||
|
assert_equal "prepend wat", template.render!('test' => 'wat')
|
||||||
|
assert_equal [Liquid::SyntaxError.new("ignored characters before filter name: #{ignored_chars.inspect}")], template.warnings
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|||||||
Reference in New Issue
Block a user