rust-lang / rust-lang/rustfmt

--file-lines range normalization can overflow at usize::MAX

Open
#6,992 0 comments 0 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

C-bug P-low UO-file_lines
Dominant language
Rust
Stars
7k
Forks
1.1k
Avg merge
2d 13h
Merged PRs (30d)
24

Description

Summary

--file-lines deserializes range endpoints directly as usize and constructs Range values without validating that the endpoints are 1-based or ordered.

When normalizing multiple ranges, Range::adjacent_to checks adjacency using unchecked addition:

self.hi + 1 == other.lo || other.hi + 1 == self.lo

On a 64-bit platform, a range ending at 18446744073709551615 (usize::MAX) causes an integer-overflow panic in builds with overflow checks enabled.

In release builds, the addition can wrap to zero. Since the parser also accepts line zero, ranges such as [0,0] and [2,usize::MAX] may be incorrectly considered adjacent and merged into a single range.

The input file can be minimal:

fn  main(){}
Expected behavior

A representable usize endpoint should not cause rustfmt to panic or incorrectly merge non-adjacent ranges.

Because --file-lines ranges are documented as 1-based, ranges containing line zero should be rejected. Reversed ranges should also be rejected.

Actual behavior

In a debug build, normalizing a range ending at usize::MAX evaluates usize::MAX + 1 and panics:

attempt to add with overflow

With overflow checks disabled, usize::MAX + 1 wraps to zero. If another range starts at line zero, the adjacency check can return true and merge ranges that have a gap between them.

Configuration

rustfmt cli options used (if applicable):

$ cargo run --bin rustfmt -- \
    --unstable-features \
    --file-lines \
    '[{"file":"test.rs","range":[1,1]},{"file":"test.rs","range":[3,18446744073709551615]}]' \
    test.rs

rustfmt configuration file (e.g. rustfmt.toml, if applicable):

No rustfmt.toml configuration is required.

Reproduction Steps

  1. Create an existing test.rs file:

    fn  main(){}
    
  2. Run rustfmt from source in the debug profile:

    cargo run --bin rustfmt -- \
      --unstable-features \
      --file-lines \
      '[{"file":"test.rs","range":[1,1]},{"file":"test.rs","range":[3,18446744073709551615]}]' \
      test.rs
    
  3. Observe that rustfmt panics with attempt to add with overflow.

  4. The release-mode incorrect-merge condition can be triggered with this input:

    cargo run --release --bin rustfmt -- \
      --unstable-features \
      --file-lines \
      '[{"file":"test.rs","range":[0,0]},{"file":"test.rs","range":[2,18446744073709551615]}]' \
      test.rs
    

    In this case, usize::MAX + 1 wraps to zero and the two non-adjacent ranges can be merged.

Meta

rustfmt --version:

rustfmt 1.10.0-nightly (8ddb21c684 2026-07-28)

Contributor guide

Open the contributing guide

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.

Research direction

Start by locating the --file-lines parser and the Range::adjacent_to implementation, then reproduce the issue with the commands and inputs shown. Check the existing range-normalization coverage if present. Done means valid usize endpoints no longer panic or merge incorrectly, while zero and reversed ranges are rejected.

Written by the indexing model from the issue text.

Assessment

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

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.