Skip to content

Commit

Permalink
Ensure File.open_buffer doesn't rewrite unchanged data.
Browse files Browse the repository at this point in the history
This is a backport of 14b63f6 from trunk.
  • Loading branch information
hainesr committed Apr 8, 2024
1 parent 900db76 commit ef89a62
Show file tree
Hide file tree
Showing 2 changed files with 27 additions and 2 deletions.
3 changes: 3 additions & 0 deletions lib/zip/file.rb
Expand Up @@ -99,6 +99,7 @@ def initialize(path_or_io, dep_create = false, dep_buffer = false,
end
elsif buffer && path_or_io.size > 0
# This zip is probably a non-empty StringIO.
@create = false
read_from_stream(path_or_io)
elsif @create
# This zip is completely new/empty and is to be created.
Expand Down Expand Up @@ -411,6 +412,8 @@ def commit

# Write buffer write changes to buffer and return
def write_buffer(io = ::StringIO.new(''))
return unless commit_required?

::Zip::OutputStream.write_buffer(io) do |zos|
@entry_set.each { |e| e.write_to_zip_output_stream(zos) }
zos.comment = comment
Expand Down
26 changes: 24 additions & 2 deletions test/file_test.rb
Expand Up @@ -104,17 +104,27 @@ def test_get_output_stream
end

def test_open_buffer_with_string
string = File.read('test/data/rubycode.zip')
data = File.read('test/data/rubycode.zip', mode: 'rb')
string = data.dup

::Zip::File.open_buffer string do |zf|
assert zf.entries.map(&:name).include?('zippedruby1.rb')
end

# Ensure the buffer hasn't changed.
assert_equal(data, string)
end

def test_open_buffer_with_stringio
string_io = StringIO.new File.read('test/data/rubycode.zip')
data = File.read('test/data/rubycode.zip', mode: 'rb')
string_io = StringIO.new(data.dup)

::Zip::File.open_buffer string_io do |zf|
assert zf.entries.map(&:name).include?('zippedruby1.rb')
end

# Ensure the buffer hasn't changed.
assert_equal(data, string_io.string)
end

def test_close_buffer_with_stringio
Expand All @@ -123,6 +133,18 @@ def test_close_buffer_with_stringio
assert_nil zf.close
end

def test_open_buffer_without_block_write_buffer_does_nothing
data = File.read('test/data/rubycode.zip', mode: 'rb')
string_io = StringIO.new(data.dup)

zf = ::Zip::File.open_buffer(string_io)
assert zf.entries.map(&:name).include?('zippedruby1.rb')

# Ensure the buffer isn't changed.
zf.write_buffer(string_io)
assert_equal(data, string_io.string)
end

def test_open_buffer_no_op_does_not_change_file
Dir.mktmpdir do |tmp|
test_zip = File.join(tmp, 'test.zip')
Expand Down

0 comments on commit ef89a62

Please sign in to comment.