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

Prevent an internal error in include tag from non-string template_name #1648

Merged
merged 2 commits into from
Oct 28, 2022

Conversation

dylanahsmith
Copy link
Contributor

Problem

The include tag wasn't validating the type of value that the template_name expression evaluates to, but also makes an assumption that it is a string by calling String#split on it.

For example, the added regression test demonstrates the problem, even with the following change to allow the partial lookup to succeed

diff --git a/test/integration/tags/include_tag_test.rb b/test/integration/tags/include_tag_test.rb
index 91f1aeab..c1b688c1 100644
--- a/test/integration/tags/include_tag_test.rb
+++ b/test/integration/tags/include_tag_test.rb
@@ -251,7 +251,7 @@ class IncludeTagTest < Minitest::Test
 
   def test_render_raise_argument_error_when_template_is_not_a_string
     assert_template_result("Liquid error (line 1): Argument error in tag 'include' - Illegal template name",
-      "{% include 123 %}", render_errors: true)
+      "{% include 123 %}", partials: { "123" => "foo" }, render_errors: false)
   end
 
   def test_including_via_variable_value
diff --git a/test/test_helper.rb b/test/test_helper.rb
index 2caa7b32..0b419751 100755
--- a/test/test_helper.rb
+++ b/test/test_helper.rb
@@ -195,7 +195,7 @@ class StubFileSystem
 
   def read_template_file(template_path)
     @file_read_count += 1
-    @values.fetch(template_path)
+    @values.fetch(template_path.to_s)
   end
 end
 

which results in the test failing with the exception

  1) Error:
IncludeTagTest#test_render_raise_argument_error_when_template_is_not_a_string:
NoMethodError: undefined method `split' for 123:Integer

      context_variable_name = @alias_name || template_name.split('/').last
                                                          ^^^^^^
    /Users/dylants/src/liquid/lib/liquid/tags/include.rb:63:in `render_to_output_buffer'

Solution

I don't think we really have a use case for adding coercion for this use case. Also, I only noticed this from looking at edge cases in the code and I don't think we have noticed this internal error being reported in practice. As such, I think we can be stricter here, especially given that we don't want to encourage more difficult to analyze dynamic include behaviour.

I simply made the unless template_name validity check stricter by requiring template.is_a?(String).

Since it doesn't reflect the real liquid usage that we are trying
to test against.
which would otherwise happen on `template_name.split('/')`
Copy link

@ojgarcia ojgarcia left a comment

Choose a reason for hiding this comment

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

LGTM

@dylanahsmith dylanahsmith merged commit ace3fe1 into master Oct 28, 2022
@dylanahsmith dylanahsmith deleted the fix-include-internal-error branch October 28, 2022 18:29
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants