rubyzip 0.9.5 → 1.3.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (135) hide show
  1. checksums.yaml +7 -0
  2. data/README.md +334 -45
  3. data/Rakefile +11 -6
  4. data/TODO +0 -1
  5. data/lib/zip/central_directory.rb +208 -0
  6. data/lib/zip/compressor.rb +1 -2
  7. data/lib/zip/constants.rb +61 -8
  8. data/lib/zip/crypto/encryption.rb +11 -0
  9. data/lib/zip/crypto/null_encryption.rb +43 -0
  10. data/lib/zip/crypto/traditional_encryption.rb +99 -0
  11. data/lib/zip/decompressor.rb +4 -4
  12. data/lib/zip/deflater.rb +18 -14
  13. data/lib/zip/dos_time.rb +48 -0
  14. data/lib/zip/entry.rb +700 -0
  15. data/lib/zip/entry_set.rb +86 -0
  16. data/lib/zip/errors.rb +18 -0
  17. data/lib/zip/extra_field/generic.rb +43 -0
  18. data/lib/zip/extra_field/ntfs.rb +90 -0
  19. data/lib/zip/extra_field/old_unix.rb +44 -0
  20. data/lib/zip/extra_field/universal_time.rb +47 -0
  21. data/lib/zip/extra_field/unix.rb +37 -0
  22. data/lib/zip/extra_field/zip64.rb +68 -0
  23. data/lib/zip/extra_field/zip64_placeholder.rb +15 -0
  24. data/lib/zip/extra_field.rb +101 -0
  25. data/lib/zip/file.rb +443 -0
  26. data/lib/zip/{zipfilesystem.rb → filesystem.rb} +179 -164
  27. data/lib/zip/inflater.rb +29 -28
  28. data/lib/zip/input_stream.rb +173 -0
  29. data/lib/zip/ioextras/abstract_input_stream.rb +111 -0
  30. data/lib/zip/ioextras/abstract_output_stream.rb +43 -0
  31. data/lib/zip/ioextras.rb +21 -149
  32. data/lib/zip/null_compressor.rb +2 -2
  33. data/lib/zip/null_decompressor.rb +8 -6
  34. data/lib/zip/null_input_stream.rb +3 -2
  35. data/lib/zip/output_stream.rb +189 -0
  36. data/lib/zip/pass_thru_compressor.rb +7 -7
  37. data/lib/zip/pass_thru_decompressor.rb +19 -19
  38. data/lib/zip/{zip_streamable_directory.rb → streamable_directory.rb} +3 -3
  39. data/lib/zip/streamable_stream.rb +56 -0
  40. data/lib/zip/version.rb +3 -0
  41. data/lib/zip.rb +71 -0
  42. data/samples/example.rb +44 -32
  43. data/samples/example_filesystem.rb +16 -18
  44. data/samples/example_recursive.rb +33 -28
  45. data/samples/{gtkRubyzip.rb → gtk_ruby_zip.rb} +26 -28
  46. data/samples/qtzip.rb +22 -31
  47. data/samples/write_simple.rb +12 -13
  48. data/samples/zipfind.rb +31 -39
  49. data/test/basic_zip_file_test.rb +60 -0
  50. data/test/case_sensitivity_test.rb +69 -0
  51. data/test/central_directory_entry_test.rb +69 -0
  52. data/test/central_directory_test.rb +100 -0
  53. data/test/crypto/null_encryption_test.rb +57 -0
  54. data/test/crypto/traditional_encryption_test.rb +80 -0
  55. data/test/data/WarnInvalidDate.zip +0 -0
  56. data/test/data/file1.txt +46 -0
  57. data/test/data/file1.txt.deflatedData +0 -0
  58. data/test/data/file2.txt +1504 -0
  59. data/test/data/globTest/foo/bar/baz/foo.txt +0 -0
  60. data/test/data/globTest/foo.txt +0 -0
  61. data/test/data/globTest/food.txt +0 -0
  62. data/test/data/globTest.zip +0 -0
  63. data/test/data/gpbit3stored.zip +0 -0
  64. data/test/data/mimetype +1 -0
  65. data/test/data/notzippedruby.rb +7 -0
  66. data/test/data/ntfs.zip +0 -0
  67. data/test/data/oddExtraField.zip +0 -0
  68. data/test/data/path_traversal/Makefile +10 -0
  69. data/test/data/path_traversal/jwilk/README.md +5 -0
  70. data/test/data/path_traversal/jwilk/absolute1.zip +0 -0
  71. data/test/data/path_traversal/jwilk/absolute2.zip +0 -0
  72. data/test/data/path_traversal/jwilk/dirsymlink.zip +0 -0
  73. data/test/data/path_traversal/jwilk/dirsymlink2a.zip +0 -0
  74. data/test/data/path_traversal/jwilk/dirsymlink2b.zip +0 -0
  75. data/test/data/path_traversal/jwilk/relative0.zip +0 -0
  76. data/test/data/path_traversal/jwilk/relative2.zip +0 -0
  77. data/test/data/path_traversal/jwilk/symlink.zip +0 -0
  78. data/test/data/path_traversal/relative1.zip +0 -0
  79. data/test/data/path_traversal/tilde.zip +0 -0
  80. data/test/data/path_traversal/tuzovakaoff/README.md +3 -0
  81. data/test/data/path_traversal/tuzovakaoff/absolutepath.zip +0 -0
  82. data/test/data/path_traversal/tuzovakaoff/symlink.zip +0 -0
  83. data/test/data/rubycode.zip +0 -0
  84. data/test/data/rubycode2.zip +0 -0
  85. data/test/data/test.xls +0 -0
  86. data/test/data/testDirectory.bin +0 -0
  87. data/test/data/zip64-sample.zip +0 -0
  88. data/test/data/zipWithDirs.zip +0 -0
  89. data/test/data/zipWithEncryption.zip +0 -0
  90. data/test/deflater_test.rb +65 -0
  91. data/test/encryption_test.rb +42 -0
  92. data/test/entry_set_test.rb +163 -0
  93. data/test/entry_test.rb +154 -0
  94. data/test/errors_test.rb +35 -0
  95. data/test/extra_field_test.rb +76 -0
  96. data/test/file_extract_directory_test.rb +54 -0
  97. data/test/file_extract_test.rb +145 -0
  98. data/test/file_permissions_test.rb +65 -0
  99. data/test/file_split_test.rb +57 -0
  100. data/test/file_test.rb +666 -0
  101. data/test/filesystem/dir_iterator_test.rb +58 -0
  102. data/test/filesystem/directory_test.rb +139 -0
  103. data/test/filesystem/file_mutating_test.rb +87 -0
  104. data/test/filesystem/file_nonmutating_test.rb +508 -0
  105. data/test/filesystem/file_stat_test.rb +64 -0
  106. data/test/gentestfiles.rb +126 -0
  107. data/test/inflater_test.rb +14 -0
  108. data/test/input_stream_test.rb +182 -0
  109. data/test/ioextras/abstract_input_stream_test.rb +102 -0
  110. data/test/ioextras/abstract_output_stream_test.rb +106 -0
  111. data/test/ioextras/fake_io_test.rb +18 -0
  112. data/test/local_entry_test.rb +154 -0
  113. data/test/output_stream_test.rb +128 -0
  114. data/test/pass_thru_compressor_test.rb +30 -0
  115. data/test/pass_thru_decompressor_test.rb +14 -0
  116. data/test/path_traversal_test.rb +141 -0
  117. data/test/samples/example_recursive_test.rb +37 -0
  118. data/test/settings_test.rb +95 -0
  119. data/test/test_helper.rb +234 -0
  120. data/test/unicode_file_names_and_comments_test.rb +62 -0
  121. data/test/zip64_full_test.rb +51 -0
  122. data/test/zip64_support_test.rb +14 -0
  123. metadata +275 -41
  124. data/NEWS +0 -162
  125. data/lib/zip/stdrubyext.rb +0 -77
  126. data/lib/zip/tempfile_bugfixed.rb +0 -195
  127. data/lib/zip/zip.rb +0 -54
  128. data/lib/zip/zip_central_directory.rb +0 -139
  129. data/lib/zip/zip_entry.rb +0 -639
  130. data/lib/zip/zip_entry_set.rb +0 -66
  131. data/lib/zip/zip_extra_field.rb +0 -213
  132. data/lib/zip/zip_file.rb +0 -318
  133. data/lib/zip/zip_input_stream.rb +0 -134
  134. data/lib/zip/zip_output_stream.rb +0 -172
  135. data/lib/zip/zip_streamable_stream.rb +0 -47
