Skip to content

Re-review remainders: preservation edges, staging sweep, path validation, module policy #126

Description

@kostyafarber

Grab-bag of lower-severity confirmed/plausible items from the 2026-07 re-review, tracked so they don't evaporate:

Preservation edges (UFO round-trip):

  • Point/contour/guideline identifier attributes are not carried — tools use these for cross-file references.
  • public.objectLibs per-object lib data: norad extracts it at load; Shift drops the extracted per-object libs on conversion — silent loss.

Write-path hardening:

  • Crash between staging and swap leaks .shift-ufo-staging-* dirs next to the user's font; no sweep on later saves. Add opportunistic cleanup of stale staging dirs (age-checked) during save.
  • exchange_unsupported treats macOS EINVAL as "filesystem unsupported" — a genuine EINVAL silently degrades atomicity to the two-rename fallback. Consider logging when the fallback engages.
  • .shift save side never validates data//images/ keys (load side does) — a hostile/odd key saves fine and then makes the package unopenable by Shift's own reader. Validate at save; also consider a size cap / duplicate-entry rejection on load, and note the a\..\b Unix-component edge that becomes traversal if a package moves to Windows.
  • font_binaries rows loaded from a corrupted working store have no path validation (font_state.rs load path) — trusted-store-only exposure, one-line check.

Policy coherence:

  • .shift's strict UnexpectedEntry rejection vs. the modules extensibility story: adding modules/shift.fontInfo.json means pre-feat: UFO round-trip preservation contract #119 readers reject new packages with a generic error, and any unknown module (including future third-party ones) is rejected. Decide: strict rejection wins (bump package schema version on every module addition) or unknown modules/* entries are preserved-and-ignored. Write the decision into the format spec.
  • Binary reader's closing-point dedup removes genuinely stored coincident points (geometry identical, point count changes) — irrelevant until point-indexed data (gvar) is consumed; note for the variable-font pipeline.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions