Class: Archive::Zip::Codec::TraditionalEncryption::Decrypt

Inherits:
Base
  • Object
show all
Includes:
IO::Like
Defined in:
lib/archive/zip/codec/traditional_encryption.rb

Overview

Archive::Zip::Codec::TraditionalEncryption::Decrypt is a readable, IO-like object which decrypts data data it reads from a delegate IO object using the traditional encryption algorithm as documented in the ZIP specification. A close method is also provided which can optionally close the delegate object.

Instances of this class should only be accessed via the Archive::Zip::Codec::TraditionalEncryption#decompressor method.

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(io, password, mtime) ⇒ Decrypt

Creates a new instance of this class using io as a data source. io must be readable and provide a read method as an IO instance would or errors will be raised when performing read operations. password should be the encryption key. mtime must be the last modified time of the entry to be encrypted/decrypted.

This class has extremely limited seek capabilities. It is possible to seek with an offset of 0 and a whence of IO::SEEK_CUR. As a result, the pos and tell methods also work as expected.

Due to certain optimizations within IO::Like#seek and if there is data in the read buffer, the seek method can be used to seek forward from the current stream position up to the end of the buffer. Unless it is known definitively how much data is in the buffer, it is best to avoid relying on this behavior.

If io also responds to rewind, then the rewind method of this class can be used to reset the whole stream back to the beginning. Using seek of this class to seek directly to offset 0 using IO::SEEK_SET for whence will also work in this case.

Any other seeking attempts, will raise Errno::EINVAL exceptions.

The fill_size attribute is set to 0 by default under the assumption that io is already buffered.


282
283
284
285
286
287
288
289
290
291
292
293
# File 'lib/archive/zip/codec/traditional_encryption.rb', line 282

def initialize(io, password, mtime)
  # Keep track of the total number of bytes read.
  # Set this here so that the call to #initialize_keys caused by the call
  # to super below does not cause errors in #unbuffered_read due to this
  # attribute being uninitialized.
  @total_bytes_out = 0

  super(io, password, mtime)

  # Assume that the delegate IO object is already buffered.
  self.fill_size = 0
end

Class Method Details

.open(io, password, mtime) ⇒ Object

Creates a new instance of this class with the given argument using #new and then passes the instance to the given block. The #close method is guaranteed to be called after the block completes.

Equivalent to #new if no block is given.


246
247
248
249
250
251
252
253
254
255
# File 'lib/archive/zip/codec/traditional_encryption.rb', line 246

def self.open(io, password, mtime)
  decrypt_io = new(io, password, mtime)
  return decrypt_io unless block_given?

  begin
    yield(decrypt_io)
  ensure
    decrypt_io.close unless decrypt_io.closed?
  end
end

Instance Method Details

#close(close_delegate = true) ⇒ Object

Closes this object so that further write operations will fail. If close_delegate is true, the delegate object used as a data source will also be closed using its close method.


298
299
300
301
# File 'lib/archive/zip/codec/traditional_encryption.rb', line 298

def close(close_delegate = true)
  super()
  io.close if close_delegate
end