diff -Nru ruby-zip-2.0.0/bin/console ruby-zip-2.3.0/bin/console --- ruby-zip-2.0.0/bin/console 1970-01-01 00:00:00.000000000 +0000 +++ ruby-zip-2.3.0/bin/console 2020-03-14 12:00:50.000000000 +0000 @@ -0,0 +1,7 @@ +#!/usr/bin/env ruby + +require 'bundler/setup' +require 'zip' + +require 'irb' +IRB.start(__FILE__) diff -Nru ruby-zip-2.0.0/Changelog.md ruby-zip-2.3.0/Changelog.md --- ruby-zip-2.0.0/Changelog.md 2019-09-25 20:23:47.000000000 +0000 +++ ruby-zip-2.3.0/Changelog.md 2020-03-14 12:00:50.000000000 +0000 @@ -1,13 +1,42 @@ # X.X.X (Next) -- +# 2.3.0 (2020-03-14) + +- Fix frozen string literal error [#431](https://github.com/rubyzip/rubyzip/pull/431) +- Set `OutputStream.write_buffer`'s buffer to binmode [#439](https://github.com/rubyzip/rubyzip/pull/439) +- Upgrade rubocop and fix various linting complaints [#437](https://github.com/rubyzip/rubyzip/pull/437) [#440](https://github.com/rubyzip/rubyzip/pull/440) + +Tooling: + +- Add a `bin/console` script for development [#420](https://github.com/rubyzip/rubyzip/pull/420) +- Update rake requirement (development dependency only) to fix a security alert. + +# 2.2.0 (2020-02-01) + +- Add support for decompression plugin gems [#427](https://github.com/rubyzip/rubyzip/pull/427) + +# 2.1.0 (2020-01-25) + +- Fix (at least partially) the `restore_times` and `restore_permissions` options to `Zip::File.new` [#413](https://github.com/rubyzip/rubyzip/pull/413) + - Previously, neither option did anything, regardless of what it was set to. We have therefore defaulted them to `false` to preserve the current behavior, for the time being. If you have explicitly set either to `true`, it will now have an effect. + - Fix handling of UniversalTime (`mtime`, `atime`, `ctime`) fields. [#421](https://github.com/rubyzip/rubyzip/pull/421) + - Previously, `Zip::File` did not pass the options to `Zip::Entry` in some cases. [#423](https://github.com/rubyzip/rubyzip/pull/423) + - Note that `restore_times` in this release does nothing on Windows and only restores `mtime`, not `atime` or `ctime`. +- Allow `Zip::File.open` to take an options hash like `Zip::File.new` [#418](https://github.com/rubyzip/rubyzip/pull/418) +- Always print warnings with `warn`, instead of a mix of `puts` and `warn` [#416](https://github.com/rubyzip/rubyzip/pull/416) +- Create temporary files in the system temporary directory instead of the directory of the zip file [#411](https://github.com/rubyzip/rubyzip/pull/411) +- Drop unused `tmpdir` requirement [#411](https://github.com/rubyzip/rubyzip/pull/411) + +Tooling + +- Move CI to xenial and include jruby on JDK11 [#419](https://github.com/rubyzip/rubyzip/pull/419/files) # 2.0.0 (2019-09-25) Security - Default the `validate_entry_sizes` option to `true`, so that callers can trust an entry's reported size when using `extract` [#403](https://github.com/rubyzip/rubyzip/pull/403) - - This option defaulted to `false` in 1.3.0 for backward compatibility, but it now defaults to `true`. If you are using an older version of ruby and can't yet upgrade to 2.x, you can still use 1.3.0 and set the option to `true`. + - This option defaulted to `false` in 1.3.0 for backward compatibility, but it now defaults to `true`. If you are using an older version of ruby and can't yet upgrade to 2.x, you can still use 1.3.0 and set the option to `true`. Tooling / Documentation @@ -19,7 +48,7 @@ Security - Add `validate_entry_sizes` option so that callers can trust an entry's reported size when using `extract` [#403](https://github.com/rubyzip/rubyzip/pull/403) - - This option defaults to `false` for backward compatibility in this release, but you are strongly encouraged to set it to `true`. It will default to `true` in rubyzip 2.0. + - This option defaults to `false` for backward compatibility in this release, but you are strongly encouraged to set it to `true`. It will default to `true` in rubyzip 2.0. New Feature diff -Nru ruby-zip-2.0.0/debian/changelog ruby-zip-2.3.0/debian/changelog --- ruby-zip-2.0.0/debian/changelog 2020-03-25 18:10:26.000000000 +0000 +++ ruby-zip-2.3.0/debian/changelog 2022-01-22 19:25:21.000000000 +0000 @@ -1,3 +1,28 @@ +ruby-zip (2.3.0-2) unstable; urgency=medium + + * Switch to gem-install layout (bundler need this for --local option now) + * Bump Standards-Version to 4.6.0 (no changes needed) + * Update watch file standard to 4 + + -- Pirate Praveen Sun, 23 Jan 2022 00:55:21 +0530 + +ruby-zip (2.3.0-1) experimental; urgency=medium + + [ Cédric Boutillier ] + * Update team name + * Add .gitattributes to keep unwanted files out of the source package + + [ Debian Janitor ] + * Apply multi-arch hints. + ruby-zip: Add Multi-Arch: foreign. + + [ Pirate Praveen ] + * New upstream version 2.3.0 + * Bump Standards-Version to 4.5.1 (no changes needed) + * Bump debhelper compatibility level to 13 + * Drop /usr/bin/console from binary package + + -- Pirate Praveen Sat, 26 Jun 2021 01:26:59 +0530 + ruby-zip (2.0.0-2) unstable; urgency=medium * Team upload. diff -Nru ruby-zip-2.0.0/debian/control ruby-zip-2.3.0/debian/control --- ruby-zip-2.0.0/debian/control 2020-03-25 18:10:26.000000000 +0000 +++ ruby-zip-2.3.0/debian/control 2022-01-22 19:25:21.000000000 +0000 @@ -1,17 +1,17 @@ Source: ruby-zip Section: ruby Priority: optional -Maintainer: Debian Ruby Extras Maintainers +Maintainer: Debian Ruby Team Uploaders: Pirate Praveen , David Suárez -Build-Depends: debhelper-compat (= 12), +Build-Depends: debhelper-compat (= 13), gem2deb, rake, ruby-minitest, unzip, zip, ruby-simplecov -Standards-Version: 4.5.0 +Standards-Version: 4.6.0 Homepage: https://github.com/rubyzip/rubyzip Vcs-Git: https://salsa.debian.org/ruby-team/ruby-zip.git Vcs-Browser: https://salsa.debian.org/ruby-team/ruby-zip @@ -26,6 +26,7 @@ zip, ${misc:Depends}, ${shlibs:Depends} +Multi-Arch: foreign Description: Ruby module for reading and writing zip files rubyzip is a ruby library for reading and writing zip (pkzip format) files, with the restriction that only uncompressed and deflated zip diff -Nru ruby-zip-2.0.0/debian/rules ruby-zip-2.3.0/debian/rules --- ruby-zip-2.0.0/debian/rules 2020-03-25 18:10:26.000000000 +0000 +++ ruby-zip-2.3.0/debian/rules 2022-01-22 19:25:21.000000000 +0000 @@ -1,17 +1,8 @@ #!/usr/bin/make -f -#export DH_VERBOSE=1 -# -# Uncomment to ignore all test failures (but the tests will run anyway) -#export DH_RUBY_IGNORE_TESTS=all -# -# Uncomment to ignore some test failures (but the tests will run anyway). -# Valid values: -#export DH_RUBY_IGNORE_TESTS=ruby1.8 ruby1.9.1 require-rubygems -# -# If you need to specify the .gemspec (eg there is more than one) -#export DH_RUBY_GEMSPEC=gem.gemspec -export LANG=C.UTF-8 +export GEM2DEB_TEST_RUNNER = --check-dependencies +export DH_RUBY = --gem-install +export LANG = C.UTF-8 %: dh $@ --buildsystem=ruby --with ruby @@ -24,3 +15,7 @@ $(RM) *.zip $(RM) extEntry $(RM) -Rf emptyOutDir + +override_dh_auto_install: + dh_auto_install + rm -rf debian/ruby-zip/usr/bin diff -Nru ruby-zip-2.0.0/debian/salsa-ci.yml ruby-zip-2.3.0/debian/salsa-ci.yml --- ruby-zip-2.0.0/debian/salsa-ci.yml 2020-03-25 18:10:26.000000000 +0000 +++ ruby-zip-2.3.0/debian/salsa-ci.yml 1970-01-01 00:00:00.000000000 +0000 @@ -1,4 +0,0 @@ ---- -include: - - https://salsa.debian.org/salsa-ci-team/pipeline/raw/master/salsa-ci.yml - - https://salsa.debian.org/salsa-ci-team/pipeline/raw/master/pipeline-jobs.yml diff -Nru ruby-zip-2.0.0/debian/watch ruby-zip-2.3.0/debian/watch --- ruby-zip-2.0.0/debian/watch 2020-03-25 18:10:26.000000000 +0000 +++ ruby-zip-2.3.0/debian/watch 2022-01-22 19:25:21.000000000 +0000 @@ -1,7 +1,5 @@ # watch control file for uscan -version=3 - -#http://pkg-ruby-extras.alioth.debian.org/cgi-bin/gemwatch/rubyzip .*/rubyzip-(.*).tar.gz +version=4 # gem releases doesn't contains tests files, use github instead opts=filenamemangle=s/.+\/v?(\d\S*)\.tar\.gz/ruby-zip-$1\.tar\.gz/ \ diff -Nru ruby-zip-2.0.0/lib/zip/central_directory.rb ruby-zip-2.3.0/lib/zip/central_directory.rb --- ruby-zip-2.0.0/lib/zip/central_directory.rb 2019-09-25 20:23:47.000000000 +0000 +++ ruby-zip-2.3.0/lib/zip/central_directory.rb 2020-03-14 12:00:50.000000000 +0000 @@ -65,7 +65,7 @@ @entry_set ? @entry_set.size : 0, # number of entries on this disk @entry_set ? @entry_set.size : 0, # number of entries total cdir_size, # size of central directory - offset, # offset of start of central directory in its disk + offset # offset of start of central directory in its disk ] io << tmp.pack('VQ 'Mac OS/X (Darwin)'.freeze, FSTYPE_ATHEOS => 'AtheOS'.freeze }.freeze + + COMPRESSION_METHOD_STORE = 0 + COMPRESSION_METHOD_SHRINK = 1 + COMPRESSION_METHOD_REDUCE_1 = 2 + COMPRESSION_METHOD_REDUCE_2 = 3 + COMPRESSION_METHOD_REDUCE_3 = 4 + COMPRESSION_METHOD_REDUCE_4 = 5 + COMPRESSION_METHOD_IMPLODE = 6 + # RESERVED = 7 + COMPRESSION_METHOD_DEFLATE = 8 + COMPRESSION_METHOD_DEFLATE_64 = 9 + COMPRESSION_METHOD_PKWARE_DCLI = 10 + # RESERVED = 11 + COMPRESSION_METHOD_BZIP2 = 12 + # RESERVED = 13 + COMPRESSION_METHOD_LZMA = 14 + # RESERVED = 15 + COMPRESSION_METHOD_IBM_CMPSC = 16 + # RESERVED = 17 + COMPRESSION_METHOD_IBM_TERSE = 18 + COMPRESSION_METHOD_IBM_LZ77 = 19 + COMPRESSION_METHOD_JPEG = 96 + COMPRESSION_METHOD_WAVPACK = 97 + COMPRESSION_METHOD_PPMD = 98 + COMPRESSION_METHOD_AES = 99 + + COMPRESSION_METHODS = { + COMPRESSION_METHOD_STORE => 'Store (no compression)', + COMPRESSION_METHOD_SHRINK => 'Shrink', + COMPRESSION_METHOD_REDUCE_1 => 'Reduce with compression factor 1', + COMPRESSION_METHOD_REDUCE_2 => 'Reduce with compression factor 2', + COMPRESSION_METHOD_REDUCE_3 => 'Reduce with compression factor 3', + COMPRESSION_METHOD_REDUCE_4 => 'Reduce with compression factor 4', + COMPRESSION_METHOD_IMPLODE => 'Implode', + # RESERVED = 7 + COMPRESSION_METHOD_DEFLATE => 'Deflate', + COMPRESSION_METHOD_DEFLATE_64 => 'Deflate64(tm)', + COMPRESSION_METHOD_PKWARE_DCLI => 'PKWARE Data Compression Library Imploding (old IBM TERSE)', + # RESERVED = 11 + COMPRESSION_METHOD_BZIP2 => 'BZIP2', + # RESERVED = 13 + COMPRESSION_METHOD_LZMA => 'LZMA', + # RESERVED = 15 + COMPRESSION_METHOD_IBM_CMPSC => 'IBM z/OS CMPSC Compression', + # RESERVED = 17 + COMPRESSION_METHOD_IBM_TERSE => 'IBM TERSE (new)', + COMPRESSION_METHOD_IBM_LZ77 => 'IBM LZ77 z Architecture (PFS)', + COMPRESSION_METHOD_JPEG => 'JPEG variant', + COMPRESSION_METHOD_WAVPACK => 'WavPack compressed data', + COMPRESSION_METHOD_PPMD => 'PPMd version I, Rev 1', + COMPRESSION_METHOD_AES => 'AES encryption' + }.freeze end diff -Nru ruby-zip-2.0.0/lib/zip/crypto/decrypted_io.rb ruby-zip-2.3.0/lib/zip/crypto/decrypted_io.rb --- ruby-zip-2.0.0/lib/zip/crypto/decrypted_io.rb 1970-01-01 00:00:00.000000000 +0000 +++ ruby-zip-2.3.0/lib/zip/crypto/decrypted_io.rb 2020-03-14 12:00:50.000000000 +0000 @@ -0,0 +1,40 @@ +module Zip + class DecryptedIo #:nodoc:all + CHUNK_SIZE = 32_768 + + def initialize(io, decrypter) + @io = io + @decrypter = decrypter + end + + def read(length = nil, outbuf = +'') + return (length.nil? || length.zero? ? '' : nil) if eof + + while length.nil? || (buffer.bytesize < length) + break if input_finished? + + buffer << produce_input + end + + outbuf.replace(buffer.slice!(0...(length || output_buffer.bytesize))) + end + + private + + def eof + buffer.empty? && input_finished? + end + + def buffer + @buffer ||= +'' + end + + def input_finished? + @io.eof + end + + def produce_input + @decrypter.decrypt(@io.read(CHUNK_SIZE)) + end + end +end diff -Nru ruby-zip-2.0.0/lib/zip/crypto/traditional_encryption.rb ruby-zip-2.3.0/lib/zip/crypto/traditional_encryption.rb --- ruby-zip-2.0.0/lib/zip/crypto/traditional_encryption.rb 2019-09-25 20:23:47.000000000 +0000 +++ ruby-zip-2.3.0/lib/zip/crypto/traditional_encryption.rb 2020-03-14 12:00:50.000000000 +0000 @@ -24,8 +24,8 @@ end end - def update_keys(n) - @key0 = ~Zlib.crc32(n, ~@key0) + def update_keys(num) + @key0 = ~Zlib.crc32(num, ~@key0) @key1 = ((@key1 + (@key0 & 0xff)) * 134_775_813 + 1) & 0xffffffff @key2 = ~Zlib.crc32((@key1 >> 24).chr, ~@key2) end @@ -63,10 +63,10 @@ private - def encode(n) + def encode(num) t = decrypt_byte - update_keys(n.chr) - t ^ n + update_keys(num.chr) + t ^ num end end @@ -86,10 +86,10 @@ private - def decode(n) - n ^= decrypt_byte - update_keys(n.chr) - n + def decode(num) + num ^= decrypt_byte + update_keys(num.chr) + num end end end diff -Nru ruby-zip-2.0.0/lib/zip/decompressor.rb ruby-zip-2.3.0/lib/zip/decompressor.rb --- ruby-zip-2.0.0/lib/zip/decompressor.rb 2019-09-25 20:23:47.000000000 +0000 +++ ruby-zip-2.3.0/lib/zip/decompressor.rb 2020-03-14 12:00:50.000000000 +0000 @@ -1,9 +1,27 @@ module Zip class Decompressor #:nodoc:all CHUNK_SIZE = 32_768 - def initialize(input_stream) + + def self.decompressor_classes + @decompressor_classes ||= {} + end + + def self.register(compression_method, decompressor_class) + decompressor_classes[compression_method] = decompressor_class + end + + def self.find_by_compression_method(compression_method) + decompressor_classes[compression_method] + end + + attr_reader :input_stream + attr_reader :decompressed_size + + def initialize(input_stream, decompressed_size = nil) super() + @input_stream = input_stream + @decompressed_size = decompressed_size end end end diff -Nru ruby-zip-2.0.0/lib/zip/dos_time.rb ruby-zip-2.3.0/lib/zip/dos_time.rb --- ruby-zip-2.0.0/lib/zip/dos_time.rb 2019-09-25 20:23:47.000000000 +0000 +++ ruby-zip-2.3.0/lib/zip/dos_time.rb 2020-03-14 12:00:50.000000000 +0000 @@ -29,13 +29,18 @@ to_i / 2 == other.to_i / 2 end - def self.parse_binary_dos_format(binaryDosDate, binaryDosTime) - second = 2 * (0b11111 & binaryDosTime) - minute = (0b11111100000 & binaryDosTime) >> 5 - hour = (0b1111100000000000 & binaryDosTime) >> 11 - day = (0b11111 & binaryDosDate) - month = (0b111100000 & binaryDosDate) >> 5 - year = ((0b1111111000000000 & binaryDosDate) >> 9) + 1980 + # Create a DOSTime instance from a vanilla Time instance. + def self.from_time(time) + local(time.year, time.month, time.day, time.hour, time.min, time.sec) + end + + def self.parse_binary_dos_format(bin_dos_date, bin_dos_time) + second = 2 * (0b11111 & bin_dos_time) + minute = (0b11111100000 & bin_dos_time) >> 5 + hour = (0b1111100000000000 & bin_dos_time) >> 11 + day = (0b11111 & bin_dos_date) + month = (0b111100000 & bin_dos_date) >> 5 + year = ((0b1111111000000000 & bin_dos_date) >> 9) + 1980 begin local(year, month, day, hour, minute, second) end diff -Nru ruby-zip-2.0.0/lib/zip/entry.rb ruby-zip-2.3.0/lib/zip/entry.rb --- ruby-zip-2.0.0/lib/zip/entry.rb 2019-09-25 20:23:47.000000000 +0000 +++ ruby-zip-2.3.0/lib/zip/entry.rb 2020-03-14 12:00:50.000000000 +0000 @@ -34,7 +34,7 @@ end @follow_symlinks = false - @restore_times = true + @restore_times = false @restore_permissions = false @restore_ownership = false # BUG: need an extra field to support uid/gid's @@ -48,6 +48,7 @@ def check_name(name) return unless name.start_with?('/') + raise ::Zip::EntryNameError, "Illegal ZipEntry name '#{name}', name must not start with /" end @@ -69,7 +70,15 @@ @time = args[8] || ::Zip::DOSTime.now @ftype = name_is_directory? ? :directory : :file - @extra = ::Zip::ExtraField.new(@extra.to_s) unless @extra.is_a?(::Zip::ExtraField) + @extra = ::Zip::ExtraField.new(@extra.to_s) unless @extra.kind_of?(::Zip::ExtraField) + end + + def encrypted? + gp_flags & 1 == 1 + end + + def incomplete? + gp_flags & 8 == 8 end def time @@ -91,11 +100,12 @@ @extra.create('UniversalTime') end (@extra['UniversalTime'] || @extra['NTFS']).mtime = value - @time = value + @time = value end def file_type_is?(type) raise InternalError, "current filetype is unknown: #{inspect}" unless @ftype + @ftype == type end @@ -116,6 +126,7 @@ def name_safe? cleanpath = Pathname.new(@name).cleanpath return false unless cleanpath.relative? + root = ::File::SEPARATOR naive_expanded_path = ::File.join(root, cleanpath.to_s) ::File.absolute_path(cleanpath.to_s, root) == naive_expanded_path @@ -145,6 +156,7 @@ # that we didn't change the header size (and thus clobber file data or something) def verify_local_header_size! return if @local_header_size.nil? + new_size = calculate_local_header_size raise Error, "local header size changed (#{@local_header_size} -> #{new_size})" if @local_header_size != new_size end @@ -163,19 +175,16 @@ # is passed. def extract(dest_path = nil, &block) if dest_path.nil? && !name_safe? - puts "WARNING: skipped #{@name} as unsafe" + warn "WARNING: skipped '#{@name}' as unsafe." return self end dest_path ||= @name block ||= proc { ::Zip.on_exists_proc } - if directory? || file? || symlink? - __send__("create_#{@ftype}", dest_path, &block) - else - raise "unknown file type #{inspect}" - end + raise "unknown file type #{inspect}" unless directory? || file? || symlink? + __send__("create_#{@ftype}", dest_path, &block) self end @@ -185,15 +194,15 @@ class << self def read_zip_short(io) # :nodoc: - io.read(2).unpack('v')[0] + io.read(2).unpack1('v') end def read_zip_long(io) # :nodoc: - io.read(4).unpack('V')[0] + io.read(4).unpack1('V') end def read_zip_64_long(io) # :nodoc: - io.read(8).unpack('Q<')[0] + io.read(8).unpack1('Q<') end def read_c_dir_entry(io) #:nodoc:all @@ -218,8 +227,6 @@ end end - public - def unpack_local_entry(buf) @header_signature, @version, @@ -249,6 +256,7 @@ unless @header_signature == ::Zip::LOCAL_ENTRY_SIGNATURE raise ::Zip::Error, "Zip local header magic not found at location '#{local_header_offset}'" end + set_time(@last_mod_date, @last_mod_time) @name = io.read(@name_length) @@ -261,13 +269,14 @@ if extra && extra.bytesize != @extra_length raise ::Zip::Error, 'Truncated local zip entry header' + end + + if @extra.kind_of?(::Zip::ExtraField) + @extra.merge(extra) if extra else - if @extra.is_a?(::Zip::ExtraField) - @extra.merge(extra) if extra - else - @extra = ::Zip::ExtraField.new(extra) - end + @extra = ::Zip::ExtraField.new(extra) end + parse_zip64_extra(true) @local_header_size = calculate_local_header_size end @@ -354,21 +363,24 @@ def check_c_dir_entry_static_header_length(buf) return if buf.bytesize == ::Zip::CDIR_ENTRY_STATIC_HEADER_LENGTH + raise Error, 'Premature end of file. Not enough data for zip cdir entry header' end def check_c_dir_entry_signature return if header_signature == ::Zip::CENTRAL_DIRECTORY_ENTRY_SIGNATURE + raise Error, "Zip local header magic not found at location '#{local_header_offset}'" end def check_c_dir_entry_comment_size return if @comment && @comment.bytesize == @comment_length + raise ::Zip::Error, 'Truncated cdir zip entry header' end def read_c_dir_extra_field(io) - if @extra.is_a?(::Zip::ExtraField) + if @extra.kind_of?(::Zip::ExtraField) @extra.merge(io.read(@extra_length)) else @extra = ::Zip::ExtraField.new(io.read(@extra_length)) @@ -402,20 +414,25 @@ def get_extra_attributes_from_path(path) # :nodoc: return if Zip::RUNNING_ON_WINDOWS + stat = file_stat(path) @unix_uid = stat.uid @unix_gid = stat.gid @unix_perms = stat.mode & 0o7777 + @time = ::Zip::DOSTime.from_time(stat.mtime) end - def set_unix_permissions_on_path(dest_path) - # BUG: does not update timestamps into account + def set_unix_attributes_on_path(dest_path) # ignore setuid/setgid bits by default. honor if @restore_ownership unix_perms_mask = 0o1777 unix_perms_mask = 0o7777 if @restore_ownership ::FileUtils.chmod(@unix_perms & unix_perms_mask, dest_path) if @restore_permissions && @unix_perms ::FileUtils.chown(@unix_uid, @unix_gid, dest_path) if @restore_ownership && @unix_uid && @unix_gid && ::Process.egid == 0 - # File::utimes() + + # Restore the timestamp on a file. This will either have come from the + # original source file that was copied into the archive, or from the + # creation date of the archive if there was no original source file. + ::FileUtils.touch(dest_path, mtime: time) if @restore_times end def set_extra_attributes_on_path(dest_path) # :nodoc: @@ -423,7 +440,7 @@ case @fstype when ::Zip::FSTYPE_UNIX - set_unix_permissions_on_path(dest_path) + set_unix_attributes_on_path(dest_path) end end @@ -484,6 +501,7 @@ def ==(other) return false unless other.class == self.class + # Compares contents of local entry and exposed fields keys_equal = %w[compression_method crc compressed_size size name extra filepath].all? do |k| other.__send__(k.to_sym) == __send__(k.to_sym) @@ -591,7 +609,7 @@ def set_time(binary_dos_date, binary_dos_time) @time = ::Zip::DOSTime.parse_binary_dos_format(binary_dos_date, binary_dos_time) rescue ArgumentError - warn 'Invalid date/time in zip entry' if ::Zip.warn_invalid_date + warn 'WARNING: invalid date/time in zip entry.' if ::Zip.warn_invalid_date end def create_file(dest_path, _continue_on_exists_proc = proc { Zip.continue_on_exists_proc }) @@ -601,30 +619,29 @@ end ::File.open(dest_path, 'wb') do |os| get_input_stream do |is| - set_extra_attributes_on_path(dest_path) - bytes_written = 0 warned = false - buf = ''.dup + buf = +'' while (buf = is.sysread(::Zip::Decompressor::CHUNK_SIZE, buf)) os << buf bytes_written += buf.bytesize - if bytes_written > size && !warned - message = "Entry #{name} should be #{size}B but is larger when inflated" - if ::Zip.validate_entry_sizes - raise ::Zip::EntrySizeError, message - else - puts "WARNING: #{message}" - warned = true - end - end + next unless bytes_written > size && !warned + + message = "entry '#{name}' should be #{size}B, but is larger when inflated." + raise ::Zip::EntrySizeError, message if ::Zip.validate_entry_sizes + + warn "WARNING: #{message}" + warned = true end end end + + set_extra_attributes_on_path(dest_path) end def create_directory(dest_path) return if ::File.directory?(dest_path) + if ::File.exist?(dest_path) if block_given? && yield(self, dest_path) ::FileUtils.rm_f dest_path @@ -642,13 +659,14 @@ def create_symlink(dest_path) # TODO: Symlinks pose security challenges. Symlink support temporarily # removed in view of https://github.com/rubyzip/rubyzip/issues/369 . - puts "WARNING: skipped symlink #{dest_path}" + warn "WARNING: skipped symlink '#{dest_path}'." end # apply missing data from the zip64 extra information field, if present # (required when file sizes exceed 2**32, but can be used for all files) def parse_zip64_extra(for_local_header) #:nodoc:all return if @extra['Zip64'].nil? + if for_local_header @size, @compressed_size = @extra['Zip64'].parse(@size, @compressed_size) else @@ -663,6 +681,7 @@ # create a zip64 extra information field if we need one def prep_zip64_extra(for_local_header) #:nodoc:all return unless ::Zip.write_zip64_support + need_zip64 = @size >= 0xFFFFFFFF || @compressed_size >= 0xFFFFFFFF need_zip64 ||= @local_header_offset >= 0xFFFFFFFF unless for_local_header if need_zip64 diff -Nru ruby-zip-2.0.0/lib/zip/entry_set.rb ruby-zip-2.3.0/lib/zip/entry_set.rb --- ruby-zip-2.0.0/lib/zip/entry_set.rb 2019-09-25 20:23:47.000000000 +0000 +++ ruby-zip-2.3.0/lib/zip/entry_set.rb 2020-03-14 12:00:50.000000000 +0000 @@ -50,6 +50,7 @@ def ==(other) return false unless other.kind_of?(EntrySet) + @entry_set.values == other.entry_set.values end @@ -60,6 +61,7 @@ def glob(pattern, flags = ::File::FNM_PATHNAME | ::File::FNM_DOTMATCH | ::File::FNM_EXTGLOB) entries.map do |entry| next nil unless ::File.fnmatch(pattern, entry.name.chomp('/'), flags) + yield(entry) if block_given? entry end.compact diff -Nru ruby-zip-2.0.0/lib/zip/errors.rb ruby-zip-2.3.0/lib/zip/errors.rb --- ruby-zip-2.0.0/lib/zip/errors.rb 2019-09-25 20:23:47.000000000 +0000 +++ ruby-zip-2.3.0/lib/zip/errors.rb 2020-03-14 12:00:50.000000000 +0000 @@ -7,6 +7,7 @@ class EntrySizeError < Error; end class InternalError < Error; end class GPFBit3Error < Error; end + class DecompressionError < Error; end # Backwards compatibility with v1 (delete in v2) ZipError = Error diff -Nru ruby-zip-2.0.0/lib/zip/extra_field/generic.rb ruby-zip-2.3.0/lib/zip/extra_field/generic.rb --- ruby-zip-2.0.0/lib/zip/extra_field/generic.rb 2019-09-25 20:23:47.000000000 +0000 +++ ruby-zip-2.3.0/lib/zip/extra_field/generic.rb 2020-03-14 12:00:50.000000000 +0000 @@ -1,9 +1,9 @@ module Zip class ExtraField::Generic def self.register_map - if const_defined?(:HEADER_ID) - ::Zip::ExtraField::ID_MAP[const_get(:HEADER_ID)] = self - end + return unless const_defined?(:HEADER_ID) + + ::Zip::ExtraField::ID_MAP[const_get(:HEADER_ID)] = self end def self.name @@ -12,18 +12,19 @@ # return field [size, content] or false def initial_parse(binstr) - if !binstr - # If nil, start with empty. - return false - elsif binstr[0, 2] != self.class.const_get(:HEADER_ID) - $stderr.puts 'Warning: weired extra feild header ID. skip parsing' + return false unless binstr + + if binstr[0, 2] != self.class.const_get(:HEADER_ID) + warn 'WARNING: weird extra field header ID. Skip parsing it.' return false end - [binstr[2, 2].unpack('v')[0], binstr[4..-1]] + + [binstr[2, 2].unpack1('v'), binstr[4..-1]] end def ==(other) return false if self.class != other.class + each do |k, v| return false if v != other[k] end diff -Nru ruby-zip-2.0.0/lib/zip/extra_field/ntfs.rb ruby-zip-2.3.0/lib/zip/extra_field/ntfs.rb --- ruby-zip-2.0.0/lib/zip/extra_field/ntfs.rb 2019-09-25 20:23:47.000000000 +0000 +++ ruby-zip-2.3.0/lib/zip/extra_field/ntfs.rb 2020-03-14 12:00:50.000000000 +0000 @@ -19,6 +19,7 @@ def merge(binstr) return if binstr.empty? + size, content = initial_parse(binstr) (size && content) || return @@ -27,6 +28,7 @@ tag1 = tags[1] return unless tag1 + ntfs_mtime, ntfs_atime, ntfs_ctime = tag1.unpack('Q binstr[i..-1].bytesize - self['Unknown'] << binstr[i..-1] + if !len || len + 4 > binstr[index..-1].bytesize + self['Unknown'] << binstr[index..-1] return end - self['Unknown'] << binstr[i, len + 4] + self['Unknown'] << binstr[index, len + 4] end def create_unknown_item - s = ''.dup + s = +'' class << s alias_method :to_c_dir_bin, :to_s alias_method :to_local_bin, :to_s @@ -36,10 +36,11 @@ def merge(binstr) return if binstr.empty? + i = 0 while i < binstr.bytesize id = binstr[i, 2] - len = binstr[i + 2, 2].to_s.unpack('v').first + len = binstr[i + 2, 2].to_s.unpack1('v') if id && ID_MAP.member?(id) extra_field_type_exist(binstr, id, len, i) elsif id @@ -54,6 +55,7 @@ unless (field_class = ID_MAP.values.find { |k| k.name == name }) raise Error, "Unknown extra field '#{name}'" end + self[name] = field_class.new end diff -Nru ruby-zip-2.0.0/lib/zip/file.rb ruby-zip-2.3.0/lib/zip/file.rb --- ruby-zip-2.0.0/lib/zip/file.rb 2019-09-25 20:23:47.000000000 +0000 +++ ruby-zip-2.3.0/lib/zip/file.rb 2020-03-14 12:00:50.000000000 +0000 @@ -49,16 +49,25 @@ MAX_SEGMENT_SIZE = 3_221_225_472 MIN_SEGMENT_SIZE = 65_536 DATA_BUFFER_SIZE = 8192 - IO_METHODS = [:tell, :seek, :read, :close] + IO_METHODS = [:tell, :seek, :read, :eof, :close] + + DEFAULT_OPTIONS = { + restore_ownership: false, + restore_permissions: false, + restore_times: false + }.freeze attr_reader :name - # default -> false + # default -> false. attr_accessor :restore_ownership - # default -> false + + # default -> false, but will be set to true in a future version. attr_accessor :restore_permissions - # default -> true + + # default -> false, but will be set to true in a future version. attr_accessor :restore_times + # Returns the zip files comment, if it has one attr_accessor :comment @@ -66,6 +75,7 @@ # a new archive if it doesn't exist already. def initialize(path_or_io, create = false, buffer = false, options = {}) super() + options = DEFAULT_OPTIONS.merge(options) @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 @@ -98,18 +108,19 @@ @stored_entries = @entry_set.dup @stored_comment = @comment - @restore_ownership = options[:restore_ownership] || false - @restore_permissions = options[:restore_permissions] || true - @restore_times = options[:restore_times] || true + @restore_ownership = options[:restore_ownership] + @restore_permissions = options[:restore_permissions] + @restore_times = options[:restore_times] end class << self - # Same as #new. If a block is passed the ZipFile object is passed - # to the block and is automatically closed afterwards just as with - # ruby's builtin File.open method. - def open(file_name, create = false) - zf = ::Zip::File.new(file_name, create) + # Similar to ::new. If a block is passed the Zip::File object is passed + # to the block and is automatically closed afterwards, just as with + # ruby's builtin File::open method. + def open(file_name, create = false, options = {}) + zf = ::Zip::File.new(file_name, create, false, options) return zf unless block_given? + begin yield zf ensure @@ -130,17 +141,18 @@ # (This can be used to extract data from a # downloaded zip archive without first saving it to disk.) def open_buffer(io, options = {}) - unless IO_METHODS.map { |method| io.respond_to?(method) }.all? || io.is_a?(String) + unless IO_METHODS.map { |method| io.respond_to?(method) }.all? || io.kind_of?(String) raise "Zip::File.open_buffer expects a String or IO-like argument (responds to #{IO_METHODS.join(', ')}). Found: #{io.class}" end - io = ::StringIO.new(io) if io.is_a?(::String) + io = ::StringIO.new(io) if io.kind_of?(::String) # https://github.com/rubyzip/rubyzip/issues/119 io.binmode if io.respond_to?(:binmode) zf = ::Zip::File.new(io, true, true, options) return zf unless block_given? + yield zf begin @@ -156,9 +168,9 @@ # whereas ZipInputStream jumps through the entire archive accessing the # local entry headers (which contain the same information as the # central directory). - def foreach(aZipFileName, &block) - open(aZipFileName) do |zipFile| - zipFile.each(&block) + def foreach(zip_file_name, &block) + ::Zip::File.open(zip_file_name) do |zip_file| + zip_file.each(&block) end end @@ -219,12 +231,14 @@ def split(zip_file_name, segment_size = MAX_SEGMENT_SIZE, delete_zip_file = true, partial_zip_file_name = nil) raise Error, "File #{zip_file_name} not found" unless ::File.exist?(zip_file_name) raise Errno::ENOENT, zip_file_name unless ::File.readable?(zip_file_name) + zip_file_size = ::File.size(zip_file_name) segment_size = get_segment_size_for_split(segment_size) return if zip_file_size <= segment_size + segment_count = get_segment_count_for_split(zip_file_size, segment_size) # Checking for correct zip structure - open(zip_file_name) {} + ::Zip::File.open(zip_file_name) {} partial_zip_file_name = get_partial_zip_file_name(zip_file_name, partial_zip_file_name) szip_file_index = 0 ::File.open(zip_file_name, 'rb') do |zip_file| @@ -241,8 +255,8 @@ # Returns an input stream to the specified entry. If a block is passed # the stream object is passed to the block and the stream is automatically # closed afterwards just as with ruby's builtin File.open method. - def get_input_stream(entry, &aProc) - get_entry(entry).get_input_stream(&aProc) + def get_input_stream(entry, &a_proc) + get_entry(entry).get_input_stream(&a_proc) end # Returns an output stream to the specified entry. If entry is not an instance @@ -250,7 +264,11 @@ # specified. If a block is passed the stream object is passed to the block and # the stream is automatically closed afterwards just as with ruby's builtin # File.open method. - def get_output_stream(entry, permission_int = nil, comment = nil, extra = nil, compressed_size = nil, crc = nil, compression_method = nil, size = nil, time = nil, &aProc) + def get_output_stream(entry, permission_int = nil, comment = nil, + extra = nil, compressed_size = nil, crc = nil, + compression_method = nil, size = nil, time = nil, + &a_proc) + new_entry = if entry.kind_of?(Entry) entry @@ -264,7 +282,7 @@ new_entry.unix_perms = permission_int zip_streamable_entry = StreamableStream.new(new_entry) @entry_set << zip_streamable_entry - zip_streamable_entry.get_output_stream(&aProc) + zip_streamable_entry.get_output_stream(&a_proc) end # Returns the name of the zip archive @@ -274,7 +292,7 @@ # Returns a string containing the contents of the specified entry def read(entry) - get_input_stream(entry) { |is| is.read } + get_input_stream(entry, &:read) end # Convenience method for adding the contents of a file to the archive @@ -301,19 +319,19 @@ # Renames the specified entry. def rename(entry, new_name, &continue_on_exists_proc) - foundEntry = get_entry(entry) + found_entry = get_entry(entry) check_entry_exists(new_name, continue_on_exists_proc, 'rename') - @entry_set.delete(foundEntry) - foundEntry.name = new_name - @entry_set << foundEntry + @entry_set.delete(found_entry) + found_entry.name = new_name + @entry_set << found_entry end - # Replaces the specified entry with the contents of srcPath (from + # Replaces the specified entry with the contents of src_path (from # the file system). - def replace(entry, srcPath) - check_file(srcPath) + def replace(entry, src_path) + check_file(src_path) remove(entry) - add(entry, srcPath) + add(entry, src_path) end # Extracts entry to file dest_path. @@ -326,7 +344,8 @@ # Commits changes that has been made since the previous commit to # the zip archive. def commit - return if name.is_a?(StringIO) || !commit_required? + return if name.kind_of?(StringIO) || !commit_required? + on_success_replace do |tmp_file| ::Zip::OutputStream.open(tmp_file) do |zos| @entry_set.each do |e| @@ -366,7 +385,13 @@ # Searches for entry with the specified name. Returns nil if # no entry is found. See also get_entry def find_entry(entry_name) - @entry_set.find_entry(entry_name) + selected_entry = @entry_set.find_entry(entry_name) + return if selected_entry.nil? + + selected_entry.restore_ownership = @restore_ownership + selected_entry.restore_permissions = @restore_permissions + selected_entry.restore_times = @restore_times + selected_entry end # Searches for entries given a glob @@ -378,43 +403,43 @@ # if no entry is found. def get_entry(entry) selected_entry = find_entry(entry) - raise Errno::ENOENT, entry unless selected_entry - selected_entry.restore_ownership = @restore_ownership - selected_entry.restore_permissions = @restore_permissions - selected_entry.restore_times = @restore_times + raise Errno::ENOENT, entry if selected_entry.nil? + selected_entry end # Creates a directory - def mkdir(entryName, permissionInt = 0o755) - raise Errno::EEXIST, "File exists - #{entryName}" if find_entry(entryName) - entryName = entryName.dup.to_s - entryName << '/' unless entryName.end_with?('/') - @entry_set << ::Zip::StreamableDirectory.new(@name, entryName, nil, permissionInt) + def mkdir(entry_name, permission = 0o755) + raise Errno::EEXIST, "File exists - #{entry_name}" if find_entry(entry_name) + + entry_name = entry_name.dup.to_s + entry_name << '/' unless entry_name.end_with?('/') + @entry_set << ::Zip::StreamableDirectory.new(@name, entry_name, nil, permission) end private - def directory?(newEntry, srcPath) - srcPathIsDirectory = ::File.directory?(srcPath) - if newEntry.directory? && !srcPathIsDirectory + def directory?(new_entry, src_path) + path_is_directory = ::File.directory?(src_path) + if new_entry.directory? && !path_is_directory raise ArgumentError, - "entry name '#{newEntry}' indicates directory entry, but " \ - "'#{srcPath}' is not a directory" - elsif !newEntry.directory? && srcPathIsDirectory - newEntry.name += '/' + "entry name '#{new_entry}' indicates directory entry, but " \ + "'#{src_path}' is not a directory" + elsif !new_entry.directory? && path_is_directory + new_entry.name += '/' end - newEntry.directory? && srcPathIsDirectory + new_entry.directory? && path_is_directory end - def check_entry_exists(entryName, continue_on_exists_proc, procedureName) + def check_entry_exists(entry_name, continue_on_exists_proc, proc_name) continue_on_exists_proc ||= proc { Zip.continue_on_exists_proc } - return unless @entry_set.include?(entryName) + return unless @entry_set.include?(entry_name) + if continue_on_exists_proc.call - remove get_entry(entryName) + remove get_entry(entry_name) else raise ::Zip::EntryExistsError, - procedureName + " failed. Entry #{entryName} already exists" + proc_name + " failed. Entry #{entry_name} already exists" end end diff -Nru ruby-zip-2.0.0/lib/zip/filesystem.rb ruby-zip-2.3.0/lib/zip/filesystem.rb --- ruby-zip-2.0.0/lib/zip/filesystem.rb 2019-09-25 20:23:47.000000000 +0000 +++ ruby-zip-2.3.0/lib/zip/filesystem.rb 2020-03-14 12:00:50.000000000 +0000 @@ -35,25 +35,25 @@ module FileSystem def initialize # :nodoc: - mappedZip = ZipFileNameMapper.new(self) - @zipFsDir = ZipFsDir.new(mappedZip) - @zipFsFile = ZipFsFile.new(mappedZip) - @zipFsDir.file = @zipFsFile - @zipFsFile.dir = @zipFsDir + mapped_zip = ZipFileNameMapper.new(self) + @zip_fs_dir = ZipFsDir.new(mapped_zip) + @zip_fs_file = ZipFsFile.new(mapped_zip) + @zip_fs_dir.file = @zip_fs_file + @zip_fs_file.dir = @zip_fs_dir end # Returns a ZipFsDir which is much like ruby's builtin Dir (class) # object, except it works on the Zip::File on which this method is # invoked def dir - @zipFsDir + @zip_fs_dir end # Returns a ZipFsFile which is much like ruby's builtin File (class) # object, except it works on the Zip::File on which this method is # invoked def file - @zipFsFile + @zip_fs_file end # Instances of this class are normally accessed via the accessor @@ -70,22 +70,22 @@ class << self def delegate_to_fs_file(*methods) methods.each do |method| - class_eval <<-end_eval, __FILE__, __LINE__ + 1 + class_eval <<-END_EVAL, __FILE__, __LINE__ + 1 def #{method} # def file? - @zipFsFile.#{method}(@entryName) # @zipFsFile.file?(@entryName) + @zip_fs_file.#{method}(@entry_name) # @zip_fs_file.file?(@entry_name) end # end - end_eval + END_EVAL end end end - def initialize(zipFsFile, entryName) - @zipFsFile = zipFsFile - @entryName = entryName + def initialize(zip_fs_file, entry_name) + @zip_fs_file = zip_fs_file + @entry_name = entry_name end - def kind_of?(t) - super || t == ::File::Stat + def kind_of?(type) + super || type == ::File::Stat end delegate_to_fs_file :file?, :directory?, :pipe?, :chardev?, :symlink?, @@ -98,7 +98,7 @@ end def get_entry - @zipFsFile.__send__(:get_entry, @entryName) + @zip_fs_file.__send__(:get_entry, @entry_name) end private :get_entry @@ -168,28 +168,29 @@ end end - def initialize(mappedZip) - @mappedZip = mappedZip + def initialize(mapped_zip) + @mapped_zip = mapped_zip end - def get_entry(fileName) - unless exists?(fileName) - raise Errno::ENOENT, "No such file or directory - #{fileName}" + def get_entry(filename) + unless exists?(filename) + raise Errno::ENOENT, "No such file or directory - #{filename}" end - @mappedZip.find_entry(fileName) + + @mapped_zip.find_entry(filename) end private :get_entry - def unix_mode_cmp(fileName, mode) - e = get_entry(fileName) + def unix_mode_cmp(filename, mode) + e = get_entry(filename) e.fstype == 3 && ((e.external_file_attributes >> 16) & mode) != 0 rescue Errno::ENOENT false end private :unix_mode_cmp - def exists?(fileName) - expand_path(fileName) == '/' || !@mappedZip.find_entry(fileName).nil? + def exists?(filename) + expand_path(filename) == '/' || !@mapped_zip.find_entry(filename).nil? end alias exist? exists? @@ -197,133 +198,133 @@ alias owned? exists? alias grpowned? exists? - def readable?(fileName) - unix_mode_cmp(fileName, 0o444) + def readable?(filename) + unix_mode_cmp(filename, 0o444) end alias readable_real? readable? - def writable?(fileName) - unix_mode_cmp(fileName, 0o222) + def writable?(filename) + unix_mode_cmp(filename, 0o222) end alias writable_real? writable? - def executable?(fileName) - unix_mode_cmp(fileName, 0o111) + def executable?(filename) + unix_mode_cmp(filename, 0o111) end alias executable_real? executable? - def setuid?(fileName) - unix_mode_cmp(fileName, 0o4000) + def setuid?(filename) + unix_mode_cmp(filename, 0o4000) end - def setgid?(fileName) - unix_mode_cmp(fileName, 0o2000) + def setgid?(filename) + unix_mode_cmp(filename, 0o2000) end - def sticky?(fileName) - unix_mode_cmp(fileName, 0o1000) + def sticky?(filename) + unix_mode_cmp(filename, 0o1000) end def umask(*args) ::File.umask(*args) end - def truncate(_fileName, _len) + def truncate(_filename, _len) raise StandardError, 'truncate not supported' end - def directory?(fileName) - entry = @mappedZip.find_entry(fileName) - expand_path(fileName) == '/' || (!entry.nil? && entry.directory?) + def directory?(filename) + entry = @mapped_zip.find_entry(filename) + expand_path(filename) == '/' || (!entry.nil? && entry.directory?) end - def open(fileName, openMode = 'r', permissionInt = 0o644, &block) - openMode.delete!('b') # ignore b option - case openMode + def open(filename, mode = 'r', permissions = 0o644, &block) + mode.delete!('b') # ignore b option + case mode when 'r' - @mappedZip.get_input_stream(fileName, &block) + @mapped_zip.get_input_stream(filename, &block) when 'w' - @mappedZip.get_output_stream(fileName, permissionInt, &block) + @mapped_zip.get_output_stream(filename, permissions, &block) else - raise StandardError, "openmode '#{openMode} not supported" unless openMode == 'r' + raise StandardError, "openmode '#{mode} not supported" unless mode == 'r' end end - def new(fileName, openMode = 'r') - open(fileName, openMode) + def new(filename, mode = 'r') + self.open(filename, mode) end - def size(fileName) - @mappedZip.get_entry(fileName).size + def size(filename) + @mapped_zip.get_entry(filename).size end # Returns nil for not found and nil for directories - def size?(fileName) - entry = @mappedZip.find_entry(fileName) + def size?(filename) + entry = @mapped_zip.find_entry(filename) entry.nil? || entry.directory? ? nil : entry.size end - def chown(ownerInt, groupInt, *filenames) - filenames.each do |fileName| - e = get_entry(fileName) + def chown(owner, group, *filenames) + filenames.each do |filename| + e = get_entry(filename) e.extra.create('IUnix') unless e.extra.member?('IUnix') - e.extra['IUnix'].uid = ownerInt - e.extra['IUnix'].gid = groupInt + e.extra['IUnix'].uid = owner + e.extra['IUnix'].gid = group end filenames.size end - def chmod(modeInt, *filenames) - filenames.each do |fileName| - e = get_entry(fileName) + def chmod(mode, *filenames) + filenames.each do |filename| + e = get_entry(filename) e.fstype = 3 # force convertion filesystem type to unix - e.unix_perms = modeInt - e.external_file_attributes = modeInt << 16 + e.unix_perms = mode + e.external_file_attributes = mode << 16 e.dirty = true end filenames.size end - def zero?(fileName) - sz = size(fileName) + def zero?(filename) + sz = size(filename) sz.nil? || sz == 0 rescue Errno::ENOENT false end - def file?(fileName) - entry = @mappedZip.find_entry(fileName) + def file?(filename) + entry = @mapped_zip.find_entry(filename) !entry.nil? && entry.file? end - def dirname(fileName) - ::File.dirname(fileName) + def dirname(filename) + ::File.dirname(filename) end - def basename(fileName) - ::File.basename(fileName) + def basename(filename) + ::File.basename(filename) end - def split(fileName) - ::File.split(fileName) + def split(filename) + ::File.split(filename) end def join(*fragments) ::File.join(*fragments) end - def utime(modifiedTime, *fileNames) - fileNames.each do |fileName| - get_entry(fileName).time = modifiedTime + def utime(modified_time, *filenames) + filenames.each do |filename| + get_entry(filename).time = modified_time end end - def mtime(fileName) - @mappedZip.get_entry(fileName).mtime + def mtime(filename) + @mapped_zip.get_entry(filename).mtime end - def atime(fileName) - e = get_entry(fileName) + def atime(filename) + e = get_entry(filename) if e.extra.member? 'UniversalTime' e.extra['UniversalTime'].atime elsif e.extra.member? 'NTFS' @@ -331,8 +332,8 @@ end end - def ctime(fileName) - e = get_entry(fileName) + def ctime(filename) + e = get_entry(filename) if e.extra.member? 'UniversalTime' e.extra['UniversalTime'].ctime elsif e.extra.member? 'NTFS' @@ -352,27 +353,27 @@ false end - def symlink?(_fileName) + def symlink?(_filename) false end - def socket?(_fileName) + def socket?(_filename) false end - def ftype(fileName) - @mappedZip.get_entry(fileName).directory? ? 'directory' : 'file' + def ftype(filename) + @mapped_zip.get_entry(filename).directory? ? 'directory' : 'file' end - def readlink(_fileName) + def readlink(_filename) raise NotImplementedError, 'The readlink() function is not implemented' end - def symlink(_fileName, _symlinkName) + def symlink(_filename, _symlink_name) raise NotImplementedError, 'The symlink() function is not implemented' end - def link(_fileName, _symlinkName) + def link(_filename, _symlink_name) raise NotImplementedError, 'The link() function is not implemented' end @@ -380,46 +381,48 @@ raise NotImplementedError, 'The pipe() function is not implemented' end - def stat(fileName) - raise Errno::ENOENT, fileName unless exists?(fileName) - ZipFsStat.new(self, fileName) + def stat(filename) + raise Errno::ENOENT, filename unless exists?(filename) + + ZipFsStat.new(self, filename) end alias lstat stat - def readlines(fileName) - open(fileName) { |is| is.readlines } + def readlines(filename) + self.open(filename, &:readlines) end - def read(fileName) - @mappedZip.read(fileName) + def read(filename) + @mapped_zip.read(filename) end - def popen(*args, &aProc) - ::File.popen(*args, &aProc) + def popen(*args, &a_proc) + ::File.popen(*args, &a_proc) end - def foreach(fileName, aSep = $/, &aProc) - open(fileName) { |is| is.each_line(aSep, &aProc) } + def foreach(filename, sep = $INPUT_RECORD_SEPARATOR, &a_proc) + self.open(filename) { |is| is.each_line(sep, &a_proc) } end def delete(*args) - args.each do |fileName| - if directory?(fileName) - raise Errno::EISDIR, "Is a directory - \"#{fileName}\"" + args.each do |filename| + if directory?(filename) + raise Errno::EISDIR, "Is a directory - \"#{filename}\"" end - @mappedZip.remove(fileName) + + @mapped_zip.remove(filename) end end - def rename(fileToRename, newName) - @mappedZip.rename(fileToRename, newName) { true } + def rename(file_to_rename, new_name) + @mapped_zip.rename(file_to_rename, new_name) { true } end alias unlink delete - def expand_path(aPath) - @mappedZip.expand_path(aPath) + def expand_path(path) + @mapped_zip.expand_path(path) end end @@ -430,76 +433,79 @@ # The individual methods are not documented due to their # similarity with the methods in Dir class ZipFsDir - def initialize(mappedZip) - @mappedZip = mappedZip + def initialize(mapped_zip) + @mapped_zip = mapped_zip end attr_writer :file - def new(aDirectoryName) - ZipFsDirIterator.new(entries(aDirectoryName)) + def new(directory_name) + ZipFsDirIterator.new(entries(directory_name)) end - def open(aDirectoryName) - dirIt = new(aDirectoryName) + def open(directory_name) + dir_iter = new(directory_name) if block_given? begin - yield(dirIt) + yield(dir_iter) return nil ensure - dirIt.close + dir_iter.close end end - dirIt + dir_iter end def pwd - @mappedZip.pwd + @mapped_zip.pwd end alias getwd pwd - def chdir(aDirectoryName) - unless @file.stat(aDirectoryName).directory? - raise Errno::EINVAL, "Invalid argument - #{aDirectoryName}" + def chdir(directory_name) + unless @file.stat(directory_name).directory? + raise Errno::EINVAL, "Invalid argument - #{directory_name}" end - @mappedZip.pwd = @file.expand_path(aDirectoryName) + + @mapped_zip.pwd = @file.expand_path(directory_name) end - def entries(aDirectoryName) + def entries(directory_name) entries = [] - foreach(aDirectoryName) { |e| entries << e } + foreach(directory_name) { |e| entries << e } entries end def glob(*args, &block) - @mappedZip.glob(*args, &block) + @mapped_zip.glob(*args, &block) end - def foreach(aDirectoryName) - unless @file.stat(aDirectoryName).directory? - raise Errno::ENOTDIR, aDirectoryName + def foreach(directory_name) + unless @file.stat(directory_name).directory? + raise Errno::ENOTDIR, directory_name end - path = @file.expand_path(aDirectoryName) + + path = @file.expand_path(directory_name) path << '/' unless path.end_with?('/') path = Regexp.escape(path) - subDirEntriesRegex = Regexp.new("^#{path}([^/]+)$") - @mappedZip.each do |fileName| - match = subDirEntriesRegex.match(fileName) + subdir_entry_regex = Regexp.new("^#{path}([^/]+)$") + @mapped_zip.each do |filename| + match = subdir_entry_regex.match(filename) yield(match[1]) unless match.nil? end end - def delete(entryName) - unless @file.stat(entryName).directory? - raise Errno::EINVAL, "Invalid argument - #{entryName}" + def delete(entry_name) + unless @file.stat(entry_name).directory? + raise Errno::EINVAL, "Invalid argument - #{entry_name}" end - @mappedZip.remove(entryName) + + @mapped_zip.remove(entry_name) end alias rmdir delete alias unlink delete - def mkdir(entryName, permissionInt = 0o755) - @mappedZip.mkdir(entryName, permissionInt) + def mkdir(entry_name, permissions = 0o755) + @mapped_zip.mkdir(entry_name, permissions) end def chroot(*_args) @@ -510,37 +516,42 @@ class ZipFsDirIterator # :nodoc:all include Enumerable - def initialize(arrayOfFileNames) - @fileNames = arrayOfFileNames + def initialize(filenames) + @filenames = filenames @index = 0 end def close - @fileNames = nil + @filenames = nil end - def each(&aProc) - raise IOError, 'closed directory' if @fileNames.nil? - @fileNames.each(&aProc) + def each(&a_proc) + raise IOError, 'closed directory' if @filenames.nil? + + @filenames.each(&a_proc) end def read - raise IOError, 'closed directory' if @fileNames.nil? - @fileNames[(@index += 1) - 1] + raise IOError, 'closed directory' if @filenames.nil? + + @filenames[(@index += 1) - 1] end def rewind - raise IOError, 'closed directory' if @fileNames.nil? + raise IOError, 'closed directory' if @filenames.nil? + @index = 0 end - def seek(anIntegerPosition) - raise IOError, 'closed directory' if @fileNames.nil? - @index = anIntegerPosition + def seek(position) + raise IOError, 'closed directory' if @filenames.nil? + + @index = position end def tell - raise IOError, 'closed directory' if @fileNames.nil? + raise IOError, 'closed directory' if @filenames.nil? + @index end end @@ -550,60 +561,65 @@ class ZipFileNameMapper # :nodoc:all include Enumerable - def initialize(zipFile) - @zipFile = zipFile + def initialize(zip_file) + @zip_file = zip_file @pwd = '/' end attr_accessor :pwd - def find_entry(fileName) - @zipFile.find_entry(expand_to_entry(fileName)) + def find_entry(filename) + @zip_file.find_entry(expand_to_entry(filename)) end - def get_entry(fileName) - @zipFile.get_entry(expand_to_entry(fileName)) + def get_entry(filename) + @zip_file.get_entry(expand_to_entry(filename)) end - def get_input_stream(fileName, &aProc) - @zipFile.get_input_stream(expand_to_entry(fileName), &aProc) + def get_input_stream(filename, &a_proc) + @zip_file.get_input_stream(expand_to_entry(filename), &a_proc) end - def get_output_stream(fileName, permissionInt = nil, &aProc) - @zipFile.get_output_stream(expand_to_entry(fileName), permissionInt, &aProc) + def get_output_stream(filename, permissions = nil, &a_proc) + @zip_file.get_output_stream( + expand_to_entry(filename), permissions, &a_proc + ) end def glob(pattern, *flags, &block) - @zipFile.glob(expand_to_entry(pattern), *flags, &block) + @zip_file.glob(expand_to_entry(pattern), *flags, &block) end - def read(fileName) - @zipFile.read(expand_to_entry(fileName)) + def read(filename) + @zip_file.read(expand_to_entry(filename)) end - def remove(fileName) - @zipFile.remove(expand_to_entry(fileName)) + def remove(filename) + @zip_file.remove(expand_to_entry(filename)) end - def rename(fileName, newName, &continueOnExistsProc) - @zipFile.rename(expand_to_entry(fileName), expand_to_entry(newName), - &continueOnExistsProc) + def rename(filename, new_name, &continue_on_exists_proc) + @zip_file.rename( + expand_to_entry(filename), + expand_to_entry(new_name), + &continue_on_exists_proc + ) end - def mkdir(fileName, permissionInt = 0o755) - @zipFile.mkdir(expand_to_entry(fileName), permissionInt) + def mkdir(filename, permissions = 0o755) + @zip_file.mkdir(expand_to_entry(filename), permissions) end # Turns entries into strings and adds leading / # and removes trailing slash on directories def each - @zipFile.each do |e| + @zip_file.each do |e| yield('/' + e.to_s.chomp('/')) end end - def expand_path(aPath) - expanded = aPath.start_with?('/') ? aPath : ::File.join(@pwd, aPath) + def expand_path(path) + expanded = path.start_with?('/') ? path : ::File.join(@pwd, path) expanded.gsub!(/\/\.(\/|$)/, '') expanded.gsub!(/[^\/]+\/\.\.(\/|$)/, '') expanded.empty? ? '/' : expanded @@ -611,8 +627,8 @@ private - def expand_to_entry(aPath) - expand_path(aPath)[1..-1] + def expand_to_entry(path) + expand_path(path)[1..-1] end end end diff -Nru ruby-zip-2.0.0/lib/zip/inflater.rb ruby-zip-2.3.0/lib/zip/inflater.rb --- ruby-zip-2.0.0/lib/zip/inflater.rb 2019-09-25 20:23:47.000000000 +0000 +++ ruby-zip-2.3.0/lib/zip/inflater.rb 2020-03-14 12:00:50.000000000 +0000 @@ -1,64 +1,52 @@ module Zip class Inflater < Decompressor #:nodoc:all - def initialize(input_stream, decrypter = NullDecrypter.new) - super(input_stream) - @zlib_inflater = ::Zlib::Inflate.new(-Zlib::MAX_WBITS) - @output_buffer = ''.dup - @has_returned_empty_string = false - @decrypter = decrypter - end + def initialize(*args) + super - def sysread(number_of_bytes = nil, buf = '') - readEverything = number_of_bytes.nil? - while readEverything || @output_buffer.bytesize < number_of_bytes - break if internal_input_finished? - @output_buffer << internal_produce_input(buf) - end - return value_when_finished if @output_buffer.bytesize == 0 && input_finished? - end_index = number_of_bytes.nil? ? @output_buffer.bytesize : number_of_bytes - @output_buffer.slice!(0...end_index) + @buffer = +'' + @zlib_inflater = ::Zlib::Inflate.new(-Zlib::MAX_WBITS) end - def produce_input - if @output_buffer.empty? - internal_produce_input - else - @output_buffer.slice!(0...(@output_buffer.length)) + def read(length = nil, outbuf = '') + return (length.nil? || length.zero? ? '' : nil) if eof + + while length.nil? || (@buffer.bytesize < length) + break if input_finished? + + @buffer << produce_input end + + outbuf.replace(@buffer.slice!(0...(length || @buffer.bytesize))) end - # to be used with produce_input, not read (as read may still have more data cached) - # is data cached anywhere other than @outputBuffer? the comment above may be wrong - def input_finished? - @output_buffer.empty? && internal_input_finished? + def eof + @buffer.empty? && input_finished? end - alias :eof input_finished? - alias :eof? input_finished? + alias eof? eof private - def internal_produce_input(buf = '') + def produce_input retried = 0 begin - @zlib_inflater.inflate(@decrypter.decrypt(@input_stream.read(Decompressor::CHUNK_SIZE, buf))) + @zlib_inflater.inflate(input_stream.read(Decompressor::CHUNK_SIZE)) rescue Zlib::BufError raise if retried >= 5 # how many times should we retry? + retried += 1 retry end + rescue Zlib::Error + raise(::Zip::DecompressionError, 'zlib error while inflating') end - def internal_input_finished? + def input_finished? @zlib_inflater.finished? end - - def value_when_finished # mimic behaviour of ruby File object. - return if @has_returned_empty_string - @has_returned_empty_string = true - '' - end end + + ::Zip::Decompressor.register(::Zip::COMPRESSION_METHOD_DEFLATE, ::Zip::Inflater) end # Copyright (C) 2002, 2003 Thomas Sondergaard diff -Nru ruby-zip-2.0.0/lib/zip/input_stream.rb ruby-zip-2.3.0/lib/zip/input_stream.rb --- ruby-zip-2.0.0/lib/zip/input_stream.rb 2019-09-25 20:23:47.000000000 +0000 +++ ruby-zip-2.3.0/lib/zip/input_stream.rb 2020-03-14 12:00:50.000000000 +0000 @@ -39,6 +39,8 @@ # class. class InputStream + CHUNK_SIZE = 32_768 + include ::Zip::IOExtras::AbstractInputStream # Opens the indicated zip file. An exception is thrown @@ -49,7 +51,7 @@ # @param offset [Integer] offset in the IO/StringIO def initialize(context, offset = 0, decrypter = nil) super() - @archive_io = get_io(context, offset) + @archive_io = get_io(context, offset) @decompressor = ::Zip::NullDecompressor @decrypter = decrypter || ::Zip::NullDecrypter.new @current_entry = nil @@ -71,6 +73,7 @@ # Rewinds the stream to the beginning of the current entry def rewind return if @current_entry.nil? + @lineno = 0 @pos = 0 @archive_io.seek(@current_entry.local_header_offset, IO::SEEK_SET) @@ -78,16 +81,10 @@ end # Modeled after IO.sysread - def sysread(number_of_bytes = nil, buf = nil) - @decompressor.sysread(number_of_bytes, buf) - end - - def eof - @output_buffer.empty? && @decompressor.eof + def sysread(length = nil, outbuf = '') + @decompressor.read(length, outbuf) end - alias :eof? eof - class << self # Same as #initialize but if a block is passed the opened # stream is passed to the block and closed when the block @@ -95,6 +92,7 @@ def open(filename_or_io, offset = 0, decrypter = nil) zio = new(filename_or_io, offset, decrypter) return zio unless block_given? + begin yield zio ensure @@ -103,8 +101,8 @@ end def open_buffer(filename_or_io, offset = 0) - puts 'open_buffer is deprecated!!! Use open instead!' - open(filename_or_io, offset) + warn 'open_buffer is deprecated!!! Use open instead!' + ::Zip::InputStream.open(filename_or_io, offset) end end @@ -124,46 +122,55 @@ def open_entry @current_entry = ::Zip::Entry.read_local_entry(@archive_io) - if @current_entry && @current_entry.gp_flags & 1 == 1 && @decrypter.is_a?(NullEncrypter) + if @current_entry && @current_entry.encrypted? && @decrypter.kind_of?(NullEncrypter) raise Error, 'password required to decode zip file' end - if @current_entry && @current_entry.gp_flags & 8 == 8 && @current_entry.crc == 0 \ + + if @current_entry && @current_entry.incomplete? && @current_entry.crc == 0 \ && @current_entry.compressed_size == 0 \ && @current_entry.size == 0 && !@complete_entry raise GPFBit3Error, 'General purpose flag Bit 3 is set so not possible to get proper info from local header.' \ 'Please use ::Zip::File instead of ::Zip::InputStream' end + @decrypted_io = get_decrypted_io @decompressor = get_decompressor flush @current_entry end + def get_decrypted_io + header = @archive_io.read(@decrypter.header_bytesize) + @decrypter.reset!(header) + + ::Zip::DecryptedIo.new(@archive_io, @decrypter) + end + def get_decompressor - if @current_entry.nil? - ::Zip::NullDecompressor - elsif @current_entry.compression_method == ::Zip::Entry::STORED - if @current_entry.gp_flags & 8 == 8 && @current_entry.crc == 0 && @current_entry.size == 0 && @complete_entry - ::Zip::PassThruDecompressor.new(@archive_io, @complete_entry.size) + return ::Zip::NullDecompressor if @current_entry.nil? + + decompressed_size = + if @current_entry.incomplete? && @current_entry.crc == 0 && @current_entry.size == 0 && @complete_entry + @complete_entry.size else - ::Zip::PassThruDecompressor.new(@archive_io, @current_entry.size) + @current_entry.size end - elsif @current_entry.compression_method == ::Zip::Entry::DEFLATED - header = @archive_io.read(@decrypter.header_bytesize) - @decrypter.reset!(header) - ::Zip::Inflater.new(@archive_io, @decrypter) - else + + decompressor_class = ::Zip::Decompressor.find_by_compression_method(@current_entry.compression_method) + if decompressor_class.nil? raise ::Zip::CompressionMethodError, "Unsupported compression method #{@current_entry.compression_method}" end + + decompressor_class.new(@decrypted_io, decompressed_size) end def produce_input - @decompressor.produce_input + @decompressor.read(CHUNK_SIZE) end def input_finished? - @decompressor.input_finished? + @decompressor.eof end end end diff -Nru ruby-zip-2.0.0/lib/zip/ioextras/abstract_input_stream.rb ruby-zip-2.3.0/lib/zip/ioextras/abstract_input_stream.rb --- ruby-zip-2.0.0/lib/zip/ioextras/abstract_input_stream.rb 2019-09-25 20:23:47.000000000 +0000 +++ ruby-zip-2.3.0/lib/zip/ioextras/abstract_input_stream.rb 2020-03-14 12:00:50.000000000 +0000 @@ -35,6 +35,7 @@ if tbuf.nil? || tbuf.empty? return nil if number_of_bytes + return '' end @@ -48,13 +49,13 @@ buf end - def readlines(a_sep_string = $/) + def readlines(a_sep_string = $INPUT_RECORD_SEPARATOR) ret_val = [] each_line(a_sep_string) { |line| ret_val << line } ret_val end - def gets(a_sep_string = $/, number_of_bytes = nil) + def gets(a_sep_string = $INPUT_RECORD_SEPARATOR, number_of_bytes = nil) @lineno = @lineno.next if number_of_bytes.respond_to?(:to_int) @@ -62,20 +63,22 @@ a_sep_string = a_sep_string.to_str if a_sep_string elsif a_sep_string.respond_to?(:to_int) number_of_bytes = a_sep_string.to_int - a_sep_string = $/ + a_sep_string = $INPUT_RECORD_SEPARATOR else number_of_bytes = nil a_sep_string = a_sep_string.to_str if a_sep_string end return read(number_of_bytes) if a_sep_string.nil? - a_sep_string = "#{$/}#{$/}" if a_sep_string.empty? + + a_sep_string = "#{$INPUT_RECORD_SEPARATOR}#{$INPUT_RECORD_SEPARATOR}" if a_sep_string.empty? buffer_index = 0 over_limit = (number_of_bytes && @output_buffer.bytesize >= number_of_bytes) while (match_index = @output_buffer.index(a_sep_string, buffer_index)).nil? && !over_limit buffer_index = [buffer_index, @output_buffer.bytesize - a_sep_string.bytesize].max return @output_buffer.empty? ? nil : flush if input_finished? + @output_buffer << produce_input over_limit = (number_of_bytes && @output_buffer.bytesize >= number_of_bytes) end @@ -94,18 +97,26 @@ ret_val end - def readline(a_sep_string = $/) + def readline(a_sep_string = $INPUT_RECORD_SEPARATOR) ret_val = gets(a_sep_string) raise EOFError unless ret_val + ret_val end - def each_line(a_sep_string = $/) - yield readline(a_sep_string) while true + def each_line(a_sep_string = $INPUT_RECORD_SEPARATOR) + loop { yield readline(a_sep_string) } rescue EOFError + # We just need to catch this; we don't need to handle it. + end + + alias each each_line + + def eof + @output_buffer.empty? && input_finished? end - alias_method :each, :each_line + alias eof? eof end end end diff -Nru ruby-zip-2.0.0/lib/zip/ioextras/abstract_output_stream.rb ruby-zip-2.3.0/lib/zip/ioextras/abstract_output_stream.rb --- ruby-zip-2.0.0/lib/zip/ioextras/abstract_output_stream.rb 2019-09-25 20:23:47.000000000 +0000 +++ ruby-zip-2.3.0/lib/zip/ioextras/abstract_output_stream.rb 2020-03-14 12:00:50.000000000 +0000 @@ -11,7 +11,7 @@ end def print(*params) - self << params.join($,) << $\.to_s + self << params.join($OUTPUT_FIELD_SEPARATOR) << $OUTPUT_RECORD_SEPARATOR.to_s end def printf(a_format_string, *params) diff -Nru ruby-zip-2.0.0/lib/zip/ioextras.rb ruby-zip-2.3.0/lib/zip/ioextras.rb --- ruby-zip-2.0.0/lib/zip/ioextras.rb 2019-09-25 20:23:47.000000000 +0000 +++ ruby-zip-2.3.0/lib/zip/ioextras.rb 2020-03-14 12:00:50.000000000 +0000 @@ -25,7 +25,7 @@ object == IO || super end end - end # IOExtras namespace module + end end require 'zip/ioextras/abstract_input_stream' diff -Nru ruby-zip-2.0.0/lib/zip/null_decompressor.rb ruby-zip-2.3.0/lib/zip/null_decompressor.rb --- ruby-zip-2.0.0/lib/zip/null_decompressor.rb 2019-09-25 20:23:47.000000000 +0000 +++ ruby-zip-2.3.0/lib/zip/null_decompressor.rb 2020-03-14 12:00:50.000000000 +0000 @@ -2,18 +2,10 @@ module NullDecompressor #:nodoc:all module_function - def sysread(_numberOfBytes = nil, _buf = nil) + def read(_length = nil, _outbuf = nil) nil end - def produce_input - nil - end - - def input_finished? - true - end - def eof true end diff -Nru ruby-zip-2.0.0/lib/zip/output_stream.rb ruby-zip-2.3.0/lib/zip/output_stream.rb --- ruby-zip-2.0.0/lib/zip/output_stream.rb 2019-09-25 20:23:47.000000000 +0000 +++ ruby-zip-2.3.0/lib/zip/output_stream.rb 2020-03-14 12:00:50.000000000 +0000 @@ -49,6 +49,7 @@ class << self def open(file_name, encrypter = nil) return new(file_name) unless block_given? + zos = new(file_name, false, encrypter) yield zos ensure @@ -57,6 +58,7 @@ # Same as #open but writes to a filestream instead def write_buffer(io = ::StringIO.new(''), encrypter = nil) + io.binmode if io.respond_to?(:binmode) zos = new(io, true, encrypter) yield zos zos.close_buffer @@ -66,6 +68,7 @@ # Closes the stream and writes the central directory to the zip file def close return if @closed + finalize_current_entry update_local_headers write_central_directory @@ -76,6 +79,7 @@ # Closes the stream and writes the central directory to the zip file def close_buffer return @output_stream if @closed + finalize_current_entry update_local_headers write_central_directory @@ -87,6 +91,7 @@ # +entry+ can be a ZipEntry object or a string. def put_next_entry(entry_name, comment = nil, extra = nil, compression_method = Entry::DEFLATED, level = Zip.default_compression) raise Error, 'zip stream is closed' if @closed + new_entry = if entry_name.kind_of?(Entry) entry_name else @@ -94,7 +99,7 @@ end new_entry.comment = comment unless comment.nil? unless extra.nil? - new_entry.extra = extra.is_a?(ExtraField) ? extra : ExtraField.new(extra.to_s) + new_entry.extra = extra.kind_of?(ExtraField) ? extra : ExtraField.new(extra.to_s) end new_entry.compression_method = compression_method unless compression_method.nil? init_next_entry(new_entry, level) @@ -104,7 +109,8 @@ def copy_raw_entry(entry) entry = entry.dup raise Error, 'zip stream is closed' if @closed - raise Error, 'entry is not a ZipEntry' unless entry.is_a?(Entry) + raise Error, 'entry is not a ZipEntry' unless entry.kind_of?(Entry) + finalize_current_entry @entry_set << entry src_pos = entry.local_header_offset @@ -123,8 +129,11 @@ def finalize_current_entry return unless @current_entry + finish - @current_entry.compressed_size = @output_stream.tell - @current_entry.local_header_offset - @current_entry.calculate_local_header_size + @current_entry.compressed_size = @output_stream.tell - \ + @current_entry.local_header_offset - \ + @current_entry.calculate_local_header_size @current_entry.size = @compressor.size @current_entry.crc = @compressor.crc @output_stream << @encrypter.data_descriptor(@current_entry.crc, @current_entry.compressed_size, @current_entry.size) @@ -144,9 +153,9 @@ def get_compressor(entry, level) case entry.compression_method - when Entry::DEFLATED then + when Entry::DEFLATED ::Zip::Deflater.new(@output_stream, level, @encrypter) - when Entry::STORED then + when Entry::STORED ::Zip::PassThruCompressor.new(@output_stream) else raise ::Zip::CompressionMethodError, diff -Nru ruby-zip-2.0.0/lib/zip/pass_thru_compressor.rb ruby-zip-2.3.0/lib/zip/pass_thru_compressor.rb --- ruby-zip-2.0.0/lib/zip/pass_thru_compressor.rb 2019-09-25 20:23:47.000000000 +0000 +++ ruby-zip-2.3.0/lib/zip/pass_thru_compressor.rb 2020-03-14 12:00:50.000000000 +0000 @@ -1,8 +1,8 @@ module Zip class PassThruCompressor < Compressor #:nodoc:all - def initialize(outputStream) + def initialize(output_stream) super() - @output_stream = outputStream + @output_stream = output_stream @crc = Zlib.crc32 @size = 0 end diff -Nru ruby-zip-2.0.0/lib/zip/pass_thru_decompressor.rb ruby-zip-2.3.0/lib/zip/pass_thru_decompressor.rb --- ruby-zip-2.0.0/lib/zip/pass_thru_decompressor.rb 2019-09-25 20:23:47.000000000 +0000 +++ ruby-zip-2.3.0/lib/zip/pass_thru_decompressor.rb 2020-03-14 12:00:50.000000000 +0000 @@ -1,38 +1,29 @@ module Zip class PassThruDecompressor < Decompressor #:nodoc:all - def initialize(input_stream, chars_to_read) - super(input_stream) - @chars_to_read = chars_to_read + def initialize(*args) + super @read_so_far = 0 - @has_returned_empty_string = false end - def sysread(number_of_bytes = nil, buf = '') - if input_finished? - has_returned_empty_string_val = @has_returned_empty_string - @has_returned_empty_string = true - return '' unless has_returned_empty_string_val - return - end + def read(length = nil, outbuf = '') + return (length.nil? || length.zero? ? '' : nil) if eof - if number_of_bytes.nil? || @read_so_far + number_of_bytes > @chars_to_read - number_of_bytes = @chars_to_read - @read_so_far + if length.nil? || (@read_so_far + length) > decompressed_size + length = decompressed_size - @read_so_far end - @read_so_far += number_of_bytes - @input_stream.read(number_of_bytes, buf) - end - def produce_input - sysread(::Zip::Decompressor::CHUNK_SIZE) + @read_so_far += length + input_stream.read(length, outbuf) end - def input_finished? - @read_so_far >= @chars_to_read + def eof + @read_so_far >= decompressed_size end - alias eof input_finished? - alias eof? input_finished? + alias eof? eof end + + ::Zip::Decompressor.register(::Zip::COMPRESSION_METHOD_STORE, ::Zip::PassThruDecompressor) end # Copyright (C) 2002, 2003 Thomas Sondergaard diff -Nru ruby-zip-2.0.0/lib/zip/streamable_directory.rb ruby-zip-2.3.0/lib/zip/streamable_directory.rb --- ruby-zip-2.0.0/lib/zip/streamable_directory.rb 2019-09-25 20:23:47.000000000 +0000 +++ ruby-zip-2.3.0/lib/zip/streamable_directory.rb 2020-03-14 12:00:50.000000000 +0000 @@ -1,11 +1,11 @@ module Zip class StreamableDirectory < Entry - def initialize(zipfile, entry, srcPath = nil, permissionInt = nil) + def initialize(zipfile, entry, src_path = nil, permission = nil) super(zipfile, entry) @ftype = :directory - entry.get_extra_attributes_from_path(srcPath) if srcPath - @unix_perms = permissionInt if permissionInt + entry.get_extra_attributes_from_path(src_path) if src_path + @unix_perms = permission if permission end end end diff -Nru ruby-zip-2.0.0/lib/zip/streamable_stream.rb ruby-zip-2.3.0/lib/zip/streamable_stream.rb --- ruby-zip-2.0.0/lib/zip/streamable_stream.rb 2019-09-25 20:23:47.000000000 +0000 +++ ruby-zip-2.3.0/lib/zip/streamable_stream.rb 2020-03-14 12:00:50.000000000 +0000 @@ -1,13 +1,8 @@ module Zip - class StreamableStream < DelegateClass(Entry) # nodoc:all + class StreamableStream < DelegateClass(Entry) # :nodoc:all def initialize(entry) super(entry) - dirname = if zipfile.is_a?(::String) - ::File.dirname(zipfile) - else - nil - end - @temp_file = Tempfile.new(::File.basename(name), dirname) + @temp_file = Tempfile.new(::File.basename(name)) @temp_file.binmode end @@ -27,6 +22,7 @@ unless @temp_file.closed? raise StandardError, "cannot open entry for reading while its open for writing - #{name}" end + @temp_file.open # reopens tempfile from top @temp_file.binmode if block_given? @@ -40,9 +36,9 @@ end end - def write_to_zip_output_stream(aZipOutputStream) - aZipOutputStream.put_next_entry(self) - get_input_stream { |is| ::Zip::IOExtras.copy_stream(aZipOutputStream, is) } + def write_to_zip_output_stream(output_stream) + output_stream.put_next_entry(self) + get_input_stream { |is| ::Zip::IOExtras.copy_stream(output_stream, is) } end def clean_up diff -Nru ruby-zip-2.0.0/lib/zip/version.rb ruby-zip-2.3.0/lib/zip/version.rb --- ruby-zip-2.0.0/lib/zip/version.rb 2019-09-25 20:23:47.000000000 +0000 +++ ruby-zip-2.3.0/lib/zip/version.rb 2020-03-14 12:00:50.000000000 +0000 @@ -1,3 +1,3 @@ module Zip - VERSION = '2.0.0' + VERSION = '2.3.0' end diff -Nru ruby-zip-2.0.0/lib/zip.rb ruby-zip-2.3.0/lib/zip.rb --- ruby-zip-2.0.0/lib/zip.rb 2019-09-25 20:23:47.000000000 +0000 +++ ruby-zip-2.3.0/lib/zip.rb 2020-03-14 12:00:50.000000000 +0000 @@ -1,10 +1,11 @@ +require 'English' require 'delegate' require 'singleton' require 'tempfile' -require 'tmpdir' require 'fileutils' require 'stringio' require 'zlib' +require 'zip/constants' require 'zip/dos_time' require 'zip/ioextras' require 'rbconfig' @@ -22,6 +23,7 @@ require 'zip/null_input_stream' require 'zip/pass_thru_compressor' require 'zip/pass_thru_decompressor' +require 'zip/crypto/decrypted_io' require 'zip/crypto/encryption' require 'zip/crypto/null_encryption' require 'zip/crypto/traditional_encryption' @@ -29,7 +31,6 @@ require 'zip/deflater' require 'zip/streamable_stream' require 'zip/streamable_directory' -require 'zip/constants' require 'zip/errors' module Zip diff -Nru ruby-zip-2.0.0/Rakefile ruby-zip-2.3.0/Rakefile --- ruby-zip-2.0.0/Rakefile 2019-09-25 20:23:47.000000000 +0000 +++ ruby-zip-2.3.0/Rakefile 2020-03-14 12:00:50.000000000 +0000 @@ -1,5 +1,6 @@ require 'bundler/gem_tasks' require 'rake/testtask' +require 'rubocop/rake_task' task default: :test @@ -10,6 +11,8 @@ test.verbose = true end +RuboCop::RakeTask.new + # Rake::TestTask.new(:zip64_full_test) do |test| # test.libs << File.join(File.dirname(__FILE__), 'lib') # test.libs << File.join(File.dirname(__FILE__), 'test') diff -Nru ruby-zip-2.0.0/.rubocop_rubyzip.yml ruby-zip-2.3.0/.rubocop_rubyzip.yml --- ruby-zip-2.0.0/.rubocop_rubyzip.yml 2019-09-25 20:23:47.000000000 +0000 +++ ruby-zip-2.3.0/.rubocop_rubyzip.yml 1970-01-01 00:00:00.000000000 +0000 @@ -1,137 +0,0 @@ -# This configuration was generated by `rubocop --auto-gen-config` -# on 2015-06-08 10:22:52 +0300 using RuboCop version 0.32.0. -# The point is for the user to remove these configuration records -# one by one as the offenses are removed from the code base. -# Note that changes in the inspected code, or installation of new -# versions of RuboCop, may require this file to be generated again. - -# Offense count: 13 -Lint/HandleExceptions: - Enabled: false - -# Offense count: 1 -Lint/LiteralInCondition: - Enabled: false - -# Offense count: 1 -Lint/RescueException: - Enabled: false - -# Offense count: 1 -Lint/UselessComparison: - Enabled: false - -# Offense count: 115 -Metrics/AbcSize: - Max: 62 - -# Offense count: 12 -# Configuration parameters: CountComments. -Metrics/ClassLength: - Max: 562 - -# Offense count: 21 -Metrics/CyclomaticComplexity: - Max: 14 - -# Offense count: 237 -# Configuration parameters: AllowURI, URISchemes. -Metrics/LineLength: - Max: 236 - -# Offense count: 108 -# Configuration parameters: CountComments. -Metrics/MethodLength: - Max: 35 - -# Offense count: 2 -# Configuration parameters: CountKeywordArgs. -Metrics/ParameterLists: - Max: 10 - -# Offense count: 15 -Metrics/PerceivedComplexity: - Max: 15 - -# Offense count: 8 -Style/AccessorMethodName: - Enabled: false - -# Offense count: 23 -# Cop supports --auto-correct. -Style/Alias: - Enabled: false - -# Offense count: 1 -# Cop supports --auto-correct. -# Configuration parameters: EnforcedStyle, SupportedStyles, ProceduralMethods, FunctionalMethods, IgnoredMethods. -Style/BlockDelimiters: - Enabled: false - -# Offense count: 7 -# Configuration parameters: EnforcedStyle, SupportedStyles. -Style/ClassAndModuleChildren: - Enabled: false - -# Offense count: 15 -# Cop supports --auto-correct. -# Configuration parameters: EnforcedStyle, SupportedStyles. -Style/ClassCheck: - Enabled: false - -# Offense count: 77 -Style/Documentation: - Enabled: false - -# Offense count: 1 -# Cop supports --auto-correct. -Style/InfiniteLoop: - Enabled: false - -# Offense count: 1 -Style/ModuleFunction: - Enabled: false - -# Offense count: 1 -Style/MultilineBlockChain: - Enabled: false - -# Offense count: 3 -# Cop supports --auto-correct. -# Configuration parameters: EnforcedStyle, SupportedStyles, AllowInnerSlashes. -Style/RegexpLiteral: - Enabled: false - -# Offense count: 2 -# Cop supports --auto-correct. -# Configuration parameters: AllowAsExpressionSeparator. -Style/Semicolon: - Enabled: false - -# Offense count: 79 -# Cop supports --auto-correct. -# Configuration parameters: EnforcedStyle, SupportedStyles. -Style/SignalException: - Enabled: false - -# Offense count: 9 -# Cop supports --auto-correct. -# Configuration parameters: MultiSpaceAllowedForOperators. -Style/SpaceAroundOperators: - Enabled: false - -# Offense count: 30 -# Cop supports --auto-correct. -Style/SpecialGlobalVars: - Enabled: false - -# Offense count: 22 -# Cop supports --auto-correct. -# Configuration parameters: IgnoredMethods. -Style/SymbolProc: - Enabled: false - -# Offense count: 151 -# Configuration parameters: EnforcedStyle, SupportedStyles. -Style/VariableName: - Enabled: false diff -Nru ruby-zip-2.0.0/.rubocop_todo.yml ruby-zip-2.3.0/.rubocop_todo.yml --- ruby-zip-2.0.0/.rubocop_todo.yml 1970-01-01 00:00:00.000000000 +0000 +++ ruby-zip-2.3.0/.rubocop_todo.yml 2020-03-14 12:00:50.000000000 +0000 @@ -0,0 +1,138 @@ +# This configuration was generated by +# `rubocop --auto-gen-config` +# on 2020-02-08 14:58:51 +0000 using RuboCop version 0.79.0. +# The point is for the user to remove these configuration records +# one by one as the offenses are removed from the code base. +# Note that changes in the inspected code, or installation of new +# versions of RuboCop, may require this file to be generated again. + +# Offense count: 15 +# Configuration parameters: CountComments. +Metrics/ClassLength: + Max: 580 + +# Offense count: 26 +Metrics/CyclomaticComplexity: + Max: 14 + +# Offense count: 120 +# Configuration parameters: CountComments, ExcludedMethods. +Metrics/MethodLength: + Max: 30 + +# Offense count: 2 +# Configuration parameters: CountKeywordArgs. +Metrics/ParameterLists: + Max: 10 + +# Offense count: 21 +Metrics/PerceivedComplexity: + Max: 15 + +# Offense count: 9 +Naming/AccessorMethodName: + Exclude: + - 'lib/zip/entry.rb' + - 'lib/zip/filesystem.rb' + - 'lib/zip/input_stream.rb' + - 'lib/zip/streamable_stream.rb' + +# Offense count: 7 +# Configuration parameters: EnforcedStyle. +# SupportedStyles: inline, group +Style/AccessModifierDeclarations: + Exclude: + - 'lib/zip/central_directory.rb' + - 'lib/zip/extra_field/zip64.rb' + - 'lib/zip/filesystem.rb' + +# Offense count: 7 +# Cop supports --auto-correct. +# Configuration parameters: AutoCorrect, EnforcedStyle. +# SupportedStyles: nested, compact +Style/ClassAndModuleChildren: + Exclude: + - 'lib/zip/extra_field/generic.rb' + - 'lib/zip/extra_field/ntfs.rb' + - 'lib/zip/extra_field/old_unix.rb' + - 'lib/zip/extra_field/universal_time.rb' + - 'lib/zip/extra_field/unix.rb' + - 'lib/zip/extra_field/zip64.rb' + - 'lib/zip/extra_field/zip64_placeholder.rb' + +# Offense count: 26 +Style/Documentation: + Enabled: false + +# Offense count: 3 +# Configuration parameters: . +# SupportedStyles: annotated, template, unannotated +Style/FormatStringToken: + EnforcedStyle: unannotated + +# Offense count: 95 +# Cop supports --auto-correct. +# Configuration parameters: EnforcedStyle. +# SupportedStyles: always, never +Style/FrozenStringLiteralComment: + Enabled: false + +# Offense count: 17 +# Cop supports --auto-correct. +Style/IfUnlessModifier: + Exclude: + - 'lib/zip/entry.rb' + - 'lib/zip/extra_field/generic.rb' + - 'lib/zip/file.rb' + - 'lib/zip/filesystem.rb' + - 'lib/zip/input_stream.rb' + - 'lib/zip/pass_thru_decompressor.rb' + - 'lib/zip/streamable_stream.rb' + +# Offense count: 1 +# Cop supports --auto-correct. +# Configuration parameters: EnforcedStyle, Autocorrect. +# SupportedStyles: module_function, extend_self +Style/ModuleFunction: + Exclude: + - 'lib/zip.rb' + +# Offense count: 56 +# Cop supports --auto-correct. +# Configuration parameters: EnforcedStyle. +# SupportedStyles: literals, strict +Style/MutableConstant: + Enabled: false + +# Offense count: 23 +# Cop supports --auto-correct. +# Configuration parameters: AutoCorrect, EnforcedStyle, IgnoredMethods. +# SupportedStyles: predicate, comparison +Style/NumericPredicate: + Exclude: + - 'spec/**/*' + - 'lib/zip/entry.rb' + - 'lib/zip/extra_field/old_unix.rb' + - 'lib/zip/extra_field/universal_time.rb' + - 'lib/zip/extra_field/unix.rb' + - 'lib/zip/file.rb' + - 'lib/zip/filesystem.rb' + - 'lib/zip/input_stream.rb' + - 'lib/zip/ioextras.rb' + - 'lib/zip/ioextras/abstract_input_stream.rb' + - 'test/file_split_test.rb' + - 'test/test_helper.rb' + +# Offense count: 17 +# Cop supports --auto-correct. +# Configuration parameters: ConvertCodeThatCanStartToReturnNil, AllowedMethods. +# AllowedMethods: present?, blank?, presence, try, try! +Style/SafeNavigation: + Exclude: + - 'lib/zip/entry.rb' + - 'lib/zip/input_stream.rb' + - 'lib/zip/output_stream.rb' + - 'test/file_extract_test.rb' + - 'test/filesystem/file_nonmutating_test.rb' + - 'test/filesystem/file_stat_test.rb' + - 'test/test_helper.rb' diff -Nru ruby-zip-2.0.0/.rubocop.yml ruby-zip-2.3.0/.rubocop.yml --- ruby-zip-2.0.0/.rubocop.yml 2019-09-25 20:23:47.000000000 +0000 +++ ruby-zip-2.3.0/.rubocop.yml 2020-03-14 12:00:50.000000000 +0000 @@ -1,6 +1,78 @@ -inherit_from: - - .rubocop_rubyzip.yml +inherit_from: .rubocop_todo.yml + +# Set this to the minimum supported ruby in the gemspec. Otherwise +# we get errors if our ruby version doesn't match. AllCops: - TargetRubyVersion: 1.9 -Style/MutableConstant: - Enabled: false # Because some existent code relies on mutable constant + TargetRubyVersion: 2.4 + +Layout/HashAlignment: + EnforcedHashRocketStyle: table + EnforcedColonStyle: table + +# Set a workable line length, given the current state of the code, +# and turn off for the tests. +Layout/LineLength: + Max: 135 + Exclude: + - 'test/**/*.rb' + +# In some cases we just need to catch an exception, rather than +# actually handle it. Allow the tests to make use of this shortcut. +Lint/SuppressedException: + AllowComments: true + Exclude: + - 'test/**/*.rb' + +# Allow this "useless" test, as we are testing <=> here. +Lint/UselessComparison: + Exclude: + - 'test/entry_test.rb' + +# Turn off ABC metrics for the tests and set a workable max given +# the current state of the code. +Metrics/AbcSize: + Max: 37 + Exclude: + - 'test/**/*.rb' + +# Turn block length metrics off for the tests. +Metrics/BlockLength: + Exclude: + - 'test/**/*.rb' + +# Turn class length metrics off for the tests. +Metrics/ClassLength: + Exclude: + - 'test/**/*.rb' + +# Turn method length metrics off for the tests. +Metrics/MethodLength: + Exclude: + - 'test/**/*.rb' + +# Set a consistent way of checking types. +Style/ClassCheck: + EnforcedStyle: kind_of? + +# Allow this multi-line block chain as it actually reads better +# than the alternatives. +Style/MultilineBlockChain: + Exclude: + - 'lib/zip/crypto/traditional_encryption.rb' + +# Allow inner slashes when using // for regex literals. Allow the +# Guardfile to use a syntax that is more consistent with its own style. +Style/RegexpLiteral: + AllowInnerSlashes: true + Exclude: + - 'Guardfile' + +Style/SymbolArray: + EnforcedStyle: brackets + +# Turn this cop off for these files as it fires for objects without +# an empty? method. +Style/ZeroLengthPredicate: + Exclude: + - 'lib/zip/file.rb' + - 'lib/zip/input_stream.rb' diff -Nru ruby-zip-2.0.0/rubyzip.gemspec ruby-zip-2.3.0/rubyzip.gemspec --- ruby-zip-2.0.0/rubyzip.gemspec 2019-09-25 20:23:47.000000000 +0000 +++ ruby-zip-2.3.0/rubyzip.gemspec 2020-03-14 12:00:50.000000000 +0000 @@ -1,6 +1,4 @@ -#-*- encoding: utf-8 -*- - -lib = File.expand_path('../lib', __FILE__) +lib = File.expand_path('lib', __dir__) $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib) require 'zip/version' @@ -23,9 +21,9 @@ 'wiki_uri' => 'https://github.com/rubyzip/rubyzip/wiki' } s.required_ruby_version = '>= 2.4' - s.add_development_dependency 'rake', '~> 10.3' - s.add_development_dependency 'pry', '~> 0.10' - s.add_development_dependency 'minitest', '~> 5.4' s.add_development_dependency 'coveralls', '~> 0.7' - s.add_development_dependency 'rubocop', '~> 0.49.1' + s.add_development_dependency 'minitest', '~> 5.4' + s.add_development_dependency 'pry', '~> 0.10' + s.add_development_dependency 'rake', '~> 12.3', '>= 12.3.3' + s.add_development_dependency 'rubocop', '~> 0.79' end diff -Nru ruby-zip-2.0.0/samples/example_filesystem.rb ruby-zip-2.3.0/samples/example_filesystem.rb --- ruby-zip-2.0.0/samples/example_filesystem.rb 2019-09-25 20:23:47.000000000 +0000 +++ ruby-zip-2.3.0/samples/example_filesystem.rb 2020-03-14 12:00:50.000000000 +0000 @@ -1,6 +1,6 @@ #!/usr/bin/env ruby -$: << '../lib' +$LOAD_PATH << '../lib' require 'zip/filesystem' diff -Nru ruby-zip-2.0.0/samples/example.rb ruby-zip-2.3.0/samples/example.rb --- ruby-zip-2.0.0/samples/example.rb 2019-09-25 20:23:47.000000000 +0000 +++ ruby-zip-2.3.0/samples/example.rb 2020-03-14 12:00:50.000000000 +0000 @@ -1,6 +1,6 @@ #!/usr/bin/env ruby -$: << '../lib' +$LOAD_PATH << '../lib' system('zip example.zip example.rb gtk_ruby_zip.rb') require 'zip' @@ -71,7 +71,7 @@ # Track splitting an archive Zip::File.split('large_zip_file.zip', 1_048_576, true, 'part_zip_file') do |part_count, part_index, chunk_bytes, segment_bytes| - puts "#{part_index} of #{part_count} part splitting: #{(chunk_bytes.to_f / segment_bytes.to_f * 100).to_i}%" + puts "#{part_index} of #{part_count} part splitting: #{(chunk_bytes.to_f / segment_bytes * 100).to_i}%" end # For other examples, look at zip.rb and ziptest.rb diff -Nru ruby-zip-2.0.0/samples/gtk_ruby_zip.rb ruby-zip-2.3.0/samples/gtk_ruby_zip.rb --- ruby-zip-2.0.0/samples/gtk_ruby_zip.rb 2019-09-25 20:23:47.000000000 +0000 +++ ruby-zip-2.3.0/samples/gtk_ruby_zip.rb 2020-03-14 12:00:50.000000000 +0000 @@ -1,6 +1,6 @@ #!/usr/bin/env ruby -$: << '../lib' +$LOAD_PATH << '../lib' $VERBOSE = true @@ -18,14 +18,14 @@ add(box) @zipfile = nil - @buttonPanel = ButtonPanel.new - @buttonPanel.openButton.signal_connect(Gtk::Button::SIGNAL_CLICKED) do + @button_panel = ButtonPanel.new + @button_panel.open_button.signal_connect(Gtk::Button::SIGNAL_CLICKED) do show_file_selector end - @buttonPanel.extractButton.signal_connect(Gtk::Button::SIGNAL_CLICKED) do + @button_panel.extract_button.signal_connect(Gtk::Button::SIGNAL_CLICKED) do puts 'Not implemented!' end - box.pack_start(@buttonPanel, false, false, 0) + box.pack_start(@button_panel, false, false, 0) sw = Gtk::ScrolledWindow.new sw.set_policy(Gtk::POLICY_AUTOMATIC, Gtk::POLICY_AUTOMATIC) @@ -42,27 +42,27 @@ end class ButtonPanel < Gtk::HButtonBox - attr_reader :openButton, :extractButton + attr_reader :open_button, :extract_button def initialize super set_layout(Gtk::BUTTONBOX_START) set_spacing(0) - @openButton = Gtk::Button.new('Open archive') - @extractButton = Gtk::Button.new('Extract entry') - pack_start(@openButton) - pack_start(@extractButton) + @open_button = Gtk::Button.new('Open archive') + @extract_button = Gtk::Button.new('Extract entry') + pack_start(@open_button) + pack_start(@extract_button) end end def show_file_selector - @fileSelector = Gtk::FileSelection.new('Open zip file') - @fileSelector.show - @fileSelector.ok_button.signal_connect(Gtk::Button::SIGNAL_CLICKED) do - open_zip(@fileSelector.filename) - @fileSelector.destroy + @file_selector = Gtk::FileSelection.new('Open zip file') + @file_selector.show + @file_selector.ok_button.signal_connect(Gtk::Button::SIGNAL_CLICKED) do + open_zip(@file_selector.filename) + @file_selector.destroy end - @fileSelector.cancel_button.signal_connect(Gtk::Button::SIGNAL_CLICKED) do - @fileSelector.destroy + @file_selector.cancel_button.signal_connect(Gtk::Button::SIGNAL_CLICKED) do + @file_selector.destroy end end @@ -77,8 +77,8 @@ end end -mainApp = MainApp.new +main_app = MainApp.new -mainApp.show_all +main_app.show_all Gtk.main diff -Nru ruby-zip-2.0.0/samples/qtzip.rb ruby-zip-2.3.0/samples/qtzip.rb --- ruby-zip-2.0.0/samples/qtzip.rb 2019-09-25 20:23:47.000000000 +0000 +++ ruby-zip-2.3.0/samples/qtzip.rb 2020-03-14 12:00:50.000000000 +0000 @@ -2,7 +2,7 @@ $VERBOSE = true -$: << '../lib' +$LOAD_PATH << '../lib' require 'Qt' system('rbuic -o zipdialogui.rb zipdialogui.ui') @@ -20,12 +20,12 @@ self, SLOT('extract_files()')) end - def zipfile(&proc) - Zip::File.open(@zip_filename, &proc) + def zipfile(&a_proc) + Zip::File.open(@zip_filename, &a_proc) end - def each(&proc) - Zip::File.foreach(@zip_filename, &proc) + def each(&a_proc) + Zip::File.foreach(@zip_filename, &a_proc) end def refresh @@ -80,7 +80,7 @@ end unless ARGV[0] - puts "usage: #{$0} zipname" + puts "usage: #{$PROGRAM_NAME} zipname" exit end diff -Nru ruby-zip-2.0.0/samples/write_simple.rb ruby-zip-2.3.0/samples/write_simple.rb --- ruby-zip-2.0.0/samples/write_simple.rb 2019-09-25 20:23:47.000000000 +0000 +++ ruby-zip-2.3.0/samples/write_simple.rb 2020-03-14 12:00:50.000000000 +0000 @@ -1,12 +1,10 @@ #!/usr/bin/env ruby -$: << '../lib' +$LOAD_PATH << '../lib' require 'zip' -include Zip - -OutputStream.open('simple.zip') do |zos| +::Zip::OutputStream.open('simple.zip') do |zos| zos.put_next_entry 'entry.txt' zos.puts 'Hello world' end diff -Nru ruby-zip-2.0.0/samples/zipfind.rb ruby-zip-2.3.0/samples/zipfind.rb --- ruby-zip-2.0.0/samples/zipfind.rb 2019-09-25 20:23:47.000000000 +0000 +++ ruby-zip-2.3.0/samples/zipfind.rb 2020-03-14 12:00:50.000000000 +0000 @@ -2,36 +2,37 @@ $VERBOSE = true -$: << '../lib' +$LOAD_PATH << '../lib' require 'zip' require 'find' module Zip module ZipFind - def self.find(path, zipFilePattern = /\.zip$/i) - Find.find(path) do |fileName| - yield(fileName) - next unless zipFilePattern.match(fileName) && File.file?(fileName) + def self.find(path, zip_file_pattern = /\.zip$/i) + Find.find(path) do |filename| + yield(filename) + next unless zip_file_pattern.match(filename) && File.file?(filename) + begin - Zip::File.foreach(fileName) do |zipEntry| - yield(fileName + File::SEPARATOR + zipEntry.to_s) + Zip::File.foreach(filename) do |entry| + yield(filename + File::SEPARATOR + entry.to_s) end - rescue Errno::EACCES => ex - puts ex + rescue Errno::EACCES => e + puts e end end end - def self.find_file(path, fileNamePattern, zipFilePattern = /\.zip$/i) - find(path, zipFilePattern) do |fileName| - yield(fileName) if fileNamePattern.match(fileName) + def self.find_file(path, filename_pattern, zip_file_pattern = /\.zip$/i) + find(path, zip_file_pattern) do |filename| + yield(filename) if filename_pattern.match(filename) end end end end -if $0 == __FILE__ +if $PROGRAM_NAME == __FILE__ module ZipFindConsoleRunner PATH_ARG_INDEX = 0 FILENAME_PATTERN_ARG_INDEX = 1 @@ -41,24 +42,24 @@ check_args(args) Zip::ZipFind.find_file(args[PATH_ARG_INDEX], args[FILENAME_PATTERN_ARG_INDEX], - args[ZIPFILE_PATTERN_ARG_INDEX]) do |fileName| - report_entry_found fileName + args[ZIPFILE_PATTERN_ARG_INDEX]) do |filename| + report_entry_found filename end end def self.check_args(args) - if args.size != 3 - usage - exit - end + return if args.size == 3 + + usage + exit end def self.usage - puts "Usage: #{$0} PATH ZIPFILENAME_PATTERN FILNAME_PATTERN" + puts "Usage: #{$PROGRAM_NAME} PATH ZIPFILENAME_PATTERN FILNAME_PATTERN" end - def self.report_entry_found(fileName) - puts fileName + def self.report_entry_found(filename) + puts filename end end diff -Nru ruby-zip-2.0.0/test/basic_zip_file_test.rb ruby-zip-2.3.0/test/basic_zip_file_test.rb --- ruby-zip-2.0.0/test/basic_zip_file_test.rb 2019-09-25 20:23:47.000000000 +0000 +++ ruby-zip-2.3.0/test/basic_zip_file_test.rb 2020-03-14 12:00:50.000000000 +0000 @@ -5,12 +5,11 @@ def setup @zip_file = ::Zip::File.new(TestZipFile::TEST_ZIP2.zip_name) - @testEntryNameIndex = 0 end def test_entries assert_equal(TestZipFile::TEST_ZIP2.entry_names.sort, - @zip_file.entries.entries.sort.map { |e| e.name }) + @zip_file.entries.entries.sort.map(&:name)) end def test_each @@ -50,11 +49,9 @@ end def test_get_input_stream_block - fileAndEntryName = @zip_file.entries.first.name - @zip_file.get_input_stream(fileAndEntryName) do |zis| - assert_entry_contents_for_stream(fileAndEntryName, - zis, - fileAndEntryName) + name = @zip_file.entries.first.name + @zip_file.get_input_stream(name) do |zis| + assert_entry_contents_for_stream(name, zis, name) end end end diff -Nru ruby-zip-2.0.0/test/bzip2_support_test.rb ruby-zip-2.3.0/test/bzip2_support_test.rb --- ruby-zip-2.0.0/test/bzip2_support_test.rb 1970-01-01 00:00:00.000000000 +0000 +++ ruby-zip-2.3.0/test/bzip2_support_test.rb 2020-03-14 12:00:50.000000000 +0000 @@ -0,0 +1,11 @@ +require 'test_helper' + +class Bzip2SupportTest < MiniTest::Test + BZIP2_ZIP_TEST_FILE = 'test/data/zipWithBzip2Compression.zip' + + def test_read + Zip::InputStream.open(BZIP2_ZIP_TEST_FILE) do |zis| + assert_raises(Zip::CompressionMethodError) { zis.get_next_entry } + end + end +end diff -Nru ruby-zip-2.0.0/test/case_sensitivity_test.rb ruby-zip-2.3.0/test/case_sensitivity_test.rb --- ruby-zip-2.0.0/test/case_sensitivity_test.rb 2019-09-25 20:23:47.000000000 +0000 +++ ruby-zip-2.3.0/test/case_sensitivity_test.rb 2020-03-14 12:00:50.000000000 +0000 @@ -20,13 +20,13 @@ SRC_FILES.each { |fn, en| zf.add(en, fn) } zf.close - zfRead = ::Zip::File.new(EMPTY_FILENAME) - assert_equal(SRC_FILES.size, zfRead.entries.length) - SRC_FILES.each_with_index { |a, i| - assert_equal(a.last, zfRead.entries[i].name) + zf_read = ::Zip::File.new(EMPTY_FILENAME) + assert_equal(SRC_FILES.size, zf_read.entries.length) + SRC_FILES.each_with_index do |a, i| + assert_equal(a.last, zf_read.entries[i].name) AssertEntry.assert_contents(a.first, - zfRead.get_input_stream(a.last) { |zis| zis.read }) - } + zf_read.get_input_stream(a.last, &:read)) + end end # Ensure that names are treated case insensitively when adding files and +case_insensitive_match = false+ @@ -53,17 +53,21 @@ ::Zip.case_insensitive_match = true - zfRead = ::Zip::File.new(EMPTY_FILENAME) - assert_equal(SRC_FILES.collect { |_fn, en| en.downcase }.uniq.size, zfRead.entries.length) - assert_equal(SRC_FILES.last.last.downcase, zfRead.entries.first.name.downcase) - AssertEntry.assert_contents(SRC_FILES.last.first, - zfRead.get_input_stream(SRC_FILES.last.last) { |zis| zis.read }) + zf_read = ::Zip::File.new(EMPTY_FILENAME) + assert_equal(SRC_FILES.collect { |_fn, en| en.downcase }.uniq.size, zf_read.entries.length) + assert_equal(SRC_FILES.last.last.downcase, zf_read.entries.first.name.downcase) + AssertEntry.assert_contents( + SRC_FILES.last.first, zf_read.get_input_stream(SRC_FILES.last.last, &:read) + ) end private - def assert_contains(zf, entryName, filename = entryName) - assert(zf.entries.detect { |e| e.name == entryName } != nil, "entry #{entryName} not in #{zf.entries.join(', ')} in zip file #{zf}") - assert_entry_contents(zf, entryName, filename) if File.exist?(filename) + def assert_contains(zip_file, entry_name, filename = entry_name) + refute_nil( + zip_file.entries.detect { |e| e.name == entry_name }, + "entry #{entry_name} not in #{zip_file.entries.join(', ')} in zip file #{zip_file}" + ) + assert_entry_contents(zip_file, entry_name, filename) if File.exist?(filename) end end diff -Nru ruby-zip-2.0.0/test/central_directory_entry_test.rb ruby-zip-2.3.0/test/central_directory_entry_test.rb --- ruby-zip-2.0.0/test/central_directory_entry_test.rb 2019-09-25 20:23:47.000000000 +0000 +++ ruby-zip-2.3.0/test/central_directory_entry_test.rb 2020-03-14 12:00:50.000000000 +0000 @@ -63,7 +63,7 @@ fragment.extend(IOizeString) entry = ::Zip::Entry.new entry.read_c_dir_entry(fragment) - fail 'ZipError expected' + raise 'ZipError expected' rescue ::Zip::Error end end diff -Nru ruby-zip-2.0.0/test/central_directory_test.rb ruby-zip-2.3.0/test/central_directory_test.rb --- ruby-zip-2.0.0/test/central_directory_test.rb 2019-09-25 20:23:47.000000000 +0000 +++ ruby-zip-2.3.0/test/central_directory_test.rb 2020-03-14 12:00:50.000000000 +0000 @@ -6,23 +6,23 @@ end def test_read_from_stream - ::File.open(TestZipFile::TEST_ZIP2.zip_name, 'rb') do |zipFile| - cdir = ::Zip::CentralDirectory.read_from_stream(zipFile) + ::File.open(TestZipFile::TEST_ZIP2.zip_name, 'rb') do |zip_file| + cdir = ::Zip::CentralDirectory.read_from_stream(zip_file) assert_equal(TestZipFile::TEST_ZIP2.entry_names.size, cdir.size) - assert(cdir.entries.sort.compare_enumerables(TestZipFile::TEST_ZIP2.entry_names.sort) do |cdirEntry, testEntryName| - cdirEntry.name == testEntryName + assert(cdir.entries.sort.compare_enumerables(TestZipFile::TEST_ZIP2.entry_names.sort) do |cdir_entry, test_entry_name| + cdir_entry.name == test_entry_name end) assert_equal(TestZipFile::TEST_ZIP2.comment, cdir.comment) end end def test_read_from_invalid_stream - File.open('test/data/file2.txt', 'rb') do |zipFile| + File.open('test/data/file2.txt', 'rb') do |zip_file| cdir = ::Zip::CentralDirectory.new - cdir.read_from_stream(zipFile) + cdir.read_from_stream(zip_file) end - fail 'ZipError expected!' + raise 'ZipError expected!' rescue ::Zip::Error end @@ -33,7 +33,7 @@ fragment.extend(IOizeString) entry = ::Zip::CentralDirectory.new entry.read_from_stream(fragment) - fail 'ZipError expected' + raise 'ZipError expected' rescue ::Zip::Error end @@ -41,12 +41,18 @@ entries = [::Zip::Entry.new('file.zip', 'flimse', 'myComment', 'somethingExtra'), ::Zip::Entry.new('file.zip', 'secondEntryName'), ::Zip::Entry.new('file.zip', 'lastEntry.txt', 'Has a comment too')] + cdir = ::Zip::CentralDirectory.new(entries, 'my zip comment') - File.open('test/data/generated/cdirtest.bin', 'wb') { |f| cdir.write_to_stream(f) } - cdirReadback = ::Zip::CentralDirectory.new - File.open('test/data/generated/cdirtest.bin', 'rb') { |f| cdirReadback.read_from_stream(f) } + File.open('test/data/generated/cdirtest.bin', 'wb') do |f| + cdir.write_to_stream(f) + end + + cdir_readback = ::Zip::CentralDirectory.new + File.open('test/data/generated/cdirtest.bin', 'rb') do |f| + cdir_readback.read_from_stream(f) + end - assert_equal(cdir.entries.sort, cdirReadback.entries.sort) + assert_equal(cdir.entries.sort, cdir_readback.entries.sort) end def test_write64_to_stream @@ -58,13 +64,19 @@ [0, 250, 18_000_000_300, 33_000_000_350].each_with_index do |offset, index| entries[index].local_header_offset = offset end + cdir = ::Zip::CentralDirectory.new(entries, 'zip comment') - File.open('test/data/generated/cdir64test.bin', 'wb') { |f| cdir.write_to_stream(f) } - cdirReadback = ::Zip::CentralDirectory.new - File.open('test/data/generated/cdir64test.bin', 'rb') { |f| cdirReadback.read_from_stream(f) } + File.open('test/data/generated/cdir64test.bin', 'wb') do |f| + cdir.write_to_stream(f) + end + + cdir_readback = ::Zip::CentralDirectory.new + File.open('test/data/generated/cdir64test.bin', 'rb') do |f| + cdir_readback.read_from_stream(f) + end - assert_equal(cdir.entries.sort, cdirReadback.entries.sort) - assert_equal(::Zip::VERSION_NEEDED_TO_EXTRACT_ZIP64, cdirReadback.instance_variable_get(:@version_needed_for_extract)) + assert_equal(cdir.entries.sort, cdir_readback.entries.sort) + assert_equal(::Zip::VERSION_NEEDED_TO_EXTRACT_ZIP64, cdir_readback.instance_variable_get(:@version_needed_for_extract)) end def test_equality diff -Nru ruby-zip-2.0.0/test/constants_test.rb ruby-zip-2.3.0/test/constants_test.rb --- ruby-zip-2.0.0/test/constants_test.rb 1970-01-01 00:00:00.000000000 +0000 +++ ruby-zip-2.3.0/test/constants_test.rb 2020-03-14 12:00:50.000000000 +0000 @@ -0,0 +1,45 @@ +require 'test_helper' + +class ConstantsTest < MiniTest::Test + def test_compression_methods + assert_equal(0, Zip::COMPRESSION_METHOD_STORE) + assert_equal(1, Zip::COMPRESSION_METHOD_SHRINK) + assert_equal(2, Zip::COMPRESSION_METHOD_REDUCE_1) + assert_equal(3, Zip::COMPRESSION_METHOD_REDUCE_2) + assert_equal(4, Zip::COMPRESSION_METHOD_REDUCE_3) + assert_equal(5, Zip::COMPRESSION_METHOD_REDUCE_4) + assert_equal(6, Zip::COMPRESSION_METHOD_IMPLODE) + assert_equal(8, Zip::COMPRESSION_METHOD_DEFLATE) + assert_equal(9, Zip::COMPRESSION_METHOD_DEFLATE_64) + assert_equal(10, Zip::COMPRESSION_METHOD_PKWARE_DCLI) + assert_equal(12, Zip::COMPRESSION_METHOD_BZIP2) + assert_equal(14, Zip::COMPRESSION_METHOD_LZMA) + assert_equal(16, Zip::COMPRESSION_METHOD_IBM_CMPSC) + assert_equal(18, Zip::COMPRESSION_METHOD_IBM_TERSE) + assert_equal(19, Zip::COMPRESSION_METHOD_IBM_LZ77) + assert_equal(96, Zip::COMPRESSION_METHOD_JPEG) + assert_equal(97, Zip::COMPRESSION_METHOD_WAVPACK) + assert_equal(98, Zip::COMPRESSION_METHOD_PPMD) + assert_equal(99, Zip::COMPRESSION_METHOD_AES) + + assert(Zip::COMPRESSION_METHODS[Zip::COMPRESSION_METHOD_STORE]) + assert(Zip::COMPRESSION_METHODS[Zip::COMPRESSION_METHOD_SHRINK]) + assert(Zip::COMPRESSION_METHODS[Zip::COMPRESSION_METHOD_REDUCE_1]) + assert(Zip::COMPRESSION_METHODS[Zip::COMPRESSION_METHOD_REDUCE_2]) + assert(Zip::COMPRESSION_METHODS[Zip::COMPRESSION_METHOD_REDUCE_3]) + assert(Zip::COMPRESSION_METHODS[Zip::COMPRESSION_METHOD_REDUCE_4]) + assert(Zip::COMPRESSION_METHODS[Zip::COMPRESSION_METHOD_IMPLODE]) + assert(Zip::COMPRESSION_METHODS[Zip::COMPRESSION_METHOD_DEFLATE]) + assert(Zip::COMPRESSION_METHODS[Zip::COMPRESSION_METHOD_DEFLATE_64]) + assert(Zip::COMPRESSION_METHODS[Zip::COMPRESSION_METHOD_PKWARE_DCLI]) + assert(Zip::COMPRESSION_METHODS[Zip::COMPRESSION_METHOD_BZIP2]) + assert(Zip::COMPRESSION_METHODS[Zip::COMPRESSION_METHOD_LZMA]) + assert(Zip::COMPRESSION_METHODS[Zip::COMPRESSION_METHOD_IBM_CMPSC]) + assert(Zip::COMPRESSION_METHODS[Zip::COMPRESSION_METHOD_IBM_TERSE]) + assert(Zip::COMPRESSION_METHODS[Zip::COMPRESSION_METHOD_IBM_LZ77]) + assert(Zip::COMPRESSION_METHODS[Zip::COMPRESSION_METHOD_JPEG]) + assert(Zip::COMPRESSION_METHODS[Zip::COMPRESSION_METHOD_WAVPACK]) + assert(Zip::COMPRESSION_METHODS[Zip::COMPRESSION_METHOD_PPMD]) + assert(Zip::COMPRESSION_METHODS[Zip::COMPRESSION_METHOD_AES]) + end +end Binary files /tmp/tmpnxqv03ab/1qH059NAFw/ruby-zip-2.0.0/test/data/file1.txt.corrupt.deflatedData and /tmp/tmpnxqv03ab/Ko8li5tL5c/ruby-zip-2.3.0/test/data/file1.txt.corrupt.deflatedData differ Binary files /tmp/tmpnxqv03ab/1qH059NAFw/ruby-zip-2.0.0/test/data/zipWithBzip2Compression.zip and /tmp/tmpnxqv03ab/Ko8li5tL5c/ruby-zip-2.3.0/test/data/zipWithBzip2Compression.zip differ Binary files /tmp/tmpnxqv03ab/1qH059NAFw/ruby-zip-2.0.0/test/data/zipWithStoredCompressionAndEncryption.zip and /tmp/tmpnxqv03ab/Ko8li5tL5c/ruby-zip-2.3.0/test/data/zipWithStoredCompressionAndEncryption.zip differ Binary files /tmp/tmpnxqv03ab/1qH059NAFw/ruby-zip-2.0.0/test/data/zipWithStoredCompression.zip and /tmp/tmpnxqv03ab/Ko8li5tL5c/ruby-zip-2.3.0/test/data/zipWithStoredCompression.zip differ diff -Nru ruby-zip-2.0.0/test/decompressor_test.rb ruby-zip-2.3.0/test/decompressor_test.rb --- ruby-zip-2.0.0/test/decompressor_test.rb 1970-01-01 00:00:00.000000000 +0000 +++ ruby-zip-2.3.0/test/decompressor_test.rb 2020-03-14 12:00:50.000000000 +0000 @@ -0,0 +1,15 @@ +require 'test_helper' +class DecompressorTest < MiniTest::Test + TEST_COMPRESSION_METHOD = 255 + + class TestCompressionClass + end + + def test_decompressor_registration + assert_nil(::Zip::Decompressor.find_by_compression_method(TEST_COMPRESSION_METHOD)) + + ::Zip::Decompressor.register(TEST_COMPRESSION_METHOD, TestCompressionClass) + + assert_equal(TestCompressionClass, ::Zip::Decompressor.find_by_compression_method(TEST_COMPRESSION_METHOD)) + end +end diff -Nru ruby-zip-2.0.0/test/deflater_test.rb ruby-zip-2.3.0/test/deflater_test.rb --- ruby-zip-2.0.0/test/deflater_test.rb 2019-09-25 20:23:47.000000000 +0000 +++ ruby-zip-2.3.0/test/deflater_test.rb 2020-03-14 12:00:50.000000000 +0000 @@ -11,8 +11,8 @@ def test_output_operator txt = load_file('test/data/file2.txt') deflate(txt, DEFLATER_TEST_FILE) - inflatedTxt = inflate(DEFLATER_TEST_FILE) - assert_equal(txt, inflatedTxt) + inflated_txt = inflate(DEFLATER_TEST_FILE) + assert_equal(txt, inflated_txt) end def test_default_compression @@ -34,15 +34,20 @@ assert(default < no) end + def test_data_error + assert_raises(::Zip::DecompressionError) do + inflate('test/data/file1.txt.corrupt.deflatedData') + end + end + private - def load_file(fileName) - txt = nil - File.open(fileName, 'rb') { |f| txt = f.read } + def load_file(filename) + File.open(filename, 'rb', &:read) end - def deflate(data, fileName) - File.open(fileName, 'wb') do |file| + def deflate(data, filename) + File.open(filename, 'wb') do |file| deflater = ::Zip::Deflater.new(file) deflater << data deflater.finish @@ -51,11 +56,10 @@ end end - def inflate(fileName) - txt = nil - File.open(fileName, 'rb') do |file| + def inflate(filename) + File.open(filename, 'rb') do |file| inflater = ::Zip::Inflater.new(file) - txt = inflater.sysread + inflater.read end end diff -Nru ruby-zip-2.0.0/test/encryption_test.rb ruby-zip-2.3.0/test/encryption_test.rb --- ruby-zip-2.0.0/test/encryption_test.rb 2019-09-25 20:23:47.000000000 +0000 +++ ruby-zip-2.3.0/test/encryption_test.rb 2020-03-14 12:00:50.000000000 +0000 @@ -14,14 +14,14 @@ end def test_encrypt - test_file = open(ENCRYPT_ZIP_TEST_FILE, 'rb').read + test_file = ::File.open(ENCRYPT_ZIP_TEST_FILE, 'rb').read @rand = [250, 143, 107, 13, 143, 22, 155, 75, 228, 150, 12] @output = ::Zip::DOSTime.stub(:now, ::Zip::DOSTime.new(2014, 12, 17, 15, 56, 24)) do Random.stub(:rand, ->(_range) { @rand.shift }) do Zip::OutputStream.write_buffer(::StringIO.new(''), Zip::TraditionalEncrypter.new('password')) do |zos| zos.put_next_entry('file1.txt') - zos.write open(INPUT_FILE1).read + zos.write ::File.open(INPUT_FILE1).read end.string end end @@ -36,7 +36,7 @@ entry = zis.get_next_entry assert_equal 'file1.txt', entry.name assert_equal 1327, entry.size - assert_equal open(INPUT_FILE1, 'r').read, zis.read + assert_equal ::File.open(INPUT_FILE1, 'r').read, zis.read end end end diff -Nru ruby-zip-2.0.0/test/entry_set_test.rb ruby-zip-2.3.0/test/entry_set_test.rb --- ruby-zip-2.0.0/test/entry_set_test.rb 2019-09-25 20:23:47.000000000 +0000 +++ ruby-zip-2.3.0/test/entry_set_test.rb 2020-03-14 12:00:50.000000000 +0000 @@ -11,7 +11,7 @@ ] def setup - @zipEntrySet = ::Zip::EntrySet.new(ZIP_ENTRIES) + @zip_entry_set = ::Zip::EntrySet.new(ZIP_ENTRIES) end def teardown @@ -19,15 +19,15 @@ end def test_include - assert(@zipEntrySet.include?(ZIP_ENTRIES.first)) - assert(!@zipEntrySet.include?(::Zip::Entry.new('different.zip', 'different', 'aComment'))) + assert(@zip_entry_set.include?(ZIP_ENTRIES.first)) + assert(!@zip_entry_set.include?(::Zip::Entry.new('different.zip', 'different', 'aComment'))) end def test_size - assert_equal(ZIP_ENTRIES.size, @zipEntrySet.size) - assert_equal(ZIP_ENTRIES.size, @zipEntrySet.length) - @zipEntrySet << ::Zip::Entry.new('a', 'b', 'c') - assert_equal(ZIP_ENTRIES.size + 1, @zipEntrySet.length) + assert_equal(ZIP_ENTRIES.size, @zip_entry_set.size) + assert_equal(ZIP_ENTRIES.size, @zip_entry_set.length) + @zip_entry_set << ::Zip::Entry.new('a', 'b', 'c') + assert_equal(ZIP_ENTRIES.size + 1, @zip_entry_set.length) end def test_add @@ -41,20 +41,20 @@ end def test_delete - assert_equal(ZIP_ENTRIES.size, @zipEntrySet.size) - entry = @zipEntrySet.delete(ZIP_ENTRIES.first) - assert_equal(ZIP_ENTRIES.size - 1, @zipEntrySet.size) + assert_equal(ZIP_ENTRIES.size, @zip_entry_set.size) + entry = @zip_entry_set.delete(ZIP_ENTRIES.first) + assert_equal(ZIP_ENTRIES.size - 1, @zip_entry_set.size) assert_equal(ZIP_ENTRIES.first, entry) - entry = @zipEntrySet.delete(ZIP_ENTRIES.first) - assert_equal(ZIP_ENTRIES.size - 1, @zipEntrySet.size) + entry = @zip_entry_set.delete(ZIP_ENTRIES.first) + assert_equal(ZIP_ENTRIES.size - 1, @zip_entry_set.size) assert_nil(entry) end def test_each # Used each instead each_with_index due the bug in jRuby count = 0 - @zipEntrySet.each do |entry| + @zip_entry_set.each do |entry| assert(ZIP_ENTRIES.include?(entry)) count += 1 end @@ -62,57 +62,57 @@ end def test_entries - assert_equal(ZIP_ENTRIES, @zipEntrySet.entries) + assert_equal(ZIP_ENTRIES, @zip_entry_set.entries) end def test_find_entry entries = [::Zip::Entry.new('zipfile.zip', 'MiXeDcAsEnAmE', 'comment1')] ::Zip.case_insensitive_match = true - zipEntrySet = ::Zip::EntrySet.new(entries) - assert_equal(entries[0], zipEntrySet.find_entry('MiXeDcAsEnAmE')) - assert_equal(entries[0], zipEntrySet.find_entry('mixedcasename')) + zip_entry_set = ::Zip::EntrySet.new(entries) + assert_equal(entries[0], zip_entry_set.find_entry('MiXeDcAsEnAmE')) + assert_equal(entries[0], zip_entry_set.find_entry('mixedcasename')) ::Zip.case_insensitive_match = false - zipEntrySet = ::Zip::EntrySet.new(entries) - assert_equal(entries[0], zipEntrySet.find_entry('MiXeDcAsEnAmE')) - assert_nil(zipEntrySet.find_entry('mixedcasename')) + zip_entry_set = ::Zip::EntrySet.new(entries) + assert_equal(entries[0], zip_entry_set.find_entry('MiXeDcAsEnAmE')) + assert_nil(zip_entry_set.find_entry('mixedcasename')) end def test_entries_with_sort ::Zip.sort_entries = true - assert_equal(ZIP_ENTRIES.sort, @zipEntrySet.entries) + assert_equal(ZIP_ENTRIES.sort, @zip_entry_set.entries) ::Zip.sort_entries = false - assert_equal(ZIP_ENTRIES, @zipEntrySet.entries) + assert_equal(ZIP_ENTRIES, @zip_entry_set.entries) end def test_entries_sorted_in_each ::Zip.sort_entries = true arr = [] - @zipEntrySet.each do |entry| + @zip_entry_set.each do |entry| arr << entry end assert_equal(ZIP_ENTRIES.sort, arr) end def test_compound - newEntry = ::Zip::Entry.new('zf.zip', 'new entry', "new entry's comment") - assert_equal(ZIP_ENTRIES.size, @zipEntrySet.size) - @zipEntrySet << newEntry - assert_equal(ZIP_ENTRIES.size + 1, @zipEntrySet.size) - assert(@zipEntrySet.include?(newEntry)) + new_entry = ::Zip::Entry.new('zf.zip', 'new entry', "new entry's comment") + assert_equal(ZIP_ENTRIES.size, @zip_entry_set.size) + @zip_entry_set << new_entry + assert_equal(ZIP_ENTRIES.size + 1, @zip_entry_set.size) + assert(@zip_entry_set.include?(new_entry)) - @zipEntrySet.delete(newEntry) - assert_equal(ZIP_ENTRIES.size, @zipEntrySet.size) + @zip_entry_set.delete(new_entry) + assert_equal(ZIP_ENTRIES.size, @zip_entry_set.size) end def test_dup - copy = @zipEntrySet.dup - assert_equal(@zipEntrySet, copy) + copy = @zip_entry_set.dup + assert_equal(@zip_entry_set, copy) # demonstrate that this is a deep copy copy.entries[0].name = 'a totally different name' - assert(@zipEntrySet != copy) + assert(@zip_entry_set != copy) end def test_parent @@ -121,15 +121,15 @@ ::Zip::Entry.new('zf.zip', 'a/b/'), ::Zip::Entry.new('zf.zip', 'a/b/c/') ] - entrySet = ::Zip::EntrySet.new(entries) + entry_set = ::Zip::EntrySet.new(entries) - assert_nil(entrySet.parent(entries[0])) - assert_equal(entries[0], entrySet.parent(entries[1])) - assert_equal(entries[1], entrySet.parent(entries[2])) + assert_nil(entry_set.parent(entries[0])) + assert_equal(entries[0], entry_set.parent(entries[1])) + assert_equal(entries[1], entry_set.parent(entries[2])) end def test_glob - res = @zipEntrySet.glob('name[2-4]') + res = @zip_entry_set.glob('name[2-4]') assert_equal(3, res.size) assert_equal(ZIP_ENTRIES[1, 3].sort, res.sort) end @@ -141,13 +141,13 @@ ::Zip::Entry.new('zf.zip', 'a/b/c/'), ::Zip::Entry.new('zf.zip', 'a/b/c/c1') ] - entrySet = ::Zip::EntrySet.new(entries) + entry_set = ::Zip::EntrySet.new(entries) - assert_equal(entries[0, 1], entrySet.glob('*')) - # assert_equal(entries[FIXME], entrySet.glob("**")) - # res = entrySet.glob('a*') + assert_equal(entries[0, 1], entry_set.glob('*')) + # assert_equal(entries[FIXME], entry_set.glob("**")) + # res = entry_set.glob('a*') # assert_equal(entries.size, res.size) - # assert_equal(entrySet.map { |e| e.name }, res.map { |e| e.name }) + # assert_equal(entry_set.map { |e| e.name }, res.map { |e| e.name }) end def test_glob3 @@ -156,8 +156,8 @@ ::Zip::Entry.new('zf.zip', 'a/b'), ::Zip::Entry.new('zf.zip', 'a/c') ] - entrySet = ::Zip::EntrySet.new(entries) + entry_set = ::Zip::EntrySet.new(entries) - assert_equal(entries[0, 2].sort, entrySet.glob('a/{a,b}').sort) + assert_equal(entries[0, 2].sort, entry_set.glob('a/{a,b}').sort) end end diff -Nru ruby-zip-2.0.0/test/entry_test.rb ruby-zip-2.3.0/test/entry_test.rb --- ruby-zip-2.0.0/test/entry_test.rb 2019-09-25 20:23:47.000000000 +0000 +++ ruby-zip-2.3.0/test/entry_test.rb 2020-03-14 12:00:50.000000000 +0000 @@ -151,4 +151,22 @@ assert_match(/mimetypeapplication\/epub\+zip/, first_100_bytes) end + + def test_encrypted? + entry = Zip::Entry.new + entry.gp_flags = 1 + assert_equal(true, entry.encrypted?) + + entry.gp_flags = 0 + assert_equal(false, entry.encrypted?) + end + + def test_incomplete? + entry = Zip::Entry.new + entry.gp_flags = 8 + assert_equal(true, entry.incomplete?) + + entry.gp_flags = 0 + assert_equal(false, entry.incomplete?) + end end diff -Nru ruby-zip-2.0.0/test/errors_test.rb ruby-zip-2.3.0/test/errors_test.rb --- ruby-zip-2.0.0/test/errors_test.rb 2019-09-25 20:23:47.000000000 +0000 +++ ruby-zip-2.3.0/test/errors_test.rb 2020-03-14 12:00:50.000000000 +0000 @@ -1,5 +1,3 @@ -# encoding: utf-8 - require 'test_helper' class ErrorsTest < MiniTest::Test diff -Nru ruby-zip-2.0.0/test/extra_field_ut_test.rb ruby-zip-2.3.0/test/extra_field_ut_test.rb --- ruby-zip-2.0.0/test/extra_field_ut_test.rb 1970-01-01 00:00:00.000000000 +0000 +++ ruby-zip-2.3.0/test/extra_field_ut_test.rb 2020-03-14 12:00:50.000000000 +0000 @@ -0,0 +1,96 @@ +require 'test_helper' + +class ZipExtraFieldUTTest < MiniTest::Test + PARSE_TESTS = [ + ["UT\x05\x00\x01PS>A", 0b001, true, true, false], + ["UT\x05\x00\x02PS>A", 0b010, false, true, true], + ["UT\x05\x00\x04PS>A", 0b100, true, false, true], + ["UT\x09\x00\x03PS>APS>A", 0b011, false, true, false], + ["UT\x09\x00\x05PS>APS>A", 0b101, true, false, false], + ["UT\x09\x00\x06PS>APS>A", 0b110, false, false, true], + ["UT\x13\x00\x07PS>APS>APS>A", 0b111, false, false, false] + ] + + def test_parse + PARSE_TESTS.each do |bin, flags, a, c, m| + ut = ::Zip::ExtraField::UniversalTime.new(bin) + assert_equal(flags, ut.flag) + assert(ut.atime.nil? == a) + assert(ut.ctime.nil? == c) + assert(ut.mtime.nil? == m) + end + end + + def test_parse_size_zero + ut = ::Zip::ExtraField::UniversalTime.new("UT\x00") + assert_equal(0b000, ut.flag) + assert_nil(ut.atime) + assert_nil(ut.ctime) + assert_nil(ut.mtime) + end + + def test_parse_size_nil + ut = ::Zip::ExtraField::UniversalTime.new('UT') + assert_equal(0b000, ut.flag) + assert_nil(ut.atime) + assert_nil(ut.ctime) + assert_nil(ut.mtime) + end + + def test_parse_nil + ut = ::Zip::ExtraField::UniversalTime.new + assert_equal(0b000, ut.flag) + assert_nil(ut.atime) + assert_nil(ut.ctime) + assert_nil(ut.mtime) + end + + def test_set_clear_times + time = ::Zip::DOSTime.now + ut = ::Zip::ExtraField::UniversalTime.new + assert_equal(0b000, ut.flag) + + ut.mtime = time + assert_equal(0b001, ut.flag) + assert_equal(time, ut.mtime) + + ut.ctime = time + assert_equal(0b101, ut.flag) + assert_equal(time, ut.ctime) + + ut.atime = time + assert_equal(0b111, ut.flag) + assert_equal(time, ut.atime) + + ut.ctime = nil + assert_equal(0b011, ut.flag) + assert_nil ut.ctime + + ut.mtime = nil + assert_equal(0b010, ut.flag) + assert_nil ut.mtime + + ut.atime = nil + assert_equal(0b000, ut.flag) + assert_nil ut.atime + end + + def test_pack + time = ::Zip::DOSTime.at('PS>A'.unpack1('l<')) + ut = ::Zip::ExtraField::UniversalTime.new + assert_equal("\x00", ut.pack_for_local) + assert_equal("\x00", ut.pack_for_c_dir) + + ut.mtime = time + assert_equal("\x01PS>A", ut.pack_for_local) + assert_equal("\x01PS>A", ut.pack_for_c_dir) + + ut.atime = time + assert_equal("\x03PS>APS>A", ut.pack_for_local) + assert_equal("\x03PS>A", ut.pack_for_c_dir) + + ut.ctime = time + assert_equal("\x07PS>APS>APS>A", ut.pack_for_local) + assert_equal("\x07PS>A", ut.pack_for_c_dir) + end +end diff -Nru ruby-zip-2.0.0/test/file_extract_directory_test.rb ruby-zip-2.3.0/test/file_extract_directory_test.rb --- ruby-zip-2.0.0/test/file_extract_directory_test.rb 2019-09-25 20:23:47.000000000 +0000 +++ ruby-zip-2.3.0/test/file_extract_directory_test.rb 2020-03-14 12:00:50.000000000 +0000 @@ -5,14 +5,14 @@ TEST_OUT_NAME = 'test/data/generated/emptyOutDir' - def open_zip(&aProc) - assert(!aProc.nil?) - ::Zip::File.open(TestZipFile::TEST_ZIP4.zip_name, &aProc) + def open_zip(&a_proc) + assert(!a_proc.nil?) + ::Zip::File.open(TestZipFile::TEST_ZIP4.zip_name, &a_proc) end - def extract_test_dir(&aProc) + def extract_test_dir(&a_proc) open_zip do |zf| - zf.extract(TestFiles::EMPTY_TEST_DIR, TEST_OUT_NAME, &aProc) + zf.extract(TestFiles::EMPTY_TEST_DIR, TEST_OUT_NAME, &a_proc) end end @@ -41,14 +41,14 @@ def test_extract_directory_exists_as_file_overwrite File.open(TEST_OUT_NAME, 'w') { |f| f.puts 'something' } - gotCalled = false - extract_test_dir do |entry, destPath| - gotCalled = true - assert_equal(TEST_OUT_NAME, destPath) + called = false + extract_test_dir do |entry, dest_path| + called = true + assert_equal(TEST_OUT_NAME, dest_path) assert(entry.directory?) true end - assert(gotCalled) + assert(called) assert(File.directory?(TEST_OUT_NAME)) end end diff -Nru ruby-zip-2.0.0/test/file_extract_test.rb ruby-zip-2.3.0/test/file_extract_test.rb --- ruby-zip-2.0.0/test/file_extract_test.rb 2019-09-25 20:23:47.000000000 +0000 +++ ruby-zip-2.3.0/test/file_extract_test.rb 2020-03-14 12:00:50.000000000 +0000 @@ -20,7 +20,7 @@ assert(File.exist?(EXTRACTED_FILENAME)) AssertEntry.assert_contents(EXTRACTED_FILENAME, - zf.get_input_stream(ENTRY_TO_EXTRACT) { |is| is.read }) + zf.get_input_stream(ENTRY_TO_EXTRACT, &:read)) ::File.unlink(EXTRACTED_FILENAME) @@ -29,13 +29,13 @@ assert(File.exist?(EXTRACTED_FILENAME)) AssertEntry.assert_contents(EXTRACTED_FILENAME, - entry.get_input_stream { |is| is.read }) + entry.get_input_stream(&:read)) end end def test_extract_exists - writtenText = 'written text' - ::File.open(EXTRACTED_FILENAME, 'w') { |f| f.write(writtenText) } + text = 'written text' + ::File.open(EXTRACTED_FILENAME, 'w') { |f| f.write(text) } assert_raises(::Zip::DestinationFileExistsError) do ::Zip::File.open(TEST_ZIP.zip_name) do |zf| @@ -43,26 +43,26 @@ end end File.open(EXTRACTED_FILENAME, 'r') do |f| - assert_equal(writtenText, f.read) + assert_equal(text, f.read) end end def test_extract_exists_overwrite - writtenText = 'written text' - ::File.open(EXTRACTED_FILENAME, 'w') { |f| f.write(writtenText) } + text = 'written text' + ::File.open(EXTRACTED_FILENAME, 'w') { |f| f.write(text) } - gotCalledCorrectly = false + called_correctly = false ::Zip::File.open(TEST_ZIP.zip_name) do |zf| - zf.extract(zf.entries.first, EXTRACTED_FILENAME) do |entry, extractLoc| - gotCalledCorrectly = zf.entries.first == entry && - extractLoc == EXTRACTED_FILENAME + zf.extract(zf.entries.first, EXTRACTED_FILENAME) do |entry, extract_loc| + called_correctly = zf.entries.first == entry && + extract_loc == EXTRACTED_FILENAME true end end - assert(gotCalledCorrectly) + assert(called_correctly) ::File.open(EXTRACTED_FILENAME, 'r') do |f| - assert(writtenText != f.read) + assert(text != f.read) end end @@ -74,15 +74,15 @@ end def test_extract_non_entry_2 - outFile = 'outfile' + out_file = 'outfile' assert_raises(Errno::ENOENT) do zf = ::Zip::File.new(TEST_ZIP.zip_name) - nonEntry = 'hotdog-diddelidoo' - assert(!zf.entries.include?(nonEntry)) - zf.extract(nonEntry, outFile) + non_entry = 'hotdog-diddelidoo' + assert(!zf.entries.include?(non_entry)) + zf.extract(non_entry, out_file) zf.close end - assert(!File.exist?(outFile)) + assert(!File.exist?(out_file)) end def test_extract_incorrect_size @@ -127,7 +127,9 @@ assert_equal fake_size, a_entry.size ::Zip.validate_entry_sizes = false - a_entry.extract + assert_output('', /.+\'a\'.+1B.+/) do + a_entry.extract + end assert_equal true_size, File.size(file_name) FileUtils.rm file_name @@ -136,7 +138,7 @@ a_entry.extract end assert_equal \ - 'Entry a should be 1B but is larger when inflated', + "entry 'a' should be 1B, but is larger when inflated.", error.message end end diff -Nru ruby-zip-2.0.0/test/file_options_test.rb ruby-zip-2.3.0/test/file_options_test.rb --- ruby-zip-2.0.0/test/file_options_test.rb 1970-01-01 00:00:00.000000000 +0000 +++ ruby-zip-2.3.0/test/file_options_test.rb 2020-03-14 12:00:50.000000000 +0000 @@ -0,0 +1,107 @@ +require 'test_helper' + +class FileOptionsTest < MiniTest::Test + ZIPPATH = ::File.join(Dir.tmpdir, 'options.zip').freeze + TXTPATH = ::File.expand_path(::File.join('data', 'file1.txt'), __dir__).freeze + TXTPATH_600 = ::File.join(Dir.tmpdir, 'file1.600.txt').freeze + TXTPATH_755 = ::File.join(Dir.tmpdir, 'file1.755.txt').freeze + EXTPATH_1 = ::File.join(Dir.tmpdir, 'extracted_1.txt').freeze + EXTPATH_2 = ::File.join(Dir.tmpdir, 'extracted_2.txt').freeze + EXTPATH_3 = ::File.join(Dir.tmpdir, 'extracted_3.txt').freeze + ENTRY_1 = 'entry_1.txt'.freeze + ENTRY_2 = 'entry_2.txt'.freeze + ENTRY_3 = 'entry_3.txt'.freeze + + def teardown + ::File.unlink(ZIPPATH) if ::File.exist?(ZIPPATH) + ::File.unlink(EXTPATH_1) if ::File.exist?(EXTPATH_1) + ::File.unlink(EXTPATH_2) if ::File.exist?(EXTPATH_2) + ::File.unlink(EXTPATH_3) if ::File.exist?(EXTPATH_3) + ::File.unlink(TXTPATH_600) if ::File.exist?(TXTPATH_600) + ::File.unlink(TXTPATH_755) if ::File.exist?(TXTPATH_755) + end + + def test_restore_permissions + # Copy and set up files with different permissions. + ::FileUtils.cp(TXTPATH, TXTPATH_600) + ::File.chmod(0o600, TXTPATH_600) + ::FileUtils.cp(TXTPATH, TXTPATH_755) + ::File.chmod(0o755, TXTPATH_755) + + ::Zip::File.open(ZIPPATH, true) do |zip| + zip.add(ENTRY_1, TXTPATH) + zip.add(ENTRY_2, TXTPATH_600) + zip.add(ENTRY_3, TXTPATH_755) + end + + ::Zip::File.open(ZIPPATH, false, restore_permissions: true) do |zip| + zip.extract(ENTRY_1, EXTPATH_1) + zip.extract(ENTRY_2, EXTPATH_2) + zip.extract(ENTRY_3, EXTPATH_3) + end + + assert_equal(::File.stat(TXTPATH).mode, ::File.stat(EXTPATH_1).mode) + assert_equal(::File.stat(TXTPATH_600).mode, ::File.stat(EXTPATH_2).mode) + assert_equal(::File.stat(TXTPATH_755).mode, ::File.stat(EXTPATH_3).mode) + end + + def test_restore_times_true + ::Zip::File.open(ZIPPATH, true) do |zip| + zip.add(ENTRY_1, TXTPATH) + zip.add_stored(ENTRY_2, TXTPATH) + end + + ::Zip::File.open(ZIPPATH, false, restore_times: true) do |zip| + zip.extract(ENTRY_1, EXTPATH_1) + zip.extract(ENTRY_2, EXTPATH_2) + end + + assert_time_equal(::File.mtime(TXTPATH), ::File.mtime(EXTPATH_1)) + assert_time_equal(::File.mtime(TXTPATH), ::File.mtime(EXTPATH_2)) + end + + def test_restore_times_false + ::Zip::File.open(ZIPPATH, true) do |zip| + zip.add(ENTRY_1, TXTPATH) + zip.add_stored(ENTRY_2, TXTPATH) + end + + ::Zip::File.open(ZIPPATH, false, restore_times: false) do |zip| + zip.extract(ENTRY_1, EXTPATH_1) + zip.extract(ENTRY_2, EXTPATH_2) + end + + assert_time_equal(::Time.now, ::File.mtime(EXTPATH_1)) + assert_time_equal(::Time.now, ::File.mtime(EXTPATH_2)) + end + + def test_get_find_consistency + testzip = ::File.expand_path(::File.join('data', 'globTest.zip'), __dir__) + file_f = ::File.expand_path('f_test.txt', Dir.tmpdir) + file_g = ::File.expand_path('g_test.txt', Dir.tmpdir) + + ::Zip::File.open(testzip) do |zip| + e1 = zip.find_entry('globTest/food.txt') + e1.extract(file_f) + e2 = zip.get_entry('globTest/food.txt') + e2.extract(file_g) + end + + assert_time_equal(::File.mtime(file_f), ::File.mtime(file_g)) + ensure + ::File.unlink(file_f) + ::File.unlink(file_g) + end + + private + + # Method to compare file times. DOS times only have 2 second accuracy. + def assert_time_equal(expected, actual) + assert_equal(expected.year, actual.year) + assert_equal(expected.month, actual.month) + assert_equal(expected.day, actual.day) + assert_equal(expected.hour, actual.hour) + assert_equal(expected.min, actual.min) + assert_in_delta(expected.sec, actual.sec, 1) + end +end diff -Nru ruby-zip-2.0.0/test/file_permissions_test.rb ruby-zip-2.3.0/test/file_permissions_test.rb --- ruby-zip-2.0.0/test/file_permissions_test.rb 2019-09-25 20:23:47.000000000 +0000 +++ ruby-zip-2.3.0/test/file_permissions_test.rb 2020-03-14 12:00:50.000000000 +0000 @@ -15,7 +15,7 @@ end def test_umask_000 - set_umask(0o000) do + apply_umask(0o000) do create_files end @@ -23,7 +23,7 @@ end def test_umask_066 - set_umask(0o066) do + apply_umask(0o066) do create_files end @@ -31,7 +31,7 @@ end def test_umask_027 - set_umask(0o027) do + apply_umask(0o027) do create_files end @@ -56,7 +56,7 @@ end # If anything goes wrong, make sure the umask is restored. - def set_umask(umask) + def apply_umask(umask) saved_umask = ::File.umask(umask) yield ensure diff -Nru ruby-zip-2.0.0/test/file_split_test.rb ruby-zip-2.3.0/test/file_split_test.rb --- ruby-zip-2.0.0/test/file_split_test.rb 2019-09-25 20:23:47.000000000 +0000 +++ ruby-zip-2.3.0/test/file_split_test.rb 2020-03-14 12:00:50.000000000 +0000 @@ -28,6 +28,7 @@ result = ::Zip::File.split(TEST_ZIP.zip_name, 65_536, false) return if result.nil? + Dir["#{TEST_ZIP.zip_name}.*"].sort.each_with_index do |zip_file_name, index| File.open(zip_file_name, 'rb') do |zip_file| zip_file.read([::Zip::File::SPLIT_SIGNATURE].pack('V').size) if index == 0 @@ -42,7 +43,7 @@ assert(File.exist?(EXTRACTED_FILENAME)) AssertEntry.assert_contents(EXTRACTED_FILENAME, - zf.get_input_stream(ENTRY_TO_EXTRACT) { |is| is.read }) + zf.get_input_stream(ENTRY_TO_EXTRACT, &:read)) File.unlink(EXTRACTED_FILENAME) @@ -51,7 +52,7 @@ assert(File.exist?(EXTRACTED_FILENAME)) AssertEntry.assert_contents(EXTRACTED_FILENAME, - entry.get_input_stream { |is| is.read }) + entry.get_input_stream(&:read)) end end end diff -Nru ruby-zip-2.0.0/test/filesystem/directory_test.rb ruby-zip-2.3.0/test/filesystem/directory_test.rb --- ruby-zip-2.0.0/test/filesystem/directory_test.rb 2019-09-25 20:23:47.000000000 +0000 +++ ruby-zip-2.3.0/test/filesystem/directory_test.rb 2020-03-14 12:00:50.000000000 +0000 @@ -65,16 +65,16 @@ def test_foreach ::Zip::File.open(TEST_ZIP) do |zf| - blockCalled = false + block_called = false assert_raises(Errno::ENOENT, 'No such file or directory - noSuchDir') do - zf.dir.foreach('noSuchDir') { |_e| blockCalled = true } + zf.dir.foreach('noSuchDir') { |_e| block_called = true } end - assert(!blockCalled) + assert(!block_called) assert_raises(Errno::ENOTDIR, 'Not a directory - file1') do - zf.dir.foreach('file1') { |_e| blockCalled = true } + zf.dir.foreach('file1') { |_e| block_called = true } end - assert(!blockCalled) + assert(!block_called) entries = [] zf.dir.foreach('.') { |e| entries << e } diff -Nru ruby-zip-2.0.0/test/filesystem/dir_iterator_test.rb ruby-zip-2.3.0/test/filesystem/dir_iterator_test.rb --- ruby-zip-2.0.0/test/filesystem/dir_iterator_test.rb 2019-09-25 20:23:47.000000000 +0000 +++ ruby-zip-2.3.0/test/filesystem/dir_iterator_test.rb 2020-03-14 12:00:50.000000000 +0000 @@ -5,54 +5,54 @@ FILENAME_ARRAY = %w[f1 f2 f3 f4 f5 f6] def setup - @dirIt = ::Zip::FileSystem::ZipFsDirIterator.new(FILENAME_ARRAY) + @dir_iter = ::Zip::FileSystem::ZipFsDirIterator.new(FILENAME_ARRAY) end def test_close - @dirIt.close + @dir_iter.close assert_raises(IOError, 'closed directory') do - @dirIt.each { |e| p e } + @dir_iter.each { |e| p e } end assert_raises(IOError, 'closed directory') do - @dirIt.read + @dir_iter.read end assert_raises(IOError, 'closed directory') do - @dirIt.rewind + @dir_iter.rewind end assert_raises(IOError, 'closed directory') do - @dirIt.seek(0) + @dir_iter.seek(0) end assert_raises(IOError, 'closed directory') do - @dirIt.tell + @dir_iter.tell end end def test_each # Tested through Enumerable.entries - assert_equal(FILENAME_ARRAY, @dirIt.entries) + assert_equal(FILENAME_ARRAY, @dir_iter.entries) end def test_read FILENAME_ARRAY.size.times do |i| - assert_equal(FILENAME_ARRAY[i], @dirIt.read) + assert_equal(FILENAME_ARRAY[i], @dir_iter.read) end end def test_rewind - @dirIt.read - @dirIt.read - assert_equal(FILENAME_ARRAY[2], @dirIt.read) - @dirIt.rewind - assert_equal(FILENAME_ARRAY[0], @dirIt.read) + @dir_iter.read + @dir_iter.read + assert_equal(FILENAME_ARRAY[2], @dir_iter.read) + @dir_iter.rewind + assert_equal(FILENAME_ARRAY[0], @dir_iter.read) end def test_tell_seek - @dirIt.read - @dirIt.read - pos = @dirIt.tell - valAtPos = @dirIt.read - @dirIt.read - @dirIt.seek(pos) - assert_equal(valAtPos, @dirIt.read) + @dir_iter.read + @dir_iter.read + pos = @dir_iter.tell + value = @dir_iter.read + @dir_iter.read + @dir_iter.seek(pos) + assert_equal(value, @dir_iter.read) end end diff -Nru ruby-zip-2.0.0/test/filesystem/file_nonmutating_test.rb ruby-zip-2.3.0/test/filesystem/file_nonmutating_test.rb --- ruby-zip-2.0.0/test/filesystem/file_nonmutating_test.rb 2019-09-25 20:23:47.000000000 +0000 +++ ruby-zip-2.3.0/test/filesystem/file_nonmutating_test.rb 2020-03-14 12:00:50.000000000 +0000 @@ -31,30 +31,30 @@ end def test_open_read - blockCalled = false + block_called = false @zip_file.file.open('file1', 'r') do |f| - blockCalled = true + block_called = true assert_equal("this is the entry 'file1' in my test archive!", f.readline.chomp) end - assert(blockCalled) + assert(block_called) - blockCalled = false + block_called = false @zip_file.file.open('file1', 'rb') do |f| # test binary flag is ignored - blockCalled = true + block_called = true assert_equal("this is the entry 'file1' in my test archive!", f.readline.chomp) end - assert(blockCalled) + assert(block_called) - blockCalled = false + block_called = false @zip_file.dir.chdir 'dir2' @zip_file.file.open('file21', 'r') do |f| - blockCalled = true + block_called = true assert_equal("this is the entry 'dir2/file21' in my test archive!", f.readline.chomp) end - assert(blockCalled) + assert(block_called) @zip_file.dir.chdir '/' assert_raises(Errno::ENOENT) do @@ -80,7 +80,7 @@ end begin is = @zip_file.file.new('file1') do - fail 'should not call block' + raise 'should not call block' end ensure is.close if is @@ -126,19 +126,19 @@ include ExtraAssertions def test_dirname - assert_forwarded(File, :dirname, 'retVal', 'a/b/c/d') do + assert_forwarded(File, :dirname, 'ret_val', 'a/b/c/d') do @zip_file.file.dirname('a/b/c/d') end end def test_basename - assert_forwarded(File, :basename, 'retVal', 'a/b/c/d') do + assert_forwarded(File, :basename, 'ret_val', 'a/b/c/d') do @zip_file.file.basename('a/b/c/d') end end def test_split - assert_forwarded(File, :split, 'retVal', 'a/b/c/d') do + assert_forwarded(File, :split, 'ret_val', 'a/b/c/d') do @zip_file.file.split('a/b/c/d') end end @@ -246,21 +246,21 @@ assert(!@zip_file.file.zero?('notAFile')) assert(!@zip_file.file.zero?('file1')) assert(@zip_file.file.zero?('dir1')) - blockCalled = false + block_called = false ::Zip::File.open('test/data/generated/5entry.zip') do |zf| - blockCalled = true + block_called = true assert(zf.file.zero?('test/data/generated/empty.txt')) end - assert(blockCalled) + assert(block_called) assert(!@zip_file.file.stat('file1').zero?) assert(@zip_file.file.stat('dir1').zero?) - blockCalled = false + block_called = false ::Zip::File.open('test/data/generated/5entry.zip') do |zf| - blockCalled = true + block_called = true assert(zf.file.stat('test/data/generated/empty.txt').zero?) end - assert(blockCalled) + assert(block_called) end def test_expand_path @@ -434,12 +434,14 @@ ::Zip::File.open('test/data/globTest.zip') do |zf| { 'globTest/foo.txt' => ['globTest/foo.txt'], - '*/foo.txt' => ['globTest/foo.txt'], - '**/foo.txt' => ['globTest/foo.txt', 'globTest/foo/bar/baz/foo.txt'], - '*/foo/**/*.txt' => ['globTest/foo/bar/baz/foo.txt'] + '*/foo.txt' => ['globTest/foo.txt'], + '**/foo.txt' => [ + 'globTest/foo.txt', 'globTest/foo/bar/baz/foo.txt' + ], + '*/foo/**/*.txt' => ['globTest/foo/bar/baz/foo.txt'] }.each do |spec, expected_results| results = zf.glob(spec) - assert results.all? { |entry| entry.is_a? ::Zip::Entry } + assert(results.all? { |entry| entry.kind_of? ::Zip::Entry }) result_strings = results.map(&:to_s) missing_matches = expected_results - result_strings @@ -466,12 +468,12 @@ if Zip::RUNNING_ON_WINDOWS # This is pretty much projectile vomit but it allows the test to be # run on windows also - system_dir = ::File.popen('dir') { |f| f.read }.gsub(/Dir\(s\).*$/, '') - zipfile_dir = @zip_file.file.popen('dir') { |f| f.read }.gsub(/Dir\(s\).*$/, '') + system_dir = ::File.popen('dir', &:read).gsub(/Dir\(s\).*$/, '') + zipfile_dir = @zip_file.file.popen('dir', &:read).gsub(/Dir\(s\).*$/, '') assert_equal(system_dir, zipfile_dir) else - assert_equal(::File.popen('ls') { |f| f.read }, - @zip_file.file.popen('ls') { |f| f.read }) + assert_equal(::File.popen('ls', &:read), + @zip_file.file.popen('ls', &:read)) end end diff -Nru ruby-zip-2.0.0/test/file_test.rb ruby-zip-2.3.0/test/file_test.rb --- ruby-zip-2.0.0/test/file_test.rb 2019-09-25 20:23:47.000000000 +0000 +++ ruby-zip-2.3.0/test/file_test.rb 2020-03-14 12:00:50.000000000 +0000 @@ -22,9 +22,9 @@ ::File.open(EMPTY_FILENAME, 'wb') { |file| file.write buffer.string } - zfRead = ::Zip::File.new(EMPTY_FILENAME) - assert_equal(comment, zfRead.comment) - assert_equal(2, zfRead.entries.length) + zf_read = ::Zip::File.new(EMPTY_FILENAME) + assert_equal(comment, zf_read.comment) + assert_equal(2, zf_read.entries.length) end def test_create_from_scratch @@ -36,9 +36,9 @@ zf.comment = comment zf.close - zfRead = ::Zip::File.new(EMPTY_FILENAME) - assert_equal(comment, zfRead.comment) - assert_equal(2, zfRead.entries.length) + zf_read = ::Zip::File.new(EMPTY_FILENAME) + assert_equal(comment, zf_read.comment) + assert_equal(2, zf_read.entries.length) end def test_create_from_scratch_with_old_create_parameter @@ -50,38 +50,38 @@ zf.comment = comment zf.close - zfRead = ::Zip::File.new(EMPTY_FILENAME) - assert_equal(comment, zfRead.comment) - assert_equal(2, zfRead.entries.length) + zf_read = ::Zip::File.new(EMPTY_FILENAME) + assert_equal(comment, zf_read.comment) + assert_equal(2, zf_read.entries.length) end def test_get_input_stream_stored_with_gpflag_bit3 ::Zip::File.open('test/data/gpbit3stored.zip') do |zf| - assert_equal("foo\n", zf.read("foo.txt")) + assert_equal("foo\n", zf.read('foo.txt')) end end def test_get_output_stream - entryCount = nil + count = nil ::Zip::File.open(TEST_ZIP.zip_name) do |zf| - entryCount = zf.size - zf.get_output_stream('newEntry.txt') do |os| - os.write 'Putting stuff in newEntry.txt' + count = zf.size + zf.get_output_stream('new_entry.txt') do |os| + os.write 'Putting stuff in new_entry.txt' end - assert_equal(entryCount + 1, zf.size) - assert_equal('Putting stuff in newEntry.txt', zf.read('newEntry.txt')) + assert_equal(count + 1, zf.size) + assert_equal('Putting stuff in new_entry.txt', zf.read('new_entry.txt')) zf.get_output_stream(zf.get_entry('test/data/generated/empty.txt')) do |os| os.write 'Putting stuff in data/generated/empty.txt' end - assert_equal(entryCount + 1, zf.size) + assert_equal(count + 1, zf.size) assert_equal('Putting stuff in data/generated/empty.txt', zf.read('test/data/generated/empty.txt')) custom_entry_args = [TEST_COMMENT, TEST_EXTRA, TEST_COMPRESSED_SIZE, TEST_CRC, ::Zip::Entry::STORED, TEST_SIZE, TEST_TIME] zf.get_output_stream('entry_with_custom_args.txt', nil, *custom_entry_args) do |os| os.write 'Some data' end - assert_equal(entryCount + 2, zf.size) + assert_equal(count + 2, zf.size) entry = zf.get_entry('entry_with_custom_args.txt') assert_equal(custom_entry_args[0], entry.comment) assert_equal(custom_entry_args[2], entry.compressed_size) @@ -96,8 +96,8 @@ end ::Zip::File.open(TEST_ZIP.zip_name) do |zf| - assert_equal(entryCount + 3, zf.size) - assert_equal('Putting stuff in newEntry.txt', zf.read('newEntry.txt')) + assert_equal(count + 3, zf.size) + assert_equal('Putting stuff in new_entry.txt', zf.read('new_entry.txt')) assert_equal('Putting stuff in data/generated/empty.txt', zf.read('test/data/generated/empty.txt')) assert_equal(File.open('test/data/generated/5entry.zip', 'rb').read, zf.read('entry.bin')) end @@ -106,14 +106,14 @@ 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') + assert zf.entries.map(&: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| - assert zf.entries.map { |e| e.name }.include?('zippedruby1.rb') + assert zf.entries.map(&:name).include?('zippedruby1.rb') end end @@ -131,7 +131,7 @@ # Note: this may change the file if it is opened with r+b instead of rb. # The 'extra fields' in this particular zip file get reordered. File.open(test_zip, 'rb') do |file| - Zip::File.open_buffer(file) do |zf| + Zip::File.open_buffer(file) do nil # do nothing end end @@ -171,7 +171,7 @@ def test_open_buffer_without_block string_io = StringIO.new File.read('test/data/rubycode.zip') zf = ::Zip::File.open_buffer string_io - assert zf.entries.map { |e| e.name }.include?('zippedruby1.rb') + assert zf.entries.map(&:name).include?('zippedruby1.rb') end def test_cleans_up_tempfiles_after_close @@ -189,52 +189,52 @@ end def test_add - srcFile = 'test/data/file2.txt' - entryName = 'newEntryName.rb' - assert(::File.exist?(srcFile)) + src_file = 'test/data/file2.txt' + entry_name = 'newEntryName.rb' + assert(::File.exist?(src_file)) zf = ::Zip::File.new(EMPTY_FILENAME, ::Zip::File::CREATE) - zf.add(entryName, srcFile) + zf.add(entry_name, src_file) zf.close - zfRead = ::Zip::File.new(EMPTY_FILENAME) - assert_equal('', zfRead.comment) - assert_equal(1, zfRead.entries.length) - assert_equal(entryName, zfRead.entries.first.name) - AssertEntry.assert_contents(srcFile, - zfRead.get_input_stream(entryName) { |zis| zis.read }) + zf_read = ::Zip::File.new(EMPTY_FILENAME) + assert_equal('', zf_read.comment) + assert_equal(1, zf_read.entries.length) + assert_equal(entry_name, zf_read.entries.first.name) + AssertEntry.assert_contents(src_file, + zf_read.get_input_stream(entry_name, &:read)) end def test_add_stored - srcFile = 'test/data/file2.txt' - entryName = 'newEntryName.rb' - assert(::File.exist?(srcFile)) + src_file = 'test/data/file2.txt' + entry_name = 'newEntryName.rb' + assert(::File.exist?(src_file)) zf = ::Zip::File.new(EMPTY_FILENAME, ::Zip::File::CREATE) - zf.add_stored(entryName, srcFile) + zf.add_stored(entry_name, src_file) zf.close - zfRead = ::Zip::File.new(EMPTY_FILENAME) - entry = zfRead.entries.first - assert_equal('', zfRead.comment) - assert_equal(1, zfRead.entries.length) - assert_equal(entryName, entry.name) - assert_equal(File.size(srcFile), entry.size) + zf_read = ::Zip::File.new(EMPTY_FILENAME) + entry = zf_read.entries.first + assert_equal('', zf_read.comment) + assert_equal(1, zf_read.entries.length) + assert_equal(entry_name, entry.name) + assert_equal(File.size(src_file), entry.size) assert_equal(entry.size, entry.compressed_size) assert_equal(::Zip::Entry::STORED, entry.compression_method) - AssertEntry.assert_contents(srcFile, - zfRead.get_input_stream(entryName) { |zis| zis.read }) + AssertEntry.assert_contents(src_file, + zf_read.get_input_stream(entry_name, &:read)) end def test_recover_permissions_after_add_files_to_archive - srcZip = TEST_ZIP.zip_name - ::File.chmod(0o664, srcZip) - srcFile = 'test/data/file2.txt' - entryName = 'newEntryName.rb' - assert_equal(::File.stat(srcZip).mode, 0o100664) - assert(::File.exist?(srcZip)) - zf = ::Zip::File.new(srcZip, ::Zip::File::CREATE) - zf.add(entryName, srcFile) + src_zip = TEST_ZIP.zip_name + ::File.chmod(0o664, src_zip) + src_file = 'test/data/file2.txt' + entry_name = 'newEntryName.rb' + assert_equal(::File.stat(src_zip).mode, 0o100664) + assert(::File.exist?(src_zip)) + zf = ::Zip::File.new(src_zip, ::Zip::File::CREATE) + zf.add(entry_name, src_file) zf.close - assert_equal(::File.stat(srcZip).mode, 0o100664) + assert_equal(::File.stat(src_zip).mode, 0o100664) end def test_add_existing_entry_name @@ -246,15 +246,18 @@ end def test_add_existing_entry_name_replace - gotCalled = false - replacedEntry = nil + called = false + replaced_entry = nil ::Zip::File.open(TEST_ZIP.zip_name) do |zf| - replacedEntry = zf.entries.first.name - zf.add(replacedEntry, 'test/data/file2.txt') { gotCalled = true; true } + replaced_entry = zf.entries.first.name + zf.add(replaced_entry, 'test/data/file2.txt') do + called = true + true + end end - assert(gotCalled) + assert(called) ::Zip::File.open(TEST_ZIP.zip_name) do |zf| - assert_contains(zf, replacedEntry, 'test/data/file2.txt') + assert_contains(zf, replaced_entry, 'test/data/file2.txt') end end @@ -262,51 +265,55 @@ ::Zip::File.open(TEST_ZIP.zip_name) do |zf| zf.add(TestFiles::EMPTY_TEST_DIR, TestFiles::EMPTY_TEST_DIR) end + ::Zip::File.open(TEST_ZIP.zip_name) do |zf| - dirEntry = zf.entries.detect { |e| e.name == TestFiles::EMPTY_TEST_DIR + '/' } - assert(dirEntry.directory?) + dir_entry = zf.entries.detect do |e| + e.name == TestFiles::EMPTY_TEST_DIR + '/' + end + + assert(dir_entry.directory?) end end def test_remove - entryToRemove, *remainingEntries = TEST_ZIP.entry_names + entry, *remaining = TEST_ZIP.entry_names FileUtils.cp(TestZipFile::TEST_ZIP2.zip_name, TEST_ZIP.zip_name) zf = ::Zip::File.new(TEST_ZIP.zip_name) - assert(zf.entries.map { |e| e.name }.include?(entryToRemove)) - zf.remove(entryToRemove) - assert(!zf.entries.map { |e| e.name }.include?(entryToRemove)) - assert_equal(zf.entries.map { |x| x.name }.sort, remainingEntries.sort) + assert(zf.entries.map(&:name).include?(entry)) + zf.remove(entry) + assert(!zf.entries.map(&:name).include?(entry)) + assert_equal(zf.entries.map(&:name).sort, remaining.sort) zf.close - zfRead = ::Zip::File.new(TEST_ZIP.zip_name) - assert(!zfRead.entries.map { |e| e.name }.include?(entryToRemove)) - assert_equal(zfRead.entries.map { |x| x.name }.sort, remainingEntries.sort) - zfRead.close + zf_read = ::Zip::File.new(TEST_ZIP.zip_name) + assert(!zf_read.entries.map(&:name).include?(entry)) + assert_equal(zf_read.entries.map(&:name).sort, remaining.sort) + zf_read.close end def test_rename - entryToRename, * = TEST_ZIP.entry_names + entry, * = TEST_ZIP.entry_names zf = ::Zip::File.new(TEST_ZIP.zip_name) - assert(zf.entries.map { |e| e.name }.include?(entryToRename)) + assert(zf.entries.map(&:name).include?(entry)) - contents = zf.read(entryToRename) - newName = 'changed entry name' - assert(!zf.entries.map { |e| e.name }.include?(newName)) + contents = zf.read(entry) + new_name = 'changed entry name' + assert(!zf.entries.map(&:name).include?(new_name)) - zf.rename(entryToRename, newName) - assert(zf.entries.map { |e| e.name }.include?(newName)) + zf.rename(entry, new_name) + assert(zf.entries.map(&:name).include?(new_name)) - assert_equal(contents, zf.read(newName)) + assert_equal(contents, zf.read(new_name)) zf.close - zfRead = ::Zip::File.new(TEST_ZIP.zip_name) - assert(zfRead.entries.map { |e| e.name }.include?(newName)) - assert_equal(contents, zfRead.read(newName)) - zfRead.close + zf_read = ::Zip::File.new(TEST_ZIP.zip_name) + assert(zf_read.entries.map(&:name).include?(new_name)) + assert_equal(contents, zf_read.read(new_name)) + zf_read.close end def test_rename_with_each @@ -339,8 +346,8 @@ end def test_rename_to_existing_entry - oldEntries = nil - ::Zip::File.open(TEST_ZIP.zip_name) { |zf| oldEntries = zf.entries } + old_entries = nil + ::Zip::File.open(TEST_ZIP.zip_name) { |zf| old_entries = zf.entries } assert_raises(::Zip::EntryExistsError) do ::Zip::File.open(TEST_ZIP.zip_name) do |zf| @@ -349,35 +356,38 @@ end ::Zip::File.open(TEST_ZIP.zip_name) do |zf| - assert_equal(oldEntries.sort.map { |e| e.name }, zf.entries.sort.map { |e| e.name }) + assert_equal(old_entries.sort.map(&:name), zf.entries.sort.map(&:name)) end end def test_rename_to_existing_entry_overwrite - oldEntries = nil - ::Zip::File.open(TEST_ZIP.zip_name) { |zf| oldEntries = zf.entries } + old_entries = nil + ::Zip::File.open(TEST_ZIP.zip_name) { |zf| old_entries = zf.entries } - gotCalled = false - renamedEntryName = nil + called = false + new_entry_name = nil ::Zip::File.open(TEST_ZIP.zip_name) do |zf| - renamedEntryName = zf.entries[0].name - zf.rename(zf.entries[0], zf.entries[1].name) { gotCalled = true; true } + new_entry_name = zf.entries[0].name + zf.rename(zf.entries[0], zf.entries[1].name) do + called = true + true + end end - assert(gotCalled) - oldEntries.delete_if { |e| e.name == renamedEntryName } + assert(called) + old_entries.delete_if { |e| e.name == new_entry_name } ::Zip::File.open(TEST_ZIP.zip_name) do |zf| - assert_equal(oldEntries.sort.map { |e| e.name }, - zf.entries.sort.map { |e| e.name }) + assert_equal(old_entries.sort.map(&:name), + zf.entries.sort.map(&:name)) end end def test_rename_non_entry - nonEntry = 'bogusEntry' + non_entry = 'bogusEntry' target_entry = 'target_entryName' zf = ::Zip::File.new(TEST_ZIP.zip_name) - assert(!zf.entries.include?(nonEntry)) - assert_raises(Errno::ENOENT) { zf.rename(nonEntry, target_entry) } + assert(!zf.entries.include?(non_entry)) + assert_raises(Errno::ENOENT) { zf.rename(non_entry, target_entry) } zf.commit assert(!zf.entries.include?(target_entry)) ensure @@ -393,42 +403,52 @@ end def test_replace - entryToReplace = TEST_ZIP.entry_names[2] - newEntrySrcFilename = 'test/data/file2.txt' + replace_entry = TEST_ZIP.entry_names[2] + replace_src = 'test/data/file2.txt' zf = ::Zip::File.new(TEST_ZIP.zip_name) - zf.replace(entryToReplace, newEntrySrcFilename) + zf.replace(replace_entry, replace_src) zf.close - zfRead = ::Zip::File.new(TEST_ZIP.zip_name) - AssertEntry.assert_contents(newEntrySrcFilename, - zfRead.get_input_stream(entryToReplace) { |is| is.read }) - AssertEntry.assert_contents(TEST_ZIP.entry_names[0], - zfRead.get_input_stream(TEST_ZIP.entry_names[0]) { |is| is.read }) - AssertEntry.assert_contents(TEST_ZIP.entry_names[1], - zfRead.get_input_stream(TEST_ZIP.entry_names[1]) { |is| is.read }) - AssertEntry.assert_contents(TEST_ZIP.entry_names[3], - zfRead.get_input_stream(TEST_ZIP.entry_names[3]) { |is| is.read }) - zfRead.close + zf_read = ::Zip::File.new(TEST_ZIP.zip_name) + AssertEntry.assert_contents( + replace_src, + zf_read.get_input_stream(replace_entry, &:read) + ) + AssertEntry.assert_contents( + TEST_ZIP.entry_names[0], + zf_read.get_input_stream(TEST_ZIP.entry_names[0], &:read) + ) + AssertEntry.assert_contents( + TEST_ZIP.entry_names[1], + zf_read.get_input_stream(TEST_ZIP.entry_names[1], &:read) + ) + AssertEntry.assert_contents( + TEST_ZIP.entry_names[3], + zf_read.get_input_stream(TEST_ZIP.entry_names[3], &:read) + ) + zf_read.close end def test_replace_non_entry - entryToReplace = 'nonExistingEntryname' + replace_entry = 'nonExistingEntryname' ::Zip::File.open(TEST_ZIP.zip_name) do |zf| - assert_raises(Errno::ENOENT) { zf.replace(entryToReplace, 'test/data/file2.txt') } + assert_raises(Errno::ENOENT) do + zf.replace(replace_entry, 'test/data/file2.txt') + end end end def test_commit - newName = 'renamedFirst' + new_name = 'renamedFirst' zf = ::Zip::File.new(TEST_ZIP.zip_name) - oldName = zf.entries.first - zf.rename(oldName, newName) + old_name = zf.entries.first + zf.rename(old_name, new_name) zf.commit - zfRead = ::Zip::File.new(TEST_ZIP.zip_name) - assert(zfRead.entries.detect { |e| e.name == newName } != nil) - assert(zfRead.entries.detect { |e| e.name == oldName }.nil?) - zfRead.close + zf_read = ::Zip::File.new(TEST_ZIP.zip_name) + refute_nil(zf_read.entries.detect { |e| e.name == new_name }) + assert_nil(zf_read.entries.detect { |e| e.name == old_name }) + zf_read.close zf.close res = system("unzip -tqq #{TEST_ZIP.zip_name}") @@ -445,8 +465,8 @@ zf.commit zf.close zf2 = ::Zip::File.open(filename) - assert(zf2.entries.detect { |e| e.name == 'test1.txt' } != nil) - assert(zf2.entries.detect { |e| e.name == 'test2.txt' } != nil) + refute_nil(zf2.entries.detect { |e| e.name == 'test1.txt' }) + refute_nil(zf2.entries.detect { |e| e.name == 'test2.txt' }) res = system("unzip -tqq #{filename}") assert_equal(res, true) end @@ -457,17 +477,17 @@ end def test_write_buffer - newName = 'renamedFirst' + new_name = 'renamedFirst' zf = ::Zip::File.new(TEST_ZIP.zip_name) - oldName = zf.entries.first - zf.rename(oldName, newName) + old_name = zf.entries.first + zf.rename(old_name, new_name) io = ::StringIO.new('') buffer = zf.write_buffer(io) File.open(TEST_ZIP.zip_name, 'wb') { |f| f.write buffer.string } - zfRead = ::Zip::File.new(TEST_ZIP.zip_name) - assert(zfRead.entries.detect { |e| e.name == newName } != nil) - assert(zfRead.entries.detect { |e| e.name == oldName }.nil?) - zfRead.close + zf_read = ::Zip::File.new(TEST_ZIP.zip_name) + refute_nil(zf_read.entries.detect { |e| e.name == new_name }) + assert_nil(zf_read.entries.detect { |e| e.name == old_name }) + zf_read.close zf.close end @@ -494,52 +514,58 @@ # end def test_compound1 - renamedName = 'renamedName' + renamed_name = 'renamed_name' filename_to_remove = '' + begin zf = ::Zip::File.new(TEST_ZIP.zip_name) - originalEntries = zf.entries.dup + orig_entries = zf.entries.dup assert_not_contains(zf, TestFiles::RANDOM_ASCII_FILE1) zf.add(TestFiles::RANDOM_ASCII_FILE1, TestFiles::RANDOM_ASCII_FILE1) assert_contains(zf, TestFiles::RANDOM_ASCII_FILE1) - entry_to_rename = zf.entries.find { |entry| entry.name.match('longAscii') } - zf.rename(entry_to_rename, renamedName) - assert_contains(zf, renamedName) + entry_to_rename = zf.entries.find do |entry| + entry.name.match('longAscii') + end + zf.rename(entry_to_rename, renamed_name) + assert_contains(zf, renamed_name) TestFiles::BINARY_TEST_FILES.each do |filename| zf.add(filename, filename) assert_contains(zf, filename) end - assert_contains(zf, originalEntries.last.to_s) - filename_to_remove = originalEntries.map(&:to_s).find { |name| name.match('longBinary') } + assert_contains(zf, orig_entries.last.to_s) + filename_to_remove = orig_entries.map(&:to_s).find do |name| + name.match('longBinary') + end zf.remove(filename_to_remove) assert_not_contains(zf, filename_to_remove) ensure zf.close end + begin - zfRead = ::Zip::File.new(TEST_ZIP.zip_name) - assert_contains(zfRead, TestFiles::RANDOM_ASCII_FILE1) - assert_contains(zfRead, renamedName) + zf_read = ::Zip::File.new(TEST_ZIP.zip_name) + assert_contains(zf_read, TestFiles::RANDOM_ASCII_FILE1) + assert_contains(zf_read, renamed_name) TestFiles::BINARY_TEST_FILES.each do |filename| - assert_contains(zfRead, filename) + assert_contains(zf_read, filename) end - assert_not_contains(zfRead, filename_to_remove) + assert_not_contains(zf_read, filename_to_remove) ensure - zfRead.close + zf_read.close end end def test_compound2 begin zf = ::Zip::File.new(TEST_ZIP.zip_name) - originalEntries = zf.entries.dup + orig_entries = zf.entries.dup - originalEntries.each do |entry| + orig_entries.each do |entry| zf.remove(entry) assert_not_contains(zf, entry) end @@ -549,25 +575,25 @@ zf.add(filename, filename) assert_contains(zf, filename) end - assert_equal(zf.entries.sort.map { |e| e.name }, TestFiles::ASCII_TEST_FILES) + assert_equal(zf.entries.sort.map(&:name), TestFiles::ASCII_TEST_FILES) - zf.rename(TestFiles::ASCII_TEST_FILES[0], 'newName') + zf.rename(TestFiles::ASCII_TEST_FILES[0], 'new_name') assert_not_contains(zf, TestFiles::ASCII_TEST_FILES[0]) - assert_contains(zf, 'newName') + assert_contains(zf, 'new_name') ensure zf.close end begin - zfRead = ::Zip::File.new(TEST_ZIP.zip_name) - asciiTestFiles = TestFiles::ASCII_TEST_FILES.dup - asciiTestFiles.shift - asciiTestFiles.each do |filename| + zf_read = ::Zip::File.new(TEST_ZIP.zip_name) + ascii_files = TestFiles::ASCII_TEST_FILES.dup + ascii_files.shift + ascii_files.each do |filename| assert_contains(zf, filename) end - assert_contains(zf, 'newName') + assert_contains(zf, 'new_name') ensure - zfRead.close + zf_read.close end end @@ -575,31 +601,31 @@ ::Zip::File.open(TEST_ZIP.zip_name) do |zf| zf.comment = 'my changed comment' end - zfRead = ::Zip::File.open(TEST_ZIP.zip_name) - assert_equal('my changed comment', zfRead.comment) + zf_read = ::Zip::File.open(TEST_ZIP.zip_name) + assert_equal('my changed comment', zf_read.comment) end def test_preserve_file_order - entryNames = nil + entry_names = nil ::Zip::File.open(TEST_ZIP.zip_name) do |zf| - entryNames = zf.entries.map { |e| e.to_s } + entry_names = zf.entries.map(&:to_s) zf.get_output_stream('a.txt') { |os| os.write 'this is a.txt' } zf.get_output_stream('z.txt') { |os| os.write 'this is z.txt' } zf.get_output_stream('k.txt') { |os| os.write 'this is k.txt' } - entryNames << 'a.txt' << 'z.txt' << 'k.txt' + entry_names << 'a.txt' << 'z.txt' << 'k.txt' end ::Zip::File.open(TEST_ZIP.zip_name) do |zf| - assert_equal(entryNames, zf.entries.map { |e| e.to_s }) - entries = zf.entries.sort_by { |e| e.name }.reverse + assert_equal(entry_names, zf.entries.map(&:to_s)) + entries = zf.entries.sort_by(&:name).reverse entries.each do |e| zf.remove e zf.get_output_stream(e) { |os| os.write 'foo' } end - entryNames = entries.map { |e| e.to_s } + entry_names = entries.map(&:to_s) end ::Zip::File.open(TEST_ZIP.zip_name) do |zf| - assert_equal(entryNames, zf.entries.map { |e| e.to_s }) + assert_equal(entry_names, zf.entries.map(&:to_s)) end end @@ -617,6 +643,7 @@ Zip::File.open_buffer(f) do |zipfile| zipfile.each do |entry| next unless entry.name =~ /README.md/ + data = zipfile.read(entry) end end @@ -653,14 +680,35 @@ ::Zip::File.open('test/data/test.xls') end + def test_find_get_entry + ::Zip::File.open(TEST_ZIP.zip_name) do |zf| + assert_nil zf.find_entry('not_in_here.txt') + + refute_nil zf.find_entry('test/data/generated/empty.txt') + + assert_raises(Errno::ENOENT) do + zf.get_entry('not_in_here.txt') + end + + # Should not raise anything. + zf.get_entry('test/data/generated/empty.txt') + end + end + private - def assert_contains(zf, entryName, filename = entryName) - assert(zf.entries.detect { |e| e.name == entryName } != nil, "entry #{entryName} not in #{zf.entries.join(', ')} in zip file #{zf}") - assert_entry_contents(zf, entryName, filename) if File.exist?(filename) + def assert_contains(zip_file, entry_name, filename = entry_name) + refute_nil( + zip_file.entries.detect { |e| e.name == entry_name }, + "entry #{entry_name} not in #{zip_file.entries.join(', ')} in zip file #{zip_file}" + ) + assert_entry_contents(zip_file, entry_name, filename) if File.exist?(filename) end - def assert_not_contains(zf, entryName) - assert(zf.entries.detect { |e| e.name == entryName }.nil?, "entry #{entryName} in #{zf.entries.join(', ')} in zip file #{zf}") + def assert_not_contains(zip_file, entry_name) + assert_nil( + zip_file.entries.detect { |e| e.name == entry_name }, + "entry #{entry_name} in #{zip_file.entries.join(', ')} in zip file #{zip_file}" + ) end end diff -Nru ruby-zip-2.0.0/test/gentestfiles.rb ruby-zip-2.3.0/test/gentestfiles.rb --- ruby-zip-2.0.0/test/gentestfiles.rb 2019-09-25 20:23:47.000000000 +0000 +++ ruby-zip-2.3.0/test/gentestfiles.rb 2020-03-14 12:00:50.000000000 +0000 @@ -52,6 +52,7 @@ def ensure_dir(name) if File.exist?(name) return if File.stat(name).directory? + File.delete(name) end Dir.mkdir(name) @@ -71,55 +72,85 @@ end def self.create_test_zips - raise "failed to create test zip '#{TEST_ZIP1.zip_name}'" unless system("/usr/bin/zip -q #{TEST_ZIP1.zip_name} test/data/file2.txt") - raise "failed to remove entry from '#{TEST_ZIP1.zip_name}'" unless system("/usr/bin/zip -q #{TEST_ZIP1.zip_name} -d test/data/file2.txt") + raise "failed to create test zip '#{TEST_ZIP1.zip_name}'" \ + unless system("/usr/bin/zip -q #{TEST_ZIP1.zip_name} test/data/file2.txt") + raise "failed to remove entry from '#{TEST_ZIP1.zip_name}'" \ + unless system( + "/usr/bin/zip -q #{TEST_ZIP1.zip_name} -d test/data/file2.txt" + ) File.open('test/data/generated/empty.txt', 'w') {} File.open('test/data/generated/empty_chmod640.txt', 'w') {} ::File.chmod(0o640, 'test/data/generated/empty_chmod640.txt') File.open('test/data/generated/short.txt', 'w') { |file| file << 'ABCDEF' } - ziptestTxt = '' - File.open('test/data/file2.txt') { |file| ziptestTxt = file.read } + test_text = '' + File.open('test/data/file2.txt') { |file| test_text = file.read } File.open('test/data/generated/longAscii.txt', 'w') do |file| - file << ziptestTxt while file.tell < 1E5 + file << test_text while file.tell < 1E5 end - testBinaryPattern = '' - File.open('test/data/generated/empty.zip') { |file| testBinaryPattern = file.read } - testBinaryPattern *= 4 + binary_pattern = '' + File.open('test/data/generated/empty.zip') do |file| + binary_pattern = file.read + end + binary_pattern *= 4 File.open('test/data/generated/longBinary.bin', 'wb') do |file| - file << testBinaryPattern << rand << "\0" while file.tell < 6E5 + file << binary_pattern << rand << "\0" while file.tell < 6E5 end - raise "failed to create test zip '#{TEST_ZIP2.zip_name}'" unless system("/usr/bin/zip -q #{TEST_ZIP2.zip_name} #{TEST_ZIP2.entry_names.join(' ')}") + raise "failed to create test zip '#{TEST_ZIP2.zip_name}'" \ + unless system( + "/usr/bin/zip -q #{TEST_ZIP2.zip_name} #{TEST_ZIP2.entry_names.join(' ')}" + ) if RUBY_PLATFORM =~ /mswin|mingw|cygwin/ - raise "failed to add comment to test zip '#{TEST_ZIP2.zip_name}'" unless system("echo #{TEST_ZIP2.comment}| /usr/bin/zip -zq #{TEST_ZIP2.zip_name}\"") + raise "failed to add comment to test zip '#{TEST_ZIP2.zip_name}'" \ + unless system( + "echo #{TEST_ZIP2.comment}| /usr/bin/zip -zq #{TEST_ZIP2.zip_name}\"" + ) else # without bash system interprets everything after echo as parameters to # echo including | zip -z ... - raise "failed to add comment to test zip '#{TEST_ZIP2.zip_name}'" unless system("bash -c \"echo #{TEST_ZIP2.comment} | /usr/bin/zip -zq #{TEST_ZIP2.zip_name}\"") + raise "failed to add comment to test zip '#{TEST_ZIP2.zip_name}'" \ + unless system( + "bash -c \"echo #{TEST_ZIP2.comment} | /usr/bin/zip -zq #{TEST_ZIP2.zip_name}\"" + ) end - raise "failed to create test zip '#{TEST_ZIP3.zip_name}'" unless system("/usr/bin/zip -q #{TEST_ZIP3.zip_name} #{TEST_ZIP3.entry_names.join(' ')}") - - raise "failed to create test zip '#{TEST_ZIP4.zip_name}'" unless system("/usr/bin/zip -q #{TEST_ZIP4.zip_name} #{TEST_ZIP4.entry_names.join(' ')}") - rescue + raise "failed to create test zip '#{TEST_ZIP3.zip_name}'" \ + unless system( + "/usr/bin/zip -q #{TEST_ZIP3.zip_name} #{TEST_ZIP3.entry_names.join(' ')}" + ) + + raise "failed to create test zip '#{TEST_ZIP4.zip_name}'" \ + unless system( + "/usr/bin/zip -q #{TEST_ZIP4.zip_name} #{TEST_ZIP4.entry_names.join(' ')}" + ) + rescue StandardError # If there are any Windows developers wanting to use a command line zip.exe # to help create the following files, there's a free one available from # http://stahlworks.com/dev/index.php?tool=zipunzip # that works with the above code - raise $!.to_s + + raise $ERROR_INFO.to_s + "\n\nziptest.rb requires the Info-ZIP program 'zip' in the path\n" \ "to create test data. If you don't have it you can download\n" \ 'the necessary test files at http://sf.net/projects/rubyzip.' end TEST_ZIP1 = TestZipFile.new('test/data/generated/empty.zip', []) - TEST_ZIP2 = TestZipFile.new('test/data/generated/5entry.zip', %w[test/data/generated/longAscii.txt test/data/generated/empty.txt test/data/generated/empty_chmod640.txt test/data/generated/short.txt test/data/generated/longBinary.bin], - 'my zip comment') + TEST_ZIP2 = TestZipFile.new( + 'test/data/generated/5entry.zip', + %w[ + test/data/generated/longAscii.txt + test/data/generated/empty.txt + test/data/generated/empty_chmod640.txt + test/data/generated/short.txt + test/data/generated/longBinary.bin + ], + 'my zip comment' + ) TEST_ZIP3 = TestZipFile.new('test/data/generated/test1.zip', %w[test/data/file1.txt]) TEST_ZIP4 = TestZipFile.new('test/data/generated/zipWithDir.zip', ['test/data/file1.txt', TestFiles::EMPTY_TEST_DIR]) diff -Nru ruby-zip-2.0.0/test/ioextras/abstract_input_stream_test.rb ruby-zip-2.3.0/test/ioextras/abstract_input_stream_test.rb --- ruby-zip-2.0.0/test/ioextras/abstract_input_stream_test.rb 2019-09-25 20:23:47.000000000 +0000 +++ ruby-zip-2.3.0/test/ioextras/abstract_input_stream_test.rb 2020-03-14 12:00:50.000000000 +0000 @@ -4,23 +4,23 @@ class AbstractInputStreamTest < MiniTest::Test # AbstractInputStream subclass that provides a read method - TEST_LINES = ["Hello world#{$/}", - "this is the second line#{$/}", + TEST_LINES = ["Hello world#{$INPUT_RECORD_SEPARATOR}", + "this is the second line#{$INPUT_RECORD_SEPARATOR}", 'this is the last line'] TEST_STRING = TEST_LINES.join class TestAbstractInputStream include ::Zip::IOExtras::AbstractInputStream - def initialize(aString) + def initialize(string) super() - @contents = aString - @readPointer = 0 + @contents = string + @read_ptr = 0 end - def sysread(charsToRead, _buf = nil) - retVal = @contents[@readPointer, charsToRead] - @readPointer += charsToRead - retVal + def sysread(chars_to_read, _buf = nil) + ret_val = @contents[@read_ptr, chars_to_read] + @read_ptr += chars_to_read + ret_val end def produce_input @@ -28,7 +28,7 @@ end def input_finished? - @contents[@readPointer].nil? + @contents[@read_ptr].nil? end end @@ -50,7 +50,7 @@ def test_gets_multi_char_seperator assert_equal('Hell', @io.gets('ll')) - assert_equal("o world#{$/}this is the second l", @io.gets('d l')) + assert_equal("o world#{$INPUT_RECORD_SEPARATOR}this is the second l", @io.gets('d l')) end LONG_LINES = [ @@ -80,10 +80,10 @@ end def test_each_line - lineNumber = 0 + line_num = 0 @io.each_line do |line| - assert_equal(TEST_LINES[lineNumber], line) - lineNumber += 1 + assert_equal(TEST_LINES[line_num], line) + line_num += 1 end end @@ -95,7 +95,7 @@ test_gets begin @io.readline - fail 'EOFError expected' + raise 'EOFError expected' rescue EOFError end end diff -Nru ruby-zip-2.0.0/test/ioextras/abstract_output_stream_test.rb ruby-zip-2.3.0/test/ioextras/abstract_output_stream_test.rb --- ruby-zip-2.0.0/test/ioextras/abstract_output_stream_test.rb 2019-09-25 20:23:47.000000000 +0000 +++ ruby-zip-2.3.0/test/ioextras/abstract_output_stream_test.rb 2020-03-14 12:00:50.000000000 +0000 @@ -20,13 +20,13 @@ def setup @output_stream = TestOutputStream.new - @origCommaSep = $, - @origOutputSep = $\ + @save_comma_sep = $OUTPUT_FIELD_SEPARATOR + @save_output_sep = $OUTPUT_RECORD_SEPARATOR end def teardown - $, = @origCommaSep - $\ = @origOutputSep + $, = @save_comma_sep + $\ = @save_output_sep end def test_write diff -Nru ruby-zip-2.0.0/test/local_entry_test.rb ruby-zip-2.3.0/test/local_entry_test.rb --- ruby-zip-2.0.0/test/local_entry_test.rb 2019-09-25 20:23:47.000000000 +0000 +++ ruby-zip-2.3.0/test/local_entry_test.rb 2020-03-14 12:00:50.000000000 +0000 @@ -41,56 +41,71 @@ end def test_read_local_entry_from_truncated_zip_file - zipFragment = '' - ::File.open(TestZipFile::TEST_ZIP2.zip_name) { |f| zipFragment = f.read(12) } # local header is at least 30 bytes - zipFragment.extend(IOizeString).reset + fragment = '' + # local header is at least 30 bytes + ::File.open(TestZipFile::TEST_ZIP2.zip_name) { |f| fragment = f.read(12) } + + fragment.extend(IOizeString).reset entry = ::Zip::Entry.new - entry.read_local_entry(zipFragment) - fail 'ZipError expected' + entry.read_local_entry(fragment) + raise 'ZipError expected' rescue ::Zip::Error end def test_write_entry - entry = ::Zip::Entry.new('file.zip', 'entryName', 'my little comment', + entry = ::Zip::Entry.new('file.zip', 'entry_name', 'my little comment', 'thisIsSomeExtraInformation', 100, 987_654, ::Zip::Entry::DEFLATED, 400) write_to_file(LEH_FILE, CEH_FILE, entry) - entryReadLocal, entryReadCentral = read_from_file(LEH_FILE, CEH_FILE) - assert(entryReadCentral.extra['Zip64Placeholder'].nil?, 'zip64 placeholder should not be used in central directory') - compare_local_entry_headers(entry, entryReadLocal) - compare_c_dir_entry_headers(entry, entryReadCentral) + local_entry, central_entry = read_from_file(LEH_FILE, CEH_FILE) + assert( + central_entry.extra['Zip64Placeholder'].nil?, + 'zip64 placeholder should not be used in central directory' + ) + compare_local_entry_headers(entry, local_entry) + compare_c_dir_entry_headers(entry, central_entry) end def test_write_entry_with_zip64 ::Zip.write_zip64_support = true - entry = ::Zip::Entry.new('file.zip', 'entryName', 'my little comment', + entry = ::Zip::Entry.new('file.zip', 'entry_name', 'my little comment', 'thisIsSomeExtraInformation', 100, 987_654, ::Zip::Entry::DEFLATED, 400) + write_to_file(LEH_FILE, CEH_FILE, entry) - entryReadLocal, entryReadCentral = read_from_file(LEH_FILE, CEH_FILE) - assert(entryReadLocal.extra['Zip64Placeholder'], 'zip64 placeholder should be used in local file header') - entryReadLocal.extra.delete('Zip64Placeholder') # it was removed when writing the c_dir_entry, so remove from compare - assert(entryReadCentral.extra['Zip64Placeholder'].nil?, 'zip64 placeholder should not be used in central directory') - compare_local_entry_headers(entry, entryReadLocal) - compare_c_dir_entry_headers(entry, entryReadCentral) + local_entry, central_entry = read_from_file(LEH_FILE, CEH_FILE) + assert( + local_entry.extra['Zip64Placeholder'], + 'zip64 placeholder should be used in local file header' + ) + + # This was removed when writing the c_dir_entry, so remove from compare. + local_entry.extra.delete('Zip64Placeholder') + assert( + central_entry.extra['Zip64Placeholder'].nil?, + 'zip64 placeholder should not be used in central directory' + ) + + compare_local_entry_headers(entry, local_entry) + compare_c_dir_entry_headers(entry, central_entry) end def test_write_64entry ::Zip.write_zip64_support = true - entry = ::Zip::Entry.new('bigfile.zip', 'entryName', 'my little equine', + entry = ::Zip::Entry.new('bigfile.zip', 'entry_name', 'my little equine', 'malformed extra field because why not', 0x7766554433221100, 0xDEADBEEF, ::Zip::Entry::DEFLATED, 0x9988776655443322) write_to_file(LEH_FILE, CEH_FILE, entry) - entryReadLocal, entryReadCentral = read_from_file(LEH_FILE, CEH_FILE) - compare_local_entry_headers(entry, entryReadLocal) - compare_c_dir_entry_headers(entry, entryReadCentral) + local_entry, central_entry = read_from_file(LEH_FILE, CEH_FILE) + compare_local_entry_headers(entry, local_entry) + compare_c_dir_entry_headers(entry, central_entry) end def test_rewrite_local_header64 ::Zip.write_zip64_support = true buf1 = StringIO.new - entry = ::Zip::Entry.new('file.zip', 'entryName') + entry = ::Zip::Entry.new('file.zip', 'entry_name') entry.write_local_entry(buf1) assert(entry.extra['Zip64'].nil?, 'zip64 extra is unnecessarily present') @@ -104,7 +119,7 @@ end def test_read_local_offset - entry = ::Zip::Entry.new('file.zip', 'entryName') + entry = ::Zip::Entry.new('file.zip', 'entry_name') entry.local_header_offset = 12_345 ::File.open(CEH_FILE, 'wb') { |f| entry.write_c_dir_entry(f) } read_entry = nil @@ -114,7 +129,7 @@ def test_read64_local_offset ::Zip.write_zip64_support = true - entry = ::Zip::Entry.new('file.zip', 'entryName') + entry = ::Zip::Entry.new('file.zip', 'entry_name') entry.local_header_offset = 0x0123456789ABCDEF ::File.open(CEH_FILE, 'wb') { |f| entry.write_c_dir_entry(f) } read_entry = nil @@ -139,16 +154,23 @@ assert_equal(entry1.comment, entry2.comment) end - def write_to_file(localFileName, centralFileName, entry) - ::File.open(localFileName, 'wb') { |f| entry.write_local_entry(f) } - ::File.open(centralFileName, 'wb') { |f| entry.write_c_dir_entry(f) } + def write_to_file(local_filename, central_filename, entry) + ::File.open(local_filename, 'wb') { |f| entry.write_local_entry(f) } + ::File.open(central_filename, 'wb') { |f| entry.write_c_dir_entry(f) } end - def read_from_file(localFileName, centralFileName) - localEntry = nil - cdirEntry = nil - ::File.open(localFileName, 'rb') { |f| localEntry = ::Zip::Entry.read_local_entry(f) } - ::File.open(centralFileName, 'rb') { |f| cdirEntry = ::Zip::Entry.read_c_dir_entry(f) } - [localEntry, cdirEntry] + def read_from_file(local_filename, central_filename) + local_entry = nil + cdir_entry = nil + + ::File.open(local_filename, 'rb') do |f| + local_entry = ::Zip::Entry.read_local_entry(f) + end + + ::File.open(central_filename, 'rb') do |f| + cdir_entry = ::Zip::Entry.read_c_dir_entry(f) + end + + [local_entry, cdir_entry] end end diff -Nru ruby-zip-2.0.0/test/output_stream_test.rb ruby-zip-2.3.0/test/output_stream_test.rb --- ruby-zip-2.0.0/test/output_stream_test.rb 2019-09-25 20:23:47.000000000 +0000 +++ ruby-zip-2.3.0/test/output_stream_test.rb 2020-03-14 12:00:50.000000000 +0000 @@ -32,6 +32,15 @@ assert_test_zip_contents(TEST_ZIP) end + def test_write_buffer_binmode + io = ::StringIO.new('') + buffer = ::Zip::OutputStream.write_buffer(io) do |zos| + zos.comment = TEST_ZIP.comment + write_test_zip(zos) + end + assert_equal Encoding::ASCII_8BIT, buffer.external_encoding + end + def test_write_buffer_with_temp_file tmp_file = Tempfile.new('') @@ -57,11 +66,11 @@ name = TestFiles::EMPTY_TEST_DIR begin ::Zip::OutputStream.open(name) - rescue Exception - assert($!.kind_of?(Errno::EISDIR) || # Linux - $!.kind_of?(Errno::EEXIST) || # Windows/cygwin - $!.kind_of?(Errno::EACCES), # Windows - "Expected Errno::EISDIR (or on win/cygwin: Errno::EEXIST), but was: #{$!.class}") + rescue SystemCallError + assert($ERROR_INFO.kind_of?(Errno::EISDIR) || # Linux + $ERROR_INFO.kind_of?(Errno::EEXIST) || # Windows/cygwin + $ERROR_INFO.kind_of?(Errno::EACCES), # Windows + "Expected Errno::EISDIR (or on win/cygwin: Errno::EEXIST), but was: #{$ERROR_INFO.class}") end end @@ -90,7 +99,8 @@ ::Zip::InputStream.open(TEST_ZIP.zip_name) do |io| while (entry = io.get_next_entry) - assert(::Zip::DOSTime.at(file.mtime).dos_equals(::Zip::DOSTime.at(entry.mtime))) # Compare DOS Times, since they are stored with two seconds accuracy + # Compare DOS Times, since they are stored with two seconds accuracy + assert(::Zip::DOSTime.at(file.mtime).dos_equals(::Zip::DOSTime.at(entry.mtime))) end end end @@ -120,9 +130,9 @@ end def write_test_zip(zos) - TEST_ZIP.entry_names.each do |entryName| - zos.put_next_entry(entryName) - File.open(entryName, 'rb') { |f| zos.write(f.read) } + TEST_ZIP.entry_names.each do |entry_name| + zos.put_next_entry(entry_name) + File.open(entry_name, 'rb') { |f| zos.write(f.read) } end end end diff -Nru ruby-zip-2.0.0/test/path_traversal_test.rb ruby-zip-2.3.0/test/path_traversal_test.rb --- ruby-zip-2.0.0/test/path_traversal_test.rb 2019-09-25 20:23:47.000000000 +0000 +++ ruby-zip-2.3.0/test/path_traversal_test.rb 2020-03-14 12:00:50.000000000 +0000 @@ -1,3 +1,5 @@ +require 'test_helper' + class PathTraversalTest < MiniTest::Test TEST_FILE_ROOT = File.absolute_path('test/data/path_traversal') @@ -8,10 +10,18 @@ FileUtils.rm_f '/tmp/file.txt' end - def extract_path_traversal_zip(name) - Zip::File.open(File.join(TEST_FILE_ROOT, name)) do |zip_file| - zip_file.each do |entry| - entry.extract + def extract_paths(zip_path, entries) + ::Zip::File.open(::File.join(TEST_FILE_ROOT, zip_path)) do |zip| + entries.each do |entry, test| + if test == :error + assert_raises(Errno::ENOENT) do + zip.find_entry(entry).extract + end + else + assert_output('', test) do + zip.find_entry(entry).extract + end + end end end end @@ -27,65 +37,79 @@ end def test_leading_slash + entries = { '/tmp/moo' => /WARNING: skipped \'\/tmp\/moo\'/ } in_tmpdir do - extract_path_traversal_zip 'jwilk/absolute1.zip' + extract_paths(['jwilk', 'absolute1.zip'], entries) refute File.exist?('/tmp/moo') end end def test_multiple_leading_slashes + entries = { '//tmp/moo' => /WARNING: skipped \'\/\/tmp\/moo\'/ } in_tmpdir do - extract_path_traversal_zip 'jwilk/absolute2.zip' + extract_paths(['jwilk', 'absolute2.zip'], entries) refute File.exist?('/tmp/moo') end end def test_leading_dot_dot + entries = { '../moo' => /WARNING: skipped \'\.\.\/moo\'/ } in_tmpdir do - extract_path_traversal_zip 'jwilk/relative0.zip' + extract_paths(['jwilk', 'relative0.zip'], entries) refute File.exist?('../moo') end end def test_non_leading_dot_dot_with_existing_folder + entries = { + 'tmp/' => '', + 'tmp/../../moo' => /WARNING: skipped \'tmp\/\.\.\/\.\.\/moo\'/ + } in_tmpdir do - extract_path_traversal_zip 'relative1.zip' + extract_paths('relative1.zip', entries) assert Dir.exist?('tmp') refute File.exist?('../moo') end end def test_non_leading_dot_dot_without_existing_folder + entries = { 'tmp/../../moo' => /WARNING: skipped \'tmp\/\.\.\/\.\.\/moo\'/ } in_tmpdir do - extract_path_traversal_zip 'jwilk/relative2.zip' + extract_paths(['jwilk', 'relative2.zip'], entries) refute File.exist?('../moo') end end def test_file_symlink + entries = { 'moo' => '' } in_tmpdir do - extract_path_traversal_zip 'jwilk/symlink.zip' + extract_paths(['jwilk', 'symlink.zip'], entries) assert File.exist?('moo') refute File.exist?('/tmp/moo') end end def test_directory_symlink + # Can't create tmp/moo, because the tmp symlink is skipped. + entries = { + 'tmp' => /WARNING: skipped symlink \'tmp\'/, + 'tmp/moo' => :error + } in_tmpdir do - # Can't create tmp/moo, because the tmp symlink is skipped. - assert_raises Errno::ENOENT do - extract_path_traversal_zip 'jwilk/dirsymlink.zip' - end + extract_paths(['jwilk', 'dirsymlink.zip'], entries) refute File.exist?('/tmp/moo') end end def test_two_directory_symlinks_a + # Can't create par/moo because the symlinks are skipped. + entries = { + 'cur' => /WARNING: skipped symlink \'cur\'/, + 'par' => /WARNING: skipped symlink \'par\'/, + 'par/moo' => :error + } in_tmpdir do - # Can't create par/moo because the symlinks are skipped. - assert_raises Errno::ENOENT do - extract_path_traversal_zip 'jwilk/dirsymlink2a.zip' - end + extract_paths(['jwilk', 'dirsymlink2a.zip'], entries) refute File.exist?('cur') refute File.exist?('par') refute File.exist?('par/moo') @@ -93,26 +117,33 @@ end def test_two_directory_symlinks_b + # Can't create par/moo, because the symlinks are skipped. + entries = { + 'cur' => /WARNING: skipped symlink \'cur\'/, + 'cur/par' => /WARNING: skipped symlink \'cur\/par\'/, + 'par/moo' => :error + } in_tmpdir do - # Can't create par/moo, because the symlinks are skipped. - assert_raises Errno::ENOENT do - extract_path_traversal_zip 'jwilk/dirsymlink2b.zip' - end + extract_paths(['jwilk', 'dirsymlink2b.zip'], entries) refute File.exist?('cur') refute File.exist?('../moo') end end def test_entry_name_with_absolute_path_does_not_extract + entries = { + '/tmp/' => /WARNING: skipped \'\/tmp\/\'/, + '/tmp/file.txt' => /WARNING: skipped \'\/tmp\/file.txt\'/ + } in_tmpdir do - extract_path_traversal_zip 'tuzovakaoff/absolutepath.zip' + extract_paths(['tuzovakaoff', 'absolutepath.zip'], entries) refute File.exist?('/tmp/file.txt') end end def test_entry_name_with_absolute_path_extract_when_given_different_path in_tmpdir do |test_path| - zip_path = File.join(TEST_FILE_ROOT, 'tuzovakaoff/absolutepath.zip') + zip_path = File.join(TEST_FILE_ROOT, 'tuzovakaoff', 'absolutepath.zip') Zip::File.open(zip_path) do |zip_file| zip_file.each do |entry| entry.extract(File.join(test_path, entry.name)) @@ -123,18 +154,20 @@ end def test_entry_name_with_relative_symlink + # Doesn't create the symlink path, so can't create path/file.txt. + entries = { + 'path' => /WARNING: skipped symlink \'path\'/, + 'path/file.txt' => :error + } in_tmpdir do - # Doesn't create the symlink path, so can't create path/file.txt. - assert_raises Errno::ENOENT do - extract_path_traversal_zip 'tuzovakaoff/symlink.zip' - end + extract_paths(['tuzovakaoff', 'symlink.zip'], entries) refute File.exist?('/tmp/file.txt') end end def test_entry_name_with_tilde in_tmpdir do - extract_path_traversal_zip 'tilde.zip' + extract_paths('tilde.zip', '~tilde~' => '') assert File.exist?('~tilde~') end end diff -Nru ruby-zip-2.0.0/test/settings_test.rb ruby-zip-2.3.0/test/settings_test.rb --- ruby-zip-2.0.0/test/settings_test.rb 2019-09-25 20:23:47.000000000 +0000 +++ ruby-zip-2.3.0/test/settings_test.rb 2020-03-14 12:00:50.000000000 +0000 @@ -17,14 +17,14 @@ ::Zip.reset! end - def open_zip(&aProc) - assert(!aProc.nil?) - ::Zip::File.open(TestZipFile::TEST_ZIP4.zip_name, &aProc) + def open_zip(&a_proc) + refute_nil(a_proc) + ::Zip::File.open(TestZipFile::TEST_ZIP4.zip_name, &a_proc) end - def extract_test_dir(&aProc) + def extract_test_dir(&a_proc) open_zip do |zf| - zf.extract(TestFiles::EMPTY_TEST_DIR, TEST_OUT_NAME, &aProc) + zf.extract(TestFiles::EMPTY_TEST_DIR, TEST_OUT_NAME, &a_proc) end end @@ -54,15 +54,15 @@ def test_true_continue_on_exists_proc Zip.continue_on_exists_proc = true - replacedEntry = nil + replaced_entry = nil ::Zip::File.open(TEST_ZIP.zip_name) do |zf| - replacedEntry = zf.entries.first.name - zf.add(replacedEntry, 'test/data/file2.txt') + replaced_entry = zf.entries.first.name + zf.add(replaced_entry, 'test/data/file2.txt') end ::Zip::File.open(TEST_ZIP.zip_name) do |zf| - assert_contains(zf, replacedEntry, 'test/data/file2.txt') + assert_contains(zf, replaced_entry, 'test/data/file2.txt') end end @@ -80,7 +80,7 @@ test_file = File.join(File.dirname(__FILE__), 'data', 'WarnInvalidDate.zip') Zip.warn_invalid_date = true - assert_output('', /Invalid date\/time in zip entry/) do + assert_output('', /invalid date\/time in zip entry/) do ::Zip::File.open(test_file) do |_zf| end end @@ -88,8 +88,11 @@ private - def assert_contains(zf, entryName, filename = entryName) - assert(zf.entries.detect { |e| e.name == entryName } != nil, "entry #{entryName} not in #{zf.entries.join(', ')} in zip file #{zf}") - assert_entry_contents(zf, entryName, filename) if File.exist?(filename) + def assert_contains(zip_file, entry_name, filename = entry_name) + refute_nil( + zip_file.entries.detect { |e| e.name == entry_name }, + "entry #{entry_name} not in #{zip_file.entries.join(', ')} in zip file #{zip_file}" + ) + assert_entry_contents(zip_file, entry_name, filename) if File.exist?(filename) end end diff -Nru ruby-zip-2.0.0/test/stored_support_test.rb ruby-zip-2.3.0/test/stored_support_test.rb --- ruby-zip-2.0.0/test/stored_support_test.rb 1970-01-01 00:00:00.000000000 +0000 +++ ruby-zip-2.3.0/test/stored_support_test.rb 2020-03-14 12:00:50.000000000 +0000 @@ -0,0 +1,34 @@ +require 'test_helper' + +class StoredSupportTest < MiniTest::Test + STORED_ZIP_TEST_FILE = 'test/data/zipWithStoredCompression.zip' + ENCRYPTED_STORED_ZIP_TEST_FILE = 'test/data/zipWithStoredCompressionAndEncryption.zip' + INPUT_FILE1 = 'test/data/file1.txt' + INPUT_FILE2 = 'test/data/file2.txt' + + def test_read + Zip::InputStream.open(STORED_ZIP_TEST_FILE) do |zis| + entry = zis.get_next_entry + assert_equal 'file1.txt', entry.name + assert_equal 1_327, entry.size + assert_equal ::File.open(INPUT_FILE1, 'r').read, zis.read + entry = zis.get_next_entry + assert_equal 'file2.txt', entry.name + assert_equal 41_234, entry.size + assert_equal ::File.open(INPUT_FILE2, 'r').read, zis.read + end + end + + def test_encrypted_read + Zip::InputStream.open(ENCRYPTED_STORED_ZIP_TEST_FILE, 0, Zip::TraditionalDecrypter.new('password')) do |zis| + entry = zis.get_next_entry + assert_equal 'file1.txt', entry.name + assert_equal 1_327, entry.size + assert_equal ::File.open(INPUT_FILE1, 'r').read, zis.read + entry = zis.get_next_entry + assert_equal 'file2.txt', entry.name + assert_equal 41_234, entry.size + assert_equal ::File.open(INPUT_FILE2, 'r').read, zis.read + end + end +end diff -Nru ruby-zip-2.0.0/test/test_helper.rb ruby-zip-2.3.0/test/test_helper.rb --- ruby-zip-2.0.0/test/test_helper.rb 2019-09-25 20:23:47.000000000 +0000 +++ ruby-zip-2.3.0/test/test_helper.rb 2020-03-14 12:00:50.000000000 +0000 @@ -2,6 +2,7 @@ require 'minitest/autorun' require 'minitest/unit' require 'fileutils' +require 'tmpdir' require 'digest/sha1' require 'zip' require 'gentestfiles' @@ -23,29 +24,28 @@ def read(count = nil) @tell ||= 0 - count = size unless count - retVal = slice(@tell, count) + count ||= size + ret_val = slice(@tell, count) @tell += count - retVal + ret_val end def seek(index, offset) @tell ||= 0 case offset when IO::SEEK_END - newPos = size + index + pos = size + index when IO::SEEK_SET - newPos = index + pos = index when IO::SEEK_CUR - newPos = @tell + index + pos = @tell + index else raise 'Error in test method IOizeString::seek' end - if newPos < 0 || newPos >= size - raise Errno::EINVAL - else - @tell = newPos - end + + raise Errno::EINVAL if pos < 0 || pos >= size + + @tell = pos end def reset @@ -54,38 +54,26 @@ end module DecompressorTests - # expects @refText, @refLines and @decompressor + # expects @ref_text, @ref_lines and @decompressor TEST_FILE = 'test/data/file1.txt' def setup - @refText = '' - File.open(TEST_FILE) { |f| @refText = f.read } - @refLines = @refText.split($/) + @ref_text = '' + File.open(TEST_FILE) { |f| @ref_text = f.read } + @ref_lines = @ref_text.split($INPUT_RECORD_SEPARATOR) end def test_read_everything - assert_equal(@refText, @decompressor.sysread) + assert_equal(@ref_text, @decompressor.read) end def test_read_in_chunks - chunkSize = 5 - while (decompressedChunk = @decompressor.sysread(chunkSize)) - assert_equal(@refText.slice!(0, chunkSize), decompressedChunk) + size = 5 + while (chunk = @decompressor.read(size)) + assert_equal(@ref_text.slice!(0, size), chunk) end - assert_equal(0, @refText.size) - end - - def test_mixing_reads_and_produce_input - # Just some preconditions to make sure we have enough data for this test - assert(@refText.length > 1000) - assert(@refLines.length > 40) - - assert_equal(@refText[0...100], @decompressor.sysread(100)) - - assert(!@decompressor.input_finished?) - buf = @decompressor.produce_input - assert_equal(@refText[100...(100 + buf.length)], buf) + assert_equal(0, @ref_text.size) end end @@ -94,20 +82,20 @@ assert_entry(filename, zis, zis.get_next_entry.name) end - def assert_entry(filename, zis, entryName) - assert_equal(filename, entryName) - assert_entry_contents_for_stream(filename, zis, entryName) + def assert_entry(filename, zis, entry_name) + assert_equal(filename, entry_name) + assert_entry_contents_for_stream(filename, zis, entry_name) end - def assert_entry_contents_for_stream(filename, zis, entryName) + def assert_entry_contents_for_stream(filename, zis, entry_name) File.open(filename, 'rb') do |file| expected = file.read actual = zis.read if expected != actual if (expected && actual) && (expected.length > 400 || actual.length > 400) - zipEntryFilename = entryName + '.zipEntry' - File.open(zipEntryFilename, 'wb') { |entryfile| entryfile << actual } - fail("File '#{filename}' is different from '#{zipEntryFilename}'") + entry_filename = entry_name + '.zipEntry' + File.open(entry_filename, 'wb') { |entryfile| entryfile << actual } + raise("File '#{filename}' is different from '#{entry_filename}'") else assert_equal(expected, actual) end @@ -115,37 +103,37 @@ end end - def self.assert_contents(filename, aString) - fileContents = '' - File.open(filename, 'rb') { |f| fileContents = f.read } - if fileContents != aString - if fileContents.length > 400 || aString.length > 400 - stringFile = filename + '.other' - File.open(stringFile, 'wb') { |f| f << aString } - fail("File '#{filename}' is different from contents of string stored in '#{stringFile}'") - else - assert_equal(fileContents, aString) - end + def self.assert_contents(filename, string) + contents = '' + File.open(filename, 'rb') { |f| contents = f.read } + return unless contents != string + + if contents.length > 400 || string.length > 400 + string_file = filename + '.other' + File.open(string_file, 'wb') { |f| f << string } + raise("File '#{filename}' is different from contents of string stored in '#{string_file}'") + else + assert_equal(contents, string) end end - def assert_stream_contents(zis, testZipFile) + def assert_stream_contents(zis, zip_file) assert(!zis.nil?) - testZipFile.entry_names.each do |entryName| - assert_next_entry(entryName, zis) + zip_file.entry_names.each do |entry_name| + assert_next_entry(entry_name, zis) end assert_nil(zis.get_next_entry) end - def assert_test_zip_contents(testZipFile) - ::Zip::InputStream.open(testZipFile.zip_name) do |zis| - assert_stream_contents(zis, testZipFile) + def assert_test_zip_contents(zip_file) + ::Zip::InputStream.open(zip_file.zip_name) do |zis| + assert_stream_contents(zis, zip_file) end end - def assert_entry_contents(zipFile, entryName, filename = entryName.to_s) - zis = zipFile.get_input_stream(entryName) - assert_entry_contents_for_stream(filename, zis, entryName) + def assert_entry_contents(zip_file, entry_name, filename = entry_name.to_s) + zis = zip_file.get_input_stream(entry_name) + assert_entry_contents_for_stream(filename, zis, entry_name) ensure zis.close if zis end @@ -167,23 +155,23 @@ end end - def run_crc_test(compressorClass) + def run_crc_test(compressor_class) str = "Here's a nice little text to compute the crc for! Ho hum, it is nice nice nice nice indeed." - fakeOut = TestOutputStream.new + fake_out = TestOutputStream.new - deflater = compressorClass.new(fakeOut) + deflater = compressor_class.new(fake_out) deflater << str assert_equal(0x919920fc, deflater.crc) end end module Enumerable - def compare_enumerables(otherEnumerable) - otherAsArray = otherEnumerable.to_a + def compare_enumerables(enumerable) + array = enumerable.to_a each_with_index do |element, index| - return false unless yield(element, otherAsArray[index]) + return false unless yield(element, array[index]) end - size == otherAsArray.size + size == array.size end end @@ -202,21 +190,24 @@ end module ExtraAssertions - def assert_forwarded(anObject, method, retVal, *expectedArgs) - callArgs = nil - setCallArgsProc = proc { |args| callArgs = args } - anObject.instance_eval <<-"end_eval" + def assert_forwarded(object, method, ret_val, *expected_args) + call_args = nil + call_args_proc = proc { |args| call_args = args } + object.instance_eval <<-END_EVAL, __FILE__, __LINE__ + 1 alias #{method}_org #{method} def #{method}(*args) - ObjectSpace._id2ref(#{setCallArgsProc.object_id}).call(args) - ObjectSpace._id2ref(#{retVal.object_id}) + ObjectSpace._id2ref(#{call_args_proc.object_id}).call(args) + ObjectSpace._id2ref(#{ret_val.object_id}) end - end_eval + END_EVAL - assert_equal(retVal, yield) # Invoke test - assert_equal(expectedArgs, callArgs) + assert_equal(ret_val, yield) # Invoke test + assert_equal(expected_args, call_args) ensure - anObject.instance_eval "undef #{method}; alias #{method} #{method}_org" + object.instance_eval <<-END_EVAL, __FILE__, __LINE__ + 1 + undef #{method} + alias #{method} #{method}_org + END_EVAL end end diff -Nru ruby-zip-2.0.0/test/unicode_file_names_and_comments_test.rb ruby-zip-2.3.0/test/unicode_file_names_and_comments_test.rb --- ruby-zip-2.0.0/test/unicode_file_names_and_comments_test.rb 2019-09-25 20:23:47.000000000 +0000 +++ ruby-zip-2.3.0/test/unicode_file_names_and_comments_test.rb 2020-03-14 12:00:50.000000000 +0000 @@ -1,5 +1,3 @@ -# encoding: utf-8 - require 'test_helper' class ZipUnicodeFileNamesAndComments < MiniTest::Test diff -Nru ruby-zip-2.0.0/.travis.yml ruby-zip-2.3.0/.travis.yml --- ruby-zip-2.0.0/.travis.yml 2019-09-25 20:23:47.000000000 +0000 +++ ruby-zip-2.3.0/.travis.yml 2020-03-14 12:00:50.000000000 +0000 @@ -1,17 +1,21 @@ language: ruby -dist: trusty +dist: xenial cache: bundler rvm: - 2.4 - 2.5 - 2.6 + - 2.7 - ruby-head matrix: + fast_finish: true include: - rvm: jruby-9.2 jdk: openjdk8 + - rvm: jruby-9.2 + jdk: openjdk11 - rvm: jruby-head - jdk: openjdk8 + jdk: openjdk11 - rvm: rbx-4 allow_failures: - rvm: ruby-head