Hacktoberfest 2026: the issues maintainers tagged for October, open and beginner-friendly. Browse Hacktoberfest issues

Range::bytes and ContentRange::bytes do unchecked u64 arithmetic on bounds

Open
#231 0 comments 0 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

Assessment

Difficulty
3/5
Estimated time
1-2 days
Newbie friendliness
78/100
Issue type
Bug
Clarity
Clearly specified
Activity status
Quiet
Tech stack
rust
Domain
api

Research direction

Start with src/common/range.rs and src/common/content_range.rs at the reported arithmetic lines, then run the supplied reproducer in debug and release profiles. Done means empty or unrepresentable bounds return InvalidRange or InvalidContentRange rather than panic or emit wrapped HTTP ranges.

Written by the indexing model from the issue text.

Description

Range::bytes and ContentRange::bytes convert range bounds with unchecked u64 arithmetic. Debug builds panic with "attempt to subtract with overflow". Release builds wrap to u64::MAX and emit headers describing a 2^64-byte span, and empty ranges with a non-zero start emit bytes=N-(N-1) in both profiles.

Crate version: headers 0.4.1, no feature flags.

Reproducer

use headers::{ContentRange, Header, HeaderValue, Range};

fn encode<H: Header>(h: &H) -> String {
    let mut values: Vec<HeaderValue> = Vec::new();
    h.encode(&mut values);
    values[0].to_str().unwrap().to_owned()
}

fn main() {
    println!("{}", encode(&Range::bytes(0u64..0u64).unwrap()));
    println!("{}", encode(&Range::bytes(3u64..3u64).unwrap()));
    println!("{}", encode(&ContentRange::bytes(0u64..0u64, 500u64).unwrap()));
    println!("{}", encode(&ContentRange::bytes(0u64.., 0u64).unwrap()));
    println!("{}", encode(&ContentRange::bytes(3u64..3u64, 100u64).unwrap()));
}

Observed

cargo run --release prints:

bytes=0-18446744073709551615
bytes=3-2
bytes 0-18446744073709551615/500
bytes 0-18446744073709551615/0
bytes 3-2/100

cargo run in debug panics on the first call at src/common/range.rs:56, so the program prints nothing. Run on their own in a debug build, ContentRange::bytes(0u64..0u64, 500u64) panics at src/common/content_range.rs:66 and ContentRange::bytes(0u64.., 0u64) panics at src/common/content_range.rs:68.

Expected

All five calls should return Err(InvalidRange) or Err(InvalidContentRange). Both constructors return a Result so unrepresentable bounds can be rejected. RFC 7233 section 2.1 requires last-byte-pos >= first-byte-pos in a byte-range-spec, so bytes=3-2 is invalid. RFC 7233 section 4.2 adds last-byte-pos < complete-length, which rules out bytes 0-18446744073709551615/0.

Root cause

  • src/common/range.rs:56: format!("bytes={}-{}", start, end - 1)
  • src/common/content_range.rs:66: Bound::Excluded(&e) => e - 1,
  • src/common/content_range.rs:68: Some(max) => max - 1,
  • src/common/content_range.rs:60: Bound::Excluded(&s) => s + 1,, the mirrored addition on an excluded start bound. Not exercised here.

Scope

Any empty half-open range N..N passed to either constructor. Any ContentRange::bytes call with an unbounded end and complete_length == 0. Those 0..0 and zero-length forms panic in debug and wrap in release. The non-zero empty forms are silent in both.

Dominant language
Rust
Stars
200
Forks
107
PR merge metrics
No merged PRs in 30d

Contributor guide

No contributing guide indexed for this repository

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

More from hyperium/headers

All issues in hyperium/headers

Similar issues

More Rust issues

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.