Skip to content

Deferred libeot-parity items (cosmetic / by-design divergences) #7

Description

@ChristopherVR

Tracking the low-severity findings from the libeot (MPL-2.0) parity review that were deliberately not changed in #5 / #6 — each is either cosmetic, unreachable on valid input, or an intentional JS-idiom divergence. Recorded so they aren't re-discovered as "bugs".

1. No EOT_OFF_BYTE_BOUNDARY enforcement (stream.ts)

libeot rejects a byte-level read/write/seek when the stream is mid-byte (bitPos != 0); it also refuses to reset bitPos on seek. Our Stream silently tolerates both. Unreached today: the only readNBits caller (ctf-parser glyph decoding) consumes whole bytes per point, so the stream is always byte-aligned at the boundary. Low value; would add guards to every byte accessor.

2. Bounding-box accumulator skips the int16 wrap (ctf-parser.ts)

libeot accumulates the int16-truncated coordinate delta into the running bbox min/max; we accumulate the raw value. Divergence is reachable only via the 16-bit triplet encodings (indices 124–127) with a raw delta > 32767 and a positive sign — which no sane encoder emits (it would use a smaller encoding). Affects only the computed bounding box, and only on malformed input. libeot's own code is itself sloppy here (implicit unsigned -> int16_t narrowing).

3. *ThroughReserve / copyTo grow instead of erroring (stream.ts)

libeot returns EOT_OUT_OF_RESERVED_SPACE / EOT_SEEK_PAST_EOS when a write/seek exceeds the reserved capacity; our Stream auto-grows (the natural JS idiom). Intentional — but it converts libeot's "reserved space exhausted" failure signal into a silent realloc. Kept as-is because auto-growth is the expected behavior for a JS builder.

4. sfnt-builder treats head as optional

dumpContainer patches head.checksumAdjustment inside if (headTable). Since parseCTF now requires head (v1.5.0), this branch is belt-and-suspenders — a head-less container can no longer reach it. Could be tightened to a hard error for defense in depth. Cosmetic.

5. Silent hdmx/VDMX skip

libeot logs a warning ("Ignoring hdmx/VDMX table — will be fixed in a future release") when it drops these tables; we drop them silently. The skip itself is correct. Purely a diagnostics gap.

Non-issues (confirmed, listed to close the loop)

  • No adaptive-Huffman rescale: libeot has none either (weight is a long; JS numbers are exact past any reachable input). Not a gap.
  • EOT_WARN_NOT_ENOUGH_GLYPHS / NOT_ENOUGH_SPACE_RESERVED: the flags that would raise these are initialized false and never assigned in libeot — dead code upstream, so their absence here is not a gap.

None of these affects a valid-input decode. Filing for traceability; happy to pick any up if they become load-bearing.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions