Fixing infinite exception loop bug

Fixing issue where submitting a malformed JSON RPC request results in the
message reader entering into an infinite loop of throwing and catching
exceptions without reading anything from the input stream.

At the same time, this change also fixes a potential memory leak where the
message read buffer is never reinstantiated or shrunk. This issue is fixed
by shifting buffer contents after a message was read successfully, or if
an error occurs during parsing.
This commit is contained in:
Benjamin Russell
2016-08-12 15:37:16 -07:00
parent a2983539a7
commit fe79f6e85c
2 changed files with 91 additions and 68 deletions

View File

@@ -8,6 +8,7 @@ using System.Collections.Generic;
using System.IO;
using System.Threading;
using System.Threading.Tasks;
using Microsoft.SqlTools.ServiceLayer.Hosting.Contracts;
using Microsoft.SqlTools.ServiceLayer.Hosting.Protocol.Channel;
using Microsoft.SqlTools.ServiceLayer.Hosting.Protocol.Contracts;
using Microsoft.SqlTools.EditorServices.Utility;
@@ -198,10 +199,9 @@ namespace Microsoft.SqlTools.ServiceLayer.Hosting.Protocol
this.SynchronizationContext = SynchronizationContext.Current;
// Run the message loop
bool isRunning = true;
while (isRunning && !cancellationToken.IsCancellationRequested)
while (!cancellationToken.IsCancellationRequested)
{
Message newMessage = null;
Message newMessage;
try
{
@@ -210,12 +210,12 @@ namespace Microsoft.SqlTools.ServiceLayer.Hosting.Protocol
}
catch (MessageParseException e)
{
// TODO: Write an error response
Logger.Write(
LogLevel.Error,
"Could not parse a message that was received:\r\n\r\n" +
e.ToString());
string message = String.Format("Exception occurred while parsing message: {0}", e.Message);
Logger.Write(LogLevel.Error, message);
await MessageWriter.WriteEvent(HostingErrorEvent.Type, new HostingErrorParams
{
Message = message
});
// Continue the loop
continue;
@@ -227,8 +227,16 @@ namespace Microsoft.SqlTools.ServiceLayer.Hosting.Protocol
}
catch (Exception e)
{
var b = e.Message;
newMessage = null;
// Log the error and send an error event to the client
string message = String.Format("Exception occurred while receiving message: {0}", e.Message);
Logger.Write(LogLevel.Error, message);
await MessageWriter.WriteEvent(HostingErrorEvent.Type, new HostingErrorParams
{
Message = message
});
// Continue the loop
continue;
}
// The message could be null if there was an error parsing the
@@ -236,9 +244,7 @@ namespace Microsoft.SqlTools.ServiceLayer.Hosting.Protocol
if (newMessage != null)
{
// Process the message
await this.DispatchMessage(
newMessage,
this.MessageWriter);
await this.DispatchMessage(newMessage, this.MessageWriter);
}
}
}