Skip to content

Resolve Executable.name(_:) against PATH only on every platform - #359

Merged
iCharlesHu merged 1 commit into
swiftlang:mainfrom
iCharlesHu:charles/executable-name-resolution
Aug 4, 2026
Merged

Resolve Executable.name(_:) against PATH only on every platform#359
iCharlesHu merged 1 commit into
swiftlang:mainfrom
iCharlesHu:charles/executable-name-resolution

Conversation

@iCharlesHu

@iCharlesHu iCharlesHu commented Jul 31, 2026

Copy link
Copy Markdown
Contributor

Executable.name(_:) is documented as a PATH lookup, but it also searched a current directory ahead of PATH. This behavior is opposite of what every POSIX runtime agreed on, and it allows potential arbitrary execution. Update Executable.name(_:) such that an executable name now resolves the same way on all platforms: by walking the PATH the subprocess will receive, falling back to the current process's value and then to the directories the platform reports as standard (confstr(_CS_PATH) on Unix, the CreateProcessW search list without the current directory on Windows). Empty and relative entries are skipped, so every resolved path is absolute and resolveExecutablePath(in:) agrees with the spawn path, and a name containing a path separator is now rejected with spawnFailed rather than resolved against a current directory.

@iCharlesHu
iCharlesHu requested a review from jakepetroules July 31, 2026 07:28
@iCharlesHu

Copy link
Copy Markdown
Contributor Author

Resolves: #357

Executable.name(_:) is documented as a PATH lookup, but it also searched a current directory ahead of PATH. This behavior is opposite of what every POSIX runtime agreed on, and it allows potential arbitrary execution. Update Executable.name(_:) such that an executable name now resolves the same way on all platforms: by walking the PATH the subprocess will receive, falling back to the current process's value and then to the directories the platform reports as standard (confstr(_CS_PATH) on Unix, the CreateProcessW search list without the current directory on Windows). Empty and relative entries are skipped, so every resolved path is absolute and resolveExecutablePath(in:) agrees with the spawn path, and a name containing a path separator is now rejected with spawnFailed rather than resolved against a current directory.
@iCharlesHu
iCharlesHu force-pushed the charles/executable-name-resolution branch from fd7e1d5 to f70630f Compare July 31, 2026 16:14
Comment thread Sources/Subprocess/Configuration.swift
@iCharlesHu
iCharlesHu merged commit b3937ab into swiftlang:main Aug 4, 2026
45 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants