Skip to content

Commit 96cf7f5

Browse files
pwallrichbnbarham
authored andcommitted
Fix empty token on swift package-registry login (Issue swiftlang#7453) (swiftlang#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 swiftlang#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. (cherry picked from commit d8c8d0f)
1 parent 49e47f9 commit 96cf7f5

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
@@ -68,12 +68,13 @@ private func readpassword(_ prompt: String) throws -> String {
6868

6969
#if canImport(Darwin)
7070
var buffer = [CChar](repeating: 0, count: PackageRegistryCommand.Login.passwordBufferSize)
71+
password = try withExtendedLifetime(buffer) {
72+
guard let passwordPtr = readpassphrase(prompt, &buffer, buffer.count, 0) else {
73+
throw StringError("unable to read input")
74+
}
7175

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

0 commit comments

Comments
 (0)