@@ -1,195 +0,0 @@
1
- #
2
- # tempfile - manipulates temporary files
3
- #
4
- # $Id: tempfile_bugfixed.rb,v 1.2 2005/02/19 20:30:33 thomas Exp $
5
- #
6
-
7
- require 'delegate'
8
- require 'tmpdir'
9
-
10
- module BugFix #:nodoc:all
11
-
12
- # A class for managing temporary files. This library is written to be
13
- # thread safe.
14
- class Tempfile < DelegateClass(File)
15
- MAX_TRY = 10
16
- @@cleanlist = []
17
-
18
- # Creates a temporary file of mode 0600 in the temporary directory
19
- # whose name is basename.pid.n and opens with mode "w+". A Tempfile
20
- # object works just like a File object.
21
- #
22
- # If tmpdir is omitted, the temporary directory is determined by
23
- # Dir::tmpdir provided by 'tmpdir.rb'.
24
- # When $SAFE > 0 and the given tmpdir is tainted, it uses
25
- # /tmp. (Note that ENV values are tainted by default)
26
- def initialize(basename, tmpdir=Dir::tmpdir)
27
- if $SAFE > 0 and tmpdir.tainted?
28
- tmpdir = '/tmp'
29
- end
30
-
31
- lock = nil
32
- n = failure = 0
33
-
34
- begin
35
- Thread.critical = true
36
-
37
- begin
38
- tmpname = sprintf('%s/%s%d.%d', tmpdir, basename, $$, n)
39
- lock = tmpname + '.lock'
40
- n += 1
41
- end while @@cleanlist.include?(tmpname) or
42
- File.exist?(lock) or File.exist?(tmpname)
43
-
44
- Dir.mkdir(lock)
45
- rescue
46
- failure += 1
47
- retry if failure < MAX_TRY
48
- raise "cannot generate tempfile `%s'" % tmpname
49
- ensure
50
- Thread.critical = false
51
- end
52
-
53
- @data = [tmpname]
54
- @clean_proc = Tempfile.callback(@data)
55
- ObjectSpace.define_finalizer(self, @clean_proc)
56
-
57
- @tmpfile = File.open(tmpname, File::RDWR|File::CREAT|File::EXCL, 0600)
58
- @tmpname = tmpname
59
- @@cleanlist << @tmpname
60
- @data[1] = @tmpfile
61
- @data[2] = @@cleanlist
62
-
63
- super(@tmpfile)
64
-
65
- # Now we have all the File/IO methods defined, you must not
66
- # carelessly put bare puts(), etc. after this.
67
-
68
- Dir.rmdir(lock)
69
- end
70
-
71
- # Opens or reopens the file with mode "r+".
72
- def open
73
- @tmpfile.close if @tmpfile
74
- @tmpfile = File.open(@tmpname, 'r+')
75
- @data[1] = @tmpfile
76
- __setobj__(@tmpfile)
77
- end
78
-
79
- def _close # :nodoc:
80
- @tmpfile.close if @tmpfile
81
- @data[1] = @tmpfile = nil
82
- end
83
- protected :_close
84
-
85
- # Closes the file. If the optional flag is true, unlinks the file
86
- # after closing.
87
- #
88
- # If you don't explicitly unlink the temporary file, the removal
89
- # will be delayed until the object is finalized.
90
- def close(unlink_now=false)
91
- if unlink_now
92
- close!
93
- else
94
- _close
95
- end
96
- end
97
-
98
- # Closes and unlinks the file.
99
- def close!
100
- _close
101
- @clean_proc.call
102
- ObjectSpace.undefine_finalizer(self)
103
- end
104
-
105
- # Unlinks the file. On UNIX-like systems, it is often a good idea
106
- # to unlink a temporary file immediately after creating and opening
107
- # it, because it leaves other programs zero chance to access the
108
- # file.
109
- def unlink
110
- # keep this order for thread safeness
111
- File.unlink(@tmpname) if File.exist?(@tmpname)
112
- @@cleanlist.delete(@tmpname) if @@cleanlist
113
- end
114
- alias delete unlink
115
-
116
- if RUBY_VERSION > '1.8.0'
117
- def __setobj__(obj)
118
- @_dc_obj = obj
119
- end
120
- else
121
- def __setobj__(obj)
122
- @obj = obj
123
- end
124
- end
125
-
126
- # Returns the full path name of the temporary file.
127
- def path
128
- @tmpname
129
- end
130
-
131
- # Returns the size of the temporary file. As a side effect, the IO
132
- # buffer is flushed before determining the size.
133
- def size
134
- if @tmpfile
135
- @tmpfile.flush
136
- @tmpfile.stat.size
137
- else
138
- 0
139
- end
140
- end
141
- alias length size
142
-
143
- class << self
144
- def callback(data) # :nodoc:
145
- pid = $$
146
- lambda{
147
- if pid == $$
148
- path, tmpfile, cleanlist = *data
149
-
150
- print "removing ", path, "..." if $DEBUG
151
-
152
- tmpfile.close if tmpfile
153
-
154
- # keep this order for thread safeness
155
- File.unlink(path) if File.exist?(path)
156
- cleanlist.delete(path) if cleanlist
157
-
158
- print "done\n" if $DEBUG
159
- end
160
- }
161
- end
162
-
163
- # If no block is given, this is a synonym for new().
164
- #
165
- # If a block is given, it will be passed tempfile as an argument,
166
- # and the tempfile will automatically be closed when the block
167
- # terminates. In this case, open() returns nil.
168
- def open(*args)
169
- tempfile = new(*args)
170
-
171
- if block_given?
172
- begin
173
- yield(tempfile)
174
- ensure
175
- tempfile.close
176
- end
177
-
178
- nil
179
- else
180
- tempfile
181
- end
182
- end
183
- end
184
- end
185
-
186
- end # module BugFix
187
- if __FILE__ == $0
188
- # $DEBUG = true
189
- f = Tempfile.new("foo")
190
- f.print("foo\n")
191
- f.close
192
- f.open
193
- p f.gets # => "foo\n"
194
- f.close!
195
- end
data/lib/zip/zip.rb DELETED
@@ -1,54 +0,0 @@
1
- require 'delegate'
2
- require 'iconv' unless RUBY_VERSION >= '1.9'
3
- require 'singleton'
4
- require 'tempfile'
5
- require 'fileutils'
6
- require 'stringio'
7
- require 'zlib'
8
- require 'zip/stdrubyext'
9
- require 'zip/ioextras'
10
- require 'rbconfig'
11
-
12
- require 'zip/zip_entry'
13
- require 'zip/zip_extra_field'
14
- require 'zip/zip_entry_set'
15
- require 'zip/zip_central_directory'
16
- require 'zip/zip_file'
17
- require 'zip/zip_input_stream'
18
- require 'zip/zip_output_stream'
19
- require 'zip/decompressor'
20
- require 'zip/compressor'
21
- require 'zip/null_decompressor'
22
- require 'zip/null_compressor'
23
- require 'zip/pass_thru_compressor'
24
- require 'zip/pass_thru_decompressor'
25
- require 'zip/inflater'
26
- require 'zip/deflater'
27
- require 'zip/zip_streamable_stream'
28
- require 'zip/zip_streamable_directory'
29
- require 'zip/constants'
30
-
31
- if Tempfile.superclass == SimpleDelegator
32
- require 'zip/tempfile_bugfixed'
33
- Tempfile = BugFix::Tempfile
34
- end
35
-
36
- module Zlib #:nodoc:all
37
- if ! const_defined? :MAX_WBITS
38
- MAX_WBITS = Zlib::Deflate.MAX_WBITS
39
- end
40
- end
41
-
42
- module Zip
43
- class ZipError < StandardError ; end
44
-
45
- class ZipEntryExistsError < ZipError; end
46
- class ZipDestinationFileExistsError < ZipError; end
47
- class ZipCompressionMethodError < ZipError; end
48
- class ZipEntryNameError < ZipError; end
49
- class ZipInternalError < ZipError; end
50
- end
51
-
52
- # Copyright (C) 2002, 2003 Thomas Sondergaard
53
- # rubyzip is free software; you can redistribute it and/or
54
- # modify it under the terms of the ruby license.
@@ -1,139 +0,0 @@
1
- module Zip
2
- class ZipCentralDirectory
3
- include Enumerable
4
-
5
- END_OF_CENTRAL_DIRECTORY_SIGNATURE = 0x06054b50
6
- MAX_END_OF_CENTRAL_DIRECTORY_STRUCTURE_SIZE = 65536 + 18
7
- STATIC_EOCD_SIZE = 22
8
-
9
- attr_reader :comment
10
-
11
- # Returns an Enumerable containing the entries.
12
- def entries
13
- @entrySet.entries
14
- end
15
-
16
- def initialize(entries = ZipEntrySet.new, comment = "") #:nodoc:
17
- super()
18
- @entrySet = entries.kind_of?(ZipEntrySet) ? entries : ZipEntrySet.new(entries)
19
- @comment = comment
20
- end
21
-
22
- def write_to_stream(io) #:nodoc:
23
- offset = io.tell
24
- @entrySet.sort.each { |entry| entry.write_c_dir_entry(io) }
25
- write_e_o_c_d(io, offset)
26
- end
27
-
28
- def write_e_o_c_d(io, offset) #:nodoc:
29
- io <<
30
- [END_OF_CENTRAL_DIRECTORY_SIGNATURE,
31
- 0 , # @numberOfThisDisk
32
- 0 , # @numberOfDiskWithStartOfCDir
33
- @entrySet? @entrySet.size : 0 ,
34
- @entrySet? @entrySet.size : 0 ,
35
- cdir_size ,
36
- offset ,
37
- @comment ? @comment.length : 0 ].pack('VvvvvVVv')
38
- io << @comment
39
- end
40
-
41
- private :write_e_o_c_d
42
-
43
- def cdir_size #:nodoc:
44
- # does not include eocd
45
- @entrySet.inject(0) { |value, entry| entry.cdir_header_size + value }
46
- end
47
-
48
- private :cdir_size
49
-
50
- def read_e_o_c_d(io) #:nodoc:
51
- buf = get_e_o_c_d(io)
52
- @numberOfThisDisk = ZipEntry::read_zip_short(buf)
53
- @numberOfDiskWithStartOfCDir = ZipEntry::read_zip_short(buf)
54
- @totalNumberOfEntriesInCDirOnThisDisk = ZipEntry::read_zip_short(buf)
55
- @size = ZipEntry::read_zip_short(buf)
56
- @sizeInBytes = ZipEntry::read_zip_long(buf)
57
- @cdirOffset = ZipEntry::read_zip_long(buf)
58
- commentLength = ZipEntry::read_zip_short(buf)
59
- @comment = buf.read(commentLength)
60
- raise ZipError, "Zip consistency problem while reading eocd structure" unless buf.size == 0
61
- end
62
-
63
- def read_central_directory_entries(io) #:nodoc:
64
- begin
65
- io.seek(@cdirOffset, IO::SEEK_SET)
66
- rescue Errno::EINVAL
67
- raise ZipError, "Zip consistency problem while reading central directory entry"
68
- end
69
- @entrySet = ZipEntrySet.new
70
- @size.times {
71
- @entrySet << ZipEntry.read_c_dir_entry(io)
72
- }
73
- end
74
-
75
- def read_from_stream(io) #:nodoc:
76
- read_e_o_c_d(io)
77
- read_central_directory_entries(io)
78
- end
79
-
80
- def get_e_o_c_d(io) #:nodoc:
81
- begin
82
- io.seek(-MAX_END_OF_CENTRAL_DIRECTORY_STRUCTURE_SIZE, IO::SEEK_END)
83
- rescue Errno::EINVAL
84
- io.seek(0, IO::SEEK_SET)
85
- rescue Errno::EFBIG # FreeBSD 4.9 raise Errno::EFBIG instead of Errno::EINVAL
86
- io.seek(0, IO::SEEK_SET)
87
- end
88
-
89
- # 'buf = io.read' substituted with lump of code to work around FreeBSD 4.5 issue
90
- retried = false
91
- buf = nil
92
- begin
93
- buf = io.read
94
- rescue Errno::EFBIG # FreeBSD 4.5 may raise Errno::EFBIG
95
- raise if (retried)
96
- retried = true
97
-
98
- io.seek(0, IO::SEEK_SET)
99
- retry
100
- end
101
-
102
- sigIndex = buf.rindex([END_OF_CENTRAL_DIRECTORY_SIGNATURE].pack('V'))
103
- raise ZipError, "Zip end of central directory signature not found" unless sigIndex
104
- buf=buf.slice!((sigIndex+4)...(buf.size))
105
- def buf.read(count)
106
- slice!(0, count)
107
- end
108
- return buf
109
- end
110
-
111
- # For iterating over the entries.
112
- def each(&proc)
113
- @entrySet.each(&proc)
114
- end
115
-
116
- # Returns the number of entries in the central directory (and
117
- # consequently in the zip archive).
118
- def size
119
- @entrySet.size
120
- end
121
-
122
- def ZipCentralDirectory.read_from_stream(io) #:nodoc:
123
- cdir = new
124
- cdir.read_from_stream(io)
125
- return cdir
126
- rescue ZipError
127
- return nil
128
- end
129
-
130
- def == (other) #:nodoc:
131
- return false unless other.kind_of?(ZipCentralDirectory)
132
- @entrySet.entries.sort == other.entries.sort && comment == other.comment
133
- end
134
- end
135
- end
136
-
137
- # Copyright (C) 2002, 2003 Thomas Sondergaard
138
- # rubyzip is free software; you can redistribute it and/or
139
- # modify it under the terms of the ruby license.