Checks to see if a token contains any illegal characters, like whitespace or a newline. If it is, throws an ArgumentException warning the user that their token may be invalid. I considered only checking the first and last character, but given that a token containing whitespace or a newline wouldn't work either I figured this made sense.pull/1305/head
@@ -1,4 +1,6 @@ | |||||
using System; | using System; | ||||
using System.Collections.Generic; | |||||
using System.Collections.Immutable; | |||||
using System.Text; | using System.Text; | ||||
namespace Discord | namespace Discord | ||||
@@ -119,6 +121,25 @@ namespace Discord | |||||
return DecodeBase64UserId(segments[0]).HasValue; | return DecodeBase64UserId(segments[0]).HasValue; | ||||
} | } | ||||
/// <summary> | |||||
/// The set of all characters that are not allowed inside of a token. | |||||
/// </summary> | |||||
internal static char[] IllegalTokenCharacters = new char[] | |||||
{ | |||||
' ', '\t', '\r', '\n' | |||||
}; | |||||
/// <summary> | |||||
/// Checks if the given token contains a whitespace or newline character | |||||
/// that would fail to log in. | |||||
/// </summary> | |||||
/// <param name="token"> The token to validate. </param> | |||||
/// <returns> | |||||
/// True if the token contains a whitespace or newline character. | |||||
/// </returns> | |||||
internal static bool CheckContainsIllegalCharacters(string token) | |||||
=> token.IndexOfAny(IllegalTokenCharacters) != -1; | |||||
/// <summary> | /// <summary> | ||||
/// Checks the validity of the supplied token of a specific type. | /// Checks the validity of the supplied token of a specific type. | ||||
/// </summary> | /// </summary> | ||||
@@ -131,6 +152,9 @@ namespace Discord | |||||
// A Null or WhiteSpace token of any type is invalid. | // A Null or WhiteSpace token of any type is invalid. | ||||
if (string.IsNullOrWhiteSpace(token)) | if (string.IsNullOrWhiteSpace(token)) | ||||
throw new ArgumentNullException(paramName: nameof(token), message: "A token cannot be null, empty, or contain only whitespace."); | throw new ArgumentNullException(paramName: nameof(token), message: "A token cannot be null, empty, or contain only whitespace."); | ||||
// ensure that there are no whitespace or newline characters | |||||
if (CheckContainsIllegalCharacters(token)) | |||||
throw new ArgumentException(message: "The token contains a whitespace or newline character. Ensure that the token has been properly trimmed.", paramName: nameof(token)); | |||||
switch (tokenType) | switch (tokenType) | ||||
{ | { | ||||
@@ -99,6 +99,16 @@ namespace Discord | |||||
[InlineData("937it3ow87i4ery69876wqire")] | [InlineData("937it3ow87i4ery69876wqire")] | ||||
// 57 char bot token | // 57 char bot token | ||||
[InlineData("MTk4NjIyNDgzNDcxOTI1MjQ4.Cl2FMQ.ZnCjm1XVW7vRze4b7Cq4se7kK")] | [InlineData("MTk4NjIyNDgzNDcxOTI1MjQ4.Cl2FMQ.ZnCjm1XVW7vRze4b7Cq4se7kK")] | ||||
// ends with invalid characters | |||||
[InlineData("MTk4NjIyNDgzNDcxOTI1MjQ4.Cl2FMQ.ZnCjm1XVW7vRze4b7Cq4se7k ")] | |||||
[InlineData("MTk4NjIyNDgzNDcxOTI1MjQ4.Cl2FMQ.ZnCjm1XVW7vRze4b7Cq4se7k\n")] | |||||
[InlineData("MTk4NjIyNDgzNDcxOTI1MjQ4.Cl2FMQ.ZnCjm1XVW7vRze4b7Cq4se7k\t")] | |||||
[InlineData("MTk4NjIyNDgzNDcxOTI1MjQ4.Cl2FMQ.ZnCjm1XVW7vRze4b7Cq4se7k\r\n")] | |||||
// starts with invalid characters | |||||
[InlineData(" MTk4NjIyNDgzNDcxOTI1MjQ4.Cl2FMQ.ZnCjm1XVW7vRze4b7Cq4se7k")] | |||||
[InlineData("\nMTk4NjIyNDgzNDcxOTI1MjQ4.Cl2FMQ.ZnCjm1XVW7vRze4b7Cq4se7k")] | |||||
[InlineData("\tMTk4NjIyNDgzNDcxOTI1MjQ4.Cl2FMQ.ZnCjm1XVW7vRze4b7Cq4se7k")] | |||||
[InlineData("\r\nMTk4NjIyNDgzNDcxOTI1MjQ4.Cl2FMQ.ZnCjm1XVW7vRze4b7Cq4se7k")] | |||||
[InlineData("This is an invalid token, but it passes the check for string length.")] | [InlineData("This is an invalid token, but it passes the check for string length.")] | ||||
// valid token, but passed in twice | // valid token, but passed in twice | ||||
[InlineData("MTk4NjIyNDgzNDcxOTI1MjQ4.Cl2FMQ.ZnCjm1XVW7vRze4b7Cq4se7kKWsMTk4NjIyNDgzNDcxOTI1MjQ4.Cl2FMQ.ZnCjm1XVW7vRze4b7Cq4se7kKWs")] | [InlineData("MTk4NjIyNDgzNDcxOTI1MjQ4.Cl2FMQ.ZnCjm1XVW7vRze4b7Cq4se7kKWsMTk4NjIyNDgzNDcxOTI1MjQ4.Cl2FMQ.ZnCjm1XVW7vRze4b7Cq4se7kKWs")] | ||||