archive-zip 0.11.0 → 0.13.0.pre1
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.
- checksums.yaml +5 -5
- data/LICENSE +1 -1
- data/NEWS.md +12 -0
- data/README.md +2 -1
- data/lib/archive/support/ioextensions.rb +5 -7
- data/lib/archive/support/iowindow.rb +34 -87
- data/lib/archive/support/stringio.rb +27 -0
- data/lib/archive/support/zlib.rb +0 -435
- data/lib/archive/zip/codec/deflate/reader.rb +187 -0
- data/lib/archive/zip/codec/deflate/writer.rb +209 -0
- data/lib/archive/zip/codec/deflate.rb +92 -244
- data/lib/archive/zip/codec/null_encryption.rb +4 -184
- data/lib/archive/zip/codec/store/reader.rb +97 -0
- data/lib/archive/zip/codec/store/writer.rb +78 -0
- data/lib/archive/zip/codec/store.rb +6 -231
- data/lib/archive/zip/codec/traditional_encryption/base.rb +85 -0
- data/lib/archive/zip/codec/traditional_encryption/reader.rb +65 -0
- data/lib/archive/zip/codec/traditional_encryption/writer.rb +71 -0
- data/lib/archive/zip/codec/traditional_encryption.rb +6 -360
- data/lib/archive/zip/codec.rb +2 -2
- data/lib/archive/zip/dos_time.rb +103 -0
- data/lib/archive/zip/entry.rb +86 -70
- data/lib/archive/zip.rb +2 -5
- metadata +37 -227
- data/.yardopts +0 -1
- data/Rakefile +0 -247
- data/lib/archive/support/binary_stringio.rb +0 -30
- data/lib/archive/support/integer.rb +0 -13
- data/lib/archive/support/io-like.rb +0 -14
- data/lib/archive/support/time.rb +0 -119
- data/lib/archive/zip/version.rb +0 -6
- data/spec/archive/dos_time_spec.rb +0 -113
- data/spec/archive/zip/archive_spec.rb +0 -54
- data/spec/archive/zip/codec/deflate/compress/checksum_spec.rb +0 -44
- data/spec/archive/zip/codec/deflate/compress/close_spec.rb +0 -45
- data/spec/archive/zip/codec/deflate/compress/crc32_spec.rb +0 -23
- data/spec/archive/zip/codec/deflate/compress/data_descriptor_spec.rb +0 -74
- data/spec/archive/zip/codec/deflate/compress/new_spec.rb +0 -39
- data/spec/archive/zip/codec/deflate/compress/open_spec.rb +0 -48
- data/spec/archive/zip/codec/deflate/compress/write_spec.rb +0 -111
- data/spec/archive/zip/codec/deflate/decompress/checksum_spec.rb +0 -20
- data/spec/archive/zip/codec/deflate/decompress/close_spec.rb +0 -34
- data/spec/archive/zip/codec/deflate/decompress/crc32_spec.rb +0 -20
- data/spec/archive/zip/codec/deflate/decompress/data_descriptor_spec.rb +0 -74
- data/spec/archive/zip/codec/deflate/decompress/new_spec.rb +0 -16
- data/spec/archive/zip/codec/deflate/decompress/open_spec.rb +0 -29
- data/spec/archive/zip/codec/deflate/fixtures/classes.rb +0 -25
- data/spec/archive/zip/codec/deflate/fixtures/compressed_file.bin +0 -1
- data/spec/archive/zip/codec/deflate/fixtures/compressed_file_nocomp.bin +0 -0
- data/spec/archive/zip/codec/deflate/fixtures/raw_file.txt +0 -10
- data/spec/archive/zip/codec/null_encryption/decrypt/close_spec.rb +0 -34
- data/spec/archive/zip/codec/null_encryption/decrypt/new_spec.rb +0 -16
- data/spec/archive/zip/codec/null_encryption/decrypt/open_spec.rb +0 -29
- data/spec/archive/zip/codec/null_encryption/decrypt/read_spec.rb +0 -26
- data/spec/archive/zip/codec/null_encryption/decrypt/rewind_spec.rb +0 -27
- data/spec/archive/zip/codec/null_encryption/decrypt/seek_spec.rb +0 -59
- data/spec/archive/zip/codec/null_encryption/decrypt/tell_spec.rb +0 -23
- data/spec/archive/zip/codec/null_encryption/encrypt/close_spec.rb +0 -34
- data/spec/archive/zip/codec/null_encryption/encrypt/new_spec.rb +0 -16
- data/spec/archive/zip/codec/null_encryption/encrypt/open_spec.rb +0 -31
- data/spec/archive/zip/codec/null_encryption/encrypt/rewind_spec.rb +0 -28
- data/spec/archive/zip/codec/null_encryption/encrypt/seek_spec.rb +0 -52
- data/spec/archive/zip/codec/null_encryption/encrypt/tell_spec.rb +0 -31
- data/spec/archive/zip/codec/null_encryption/encrypt/write_spec.rb +0 -31
- data/spec/archive/zip/codec/null_encryption/fixtures/classes.rb +0 -12
- data/spec/archive/zip/codec/null_encryption/fixtures/raw_file.txt +0 -10
- data/spec/archive/zip/codec/store/compress/close_spec.rb +0 -34
- data/spec/archive/zip/codec/store/compress/data_descriptor_spec.rb +0 -77
- data/spec/archive/zip/codec/store/compress/new_spec.rb +0 -16
- data/spec/archive/zip/codec/store/compress/open_spec.rb +0 -29
- data/spec/archive/zip/codec/store/compress/rewind_spec.rb +0 -28
- data/spec/archive/zip/codec/store/compress/seek_spec.rb +0 -52
- data/spec/archive/zip/codec/store/compress/tell_spec.rb +0 -31
- data/spec/archive/zip/codec/store/compress/write_spec.rb +0 -29
- data/spec/archive/zip/codec/store/decompress/close_spec.rb +0 -34
- data/spec/archive/zip/codec/store/decompress/data_descriptor_spec.rb +0 -75
- data/spec/archive/zip/codec/store/decompress/new_spec.rb +0 -16
- data/spec/archive/zip/codec/store/decompress/open_spec.rb +0 -29
- data/spec/archive/zip/codec/store/decompress/read_spec.rb +0 -26
- data/spec/archive/zip/codec/store/decompress/rewind_spec.rb +0 -27
- data/spec/archive/zip/codec/store/decompress/seek_spec.rb +0 -59
- data/spec/archive/zip/codec/store/decompress/tell_spec.rb +0 -23
- data/spec/archive/zip/codec/store/fixtures/classes.rb +0 -12
- data/spec/archive/zip/codec/store/fixtures/raw_file.txt +0 -10
- data/spec/archive/zip/codec/traditional_encryption/decrypt/close_spec.rb +0 -53
- data/spec/archive/zip/codec/traditional_encryption/decrypt/new_spec.rb +0 -20
- data/spec/archive/zip/codec/traditional_encryption/decrypt/open_spec.rb +0 -43
- data/spec/archive/zip/codec/traditional_encryption/decrypt/read_spec.rb +0 -127
- data/spec/archive/zip/codec/traditional_encryption/decrypt/rewind_spec.rb +0 -36
- data/spec/archive/zip/codec/traditional_encryption/decrypt/seek_spec.rb +0 -80
- data/spec/archive/zip/codec/traditional_encryption/decrypt/tell_spec.rb +0 -27
- data/spec/archive/zip/codec/traditional_encryption/encrypt/close_spec.rb +0 -53
- data/spec/archive/zip/codec/traditional_encryption/encrypt/new_spec.rb +0 -20
- data/spec/archive/zip/codec/traditional_encryption/encrypt/open_spec.rb +0 -41
- data/spec/archive/zip/codec/traditional_encryption/encrypt/rewind_spec.rb +0 -39
- data/spec/archive/zip/codec/traditional_encryption/encrypt/seek_spec.rb +0 -73
- data/spec/archive/zip/codec/traditional_encryption/encrypt/tell_spec.rb +0 -40
- data/spec/archive/zip/codec/traditional_encryption/encrypt/write_spec.rb +0 -114
- data/spec/archive/zip/codec/traditional_encryption/fixtures/classes.rb +0 -27
- data/spec/archive/zip/codec/traditional_encryption/fixtures/encrypted_file.bin +0 -0
- data/spec/archive/zip/codec/traditional_encryption/fixtures/raw_file.txt +0 -10
- data/spec/binary_stringio/new_spec.rb +0 -40
- data/spec/binary_stringio/set_encoding_spec.rb +0 -17
- data/spec/ioextensions/read_exactly_spec.rb +0 -52
- data/spec/zlib/fixtures/classes.rb +0 -65
- data/spec/zlib/fixtures/compressed_file.bin +0 -1
- data/spec/zlib/fixtures/compressed_file_gzip.bin +0 -0
- data/spec/zlib/fixtures/compressed_file_huffman.bin +0 -2
- data/spec/zlib/fixtures/compressed_file_minmem.bin +0 -0
- data/spec/zlib/fixtures/compressed_file_minwin.bin +0 -1
- data/spec/zlib/fixtures/compressed_file_nocomp.bin +0 -0
- data/spec/zlib/fixtures/compressed_file_raw.bin +0 -1
- data/spec/zlib/fixtures/raw_file.txt +0 -10
- data/spec/zlib/zreader/checksum_spec.rb +0 -42
- data/spec/zlib/zreader/close_spec.rb +0 -16
- data/spec/zlib/zreader/compressed_size_spec.rb +0 -20
- data/spec/zlib/zreader/new_spec.rb +0 -43
- data/spec/zlib/zreader/open_spec.rb +0 -51
- data/spec/zlib/zreader/read_spec.rb +0 -58
- data/spec/zlib/zreader/rewind_spec.rb +0 -25
- data/spec/zlib/zreader/seek_spec.rb +0 -57
- data/spec/zlib/zreader/tell_spec.rb +0 -23
- data/spec/zlib/zreader/uncompressed_size_spec.rb +0 -20
- data/spec/zlib/zwriter/checksum_spec.rb +0 -43
- data/spec/zlib/zwriter/close_spec.rb +0 -16
- data/spec/zlib/zwriter/compressed_size_spec.rb +0 -21
- data/spec/zlib/zwriter/new_spec.rb +0 -66
- data/spec/zlib/zwriter/open_spec.rb +0 -70
- data/spec/zlib/zwriter/rewind_spec.rb +0 -28
- data/spec/zlib/zwriter/seek_spec.rb +0 -52
- data/spec/zlib/zwriter/tell_spec.rb +0 -31
- data/spec/zlib/zwriter/uncompressed_size_spec.rb +0 -21
- data/spec/zlib/zwriter/write_spec.rb +0 -28
@@ -0,0 +1,103 @@
|
|
1
|
+
# encoding: UTF-8
|
2
|
+
|
3
|
+
module Archive; class Zip
|
4
|
+
# A representation of the DOS time structure which can be converted into
|
5
|
+
# instances of Time.
|
6
|
+
class DOSTime
|
7
|
+
include Comparable
|
8
|
+
|
9
|
+
# Creates a new instance of DOSTime. _dos_time_ is a 4 byte String or
|
10
|
+
# unsigned number (Integer) representing an MS-DOS time structure where:
|
11
|
+
# Bits 0-4:: 2 second increments (0-29)
|
12
|
+
# Bits 5-10:: minutes (0-59)
|
13
|
+
# Bits 11-15:: hours (0-24)
|
14
|
+
# Bits 16-20:: day (1-31)
|
15
|
+
# Bits 21-24:: month (1-12)
|
16
|
+
# Bits 25-31:: four digit year minus 1980 (0-119)
|
17
|
+
#
|
18
|
+
# If _dos_time_ is ommitted or +nil+, a new instance is created based on the
|
19
|
+
# current time.
|
20
|
+
def initialize(time = nil)
|
21
|
+
@dos_time = case time
|
22
|
+
when nil
|
23
|
+
from_time(Time.now)
|
24
|
+
when Time
|
25
|
+
from_time(time)
|
26
|
+
else
|
27
|
+
time
|
28
|
+
end
|
29
|
+
|
30
|
+
validate
|
31
|
+
end
|
32
|
+
|
33
|
+
# Returns 1 if _other_ is a time earlier than this one, 0 if _other_ is the
|
34
|
+
# same time, and -1 if _other_ is a later time.
|
35
|
+
def cmp(other)
|
36
|
+
raise ArgumentError, 'other must be a DOSTime' unless DOSTime === other
|
37
|
+
to_i <=> other.to_i
|
38
|
+
end
|
39
|
+
alias_method :<=>, :cmp
|
40
|
+
|
41
|
+
# Returns the time value of this object as an integer representing the DOS
|
42
|
+
# time structure.
|
43
|
+
def to_i
|
44
|
+
@dos_time
|
45
|
+
end
|
46
|
+
|
47
|
+
# Returns a Time instance which is equivalent to the time represented by
|
48
|
+
# this object.
|
49
|
+
def to_time
|
50
|
+
second = ((0b11111 & @dos_time) ) * 2
|
51
|
+
minute = ((0b111111 << 5 & @dos_time) >> 5)
|
52
|
+
hour = ((0b11111 << 11 & @dos_time) >> 11)
|
53
|
+
day = ((0b11111 << 16 & @dos_time) >> 16)
|
54
|
+
month = ((0b1111 << 21 & @dos_time) >> 21)
|
55
|
+
year = ((0b1111111 << 25 & @dos_time) >> 25) + 1980
|
56
|
+
return Time.local(year, month, day, hour, minute, second)
|
57
|
+
end
|
58
|
+
|
59
|
+
private
|
60
|
+
|
61
|
+
# Converts an instance of Time into a DOS date-time structure. Times are
|
62
|
+
# bracketed by the limits of the ability of the DOS date-time structure to
|
63
|
+
# represent them. Accuracy is 2 seconds and years range from 1980 to 2099.
|
64
|
+
def from_time(time)
|
65
|
+
dos_sec = time.sec/2
|
66
|
+
dos_year = time.year - 1980
|
67
|
+
dos_year = 0 if dos_year < 0
|
68
|
+
dos_year = 119 if dos_year > 119
|
69
|
+
|
70
|
+
(dos_sec ) |
|
71
|
+
(time.min << 5) |
|
72
|
+
(time.hour << 11) |
|
73
|
+
(time.day << 16) |
|
74
|
+
(time.month << 21) |
|
75
|
+
(dos_year << 25)
|
76
|
+
end
|
77
|
+
|
78
|
+
def validate
|
79
|
+
second = (0b11111 & @dos_time)
|
80
|
+
minute = (0b111111 << 5 & @dos_time) >> 5
|
81
|
+
hour = (0b11111 << 11 & @dos_time) >> 11
|
82
|
+
day = (0b11111 << 16 & @dos_time) >> 16
|
83
|
+
month = (0b1111 << 21 & @dos_time) >> 21
|
84
|
+
year = (0b1111111 << 25 & @dos_time) >> 25
|
85
|
+
|
86
|
+
if second > 29
|
87
|
+
raise ArgumentError, 'second must not be greater than 29'
|
88
|
+
elsif minute > 59
|
89
|
+
raise ArgumentError, 'minute must not be greater than 59'
|
90
|
+
elsif hour > 23
|
91
|
+
raise ArgumentError, 'hour must not be greater than 23'
|
92
|
+
elsif day < 1
|
93
|
+
raise ArgumentError, 'day must not be less than 1'
|
94
|
+
elsif month < 1
|
95
|
+
raise ArgumentError, 'month must not be less than 1'
|
96
|
+
elsif month > 12
|
97
|
+
raise ArgumentError, 'month must not be greater than 12'
|
98
|
+
elsif year > 119
|
99
|
+
raise ArgumentError, 'year must not be greater than 119'
|
100
|
+
end
|
101
|
+
end
|
102
|
+
end
|
103
|
+
end; end
|
data/lib/archive/zip/entry.rb
CHANGED
@@ -1,12 +1,15 @@
|
|
1
1
|
# encoding: UTF-8
|
2
2
|
|
3
|
+
require 'io/like_helpers/io_wrapper'
|
4
|
+
|
3
5
|
require 'archive/support/ioextensions'
|
4
|
-
require 'archive/support/
|
6
|
+
require 'archive/support/stringio'
|
5
7
|
require 'archive/zip/codec/deflate'
|
6
8
|
require 'archive/zip/codec/null_encryption'
|
7
9
|
require 'archive/zip/codec/store'
|
8
10
|
require 'archive/zip/codec/traditional_encryption'
|
9
11
|
require 'archive/zip/data_descriptor'
|
12
|
+
require 'archive/zip/dos_time'
|
10
13
|
require 'archive/zip/error'
|
11
14
|
require 'archive/zip/extra_field'
|
12
15
|
|
@@ -220,6 +223,8 @@ module Archive; class Zip
|
|
220
223
|
cfr = parse_central_file_record(io)
|
221
224
|
next_record_position = io.pos
|
222
225
|
io.seek(cfr.local_header_position)
|
226
|
+
IOExtensions.read_exactly(io, 4)
|
227
|
+
io.pos -= 4
|
223
228
|
unless IOExtensions.read_exactly(io, 4) == LFH_SIGNATURE then
|
224
229
|
raise Zip::EntryError, 'bad local file header signature'
|
225
230
|
end
|
@@ -258,7 +263,9 @@ module Archive; class Zip
|
|
258
263
|
|
259
264
|
# Create the entry.
|
260
265
|
expanded_path = expand_path(cfr.zip_path)
|
261
|
-
io_window = IOWindow.new(
|
266
|
+
io_window = IOWindow.new(
|
267
|
+
IO::LikeHelpers::IOWrapper.new(io), io.pos, cfr.compressed_size
|
268
|
+
)
|
262
269
|
if cfr.zip_path[-1..-1] == '/' then
|
263
270
|
# This is a directory entry.
|
264
271
|
entry = Entry::Directory.new(expanded_path, io_window)
|
@@ -391,23 +398,31 @@ module Archive; class Zip
|
|
391
398
|
raise Zip::EntryError, 'unexpected end of file'
|
392
399
|
end
|
393
400
|
|
401
|
+
def self.parse_extra_fields(bytes)
|
402
|
+
extra_fields = []
|
403
|
+
idx = 0
|
404
|
+
while idx < bytes.size do
|
405
|
+
raise EntryError, 'insufficient data available' if bytes.size < idx + 4
|
406
|
+
header_id, data_size = bytes[idx, 4].unpack('vv')
|
407
|
+
idx += 4
|
408
|
+
|
409
|
+
if bytes.size < idx + data_size
|
410
|
+
raise EntryError, 'insufficient data available'
|
411
|
+
end
|
412
|
+
data = bytes[idx, data_size]
|
413
|
+
idx += data_size
|
414
|
+
|
415
|
+
extra_fields << yield(header_id, data)
|
416
|
+
end
|
417
|
+
extra_fields
|
418
|
+
end
|
419
|
+
|
394
420
|
# Parses the extra fields for central file records and returns an array of
|
395
421
|
# extra field objects. _bytes_ must be a String containing all of the extra
|
396
422
|
# field data to be parsed.
|
397
423
|
def self.parse_central_extra_fields(bytes)
|
398
|
-
|
399
|
-
|
400
|
-
while ! io.eof? do
|
401
|
-
begin
|
402
|
-
header_id, data_size = IOExtensions.read_exactly(io, 4).unpack('vv')
|
403
|
-
data = IOExtensions.read_exactly(io, data_size)
|
404
|
-
rescue ::EOFError
|
405
|
-
raise EntryError, 'insufficient data available'
|
406
|
-
end
|
407
|
-
|
408
|
-
extra_fields << ExtraField.parse_central(header_id, data)
|
409
|
-
end
|
410
|
-
extra_fields
|
424
|
+
parse_extra_fields(bytes) do |header_id, data|
|
425
|
+
ExtraField.parse_central(header_id, data)
|
411
426
|
end
|
412
427
|
end
|
413
428
|
|
@@ -415,19 +430,8 @@ module Archive; class Zip
|
|
415
430
|
# extra field objects. _bytes_ must be a String containing all of the extra
|
416
431
|
# field data to be parsed.
|
417
432
|
def self.parse_local_extra_fields(bytes)
|
418
|
-
|
419
|
-
|
420
|
-
while ! io.eof? do
|
421
|
-
begin
|
422
|
-
header_id, data_size = IOExtensions.read_exactly(io, 4).unpack('vv')
|
423
|
-
data = IOExtensions.read_exactly(io, data_size)
|
424
|
-
rescue ::EOFError
|
425
|
-
raise EntryError, 'insufficient data available'
|
426
|
-
end
|
427
|
-
|
428
|
-
extra_fields << ExtraField.parse_local(header_id, data)
|
429
|
-
end
|
430
|
-
extra_fields
|
433
|
+
parse_extra_fields(bytes) do |header_id, data|
|
434
|
+
ExtraField.parse_local(header_id, data)
|
431
435
|
end
|
432
436
|
end
|
433
437
|
|
@@ -604,11 +608,11 @@ module Archive; class Zip
|
|
604
608
|
if encryption_codec.class == Codec::TraditionalEncryption then
|
605
609
|
# HACK:
|
606
610
|
# According to the ZIP specification, a trailing data descriptor should
|
607
|
-
# only be required when writing to non-seekable IO
|
608
|
-
#
|
609
|
-
#
|
610
|
-
#
|
611
|
-
#
|
611
|
+
# only be required when writing to non-seekable IO, but InfoZIP *always*
|
612
|
+
# does this when using traditional encryption even though it will also
|
613
|
+
# write the data descriptor in the usual place if possible. Failure to
|
614
|
+
# emulate InfoZIP in this behavior will prevent InfoZIP compatibility
|
615
|
+
# with traditionally encrypted entries.
|
612
616
|
need_trailing_data_descriptor = true
|
613
617
|
# HACK:
|
614
618
|
# The InfoZIP implementation of traditional encryption requires that the
|
@@ -639,7 +643,7 @@ module Archive; class Zip
|
|
639
643
|
version_needed_to_extract,
|
640
644
|
general_purpose_flags,
|
641
645
|
compression_codec.compression_method,
|
642
|
-
mtime.
|
646
|
+
DOSTime.new(mtime).to_i,
|
643
647
|
0,
|
644
648
|
0,
|
645
649
|
0,
|
@@ -649,20 +653,24 @@ module Archive; class Zip
|
|
649
653
|
)
|
650
654
|
bytes_written += io.write(zip_path)
|
651
655
|
bytes_written += io.write(extra_field_data)
|
656
|
+
# Flush buffered data here because writing to the compression pipeline
|
657
|
+
# next bypasses the buffer.
|
658
|
+
io.flush
|
652
659
|
|
653
660
|
# Pipeline a compressor into an encryptor, write all the file data to the
|
654
661
|
# compressor, and get a data descriptor from it.
|
655
|
-
|
656
|
-
|
657
|
-
|
658
|
-
|
659
|
-
|
660
|
-
|
661
|
-
|
662
|
-
|
663
|
-
|
664
|
-
|
665
|
-
|
662
|
+
compression_codec.compressor(
|
663
|
+
encryption_codec.encryptor(
|
664
|
+
IO::LikeHelpers::IOWrapper.open(io, autoclose: false), password
|
665
|
+
)
|
666
|
+
) do |c|
|
667
|
+
dump_file_data(c)
|
668
|
+
c.close
|
669
|
+
@data_descriptor = DataDescriptor.new(
|
670
|
+
c.data_descriptor.crc32,
|
671
|
+
c.data_descriptor.compressed_size + encryption_codec.header_size,
|
672
|
+
c.data_descriptor.uncompressed_size
|
673
|
+
)
|
666
674
|
end
|
667
675
|
bytes_written += @data_descriptor.compressed_size
|
668
676
|
|
@@ -735,7 +743,7 @@ module Archive; class Zip
|
|
735
743
|
version_needed_to_extract,
|
736
744
|
general_purpose_flags,
|
737
745
|
compression_codec.compression_method,
|
738
|
-
mtime.
|
746
|
+
DOSTime.new(mtime).to_i
|
739
747
|
].pack('vvvvV')
|
740
748
|
)
|
741
749
|
bytes_written += @data_descriptor.dump(io)
|
@@ -912,18 +920,18 @@ module Archive; class Zip; module Entry
|
|
912
920
|
def link_target
|
913
921
|
return @link_target unless @link_target.nil?
|
914
922
|
|
915
|
-
raw_data.
|
916
|
-
|
917
|
-
|
918
|
-
|
919
|
-
|
920
|
-
|
921
|
-
|
922
|
-
|
923
|
-
|
924
|
-
rescue => e
|
925
|
-
raise Zip::EntryError, "`#{zip_path}': #{e.message}"
|
923
|
+
raw_data.seek(0)
|
924
|
+
compression_codec.decompressor(
|
925
|
+
encryption_codec.decryptor(raw_data, password)
|
926
|
+
) do |decompressor|
|
927
|
+
@link_target = decompressor.read
|
928
|
+
# Verify that the extracted data is good.
|
929
|
+
begin
|
930
|
+
unless expected_data_descriptor.nil? then
|
931
|
+
expected_data_descriptor.verify(decompressor.data_descriptor)
|
926
932
|
end
|
933
|
+
rescue => e
|
934
|
+
raise Zip::EntryError, "`#{zip_path}': #{e.message}"
|
927
935
|
end
|
928
936
|
end
|
929
937
|
@link_target
|
@@ -1064,20 +1072,22 @@ module Archive; class Zip; module Entry
|
|
1064
1072
|
def file_data
|
1065
1073
|
return @file_data unless @file_data.nil? || @file_data.closed?
|
1066
1074
|
|
1067
|
-
|
1068
|
-
raw_data.rewind
|
1069
|
-
@file_data = compression_codec.decompressor(
|
1070
|
-
encryption_codec.decryptor(raw_data, password)
|
1071
|
-
)
|
1072
|
-
else
|
1075
|
+
if raw_data.nil? then
|
1073
1076
|
if @file_path.nil? then
|
1074
|
-
simulated_raw_data =
|
1077
|
+
simulated_raw_data = StringIO.new('', 'rb')
|
1075
1078
|
else
|
1076
1079
|
simulated_raw_data = ::File.new(@file_path, 'rb')
|
1077
1080
|
end
|
1078
1081
|
# Ensure that the IO-like object can return a data descriptor so that
|
1079
1082
|
# it's possible to verify extraction later if desired.
|
1080
|
-
@file_data = Zip::Codec::Store.new.decompressor(
|
1083
|
+
@file_data = Zip::Codec::Store.new.decompressor(
|
1084
|
+
IO::LikeHelpers::IOWrapper.new(simulated_raw_data)
|
1085
|
+
)
|
1086
|
+
else
|
1087
|
+
raw_data.seek(0)
|
1088
|
+
@file_data = compression_codec.decompressor(
|
1089
|
+
encryption_codec.decryptor(raw_data, password)
|
1090
|
+
)
|
1081
1091
|
end
|
1082
1092
|
@file_data
|
1083
1093
|
end
|
@@ -1140,8 +1150,10 @@ module Archive; class Zip; module Entry
|
|
1140
1150
|
|
1141
1151
|
# Dump the file contents.
|
1142
1152
|
::File.open(file_path, 'wb') do |f|
|
1143
|
-
|
1144
|
-
f.write(
|
1153
|
+
begin
|
1154
|
+
loop do f.write(file_data.read(8192)) end
|
1155
|
+
rescue EOFError
|
1156
|
+
# Ignore
|
1145
1157
|
end
|
1146
1158
|
end
|
1147
1159
|
|
@@ -1162,7 +1174,7 @@ module Archive; class Zip; module Entry
|
|
1162
1174
|
# Attempt to rewind the file data back to the beginning, but ignore
|
1163
1175
|
# errors.
|
1164
1176
|
begin
|
1165
|
-
file_data.
|
1177
|
+
file_data.seek(0)
|
1166
1178
|
rescue
|
1167
1179
|
# Ignore.
|
1168
1180
|
end
|
@@ -1174,7 +1186,11 @@ module Archive; class Zip; module Entry
|
|
1174
1186
|
|
1175
1187
|
# Write the file data to _io_.
|
1176
1188
|
def dump_file_data(io)
|
1177
|
-
|
1189
|
+
begin
|
1190
|
+
loop do io.write(file_data.read(8192)) end
|
1191
|
+
rescue EOFError
|
1192
|
+
# Ignore
|
1193
|
+
end
|
1178
1194
|
|
1179
1195
|
# Attempt to ensure that the file data will still be in a readable state
|
1180
1196
|
# at the beginning of the data for the next user, but close it if possible
|
@@ -1184,7 +1200,7 @@ module Archive; class Zip; module Entry
|
|
1184
1200
|
# reinitialize the IO object it returns, so attempt to rewind the file
|
1185
1201
|
# data back to the beginning, but ignore errors.
|
1186
1202
|
begin
|
1187
|
-
file_data.
|
1203
|
+
file_data.seek(0)
|
1188
1204
|
rescue
|
1189
1205
|
# Ignore.
|
1190
1206
|
end
|
data/lib/archive/zip.rb
CHANGED
@@ -6,7 +6,6 @@ require 'tempfile'
|
|
6
6
|
|
7
7
|
require 'archive/support/ioextensions'
|
8
8
|
require 'archive/support/iowindow'
|
9
|
-
require 'archive/support/time'
|
10
9
|
require 'archive/support/zlib'
|
11
10
|
require 'archive/zip/codec'
|
12
11
|
require 'archive/zip/entry'
|
@@ -112,7 +111,7 @@ module Archive # :nodoc:
|
|
112
111
|
begin
|
113
112
|
yield(zf)
|
114
113
|
ensure
|
115
|
-
zf.close
|
114
|
+
zf.close
|
116
115
|
end
|
117
116
|
end
|
118
117
|
|
@@ -164,10 +163,8 @@ module Archive # :nodoc:
|
|
164
163
|
#
|
165
164
|
# <b>NOTE:</b> The underlying stream is only closed if the archive was
|
166
165
|
# opened with a String for the _archive_ parameter.
|
167
|
-
#
|
168
|
-
# Raises Archive::Zip::IOError if called more than once.
|
169
166
|
def close
|
170
|
-
|
167
|
+
return nil if closed?
|
171
168
|
|
172
169
|
if writable? then
|
173
170
|
# Write the new archive contents.
|