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
This commit is contained in:
Arvind Shyamsundar 2022-04-01 16:46:33 -07:00 коммит произвёл GitHub
Родитель 69181bf77f
Коммит 8d8cff3aea
Не найден ключ, соответствующий данной подписи
Идентификатор ключа GPG: 4AEE18F83AFDEB23
6 изменённых файлов: 32 добавлений и 12 удалений

Просмотреть файл

@ -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, @"\<frame").Success) {
if (Regex.Match(text, @"\<Slot.+\<\/Slot\>").Success) return true;

Просмотреть файл

@ -8,5 +8,6 @@
<add key="SQLBuildInfoUpdateURLs" value="https://raw.githubusercontent.com/microsoft/SQLCallStackResolver/main/lastupdated.txt;https://raw.githubusercontent.com/arvindshmicrosoft/SQLCallStackResolver/main/lastupdated.txt" />
<add key="SQLBuildInfoURLs" value="https://raw.githubusercontent.com/microsoft/SQLCallStackResolver/main/sqlbuildinfo.json;https://raw.githubusercontent.com/arvindshmicrosoft/SQLCallStackResolver/main/sqlbuildinfo.json" />
<add key="LatestReleaseURLs" value="https://raw.githubusercontent.com/microsoft/SQLCallStackResolver/main/latestrelease.txt" />
<add key="PatternsToTreatAsMultiline" value="BEGIN STACK DUMP|Short Stack Dump"/>
</appSettings>
</configuration>

Просмотреть файл

@ -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. " +

2
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;

Просмотреть файл

@ -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();

Просмотреть файл

@ -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("<HistogramTarget truncated=\"0\" buckets=\"256\"><Slot count=\"5\"><value>0x00007FFEABD0D919 0x00007FFEABC4D45D 0x00007FFEAC0F7EE0 0x00007FFEAC0F80CF 0x00007FFEAC1EE447 0x00007FFEAC1EE6F5 0x00007FFEAC1D48B0 0x00007FFEAC71475A 0x00007FFEA9A708F1 0x00007FFEA9991FB9 0x00007FFEA9993D21 0x00007FFEA99B59F1 0x00007FFEA99B5055 0x00007FFEA99B2B8F 0x00007FFEA9675AD1 0x00007FFEA9671EFB 0x00007FFEAA37D83D 0x00007FFEAA37D241 0x00007FFEAA379F98 0x00007FFEA96719CA 0x00007FFEA9672933 0x00007FFEA9672041 0x00007FFEA967A82B 0x00007FFEA9681542</value></Slot></HistogramTarget>"));
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("<HistogramTarget truncated=\"0\" buckets=\"256\"><Slot count=\"5\"><value>0x00007FFEABD0D919 0x00007FFEABC4D45D 0x00007FFEAC0F7EE0 0x00007FFEAC0F80CF 0x00007FFEAC1EE447 0x00007FFEAC1EE6F5 0x00007FFEAC1D48B0 0x00007FFEAC71475A 0x00007FFEA9A708F1 0x00007FFEA9991FB9 0x00007FFEA9993D21 0x00007FFEA99B59F1 0x00007FFEA99B5055 0x00007FFEA99B2B8F 0x00007FFEA9675AD1 0x00007FFEA9671EFB 0x00007FFEAA37D83D 0x00007FFEAA37D241 0x00007FFEAA379F98 0x00007FFEA96719CA 0x00007FFEA9672933 0x00007FFEA9672041 0x00007FFEA967A82B 0x00007FFEA9681542</value></Slot></HistogramTarget>", PatternsToTreatAsMultiline));
Assert.True(csr.IsInputSingleLine("annotation for histogram #1 0 <HistogramTarget truncated=\"0\" buckets=\"256\"><Slot count=\"5\"><value>0x00007FFEABD0D919 0x00007FFEABC4D45D 0x00007FFEAC0F7EE0 0x00007FFEAC0F80CF 0x00007FFEAC1EE447 0x00007FFEAC1EE6F5 0x00007FFEAC1D48B0 0x00007FFEAC71475A 0x00007FFEA9A708F1 0x00007FFEA9991FB9 0x00007FFEA9993D21 0x00007FFEA99B59F1 0x00007FFEA99B5055 0x00007FFEA99B2B8F 0x00007FFEA9675AD1 0x00007FFEA9671EFB 0x00007FFEAA37D83D 0x00007FFEAA37D241 0x00007FFEAA379F98 0x00007FFEA96719CA 0x00007FFEA9672933 0x00007FFEA9672041 0x00007FFEA967A82B 0x00007FFEA9681542</value></Slot></HistogramTarget>\r\n" +
"annotation for histogram #2 1 <HistogramTarget truncated=\"0\" buckets=\"256\"><Slot count=\"5\"><value>0x00007FFEABD0D919 0x00007FFEABC4D45D 0x00007FFEAC0F7EE0 0x00007FFEAC0F80CF 0x00007FFEAC1EE447 0x00007FFEAC1EE6F5 0x00007FFEAC1D48B0 0x00007FFEAC71475A 0x00007FFEA9A708F1 0x00007FFEA9991FB9 0x00007FFEA9993D21 0x00007FFEA99B59F1 0x00007FFEA99B5055 0x00007FFEA99B2B8F 0x00007FFEA9675AD1 0x00007FFEA9671EFB 0x00007FFEAA37D83D 0x00007FFEAA37D241 0x00007FFEAA379F98 0x00007FFEA96719CA 0x00007FFEA9672933 0x00007FFEA9672041 0x00007FFEA967A82B 0x00007FFEA9681542</value></Slot></HistogramTarget>\r\n"));
"annotation for histogram #2 1 <HistogramTarget truncated=\"0\" buckets=\"256\"><Slot count=\"5\"><value>0x00007FFEABD0D919 0x00007FFEABC4D45D 0x00007FFEAC0F7EE0 0x00007FFEAC0F80CF 0x00007FFEAC1EE447 0x00007FFEAC1EE6F5 0x00007FFEAC1D48B0 0x00007FFEAC71475A 0x00007FFEA9A708F1 0x00007FFEA9991FB9 0x00007FFEA9993D21 0x00007FFEA99B59F1 0x00007FFEA99B5055 0x00007FFEA99B2B8F 0x00007FFEA9675AD1 0x00007FFEA9671EFB 0x00007FFEAA37D83D 0x00007FFEAA37D241 0x00007FFEAA379F98 0x00007FFEA96719CA 0x00007FFEA9672933 0x00007FFEA9672041 0x00007FFEA967A82B 0x00007FFEA9681542</value></Slot></HistogramTarget>\r\n", PatternsToTreatAsMultiline));
Assert.False(csr.IsInputSingleLine("<HistogramTarget truncated=\"0\" buckets=\"256\"><Slot count=\"5\"><value><![CDATA[<frame id=\"00\" pdb=\"ntdll.pdb\" age=\"1\" guid=\"C374E059-5793-9B92-6525-386A66A2D3F5\" module=\"ntdll.dll\" rva=\"0x9F7E4\" />" +
"<frame id=\"01\" pdb=\"kernelbase.pdb\" age=\"1\" guid=\"E77E26E7-D1C4-72BB-2C05-DD17624A9E58\" module=\"KERNELBASE.dll\" rva=\"0x38973\" />" +
"<frame id=\"02\" pdb=\"SqlDK.pdb\" age=\"2\" guid=\"6a193443-3512-464b-8b8e-d905ad930ee6\" module=\"sqldk.dll\" rva=\"0x40609\" />" +
"]]></value></Slot><Slot count=\"3\"><value><![CDATA[<frame id=\"00\" pdb=\"vcruntime140.amd64.pdb\" age=\"1\" guid=\"AF138C3F-2933-4097-8883-C1071B13375E\" module=\"VCRUNTIME140.dll\" rva=\"0xB8F0\" />" +
"<frame id=\"01\" pdb=\"SqlDK.pdb\" age=\"2\" guid=\"6a193443-3512-464b-8b8e-d905ad930ee6\" module=\"sqldk.dll\" rva=\"0x2249f\" />" +
"]]></value></Slot></HistogramTarget>"));
"]]></value></Slot></HistogramTarget>", PatternsToTreatAsMultiline));
Assert.False(csr.IsInputSingleLine("<HistogramTarget truncated=\"0\" buckets=\"256\">\r\n<Slot count=\"5\">\r\n<value>&lt;frame id=\"00\" address=\"0xf00\" pdb=\"ntdll.pdb\" age=\"1\" guid=\"C374E059-5793-9B92-6525-386A66A2D3F5\" module=\"ntdll.dll\" rva=\"0x9F7E4\" /&gt;&lt;" +
"frame id=\"01\" address=\"0xf00\" pdb=\"kernelbase.pdb\" age=\"1\" guid=\"E77E26E7-D1C4-72BB-2C05-DD17624A9E58\" module=\"KERNELBASE.dll\" rva=\"0x38973\" /&gt;&lt;" +
"frame id=\"02\" address=\"0xf00\" pdb=\"SqlDK.pdb\" age=\"2\" guid=\"6a193443-3512-464b-8b8e-d905ad930ee6\" module=\"sqldk.dll\" rva=\"0x40609\" /&gt;" +
"</value>\r\n</Slot>\r\n<Slot count=\"3\">\r\n<value><frame id=\"00\" address=\"0xf00\" pdb=\"vcruntime140.amd64.pdb\" age=\"1\" guid=\"AF138C3F-2933-4097-8883-C1071B13375E\" module=\"VCRUNTIME140.dll\" rva=\"0xB8F0\" /&gt;&lt;" +
"frame id=\"01\" address=\"0xf00\" pdb=\"SqlDK.pdb\" age=\"2\" guid=\"6a193443-3512-464b-8b8e-d905ad930ee6\" module=\"sqldk.dll\" rva=\"0x2249f\" /&gt;" +
"</value>\r\n</Slot>\r\n</HistogramTarget>", 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));
}
}