From bfa40e86e44cf85acf36eb40f37c6a502f74bbb5 Mon Sep 17 00:00:00 2001 From: Alan Ren Date: Wed, 27 Jul 2022 18:35:54 -0700 Subject: [PATCH] handle null ref exceptions in managed parser (#1606) * handle null ref exceptions * add comment --- .../BatchParser/BatchParserWrapper.cs | 32 ++++++++++--------- 1 file changed, 17 insertions(+), 15 deletions(-) diff --git a/src/Microsoft.SqlTools.ManagedBatchParser/BatchParser/BatchParserWrapper.cs b/src/Microsoft.SqlTools.ManagedBatchParser/BatchParser/BatchParserWrapper.cs index 55f9bfc6..aedb08e1 100644 --- a/src/Microsoft.SqlTools.ManagedBatchParser/BatchParser/BatchParserWrapper.cs +++ b/src/Microsoft.SqlTools.ManagedBatchParser/BatchParser/BatchParserWrapper.cs @@ -14,7 +14,7 @@ using Microsoft.SqlTools.ManagedBatchParser; namespace Microsoft.SqlTools.ServiceLayer.BatchParser { - + /// /// Wraps the SMO Batch parser to make it a easily useable component. /// @@ -23,7 +23,7 @@ namespace Microsoft.SqlTools.ServiceLayer.BatchParser private List batchInfos; private ExecutionEngine executionEngine; private BatchEventNotificationHandler notificationHandler; - + /// /// Helper method used to Convert line/column information in a file to offset /// @@ -31,7 +31,7 @@ namespace Microsoft.SqlTools.ServiceLayer.BatchParser { List batchDefinitionList = new List(); - if (batchInfos.Count == 0) + if (batchInfos.Count == 0) { return batchDefinitionList; } @@ -77,13 +77,13 @@ namespace Microsoft.SqlTools.ServiceLayer.BatchParser batchDefinitionList.Add(batchDef); - if (count > 1) + if (count > 1) { offset = offsets[1] + batchInfos[0].startColumn; } // 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; position = ReadLines(reader, lineDifference, endLine); @@ -121,12 +121,12 @@ namespace Microsoft.SqlTools.ServiceLayer.BatchParser return batchDefinitionList; } - private static int GetMaxStartLine(IList batchInfos) + private static int GetMaxStartLine(IList batchInfos) { int highest = 0; - foreach (var batchInfo in batchInfos) + foreach (var batchInfo in batchInfos) { - if (batchInfo.startLine > highest) + if (batchInfo.startLine > highest) { highest = batchInfo.startLine; } @@ -137,7 +137,7 @@ namespace Microsoft.SqlTools.ServiceLayer.BatchParser /// /// Gets offsets for all batches /// - private static List GetOffsets(string content, IList batchInfos) + private static List GetOffsets(string content, IList batchInfos) { List offsets = new List(); @@ -151,7 +151,7 @@ namespace Microsoft.SqlTools.ServiceLayer.BatchParser while (!foundAllOffsets) { // 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 ReadLines(reader, ref count, ref offset, ref foundAllOffsets, batchInfos, offsets, i); @@ -164,14 +164,14 @@ namespace Microsoft.SqlTools.ServiceLayer.BatchParser } } - } + } return offsets; } /// /// Helper function to read lines of batches to get offsets /// - 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 batchInfos, List offsets, int iteration) { int ch; @@ -229,7 +229,8 @@ namespace Microsoft.SqlTools.ServiceLayer.BatchParser } // 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( batchText, @@ -263,7 +264,8 @@ namespace Microsoft.SqlTools.ServiceLayer.BatchParser } // 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 return Tuple.Create(endLine, endColumn); @@ -377,7 +379,7 @@ namespace Microsoft.SqlTools.ServiceLayer.BatchParser string batchText = args.Batch.Text; int batchTextLength = batchText.Length; - if (!batchText.EndsWith(Environment.NewLine, StringComparison.Ordinal) + if (!batchText.EndsWith(Environment.NewLine, StringComparison.Ordinal) && batchText.EndsWith("\n", StringComparison.Ordinal)) { batchTextLength -= 1;