proofs.rs

Report #22 — Unindentation of bytes and strings in an adapted implementation

creusot 0.13.0

2 verified claims · 0 findings

Recorded by the author; proofs.rs has not re-run it. How to read a report

MasWag · 2026-11-04 16:53 UTC

Revision v1

Overview

This Creusot continuation checks an adapted implementation of unindent 0.2.4. Its contracts cover unindent_bytes, unindent, and the concrete Unindent implementations for [u8], str, and String. The byte API accepts arbitrary representable byte slices, including invalid UTF-8; the string API starts with a valid Rust string.

The specified output is the ordered sequence of retained input bytes. The first line does not contribute to the indentation minimum. For subsequent nonblank lines, the minimum counts leading SPACE and TAB bytes, each as one byte; each later line loses up to that many bytes. A leading LF or CRLF is suppressed, and an initial CR in CRLF is removed. Other CR bytes remain ordinary bytes, including in interior CRLF sequences. Empty and trailing fields are retained according to the source-position selection rule. The contracts state exact output bytes, an output length no greater than the input, and termination without a modeled panic. The string contract also requires successful UTF-8 conversion: the application proof connects the byte selection to preservation of UTF-8 by showing that omitted bytes are ASCII.

Findings (0)

No findings reported.

APIs (2)

Recorded callables

unindent recorded callable · signature and safety not recorded
unindent_bytes recorded callable · signature and safety not recorded

Evidence

https://github.com/MasWag/crate-proofs/tree/ce78df957d982a6049e602a5083bee5b3636b5ea

Reproduce

Toolchain source metadata: not recorded.

Run locally

git clone -- https://github.com/MasWag/crate-proofs report-22-source-1
git -C report-22-source-1 checkout --detach ce78df957d982a6049e602a5083bee5b3636b5ea
git -C report-22-source-1 submodule update --init --recursive --checkout
cd report-22-source-1/unindent/0.2.4/creusot

cargo creusot --no-cache --why3find-arg=--no-autodetect-provers --why3find-arg=-P '--why3find-arg=z3,cvc5,alt-ergo' --why3find-arg=-j --why3find-arg=2 --why3find-arg=--fast --why3find-arg=1 --why3find-arg=--time --why3find-arg=10 --why3find-arg=-d --why3find-arg=6

Checks out the recorded source commit from GitHub. Install the report’s tool version before running.

Source on GitHub · SARIF with logs (.json)

Recorded run

Completed · 4 checks passed · 0 failed

2026-11-04T16:49:50.972967303+00:00 · 157.9 seconds · Exit code 0

Recorded on the author’s machine.

CheckResultClaim
vc_do_unindent
unindent::unindent
unindent/0.2.4/creusot/src/lib.rs:159
PassedClaim #1
vc_unindent
unindent::unindent
unindent/0.2.4/creusot/src/lib.rs:159
PassedClaim #1
vc_do_unindent_bytes
unindent::unindent_bytes
unindent/0.2.4/creusot/src/lib.rs:91
PassedClaim #2
vc_unindent_bytes
unindent::unindent_bytes
unindent/0.2.4/creusot/src/lib.rs:91
PassedClaim #2
Execution details
Started
2026-11-04T16:49:50.972967303+00:00
Finished
2026-11-04T16:52:28.889989975+00:00
Platform
linux x86_64
Rust compiler
rustc 1.91.0 (f8297e351 2025-10-28) binary: rustc commit-hash: f8297e351a40c1439a467bbbb6879088047f50b3 commit-date: 2025-10-28 host: x86_64-unknown-linux-gnu release: 1.91.0 LLVM version: 21.1.2
Working directory
unindent/0.2.4/creusot
Environment overrides
None recorded
Git repository
https://github.com/MasWag/crate-proofs
Git commit
ce78df957d982a6049e602a5083bee5b3636b5ea
Diagnostics & logs
=== stdout ===
Proved (36 files) ✔

=== stderr ===
warning: patch `creusot-std v0.15.0-dev (/home/lab8/mwaga/creusot/creusot-std)` was not used in the crate graph
help: Check that the patched package version and available features are compatible
      with the dependency requirements. If the patch has a different version from
      what is locked in the Cargo.lock file, run `cargo update` to use the new
      version. This may also occur with an optional dependency that is not enabled.
   Compiling proc-macro2 v1.0.107
   Compiling unicode-ident v1.0.27
   Compiling quote v1.0.47
   Compiling libc v0.2.191
   Compiling getrandom v0.4.3
   Compiling cfg-if v1.0.5
   Compiling syn v2.0.119
   Compiling uuid v1.29.0
   Compiling pearlite-syn v0.13.0
   Compiling creusot-std-proc v0.13.0
    Checking creusot-std v0.13.0
    Checking unindent v0.2.4 (./unindent/0.2.4/creusot)
