class Ronin::Support::Archive::Zip::Reader
Handles reading zip archives.
@note
This provides a simple interface for reading zip archives using the `unzip` command. If you need something more powerful, use the [archive-zip] gem instead.
[archive-zip]: github.com/javanthropus/archive-zip
@api public
@since 1.0.0
Constants
- METHODS
-
Translates the Method column in ‘unzip -v -l` output to Symbols.
Attributes
The optional password to use when reading the zip archive.
@return [String, nil]
The path to the zip archive that will be read.
@return [String]
Public Class Methods
Source
# File lib/ronin/support/archive/zip/reader.rb, line 71 def initialize(path, password: nil) @path = File.expand_path(path) @password = password yield self if block_given? end
Initializes the zip archive reader.
@param [String] path
The path to the zip archive file.
@param [String, nil] password
Optional password to use when reading the zip archive.
@yield [zip]
If a block is given, it will be yielded the new zip reader.
@yieldparam [Reader] zip
The new zip reacher.
Source
# File lib/ronin/support/archive/zip/reader.rb, line 98 def self.open(path,**kwargs,&block) new(path,**kwargs,&block) end
Alias to {#initialize new}.
@param [String] path
The path to the zip archive file.
@param [Hash{Symbol => Object}] kwargs
Additional keyword arguments for {#initialize new}.
@option kwargs [String, nil] :password
Optional password to use when reading the zip archive.
@yield [zip]
If a block is given, it will be yielded the new zip reader.
@yieldparam [Reader] zip
The new zip reacher.
@see initialize
Public Instance Methods
Source
# File lib/ronin/support/archive/zip/reader.rb, line 157 def [](name) find { |entry| entry.name == name } end
Finds the entry with the given name.
@param [String] name
The file name to search for.
@return [Entry, nil]
The matching entry or `nil` if no entry could be found.
Source
# File lib/ronin/support/archive/zip/reader.rb, line 120 def each return enum_for(__method__) unless block_given? io = IO.popen(command_argv('-v','-l',@path)) # skip lines until the "--------- ---------- ----- ----" line until io.eof? break if io.readline.start_with?('-') end until io.eof? line = io.readline(chomp: true) unless line.start_with?('-') yield parse_entry_line(line) else # reached the "--------- -------" line break end end last_line = io.readline(chomp: true) return parse_statistics_line(last_line) end
Lists the contents of the zip archive.
@yield [entry]
If a block is given it will be passed each parsed entry in the zip archive.
@yieldparam [Entry] entry
An entry in the zip archive.
@return [Enumerator, Statistics]
If no block is given an enumerator will be returned. If a block was given, then a statistics object will be returned.
@note
This method actually executes the `unzip -v -l ZIP` command and parses it's output.
Source
# File lib/ronin/support/archive/zip/reader.rb, line 177 def read(name, length: nil) io = IO.popen(command_argv('-p', @path, name)) if length then io.read(length) else io.read end end
Reads the contents of an entry from the zip archive.
@param [String] name
The name of the entry to read.
@param [Integer, nil] length
Optional number of bytes to read.
@return [String]
The read data.
@note
This method actually executes the `unzip -p ZIP FILE` command and reads it's output.
Private Instance Methods
Source
# File lib/ronin/support/archive/zip/reader.rb, line 196 def command_argv(*arguments) argv = ['unzip'] if @password argv << '-P' << @password end argv.concat(arguments) end
Creates an ‘unzip` command with the additional arguments.
@param [Array<String>] arguments
Additional arguments for the `unzip` command.
@return [Array<String>]
The `unzip` command argv.
Source
# File lib/ronin/support/archive/zip/reader.rb, line 221 def parse_entry_line(line) length, method, size, compression, date, time, crc32, name = line.lstrip.split(/\s+/,8) time_fmt = case date when /\A\d{2}-\d{2}-\d{4}\z/ then "%m-%d-%Y %H:%M" when /\A\d{4}-\d{2}-\d{2}\z/ then "%Y-%m-%d %H:%M" else raise(NotImplementedError,"unrecognized date format: #{date.inspect}") end length = length.to_i method = METHODS.fetch(method) size = size.to_i compression = compression.chomp('%').to_i time = Time.strptime("#{date} #{time}",time_fmt) date = time.to_date return Entry.new(self, length: length, method: method, size: size, compression: compression, date: date, time: time, crc32: crc32, name: name) end
Parses a entry line from the output of ‘unzip -v -l ZIP`.
@param [String] line
The line to parse.
@return [Entry]
The parsed entry.
Source
# File lib/ronin/support/archive/zip/reader.rb, line 258 def parse_statistics_line(line) length, size, compression, files, _rest = line.lstrip.split(/\s+/,5) return Statistics.new( length: length.to_i, size: size.to_i, compression: compression.chomp('%').to_i, files: files.to_i ) end
Parses the last line from the output of ‘unzip -v -l ZIP`.
@param [String] line
The line to parse.
@return [Statistics]
The parsed statistics.