Fix off by one error in GetPrefixLocation recursion (#584)

* Fix off by one error in GetPrefixLocation recursion

* Adds new quoted strings test case
This commit is contained in:
Gabe Stocco 2024-04-30 19:12:17 +00:00 коммит произвёл GitHub
Родитель c8bfea6cb5
Коммит e2e13eefa3
Не найден ключ, соответствующий данной подписи
Идентификатор ключа GPG: B5690EEEBB952194
2 изменённых файлов: 69 добавлений и 2 удалений

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

@ -276,6 +276,14 @@ public class TextContainer
}
}
/// <summary>
/// Find the location of the provided prefix string if any in the text container between the provided start of line index and the current index
/// </summary>
/// <param name="startOfLineIndex">Minimum Character index in FullContent to locate Prefix</param>
/// <param name="currentIndex">Maximal Chracter index in FullContent to locate Prefix</param>
/// <param name="prefix">Prefix string to attempt to locate</param>
/// <param name="multiline">If multi-line comments should be detected</param>
/// <returns>The index of the specified prefix string in the FullContent if found, otherwise -1</returns>
private int GetPrefixLocation(int startOfLineIndex, int currentIndex, string prefix, bool multiline)
{
// Find the first potential index of the prefix
@ -300,7 +308,12 @@ public class TextContainer
// It might be like var address = "http://contoso.com";
if (numDoubleQuotes % 2 == 1 || numSingleQuotes % 2 == 1)
{
return GetPrefixLocation(startOfLineIndex, prefixLoc, prefix, multiline);
// The second argument is the maximal index to return since this calls LastIndexOf, subtract 1 to exclude this instance
if ((prefixLoc -1) >= startOfLineIndex)
{
return GetPrefixLocation(startOfLineIndex, prefixLoc - 1, prefix, multiline);
}
return -1;
}
}

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

@ -10,6 +10,9 @@ using Serilog.Events;
namespace AppInspector.Tests.RuleProcessor;
/// <summary>
/// Tests for properly detecting commented/live code status in the presence of comment markers inside of quoted strings
/// </summary>
[TestClass]
public class QuotedStringsTests
{
@ -29,6 +32,12 @@ contoso.com
/*
contoso.com
*/ var url = ""https://contoso.com""";
private const string testRubyInterpolatedStrings = @"findMe = ""findMe""
puts ""Hello, #{findMe}!"" # findMe
def inspect # :nodoc:
""#<#{findMe} #{findMe}>"" #findMe
end
"; // Should find 5 instances, excluding the two true comments
private static string detectContosoRule = @"
[
@ -54,7 +63,32 @@ contoso.com
}
]
";
private static string detectFindMeRule = @"
[
{
""id"": ""RE000001"",
""name"": ""Testing.Rules.Quotes"",
""tags"": [
""Testing.Rules.Quotes""
],
""severity"": ""Critical"",
""description"": ""Find findMe"",
""patterns"": [
{
""pattern"": ""findMe"",
""type"": ""regex"",
""confidence"": ""High"",
""scopes"": [
""code""
]
}
],
""_comment"": """"
}
]
";
private readonly ILoggerFactory _loggerFactory =
new LogOptions { ConsoleVerbosityLevel = LogEventLevel.Verbose }.GetLoggerFactory();
@ -78,4 +112,24 @@ contoso.com
Assert.AreEqual(numIssues,
ruleProcessor.AnalyzeFile(content, new FileEntry("testfile.cs", new MemoryStream()), info).Count());
}
/// <summary>
/// Ruby interpolated strings provide an interesting test case because they use the comment character as part of interpolation
/// the comment marker is one character long, and it may often come right after the quotation mark
/// </summary>
/// <param name="content"></param>
/// <param name="numIssues"></param>
[DataRow(testRubyInterpolatedStrings, 5)]
[DataTestMethod]
public void QuotedStringsRuby(string content, int numIssues)
{
RuleSet rules = new(_loggerFactory);
rules.AddString(detectFindMeRule, "findMeRule");
Microsoft.ApplicationInspector.RulesEngine.RuleProcessor ruleProcessor =
new Microsoft.ApplicationInspector.RulesEngine.RuleProcessor(rules, new RuleProcessorOptions());
_languages.FromFileNameOut("testfile.rb", out LanguageInfo info);
Assert.AreEqual(numIssues,
ruleProcessor.AnalyzeFile(content, new FileEntry("testfile.rb", new MemoryStream()), info).Count());
}
}