rubyzip 1.3.0 → 2.3.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (115) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +2 -8
  3. data/Rakefile +3 -0
  4. data/lib/zip.rb +4 -3
  5. data/lib/zip/central_directory.rb +9 -5
  6. data/lib/zip/constants.rb +52 -0
  7. data/lib/zip/crypto/decrypted_io.rb +40 -0
  8. data/lib/zip/crypto/traditional_encryption.rb +9 -9
  9. data/lib/zip/decompressor.rb +19 -1
  10. data/lib/zip/dos_time.rb +12 -7
  11. data/lib/zip/entry.rb +57 -38
  12. data/lib/zip/entry_set.rb +2 -0
  13. data/lib/zip/errors.rb +1 -0
  14. data/lib/zip/extra_field.rb +11 -9
  15. data/lib/zip/extra_field/generic.rb +10 -9
  16. data/lib/zip/extra_field/ntfs.rb +4 -0
  17. data/lib/zip/extra_field/old_unix.rb +3 -1
  18. data/lib/zip/extra_field/universal_time.rb +42 -12
  19. data/lib/zip/extra_field/unix.rb +3 -1
  20. data/lib/zip/extra_field/zip64.rb +4 -2
  21. data/lib/zip/file.rb +79 -54
  22. data/lib/zip/filesystem.rb +193 -177
  23. data/lib/zip/inflater.rb +24 -36
  24. data/lib/zip/input_stream.rb +33 -26
  25. data/lib/zip/ioextras.rb +1 -1
  26. data/lib/zip/ioextras/abstract_input_stream.rb +19 -8
  27. data/lib/zip/ioextras/abstract_output_stream.rb +1 -1
  28. data/lib/zip/null_decompressor.rb +1 -9
  29. data/lib/zip/output_stream.rb +14 -5
  30. data/lib/zip/pass_thru_compressor.rb +2 -2
  31. data/lib/zip/pass_thru_decompressor.rb +13 -22
  32. data/lib/zip/streamable_directory.rb +3 -3
  33. data/lib/zip/streamable_stream.rb +6 -10
  34. data/lib/zip/version.rb +1 -1
  35. data/samples/example.rb +2 -2
  36. data/samples/example_filesystem.rb +1 -1
  37. data/samples/gtk_ruby_zip.rb +19 -19
  38. data/samples/qtzip.rb +6 -6
  39. data/samples/write_simple.rb +2 -4
  40. data/samples/zipfind.rb +23 -22
  41. metadata +28 -169
  42. data/test/basic_zip_file_test.rb +0 -60
  43. data/test/case_sensitivity_test.rb +0 -69
  44. data/test/central_directory_entry_test.rb +0 -69
  45. data/test/central_directory_test.rb +0 -100
  46. data/test/crypto/null_encryption_test.rb +0 -57
  47. data/test/crypto/traditional_encryption_test.rb +0 -80
  48. data/test/data/WarnInvalidDate.zip +0 -0
  49. data/test/data/file1.txt +0 -46
  50. data/test/data/file1.txt.deflatedData +0 -0
  51. data/test/data/file2.txt +0 -1504
  52. data/test/data/globTest.zip +0 -0
  53. data/test/data/globTest/foo.txt +0 -0
  54. data/test/data/globTest/foo/bar/baz/foo.txt +0 -0
  55. data/test/data/globTest/food.txt +0 -0
  56. data/test/data/gpbit3stored.zip +0 -0
  57. data/test/data/mimetype +0 -1
  58. data/test/data/notzippedruby.rb +0 -7
  59. data/test/data/ntfs.zip +0 -0
  60. data/test/data/oddExtraField.zip +0 -0
  61. data/test/data/path_traversal/Makefile +0 -10
  62. data/test/data/path_traversal/jwilk/README.md +0 -5
  63. data/test/data/path_traversal/jwilk/absolute1.zip +0 -0
  64. data/test/data/path_traversal/jwilk/absolute2.zip +0 -0
  65. data/test/data/path_traversal/jwilk/dirsymlink.zip +0 -0
  66. data/test/data/path_traversal/jwilk/dirsymlink2a.zip +0 -0
  67. data/test/data/path_traversal/jwilk/dirsymlink2b.zip +0 -0
  68. data/test/data/path_traversal/jwilk/relative0.zip +0 -0
  69. data/test/data/path_traversal/jwilk/relative2.zip +0 -0
  70. data/test/data/path_traversal/jwilk/symlink.zip +0 -0
  71. data/test/data/path_traversal/relative1.zip +0 -0
  72. data/test/data/path_traversal/tilde.zip +0 -0
  73. data/test/data/path_traversal/tuzovakaoff/README.md +0 -3
  74. data/test/data/path_traversal/tuzovakaoff/absolutepath.zip +0 -0
  75. data/test/data/path_traversal/tuzovakaoff/symlink.zip +0 -0
  76. data/test/data/rubycode.zip +0 -0
  77. data/test/data/rubycode2.zip +0 -0
  78. data/test/data/test.xls +0 -0
  79. data/test/data/testDirectory.bin +0 -0
  80. data/test/data/zip64-sample.zip +0 -0
  81. data/test/data/zipWithDirs.zip +0 -0
  82. data/test/data/zipWithEncryption.zip +0 -0
  83. data/test/deflater_test.rb +0 -65
  84. data/test/encryption_test.rb +0 -42
  85. data/test/entry_set_test.rb +0 -163
  86. data/test/entry_test.rb +0 -154
  87. data/test/errors_test.rb +0 -35
  88. data/test/extra_field_test.rb +0 -76
  89. data/test/file_extract_directory_test.rb +0 -54
  90. data/test/file_extract_test.rb +0 -145
  91. data/test/file_permissions_test.rb +0 -65
  92. data/test/file_split_test.rb +0 -57
  93. data/test/file_test.rb +0 -666
  94. data/test/filesystem/dir_iterator_test.rb +0 -58
  95. data/test/filesystem/directory_test.rb +0 -139
  96. data/test/filesystem/file_mutating_test.rb +0 -87
  97. data/test/filesystem/file_nonmutating_test.rb +0 -508
  98. data/test/filesystem/file_stat_test.rb +0 -64
  99. data/test/gentestfiles.rb +0 -126
  100. data/test/inflater_test.rb +0 -14
  101. data/test/input_stream_test.rb +0 -182
  102. data/test/ioextras/abstract_input_stream_test.rb +0 -102
  103. data/test/ioextras/abstract_output_stream_test.rb +0 -106
  104. data/test/ioextras/fake_io_test.rb +0 -18
  105. data/test/local_entry_test.rb +0 -154
  106. data/test/output_stream_test.rb +0 -128
  107. data/test/pass_thru_compressor_test.rb +0 -30
  108. data/test/pass_thru_decompressor_test.rb +0 -14
  109. data/test/path_traversal_test.rb +0 -141
  110. data/test/samples/example_recursive_test.rb +0 -37
  111. data/test/settings_test.rb +0 -95
  112. data/test/test_helper.rb +0 -234
  113. data/test/unicode_file_names_and_comments_test.rb +0 -62
  114. data/test/zip64_full_test.rb +0 -51
  115. data/test/zip64_support_test.rb +0 -14
data/lib/zip/inflater.rb CHANGED
@@ -1,64 +1,52 @@
1
1
  module Zip
2
2
  class Inflater < Decompressor #:nodoc:all
3
- def initialize(input_stream, decrypter = NullDecrypter.new)
4
- super(input_stream)
5
- @zlib_inflater = ::Zlib::Inflate.new(-Zlib::MAX_WBITS)
6
- @output_buffer = ''.dup
7
- @has_returned_empty_string = false
8
- @decrypter = decrypter
9
- end
3
+ def initialize(*args)
4
+ super
10
5
 
11
- def sysread(number_of_bytes = nil, buf = '')
12
- readEverything = number_of_bytes.nil?
13
- while readEverything || @output_buffer.bytesize < number_of_bytes
14
- break if internal_input_finished?
15
- @output_buffer << internal_produce_input(buf)
16
- end
17
- return value_when_finished if @output_buffer.bytesize == 0 && input_finished?
18
- end_index = number_of_bytes.nil? ? @output_buffer.bytesize : number_of_bytes
19
- @output_buffer.slice!(0...end_index)
6
+ @buffer = +''
7
+ @zlib_inflater = ::Zlib::Inflate.new(-Zlib::MAX_WBITS)
20
8
  end
21
9
 
22
- def produce_input
23
- if @output_buffer.empty?
24
- internal_produce_input
25
- else
26
- @output_buffer.slice!(0...(@output_buffer.length))
10
+ def read(length = nil, outbuf = '')
11
+ return (length.nil? || length.zero? ? '' : nil) if eof
12
+
13
+ while length.nil? || (@buffer.bytesize < length)
14
+ break if input_finished?
15
+
16
+ @buffer << produce_input
27
17
  end
