-
Notifications
You must be signed in to change notification settings - Fork 313
Fix #280 - open_buffer
mangles the content of the buffer it is given.
#360
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
7cd263e
cfa9441
0363393
15ccc25
84c2089
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -64,24 +64,38 @@ class File < CentralDirectory | |
|
||
# Opens a zip archive. Pass true as the second parameter to create | ||
# a new archive if it doesn't exist already. | ||
def initialize(file_name, create = false, buffer = false, options = {}) | ||
def initialize(path_or_io, create = false, buffer = false, options = {}) | ||
super() | ||
@name = file_name | ||
@name = path_or_io.respond_to?(:path) ? path_or_io.path : path_or_io | ||
@comment = '' | ||
@create = create ? true : false # allow any truthy value to mean true | ||
if !buffer && ::File.size?(file_name) | ||
|
||
if ::File.size?(@name.to_s) | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. If |
||
# There is a file, which exists, that is associated with this zip. | ||
@create = false | ||
@file_permissions = ::File.stat(file_name).mode | ||
::File.open(name, 'rb') do |f| | ||
read_from_stream(f) | ||
@file_permissions = ::File.stat(@name).mode | ||
|
||
if buffer | ||
read_from_stream(path_or_io) | ||
else | ||
::File.open(@name, 'rb') do |f| | ||
read_from_stream(f) | ||
end | ||
end | ||
elsif buffer && path_or_io.size > 0 | ||
# This zip is probably a non-empty StringIO. | ||
read_from_stream(path_or_io) | ||
elsif @create | ||
# This zip is completely new/empty and is to be created. | ||
@entry_set = EntrySet.new | ||
elsif ::File.zero?(file_name) | ||
raise Error, "File #{file_name} has zero size. Did you mean to pass the create flag?" | ||
elsif ::File.zero?(@name) | ||
# A file exists, but it is empty. | ||
raise Error, "File #{@name} has zero size. Did you mean to pass the create flag?" | ||
else | ||
raise Error, "File #{file_name} not found" | ||
# Everything is wrong. | ||
raise Error, "File #{@name} not found" | ||
end | ||
|
||
@stored_entries = @entry_set.dup | ||
@stored_comment = @comment | ||
@restore_ownership = options[:restore_ownership] || false | ||
|
@@ -119,17 +133,16 @@ def open_buffer(io, options = {}) | |
unless IO_METHODS.map { |method| io.respond_to?(method) }.all? || io.is_a?(String) | ||
raise "Zip::File.open_buffer expects a String or IO-like argument (responds to #{IO_METHODS.join(', ')}). Found: #{io.class}" | ||
end | ||
if io.is_a?(::String) | ||
require 'stringio' | ||
io = ::StringIO.new(io) | ||
elsif io.respond_to?(:binmode) | ||
# https://github.com/rubyzip/rubyzip/issues/119 | ||
io.binmode | ||
end | ||
|
||
io = ::StringIO.new(io) if io.is_a?(::String) | ||
|
||
# https://github.com/rubyzip/rubyzip/issues/119 | ||
io.binmode if io.respond_to?(:binmode) | ||
|
||
zf = ::Zip::File.new(io, true, true, options) | ||
zf.read_from_stream(io) | ||
return zf unless block_given? | ||
yield zf | ||
|
||
begin | ||
zf.write_buffer(io) | ||
rescue IOError => e | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -97,6 +97,13 @@ def test_get_output_stream | |
end | ||
end | ||
|
||
def test_open_buffer_with_string | ||
string = File.read('test/data/rubycode.zip') | ||
::Zip::File.open_buffer string do |zf| | ||
assert zf.entries.map { |e| e.name }.include?('zippedruby1.rb') | ||
end | ||
end | ||
|
||
def test_open_buffer_with_stringio | ||
string_io = StringIO.new File.read('test/data/rubycode.zip') | ||
::Zip::File.open_buffer string_io do |zf| | ||
|
@@ -107,13 +114,14 @@ def test_open_buffer_with_stringio | |
def test_close_buffer_with_stringio | ||
string_io = StringIO.new File.read('test/data/rubycode.zip') | ||
zf = ::Zip::File.open_buffer string_io | ||
assert(zf.close || true) # Poor man's refute_raises | ||
assert_nil zf.close | ||
end | ||
|
||
def test_close_buffer_with_io | ||
f = File.open('test/data/rubycode.zip') | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. |
||
zf = ::Zip::File.open_buffer f | ||
assert zf.close | ||
refute zf.commit_required? | ||
assert_nil zf.close | ||
f.close | ||
end | ||
|
||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think this is good... but it seems a bit optional. Was it aimed at solving a particular problem?