Artifact b41df35dd82536fd998b3c220589265a8cc5498449b3f27a8fe83e3e27f33ac0:
- File
src/root.zig
— part of check-in
[949e2b5542]
at
2026-07-30 21:47:09
on branch trunk
— release_assert: a guard against assert used as input validation
std.debug.assert is right for an internal invariant and wrong for a rule about data the function did not produce, and it is wrong in two different ways. Under the ReleaseSafe default it survives and PANICS: on the write path that is the trade we want, a crash over a durable bad frame, but on a peer-reachable path it is a remote denial of service. Under an explicitly chosen --release=fast it compiles to nothing and the input flows through unvalidated. One fix, a checked error, closes both.
Flags an assert only when all of: the fn is pub, returns an error union so a rejection was already available, the assert names one of its own parameters, and no earlier return in the body already rejects on that parameter. That last rule is what makes it signal -- delta.applyCopy returns MalformedDelta and then asserts to restate it, which is the CORRECT shape and must not be flagged.
The baseline is keyed on file, function and COUNT, never on line numbers: line numbers churn on every edit above them, while a count still catches a second bad assert added to a function that already has one. It fails in both directions, so a fixed finding must be removed from the list and the list can only shrink.
Existing findings are recorded, not fixed. Triage belongs in issue 19, where the ReleaseSafe default already reduces the write-path subset to crash-instead-of-corrupt and leaves the sync-side ones as the live exposure. (user: dmestas, size: 6828) [annotate] [blame] [check-ins using]
//! zit — a Fossil version-control system implemented in Zig. //! //! zit is a direct port of the Fossil formats and protocol as specified by //! four companion Internet-Drafts, kept in `docs/rfcs/`: //! //! * delta — draft-fossil-delta-format-00 (byte-level delta encoding) //! * artifact— draft-fossil-artifact-format-00 (manifest/control-artifact cards) //! * reposta.— draft-fossil-repo-state-00 (derived branch/tag/leaf/trunk views) //! * sync — draft-fossil-sync-protocol-00 (HTTP sync/clone protocol) //! //! Implementation order follows the RFC dependency layering: //! delta -> artifact -> repostate -> sync //! //! Each module cites the section of its RFC that governs a given rule. const std = @import("std"); /// The §4.1 zlib container codec — a leaf below delta/artifact/repostate/sync, /// the single home for the container framing those layers store and transmit. pub const container = @import("container.zig"); pub const delta = @import("delta.zig"); pub const artifact = @import("artifact.zig"); pub const repostate = @import("repostate.zig"); pub const sync = @import("sync.zig"); pub const managed = @import("managed.zig"); /// The persistence layers, folded into the one embeddable `zit` module so a /// library consumer wires a single dependency instead of five peers: the /// content-addressed on-disk file (`storage`), the framed append-only log over /// it (`logstore`), the `.zit-checkout` working-state record (`checkout`), and /// the working-tree materializer (`update`). Circular file-level imports among /// these and the per-RFC modules are legal within one module; only cross-module /// edges may not cycle. pub const storage = @import("storage.zig"); pub const logstore = @import("logstore.zig"); /// The vendored CRC-32/ISO-HDLC every on-disk checksum in the store is defined /// in terms of. Exported for the same reason `storestat` is: the benchmark that /// measures the checksum must measure the one the product actually runs, and a /// file can belong to only one module — so `warmread_benchmark.zig` cannot /// import it by path. Not a promise about the algorithm; the guarantee is only /// that it is bit-identical to `std.hash.Crc32`, which the formats already fix. /// /// NOT a precedent for exporting other leaf modules — the default stays the one /// `repocache.zig` sets, which is no export. This line is forced rather than /// chosen: `crc32.zig` is a `zit` member (`logstore`, `repocache`, `bisect` and /// `undo` all import it by path), and its two out-of-module consumers — the /// benchmark's `phaseCrc` and `crc32_fuzz.zig`'s differential-against-std lane, /// both of which live in their own root modules — have no other way to reach /// it. `@import("crc32.zig")` from either is `error: file exists in modules /// 'zit' and 'root'`. Reverting this export does not close the surface; it /// deletes the only benchmark of the hot checksum and the only test in the tree /// that diffs against an outside oracle. Add an export here only when a leaf /// module acquires an out-of-module consumer with the same no-alternative /// shape. pub const crc32 = @import("crc32.zig"); /// The store's own byte accounting — the single physical frame walk behind /// both `zit stat` and the storage benchmark, so the two can never drift into /// reporting different totals for the same file. pub const storestat = @import("storestat.zig"); pub const checkout = @import("checkout.zig"); pub const update = @import("update.zig"); pub const bisect = @import("bisect.zig"); /// The `zit pack` re-deltification pass (storage-delta-base-selection.md §6): /// the pure store-to-store generational rewrite that re-bases every artifact /// through `logstore`'s `pickBase` policy. In the module so the CLI wiring /// (main.zig) and the DST/fuzz harnesses drive the identical transform. pub const pack = @import("pack.zig"); /// The repository facade — the deep module the north star names as the public /// repo surface: open a repository, resolve a name, read the derived view, list /// and cat content. `repoview` (the derived-view loader) is re-exported as its /// public collaborator; `repocache` stays library-internal, reached only /// through `Repository`. pub const Repository = @import("repository.zig").Repository; pub const repoview = @import("repoview.zig"); /// The zero-parse read image — the materialized hot query answers a warm read /// reloads without re-deriving. Re-exported for the simulation harness, which /// pins the round-trip property (a materialized image is query-equivalent to /// the derived state it was made from). pub const repoimage = @import("repoimage.zig"); pub const repo_filename = @import("repository.zig").repo_filename; /// Suite version of the specifications this implementation targets. pub const rfc_revision = "00"; test { // Aggregate every module's tests into the library test binary. _ = @import("container.zig"); _ = @import("container_test.zig"); _ = @import("delta.zig"); _ = @import("delta_test.zig"); _ = @import("artifact.zig"); _ = @import("artifact_test.zig"); _ = @import("repostate.zig"); _ = @import("repostate_test.zig"); _ = @import("sync.zig"); _ = @import("sync_test.zig"); _ = @import("managed.zig"); // The folded store layers and their sibling public-surface test files. _ = @import("storage.zig"); _ = @import("logstore.zig"); _ = @import("logstore_test.zig"); _ = @import("storestat.zig"); _ = @import("pack.zig"); _ = @import("checkout.zig"); _ = @import("update.zig"); _ = @import("update_test.zig"); // The repository facade and its derived-view collaborators. _ = @import("repoview.zig"); _ = @import("repoimage.zig"); _ = @import("repocache.zig"); // The vendored CRC-32/ISO-HDLC the storage formats are checksummed with. _ = @import("crc32.zig"); _ = @import("repository.zig"); _ = @import("repository_test.zig"); // The checkout-local bisection state module (`.zit-bisect`). _ = @import("bisect.zig"); // Structural pins over the shipped source distribution (LICENSE, the // package manifest's `.paths`, the versioned ignore-glob). _ = @import("packaging_test.zig"); // Structural pins over the CI workflow (the battery it runs, the pinned // toolchain, and the build steps it deliberately skips). _ = @import("ci_test.zig"); // The dead-file guard: every src/**/*.zig must be reachable from a test root, // so a moved file cannot silently stop running its tests. _ = @import("tidy.zig"); // The release-assert guard: no NEW `std.debug.assert` may stand in for // validation of untrusted input in a `pub fn` that returns an error union. _ = @import("release_assert_test.zig"); }