warning: unnecessary parentheses around function argument
  --> src/lib.rs:56:20
   |
56 |         (found ==> (exists<a: Int,k: Int> a < bound && spec::later_candidate(s,a,k) && k-a == margin)) &&
   |                    ^                                                                                ^
   |
   = note: `#[warn(unused_parens)]` (part of `#[warn(unused)]`) on by default
help: remove these parentheses
   |
56 -         (found ==> (exists<a: Int,k: Int> a < bound && spec::later_candidate(s,a,k) && k-a == margin)) &&
56 +         (found ==> exists<a: Int,k: Int> a < bound && spec::later_candidate(s,a,k) && k-a == margin ) &&
   |

warning: unused variable: `k`
  --> src/lemmas.rs:48:24
   |
48 |         if a > 0 { let k = first_nonwhite(s,a,a,i); }
   |                        ^ help: if this is intentional, prefix it with an underscore: `_k`
   |
   = note: `#[warn(unused_variables)]` (part of `#[warn(unused)]`) on by default

warning: function `append_range` is never used
  --> src/lib.rs:40:4
   |
40 | fn append_range(s: &[u8], start: usize, end: usize, initial: Vec<u8>) -> Vec<u8> {
   |    ^^^^^^^^^^^^
   |
   = note: `#[warn(dead_code)]` (part of `#[warn(unused)]`) on by default

warning: `unindent` (lib) generated 3 warnings (run `cargo fix --lib -p unindent` to apply 2 suggestions)
    Finished `dev` profile [unoptimized + debuginfo] target(s) in 28.48s
Environment

The selected subject is the verification adaptation of crates.io unindent 0.2.4, using Creusot 0.13 with its nightly-2026-06-22 extraction compiler and Why3/Why3find on x86_64-unknown-linux-gnu. The source identity, specification, standard-library boundary ledger, and proof inputs and evidence are recorded in this workspace's verification directory. The integrated proof results, independent audit, and fingerprints are recorded in verification/results.md.

What is trusted

The proof uses Creusot's standard-library models for arithmetic, slices, vectors, results, characters, and strings. These describe observable values and operations rather than proving the standard library or allocator. In addition, the model assumes two standard UTF-8 encoding facts: an ASCII scalar encodes as its corresponding single byte, and every byte encoding a non-ASCII scalar is at least 128. It models str::as_bytes as the UTF-8 encoding of the string view and String::from_utf8 as succeeding exactly for bytes with a valid encoding witness, preserving those bytes. These are assumptions about standard encoding and conversion, not assumptions that unindentation preserves UTF-8; the application preservation bridge is a separate proof obligation.

Technical limitations

The executable proof subject is a verification adaptation: it replaces the release's iterator-based processing with indexed margin discovery and a bytewise retention scan. Extraction of the original Split pipeline is unsupported by this track. Finite native comparisons against the release covered 300,617 byte inputs, 299,593 Unicode inputs, and 74,898 input/flag pairs; these comparisons are evidence of agreement on those cases, not an all-input equivalence proof. No formal release-equivalence theorem is established.

The checked output contract is expressed in terms of retained source positions. An independent mathematical review relates it to the separate sequence-of-lines specification, but a machine-checked bridge between those specifications remains open. The generic &T extension is available in native code and excluded from this Creusot selection; behavior of an arbitrary downstream T is not covered. The prior Aeneas report is a separate result tied to its own inputs.

The cargo-proofs 0.4.1 Creusot importer records only panic_contract. The local functional and termination contracts described here are not additional service functional_correctness or no_ub claims.

The models do not establish allocation availability or behavior under external resource exhaustion. Other targets and minimum supported Rust versions are outside this run's scope.

Tool limitations

Verification is relative to the supplied specifications and trusted contracts. Results apply to the compilation target used for verification. The standard-library specifications do not exclude all panics: Vec capacity overflow in operations such as push, insert, and extend is not ruled out, including for vectors of zero-sized types. Out-of-memory failures are also outside the guarantees. The standard vec! macro is unsupported; verified code must use the Creusot replacement where needed. Reference: https://github.com/creusot-rs/creusot/blob/v0.13.0/guide/src/limitations.md

Updated 2026-09-24 05:03 UTC

creusot 0.13.0 — version details

Dependencies (0)

No direct dependencies.

Comments (0)

No comments.

Sign in to comment.