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

@@ -109,6 +109,7 @@ pub struct AppState {
pub wizard: Rc<RefCell<WizardState>>,
pub loaded_files: Rc<RefCell<Vec<std::path::PathBuf>>>,
pub excluded_files: Rc<RefCell<std::collections::HashSet<std::path::PathBuf>>>,
pub file_sizes: Rc<RefCell<std::collections::HashMap<std::path::PathBuf, u64>>>,
pub output_dir: Rc<RefCell<Option<std::path::PathBuf>>>,
pub job_config: Rc<RefCell<JobConfig>>,
pub detailed_mode: bool,
@@ -321,6 +322,7 @@ fn build_ui(app: &adw::Application) {
wizard: Rc::new(RefCell::new(WizardState::new())),
loaded_files: Rc::new(RefCell::new(Vec::new())),
excluded_files: Rc::new(RefCell::new(std::collections::HashSet::new())),
file_sizes: Rc::new(RefCell::new(std::collections::HashMap::new())),
output_dir: Rc::new(RefCell::new(None)),
detailed_mode: app_cfg.skill_level.is_advanced(),
batch_queue: Rc::new(RefCell::new(BatchQueue::default())),
@@ -1397,6 +1399,7 @@ fn update_images_count_label(ui: &WizardUi, count: usize) {
&loaded_box,
&ui.state.loaded_files,
&ui.state.excluded_files,
&ui.state.file_sizes,
);
}
}
@@ -2576,14 +2579,10 @@ fn update_progress_labels(nav_view: &adw::NavigationView, current: usize, total:
if let Some(page) = nav_view.visible_page() {
walk_widgets(&page.child(), &|widget| {
if let Some(label) = widget.downcast_ref::<gtk::Label>() {
if label.css_classes().iter().any(|c| c == "heading")
&& (label.label().contains("images") || label.label().contains("0 /"))
{
if label.widget_name() == "processing-count-label" {
label.set_label(&format!("{} / {} images", current, total));
}
if label.css_classes().iter().any(|c| c == "dim-label")
&& (label.label().contains("Estimating") || label.label().contains("ETA") || label.label().contains("Almost") || label.label().contains("Current"))
{
if label.widget_name() == "processing-eta-label" {
if current < total {
label.set_label(&format!("{} - {}", eta, file));
} else {
@@ -2599,8 +2598,7 @@ fn add_log_entry(nav_view: &adw::NavigationView, current: usize, total: usize, f
if let Some(page) = nav_view.visible_page() {
walk_widgets(&page.child(), &|widget| {
if let Some(bx) = widget.downcast_ref::<gtk::Box>()
&& bx.spacing() == 2
&& bx.orientation() == gtk::Orientation::Vertical
&& bx.widget_name() == "processing-log-box"
{
let entry = gtk::Label::builder()
.label(format!("[{}/{}] {} - Done", current, total, file))