-
Notifications
You must be signed in to change notification settings - Fork 103
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
Conversation
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.
@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 |
There was a problem hiding this comment.
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) |
There was a problem hiding this comment.
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 |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Drive-by fix.
@swift-ci test |
while result == nil { | ||
result = withUnsafeTemporaryAllocation(of: CChar.self, capacity: Int(bufferCount)) { buffer in |
There was a problem hiding this comment.
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.
@swift-ci test |
There was a problem hiding this 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.
Eh, all but one are in the same function, just different platforms. I can live with it. 🙃 |
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 returningfalse
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: