Skip to content

Commit 7575141

Browse files
Copilotlouis-e
andcommitted
Add defensive checks to prevent crash with zero-dimension elevation grids
Co-authored-by: louis-e <[email protected]>
1 parent eb288e9 commit 7575141

File tree

2 files changed

+31
-2
lines changed

2 files changed

+31
-2
lines changed

src/elevation_data.rs

Lines changed: 18 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -83,8 +83,9 @@ pub fn fetch_elevation_data(
8383
let tiles: Vec<(u32, u32)> = get_tile_coordinates(bbox, zoom);
8484

8585
// Match grid dimensions with Minecraft world size
86-
let grid_width: usize = scale_factor_x as usize;
87-
let grid_height: usize = scale_factor_z as usize;
86+
// Ensure minimum grid size of 1 to prevent division by zero and indexing errors
87+
let grid_width: usize = (scale_factor_x as usize).max(1);
88+
let grid_height: usize = (scale_factor_z as usize).max(1);
8889

8990
// Initialize height grid with proper dimensions
9091
let mut height_grid: Vec<Vec<f64>> = vec![vec![f64::NAN; grid_width]; grid_height];
@@ -376,6 +377,11 @@ fn get_tile_coordinates(bbox: &LLBBox, zoom: u8) -> Vec<(u32, u32)> {
376377
}
377378

378379
fn apply_gaussian_blur(heights: &[Vec<f64>], sigma: f64) -> Vec<Vec<f64>> {
380+
// Guard against empty input
381+
if heights.is_empty() || heights[0].is_empty() {
382+
return heights.to_owned();
383+
}
384+
379385
let kernel_size: usize = (sigma * 3.0).ceil() as usize * 2 + 1;
380386
let kernel: Vec<f64> = create_gaussian_kernel(kernel_size, sigma);
381387

@@ -445,6 +451,11 @@ fn create_gaussian_kernel(size: usize, sigma: f64) -> Vec<f64> {
445451
}
446452

447453
fn fill_nan_values(height_grid: &mut [Vec<f64>]) {
454+
// Guard against empty grid
455+
if height_grid.is_empty() || height_grid[0].is_empty() {
456+
return;
457+
}
458+
448459
let height: usize = height_grid.len();
449460
let width: usize = height_grid[0].len();
450461

@@ -485,6 +496,11 @@ fn fill_nan_values(height_grid: &mut [Vec<f64>]) {
485496
}
486497

487498
fn filter_elevation_outliers(height_grid: &mut [Vec<f64>]) {
499+
// Guard against empty grid
500+
if height_grid.is_empty() || height_grid[0].is_empty() {
501+
return;
502+
}
503+
488504
let height = height_grid.len();
489505
let width = height_grid[0].len();
490506

src/ground.rs

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -75,6 +75,10 @@ impl Ground {
7575
/// Converts game coordinates to elevation data coordinates
7676
#[inline(always)]
7777
fn get_data_coordinates(&self, coord: XZPoint, data: &ElevationData) -> (f64, f64) {
78+
// Guard against division by zero for edge cases
79+
if data.width == 0 || data.height == 0 {
80+
return (0.0, 0.0);
81+
}
7882
let x_ratio: f64 = coord.x as f64 / data.width as f64;
7983
let z_ratio: f64 = coord.z as f64 / data.height as f64;
8084
(x_ratio.clamp(0.0, 1.0), z_ratio.clamp(0.0, 1.0))
@@ -83,8 +87,17 @@ impl Ground {
8387
/// Interpolates height value from the elevation grid
8488
#[inline(always)]
8589
fn interpolate_height(&self, x_ratio: f64, z_ratio: f64, data: &ElevationData) -> i32 {
90+
// Guard against out of bounds access
91+
if data.width == 0 || data.height == 0 || data.heights.is_empty() {
92+
return self.ground_level;
93+
}
8694
let x: usize = ((x_ratio * (data.width - 1) as f64).round() as usize).min(data.width - 1);
8795
let z: usize = ((z_ratio * (data.height - 1) as f64).round() as usize).min(data.height - 1);
96+
97+
// Additional safety check for row length
98+
if z >= data.heights.len() || x >= data.heights[z].len() {
99+
return self.ground_level;
100+
}
88101
data.heights[z][x]
89102
}
90103

0 commit comments

Comments
 (0)