Class: Omnizip::Formats::XzImpl::StreamFooterParser

Inherits:
Object
  • Object
show all
Defined in:
lib/omnizip/formats/xz_impl/stream_footer_parser.rb

Overview

XZ Stream Footer parser

Stream Footer format (12 bytes):

  • CRC32: of backward_size + flags (4 bytes, little-endian)
  • Backward Size: size of Index in 4-byte units (4 bytes, little-endian)
  • Stream Flags: same as in Stream Header (2 bytes)
  • Magic: 0x59 0x5A (2 bytes)

Reference: /tmp/xz-source/src/liblzma/common/stream_footer_decoder.c

Constant Summary collapse

[0x59, 0x5A].freeze
12

Class Method Summary collapse

Class Method Details

.parse(input) ⇒ Hash

Parse stream footer from input stream

Parameters:

  • input (IO)

    Input stream positioned at footer start

Returns:

  • (Hash)

    Parsed footer data with keys:

    • backward_size: Integer (size of Index in 4-byte units)
    • check_type: Integer (0=None, 1=CRC32, 4=CRC64, 10=SHA256)

Raises:

  • (RuntimeError)

    If footer is invalid or CRC mismatch



51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
# File 'lib/omnizip/formats/xz_impl/stream_footer_parser.rb', line 51

def self.parse(input)
  # Read 12 bytes
  footer = input.read(FOOTER_SIZE)
  if footer.nil? || footer.bytesize < FOOTER_SIZE
    raise FormatError,
          "Unexpected end of file: incomplete stream footer"
  end

  # Verify magic bytes (last 2 bytes)
  magic = footer[-2..].bytes
  unless magic == FOOTER_MAGIC
    raise FormatError, "Invalid XZ footer magic: got #{magic.map do |b|
      b.to_s(16).upcase
    end.join(' ')}"
  end

  # Parse CRC32 (first 4 bytes)
  stored_crc = footer[0..3].unpack1("V")

  # Parse backward size (next 4 bytes, little-endian)
  backward_size = footer[4..7].unpack1("V")

  # Parse stream flags (next 2 bytes)
  flags = footer[8..9]

  # Byte 8: reserved (must be 0)
  if flags.getbyte(0) != 0
    raise FormatError,
          "Invalid stream footer: reserved byte is non-zero"
  end

  # Byte 9: check type (low 4 bits) + reserved (high 4 bits)
  check_flags = flags.getbyte(1)
  check_type = check_flags & 0x0F
  reserved = (check_flags >> 4) & 0x0F

  if reserved != 0
    raise FormatError,
          "Invalid stream footer: reserved bits are non-zero"
  end

  # Validate check type
  unless [0, 1, 4, 10].include?(check_type)
    raise FormatError, "Invalid check type in footer: #{check_type}"
  end

  # Verify CRC32
  # CRC is calculated over backward_size + flags (bytes 4-9)
  crc_data = footer[4..9]
  actual_crc = Zlib.crc32(crc_data)

  if actual_crc != stored_crc
    raise FormatError,
          "Stream footer CRC mismatch: expected #{stored_crc}, got #{actual_crc}"
  end

  {
    backward_size: backward_size,
    check_type: check_type,
  }
end