Skip to content
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

Fix #280 - open_buffer mangles the content of the buffer it is given. #360

Merged
merged 5 commits into from Sep 5, 2019

Conversation

hainesr
Copy link
Member

@hainesr hainesr commented Apr 4, 2018

Things are now more carefully set up, and if a buffer is passed in which represents a file that already exists then this is taken into account. All initialization is now done in File.new, rather than being split between there and File.open_buffer.

This has also needed a bit of a re-write of Zip::File.initialize. I've tried to bring some logic to it as a result, and have added comments to explain what is now happening.

This PR includes some other related fixes too. All tests pass.

This now actually extracts the path from the IO if one is passed in.
Things are now more carefully set up, and if a buffer is passed in which
represents a file that already exists then this is taken into account. All
initialization is now done in File.new, rather than being split between there
and File.open_buffer.

This has also needed a bit of a re-write of Zip::File.initialize. I've tried to
bring some logic to it as a result, and have added comments to explain what is
now happening.
StringIO objects created within File.open_buffer were not being switched into
binmode, but those passed in were. Fix this inconsistency and add a test.
@coveralls
Copy link

coveralls commented Apr 4, 2018

Coverage Status

Coverage decreased (-0.1%) to 96.422% when pulling 84c2089 on hainesr:fix-open-buffer into 05af123 on rubyzip:master.

Copy link
Member

@jdleesmiller jdleesmiller left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for putting this together. It looks good, and there are several open tickets about this method, so it's probably worth fixing, but I have a few questions.

Overall, this open_buffer method seems a bit confusing. It seems to have started its life as a way of handling in-memory zip files #49 but has grown in scope to accept arbitrary IOs. This makes the name a bit confusing IMHO (is it still opening a buffer if you pass a file IO?). It looks like InputStream handles IOs through open/new:

def initialize(context, offset = 0, decrypter = nil)
super()
@archive_io = get_io(context, offset)

def open(filename_or_io, offset = 0, decrypter = nil)
zio = new(filename_or_io, offset, decrypter)

and does the file / IO detection in new. This interface seems a bit inconsistent (which happened before this PR). Whether there is a way of doing the same thing here without breaking compatibility with what's already there, I am not yet sure.

I'll leave this open for comment for another week or so (or whenever I get some time to come back to it). If I don't hear back, I'll probably merge it and then do another PR to see if I can tweak it.

@comment = ''
@create = create ? true : false # allow any truthy value to mean true
if !buffer && ::File.size?(file_name)

if ::File.size?(@name.to_s)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If @name is a StringIO, @name.to_s will return something like "#<StringIO:0x00007f98b09766c0>". It's unlikely that such a file exists, of course, but hitting the file system to find this out seems a bit odd. Could it be reorganised to not check the file system at all when buffer is true?

@@ -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')
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Note: this is similar (but not identical) to the test cases in #146 and #192, so they can probably be closed once we sort this out.

super()
@name = file_name
@name = path_or_io.respond_to?(:path) ? path_or_io.path : path_or_io
Copy link
Member

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?

@hainesr
Copy link
Member Author

hainesr commented May 25, 2019

Thanks for picking this up! It's been a while since I looked at this, but I'll try and find time to get it all back in my head and respond properly soon. As I remember it though, it turned into one of those problems that uncovered all sorts of other problems, and was originally a piece of code that was rather unclear as to what was going on 😬

@jdleesmiller
Copy link
Member

I reviewed this again today, and I think it is good to merge. Thanks again for the fix.

@jdleesmiller jdleesmiller merged commit 7fbaf1e into rubyzip:master Sep 5, 2019
@hainesr
Copy link
Member Author

hainesr commented Sep 5, 2019

Sorry for not getting round to looking at it again myself; a change of role at work has left little time for extra-curricular coding recently, but I hope to get back into it again soon.

Thanks for merging, and thanks for picking up maintaining this gem @jdleesmiller.

@hainesr hainesr deleted the fix-open-buffer branch September 5, 2019 18:43
@jdleesmiller
Copy link
Member

Definitely get that :) I was able to progress this mainly because we had a hackathon day at my company, Overleaf. I will work it up into a new release.

@hainesr
Copy link
Member Author

hainesr commented Sep 8, 2019

Oh cool. I'm a big fan of Overleaf!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

3 participants