Skip to content

Panic in check_file_or_append when filename has no extension #1183

@kuishou68

Description

@kuishou68

Bug Report

File: src-tauri/src/util.rscheck_file_or_append function

Description

The check_file_or_append function panics at runtime when a file path has no extension, because it calls .unwrap() on the result of PathBuf::extension(), which returns None for extension-less filenames.

let extension = new_path.extension().unwrap().to_string_lossy().to_string();
//                                  ^^^^^^^^ panics if no extension!

Similarly, file_stem().unwrap() will panic for root paths (though that's a rarer edge case).

Steps to Reproduce

  1. Use the download_file or download_file_by_binary command with a filename that has no extension (e.g., myfile, Makefile, README).
  2. If the file already exists in the download directory, check_file_or_append is invoked and the extension().unwrap() call panics, crashing the backend.

Expected Behavior

The function should gracefully handle files without an extension by appending a counter suffix directly to the stem (e.g., myfilemyfile-1, myfile-2).

Proposed Fix

Use map_or / unwrap_or_default for the extension, and match on an Option for the stem:

let file_stem = new_path.file_stem().map(|s| s.to_string_lossy().to_string()).unwrap_or_default();
let extension = new_path.extension().map(|e| e.to_string_lossy().to_string());
let parent_dir = new_path.parent().unwrap_or(Path::new(""));

let new_file_stem = match file_stem.rfind('-') {
    Some(index) if file_stem[index + 1..].parse::<u32>().is_ok() => {
        let base_name = &file_stem[..index];
        counter = file_stem[index + 1..].parse::<u32>().unwrap() + 1;
        format!("{base_name}-{counter}")
    }
    _ => {
        counter += 1;
        format!("{file_stem}-{counter}")
    }
};

new_path = match &extension {
    Some(ext) => parent_dir.join(format!("{new_file_stem}.{ext}")),
    None => parent_dir.join(new_file_stem),
};

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions