Browse Source

fix: Use double precision for X-Reset-After, set CultureInfo when parsing numeric types (#1375)

* Parse double for X-Reset-After instead of float, needs more precision

Float did not contain enough precision to store the millisecond unix
time value, which resulted in the second and millisecond values being
slightly off.

This can be easily tested using:

```cs
> DateTimeOffset.FromUnixTimeMilliseconds((long)(1470173022.123f *
1000)).Millisecond
160 // wrong

> DateTimeOffset.FromUnixTimeMilliseconds((long)(1470173022.123 *
1000)).Millisecond
123 // correct
```

* Parse RateLimit-Reset using an IFormatProvider

* State NumberStyle and use CultureInfo.InvariantCulture for any parsing

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.

* Use default format spec in Commands
tags/2.2.0
Chris Johnston Christopher F 5 years ago
parent
commit
606dac3e1a
7 changed files with 19 additions and 13 deletions
  1. +2
    -1
      src/Discord.Net.Core/Utils/TokenUtils.cs
  2. +1
    -1
      src/Discord.Net.Rest/DiscordRestApiClient.cs
  3. +2
    -1
      src/Discord.Net.Rest/Entities/Users/RestUser.cs
  4. +3
    -2
      src/Discord.Net.Rest/Net/Converters/UInt64EntityOrIdConverter.cs
  5. +6
    -5
      src/Discord.Net.Rest/Net/RateLimitInfo.cs
  6. +3
    -2
      src/Discord.Net.WebSocket/Entities/Users/SocketUser.cs
  7. +2
    -1
      src/Discord.Net.Webhook/DiscordWebhookClient.cs

+ 2
- 1
src/Discord.Net.Core/Utils/TokenUtils.cs View File

@@ -1,4 +1,5 @@
using System;
using System.Globalization;
using System.Text;

namespace Discord
@@ -76,7 +77,7 @@ namespace Discord
var bytes = Convert.FromBase64String(encoded);
var idStr = Encoding.UTF8.GetString(bytes);
// 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;
}
catch (DecoderFallbackException)


+ 1
- 1
src/Discord.Net.Rest/DiscordRestApiClient.cs View File

@@ -1488,7 +1488,7 @@ namespace Discord.API
builder.Append(format, lastIndex, leftIndex - lastIndex);
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]);

var mappedId = BucketIds.GetIndex(fieldName);


+ 2
- 1
src/Discord.Net.Rest/Entities/Users/RestUser.cs View File

@@ -1,6 +1,7 @@
using System;
using System.Collections.Immutable;
using System.Diagnostics;
using System.Globalization;
using System.Threading.Tasks;
using Model = Discord.API.User;

@@ -57,7 +58,7 @@ namespace Discord.Rest
if (model.Avatar.IsSpecified)
AvatarId = model.Avatar.Value;
if (model.Discriminator.IsSpecified)
DiscriminatorValue = ushort.Parse(model.Discriminator.Value);
DiscriminatorValue = ushort.Parse(model.Discriminator.Value, NumberStyles.None, CultureInfo.InvariantCulture);
if (model.Bot.IsSpecified)
IsBot = model.Bot.Value;
if (model.Username.IsSpecified)


+ 3
- 2
src/Discord.Net.Rest/Net/Converters/UInt64EntityOrIdConverter.cs View File

@@ -1,6 +1,7 @@
using Discord.API;
using Discord.API;
using Newtonsoft.Json;
using System;
using System.Globalization;

namespace Discord.Net.Converters
{
@@ -23,7 +24,7 @@ namespace Discord.Net.Converters
{
case JsonToken.String:
case JsonToken.Integer:
return new EntityOrId<T>(ulong.Parse(reader.ReadAsString()));
return new EntityOrId<T>(ulong.Parse(reader.ReadAsString(), NumberStyles.None, CultureInfo.InvariantCulture));
default:
T obj;
if (_innerConverter != null)


+ 6
- 5
src/Discord.Net.Rest/Net/RateLimitInfo.cs View File

@@ -1,5 +1,6 @@
using System;
using System.Collections.Generic;
using System.Globalization;

namespace Discord.Net
{
@@ -17,15 +18,15 @@ namespace Discord.Net
IsGlobal = headers.TryGetValue("X-RateLimit-Global", out string temp) &&
bool.TryParse(temp, out var isGlobal) && isGlobal;
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) &&
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) &&
float.TryParse(temp, 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) &&
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) &&
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;
}
}
}

+ 3
- 2
src/Discord.Net.WebSocket/Entities/Users/SocketUser.cs View File

@@ -2,6 +2,7 @@ using System;
using System.Collections.Generic;
using System.Collections.Immutable;
using System.Diagnostics;
using System.Globalization;
using System.Linq;
using System.Threading.Tasks;
using Discord.Rest;
@@ -60,10 +61,10 @@ namespace Discord.WebSocket
}
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)
{
DiscriminatorValue = ushort.Parse(model.Discriminator.Value);
DiscriminatorValue = ushort.Parse(model.Discriminator.Value, NumberStyles.None, CultureInfo.InvariantCulture);
hasChanges = true;
}
}


+ 2
- 1
src/Discord.Net.Webhook/DiscordWebhookClient.cs View File

@@ -1,5 +1,6 @@
using System;
using System.Collections.Generic;
using System.Globalization;
using System.IO;
using System.Text.RegularExpressions;
using System.Threading.Tasks;
@@ -132,7 +133,7 @@ namespace Discord.Webhook
{
// ensure that the first group is a ulong, set the _webhookId
// 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.");

if (!match.Groups[2].Success)


Loading…
Cancel
Save