rubyzip 0.9.9 → 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 +284 -41
  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 +59 -7
  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 +17 -13
  13. data/lib/zip/dos_time.rb +13 -14
  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} +162 -157
  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 +6 -6
  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 +274 -41
  124. data/NEWS +0 -172
  125. data/lib/zip/settings.rb +0 -10
  126. data/lib/zip/tempfile_bugfixed.rb +0 -195
  127. data/lib/zip/zip.rb +0 -56
  128. data/lib/zip/zip_central_directory.rb +0 -135
  129. data/lib/zip/zip_entry.rb +0 -638
  130. data/lib/zip/zip_entry_set.rb +0 -77
  131. data/lib/zip/zip_extra_field.rb +0 -213
  132. data/lib/zip/zip_file.rb +0 -340
  133. data/lib/zip/zip_input_stream.rb +0 -144
  134. data/lib/zip/zip_output_stream.rb +0 -173
  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) ||
42
- ::File.exist?(lock) || ::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,56 +0,0 @@
1
- require 'delegate'
2
- require 'singleton'
3
- require 'tempfile'
4
- require 'fileutils'
5
- require 'stringio'
6
- require 'zlib'
7
- require 'zip/dos_time'
8
- require 'zip/ioextras'
9
- require 'rbconfig'
10
-
11
- require 'zip/zip_entry'
12
- require 'zip/zip_extra_field'
13
- require 'zip/zip_entry_set'
14
- require 'zip/zip_central_directory'
15
- require 'zip/zip_file'
16
- require 'zip/zip_input_stream'
17
- require 'zip/zip_output_stream'
18
- require 'zip/decompressor'
19
- require 'zip/compressor'
20
- require 'zip/null_decompressor'
21
- require 'zip/null_compressor'
22
- require 'zip/null_input_stream'
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
- require 'zip/settings'
32
-
33
- if Tempfile.superclass == SimpleDelegator
34
- require 'zip/tempfile_bugfixed'
35
- Tempfile = BugFix::Tempfile
36
- end
37
-
38
- module Zlib #:nodoc:all
39
- if !const_defined?(:MAX_WBITS)
40
- MAX_WBITS = Zlib::Deflate.MAX_WBITS
41
- end
42
- end
43
-
44
- module Zip
45
- class ZipError < StandardError ; end
46
-
47
- class ZipEntryExistsError < ZipError; end
48
- class ZipDestinationFileExistsError < ZipError; end
49
- class ZipCompressionMethodError < ZipError; end
50
- class ZipEntryNameError < ZipError; end
51
- class ZipInternalError < ZipError; end
52
- end
53
-
54
- # Copyright (C) 2002, 2003 Thomas Sondergaard
55
- # rubyzip is free software; you can redistribute it and/or
56
- # modify it under the terms of the ruby license.
@@ -1,135 +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.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
- tmp = [
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
38
- ]
39
- io << tmp.pack('VvvvvVVv')
40
- io << @comment
41
- end
42
-
43
- private :write_e_o_c_d
44
-
45
- def cdir_size #:nodoc:
46
- # does not include eocd
47
- @entrySet.inject(0) do |value, entry|
48
- entry.cdir_header_size + value
49
- end
50
- end
51
-
52
- private :cdir_size
53
-
54
- def read_e_o_c_d(io) #:nodoc:
55
- buf = get_e_o_c_d(io)
56
- @numberOfThisDisk = ZipEntry.read_zip_short(buf)
57
- @numberOfDiskWithStartOfCDir = ZipEntry.read_zip_short(buf)
58
- @totalNumberOfEntriesInCDirOnThisDisk = ZipEntry.read_zip_short(buf)
59
- @size = ZipEntry.read_zip_short(buf)
60
- @sizeInBytes = ZipEntry.read_zip_long(buf)
61
- @cdirOffset = ZipEntry.read_zip_long(buf)
62
- commentLength = ZipEntry.read_zip_short(buf)
63
- if commentLength <= 0
64
- @comment = buf.slice!(0, buf.size)
65
- else
66
- @comment = buf.read(commentLength)
67
- end
68
- raise ZipError, "Zip consistency problem while reading eocd structure" unless buf.size == 0
69
- end
70
-
71
- def read_central_directory_entries(io) #:nodoc:
72
- begin
73
- io.seek(@cdirOffset, IO::SEEK_SET)
74
- rescue Errno::EINVAL
75
- raise ZipError, "Zip consistency problem while reading central directory entry"
76
- end
77
- @entrySet = ZipEntrySet.new
78
- @size.times do
79
- tmp = ZipEntry.read_c_dir_entry(io)
80
- @entrySet << tmp
81
- end
82
- end
83
-
84
- def read_from_stream(io) #:nodoc:
85
- read_e_o_c_d(io)
86
- read_central_directory_entries(io)
87
- end
88
-
89
- def get_e_o_c_d(io) #:nodoc:
90
- begin
91
- io.seek(-MAX_END_OF_CENTRAL_DIRECTORY_STRUCTURE_SIZE, IO::SEEK_END)
92
- rescue Errno::EINVAL
93
- io.seek(0, IO::SEEK_SET)
94
- end
95
- buf = io.read
96
- sigIndex = buf.rindex([END_OF_CENTRAL_DIRECTORY_SIGNATURE].pack('V'))
97
- raise ZipError, "Zip end of central directory signature not found" unless sigIndex
98
- buf = buf.slice!((sigIndex + 4)..(buf.bytesize))
99
-
100
- def buf.read(count)
101
- slice!(0, count)
102
- end
103
-
104
- buf
105
- end
106
-
107
- # For iterating over the entries.
108
- def each(&proc)
109
- @entrySet.each(&proc)
110
- end
111
-
112
- # Returns the number of entries in the central directory (and
113
- # consequently in the zip archive).
114
- def size
115
- @entrySet.size
116
- end
117
-
118
- def ZipCentralDirectory.read_from_stream(io) #:nodoc:
119
- cdir = new
120
- cdir.read_from_stream(io)
121
- return cdir
122
- rescue ZipError
123
- return nil
124
- end
125
-
126
- def ==(other) #:nodoc:
127
- return false unless other.kind_of?(ZipCentralDirectory)
128
- @entrySet.entries.sort == other.entries.sort && comment == other.comment
129
- end
130
- end
131
- end
132
-
133
- # Copyright (C) 2002, 2003 Thomas Sondergaard
134
- # rubyzip is free software; you can redistribute it and/or
135
- # modify it under the terms of the ruby license.