Releases: excelano/slpc-rust
Release list
0.3.11 - 2026-08-31
Release Notes
Added
-
Container::payload_crc, the CRC-32 the ZIP central directory already
records for the payload member. Read in the same pass as the name, the size
and the kind, so it decompresses nothing and needs no&mut, and it refuses
the waypayload_sizedoes for a container declaring a version this build
does not implement.It answers one question: whether a file on disk is the one that came out of
this container. A caller that extracted a payload earlier and wants to know
whether it has been edited since had no way to ask without keeping a record of
what it wrote — a second copy of a fact, which can drift from the fact, and
which is least trustworthy at the moment such a record is usually consulted:
after something went wrong. The container's own value needs nothing
maintaining it, because repacking recomputes it.Documented as the ZIP field it is. SPEC 5 defines no checksum or fixity
key, and this is not one arriving by another road. A format library exposing a
checksum invites the reading the specification declined to license, so the doc
comment says what it does not answer as plainly as what it does.
Install slipcase 0.3.11
Install prebuilt binaries via shell script
curl --proto '=https' --tlsv1.2 -LsSf https://github.com/excelano/slpc-rust/releases/download/v0.3.11/slipcase-installer.sh | shInstall prebuilt binaries via powershell script
powershell -ExecutionPolicy Bypass -c "irm https://github.com/excelano/slpc-rust/releases/download/v0.3.11/slipcase-installer.ps1 | iex"Install prebuilt binaries via Homebrew
brew install excelano/tap/slipcaseDownload slipcase 0.3.11
| File | Platform | Checksum |
|---|---|---|
| slipcase-aarch64-apple-darwin.tar.xz | Apple Silicon macOS | checksum |
| slipcase-x86_64-apple-darwin.tar.xz | Intel macOS | checksum |
| slipcase-x86_64-pc-windows-msvc.zip | x64 Windows | checksum |
| slipcase-aarch64-unknown-linux-gnu.tar.xz | ARM64 Linux | checksum |
| slipcase-x86_64-unknown-linux-gnu.tar.xz | x64 Linux | checksum |
0.3.10 - 2026-08-28
Release Notes
Added
-
Mark::Recorded, and an origin note that survives what the App Sandbox
destroys. Under the sandbox the platform marks whatever the calling process
writes and refuses to have that mark replaced, socarryreported
AlreadyMarkedand the source's value was lost. The gate was never the
problem — the copy is gated whoever marked it — but the answer to where did
it come from was, and a caller that reports provenance could no longer tell a
container that arrived from elsewhere from one made on the machine. Found in
slipcase-desktop, where saving an edit to a downloaded container made the
card's arrived from elsewhere line disappear.carrynow keeps the source's quarantine value verbatim under
com.excelano.slipcase.originwhen the platform refuses to carry it, and
answersMark::Recordedrather thanMark::AlreadyMarkedwhen it did.
arrived_from_elsewhereconsults the note.carries_a_markdeliberately does
not: the note gates nothing, nothing outside this crate reads it, and a
caller deciding whether to hand a payload to the system must not read our own
writing as the platform's word.Three things measured inside a bundle signed with the sandbox entitlement
rather than assumed: the refusal is specific tocom.apple.quarantineand an
attribute of our own goes on without complaint; the note survives
-[NSFileManager replaceItemAtURL:], which is the operation that destroys the
attribution; and no supported API preserves the original attribution, since
NSURL'squarantinePropertiesKeysucceeds and then substitutes the calling
process as the agent.macOS only. Windows can reach the same branch and does nothing there yet, for
want of a measurement; Linux cannot reach it, because itscarrynever fails.
Nothing changes for a caller that is not sandboxed.Markis#[non_exhaustive], so the new variant is not a breaking change for
anyone matching on it.
Install slipcase 0.3.10
Install prebuilt binaries via shell script
curl --proto '=https' --tlsv1.2 -LsSf https://github.com/excelano/slpc-rust/releases/download/v0.3.10/slipcase-installer.sh | shInstall prebuilt binaries via powershell script
powershell -ExecutionPolicy Bypass -c "irm https://github.com/excelano/slpc-rust/releases/download/v0.3.10/slipcase-installer.ps1 | iex"Install prebuilt binaries via Homebrew
brew install excelano/tap/slipcaseDownload slipcase 0.3.10
| File | Platform | Checksum |
|---|---|---|
| slipcase-aarch64-apple-darwin.tar.xz | Apple Silicon macOS | checksum |
| slipcase-x86_64-apple-darwin.tar.xz | Intel macOS | checksum |
| slipcase-x86_64-pc-windows-msvc.zip | x64 Windows | checksum |
| slipcase-aarch64-unknown-linux-gnu.tar.xz | ARM64 Linux | checksum |
| slipcase-x86_64-unknown-linux-gnu.tar.xz | x64 Linux | checksum |
0.3.9 - 2026-08-27
Release Notes
An adversarial review of the same day's hardening, which found that the
hardening was incomplete and that one of its fixes did not fire.
Security
-
A member could still be renamed out from under the uniqueness check. 0.3.8
refused three ways a crafted end of central directory record could make this
crate and its ZIP dependency resolve different directories. There was a
fourth, and it is inside a single well-formed entry where no record-level
guard can see it: the Info-ZIP Unicode Path extra field, tag 0x7075, carries a
replacement name and the ZIP crate applies it, whilecentral.rsskipped
extra fields and counted the recorded name. Three members with distinct
recorded names — the third renaming itself to the second's — came back
conformant and unpacked to the third's bytes, while Python'szipfilesaw two
members of one name. The metadata member is swappable the same way.Refused rather than honoured, which is the decision §2.1 has now taken four
times. Honouring it would make the field a third way to spell a member's name,
after the name field and the bit 11 encoding SPEC §2.1 defines, and that is a
change to the format rather than a fix to a reader. Measured against the tools
available: Info-ZIP writes 0x5455 and 0x7875 even with-UN=UTF8, 7-Zip
writes 0x000a, Python writes none. Those fields are untouched. -
The provenance carry added in 0.3.7 did not fire on a read-only container.
commitset the replacement's permissions — taken from the file being
replaced — before carrying the mark onto it, so a container at 0444 made the
temporary read-only andxattr::setwas then denied. Measured: a marked
container at 0444 came back fromrepackwith no mark, silently, exit zero.
Where a platform enforces the mark it is worse: the carry fails,commit
propagates it, and an in-place rewrite of any read-only marked container fails
outright. The carry now runs first. The test that should have caught this used
a default-mode file. -
A failed
unpack --metadatano longer leaves the metadata behind. 0.3.8
reordered the commits so a refusal leaves no payload; the inverse was left
standing, so a payload that could not land left a metadata file the error
never mentioned and the obvious retry then failed on it.
Fixed
display_nameescapes a backslash, so its rendering is reversible. A name
that literally spellsreport\u{202E}fdp.exeand one carrying the override
used to come out identical.
Install slipcase 0.3.9
Install prebuilt binaries via shell script
curl --proto '=https' --tlsv1.2 -LsSf https://github.com/excelano/slpc-rust/releases/download/v0.3.9/slipcase-installer.sh | shInstall prebuilt binaries via powershell script
powershell -ExecutionPolicy Bypass -c "irm https://github.com/excelano/slpc-rust/releases/download/v0.3.9/slipcase-installer.ps1 | iex"Install prebuilt binaries via Homebrew
brew install excelano/tap/slipcaseDownload slipcase 0.3.9
| File | Platform | Checksum |
|---|---|---|
| slipcase-aarch64-apple-darwin.tar.xz | Apple Silicon macOS | checksum |
| slipcase-x86_64-apple-darwin.tar.xz | Intel macOS | checksum |
| slipcase-x86_64-pc-windows-msvc.zip | x64 Windows | checksum |
| slipcase-aarch64-unknown-linux-gnu.tar.xz | ARM64 Linux | checksum |
| slipcase-x86_64-unknown-linux-gnu.tar.xz | x64 Linux | checksum |
0.3.8 - 2026-08-27
Release Notes
Findings from a security review of all three repositories, run the same day.
Everything here was measured against a fixture, and every fix was checked by
breaking it and watching the test that guards it fail.
Security
-
A crafted end of central directory record could hide a duplicate member from
the check SPEC §3 requires. This crate resolves the central directory twice:
once here, to count names the ZIP crate cannot see, and once in that crate,
for every byte anything reads. Three fields in that record could be made to
split the two, so uniqueness was established over one set of members while the
payload came from another — the ambiguity SPEC §3's enumeration rule exists to
prevent, arriving through the rule's own implementation.The counts. The record carries entries-on-this-disk and entries-in-total; this
crate read the total and the ZIP crate reads the count on this disk. A record
declaring 3 and 2 was counted here as two members and served by the crate as
three, so a secondreport.pdfpassed a conformant verdict and was the one
extracted.The comment length. Overrun it and a reader taking the last signature it finds
parts company with one that checks the length and keeps looking. Measured:
this crate served the first archive in a file and Python'szipfilethe
second, with a conformant verdict on it.The Zip64 sentinel. The ZIP crate goes looking for a Zip64 record when the
directory size field is saturated; this crate did not, so setting only that
field pointed the two at different records.Chasing the crate's behaviour field by field is not the fix, because the next
field is the next bug.central.rsnow refuses any record that is not
internally consistent: it must end the file, its two counts must agree, the
archive must be single-disk, and the Zip64 gate matches the crate's. SPEC §2.1
states the same rule, with three corpus cases in a class that had none. -
slipcase unpack --metadatacould leave the payload on disk, unmarked,
while reporting failure. Both destinations are reserved before either is
written, and the code said that made this impossible. Reserving is a check and
committing is the guarantee:Destination::newasks whether the path exists
and a dangling symbolic link answers no, so the refusal arrived at the
no-clobber rename — after the payload had been committed and before provenance
was carried. One planted link in a directory somebody unpacks into was enough.
The metadata commits first now, so a failure there leaves nothing at all. -
slipcase repack -o -wrote provenance onto a file named-. The carry
added in 0.3.7 guarded-on the input and not on the output, so with the
container going to standard output the mark went to a real file of that name
in the working directory — and on Windows, where the mark is an alternate data
stream reached throughstd::fs, it would have created one.
Changed
Destination::in_place's documentation now names hard links alongside
ownership as something a rename cannot carry: a container reachable under two
names is rewritten under only the one it was opened by.
Install slipcase 0.3.8
Install prebuilt binaries via shell script
curl --proto '=https' --tlsv1.2 -LsSf https://github.com/excelano/slpc-rust/releases/download/v0.3.8/slipcase-installer.sh | shInstall prebuilt binaries via powershell script
powershell -ExecutionPolicy Bypass -c "irm https://github.com/excelano/slpc-rust/releases/download/v0.3.8/slipcase-installer.ps1 | iex"Install prebuilt binaries via Homebrew
brew install excelano/tap/slipcaseDownload slipcase 0.3.8
| File | Platform | Checksum |
|---|---|---|
| slipcase-aarch64-apple-darwin.tar.xz | Apple Silicon macOS | checksum |
| slipcase-x86_64-apple-darwin.tar.xz | Intel macOS | checksum |
| slipcase-x86_64-pc-windows-msvc.zip | x64 Windows | checksum |
| slipcase-aarch64-unknown-linux-gnu.tar.xz | ARM64 Linux | checksum |
| slipcase-x86_64-unknown-linux-gnu.tar.xz | x64 Linux | checksum |
0.3.7 - 2026-08-27
Release Notes
Added
Limits::DEFAULT, the defaults as a constant.Default::defaultis not
constand the struct is#[non_exhaustive], so without it a caller outside
this crate cannot say the defaults, with this one changed in aconst—
which is where a caller with a considered bound wants to put it.
Security
-
Rewriting a container in place no longer launders it.
Destination::in_place
replaces a file the way an editor does: it writes a fresh file beside the
original and renames it over the top. A fresh file carries no mark, so
whatever the platform had recorded about where the original came from —
com.apple.quarantine, aZone.Identifierstream,user.xdg.origin.url—
was gone the moment anything rewrote the container.slipcase repack --meta
on a container marked as downloaded returned it unmarked, and every payload
unpacked from it afterwards was unmarked too, becauseprovenance::carry
copies from the container. True sincein_placeexisted.This is the defect 0.3.5 fixed on the unpacking side arriving through a door
nobody had looked at.commitnow carries the mark onto the replacement
before the rename, so the file that appears at the path is complete at the
instant it appears.Destination::newis unchanged and inherits nothing: a
caller naming an output file is creating one, there is no original whose
origin it takes, and inventing one would be claiming a download that never
happened. That is the linenewalready took about permissions.slipcase repack -o <new>carries it too, in the CLI rather than the library,
because only the caller knows which container the bytes came out of. It warns
rather than failing where it cannot: what the failing rule inunpackguards
is a payload about to be handed to the operating system, and a container is
opened by nothing but this tool, which reports provenance rather than acting
on it.
Changed
-
The default metadata bound is 1 MiB, down from the 16 MiB 0.3.6 shipped a
few hours earlier. That number rested on an estimate — that a parsed
document costs several times its source — which was wrong by more than an
order of magnitude. Measured against the densest conformant shape, shortest
legal keys and shortest legal values: 256 KiB of metadata parses to 22 MB
resident and 1 MiB to 85 MB, about 85 times, becausetoml_editkeeps a key's
decor, span and representation so that a rewrite can put back what it did not
touch. 16 MiB was therefore about 1.4 GB parsed, and several times that again
in anything that renders the document.The multiplier follows key count rather than size, so the number is chosen
against the dense shape. 1 MiB costs 85 MB at worst and is generous against
every legitimate document: the format defines two keys, SPEC §2.2's example is
four lines, and the largest metadata member in the conformance corpus is
64 KiB. -
fsimpliesprovenance. Not convenience: without the carry above,
enablingfsin order to replace containers is enabling a laundering bug, and
a security property should not depend on a caller having guessed that a second
feature was involved. It costs one crate on Unix —xattritself, whose tree
ofrustix,bitflagsandlinux-raw-systempfilealready brings in — and
nothing on Windows, where an alternate data stream is reached through
std::fs. The other direction is unchanged:provenancedoes not implyfs.
Install slipcase 0.3.7
Install prebuilt binaries via shell script
curl --proto '=https' --tlsv1.2 -LsSf https://github.com/excelano/slpc-rust/releases/download/v0.3.7/slipcase-installer.sh | shInstall prebuilt binaries via powershell script
powershell -ExecutionPolicy Bypass -c "irm https://github.com/excelano/slpc-rust/releases/download/v0.3.7/slipcase-installer.ps1 | iex"Install prebuilt binaries via Homebrew
brew install excelano/tap/slipcaseDownload slipcase 0.3.7
| File | Platform | Checksum |
|---|---|---|
| slipcase-aarch64-apple-darwin.tar.xz | Apple Silicon macOS | checksum |
| slipcase-x86_64-apple-darwin.tar.xz | Intel macOS | checksum |
| slipcase-x86_64-pc-windows-msvc.zip | x64 Windows | checksum |
| slipcase-aarch64-unknown-linux-gnu.tar.xz | ARM64 Linux | checksum |
| slipcase-x86_64-unknown-linux-gnu.tar.xz | x64 Linux | checksum |
0.3.6 - 2026-08-27
Release Notes
Everything here follows excelano/slipcase's reader-side hardening of the same
day, which added four requirements to SPEC §3 and a Security Considerations
section as SPEC §6. Two of the four this library already satisfied and now
proves it does; the other two are new work.
Security
-
A hostile metadata member no longer costs whatever it likes. Identifying a
container means decompressing the metadata member and parsing it as TOML, so a
reader spends the memory before it knows whether the file was a container at
all — which is not the position of a general ZIP consumer, who chooses what to
extract. Measured before the fix: a 204,151-byte container whose metadata
member deflates at a little over a thousand to one cost 620 MB resident here
and 1,020 MB in the desktop viewer, took 0.61 seconds, and was reported
conformant. At 1,019,488 bytes it was 5,019 MB and 5.1 seconds.Limitsbounds it, defaulting to 16 MiB, and the four entry points that read
a metadata member gained a_withtwin that takes one:Container::read_with,
Container::open_with,validate_withandmetadata_of_with. The same two
containers now cost 11 MB and 0.00 seconds. A container over the bound is
Verdict::Undetermined, neverNonConformant, because the bound belongs to
the reader: answering non-conformant would publish this build's configuration
as a property of somebody else's file, and two readers with different bounds
would then disagree about conformance.The size a central directory records is not the bound and cannot be. Measured
againstzip8.6: a directory rewritten to declare 100 bytes for that same
member still inflated the whole of it and still cost 621 MB, because nothing
in ZIP checks the two against each other. It is read first because it refuses
the ordinary case without spending anything, and the guarantee is the bound on
the bytes as they arrive.The parse-depth half of SPEC §6 is
toml_edit's and is already met. Measured
across nested arrays, nested inline tables, dotted keys and table headers: it
accepts nesting to depth 80 and refuses 81, with an error naming a recursion
limit rather than a stack overflow. -
display_nameescapes the Unicode bidirectional formatting characters.
SPEC §2.3 permits them inpayload.fileand DESIGN says why — they are legal
on every filesystem and a writer may hold a file that genuinely has one — so
SPEC §3 puts the rule on the display, where the problem is. A payload called
report<U+202E>fdp.exereads asreport.pdfwherever the override is applied,
beside whatever offers to open it.slipcase validatenow names the payload through it.slipcase infosplits
the waylsandgitsplit: redirected into a file or a pipe it still
reproduces the member byte for byte, which is what a caller redirecting it
asked for, and onto a terminal it escapes — a terminal being the one place
these characters are applied, and an unterminated override running to the end
of the paragraph rather than the end of the value it sat in.
Added
-
Container::payload_mode— the permission bits the archive records for
the payload, where it records any, with the file-type bits masked off. For
saying and not for applying: SPEC §3 forbids putting an archive's recorded
mode on an extracted file, and this exists so that something can tell a person
a payload was executable where it came from and that their copy will not be.Ok(None)where the container says nothing, which is the common case and the
reason this reads the external attributes off the central directory rather
than asking the ZIP crate. The crate'sunix_modeinvents a mode for an
archive made on DOS —S_IFREG | 0o664, or0o444where the read-only bit is
set — which for its purposes beats nothing and here would mean every container
written by a Windows tool got a confident answer to a question it never
answered.
Changed
RawNamebecameRecordedinternally, carrying the external attributes
alongside the name it was already reading from the same header. Not public.
Fixed
cargo test --all-featuresinside the published crate would not compile,
in 0.3.5 and in this release until it was caught.testsupportis a path
dev-dependency andcargo packagestrips a path dependency it cannot resolve,
so the test files using it referenced a crate the packaged manifest no longer
declared. That is what anybody vendoring or auditing the crate runs.
slpc/tests/provenance.rsandslipcase/tests/cli.rsare now excluded from
their packages rather than shipped broken: the helper they need marks a file
the way a platform's downloader does, and it is shared precisely because two
copies of it disagreed about the Windows arm within an hour, so inlining a
third would undo that on purpose. Those tests need the workspace and stay in
it.
Notes
Two SPEC §3 requirements were already met and are now pinned by tests rather
than by luck. Extraction refuses to replace an existing file through an atomic
no-clobber rename rather than a check before the write, and the new test stands
the race still: the file arrives after Destination::new returned and commit
still refuses. Nothing applies an archive's permission bits, structurally —
Container::payload hands back a reader and Destination takes a path, and the
two never meet — and the new test would catch somebody wiring them together,
which is a two-line change and more tempting now that payload_mode exists.
Install slipcase 0.3.6
Install prebuilt binaries via shell script
curl --proto '=https' --tlsv1.2 -LsSf https://github.com/excelano/slpc-rust/releases/download/v0.3.6/slipcase-installer.sh | shInstall prebuilt binaries via powershell script
powershell -ExecutionPolicy Bypass -c "irm https://github.com/excelano/slpc-rust/releases/download/v0.3.6/slipcase-installer.ps1 | iex"Install prebuilt binaries via Homebrew
brew install excelano/tap/slipcaseDownload slipcase 0.3.6
| File | Platform | Checksum |
|---|---|---|
| slipcase-aarch64-apple-darwin.tar.xz | Apple Silicon macOS | checksum |
| slipcase-x86_64-apple-darwin.tar.xz | Intel macOS | checksum |
| slipcase-x86_64-pc-windows-msvc.zip | x64 Windows | checksum |
| slipcase-aarch64-unknown-linux-gnu.tar.xz | ARM64 Linux | checksum |
| slipcase-x86_64-unknown-linux-gnu.tar.xz | x64 Linux | checksum |
0.3.5 - 2026-08-26
Release Notes
Security
-
slipcase unpackno longer launders where a container came from. A
container downloaded from the internet is marked as such by the platform that
downloaded it —com.apple.quarantineon macOS, aZone.Identifierstream on
Windows,user.xdg.origin.urlon Linux — and all three are properties of the
file rather than of its contents. The payload written out of it carried none
of them, so whatever opened that payload next saw a file this machine made and
the warning the container would have raised never appeared. That has been true
since 0.1.0.provenance::carry, behind the newprovenancefeature, moves the mark
across, andunpackcalls it. It fails only where the platform gates opening
on a mark, the source carries one, and the copy ends up carrying none — so for
a caller about to hand a payload to the system, an error means do not open it.
Whereunpackmeets that failure it removes the payload rather than leaving
one that opens without the warning its origin earned. A container read from
standard input has no source to read a mark from and is unpacked without one.Linux is a note rather than a gate: nothing there consults the attribute
before opening a file, andMark::Notedis a separate answer so that nothing
reads one as the other.
Fixed
-
A payload named for a Windows device now extracts as a file. SPEC 2.3
acceptsCON,COM1,AUX,LPT1,PRNandNUL, and the conformance
corpus carries a case for one, but Win32 resolves those names to devices
wherever they appear.dest.join(payload_name())was therefore not a path in
that directory — it was the console. WritingCONreturned success at every
step and left no file, and reading it back never returned at all, so
slipcase unpackon such a container hung rather than failing.payload_pathaskscanonicalizeof the directory and joins the name onto
the answer, which reaches the filesystem without those names being looked for.
Nothing holds a list of reserved names: which names are devices stays
Windows's to know. Asking the shell to open such a file still fails, which
is the truth about that container on that platform.
Added
-
payload_pathanddisplay_path, with thefsfeature. The first is
above; the second takes the\\?\prefix off a path before a person reads it,
since that prefix is how a path is addressed rather than part of its name.
Note that on Windowspayload_pathreports where the file is rather than how
the caller spelled it:canonicalizeexpands 8.3 short names and resolves
junctions, so a caller comparing its result against a path of their own must
compare files and not strings. -
The
provenancefeature, off by default and separate fromfs. It adds
no crates on Windows, where an alternate data stream is reached through
std::fs, and on Unix one crate on top offsor four on its own —fs
already bringsxattr's tree ofrustix,bitflagsandlinux-raw-sysin
throughtempfile.provenance::arrived_from_elsewhereis there for a
caller that wants to report where a container came from rather than act on it.
Changed
Markis#[non_exhaustive], as every other public enum in the crate is.
What a platform records about a downloaded file is that platform's to change.
Install slipcase 0.3.5
Install prebuilt binaries via shell script
curl --proto '=https' --tlsv1.2 -LsSf https://github.com/excelano/slpc-rust/releases/download/v0.3.5/slipcase-installer.sh | shInstall prebuilt binaries via powershell script
powershell -ExecutionPolicy Bypass -c "irm https://github.com/excelano/slpc-rust/releases/download/v0.3.5/slipcase-installer.ps1 | iex"Install prebuilt binaries via Homebrew
brew install excelano/tap/slipcaseDownload slipcase 0.3.5
| File | Platform | Checksum |
|---|---|---|
| slipcase-aarch64-apple-darwin.tar.xz | Apple Silicon macOS | checksum |
| slipcase-x86_64-apple-darwin.tar.xz | Intel macOS | checksum |
| slipcase-x86_64-pc-windows-msvc.zip | x64 Windows | checksum |
| slipcase-aarch64-unknown-linux-gnu.tar.xz | ARM64 Linux | checksum |
| slipcase-x86_64-unknown-linux-gnu.tar.xz | x64 Linux | checksum |
0.3.4 - 2026-08-21
Release Notes
Fixed
-
Repointing
payload.fileno longer discards the comment and the whitespace
around it, and no longer runs when the value has not changed.Repack
documents that a document handed to it is serialized without losing comments,
key order, or whitespace, and that held for every key except the one the
library edits itself. Setting the key dropped a fresh item over the old one,
which takes the decortoml_editkeeps beside a value with it, so replacing a
payload under a new name silently deleted whatever a person had written after
file = "...", and a container whose metadata is a multi-line inline table
came back with the spacing before its trailing comma changed.Two callers reached it. A rename lost the comment because the value genuinely
changed. Handing over the document and replacing the payload under the name it
already had lost the comment for nothing, because the key was assigned the
string it already held rather than left alone.The key is now set inside the existing value with its decor restored, and a
key already holding the string being written is not touched at all. Packing is
unaffected: it only ever sets a key that is absent, where there is no decor to
carry over. Wrong since 0.3.0, whereRepackshipped.
Install slipcase 0.3.4
Install prebuilt binaries via shell script
curl --proto '=https' --tlsv1.2 -LsSf https://github.com/excelano/slpc-rust/releases/download/v0.3.4/slipcase-installer.sh | shInstall prebuilt binaries via powershell script
powershell -ExecutionPolicy Bypass -c "irm https://github.com/excelano/slpc-rust/releases/download/v0.3.4/slipcase-installer.ps1 | iex"Install prebuilt binaries via Homebrew
brew install excelano/tap/slipcaseDownload slipcase 0.3.4
| File | Platform | Checksum |
|---|---|---|
| slipcase-aarch64-apple-darwin.tar.xz | Apple Silicon macOS | checksum |
| slipcase-x86_64-apple-darwin.tar.xz | Intel macOS | checksum |
| slipcase-x86_64-pc-windows-msvc.zip | x64 Windows | checksum |
| slipcase-aarch64-unknown-linux-gnu.tar.xz | ARM64 Linux | checksum |
| slipcase-x86_64-unknown-linux-gnu.tar.xz | x64 Linux | checksum |
0.3.3 - 2026-08-21
Release Notes
Added
-
Container::check_payload_readable, which says whether this build can
decode the payload before anything is extracted.Containercould already
state the payload's name and size without touching its bytes, and nothing
said whether those bytes were reachable: a caller found out by attempting the
extraction. That is the wrong shape for anything that commits to an operation
before performing it, such as a window putting an Open button on a payload
card.It refuses with the same three
UnsupportedvariantsContainer::payload
does, in the order that function meets them, so the two never name different
reasons for one refusal. Both facts come from the central directory entry
read when the container was opened, so it borrows shared, decompresses
nothing, and reads nothing further.Oksays the decoder exists rather than that extraction will succeed:
truncated data, a failed checksum, and an i/o error are still ahead. And it
is a capability query rather than a verdict — SPEC 2.5 puts compression and
encryption outside the conformance question, so a container whose payload is
encrypted is conformant and its payload is out of reach, andvalidategoes
on saying the first of those.
Install slipcase 0.3.3
Install prebuilt binaries via shell script
curl --proto '=https' --tlsv1.2 -LsSf https://github.com/excelano/slpc-rust/releases/download/v0.3.3/slipcase-installer.sh | shInstall prebuilt binaries via powershell script
powershell -ExecutionPolicy Bypass -c "irm https://github.com/excelano/slpc-rust/releases/download/v0.3.3/slipcase-installer.ps1 | iex"Install prebuilt binaries via Homebrew
brew install excelano/tap/slipcaseDownload slipcase 0.3.3
| File | Platform | Checksum |
|---|---|---|
| slipcase-aarch64-apple-darwin.tar.xz | Apple Silicon macOS | checksum |
| slipcase-x86_64-apple-darwin.tar.xz | Intel macOS | checksum |
| slipcase-x86_64-pc-windows-msvc.zip | x64 Windows | checksum |
| slipcase-aarch64-unknown-linux-gnu.tar.xz | ARM64 Linux | checksum |
| slipcase-x86_64-unknown-linux-gnu.tar.xz | x64 Linux | checksum |
0.3.2 - 2026-08-20
Release Notes
Changed
-
Container::payload_sizeborrows shared rather than mutably. In 0.3.1 it
reached into the archive at call time and so took&mut self, which meant the
question anything reporting a container's contents actually asks did not
compile:println!("{} is {} bytes", c.payload_name(), c.payload_size()?);
The size now comes from the central directory entry read when the container
was opened, eight bytes per member against a lookup that needed the archive.
Tightening a&mut selfreceiver to&selfbreaks no caller, so 0.3.1 code
compiles unchanged.
Install slipcase 0.3.2
Install prebuilt binaries via shell script
curl --proto '=https' --tlsv1.2 -LsSf https://github.com/excelano/slpc-rust/releases/download/v0.3.2/slipcase-installer.sh | shInstall prebuilt binaries via powershell script
powershell -ExecutionPolicy Bypass -c "irm https://github.com/excelano/slpc-rust/releases/download/v0.3.2/slipcase-installer.ps1 | iex"Install prebuilt binaries via Homebrew
brew install excelano/tap/slipcaseDownload slipcase 0.3.2
| File | Platform | Checksum |
|---|---|---|
| slipcase-aarch64-apple-darwin.tar.xz | Apple Silicon macOS | checksum |
| slipcase-x86_64-apple-darwin.tar.xz | Intel macOS | checksum |
| slipcase-x86_64-pc-windows-msvc.zip | x64 Windows | checksum |
| slipcase-aarch64-unknown-linux-gnu.tar.xz | ARM64 Linux | checksum |
| slipcase-x86_64-unknown-linux-gnu.tar.xz | x64 Linux | checksum |