diff --git a/.rubocop.yml b/.rubocop.yml index a408fa0d..27712bd8 100644 --- a/.rubocop.yml +++ b/.rubocop.yml @@ -1,6 +1,84 @@ -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' + +# Rubocop confuses these as instances of "memoization". +Naming/MemoizedInstanceVariableName: + Exclude: + - 'lib/zip/extra_field/old_unix.rb' + - 'lib/zip/extra_field/unix.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 --git a/.rubocop_rubyzip.yml b/.rubocop_rubyzip.yml deleted file mode 100644 index 3030f8a0..00000000 --- a/.rubocop_rubyzip.yml +++ /dev/null @@ -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 --git a/.rubocop_todo.yml b/.rubocop_todo.yml new file mode 100644 index 00000000..4bff4fa4 --- /dev/null +++ b/.rubocop_todo.yml @@ -0,0 +1,164 @@ +# 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' + - 'test/file_permissions_test.rb' + +# Offense count: 18 +# Configuration parameters: MinNameLength, AllowNamesEndingInNumbers, AllowedNames, ForbiddenNames. +Naming/BlockParameterName: + Exclude: + - 'lib/zip/file.rb' + - 'lib/zip/filesystem.rb' + - 'samples/zipfind.rb' + - 'test/central_directory_test.rb' + - 'test/file_extract_directory_test.rb' + - 'test/file_extract_test.rb' + - 'test/output_stream_test.rb' + - 'test/test_helper.rb' + +# Offense count: 140 +# Configuration parameters: MinNameLength, AllowNamesEndingInNumbers, AllowedNames, ForbiddenNames. +# AllowedNames: io, id, to, by, on, in, at, ip, db, os +Naming/MethodParameterName: + Enabled: false + +# Offense count: 721 +# Configuration parameters: EnforcedStyle. +# SupportedStyles: snake_case, camelCase +Naming/VariableName: + Enabled: false + +# 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 --git a/Rakefile b/Rakefile index 44a9b287..717c6b73 100644 --- a/Rakefile +++ b/Rakefile @@ -1,5 +1,6 @@ require 'bundler/gem_tasks' require 'rake/testtask' +require 'rubocop/rake_task' task default: :test @@ -10,6 +11,8 @@ Rake::TestTask.new(:test) do |test| 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 --git a/lib/zip.rb b/lib/zip.rb index 5261fd77..8cf982a5 100644 --- a/lib/zip.rb +++ b/lib/zip.rb @@ -1,3 +1,4 @@ +require 'English' require 'delegate' require 'singleton' require 'tempfile' diff --git a/lib/zip/central_directory.rb b/lib/zip/central_directory.rb index 0b6874ef..496d668d 100644 --- a/lib/zip/central_directory.rb +++ b/lib/zip/central_directory.rb @@ -65,7 +65,7 @@ def write_64_e_o_c_d(io, offset, cdir_size) #:nodoc: @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 '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', + 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_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', + COMPRESSION_METHOD_BZIP2 => 'BZIP2', # RESERVED = 13 - COMPRESSION_METHOD_LZMA => 'LZMA', + COMPRESSION_METHOD_LZMA => 'LZMA', # RESERVED = 15 - COMPRESSION_METHOD_IBM_CMPSC => 'IBM z/OS CMPSC Compression', + 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', + 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 --git a/lib/zip/crypto/decrypted_io.rb b/lib/zip/crypto/decrypted_io.rb index 1dab17c0..61a377da 100644 --- a/lib/zip/crypto/decrypted_io.rb +++ b/lib/zip/crypto/decrypted_io.rb @@ -8,10 +8,11 @@ def initialize(io, decrypter) end def read(length = nil, outbuf = +'') - return ((length.nil? || length.zero?) ? "" : nil) if eof + return (length.nil? || length.zero? ? '' : nil) if eof while length.nil? || (buffer.bytesize < length) break if input_finished? + buffer << produce_input end diff --git a/lib/zip/entry.rb b/lib/zip/entry.rb index a24fb791..a67c6568 100644 --- a/lib/zip/entry.rb +++ b/lib/zip/entry.rb @@ -48,6 +48,7 @@ def set_default_vars_values 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,7 @@ def initialize(*args) @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? @@ -99,11 +100,12 @@ def time=(value) @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 @@ -124,6 +126,7 @@ def name_is_directory? #:nodoc:all 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 @@ -153,6 +156,7 @@ def calculate_local_header_size #:nodoc:all # 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 @@ -178,12 +182,9 @@ def extract(dest_path = nil, &block) 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 @@ -193,15 +194,15 @@ def to_s 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 @@ -226,8 +227,6 @@ def read_local_entry(io) end end - public - def unpack_local_entry(buf) @header_signature, @version, @@ -257,6 +256,7 @@ def read_local_entry(io) #:nodoc:all 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) @@ -269,13 +269,14 @@ def read_local_entry(io) #:nodoc:all 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 @@ -362,21 +363,24 @@ def set_ftype_from_c_dir_entry 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)) @@ -410,6 +414,7 @@ def file_stat(path) # :nodoc: 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 @@ -496,6 +501,7 @@ def write_c_dir_entry(io) #:nodoc:all 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) @@ -619,15 +625,13 @@ def create_file(dest_path, _continue_on_exists_proc = proc { Zip.continue_on_exi 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 - warn "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 @@ -637,6 +641,7 @@ def create_file(dest_path, _continue_on_exists_proc = proc { Zip.continue_on_exi 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 @@ -661,6 +666,7 @@ def create_symlink(dest_path) # (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 @@ -675,6 +681,7 @@ def data_descriptor_size # 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 --git a/lib/zip/entry_set.rb b/lib/zip/entry_set.rb index 3272b2a4..9c503781 100644 --- a/lib/zip/entry_set.rb +++ b/lib/zip/entry_set.rb @@ -50,6 +50,7 @@ def dup def ==(other) return false unless other.kind_of?(EntrySet) + @entry_set.values == other.entry_set.values end @@ -60,6 +61,7 @@ def parent(entry) 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 --git a/lib/zip/extra_field.rb b/lib/zip/extra_field.rb index 0dcf0d5e..e4b00b66 100644 --- a/lib/zip/extra_field.rb +++ b/lib/zip/extra_field.rb @@ -36,10 +36,11 @@ class << s 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 @@ def create(name) 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 --git a/lib/zip/extra_field/generic.rb b/lib/zip/extra_field/generic.rb index d61137fe..5eb702d6 100644 --- a/lib/zip/extra_field/generic.rb +++ b/lib/zip/extra_field/generic.rb @@ -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 @@ def self.name # 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) + 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 --git a/lib/zip/extra_field/ntfs.rb b/lib/zip/extra_field/ntfs.rb index 687704d8..f4f11b2d 100644 --- a/lib/zip/extra_field/ntfs.rb +++ b/lib/zip/extra_field/ntfs.rb @@ -19,6 +19,7 @@ def initialize(binstr = nil) def merge(binstr) return if binstr.empty? + size, content = initial_parse(binstr) (size && content) || return @@ -27,6 +28,7 @@ def merge(binstr) tag1 = tags[1] return unless tag1 + ntfs_mtime, ntfs_atime, ntfs_ctime = tag1.unpack('Q= 5 # how many times should we retry? + retried += 1 retry end diff --git a/lib/zip/input_stream.rb b/lib/zip/input_stream.rb index b4c502f5..f942d190 100644 --- a/lib/zip/input_stream.rb +++ b/lib/zip/input_stream.rb @@ -51,7 +51,7 @@ class InputStream # @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 @@ -73,6 +73,7 @@ def get_next_entry # 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) @@ -91,6 +92,7 @@ class << self 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 @@ -100,7 +102,7 @@ def open(filename_or_io, offset = 0, decrypter = nil) def open_buffer(filename_or_io, offset = 0) warn 'open_buffer is deprecated!!! Use open instead!' - open(filename_or_io, offset) + ::Zip::InputStream.open(filename_or_io, offset) end end @@ -120,9 +122,10 @@ def get_io(io_or_file, offset = 0) def open_entry @current_entry = ::Zip::Entry.read_local_entry(@archive_io) - if @current_entry && @current_entry.encrypted? && @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.incomplete? && @current_entry.crc == 0 \ && @current_entry.compressed_size == 0 \ && @current_entry.size == 0 && !@complete_entry diff --git a/lib/zip/ioextras.rb b/lib/zip/ioextras.rb index 2412480b..63774d33 100644 --- a/lib/zip/ioextras.rb +++ b/lib/zip/ioextras.rb @@ -25,7 +25,7 @@ def kind_of?(object) object == IO || super end end - end # IOExtras namespace module + end end require 'zip/ioextras/abstract_input_stream' diff --git a/lib/zip/ioextras/abstract_input_stream.rb b/lib/zip/ioextras/abstract_input_stream.rb index 58678a3f..8392d240 100644 --- a/lib/zip/ioextras/abstract_input_stream.rb +++ b/lib/zip/ioextras/abstract_input_stream.rb @@ -35,6 +35,7 @@ def read(number_of_bytes = nil, buf = '') if tbuf.nil? || tbuf.empty? return nil if number_of_bytes + return '' end @@ -48,13 +49,13 @@ def read(number_of_bytes = nil, buf = '') 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 @@ def gets(a_sep_string = $/, number_of_bytes = nil) 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,24 +97,26 @@ def flush 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_method :each, :each_line + alias each each_line def eof @output_buffer.empty? && input_finished? end - alias_method :eof?, :eof + alias eof? eof end end end diff --git a/lib/zip/ioextras/abstract_output_stream.rb b/lib/zip/ioextras/abstract_output_stream.rb index 69d0cc7c..b94c9d49 100644 --- a/lib/zip/ioextras/abstract_output_stream.rb +++ b/lib/zip/ioextras/abstract_output_stream.rb @@ -11,7 +11,7 @@ def write(data) 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 --git a/lib/zip/output_stream.rb b/lib/zip/output_stream.rb index d9bbc4df..2f628931 100644 --- a/lib/zip/output_stream.rb +++ b/lib/zip/output_stream.rb @@ -49,6 +49,7 @@ def initialize(file_name, stream = false, encrypter = nil) class << self def open(file_name, encrypter = nil) return new(file_name) unless block_given? + zos = new(file_name, false, encrypter) yield zos ensure @@ -66,6 +67,7 @@ def write_buffer(io = ::StringIO.new(''), encrypter = nil) # 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 +78,7 @@ def close # 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 +90,7 @@ def close_buffer # +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 +98,7 @@ def put_next_entry(entry_name, comment = nil, extra = nil, compression_method = 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 +108,8 @@ def put_next_entry(entry_name, comment = nil, extra = nil, compression_method = 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 +128,11 @@ def copy_raw_entry(entry) 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 +152,9 @@ def init_next_entry(entry, level = Zip.default_compression) 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 --git a/lib/zip/pass_thru_decompressor.rb b/lib/zip/pass_thru_decompressor.rb index ac21b61e..e638540e 100644 --- a/lib/zip/pass_thru_decompressor.rb +++ b/lib/zip/pass_thru_decompressor.rb @@ -6,7 +6,7 @@ def initialize(*args) end def read(length = nil, outbuf = '') - return ((length.nil? || length.zero?) ? "" : nil) if eof + return (length.nil? || length.zero? ? '' : nil) if eof if length.nil? || (@read_so_far + length) > decompressed_size length = decompressed_size - @read_so_far @@ -20,7 +20,7 @@ def eof @read_so_far >= decompressed_size end - alias_method :eof?, :eof + alias eof? eof end ::Zip::Decompressor.register(::Zip::COMPRESSION_METHOD_STORE, ::Zip::PassThruDecompressor) diff --git a/lib/zip/streamable_stream.rb b/lib/zip/streamable_stream.rb index 642ddae2..1a726b99 100644 --- a/lib/zip/streamable_stream.rb +++ b/lib/zip/streamable_stream.rb @@ -1,5 +1,5 @@ module Zip - class StreamableStream < DelegateClass(Entry) # nodoc:all + class StreamableStream < DelegateClass(Entry) # :nodoc:all def initialize(entry) super(entry) @temp_file = Tempfile.new(::File.basename(name)) @@ -22,6 +22,7 @@ def get_input_stream 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? diff --git a/rubyzip.gemspec b/rubyzip.gemspec index f8c59a18..1707ef5d 100644 --- a/rubyzip.gemspec +++ b/rubyzip.gemspec @@ -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 @@ Gem::Specification.new do |s| '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', '~> 10.3' + s.add_development_dependency 'rubocop', '~> 0.79' end diff --git a/samples/example.rb b/samples/example.rb index 224d4f1c..345e7e19 100755 --- a/samples/example.rb +++ b/samples/example.rb @@ -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 --git a/samples/example_filesystem.rb b/samples/example_filesystem.rb index f253a5e5..0d93ab6b 100755 --- a/samples/example_filesystem.rb +++ b/samples/example_filesystem.rb @@ -1,6 +1,6 @@ #!/usr/bin/env ruby -$: << '../lib' +$LOAD_PATH << '../lib' require 'zip/filesystem' diff --git a/samples/gtk_ruby_zip.rb b/samples/gtk_ruby_zip.rb index 62f005a5..4ce1cae0 100755 --- a/samples/gtk_ruby_zip.rb +++ b/samples/gtk_ruby_zip.rb @@ -1,6 +1,6 @@ #!/usr/bin/env ruby -$: << '../lib' +$LOAD_PATH << '../lib' $VERBOSE = true diff --git a/samples/qtzip.rb b/samples/qtzip.rb index 1d450a78..f76f57a7 100755 --- a/samples/qtzip.rb +++ b/samples/qtzip.rb @@ -2,7 +2,7 @@ $VERBOSE = true -$: << '../lib' +$LOAD_PATH << '../lib' require 'Qt' system('rbuic -o zipdialogui.rb zipdialogui.ui') @@ -80,7 +80,7 @@ def extract_files end unless ARGV[0] - puts "usage: #{$0} zipname" + puts "usage: #{$PROGRAM_NAME} zipname" exit end diff --git a/samples/write_simple.rb b/samples/write_simple.rb index be2a9704..8bb31bb3 100755 --- a/samples/write_simple.rb +++ b/samples/write_simple.rb @@ -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 --git a/samples/zipfind.rb b/samples/zipfind.rb index 400e0a69..a88bc42d 100755 --- a/samples/zipfind.rb +++ b/samples/zipfind.rb @@ -2,7 +2,7 @@ $VERBOSE = true -$: << '../lib' +$LOAD_PATH << '../lib' require 'zip' require 'find' @@ -13,12 +13,13 @@ def self.find(path, zipFilePattern = /\.zip$/i) Find.find(path) do |fileName| yield(fileName) next unless zipFilePattern.match(fileName) && File.file?(fileName) + begin Zip::File.foreach(fileName) do |zipEntry| yield(fileName + File::SEPARATOR + zipEntry.to_s) end - rescue Errno::EACCES => ex - puts ex + rescue Errno::EACCES => e + puts e end end end @@ -31,7 +32,7 @@ def self.find_file(path, fileNamePattern, zipFilePattern = /\.zip$/i) end end -if $0 == __FILE__ +if $PROGRAM_NAME == __FILE__ module ZipFindConsoleRunner PATH_ARG_INDEX = 0 FILENAME_PATTERN_ARG_INDEX = 1 @@ -47,14 +48,14 @@ def self.run(args) 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) diff --git a/test/basic_zip_file_test.rb b/test/basic_zip_file_test.rb index 9e490b4a..3d21ae89 100644 --- a/test/basic_zip_file_test.rb +++ b/test/basic_zip_file_test.rb @@ -10,7 +10,7 @@ def setup 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 diff --git a/test/case_sensitivity_test.rb b/test/case_sensitivity_test.rb index 4aab1667..92fc0f6c 100644 --- a/test/case_sensitivity_test.rb +++ b/test/case_sensitivity_test.rb @@ -22,11 +22,11 @@ def test_add_case_sensitive zfRead = ::Zip::File.new(EMPTY_FILENAME) assert_equal(SRC_FILES.size, zfRead.entries.length) - SRC_FILES.each_with_index { |a, i| + SRC_FILES.each_with_index do |a, i| assert_equal(a.last, zfRead.entries[i].name) AssertEntry.assert_contents(a.first, - zfRead.get_input_stream(a.last) { |zis| zis.read }) - } + zfRead.get_input_stream(a.last, &:read)) + end end # Ensure that names are treated case insensitively when adding files and +case_insensitive_match = false+ @@ -56,14 +56,15 @@ def test_add_case_sensitive_read_case_insensitive 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 }) + AssertEntry.assert_contents( + SRC_FILES.last.first, zfRead.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}") + refute_nil(zf.entries.detect { |e| e.name == entryName }, "entry #{entryName} not in #{zf.entries.join(', ')} in zip file #{zf}") assert_entry_contents(zf, entryName, filename) if File.exist?(filename) end end diff --git a/test/central_directory_entry_test.rb b/test/central_directory_entry_test.rb index fa0d8065..c060a4d3 100644 --- a/test/central_directory_entry_test.rb +++ b/test/central_directory_entry_test.rb @@ -63,7 +63,7 @@ def test_read_entry_from_truncated_zip_file 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 --git a/test/central_directory_test.rb b/test/central_directory_test.rb index 26be6424..28e12f4a 100644 --- a/test/central_directory_test.rb +++ b/test/central_directory_test.rb @@ -22,7 +22,7 @@ def test_read_from_invalid_stream cdir = ::Zip::CentralDirectory.new cdir.read_from_stream(zipFile) end - fail 'ZipError expected!' + raise 'ZipError expected!' rescue ::Zip::Error end @@ -33,7 +33,7 @@ def test_read_from_truncated_zip_file fragment.extend(IOizeString) entry = ::Zip::CentralDirectory.new entry.read_from_stream(fragment) - fail 'ZipError expected' + raise 'ZipError expected' rescue ::Zip::Error end diff --git a/test/deflater_test.rb b/test/deflater_test.rb index d1970ce9..78c22dfc 100644 --- a/test/deflater_test.rb +++ b/test/deflater_test.rb @@ -43,7 +43,7 @@ def test_data_error private def load_file(fileName) - File.open(fileName, 'rb') { |f| f.read } + File.open(fileName, 'rb', &:read) end def deflate(data, fileName) diff --git a/test/encryption_test.rb b/test/encryption_test.rb index 46770a17..d3ed5ffb 100644 --- a/test/encryption_test.rb +++ b/test/encryption_test.rb @@ -14,14 +14,14 @@ def teardown 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 @@ def test_decrypt 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 --git a/test/errors_test.rb b/test/errors_test.rb index 2c6adb2f..5e6260f8 100644 --- a/test/errors_test.rb +++ b/test/errors_test.rb @@ -1,5 +1,3 @@ -# encoding: utf-8 - require 'test_helper' class ErrorsTest < MiniTest::Test diff --git a/test/extra_field_ut_test.rb b/test/extra_field_ut_test.rb index ad2ab7a6..6b854978 100644 --- a/test/extra_field_ut_test.rb +++ b/test/extra_field_ut_test.rb @@ -1,7 +1,6 @@ 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], diff --git a/test/file_extract_test.rb b/test/file_extract_test.rb index a494f781..3992a1ad 100644 --- a/test/file_extract_test.rb +++ b/test/file_extract_test.rb @@ -20,7 +20,7 @@ def test_extract 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,7 +29,7 @@ def test_extract assert(File.exist?(EXTRACTED_FILENAME)) AssertEntry.assert_contents(EXTRACTED_FILENAME, - entry.get_input_stream { |is| is.read }) + entry.get_input_stream(&:read)) end end diff --git a/test/file_options_test.rb b/test/file_options_test.rb index 1a73e980..61b86e85 100644 --- a/test/file_options_test.rb +++ b/test/file_options_test.rb @@ -24,9 +24,9 @@ def teardown def test_restore_permissions # Copy and set up files with different permissions. ::FileUtils.cp(TXTPATH, TXTPATH_600) - ::File.chmod(0600, TXTPATH_600) + ::File.chmod(0o600, TXTPATH_600) ::FileUtils.cp(TXTPATH, TXTPATH_755) - ::File.chmod(0755, TXTPATH_755) + ::File.chmod(0o755, TXTPATH_755) ::Zip::File.open(ZIPPATH, true) do |zip| zip.add(ENTRY_1, TXTPATH) diff --git a/test/file_split_test.rb b/test/file_split_test.rb index dfea837d..22dd1348 100644 --- a/test/file_split_test.rb +++ b/test/file_split_test.rb @@ -28,6 +28,7 @@ def test_split 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 @@ def test_split 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 @@ def test_split 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 --git a/test/file_test.rb b/test/file_test.rb index d7f5cb8e..21aa72f7 100644 --- a/test/file_test.rb +++ b/test/file_test.rb @@ -57,7 +57,7 @@ def test_create_from_scratch_with_old_create_parameter 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 @@ -106,14 +106,14 @@ def test_get_output_stream 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 @@ def test_open_buffer_no_op_does_not_change_file # 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_with_io_and_block 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 @@ -201,7 +201,7 @@ def test_add 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 }) + zfRead.get_input_stream(entryName, &:read)) end def test_add_stored @@ -221,7 +221,7 @@ def test_add_stored 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 }) + zfRead.get_input_stream(entryName, &:read)) end def test_recover_permissions_after_add_files_to_archive @@ -250,7 +250,10 @@ def test_add_existing_entry_name_replace replacedEntry = 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 } + zf.add(replacedEntry, 'test/data/file2.txt') do + gotCalled = true + true + end end assert(gotCalled) ::Zip::File.open(TEST_ZIP.zip_name) do |zf| @@ -274,15 +277,15 @@ def test_remove 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)) + assert(zf.entries.map(&: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?(entryToRemove)) + assert_equal(zf.entries.map(&:name).sort, remainingEntries.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) + assert(!zfRead.entries.map(&:name).include?(entryToRemove)) + assert_equal(zfRead.entries.map(&:name).sort, remainingEntries.sort) zfRead.close end @@ -290,21 +293,21 @@ def test_rename entryToRename, * = 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?(entryToRename)) contents = zf.read(entryToRename) newName = 'changed entry name' - assert(!zf.entries.map { |e| e.name }.include?(newName)) + assert(!zf.entries.map(&:name).include?(newName)) zf.rename(entryToRename, newName) - assert(zf.entries.map { |e| e.name }.include?(newName)) + assert(zf.entries.map(&:name).include?(newName)) assert_equal(contents, zf.read(newName)) zf.close zfRead = ::Zip::File.new(TEST_ZIP.zip_name) - assert(zfRead.entries.map { |e| e.name }.include?(newName)) + assert(zfRead.entries.map(&:name).include?(newName)) assert_equal(contents, zfRead.read(newName)) zfRead.close end @@ -349,7 +352,7 @@ def test_rename_to_existing_entry 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(oldEntries.sort.map(&:name), zf.entries.sort.map(&:name)) end end @@ -361,14 +364,17 @@ def test_rename_to_existing_entry_overwrite renamedEntryName = 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 } + zf.rename(zf.entries[0], zf.entries[1].name) do + gotCalled = true + true + end end assert(gotCalled) oldEntries.delete_if { |e| e.name == renamedEntryName } ::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(oldEntries.sort.map(&:name), + zf.entries.sort.map(&:name)) end end @@ -401,13 +407,16 @@ def test_replace zf.close zfRead = ::Zip::File.new(TEST_ZIP.zip_name) AssertEntry.assert_contents(newEntrySrcFilename, - zfRead.get_input_stream(entryToReplace) { |is| is.read }) + zfRead.get_input_stream(entryToReplace, &:read)) AssertEntry.assert_contents(TEST_ZIP.entry_names[0], - zfRead.get_input_stream(TEST_ZIP.entry_names[0]) { |is| is.read }) + zfRead.get_input_stream(TEST_ZIP.entry_names[0], + &:read)) AssertEntry.assert_contents(TEST_ZIP.entry_names[1], - zfRead.get_input_stream(TEST_ZIP.entry_names[1]) { |is| is.read }) + zfRead.get_input_stream(TEST_ZIP.entry_names[1], + &:read)) AssertEntry.assert_contents(TEST_ZIP.entry_names[3], - zfRead.get_input_stream(TEST_ZIP.entry_names[3]) { |is| is.read }) + zfRead.get_input_stream(TEST_ZIP.entry_names[3], + &:read)) zfRead.close end @@ -426,8 +435,8 @@ def test_commit 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?) + refute_nil(zfRead.entries.detect { |e| e.name == newName }) + assert_nil(zfRead.entries.detect { |e| e.name == oldName }) zfRead.close zf.close @@ -445,8 +454,8 @@ def test_double_commit(filename = 'test/data/generated/double_commit_test.zip') 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 @@ -465,8 +474,8 @@ def test_write_buffer 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?) + refute_nil(zfRead.entries.detect { |e| e.name == newName }) + assert_nil(zfRead.entries.detect { |e| e.name == oldName }) zfRead.close zf.close @@ -549,7 +558,7 @@ def test_compound2 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') assert_not_contains(zf, TestFiles::ASCII_TEST_FILES[0]) @@ -582,7 +591,7 @@ def test_change_comment def test_preserve_file_order entryNames = nil ::Zip::File.open(TEST_ZIP.zip_name) do |zf| - entryNames = zf.entries.map { |e| e.to_s } + entryNames = 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' } @@ -590,16 +599,16 @@ def test_preserve_file_order 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(entryNames, 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 } + entryNames = 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(entryNames, zf.entries.map(&:to_s)) end end @@ -617,6 +626,7 @@ def test_streaming Zip::File.open_buffer(f) do |zipfile| zipfile.each do |entry| next unless entry.name =~ /README.md/ + data = zipfile.read(entry) end end @@ -671,11 +681,11 @@ def test_find_get_entry 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}") + refute_nil(zf.entries.detect { |e| e.name == entryName }, "entry #{entryName} not in #{zf.entries.join(', ')} in zip file #{zf}") assert_entry_contents(zf, entryName, 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}") + assert_nil(zf.entries.detect { |e| e.name == entryName }, "entry #{entryName} in #{zf.entries.join(', ')} in zip file #{zf}") end end diff --git a/test/filesystem/file_nonmutating_test.rb b/test/filesystem/file_nonmutating_test.rb index 62486666..cfe18ade 100644 --- a/test/filesystem/file_nonmutating_test.rb +++ b/test/filesystem/file_nonmutating_test.rb @@ -80,7 +80,7 @@ def test_new 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 @@ -434,12 +434,14 @@ def test_glob ::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 @@ def test_popen 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 --git a/test/gentestfiles.rb b/test/gentestfiles.rb index 3e76e7d0..acdada45 100755 --- a/test/gentestfiles.rb +++ b/test/gentestfiles.rb @@ -52,6 +52,7 @@ def create_random_binary(filename, size) def ensure_dir(name) if File.exist?(name) return if File.stat(name).directory? + File.delete(name) end Dir.mkdir(name) @@ -71,8 +72,12 @@ def initialize(zip_name, entry_names, comment = '') 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') {} @@ -93,33 +98,57 @@ def self.create_test_zips file << testBinaryPattern << 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_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_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 --git a/test/ioextras/abstract_input_stream_test.rb b/test/ioextras/abstract_input_stream_test.rb index 3ae005d1..f8986b84 100644 --- a/test/ioextras/abstract_input_stream_test.rb +++ b/test/ioextras/abstract_input_stream_test.rb @@ -4,8 +4,8 @@ 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 @@ -50,7 +50,7 @@ def test_gets 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 = [ @@ -95,7 +95,7 @@ def test_readline test_gets begin @io.readline - fail 'EOFError expected' + raise 'EOFError expected' rescue EOFError end end diff --git a/test/ioextras/abstract_output_stream_test.rb b/test/ioextras/abstract_output_stream_test.rb index 3077db43..17b31a78 100644 --- a/test/ioextras/abstract_output_stream_test.rb +++ b/test/ioextras/abstract_output_stream_test.rb @@ -20,8 +20,8 @@ def <<(data) def setup @output_stream = TestOutputStream.new - @origCommaSep = $, - @origOutputSep = $\ + @origCommaSep = $OUTPUT_FIELD_SEPARATOR + @origOutputSep = $OUTPUT_RECORD_SEPARATOR end def teardown diff --git a/test/local_entry_test.rb b/test/local_entry_test.rb index 666a63a0..b02deb67 100644 --- a/test/local_entry_test.rb +++ b/test/local_entry_test.rb @@ -46,7 +46,7 @@ def test_read_local_entry_from_truncated_zip_file zipFragment.extend(IOizeString).reset entry = ::Zip::Entry.new entry.read_local_entry(zipFragment) - fail 'ZipError expected' + raise 'ZipError expected' rescue ::Zip::Error end diff --git a/test/output_stream_test.rb b/test/output_stream_test.rb index a7725e22..40205076 100644 --- a/test/output_stream_test.rb +++ b/test/output_stream_test.rb @@ -57,11 +57,11 @@ def test_cannot_open_file 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 +90,8 @@ def test_put_next_entry_using_zip_entry_creates_entries_with_correct_timestamps ::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 diff --git a/test/path_traversal_test.rb b/test/path_traversal_test.rb index 8b6f67d5..47c7e30f 100644 --- a/test/path_traversal_test.rb +++ b/test/path_traversal_test.rb @@ -62,9 +62,9 @@ def test_leading_dot_dot def test_non_leading_dot_dot_with_existing_folder entries = { - 'tmp/' => '', + 'tmp/' => '', 'tmp/../../moo' => /WARNING: skipped \'tmp\/\.\.\/\.\.\/moo\'/ - } + } in_tmpdir do extract_paths('relative1.zip', entries) assert Dir.exist?('tmp') @@ -92,7 +92,7 @@ def test_file_symlink def test_directory_symlink # Can't create tmp/moo, because the tmp symlink is skipped. entries = { - 'tmp' => /WARNING: skipped symlink \'tmp\'/, + 'tmp' => /WARNING: skipped symlink \'tmp\'/, 'tmp/moo' => :error } in_tmpdir do @@ -104,8 +104,8 @@ def test_directory_symlink 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\'/, + 'cur' => /WARNING: skipped symlink \'cur\'/, + 'par' => /WARNING: skipped symlink \'par\'/, 'par/moo' => :error } in_tmpdir do @@ -119,7 +119,7 @@ def test_two_directory_symlinks_a def test_two_directory_symlinks_b # Can't create par/moo, because the symlinks are skipped. entries = { - 'cur' => /WARNING: skipped symlink \'cur\'/, + 'cur' => /WARNING: skipped symlink \'cur\'/, 'cur/par' => /WARNING: skipped symlink \'cur\/par\'/, 'par/moo' => :error } @@ -132,7 +132,7 @@ def test_two_directory_symlinks_b def test_entry_name_with_absolute_path_does_not_extract entries = { - '/tmp/' => /WARNING: skipped \'\/tmp\/\'/, + '/tmp/' => /WARNING: skipped \'\/tmp\/\'/, '/tmp/file.txt' => /WARNING: skipped \'\/tmp\/file.txt\'/ } in_tmpdir do @@ -156,7 +156,7 @@ def test_entry_name_with_absolute_path_extract_when_given_different_path 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' => /WARNING: skipped symlink \'path\'/, 'path/file.txt' => :error } in_tmpdir do diff --git a/test/settings_test.rb b/test/settings_test.rb index 7c1331a6..ab5aa223 100644 --- a/test/settings_test.rb +++ b/test/settings_test.rb @@ -18,7 +18,7 @@ def teardown end def open_zip(&aProc) - assert(!aProc.nil?) + refute_nil(aProc) ::Zip::File.open(TestZipFile::TEST_ZIP4.zip_name, &aProc) end @@ -89,7 +89,7 @@ def test_true_warn_invalid_date 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}") + refute_nil(zf.entries.detect { |e| e.name == entryName }, "entry #{entryName} not in #{zf.entries.join(', ')} in zip file #{zf}") assert_entry_contents(zf, entryName, filename) if File.exist?(filename) end end diff --git a/test/stored_support_test.rb b/test/stored_support_test.rb index 8260e4a9..28836b9e 100644 --- a/test/stored_support_test.rb +++ b/test/stored_support_test.rb @@ -10,12 +10,12 @@ 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 1327, entry.size - assert_equal open(INPUT_FILE1, 'r').read, zis.read + 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 41234, entry.size - assert_equal open(INPUT_FILE2, 'r').read, zis.read + assert_equal 41_234, entry.size + assert_equal ::File.open(INPUT_FILE2, 'r').read, zis.read end end @@ -23,12 +23,12 @@ 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 1327, entry.size - assert_equal open(INPUT_FILE1, 'r').read, zis.read + 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 41234, entry.size - assert_equal open(INPUT_FILE2, 'r').read, zis.read + assert_equal 41_234, entry.size + assert_equal ::File.open(INPUT_FILE2, 'r').read, zis.read end end end diff --git a/test/test_helper.rb b/test/test_helper.rb index 224a1eb2..0e14b6da 100644 --- a/test/test_helper.rb +++ b/test/test_helper.rb @@ -24,7 +24,7 @@ module IOizeString def read(count = nil) @tell ||= 0 - count = size unless count + count ||= size retVal = slice(@tell, count) @tell += count retVal @@ -42,11 +42,10 @@ def seek(index, offset) 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 newPos < 0 || newPos >= size + + @tell = newPos end def reset @@ -62,7 +61,7 @@ module DecompressorTests def setup @refText = '' File.open(TEST_FILE) { |f| @refText = f.read } - @refLines = @refText.split($/) + @refLines = @refText.split($INPUT_RECORD_SEPARATOR) end def test_read_everything @@ -96,7 +95,7 @@ def assert_entry_contents_for_stream(filename, zis, entryName) 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}'") + raise("File '#{filename}' is different from '#{zipEntryFilename}'") else assert_equal(expected, actual) end @@ -107,14 +106,14 @@ def assert_entry_contents_for_stream(filename, zis, entryName) 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 + return unless fileContents != aString + + if fileContents.length > 400 || aString.length > 400 + stringFile = filename + '.other' + File.open(stringFile, 'wb') { |f| f << aString } + raise("File '#{filename}' is different from contents of string stored in '#{stringFile}'") + else + assert_equal(fileContents, aString) end end @@ -194,18 +193,21 @@ module ExtraAssertions def assert_forwarded(anObject, method, retVal, *expectedArgs) callArgs = nil setCallArgsProc = proc { |args| callArgs = args } - anObject.instance_eval <<-"end_eval" + anObject.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}) end - end_eval + END_EVAL assert_equal(retVal, yield) # Invoke test assert_equal(expectedArgs, callArgs) ensure - anObject.instance_eval "undef #{method}; alias #{method} #{method}_org" + anObject.instance_eval <<-END_EVAL, __FILE__, __LINE__ + 1 + undef #{method} + alias #{method} #{method}_org + END_EVAL end end diff --git a/test/unicode_file_names_and_comments_test.rb b/test/unicode_file_names_and_comments_test.rb index aac3e256..4d2fc20f 100644 --- a/test/unicode_file_names_and_comments_test.rb +++ b/test/unicode_file_names_and_comments_test.rb @@ -1,5 +1,3 @@ -# encoding: utf-8 - require 'test_helper' class ZipUnicodeFileNamesAndComments < MiniTest::Test