8000 Merge pull request #360 from hainesr/fix-open-buffer · rubyzip/rubyzip@7fbaf1e · GitHub
[go: up one dir, main page]

Skip to content

Commit 7fbaf1e

Browse files
authored
Merge pull request #360 from hainesr/fix-open-buffer
Fix #280 - `open_buffer` mangles the content of the buffer it is given.
2 parents ee6fb82 + 84c2089 commit 7fbaf1e

File tree

2 files changed

+40
-19
lines changed

2 files changed

+40
-19
lines changed

lib/zip/file.rb

Lines changed: 30 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -64,24 +64,38 @@ class File < CentralDirectory
6464

6565
# Opens a zip archive. Pass true as the second parameter to create
6666
# a new archive if it doesn't exist already.
67-
def initialize(file_name, create = false, buffer = false, options = {})
67+
def initialize(path_or_io, create = false, buffer = false, options = {})
6868
super()
69-
@name = file_name
69+
@name = path_or_io.respond_to?(:path) ? path_or_io.path : path_or_io
7070
@comment = ''
7171
@create = create ? true : false # allow any truthy value to mean true
72-
if !buffer && ::File.size?(file_name)
72+
73+
if ::File.size?(@name.to_s)
74+
# There is a file, which exists, that is associated with this zip.
7375
@create = false
74-
@file_permissions = ::File.stat(file_name).mode
75-
::File.open(name, 'rb') do |f|
76-
read_from_stream(f)
76+
@file_permissions = ::File.stat(@name).mode
77+
78+
if buffer
79+
read_from_stream(path_or_io)
80+
else
81+
::File.open(@name, 'rb') do |f|
82+
read_from_stream(f)
83+
end
7784
end
85+
elsif buffer && path_or_io.size > 0
86+
# This zip is probably a non-empty StringIO.
87+
read_from_stream(path_or_io)
7888
elsif @create
89+
# This zip is completely new/empty and is to be created.
7990
@entry_set = EntrySet.new
80-
elsif ::File.zero?(file_name)
81-
raise Error, "File #{file_name} has zero size. Did you mean to pass the create flag?"
91+
elsif ::File.zero?(@name)
92+
# A file exists, but it is empty.
93+
raise Error, "File #{@name} has zero size. Did you mean to pass the create flag?"
8294
else
83-
raise Error, "File #{file_name} not found"
95+
# Everything is wrong.
96+
raise Error, "File #{@name} not found"
8497
end
98+
8599
@stored_entries = @entry_set.dup
86100
@stored_comment = @comment
87101
@restore_ownership = options[:restore_ownership] || false
@@ -119,17 +133,16 @@ def open_buffer(io, options = {})
119133
unless IO_METHODS.map { |method| io.respond_to?(method) }.all? || io.is_a?(String)
120134
raise "Zip::File.open_buffer expects a String or IO-like argument (responds to #{IO_METHODS.join(', ')}). Found: #{io.class}"
121135
end
122-
if io.is_a?(::String)
123-
require 'stringio'
124-
io = ::StringIO.new(io)
125-
elsif io.respond_to?(:binmode)
126-
# https://github.com/rubyzip/rubyzip/issues/119
127-
io.binmode
128-
end
136+
137+
io = ::StringIO.new(io) if io.is_a?(::String)
138+
139+
# https://github.com/rubyzip/rubyzip/issues/119
140+
io.binmode if io.respond_to?(:binmode)
141+
129142
zf = ::Zip::File.new(io, true, true, options)
130-
zf.read_from_stream(io)
131143
return zf unless block_given?
132144
yield zf
145+
133146
begin
134147
zf.write_buffer(io)
135148
rescue IOError => e

test/file_test.rb

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -103,6 +103,13 @@ def test_get_output_stream
103103
end
104104
end
105105

106+
def test_open_buffer_with_string
107+
string = File.read('test/data/rubycode.zip')
108+
::Zip::File.open_buffer string do |zf|
109+
assert zf.entries.map { |e| e.name }.include?('zippedruby1.rb')
110+
end
111+
end
112+
106113
def test_open_buffer_with_stringio
107114
string_io = StringIO.new File.read('test/data/rubycode.zip')
108115
::Zip::File.open_buffer string_io do |zf|
@@ -113,13 +120,14 @@ def test_open_buffer_with_stringio
113120
def test_close_buffer_with_stringio
114121
string_io = StringIO.new File.read('test/data/rubycode.zip')
115122
zf = ::Zip::File.open_buffer string_io
116-
assert(zf.close || true) # Poor man's refute_raises
123+
assert_nil zf.close
117124
end
118125

119126
def test_close_buffer_with_io
120127
f = File.open('test/data/rubycode.zip')
121128
zf = ::Zip::File.open_buffer f
122-
assert zf.close
129+
refute zf.commit_required?
130+
assert_nil zf.close
123131
f.close
124132
end
125133

0 commit comments

Comments
 (0)
0