18
+
19
+ outbuf.replace(@buffer.slice!(0...(length || @buffer.bytesize)))
28
20
  end
29
21
 
30
- # to be used with produce_input, not read (as read may still have more data cached)
31
- # is data cached anywhere other than @outputBuffer? the comment above may be wrong
32
- def input_finished?
33
- @output_buffer.empty? && internal_input_finished?
22
+ def eof
23
+ @buffer.empty? && input_finished?
34
24
  end
35
25
 
36
- alias :eof input_finished?
37
- alias :eof? input_finished?
26
+ alias eof? eof
38
27
 
39
28
  private
40
29
 
41
- def internal_produce_input(buf = '')
30
+ def produce_input
42
31
  retried = 0
43
32
  begin
44
- @zlib_inflater.inflate(@decrypter.decrypt(@input_stream.read(Decompressor::CHUNK_SIZE, buf)))
33
+ @zlib_inflater.inflate(input_stream.read(Decompressor::CHUNK_SIZE))
45
34
  rescue Zlib::BufError
46
35
  raise if retried >= 5 # how many times should we retry?
36
+
47
37
  retried += 1
48
38
  retry
49
39
  end
40
+ rescue Zlib::Error
41
+ raise(::Zip::DecompressionError, 'zlib error while inflating')
50
42
  end
51
43
 
52
- def internal_input_finished?
44
+ def input_finished?
53
45
  @zlib_inflater.finished?
54
46
  end
55
-
56
- def value_when_finished # mimic behaviour of ruby File object.
57
- return if @has_returned_empty_string
58
- @has_returned_empty_string = true
59
- ''
60
- end
61
47
  end
48
+
49
+ ::Zip::Decompressor.register(::Zip::COMPRESSION_METHOD_DEFLATE, ::Zip::Inflater)
62
50
  end
63
51
 
64
52
  # Copyright (C) 2002, 2003 Thomas Sondergaard
@@ -39,6 +39,8 @@ module Zip
39
39
  # class.
40
40
 
41
41
  class InputStream
42
+ CHUNK_SIZE = 32_768
43
+
42
44
  include ::Zip::IOExtras::AbstractInputStream
43
45
 
44
46
  # Opens the indicated zip file. An exception is thrown
@@ -49,7 +51,7 @@ module Zip
49
51
  # @param offset [Integer] offset in the IO/StringIO
50
52
  def initialize(context, offset = 0, decrypter = nil)
51
53
  super()
52
- @archive_io = get_io(context, offset)
54
+ @archive_io = get_io(context, offset)
53
55
  @decompressor = ::Zip::NullDecompressor
54
56
  @decrypter = decrypter || ::Zip::NullDecrypter.new
55
57
  @current_entry = nil
@@ -71,6 +73,7 @@ module Zip
71
73
  # Rewinds the stream to the beginning of the current entry
72
74
  def rewind
73
75
  return if @current_entry.nil?
76
+
74
77
  @lineno = 0
75
78
  @pos = 0
