Skip to content

Commit

Permalink
Merge pull request rubyzip#25 from 2potatocakes/master
Browse files Browse the repository at this point in the history
Added better support for windows mingw users
Need more testing on windows.
  • Loading branch information
simonoff committed Feb 7, 2012
2 parents f826268 + 3f8b14f commit 5d0b4db
Show file tree
Hide file tree
Showing 9 changed files with 181 additions and 170 deletions.
2 changes: 1 addition & 1 deletion TODO
Original file line number Original file line Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
* Suggestion: Add ZipFile/ZipInputStream example that demonstrates extracting all entries. * Suggestion: Add ZipFile/ZipInputStream example that demonstrates extracting all entries.
* Suggestion: ZipFile#extract destination should default to "." * Suggestion: ZipFile#extract destination should default to "."
* Suggestion: ZipEntry should have extract(), get_input_stream() methods etc * Suggestion: ZipEntry should have extract(), get_input_stream() methods etc
* SUggestion: ZipInputStream/ZipOutputStream should accept an IO object in addition to a filename. * Suggestion: ZipInputStream/ZipOutputStream should accept an IO object in addition to a filename.
* (is buffering used anywhere with write?) * (is buffering used anywhere with write?)
* Inflater.sysread should pass the buffer to produce_input. * Inflater.sysread should pass the buffer to produce_input.
* Implement ZipFsDir.glob * Implement ZipFsDir.glob
Expand Down
5 changes: 3 additions & 2 deletions lib/zip/constants.rb
Original file line number Original file line Diff line number Diff line change
@@ -1,7 +1,8 @@
module Zip module Zip
VERSION = '0.9.4' VERSION = '0.9.5'
RUBY_MINOR_VERSION = RUBY_VERSION.split(".")[1].to_i RUBY_MINOR_VERSION = RUBY_VERSION.split(".")[1].to_i
RUNNING_ON_WINDOWS = RbConfig::CONFIG['host_os'] =~ /^win|mswin/i RUNNING_ON_WINDOWS = RbConfig::CONFIG['host_os'] =~ /mswin|mingw|cygwin/i

# Ruby 1.7.x compatibility # Ruby 1.7.x compatibility
# In ruby 1.6.x and 1.8.0 reading from an empty stream returns # In ruby 1.6.x and 1.8.0 reading from an empty stream returns
# an empty string the first time and then nil. # an empty string the first time and then nil.
Expand Down
6 changes: 3 additions & 3 deletions lib/zip/zip_entry.rb
Original file line number Original file line Diff line number Diff line change
Expand Up @@ -62,7 +62,7 @@ class ZipEntry


# Returns the character encoding used for name and comment # Returns the character encoding used for name and comment
def name_encoding def name_encoding
(@gp_flags & 0b100000000000) != 0 ? "utf8" : "CP437//" (@gp_flags & 0b100000000000) != 0 ? "UTF-8" : "CP437//"
end end


# Returns the name in the encoding specified by enc # Returns the name in the encoding specified by enc
Expand Down Expand Up @@ -140,7 +140,7 @@ def time
if @extra["UniversalTime"] if @extra["UniversalTime"]
@extra["UniversalTime"].mtime @extra["UniversalTime"].mtime
else else
# Atandard time field in central directory has local time # Standard time field in central directory has local time
# under archive creator. Then, we can't get timezone. # under archive creator. Then, we can't get timezone.
@time @time
end end
Expand Down Expand Up @@ -635,4 +635,4 @@ def create_symlink(destPath)


# Copyright (C) 2002, 2003 Thomas Sondergaard # Copyright (C) 2002, 2003 Thomas Sondergaard
# rubyzip is free software; you can redistribute it and/or # rubyzip is free software; you can redistribute it and/or
# modify it under the terms of the ruby license. # modify it under the terms of the ruby license.
3 changes: 2 additions & 1 deletion lib/zip/zip_file.rb
Original file line number Original file line Diff line number Diff line change
Expand Up @@ -177,7 +177,8 @@ def rename(entry, newName, &continueOnExistsProc)
# the file system). # the file system).
def replace(entry, srcPath) def replace(entry, srcPath)
check_file(srcPath) check_file(srcPath)
add(remove(entry), srcPath) remove(entry)
add(entry, srcPath)
end end


# Extracts entry to file destPath. # Extracts entry to file destPath.
Expand Down
18 changes: 8 additions & 10 deletions lib/zip/zip_input_stream.rb
Original file line number Original file line Diff line number Diff line change
Expand Up @@ -88,8 +88,7 @@ def ZipInputStream.open_buffer(io)
# no more entries. # no more entries.


