{"record":{"id":"e924cb13c9d2e83d","repo":"louis-e/arnis","slug":"coordinatebitmap-world-size-too-large-width-he","errorCode":null,"errorMessage":"CoordinateBitmap: world size too large (width * height overflowed)","messagePattern":"CoordinateBitmap: world size too large \\(width \\* height overflowed\\)","errorType":"panic","errorClass":null,"httpStatus":null,"severity":"error","filePath":"src/floodfill_cache.rs","lineNumber":93,"sourceCode":"    #[allow(dead_code)]\n    height: usize,\n    /// Number of coordinates marked\n    count: usize,\n}\n\nimpl CoordinateBitmap {\n    /// Creates a new empty bitmap covering the given world bounds.\n    pub fn new(xzbbox: &XZBBox) -> Self {\n        let min_x = xzbbox.min_x();\n        let min_z = xzbbox.min_z();\n        // Use i64 to avoid overflow when world spans more than i32::MAX in either dimension\n        let width = (i64::from(xzbbox.max_x()) - i64::from(min_x) + 1) as usize;\n        let height = (i64::from(xzbbox.max_z()) - i64::from(min_z) + 1) as usize;\n\n        // Calculate number of bytes needed (round up to nearest byte)\n        let total_bits = width\n            .checked_mul(height)\n            .expect(\"CoordinateBitmap: world size too large (width * height overflowed)\");\n        let num_bytes = total_bits.div_ceil(8);\n\n        Self {\n            bits: vec![0u8; num_bytes],\n            min_x,\n            min_z,\n            width,\n            height,\n            count: 0,\n        }\n    }\n\n    /// Creates a zero-size bitmap that contains nothing and allocates no memory.\n    pub fn new_empty() -> Self {\n        Self {\n            bits: Vec::new(),\n            min_x: 0,\n            min_z: 0,","sourceCodeStart":75,"sourceCodeEnd":111,"githubUrl":"https://github.com/louis-e/arnis/blob/34048924d9365795fb0d832e76140a3fbdc413d9/src/floodfill_cache.rs#L75-L111","documentation":"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.","triggerScenarios":"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).","commonSituations":"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.","solutions":["Validate the bbox extent before constructing the bitmap: reject width*height products above a sane world-size limit with a user-facing error.","Fix coordinate-space mixing so min_x/min_z come from the same bbox/source as xzbbox.","On 32-bit platforms, cap the world size explicitly or use checked arithmetic upstream and return an error instead of panicking."],"exampleFix":"// before\nlet bitmap = CoordinateBitmap::new(xzbbox, min_x, min_z); // panics on overflow\n// after\nlet w = i64::from(xzbbox.max_x()) - i64::from(min_x) + 1;\nlet h = i64::from(xzbbox.max_z()) - i64::from(min_z) + 1;\nif w <= 0 || h <= 0 || w.checked_mul(h).filter(|b| *b < 1_000_000_000).is_none() {\n    return Err(\"world bbox too large or invalid\".into());\n}\nlet bitmap = CoordinateBitmap::new(xzbbox, min_x, min_z);","handlingStrategy":"validation","validationCode":"const w = BigInt(xzbbox.max_x()) - BigInt(min_x) + 1n;\nconst h = BigInt(xzbbox.max_z()) - BigInt(min_z) + 1n;\nif (w * h > BigInt(Number.MAX_SAFE_INTEGER)) throw new Error('world size too large');","typeGuard":"fn world_size_fits(xzbbox: &XZBBox, min_x: i32, min_z: i32, max_bits: usize) -> bool {\n    let w = i64::from(xzbbox.max_x()) - i64::from(min_x) + 1;\n    let h = i64::from(xzbbox.max_z()) - i64::from(min_z) + 1;\n    w > 0 && h > 0 && (w as u128) * (h as u128) <= max_bits as u128\n}","tryCatchPattern":"std::panic::catch_unwind(|| CoordinateBitmap::new(xzbbox, min_x, min_z))\n    .map_err(|_| \"world bbox too large\".to_string())","preventionTips":["Sanity-check bbox extents against a configured world-size cap before bitmap allocation","Ensure min_x/min_z derive from the same coordinate space as xzbbox","Never initialize min coordinates to i32::MIN/i64::MIN sentinels combined with large maxima"],"tags":["panic","overflow","memory","floodfill"],"backgroundTag":"integer-overflow-allocation","analyzedSha":"34048924d9365795fb0d832e76140a3fbdc413d9","analyzedAt":"2026-09-03T14:05:17.283Z","contentChangedAt":"2026-09-03T14:05:17.283Z","schemaVersion":2},"datasetVersion":"2026-09-10T17:17:09.494Z"}