76
79
  @archive_io.seek(@current_entry.local_header_offset, IO::SEEK_SET)
@@ -78,16 +81,10 @@ module Zip
78
81
  end
79
82
 
80
83
  # Modeled after IO.sysread
81
- def sysread(number_of_bytes = nil, buf = nil)
82
- @decompressor.sysread(number_of_bytes, buf)
83
- end
84
-
85
- def eof
86
- @output_buffer.empty? && @decompressor.eof
84
+ def sysread(length = nil, outbuf = '')
85
+ @decompressor.read(length, outbuf)
87
86
  end
88
87
 
89
- alias :eof? eof
90
-
91
88
  class << self
92
89
  # Same as #initialize but if a block is passed the opened
93
90
  # stream is passed to the block and closed when the block
@@ -95,6 +92,7 @@ module Zip
95
92
  def open(filename_or_io, offset = 0, decrypter = nil)
96
93
  zio = new(filename_or_io, offset, decrypter)
97
94
  return zio unless block_given?
95
+
98
96
  begin
99
97
  yield zio
100
98
  ensure
@@ -103,8 +101,8 @@ module Zip
103
101
  end
104
102
 
105
103
  def open_buffer(filename_or_io, offset = 0)
106
- puts 'open_buffer is deprecated!!! Use open instead!'
107
- open(filename_or_io, offset)
104
+ warn 'open_buffer is deprecated!!! Use open instead!'
105
+ ::Zip::InputStream.open(filename_or_io, offset)
108
106
  end
109
107
  end
110
108
 
@@ -124,46 +122,55 @@ module Zip
124
122
 
125
123
  def open_entry
126
124
  @current_entry = ::Zip::Entry.read_local_entry(@archive_io)
127
- if @current_entry && @current_entry.gp_flags & 1 == 1 && @decrypter.is_a?(NullEncrypter)
125
+ if @current_entry && @current_entry.encrypted? && @decrypter.kind_of?(NullEncrypter)
128
126
  raise Error, 'password required to decode zip file'
129
127
  end
130
- if @current_entry && @current_entry.gp_flags & 8 == 8 && @current_entry.crc == 0 \
128
+
129
+ if @current_entry && @current_entry.incomplete? && @current_entry.crc == 0 \
131
130
  && @current_entry.compressed_size == 0 \
132
131
  && @current_entry.size == 0 && !@complete_entry
133
132
  raise GPFBit3Error,
134
133
  'General purpose flag Bit 3 is set so not possible to get proper info from local header.' \
135
134
  'Please use ::Zip::File instead of ::Zip::InputStream'
136
135
  end
136
+ @decrypted_io = get_decrypted_io
137
137
  @decompressor = get_decompressor
138
138
  flush
139
139
  @current_entry
140
140
  end
141
141
 
142
+ def get_decrypted_io
143
+ header = @archive_io.read(@decrypter.header_bytesize)
144
+ @decrypter.reset!(header)
145
+
146
+ ::Zip::DecryptedIo.new(@archive_io, @decrypter)
147
+ end
148
+
142
149
  def get_decompressor
143
- if @current_entry.nil?
144
- ::Zip::NullDecompressor
145
- elsif @current_entry.compression_method == ::Zip::Entry::STORED
146
- if @current_entry.gp_flags & 8 == 8 && @current_entry.crc == 0 && @current_entry.size == 0 && @complete_entry
147
- ::Zip::PassThruDecompressor.new(@archive_io, @complete_entry.size)
150
+ return ::Zip::NullDecompressor if @current_entry.nil?
151
+
152
+ decompressed_size =
153
+ if @current_entry.incomplete? && @current_entry.crc == 0 && @current_entry.size == 0 && @complete_entry
154
+ @complete_entry.size
148
155
  else
149
- ::Zip::PassThruDecompressor.new(@archive_io, @current_entry.size)
156
+ @current_entry.size
150
157
  end