def get_next_entry def get_next_entry
@archiveIO.seek(@currentEntry.next_header_offset, @archiveIO.seek(@currentEntry.next_header_offset, IO::SEEK_SET) if @currentEntry
IO::SEEK_SET) if @currentEntry
open_entry open_entry
end end


Expand All @@ -116,16 +115,15 @@ def eof


def open_entry def open_entry
@currentEntry = ZipEntry.read_local_entry(@archiveIO) @currentEntry = ZipEntry.read_local_entry(@archiveIO)
if (@currentEntry == nil) if @currentEntry.nil?
@decompressor = NullDecompressor.instance @decompressor = NullDecompressor.instance
elsif @currentEntry.compression_method == ZipEntry::STORED elsif @currentEntry.compression_method == ZipEntry::STORED
@decompressor = PassThruDecompressor.new(@archiveIO, @decompressor = PassThruDecompressor.new(@archiveIO, @currentEntry.size)
@currentEntry.size)
elsif @currentEntry.compression_method == ZipEntry::DEFLATED elsif @currentEntry.compression_method == ZipEntry::DEFLATED
@decompressor = Inflater.new(@archiveIO) @decompressor = Inflater.new(@archiveIO)
else else
raise ZipCompressionMethodError, raise ZipCompressionMethodError,
"Unsupported compression method #{@currentEntry.compression_method}" "Unsupported compression method #{@currentEntry.compression_method}"
end end
flush flush
return @currentEntry return @currentEntry
Expand All @@ -143,4 +141,4 @@ def input_finished?


# Copyright (C) 2002, 2003 Thomas Sondergaard # Copyright (C) 2002, 2003 Thomas Sondergaard
# rubyzip is free software; you can redistribute it and/or # rubyzip is free software; you can redistribute it and/or
# modify it under the terms of the ruby license. # modify it under the terms of the ruby license.
5 changes: 2 additions & 3 deletions lib/zip/zip_output_stream.rb
Original file line number Original file line Diff line number Diff line change
Expand Up @@ -101,11 +101,10 @@ def copy_raw_entry(entry)
src_pos = entry.local_entry_offset src_pos = entry.local_entry_offset
entry.write_local_entry(@outputStream) entry.write_local_entry(@outputStream)
@compressor = NullCompressor.instance @compressor = NullCompressor.instance
entry.get_raw_input_stream { entry.get_raw_input_stream do |is|
|is|
is.seek(src_pos, IO::SEEK_SET) is.seek(src_pos, IO::SEEK_SET)
IOExtras.copy_stream_n(@outputStream, is, entry.compressed_size) IOExtras.copy_stream_n(@outputStream, is, entry.compressed_size)
} end
@compressor = NullCompressor.instance @compressor = NullCompressor.instance
@currentEntry = nil @currentEntry = nil
end end
Expand Down
91 changes: 48 additions & 43 deletions test/gentestfiles.rb
Original file line number Original file line Diff line number Diff line change
Expand Up @@ -22,37 +22,33 @@ def TestFiles.create_test_files(recreate)


Dir.mkdir "data/generated" rescue Errno::EEXIST Dir.mkdir "data/generated" rescue Errno::EEXIST


ASCII_TEST_FILES.each_with_index { ASCII_TEST_FILES.each_with_index do |filename, index|
|filename, index| create_random_ascii(filename, 1E4 * (index+1))
create_random_ascii(filename, 1E4 * (index+1)) end
}


BINARY_TEST_FILES.each_with_index { BINARY_TEST_FILES.each_with_index do |filename, index|
|filename, index| create_random_binary(filename, 1E4 * (index+1))
create_random_binary(filename, 1E4 * (index+1)) end
}


ensure_dir(EMPTY_TEST_DIR) ensure_dir(EMPTY_TEST_DIR)
end end
end end


private private
def TestFiles.create_random_ascii(filename, size) def TestFiles.create_random_ascii(filename, size)
File.open(filename, "wb") { File.open(filename, "wb") do |file|
|file|
while (file.tell < size) while (file.tell < size)
file << rand file << rand
end end
} end
end end


def TestFiles.create_random_binary(filename, size) def TestFiles.create_random_binary(filename, size)
File.open(filename, "wb") { File.open(filename, "wb") do |file|
|file|
while (file.tell < size) while (file.tell < size)
file << [rand].pack("V") file << [rand].pack("V")
end end
} end
end end


