rubyzip 0.9.6.1 → 0.9.7

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.

data/README.md CHANGED
@@ -1,18 +1,49 @@
1
- rubyzip
1
+ rubyzip [![Build Status](https://secure.travis-ci.org/aussiegeek/rubyzip.png)](http://travis-ci.org/aussiegeek/rubyzip)
2
2
  =======
3
3
 
4
4
  rubyzip is a ruby library for reading and writing zip files.
5
5
 
6
- Install
7
- -------
6
+ Installation
7
+ ------------
8
+ rubyzip is available on RubyGems, so:
9
+
10
+ ```
11
+ gem install rubyzip
12
+ ```
13
+
14
+ Or in your Gemfile:
15
+
16
+ ```ruby
17
+ gem 'rubyzip'
18
+ ```
19
+
20
+ Developing
21
+ ----------
22
+
23
+ To run tests you need run next commands:
8
24
 
9
- gem install rubyzip
25
+ ```
26
+ bundle install
27
+ rake
28
+ ```
10
29
 
30
+ Configuration
31
+ -------------
32
+
33
+ By default, rubyzip will not overwrite files if they already exist inside of the extracted path. To change this behavior, you may specify a configuration option like so:
34
+
35
+ ```
36
+ Zip.options[:on_exists_proc] = true
37
+ ```
11
38
 
12
- To run the unit tests you need to have test::unit installed
39
+ If you're using rubyzip with rails, consider placing this snippet of code in an initializer file such as `config/initializers/rubyzip.rb`
40
+
41
+ Additionally, if you want to configure rubyzip to overwrite existing files while creating a .zip file, you can do so with the following:
42
+
43
+ ```
44
+ Zip.options[:continue_on_exists_proc] = true
45
+ ```
13
46
 
14
- rake test
15
- [![Build Status](https://secure.travis-ci.org/aussiegeek/rubyzip.png)](http://travis-ci.org/aussiegeek/rubyzip)
16
47
 
17
48
  Documentation
18
49
  -------------
@@ -62,10 +93,12 @@ http://rdoc.info/github/aussiegeek/rubyzip/master/frames
62
93
  Authors
63
94
  -------
64
95
 
96
+ Alexander Simonov ( alex at simonov.me)
97
+
65
98
  Alan Harper ( alan at aussiegeek.net)
66
99
 
67
100
  Thomas Sondergaard (thomas at sondergaard.cc)
68
101
 
69
102
  Technorama Ltd. (oss-ruby-zip at technorama.net)
70
103
 
71
- extra-field support contributed by Tatsuki Sugiura (sugi at nemui.org)
104
+ extra-field support contributed by Tatsuki Sugiura (sugi at nemui.org)
data/lib/zip/constants.rb CHANGED
@@ -1,5 +1,5 @@
1
1
  module Zip
2
- VERSION = '0.9.5'
2
+ VERSION = '0.9.7'
3
3
  RUBY_MINOR_VERSION = RUBY_VERSION.split(".")[1].to_i
4
4
  RUNNING_ON_WINDOWS = RbConfig::CONFIG['host_os'] =~ /mswin|mingw|cygwin/i
5
5
 
data/lib/zip/dos_time.rb CHANGED
@@ -1,43 +1,45 @@
1
- class DOSTime < Time #:nodoc:all
1
+ module Zip
2
+ class DOSTime < Time #:nodoc:all
2
3
 
3
- #MS-DOS File Date and Time format as used in Interrupt 21H Function 57H:
4
+ #MS-DOS File Date and Time format as used in Interrupt 21H Function 57H:
4
5
 
5
- # Register CX, the Time:
6
- # Bits 0-4 2 second increments (0-29)
7
- # Bits 5-10 minutes (0-59)
8
- # bits 11-15 hours (0-24)
6
+ # Register CX, the Time:
7
+ # Bits 0-4 2 second increments (0-29)
8
+ # Bits 5-10 minutes (0-59)
9
+ # bits 11-15 hours (0-24)
9
10
 
10
- # Register DX, the Date:
11
- # Bits 0-4 day (1-31)
12
- # bits 5-8 month (1-12)
13
- # bits 9-15 year (four digit year minus 1980)
11
+ # Register DX, the Date:
12
+ # Bits 0-4 day (1-31)
13
+ # bits 5-8 month (1-12)
14
+ # bits 9-15 year (four digit year minus 1980)
14
15
 
15
- def to_binary_dos_time
16
- (sec/2) +
17
- (min << 5) +
18
- (hour << 11)
19
- end
16
+ def to_binary_dos_time
17
+ (sec/2) +
18
+ (min << 5) +
19
+ (hour << 11)
20
+ end
20
21
 
21
- def to_binary_dos_date
22
- (day) +
23
- (month << 5) +
24
- ((year - 1980) << 9)
25
- end
22
+ def to_binary_dos_date
23
+ (day) +
24
+ (month << 5) +
25
+ ((year - 1980) << 9)
26
+ end
26
27
 
27
- # Dos time is only stored with two seconds accuracy
28
- def dos_equals(other)
29
- to_i/2 == other.to_i/2
30
- end
28
+ # Dos time is only stored with two seconds accuracy
29
+ def dos_equals(other)
30
+ to_i/2 == other.to_i/2
31
+ end
31
32
 
32
- def self.parse_binary_dos_format(binaryDosDate, binaryDosTime)
33
- second = 2 * ( 0b11111 & binaryDosTime)
34
- minute = ( 0b11111100000 & binaryDosTime) >> 5
35
- hour = (0b1111100000000000 & binaryDosTime) >> 11
36
- day = ( 0b11111 & binaryDosDate)
37
- month = ( 0b111100000 & binaryDosDate) >> 5
38
- year = ((0b1111111000000000 & binaryDosDate) >> 9) + 1980
39
- begin
40
- return self.local(year, month, day, hour, minute, second)
33
+ def self.parse_binary_dos_format(binaryDosDate, binaryDosTime)
34
+ second = 2 * ( 0b11111 & binaryDosTime)
35
+ minute = ( 0b11111100000 & binaryDosTime) >> 5
36
+ hour = (0b1111100000000000 & binaryDosTime) >> 11
37
+ day = ( 0b11111 & binaryDosDate)
38
+ month = ( 0b111100000 & binaryDosDate) >> 5
39
+ year = ((0b1111111000000000 & binaryDosDate) >> 9) + 1980
40
+ begin
41
+ return self.local(year, month, day, hour, minute, second)
42
+ end
41
43
  end
42
44
  end
43
45
  end
@@ -0,0 +1,10 @@
1
+ module Zip
2
+ class << self
3
+ def options
4
+ @options ||= {
5
+ :on_exists_proc => false,
6
+ :continue_on_exists_proc => false
7
+ }
8
+ end
9
+ end
10
+ end
data/lib/zip/zip.rb CHANGED
@@ -28,6 +28,8 @@ require 'zip/zip_streamable_stream'
28
28
  require 'zip/zip_streamable_directory'
29
29
  require 'zip/constants'
30
30
 
31
+ require 'zip/settings'
32
+
31
33
  if Tempfile.superclass == SimpleDelegator
32
34
  require 'zip/tempfile_bugfixed'
33
35
  Tempfile = BugFix::Tempfile
@@ -21,41 +21,45 @@ module Zip
21
21
 
22
22
  def write_to_stream(io) #:nodoc:
23
23
  offset = io.tell
24
- @entrySet.sort.each { |entry| entry.write_c_dir_entry(io) }
24
+ @entrySet.each { |entry| entry.write_c_dir_entry(io) }
25
25
  write_e_o_c_d(io, offset)
26
26
  end
27
27
 
28
28
  def write_e_o_c_d(io, offset) #:nodoc:
29
- io <<
30
- [END_OF_CENTRAL_DIRECTORY_SIGNATURE,
29
+ tmp = [
30
+ END_OF_CENTRAL_DIRECTORY_SIGNATURE,
31
31
  0 , # @numberOfThisDisk
32
32
  0 , # @numberOfDiskWithStartOfCDir
33
- @entrySet? @entrySet.size : 0 ,
34
- @entrySet? @entrySet.size : 0 ,
35
- cdir_size ,
33
+ @entrySet? @entrySet.size : 0 ,
34
+ @entrySet? @entrySet.size : 0 ,
35
+ cdir_size ,
36
36
  offset ,
37
- @comment ? @comment.length : 0 ].pack('VvvvvVVv')
38
- io << @comment
37
+ @comment ? @comment.length : 0
38
+ ]
39
+ io << tmp.pack('VvvvvVVv')
40
+ io << @comment
39
41
  end
40
42
 
41
43
  private :write_e_o_c_d
42
44
 
43
45
  def cdir_size #:nodoc:
44
46
  # does not include eocd
45
- @entrySet.inject(0) { |value, entry| entry.cdir_header_size + value }
47
+ @entrySet.inject(0) do |value, entry|
48
+ entry.cdir_header_size + value
49
+ end
46
50
  end
47
51
 
48
52
  private :cdir_size
49
53
 
50
54
  def read_e_o_c_d(io) #:nodoc:
51
55
  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)
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)
59
63
  @comment = buf.read(commentLength)
60
64
  raise ZipError, "Zip consistency problem while reading eocd structure" unless buf.size == 0
61
65
  end
@@ -67,9 +71,10 @@ module Zip
67
71
  raise ZipError, "Zip consistency problem while reading central directory entry"
68
72
  end
69
73
  @entrySet = ZipEntrySet.new
70
- @size.times {
71
- @entrySet << ZipEntry.read_c_dir_entry(io)
72
- }
74
+ @size.times do
75
+ tmp = ZipEntry.read_c_dir_entry(io)
76
+ @entrySet << tmp
77
+ end
73
78
  end
74
79
 
75
80
  def read_from_stream(io) #:nodoc:
@@ -94,18 +99,19 @@ module Zip
94
99
  rescue Errno::EFBIG # FreeBSD 4.5 may raise Errno::EFBIG
95
100
  raise if (retried)
96
101
  retried = true
97
-
98
102
  io.seek(0, IO::SEEK_SET)
99
103
  retry
100
104
  end
101
105
 
102
106
  sigIndex = buf.rindex([END_OF_CENTRAL_DIRECTORY_SIGNATURE].pack('V'))
103
107
  raise ZipError, "Zip end of central directory signature not found" unless sigIndex
104
- buf=buf.slice!((sigIndex+4)...(buf.size))
108
+ buf = buf.slice!((sigIndex + 4)...(buf.bytesize))
109
+
105
110
  def buf.read(count)
106
111
  slice!(0, count)
107
112
  end
108
- return buf
113
+
114
+ buf
109
115
  end
110
116
 
111
117
  # For iterating over the entries.
@@ -127,7 +133,7 @@ module Zip
127
133
  return nil
128
134
  end
129
135
 
130
- def == (other) #:nodoc:
136
+ def ==(other) #:nodoc:
131
137
  return false unless other.kind_of?(ZipCentralDirectory)
132
138
  @entrySet.entries.sort == other.entries.sort && comment == other.comment
133
139
  end
data/lib/zip/zip_entry.rb CHANGED
@@ -11,7 +11,7 @@ module Zip
11
11
  FSTYPE_ATARI = 5
12
12
  FSTYPE_HPFS = 6
13
13
  FSTYPE_MAC = 7
14
- FSTYPE_Z_SYSTEM = 8
14
+ FSTYPE_Z_SYSTEM = 8
15
15
  FSTYPE_CPM = 9
16
16
  FSTYPE_TOPS20 = 10
17
17
  FSTYPE_NTFS = 11
@@ -49,40 +49,19 @@ module Zip
49
49
  FSTYPE_ATHEOS => 'AtheOS'.freeze,
50
50
  }.freeze
51
51
 
52
- attr_accessor :comment, :compressed_size, :crc, :extra, :compression_method,
52
+ attr_accessor :comment, :compressed_size, :crc, :extra, :compression_method,
53
53
  :name, :size, :localHeaderOffset, :zipfile, :fstype, :externalFileAttributes, :gp_flags, :header_signature
54
54
 
55
55
  attr_accessor :follow_symlinks
56
56
  attr_accessor :restore_times, :restore_permissions, :restore_ownership
57
57
  attr_accessor :unix_uid, :unix_gid, :unix_perms
58
-
59
58
  attr_accessor :dirty
60
-
61
59
  attr_reader :ftype, :filepath # :nodoc:
62
60
 
63
- # Returns the character encoding used for name and comment
64
- def name_encoding
65
- (@gp_flags & 0b100000000000) != 0 ? "UTF-8" : "CP437//"
66
- end
67
-
68
- # Returns the name in the encoding specified by enc
69
- def name_in(enc)
70
- if RUBY_VERSION >= '1.9'
71
- @name.encode(enc)
72
- else
73
- Iconv.conv(enc, name_encoding, @name)
74
- end
75
- end
76
-
77
- # Returns the name in the encoding specified by enc
78
- def comment_in(enc)
79
- name_in(enc)
80
- end
81
-
82
- def initialize(zipfile = "", name = "", comment = "", extra = "",
61
+ def initialize(zipfile = "", name = "", comment = "", extra = "",
83
62
  compressed_size = 0, crc = 0,
84
- compression_method = ZipEntry::DEFLATED, size = 0,
85
- time = DOSTime.now)
63
+ compression_method = ZipEntry::DEFLATED, size = 0,
64
+ time = DOSTime.now)
86
65
  super()
87
66
  if name.start_with?("/")
88
67
  raise ZipEntryNameError, "Illegal ZipEntry name '#{name}', name must not start with /"
@@ -91,6 +70,8 @@ module Zip
91
70
  @local_header_size = 0
92
71
  @internalFileAttributes = 1
93
72
  @externalFileAttributes = 0
73
+ @header_signature = CENTRAL_DIRECTORY_ENTRY_SIGNATURE
74
+ @versionNeededToExtract = VERSION_NEEDED_TO_EXTRACT
94
75
  @version = 52 # this library's version
95
76
  @ftype = nil # unspecified or unknown
96
77
  @filepath = nil
@@ -108,7 +89,7 @@ module Zip
108
89
  @name = name
109
90
  @size = size
110
91
  @time = time
111
- @gp_flags = nil
92
+ @gp_flags = 0
112
93
 
113
94
  @follow_symlinks = false
114
95
 
@@ -187,7 +168,7 @@ module Zip
187
168
  end
188
169
 
189
170
  def cdir_header_size #:nodoc:all
190
- CDIR_ENTRY_STATIC_HEADER_LENGTH + (@name ? @name.bytesize : 0) +
171
+ CDIR_ENTRY_STATIC_HEADER_LENGTH + (@name ? @name.bytesize : 0) +
191
172
  (@extra ? @extra.c_dir_size : 0) + (@comment ? @comment.bytesize : 0)
192
173
  end
193
174
 
@@ -197,7 +178,7 @@ module Zip
197
178
 
198
179
  # Extracts entry to file destPath (defaults to @name).
199
180
  def extract(destPath = @name, &onExistsProc)
200
- onExistsProc ||= proc { false }
181
+ onExistsProc ||= proc { Zip.options[:on_exists_proc] }
201
182
 
202
183
  if directory?
203
184
  create_directory(destPath, &onExistsProc)
@@ -218,24 +199,44 @@ module Zip
218
199
 
219
200
  protected
220
201
 
221
- def ZipEntry.read_zip_short(io) # :nodoc:
222
- io.read(2).unpack('v')[0]
223
- end
202
+ class << self
203
+ def read_zip_short(io) # :nodoc:
204
+ io.read(2).unpack('v')[0]
205
+ end
206
+
207
+ def read_zip_long(io) # :nodoc:
208
+ io.read(4).unpack('V')[0]
209
+ end
210
+
211
+ def read_c_dir_entry(io) #:nodoc:all
212
+ entry = new(io.path)
213
+ entry.read_c_dir_entry(io)
214
+ entry
215
+ rescue ZipError
216
+ nil
217
+ end
218
+
219
+ def read_local_entry(io)
220
+ entry = new(io.path)
221
+ entry.read_local_entry(io)
222
+ entry
223
+ rescue ZipError
224
+ nil
225
+ end
224
226
 
225
- def ZipEntry.read_zip_long(io) # :nodoc:
226
- io.read(4).unpack('V')[0]
227
227
  end
228
+
228
229
  public
229
230
 
230
231
  LOCAL_ENTRY_SIGNATURE = 0x04034b50
231
232
  LOCAL_ENTRY_STATIC_HEADER_LENGTH = 30
232
233
  LOCAL_ENTRY_TRAILING_DESCRIPTOR_LENGTH = 4+4+4
233
- VERSION_NEEDED_TO_EXTRACT = 10
234
+ VERSION_NEEDED_TO_EXTRACT = 20
234
235
 
235
236
  def read_local_entry(io) #:nodoc:all
236
237
  @localHeaderOffset = io.tell
237
238
  staticSizedFieldsBuf = io.read(LOCAL_ENTRY_STATIC_HEADER_LENGTH)
238
- unless (staticSizedFieldsBuf.size==LOCAL_ENTRY_STATIC_HEADER_LENGTH)
239
+ unless (staticSizedFieldsBuf.size == LOCAL_ENTRY_STATIC_HEADER_LENGTH)
239
240
  raise ZipError, "Premature end of file. Not enough data for zip entry local header"
240
241
  end
241
242
 
@@ -272,21 +273,15 @@ module Zip
272
273
  @local_header_size = calculate_local_header_size
273
274
  end
274
275
 
275
- def ZipEntry.read_local_entry(io)
276
- entry = new(io.path)
277
- entry.read_local_entry(io)
278
- return entry
279
- rescue ZipError
280
- return nil
281
- end
276
+
282
277
 
283
278
  def write_local_entry(io) #:nodoc:all
284
279
  @localHeaderOffset = io.tell
285
280
 
286
- io <<
281
+ io <<
287
282
  [LOCAL_ENTRY_SIGNATURE ,
288
- VERSION_NEEDED_TO_EXTRACT , # version needed to extract
289
- 0 , # @gp_flags ,
283
+ @versionNeededToExtract , # version needed to extract
284
+ @gp_flags , # @gp_flags ,
290
285
  @compression_method ,
291
286
  @time.to_binary_dos_time , # @lastModTime ,
292
287
  @time.to_binary_dos_date , # @lastModDate ,
@@ -304,30 +299,31 @@ module Zip
304
299
 
305
300
  def read_c_dir_entry(io) #:nodoc:all
306
301
  staticSizedFieldsBuf = io.read(CDIR_ENTRY_STATIC_HEADER_LENGTH)
307
- unless (staticSizedFieldsBuf.size == CDIR_ENTRY_STATIC_HEADER_LENGTH)
302
+ unless (staticSizedFieldsBuf.bytesize == CDIR_ENTRY_STATIC_HEADER_LENGTH)
308
303
  raise ZipError, "Premature end of file. Not enough data for zip cdir entry header"
309
304
  end
310
305
 
311
- @header_signature ,
312
- @version , # version of encoding software
313
- @fstype , # filesystem type
314
- @versionNeededToExtract,
315
- @gp_flags ,
316
- @compression_method ,
317
- lastModTime ,
318
- lastModDate ,
319
- @crc ,
320
- @compressed_size ,
321
- @size ,
322
- nameLength ,
323
- extraLength ,
324
- commentLength ,
325
- diskNumberStart ,
326
- @internalFileAttributes,
327
- @externalFileAttributes,
328
- @localHeaderOffset ,
329
- @name ,
330
- @extra ,
306
+
307
+ @header_signature ,
308
+ @version , # version of encoding software
309
+ @fstype , # filesystem type
310
+ @versionNeededToExtract ,
311
+ @gp_flags ,
312
+ @compression_method ,
313
+ lastModTime ,
314
+ lastModDate ,
315
+ @crc ,
316
+ @compressed_size ,
317
+ @size ,
318
+ nameLength ,
319
+ extraLength ,
320
+ commentLength ,
321
+ diskNumberStart ,
322
+ @internalFileAttributes ,
323
+ @externalFileAttributes ,
324
+ @localHeaderOffset ,
325
+ @name ,
326
+ @extra ,
331
327
  @comment = staticSizedFieldsBuf.unpack('VCCvvvvvVVVvvvvvVV')
332
328
 
333
329
  unless (@header_signature == CENTRAL_DIRECTORY_ENTRY_SIGNATURE)
@@ -335,13 +331,13 @@ module Zip
335
331
  end
336
332
  set_time(lastModDate, lastModTime)
337
333
 
338
- @name = io.read(nameLength)
334
+ @name = io.read(nameLength)
339
335
  if ZipExtraField === @extra
340
336
  @extra.merge(io.read(extraLength))
341
337
  else
342
338
  @extra = ZipExtraField.new(io.read(extraLength))
343
339
  end
344
- @comment = io.read(commentLength)
340
+ @comment = io.read(commentLength)
345
341
  unless (@comment && @comment.bytesize == commentLength)
346
342
  raise ZipError, "Truncated cdir zip entry header"
347
343
  end
@@ -358,7 +354,13 @@ module Zip
358
354
  when 012
359
355
  @ftype = :symlink
360
356
  else
361
- @ftype = :unknown
357
+ #best case guess for whether it is a file or not
358
+ #Otherwise this would be set to unknown and that entry would never be able to extracted
359
+ if name_is_directory?
360
+ @ftype = :directory
361
+ else
362
+ @ftype = :file
363
+ end
362
364
  end
363
365
  else
364
366
  if name_is_directory?
@@ -370,13 +372,7 @@ module Zip
370
372
  @local_header_size = calculate_local_header_size
371
373
  end
372
374
 
373
- def ZipEntry.read_c_dir_entry(io) #:nodoc:all
374
- entry = new(io.path)
375
- entry.read_c_dir_entry(io)
376
- return entry
377
- rescue ZipError
378
- return nil
379
- end
375
+
380
376
 
381
377
  def file_stat(path) # :nodoc:
382
378
  if @follow_symlinks
@@ -431,28 +427,31 @@ module Zip
431
427
  end
432
428
  end
433
429
 
434
- io <<
435
- [CENTRAL_DIRECTORY_ENTRY_SIGNATURE,
436
- @version , # version of encoding software
437
- @fstype , # filesystem type
438
- VERSION_NEEDED_TO_EXTRACT , # @versionNeededToExtract ,
439
- 0 , # @gp_flags ,
440
- @compression_method ,
441
- @time.to_binary_dos_time , # @lastModTime ,
442
- @time.to_binary_dos_date , # @lastModDate ,
443
- @crc ,
444
- @compressed_size ,
445
- @size ,
446
- @name ? @name.bytesize : 0 ,
447
- @extra ? @extra.c_dir_length : 0 ,
448
- @comment ? @comment.bytesize : 0 ,
449
- 0 , # disk number start
450
- @internalFileAttributes , # file type (binary=0, text=1)
451
- @externalFileAttributes , # native filesystem attributes
452
- @localHeaderOffset ,
453
- @name ,
454
- @extra ,
455
- @comment ].pack('VCCvvvvvVVVvvvvvVV')
430
+ tmp = [
431
+ @header_signature,
432
+ @version , # version of encoding software
433
+ @fstype , # filesystem type
434
+ @versionNeededToExtract , # @versionNeededToExtract ,
435
+ @gp_flags , # @gp_flags ,
436
+ @compression_method ,
437
+ @time.to_binary_dos_time , # @lastModTime ,
438
+ @time.to_binary_dos_date , # @lastModDate ,
439
+ @crc ,
440
+ @compressed_size ,
441
+ @size ,
442
+ @name ? @name.bytesize : 0 ,
443
+ @extra ? @extra.c_dir_length : 0 ,
444
+ @comment ? @comment.bytesize : 0 ,
445
+ 0 , # disk number start
446
+ @internalFileAttributes , # file type (binary=0, text=1)
447
+ @externalFileAttributes , # native filesystem attributes
448
+ @localHeaderOffset ,
449
+ @name ,
450
+ @extra ,
451
+ @comment
452
+ ]
453
+
454
+ io << tmp.pack('VCCvvvvvVVVvvvvvVV')
456
455
 
457
456
  io << @name
458
457
  io << (@extra ? @extra.to_c_dir_bin : "")
@@ -544,7 +543,7 @@ module Zip
544
543
  aZipOutputStream.put_next_entry(self)
545
544
  elsif @filepath
546
545
  aZipOutputStream.put_next_entry(self)
547
- get_input_stream { |is| IOExtras.copy_stream(aZipOutputStream, is) }
546
+ get_input_stream { |is| IOExtras.copy_stream(aZipOutputStream, is) }
548
547
  else
549
548
  aZipOutputStream.copy_raw_entry(self)
550
549
  end
@@ -568,7 +567,7 @@ module Zip
568
567
  puts "Invalid date/time in zip entry"
569
568
  end
570
569
 
571
- def write_file(destPath, continueOnExistsProc = proc { false })
570
+ def write_file(destPath, continueOnExistsProc = proc { Zip.options[:continue_on_exists_proc] })
572
571
  if ::File.exists?(destPath) && ! yield(self, destPath)
573
572
  raise ZipDestinationFileExistsError,
574
573
  "Destination '#{destPath}' already exists"
@@ -635,4 +634,4 @@ end
635
634
 
636
635
  # Copyright (C) 2002, 2003 Thomas Sondergaard
637
636
  # rubyzip is free software; you can redistribute it and/or
638
- # modify it under the terms of the ruby license.
637
+ # modify it under the terms of the ruby license.
@@ -9,11 +9,15 @@ module Zip
9
9
  end
10
10
 
11
11
  def include?(entry)
12
- @entrySet.include?(entry.to_s)
12
+ @entrySet.include?(to_key(entry))
13
+ end
14
+
15
+ def find_entry(entry)
16
+ @entrySet[to_key(entry)]
13
17
  end
14
18
 
15
19
  def <<(entry)
16
- @entrySet[entry.to_s] = entry
20
+ @entrySet[to_key(entry)] = entry
17
21
  end
18
22
  alias :push :<<
19
23
 
@@ -24,7 +28,7 @@ module Zip
24
28
  alias :length :size
25
29
 
26
30
  def delete(entry)
27
- @entrySet.delete(entry.to_s) ? entry : nil
31
+ @entrySet.delete(to_key(entry)) ? entry : nil
28
32
  end
29
33
 
30
34
  def each(&aProc)
@@ -46,7 +50,7 @@ module Zip
46
50
  end
47
51
 
48
52
  def parent(entry)
49
- @entrySet[entry.parent_as_string]
53
+ @entrySet[to_key(entry.parent_as_string)]
50
54
  end
51
55
 
52
56
  def glob(pattern, flags = ::File::FNM_PATHNAME|::File::FNM_DOTMATCH)
@@ -58,6 +62,11 @@ module Zip
58
62
  #TODO attr_accessor :auto_create_directories
59
63
  protected
60
64
  attr_accessor :entrySet
65
+
66
+ private
67
+ def to_key(entry)
68
+ entry.to_s.sub(/\/$/, "")
69
+ end
61
70
  end
62
71
  end
63
72
 
@@ -27,21 +27,21 @@ module Zip
27
27
  end
28
28
 
29
29
  def ==(other)
30
- self.class != other.class and return false
31
- each { |k, v|
30
+ return false if self.class != other.class
31
+ each do |k, v|
32
32
  v != other[k] and return false
33
- }
33
+ end
34
34
  true
35
35
  end
36
36
 
37
37
  def to_local_bin
38
38
  s = pack_for_local
39
- self.class.const_get(:HEADER_ID) + [s.length].pack("v") + s
39
+ self.class.const_get(:HEADER_ID) + [s.bytesize].pack("v") + s
40
40
  end
41
41
 
42
42
  def to_c_dir_bin
43
43
  s = pack_for_c_dir
44
- self.class.const_get(:HEADER_ID) + [s.length].pack("v") + s
44
+ self.class.const_get(:HEADER_ID) + [s.bytesize].pack("v") + s
45
45
  end
46
46
  end
47
47
 
@@ -60,7 +60,7 @@ module Zip
60
60
  attr_accessor :atime, :ctime, :mtime, :flag
61
61
 
62
62
  def merge(binstr)
63
- binstr == "" and return
63
+ return if binstr.empty?
64
64
  size, content = initial_parse(binstr)
65
65
  size or return
66
66
  @flag, mtime, atime, ctime = content.unpack("CVVV")
@@ -103,10 +103,10 @@ module Zip
103
103
  attr_accessor :uid, :gid
104
104
 
105
105
  def merge(binstr)
106
- binstr == "" and return
106
+ return if binstr.empty?
107
107
  size, content = initial_parse(binstr)
108
- # size: 0 for central direcotry. 4 for local header
109
- return if(! size || size == 0)
108
+ # size: 0 for central directory. 4 for local header
109
+ return if(!size || size == 0)
110
110
  uid, gid = content.unpack("vv")
111
111
  @uid ||= uid
112
112
  @gid ||= gid
@@ -132,17 +132,17 @@ module Zip
132
132
  end
133
133
 
134
134
  def merge(binstr)
135
- binstr == "" and return
135
+ return if binstr.empty?
136
136
  i = 0
137
- while i < binstr.length
137
+ while i < binstr.bytesize
138
138
  id = binstr[i,2]
139
- len = binstr[i+2,2].to_s.unpack("v")[0]
139
+ len = binstr[i + 2,2].to_s.unpack("v")[0]
140
140
  if id && ID_MAP.member?(id)
141
141
  field_name = ID_MAP[id].name
142
142
  if self.member?(field_name)
143
- self[field_name].mergea(binstr[i, len+4])
143
+ self[field_name].mergea(binstr[i, len + 4])
144
144
  else
145
- field_obj = ID_MAP[id].new(binstr[i, len+4])
145
+ field_obj = ID_MAP[id].new(binstr[i, len + 4])
146
146
  self[field_name] = field_obj
147
147
  end
148
148
  elsif id
@@ -154,13 +154,13 @@ module Zip
154
154
  end
155
155
  self["Unknown"] = s
156
156
  end
157
- if ! len || len+4 > binstr[i..-1].length
157
+ if !len || len + 4 > binstr[i..-1].bytesize
158
158
  self["Unknown"] << binstr[i..-1]
159
- break;
159
+ break
160
160
  end
161
- self["Unknown"] << binstr[i, len+4]
161
+ self["Unknown"] << binstr[i, len + 4]
162
162
  end
163
- i += len+4
163
+ i += len + 4
164
164
  end
165
165
  end
166
166
 
@@ -180,26 +180,26 @@ module Zip
180
180
 
181
181
  def to_local_bin
182
182
  s = ""
183
- each { |k, v|
183
+ each do |k, v|
184
184
  s << v.to_local_bin
185
- }
185
+ end
186
186
  s
187
187
  end
188
188
  alias :to_s :to_local_bin
189
189
 
190
190
  def to_c_dir_bin
191
191
  s = ""
192
- each { |k, v|
192
+ each do |k, v|
193
193
  s << v.to_c_dir_bin
194
- }
194
+ end
195
195
  s
196
196
  end
197
197
 
198
198
  def c_dir_length
199
- to_c_dir_bin.length
199
+ to_c_dir_bin.bytesize
200
200
  end
201
201
  def local_length
202
- to_local_bin.length
202
+ to_local_bin.bytesize
203
203
  end
204
204
  alias :c_dir_size :c_dir_length
205
205
  alias :local_size :local_length
data/lib/zip/zip_file.rb CHANGED
@@ -61,63 +61,64 @@ module Zip
61
61
  super()
62
62
  @name = fileName
63
63
  @comment = ""
64
- if (::File.exists?(fileName)) and !buffer
65
- ::File.open(name, "rb") { |f| read_from_stream(f) }
66
- elsif (create)
67
- @entrySet = ZipEntrySet.new
68
- else
69
- raise ZipError, "File #{fileName} not found"
64
+ case
65
+ when ::File.exists?(fileName) && !buffer
66
+ ::File.open(name, "rb") do |f|
67
+ read_from_stream(f)
68
+ end
69
+ when create
70
+ @entrySet = ZipEntrySet.new
71
+ else
72
+ raise ZipError, "File #{fileName} not found"
70
73
  end
71
74
  @create = create
72
75
  @storedEntries = @entrySet.dup
73
-
76
+ @storedComment = @comment
74
77
  @restore_ownership = false
75
78
  @restore_permissions = false
76
79
  @restore_times = true
77
80
  end
78
81
 
79
- # Same as #new. If a block is passed the ZipFile object is passed
80
- # to the block and is automatically closed afterwards just as with
81
- # ruby's builtin File.open method.
82
- def ZipFile.open(fileName, create = nil)
83
- zf = ZipFile.new(fileName, create)
84
- if block_given?
85
- begin
86
- yield zf
87
- ensure
88
- zf.close
82
+ class << self
83
+ # Same as #new. If a block is passed the ZipFile object is passed
84
+ # to the block and is automatically closed afterwards just as with
85
+ # ruby's builtin File.open method.
86
+ def open(fileName, create = nil)
87
+ zf = ZipFile.new(fileName, create)
88
+ if block_given?
89
+ begin
90
+ yield zf
91
+ ensure
92
+ zf.close
93
+ end
94
+ else
95
+ zf
89
96
  end
90
- else
91
- zf
92
97
  end
93
- end
94
98
 
95
- # Same as #open. But outputs data to a buffer instead of a file
96
- def ZipFile.add_buffer
97
- zf = ZipFile.new('', true, true)
98
- begin
99
+ # Same as #open. But outputs data to a buffer instead of a file
100
+ def add_buffer
101
+ zf = ZipFile.new('', true, true)
99
102
  yield zf
100
- ensure
101
- buffer = zf.write_buffer
102
- return buffer
103
+ zf.write_buffer
104
+ end
105
+
106
+ # Iterates over the contents of the ZipFile. This is more efficient
107
+ # than using a ZipInputStream since this methods simply iterates
108
+ # through the entries in the central directory structure in the archive
109
+ # whereas ZipInputStream jumps through the entire archive accessing the
110
+ # local entry headers (which contain the same information as the
111
+ # central directory).
112
+ def foreach(aZipFileName, &block)
113
+ open(aZipFileName) do |zipFile|
114
+ zipFile.each(&block)
115
+ end
103
116
  end
104
117
  end
105
118
 
106
119
  # Returns the zip files comment, if it has one
107
120
  attr_accessor :comment
108
121
 
109
- # Iterates over the contents of the ZipFile. This is more efficient
110
- # than using a ZipInputStream since this methods simply iterates
111
- # through the entries in the central directory structure in the archive
112
- # whereas ZipInputStream jumps through the entire archive accessing the
113
- # local entry headers (which contain the same information as the
114
- # central directory).
115
- def ZipFile.foreach(aZipFileName, &block)
116
- ZipFile.open(aZipFileName) do |zipFile|
117
- zipFile.each(&block)
118
- end
119
- end
120
-
121
122
  # Returns an input stream to the specified entry. If a block is passed
122
123
  # the stream object is passed to the block and the stream is automatically
123
124
  # closed afterwards just as with ruby's builtin File.open method.
@@ -152,7 +153,7 @@ module Zip
152
153
 
153
154
  # Convenience method for adding the contents of a file to the archive
154
155
  def add(entry, srcPath, &continueOnExistsProc)
155
- continueOnExistsProc ||= proc { false }
156
+ continueOnExistsProc ||= proc { Zip.options[:continue_on_exists_proc] }
156
157
  check_entry_exists(entry, continueOnExistsProc, "add")
157
158
  newEntry = entry.kind_of?(ZipEntry) ? entry : ZipEntry.new(@name, entry.to_s)
158
159
  newEntry.gather_fileinfo_from_srcpath(srcPath)
@@ -183,7 +184,7 @@ module Zip
183
184
 
184
185
  # Extracts entry to file destPath.
185
186
  def extract(entry, destPath, &onExistsProc)
186
- onExistsProc ||= proc { false }
187
+ onExistsProc ||= proc { Zip.options[:on_exists_proc] }
187
188
  foundEntry = get_entry(entry)
188
189
  foundEntry.extract(destPath, &onExistsProc)
189
190
  end
@@ -191,7 +192,7 @@ module Zip
191
192
  # Commits changes that has been made since the previous commit to
192
193
  # the zip archive.
193
194
  def commit
194
- return if ! commit_required?
195
+ return if !commit_required?
195
196
  on_success_replace(name) {
196
197
  |tmpFile|
197
198
  ZipOutputStream.open(tmpFile) {
@@ -229,16 +230,13 @@ module Zip
229
230
  @entrySet.each do |e|
230
231
  return true if e.dirty
231
232
  end
232
- return @entrySet != @storedEntries || @create == ZipFile::CREATE
233
+ @comment != @storedComment || @entrySet != @storedEntries || @create == ZipFile::CREATE
233
234
  end
234
235
 
235
236
  # Searches for entry with the specified name. Returns nil if
236
237
  # no entry is found. See also get_entry
237
- def find_entry(entry)
238
- @entrySet.detect {
239
- |e|
240
- e.name.sub(/\/$/, "") == entry.to_s.sub(/\/$/, "")
241
- }
238
+ def find_entry(entry_name)
239
+ @entrySet.find_entry(entry_name)
242
240
  end
243
241
 
244
242
  # Searches for an entry just as find_entry, but throws Errno::ENOENT
@@ -259,7 +257,7 @@ module Zip
259
257
  if find_entry(entryName)
260
258
  raise Errno::EEXIST, "File exists - #{entryName}"
261
259
  end
262
- entryName = entryName.to_s
260
+ entryName = entryName.dup.to_s
263
261
  entryName << '/' unless entryName.end_with?('/')
264
262
  @entrySet << ZipStreamableDirectory.new(@name, entryName, nil, permissionInt)
265
263
  end
@@ -279,8 +277,8 @@ module Zip
279
277
  end
280
278
 
281
279
  def check_entry_exists(entryName, continueOnExistsProc, procedureName)
282
- continueOnExistsProc ||= proc { false }
283
- if @entrySet.detect { |e| e.name == entryName }
280
+ continueOnExistsProc ||= proc { Zip.options[:continue_on_exists_proc] }
281
+ if @entrySet.include?(entryName)
284
282
  if continueOnExistsProc.call
285
283
  remove get_entry(entryName)
286
284
  else
@@ -74,20 +74,23 @@ module Zip
74
74
  update_local_headers
75
75
  write_central_directory
76
76
  @closed = true
77
- return @outputStream
77
+ @outputStream
78
78
  end
79
79
 
80
80
  # Closes the current entry and opens a new for writing.
81
81
  # +entry+ can be a ZipEntry object or a string.
82
82
  def put_next_entry(entryname, comment = nil, extra = nil, compression_method = ZipEntry::DEFLATED, level = Zlib::DEFAULT_COMPRESSION)
83
83
  raise ZipError, "zip stream is closed" if @closed
84
- new_entry = ZipEntry.new(@fileName, entryname.to_s)
85
- new_entry.unix_perms = entryname.unix_perms if entryname.respond_to? :unix_perms
84
+ if entryname.kind_of?(ZipEntry)
85
+ new_entry = entryname
86
+ else
87
+ new_entry = ZipEntry.new(@fileName, entryname.to_s)
88
+ end
86
89
  new_entry.comment = comment if !comment.nil?
87
90
  if (!extra.nil?)
88
91
  new_entry.extra = ZipExtraField === extra ? extra : ZipExtraField.new(extra.to_s)
89
92
  end
90
- new_entry.compression_method = compression_method
93
+ new_entry.compression_method = compression_method if !compression_method.nil?
91
94
  init_next_entry(new_entry, level)
92
95
  @currentEntry = new_entry
93
96
  end
@@ -110,11 +113,11 @@ module Zip
110
113
  end
111
114
 
112
115
  private
116
+
113
117
  def finalize_current_entry
114
118
  return unless @currentEntry
115
119
  finish
116
- @currentEntry.compressed_size = @outputStream.tell - @currentEntry.localHeaderOffset -
117
- @currentEntry.calculate_local_header_size
120
+ @currentEntry.compressed_size = @outputStream.tell - @currentEntry.localHeaderOffset - @currentEntry.calculate_local_header_size
118
121
  @currentEntry.size = @compressor.size
119
122
  @currentEntry.crc = @compressor.crc
120
123
  @currentEntry = nil
@@ -138,12 +141,11 @@ module Zip
138
141
  end
139
142
 
140
143
  def update_local_headers
141
- pos = @outputStream.tell
142
- @entrySet.each {
143
- |entry|
144
+ pos = @outputStream.pos
145
+ @entrySet.each do |entry|
144
146
  @outputStream.pos = entry.localHeaderOffset
145
147
  entry.write_local_entry(@outputStream)
146
- }
148
+ end
147
149
  @outputStream.pos = pos
148
150
  end
149
151
 
metadata CHANGED
@@ -1,22 +1,27 @@
1
- --- !ruby/object:Gem::Specification
1
+ --- !ruby/object:Gem::Specification
2
2
  name: rubyzip
3
- version: !ruby/object:Gem::Version
4
- version: 0.9.6.1
3
+ version: !ruby/object:Gem::Version
5
4
  prerelease:
5
+ version: 0.9.7
6
6
  platform: ruby
7
- authors:
7
+ authors:
8
8
  - Alan Harper
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2012-02-08 00:00:00.000000000Z
12
+
13
+ date: 2012-04-07 00:00:00 Z
13
14
  dependencies: []
15
+
14
16
  description:
15
17
  email: alan@aussiegeek.net
16
18
  executables: []
19
+
17
20
  extensions: []
21
+
18
22
  extra_rdoc_files: []
19
- files:
23
+
24
+ files:
20
25
  - samples/example.rb
21
26
  - samples/example_filesystem.rb
22
27
  - samples/example_recursive.rb
@@ -36,6 +41,7 @@ files:
36
41
  - lib/zip/null_input_stream.rb
37
42
  - lib/zip/pass_thru_compressor.rb
38
43
  - lib/zip/pass_thru_decompressor.rb
44
+ - lib/zip/settings.rb
39
45
  - lib/zip/tempfile_bugfixed.rb
40
46
  - lib/zip/zip.rb
41
47
  - lib/zip/zip_central_directory.rb
@@ -54,27 +60,31 @@ files:
54
60
  - Rakefile
55
61
  homepage: http://github.com/aussiegeek/rubyzip
56
62
  licenses: []
63
+
57
64
  post_install_message:
58
65
  rdoc_options: []
59
- require_paths:
66
+
67
+ require_paths:
60
68
  - lib
61
- required_ruby_version: !ruby/object:Gem::Requirement
69
+ required_ruby_version: !ruby/object:Gem::Requirement
62
70
  none: false
63
- requirements:
64
- - - ! '>='
65
- - !ruby/object:Gem::Version
71
+ requirements:
72
+ - - ">="
73
+ - !ruby/object:Gem::Version
66
74
  version: 1.8.7
67
- required_rubygems_version: !ruby/object:Gem::Requirement
75
+ required_rubygems_version: !ruby/object:Gem::Requirement
68
76
  none: false
69
- requirements:
70
- - - ! '>='
71
- - !ruby/object:Gem::Version
72
- version: '0'
77
+ requirements:
78
+ - - ">="
79
+ - !ruby/object:Gem::Version
80
+ version: "0"
73
81
  requirements: []
82
+
74
83
  rubyforge_project:
75
- rubygems_version: 1.8.10
84
+ rubygems_version: 1.8.19
76
85
  signing_key:
77
86
  specification_version: 3
78
87
  summary: rubyzip is a ruby module for reading and writing zip files
79
88
  test_files: []
89
+
80
90
  has_rdoc: