From 8d8cff3aea594135e0034e40da94dd3f8b3afc82 Mon Sep 17 00:00:00 2001 From: Arvind Shyamsundar Date: Fri, 1 Apr 2022 16:46:33 -0700 Subject: [PATCH] Handle more cases in single-line input detection (#35) * Decode XML markup when checking input * Add tests for variations when detecting single line input * Minor unrelated UI bugfix for trimming input when searching for builds --- Engine/StackResolver.cs | 4 +++- GUI/App.config | 1 + GUI/MainForm.cs | 2 +- GUI/SQLBuildsForm.Designer.cs | 2 +- GUI/SQLBuildsForm.cs | 4 ++-- Tests/Tests.cs | 31 ++++++++++++++++++++++++------- 6 files changed, 32 insertions(+), 12 deletions(-) diff --git a/Engine/StackResolver.cs b/Engine/StackResolver.cs index 8b22ef7..a78ddd8 100644 --- a/Engine/StackResolver.cs +++ b/Engine/StackResolver.cs @@ -78,7 +78,9 @@ namespace Microsoft.SqlServer.Utils.Misc.SQLCallStackResolver { return retval; } - public bool IsInputSingleLine(string text) { + public bool IsInputSingleLine(string text, string patternsToTreatAsMultiline) { + if (Regex.Match(text, patternsToTreatAsMultiline).Success) return false; + text = System.Net.WebUtility.HtmlDecode(text); // decode XML markup if present if (!Regex.Match(text, "Histogram").Success && !text.Replace("\r", string.Empty).Trim().Contains('\n')) return true; if (!Regex.Match(text, @"\").Success) return true; diff --git a/GUI/App.config b/GUI/App.config index e1ad4b5..5987102 100644 --- a/GUI/App.config +++ b/GUI/App.config @@ -8,5 +8,6 @@ + diff --git a/GUI/MainForm.cs b/GUI/MainForm.cs index 608e6d6..8404097 100644 --- a/GUI/MainForm.cs +++ b/GUI/MainForm.cs @@ -52,7 +52,7 @@ namespace Microsoft.SqlServer.Utils.Misc.SQLCallStackResolver { return; } - bool isSingleLineInput = this._resolver.IsInputSingleLine(callStackInput.Text); + bool isSingleLineInput = this._resolver.IsInputSingleLine(callStackInput.Text, ConfigurationManager.AppSettings["PatternsToTreatAsMultiline"]); if (isSingleLineInput && !FramesOnSingleLine.Checked) { if (DialogResult.Yes == MessageBox.Show(this, "Maybe this is intentional, but your input seems to have all the frames on a single line, but the 'Callstack frames are in single line' checkbox is unchecked. " + diff --git a/GUI/SQLBuildsForm.Designer.cs b/GUI/SQLBuildsForm.Designer.cs index 1b79e37..a842dbf 100644 --- a/GUI/SQLBuildsForm.Designer.cs +++ b/GUI/SQLBuildsForm.Designer.cs @@ -113,7 +113,7 @@ namespace Microsoft.SqlServer.Utils.Misc.SQLCallStackResolver { this.findNext.TabIndex = 2; this.findNext.Text = "Find"; this.findNext.UseVisualStyleBackColor = true; - this.findNext.Click += new System.EventHandler(this.findNext_Click); + this.findNext.Click += new System.EventHandler(this.FindNext_Click); this.AcceptButton = this.dnldButton; this.AutoScaleDimensions = new System.Drawing.SizeF(8F, 16F); this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; diff --git a/GUI/SQLBuildsForm.cs b/GUI/SQLBuildsForm.cs index c8d75b1..c4ec781 100644 --- a/GUI/SQLBuildsForm.cs +++ b/GUI/SQLBuildsForm.cs @@ -113,7 +113,7 @@ namespace Microsoft.SqlServer.Utils.Misc.SQLCallStackResolver { } } - private void findNext_Click(object sender, EventArgs e) { + private void FindNext_Click(object sender, EventArgs e) { foreach (TreeNode node in treeviewSyms.Nodes) { if (CheckIfAnyNodesMatch(node)) { return; @@ -128,7 +128,7 @@ namespace Microsoft.SqlServer.Utils.Misc.SQLCallStackResolver { private bool CheckIfAnyNodesMatch(TreeNode node) { if (node.Tag is SQLBuildInfo bld) { - if (bld.ToString().ToLower(CultureInfo.CurrentCulture).Contains(searchText.Text.ToLower(CultureInfo.CurrentCulture))) { + if (bld.ToString().ToLower(CultureInfo.CurrentCulture).Contains(searchText.Text.Trim().ToLower(CultureInfo.CurrentCulture))) { treeviewSyms.SelectedNode = node; treeviewSyms.Select(); treeviewSyms.Refresh(); diff --git a/Tests/Tests.cs b/Tests/Tests.cs index 3942b1c..5a989db 100644 --- a/Tests/Tests.cs +++ b/Tests/Tests.cs @@ -15,19 +15,36 @@ namespace Microsoft.SqlServer.Utils.Misc.SQLCallStackResolver { [Trait("Category", "Unit")] public void SingleLineDetection() { using (var csr = new StackResolver()) { - Assert.True(csr.IsInputSingleLine(@"callstack 0x00007FFEABD0D919 0x00007FFEABC4D45D 0x00007FFEAC0F7EE0 0x00007FFEAC0F80CF 0x00007FFEAC1EE447 0x00007FFEAC1EE6F5 0x00007FFEAC1D48B0 0x00007FFEAC71475A 0x00007FFEA9A708F1 0x00007FFEA9991FB9 0x00007FFEA9993D21 0x00007FFEA99B59F1 0x00007FFEA99B5055 0x00007FFEA99B2B8F 0x00007FFEA9675AD1 0x00007FFEA9671EFB 0x00007FFEAA37D83D 0x00007FFEAA37D241 0x00007FFEAA379F98 0x00007FFEA96719CA 0x00007FFEA9672933 0x00007FFEA9672041 0x00007FFEA967A82B 0x00007FFEA9681542 ")); - Assert.True(csr.IsInputSingleLine(@"callstack 0x00007FFEABD0D919 0x00007FFEABC4D45D 0x00007FFEAC0F7EE0 0x00007FFEAC0F80CF 0x00007FFEAC1EE447 0x00007FFEAC1EE6F5 0x00007FFEAC1D48B0 0x00007FFEAC71475A 0x00007FFEA9A708F1 0x00007FFEA9991FB9 0x00007FFEA9993D21\r\n0x00007FFEA99B59F1 0x00007FFEA99B5055 0x00007FFEA99B2B8F 0x00007FFEA9675AD1 0x00007FFEA9671EFB 0x00007FFEAA37D83D 0x00007FFEAA37D241 0x00007FFEAA379F98 0x00007FFEA96719CA 0x00007FFEA9672933 0x00007FFEA9672041 0x00007FFEA967A82B\r\n0x00007FFEA9681542 ")); - Assert.True(csr.IsInputSingleLine(@"\r\n sqldk+0x40609 sqldk+40609\r\n")); - Assert.True(csr.IsInputSingleLine(@"\r\ncallstack 0x00007FFEABD0D919 0x00007FFEABC4D45D 0x00007FFEAC0F7EE0 0x00007FFEAC0F80CF 0x00007FFEAC1EE447 0x00007FFEAC1EE6F5 0x00007FFEAC1D48B0 0x00007FFEAC71475A 0x00007FFEA9A708F1 0x00007FFEA9991FB9 0x00007FFEA9993D21 0x00007FFEA99B59F1 0x00007FFEA99B5055 0x00007FFEA99B2B8F 0x00007FFEA9675AD1 0x00007FFEA9671EFB 0x00007FFEAA37D83D 0x00007FFEAA37D241 0x00007FFEAA379F98 0x00007FFEA96719CA 0x00007FFEA9672933 0x00007FFEA9672041 0x00007FFEA967A82B 0x00007FFEA9681542 \r\n\r\n")); - Assert.True(csr.IsInputSingleLine("0x00007FFEABD0D919 0x00007FFEABC4D45D 0x00007FFEAC0F7EE0 0x00007FFEAC0F80CF 0x00007FFEAC1EE447 0x00007FFEAC1EE6F5 0x00007FFEAC1D48B0 0x00007FFEAC71475A 0x00007FFEA9A708F1 0x00007FFEA9991FB9 0x00007FFEA9993D21 0x00007FFEA99B59F1 0x00007FFEA99B5055 0x00007FFEA99B2B8F 0x00007FFEA9675AD1 0x00007FFEA9671EFB 0x00007FFEAA37D83D 0x00007FFEAA37D241 0x00007FFEAA379F98 0x00007FFEA96719CA 0x00007FFEA9672933 0x00007FFEA9672041 0x00007FFEA967A82B 0x00007FFEA9681542")); + var PatternsToTreatAsMultiline = "BEGIN STACK DUMP|Short Stack Dump"; + Assert.True(csr.IsInputSingleLine(@"callstack 0x00007FFEABD0D919 0x00007FFEABC4D45D 0x00007FFEAC0F7EE0 0x00007FFEAC0F80CF 0x00007FFEAC1EE447 0x00007FFEAC1EE6F5 0x00007FFEAC1D48B0 0x00007FFEAC71475A 0x00007FFEA9A708F1 0x00007FFEA9991FB9 0x00007FFEA9993D21 0x00007FFEA99B59F1 0x00007FFEA99B5055 0x00007FFEA99B2B8F 0x00007FFEA9675AD1 0x00007FFEA9671EFB 0x00007FFEAA37D83D 0x00007FFEAA37D241 0x00007FFEAA379F98 0x00007FFEA96719CA 0x00007FFEA9672933 0x00007FFEA9672041 0x00007FFEA967A82B 0x00007FFEA9681542 ", PatternsToTreatAsMultiline)); + Assert.True(csr.IsInputSingleLine(@"callstack 0x00007FFEABD0D919 0x00007FFEABC4D45D 0x00007FFEAC0F7EE0 0x00007FFEAC0F80CF 0x00007FFEAC1EE447 0x00007FFEAC1EE6F5 0x00007FFEAC1D48B0 0x00007FFEAC71475A 0x00007FFEA9A708F1 0x00007FFEA9991FB9 0x00007FFEA9993D21\r\n0x00007FFEA99B59F1 0x00007FFEA99B5055 0x00007FFEA99B2B8F 0x00007FFEA9675AD1 0x00007FFEA9671EFB 0x00007FFEAA37D83D 0x00007FFEAA37D241 0x00007FFEAA379F98 0x00007FFEA96719CA 0x00007FFEA9672933 0x00007FFEA9672041 0x00007FFEA967A82B\r\n0x00007FFEA9681542 ", PatternsToTreatAsMultiline)); + Assert.True(csr.IsInputSingleLine(@"\r\n sqldk+0x40609 sqldk+40609\r\n", PatternsToTreatAsMultiline)); + Assert.True(csr.IsInputSingleLine(@"\r\n sqldk+0x40609 sqldk+40609\r\nsqldk+0x40609 sqldk+40609", PatternsToTreatAsMultiline)); + Assert.True(csr.IsInputSingleLine(@"\r\ncallstack 0x00007FFEABD0D919 0x00007FFEABC4D45D 0x00007FFEAC0F7EE0 0x00007FFEAC0F80CF 0x00007FFEAC1EE447 0x00007FFEAC1EE6F5 0x00007FFEAC1D48B0 0x00007FFEAC71475A 0x00007FFEA9A708F1 0x00007FFEA9991FB9 0x00007FFEA9993D21 0x00007FFEA99B59F1 0x00007FFEA99B5055 0x00007FFEA99B2B8F 0x00007FFEA9675AD1 0x00007FFEA9671EFB 0x00007FFEAA37D83D 0x00007FFEAA37D241 0x00007FFEAA379F98 0x00007FFEA96719CA 0x00007FFEA9672933 0x00007FFEA9672041 0x00007FFEA967A82B 0x00007FFEA9681542 \r\n\r\n", PatternsToTreatAsMultiline)); + Assert.True(csr.IsInputSingleLine("0x00007FFEABD0D919 0x00007FFEABC4D45D 0x00007FFEAC0F7EE0 0x00007FFEAC0F80CF 0x00007FFEAC1EE447 0x00007FFEAC1EE6F5 0x00007FFEAC1D48B0 0x00007FFEAC71475A 0x00007FFEA9A708F1 0x00007FFEA9991FB9 0x00007FFEA9993D21 0x00007FFEA99B59F1 0x00007FFEA99B5055 0x00007FFEA99B2B8F 0x00007FFEA9675AD1 0x00007FFEA9671EFB 0x00007FFEAA37D83D 0x00007FFEAA37D241 0x00007FFEAA379F98 0x00007FFEA96719CA 0x00007FFEA9672933 0x00007FFEA9672041 0x00007FFEA967A82B 0x00007FFEA9681542", PatternsToTreatAsMultiline)); Assert.True(csr.IsInputSingleLine("annotation for histogram #1 0 0x00007FFEABD0D919 0x00007FFEABC4D45D 0x00007FFEAC0F7EE0 0x00007FFEAC0F80CF 0x00007FFEAC1EE447 0x00007FFEAC1EE6F5 0x00007FFEAC1D48B0 0x00007FFEAC71475A 0x00007FFEA9A708F1 0x00007FFEA9991FB9 0x00007FFEA9993D21 0x00007FFEA99B59F1 0x00007FFEA99B5055 0x00007FFEA99B2B8F 0x00007FFEA9675AD1 0x00007FFEA9671EFB 0x00007FFEAA37D83D 0x00007FFEAA37D241 0x00007FFEAA379F98 0x00007FFEA96719CA 0x00007FFEA9672933 0x00007FFEA9672041 0x00007FFEA967A82B 0x00007FFEA9681542\r\n" + - "annotation for histogram #2 1 0x00007FFEABD0D919 0x00007FFEABC4D45D 0x00007FFEAC0F7EE0 0x00007FFEAC0F80CF 0x00007FFEAC1EE447 0x00007FFEAC1EE6F5 0x00007FFEAC1D48B0 0x00007FFEAC71475A 0x00007FFEA9A708F1 0x00007FFEA9991FB9 0x00007FFEA9993D21 0x00007FFEA99B59F1 0x00007FFEA99B5055 0x00007FFEA99B2B8F 0x00007FFEA9675AD1 0x00007FFEA9671EFB 0x00007FFEAA37D83D 0x00007FFEAA37D241 0x00007FFEAA379F98 0x00007FFEA96719CA 0x00007FFEA9672933 0x00007FFEA9672041 0x00007FFEA967A82B 0x00007FFEA9681542\r\n")); + "annotation for histogram #2 1 0x00007FFEABD0D919 0x00007FFEABC4D45D 0x00007FFEAC0F7EE0 0x00007FFEAC0F80CF 0x00007FFEAC1EE447 0x00007FFEAC1EE6F5 0x00007FFEAC1D48B0 0x00007FFEAC71475A 0x00007FFEA9A708F1 0x00007FFEA9991FB9 0x00007FFEA9993D21 0x00007FFEA99B59F1 0x00007FFEA99B5055 0x00007FFEA99B2B8F 0x00007FFEA9675AD1 0x00007FFEA9671EFB 0x00007FFEAA37D83D 0x00007FFEAA37D241 0x00007FFEAA379F98 0x00007FFEA96719CA 0x00007FFEA9672933 0x00007FFEA9672041 0x00007FFEA967A82B 0x00007FFEA9681542\r\n", PatternsToTreatAsMultiline)); Assert.False(csr.IsInputSingleLine("" + "" + "" + "]]>" + "" + -"]]>")); +"]]>", PatternsToTreatAsMultiline)); + Assert.False(csr.IsInputSingleLine("\r\n\r\n<frame id=\"00\" address=\"0xf00\" pdb=\"ntdll.pdb\" age=\"1\" guid=\"C374E059-5793-9B92-6525-386A66A2D3F5\" module=\"ntdll.dll\" rva=\"0x9F7E4\" /><" + +"frame id=\"01\" address=\"0xf00\" pdb=\"kernelbase.pdb\" age=\"1\" guid=\"E77E26E7-D1C4-72BB-2C05-DD17624A9E58\" module=\"KERNELBASE.dll\" rva=\"0x38973\" /><" + +"frame id=\"02\" address=\"0xf00\" pdb=\"SqlDK.pdb\" age=\"2\" guid=\"6a193443-3512-464b-8b8e-d905ad930ee6\" module=\"sqldk.dll\" rva=\"0x40609\" />" + +"\r\n\r\n\r\n\r\n\r\n", PatternsToTreatAsMultiline)); + Assert.False(csr.IsInputSingleLine(@" +This file is generated by Microsoft SQL Server + +* BEGIN STACK DUMP: + +a = 0x0000000000000000 a1 = 0x0000000000000000 +b = 0x0000000000000000 +c = 0x0000000000000000 d = 0x0000000000000000 +", PatternsToTreatAsMultiline)); } }