Skip to content

Commit d8c8d0f

Browse files
authored
Fix empty token on swift package-registry login (Issue #7453) (#7454)
Fix empty token when adding a new package-registry and adding token interactively on release builds ### Motivation: When executing swift package-registry login it asks for a token but fails to retrieve it properly. It sends an empty string to the registry server and login therefore fails. (see #7453) ### Modifications: I've debugged the code a bit and found out, that somehow `buffer` and `passwordPtr` don't seem to be holding correct values after the `readpassphrase` call. - An easy quick fix is to make sure that `buffer` doesn't get deallocated by adding smth like `_ = buffer` after the String init. This works but is not nice. - My first try was to use `buffer` instead of `passwordPtr` to create the string. These works, but I remember reading somewhere that `&` can be quite nasty sometimes. - I also tried `buffer.withUnsafeMutablePointer`. However `readpassphrase` seems to not only change the content of `buffer` but move it. This leads to a runtime failure `Fatal error: Array withUnsafeMutableBufferPointer: replacing the buffer is not allowed` ### Result: The buffer is retained, the token is properly parsed and sent to the server.
1 parent f249153 commit d8c8d0f

File tree

1 file changed

+5
-4
lines changed

1 file changed

+5
-4
lines changed

Sources/PackageRegistryCommand/PackageRegistryCommand+Auth.swift

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -71,12 +71,13 @@ private func readpassword(_ prompt: String) throws -> String {
7171

7272
#if canImport(Darwin)
7373
var buffer = [CChar](repeating: 0, count: PackageRegistryCommand.Login.passwordBufferSize)
74+
password = try withExtendedLifetime(buffer) {
75+
guard let passwordPtr = readpassphrase(prompt, &buffer, buffer.count, 0) else {
76+
throw StringError("unable to read input")
77+
}
7478

75-
guard let passwordPtr = readpassphrase(prompt, &buffer, buffer.count, 0) else {
76-
throw StringError("unable to read input")
79+
return String(cString: passwordPtr)
7780
}
78-
79-
password = String(cString: passwordPtr)
8081
#else
8182
// GNU C implementation of getpass has no limit on the password length
8283
// (https://man7.org/linux/man-pages/man3/getpass.3.html)

0 commit comments

Comments
 (0)