Module: AppInfo::Helper::IOBlock

Included in:
Android::Signature::Info, Android::Signature::V2, Android::Signature::V3
Defined in:
lib/app_info/helper/signatures.rb

Overview

Binary IO Block Helper

Instance Method Summary collapse

Instance Method Details

#left_bytes_check(io, max_bytes, exception, message = nil, &block) ⇒ Object

Raises:

  • (exception)


51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
# File 'lib/app_info/helper/signatures.rb', line 51

def left_bytes_check(io, max_bytes, exception, message = nil, &block)
  return if max_bytes.nil?

  left_bytes = io.size - io.pos
  return left_bytes if left_bytes.zero?

  message ||= if block_given?
                block.call(left_bytes)
              else
                "IO too short: #{offset} < #{max_bytes}"
              end

  raise exception, message if left_bytes < max_bytes

  left_bytes
end

#length_prefix_block(io, size: AppInfo::Android::Signature::UINT32_SIZE, raw: false, ignore_left_size_precheck: false) ⇒ Object

Raises:

  • (SecurityError)


6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
# File 'lib/app_info/helper/signatures.rb', line 6

def length_prefix_block(
  io, size: AppInfo::Android::Signature::UINT32_SIZE,
  raw: false, ignore_left_size_precheck: false
)
  offset = io.size - io.pos
  if offset < AppInfo::Android::Signature::UINT32_SIZE
    raise SecurityError,
          'Remaining buffer too short to contain length of length-prefixed field.'
  end

  size = io.read(size).unpack1('I')
  raise SecurityError, 'Negative length' if size.negative?

  if !ignore_left_size_precheck && size > io.size
    message = "Underflow while reading length-prefixed value. #{size} > #{io.size}"
    raise SecurityError, message
  end

  raw_data = io.read(size)
  raw ? raw_data : StringIO.new(raw_data)
end

#loop_length_prefix_io(io, name:, max_bytes: nil, logger: nil, raw: false, ignore_left_size_precheck: false, &block) ⇒ Object

Only use for uint32 length-prefixed block



29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
# File 'lib/app_info/helper/signatures.rb', line 29

def loop_length_prefix_io(
  io, name:, max_bytes: nil, logger: nil, raw: false,
  ignore_left_size_precheck: false, &block
)
  index = 0
  until io.eof?
    logger&.debug "#{name} count ##{index}"
    buffer = length_prefix_block(
      io,
      raw: raw,
      ignore_left_size_precheck: ignore_left_size_precheck
    )

    left_bytes_check(buffer, max_bytes, SecurityError) do |left_bytes|
      "#{name} too short: #{left_bytes} < #{max_bytes}"
    end

    block.call(buffer)
    index += 1
  end
end