F3. Postscript
(F3 v0.1.0)
Copy Markdown
The 32-byte tail of an F3 file.
Fields are little-endian, in the order fixed by F3.Format.postscript_layout/0.
The magic F3 is last. This module checks the tail and the claimed sizes.
It does not decode the footer and it does not verify checksums.
metadata_size and footer_size are attacker-controlled. A claim larger
than max_metadata_bytes is :resource_limit and is not allocated.
The default cap is 16 MiB. Pass a non-negative integer to decode/2
to use another cap for that call.
Summary
Types
@type checksum_type() :: :xxhash | {:unknown, 0..255}
@type compression() :: :uncompressed
@type t() :: %F3.Postscript{ checksum_type: checksum_type(), data_checksum: non_neg_integer(), file_size: non_neg_integer(), footer_compression: compression(), footer_offset: non_neg_integer(), footer_size: non_neg_integer(), major_version: non_neg_integer(), metadata_offset: non_neg_integer(), metadata_size: non_neg_integer(), minor_version: non_neg_integer(), schema_checksum: non_neg_integer() }
Functions
@spec decode(F3.File.t(), non_neg_integer()) :: {:ok, t()} | {:error, F3.Error.t()}
Reads and checks the postscript of an open file.
max_metadata_bytes limits metadata_size and footer_size. Checksum
type 0 is :xxhash. Any other byte is {:unknown, byte} and is not
a reason to stop. Footer compression other than uncompressed is
:unsupported_encoding. A file shorter than 32 bytes is :truncated.
max must be a non-negative integer. This does not raise for a short file.
Examples
iex> {:ok, file} = F3.open("test/fixtures/small.f3")
iex> {:ok, post} = F3.Postscript.decode(file, F3.Postscript.max_metadata_bytes())
iex> {post.major_version, post.minor_version, post.footer_compression}
{0, 1, :uncompressed}
iex> {:ok, short} = F3.open({:memory, "no"})
iex> {:error, error} = F3.Postscript.decode(short, 32)
iex> error.category
:truncated
@spec max_metadata_bytes() :: pos_integer()
Default maximum metadata span, in bytes, for one decode/2 call.
Examples
iex> F3.Postscript.max_metadata_bytes()
16_777_216