diff options
| author | Ralph Amissah <ralph.amissah@gmail.com> | 2026-09-21 08:58:06 -0400 |
|---|---|---|
| committer | Ralph Amissah <ralph.amissah@gmail.com> | 2026-09-22 13:46:31 -0400 |
| commit | f89f0152a913cec14c6ee688a4f1b2ac7c4758ff (patch) | |
| tree | 9701dd52ec89b5a8e5431eb1dbd29d2c6c349d2c /derivation.nix | |
| parent | odt: office:meta from the document, not the run (diff) | |
pod: read when zstd-wrapped
sisupod using zstd compression recognised by first bytes.
<doc>.sisupod: spine reads one before it writes one, so when the name
changes (from .zip to .ssiupod) every pod already published stays
readable.
A .sisupod is one zstd frame wrapping the archive spine already builds.
The reader unwraps the bytes and hands the same archive to the same
parser, so every guard downstream is untouched: entry names, per-entry
and total size, path depth, escape and symlinks.
Which container it is comes from the first four bytes (rather than the
name). A pod published as a plain .zip reads as it always did, a
.sisupod reads, and either one renamed reads too. The suffix is still
recognised, both spellings, for the argument and for a url.
libzstd is declared rather than bound: provides the whole surface of
fifteen extern C prototypes (there is nothing to generate and no
upstream tree to track, which is the arrangement sqlite3 already has).
dub links it with "libs": [ "zstd" ]; nix needs zstd.out rather than
zstd, whose default output is the binaries and carries no library at
all.
A frame declares its uncompressed size in its own header, and for a pod
fetched over https that number is attacker controlled. The declared size
is checked against a ceiling before a buffer is asked for, a frame that
will not declare one is refused, and what comes out is checked against
what was promised. The ceiling is the extraction limit the archive
reader already applies, so the two bounds agree.
Measured: output built from a .sisupod is byte identical to output built
from the same pod's .zip, 359 files over text, html, epub, odt and .ssp
for three documents, live-manual's ten languages included. A truncated
frame is refused and the document skipped.
free_culture 2863504 -> 1099736 2.60x
the_wealth_of_networks 4294022 -> 1172649 3.66x
live-manual 6972418 -> 675970 10.31x
(assisted by Claude-Code)
Diffstat (limited to 'derivation.nix')
| -rwxr-xr-x | derivation.nix | 2 |
1 files changed, 1 insertions, 1 deletions
diff --git a/derivation.nix b/derivation.nix index 6619dc9..9b5e0ff 100755 --- a/derivation.nix +++ b/derivation.nix @@ -91,7 +91,7 @@ with ( version = "0.24.1"; src = ./.; nativeBuildInputs = with pkgs; [dub ldc]; - buildInputs = with pkgs; [nixVersions.latest sqlite]; + buildInputs = with pkgs; [nixVersions.latest sqlite zstd.out]; meta = with pkgs.lib; { description = "A sisu like parser & document generator"; longDescription = '' |
