handle null ref exceptions in managed parser (#1606)

* handle null ref exceptions

* add comment
This commit is contained in:
Alan Ren
2022-07-27 18:35:54 -07:00
committed by GitHub
parent 46e3c5270e
commit bfa40e86e4

View File

@@ -14,7 +14,7 @@ using Microsoft.SqlTools.ManagedBatchParser;
namespace Microsoft.SqlTools.ServiceLayer.BatchParser namespace Microsoft.SqlTools.ServiceLayer.BatchParser
{ {
/// <summary> /// <summary>
/// Wraps the SMO Batch parser to make it a easily useable component. /// Wraps the SMO Batch parser to make it a easily useable component.
/// </summary> /// </summary>
@@ -23,7 +23,7 @@ namespace Microsoft.SqlTools.ServiceLayer.BatchParser
private List<BatchInfo> batchInfos; private List<BatchInfo> batchInfos;
private ExecutionEngine executionEngine; private ExecutionEngine executionEngine;
private BatchEventNotificationHandler notificationHandler; private BatchEventNotificationHandler notificationHandler;
/// <summary> /// <summary>
/// Helper method used to Convert line/column information in a file to offset /// Helper method used to Convert line/column information in a file to offset
/// </summary> /// </summary>
@@ -31,7 +31,7 @@ namespace Microsoft.SqlTools.ServiceLayer.BatchParser
{ {
List<BatchDefinition> batchDefinitionList = new List<BatchDefinition>(); List<BatchDefinition> batchDefinitionList = new List<BatchDefinition>();
if (batchInfos.Count == 0) if (batchInfos.Count == 0)
{ {
return batchDefinitionList; return batchDefinitionList;
} }
@@ -77,13 +77,13 @@ namespace Microsoft.SqlTools.ServiceLayer.BatchParser
batchDefinitionList.Add(batchDef); batchDefinitionList.Add(batchDef);
if (count > 1) if (count > 1)
{ {
offset = offsets[1] + batchInfos[0].startColumn; offset = offsets[1] + batchInfos[0].startColumn;
} }
// Generate the rest batch definitions // Generate the rest batch definitions
for (int index = 1; index < count - 1 ; index++) for (int index = 1; index < count - 1; index++)
{ {
lineDifference = batchInfos[index + 1].startLine - batchInfos[index].startLine; lineDifference = batchInfos[index + 1].startLine - batchInfos[index].startLine;
position = ReadLines(reader, lineDifference, endLine); position = ReadLines(reader, lineDifference, endLine);
@@ -121,12 +121,12 @@ namespace Microsoft.SqlTools.ServiceLayer.BatchParser
return batchDefinitionList; return batchDefinitionList;
} }
private static int GetMaxStartLine(IList<BatchInfo> batchInfos) private static int GetMaxStartLine(IList<BatchInfo> batchInfos)
{ {
int highest = 0; int highest = 0;
foreach (var batchInfo in batchInfos) foreach (var batchInfo in batchInfos)
{ {
if (batchInfo.startLine > highest) if (batchInfo.startLine > highest)
{ {
highest = batchInfo.startLine; highest = batchInfo.startLine;
} }
@@ -137,7 +137,7 @@ namespace Microsoft.SqlTools.ServiceLayer.BatchParser
/// <summary> /// <summary>
/// Gets offsets for all batches /// Gets offsets for all batches
/// </summary> /// </summary>
private static List<int> GetOffsets(string content, IList<BatchInfo> batchInfos) private static List<int> GetOffsets(string content, IList<BatchInfo> batchInfos)
{ {
List<int> offsets = new List<int>(); List<int> offsets = new List<int>();
@@ -151,7 +151,7 @@ namespace Microsoft.SqlTools.ServiceLayer.BatchParser
while (!foundAllOffsets) while (!foundAllOffsets)
{ {
// go until the last start line of the batches // go until the last start line of the batches
for (int i = 0; i <= maxStartLine ; i++) for (int i = 0; i <= maxStartLine; i++)
{ {
// get offset for the current batch // get offset for the current batch
ReadLines(reader, ref count, ref offset, ref foundAllOffsets, batchInfos, offsets, i); ReadLines(reader, ref count, ref offset, ref foundAllOffsets, batchInfos, offsets, i);
@@ -164,14 +164,14 @@ namespace Microsoft.SqlTools.ServiceLayer.BatchParser
} }
} }
} }
return offsets; return offsets;
} }
/// <summary> /// <summary>
/// Helper function to read lines of batches to get offsets /// Helper function to read lines of batches to get offsets
/// </summary> /// </summary>
private static void ReadLines(StringReader reader, ref int count, ref int offset, ref bool foundAllOffsets, private static void ReadLines(StringReader reader, ref int count, ref int offset, ref bool foundAllOffsets,
IList<BatchInfo> batchInfos, List<int> offsets, int iteration) IList<BatchInfo> batchInfos, List<int> offsets, int iteration)
{ {
int ch; int ch;
@@ -229,7 +229,8 @@ namespace Microsoft.SqlTools.ServiceLayer.BatchParser
} }
// get number of characters in the last line // get number of characters in the last line
int endColumn = prevLine.ToCharArray().Length; // for some SQLCMD scenarios, the reader is already at the end of file and causing the prevLine to be null.
int endColumn = prevLine == null ? 0 : prevLine.ToCharArray().Length;
return new BatchDefinition( return new BatchDefinition(
batchText, batchText,
@@ -263,7 +264,8 @@ namespace Microsoft.SqlTools.ServiceLayer.BatchParser
} }
// get number of characters in the last line // get number of characters in the last line
int endColumn = prevLine.ToCharArray().Length; // for some SQLCMD scenarios, the reader is already at the end of file and causing the prevLine to be null.
int endColumn = prevLine == null ? 0 : prevLine.ToCharArray().Length;
//lineOffset doesn't matter because its the last batch //lineOffset doesn't matter because its the last batch
return Tuple.Create(endLine, endColumn); return Tuple.Create(endLine, endColumn);
@@ -377,7 +379,7 @@ namespace Microsoft.SqlTools.ServiceLayer.BatchParser
string batchText = args.Batch.Text; string batchText = args.Batch.Text;
int batchTextLength = batchText.Length; int batchTextLength = batchText.Length;
if (!batchText.EndsWith(Environment.NewLine, StringComparison.Ordinal) if (!batchText.EndsWith(Environment.NewLine, StringComparison.Ordinal)
&& batchText.EndsWith("\n", StringComparison.Ordinal)) && batchText.EndsWith("\n", StringComparison.Ordinal))
{ {
batchTextLength -= 1; batchTextLength -= 1;