151
- elsif @current_entry.compression_method == ::Zip::Entry::DEFLATED
152
- header = @archive_io.read(@decrypter.header_bytesize)
153
- @decrypter.reset!(header)
154
- ::Zip::Inflater.new(@archive_io, @decrypter)
155
- else
158
+
159
+ decompressor_class = ::Zip::Decompressor.find_by_compression_method(@current_entry.compression_method)
160
+ if decompressor_class.nil?
156
161
  raise ::Zip::CompressionMethodError,
157
162
  "Unsupported compression method #{@current_entry.compression_method}"
158
163
  end
164
+
165
+ decompressor_class.new(@decrypted_io, decompressed_size)
159
166
  end
160
167
 
161
168
  def produce_input
162
- @decompressor.produce_input
169
+ @decompressor.read(CHUNK_SIZE)
163
170
  end
164
171
 
165
172
  def input_finished?
166
- @decompressor.input_finished?
173
+ @decompressor.eof
167
174
  end
168
175
  end
169
176
  end
data/lib/zip/ioextras.rb CHANGED
@@ -25,7 +25,7 @@ module Zip
25
25
  object == IO || super
26
26
  end
27
27
  end
28
- end # IOExtras namespace module
28
+ end
29
29
  end
30
30
 
31
31
  require 'zip/ioextras/abstract_input_stream'
@@ -35,6 +35,7 @@ module Zip
35
35
 
36
36
  if tbuf.nil? || tbuf.empty?
37
37
  return nil if number_of_bytes
38
+
38
39
  return ''
39
40
  end
40
41
 
@@ -48,13 +49,13 @@ module Zip
48
49
  buf
49
50
  end
50
51
 
51
- def readlines(a_sep_string = $/)
52
+ def readlines(a_sep_string = $INPUT_RECORD_SEPARATOR)
52
53
  ret_val = []
53
54
  each_line(a_sep_string) { |line| ret_val << line }
54
55
  ret_val
55
56
  end
56
57
 
57
- def gets(a_sep_string = $/, number_of_bytes = nil)
58
+ def gets(a_sep_string = $INPUT_RECORD_SEPARATOR, number_of_bytes = nil)
58
59
  @lineno = @lineno.next
59
60
 
60
61
  if number_of_bytes.respond_to?(:to_int)
@@ -62,20 +63,22 @@ module Zip
62
63
  a_sep_string = a_sep_string.to_str if a_sep_string
63
64
  elsif a_sep_string.respond_to?(:to_int)
64
65
  number_of_bytes = a_sep_string.to_int
65
- a_sep_string = $/
66
+ a_sep_string = $INPUT_RECORD_SEPARATOR
66
67
  else
67
68
  number_of_bytes = nil
68
69
  a_sep_string = a_sep_string.to_str if a_sep_string
69
70
  end
70
71
 
71
72
  return read(number_of_bytes) if a_sep_string.nil?
72
- a_sep_string = "#{$/}#{$/}" if a_sep_string.empty?
73
+
74
+ a_sep_string = "#{$INPUT_RECORD_SEPARATOR}#{$INPUT_RECORD_SEPARATOR}" if a_sep_string.empty?
73
75
 
74
76
  buffer_index = 0
75
77
  over_limit = (number_of_bytes && @output_buffer.bytesize >= number_of_bytes)
76
78
  while (match_index = @output_buffer.index(a_sep_string, buffer_index)).nil? && !over_limit
77
79
  buffer_index = [buffer_index, @output_buffer.bytesize - a_sep_string.bytesize].max
78
80
  return @output_buffer.empty? ? nil : flush if input_finished?
81
+
79
82
  @output_buffer << produce_input
80
83
  over_limit = (number_of_bytes && @output_buffer.bytesize >= number_of_bytes)
81
84
  end
@@ -94,18 +97,26 @@ module Zip
94
97
  ret_val
95
98
  end
96
99
 
97
- def readline(a_sep_string = $/)
100
+ def readline(a_sep_string = $INPUT_RECORD_SEPARATOR)
98
101
  ret_val = gets(a_sep_string)
99
102
  raise EOFError unless ret_val
