rubyzip 1.0.0 → 1.2.0
Sign up to get free protection for your applications and to get access to all the features.
Potentially problematic release.
This version of rubyzip might be problematic. Click here for more details.
- checksums.yaml +6 -14
- data/README.md +173 -42
- data/Rakefile +10 -5
- data/TODO +0 -1
- data/lib/zip/central_directory.rb +55 -24
- data/lib/zip/compressor.rb +0 -0
- data/lib/zip/constants.rb +4 -2
- data/lib/zip/crypto/encryption.rb +11 -0
- data/lib/zip/crypto/null_encryption.rb +45 -0
- data/lib/zip/crypto/traditional_encryption.rb +99 -0
- data/lib/zip/decompressor.rb +2 -2
- data/lib/zip/deflater.rb +11 -6
- data/lib/zip/dos_time.rb +4 -5
- data/lib/zip/entry.rb +159 -97
- data/lib/zip/entry_set.rb +18 -18
- data/lib/zip/errors.rb +15 -6
- data/lib/zip/extra_field/generic.rb +8 -8
- data/lib/zip/extra_field/ntfs.rb +90 -0
- data/lib/zip/extra_field/old_unix.rb +44 -0
- data/lib/zip/extra_field/universal_time.rb +14 -14
- data/lib/zip/extra_field/unix.rb +8 -9
- data/lib/zip/extra_field/zip64.rb +44 -6
- data/lib/zip/extra_field/zip64_placeholder.rb +16 -0
- data/lib/zip/extra_field.rb +20 -8
- data/lib/zip/file.rb +126 -114
- data/lib/zip/filesystem.rb +140 -139
- data/lib/zip/inflater.rb +10 -9
- data/lib/zip/input_stream.rb +105 -80
- data/lib/zip/ioextras/abstract_input_stream.rb +15 -12
- data/lib/zip/ioextras/abstract_output_stream.rb +0 -2
- data/lib/zip/ioextras.rb +1 -3
- data/lib/zip/null_compressor.rb +2 -2
- data/lib/zip/null_decompressor.rb +4 -4
- data/lib/zip/null_input_stream.rb +2 -1
- data/lib/zip/output_stream.rb +57 -43
- data/lib/zip/pass_thru_compressor.rb +4 -4
- data/lib/zip/pass_thru_decompressor.rb +4 -5
- data/lib/zip/streamable_directory.rb +2 -2
- data/lib/zip/streamable_stream.rb +22 -13
- data/lib/zip/version.rb +1 -1
- data/lib/zip.rb +11 -2
- data/samples/example.rb +30 -40
- data/samples/example_filesystem.rb +16 -18
- data/samples/example_recursive.rb +35 -27
- data/samples/{gtkRubyzip.rb → gtk_ruby_zip.rb} +25 -27
- data/samples/qtzip.rb +19 -28
- data/samples/write_simple.rb +12 -13
- data/samples/zipfind.rb +29 -37
- data/test/basic_zip_file_test.rb +60 -0
- data/test/case_sensitivity_test.rb +69 -0
- data/test/central_directory_entry_test.rb +69 -0
- data/test/central_directory_test.rb +100 -0
- data/test/crypto/null_encryption_test.rb +53 -0
- data/test/crypto/traditional_encryption_test.rb +80 -0
- data/test/data/WarnInvalidDate.zip +0 -0
- data/test/data/file1.txt +46 -0
- data/test/data/file1.txt.deflatedData +0 -0
- data/test/data/file2.txt +1504 -0
- data/test/data/globTest/foo/bar/baz/foo.txt +0 -0
- data/test/data/globTest/foo.txt +0 -0
- data/test/data/globTest/food.txt +0 -0
- data/test/data/globTest.zip +0 -0
- data/test/data/mimetype +1 -0
- data/test/data/notzippedruby.rb +7 -0
- data/test/data/ntfs.zip +0 -0
- data/test/data/oddExtraField.zip +0 -0
- data/test/data/rubycode.zip +0 -0
- data/test/data/rubycode2.zip +0 -0
- data/test/data/test.xls +0 -0
- data/test/data/testDirectory.bin +0 -0
- data/test/data/zip64-sample.zip +0 -0
- data/test/data/zipWithDirs.zip +0 -0
- data/test/data/zipWithEncryption.zip +0 -0
- data/test/deflater_test.rb +65 -0
- data/test/encryption_test.rb +42 -0
- data/test/entry_set_test.rb +152 -0
- data/test/entry_test.rb +163 -0
- data/test/errors_test.rb +34 -0
- data/test/extra_field_test.rb +76 -0
- data/test/file_extract_directory_test.rb +54 -0
- data/test/file_extract_test.rb +83 -0
- data/test/file_permissions_test.rb +69 -0
- data/test/file_split_test.rb +57 -0
- data/test/file_test.rb +563 -0
- data/test/filesystem/dir_iterator_test.rb +58 -0
- data/test/filesystem/directory_test.rb +121 -0
- data/test/filesystem/file_mutating_test.rb +88 -0
- data/test/filesystem/file_nonmutating_test.rb +508 -0
- data/test/filesystem/file_stat_test.rb +64 -0
- data/test/gentestfiles.rb +122 -0
- data/test/inflater_test.rb +14 -0
- data/test/input_stream_test.rb +182 -0
- data/test/ioextras/abstract_input_stream_test.rb +102 -0
- data/test/ioextras/abstract_output_stream_test.rb +106 -0
- data/test/ioextras/fake_io_test.rb +18 -0
- data/test/local_entry_test.rb +154 -0
- data/test/output_stream_test.rb +128 -0
- data/test/pass_thru_compressor_test.rb +30 -0
- data/test/pass_thru_decompressor_test.rb +14 -0
- data/test/samples/example_recursive_test.rb +37 -0
- data/test/settings_test.rb +95 -0
- data/test/test_helper.rb +221 -0
- data/test/unicode_file_names_and_comments_test.rb +50 -0
- data/test/zip64_full_test.rb +51 -0
- data/test/zip64_support_test.rb +14 -0
- metadata +198 -22
- data/NEWS +0 -182
data/lib/zip/filesystem.rb
CHANGED
@@ -1,41 +1,39 @@
|
|
1
1
|
require 'zip'
|
2
2
|
|
3
3
|
module Zip
|
4
|
-
|
5
|
-
#
|
6
|
-
# a zip archive that is similar to ruby's builtin File and Dir
|
4
|
+
# The ZipFileSystem API provides an API for accessing entries in
|
5
|
+
# a zip archive that is similar to ruby's builtin File and Dir
|
7
6
|
# classes.
|
8
7
|
#
|
9
|
-
# Requiring 'zip/
|
10
|
-
# making the methods in this module available on
|
8
|
+
# Requiring 'zip/filesystem' includes this module in Zip::File
|
9
|
+
# making the methods in this module available on Zip::File objects.
|
11
10
|
#
|
12
|
-
# Using this API the following example creates a new zip file
|
11
|
+
# Using this API the following example creates a new zip file
|
13
12
|
# <code>my.zip</code> containing a normal entry with the name
|
14
13
|
# <code>first.txt</code>, a directory entry named <code>mydir</code>
|
15
14
|
# and finally another normal entry named <code>second.txt</code>
|
16
15
|
#
|
17
16
|
# require 'zip/filesystem'
|
18
|
-
#
|
19
|
-
# Zip::File.open("my.zip", Zip::
|
17
|
+
#
|
18
|
+
# Zip::File.open("my.zip", Zip::File::CREATE) {
|
20
19
|
# |zipfile|
|
21
20
|
# zipfile.file.open("first.txt", "w") { |f| f.puts "Hello world" }
|
22
21
|
# zipfile.dir.mkdir("mydir")
|
23
22
|
# zipfile.file.open("mydir/second.txt", "w") { |f| f.puts "Hello again" }
|
24
23
|
# }
|
25
24
|
#
|
26
|
-
# Reading is as easy as writing, as the following example shows. The
|
25
|
+
# Reading is as easy as writing, as the following example shows. The
|
27
26
|
# example writes the contents of <code>first.txt</code> from zip archive
|
28
27
|
# <code>my.zip</code> to standard out.
|
29
28
|
#
|
30
29
|
# require 'zip/filesystem'
|
31
|
-
#
|
30
|
+
#
|
32
31
|
# Zip::File.open("my.zip") {
|
33
32
|
# |zipfile|
|
34
33
|
# puts zipfile.file.read("first.txt")
|
35
34
|
# }
|
36
35
|
|
37
36
|
module FileSystem
|
38
|
-
|
39
37
|
def initialize # :nodoc:
|
40
38
|
mappedZip = ZipFileNameMapper.new(self)
|
41
39
|
@zipFsDir = ZipFsDir.new(mappedZip)
|
@@ -45,44 +43,40 @@ module Zip
|
|
45
43
|
end
|
46
44
|
|
47
45
|
# Returns a ZipFsDir which is much like ruby's builtin Dir (class)
|
48
|
-
# object, except it works on the
|
46
|
+
# object, except it works on the Zip::File on which this method is
|
49
47
|
# invoked
|
50
48
|
def dir
|
51
49
|
@zipFsDir
|
52
50
|
end
|
53
51
|
|
54
52
|
# Returns a ZipFsFile which is much like ruby's builtin File (class)
|
55
|
-
# object, except it works on the
|
53
|
+
# object, except it works on the Zip::File on which this method is
|
56
54
|
# invoked
|
57
55
|
def file
|
58
56
|
@zipFsFile
|
59
57
|
end
|
60
58
|
|
61
59
|
# Instances of this class are normally accessed via the accessor
|
62
|
-
#
|
63
|
-
# builtin File (class) object, except it works on
|
60
|
+
# Zip::File::file. An instance of ZipFsFile behaves like ruby's
|
61
|
+
# builtin File (class) object, except it works on Zip::File entries.
|
64
62
|
#
|
65
63
|
# The individual methods are not documented due to their
|
66
64
|
# similarity with the methods in File
|
67
65
|
class ZipFsFile
|
68
|
-
|
69
66
|
attr_writer :dir
|
70
|
-
#
|
67
|
+
# protected :dir
|
71
68
|
|
72
69
|
class ZipFsStat
|
73
|
-
|
74
70
|
class << self
|
75
|
-
|
76
71
|
def delegate_to_fs_file(*methods)
|
77
72
|
methods.each do |method|
|
78
|
-
|
73
|
+
class_eval <<-end_eval, __FILE__, __LINE__ + 1
|
79
74
|
def #{method} # def file?
|
80
75
|
@zipFsFile.#{method}(@entryName) # @zipFsFile.file?(@entryName)
|
81
76
|
end # end
|
82
77
|
end_eval
|
83
78
|
end
|
84
79
|
end
|
85
|
-
|
86
80
|
end
|
87
81
|
|
88
82
|
def initialize(zipFsFile, entryName)
|
@@ -91,15 +85,17 @@ module Zip
|
|
91
85
|
end
|
92
86
|
|
93
87
|
def kind_of?(t)
|
94
|
-
super || t == ::File::Stat
|
88
|
+
super || t == ::File::Stat
|
95
89
|
end
|
96
90
|
|
97
91
|
delegate_to_fs_file :file?, :directory?, :pipe?, :chardev?, :symlink?,
|
98
|
-
|
99
|
-
|
100
|
-
|
92
|
+
:socket?, :blockdev?, :readable?, :readable_real?, :writable?, :ctime,
|
93
|
+
:writable_real?, :executable?, :executable_real?, :sticky?, :owned?,
|
94
|
+
:grpowned?, :setuid?, :setgid?, :zero?, :size, :size?, :mtime, :atime
|
101
95
|
|
102
|
-
def blocks
|
96
|
+
def blocks
|
97
|
+
nil
|
98
|
+
end
|
103
99
|
|
104
100
|
def get_entry
|
105
101
|
@zipFsFile.__send__(:get_entry, @entryName)
|
@@ -108,8 +104,8 @@ module Zip
|
|
108
104
|
|
109
105
|
def gid
|
110
106
|
e = get_entry
|
111
|
-
if e.extra.member?
|
112
|
-
e.extra[
|
107
|
+
if e.extra.member? 'IUnix'
|
108
|
+
e.extra['IUnix'].gid || 0
|
113
109
|
else
|
114
110
|
0
|
115
111
|
end
|
@@ -117,43 +113,57 @@ module Zip
|
|
117
113
|
|
118
114
|
def uid
|
119
115
|
e = get_entry
|
120
|
-
if e.extra.member?
|
121
|
-
e.extra[
|
116
|
+
if e.extra.member? 'IUnix'
|
117
|
+
e.extra['IUnix'].uid || 0
|
122
118
|
else
|
123
119
|
0
|
124
120
|
end
|
125
121
|
end
|
126
122
|
|
127
|
-
def ino
|
123
|
+
def ino
|
124
|
+
0
|
125
|
+
end
|
128
126
|
|
129
|
-
def dev
|
127
|
+
def dev
|
128
|
+
0
|
129
|
+
end
|
130
130
|
|
131
|
-
def rdev
|
131
|
+
def rdev
|
132
|
+
0
|
133
|
+
end
|
132
134
|
|
133
|
-
def rdev_major
|
135
|
+
def rdev_major
|
136
|
+
0
|
137
|
+
end
|
134
138
|
|
135
|
-
def rdev_minor
|
139
|
+
def rdev_minor
|
140
|
+
0
|
141
|
+
end
|
136
142
|
|
137
143
|
def ftype
|
138
144
|
if file?
|
139
|
-
return
|
145
|
+
return 'file'
|
140
146
|
elsif directory?
|
141
|
-
return
|
147
|
+
return 'directory'
|
142
148
|
else
|
143
|
-
raise StandardError,
|
149
|
+
raise StandardError, 'Unknown file type'
|
144
150
|
end
|
145
151
|
end
|
146
152
|
|
147
|
-
def nlink
|
153
|
+
def nlink
|
154
|
+
1
|
155
|
+
end
|
148
156
|
|
149
|
-
def blksize
|
157
|
+
def blksize
|
158
|
+
nil
|
159
|
+
end
|
150
160
|
|
151
161
|
def mode
|
152
162
|
e = get_entry
|
153
163
|
if e.fstype == 3
|
154
164
|
e.external_file_attributes >> 16
|
155
165
|
else
|
156
|
-
|
166
|
+
33_206 # 33206 is equivalent to -rw-rw-rw-
|
157
167
|
end
|
158
168
|
end
|
159
169
|
end
|
@@ -163,7 +173,7 @@ module Zip
|
|
163
173
|
end
|
164
174
|
|
165
175
|
def get_entry(fileName)
|
166
|
-
|
176
|
+
unless exists?(fileName)
|
167
177
|
raise Errno::ENOENT, "No such file or directory - #{fileName}"
|
168
178
|
end
|
169
179
|
@mappedZip.find_entry(fileName)
|
@@ -171,33 +181,31 @@ module Zip
|
|
171
181
|
private :get_entry
|
172
182
|
|
173
183
|
def unix_mode_cmp(fileName, mode)
|
174
|
-
|
175
|
-
|
176
|
-
|
177
|
-
|
178
|
-
false
|
179
|
-
end
|
184
|
+
e = get_entry(fileName)
|
185
|
+
e.fstype == 3 && ((e.external_file_attributes >> 16) & mode) != 0
|
186
|
+
rescue Errno::ENOENT
|
187
|
+
false
|
180
188
|
end
|
181
189
|
private :unix_mode_cmp
|
182
190
|
|
183
191
|
def exists?(fileName)
|
184
|
-
expand_path(fileName) ==
|
192
|
+
expand_path(fileName) == '/' || !@mappedZip.find_entry(fileName).nil?
|
185
193
|
end
|
186
|
-
alias
|
194
|
+
alias exist? exists?
|
187
195
|
|
188
196
|
# Permissions not implemented, so if the file exists it is accessible
|
189
|
-
alias owned?
|
190
|
-
alias grpowned?
|
197
|
+
alias owned? exists?
|
198
|
+
alias grpowned? exists?
|
191
199
|
|
192
200
|
def readable?(fileName)
|
193
201
|
unix_mode_cmp(fileName, 0444)
|
194
202
|
end
|
195
|
-
alias readable_real?
|
203
|
+
alias readable_real? readable?
|
196
204
|
|
197
205
|
def writable?(fileName)
|
198
206
|
unix_mode_cmp(fileName, 0222)
|
199
207
|
end
|
200
|
-
alias writable_real?
|
208
|
+
alias writable_real? writable?
|
201
209
|
|
202
210
|
def executable?(fileName)
|
203
211
|
unix_mode_cmp(fileName, 0111)
|
@@ -220,28 +228,28 @@ module Zip
|
|
220
228
|
::File.umask(*args)
|
221
229
|
end
|
222
230
|
|
223
|
-
def truncate(
|
224
|
-
raise StandardError,
|
231
|
+
def truncate(_fileName, _len)
|
232
|
+
raise StandardError, 'truncate not supported'
|
225
233
|
end
|
226
234
|
|
227
235
|
def directory?(fileName)
|
228
236
|
entry = @mappedZip.find_entry(fileName)
|
229
|
-
expand_path(fileName) ==
|
237
|
+
expand_path(fileName) == '/' || (!entry.nil? && entry.directory?)
|
230
238
|
end
|
231
239
|
|
232
|
-
def open(fileName, openMode =
|
233
|
-
openMode.gsub!(
|
240
|
+
def open(fileName, openMode = 'r', permissionInt = 0644, &block)
|
241
|
+
openMode.gsub!('b', '') # ignore b option
|
234
242
|
case openMode
|
235
|
-
|
236
|
-
|
237
|
-
|
238
|
-
|
239
|
-
|
240
|
-
|
243
|
+
when 'r'
|
244
|
+
@mappedZip.get_input_stream(fileName, &block)
|
245
|
+
when 'w'
|
246
|
+
@mappedZip.get_output_stream(fileName, permissionInt, &block)
|
247
|
+
else
|
248
|
+
raise StandardError, "openmode '#{openMode} not supported" unless openMode == 'r'
|
241
249
|
end
|
242
250
|
end
|
243
251
|
|
244
|
-
def new(fileName, openMode =
|
252
|
+
def new(fileName, openMode = 'r')
|
245
253
|
open(fileName, openMode)
|
246
254
|
end
|
247
255
|
|
@@ -252,43 +260,41 @@ module Zip
|
|
252
260
|
# Returns nil for not found and nil for directories
|
253
261
|
def size?(fileName)
|
254
262
|
entry = @mappedZip.find_entry(fileName)
|
255
|
-
|
263
|
+
(entry.nil? || entry.directory?) ? nil : entry.size
|
256
264
|
end
|
257
265
|
|
258
266
|
def chown(ownerInt, groupInt, *filenames)
|
259
|
-
filenames.each
|
267
|
+
filenames.each do |fileName|
|
260
268
|
e = get_entry(fileName)
|
261
|
-
unless e.extra.member?(
|
262
|
-
|
263
|
-
|
264
|
-
|
265
|
-
e.extra["IUnix"].gid = groupInt
|
266
|
-
}
|
269
|
+
e.extra.create('IUnix') unless e.extra.member?('IUnix')
|
270
|
+
e.extra['IUnix'].uid = ownerInt
|
271
|
+
e.extra['IUnix'].gid = groupInt
|
272
|
+
end
|
267
273
|
filenames.size
|
268
274
|
end
|
269
275
|
|
270
|
-
def chmod
|
271
|
-
filenames.each
|
276
|
+
def chmod(modeInt, *filenames)
|
277
|
+
filenames.each do |fileName|
|
272
278
|
e = get_entry(fileName)
|
273
279
|
e.fstype = 3 # force convertion filesystem type to unix
|
274
280
|
e.unix_perms = modeInt
|
275
281
|
e.external_file_attributes = modeInt << 16
|
276
282
|
e.dirty = true
|
277
|
-
|
283
|
+
end
|
278
284
|
filenames.size
|
279
285
|
end
|
280
286
|
|
281
287
|
def zero?(fileName)
|
282
288
|
sz = size(fileName)
|
283
|
-
sz
|
289
|
+
sz.nil? || sz == 0
|
284
290
|
rescue Errno::ENOENT
|
285
291
|
false
|
286
292
|
end
|
287
293
|
|
288
294
|
def file?(fileName)
|
289
295
|
entry = @mappedZip.find_entry(fileName)
|
290
|
-
entry
|
291
|
-
end
|
296
|
+
!entry.nil? && entry.file?
|
297
|
+
end
|
292
298
|
|
293
299
|
def dirname(fileName)
|
294
300
|
::File.dirname(fileName)
|
@@ -307,9 +313,9 @@ module Zip
|
|
307
313
|
end
|
308
314
|
|
309
315
|
def utime(modifiedTime, *fileNames)
|
310
|
-
fileNames.each
|
316
|
+
fileNames.each do |fileName|
|
311
317
|
get_entry(fileName).time = modifiedTime
|
312
|
-
|
318
|
+
end
|
313
319
|
end
|
314
320
|
|
315
321
|
def mtime(fileName)
|
@@ -318,66 +324,64 @@ module Zip
|
|
318
324
|
|
319
325
|
def atime(fileName)
|
320
326
|
e = get_entry(fileName)
|
321
|
-
if e.extra.member?
|
322
|
-
e.extra[
|
323
|
-
|
324
|
-
|
327
|
+
if e.extra.member? 'UniversalTime'
|
328
|
+
e.extra['UniversalTime'].atime
|
329
|
+
elsif e.extra.member? 'NTFS'
|
330
|
+
e.extra['NTFS'].atime
|
325
331
|
end
|
326
332
|
end
|
327
333
|
|
328
334
|
def ctime(fileName)
|
329
335
|
e = get_entry(fileName)
|
330
|
-
if e.extra.member?
|
331
|
-
e.extra[
|
332
|
-
|
333
|
-
|
336
|
+
if e.extra.member? 'UniversalTime'
|
337
|
+
e.extra['UniversalTime'].ctime
|
338
|
+
elsif e.extra.member? 'NTFS'
|
339
|
+
e.extra['NTFS'].ctime
|
334
340
|
end
|
335
341
|
end
|
336
342
|
|
337
|
-
def pipe?(
|
343
|
+
def pipe?(_filename)
|
338
344
|
false
|
339
345
|
end
|
340
346
|
|
341
|
-
def blockdev?(
|
347
|
+
def blockdev?(_filename)
|
342
348
|
false
|
343
349
|
end
|
344
350
|
|
345
|
-
def chardev?(
|
351
|
+
def chardev?(_filename)
|
346
352
|
false
|
347
353
|
end
|
348
354
|
|
349
|
-
def symlink?(
|
355
|
+
def symlink?(_fileName)
|
350
356
|
false
|
351
357
|
end
|
352
358
|
|
353
|
-
def socket?(
|
359
|
+
def socket?(_fileName)
|
354
360
|
false
|
355
361
|
end
|
356
362
|
|
357
363
|
def ftype(fileName)
|
358
|
-
@mappedZip.get_entry(fileName).directory? ?
|
364
|
+
@mappedZip.get_entry(fileName).directory? ? 'directory' : 'file'
|
359
365
|
end
|
360
366
|
|
361
|
-
def readlink(
|
362
|
-
raise NotImplementedError,
|
367
|
+
def readlink(_fileName)
|
368
|
+
raise NotImplementedError, 'The readlink() function is not implemented'
|
363
369
|
end
|
364
370
|
|
365
|
-
def symlink(
|
366
|
-
raise NotImplementedError,
|
371
|
+
def symlink(_fileName, _symlinkName)
|
372
|
+
raise NotImplementedError, 'The symlink() function is not implemented'
|
367
373
|
end
|
368
374
|
|
369
|
-
def link(
|
370
|
-
raise NotImplementedError,
|
375
|
+
def link(_fileName, _symlinkName)
|
376
|
+
raise NotImplementedError, 'The link() function is not implemented'
|
371
377
|
end
|
372
378
|
|
373
379
|
def pipe
|
374
|
-
raise NotImplementedError,
|
380
|
+
raise NotImplementedError, 'The pipe() function is not implemented'
|
375
381
|
end
|
376
382
|
|
377
383
|
def stat(fileName)
|
378
|
-
|
379
|
-
raise Errno::ENOENT, fileName
|
380
|
-
end
|
384
|
+
raise Errno::ENOENT, fileName unless exists?(fileName)
|
381
385
|
ZipFsStat.new(self, fileName)
|
382
386
|
end
|
383
387
|
|
@@ -400,20 +404,19 @@ module Zip
|
|
400
404
|
end
|
401
405
|
|
402
406
|
def delete(*args)
|
403
|
-
args.each
|
404
|
-
|fileName|
|
407
|
+
args.each do |fileName|
|
405
408
|
if directory?(fileName)
|
406
409
|
raise Errno::EISDIR, "Is a directory - \"#{fileName}\""
|
407
410
|
end
|
408
411
|
@mappedZip.remove(fileName)
|
409
|
-
|
412
|
+
end
|
410
413
|
end
|
411
414
|
|
412
415
|
def rename(fileToRename, newName)
|
413
416
|
@mappedZip.rename(fileToRename, newName) { true }
|
414
417
|
end
|
415
418
|
|
416
|
-
alias
|
419
|
+
alias unlink delete
|
417
420
|
|
418
421
|
def expand_path(aPath)
|
419
422
|
@mappedZip.expand_path(aPath)
|
@@ -427,7 +430,6 @@ module Zip
|
|
427
430
|
# The individual methods are not documented due to their
|
428
431
|
# similarity with the methods in Dir
|
429
432
|
class ZipFsDir
|
430
|
-
|
431
433
|
def initialize(mappedZip)
|
432
434
|
@mappedZip = mappedZip
|
433
435
|
end
|
@@ -451,7 +453,9 @@ module Zip
|
|
451
453
|
dirIt
|
452
454
|
end
|
453
455
|
|
454
|
-
def pwd
|
456
|
+
def pwd
|
457
|
+
@mappedZip.pwd
|
458
|
+
end
|
455
459
|
alias getwd pwd
|
456
460
|
|
457
461
|
def chdir(aDirectoryName)
|
@@ -467,8 +471,8 @@ module Zip
|
|
467
471
|
entries
|
468
472
|
end
|
469
473
|
|
470
|
-
def glob(*args
|
471
|
-
@mappedZip.glob(*args
|
474
|
+
def glob(*args, &block)
|
475
|
+
@mappedZip.glob(*args, &block)
|
472
476
|
end
|
473
477
|
|
474
478
|
def foreach(aDirectoryName)
|
@@ -479,11 +483,10 @@ module Zip
|
|
479
483
|
path << '/' unless path.end_with?('/')
|
480
484
|
path = Regexp.escape(path)
|
481
485
|
subDirEntriesRegex = Regexp.new("^#{path}([^/]+)$")
|
482
|
-
@mappedZip.each
|
483
|
-
|fileName|
|
486
|
+
@mappedZip.each do |fileName|
|
484
487
|
match = subDirEntriesRegex.match(fileName)
|
485
|
-
yield(match[1]) unless match
|
486
|
-
|
488
|
+
yield(match[1]) unless match.nil?
|
489
|
+
end
|
487
490
|
end
|
488
491
|
|
489
492
|
def delete(entryName)
|
@@ -492,17 +495,16 @@ module Zip
|
|
492
495
|
end
|
493
496
|
@mappedZip.remove(entryName)
|
494
497
|
end
|
495
|
-
alias rmdir
|
498
|
+
alias rmdir delete
|
496
499
|
alias unlink delete
|
497
500
|
|
498
501
|
def mkdir(entryName, permissionInt = 0755)
|
499
502
|
@mappedZip.mkdir(entryName, permissionInt)
|
500
503
|
end
|
501
504
|
|
502
|
-
def chroot(*
|
503
|
-
raise NotImplementedError,
|
505
|
+
def chroot(*_args)
|
506
|
+
raise NotImplementedError, 'The chroot() function is not implemented'
|
504
507
|
end
|
505
|
-
|
506
508
|
end
|
507
509
|
|
508
510
|
class ZipFsDirIterator # :nodoc:all
|
@@ -518,39 +520,39 @@ module Zip
|
|
518
520
|
end
|
519
521
|
|
520
522
|
def each(&aProc)
|
521
|
-
raise IOError,
|
523
|
+
raise IOError, 'closed directory' if @fileNames.nil?
|
522
524
|
@fileNames.each(&aProc)
|
523
525
|
end
|
524
526
|
|
525
527
|
def read
|
526
|
-
raise IOError,
|
527
|
-
@fileNames[(@index+=1)-1]
|
528
|
+
raise IOError, 'closed directory' if @fileNames.nil?
|
529
|
+
@fileNames[(@index += 1) - 1]
|
528
530
|
end
|
529
531
|
|
530
532
|
def rewind
|
531
|
-
raise IOError,
|
533
|
+
raise IOError, 'closed directory' if @fileNames.nil?
|
532
534
|
@index = 0
|
533
535
|
end
|
534
536
|
|
535
537
|
def seek(anIntegerPosition)
|
536
|
-
raise IOError,
|
538
|
+
raise IOError, 'closed directory' if @fileNames.nil?
|
537
539
|
@index = anIntegerPosition
|
538
540
|
end
|
539
541
|
|
540
542
|
def tell
|
541
|
-
raise IOError,
|
543
|
+
raise IOError, 'closed directory' if @fileNames.nil?
|
542
544
|
@index
|
543
545
|
end
|
544
546
|
end
|
545
547
|
|
546
|
-
# All access to
|
548
|
+
# All access to Zip::File from ZipFsFile and ZipFsDir goes through a
|
547
549
|
# ZipFileNameMapper, which has one responsibility: ensure
|
548
550
|
class ZipFileNameMapper # :nodoc:all
|
549
551
|
include Enumerable
|
550
552
|
|
551
553
|
def initialize(zipFile)
|
552
554
|
@zipFile = zipFile
|
553
|
-
@pwd =
|
555
|
+
@pwd = '/'
|
554
556
|
end
|
555
557
|
|
556
558
|
attr_accessor :pwd
|
@@ -580,7 +582,7 @@ module Zip
|
|
580
582
|
end
|
581
583
|
|
582
584
|
def rename(fileName, newName, &continueOnExistsProc)
|
583
|
-
@zipFile.rename(expand_to_entry(fileName), expand_to_entry(newName),
|
585
|
+
@zipFile.rename(expand_to_entry(fileName), expand_to_entry(newName),
|
584
586
|
&continueOnExistsProc)
|
585
587
|
end
|
586
588
|
|
@@ -591,17 +593,16 @@ module Zip
|
|
591
593
|
# Turns entries into strings and adds leading /
|
592
594
|
# and removes trailing slash on directories
|
593
595
|
def each
|
594
|
-
@zipFile.each
|
595
|
-
|
596
|
-
|
597
|
-
}
|
596
|
+
@zipFile.each do |e|
|
597
|
+
yield('/' + e.to_s.chomp('/'))
|
598
|
+
end
|
598
599
|
end
|
599
600
|
|
600
601
|
def expand_path(aPath)
|
601
|
-
expanded = aPath.start_with?(
|
602
|
-
expanded.gsub!(/\/\.(\/|$)/,
|
603
|
-
expanded.gsub!(/[^\/]+\/\.\.(\/|$)/,
|
604
|
-
expanded.empty? ?
|
602
|
+
expanded = aPath.start_with?('/') ? aPath : ::File.join(@pwd, aPath)
|
603
|
+
expanded.gsub!(/\/\.(\/|$)/, '')
|
604
|
+
expanded.gsub!(/[^\/]+\/\.\.(\/|$)/, '')
|
605
|
+
expanded.empty? ? '/' : expanded
|
605
606
|
end
|
606
607
|
|
607
608
|
private
|
data/lib/zip/inflater.rb
CHANGED
@@ -1,15 +1,16 @@
|
|
1
1
|
module Zip
|
2
2
|
class Inflater < Decompressor #:nodoc:all
|
3
|
-
def initialize(input_stream)
|
4
|
-
super
|
3
|
+
def initialize(input_stream, decrypter = NullDecrypter.new)
|
4
|
+
super(input_stream)
|
5
5
|
@zlib_inflater = ::Zlib::Inflate.new(-Zlib::MAX_WBITS)
|
6
6
|
@output_buffer = ''
|
7
7
|
@has_returned_empty_string = false
|
8
|
+
@decrypter = decrypter
|
8
9
|
end
|
9
10
|
|
10
|
-
def sysread(number_of_bytes = nil, buf =
|
11
|
+
def sysread(number_of_bytes = nil, buf = '')
|
11
12
|
readEverything = number_of_bytes.nil?
|
12
|
-
while
|
13
|
+
while readEverything || @output_buffer.bytesize < number_of_bytes
|
13
14
|
break if internal_input_finished?
|
14
15
|
@output_buffer << internal_produce_input(buf)
|
15
16
|
end
|
@@ -19,7 +20,7 @@ module Zip
|
|
19
20
|
end
|
20
21
|
|
21
22
|
def produce_input
|
22
|
-
if
|
23
|
+
if @output_buffer.empty?
|
23
24
|
internal_produce_input
|
24
25
|
else
|
25
26
|
@output_buffer.slice!(0...(@output_buffer.length))
|
@@ -32,15 +33,15 @@ module Zip
|
|
32
33
|
@output_buffer.empty? && internal_input_finished?
|
33
34
|
end
|
34
35
|
|
35
|
-
alias :eof
|
36
|
-
alias :eof?
|
36
|
+
alias :eof input_finished?
|
37
|
+
alias :eof? input_finished?
|
37
38
|
|
38
39
|
private
|
39
40
|
|
40
|
-
def internal_produce_input(buf =
|
41
|
+
def internal_produce_input(buf = '')
|
41
42
|
retried = 0
|
42
43
|
begin
|
43
|
-
@zlib_inflater.inflate(@input_stream.read(Decompressor::CHUNK_SIZE, buf))
|
44
|
+
@zlib_inflater.inflate(@decrypter.decrypt(@input_stream.read(Decompressor::CHUNK_SIZE, buf)))
|
44
45
|
rescue Zlib::BufError
|
45
46
|
raise if retried >= 5 # how many times should we retry?
|
46
47
|
retried += 1
|