From 088ec2fc8490eb05093062d08cc66bce06d5ec5e Mon Sep 17 00:00:00 2001 From: Curtis Vogt Date: Thu, 29 Nov 2018 15:49:41 -0600 Subject: [PATCH] Fix issue with Git Credential Manager for Windows (#30195) - Ignores additional whitespace when reading in credentials. - Warn when encountering unknown attributes. Should allow for more graceful failures in the future if the protocol is extended. (cherry picked from commit 4b270b13ba935cfe061c8350c4bded006873bcf0) --- stdlib/LibGit2/src/gitcredential.jl | 7 +++++- stdlib/LibGit2/test/libgit2.jl | 39 +++++++++++++++++++++++++++++ 2 files changed, 45 insertions(+), 1 deletion(-) diff --git a/stdlib/LibGit2/src/gitcredential.jl b/stdlib/LibGit2/src/gitcredential.jl index ce51ea7dd15e4..7490a93cefe2e 100644 --- a/stdlib/LibGit2/src/gitcredential.jl +++ b/stdlib/LibGit2/src/gitcredential.jl @@ -1,5 +1,7 @@ # This file is a part of Julia. License is MIT: https://julialang.org/license +const GIT_CRED_ATTRIBUTES = ("protocol", "host", "path", "username", "password", "url") + """ GitCredential @@ -111,16 +113,19 @@ function Base.read!(io::IO, cred::GitCredential) else value = readuntil(io, '\n') end + if key == "url" # Any components which are missing from the URL will be set to empty # https://git-scm.com/docs/git-credential#git-credential-codeurlcode Base.shred!(parse(GitCredential, value)) do urlcred copy!(cred, urlcred) end - else + elseif key in GIT_CRED_ATTRIBUTES field = getproperty(cred, Symbol(key)) field !== nothing && Symbol(key) == :password && Base.shred!(field) setproperty!(cred, Symbol(key), value) + elseif !all(isspace, key) + @warn "Unknown git credential attribute found: $(repr(key))" end end diff --git a/stdlib/LibGit2/test/libgit2.jl b/stdlib/LibGit2/test/libgit2.jl index 7c95aa6e89ecc..23d4c17da32fd 100644 --- a/stdlib/LibGit2/test/libgit2.jl +++ b/stdlib/LibGit2/test/libgit2.jl @@ -462,6 +462,45 @@ end Base.shred!(expected_cred) end + @testset "extra newline" begin + # The "Git for Windows" installer will also install the "Git Credential Manager for + # Windows" (https://github.com/Microsoft/Git-Credential-Manager-for-Windows) (also + # known as "manager" in the .gitconfig files). This credential manager returns an + # additional newline when returning the results. + str = """ + protocol=https + host=example.com + path= + username=bob + password=***** + + """ + expected_cred = LibGit2.GitCredential("https", "example.com", "", "bob", "*****") + + cred = read!(IOBuffer(str), LibGit2.GitCredential()) + @test cred == expected_cred + @test sprint(write, cred) * "\n" == str + Base.shred!(cred) + Base.shred!(expected_cred) + end + + @testset "unknown attribute" begin + str = """ + protocol=https + host=example.com + attribute=value + username=bob + password=***** + """ + expected_cred = LibGit2.GitCredential("https", "example.com", nothing, "bob", "*****") + expected_log = (:warn, "Unknown git credential attribute found: \"attribute\"") + + cred = @test_logs expected_log read!(IOBuffer(str), LibGit2.GitCredential()) + @test cred == expected_cred + Base.shred!(cred) + Base.shred!(expected_cred) + end + @testset "use http path" begin cred = LibGit2.GitCredential("https", "example.com", "dir/file", "alice", "*****") expected = """