My project was using zipruby but I need to include a gem which is dependent on rubyzip. Since these two gems gives conflict errors, I decided to switch to rubyzip and in the process for migrating. I was able to handle every other case except the one where I need to use encryption on zip.
Using rubyzip 2.3.2
code with zipruby:
Zip::Archive.open(<zip-file-name>, Zip::CREATE) do |z|
<list-of-strings>.each_with_index do |check, i|
z.add_buffer 'r_%02d' % i, check
end
end
Zip::Archive.encrypt(<zip-file-name>, <password-string>)
And I tried replacing it with:
buffer = Zip::OutputStream.write_buffer(::StringIO.new(''), Zip::TraditionalEncrypter.new(<password-string>)) do |output|
<list-of-strings>.each_with_index do |check, i|
output.put_next_entry('r_%02d' % i)
output.write(check)
end
end
File.open(<zip-file-name>, 'wb') {|f| f.write(buffer.string) }
But for this new code, the code fails at line output.put_next_entry('r_%02d' % i)
with error IOError: not opened for writing
Can somebody help with what I am doing wrong with code or is there a way to fix it.
Backtrace for reference:
entry.rb 304 write(...)
[GEM_ROOT]/gems/rubyzip-2.3.2/lib/zip/entry.rb:304:in `write'
entry.rb 304 <<(...)
[GEM_ROOT]/gems/rubyzip-2.3.2/lib/zip/entry.rb:304:in `<<'
entry.rb 304 write_local_entry(...)
[GEM_ROOT]/gems/rubyzip-2.3.2/lib/zip/entry.rb:304:in `write_local_entry'
output_stream.rb 148 init_next_entry(...)
[GEM_ROOT]/gems/rubyzip-2.3.2/lib/zip/output_stream.rb:148:in `init_next_entry'
output_stream.rb 105 put_next_entry(...)
[GEM_ROOT]/gems/rubyzip-2.3.2/lib/zip/output_stream.rb:105:in `put_next_entry'
Found the fix. My file had the comment # frozen_string_literal: true
which was causing this.
It got fixed by using following code instead:
buffer = Zip::OutputStream.write_buffer(::StringIO.new((+'')), Zip::TraditionalEncrypter.new(<password-string>)) do |output|
<list-of-strings>.each_with_index do |check, i|
output.put_next_entry('r_%02d' % i)
output.write(check)
end
end
File.open(<zip-file-name>, 'wb') {|f| f.write(buffer.string) }