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
open_buffer
mangles the content of the buffer it is given.
#280
Comments
Using the first code What you are missing is you forgot the buf.freeze in the first code. if you add that in and do
|
The reason for the increased amount of file size is due to the fact that sending just nil also sends the instance variables of nil while sending nil.freeze sends just the object, and since the object is nothing it doesn't increase the size of the file. |
@seth-at-at: According to the documentation:
It does not say anything about modifying the source data. When you read something from a magazine, you do not expect the letters to disappear as you read them, or for the magazine to become crumbled or dirty; when I open a magazine and read from it, I expect to be able to put it down (after I'm done reading) in the original condition (so my wife can pick it up and read it as if it was never touched). When I read things from a zip file, I do not expect the file to be altered in any way, either; I expect to also be able to "put it down" in the original condition. Whatever is happening in My point about |
This is replicated in RuyZip's own tests, here: https://github.com/rubyzip/rubyzip/blob/master/test/file_test.rb#L113 def test_close_buffer_with_io
f = File.open('test/data/rubycode.zip')
zf = ::Zip::File.open_buffer f
assert zf.close
f.close
end The file is simply opened and closed, but the file changes - it is listed as modified by I really don't think this should happen. I am trying to work out what is going on and will submit a PR if I manage to figure it out. |
I think I figured it out and was able to fix this in #360. More testing by others would be appreciated. |
In the course of looking at this, I wrote a small utility to see why the zip file was changing when it was rewritten. Not all zip files change when rubyzip rewrites them, so we were a bit lucky to have the
For want of a better place to put that utility, I'll put it here: require 'pp'
STDIN.binmode
LOCAL_FILE_HEADER_SIGNATURE = 0x04034b50
CENTRAL_DIRECTORY_FILE_HEADER_SIGNATURE = 0x02014b50
loop do
signature, = STDIN.read(4).unpack('L')
case signature
when LOCAL_FILE_HEADER_SIGNATURE
# keep going
when CENTRAL_DIRECTORY_FILE_HEADER_SIGNATURE
break
else
raise "bad signature #{signature.to_s(16)}"
end
header = STDIN.read(26)
version_needed_to_extract,
general_purpose_bit_flag,
compression_method,
last_mod_file_time,
last_mod_file_date,
crc32,
compressed_size,
uncompressed_size,
file_name_length,
extra_field_length = header.unpack('SSSSSLLLSS')
file_name = STDIN.read(file_name_length) if file_name_length > 0
extra_fields = []
total_size = 0
while total_size < extra_field_length
tag, size = STDIN.read(4).unpack('SS')
extra_fields << {
tag: tag.to_s(16),
size: size,
data: STDIN.read(size)
}
total_size += 4 + size
end
raise 'bad extra field size' if total_size != extra_field_length
_payload = STDIN.read(compressed_size)
pp(
version_needed_to_extract: version_needed_to_extract,
general_purpose_bit_flag: general_purpose_bit_flag,
compression_method: compression_method,
last_mod_file_time: last_mod_file_time,
last_mod_file_date: last_mod_file_date,
crc32: crc32,
compressed_size: compressed_size,
uncompressed_size: uncompressed_size,
file_name: file_name,
extra_fields: extra_fields
)
end |
Allegedly this has started happening again, see the report |
Thanks for fowading the issue. ReproductionThis is the reproduction. $ echo "This is a test file." > test.txt
$ zip test.zip test.txt
updating: test.txt (stored 0%)
$ gem list | grep rubyzip
rubyzip (2.3.2)
$ irb
irb(main):001> require 'zip'
irb(main):002> buffer = File.read('./test.zip')
irb(main):003> buffer.size
=> 187
irb(main):004> Zip::File.open_buffer(buffer) { |b| nil } # do nothing
irb(main):005> buffer.size
=> 208 # changed CauseI think the cause is here. Line 122 in 73c8e11
Looking back at history, it appears that in the initilal implementation Solution suggestionIf the above is indeed a problem, how about the following solutions? I would like to send a PR if necessary.
|
Oh goodness me I fixed this over 2 years ago in trunk (14b63f6)... I will backport the fix to the 2.x branch and try and release 2.4 ASAP. Thanks for the heads-up that this is still an issue. And sorry it's still causing problems. (I will reopen this issue for now to track.) |
I've pushed 2.4.rc1 to rubygems with this fix included. Please test it if you can. |
Thank you for replying and quick fix !! Looks good in my tests. $ echo "This is a test file." > test.txt
$ zip test.zip test.txt
updating: test.txt (stored 0%)
$ gem list | grep rubyzip
rubyzip (2.4.rc1, 2.3.2)
$ irb
irb(main):001> require 'zip'
irb(main):002> buffer = File.read('./test.zip')
irb(main):003> buffer.size
=> 187
irb(main):004> Zip::File.open_buffer(buffer) { |b| nil } # do nothing
irb(main):005> buffer.size
=> 187 # same size !
irb(main):006> buffer2 = File.read('./test.zip')
irb(main):007> buffer.bytes == buffer2.bytes
=> true # same ! |
Here, you can use absolutely any ZIP file for
test.zip
:Note that
after.zip
differs frombefore.zip
, despite the fact that there's absolutely no reason to be changed.However, if you do:
then everything works perfectly,
buf
is not damaged and nothing crashes.The text was updated successfully, but these errors were encountered: