Skip to content

Commit c990609

Browse files
Merge pull request #57 from OmniSharp/update/spec
Added check to allow non spec compliant consumers to send us null for…
2 parents 584051d + 3d1e56d commit c990609

File tree

4 files changed

+49
-13
lines changed

4 files changed

+49
-13
lines changed

src/JsonRpc/Reciever.cs

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -79,11 +79,18 @@ protected virtual Renor GetRenor(JToken @object)
7979
}
8080

8181
var hasParams = request.TryGetValue("params", out var @params);
82-
if (hasParams && @params?.Type != JTokenType.Array && @params?.Type != JTokenType.Object)
82+
if (hasParams && @params?.Type != JTokenType.Array && @params?.Type != JTokenType.Object && @params?.Type != JTokenType.Null)
8383
{
8484
return new InvalidRequest(requestId, "Invalid params");
8585
}
8686

87+
// Special case params such that if we get a null value (from a non spec compliant system)
88+
// that we don't fall over and throw an error.
89+
if (@params?.Type == JTokenType.Null)
90+
{
91+
@params = null;
92+
}
93+
8794
// id == request
8895
// !id == notification
8996
if (!hasRequestId)

src/Protocol/General/IShutdownHandler.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,5 +11,5 @@ public static partial class GeneralNames
1111
}
1212

1313
[Serial, Method(Shutdown)]
14-
public interface IShutdownHandler : INotificationHandler { }
14+
public interface IShutdownHandler : IRequestHandler<object> { }
1515
}
Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
using System.Threading;
12
using System.Threading.Tasks;
23
using OmniSharp.Extensions.LanguageServer.Protocol;
34
using OmniSharp.Extensions.LanguageServer.Server.Abstractions;
@@ -6,19 +7,18 @@ namespace OmniSharp.Extensions.LanguageServer.Server.Handlers
67
{
78
public class ShutdownHandler : IShutdownHandler, IAwaitableTermination
89
{
9-
public Task Handle()
10+
public event ShutdownEventHandler Shutdown;
11+
12+
public bool ShutdownRequested { get; private set; }
13+
14+
private readonly TaskCompletionSource<bool> _shutdownSource = new TaskCompletionSource<bool>(TaskContinuationOptions.LongRunning);
15+
Task IAwaitableTermination.WasShutDown => _shutdownSource.Task;
16+
public Task Handle(object request, CancellationToken token)
1017
{
1118
ShutdownRequested = true;
1219
Shutdown?.Invoke(ShutdownRequested);
13-
shutdownSource.SetResult(true); // after all event sinks were notified
20+
_shutdownSource.SetResult(true); // after all event sinks were notified
1421
return Task.CompletedTask;
1522
}
16-
17-
public event ShutdownEventHandler Shutdown;
18-
19-
public bool ShutdownRequested { get; private set; }
20-
21-
private readonly TaskCompletionSource<bool> shutdownSource = new TaskCompletionSource<bool>(TaskContinuationOptions.LongRunning);
22-
Task IAwaitableTermination.WasShutDown => shutdownSource.Task;
2323
}
2424
}

test/JsonRpc.Tests/Server/SpecifictionRecieverTests.cs

Lines changed: 31 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
using System;
1+
using System;
22
using System.Collections.Generic;
33
using System.Linq;
44
using FluentAssertions;
@@ -56,6 +56,24 @@ public override IEnumerable<ValueTuple<string, Renor[]>> GetValues()
5656
new Request(4, "subtract", JObject.FromObject(new {minuend = 42, subtrahend = 23}))
5757
});
5858

59+
yield return (
60+
@"{""jsonrpc"": ""2.0"", ""method"": ""subtract"", ""id"": 4}",
61+
new Renor[]
62+
{
63+
new Request(4, "subtract", null)
64+
});
65+
66+
// http://www.jsonrpc.org/specification says:
67+
// If present, parameters for the rpc call MUST be provided as a Structured value.
68+
// Some clients may serialize params as null, instead of omitting it
69+
// We're going to pretend we never got the null in the first place.
70+
yield return (
71+
@"{""jsonrpc"": ""2.0"", ""method"": ""subtract"", ""params"": null, ""id"": 4}",
72+
new Renor[]
73+
{
74+
new Request(4, "subtract", null)
75+
});
76+
5977
yield return (
6078
@"{""jsonrpc"": ""2.0"", ""method"": ""update"", ""params"": [1,2,3,4,5]}",
6179
new Renor[]
@@ -70,6 +88,17 @@ public override IEnumerable<ValueTuple<string, Renor[]>> GetValues()
7088
new Notification("foobar", null)
7189
});
7290

91+
// http://www.jsonrpc.org/specification says:
92+
// If present, parameters for the rpc call MUST be provided as a Structured value.
93+
// Some clients may serialize params as null, instead of omitting it
94+
// We're going to pretend we never got the null in the first place.
95+
yield return (
96+
@"{""jsonrpc"": ""2.0"", ""method"": ""foobar"", ""params"": null}",
97+
new Renor[]
98+
{
99+
new Notification("foobar", null)
100+
});
101+
73102
yield return (
74103
@"{""jsonrpc"": ""2.0"", ""method"": 1, ""params"": ""bar""}",
75104
new Renor[]
@@ -144,4 +173,4 @@ public override IEnumerable<ValueTuple<string, bool>> GetValues()
144173
}
145174
}
146175
}
147-
}
176+
}

0 commit comments

Comments
 (0)