stet 0.4.1 — systemparams conformance fixes
Patch release. Two currentsystemparams values were wrong in every release
up to and including 0.4.0, and PDFs now record which build wrote them. No API
changes; no rendering changes.
Fixed
-
/PrinterNamereturned(stetIE)instead of(stet). The string was
allocated with the four bytes ofstetbut declared six bytes long, so
reading it ran two bytes into the next allocation — which happened to be
/RealFormat. Not memory-unsafe (the arena is a single buffer), but it put
a neighbouring allocation's bytes into a value any PostScript program can
read, and the value would have changed as soon as allocation order did. -
/RealFormatreturned(IEE)instead of(IEEE)— a missingEin
the literal, independent of the overrun above. The PLRM specifies this key
as naming the internal real representation, and Ghostscript reports
(IEEE).Both lengths are now derived from the literal rather than written out
twice, which is what allowed them to disagree. The other three
allocate-then-declare sites inContext::newwere audited and are correct.
Regression coverage inunit_tests/interpreter_param_tests.psasserts
lengths as well as contents — the contents alone read plausibly, and it was
the overrun that made them wrong.
Changed
- PDF
/Producernow carries the version, e.g.stet 0.4.1, where it
previously wrote a barestet. Every other producer does this —
Ghostscript writesGPL Ghostscript 10.05.1, Distiller
Acrobat Distiller 20.0— and it is the first thing checked when a
prepress shop is chasing a rendering difference between two files. A
pdfmark/DOCINFO /Produceroverride still takes precedence; this
changes only the default. Note that this alters bytes in the/Infodict
of every PDF stet writes, at every release. - Documented MSRV corrected to Rust 1.88. The README badge had claimed
1.85 since it was added — a number inferred fromedition = "2024"and
never compiled against. The real floor is 1.88: first-party code uses
let-chains in 282 places across nine crates,jpeg-encoderdeclares 1.87,
andfearless_simddeclares 1.86. Nothing about what stet requires has
changed; only the claim is now true.rust-version = "1.88"is declared in
[workspace.package]and inherited by all eleven first-party crates, so
cargo now reports a clear "requires rustc 1.88" instead of failing with a
confusing edition parse error on an older toolchain. - A pinned
MSRV 1.88CI job builds the workspace on exactly that toolchain
on every push, andscripts/check-release-versions.shnow ties the README
badge, the README prose, and the CI job's pin torust-versionso the four
cannot drift apart. The script also asserts every publishable crate
declares an MSRV, so none can reach crates.io without one. - Switched to
resolver = "3"(MSRV-aware dependency resolution). Cargo
now prefers dependency versions compatible with the declared
rust-versionrather than always taking the newest, so a routine
cargo updatecan no longer silently break the floor. The lockfile was
byte-identical on adoption, but this is already doing work: it holds back
hayro-jpeg20000.4.0 (needs 1.92) andmoxcms0.9.0 (needs 1.89).
Note for downstream users
Releases up to and including 0.4.0 published with no rust-version in their
manifests, so crates.io and docs.rs show no MSRV for them and cargo cannot
warn an old toolchain before it fails to compile. Published versions are
immutable; this release is the first to carry the metadata.