def TestFiles.ensure_dir(name) def TestFiles.ensure_dir(name)
Expand Down Expand Up @@ -90,57 +86,66 @@ def TestZipFile.create_test_zips(recreate)
files.index("short.txt") && files.index("short.txt") &&
files.index("longAscii.txt") && files.index("longAscii.txt") &&
files.index("longBinary.bin") )) files.index("longBinary.bin") ))
raise "failed to create test zip '#{TEST_ZIP1.zip_name}'" unless
system("zip #{TEST_ZIP1.zip_name} data/file2.txt") raise "failed to create test zip '#{TEST_ZIP1.zip_name}'" unless
raise "failed to remove entry from '#{TEST_ZIP1.zip_name}'" unless system("zip #{TEST_ZIP1.zip_name} data/file2.txt")
system("zip #{TEST_ZIP1.zip_name} -d data/file2.txt") raise "failed to remove entry from '#{TEST_ZIP1.zip_name}'" unless
system("zip #{TEST_ZIP1.zip_name} -d data/file2.txt")


File.open("data/generated/empty.txt", "w") {} File.open("data/generated/empty.txt", "w") {}
File.open("data/generated/empty_chmod640.txt", "w") { |f| f.chmod(0640) } File.open("data/generated/empty_chmod640.txt", "w") { |f| f.chmod(0640) }


File.open("data/generated/short.txt", "w") { |file| file << "ABCDEF" } File.open("data/generated/short.txt", "w") { |file| file << "ABCDEF" }
ziptestTxt="" ziptestTxt=""
File.open("data/file2.txt") { |file| ziptestTxt=file.read } File.open("data/file2.txt") { |file| ziptestTxt=file.read }
File.open("data/generated/longAscii.txt", "w") { File.open("data/generated/longAscii.txt", "w") do |file|
|file| while (file.tell < 1E5)
while (file.tell < 1E5) file << ziptestTxt
file << ziptestTxt end
end end
}


testBinaryPattern="" testBinaryPattern=""
File.open("data/generated/empty.zip") { |file| testBinaryPattern=file.read } File.open("data/generated/empty.zip") { |file| testBinaryPattern=file.read }
testBinaryPattern *= 4 testBinaryPattern *= 4


File.open("data/generated/longBinary.bin", "wb") { File.open("data/generated/longBinary.bin", "wb") do |file|
|file| while (file.tell < 3E5)
while (file.tell < 3E5) file << testBinaryPattern << rand << "\0"
file << testBinaryPattern << rand << "\0" end
end end
}
raise "failed to create test zip '#{TEST_ZIP2.zip_name}'" unless
system("zip #{TEST_ZIP2.zip_name} #{TEST_ZIP2.entry_names.join(' ')}")


raise "failed to create test zip '#{TEST_ZIP2.zip_name}'" unless
system("zip #{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}| zip -z #{TEST_ZIP2.zip_name}\"")
else
# without bash system interprets everything after echo as parameters to # without bash system interprets everything after echo as parameters to
# echo including | zip -z ... # echo including | zip -z ...
raise "failed to add comment to test zip '#{TEST_ZIP2.zip_name}'" unless raise "failed to add comment to test zip '#{TEST_ZIP2.zip_name}'" unless
system("bash -c \"echo #{TEST_ZIP2.comment} | zip -z #{TEST_ZIP2.zip_name}\"") system("bash -c \"echo #{TEST_ZIP2.comment} | zip -z #{TEST_ZIP2.zip_name}\"")
end


raise "failed to create test zip '#{TEST_ZIP3.zip_name}'" unless raise "failed to create test zip '#{TEST_ZIP3.zip_name}'" unless
system("zip #{TEST_ZIP3.zip_name} #{TEST_ZIP3.entry_names.join(' ')}") system("zip #{TEST_ZIP3.zip_name} #{TEST_ZIP3.entry_names.join(' ')}")


raise "failed to create test zip '#{TEST_ZIP4.zip_name}'" unless raise "failed to create test zip '#{TEST_ZIP4.zip_name}'" unless
system("zip #{TEST_ZIP4.zip_name} #{TEST_ZIP4.entry_names.join(' ')}") system("zip #{TEST_ZIP4.zip_name} #{TEST_ZIP4.entry_names.join(' ')}")
end end
rescue rescue
raise $!.to_s + # 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 +
"\n\nziptest.rb requires the Info-ZIP program 'zip' in the path\n" + "\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" + "to create test data. If you don't have it you can download\n" +
"the necessary test files at http://sf.net/projects/rubyzip." "the necessary test files at http://sf.net/projects/rubyzip."
end end


TEST_ZIP1 = TestZipFile.new("data/generated/empty.zip", []) TEST_ZIP1 = TestZipFile.new("data/generated/empty.zip", [])
TEST_ZIP2 = TestZipFile.new("data/generated/5entry.zip", %w{ data/generated/longAscii.txt data/generated/empty.txt data/generated/empty_chmod640.txt data/generated/short.txt data/generated/longBinary.bin}, TEST_ZIP2 = TestZipFile.new("data/generated/5entry.zip", %w{ data/generated/longAscii.txt data/generated/empty.txt data/generated/empty_chmod640.txt data/generated/short.txt data/generated/longBinary.bin},
"my zip comment") "my zip comment")
TEST_ZIP3 = TestZipFile.new("data/generated/test1.zip", %w{ data/file1.txt }) TEST_ZIP3 = TestZipFile.new("data/generated/test1.zip", %w{ data/file1.txt })
TEST_ZIP4 = TestZipFile.new("data/generated/zipWithDir.zip", [ "data/file1.txt", TEST_ZIP4 = TestZipFile.new("data/generated/zipWithDir.zip", [ "data/file1.txt",
Expand Down
72 changes: 43 additions & 29 deletions test/zipfilesystemtest.rb
Original file line number Original file line Diff line number Diff line change
Expand Up @@ -432,39 +432,46 @@ def test_pipe
end end


def test_foreach def test_foreach
ZipFile.open("data/generated/zipWithDir.zip") { ZipFile.open("data/generated/zipWithDir.zip") do |zf|
|zf|
ref = [] ref = []
File.foreach("data/file1.txt") { |e| ref << e } File.foreach("data/file1.txt") { |e| ref << e }

index = 0 index = 0
zf.file.foreach("data/file1.txt") {
|l| zf.file.foreach("data/file1.txt") do |l|
assert_equal(ref[index], l) #Ruby replaces \n with \r\n automatically on windows
newline = Zip::RUNNING_ON_WINDOWS ? l.gsub(/\r\n/, "\n") : l
assert_equal(ref[index], newline)
index = index.next index = index.next
} end
assert_equal(ref.size, index) assert_equal(ref.size, index)
} end


ZipFile.open("data/generated/zipWithDir.zip") { ZipFile.open("data/generated/zipWithDir.zip") do |zf|
|zf|
ref = [] ref = []
File.foreach("data/file1.txt", " ") { |e| ref << e } File.foreach("data/file1.txt", " ") { |e| ref << e }

index = 0 index = 0
zf.file.foreach("data/file1.txt", " ") {
|l| zf.file.foreach("data/file1.txt", " ") do |l|
assert_equal(ref[index], l) #Ruby replaces \n with \r\n automatically on windows
newline = Zip::RUNNING_ON_WINDOWS ? l.gsub(/\r\n/, "\n") : l
assert_equal(ref[index], newline)
index = index.next index = index.next
} end
assert_equal(ref.size, index) assert_equal(ref.size, index)
} end
end end


def test_popen def test_popen
cmd = /mswin/i =~ RUBY_PLATFORM ? 'dir' : 'ls' if Zip::RUNNING_ON_WINDOWS
assert_equal(File.popen(cmd) { |f| f.read }, #This is pretty much projectile vomit but it allows the test to be
@zipFile.file.popen(cmd) { |f| f.read }) #run on windows also
system_dir = File.popen('dir') { |f| f.read }.gsub(/Dir\(s\).*$/, '')
zipfile_dir = @zipFile.file.popen('dir') { |f| f.read }.gsub(/Dir\(s\).*$/, '')
assert_equal(system_dir, zipfile_dir)
else
assert_equal(File.popen('ls') { |f| f.read },
@zipFile.file.popen('ls') { |f| f.read })
end
end end


# Can be added later # Can be added later
Expand All @@ -473,19 +480,26 @@ def test_popen
# end # end


def test_readlines def test_readlines
ZipFile.open("data/generated/zipWithDir.zip") { ZipFile.open("data/generated/zipWithDir.zip") do |zf|
|zf| orig_file = File.readlines("data/file1.txt")
assert_equal(File.readlines("data/file1.txt"), zip_file = zf.file.readlines("data/file1.txt")
zf.file.readlines("data/file1.txt"))
} #Ruby replaces \n with \r\n automatically on windows
zip_file.each { |l| l.gsub!(/\r\n/, "\n") } if Zip::RUNNING_ON_WINDOWS

assert_equal(orig_file, zip_file)
end
end end


def test_read def test_read
ZipFile.open("data/generated/zipWithDir.zip") { ZipFile.open("data/generated/zipWithDir.zip") do |zf|
|zf| orig_file = File.read("data/file1.txt")
assert_equal(File.read("data/file1.txt"),
zf.file.read("data/file1.txt")) #Ruby replaces \n with \r\n automatically on windows
} zip_file = Zip::RUNNING_ON_WINDOWS ? \
zf.file.read("data/file1.txt").gsub(/\r\n/, "\n") : zf.file.read("data/file1.txt")
assert_equal(orig_file, zip_file)
end
end end


end end
Expand Down
Loading

0 comments on commit 5d0b4db

Please sign in to comment.