103
+
100
104
  ret_val
101
105
  end
102
106
 
103
- def each_line(a_sep_string = $/)
104
- yield readline(a_sep_string) while true
107
+ def each_line(a_sep_string = $INPUT_RECORD_SEPARATOR)
108
+ loop { yield readline(a_sep_string) }
105
109
  rescue EOFError
110
+ # We just need to catch this; we don't need to handle it.
111
+ end
112
+
113
+ alias each each_line
114
+
115
+ def eof
116
+ @output_buffer.empty? && input_finished?
106
117
  end
107
118
 
108
- alias_method :each, :each_line
119
+ alias eof? eof
109
120
  end
110
121
  end
111
122
  end
@@ -11,7 +11,7 @@ module Zip
11
11
  end
12
12
 
13
13
  def print(*params)
14
- self << params.join($,) << $\.to_s
14
+ self << params.join($OUTPUT_FIELD_SEPARATOR) << $OUTPUT_RECORD_SEPARATOR.to_s
15
15
  end
16
16
 
17
17
  def printf(a_format_string, *params)
@@ -2,18 +2,10 @@ module Zip
2
2
  module NullDecompressor #:nodoc:all
3
3
  module_function
4
4
 
5
- def sysread(_numberOfBytes = nil, _buf = nil)
5
+ def read(_length = nil, _outbuf = nil)
6
6
  nil
7
7
  end
8
8
 
9
- def produce_input
10
- nil
11
- end
12
-
13
- def input_finished?
14
- true
15
- end
16
-
17
9
  def eof
18
10
  true
19
11
  end
@@ -49,6 +49,7 @@ module Zip
49
49
  class << self
50
50
  def open(file_name, encrypter = nil)
51
51
  return new(file_name) unless block_given?
52
+
52
53
  zos = new(file_name, false, encrypter)
53
54
  yield zos
54
55
  ensure
@@ -57,6 +58,7 @@ module Zip
57
58
 
58
59
  # Same as #open but writes to a filestream instead
59
60
  def write_buffer(io = ::StringIO.new(''), encrypter = nil)
61
+ io.binmode if io.respond_to?(:binmode)
60
62
  zos = new(io, true, encrypter)
61
63
  yield zos
62
64
  zos.close_buffer
@@ -66,6 +68,7 @@ module Zip
66
68
  # Closes the stream and writes the central directory to the zip file
67
69
  def close
68
70
  return if @closed
71
+
69
72
  finalize_current_entry
70
73
  update_local_headers
71
74
  write_central_directory
@@ -76,6 +79,7 @@ module Zip
76
79
  # Closes the stream and writes the central directory to the zip file
77
80
  def close_buffer
78
81
  return @output_stream if @closed
82
+
79
83
  finalize_current_entry
80
84
  update_local_headers
81
85
  write_central_directory
@@ -87,6 +91,7 @@ module Zip
87
91
  # +entry+ can be a ZipEntry object or a string.
88
92
  def put_next_entry(entry_name, comment = nil, extra = nil, compression_method = Entry::DEFLATED, level = Zip.default_compression)
89
93
  raise Error, 'zip stream is closed' if @closed
94
+
90
95
  new_entry = if entry_name.kind_of?(Entry)
91
96
  entry_name
92
97
  else
@@ -94,7 +99,7 @@ module Zip
94
99
  end
95
100
  new_entry.comment = comment unless comment.nil?
96
101
  unless extra.nil?
97
- new_entry.extra = extra.is_a?(ExtraField) ? extra : ExtraField.new(extra.to_s)
102
+ new_entry.extra = extra.kind_of?(ExtraField) ? extra : ExtraField.new(extra.to_s)
98
103
  end
99
104
  new_entry.compression_method = compression_method unless compression_method.nil?
100
105
  init_next_entry(new_entry, level)
@@ -104,7 +109,8 @@ module Zip
104
109
  def copy_raw_entry(entry)
105
110
  entry = entry.dup
106
111
  raise Error, 'zip stream is closed' if @closed
