diff --git a/actionpack/lib/action_controller/caching/fragments.rb b/actionpack/lib/action_controller/caching/fragments.rb index 56ccc4ada199d..a55abdf1dc7bd 100644 --- a/actionpack/lib/action_controller/caching/fragments.rb +++ b/actionpack/lib/action_controller/caching/fragments.rb @@ -39,9 +39,9 @@ def fragment_for(buffer, name = {}, options = nil, &block) #:nodoc: if cache = read_fragment(name, options) buffer.safe_concat(cache.html_safe) else - pos = buffer.length + pos = buffer.bytesize block.call - write_fragment(name, buffer[pos..-1], options) + write_fragment(name, buffer.byteslice(pos..-1), options) end else block.call diff --git a/actionpack/test/controller/caching_test.rb b/actionpack/test/controller/caching_test.rb index 021ef22311bc0..4501e7766334f 100644 --- a/actionpack/test/controller/caching_test.rb +++ b/actionpack/test/controller/caching_test.rb @@ -622,6 +622,19 @@ def test_fragment_for assert_equal 'generated till now -> fragment content', buffer end + def test_fragment_for_bytesize + buffer = "\xC4\x8D" + buffer.force_encoding('ASCII-8BIT') + + @controller.fragment_for(buffer, 'bytesize') do + buffer.force_encoding('UTF-8') + buffer << "abc" + end + + assert_equal Encoding::UTF_8, buffer.encoding + assert_equal "abc", @store.read('views/bytesize') + end + def test_html_safety assert_nil @store.read('views/name') content = 'value'.html_safe