Skip to content

Commit 56ace43

Browse files
authored
Merge pull request #391 from josh-/fix-otp-space-escaping
Ensure that an OTP's issuer and label values are escaped correctly
2 parents b187fdf + 0fd25bc commit 56ace43

File tree

2 files changed

+44
-8
lines changed

2 files changed

+44
-8
lines changed

QRCoder/PayloadGenerator.cs

Lines changed: 11 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -2012,6 +2012,7 @@ private void ProcessCommonFields(StringBuilder sb)
20122012
}
20132013
string strippedSecret = Secret.Replace(" ", "");
20142014
string escapedIssuer = null;
2015+
string escapedLabel = null;
20152016
string label = null;
20162017

20172018
if (!String40Methods.IsNullOrWhiteSpace(Issuer))
@@ -2023,18 +2024,22 @@ private void ProcessCommonFields(StringBuilder sb)
20232024
escapedIssuer = Uri.EscapeDataString(Issuer);
20242025
}
20252026

2026-
if (!String40Methods.IsNullOrWhiteSpace(Label) && Label.Contains(":"))
2027+
if (!String40Methods.IsNullOrWhiteSpace(Label))
20272028
{
2028-
throw new Exception("Label must not have a ':'");
2029+
if (Label.Contains(":"))
2030+
{
2031+
throw new Exception("Label must not have a ':'");
2032+
}
2033+
escapedLabel = Uri.EscapeDataString(Label);
20292034
}
20302035

2031-
if (Label != null && Issuer != null)
2036+
if (escapedLabel != null && escapedIssuer != null)
20322037
{
2033-
label = Issuer + ":" + Label;
2038+
label = escapedIssuer + ":" + escapedLabel;
20342039
}
2035-
else if (Issuer != null)
2040+
else if (escapedIssuer != null)
20362041
{
2037-
label = Issuer;
2042+
label = escapedIssuer;
20382043
}
20392044

20402045
if (label != null)

QRCoderTests/PayloadGeneratorTests.cs

Lines changed: 33 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2656,7 +2656,22 @@ public void one_time_password_generator_time_based_generates_with_standard_optio
26562656
Label = "test@google.com",
26572657
};
26582658

2659-
pg.ToString().ShouldBe("otpauth://totp/Google:test@google.com?secret=pwq65q55&issuer=Google");
2659+
pg.ToString().ShouldBe("otpauth://totp/Google:test%40google.com?secret=pwq65q55&issuer=Google");
2660+
}
2661+
2662+
2663+
[Fact]
2664+
[Category("PayloadGenerator/OneTimePassword")]
2665+
public void one_time_password_generator_time_based_generates_with_standard_options_escapes_issuer_and_label()
2666+
{
2667+
var pg = new PayloadGenerator.OneTimePassword
2668+
{
2669+
Secret = "pwq6 5q55",
2670+
Issuer = "Google Google",
2671+
Label = "test/test@google.com",
2672+
};
2673+
2674+
pg.ToString().ShouldBe("otpauth://totp/Google%20Google:test%2Ftest%40google.com?secret=pwq65q55&issuer=Google%20Google");
26602675
}
26612676

26622677

@@ -2673,7 +2688,23 @@ public void one_time_password_generator_hmac_based_generates_with_standard_optio
26732688
Counter = 500,
26742689
};
26752690

2676-
pg.ToString().ShouldBe("otpauth://hotp/Google:test@google.com?secret=pwq65q55&issuer=Google&counter=500");
2691+
pg.ToString().ShouldBe("otpauth://hotp/Google:test%40google.com?secret=pwq65q55&issuer=Google&counter=500");
2692+
}
2693+
2694+
[Fact]
2695+
[Category("PayloadGenerator/OneTimePassword")]
2696+
public void one_time_password_generator_hmac_based_generates_with_standard_options_escapes_issuer_and_label()
2697+
{
2698+
var pg = new PayloadGenerator.OneTimePassword
2699+
{
2700+
Secret = "pwq6 5q55",
2701+
Issuer = "Google Google",
2702+
Label = "test/test@google.com",
2703+
Type = PayloadGenerator.OneTimePassword.OneTimePasswordAuthType.HOTP,
2704+
Counter = 500,
2705+
};
2706+
2707+
pg.ToString().ShouldBe("otpauth://hotp/Google%20Google:test%2Ftest%40google.com?secret=pwq65q55&issuer=Google%20Google&counter=500");
26772708
}
26782709

26792710

0 commit comments

Comments
 (0)