Module: MailReport::Archive

Defined in:
lib/mailreport/archive.rb

Overview

Attachment wrapping per RFC 7489 §7.2.1.1 / RFC 8460 §3. Detected from magic bytes, not the filename.

Constant Summary collapse

GZIP =
"\x1f\x8b".b
ZIP =
"PK".b
MAX_SIZE =

Real reports run to KBs; this is headroom, not an expectation - and every byte of it is parse cost a caller may pay before refusing.

2 * 1024 * 1024
CHUNK_SIZE =
64 * 1024
STORED =
0
UNREADABLE =
[
  ZipKit::FileReader::ReadError, ZipKit::FileReader::MissingEOCD,
  ZipKit::FileReader::UnsupportedFeature, Zlib::Error
].freeze

Class Method Summary collapse

Class Method Details

.open(bytes, max_size: MAX_SIZE, name: nil) ⇒ Object

name prefers a zip entry whose filename matches (e.g. /.xml\z/i).



25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
# File 'lib/mailreport/archive.rb', line 25

def open(bytes, max_size: MAX_SIZE, name: nil)
  bytes = bytes.to_s.b

  # A real report's container never exceeds what it holds; refuse before
  # reading a zip's central directory, whose entry count (not its bytes)
  # is what costs time to walk.
  if bytes.empty?
    nil
  elsif bytes.bytesize > max_size
    nil
  elsif gzipped?(bytes)
    inflated(bytes, max_size)
  elsif zipped?(bytes)
    unzipped(bytes, max_size, name)
  else
    bytes
  end
rescue *UNREADABLE
  nil
end