rubyzip 0.9.9 → 1.3.0

Sign up to get free protection for your applications and to get access to all the features.
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.