From 6bc2ebb4c5556fa04926c6fa7aca811a13cd349b Mon Sep 17 00:00:00 2001 From: James Newton-King Date: Tue, 10 Apr 2018 16:52:19 +1200 Subject: [PATCH] Use invariant culture and ordinal comparisons (#1928) --- samples/JwtClientSample/Program.cs | 2 +- samples/SignalRSamples/ConnectionList.cs | 2 +- samples/SocialWeather/ConnectionList.cs | 3 ++- src/Common/JsonUtils.cs | 3 ++- .../HttpConnectionDispatcher.cs | 2 +- .../HttpConnectionManager.cs | 3 ++- .../HubConnection.cs | 7 ++++--- .../HttpConnectionOptions.cs | 2 +- .../HubConnectionContext.cs | 2 +- .../HubConnectionStore.cs | 4 +++- src/Microsoft.AspNetCore.SignalR.Core/HubGroupList.cs | 3 ++- .../Internal/Protocol/JsonHubProtocol.cs | 2 +- .../Internal/Protocol/MessagePackHubProtocol.cs | 2 +- .../RedisHubLifetimeManager.cs | 2 +- 14 files changed, 23 insertions(+), 16 deletions(-) diff --git a/samples/JwtClientSample/Program.cs b/samples/JwtClientSample/Program.cs index 8193236ea6..324d7b9a8f 100644 --- a/samples/JwtClientSample/Program.cs +++ b/samples/JwtClientSample/Program.cs @@ -23,7 +23,7 @@ namespace JwtClientSample private const string ServerUrl = "http://localhost:54543"; - private readonly ConcurrentDictionary _tokens = new ConcurrentDictionary(); + private readonly ConcurrentDictionary _tokens = new ConcurrentDictionary(StringComparer.Ordinal); private readonly Random _random = new Random(); private async Task RunConnection(HttpTransportType transportType) diff --git a/samples/SignalRSamples/ConnectionList.cs b/samples/SignalRSamples/ConnectionList.cs index 995d57fab4..f6b680d173 100644 --- a/samples/SignalRSamples/ConnectionList.cs +++ b/samples/SignalRSamples/ConnectionList.cs @@ -11,7 +11,7 @@ namespace SignalRSamples { internal class ConnectionList : IReadOnlyCollection { - private readonly ConcurrentDictionary _connections = new ConcurrentDictionary(); + private readonly ConcurrentDictionary _connections = new ConcurrentDictionary(StringComparer.Ordinal); public ConnectionContext this[string connectionId] { diff --git a/samples/SocialWeather/ConnectionList.cs b/samples/SocialWeather/ConnectionList.cs index 63d1d27c20..54b5882201 100644 --- a/samples/SocialWeather/ConnectionList.cs +++ b/samples/SocialWeather/ConnectionList.cs @@ -11,7 +11,8 @@ namespace SocialWeather { internal class ConnectionList : IReadOnlyCollection { - private readonly ConcurrentDictionary _connections = new ConcurrentDictionary(); + private readonly ConcurrentDictionary _connections = + new ConcurrentDictionary(StringComparer.Ordinal); public ConnectionContext this[string connectionId] { diff --git a/src/Common/JsonUtils.cs b/src/Common/JsonUtils.cs index bd37090763..4c7d6219ad 100644 --- a/src/Common/JsonUtils.cs +++ b/src/Common/JsonUtils.cs @@ -3,6 +3,7 @@ using System; using System.Buffers; +using System.Globalization; using System.IO; using Newtonsoft.Json; using Newtonsoft.Json.Linq; @@ -127,7 +128,7 @@ namespace Microsoft.AspNetCore.Internal return null; } - return Convert.ToInt32(reader.Value); + return Convert.ToInt32(reader.Value, CultureInfo.InvariantCulture); } public static string ReadAsString(JsonTextReader reader, string propertyName) diff --git a/src/Microsoft.AspNetCore.Http.Connections/HttpConnectionDispatcher.cs b/src/Microsoft.AspNetCore.Http.Connections/HttpConnectionDispatcher.cs index 6b6b304c16..d7bb2b6348 100644 --- a/src/Microsoft.AspNetCore.Http.Connections/HttpConnectionDispatcher.cs +++ b/src/Microsoft.AspNetCore.Http.Connections/HttpConnectionDispatcher.cs @@ -567,7 +567,7 @@ namespace Microsoft.AspNetCore.Http.Connections requestFeature.PathBase = existingRequestFeature.PathBase; requestFeature.QueryString = existingRequestFeature.QueryString; requestFeature.RawTarget = existingRequestFeature.RawTarget; - var requestHeaders = new Dictionary(existingRequestFeature.Headers.Count); + var requestHeaders = new Dictionary(existingRequestFeature.Headers.Count, StringComparer.Ordinal); foreach (var header in existingRequestFeature.Headers) { requestHeaders[header.Key] = header.Value; diff --git a/src/Microsoft.AspNetCore.Http.Connections/HttpConnectionManager.cs b/src/Microsoft.AspNetCore.Http.Connections/HttpConnectionManager.cs index 0971639f38..494c867063 100644 --- a/src/Microsoft.AspNetCore.Http.Connections/HttpConnectionManager.cs +++ b/src/Microsoft.AspNetCore.Http.Connections/HttpConnectionManager.cs @@ -26,7 +26,8 @@ namespace Microsoft.AspNetCore.Http.Connections private static readonly RNGCryptoServiceProvider _keyGenerator = new RNGCryptoServiceProvider(); - private readonly ConcurrentDictionary _connections = new ConcurrentDictionary(); + private readonly ConcurrentDictionary _connections = + new ConcurrentDictionary(StringComparer.Ordinal); private Timer _timer; private readonly ILogger _logger; private readonly ILogger _connectionLogger; diff --git a/src/Microsoft.AspNetCore.SignalR.Client.Core/HubConnection.cs b/src/Microsoft.AspNetCore.SignalR.Client.Core/HubConnection.cs index 606533ed58..5245479e87 100644 --- a/src/Microsoft.AspNetCore.SignalR.Client.Core/HubConnection.cs +++ b/src/Microsoft.AspNetCore.SignalR.Client.Core/HubConnection.cs @@ -5,6 +5,7 @@ using System; using System.Collections.Concurrent; using System.Collections.Generic; using System.Diagnostics; +using System.Globalization; using System.Runtime.CompilerServices; using System.Threading; using System.Threading.Channels; @@ -33,7 +34,7 @@ namespace Microsoft.AspNetCore.SignalR.Client private readonly IHubProtocol _protocol; private readonly IServiceProvider _serviceProvider; private readonly IConnectionFactory _connectionFactory; - private readonly ConcurrentDictionary> _handlers = new ConcurrentDictionary>(); + private readonly ConcurrentDictionary> _handlers = new ConcurrentDictionary>(StringComparer.Ordinal); private bool _disposed; // Transient state to a connection @@ -835,7 +836,7 @@ namespace Microsoft.AspNetCore.SignalR.Client private TaskCompletionSource _stopTcs; private readonly object _lock = new object(); - private readonly Dictionary _pendingCalls = new Dictionary(); + private readonly Dictionary _pendingCalls = new Dictionary(StringComparer.Ordinal); private int _nextId; public ConnectionContext Connection { get; } @@ -854,7 +855,7 @@ namespace Microsoft.AspNetCore.SignalR.Client Connection = connection; } - public string GetNextId() => Interlocked.Increment(ref _nextId).ToString(); + public string GetNextId() => Interlocked.Increment(ref _nextId).ToString(CultureInfo.InvariantCulture); public void AddInvocation(InvocationRequest irq) { diff --git a/src/Microsoft.AspNetCore.SignalR.Client/HttpConnectionOptions.cs b/src/Microsoft.AspNetCore.SignalR.Client/HttpConnectionOptions.cs index 6201378ab6..745691667d 100644 --- a/src/Microsoft.AspNetCore.SignalR.Client/HttpConnectionOptions.cs +++ b/src/Microsoft.AspNetCore.SignalR.Client/HttpConnectionOptions.cs @@ -64,7 +64,7 @@ namespace Microsoft.AspNetCore.SignalR.Client { if (_headers == null) { - _headers = new Dictionary(); + _headers = new Dictionary(StringComparer.Ordinal); } return _headers; diff --git a/src/Microsoft.AspNetCore.SignalR.Core/HubConnectionContext.cs b/src/Microsoft.AspNetCore.SignalR.Core/HubConnectionContext.cs index fe9718084d..62dab627ad 100644 --- a/src/Microsoft.AspNetCore.SignalR.Core/HubConnectionContext.cs +++ b/src/Microsoft.AspNetCore.SignalR.Core/HubConnectionContext.cs @@ -63,7 +63,7 @@ namespace Microsoft.AspNetCore.SignalR internal ExceptionDispatchInfo AbortException { get; private set; } // Currently used only for streaming methods - internal ConcurrentDictionary ActiveRequestCancellationSources { get; } = new ConcurrentDictionary(); + internal ConcurrentDictionary ActiveRequestCancellationSources { get; } = new ConcurrentDictionary(StringComparer.Ordinal); public virtual ValueTask WriteAsync(HubMessage message) { diff --git a/src/Microsoft.AspNetCore.SignalR.Core/HubConnectionStore.cs b/src/Microsoft.AspNetCore.SignalR.Core/HubConnectionStore.cs index 2a2842950c..a94ccda601 100644 --- a/src/Microsoft.AspNetCore.SignalR.Core/HubConnectionStore.cs +++ b/src/Microsoft.AspNetCore.SignalR.Core/HubConnectionStore.cs @@ -1,6 +1,7 @@ // Copyright (c) .NET Foundation. All rights reserved. // Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. +using System; using System.Collections; using System.Collections.Concurrent; using System.Collections.Generic; @@ -9,7 +10,8 @@ namespace Microsoft.AspNetCore.SignalR { public class HubConnectionStore { - private readonly ConcurrentDictionary _connections = new ConcurrentDictionary(); + private readonly ConcurrentDictionary _connections = + new ConcurrentDictionary(StringComparer.Ordinal); public HubConnectionContext this[string connectionId] { diff --git a/src/Microsoft.AspNetCore.SignalR.Core/HubGroupList.cs b/src/Microsoft.AspNetCore.SignalR.Core/HubGroupList.cs index b8b28ce051..8142735005 100644 --- a/src/Microsoft.AspNetCore.SignalR.Core/HubGroupList.cs +++ b/src/Microsoft.AspNetCore.SignalR.Core/HubGroupList.cs @@ -1,6 +1,7 @@ // Copyright (c) .NET Foundation. All rights reserved. // Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. +using System; using System.Collections; using System.Collections.Concurrent; using System.Collections.Generic; @@ -11,7 +12,7 @@ namespace Microsoft.AspNetCore.SignalR public class HubGroupList : IReadOnlyCollection> { private readonly ConcurrentDictionary _groups = - new ConcurrentDictionary(); + new ConcurrentDictionary(StringComparer.Ordinal); private static readonly GroupConnectionList EmptyGroupConnectionList = new GroupConnectionList(); diff --git a/src/Microsoft.AspNetCore.SignalR.Protocols.Json/Internal/Protocol/JsonHubProtocol.cs b/src/Microsoft.AspNetCore.SignalR.Protocols.Json/Internal/Protocol/JsonHubProtocol.cs index 0e886b8ef2..c0b21f4cf7 100644 --- a/src/Microsoft.AspNetCore.SignalR.Protocols.Json/Internal/Protocol/JsonHubProtocol.cs +++ b/src/Microsoft.AspNetCore.SignalR.Protocols.Json/Internal/Protocol/JsonHubProtocol.cs @@ -307,7 +307,7 @@ namespace Microsoft.AspNetCore.SignalR.Internal.Protocol private Dictionary ReadHeaders(JsonTextReader reader) { - var headers = new Dictionary(); + var headers = new Dictionary(StringComparer.Ordinal); if (reader.TokenType != JsonToken.StartObject) { diff --git a/src/Microsoft.AspNetCore.SignalR.Protocols.MsgPack/Internal/Protocol/MessagePackHubProtocol.cs b/src/Microsoft.AspNetCore.SignalR.Protocols.MsgPack/Internal/Protocol/MessagePackHubProtocol.cs index 8bf93d7635..7b98831bc8 100644 --- a/src/Microsoft.AspNetCore.SignalR.Protocols.MsgPack/Internal/Protocol/MessagePackHubProtocol.cs +++ b/src/Microsoft.AspNetCore.SignalR.Protocols.MsgPack/Internal/Protocol/MessagePackHubProtocol.cs @@ -232,7 +232,7 @@ namespace Microsoft.AspNetCore.SignalR.Internal.Protocol if (headerCount > 0) { // If headerCount is larger than int.MaxValue, things are going to go horribly wrong anyway :) - var headers = new Dictionary((int)headerCount); + var headers = new Dictionary((int)headerCount, StringComparer.Ordinal); for (var i = 0; i < headerCount; i++) { diff --git a/src/Microsoft.AspNetCore.SignalR.Redis/RedisHubLifetimeManager.cs b/src/Microsoft.AspNetCore.SignalR.Redis/RedisHubLifetimeManager.cs index 59aae0ae1e..7623f11bf7 100644 --- a/src/Microsoft.AspNetCore.SignalR.Redis/RedisHubLifetimeManager.cs +++ b/src/Microsoft.AspNetCore.SignalR.Redis/RedisHubLifetimeManager.cs @@ -23,7 +23,7 @@ namespace Microsoft.AspNetCore.SignalR.Redis { private readonly HubConnectionStore _connections = new HubConnectionStore(); // TODO: Investigate "memory leak" entries never get removed - private readonly ConcurrentDictionary _groups = new ConcurrentDictionary(); + private readonly ConcurrentDictionary _groups = new ConcurrentDictionary(StringComparer.Ordinal); private readonly IConnectionMultiplexer _redisServerConnection; private readonly ISubscriber _bus; private readonly ILogger _logger;