louis-e/arnis · error

CoordinateBitmap: world size too large (width * height overf

Error message

CoordinateBitmap: world size too large (width * height overflowed)

What it means

CoordinateBitmap::new allocates a bit-packed grid sized to the given xz bounding box. width and height are computed as usize from i64 differences; if their product exceeds usize::MAX, checked_mul returns None and the code panics with this message. This guards against absurdly large or corrupted world bounding boxes that would otherwise cause silent wrap-around and a too-small allocation.

Source

Thrown at src/floodfill_cache.rs:93

    #[allow(dead_code)]
    height: usize,
    /// Number of coordinates marked
    count: usize,
}

impl CoordinateBitmap {
    /// Creates a new empty bitmap covering the given world bounds.
    pub fn new(xzbbox: &XZBBox) -> Self {
        let min_x = xzbbox.min_x();
        let min_z = xzbbox.min_z();
        // Use i64 to avoid overflow when world spans more than i32::MAX in either dimension
        let width = (i64::from(xzbbox.max_x()) - i64::from(min_x) + 1) as usize;
        let height = (i64::from(xzbbox.max_z()) - i64::from(min_z) + 1) as usize;

        // Calculate number of bytes needed (round up to nearest byte)
        let total_bits = width
            .checked_mul(height)
            .expect("CoordinateBitmap: world size too large (width * height overflowed)");
        let num_bytes = total_bits.div_ceil(8);

        Self {
            bits: vec![0u8; num_bytes],
            min_x,
            min_z,
            width,
            height,
            count: 0,
        }
    }

    /// Creates a zero-size bitmap that contains nothing and allocates no memory.
    pub fn new_empty() -> Self {
        Self {
            bits: Vec::new(),
            min_x: 0,
            min_z: 0,

View on GitHub (pinned to 34048924d9)

Solutions

  1. Validate the bbox extent before constructing the bitmap: reject width*height products above a sane world-size limit with a user-facing error.
  2. Fix coordinate-space mixing so min_x/min_z come from the same bbox/source as xzbbox.
  3. On 32-bit platforms, cap the world size explicitly or use checked arithmetic upstream and return an error instead of panicking.

Example fix

// before
let bitmap = CoordinateBitmap::new(xzbbox, min_x, min_z); // panics on overflow
// after
let w = i64::from(xzbbox.max_x()) - i64::from(min_x) + 1;
let h = i64::from(xzbbox.max_z()) - i64::from(min_z) + 1;
if w <= 0 || h <= 0 || w.checked_mul(h).filter(|b| *b < 1_000_000_000).is_none() {
    return Err("world bbox too large or invalid".into());
}
let bitmap = CoordinateBitmap::new(xzbbox, min_x, min_z);
Defensive patterns

Strategy: validation

Validate before calling

const w = BigInt(xzbbox.max_x()) - BigInt(min_x) + 1n;
const h = BigInt(xzbbox.max_z()) - BigInt(min_z) + 1n;
if (w * h > BigInt(Number.MAX_SAFE_INTEGER)) throw new Error('world size too large');

Type guard

fn world_size_fits(xzbbox: &XZBBox, min_x: i32, min_z: i32, max_bits: usize) -> bool {
    let w = i64::from(xzbbox.max_x()) - i64::from(min_x) + 1;
    let h = i64::from(xzbbox.max_z()) - i64::from(min_z) + 1;
    w > 0 && h > 0 && (w as u128) * (h as u128) <= max_bits as u128
}

Try / catch

std::panic::catch_unwind(|| CoordinateBitmap::new(xzbbox, min_x, min_z))
    .map_err(|_| "world bbox too large".to_string())

Prevention

When it happens

Trigger: Calling CoordinateBitmap::new with an xzbbox whose (max_x - min_x + 1) * (max_z - min_z + 1) overflows usize — e.g. a bbox spanning near-full i64 coordinate range, or min computed from a different/unrelated bbox than max (mixed coordinate spaces).

Common situations: A floodfill cache initialized with world-size coordinates on a 32-bit target; a bug where min_x/min_z default to i64::MIN while the bbox max is huge; corrupt or unvalidated region bounds read from a save file.

Related errors


AI-assisted analysis of louis-e/arnis@34048924d9 (2026-09-03). Data as JSON: /api/errors/e924cb13c9d2e83d. Report an issue: GitHub.