Fix 16 medium-severity bugs from audit

CLI: add UTC suffix to timestamps, validate image extensions on
single-file input, canonicalize watch paths for reliable matching,
derive counter_enabled from template presence, warn when undo count
exceeds available batches.

Core: apply space/special-char transforms in template rename path,
warn on metadata preservation for unsupported formats, derive AVIF
speed from compress preset quality level.

GTK: use buffer size for apples-to-apples compress preview comparison,
shorten approximate format labels, cache file sizes to avoid repeated
syscalls on checkbox toggle, add batch-update guard to prevent O(n^2)
in select/deselect all, use widget names for reliable progress/log
lookup, add unique suffix for duplicate download filenames.
This commit is contained in:
2026-03-07 23:02:57 +02:00
parent 9ef33fa90f
commit 9fcbe237bd
7 changed files with 136 additions and 50 deletions

View File

@@ -252,7 +252,15 @@ fn cmd_process(args: CmdProcessArgs) {
let files = discovery::discover_images(&path, args.recursive);
source_files.extend(files);
} else if path.is_file() {
source_files.push(path);
if path.extension()
.and_then(|e| e.to_str())
.and_then(pixstrip_core::types::ImageFormat::from_extension)
.is_some()
{
source_files.push(path);
} else {
eprintln!("Warning: '{}' is not a recognized image format, skipping", path_str);
}
} else {
eprintln!("Warning: '{}' not found, skipping", path_str);
}
@@ -338,7 +346,7 @@ fn cmd_process(args: CmdProcessArgs) {
suffix: args.rename_suffix.unwrap_or_default(),
counter_start: 1,
counter_padding: 3,
counter_enabled: true,
counter_enabled: args.rename_template.is_some(),
counter_position: 3,
template: args.rename_template,
case_mode: 0,
@@ -398,16 +406,26 @@ fn cmd_process(args: CmdProcessArgs) {
if result.failed > 0 {
println!(" Failed: {}", result.failed);
}
println!(
" Size: {} -> {} ({:.0}% reduction)",
format_bytes(result.total_input_bytes),
format_bytes(result.total_output_bytes),
if result.total_input_bytes > 0 {
(1.0 - result.total_output_bytes as f64 / result.total_input_bytes as f64) * 100.0
} else {
0.0
}
);
if result.total_input_bytes > 0 && result.total_output_bytes > result.total_input_bytes {
let increase = (result.total_output_bytes as f64 / result.total_input_bytes as f64 - 1.0) * 100.0;
println!(
" Size: {} -> {} (+{:.0}% increase)",
format_bytes(result.total_input_bytes),
format_bytes(result.total_output_bytes),
increase,
);
} else {
println!(
" Size: {} -> {} ({:.0}% reduction)",
format_bytes(result.total_input_bytes),
format_bytes(result.total_output_bytes),
if result.total_input_bytes > 0 {
(1.0 - result.total_output_bytes as f64 / result.total_input_bytes as f64) * 100.0
} else {
0.0
}
);
}
println!(" Time: {}", format_duration(result.elapsed_ms));
println!(" Output: {}", output_dir.display());
@@ -533,6 +551,9 @@ fn cmd_undo(count: usize) {
}
let undo_count = count.min(entries.len());
if count > entries.len() {
eprintln!("Warning: requested {} batches but only {} available", count, entries.len());
}
let to_undo = entries.split_off(entries.len() - undo_count);
let mut total_trashed = 0;
let mut failed_entries = Vec::new();
@@ -598,6 +619,7 @@ fn cmd_watch_add(path: &str, preset_name: &str, recursive: bool) {
std::process::exit(1);
}
let watch_path = PathBuf::from(path);
let watch_path = watch_path.canonicalize().unwrap_or(watch_path);
if !watch_path.exists() {
eprintln!("Watch folder does not exist: {}", path);
std::process::exit(1);
@@ -711,7 +733,8 @@ fn cmd_watch_remove(path: &str) {
let original_len = watches.len();
let target = PathBuf::from(path);
watches.retain(|w| w.path != target);
let target_canonical = target.canonicalize().unwrap_or(target.clone());
watches.retain(|w| w.path != target && w.path != target_canonical);
if watches.len() == original_len {
println!("Watch folder not found: {}", path);
@@ -1082,7 +1105,7 @@ fn format_timestamp(ts: &str) -> String {
month += 1;
}
format!("{:04}-{:02}-{:02} {:02}:{:02}:{:02}", year, month, d + 1, hours, minutes, seconds)
format!("{:04}-{:02}-{:02} {:02}:{:02}:{:02} UTC", year, month, d + 1, hours, minutes, seconds)
}
#[cfg(test)]