Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 7 additions & 5 deletions crates/rustille/src/canvas.rs
Original file line number Diff line number Diff line change
Expand Up @@ -24,10 +24,12 @@ use crate::error::{Error, Result};

/// Largest canvas Rustille will allocate, in character cells.
///
/// One cell is one byte, so this caps a canvas at 256 MiB — roughly a
/// 32,768 × 65,536 dot surface. Anything larger is rejected with
/// One cell is one byte, so this caps a canvas at 16 MiB — roughly a
/// 8,192 × 16,384 dot surface. Anything larger is rejected with
/// [`Error::InvalidDimensions`] rather than aborting on allocation failure.
pub const MAX_CANVAS_CELLS: u64 = 1 << 28;
/// This acts as a safeguard against accidental or malicious memory exhaustion
/// (e.g. over web APIs or FFI boundaries).
pub const MAX_CANVAS_CELLS: u64 = 1 << 24;

/// A fixed-size grid of Braille dots.
#[derive(Clone, PartialEq, Eq)]
Expand Down Expand Up @@ -247,8 +249,8 @@ impl Canvas {
}

fn plot_line(&mut self, x0: i32, y0: i32, x1: i32, y1: i32, value: bool) {
let dx = (x1 - x0).abs();
let dy = -(y1 - y0).abs();
let dx = (i64::from(x1) - i64::from(x0)).abs();
let dy = -(i64::from(y1) - i64::from(y0)).abs();
let step_x = if x0 < x1 { 1 } else { -1 };
let step_y = if y0 < y1 { 1 } else { -1 };
let mut error = dx + dy;
Expand Down
6 changes: 4 additions & 2 deletions crates/rustille/src/options.rs
Original file line number Diff line number Diff line change
Expand Up @@ -401,9 +401,11 @@ impl RenderOptions {
if self.height == Some(0) {
return Err(Error::invalid_options("height must be greater than zero"));
}
if !self.cell_aspect_ratio.is_finite() || self.cell_aspect_ratio <= 0.0 {
// Prevent extremely small values that could cause division by zero or infinities
// during rendering size calculations.
if !self.cell_aspect_ratio.is_finite() || self.cell_aspect_ratio <= 1e-6 {
return Err(Error::invalid_options(format!(
"cell_aspect_ratio must be a positive finite number, got {}",
"cell_aspect_ratio must be a positive finite number >= 1e-6, got {}",
self.cell_aspect_ratio
)));
}
Expand Down
3 changes: 2 additions & 1 deletion crates/rustille/src/render.rs
Original file line number Diff line number Diff line change
Expand Up @@ -280,7 +280,8 @@ fn pack_cells(
fn cover_crop(surface: &Surface, cells_width: u32, cells_height: u32, cell_aspect: f32) -> Surface {
let box_aspect = f64::from(cells_width) / (f64::from(cells_height) * f64::from(cell_aspect));
let source_aspect = f64::from(surface.width()) / f64::from(surface.height());
if (source_aspect - box_aspect).abs() < 1e-9 {
// Use a small epsilon to handle precision issues
if (source_aspect - box_aspect).abs() < 1e-6 {
return surface.clone();
}
if source_aspect > box_aspect {
Expand Down
Loading