liquid icon indicating copy to clipboard operation
liquid copied to clipboard

Fix large for-loop collection

Open stayhero opened this issue 6 years ago • 4 comments

When a large Range is given in a for-loop (e.g. 1..100000000000000), it may crash the Ruby process or at least eats a lot of memory and takes a significant amount of time to render the template.

I added the following testcase to template_test.rb:

    t = Template.parse("{% for a in (1..100000000000000) %} {% for a in (1..10) %} foo {% endfor %} {% endfor %}")
    t.resource_limits.render_score_limit = 50
    assert_equal "Liquid error: Memory limits exceeded", t.render
    assert t.resource_limits.reached?

The render_score_limit does not help here because it's more of a Ruby performance problem in for.rb, where the collection = collection.to_a if collection.is_a?(Range) happens.

A fix may be to check if the given Range is larger than the given render_score_limit. I'm actually not sure if there may be a better fix (e.g. checking the resource limits somewhere else) but at least it works for the given test case.

stayhero avatar Mar 11 '19 22:03 stayhero

BTW: You can checkout this branch to show the behavior for a large given collection without the fix:

https://github.com/stayhero/liquid/tree/large_forloop_failing_test?files=1

stayhero avatar Mar 12 '19 07:03 stayhero

@pushrax Anything missing to merge the PR?

stayhero avatar Apr 03 '19 14:04 stayhero

@pushrax: ping

fw42 avatar Apr 26 '19 12:04 fw42

👋 Friendly bump to see what it would take to merge.

gjtorikian avatar Nov 06 '23 21:11 gjtorikian