diff --git a/ext/liquid_c/raw.c b/ext/liquid_c/raw.c index 0d4ff5af..a4ad9aa6 100644 --- a/ext/liquid_c/raw.c +++ b/ext/liquid_c/raw.c @@ -27,6 +27,12 @@ static bool match_full_token_possibly_invalid(token_t *token, struct full_token_ const char *curr_delimiter_start; long curr_delimiter_len = 0; + bool is_last_char_whitespace = true; + + // Search from the end of the string. + // The token could have a part of the body like this: + // {% endraw {% endraw %} + // In this case, we need to return body_len to 10 to preserve the body content. for (long i = len - 3; i > 1; i--) { char c = str[i]; @@ -35,13 +41,22 @@ static bool match_full_token_possibly_invalid(token_t *token, struct full_token_ if (is_word_char(c)) { curr_delimiter_start = str + i; - curr_delimiter_len++; + + if (is_last_char_whitespace) { + // start a new delimiter match + curr_delimiter_len = 1; + } else { + curr_delimiter_len++; + } } else if (!is_word_char(c) && !is_whitespace) { curr_delimiter_start = NULL; curr_delimiter_len = 0; } + is_last_char_whitespace = is_whitespace; + if (curr_delimiter_len > 0) { + // match start of a tag which is {% or {%- if ( (str[i - 1] == '%' && str[i - 2] == '{') || (i - 3 >= 0 && str[i - 1] == '-' && str[i - 2] == '%' && str[i - 3] == '{') diff --git a/test/unit/raw_test.rb b/test/unit/raw_test.rb index b130089c..8f7a2442 100644 --- a/test/unit/raw_test.rb +++ b/test/unit/raw_test.rb @@ -30,6 +30,14 @@ def test_derived_class end end + def test_allows_extra_string_after_tag_delimiter + output = Liquid::Template.parse("{% raw %}message{% endraw this_is_allowed %}").render + assert_equal("message", output) + + output = Liquid::Template.parse("{% raw %}message{% endraw r%}").render + assert_equal("message", output) + end + def test_ignores_incomplete_tag_delimter output = Liquid::Template.parse("{% raw %}{% endraw {% endraw %}").render assert_equal("{% endraw ", output) @@ -55,6 +63,7 @@ def test_does_not_allow_nbsp_in_tag_delimiter Liquid::Template.parse("{% raw %}body{% endraw\u00A0 %}") Liquid::Template.parse("{% raw %}body{% endraw \u00A0 %}") Liquid::Template.parse("{% raw %}body{% endraw \u00A0 endraw %}") + Liquid::Template.parse("{% raw %}body{% endraw\u00A0endraw %}") [ "{%\u00A0endraw%}", @@ -63,6 +72,7 @@ def test_does_not_allow_nbsp_in_tag_delimiter "{% \u00A0 endraw%}", "{%\u00A0endraw\u00A0%}", "{% - endraw %}", + "{% endnot endraw %}", ].each do |bad_delimiter| exception = assert_raises( Liquid::SyntaxError,