Skip to content

Avoid truncating the path to the test executable on Windows. #724

New issue

Have a question about this project? # for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “#”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? # to your account

Merged
merged 3 commits into from
Sep 22, 2024

Conversation

grynspan
Copy link
Contributor

@grynspan grynspan commented Sep 21, 2024

On Windows, we get the path to the (current) test executable by calling GetModuleFileNameW(). This function has odd behaviour when the input buffer is too short. Rather than returning false or -1 or some such, as you might expect, it returns successfully but truncates the path (and null-terminates while doing so.)

The function does set the last error in this case to ERROR_INSUFFICIENT_BUFFER, indicating we need a larger buffer. (The error behaviour on Windows XP is different, but we don't support Windows XP. If you decide to add support for Windows XP to Swift Testing, keep this in mind.)

So this PR checks for ERROR_INSUFFICIENT_BUFFER and loops with a larger buffer, similar to what we do on Darwin.

Checklist:

  • Code and documentation should follow the style of the Style Guide.
  • If public symbols are renamed or modified, DocC references should be updated.

On Windows, we get the path to the (current) test executable by calling `GetModuleFileNameW()`. This function has odd behaviour when the input buffer is too short. Rather than returning `false` or `-1` or some such, as you might expect, it returns successfully but truncates the path (and null-terminates while doing so.)

The function _does_ set the last error in this case to `ERROR_INSUFFICIENT_BUFFER`, indicating we need a larger buffer. (The error behaviour on Windows XP is different, but we don't support Windows XP. If you decide to add support for Windows XP to Swift Testing, keep this in mind.)

So this PR checks for `ERROR_INSUFFICIENT_BUFFER` and loops with a larger buffer, similar to what we do on Darwin.
@grynspan grynspan added bug 🪲 Something isn't working windows 🪟 Windows support freebsd 😈 FreeBSD support labels Sep 21, 2024
@grynspan grynspan requested a review from compnerd September 21, 2024 21:25
@grynspan grynspan self-assigned this Sep 21, 2024
@grynspan
Copy link
Contributor Author

@swift-ci test

@@ -46,9 +46,9 @@ func spawnExecutable(
) throws -> ProcessID {
// Darwin and Linux differ in their optionality for the posix_spawn types we
// use, so use this typealias to paper over the differences.
#if SWT_TARGET_OS_APPLE
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Drive-by fix: FreeBSD defines these POSIX types as pointers to opaque structs, so they get imported similarly to Darwin (where they're just raw pointers) rather than Linux (where they're actually structures.)

@@ -16,7 +16,7 @@ extension CommandLine {
get throws {
#if os(macOS)
var result: String?
var bufferCount = UInt32(1024)
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Drive-by fix to use a named constant.

@@ -40,7 +40,7 @@ extension CommandLine {
}
#elseif os(FreeBSD)
var mib = [CTL_KERN, KERN_PROC, KERN_PROC_PATHNAME, -1]
try mib.withUnsafeMutableBufferPointer { mib in
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Drive-by fix.

@grynspan
Copy link
Contributor Author

@swift-ci test

while result == nil {
result = withUnsafeTemporaryAllocation(of: CChar.self, capacity: Int(bufferCount)) { buffer in
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Let's consistently set result in the buffer's scope rather than returning it. This saves us a return nil line and will be easier to translate if/when we get non-escaping buffers.

@grynspan
Copy link
Contributor Author

@swift-ci test

Copy link
Member

@compnerd compnerd left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

There's a good number of ancillary drive by fixes. Generally, it's nicer to split those out into a separate change.

@grynspan
Copy link
Contributor Author

Eh, all but one are in the same function, just different platforms. I can live with it. 🙃

@grynspan grynspan merged commit 9356239 into main Sep 22, 2024
3 checks passed
@grynspan grynspan deleted the jgrynspan/win32-GetModuleFileNameW-length branch September 22, 2024 17:21
# for free to join this conversation on GitHub. Already have an account? # to comment
Labels
bug 🪲 Something isn't working freebsd 😈 FreeBSD support windows 🪟 Windows support
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants