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

Abierto Apto para principiantes
#183 0 comentarios 0 reacciones 0 asignados Ver en GitHub

Nadie ha tomado este issue todavía.

Evaluación

Dificultad
2/5
Tiempo estimado
1-3 horas
Aptitud para principiantes
78/100
Tipo de issue
Error
Claridad
Bien especificado
Estado de actividad
Activo
Stack tecnológico
rust

Línea de trabajo

El issue apunta a src/size_hint.rs, donde Add for SizeHint produce un desbordamiento al combinar límites. Lee primero esa implementación y las pruebas cercanas; después, comprueba cómo encajan el límite inferior saturante propuesto y el límite superior comprobado con el comportamiento existente. La tarea está completa cuando las sumas con desbordamiento ya no provocan un panic ni dan la vuelta, y las pruebas cubren los límites resultantes.

Escrito por el modelo de indexación a partir del texto del issue.

Descripción

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.

Lenguaje dominante
Rust
Estrellas
173
Forks
71
Merge medio
1 d 12 h
PR fusionados (30 d)
1

Preparar el entorno

Este proyecto no incluye contenedor de desarrollo, Dockerfile ni guía de contribución, así que la configuración corre por tu cuenta: empieza por su README y consulta nuestra guía para la primera contribución para los pasos generales.

Primeros pasos

  1. Lee el issue completo y luego la guía de contribución del proyecto.
  2. Comenta en el issue que vas a ocuparte — evita que dos personas hagan lo mismo.
  3. Haz un fork del repositorio y trabaja en una rama.
  4. Abre un pull request que haga referencia al número del issue.

Más de hyperium/http-body

Todos los issues de hyperium/http-body

Issues similares

Más issues de Rust

Recibe los nuevos issues en tu correo

Un resumen breve de issues de GitHub para principiantes.