From cfc38b30a1f39e20013074e6aecf12b08d9f2ec2 Mon Sep 17 00:00:00 2001 From: weshatheleopard Date: Sun, 8 Mar 2015 13:38:57 -0500 Subject: [PATCH 1/5] PROPER case insensitivity handling --- lib/zip.rb | 3 ++- lib/zip/entry_set.rb | 4 +++- test/entry_set_test.rb | 14 +++++++++++--- 3 files changed, 16 insertions(+), 5 deletions(-) diff --git a/lib/zip.rb b/lib/zip.rb index e6ebad3..c021f47 100644 --- a/lib/zip.rb +++ b/lib/zip.rb @@ -37,7 +37,7 @@ end module Zip extend self - attr_accessor :unicode_names, :on_exists_proc, :continue_on_exists_proc, :sort_entries, :default_compression, :write_zip64_support, :warn_invalid_date + attr_accessor :unicode_names, :on_exists_proc, :continue_on_exists_proc, :sort_entries, :default_compression, :write_zip64_support, :warn_invalid_date, :case_insensitive_match def reset! @_ran_once = false @@ -48,6 +48,7 @@ module Zip @default_compression = ::Zlib::DEFAULT_COMPRESSION @write_zip64_support = false @warn_invalid_date = true + @case_insensitive_match = false end def setup diff --git a/lib/zip/entry_set.rb b/lib/zip/entry_set.rb index 91c7cca..b9cbde3 100755 --- a/lib/zip/entry_set.rb +++ b/lib/zip/entry_set.rb @@ -78,7 +78,9 @@ module Zip private def to_key(entry) - entry.to_s.chomp('/') + k = entry.to_s.chomp('/') + k.downcase! if ::Zip.case_insensitive_match + k end end end diff --git a/test/entry_set_test.rb b/test/entry_set_test.rb index 10d6db8..fb77e5e 100644 --- a/test/entry_set_test.rb +++ b/test/entry_set_test.rb @@ -66,9 +66,17 @@ class ZipEntrySetTest < MiniTest::Test end def test_find_entry - # by default, #find_entry is case-sensitive - assert_equal(ZIP_ENTRIES[0], @zipEntrySet.find_entry('name1')) - assert_equal(ZIP_ENTRIES[0], @zipEntrySet.find_entry('NaMe1', false)) + 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.case_insensitive_match = false + zipEntrySet = ::Zip::EntrySet.new(entries) + assert_equal(entries[0], zipEntrySet.find_entry('MiXeDcAsEnAmE')) + assert_equal(nil, zipEntrySet.find_entry('mixedcasename')) end def test_entries_with_sort From f030cdadb8bf5aab89501793fb89ef502d7b08af Mon Sep 17 00:00:00 2001 From: weshatheleopard Date: Sun, 8 Mar 2015 13:40:43 -0500 Subject: [PATCH 2/5] ...and remove that crazy abomination --- lib/zip/entry_set.rb | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/lib/zip/entry_set.rb b/lib/zip/entry_set.rb index b9cbde3..77484d1 100755 --- a/lib/zip/entry_set.rb +++ b/lib/zip/entry_set.rb @@ -14,9 +14,7 @@ module Zip end def find_entry(entry, case_sensitively = true) - return @entry_set[to_key(entry)] if case_sensitively - entry = @entry_set.find { |k, _| k.downcase == to_key(entry).downcase } - entry.last if entry + @entry_set[to_key(entry)] end def <<(entry) From d81e0f207ddf0969544c316a59b5d46a881dba6d Mon Sep 17 00:00:00 2001 From: weshatheleopard Date: Wed, 11 Mar 2015 09:41:03 -0500 Subject: [PATCH 3/5] Oops, forgot to remove --- lib/zip/entry_set.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/zip/entry_set.rb b/lib/zip/entry_set.rb index 77484d1..a848fb3 100755 --- a/lib/zip/entry_set.rb +++ b/lib/zip/entry_set.rb @@ -13,7 +13,7 @@ module Zip @entry_set.include?(to_key(entry)) end - def find_entry(entry, case_sensitively = true) + def find_entry(entry) @entry_set[to_key(entry)] end From 360636ca417932e40750d844ad1c8bd5675f7b59 Mon Sep 17 00:00:00 2001 From: weshatheleopard Date: Mon, 16 Mar 2015 22:09:01 +0000 Subject: [PATCH 4/5] Integration test --- test/case_sensitivity_test.rb | 70 +++++++++++++++++++++++++++++++++++ 1 file changed, 70 insertions(+) create mode 100644 test/case_sensitivity_test.rb diff --git a/test/case_sensitivity_test.rb b/test/case_sensitivity_test.rb new file mode 100644 index 0000000..1ecfad5 --- /dev/null +++ b/test/case_sensitivity_test.rb @@ -0,0 +1,70 @@ +require 'test_helper' + + +class ZipFileTest < MiniTest::Test + include CommonZipFileFixture + + SRC_FILES = [ [ "test/data/file1.txt", "testfile.rb" ], + [ "test/data/file2.txt", "testFILE.rb" ] ] + + def teardown + ::Zip.case_insensitive_match = false + end + + # Ensure that everything functions normally when +case_insensitive_match = false+ + def test_add_case_sensitive + ::Zip.case_insensitive_match = false + + SRC_FILES.each { |fn, en| assert(::File.exist?(fn)) } + zf = ::Zip::File.new(EMPTY_FILENAME, ::Zip::File::CREATE) + + 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) + AssertEntry.assert_contents(a.first, + zfRead.get_input_stream(a.last) { |zis| zis.read }) + } + end + + # Ensure that names are treated case insensitively when adding files and +case_insensitive_match = false+ + def test_add_case_insensitive + ::Zip.case_insensitive_match = true + + SRC_FILES.each { |fn, en| assert(::File.exist?(fn)) } + zf = ::Zip::File.new(EMPTY_FILENAME, ::Zip::File::CREATE) + + assert_raises Zip::EntryExistsError do + SRC_FILES.each { |fn, en| zf.add(en, fn) } + end + + end + + # Ensure that names are treated case insensitively when reading files and +case_insensitive_match = true+ + def test_add_case_sensitive_read_case_insensitive + ::Zip.case_insensitive_match = false + + SRC_FILES.each { |fn, en| assert(::File.exist?(fn)) } + zf = ::Zip::File.new(EMPTY_FILENAME, ::Zip::File::CREATE) + + SRC_FILES.each { |fn, en| zf.add(en, fn) } + zf.close + + ::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 }) + 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_entryContents(zf, entryName, filename) if File.exist?(filename) + end +end From 17ac4fdba1d799554d05ed72ac1986804837e8fa Mon Sep 17 00:00:00 2001 From: Pavel Lobashov Date: Thu, 19 Mar 2015 17:32:33 +0300 Subject: [PATCH 5/5] Fix #218 Ouput Invalid Date/time to STDERR --- lib/zip/entry.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/zip/entry.rb b/lib/zip/entry.rb index c156356..bc0092b 100755 --- a/lib/zip/entry.rb +++ b/lib/zip/entry.rb @@ -571,7 +571,7 @@ module Zip def set_time(binary_dos_date, binary_dos_time) @time = ::Zip::DOSTime.parse_binary_dos_format(binary_dos_date, binary_dos_time) rescue ArgumentError - puts "Invalid date/time in zip entry" if ::Zip.warn_invalid_date + STDERR.puts "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 })