Skip to content

Windows: Audit, clarify, and add tests for resolve_exe() "append .EXE extension if the extension is different" (not just missing) behavior. #93124

@briansmith

Description

@briansmith

I was reading the code for resolve_exe() for some reason and I saw this code:

    let has_exe_suffix = if exe_path.len() >= EXE_SUFFIX.len() {
        exe_path.bytes()[exe_path.len() - EXE_SUFFIX.len()..]
            .eq_ignore_ascii_case(EXE_SUFFIX.as_bytes())
    } else {
        false
    };

(Incidentally, can't this be simplified?)

Then later:

        if has_exe_suffix {
             return [...];
        };

        // Append `.exe` if not already there.
        path = path::append_suffix(path, EXE_SUFFIX.as_ref());
        if path.try_exists().unwrap_or(false) {
            return Ok(path);
        } else {
            // It's ok to use `set_extension` here because the intent is to
            // remove the extension that was just added.
            path.set_extension("");
            return Ok(path);
        }

Appending EXE_SUFFIX if the extension isn't already EXE seems wrong to me; I think instead it would make more sense to use exactly the same rules that CreateProcessW is documented to use, which is roughly "there is no extension," not "the extension isn't .exe".

Further, let's say there is an extension that isn't EXE_SUFFIX, and we append EXE_SUFFIX and we find that the file doesn't exist. Then we remove the extension. The comment implies that this will reset the extension to what it was before, but this is only true if there was no extension at all. What if there was an extension that wasn't EXE_SUFFIX?

Metadata

Metadata

Assignees

No one assigned

    Labels

    C-bugCategory: This is a bug.O-windowsOperating system: Windows

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions