Skip to content

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

Description

@cuishuang

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)

Metadata

Metadata

Assignees

No one assigned

    Labels

    C-bugCategory: this is a bug; use also I-* labels for specific bug kinds, e.g. I-non-idempotency or I-ICEP-lowLow priorityUO-file_linesUnstable option: file_lines

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions