Files
lightcraft/crates/tiff/README.md
T
Alex ChambersandClaude Opus 5.5 8feda7a997 LR-IMP-FORMATS: the TIFF reader's next-IFD pointer no longer overflows on huge BigTIFF entry counts
Pre-existing on main. The reader computed the position of a directory's next-IFD pointer before it
checked that every declared entry had been read: a saturating multiplication of the declared count,
then an unchecked addition. A 44-byte BigTIFF declaring u64::MAX entries therefore panicked with
overflow checks on. The position is now computed only for a directory read whole, with checked
arithmetic.

32-bit note: the same guard compared the counts after narrowing the declared one to usize, so on
wasm32 a BigTIFF declaring 4,294,967,297 entries but holding one passed for a whole directory and its
next pointer was followed. The counts now compare as 64-bit numbers (reads_every_entry). On wasm32 the
old comparison followed all six malformed test chains and the new one follows none; 64-bit results
are unchanged for every directory whose count is read whole.

Regression tests (crates/tiff/src/reader.rs):
a_bigtiff_directory_declaring_u64_max_entries_parses_without_overflow, which panicked before;
a_bigtiff_count_past_u32_max_never_follows_the_next_pointer (the whole chain, on every target); and
only_a_directory_read_whole_has_a_next_pointer (the comparison itself, on every target).

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-14 08:40:42 +02:00

43 lines
2.8 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# lightcraft-tiff (L0)
TIFF / IFD reader and writer. Used by `lightcraft-raw` (DNG, CR2, NEF, ARW…), `lightcraft-meta` (Exif) and
later the TIFF/DNG exporters.
## Features
- Classic TIFF and BigTIFF, little- and big-endian (`II`/`MM`). Also accepts the TIFF-like magic numbers of
some raw formats (ORF `IIRO`/`IIRS`, RW2 `IIU`) when `ParseOptions::accept_raw_magic` is set (default).
- Every field type: BYTE, ASCII, SHORT, LONG, RATIONAL, SBYTE, UNDEFINED, SSHORT, SLONG, SRATIONAL, FLOAT,
DOUBLE, IFD, LONG8, SLONG8, IFD8.
- IFD chain + `SubIFDs` (330) + Exif (34665) / GPS (34853) / Interoperability (40965) pointer IFDs, resolved
into a tree (`Ifd::sub_ifds`, `exif`, `gps`, `interop`). `Entry::offset` records the absolute position of
each value (needed for maker notes and embedded blobs).
- `parse_ifd_at(data, offset, order, base, bigtiff, opts)` parses an IFD whose offsets are relative to an
arbitrary base; `makernote::parse_makernote` knows the header / byte-order / offset-base conventions of
Canon, Nikon (types 1 and 3), Sony, Fujifilm, Olympus (old and new), Panasonic and Pentax notes.
- `image::ImageInfo` — width/height, bits, samples, compression, photometric, planar config, predictor,
sample format and the strip or tile chunk list (`chunks()`, `chunk_bytes()`); missing byte counts are
inferred.
- `directory_entries`, `entry_span`, `ParseOptions::budget_for` and `decode_value` are the reader's own rules
(directory layout and entry limit, which entries it reads, its value budget, value decoding), for callers that
must select entries exactly as `parse_ifd_at` would without decoding the whole directory (`lightcraft-raw`'s
Sony `SR2Private` lookup).
- `TiffWriter` writes IFD chains with strips or tiles, `SubIFDs` and pointer IFDs, in either byte order,
classic or BigTIFF; `writer::rational` / `srational` approximate floats as rationals.
## Robustness
The reader never panics on malformed input (proptests feed random and mutated files): offsets are
bounds-checked; out-of-range or unknown-type entries are skipped; IFD loops are detected; IFD count,
nesting depth and entries per IFD are limited; a next-IFD pointer is followed only when every declared entry was
read, with the counts compared as 64-bit numbers (a BigTIFF declaring 4,294,967,297 entries but holding one can't
pass for a whole directory on a 32-bit target); the total bytes of decoded values are capped at
`8 × input + 1 MiB` so a file cannot make us allocate far more than its own size.
## Sources
Public specifications only: TIFF 6.0 (Adobe, 1992), the TIFF 6.0 supplements (IFD type, SubIFDs), the
BigTIFF format description (AWare Systems), Adobe DNG Specification 1.7 (tag numbers), CIPA DC-008 Exif 2.32,
and the ExifTool tag-name documentation (maker-note header conventions, prose only). No third-party code
was consulted.