mirror of
https://github.com/Shopify/liquid.git
synced 2026-09-26 13:45:13 -07:00
Use ExpressionParser in the ParseContext when parsing in :rigid mode
This commit is contained in:
committed by
Guilherme Carreiro
parent
1bff382ebc
commit
d56e3c50f9
+13
-18
@@ -52,26 +52,21 @@ module Liquid
|
|||||||
|
|
||||||
def parse_expression(markup)
|
def parse_expression(markup)
|
||||||
if @error_mode == :rigid
|
if @error_mode == :rigid
|
||||||
parser = new_parser(markup)
|
# ExpressionParser doesn't use @expression_cache because rigid mode
|
||||||
|
# must run Lexer and Parser validation on every call to ensure all
|
||||||
# Return nil immediately if the markup is empty or contains only
|
# tokens are valid and properly consumed.
|
||||||
# whitespaces
|
|
||||||
return if parser.look(:end_of_string)
|
|
||||||
|
|
||||||
expression_string = parser.expression
|
|
||||||
|
|
||||||
# In rigid mode, verify that all tokens have been consumed
|
|
||||||
#
|
#
|
||||||
# Extra tokens remaining after the expression indicate invalid syntaxes,
|
# The expensive operations (tokenization and validation) cannot be
|
||||||
# such as: "product title" (instead of "product.title")
|
# cached, while the cheap operation (building Expression objects from
|
||||||
parser.consume(:end_of_string) unless parser.look(:end_of_string)
|
# validated tokens) provides minimal benefit from caching.
|
||||||
|
#
|
||||||
# Use Parser for strict token validation, but still return
|
# Most importantly, caching would skip the validation step entirely,
|
||||||
# Expression objects for compatibility with the rendering pipeline.
|
# which defeats the core purpose of rigid mode: strict validation of
|
||||||
markup = expression_string
|
# every expression to catch syntax errors like "product title".
|
||||||
|
ExpressionParser.parse(markup, self)
|
||||||
|
else
|
||||||
|
Expression.parse(markup, @string_scanner, @expression_cache)
|
||||||
end
|
end
|
||||||
|
|
||||||
Expression.parse(markup, @string_scanner, @expression_cache)
|
|
||||||
end
|
end
|
||||||
|
|
||||||
def partial=(value)
|
def partial=(value)
|
||||||
|
|||||||
@@ -42,14 +42,25 @@ class ExpressionTest < Minitest::Test
|
|||||||
assert_template_result("3..4", "{{ ( 3 .. 4 ) }}")
|
assert_template_result("3..4", "{{ ( 3 .. 4 ) }}")
|
||||||
assert_expression_result(1..2, "(1..2)")
|
assert_expression_result(1..2, "(1..2)")
|
||||||
|
|
||||||
assert_match_syntax_error(
|
if Liquid::Environment.default.error_mode == :rigid
|
||||||
"Liquid syntax error (line 1): Invalid expression type 'false' in range expression",
|
assert_match_syntax_error(
|
||||||
"{{ (false..true) }}",
|
'Invalid expression type in range expression in "{{ (false..true) }}"',
|
||||||
)
|
"{{ (false..true) }}",
|
||||||
assert_match_syntax_error(
|
)
|
||||||
"Liquid syntax error (line 1): Invalid expression type '(1..2)' in range expression",
|
assert_match_syntax_error(
|
||||||
"{{ ((1..2)..3) }}",
|
'Liquid syntax error (line 1): Invalid expression type in range expression in "{{ ((1..2)..3) }}"',
|
||||||
)
|
"{{ ((1..2)..3) }}",
|
||||||
|
)
|
||||||
|
else
|
||||||
|
assert_match_syntax_error(
|
||||||
|
"Liquid syntax error (line 1): Invalid expression type 'false' in range expression",
|
||||||
|
"{{ (false..true) }}",
|
||||||
|
)
|
||||||
|
assert_match_syntax_error(
|
||||||
|
"Liquid syntax error (line 1): Invalid expression type '(1..2)' in range expression",
|
||||||
|
"{{ ((1..2)..3) }}",
|
||||||
|
)
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
def test_quirky_negative_sign_expression_markup
|
def test_quirky_negative_sign_expression_markup
|
||||||
@@ -66,6 +77,7 @@ class ExpressionTest < Minitest::Test
|
|||||||
|
|
||||||
def test_expression_cache
|
def test_expression_cache
|
||||||
skip("Liquid-C does not support Expression caching") if defined?(Liquid::C) && Liquid::C.enabled
|
skip("Liquid-C does not support Expression caching") if defined?(Liquid::C) && Liquid::C.enabled
|
||||||
|
skip("Rigid mode does not use Expression caching") if Liquid::Environment.default.error_mode == :rigid
|
||||||
|
|
||||||
cache = {}
|
cache = {}
|
||||||
template = <<~LIQUID
|
template = <<~LIQUID
|
||||||
@@ -87,6 +99,7 @@ class ExpressionTest < Minitest::Test
|
|||||||
|
|
||||||
def test_expression_cache_with_true_boolean
|
def test_expression_cache_with_true_boolean
|
||||||
skip("Liquid-C does not support Expression caching") if defined?(Liquid::C) && Liquid::C.enabled
|
skip("Liquid-C does not support Expression caching") if defined?(Liquid::C) && Liquid::C.enabled
|
||||||
|
skip("Rigid mode does not use Expression caching") if Liquid::Environment.default.error_mode == :rigid
|
||||||
|
|
||||||
template = <<~LIQUID
|
template = <<~LIQUID
|
||||||
{% assign x = 1 %}
|
{% assign x = 1 %}
|
||||||
@@ -111,6 +124,7 @@ class ExpressionTest < Minitest::Test
|
|||||||
|
|
||||||
def test_expression_cache_with_lru_redux
|
def test_expression_cache_with_lru_redux
|
||||||
skip("Liquid-C does not support Expression caching") if defined?(Liquid::C) && Liquid::C.enabled
|
skip("Liquid-C does not support Expression caching") if defined?(Liquid::C) && Liquid::C.enabled
|
||||||
|
skip("Rigid mode does not use Expression caching") if Liquid::Environment.default.error_mode == :rigid
|
||||||
|
|
||||||
cache = LruRedux::Cache.new(10)
|
cache = LruRedux::Cache.new(10)
|
||||||
template = <<~LIQUID
|
template = <<~LIQUID
|
||||||
@@ -132,6 +146,7 @@ class ExpressionTest < Minitest::Test
|
|||||||
|
|
||||||
def test_disable_expression_cache
|
def test_disable_expression_cache
|
||||||
skip("Liquid-C does not support Expression caching") if defined?(Liquid::C) && Liquid::C.enabled
|
skip("Liquid-C does not support Expression caching") if defined?(Liquid::C) && Liquid::C.enabled
|
||||||
|
skip("Rigid mode does not use Expression caching") if Liquid::Environment.default.error_mode == :rigid
|
||||||
|
|
||||||
template = <<~LIQUID
|
template = <<~LIQUID
|
||||||
{% assign x = 1 %}
|
{% assign x = 1 %}
|
||||||
|
|||||||
Reference in New Issue
Block a user