Skip to content

Commit b44e9c6

Browse files
KahbaziBrennanConroy
authored andcommitted
Fix null reference exception for Streaming null object (#14004)
1 parent 2359634 commit b44e9c6

File tree

4 files changed

+92
-3
lines changed

4 files changed

+92
-3
lines changed

src/SignalR/server/Core/src/Internal/DefaultHubDispatcher.cs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -265,7 +265,8 @@ await SendInvocationError(hubMethodInvocationMessage.InvocationId, connection,
265265
for (var parameterPointer = 0; parameterPointer < arguments.Length; parameterPointer++)
266266
{
267267
if (hubMethodInvocationMessage.Arguments.Length > hubInvocationArgumentPointer &&
268-
descriptor.OriginalParameterTypes[parameterPointer].IsAssignableFrom(hubMethodInvocationMessage.Arguments[hubInvocationArgumentPointer].GetType()))
268+
(hubMethodInvocationMessage.Arguments[hubInvocationArgumentPointer] == null ||
269+
descriptor.OriginalParameterTypes[parameterPointer].IsAssignableFrom(hubMethodInvocationMessage.Arguments[hubInvocationArgumentPointer].GetType())))
269270
{
270271
// The types match so it isn't a synthetic argument, just copy it into the arguments array
271272
arguments[parameterPointer] = hubMethodInvocationMessage.Arguments[hubInvocationArgumentPointer];

src/SignalR/server/SignalR/test/HubConnectionHandlerTestUtils/Hubs.cs

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -933,6 +933,36 @@ public ChannelReader<int> CancelableStreamMultiParameter(int ignore, int ignore2
933933
return channel.Reader;
934934
}
935935

936+
public ChannelReader<int> CancelableStreamNullableParameter(int x, string y, CancellationToken token)
937+
{
938+
var channel = Channel.CreateBounded<int>(10);
939+
940+
Task.Run(async () =>
941+
{
942+
_tcsService.StartedMethod.SetResult(x);
943+
await token.WaitForCancellationAsync();
944+
channel.Writer.TryComplete();
945+
_tcsService.EndMethod.SetResult(y);
946+
});
947+
948+
return channel.Reader;
949+
}
950+
951+
public ChannelReader<int> StreamNullableParameter(int x, int? input)
952+
{
953+
var channel = Channel.CreateBounded<int>(10);
954+
955+
Task.Run(() =>
956+
{
957+
_tcsService.StartedMethod.SetResult(x);
958+
channel.Writer.TryComplete();
959+
_tcsService.EndMethod.SetResult(input);
960+
return Task.CompletedTask;
961+
});
962+
963+
return channel.Reader;
964+
}
965+
936966
public ChannelReader<int> CancelableStreamMiddleParameter(int ignore, CancellationToken token, int ignore2)
937967
{
938968
var channel = Channel.CreateBounded<int>(10);

src/SignalR/server/SignalR/test/HubConnectionHandlerTests.cs

Lines changed: 58 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3591,6 +3591,64 @@ public async Task StreamHubMethodCanAcceptCancellationTokenAsArgumentAndBeTrigge
35913591
}
35923592
}
35933593

3594+
[Fact]
3595+
public async Task StreamHubMethodCanAcceptNullableParameter()
3596+
{
3597+
using (StartVerifiableLog())
3598+
{
3599+
var tcsService = new TcsService();
3600+
var serviceProvider = HubConnectionHandlerTestUtils.CreateServiceProvider(builder =>
3601+
{
3602+
builder.AddSingleton(tcsService);
3603+
}, LoggerFactory);
3604+
var connectionHandler = serviceProvider.GetService<HubConnectionHandler<LongRunningHub>>();
3605+
3606+
using (var client = new TestClient())
3607+
{
3608+
var connectionHandlerTask = await client.ConnectAsync(connectionHandler).OrTimeout();
3609+
3610+
var streamInvocationId = await client.SendStreamInvocationAsync(nameof(LongRunningHub.StreamNullableParameter), 5, null).OrTimeout();
3611+
// Wait for the stream method to start
3612+
var firstArgument = await tcsService.StartedMethod.Task.OrTimeout();
3613+
Assert.Equal(5, firstArgument);
3614+
3615+
var secondArgument = await tcsService.EndMethod.Task.OrTimeout();
3616+
Assert.Null(secondArgument);
3617+
}
3618+
}
3619+
}
3620+
3621+
3622+
[Fact]
3623+
public async Task StreamHubMethodCanAcceptNullableParameterWithCancellationToken()
3624+
{
3625+
using (StartVerifiableLog())
3626+
{
3627+
var tcsService = new TcsService();
3628+
var serviceProvider = HubConnectionHandlerTestUtils.CreateServiceProvider(builder =>
3629+
{
3630+
builder.AddSingleton(tcsService);
3631+
}, LoggerFactory);
3632+
var connectionHandler = serviceProvider.GetService<HubConnectionHandler<LongRunningHub>>();
3633+
3634+
using (var client = new TestClient())
3635+
{
3636+
var connectionHandlerTask = await client.ConnectAsync(connectionHandler).OrTimeout();
3637+
3638+
var streamInvocationId = await client.SendStreamInvocationAsync(nameof(LongRunningHub.CancelableStreamNullableParameter), 5, null).OrTimeout();
3639+
// Wait for the stream method to start
3640+
var firstArgument = await tcsService.StartedMethod.Task.OrTimeout();
3641+
Assert.Equal(5, firstArgument);
3642+
3643+
// Cancel the stream which should trigger the CancellationToken in the hub method
3644+
await client.SendHubMessageAsync(new CancelInvocationMessage(streamInvocationId)).OrTimeout();
3645+
3646+
var secondArgument = await tcsService.EndMethod.Task.OrTimeout();
3647+
Assert.Null(secondArgument);
3648+
}
3649+
}
3650+
}
3651+
35943652
[Fact]
35953653
public async Task InvokeHubMethodCannotAcceptCancellationTokenAsArgument()
35963654
{

src/SignalR/server/SignalR/test/Internal/TypedClientBuilderTests.cs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -92,7 +92,7 @@ public async Task SupportsCancellationToken()
9292
send1 =>
9393
{
9494
Assert.Equal("Method", send1.Method);
95-
Assert.Equal(1, send1.Arguments.Length);
95+
Assert.Single(send1.Arguments);
9696
Assert.Collection(send1.Arguments,
9797
arg1 => Assert.Equal("foo", arg1));
9898
Assert.Equal(cts1.Token, send1.CancellationToken);
@@ -101,7 +101,7 @@ public async Task SupportsCancellationToken()
101101
send2 =>
102102
{
103103
Assert.Equal("NoArgumentMethod", send2.Method);
104-
Assert.Equal(0, send2.Arguments.Length);
104+
Assert.Empty(send2.Arguments);
105105
Assert.Equal(cts2.Token, send2.CancellationToken);
106106
send2.Complete();
107107
});

0 commit comments

Comments
 (0)