107
- raise Error, 'entry is not a ZipEntry' unless entry.is_a?(Entry)
112
+ raise Error, 'entry is not a ZipEntry' unless entry.kind_of?(Entry)
113
+
108
114
  finalize_current_entry
109
115
  @entry_set << entry
110
116
  src_pos = entry.local_header_offset
@@ -123,8 +129,11 @@ module Zip
123
129
 
124
130
  def finalize_current_entry
125
131
  return unless @current_entry
132
+
126
133
  finish
127
- @current_entry.compressed_size = @output_stream.tell - @current_entry.local_header_offset - @current_entry.calculate_local_header_size
134
+ @current_entry.compressed_size = @output_stream.tell - \
135
+ @current_entry.local_header_offset - \
136
+ @current_entry.calculate_local_header_size
128
137
  @current_entry.size = @compressor.size
129
138
  @current_entry.crc = @compressor.crc
130
139
  @output_stream << @encrypter.data_descriptor(@current_entry.crc, @current_entry.compressed_size, @current_entry.size)
@@ -144,9 +153,9 @@ module Zip
144
153
 
145
154
  def get_compressor(entry, level)
146
155
  case entry.compression_method
147
- when Entry::DEFLATED then
156
+ when Entry::DEFLATED
148
157
  ::Zip::Deflater.new(@output_stream, level, @encrypter)
149
- when Entry::STORED then
158
+ when Entry::STORED
150
159
  ::Zip::PassThruCompressor.new(@output_stream)
151
160
  else
152
161
  raise ::Zip::CompressionMethodError,
@@ -1,8 +1,8 @@
1
1
  module Zip
2
2
  class PassThruCompressor < Compressor #:nodoc:all
3
- def initialize(outputStream)
3
+ def initialize(output_stream)
4
4
  super()
5
- @output_stream = outputStream
5
+ @output_stream = output_stream
6
6
  @crc = Zlib.crc32
7
7
  @size = 0
8
8
  end
@@ -1,38 +1,29 @@
1
1
  module Zip
2
2
  class PassThruDecompressor < Decompressor #:nodoc:all
3
- def initialize(input_stream, chars_to_read)
4
- super(input_stream)
5
- @chars_to_read = chars_to_read
3
+ def initialize(*args)
4
+ super
6
5
  @read_so_far = 0
7
- @has_returned_empty_string = false
8
6
  end
9
7
 
10
- def sysread(number_of_bytes = nil, buf = '')
11
- if input_finished?
12
- has_returned_empty_string_val = @has_returned_empty_string
13
- @has_returned_empty_string = true
14
- return '' unless has_returned_empty_string_val
15
- return
16
- end
8
+ def read(length = nil, outbuf = '')
9
+ return (length.nil? || length.zero? ? '' : nil) if eof
17
10
 
18
- if number_of_bytes.nil? || @read_so_far + number_of_bytes > @chars_to_read
19
- number_of_bytes = @chars_to_read - @read_so_far
11
+ if length.nil? || (@read_so_far + length) > decompressed_size
12
+ length = decompressed_size - @read_so_far
20
13
  end
21
- @read_so_far += number_of_bytes
22
- @input_stream.read(number_of_bytes, buf)
23
- end
24
14
 
25
- def produce_input
26
- sysread(::Zip::Decompressor::CHUNK_SIZE)
15
+ @read_so_far += length
16
+ input_stream.read(length, outbuf)
27
17
  end
28
18
 
29
- def input_finished?
30
- @read_so_far >= @chars_to_read
19
+ def eof
20
+ @read_so_far >= decompressed_size
31
21
  end
32
22
 
33
- alias eof input_finished?
34
- alias eof? input_finished?
23
+ alias eof? eof
35
24
  end
25
+
26
+ ::Zip::Decompressor.register(::Zip::COMPRESSION_METHOD_STORE, ::Zip::PassThruDecompressor)
36
27
  end
37
28
 
38
29
  # Copyright (C) 2002, 2003 Thomas Sondergaard