Skip to content
This repository was archived by the owner on Jul 15, 2023. It is now read-only.

Commit ebcaec0

Browse files
simonechwhoisj
authored andcommitted
Escaping reserved characters in username when creating resposity uri
Since username needs to be part of URIs, they cannot contain reserved characters, so they need to be escaped
1 parent 9f79cfd commit ebcaec0

File tree

2 files changed

+72
-1
lines changed

2 files changed

+72
-1
lines changed

Cli-CredentialHelper.Test/OperationArgumentsTests.cs

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -84,6 +84,43 @@ public void SpecialCharacters()
8484
Assert.Equal(expected, actual, StringComparer.Ordinal);
8585
}
8686

87+
[Fact]
88+
public void EmailAsUserName()
89+
{
90+
var input = new InputArg
91+
{
92+
Host = "example.visualstudio.com",
93+
Password = "ḭncorrect",
94+
Path = "path",
95+
Protocol = Uri.UriSchemeHttps,
96+
Username = "[email protected]"
97+
};
98+
99+
OperationArguments cut;
100+
using (var memory = new MemoryStream())
101+
using (var writer = new StreamWriter(memory))
102+
{
103+
writer.Write(input.ToString());
104+
writer.Flush();
105+
106+
memory.Seek(0, SeekOrigin.Begin);
107+
108+
cut = new OperationArguments(memory);
109+
}
110+
111+
Assert.Equal(input.Protocol, cut.QueryProtocol, StringComparer.Ordinal);
112+
Assert.Equal(input.Host, cut.QueryHost, StringComparer.Ordinal);
113+
Assert.Equal(input.Path, cut.QueryPath, StringComparer.Ordinal);
114+
Assert.Equal(input.Username, cut.Username, StringComparer.Ordinal);
115+
Assert.Equal(input.Password, cut.Password, StringComparer.Ordinal);
116+
117+
Assert.Equal("https://[email protected]@example.visualstudio.com/path", cut.TargetUri.ToString(), StringComparer.Ordinal);
118+
119+
var expected = input.ToString();
120+
var actual = cut.ToString();
121+
Assert.Equal(expected, actual, StringComparer.Ordinal);
122+
}
123+
87124
[Fact]
88125
public void CreateTargetUriGitHubSimple()
89126
{

Cli-Shared/OperationArguments.cs

Lines changed: 35 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -511,7 +511,11 @@ internal virtual void CreateTargetUri()
511511
// Username.
512512
if (!string.IsNullOrWhiteSpace(_username))
513513
{
514-
buffer.Append(_username)
514+
var username = NeedsToBeEscaped(_username)
515+
? Uri.EscapeDataString(_username)
516+
: _username;
517+
518+
buffer.Append(username)
515519
.Append('@');
516520
}
517521

@@ -530,5 +534,35 @@ internal virtual void CreateTargetUri()
530534
// Create the target URI object.
531535
_targetUri = new TargetUri(queryUrl, proxyUrl);
532536
}
537+
538+
private static bool NeedsToBeEscaped(string value)
539+
{
540+
for (int i = 0; i < value.Length; i += 1)
541+
{
542+
switch (value[i])
543+
{
544+
case ':':
545+
case '/':
546+
case '?':
547+
case '#':
548+
case '[':
549+
case ']':
550+
case '@':
551+
case '!':
552+
case '$':
553+
case '&':
554+
case '\'':
555+
case '(':
556+
case ')':
557+
case '*':
558+
case '+':
559+
case ',':
560+
case ';':
561+
case '=':
562+
return true;
563+
}
564+
}
565+
return false;
566+
}
533567
}
534568
}

0 commit comments

Comments
 (0)