Skip to content

Commit

Permalink
Add empty string in non-multi dictionary for empty lines (#1332)
Browse files Browse the repository at this point in the history
Before 2.2.0, we only accepted input arguments in the form `key=value`.
To support the new `wwwauth[]` argument from Git, we added support for
these multi-value args `key[]=value`.

In changing from an dictionary of `string:string` to
`string:list<string>` we accidentally changed the behaviour of
dictionary parsing in the case that an empty valued (non-multi) argument
was provided. For example:

```text
username=\n
```

Previously this was returned as an empty string. Post 2.2.0 this became
`null`, causing an error in scenarios were before there was none.

One such scenario is with Windows Integrated Authentication (for example
when connecting to Azure DevOps Server/TFS instances), whereby we return
an empty username and password to Git to signal this auth mode. Git then
returns to us the empty username and password in a `store` call.

Update the handling in `ParseMultiLine` to restore the previous
behaviour for empty-valued arguments being mapped to the empty string.

Fixes #1331

---

**Bug reproduction steps:**

```console
% printf "url=https://example.com\nusername=\npassword=\n\n" | git credential approve
fatal: Missing 'username' input argument
```
  • Loading branch information
mjcheetham authored Jul 12, 2023
2 parents 0d70623 + 93cada9 commit a36bb0e
Show file tree
Hide file tree
Showing 2 changed files with 18 additions and 4 deletions.
13 changes: 13 additions & 0 deletions src/shared/Core.Tests/StreamExtensionsTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -254,6 +254,19 @@ public void StreamExtensions_ReadMultiDictionary_CaseInsensitive_ReturnsDictiona
AssertMultiDictionary(new[] { "2" }, "a", output);
}

[Fact]
public void StreamExtensions_ReadMultiDictionary_EmptyString_ReturnsKeyWithEmptyStringValue()
{
string input = "a=\n\n";

var output = ReadStringStream(input, StreamExtensions.ReadMultiDictionary);

Assert.NotNull(output);
Assert.Equal(1, output.Count);

AssertMultiDictionary(new[] { String.Empty, }, "a", output);
}

[Fact]
public void StreamExtensions_ReadMultiDictionary_Spaces_ReturnsCorrectKeysAndValues()
{
Expand Down
9 changes: 5 additions & 4 deletions src/shared/Core/StreamExtensions.cs
Original file line number Diff line number Diff line change
Expand Up @@ -248,14 +248,15 @@ private static void ParseMultiLine(IDictionary<string, IList<string>> dict, stri
// Only allow one value for non-multi/array entries ("key=value")
// and reset the array of a multi-entry if the value is empty ("key[]=<empty>")
bool emptyValue = string.IsNullOrEmpty(value);

if (!multi || emptyValue)
{
list.Clear();
}

if (emptyValue)
{
return;
}
if (multi && emptyValue)
{
return;
}

list.Add(value);
Expand Down

0 comments on commit a36bb0e

Please sign in to comment.