diff --git a/src/Microsoft.AspNetCore.SignalR.Protocols.Json/Protocol/JsonHubProtocol.cs b/src/Microsoft.AspNetCore.SignalR.Protocols.Json/Protocol/JsonHubProtocol.cs index 423fb60555..f61d6132fb 100644 --- a/src/Microsoft.AspNetCore.SignalR.Protocols.Json/Protocol/JsonHubProtocol.cs +++ b/src/Microsoft.AspNetCore.SignalR.Protocols.Json/Protocol/JsonHubProtocol.cs @@ -209,6 +209,7 @@ namespace Microsoft.AspNetCore.SignalR.Protocol case ArgumentsPropertyName: JsonUtils.CheckRead(reader); + int initialDepth = reader.Depth; if (reader.TokenType != JsonToken.StartArray) { throw new InvalidDataException($"Expected '{ArgumentsPropertyName}' to be of type {JTokenType.Array}."); @@ -231,6 +232,14 @@ namespace Microsoft.AspNetCore.SignalR.Protocol catch (Exception ex) { argumentBindingException = ExceptionDispatchInfo.Capture(ex); + + // Could be at any point in argument array JSON when an error is thrown + // Read until the end of the argument JSON array + while (reader.Depth == initialDepth && reader.TokenType == JsonToken.StartArray || + reader.Depth > initialDepth) + { + JsonUtils.CheckRead(reader); + } } } break; diff --git a/test/Microsoft.AspNetCore.SignalR.Common.Tests/Internal/Protocol/JsonHubProtocolTests.cs b/test/Microsoft.AspNetCore.SignalR.Common.Tests/Internal/Protocol/JsonHubProtocolTests.cs index db6ed25702..cb9a593afa 100644 --- a/test/Microsoft.AspNetCore.SignalR.Common.Tests/Internal/Protocol/JsonHubProtocolTests.cs +++ b/test/Microsoft.AspNetCore.SignalR.Common.Tests/Internal/Protocol/JsonHubProtocolTests.cs @@ -291,6 +291,18 @@ namespace Microsoft.AspNetCore.SignalR.Common.Tests.Internal.Protocol Assert.Equal(DateTimeKind.Utc, dt.Kind); } + [Fact] + public void ReadToEndOfArgumentArrayOnError() + { + var binder = new TestBinder(new[] { typeof(string) }); + var protocol = new JsonHubProtocol(); + var data = new ReadOnlySequence(Encoding.UTF8.GetBytes(Frame("{'type':1,'invocationId':'42','target':'foo','arguments':[[],{'target':'foo2'}]}"))); + protocol.TryParseMessage(ref data, binder, out var message); + var bindingFailure = Assert.IsType(message); + + Assert.Equal("foo", bindingFailure.Target); + } + private static string Frame(string input) { var data = Encoding.UTF8.GetBytes(input);