public void UseCase_Normal_Test() { Ruleset rules = Ruleset.FromDirectory(@"rules\valid", null); rules.AddDirectory(@"rules\custom", "my rules"); RuleProcessor processor = new RuleProcessor(rules); string lang = Language.FromFileName("testfilename.cpp"); string testString = "strcpy(dest,src);"; // strcpy test Issue[] issues = processor.Analyze(testString, lang); Assert.AreEqual(1, issues.Length, "strcpy should be flagged"); Assert.AreEqual(0, issues[0].Index, "strcpy invalid index"); Assert.AreEqual(16, issues[0].Length, "strcpy invalid length "); Assert.AreEqual("DS185832", issues[0].Rule.Id, "strcpy invalid rule"); // Fix it test Assert.AreNotEqual(issues[0].Rule.Fixes.Length, 0, "strcpy invalid Fixes"); CodeFix fix = issues[0].Rule.Fixes[0]; string fixedCode = RuleProcessor.Fix(testString, fix); Assert.AreEqual("strcpy_s(dest, <size of dest>, src);", fixedCode, "strcpy invalid code fix"); Assert.IsTrue(fix.Name.Contains("Change to strcpy_s"), "strcpy wrong fix name"); // QUICKFIX test processor.SeverityLevel |= Severity.ManualReview; testString = "//QUICKFIX: fix this later"; issues = processor.Analyze(testString, "csharp"); Assert.AreEqual(1, issues.Length, "QUICKFIX should be flagged"); Assert.AreEqual(2, issues[0].Index, "QUICKFIX invalid index"); Assert.AreEqual(8, issues[0].Length, "QUICKFIX invalid length "); Assert.AreEqual("DS276209", issues[0].Rule.Id, "QUICKFIX invalid rule"); Assert.AreEqual(0, issues[0].Rule.Fixes.Length, "QUICKFIX invalid Fixes"); Assert.AreEqual("my rules", issues[0].Rule.RuntimeTag, "QUICKFIX invalid tag"); // Same issue twice test testString = "MD5 hash = MD5.Create();"; issues = processor.Analyze(testString, "csharp"); Assert.AreEqual(2, issues.Length, "Same issue should be twice on line"); Assert.AreEqual(issues[0].Rule, issues[1].Rule, "Same issues should have sames rule IDs"); // Overlaping issues testString = " MD5 hash = new MD5CryptoServiceProvider();"; issues = processor.Analyze(testString, "csharp"); Assert.AreEqual(2, issues.Length, "Overlaping issue count doesn't add up"); // Override test testString = "strncat(dest, \"this is also bad\", strlen(dest))"; issues = processor.Analyze(testString, new string[] { "c", "cpp" }); Assert.AreEqual(2, issues.Length, "Override test failed"); }
public void UseCase_OnError_Test() { bool error = false; Ruleset rules = new Ruleset(); rules.OnDeserializationError += delegate(object sender, Newtonsoft.Json.Serialization.ErrorEventArgs args) { error = true; args.ErrorContext.Handled = true; }; rules.AddDirectory(@"rules\invalid", null); Assert.IsTrue(error, "Error should be raised"); }
public void UseCase_SeverityFilter_Test() { Ruleset rules = Ruleset.FromDirectory(@"rules\valid", null); rules.AddDirectory(@"rules\custom", null); RuleProcessor processor = new RuleProcessor(rules); string testString = "eval(something)"; Issue[] issues = processor.Analyze(testString, "javascript"); Assert.AreEqual(0, issues.Length, "Manual Review should not be flagged"); processor.SeverityLevel |= Severity.ManualReview; issues = processor.Analyze(testString, "javascript"); Assert.AreEqual(1, issues.Length, "Manual Review should be flagged"); }
public void UseCase_IgnoreRules_Test() { Ruleset rules = Ruleset.FromDirectory(@"rules\valid", null); rules.AddDirectory(@"rules\custom", null); RuleProcessor processor = new RuleProcessor(rules) { EnableSuppressions = true }; // MD5CryptoServiceProvider test string testString = "MD5 hash = new MD5CryptoServiceProvider(); //DevSkim: ignore DS126858"; Issue[] issues = processor.Analyze(testString, "csharp"); Assert.AreEqual(1, issues.Length, "MD5CryptoServiceProvider should be flagged"); Assert.AreEqual(15, issues[0].Index, "MD5CryptoServiceProvider invalid index"); Assert.AreEqual(24, issues[0].Length, "MD5CryptoServiceProvider invalid length "); Assert.AreEqual("DS168931", issues[0].Rule.Id, "MD5CryptoServiceProvider invalid rule"); // Ignore until test DateTime expirationDate = DateTime.Now.AddDays(5); testString = "requests.get('somelink', verify = False) #DevSkim: ignore DS130821 until {0:yyyy}-{0:MM}-{0:dd}"; issues = processor.Analyze(string.Format(testString, expirationDate), "python"); Assert.AreEqual(0, issues.Length, "Ignore until should not be flagged"); // Expired until test expirationDate = DateTime.Now; issues = processor.Analyze(string.Format(testString, expirationDate), "python"); Assert.AreEqual(1, issues.Length, "Expired until should be flagged"); // Ignore all until test expirationDate = DateTime.Now.AddDays(5); testString = "MD5 hash = new MD5.Create(); #DevSkim: ignore all until {0:yyyy}-{0:MM}-{0:dd}"; issues = processor.Analyze(string.Format(testString, expirationDate), "csharp"); Assert.AreEqual(0, issues.Length, "Ignore all until should not be flagged"); // Expired all test expirationDate = DateTime.Now; testString = "MD5 hash = new MD5CryptoServiceProvider(); //DevSkim: ignore all until {0:yyyy}-{0:MM}-{0:dd}"; issues = processor.Analyze(string.Format(testString, expirationDate), "csharp"); Assert.AreEqual(2, issues.Length, "Expired all should be flagged"); }
public void UseCase_IgnoreSuppression_Test() { Ruleset rules = Ruleset.FromDirectory(@"rules\valid", null); rules.AddDirectory(@"rules\custom", null); RuleProcessor processor = new RuleProcessor(rules); processor.EnableSuppressions = false; // MD5CryptoServiceProvider test string testString = "MD5 hash = new MD5CryptoServiceProvider(); //DevSkim: ignore DS126858"; Issue[] issues = processor.Analyze(testString, "csharp"); Assert.AreEqual(2, issues.Length, "MD5CryptoServiceProvider should be flagged"); Assert.AreEqual(0, issues[1].Index, "MD5CryptoServiceProvider invalid index"); Assert.AreEqual(3, issues[1].Length, "MD5CryptoServiceProvider invalid length "); Assert.AreEqual("DS126858", issues[1].Rule.Id, "MD5CryptoServiceProvider invalid rule"); }
/// <summary> /// Reloads rules based on settings /// </summary> private void LoadRules() { Settings set = Settings.GetSettings(); ruleset = new Ruleset(); string rulesFile = Path.GetDirectoryName(System.Reflection.Assembly.GetExecutingAssembly().Location); rulesFile = Path.Combine(Path.Combine(rulesFile, "Content"), "devskim-rules.json"); if (set.UseDefaultRules) { ruleset.AddFile(rulesFile, null); } if (set.UseCustomRules) { ruleset.AddDirectory(set.CustomRulesPath, "custom"); } processor.Rules = ruleset; processor.SeverityLevel = Severity.Critical; if (set.EnableImportantRules) { processor.SeverityLevel |= Severity.Important; } if (set.EnableModerateRules) { processor.SeverityLevel |= Severity.Moderate; } if (set.EnableBestPracticeRules) { processor.SeverityLevel |= Severity.BestPractice; } if (set.EnableManualReviewRules) { processor.SeverityLevel |= Severity.ManualReview; } }