diff --git a/lib/liquid/block_body.rb b/lib/liquid/block_body.rb index ba29415..d4fab30 100644 --- a/lib/liquid/block_body.rb +++ b/lib/liquid/block_body.rb @@ -115,7 +115,7 @@ module Liquid end def check_resources(context, node_output) - context.resource_limits.render_length += node_output.length + context.resource_limits.render_length += node_output.bytesize return unless context.resource_limits.reached? raise MemoryError.new("Memory limits exceeded".freeze) end diff --git a/lib/liquid/tags/assign.rb b/lib/liquid/tags/assign.rb index c8d0574..3b696dd 100644 --- a/lib/liquid/tags/assign.rb +++ b/lib/liquid/tags/assign.rb @@ -37,7 +37,7 @@ module Liquid def assign_score_of(val) if val.instance_of?(String) - val.length + val.bytesize elsif val.instance_of?(Array) || val.instance_of?(Hash) sum = 1 # Uses #each to avoid extra allocations. diff --git a/lib/liquid/tags/capture.rb b/lib/liquid/tags/capture.rb index 8674356..d5b8e29 100644 --- a/lib/liquid/tags/capture.rb +++ b/lib/liquid/tags/capture.rb @@ -25,7 +25,7 @@ module Liquid def render(context) output = super context.scopes.last[@to] = output - context.resource_limits.assign_score += output.length + context.resource_limits.assign_score += output.bytesize ''.freeze end diff --git a/test/integration/template_test.rb b/test/integration/template_test.rb index d10e1c5..0dc0ae5 100644 --- a/test/integration/template_test.rb +++ b/test/integration/template_test.rb @@ -139,6 +139,16 @@ class TemplateTest < Minitest::Test refute_nil t.resource_limits.assign_score end + def test_resource_limits_assign_score_counts_bytes_not_characters + t = Template.parse("{% assign foo = 'すごい' %}") + t.render + assert_equal 9, t.resource_limits.assign_score + + t = Template.parse("{% capture foo %}すごい{% endcapture %}") + t.render + assert_equal 9, t.resource_limits.assign_score + end + def test_resource_limits_assign_score_nested t = Template.parse("{% assign foo = 'aaaa' | reverse %}") @@ -187,6 +197,14 @@ class TemplateTest < Minitest::Test assert_equal "ababab", t.render end + def test_render_length_uses_number_of_bytes_not_characters + t = Template.parse("{% if true %}すごい{% endif %}") + t.resource_limits.render_length_limit = 10 + assert_equal "Liquid error: Memory limits exceeded", t.render + t.resource_limits.render_length_limit = 18 + assert_equal "すごい", t.render + end + def test_default_resource_limits_unaffected_by_render_with_context context = Context.new t = Template.parse("{% for a in (1..100) %} {% assign foo = 1 %} {% endfor %}")