`SizeHint` addition overflows (panics in debug builds, wraps in release)

Aperta Adatta ai principianti
#183 0 commenti 0 reazioni 0 assegnatari Vedi su GitHub

Nessuno ha ancora preso questa issue.

Valutazione

Difficoltà
2/5
Tempo stimato
1-3 ore
Idoneità per principianti
78/100
Tipo di issue
Bug
Chiarezza
Specificata chiaramente
Stato di attività
Attiva
Stack tecnologico
rust

Direzione di ricerca

L’issue indica src/size_hint.rs, dove Add for SizeHint va in overflow quando combina i limiti. Leggi prima questa implementazione e i test vicini, poi verifica come il limite inferiore saturante proposto e il limite superiore controllato si integrano con il comportamento esistente. Il lavoro è completo quando le addizioni con overflow non causano più panic né ritornano al valore iniziale, e i test coprono i limiti risultanti.

Scritto dal modello di indicizzazione a partire dal testo della issue.

Descrizione

impl Add for SizeHint adds the lower and upper bounds with plain +, so it panics with "attempt to add with overflow" in debug builds when a sum exceeds u64::MAX. In release builds it wraps, and the result can be a hint whose bounds are smaller than either input.

// Cargo.toml: http-body = { git = "https://github.com/hyperium/http-body" }
use http_body::SizeHint;

fn main() {
    let s = SizeHint::with_exact(u64::MAX) + SizeHint::with_exact(1);
    println!("{:?} {:?}", s.lower(), s.upper());
}

Debug build:

thread 'main' panicked at http-body/src/size_hint.rs:95:20:
attempt to add with overflow

Release build: prints 0 Some(0).

I expected the sum to saturate at u64::MAX (a size hint that cannot be represented exactly is still a valid lower bound when saturated), or the overflow to be documented. Checked on master at c6ca645.

fn add(self, rhs: Self) -> Self::Output {
    SizeHint {
        lower: self.lower() + rhs.lower(),                                   // overflows
        upper: self.upper().and_then(|this| rhs.upper().map(|rhs| this + rhs)), // overflows
    }
}

Suggested fix: self.lower().saturating_add(rhs.lower()), and for the upper bound checked_add, giving None (no upper bound) when the sum does not fit.

Kani harness that fails on master (cargo kani --harness add_does_not_overflow, appended to src/size_hint.rs):

#[cfg(kani)]
mod kani_proofs {
    use super::SizeHint;

    #[kani::proof]
    fn add_does_not_overflow() {
        let a = SizeHint::with_exact(kani::any());
        let b = SizeHint::with_exact(kani::any());
        let _ = a + b;
    }
}
Failed Checks: attempt to add with overflow
 File: "src/size_hint.rs", line 95, in <size_hint::SizeHint as std::ops::Add>::add
VERIFICATION:- FAILED

It takes about 1.6 s and under 200 MB.


This was found with Kani 0.68.0 in an experiment where AI agents verified popular crates using the Kani agent plugin (model-checking/kani#5059). The text was written with AI assistance; the reproducer and the Kani harness were re-run by hand on the commit named above.

Lingua principale
Rust
Stelle
173
Fork
71
Merge medio
1g 12h
PR unite (30g)
1

Preparare l'ambiente

Questo progetto non fornisce container di sviluppo, Dockerfile né guida per i contributori, quindi l'ambiente è a tuo carico: parti dal suo README e consulta la nostra guida al primo contributo per i passaggi generali.

Come iniziare

  1. Leggi tutta la issue e poi la guida ai contributi del progetto.
  2. Commenta sulla issue per dire che te ne occupi tu — evita che due persone facciano lo stesso lavoro.
  3. Fai un fork del repository e lavora su un branch.
  4. Apri una pull request che faccia riferimento al numero della issue.

Altre issue di hyperium/http-body

Tutte le issue di hyperium/http-body

Issue simili

Altre issue su Rust

Ricevi le nuove issue nella tua casella

Un breve riepilogo di issue GitHub adatte ai principianti.