gitbutlerapp/gitbutler · warning

u32 -> i32 conversion overflow

Error message

u32 -> i32 conversion overflow

What it means

InputDiffHunk::net_lines() computes new_lines - old_lines as an i64 and then narrows to i32. The error is thrown when the arithmetic subtraction would underflow/overflow at the i64 level or the result does not fit into an i32, which cannot happen with realistic u32 line counts but is guarded anyway because `checked_signed_diff` is not yet stable.

Solutions

  1. Verify the InputDiffHunk was built from a real unified diff, not synthetic values
  2. Clamp or validate new_lines/old_lines before constructing the hunk
  3. If truly needed, change the return type to i64 to eliminate the i32 narrowing

Example fix

// before
let net = hunk.net_lines()?;
// after
let net = i64::from(hunk.new_lines()) - i64::from(hunk.old_lines()); // no i32 narrowing
Defensive patterns

Strategy: validation

Validate before calling

fn net_lines_safe(new_lines: u32, old_lines: u32) -> Option<i32> {
    let diff = i64::from(new_lines) - i64::from(old_lines);
    i32::try_from(diff).ok()
}
// call net_lines() only when this returns Some

Try / catch

// Rust: match on Result
match hunk.net_lines() {
    Ok(n) => use_net(n),
    Err(e) => log::warn!("net_lines unavailable: {e:#}"),
}

Prevention

When it happens

Trigger: Calling net_lines() on an InputDiffHunk whose new_lines/old_lines combination yields a value outside i32 range (theoretically |diff| > 2^31-1, impossible for real diffs since both operands are u32); in practice it indicates corrupted or adversarially constructed hunk input.

Common situations: Feeding fabricated or fuzzed diff data into the hunk-dependency machinery rather than real git diffs; deserializing InputDiffHunk from untrusted JSON with huge line counts.

Understand the failure class

Background: "value must be between 0 and 1" / "out of range" / "must not be negative" errors: fixing range-validation failures across open-source libraries — this error's family across 42 libraries.

Related errors


AI-assisted analysis of gitbutlerapp/gitbutler@58e5313667 (2026-09-18). Data as JSON: /api/errors/04d5b5e246292e69. Report an issue: GitHub.

Appendix: source

Thrown at crates/but-hunk-dependency/src/input.rs:60

pub struct InputDiffHunk {
    /// The 1-based line number at which the previous version of the file started.
    pub old_start: u32,
    /// The non-zero amount of lines included in the previous version of the file.
    pub old_lines: u32,
    /// The 1-based line number at which the new version of the file started.
    pub new_start: u32,
    /// The non-zero amount of lines included in the new version of the file.
    pub new_lines: u32,
}

impl InputDiffHunk {
    /// Compute the amount of lines that are left when subtracting old-lines from new-lines.
    pub fn net_lines(&self) -> anyhow::Result<i32> {
        // TODO: use `checked_signed_diff` instead when stable.
        (self.new_lines as i64)
            .checked_sub(self.old_lines as i64)
            .and_then(|n| i32::try_from(n).ok())
            .ok_or(anyhow!("u32 -> i32 conversion overflow"))
    }
}

impl InputDiffHunk {
    /// Create a new instance from unified `diff`.
    pub fn from_unified_diff(
        but_core::unified_diff::DiffHunk {
            old_start,
            old_lines,
            new_start,
            new_lines,
            diff: _,
        }: &but_core::unified_diff::DiffHunk,
    ) -> Self {
        InputDiffHunk {
            old_start: *old_start,
            old_lines: *old_lines,
            new_start: *new_start,

View on GitHub (pinned to 58e5313667)