Closed
Description
Summary
Certain kinds of URIs that are RFC spec valid URIs are not parseable by System.Uri. The main case for this is if there are sub-delims
in the host name. Some examples of when we get this
- Perforce for VS Code will sometimes have
#
percent encoded in the host name. - Notebook URIs provided by VSCode when running in a devcontainer can have
+
in the URI (Microsoft.CodeAnalysis.LanguageServer server crashed 5 times in the last 3 minutes #7630 (comment))
Both of these are caused by dotnet/runtime#64707 - System.Uri does extra host name validation beyond what the RFC spec indicates.
Since we can't deserialize, we throw exceptions and the server crashes if the file is opened (we can't handle the didOpen request). To solve this, we have a few different paths forward:
- Push on the runtime to allow a parsing mode that is fully RFC spec compliant and does not do extra host name validation.
a. This would only apply to newer runtimes, so if implemented today, the earliest we could use it when we switch to the .NET 10 runtime. - Remove usages of System.Uri entirely and do our own URI parsing (O# does this - https://github.com/OmniSharp/csharp-language-server-protocol/blob/master/src/Protocol/DocumentUri.cs)
a. This is fairly complicated to get right, and we have to maintain our own URI parser. - Remove usages of System.Uri in our protocol serialization types (use string, or wrapper for string). Only when we need to actually parse the URI to find the file path do we call out to System.Uri to parse it. This would allow us to handle the normal text sync requests for these documents and prevent the server from crashing. Only individual requests would fail when we try and find the document in the sln.
Original perforce issue text
Describe the Issue
When enable the extention plugin "Perforce for VS Code", the total function will not work and it says:
[stdout] {"pipeName":"\\\\.\\pipe\\6801cf8c"}
received named pipe information from server
attempting to connect client to server...
client has connected to server
[Info - 10:43:39 AM] [Program] Language server initialized
[Error - 10:43:40 AM] [LanguageServerHost] System.UriFormatException: Invalid URI: The hostname could not be parsed.
at System.Uri.CreateThis(String uri, Boolean dontEscape, UriKind uriKind, UriCreationOptions& creationOptions)
at System.Uri..ctor(String uriString)
at Roslyn.LanguageServer.Protocol.DocumentUriConverter.Read(Utf8JsonReader& reader, Type typeToConvert, JsonSerializerOptions options) in /_/src/LanguageServer/Protocol/Protocol/Converters/DocumentUriConverter.cs:line 17
at System.Text.Json.Serialization.JsonConverter`1.TryRead(Utf8JsonReader& reader, Type typeToConvert, JsonSerializerOptions options, ReadStack& state, T& value, Boolean& isPopulatedValue)
at System.Text.Json.Serialization.Metadata.JsonPropertyInfo`1.ReadJsonAndSetMember(Object obj, ReadStack& state, Utf8JsonReader& reader)
at System.Text.Json.Serialization.Converters.ObjectDefaultConverter`1.OnTryRead(Utf8JsonReader& reader, Type typeToConvert, JsonSerializerOptions options, ReadStack& state, T& value)
at System.Text.Json.Serialization.JsonConverter`1.TryRead(Utf8JsonReader& reader, Type typeToConvert, JsonSerializerOptions options, ReadStack& state, T& value, Boolean& isPopulatedValue)
at System.Text.Json.Serialization.Metadata.JsonPropertyInfo`1.ReadJsonAndSetMember(Object obj, ReadStack& state, Utf8JsonReader& reader)
at System.Text.Json.Serialization.Converters.ObjectDefaultConverter`1.OnTryRead(Utf8JsonReader& reader, Type typeToConvert, JsonSerializerOptions options, ReadStack& state, T& value)
at System.Text.Json.Serialization.JsonConverter`1.TryRead(Utf8JsonReader& reader, Type typeToConvert, JsonSerializerOptions options, ReadStack& state, T& value, Boolean& isPopulatedValue)
at System.Text.Json.Serialization.JsonConverter`1.ReadCore(Utf8JsonReader& reader, JsonSerializerOptions options, ReadStack& state)
at System.Text.Json.JsonSerializer.ReadFromSpan[TValue](ReadOnlySpan`1 utf8Json, JsonTypeInfo`1 jsonTypeInfo, Nullable`1 actualByteCount)
at System.Text.Json.JsonSerializer.Deserialize[TValue](JsonElement element, JsonSerializerOptions options)
at Microsoft.CommonLanguageServerProtocol.Framework.SystemTextJsonLanguageServer`1.DeserializeRequest[TRequest](Object serializedRequest, RequestHandlerMetadata metadata) in /_/src/LanguageServer/Microsoft.CommonLanguageServerProtocol.Framework/SystemTextJsonLanguageServer.cs:line 50
at Microsoft.CommonLanguageServerProtocol.Framework.QueueItem`1.TryDeserializeRequest[TRequest](AbstractLanguageServer`1 languageServer, RequestHandlerMetadata requestHandlerMetadata, Boolean isMutating, TRequest& request) in /_/src/LanguageServer/Microsoft.CommonLanguageServerProtocol.Framework/QueueItem.cs:line 117
[Error - 10:43:40 AM] [LanguageServerHost] System.UriFormatException: Invalid URI: The hostname could not be parsed.
at System.Uri.CreateThis(String uri, Boolean dontEscape, UriKind uriKind, UriCreationOptions& creationOptions)
at System.Uri..ctor(String uriString)
at Roslyn.LanguageServer.Protocol.DocumentUriConverter.Read(Utf8JsonReader& reader, Type typeToConvert, JsonSerializerOptions options) in /_/src/LanguageServer/Protocol/Protocol/Converters/DocumentUriConverter.cs:line 17
at System.Text.Json.Serialization.JsonConverter`1.TryRead(Utf8JsonReader& reader, Type typeToConvert, JsonSerializerOptions options, ReadStack& state, T& value, Boolean& isPopulatedValue)
at System.Text.Json.Serialization.Metadata.JsonPropertyInfo`1.ReadJsonAndSetMember(Object obj, ReadStack& state, Utf8JsonReader& reader)
at System.Text.Json.Serialization.Converters.ObjectDefaultConverter`1.OnTryRead(Utf8JsonReader& reader, Type typeToConvert, JsonSerializerOptions options, ReadStack& state, T& value)
at System.Text.Json.Serialization.JsonConverter`1.TryRead(Utf8JsonReader& reader, Type typeToConvert, JsonSerializerOptions options, ReadStack& state, T& value, Boolean& isPopulatedValue)
at System.Text.Json.Serialization.Metadata.JsonPropertyInfo`1.ReadJsonAndSetMember(Object obj, ReadStack& state, Utf8JsonReader& reader)
at System.Text.Json.Serialization.Converters.ObjectDefaultConverter`1.OnTryRead(Utf8JsonReader& reader, Type typeToConvert, JsonSerializerOptions options, ReadStack& state, T& value)
at System.Text.Json.Serialization.JsonConverter`1.TryRead(Utf8JsonReader& reader, Type typeToConvert, JsonSerializerOptions options, ReadStack& state, T& value, Boolean& isPopulatedValue)
at System.Text.Json.Serialization.JsonConverter`1.ReadCore(Utf8JsonReader& reader, JsonSerializerOptions options, ReadStack& state)
at System.Text.Json.JsonSerializer.ReadFromSpan[TValue](ReadOnlySpan`1 utf8Json, JsonTypeInfo`1 jsonTypeInfo, Nullable`1 actualByteCount)
at System.Text.Json.JsonSerializer.Deserialize[TValue](JsonElement element, JsonSerializerOptions options)
at Microsoft.CommonLanguageServerProtocol.Framework.SystemTextJsonLanguageServer`1.DeserializeRequest[TRequest](Object serializedRequest, RequestHandlerMetadata metadata) in /_/src/LanguageServer/Microsoft.CommonLanguageServerProtocol.Framework/SystemTextJsonLanguageServer.cs:line 50
at Microsoft.CommonLanguageServerProtocol.Framework.QueueItem`1.TryDeserializeRequest[TRequest](AbstractLanguageServer`1 languageServer, RequestHandlerMetadata requestHandlerMetadata, Boolean isMutating, TRequest& request) in /_/src/LanguageServer/Microsoft.CommonLanguageServerProtocol.Framework/QueueItem.cs:line 117
--- End of stack trace from previous location ---
at Microsoft.CommonLanguageServerProtocol.Framework.AbstractLanguageServer`1.DelegatingEntryPoint.InvokeAsync(IRequestExecutionQueue`1 queue, Object requestObject, ILspServices lspServices, CancellationToken cancellationToken) in /_/src/LanguageServer/Microsoft.CommonLanguageServerProtocol.Framework/AbstractLanguageServer.cs:line 202
at Microsoft.CommonLanguageServerProtocol.Framework.SystemTextJsonLanguageServer`1.SystemTextJsonDelegatingEntryPoint.ExecuteRequestAsync(Nullable`1 request, CancellationToken cancellationToken) in /_/src/LanguageServer/Microsoft.CommonLanguageServerProtocol.Framework/SystemTextJsonLanguageServer.cs:line 88
at Microsoft.CommonLanguageServerProtocol.Framework.QueueItem`1.CreateRequestContextAsync[TRequest](IMethodHandler handler, RequestHandlerMetadata requestHandlerMetadata, AbstractLanguageServer`1 languageServer, CancellationToken cancellationToken)
at Microsoft.CommonLanguageServerProtocol.Framework.RequestExecutionQueue`1.ProcessQueueCoreAsync[TRequest,TResponse](IQueueItem`1 work, IMethodHandler handler, RequestHandlerMetadata metadata, ConcurrentDictionary`2 concurrentlyExecutingTasks, CancellationTokenSource currentWorkCts, CancellationToken cancellationToken) in /_/src/LanguageServer/Microsoft.CommonLanguageServerProtocol.Framework/RequestExecutionQueue.cs:line 319
at Microsoft.CommonLanguageServerProtocol.Framework.RequestExecutionQueue`1.InvokeProcessCoreAsync(IQueueItem`1 work, RequestHandlerMetadata metadata, IMethodHandler handler, MethodInfo methodInfo, ConcurrentDictionary`2 concurrentlyExecutingTasks, CancellationTokenSource currentWorkCts, CancellationToken cancellationToken) in /_/src/LanguageServer/Microsoft.CommonLanguageServerProtocol.Framework/RequestExecutionQueue.cs:line 302
at Microsoft.CommonLanguageServerProtocol.Framework.RequestExecutionQueue`1.ProcessQueueAsync() in /_/src/LanguageServer/Microsoft.CommonLanguageServerProtocol.Framework/RequestExecutionQueue.cs:line 254
[Info - 10:43:40 AM] Error processing queue, shutting down
[Error - 10:43:40 AM] Workspace diagnostic pull failed.
Canceled: Canceled
at a.handleFailedRequest (c:\Users\zhentao.wang\.vscode\extensions\ms-dotnettools.csharp-2.45.25-win32-x64\dist\extension.js:2:2137527)
at a.handleFailedRequest (c:\Users\zhentao.wang\.vscode\extensions\ms-dotnettools.csharp-2.45.25-win32-x64\dist\extension.js:2:1253271)
at c:\Users\zhentao.wang\.vscode\extensions\ms-dotnettools.csharp-2.45.25-win32-x64\dist\extension.js:2:2174939
at async g.pullWorkspaceAsync (c:\Users\zhentao.wang\.vscode\extensions\ms-dotnettools.csharp-2.45.25-win32-x64\dist\extension.js:2:2172247)
[Error - 10:43:40 AM] Workspace diagnostic pull failed.
Canceled: Canceled
at a.handleFailedRequest (c:\Users\zhentao.wang\.vscode\extensions\ms-dotnettools.csharp-2.45.25-win32-x64\dist\extension.js:2:2137527)
at a.handleFailedRequest (c:\Users\zhentao.wang\.vscode\extensions\ms-dotnettools.csharp-2.45.25-win32-x64\dist\extension.js:2:1253271)
at c:\Users\zhentao.wang\.vscode\extensions\ms-dotnettools.csharp-2.45.25-win32-x64\dist\extension.js:2:2174939
at runNextTicks (node:internal/process/task_queues:60:5)
at process.processImmediate (node:internal/timers:449:9)
at async g.pullWorkspaceAsync (c:\Users\zhentao.wang\.vscode\extensions\ms-dotnettools.csharp-2.45.25-win32-x64\dist\extension.js:2:2172247)
[Error - 10:43:40 AM] Workspace diagnostic pull failed.
Canceled: Canceled
at a.handleFailedRequest (c:\Users\zhentao.wang\.vscode\extensions\ms-dotnettools.csharp-2.45.25-win32-x64\dist\extension.js:2:2137527)
at a.handleFailedRequest (c:\Users\zhentao.wang\.vscode\extensions\ms-dotnettools.csharp-2.45.25-win32-x64\dist\extension.js:2:1253271)
at c:\Users\zhentao.wang\.vscode\extensions\ms-dotnettools.csharp-2.45.25-win32-x64\dist\extension.js:2:2174939
at runNextTicks (node:internal/process/task_queues:60:5)
at process.processImmediate (node:internal/timers:449:9)
at async g.pullWorkspaceAsync (c:\Users\zhentao.wang\.vscode\extensions\ms-dotnettools.csharp-2.45.25-win32-x64\dist\extension.js:2:2172247)
[Error - 10:43:40 AM] Request textDocument/diagnostic failed.
Message: Server was requested to shut down.
Code: -32000
Steps To Reproduce
- Download and Enable "Perforce for Vs Code"
- Open the c# project
- The error pops up and c# Dev kit cannot work
Expected Behavior
No response
Environment Information
Windows, C# Dev Kit v1.10.18, Perforce for VS Code v4.15.7