Fix overflow, race condition, and format bugs
This commit is contained in:
@@ -94,7 +94,7 @@ fn find_system_font(family: Option<&str>) -> Result<Vec<u8>> {
|
||||
.to_lowercase();
|
||||
if file_name.contains(&name_lower)
|
||||
&& (file_name.ends_with(".ttf") || file_name.ends_with(".otf"))
|
||||
&& (file_name.contains("regular") || !file_name.contains("bold") && !file_name.contains("italic"))
|
||||
&& (file_name.contains("regular") || (!file_name.contains("bold") && !file_name.contains("italic")))
|
||||
{
|
||||
if let Ok(data) = std::fs::read(&path) {
|
||||
return Ok(data);
|
||||
@@ -136,24 +136,27 @@ fn walkdir(dir: &std::path::Path) -> std::io::Result<Vec<std::path::PathBuf>> {
|
||||
fn walkdir_depth(dir: &std::path::Path, max_depth: u32) -> std::io::Result<Vec<std::path::PathBuf>> {
|
||||
const MAX_RESULTS: usize = 10_000;
|
||||
let mut results = Vec::new();
|
||||
if max_depth == 0 || !dir.is_dir() {
|
||||
return Ok(results);
|
||||
walkdir_depth_inner(dir, max_depth, &mut results, MAX_RESULTS);
|
||||
Ok(results)
|
||||
}
|
||||
|
||||
fn walkdir_depth_inner(dir: &std::path::Path, max_depth: u32, results: &mut Vec<std::path::PathBuf>, max: usize) {
|
||||
if max_depth == 0 || !dir.is_dir() || results.len() >= max {
|
||||
return;
|
||||
}
|
||||
for entry in std::fs::read_dir(dir)? {
|
||||
if results.len() >= MAX_RESULTS {
|
||||
let Ok(entries) = std::fs::read_dir(dir) else { return };
|
||||
for entry in entries {
|
||||
if results.len() >= max {
|
||||
break;
|
||||
}
|
||||
let entry = entry?;
|
||||
let Ok(entry) = entry else { continue };
|
||||
let path = entry.path();
|
||||
if path.is_dir() {
|
||||
if let Ok(sub) = walkdir_depth(&path, max_depth - 1) {
|
||||
results.extend(sub);
|
||||
}
|
||||
walkdir_depth_inner(&path, max_depth - 1, results, max);
|
||||
} else {
|
||||
results.push(path);
|
||||
}
|
||||
}
|
||||
Ok(results)
|
||||
}
|
||||
|
||||
/// Render text onto a transparent RGBA buffer and return it as a DynamicImage
|
||||
@@ -333,7 +336,7 @@ fn apply_tiled_text_watermark(
|
||||
let alpha = (opacity * 255.0).clamp(0.0, 255.0) as u8;
|
||||
let draw_color = Rgba([color[0], color[1], color[2], alpha]);
|
||||
|
||||
let text_width = ((text.len().min(10_000) as f32 * font_size.min(1000.0) * 0.6) as i64 + 4).min(8192);
|
||||
let text_width = ((text.chars().count().min(10_000) as f32 * font_size.min(1000.0) * 0.6) as i64 + 4).min(8192);
|
||||
let text_height = ((font_size.min(1000.0) * 1.4) as i64 + 4).min(4096);
|
||||
|
||||
let mut y = spacing as i64;
|
||||
@@ -363,8 +366,9 @@ fn apply_tiled_image_watermark(
|
||||
reason: format!("Failed to load watermark image: {}", e),
|
||||
})?;
|
||||
|
||||
let wm_width = ((watermark.width() as f32 * scale) as u32).clamp(1, 16384);
|
||||
let wm_height = ((watermark.height() as f32 * scale) as u32).clamp(1, 16384);
|
||||
let safe_scale = if scale.is_finite() && scale > 0.0 { scale } else { 1.0 };
|
||||
let wm_width = ((watermark.width() as f32 * safe_scale) as u32).clamp(1, 16384);
|
||||
let wm_height = ((watermark.height() as f32 * safe_scale) as u32).clamp(1, 16384);
|
||||
|
||||
let mut watermark = watermark.resize_exact(wm_width, wm_height, image::imageops::FilterType::Lanczos3);
|
||||
if let Some(rot) = rotation {
|
||||
@@ -426,8 +430,9 @@ fn apply_image_watermark(
|
||||
})?;
|
||||
|
||||
// Scale the watermark (capped to prevent OOM on extreme scale values)
|
||||
let wm_width = ((watermark.width() as f32 * scale) as u32).clamp(1, 16384);
|
||||
let wm_height = ((watermark.height() as f32 * scale) as u32).clamp(1, 16384);
|
||||
let safe_scale = if scale.is_finite() && scale > 0.0 { scale } else { 1.0 };
|
||||
let wm_width = ((watermark.width() as f32 * safe_scale) as u32).clamp(1, 16384);
|
||||
let wm_height = ((watermark.height() as f32 * safe_scale) as u32).clamp(1, 16384);
|
||||
|
||||
let mut watermark = watermark.resize_exact(
|
||||
wm_width,
|
||||
|
||||
Reference in New Issue
Block a user