This updates most occurances in the code where a Parse or TryParse method was used to explicitly state the NumberStyle, and to use CultureInfo.InvariantCulture. CultureInfo was used over NumberInfo, as it also works on DateTime parsing too.pull/1375/head
| @@ -47,7 +47,7 @@ namespace Discord.Commands | |||||
| if (index >= 0) | if (index >= 0) | ||||
| { | { | ||||
| string username = input.Substring(0, index); | string username = input.Substring(0, index); | ||||
| if (ushort.TryParse(input.Substring(index + 1), out ushort discriminator)) | |||||
| if (ushort.TryParse(input.Substring(index + 1), NumberStyles.None, CultureInfo.InvariantCulture, out ushort discriminator)) | |||||
| { | { | ||||
| var channelUser = await channelUsers.FirstOrDefault(x => x.DiscriminatorValue == discriminator && | var channelUser = await channelUsers.FirstOrDefault(x => x.DiscriminatorValue == discriminator && | ||||
| string.Equals(username, x.Username, StringComparison.OrdinalIgnoreCase)).ConfigureAwait(false); | string.Equals(username, x.Username, StringComparison.OrdinalIgnoreCase)).ConfigureAwait(false); | ||||
| @@ -1,4 +1,5 @@ | |||||
| using System; | using System; | ||||
| using System.Globalization; | |||||
| using System.Text; | using System.Text; | ||||
| namespace Discord | namespace Discord | ||||
| @@ -76,7 +77,7 @@ namespace Discord | |||||
| var bytes = Convert.FromBase64String(encoded); | var bytes = Convert.FromBase64String(encoded); | ||||
| var idStr = Encoding.UTF8.GetString(bytes); | var idStr = Encoding.UTF8.GetString(bytes); | ||||
| // try to parse a ulong from the resulting string | // try to parse a ulong from the resulting string | ||||
| if (ulong.TryParse(idStr, out var id)) | |||||
| if (ulong.TryParse(idStr, NumberStyles.None, CultureInfo.InvariantCulture, out var id)) | |||||
| return id; | return id; | ||||
| } | } | ||||
| catch (DecoderFallbackException) | catch (DecoderFallbackException) | ||||
| @@ -1488,7 +1488,7 @@ namespace Discord.API | |||||
| builder.Append(format, lastIndex, leftIndex - lastIndex); | builder.Append(format, lastIndex, leftIndex - lastIndex); | ||||
| int rightIndex = format.IndexOf("}", leftIndex); | int rightIndex = format.IndexOf("}", leftIndex); | ||||
| int argId = int.Parse(format.Substring(leftIndex + 1, rightIndex - leftIndex - 1)); | |||||
| int argId = int.Parse(format.Substring(leftIndex + 1, rightIndex - leftIndex - 1), NumberStyles.None, CultureInfo.InvariantCulture); | |||||
| string fieldName = GetFieldName(methodArgs[argId + 1]); | string fieldName = GetFieldName(methodArgs[argId + 1]); | ||||
| var mappedId = BucketIds.GetIndex(fieldName); | var mappedId = BucketIds.GetIndex(fieldName); | ||||
| @@ -1,6 +1,7 @@ | |||||
| using System; | using System; | ||||
| using System.Collections.Immutable; | using System.Collections.Immutable; | ||||
| using System.Diagnostics; | using System.Diagnostics; | ||||
| using System.Globalization; | |||||
| using System.Threading.Tasks; | using System.Threading.Tasks; | ||||
| using Model = Discord.API.User; | using Model = Discord.API.User; | ||||
| @@ -57,7 +58,7 @@ namespace Discord.Rest | |||||
| if (model.Avatar.IsSpecified) | if (model.Avatar.IsSpecified) | ||||
| AvatarId = model.Avatar.Value; | AvatarId = model.Avatar.Value; | ||||
| if (model.Discriminator.IsSpecified) | if (model.Discriminator.IsSpecified) | ||||
| DiscriminatorValue = ushort.Parse(model.Discriminator.Value); | |||||
| DiscriminatorValue = ushort.Parse(model.Discriminator.Value, NumberStyles.None, CultureInfo.InvariantCulture); | |||||
| if (model.Bot.IsSpecified) | if (model.Bot.IsSpecified) | ||||
| IsBot = model.Bot.Value; | IsBot = model.Bot.Value; | ||||
| if (model.Username.IsSpecified) | if (model.Username.IsSpecified) | ||||
| @@ -1,6 +1,7 @@ | |||||
| using Discord.API; | |||||
| using Discord.API; | |||||
| using Newtonsoft.Json; | using Newtonsoft.Json; | ||||
| using System; | using System; | ||||
| using System.Globalization; | |||||
| namespace Discord.Net.Converters | namespace Discord.Net.Converters | ||||
| { | { | ||||
| @@ -23,7 +24,7 @@ namespace Discord.Net.Converters | |||||
| { | { | ||||
| case JsonToken.String: | case JsonToken.String: | ||||
| case JsonToken.Integer: | case JsonToken.Integer: | ||||
| return new EntityOrId<T>(ulong.Parse(reader.ReadAsString())); | |||||
| return new EntityOrId<T>(ulong.Parse(reader.ReadAsString(), NumberStyles.None, CultureInfo.InvariantCulture)); | |||||
| default: | default: | ||||
| T obj; | T obj; | ||||
| if (_innerConverter != null) | if (_innerConverter != null) | ||||
| @@ -18,15 +18,15 @@ namespace Discord.Net | |||||
| IsGlobal = headers.TryGetValue("X-RateLimit-Global", out string temp) && | IsGlobal = headers.TryGetValue("X-RateLimit-Global", out string temp) && | ||||
| bool.TryParse(temp, out var isGlobal) && isGlobal; | bool.TryParse(temp, out var isGlobal) && isGlobal; | ||||
| Limit = headers.TryGetValue("X-RateLimit-Limit", out temp) && | Limit = headers.TryGetValue("X-RateLimit-Limit", out temp) && | ||||
| int.TryParse(temp, out var limit) ? limit : (int?)null; | |||||
| int.TryParse(temp, NumberStyles.None, CultureInfo.InvariantCulture, out var limit) ? limit : (int?)null; | |||||
| Remaining = headers.TryGetValue("X-RateLimit-Remaining", out temp) && | Remaining = headers.TryGetValue("X-RateLimit-Remaining", out temp) && | ||||
| int.TryParse(temp, out var remaining) ? remaining : (int?)null; | |||||
| int.TryParse(temp, NumberStyles.None, CultureInfo.InvariantCulture, out var remaining) ? remaining : (int?)null; | |||||
| Reset = headers.TryGetValue("X-RateLimit-Reset", out temp) && | Reset = headers.TryGetValue("X-RateLimit-Reset", out temp) && | ||||
| double.TryParse(temp, NumberStyles.AllowDecimalPoint, NumberFormatInfo.InvariantInfo, out var reset) ? DateTimeOffset.FromUnixTimeMilliseconds((long)(reset * 1000)) : (DateTimeOffset?)null; | |||||
| double.TryParse(temp, NumberStyles.AllowDecimalPoint, CultureInfo.InvariantCulture, out var reset) ? DateTimeOffset.FromUnixTimeMilliseconds((long)(reset * 1000)) : (DateTimeOffset?)null; | |||||
| RetryAfter = headers.TryGetValue("Retry-After", out temp) && | RetryAfter = headers.TryGetValue("Retry-After", out temp) && | ||||
| int.TryParse(temp, out var retryAfter) ? retryAfter : (int?)null; | |||||
| int.TryParse(temp, NumberStyles.None, CultureInfo.InvariantCulture, out var retryAfter) ? retryAfter : (int?)null; | |||||
| Lag = headers.TryGetValue("Date", out temp) && | Lag = headers.TryGetValue("Date", out temp) && | ||||
| DateTimeOffset.TryParse(temp, out var date) ? DateTimeOffset.UtcNow - date : (TimeSpan?)null; | |||||
| DateTimeOffset.TryParse(temp, CultureInfo.InvariantCulture, DateTimeStyles.None, out var date) ? DateTimeOffset.UtcNow - date : (TimeSpan?)null; | |||||
| } | } | ||||
| } | } | ||||
| } | } | ||||
| @@ -2,6 +2,7 @@ using System; | |||||
| using System.Collections.Generic; | using System.Collections.Generic; | ||||
| using System.Collections.Immutable; | using System.Collections.Immutable; | ||||
| using System.Diagnostics; | using System.Diagnostics; | ||||
| using System.Globalization; | |||||
| using System.Linq; | using System.Linq; | ||||
| using System.Threading.Tasks; | using System.Threading.Tasks; | ||||
| using Discord.Rest; | using Discord.Rest; | ||||
| @@ -60,10 +61,10 @@ namespace Discord.WebSocket | |||||
| } | } | ||||
| if (model.Discriminator.IsSpecified) | if (model.Discriminator.IsSpecified) | ||||
| { | { | ||||
| var newVal = ushort.Parse(model.Discriminator.Value); | |||||
| var newVal = ushort.Parse(model.Discriminator.Value, NumberStyles.None, CultureInfo.InvariantCulture); | |||||
| if (newVal != DiscriminatorValue) | if (newVal != DiscriminatorValue) | ||||
| { | { | ||||
| DiscriminatorValue = ushort.Parse(model.Discriminator.Value); | |||||
| DiscriminatorValue = ushort.Parse(model.Discriminator.Value, NumberStyles.None, CultureInfo.InvariantCulture); | |||||
| hasChanges = true; | hasChanges = true; | ||||
| } | } | ||||
| } | } | ||||
| @@ -1,5 +1,6 @@ | |||||
| using System; | using System; | ||||
| using System.Collections.Generic; | using System.Collections.Generic; | ||||
| using System.Globalization; | |||||
| using System.IO; | using System.IO; | ||||
| using System.Text.RegularExpressions; | using System.Text.RegularExpressions; | ||||
| using System.Threading.Tasks; | using System.Threading.Tasks; | ||||
| @@ -132,7 +133,7 @@ namespace Discord.Webhook | |||||
| { | { | ||||
| // ensure that the first group is a ulong, set the _webhookId | // ensure that the first group is a ulong, set the _webhookId | ||||
| // 0th group is always the entire match, so start at index 1 | // 0th group is always the entire match, so start at index 1 | ||||
| if (!(match.Groups[1].Success && ulong.TryParse(match.Groups[1].Value, out webhookId))) | |||||
| if (!(match.Groups[1].Success && ulong.TryParse(match.Groups[1].Value, NumberStyles.None, CultureInfo.InvariantCulture, out webhookId))) | |||||
| throw ex("The webhook Id could not be parsed."); | throw ex("The webhook Id could not be parsed."); | ||||
| if (!match.Groups[2].Success) | if (!match.Groups[2].Success) | ||||