From e976a5c3e3afa075881fab095b2ab8a6deaf4ab4 Mon Sep 17 00:00:00 2001 From: Gabe Stocco <98900+gfs@users.noreply.github.com> Date: Thu, 21 May 2020 10:13:40 -0700 Subject: [PATCH] Adds Analyze Single vs Multi-thread benchmark (#215) * Add benchmarks * Delete defaultRulesPkd.json * Switch to using threadsafe ConcurrentDictionary over Unsafe HashSet * Improve multithreaded reliability Switch to concurrentstack instead of list internally * Cleanup * Update multiextractor from OSSGadget current Dramatically improves speed and reliability. * Fix two edge cases in MultiExtractor. * No need to check null, this no longer returns nulls. * Add note about path for benchmarks --- .gitignore | 1 + AppInspector.CLI/Writers/AnalyzeHtmlWriter.cs | 8 +- AppInspector.CLI/Writers/AnalyzeJsonWriter.cs | 2 +- AppInspector.CLI/Writers/AnalyzeTextWriter.cs | 18 +- AppInspector.sln | 18 +- AppInspector/AppInspector.Commands.csproj | 6 +- AppInspector/Commands/AnalyzeCommand.cs | 29 +- AppInspector/Commands/TagDiffCommand.cs | 4 +- AppInspector/Commands/TagTestCommand.cs | 2 +- AppInspector/MetaData.cs | 52 +- AppInspector/MetaDataHelper.cs | 12 +- AppInspector/Resources/defaultRulesPkd.json | 17160 ---------------- Benchmarks/AnalyzeBenchmark.cs | 56 + Benchmarks/Benchmarks.csproj | 21 + Benchmarks/Program.cs | 19 + MultiExtractor/ArFile.cs | 302 + MultiExtractor/DebArchiveFile.cs | 47 + MultiExtractor/Extractor.cs | 1501 +- MultiExtractor/FileEntry.cs | 83 +- MultiExtractor/MiniMagic.cs | 196 +- MultiExtractor/MultiExtractor.csproj | 24 - MultiExtractor/Shared.MultiExtractor.csproj | 37 + RulesEngine/RuleProcessor.cs | 10 +- .../Tests_NuGet/TestAnalyzeCmd.cs | 4 +- UnitTest.Commands/UnitTest.Commands.csproj | 1 - 25 files changed, 2147 insertions(+), 17466 deletions(-) delete mode 100644 AppInspector/Resources/defaultRulesPkd.json create mode 100644 Benchmarks/AnalyzeBenchmark.cs create mode 100644 Benchmarks/Benchmarks.csproj create mode 100644 Benchmarks/Program.cs create mode 100644 MultiExtractor/ArFile.cs create mode 100644 MultiExtractor/DebArchiveFile.cs delete mode 100644 MultiExtractor/MultiExtractor.csproj create mode 100644 MultiExtractor/Shared.MultiExtractor.csproj diff --git a/.gitignore b/.gitignore index 76d9b7f6..e4e2f589 100644 --- a/.gitignore +++ b/.gitignore @@ -265,3 +265,4 @@ __pycache__/ /UnitTest.Commands/output /RulesPacker/log.txt /AppInspector/ApplicationInspector.Commands.xml +AppInspector/Resources/defaultRulesPkd.json diff --git a/AppInspector.CLI/Writers/AnalyzeHtmlWriter.cs b/AppInspector.CLI/Writers/AnalyzeHtmlWriter.cs index ff069b96..02d3548c 100644 --- a/AppInspector.CLI/Writers/AnalyzeHtmlWriter.cs +++ b/AppInspector.CLI/Writers/AnalyzeHtmlWriter.cs @@ -144,7 +144,7 @@ public void PopulateTagGroups() { foreach (TagSearchPattern pattern in tagGroup.Patterns) { - pattern.Detected = _appMetaData.UniqueTags.Any(v => v.Contains(pattern.SearchPattern)); + pattern.Detected = _appMetaData.UniqueTags.Any(v => v.Key.Contains(pattern.SearchPattern)); //create dynamic "category" groups of tags with pattern relationship established from TagReportGroups.json //that can be used to populate reports with various attributes for each tag detected if (pattern.Detected) @@ -382,7 +382,7 @@ private List GetAllMatchingTagInfoList(TagGroup tagGroup, bool addNotFo /// private List GetTagInfoListByName() { - List orderedTags = _appMetaData.UniqueTags.ToList(); + List orderedTags = _appMetaData.UniqueTags.Keys.ToList(); orderedTags.Sort(); HashSet dupCheck = new HashSet(); List result = new List(); @@ -427,7 +427,7 @@ private List GetTagInfoListByConfidence() RulesEngine.Confidence[] confidences = { Confidence.High, Confidence.Medium, Confidence.Low }; - foreach (string tag in _appMetaData.UniqueTags) + foreach (string tag in _appMetaData.UniqueTags.Keys) { var searchPattern = new Regex(tag, RegexOptions.IgnoreCase); foreach (Confidence test in confidences) @@ -470,7 +470,7 @@ private List GetTagInfoListBySeverity() RulesEngine.Severity[] severities = { Severity.Critical, Severity.Important, Severity.Moderate, Severity.BestPractice, Severity.ManualReview }; - foreach (string tag in _appMetaData.UniqueTags) + foreach (string tag in _appMetaData.UniqueTags.Keys) { // TODO: How frequently are these generated? Cache? var searchPattern = new Regex(tag, RegexOptions.IgnoreCase); diff --git a/AppInspector.CLI/Writers/AnalyzeJsonWriter.cs b/AppInspector.CLI/Writers/AnalyzeJsonWriter.cs index b1a9d921..807c5ee8 100644 --- a/AppInspector.CLI/Writers/AnalyzeJsonWriter.cs +++ b/AppInspector.CLI/Writers/AnalyzeJsonWriter.cs @@ -40,7 +40,7 @@ public override void WriteResults(Result result, CLICommandOptions commandOption if (cLIAnalyzeCmdOptions.SimpleTagsOnly) { - List keys = new List(analyzeResult.Metadata.UniqueTags); + List keys = new List(analyzeResult.Metadata.UniqueTags.Keys); keys.Sort(); TagsFile tags = new TagsFile(); tags.Tags = keys.ToArray(); diff --git a/AppInspector.CLI/Writers/AnalyzeTextWriter.cs b/AppInspector.CLI/Writers/AnalyzeTextWriter.cs index 8a6e3afe..8a980a28 100644 --- a/AppInspector.CLI/Writers/AnalyzeTextWriter.cs +++ b/AppInspector.CLI/Writers/AnalyzeTextWriter.cs @@ -26,7 +26,7 @@ public override void WriteResults(Result result, CLICommandOptions commandOption if (cLIAnalyzeCmdOptions.SimpleTagsOnly) { - List keys = new List(analyzeResult.Metadata.UniqueTags); + List keys = new List(analyzeResult.Metadata.UniqueTags.Keys); keys.Sort(); foreach (string tag in keys) @@ -66,17 +66,9 @@ public AnalyzeTextWriter(string formatString) #region helpers - private string StringList(HashSet data) + private string StringList(ConcurrentDictionary data) { - StringBuilder build = new StringBuilder(); - - foreach (string s in data) - { - build.Append(s); - build.Append(" "); - } - - return build.ToString(); + return string.Join(' ', data.Keys); } private string StringList(Dictionary data) @@ -166,7 +158,7 @@ public void WriteAppMeta(MetaData metaData) WriteOnce.General(string.Format("Unique matches: {0}", metaData.UniqueMatchesCount)); WriteOnce.General(MakeHeading("UniqueTags")); - List orderedTags = metaData.UniqueTags.ToList(); + List orderedTags = metaData.UniqueTags.Keys.ToList(); orderedTags.Sort(); foreach (string tag in orderedTags) @@ -205,7 +197,7 @@ private void WriteDependencies(MetaData metaData) { WriteOnce.General(MakeHeading("Dependencies")); - foreach (string s in metaData.UniqueDependencies) + foreach (string s in metaData.UniqueDependencies.Keys) { WriteOnce.General(s); } diff --git a/AppInspector.sln b/AppInspector.sln index 40d9262b..368ddbd9 100644 --- a/AppInspector.sln +++ b/AppInspector.sln @@ -13,8 +13,6 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "AppInspector.RulesEngine", "RulesEngine\AppInspector.RulesEngine.csproj", "{C19A98D2-629D-4F4D-87E4-3154416970BA}" EndProject -Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "MultiExtractor", "MultiExtractor\MultiExtractor.csproj", "{7C07A2A2-508E-4BBE-873F-F60F9FB4A9D9}" -EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "AppInspector.CLI", "AppInspector.CLI\AppInspector.CLI.csproj", "{824ED27E-A4CF-46A6-A01F-98B0821EB61C}" EndProject Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "RulesPacker", "RulesPacker", "{C464D0CE-5254-4EA5-87C9-C0C96E40C3CB}" @@ -39,6 +37,10 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "RulesPacker", "RulesPacker" EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "UnitTest.Commands", "UnitTest.Commands\UnitTest.Commands.csproj", "{181BD826-A428-41D9-8BEC-0D8EB2288DF5}" EndProject +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Benchmarks", "Benchmarks\Benchmarks.csproj", "{F031887C-EA60-4390-9940-765E99E69B8F}" +EndProject +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Shared.MultiExtractor", "MultiExtractor\Shared.MultiExtractor.csproj", "{9D6C861B-845F-4ADC-86ED-2F1E7BB4A229}" +EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Any CPU = Debug|Any CPU @@ -53,10 +55,6 @@ Global {C19A98D2-629D-4F4D-87E4-3154416970BA}.Debug|Any CPU.Build.0 = Debug|Any CPU {C19A98D2-629D-4F4D-87E4-3154416970BA}.Release|Any CPU.ActiveCfg = Release|Any CPU {C19A98D2-629D-4F4D-87E4-3154416970BA}.Release|Any CPU.Build.0 = Release|Any CPU - {7C07A2A2-508E-4BBE-873F-F60F9FB4A9D9}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {7C07A2A2-508E-4BBE-873F-F60F9FB4A9D9}.Debug|Any CPU.Build.0 = Debug|Any CPU - {7C07A2A2-508E-4BBE-873F-F60F9FB4A9D9}.Release|Any CPU.ActiveCfg = Release|Any CPU - {7C07A2A2-508E-4BBE-873F-F60F9FB4A9D9}.Release|Any CPU.Build.0 = Release|Any CPU {824ED27E-A4CF-46A6-A01F-98B0821EB61C}.Debug|Any CPU.ActiveCfg = Debug|Any CPU {824ED27E-A4CF-46A6-A01F-98B0821EB61C}.Debug|Any CPU.Build.0 = Debug|Any CPU {824ED27E-A4CF-46A6-A01F-98B0821EB61C}.Release|Any CPU.ActiveCfg = Release|Any CPU @@ -65,6 +63,14 @@ Global {181BD826-A428-41D9-8BEC-0D8EB2288DF5}.Debug|Any CPU.Build.0 = Debug|Any CPU {181BD826-A428-41D9-8BEC-0D8EB2288DF5}.Release|Any CPU.ActiveCfg = Release|Any CPU {181BD826-A428-41D9-8BEC-0D8EB2288DF5}.Release|Any CPU.Build.0 = Release|Any CPU + {F031887C-EA60-4390-9940-765E99E69B8F}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {F031887C-EA60-4390-9940-765E99E69B8F}.Debug|Any CPU.Build.0 = Debug|Any CPU + {F031887C-EA60-4390-9940-765E99E69B8F}.Release|Any CPU.ActiveCfg = Release|Any CPU + {F031887C-EA60-4390-9940-765E99E69B8F}.Release|Any CPU.Build.0 = Release|Any CPU + {9D6C861B-845F-4ADC-86ED-2F1E7BB4A229}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {9D6C861B-845F-4ADC-86ED-2F1E7BB4A229}.Debug|Any CPU.Build.0 = Debug|Any CPU + {9D6C861B-845F-4ADC-86ED-2F1E7BB4A229}.Release|Any CPU.ActiveCfg = Release|Any CPU + {9D6C861B-845F-4ADC-86ED-2F1E7BB4A229}.Release|Any CPU.Build.0 = Release|Any CPU EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE diff --git a/AppInspector/AppInspector.Commands.csproj b/AppInspector/AppInspector.Commands.csproj index 3d50c417..ce4f8752 100644 --- a/AppInspector/AppInspector.Commands.csproj +++ b/AppInspector/AppInspector.Commands.csproj @@ -76,11 +76,7 @@ - - true - MultiExtractor.dll - - + true ApplicationInspector.RulesEngine.dll diff --git a/AppInspector/Commands/AnalyzeCommand.cs b/AppInspector/Commands/AnalyzeCommand.cs index 3e0ccfd2..48b44981 100644 --- a/AppInspector/Commands/AnalyzeCommand.cs +++ b/AppInspector/Commands/AnalyzeCommand.cs @@ -2,7 +2,7 @@ // Licensed under the MIT License. See LICENSE.txt in the project root for license information. using Microsoft.ApplicationInspector.RulesEngine; -using MultiExtractor; +using Microsoft.CST.OpenSource.MultiExtractor; using Newtonsoft.Json; using NLog; using System; @@ -11,6 +11,7 @@ using System.Linq; using System.Text; using System.Text.RegularExpressions; +using System.Threading.Tasks; namespace Microsoft.ApplicationInspector.Commands { @@ -289,7 +290,6 @@ private void ConfigRules() public AnalyzeResult GetResult() { WriteOnce.SafeLog("AnalyzeCommand::Run", LogLevel.Trace); - WriteOnce.Operation(MsgHelp.FormatString(MsgHelp.ID.CMD_RUNNING, "Analyze")); AnalyzeResult analyzeResult = new AnalyzeResult() { @@ -339,7 +339,7 @@ public AnalyzeResult GetResult() } else { - _srcfileList.AsParallel().ForAll(filename => ProcessFile(filename)); + Parallel.ForEach(_srcfileList, filename => ProcessFile(filename)); } WriteOnce.General("\r" + MsgHelp.FormatString(MsgHelp.ID.ANALYZE_FILES_PROCESSED_PCNT, 100)); @@ -385,7 +385,7 @@ private void ProcessAsFile(string filename) if (FileChecksPassed(filename, ref languageInfo)) { LastUpdated = File.GetLastWriteTime(filename); - _metaDataHelper.Metadata.PackageTypes.Add(MsgHelp.GetString(MsgHelp.ID.ANALYZE_UNCOMPRESSED_FILETYPE)); + _ = _metaDataHelper.Metadata.PackageTypes.TryAdd(MsgHelp.GetString(MsgHelp.ID.ANALYZE_UNCOMPRESSED_FILETYPE),0); string fileText = File.ReadAllText(filename); ProcessInMemory(filename, fileText, languageInfo); @@ -602,7 +602,7 @@ private string ExtractDependency(string text, int startIndex, SearchPattern patt } string finalResult = rawResult.Replace(";", ""); - _metaDataHelper.Metadata.UniqueDependencies.Add(finalResult); + _ = _metaDataHelper.Metadata.UniqueDependencies.TryAdd(finalResult,0); return System.Net.WebUtility.HtmlEncode(finalResult); } @@ -645,11 +645,12 @@ private void UnZipAndProcess(string filePath, ArchiveFileType archiveFileType, b } LastUpdated = File.GetLastWriteTime(filePath); - _metaDataHelper.Metadata.PackageTypes.Add(MsgHelp.GetString(MsgHelp.ID.ANALYZE_COMPRESSED_FILETYPE)); + _ = _metaDataHelper.Metadata.PackageTypes.TryAdd(MsgHelp.GetString(MsgHelp.ID.ANALYZE_COMPRESSED_FILETYPE),0); try { - IEnumerable files = Extractor.ExtractFile(filePath).Where(x => x != null); + var extractor = new Extractor(); + IEnumerable files = extractor.ExtractFile(filePath,!_options.SingleThread); if (_options.SingleThread) { @@ -661,8 +662,9 @@ private void UnZipAndProcess(string filePath, ArchiveFileType archiveFileType, b LanguageInfo languageInfo = new LanguageInfo(); if (FileChecksPassed(file.FullPath, ref languageInfo, file.Content.Length)) { - byte[] streamByteArray = file.Content.ToArray(); - ProcessInMemory(file.FullPath, Encoding.UTF8.GetString(streamByteArray, 0, streamByteArray.Length), languageInfo); + var streamByteArray = new byte[file.Content.Length]; + file.Content.Read(streamByteArray); + ProcessInMemory(file.FullPath, Encoding.UTF8.GetString(streamByteArray), languageInfo); } } catch (Exception) @@ -673,7 +675,7 @@ private void UnZipAndProcess(string filePath, ArchiveFileType archiveFileType, b } else { - files.AsParallel().ForAll(file => + Parallel.ForEach(files, file => { try { @@ -681,8 +683,9 @@ private void UnZipAndProcess(string filePath, ArchiveFileType archiveFileType, b LanguageInfo languageInfo = new LanguageInfo(); if (FileChecksPassed(file.FullPath, ref languageInfo, file.Content.Length)) { - byte[] streamByteArray = file.Content.ToArray(); - ProcessInMemory(file.FullPath, Encoding.UTF8.GetString(streamByteArray, 0, streamByteArray.Length), languageInfo); + var streamByteArray = new byte[file.Content.Length]; + file.Content.Read(streamByteArray); + ProcessInMemory(file.FullPath, Encoding.UTF8.GetString(streamByteArray), languageInfo); } } catch (Exception) @@ -712,7 +715,7 @@ private void UnZipAndProcess(string filePath, ArchiveFileType archiveFileType, b /// private bool FileChecksPassed(string filePath, ref LanguageInfo languageInfo, long fileLength = 0) { - _metaDataHelper.Metadata.FileExtensions.Add(Path.GetExtension(filePath).Replace('.', ' ').TrimStart()); + _ = _metaDataHelper.Metadata.FileExtensions.TryAdd(Path.GetExtension(filePath).Replace('.', ' ').TrimStart(),0); // 1. Skip files written in unknown language if (!Language.FromFileName(filePath, ref languageInfo)) diff --git a/AppInspector/Commands/TagDiffCommand.cs b/AppInspector/Commands/TagDiffCommand.cs index 20e81819..4503b0be 100644 --- a/AppInspector/Commands/TagDiffCommand.cs +++ b/AppInspector/Commands/TagDiffCommand.cs @@ -222,7 +222,7 @@ public TagDiffResult GetResult() int sizeTags1 = analyze1.Metadata.UniqueTags.Count; string[] file1Tags = new string[sizeTags1]; - foreach (string tag in analyze1.Metadata.UniqueTags.ToList()) + foreach (string tag in analyze1.Metadata.UniqueTags.Keys.ToList()) { file1Tags[count1++] = tag; } @@ -231,7 +231,7 @@ public TagDiffResult GetResult() int sizeTags2 = analyze2.Metadata.UniqueTags.Count; string[] file2Tags = new string[sizeTags2]; - foreach (string tag in analyze2.Metadata.UniqueTags.ToList()) + foreach (string tag in analyze2.Metadata.UniqueTags.Keys.ToList()) { file2Tags[count2++] = tag; } diff --git a/AppInspector/Commands/TagTestCommand.cs b/AppInspector/Commands/TagTestCommand.cs index 64ed9c37..74b2600b 100644 --- a/AppInspector/Commands/TagTestCommand.cs +++ b/AppInspector/Commands/TagTestCommand.cs @@ -213,7 +213,7 @@ public TagTestResult GetResult() int sizeTags = analyze1.Metadata.UniqueTags.Count; string[] tagsFound = new string[sizeTags]; - foreach (string tag in analyze1.Metadata.UniqueTags.ToList()) + foreach (string tag in analyze1.Metadata.UniqueTags.Keys.ToList()) { tagsFound[count++] = tag; } diff --git a/AppInspector/MetaData.cs b/AppInspector/MetaData.cs index 9a186c98..36d34717 100644 --- a/AppInspector/MetaData.cs +++ b/AppInspector/MetaData.cs @@ -15,7 +15,7 @@ namespace Microsoft.ApplicationInspector.Commands public class MetaData { [JsonIgnore] - public Dictionary> KeyedPropertyLists { get; } //dynamic keyed list of properties with more than one value + public Dictionary> KeyedPropertyLists { get; } //dynamic keyed list of properties with more than one value //simple properties /// @@ -116,43 +116,43 @@ public class MetaData /// List of detected package types /// [JsonProperty(PropertyName = "packageTypes")] - public HashSet PackageTypes => KeyedPropertyLists["strGrpPackageTypes"]; + public ConcurrentDictionary PackageTypes => KeyedPropertyLists["strGrpPackageTypes"]; /// /// List of detected application types /// [JsonProperty(PropertyName = "appTypes")] - public HashSet AppTypes => KeyedPropertyLists["strGrpAppTypes"]; + public ConcurrentDictionary AppTypes => KeyedPropertyLists["strGrpAppTypes"]; [JsonIgnore] - public HashSet RulePaths { get => KeyedPropertyLists["strGrpRulePaths"]; set => KeyedPropertyLists["strGrpRulePaths"] = value; } + public ConcurrentDictionary RulePaths { get => KeyedPropertyLists["strGrpRulePaths"]; set => KeyedPropertyLists["strGrpRulePaths"] = value; } [JsonIgnore] - public HashSet FileNames => KeyedPropertyLists["strGrpFileNames"]; + public ConcurrentDictionary FileNames => KeyedPropertyLists["strGrpFileNames"]; /// /// List of detected unique tags /// [JsonProperty(PropertyName = "uniqueTags")] - public HashSet UniqueTags { get => KeyedPropertyLists["strGrpUniqueTags"]; set => KeyedPropertyLists["strGrpUniqueTags"] = value; } + public ConcurrentDictionary UniqueTags { get => KeyedPropertyLists["strGrpUniqueTags"]; set => KeyedPropertyLists["strGrpUniqueTags"] = value; } /// /// List of detected unique code dependency includes /// [JsonProperty(PropertyName = "uniqueDependencies")] - public HashSet UniqueDependencies => KeyedPropertyLists["strGrpUniqueDependencies"]; + public ConcurrentDictionary UniqueDependencies => KeyedPropertyLists["strGrpUniqueDependencies"]; /// /// List of detected output types /// [JsonProperty(PropertyName = "outputs")] - public HashSet Outputs => KeyedPropertyLists["strGrpOutputs"]; + public ConcurrentDictionary Outputs => KeyedPropertyLists["strGrpOutputs"]; /// /// List of detected target types /// [JsonProperty(PropertyName = "targets")] - public HashSet Targets => KeyedPropertyLists["strGrpTargets"]; + public ConcurrentDictionary Targets => KeyedPropertyLists["strGrpTargets"]; /// /// List of detected programming languages used @@ -164,25 +164,25 @@ public class MetaData /// List of detected OS targets /// [JsonProperty(PropertyName = "OSTargets")] - public HashSet OSTargets => KeyedPropertyLists["strGrpOSTargets"]; + public ConcurrentDictionary OSTargets => KeyedPropertyLists["strGrpOSTargets"]; /// /// LIst of detected file types (extension based) /// [JsonProperty(PropertyName = "fileExtensions")] - public HashSet FileExtensions => KeyedPropertyLists["strGrpFileExtensions"]; + public ConcurrentDictionary FileExtensions => KeyedPropertyLists["strGrpFileExtensions"]; /// /// List of detected cloud host targets /// [JsonProperty(PropertyName = "cloudTargets")] - public HashSet CloudTargets => KeyedPropertyLists["strGrpCloudTargets"]; + public ConcurrentDictionary CloudTargets => KeyedPropertyLists["strGrpCloudTargets"]; /// /// List of detected cpu targets /// [JsonProperty(PropertyName = "CPUTargets")] - public HashSet CPUTargets => KeyedPropertyLists["strGrpCPUTargets"]; + public ConcurrentDictionary CPUTargets => KeyedPropertyLists["strGrpCPUTargets"]; //other data types @@ -208,20 +208,20 @@ public MetaData(string applicationName, string sourcePath) Matches = new List(); //initialize standard set groups using dynamic lists variables that may have more than one value - KeyedPropertyLists = new Dictionary> + KeyedPropertyLists = new Dictionary> { - ["strGrpPackageTypes"] = new HashSet(), - ["strGrpAppTypes"] = new HashSet(), - ["strGrpFileTypes"] = new HashSet(), - ["strGrpUniqueTags"] = new HashSet(), - ["strGrpOutputs"] = new HashSet(), - ["strGrpTargets"] = new HashSet(), - ["strGrpOSTargets"] = new HashSet(), - ["strGrpFileExtensions"] = new HashSet(), - ["strGrpFileNames"] = new HashSet(), - ["strGrpCPUTargets"] = new HashSet(), - ["strGrpCloudTargets"] = new HashSet(), - ["strGrpUniqueDependencies"] = new HashSet() + ["strGrpPackageTypes"] = new ConcurrentDictionary(), + ["strGrpAppTypes"] = new ConcurrentDictionary(), + ["strGrpFileTypes"] = new ConcurrentDictionary(), + ["strGrpUniqueTags"] = new ConcurrentDictionary(), + ["strGrpOutputs"] = new ConcurrentDictionary(), + ["strGrpTargets"] = new ConcurrentDictionary(), + ["strGrpOSTargets"] = new ConcurrentDictionary(), + ["strGrpFileExtensions"] = new ConcurrentDictionary(), + ["strGrpFileNames"] = new ConcurrentDictionary(), + ["strGrpCPUTargets"] = new ConcurrentDictionary(), + ["strGrpCloudTargets"] = new ConcurrentDictionary(), + ["strGrpUniqueDependencies"] = new ConcurrentDictionary() }; Languages = new ConcurrentDictionary(); diff --git a/AppInspector/MetaDataHelper.cs b/AppInspector/MetaDataHelper.cs index 65bf408e..a80ba474 100644 --- a/AppInspector/MetaDataHelper.cs +++ b/AppInspector/MetaDataHelper.cs @@ -45,7 +45,7 @@ public void AddMatchRecord(MatchRecord matchRecord) { if (matchRecord.Tags.Any(v => _propertyTagSearchPatterns[key].IsMatch(v))) { - Metadata.KeyedPropertyLists[key].Add(matchRecord.Sample); + _ = Metadata.KeyedPropertyLists[key].TryAdd(matchRecord.Sample,0); } } @@ -77,17 +77,17 @@ public void AddMatchRecord(MatchRecord matchRecord) if (matchRecord.Tags.Any(v => v.Contains("Metadata.Application.Target.Processor"))) { - Metadata.CPUTargets.Add(ExtractValue(matchRecord.Sample).ToLower()); + _ = Metadata.CPUTargets.TryAdd(ExtractValue(matchRecord.Sample).ToLower(), 0); } if (matchRecord.Tags.Any(v => v.Contains("Metadata.Application.Output.Type"))) { - Metadata.Outputs.Add(ExtractValue(matchRecord.Sample).ToLower()); + _ = Metadata.Outputs.TryAdd(ExtractValue(matchRecord.Sample).ToLower(), 0); } if (matchRecord.Tags.Any(v => v.Contains("Platform.OS"))) { - Metadata.OSTargets.Add(ExtractValue(matchRecord.Sample).ToLower()); + _ = Metadata.OSTargets.TryAdd(ExtractValue(matchRecord.Sample).ToLower(), 0); } if (matchRecord.Tags.Any(v => v.Contains("Metric."))) @@ -106,7 +106,7 @@ public void AddMatchRecord(MatchRecord matchRecord) string solutionType = DetectSolutionType(matchRecord); if (!string.IsNullOrEmpty(solutionType)) { - Metadata.AppTypes.Add(solutionType); + _ = Metadata.AppTypes.TryAdd(solutionType,0); } //Update metric counters for default or user specified tags; don't add as match detail @@ -127,7 +127,7 @@ public void AddMatchRecord(MatchRecord matchRecord) //update list of unique tags as we go foreach (string tag in matchRecord.Tags) { - Metadata.UniqueTags.Add(tag); + _ = Metadata.UniqueTags.TryAdd(tag,0); } Metadata.Matches.Add(matchRecord); diff --git a/AppInspector/Resources/defaultRulesPkd.json b/AppInspector/Resources/defaultRulesPkd.json deleted file mode 100644 index d2714662..00000000 --- a/AppInspector/Resources/defaultRulesPkd.json +++ /dev/null @@ -1,17160 +0,0 @@ -[ - { - "name": "Platform: Microsoft .NET Core", - "id": "AI028500", - "description": "Platform: .NET Core", - "applies_to": [ - "VSProject", - "csharp" - ], - "tags": [ - "Metadata.Platform.Microsoft.NETCore" - ], - "severity": "moderate", - "overrides": null, - "patterns": [ - { - "pattern": "\\b(netcore)\\b", - "type": "regex", - "modifiers": [ - "i" - ], - "scopes": [ - "code" - ], - "confidence": "medium" - } - ], - "conditions": [] - }, - { - "name": "Platform: Microsoft .NET Standard", - "id": "AI028600", - "description": "Platform: Microsoft .NET Standard", - "applies_to": [ - "VSProject", - "csharp" - ], - "tags": [ - "Metadata.Platform.Microsoft.NETStandard" - ], - "severity": "moderate", - "overrides": null, - "patterns": [ - { - "pattern": "\\b(Microsoft\\.NET\\.Sdk)\\b", - "type": "regex", - "modifiers": [ - "i" - ], - "scopes": [ - "code" - ], - "confidence": "medium" - } - ], - "conditions": [] - }, - { - "name": "Platform: Microsoft Mono", - "id": "AI028700", - "description": "Platform: Microsoft Mono", - "applies_to": [ - "VSProject", - "csharp" - ], - "tags": [ - "Metadata.Platform.Microsoft.Mono" - ], - "severity": "moderate", - "overrides": null, - "patterns": [ - { - "pattern": "\\b(using\\ \\(gtk\\|Glade\\))\\b", - "type": "regex", - "modifiers": [ - "i" - ], - "scopes": [ - "code" - ], - "confidence": "medium" - } - ], - "conditions": [] - }, - { - "name": "Platform: Google Android", - "id": "AI028800", - "description": "Platform: Google Android", - "applies_to": null, - "tags": [ - "Metadata.Platform.OS.Google.Android" - ], - "severity": "moderate", - "overrides": null, - "patterns": [ - { - "pattern": "\\b(android)\\b", - "type": "regex", - "modifiers": [ - "i" - ], - "scopes": [ - "code", - "comment" - ], - "confidence": "high" - }, - { - "pattern": "\\b(kitkat|jellybean|lollipop|marshmallow|nougat|oreo|pie)\\b", - "type": "regex", - "modifiers": [ - "i" - ], - "scopes": [ - "code", - "comment" - ], - "confidence": "high" - } - ], - "conditions": [] - }, - { - "name": "Platform: Apple iOS", - "id": "AI028900", - "description": "Platform: Apple iOS", - "applies_to": null, - "tags": [ - "Metadata.Platform.OS.Apple.iOS" - ], - "severity": "moderate", - "overrides": null, - "patterns": [ - { - "pattern": "\\b(UIKit|ios)\\b", - "type": "regex", - "modifiers": [ - "i" - ], - "scopes": [ - "code", - "comment" - ], - "confidence": "high" - } - ], - "conditions": [] - }, - { - "name": "Platform: Apple MacOS", - "id": "AI029000", - "description": "Platform: Apple MacOS", - "applies_to": null, - "tags": [ - "Metadata.Platform.OS.Apple.MacOS" - ], - "severity": "moderate", - "overrides": null, - "patterns": [ - { - "pattern": "\\b((os x)|osx|macos|macosx)\\b", - "type": "regex", - "modifiers": [ - "i" - ], - "scopes": [ - "code", - "comment" - ], - "confidence": "high" - } - ], - "conditions": [] - }, - { - "name": "Platform: Microsoft Windows", - "id": "AI029100", - "description": "Platform: Microsoft Windows Server", - "applies_to": null, - "tags": [ - "Metadata.Platform.OS.Microsoft.WindowsServer" - ], - "severity": "moderate", - "overrides": null, - "patterns": [ - { - "pattern": "windows server", - "type": "regex", - "modifiers": [ - "i" - ], - "scopes": [ - "code", - "comment" - ], - "confidence": "high" - } - ], - "conditions": [] - }, - { - "name": "Platform: Microsoft Windows", - "id": "AI029200", - "description": "Platform: Microsoft Windows", - "applies_to": null, - "tags": [ - "Metadata.Platform.OS.Microsoft.WindowsStandard" - ], - "severity": "moderate", - "overrides": null, - "patterns": [ - { - "pattern": "windows", - "type": "regex", - "modifiers": [ - "i" - ], - "scopes": [ - "code", - "comment" - ], - "confidence": "high" - } - ], - "conditions": [] - }, - { - "name": "Platform: Microsoft Windows", - "id": "AI029300", - "description": "Platform: Microsoft Windows", - "applies_to": null, - "tags": [ - "Metadata.Platform.OS.Microsoft.WindowsCE" - ], - "severity": "moderate", - "overrides": null, - "patterns": [ - { - "pattern": "PlatformID.WinCE|Windows Mobile|Windows Embedded|Windows Phone", - "type": "regex", - "modifiers": [ - "i" - ], - "scopes": [ - "code", - "comment" - ], - "confidence": "high" - } - ], - "conditions": [] - }, - { - "name": "Development Framework: Windows Universal Platform", - "id": "AI029400", - "description": "Development Framework: Windows Universal Platform", - "applies_to": null, - "tags": [ - "Metadata.Platform.OS.Microsoft.WindowsUniversalPlatform" - ], - "severity": "moderate", - "overrides": null, - "patterns": [ - { - "pattern": "Windows universal platform|UWP", - "type": "regex", - "modifiers": [ - "i" - ], - "scopes": [ - "code" - ], - "confidence": "medium" - } - ], - "conditions": [] - }, - { - "name": "Platform: Linux", - "id": "AI029500", - "description": "Platform: Linux", - "applies_to": null, - "tags": [ - "Metadata.Platform.OS.Linux.Distro" - ], - "severity": "moderate", - "overrides": null, - "patterns": [ - { - "pattern": "\\b(linux|xubuntu|ubuntu|coreos|manjaro|archlinux|debian|mint|gentoo|opensuse|redhat|mandrake|mandriva|slackware)\\b", - "type": "regex", - "modifiers": [ - "i" - ], - "scopes": [ - "code", - "comment" - ], - "confidence": "high" - } - ], - "conditions": [] - }, - { - "name": "Platform: Microsoft XBox", - "id": "AI029600", - "description": "Platform: Microsoft XBox", - "applies_to": null, - "tags": [ - "Metadata.Platform.OS.Microsoft.XBox" - ], - "severity": "moderate", - "overrides": null, - "patterns": [ - { - "pattern": "\\b(xbox)\\b", - "type": "regex", - "modifiers": [ - "i" - ], - "scopes": [ - "code", - "comment" - ], - "confidence": "high" - } - ], - "conditions": [] - }, - { - "name": "Platform: Mobile Device", - "id": "AI029700", - "description": "Platform: Mobile Device", - "applies_to": null, - "tags": [ - "Metadata.Platform.Device.Mobile" - ], - "severity": "moderate", - "overrides": null, - "patterns": [ - { - "pattern": "mobile|tablet|iphone", - "type": "regex", - "modifiers": [ - "i" - ], - "scopes": [ - "code", - "comment" - ], - "confidence": "high" - } - ], - "conditions": [ - { - "pattern": { - "pattern": "address|(first|last|sur)name|contact|gender|email", - "type": "regex", - "modifiers": [ - "i" - ], - "scopes": [ - "code" - ], - "confidence": "medium" - }, - "search_in": "finding-region(-7,7)", - "negate_finding": true - } - ] - }, - { - "name": "Platform: IOT", - "id": "AI029800", - "description": "Platform: IOT", - "applies_to": null, - "tags": [ - "Metadata.Platform.Device.IOT" - ], - "severity": "moderate", - "overrides": null, - "patterns": [ - { - "pattern": "\\b(IOT)\\b", - "type": "regex", - "modifiers": [ - "i" - ], - "scopes": [ - "code", - "comment" - ], - "confidence": "high" - } - ], - "conditions": [] - }, - { - "name": "Hardware: Microsoft Kinex", - "id": "AI029900", - "description": "Platform: Microsoft Kinex", - "applies_to": null, - "tags": [ - "Hardware.Accessory.Microsoft.Kinex" - ], - "severity": "moderate", - "overrides": null, - "patterns": [ - { - "pattern": "\\b(kinex)\\b", - "type": "regex", - "modifiers": [ - "i" - ], - "scopes": [ - "code", - "comment" - ], - "confidence": "high" - } - ], - "conditions": [] - }, - { - "name": "Hardware: Reference Design", - "id": "AI030000", - "description": "Hardware: Reference Design", - "applies_to": null, - "tags": [ - "Hardware.ReferenceDesign" - ], - "severity": "moderate", - "overrides": null, - "patterns": [ - { - "pattern": "Reference Design", - "type": "regex", - "modifiers": [ - "i" - ], - "scopes": [ - "code", - "comment" - ], - "confidence": "high" - } - ], - "conditions": [] - }, - { - "name": "Dependency: Included Source", - "id": "AI026400", - "description": "Dependency: Included Source", - "applies_to": [ - "c", - "cpp" - ], - "tags": [ - "Dependency.SourceInclude" - ], - "severity": "moderate", - "overrides": null, - "patterns": [ - { - "pattern": "#include ?[\\\"<](.*)[\\\">]", - "type": "regex", - "modifiers": null, - "scopes": [ - "code" - ], - "confidence": "high" - } - ], - "conditions": [] - }, - { - "name": "Dependency: Included Source", - "id": "AI026500", - "description": "Dependency: Included Source", - "applies_to": [ - "php" - ], - "tags": [ - "Dependency.SourceInclude" - ], - "severity": "moderate", - "overrides": null, - "patterns": [ - { - "pattern": "(include|require) .*", - "type": "regex", - "modifiers": null, - "scopes": [ - "code" - ], - "confidence": "high" - } - ], - "conditions": [] - }, - { - "name": "Dependency: Included Source", - "id": "AI026600", - "description": "Dependency: Included Source", - "applies_to": [ - "objective-c" - ], - "tags": [ - "Dependency.SourceInclude" - ], - "severity": "moderate", - "overrides": null, - "patterns": [ - { - "pattern": "import .*", - "type": "regex", - "modifiers": null, - "scopes": [ - "code" - ], - "confidence": "high" - } - ], - "conditions": [] - }, - { - "name": "Dependency: Included Source", - "id": "AI026700", - "description": "Dependency: Included Source", - "applies_to": [ - "groovy" - ], - "tags": [ - "Dependency.SourceInclude" - ], - "severity": "moderate", - "overrides": null, - "patterns": [ - { - "pattern": "import .*", - "type": "regex", - "modifiers": null, - "scopes": [ - "code" - ], - "confidence": "high" - }, - { - "pattern": "loadScriptByName.*", - "type": "regex", - "modifiers": null, - "scopes": [ - "code" - ], - "confidence": "high" - }, - { - "pattern": "evaluate ?\\(.*", - "type": "regex", - "modifiers": null, - "scopes": [ - "code" - ], - "confidence": "medium" - }, - { - "pattern": "shell\\.parse ?\\(*", - "type": "regex", - "modifiers": null, - "scopes": [ - "code" - ], - "confidence": "high" - } - ], - "conditions": [] - }, - { - "name": "Dependency: Included Source", - "id": "AI026800", - "description": "Dependency: Included Source", - "applies_to": [ - "python", - "java", - "swift", - "go" - ], - "tags": [ - "Dependency.SourceInclude" - ], - "severity": "moderate", - "overrides": null, - "patterns": [ - { - "pattern": "import .*", - "type": "regex", - "modifiers": null, - "scopes": [ - "code" - ], - "confidence": "high" - }, - { - "pattern": "package .*", - "type": "regex", - "modifiers": null, - "scopes": [ - "code" - ], - "confidence": "high" - } - ], - "conditions": [] - }, - { - "name": "Dependency: Included Source", - "id": "AI026900", - "description": "Dependency: Included Source", - "applies_to": [ - "perl" - ], - "tags": [ - "Dependency.SourceInclude" - ], - "severity": "moderate", - "overrides": null, - "patterns": [ - { - "pattern": "use .*", - "type": "regex", - "modifiers": null, - "scopes": [ - "code" - ], - "confidence": "high" - }, - { - "pattern": "package. *", - "type": "regex", - "modifiers": null, - "scopes": [ - "code" - ], - "confidence": "high" - } - ], - "conditions": [] - }, - { - "name": "Dependency: Included Source", - "id": "AI027000", - "description": "Dependency: Included Source", - "applies_to": [ - "ruby" - ], - "tags": [ - "Dependency.SourceInclude" - ], - "severity": "moderate", - "overrides": null, - "patterns": [ - { - "pattern": "load .*", - "type": "regex", - "modifiers": null, - "scopes": [ - "code" - ], - "confidence": "high" - }, - { - "pattern": "require .*", - "type": "regex", - "modifiers": null, - "scopes": [ - "code" - ], - "confidence": "high" - } - ], - "conditions": [] - }, - { - "name": "Dependency: Included Source", - "id": "AI027100", - "description": "Dependency: Included Source", - "applies_to": [ - "csharp" - ], - "tags": [ - "Dependency.SourceInclude" - ], - "severity": "moderate", - "overrides": null, - "patterns": [ - { - "pattern": "using (.*);", - "type": "regex", - "modifiers": null, - "scopes": [ - "code" - ], - "confidence": "medium" - } - ], - "conditions": [] - }, - { - "name": "Dependency: Included Source", - "id": "AI027200", - "description": "Dependency: Included Source", - "applies_to": [ - "javascript" - ], - "tags": [ - "Dependency.SourceInclude" - ], - "severity": "moderate", - "overrides": null, - "patterns": [ - { - "pattern": "import .*", - "type": "regex", - "modifiers": null, - "scopes": [ - "code" - ], - "confidence": "high" - }, - { - "pattern": "fetchInject ?\\(.*", - "type": "regex", - "modifiers": null, - "scopes": [ - "code" - ], - "confidence": "high" - }, - { - "pattern": "require ?\\(['\\\"]([^'\\\"]+)", - "type": "regex", - "modifiers": null, - "scopes": [ - "code" - ], - "confidence": "high" - }, - { - "pattern": "\\$\\.getScript\\(.*", - "type": "regex", - "modifiers": null, - "scopes": [ - "code" - ], - "confidence": "high" - } - ], - "conditions": [] - }, - { - "name": "Metadata: Target Processor", - "id": "AI030100", - "description": "Metadata: Target Processor", - "applies_to": [ - "VSsolution", - "VSProject", - "cpp" - ], - "tags": [ - "Metadata.Application.Target.Processor" - ], - "severity": "moderate", - "overrides": null, - "patterns": [ - { - "pattern": "\\b(Win32|Any CPU|Win64|x64|x86|Arm|Arm64)\\b", - "type": "regex", - "modifiers": [ - "i" - ], - "scopes": [ - "code" - ], - "confidence": "high" - } - ], - "conditions": [] - }, - { - "name": "Metadata: Application Name", - "id": "AI030200", - "description": "Metadata: Application Name", - "applies_to": [ - "VSProject" - ], - "tags": [ - "Metadata.Application.Name" - ], - "severity": "moderate", - "overrides": null, - "patterns": [ - { - "pattern": ".*", - "type": "regex", - "modifiers": null, - "scopes": [ - "code" - ], - "confidence": "high" - } - ], - "conditions": [] - }, - { - "name": "Metadata: Build Output Type", - "id": "AI030300", - "description": "Metadata: Build Output Type", - "applies_to": [ - "VSProject" - ], - "tags": [ - "Metadata.Application.Output.Type" - ], - "severity": "moderate", - "overrides": null, - "patterns": [ - { - "pattern": ".*", - "type": "regex", - "modifiers": null, - "scopes": [ - "code" - ], - "confidence": "high" - }, - { - "pattern": ".*", - "type": "regex", - "modifiers": null, - "scopes": [ - "code" - ], - "confidence": "high" - } - ], - "conditions": [] - }, - { - "name": "Metadata: Application Type (Windows Forms)", - "id": "AI030400", - "description": "Metadata: Application Type (Windows Forms)", - "applies_to": [ - "csharp" - ], - "tags": [ - "Metadata.Application.Type.Client.Winforms" - ], - "severity": "moderate", - "overrides": null, - "patterns": [ - { - "pattern": "\\b(winforms)\\b", - "type": "regex", - "modifiers": [ - "i" - ], - "scopes": [ - "code" - ], - "confidence": "high" - } - ], - "conditions": [] - }, - { - "name": "Metadata: Application Type (Service)", - "id": "AI030500", - "description": "Metadata: Application Type (Service)", - "applies_to": [ - "csharp" - ], - "tags": [ - "Metadata.Application.Type.Client.Service.Windows" - ], - "severity": "moderate", - "overrides": null, - "patterns": [ - { - "pattern": "\\b(ServiceStatus|ServiceController|InstallService)\\b", - "type": "regex", - "modifiers": null, - "scopes": [ - "code" - ], - "confidence": "high" - } - ], - "conditions": [] - }, - { - "name": "Metadata: Application Type (Service)", - "id": "AI030600", - "description": "Metadata: Application Type (Service)", - "applies_to": [ - "c", - "cpp", - "shellscript" - ], - "tags": [ - "Metadata.Application.Type.Client.Service.Windows" - ], - "severity": "moderate", - "overrides": null, - "patterns": [ - { - "pattern": "(/etc/rc\\.d/service|/etc/systemd/system)", - "type": "regex", - "modifiers": null, - "scopes": [ - "code" - ], - "confidence": "high" - } - ], - "conditions": [] - }, - { - "name": "Metadata: Application Type (Service)", - "id": "AI030700", - "description": "Metadata: Application Type (Service)", - "applies_to": [ - "cpp" - ], - "tags": [ - "Metadata.Application.Type.Client.Service.Windows" - ], - "severity": "moderate", - "overrides": null, - "patterns": [ - { - "pattern": "\\b(RegisterServiceCtrlHandler|serviceCtrlHandler|StartServiceCtrlDispatcher|SERVICE_STATUS|SERVICE_RUNNING|SERVICE_WIN32|SERVICE_CONTROL)\\b", - "type": "regex", - "modifiers": null, - "scopes": [ - "code" - ], - "confidence": "high" - } - ], - "conditions": [] - }, - { - "name": "Metadata: Application Name", - "id": "AI030800", - "description": "Metadata: Application Name", - "applies_to": [ - "pom.xml", - "build.gradle", - "build.make.xml" - ], - "tags": [ - "Metadata.Application.Name" - ], - "severity": "moderate", - "overrides": null, - "patterns": [ - { - "pattern": "(.*)", - "type": "regex", - "modifiers": null, - "scopes": [ - "code" - ], - "confidence": "high" - } - ], - "conditions": [] - }, - { - "name": "Metadata: Application Description", - "id": "AI030900", - "description": "Metadata: Application Description", - "applies_to": [ - "package.json" - ], - "tags": [ - "Metadata.Application.Description" - ], - "severity": "moderate", - "overrides": null, - "patterns": [ - { - "pattern": "\\\"description\\\"\\s*:\\s*\\\"([^\\\"])+\\\"", - "type": "regex", - "modifiers": null, - "scopes": [ - "code" - ], - "confidence": "high" - } - ], - "conditions": [] - }, - { - "name": "Metadata: Application Version", - "id": "AI031000", - "description": "Metadata: Application Version", - "applies_to": [ - "package.json" - ], - "tags": [ - "Metadata.Application.Version" - ], - "severity": "moderate", - "overrides": null, - "patterns": [ - { - "pattern": "\\\"version\\\"\\s*:\\s*\\\"([^\\\"])+\\\"", - "type": "regex", - "modifiers": null, - "scopes": [ - "code" - ], - "confidence": "high" - } - ], - "conditions": [] - }, - { - "name": "Metadata: Application Version", - "id": "AI031100", - "description": "Metadata: Application Version", - "applies_to": [ - "plaintext", - "markdown" - ], - "tags": [ - "Metadata.Application.Version" - ], - "severity": "moderate", - "overrides": null, - "patterns": [ - { - "pattern": "version [^\\b]+", - "type": "regex", - "modifiers": null, - "scopes": [ - "code" - ], - "confidence": "high" - } - ], - "conditions": [] - }, - { - "name": "Metadata: Application Author", - "id": "AI031200", - "description": "Metadata: Application Author", - "applies_to": [ - "package.json" - ], - "tags": [ - "Metadata.Application.Author" - ], - "severity": "moderate", - "overrides": null, - "patterns": [ - { - "pattern": "\\\"author\\\"\\s*:\\s*\\\"([^\\\"])+\\\"", - "type": "regex", - "modifiers": null, - "scopes": [ - "code" - ], - "confidence": "high" - } - ], - "conditions": [] - }, - { - "name": "Metadata: Application Author", - "id": "AI031300", - "description": "Metadata: Application Author", - "applies_to": null, - "tags": [ - "Metadata.Application.Author" - ], - "severity": "moderate", - "overrides": null, - "patterns": [ - { - "pattern": "author[=: ](.*)", - "type": "regex", - "modifiers": [ - "i" - ], - "scopes": [ - "code" - ], - "confidence": "high" - } - ], - "conditions": [] - }, - { - "name": "Metadata: Application Publisher", - "id": "AI031400", - "description": "Metadata: Application Publisher", - "applies_to": [ - "VSProject" - ], - "tags": [ - "Metadata.Application.Publisher" - ], - "severity": "moderate", - "overrides": null, - "patterns": [ - { - "pattern": ".*", - "type": "regex", - "modifiers": [ - "i" - ], - "scopes": [ - "code" - ], - "confidence": "high" - } - ], - "conditions": [] - }, - { - "name": "Metadata: Target Framework", - "id": "AI031500", - "description": "Metadata: Target Framework", - "applies_to": null, - "tags": [ - "Metadata.Application.Target.Framework" - ], - "severity": "moderate", - "overrides": null, - "patterns": [ - { - "pattern": ".*", - "type": "regex", - "modifiers": [ - "i" - ], - "scopes": [ - "code" - ], - "confidence": "high" - } - ], - "conditions": [] - }, - { - "name": "Metadata: Application Container (Kubernetes)", - "id": "AI031510", - "description": "Metadata: Application Container (Kubernetes)", - "applies_to": null, - "tags": [ - "Metadata.Application.Container.Kubernetes" - ], - "severity": "moderate", - "overrides": null, - "patterns": [ - { - "pattern": "\\b(Kubernetes)\\b", - "type": "regex", - "modifiers": [ - "i" - ], - "scopes": [ - "code" - ], - "confidence": "high" - } - ], - "conditions": [] - }, - { - "name": "Metadata: Application Container (Docker)", - "id": "AI031520", - "description": "Metadata: Application Container (Docker)", - "applies_to": null, - "tags": [ - "Metadata.Application.Container.Docker" - ], - "severity": "moderate", - "overrides": null, - "patterns": [ - { - "pattern": "\\b(Docker|RancherOS)\\b", - "type": "regex", - "modifiers": [ - "i" - ], - "scopes": [ - "code" - ], - "confidence": "high" - } - ], - "conditions": [] - }, - { - "name": "Metadata: Application Container (rktlet)", - "id": "AI031530", - "description": "Metadata: Application Container (rktlet)", - "applies_to": null, - "tags": [ - "Metadata.Application.Container.rktlet" - ], - "severity": "moderate", - "overrides": null, - "patterns": [ - { - "pattern": "\\b(rktlet)\\b", - "type": "regex", - "modifiers": [ - "i" - ], - "scopes": [ - "code" - ], - "confidence": "high" - } - ], - "conditions": [] - }, - { - "name": "Metadata: Application Container (CRI-O)", - "id": "AI031540", - "description": "Metadata: Application Container (CRI-O)", - "applies_to": null, - "tags": [ - "Metadata.Application.Container.CRI-O" - ], - "severity": "moderate", - "overrides": null, - "patterns": [ - { - "pattern": "\\b(CRI-O)\\b", - "type": "regex", - "modifiers": [ - "i" - ], - "scopes": [ - "code" - ], - "confidence": "high" - } - ], - "conditions": [] - }, - { - "name": "Metadata: Application Container (Microsoft Hyper-V)", - "id": "AI031550", - "description": "Metadata: Application Container (Microsoft Hyper-V)", - "applies_to": null, - "tags": [ - "Metadata.Application.Container.Microsoft.Hyper-V" - ], - "severity": "moderate", - "overrides": null, - "patterns": [ - { - "pattern": "\\b(hyper-v)\\b", - "type": "regex", - "modifiers": [ - "i" - ], - "scopes": [ - "code" - ], - "confidence": "high" - } - ], - "conditions": [] - }, - { - "name": "Metadata: Application Container (Microsoft Server)", - "id": "AI031560", - "description": "Metadata: Application Container (Microsoft Server)", - "applies_to": null, - "tags": [ - "Metadata.Application.Container.Microsoft.Core" - ], - "severity": "moderate", - "overrides": null, - "patterns": [ - { - "pattern": "\\b(Nano Server|Server Core)\\b", - "type": "regex", - "modifiers": [ - "i" - ], - "scopes": [ - "code" - ], - "confidence": "high" - } - ], - "conditions": [] - }, - { - "name": "Hygiene: Todo Comment", - "id": "AI027300", - "description": "Hygiene: Todo Comment", - "applies_to": null, - "tags": [ - "Miscellaneous.CodeHygiene.Comment.Todo" - ], - "severity": "moderate", - "overrides": null, - "patterns": [ - { - "pattern": "todo", - "type": "regex", - "modifiers": [ - "i" - ], - "scopes": [ - "comment" - ], - "confidence": "medium" - } - ], - "conditions": [] - }, - { - "name": "Hygiene: Fix Comment", - "id": "AI027400", - "description": "Hygiene: Fix Comment", - "applies_to": null, - "tags": [ - "Miscellaneous.CodeHygiene.Comment.Fix" - ], - "severity": "moderate", - "overrides": null, - "patterns": [ - { - "pattern": "fixme|broke|broken", - "type": "regex", - "modifiers": [ - "i" - ], - "scopes": [ - "comment" - ], - "confidence": "medium" - } - ], - "conditions": [] - }, - { - "name": "Hygiene: Suspicious Comment", - "id": "AI027500", - "description": "Hygiene: Suspicious Comment", - "applies_to": null, - "tags": [ - "Miscellaneous.CodeHygiene.Comment.Suspicious" - ], - "severity": "moderate", - "overrides": null, - "patterns": [ - { - "pattern": "hack|insecure|black magic|high risk|risky|riskiest|obfuscation|obfuscate|obfuscated", - "type": "regex", - "modifiers": [ - "i" - ], - "scopes": [ - "comment" - ], - "confidence": "medium" - } - ], - "conditions": [] - }, - { - "name": "Metric: Class Definition", - "id": "AI025700", - "description": "Metric: Classes Defined", - "applies_to": [ - "csharp", - "cpp", - "javascript", - "python", - "vb", - "rust", - "ruby", - "groovy", - "php" - ], - "tags": [ - "Metric.Code.Class.Defined" - ], - "severity": "moderate", - "overrides": null, - "patterns": [ - { - "pattern": "\\b(class)\\b", - "type": "regex", - "modifiers": null, - "scopes": [ - "code" - ], - "confidence": "high" - } - ], - "conditions": [] - }, - { - "name": "Metric: Function Definition", - "id": "AI025800", - "description": "Metric: Function Defined", - "applies_to": null, - "tags": [ - "Metric.Code.Function.Defined" - ], - "severity": "moderate", - "overrides": null, - "patterns": [ - { - "pattern": "\\b((def|function|fun) (.*))\\b", - "type": "regex", - "modifiers": null, - "scopes": [ - "code" - ], - "confidence": "medium" - } - ], - "conditions": [] - }, - { - "name": "Metric: HTML Form Definition", - "id": "AI025900", - "description": "Metric: HTML Form Defined", - "applies_to": null, - "tags": [ - "Metric.Code.HTMLForm.Defined" - ], - "severity": "moderate", - "overrides": null, - "patterns": [ - { - "pattern": "\\b(", - "type": "regex", - "modifiers": null, - "scopes": [ - "code" - ], - "confidence": "high" - } - ], - "conditions": [] - }, - { - "name": "CloudServices: DataStorage (Microsoft OneDrive)", - "id": "AI002900", - "description": "CloudServices: DataStorage (Microsoft OneDrive)", - "applies_to": null, - "tags": [ - "CloudServices.DataStorage.Microsoft.OneDrive" - ], - "severity": "moderate", - "overrides": null, - "patterns": [ - { - "pattern": "OneDrive", - "type": "regex", - "modifiers": [ - "i" - ], - "scopes": [ - "code" - ], - "confidence": "high" - } - ], - "conditions": [] - }, - { - "name": "CloudServices: DataStorage (Amazon S3)", - "id": "AI003000", - "description": "CloudServices: DataStorage (Amazon S3)", - "applies_to": [ - "c", - "c++" - ], - "tags": [ - "CloudServices.DataStorage.Amazon.S3" - ], - "severity": "moderate", - "overrides": null, - "patterns": [ - { - "pattern": "aws/s3/|Aws::S3", - "type": "regex", - "modifiers": null, - "scopes": [ - "code" - ], - "confidence": "high" - } - ], - "conditions": [] - }, - { - "name": "CloudServices: DataStorage (Amazon S3)", - "id": "AI003100", - "description": "CloudServices: DataStorage (Amazon S3)", - "applies_to": [ - "csharp" - ], - "tags": [ - "CloudServices.DataStorage.Amazon.S3" - ], - "severity": "moderate", - "overrides": null, - "patterns": [ - { - "pattern": "\\b(using\\ Amazon\\.S3;)\\b", - "type": "regex", - "modifiers": null, - "scopes": [ - "code" - ], - "confidence": "high" - } - ], - "conditions": [] - }, - { - "name": "CloudServices: DataStorage (Amazon S3)", - "id": "AI003200", - "description": "CloudServices: DataStorage (Amazon S3)", - "applies_to": [ - "python" - ], - "tags": [ - "CloudServices.DataStorage.Amazon.S3" - ], - "severity": "moderate", - "overrides": null, - "patterns": [ - { - "pattern": "import boto3", - "type": "regex", - "modifiers": null, - "scopes": [ - "code" - ], - "confidence": "high" - } - ], - "conditions": [] - }, - { - "name": "CloudServices: DataStorage (Google Drive)", - "id": "AI003300", - "description": "CloudServices: DataStorage (Google Drive)", - "applies_to": null, - "tags": [ - "CloudServices.DataStorage.Google.Drive" - ], - "severity": "moderate", - "overrides": null, - "patterns": [ - { - "pattern": "\\b(googleapis\\.com/upload/drive)\\b", - "type": "regex", - "modifiers": null, - "scopes": [ - "code" - ], - "confidence": "high" - } - ], - "conditions": [] - }, - { - "name": "CloudServices: DataStorage (DropBox)", - "id": "AI003400", - "description": "CloudServices: DataStorage (DropBox)", - "applies_to": null, - "tags": [ - "CloudServices.DataStorage.DropBox" - ], - "severity": "moderate", - "overrides": null, - "patterns": [ - { - "pattern": "\\b(api\\.dropboxapi\\.com)\\b", - "type": "regex", - "modifiers": null, - "scopes": [ - "code" - ], - "confidence": "high" - } - ], - "conditions": [] - }, - { - "name": "CloudServices: DataStorage (MediaFire)", - "id": "AI003500", - "description": "CloudServices: DataStorage (MediaFire)", - "applies_to": null, - "tags": [ - "CloudServices.DataStorage.MediaFire" - ], - "severity": "moderate", - "overrides": null, - "patterns": [ - { - "pattern": "MediaFire", - "type": "regex", - "modifiers": null, - "scopes": [ - "code" - ], - "confidence": "high" - } - ], - "conditions": [] - }, - { - "name": "Cloud Service: Azure (DataBricks)", - "id": "AI000400", - "description": "Cloud Service: DataBricks", - "applies_to": null, - "tags": [ - "CloudServices.BigData.Analytics.DataBricks", - "CloudServices.Hosting.Microsoft.Azure" - ], - "severity": "moderate", - "overrides": null, - "patterns": [ - { - "pattern": "\\b(\\.cloud\\.databricks\\.com)\\b", - "type": "regex", - "modifiers": [ - "i" - ], - "scopes": [ - "code" - ], - "confidence": "high" - } - ], - "conditions": [] - }, - { - "name": "Data: Serialization", - "id": "AI012100", - "description": "Data: Serialization", - "applies_to": [ - "python" - ], - "tags": [ - "Data.Serialization" - ], - "severity": "critical", - "overrides": null, - "patterns": [ - { - "pattern": "(de)?serialize", - "type": "regex", - "modifiers": null, - "scopes": [ - "code" - ], - "confidence": "medium" - } - ], - "conditions": [] - }, - { - "name": "Data: Serialization", - "id": "AI012200", - "description": "Data: Serialization", - "applies_to": [ - "python" - ], - "tags": [ - "Data.Serialization" - ], - "severity": "critical", - "overrides": null, - "patterns": [ - { - "pattern": "import .*c?pickle", - "type": "regex", - "modifiers": null, - "scopes": [ - "code" - ], - "confidence": "high" - } - ], - "conditions": [] - }, - { - "name": "Data: Serialization", - "id": "AI012300", - "description": "Data: Serialization", - "applies_to": [ - "python" - ], - "tags": [ - "Data.Serialization" - ], - "severity": "critical", - "overrides": null, - "patterns": [ - { - "pattern": "c?pickle\\.dump", - "type": "regex", - "modifiers": null, - "scopes": [ - "code" - ], - "confidence": "high" - } - ], - "conditions": [] - }, - { - "name": "Data: Deserialization", - "id": "AI012400", - "description": "Data: Deserialization", - "applies_to": [ - "python" - ], - "tags": [ - "Data.Deserialization" - ], - "severity": "critical", - "overrides": null, - "patterns": [ - { - "pattern": "c?pickle\\.load", - "type": "regex", - "modifiers": null, - "scopes": [ - "code" - ], - "confidence": "high" - } - ], - "conditions": [] - }, - { - "name": "Data: Deserialization", - "id": "AI012500", - "description": "Data: Deserialization", - "applies_to": [ - "java" - ], - "tags": [ - "Data.Deserialization" - ], - "severity": "critical", - "overrides": null, - "patterns": [ - { - "pattern": ".readObject", - "type": "regex", - "modifiers": null, - "scopes": [ - "code" - ], - "confidence": "high" - } - ], - "conditions": [] - }, - { - "name": "Data: Deserialization", - "id": "AI012600", - "description": "Data: Deserialization", - "applies_to": [ - "php" - ], - "tags": [ - "Data.Deserialization" - ], - "severity": "critical", - "overrides": null, - "patterns": [ - { - "pattern": "\\b(unserialize\\()\\b", - "type": "regex", - "modifiers": null, - "scopes": [ - "code" - ], - "confidence": "high" - } - ], - "conditions": [] - }, - { - "name": "Data: Deserialization", - "id": "AI012700", - "description": "Data: Deserialization", - "applies_to": [ - "ruby" - ], - "tags": [ - "Data.Deserialization" - ], - "severity": "critical", - "overrides": null, - "patterns": [ - { - "pattern": "(YAML|Syck|Marshal)\\.load", - "type": "regex", - "modifiers": null, - "scopes": [ - "code" - ], - "confidence": "high" - } - ], - "conditions": [] - }, - { - "name": "Data: Serialization", - "id": "AI012800", - "description": "Data: Serialization", - "applies_to": [ - "csharp" - ], - "tags": [ - "Data.Serialization" - ], - "severity": "critical", - "overrides": null, - "patterns": [ - { - "pattern": "\\b(SerializeObject|JavaScriptSerializer|Newtonsoft|json\\.net)\\b", - "type": "regex", - "modifiers": null, - "scopes": [ - "code" - ], - "confidence": "high" - } - ], - "conditions": [] - }, - { - "name": "Data: Deserialization", - "id": "AI012900", - "description": "Data: Deserialization", - "applies_to": [ - "csharp" - ], - "tags": [ - "Data.Deserialization" - ], - "severity": "critical", - "overrides": null, - "patterns": [ - { - "pattern": "\\b(DeserializeObject)\\b", - "type": "regex", - "modifiers": null, - "scopes": [ - "code" - ], - "confidence": "high" - }, - { - "pattern": "\\b(PopulateObject)\\b", - "type": "regex", - "modifiers": null, - "scopes": [ - "code" - ], - "confidence": "high" - }, - { - "pattern": "\\b(TypeNameHandling)\\b", - "type": "regex", - "modifiers": null, - "scopes": [ - "code" - ], - "confidence": "high" - } - ], - "conditions": [] - }, - { - "name": "Data: Deserialization", - "id": "AI013000", - "description": "Data: Deserialization", - "applies_to": [ - "csharp" - ], - "tags": [ - "Data.Deserialization" - ], - "severity": "critical", - "overrides": null, - "patterns": [ - { - "pattern": "\\b(System\\.Runtime\\.Serialization)\\b", - "type": "regex", - "modifiers": null, - "scopes": [ - "code" - ], - "confidence": "high" - }, - { - "pattern": "\\b(BinaryFormatter)\\b", - "type": "regex", - "modifiers": null, - "scopes": [ - "code" - ], - "confidence": "high" - }, - { - "pattern": "\\b(TypeNameHandling)\\b", - "type": "regex", - "modifiers": null, - "scopes": [ - "code" - ], - "confidence": "high" - } - ], - "conditions": [] - }, - { - "name": "Data: Bluetooth Serialization", - "id": "AI013100", - "description": "Data: Bluetooth Serialization", - "applies_to": null, - "tags": [ - "Data.Deserialization.Signal.Bluetooth" - ], - "severity": "critical", - "overrides": null, - "patterns": [ - { - "pattern": "\\b(Bluetooth)\\b", - "type": "regex", - "modifiers": [ - "i" - ], - "scopes": [ - "code" - ], - "confidence": "high" - } - ], - "conditions": [] - }, - { - "name": "Data: Cellular Serialization", - "id": "AI013200", - "description": "Data: Cellular Serialization", - "applies_to": null, - "tags": [ - "Data.Deserialization.Signal.Cellular" - ], - "severity": "critical", - "overrides": null, - "patterns": [ - { - "pattern": "\\b(Cellular)\\b", - "type": "regex", - "modifiers": [ - "i" - ], - "scopes": [ - "code" - ], - "confidence": "high" - } - ], - "conditions": [] - }, - { - "name": "Data: USB", - "id": "AI013300", - "description": "Data: USB Serialization", - "applies_to": null, - "tags": [ - "Data.Deserialization.Signal.USB" - ], - "severity": "critical", - "overrides": null, - "patterns": [ - { - "pattern": "\\b(USB)\\b", - "type": "regex", - "modifiers": [ - "i" - ], - "scopes": [ - "code" - ], - "confidence": "high" - } - ], - "conditions": [] - }, - { - "name": "Data: Ethernet", - "id": "AI013400", - "description": "Data: Ethernet Serialization", - "applies_to": null, - "tags": [ - "Data.Deserialization.Signal.Ethernet" - ], - "severity": "critical", - "overrides": null, - "patterns": [ - { - "pattern": "\\b(Ethernet)\\b", - "type": "regex", - "modifiers": [ - "i" - ], - "scopes": [ - "code" - ], - "confidence": "high" - } - ], - "conditions": [] - }, - { - "name": "Data: Modem", - "id": "AI013500", - "description": "Data: Modem Serialization", - "applies_to": null, - "tags": [ - "Data.Deserialization.Signal.Modem" - ], - "severity": "critical", - "overrides": null, - "patterns": [ - { - "pattern": "\\b(Modem)\\b", - "type": "regex", - "modifiers": [ - "i" - ], - "scopes": [ - "code" - ], - "confidence": "high" - } - ], - "conditions": [] - }, - { - "name": "Data: Parses XML", - "id": "AI014100", - "description": "Data: Parses XML", - "applies_to": null, - "tags": [ - "Data.Parsing.XML" - ], - "severity": "critical", - "overrides": null, - "patterns": [ - { - "pattern": "\\b(sax|xpath|xmldom|xelement|xmldocument)\\b", - "type": "regex", - "modifiers": null, - "scopes": [ - "code" - ], - "confidence": "high" - } - ], - "conditions": [] - }, - { - "name": "Data: Parses XML", - "id": "AI014200", - "description": "Data: Parses XML", - "applies_to": [ - "python" - ], - "tags": [ - "Data.Parsing.XML" - ], - "severity": "critical", - "overrides": null, - "patterns": [ - { - "pattern": "\\b(lxml|etree|ElementTree|minidom|pulldom|xmlrpc)\\b", - "type": "regex", - "modifiers": null, - "scopes": [ - "code" - ], - "confidence": "high" - } - ], - "conditions": [] - }, - { - "name": "Data: Parses XML", - "id": "AI014300", - "description": "Data: Parses XML", - "applies_to": [ - "javascript" - ], - "tags": [ - "Data.Parsing.XML" - ], - "severity": "critical", - "overrides": null, - "patterns": [ - { - "pattern": "\\b(parseFromString\\(.*,\"text/xml\"\\)|xhttp\\.responseXML)\\b", - "type": "regex", - "modifiers": null, - "scopes": [ - "code" - ], - "confidence": "high" - } - ], - "conditions": [] - }, - { - "name": "Data: Parses XML", - "id": "AI014400", - "description": "Data: Parses XML", - "applies_to": [ - "java" - ], - "tags": [ - "Data.Parsing.XML" - ], - "severity": "critical", - "overrides": null, - "patterns": [ - { - "pattern": "\\b(jdom2|SAXBuilder)\\b", - "type": "regex", - "modifiers": null, - "scopes": [ - "code" - ], - "confidence": "high" - } - ], - "conditions": [] - }, - { - "name": "Data: XSLT Transformations", - "id": "AI014500", - "description": "Data: XSLT Transformations", - "applies_to": [ - "csharp" - ], - "tags": [ - "Data.Parsing.XSLT" - ], - "severity": "critical", - "overrides": null, - "patterns": [ - { - "pattern": "XslTransform|System\\.Xml\\.Xsl|XslCompiledTransform|transformNode", - "type": "regex", - "modifiers": null, - "scopes": [ - "code" - ], - "confidence": "high" - } - ], - "conditions": [] - }, - { - "name": "Data: XSLT Transformations", - "id": "AI014600", - "description": "Data: XSLT Transformations", - "applies_to": [ - "java" - ], - "tags": [ - "Data.Parsing.XSLT" - ], - "severity": "critical", - "overrides": null, - "patterns": [ - { - "pattern": "TransformerFactory|XSLDocument|javax\\.xml\\.transform", - "type": "regex", - "modifiers": null, - "scopes": [ - "code" - ], - "confidence": "high" - } - ], - "conditions": [] - }, - { - "name": "Data: XSLT Transformations", - "id": "AI014700", - "description": "Data: XSLT Transformations", - "applies_to": [ - "javascript" - ], - "tags": [ - "Data.Parsing.XSLT" - ], - "severity": "critical", - "overrides": null, - "patterns": [ - { - "pattern": "XSLTProcessor", - "type": "regex", - "modifiers": null, - "scopes": [ - "code" - ], - "confidence": "high" - } - ], - "conditions": [] - }, - { - "name": "Data: XSLT Transformations", - "id": "AI014800", - "description": "Data: XSLT Transformations", - "applies_to": null, - "tags": [ - "Data.Parsing.XSLT" - ], - "severity": "critical", - "overrides": null, - "patterns": [ - { - "pattern": "\\.xslt", - "type": "regex", - "modifiers": null, - "scopes": [ - "code" - ], - "confidence": "high" - } - ], - "conditions": [] - }, - { - "name": "Data: XSLT Transformations", - "id": "AI014900", - "description": "Data: XSLT Transformations", - "applies_to": null, - "tags": [ - "Data.Parsing.XSLT" - ], - "severity": "critical", - "overrides": null, - "patterns": [ - { - "pattern": "\\b(xslt|xsl:stylesheet)\\b", - "type": "regex", - "modifiers": [ - "i" - ], - "scopes": [ - "code" - ], - "confidence": "high" - } - ], - "conditions": [] - }, - { - "name": "Data: Parses JSON", - "id": "AI013600", - "description": "Data: Parses JSON", - "applies_to": [ - "javascript" - ], - "tags": [ - "Data.Parsing.JSON" - ], - "severity": "moderate", - "overrides": null, - "patterns": [ - { - "pattern": "\\b(JSON\\.Parse)\\b", - "type": "regex", - "modifiers": null, - "scopes": [ - "code" - ], - "confidence": "high" - } - ], - "conditions": [] - }, - { - "name": "Data: Parses JSON", - "id": "AI013700", - "description": "Data: Parses JSON", - "applies_to": [ - "csharp" - ], - "tags": [ - "Data.Parsing.JSON" - ], - "severity": "moderate", - "overrides": null, - "patterns": [ - { - "pattern": "JSON\\.createParser|JObject\\.Parse", - "type": "regex", - "modifiers": null, - "scopes": [ - "code" - ], - "confidence": "high" - } - ], - "conditions": [] - }, - { - "name": "Data: Parses JSON", - "id": "AI013800", - "description": "Data: Parses JSON", - "applies_to": null, - "tags": [ - "Data.Parsing.JSON" - ], - "severity": "moderate", - "overrides": null, - "patterns": [ - { - "pattern": "json.*parser", - "type": "regex", - "modifiers": null, - "scopes": [ - "code" - ], - "confidence": "high" - } - ], - "conditions": [] - }, - { - "name": "Audio Video Media Codec", - "id": "AI013900", - "description": "Audio Video Media Codec", - "applies_to": null, - "tags": [ - "Data.Parsing.Media" - ], - "severity": "critical", - "overrides": null, - "patterns": [ - { - "pattern": "\\b(ffmpeg|libraw|webp|mux|DivX|XviDH.263|H.264|HEVC|MPEG4|Theora|3GP|Windows Media|JPEG 2000)\\b", - "type": "regex", - "modifiers": [ - "i" - ], - "scopes": [ - "code", - "comment" - ], - "confidence": "high" - }, - { - "pattern": "\\b(Quicktime|MPEG-4|VP8|VP6|MPEG1|MPEG2|MPEG-TS|MPEG-4|DNXHD|XDCAM|DVCPRO|IMX|XDCAM)\\b", - "type": "regex", - "modifiers": [ - "i" - ], - "scopes": [ - "code", - "comment" - ], - "confidence": "high" - } - ], - "conditions": [] - }, - { - "name": "Data: Compressed File (Zip,Tgz)", - "id": "AI010600", - "description": "Data: Compressed File Handling", - "applies_to": null, - "tags": [ - "Data.Zipfile" - ], - "severity": "moderate", - "overrides": null, - "patterns": [ - { - "pattern": "\\b(\\.(zip|gz|gzip|gem|tar|tgz|tar\\.gz|xz|7z))\\b", - "type": "regex", - "modifiers": [ - "i" - ], - "scopes": [ - "code", - "comment" - ], - "confidence": "high" - } - ], - "conditions": [] - }, - { - "name": "Data: ORM (SQL Alchemy)", - "id": "AI010700", - "description": "Data: ORM (SQL Alchemy)", - "applies_to": [ - "python" - ], - "tags": [ - "Data.DBMS.ORM.SQLAlchemy" - ], - "severity": "moderate", - "overrides": null, - "patterns": [ - { - "pattern": "\\b(sqlalchemy)\\b", - "type": "regex", - "modifiers": [ - "i" - ], - "scopes": [ - "code", - "comment" - ], - "confidence": "high" - } - ], - "conditions": [] - }, - { - "name": "Data: ORM (Django)", - "id": "AI010800", - "description": "Data: ORM (Django)", - "applies_to": [ - "python" - ], - "tags": [ - "Data.DBMS.ORM.Django" - ], - "severity": "moderate", - "overrides": null, - "patterns": [ - { - "pattern": "\\b(django)\\b", - "type": "regex", - "modifiers": [ - "i" - ], - "scopes": [ - "code", - "comment" - ], - "confidence": "medium" - } - ], - "conditions": [] - }, - { - "name": "Data: DBMS (SQLite)", - "id": "AI010900", - "description": "Data: DBMS (SQLite)", - "applies_to": [ - "python" - ], - "tags": [ - "Data.DBMS.SQLite" - ], - "severity": "moderate", - "overrides": null, - "patterns": [ - { - "pattern": "sqlite|python3-apsw", - "type": "regex", - "modifiers": null, - "scopes": [ - "code" - ], - "confidence": "high" - }, - { - "pattern": "\\b(apsw)\\b", - "type": "regex", - "modifiers": null, - "scopes": [ - "code" - ], - "confidence": "medium" - } - ], - "conditions": [] - }, - { - "name": "Data: DBMS (SQLite)", - "id": "AI010910", - "description": "Data: DBMS (SQLite)", - "applies_to": [ - "csharp" - ], - "tags": [ - "Data.DBMS.SQLite" - ], - "severity": "moderate", - "overrides": null, - "patterns": [ - { - "pattern": "SqliteCommand|SqliteConnection|System\\.Data\\.SQLite|Microsoft\\.Data\\.SQLite", - "type": "regex", - "modifiers": null, - "scopes": [ - "code" - ], - "confidence": "high" - } - ], - "conditions": [] - }, - { - "name": "Data: DBMS (SQLite)", - "id": "AI010920", - "description": "Data: DBMS (SQLite)", - "applies_to": [ - "java", - "objective-c", - "php", - "c", - "cpp" - ], - "tags": [ - "Data.DBMS.SQLite" - ], - "severity": "moderate", - "overrides": null, - "patterns": [ - { - "pattern": "sqlite", - "type": "regex", - "modifiers": null, - "scopes": [ - "code" - ], - "confidence": "high" - } - ], - "conditions": [] - }, - { - "name": "Data: DBMS (PostgreSQL)", - "id": "AI011000", - "description": "Data: DBMS (PostgreSQL)", - "applies_to": [ - "javascript" - ], - "tags": [ - "Data.DBMS.PostgreSQL" - ], - "severity": "moderate", - "overrides": null, - "patterns": [ - { - "pattern": "(pgsql|PG)\\.connect|PG::Connection", - "type": "regex", - "modifiers": [ - "i" - ], - "scopes": [ - "code" - ], - "confidence": "high" - } - ], - "conditions": [] - }, - { - "name": "Data: DBMS (PostgreSQL)", - "id": "AI011100", - "description": "Data: DBMS (PostgreSQL)", - "applies_to": [ - "python" - ], - "tags": [ - "Data.DBMS.PostgreSQL" - ], - "severity": "moderate", - "overrides": null, - "patterns": [ - { - "pattern": "\\b(psycopg2)\\b", - "type": "regex", - "modifiers": [ - "i" - ], - "scopes": [ - "code" - ], - "confidence": "high" - } - ], - "conditions": [] - }, - { - "name": "Data: DBMS (PostgreSQL)", - "id": "AI011200", - "description": "Data: DBMS (PostgreSQL)", - "applies_to": [ - "csharp" - ], - "tags": [ - "Data.DBMS.PostgreSQL" - ], - "severity": "moderate", - "overrides": null, - "patterns": [ - { - "pattern": "\\b(npgsql)\\b", - "type": "regex", - "modifiers": [ - "i" - ], - "scopes": [ - "code" - ], - "confidence": "high" - } - ], - "conditions": [] - }, - { - "name": "Data: DBMS (NoSQL)", - "id": "AI011300", - "description": "Data: DBMS (NoSQL)", - "applies_to": null, - "tags": [ - "Data.DBMS.NoSQL" - ], - "severity": "moderate", - "overrides": null, - "patterns": [ - { - "pattern": "\\b(mongodb|mongoose|mongoclient|pymongo|redis|hbase|neo4j|cassandra|couchbase|memcached|couchdb|litedb|LiteDatabase|tinydb)\\b", - "type": "regex", - "modifiers": [ - "i" - ], - "scopes": [ - "code" - ], - "confidence": "high" - } - ], - "conditions": [] - }, - { - "name": "Data: DBMS (SQL)", - "id": "AI011400", - "description": "Data: DBMS SQL", - "applies_to": [ - "java" - ], - "tags": [ - "Data.DBMS.SQL" - ], - "severity": "moderate", - "overrides": null, - "patterns": [ - { - "pattern": "\\b(import\\ java\\.sql)\\b", - "type": "regex", - "modifiers": [ - "i" - ], - "scopes": [ - "code" - ], - "confidence": "high" - } - ], - "conditions": [] - }, - { - "name": "Data: DBMS (SQL)", - "id": "AI011500", - "description": "Data: DBMS (SQL)", - "applies_to": [ - "csharp" - ], - "tags": [ - "Data.DBMS.SQL" - ], - "severity": "moderate", - "overrides": null, - "patterns": [ - { - "pattern": "\\b(using\\ system\\.data\\.sqlclient)\\b", - "type": "regex", - "modifiers": [ - "i" - ], - "scopes": [ - "code" - ], - "confidence": "high" - } - ], - "conditions": [] - }, - { - "name": "Data: DBMS (SQL)", - "id": "AI011600", - "description": "Data: DBMS (SQL)", - "applies_to": [], - "tags": [ - "Data.DBMS.SQL" - ], - "severity": "moderate", - "overrides": null, - "patterns": [ - { - "pattern": "['\\\"](select|insert|delete|update)\\s.*", - "type": "regex", - "modifiers": [ - "i" - ], - "scopes": [ - "code" - ], - "confidence": "high" - } - ], - "conditions": [ - { - "pattern": { - "pattern": "\\b(from|where)\\b", - "type": "regex", - "modifiers": [ - "i" - ], - "scopes": [ - "code" - ], - "confidence": "medium" - }, - "search_in": "finding-region(-5,5)", - "negate_finding": false - } - ] - }, - { - "name": "Data: DBMS (SQL)", - "id": "AI011610", - "description": "Data: DBMS (SQL)", - "applies_to": [], - "tags": [ - "Data.DBMS.SQL" - ], - "severity": "moderate", - "overrides": null, - "patterns": [ - { - "pattern": "\\b(mysql)\\b", - "type": "regex", - "modifiers": [ - "i" - ], - "scopes": [ - "code", - "comment" - ], - "confidence": "high" - } - ], - "conditions": [] - }, - { - "name": "Data: DBMS (Oracle)", - "id": "AI011700", - "description": "Data: DBMS (Oracle)", - "applies_to": [ - "java", - "pom" - ], - "tags": [ - "Data.DBMS.SQL.Oracle" - ], - "severity": "moderate", - "overrides": null, - "patterns": [ - { - "pattern": "oracle\\.jdbc|oracledriver|com.oracle", - "type": "regex", - "modifiers": [ - "i" - ], - "scopes": [ - "code" - ], - "confidence": "high" - }, - { - "pattern": "\\b(oracle)\\b", - "type": "regex", - "modifiers": [ - "i" - ], - "scopes": [ - "code" - ], - "confidence": "medium" - } - ], - "conditions": [] - }, - { - "name": "Data: DBMS (Oracle)", - "id": "AI011800", - "description": "Data: DBMS (Oracle)", - "applies_to": [ - "python" - ], - "tags": [ - "Data.DBMS.SQL.Oracle" - ], - "severity": "moderate", - "overrides": null, - "patterns": [ - { - "pattern": "import cx_Oracle", - "type": "regex", - "modifiers": [ - "i" - ], - "scopes": [ - "code" - ], - "confidence": "high" - }, - { - "pattern": "\\b(oracle)\\b", - "type": "regex", - "modifiers": [ - "i" - ], - "scopes": [ - "code" - ], - "confidence": "medium" - } - ], - "conditions": [] - }, - { - "name": "Data: DBMS (General)", - "id": "AI011900", - "description": "Data: DBMS (General)", - "applies_to": [ - "csharp", - "c++", - "java", - "python", - "objective-c", - "go" - ], - "tags": [ - "Data.DBMS.General" - ], - "severity": "moderate", - "overrides": null, - "patterns": [ - { - "pattern": "\\b(database)\\b", - "type": "regex", - "modifiers": null, - "scopes": [ - "code", - "comment" - ], - "confidence": "high" - } - ], - "conditions": [] - }, - { - "name": "Data: ODBC", - "id": "AI012000", - "description": "Data: ODBC", - "applies_to": [ - "csharp" - ], - "tags": [ - "Data.DBMS.Connection.ODBC" - ], - "severity": "moderate", - "overrides": null, - "patterns": [ - { - "pattern": "\\b(OdbcConnection|OdbcCommand|OdbcDataReader)\\b", - "type": "regex", - "modifiers": null, - "scopes": [ - "code" - ], - "confidence": "high" - } - ], - "conditions": [] - }, - { - "name": "Data: ODBC", - "id": "AI012010", - "description": "Data: ODBC", - "applies_to": [ - "csharp", - "c++", - "java", - "python", - "objective-c", - "go" - ], - "tags": [ - "Data.DBMS.Connection.ODBC" - ], - "severity": "moderate", - "overrides": null, - "patterns": [ - { - "pattern": "\\b(Odbc)\\b", - "type": "regex", - "modifiers": null, - "scopes": [ - "code" - ], - "confidence": "high" - } - ], - "conditions": [] - }, - { - "name": "CloudServices: DataStorage (PasteBin or Similar)", - "id": "AI014000", - "description": "CloudServices: DataStorage (PasteBin or Similar)", - "applies_to": null, - "tags": [ - "CloudServices.DataStorage.PasteBin" - ], - "severity": "moderate", - "overrides": null, - "patterns": [ - { - "pattern": "pastebin|zerobin|ghostbin|hastebin", - "type": "regex", - "modifiers": [ - "i" - ], - "scopes": [ - "code", - "comment" - ], - "confidence": "high" - } - ], - "conditions": [] - }, - { - "name": "Development Framework: Spring", - "id": "AI018200", - "description": "Development Framework: Spring", - "applies_to": [ - "java" - ], - "tags": [ - "Framework.Development.Spring" - ], - "severity": "moderate", - "overrides": null, - "patterns": [ - { - "pattern": "\\b(springframework)\\b", - "type": "regex", - "modifiers": [], - "scopes": [ - "code" - ], - "confidence": "high" - } - ], - "conditions": [] - }, - { - "name": "Development Framework: Hibernate", - "id": "AI018300", - "description": "Development Framework: Hibernate", - "applies_to": [ - "java" - ], - "tags": [ - "Framework.Development.Hibernate" - ], - "severity": "moderate", - "overrides": null, - "patterns": [ - { - "pattern": "\\b(hibernate)\\b", - "type": "regex", - "modifiers": [], - "scopes": [ - "code" - ], - "confidence": "high" - } - ], - "conditions": [] - }, - { - "name": "Development Framework: Blade", - "id": "AI018400", - "description": "Development Framework: Blade", - "applies_to": [ - "java" - ], - "tags": [ - "Framework.Development.Blade" - ], - "severity": "moderate", - "overrides": null, - "patterns": [ - { - "pattern": "\\b(blade)\\b", - "type": "regex", - "modifiers": [], - "scopes": [ - "code" - ], - "confidence": "high" - } - ], - "conditions": [] - }, - { - "name": "Development Framework: DropWizard", - "id": "AI018500", - "description": "Development Framework: DropWizard", - "applies_to": [ - "java" - ], - "tags": [ - "Framework.Development.DropWizard" - ], - "severity": "moderate", - "overrides": null, - "patterns": [ - { - "pattern": "\\b(dropwizard)\\b", - "type": "regex", - "modifiers": [ - "i" - ], - "scopes": [ - "code" - ], - "confidence": "high" - } - ], - "conditions": [] - }, - { - "name": "Development Framework: GWT", - "id": "AI018600", - "description": "Development Framework: GWT", - "applies_to": [ - "java" - ], - "tags": [ - "Framework.Development.GWT" - ], - "severity": "moderate", - "overrides": null, - "patterns": [ - { - "pattern": "\\b(gwt)\\b", - "type": "regex", - "modifiers": [], - "scopes": [ - "code" - ], - "confidence": "high" - } - ], - "conditions": [] - }, - { - "name": "Development Framework: JSF", - "id": "AI018700", - "description": "Development Framework: JSF", - "applies_to": [ - "java" - ], - "tags": [ - "Framework.Development.JSF" - ], - "severity": "moderate", - "overrides": null, - "patterns": [ - { - "pattern": "\\b(jsf)\\b", - "type": "regex", - "modifiers": [], - "scopes": [ - "code" - ], - "confidence": "high" - } - ], - "conditions": [] - }, - { - "name": "Development Framework: JHipster", - "id": "AI018800", - "description": "Development Framework: JHipster", - "applies_to": [ - "java" - ], - "tags": [ - "Framework.Development.JHipster" - ], - "severity": "moderate", - "overrides": null, - "patterns": [ - { - "pattern": "\\b(jhipster)\\b", - "type": "regex", - "modifiers": [ - "i" - ], - "scopes": [ - "code" - ], - "confidence": "high" - } - ], - "conditions": [] - }, - { - "name": "Development Framework: MyBatis", - "id": "AI018900", - "description": "Development Framework: MyBatis", - "applies_to": [ - "java" - ], - "tags": [ - "Framework.Development.MyBatis" - ], - "severity": "moderate", - "overrides": null, - "patterns": [ - { - "pattern": "\\b(mybatis)\\b", - "type": "regex", - "modifiers": [ - "i" - ], - "scopes": [ - "code" - ], - "confidence": "high" - } - ], - "conditions": [] - }, - { - "name": "Development Framework: Play Framework", - "id": "AI019000", - "description": "Development Framework: Play Framework", - "applies_to": [ - "java" - ], - "tags": [ - "Framework.Development.PlayFramework" - ], - "severity": "moderate", - "overrides": null, - "patterns": [ - { - "pattern": "\\b(import\\ play\\.)\\b", - "type": "regex", - "modifiers": [], - "scopes": [ - "code" - ], - "confidence": "high" - } - ], - "conditions": [] - }, - { - "name": "Development Framework: PrimeFaces", - "id": "AI019100", - "description": "Development Framework: PrimeFaces", - "applies_to": [ - "java" - ], - "tags": [ - "Framework.Development.PrimeFaces" - ], - "severity": "moderate", - "overrides": null, - "patterns": [ - { - "pattern": "\\b(primefaces)\\b", - "type": "regex", - "modifiers": [ - "i" - ], - "scopes": [ - "code" - ], - "confidence": "high" - } - ], - "conditions": [] - }, - { - "name": "Development Framework: Spark", - "id": "AI019200", - "description": "Development Framework: Spark", - "applies_to": [ - "java" - ], - "tags": [ - "Framework.Development.Spark" - ], - "severity": "moderate", - "overrides": null, - "patterns": [ - { - "pattern": "\\b(import\\ spark\\.)\\b", - "type": "regex", - "modifiers": [], - "scopes": [ - "code" - ], - "confidence": "high" - } - ], - "conditions": [] - }, - { - "name": "Development Framework: Apache Struts", - "id": "AI019300", - "description": "Development Framework: Apache Struts", - "applies_to": [ - "java" - ], - "tags": [ - "Framework.Development.ApacheStruts" - ], - "severity": "moderate", - "overrides": null, - "patterns": [ - { - "pattern": "\\b(struts)\\b", - "type": "regex", - "modifiers": [], - "scopes": [ - "code" - ], - "confidence": "high" - } - ], - "conditions": [] - }, - { - "name": "Development Framework: Apache Tapestry", - "id": "AI019400", - "description": "Development Framework: Apache Tapestry", - "applies_to": [ - "java" - ], - "tags": [ - "Framework.Development.ApacheTapestry" - ], - "severity": "moderate", - "overrides": null, - "patterns": [ - { - "pattern": "\\b(tapestry)\\b", - "type": "regex", - "modifiers": [], - "scopes": [ - "code" - ], - "confidence": "high" - } - ], - "conditions": [] - }, - { - "name": "Development Framework: Vaadin", - "id": "AI019500", - "description": "Development Framework: Vaadin", - "applies_to": [ - "java" - ], - "tags": [ - "Framework.Development.Vaadin" - ], - "severity": "moderate", - "overrides": null, - "patterns": [ - { - "pattern": "\\b(vaadin)\\b", - "type": "regex", - "modifiers": [], - "scopes": [ - "code" - ], - "confidence": "high" - } - ], - "conditions": [] - }, - { - "name": "Development Framework: Vert.x", - "id": "AI019600", - "description": "Development Framework: Vert.x", - "applies_to": [ - "java" - ], - "tags": [ - "Framework.Development.Vertx" - ], - "severity": "moderate", - "overrides": null, - "patterns": [ - { - "pattern": "\\b(vert\\.x)\\b", - "type": "regex", - "modifiers": [ - "i" - ], - "scopes": [ - "code" - ], - "confidence": "high" - } - ], - "conditions": [] - }, - { - "name": "Development Framework: Wicket", - "id": "AI019700", - "description": "Development Framework: Wicket", - "applies_to": [ - "java" - ], - "tags": [ - "Framework.Development.Wicket" - ], - "severity": "moderate", - "overrides": null, - "patterns": [ - { - "pattern": "\\b(wicket)\\b", - "type": "regex", - "modifiers": [ - "i" - ], - "scopes": [ - "code" - ], - "confidence": "high" - } - ], - "conditions": [] - }, - { - "name": "Development Framework: Google API's", - "id": "AI019800", - "description": "Development Framework: Google API's", - "applies_to": [ - "java" - ], - "tags": [ - "Framework.Development.Google.API" - ], - "severity": "moderate", - "overrides": null, - "patterns": [ - { - "pattern": "googleapis", - "type": "regex", - "modifiers": [ - "i" - ], - "scopes": [ - "code" - ], - "confidence": "high" - } - ], - "conditions": [] - }, - { - "name": "Development Framework: Django", - "id": "AI023800", - "description": "Development Framework: Django", - "applies_to": [ - "python" - ], - "tags": [ - "Framework.Development.Django" - ], - "severity": "moderate", - "overrides": null, - "patterns": [ - { - "pattern": "\\b(django)\\b", - "type": "regex", - "modifiers": [ - "i" - ], - "scopes": [ - "code" - ], - "confidence": "high" - } - ], - "conditions": [] - }, - { - "name": "Development Framework: Pyramid", - "id": "AI023900", - "description": "Development Framework: Pyramid", - "applies_to": [ - "python" - ], - "tags": [ - "Framework.Development.Pyramid" - ], - "severity": "moderate", - "overrides": null, - "patterns": [ - { - "pattern": "\\b(pyramid)\\b", - "type": "regex", - "modifiers": [ - "i" - ], - "scopes": [ - "code" - ], - "confidence": "high" - } - ], - "conditions": [] - }, - { - "name": "Development Framework: Web2Py", - "id": "AI024000", - "description": "Development Framework: Web2Py", - "applies_to": [ - "python" - ], - "tags": [ - "Framework.Development.Web2Py" - ], - "severity": "moderate", - "overrides": null, - "patterns": [ - { - "pattern": "\\b(web2py)\\b", - "type": "regex", - "modifiers": [ - "i" - ], - "scopes": [ - "code" - ], - "confidence": "high" - } - ], - "conditions": [] - }, - { - "name": "Development Framework: CubicWeb", - "id": "AI024100", - "description": "Development Framework: CubicWeb", - "applies_to": [ - "python" - ], - "tags": [ - "Framework.Development.CubicWeb" - ], - "severity": "moderate", - "overrides": null, - "patterns": [ - { - "pattern": "\\b(cubicweb)\\b", - "type": "regex", - "modifiers": [ - "i" - ], - "scopes": [ - "code" - ], - "confidence": "high" - } - ], - "conditions": [] - }, - { - "name": "Development Framework: OWL", - "id": "AI024200", - "description": "Development Framework: OWL", - "applies_to": [ - "python" - ], - "tags": [ - "Framework.Development.OWL" - ], - "severity": "moderate", - "overrides": null, - "patterns": [ - { - "pattern": "\\b(owlready)\\b", - "type": "regex", - "modifiers": [ - "i" - ], - "scopes": [ - "code" - ], - "confidence": "high" - } - ], - "conditions": [] - }, - { - "name": "Development Framework: RDF", - "id": "AI024300", - "description": "Development Framework: RDF", - "applies_to": [ - "python" - ], - "tags": [ - "Framework.Development.RDF" - ], - "severity": "moderate", - "overrides": null, - "patterns": [ - { - "pattern": "\\b(rdflib)\\b", - "type": "regex", - "modifiers": [ - "i" - ], - "scopes": [ - "code" - ], - "confidence": "high" - } - ], - "conditions": [] - }, - { - "name": "Development Framework: RQL", - "id": "AI024400", - "description": "Development Framework: RQL", - "applies_to": [ - "python" - ], - "tags": [ - "Framework.Development.RQL" - ], - "severity": "moderate", - "overrides": null, - "patterns": [ - { - "pattern": "\\b(rql)\\b", - "type": "regex", - "modifiers": [ - "i" - ], - "scopes": [ - "code" - ], - "confidence": "high" - } - ], - "conditions": [] - }, - { - "name": "Development Framework: Flask", - "id": "AI024500", - "description": "Development Framework: Flask", - "applies_to": [ - "python" - ], - "tags": [ - "Framework.Development.Flask" - ], - "severity": "moderate", - "overrides": null, - "patterns": [ - { - "pattern": "\\b(flask)\\b", - "type": "regex", - "modifiers": [ - "i" - ], - "scopes": [ - "code" - ], - "confidence": "high" - } - ], - "conditions": [] - }, - { - "name": "Development Framework: Bottle", - "id": "AI024600", - "description": "Development Framework: Bottle", - "applies_to": [ - "python" - ], - "tags": [ - "Framework.Development.Bottle" - ], - "severity": "moderate", - "overrides": null, - "patterns": [ - { - "pattern": "\\b(bottle)\\b", - "type": "regex", - "modifiers": [ - "i" - ], - "scopes": [ - "code" - ], - "confidence": "high" - } - ], - "conditions": [] - }, - { - "name": "Development Framework: CherryPy", - "id": "AI024700", - "description": "Development Framework: CherryPy", - "applies_to": [ - "python" - ], - "tags": [ - "Framework.Development.CherryPy" - ], - "severity": "moderate", - "overrides": null, - "patterns": [ - { - "pattern": "\\b(cherrypy)\\b", - "type": "regex", - "modifiers": [ - "i" - ], - "scopes": [ - "code" - ], - "confidence": "high" - } - ], - "conditions": [] - }, - { - "name": "Development Framework: Sanic", - "id": "AI024800", - "description": "Development Framework: Sanic", - "applies_to": [ - "python" - ], - "tags": [ - "Framework.Development.Sanic" - ], - "severity": "moderate", - "overrides": null, - "patterns": [ - { - "pattern": "\\b(sanic)\\b", - "type": "regex", - "modifiers": [ - "i" - ], - "scopes": [ - "code" - ], - "confidence": "high" - } - ], - "conditions": [] - }, - { - "name": "Development Framework: Tornado", - "id": "AI024900", - "description": "Development Framework: Tornado", - "applies_to": [ - "python" - ], - "tags": [ - "Framework.Development.Tornado" - ], - "severity": "moderate", - "overrides": null, - "patterns": [ - { - "pattern": "\\b(tornado)\\b", - "type": "regex", - "modifiers": [ - "i" - ], - "scopes": [ - "code" - ], - "confidence": "high" - } - ], - "conditions": [] - }, - { - "name": "Development Framework: TurboGears", - "id": "AI025000", - "description": "Development Framework: TurboGears", - "applies_to": [ - "python", - "requirements.txt" - ], - "tags": [ - "Framework.Development.TurboGears" - ], - "severity": "moderate", - "overrides": null, - "patterns": [ - { - "pattern": "TGController|TurboGears2", - "type": "regex", - "modifiers": [ - "i" - ], - "scopes": [ - "code" - ], - "confidence": "high" - } - ], - "conditions": [] - }, - { - "name": "Development Framework: Giotto", - "id": "AI025100", - "description": "Development Framework: Giotto", - "applies_to": [ - "python" - ], - "tags": [ - "Framework.Development.Giotto" - ], - "severity": "moderate", - "overrides": null, - "patterns": [ - { - "pattern": "\\b(giotto)\\b", - "type": "regex", - "modifiers": [ - "i" - ], - "scopes": [ - "code" - ], - "confidence": "high" - } - ], - "conditions": [] - }, - { - "name": "Development Framework: Pylons", - "id": "AI025200", - "description": "Development Framework: Pylons", - "applies_to": [ - "python" - ], - "tags": [ - "Framework.Development.Pylons" - ], - "severity": "moderate", - "overrides": null, - "patterns": [ - { - "pattern": "\\b(pylons)\\b", - "type": "regex", - "modifiers": [ - "i" - ], - "scopes": [ - "code" - ], - "confidence": "high" - } - ], - "conditions": [] - }, - { - "name": "Development Framework: Google API's", - "id": "AI025300", - "description": "Development Framework: Google API's", - "applies_to": [ - "python" - ], - "tags": [ - "Framework.Development.Google.API" - ], - "severity": "moderate", - "overrides": null, - "patterns": [ - { - "pattern": "googleapis|googleapiclient", - "type": "regex", - "modifiers": [ - "i" - ], - "scopes": [ - "code" - ], - "confidence": "high" - } - ], - "conditions": [] - }, - { - "name": "Development Framework: Angular.JS", - "id": "AI019900", - "description": "Development Framework: Angular.JS", - "applies_to": [ - "javascript" - ], - "tags": [ - "Framework.Development.AngularJS" - ], - "severity": "moderate", - "overrides": null, - "patterns": [ - { - "pattern": "Angular", - "type": "regex", - "modifiers": [ - "i" - ], - "scopes": [ - "code" - ], - "confidence": "high" - } - ], - "conditions": [] - }, - { - "name": "Development Framework: Vue", - "id": "AI020000", - "description": "Development Framework: Vue", - "applies_to": [ - "javascript" - ], - "tags": [ - "Framework.Development.Vue" - ], - "severity": "moderate", - "overrides": null, - "patterns": [ - { - "pattern": "\\b(Vue)\\b", - "type": "regex", - "modifiers": [ - "i" - ], - "scopes": [ - "code" - ], - "confidence": "high" - } - ], - "conditions": [] - }, - { - "name": "Development Framework: EmberJS", - "id": "AI020100", - "description": "Development Framework: EmberJS", - "applies_to": [ - "javascript" - ], - "tags": [ - "Framework.Development.EmberJS" - ], - "severity": "moderate", - "overrides": null, - "patterns": [ - { - "pattern": "\\b(Ember)\\b", - "type": "regex", - "modifiers": [ - "i" - ], - "scopes": [ - "code" - ], - "confidence": "high" - } - ], - "conditions": [] - }, - { - "name": "Development Framework: Backbone", - "id": "AI020200", - "description": "Development Framework: Backbone", - "applies_to": [ - "javascript" - ], - "tags": [ - "Framework.Development.Backbone" - ], - "severity": "moderate", - "overrides": null, - "patterns": [ - { - "pattern": "\\b(backbone)\\b", - "type": "regex", - "modifiers": [ - "i" - ], - "scopes": [ - "code" - ], - "confidence": "medium" - } - ], - "conditions": [] - }, - { - "name": "Development Framework: jQuery", - "id": "AI020300", - "description": "Development Framework: jQuery", - "applies_to": [ - "javascript" - ], - "tags": [ - "Framework.Development.jQuery" - ], - "severity": "moderate", - "overrides": null, - "patterns": [ - { - "pattern": "\\b(jquery)\\b", - "type": "regex", - "modifiers": [ - "i" - ], - "scopes": [ - "code" - ], - "confidence": "high" - } - ], - "conditions": [] - }, - { - "name": "Development Framework: Redux", - "id": "AI020400", - "description": "Development Framework: Redux", - "applies_to": [ - "javascript" - ], - "tags": [ - "Framework.Development.Redux" - ], - "severity": "moderate", - "overrides": null, - "patterns": [ - { - "pattern": "\\b(redux)\\b", - "type": "regex", - "modifiers": [ - "i" - ], - "scopes": [ - "code" - ], - "confidence": "high" - } - ], - "conditions": [] - }, - { - "name": "Development Framework: Redux-Saga", - "id": "AI020500", - "description": "Development Framework: Redux-Saga", - "applies_to": [ - "javascript" - ], - "tags": [ - "Framework.Development.Redux-Saga" - ], - "severity": "moderate", - "overrides": null, - "patterns": [ - { - "pattern": "\\b(redux-saga)\\b", - "type": "regex", - "modifiers": [ - "i" - ], - "scopes": [ - "code" - ], - "confidence": "high" - } - ], - "conditions": [] - }, - { - "name": "Development Framework: React", - "id": "AI020600", - "description": "Development Framework: React", - "applies_to": [ - "javascript" - ], - "tags": [ - "Framework.Development.React" - ], - "severity": "moderate", - "overrides": null, - "patterns": [ - { - "pattern": "\\b(react)\\b", - "type": "regex", - "modifiers": [ - "i" - ], - "scopes": [ - "all" - ], - "confidence": "high" - } - ], - "conditions": [] - }, - { - "name": "Development Framework: RITEWay", - "id": "AI020700", - "description": "Development Framework: RITEWay", - "applies_to": [ - "javascript" - ], - "tags": [ - "Framework.Development.RITEWay" - ], - "severity": "moderate", - "overrides": null, - "patterns": [ - { - "pattern": "\\b(riteway)\\b", - "type": "regex", - "modifiers": [ - "i" - ], - "scopes": [ - "code" - ], - "confidence": "high" - } - ], - "conditions": [] - }, - { - "name": "Development Framework: Meteor", - "id": "AI020800", - "description": "Development Framework: Meteor", - "applies_to": [ - "javascript" - ], - "tags": [ - "Framework.Development.Meteor" - ], - "severity": "moderate", - "overrides": null, - "patterns": [ - { - "pattern": "\\b(meteor)\\b", - "type": "regex", - "modifiers": [ - "i" - ], - "scopes": [ - "code" - ], - "confidence": "high" - } - ], - "conditions": [] - }, - { - "name": "Development Framework: Mithril", - "id": "AI020900", - "description": "Development Framework: Mithril", - "applies_to": [ - "javascript" - ], - "tags": [ - "Framework.Development.Mithril" - ], - "severity": "moderate", - "overrides": null, - "patterns": [ - { - "pattern": "\\b(mithril)\\b", - "type": "regex", - "modifiers": [ - "i" - ], - "scopes": [ - "code" - ], - "confidence": "medium" - } - ], - "conditions": [] - }, - { - "name": "Development Framework: Polymer", - "id": "AI021000", - "description": "Development Framework: Polymer", - "applies_to": [ - "javascript" - ], - "tags": [ - "Framework.Development.Polymer" - ], - "severity": "moderate", - "overrides": null, - "patterns": [ - { - "pattern": "\\b(polymer)\\b", - "type": "regex", - "modifiers": [ - "i" - ], - "scopes": [ - "code" - ], - "confidence": "high" - } - ], - "conditions": [] - }, - { - "name": "Development Framework: Aurelia", - "id": "AI021100", - "description": "Development Framework: Aurelia", - "applies_to": [ - "javascript" - ], - "tags": [ - "Framework.Development.Aurelia" - ], - "severity": "moderate", - "overrides": null, - "patterns": [ - { - "pattern": "\\b(aurelia)\\b", - "type": "regex", - "modifiers": [ - "i" - ], - "scopes": [ - "code" - ], - "confidence": "high" - } - ], - "conditions": [] - }, - { - "name": "Content Management Framework: Wordpress", - "id": "AI021200", - "description": "Development Framework: Wordpress", - "applies_to": [ - "javascript", - "html" - ], - "tags": [ - "Framework.CMS.Wordpress" - ], - "severity": "moderate", - "overrides": null, - "patterns": [ - { - "pattern": "\\b(wordpress)\\b", - "type": "regex", - "modifiers": [ - "i" - ], - "scopes": [ - "code", - "comment" - ], - "confidence": "high" - } - ], - "conditions": [] - }, - { - "name": "Content Management Framework: Drupal", - "id": "AI021300", - "description": "Development Framework: Drupal", - "applies_to": [ - "javascript", - "html" - ], - "tags": [ - "Framework.CMS.Drupal" - ], - "severity": "moderate", - "overrides": null, - "patterns": [ - { - "pattern": "\\b(drupal)\\b", - "type": "regex", - "modifiers": [ - "i" - ], - "scopes": [ - "code", - "comment" - ], - "confidence": "high" - } - ], - "conditions": [] - }, - { - "name": "Content Management Framework: Sharepoint", - "id": "AI021400", - "description": "Development Framework: Sharepoint", - "applies_to": [ - "javascript", - "html" - ], - "tags": [ - "Framework.CMS.Sharepoint" - ], - "severity": "moderate", - "overrides": null, - "patterns": [ - { - "pattern": "\\b(sharepoint)\\b", - "type": "regex", - "modifiers": [ - "i" - ], - "scopes": [ - "code", - "comment" - ], - "confidence": "high" - } - ], - "conditions": [] - }, - { - "name": "Content Management Framework: Joomla", - "id": "AI021500", - "description": "Development Framework: Joomla", - "applies_to": [ - "javascript", - "html" - ], - "tags": [ - "Framework.CMS.Joomla" - ], - "severity": "moderate", - "overrides": null, - "patterns": [ - { - "pattern": "\\b(joomla)\\b", - "type": "regex", - "modifiers": [ - "i" - ], - "scopes": [ - "code", - "comment" - ], - "confidence": "high" - } - ], - "conditions": [] - }, - { - "name": "Development Framework: Google API's", - "id": "AI021600", - "description": "Development Framework: Google API's", - "applies_to": [ - "javascript" - ], - "tags": [ - "Framework.Development.Google.API" - ], - "severity": "moderate", - "overrides": null, - "patterns": [ - { - "pattern": "apis\\.google\\.com/js/api\\.js", - "type": "regex", - "modifiers": [ - "i" - ], - "scopes": [ - "code" - ], - "confidence": "high" - } - ], - "conditions": [] - }, - { - "name": "Development Framework: Node", - "id": "AI021610", - "description": "Development Framework: Node", - "applies_to": [ - "javascript" - ], - "tags": [ - "Metadata.Application.Type.Web.Service" - ], - "severity": "moderate", - "overrides": null, - "patterns": [ - { - "pattern": "app\\.listen|server\\.listen", - "type": "regex", - "modifiers": [ - "i" - ], - "scopes": [ - "code" - ], - "confidence": "high" - }, - { - "pattern": "\\.listen\\(", - "type": "regex", - "modifiers": [ - "i" - ], - "scopes": [ - "code" - ], - "confidence": "medium" - } - ], - "conditions": [] - }, - { - "name": "Development Framework: Google API's", - "id": "AI018100", - "description": "Development Framework: Google API's", - "applies_to": [ - "csharp" - ], - "tags": [ - "Framework.Development.Google.API" - ], - "severity": "moderate", - "overrides": null, - "patterns": [ - { - "pattern": "using Google.Apis", - "type": "regex", - "modifiers": [ - "i" - ], - "scopes": [ - "code" - ], - "confidence": "high" - } - ], - "conditions": [] - }, - { - "name": "Framework: Logging (Log4J)", - "id": "AI021700", - "description": "Framework: Logging (Log4J)", - "applies_to": [ - "java" - ], - "tags": [ - "Framework.Development.Logging.Log4j" - ], - "severity": "moderate", - "overrides": null, - "patterns": [ - { - "pattern": "\\b(log4j)\\b", - "type": "regex", - "modifiers": null, - "scopes": [ - "code" - ], - "confidence": "high" - } - ], - "conditions": [] - }, - { - "name": "Framework: Logging (NLog)", - "id": "AI021800", - "description": "Framework: Logging (NLog)", - "applies_to": [ - "csharp" - ], - "tags": [ - "Framework.Development.Logging.NLog" - ], - "severity": "moderate", - "overrides": null, - "patterns": [ - { - "pattern": "\\b(nlog)\\b", - "type": "regex", - "modifiers": null, - "scopes": [ - "code" - ], - "confidence": "high" - } - ], - "conditions": [] - }, - { - "name": "Framework: Logging (Serilog)", - "id": "AI021900", - "description": "Framework: Logging (Serilog)", - "applies_to": [ - "csharp" - ], - "tags": [ - "Framework.Development.Logging.Serilog" - ], - "severity": "moderate", - "overrides": null, - "patterns": [ - { - "pattern": "\\b(serilog)\\b", - "type": "regex", - "modifiers": null, - "scopes": [ - "code" - ], - "confidence": "high" - } - ], - "conditions": [] - }, - { - "name": "Framework: Logging (log4net)", - "id": "AI022000", - "description": "Framework: Logging (log4net)", - "applies_to": [ - "csharp" - ], - "tags": [ - "Framework.Development.Logging.Log4Net" - ], - "severity": "moderate", - "overrides": null, - "patterns": [ - { - "pattern": "\\b(log4net)\\b", - "type": "regex", - "modifiers": null, - "scopes": [ - "code" - ], - "confidence": "high" - } - ], - "conditions": [] - }, - { - "name": "Framework: Logging (ulog)", - "id": "AI022100", - "description": "Framework: Logging (ulog)", - "applies_to": [ - "csharp" - ], - "tags": [ - "Framework.Development.Logging.ULog" - ], - "severity": "moderate", - "overrides": null, - "patterns": [ - { - "pattern": "\\b(ulog)\\b", - "type": "regex", - "modifiers": null, - "scopes": [ - "code" - ], - "confidence": "high" - } - ], - "conditions": [] - }, - { - "name": "Framework: Logging (Winston)", - "id": "AI022200", - "description": "Framework: Logging (Winston)", - "applies_to": [ - "csharp" - ], - "tags": [ - "Framework.Development.Logging.Winston" - ], - "severity": "moderate", - "overrides": null, - "patterns": [ - { - "pattern": "\\b(winston)\\b", - "type": "regex", - "modifiers": null, - "scopes": [ - "code" - ], - "confidence": "high" - } - ], - "conditions": [] - }, - { - "name": "Development Framework: Grails", - "id": "AI025400", - "description": "Development Framework: Grails", - "applies_to": [ - "groovy" - ], - "tags": [ - "Framework.Development.Grails" - ], - "severity": "moderate", - "overrides": null, - "patterns": [ - { - "pattern": "\\b(grails)\\b", - "type": "regex", - "modifiers": [ - "i" - ], - "scopes": [ - "code" - ], - "confidence": "high" - } - ], - "conditions": [] - }, - { - "name": "Development Framework: Rails", - "id": "AI025500", - "description": "Development Framework: Rails", - "applies_to": [ - "ruby" - ], - "tags": [ - "Framework.Development.Rails" - ], - "severity": "moderate", - "overrides": null, - "patterns": [ - { - "pattern": "\\b(rails)\\b", - "type": "regex", - "modifiers": [ - "i" - ], - "scopes": [ - "code" - ], - "confidence": "high" - } - ], - "conditions": [] - }, - { - "name": "Development Framework: Google API's", - "id": "AI025600", - "description": "Development Framework: Google API's", - "applies_to": [ - "ruby" - ], - "tags": [ - "Framework.Development.Google.API" - ], - "severity": "moderate", - "overrides": null, - "patterns": [ - { - "pattern": "google/apis", - "type": "regex", - "modifiers": [ - "i" - ], - "scopes": [ - "code" - ], - "confidence": "high" - } - ], - "conditions": [] - }, - { - "name": "Development Framework: Standard C Library", - "id": "AI017900", - "description": "Development Framework: Standard C Library", - "applies_to": [ - "c" - ], - "tags": [ - "Framework.Development.Library.StandardC" - ], - "severity": "moderate", - "overrides": null, - "patterns": [ - { - "pattern": "\\b(std::)\\b", - "type": "regex", - "modifiers": [ - "i" - ], - "scopes": [ - "code" - ], - "confidence": "medium" - } - ], - "conditions": [] - }, - { - "name": "Development Framework: Boost", - "id": "AI018000", - "description": "Development Framework: Boost", - "applies_to": [ - "c" - ], - "tags": [ - "Framework.Development.Library.Boost" - ], - "severity": "moderate", - "overrides": null, - "patterns": [ - { - "pattern": "\\b(boost::)\\b", - "type": "regex", - "modifiers": [ - "i" - ], - "scopes": [ - "code" - ], - "confidence": "medium" - }, - { - "pattern": "#include ", - "type": "regex", - "modifiers": [ - "i" - ], - "scopes": [ - "code" - ], - "confidence": "medium" - } - ], - "conditions": [] - }, - { - "name": "Development: Build Tool (Maven)", - "id": "AI016800", - "description": "Development: Build Tool (Maven)", - "applies_to": [ - "pom.xml" - ], - "tags": [ - "Metadata.Development.Build.Maven" - ], - "severity": "moderate", - "overrides": null, - "patterns": [ - { - "pattern": "Maven", - "type": "regex", - "modifiers": [ - "i" - ], - "scopes": [ - "code", - "comment" - ], - "confidence": "medium" - } - ], - "conditions": [] - }, - { - "name": "Development: Build Tool (Ant)", - "id": "AI016900", - "description": "Development: Build Tool (Ant)", - "applies_to": [ - "build.xml" - ], - "tags": [ - "Metadata.Development.Build.Ant" - ], - "severity": "moderate", - "overrides": null, - "patterns": [ - { - "pattern": "target", - "type": "regex", - "modifiers": [ - "i" - ], - "scopes": [ - "code", - "comment" - ], - "confidence": "medium" - } - ], - "conditions": [] - }, - { - "name": "Development: Build Tool (Gradle)", - "id": "AI017000", - "description": "Development: Build Tool (Gradle)", - "applies_to": [ - "build.gradle" - ], - "tags": [ - "Metadata.Development.Build.Gradle" - ], - "severity": "moderate", - "overrides": null, - "patterns": [ - { - "pattern": "sourceSets", - "type": "regex", - "modifiers": [ - "i" - ], - "scopes": [ - "code", - "comment" - ], - "confidence": "medium" - } - ], - "conditions": [] - }, - { - "name": "Development: Build Tool (Jenkins)", - "id": "AI017100", - "description": "Development: Build Tool (Jenkins)", - "applies_to": [ - "jenkins" - ], - "tags": [ - "Metadata.Development.Build.Jenkins" - ], - "severity": "moderate", - "overrides": null, - "patterns": [ - { - "pattern": "\\b(pipeline)\\b", - "type": "regex", - "modifiers": [ - "i" - ], - "scopes": [ - "code", - "comment" - ], - "confidence": "medium" - } - ], - "conditions": [] - }, - { - "name": "Development: Build Tool (SBT)", - "id": "AI017200", - "description": "Development: Build Tool (SBT)", - "applies_to": [ - "sbt" - ], - "tags": [ - "Metadata.Development.Build.SBT" - ], - "severity": "moderate", - "overrides": null, - "patterns": [ - { - "pattern": "\\b(build)\\b", - "type": "regex", - "modifiers": [ - "i" - ], - "scopes": [ - "code", - "comment" - ], - "confidence": "medium" - } - ], - "conditions": [] - }, - { - "name": "Development: Build Tool (Bamboo)", - "id": "AI017300", - "description": "Development: Build Tool (Bamboo)", - "applies_to": [ - "yaml" - ], - "tags": [ - "Metadata.Development.Build.Bamboo" - ], - "severity": "moderate", - "overrides": null, - "patterns": [ - { - "pattern": "\\b(bamboo)\\b", - "type": "regex", - "modifiers": [ - "i" - ], - "scopes": [ - "code", - "comment" - ], - "confidence": "medium" - } - ], - "conditions": [] - }, - { - "name": "Development: Build Tool (TeamCity)", - "id": "AI017400", - "description": "Development: Build Tool (TeamCity)", - "applies_to": null, - "tags": [ - "Metadata.Development.Build.TeamCity" - ], - "severity": "moderate", - "overrides": null, - "patterns": [ - { - "pattern": "\\b(teamcity)\\b", - "type": "regex", - "modifiers": [ - "i" - ], - "scopes": [ - "code", - "comment" - ], - "confidence": "medium" - } - ], - "conditions": [] - }, - { - "name": "Development: Build Tool (Grape)", - "id": "AI017500", - "description": "Development: Build Tool (Grape)", - "applies_to": [ - "java" - ], - "tags": [ - "Metadata.Development.Build.Grape" - ], - "severity": "moderate", - "overrides": null, - "patterns": [ - { - "pattern": "\\b(grape)\\b", - "type": "regex", - "modifiers": [ - "i" - ], - "scopes": [ - "code", - "comment" - ], - "confidence": "medium" - } - ], - "conditions": [] - }, - { - "name": "Development: Build Tool (Ivy)", - "id": "AI017600", - "description": "Development: Build Tool (Ivy)", - "applies_to": [ - "build.xml" - ], - "tags": [ - "Metadata.Development.Build.Ivy" - ], - "severity": "moderate", - "overrides": null, - "patterns": [ - { - "pattern": "\\b(ivy)\\b", - "type": "regex", - "modifiers": [ - "i" - ], - "scopes": [ - "code", - "comment" - ], - "confidence": "medium" - } - ], - "conditions": [] - }, - { - "name": "Development: Build Tool (Leiningen)", - "id": "AI017700", - "description": "Development: Build Tool (Leiningen)", - "applies_to": [ - "project.clj" - ], - "tags": [ - "Metadata.Development.Build.Leiningen" - ], - "severity": "moderate", - "overrides": null, - "patterns": [ - { - "pattern": "\\b(plug-ins|repositories|build|java)\\b", - "type": "regex", - "modifiers": [ - "i" - ], - "scopes": [ - "code", - "comment" - ], - "confidence": "medium" - } - ], - "conditions": [] - }, - { - "name": "Development: Build Tool (Visual Studio)", - "id": "AI017800", - "description": "Development: Build Tool (Studio)", - "applies_to": [ - "VSSolution", - "VSProject" - ], - "tags": [ - "Metadata.Development.Build.VisualStudio" - ], - "severity": "moderate", - "overrides": null, - "patterns": [ - { - "pattern": "VisualStudio|Visual Studio", - "type": "regex", - "modifiers": [ - "i" - ], - "scopes": [ - "code", - "comment" - ], - "confidence": "medium" - } - ], - "conditions": [] - }, - { - "name": "Detect Frameworks", - "id": "AI023700", - "description": "Detect well-known frameworks used", - "applies_to": [ - "php" - ], - "tags": [ - "Framework.Development.PHP" - ], - "severity": "moderate", - "overrides": null, - "patterns": [ - { - "pattern": "Laravel", - "type": "regex", - "modifiers": [ - "i" - ], - "scopes": [ - "code", - "comment" - ], - "confidence": "high" - }, - { - "pattern": "Symfony", - "type": "regex", - "modifiers": [ - "i" - ], - "scopes": [ - "code", - "comment" - ], - "confidence": "high" - }, - { - "pattern": "CodeIgniter", - "type": "regex", - "modifiers": [ - "i" - ], - "scopes": [ - "code", - "comment" - ], - "confidence": "high" - }, - { - "pattern": "Zend", - "type": "regex", - "modifiers": [ - "i" - ], - "scopes": [ - "code", - "comment" - ], - "confidence": "high" - }, - { - "pattern": "Fuelphp", - "type": "regex", - "modifiers": [ - "i" - ], - "scopes": [ - "code", - "comment" - ], - "confidence": "high" - }, - { - "pattern": "Slim", - "type": "regex", - "modifiers": [ - "i" - ], - "scopes": [ - "code", - "comment" - ], - "confidence": "high" - }, - { - "pattern": "Phalcon", - "type": "regex", - "modifiers": [ - "i" - ], - "scopes": [ - "code", - "comment" - ], - "confidence": "high" - }, - { - "pattern": "Aura", - "type": "regex", - "modifiers": [ - "i" - ], - "scopes": [ - "code", - "comment" - ], - "confidence": "high" - }, - { - "pattern": "Yii", - "type": "regex", - "modifiers": [ - "i" - ], - "scopes": [ - "code", - "comment" - ], - "confidence": "high" - }, - { - "pattern": "Cakephp", - "type": "regex", - "modifiers": [ - "i" - ], - "scopes": [ - "code", - "comment" - ], - "confidence": "high" - } - ], - "conditions": [] - }, - { - "name": "Development Framework: .NET Core", - "id": "AI022300", - "description": "Development Framework: .NET Core", - "applies_to": [ - "csharp" - ], - "tags": [ - "Framework.Development.Microsoft.NETCore" - ], - "severity": "moderate", - "overrides": null, - "patterns": [ - { - "pattern": "\\b(netcore)\\b", - "type": "regex", - "modifiers": [ - "i" - ], - "scopes": [ - "code" - ], - "confidence": "medium" - } - ], - "conditions": [] - }, - { - "name": "Development Framework: .NET Standard", - "id": "AI022400", - "description": "Development Framework: .NET Standard", - "applies_to": [ - "csharp" - ], - "tags": [ - "Framework.Development.Microsoft.NETStandard" - ], - "severity": "moderate", - "overrides": null, - "patterns": [ - { - "pattern": "\\b(Microsoft\\.NET\\.Sdk)\\b", - "type": "regex", - "modifiers": [ - "i" - ], - "scopes": [ - "code" - ], - "confidence": "medium" - } - ], - "conditions": [] - }, - { - "name": "Development Framework: Mono", - "id": "AI022500", - "description": "Development Framework: Mono", - "applies_to": [ - "csharp" - ], - "tags": [ - "Framework.Development.Microsoft.Mono" - ], - "severity": "moderate", - "overrides": null, - "patterns": [ - { - "pattern": "using (gtk|Glade)", - "type": "regex", - "modifiers": [ - "i" - ], - "scopes": [ - "code" - ], - "confidence": "medium" - } - ], - "conditions": [] - }, - { - "name": "Development Framework: Microsoft Azure", - "id": "AI022600", - "description": "Development Framework: Microsoft Azure", - "applies_to": [ - "csharp" - ], - "tags": [ - "Framework.Development.Microsoft.Azure", - "Metadata.Application.Type.Web.Application" - ], - "severity": "moderate", - "overrides": null, - "patterns": [ - { - "pattern": "\\b(Microsoft\\.Azure\\.WebJobs\\.Host)\\b", - "type": "regex", - "modifiers": [ - "i" - ], - "scopes": [ - "code" - ], - "confidence": "medium" - } - ], - "conditions": [] - }, - { - "name": "Development Framework: Microsoft WCF", - "id": "AI022700", - "description": "Development Framework: Microsoft WCF", - "applies_to": [ - "csharp" - ], - "tags": [ - "Framework.Development.Microsoft.WCF", - "Metadata.Application.Type.Web.Service" - ], - "severity": "moderate", - "overrides": null, - "patterns": [ - { - "pattern": "\\b(ServiceContract|using System\\.ServiceModel|WSHttpBinding|[HttpGet]|[HttpPut])\\b", - "type": "regex", - "modifiers": [ - "i" - ], - "scopes": [ - "code" - ], - "confidence": "medium" - }, - { - "pattern": "Controller\\b", - "type": "regex", - "modifiers": [ - "i" - ], - "scopes": [ - "code" - ], - "confidence": "medium" - } - ], - "conditions": [] - }, - { - "name": "Development Framework: Microsoft MFC", - "id": "AI022800", - "description": "Development Framework: Microsoft MFC", - "applies_to": [ - "c", - "cpp", - "csharp" - ], - "tags": [ - "Framework.Development.Microsoft.MFC", - "Metadata.Application.Type.Client.Windows" - ], - "severity": "moderate", - "overrides": null, - "patterns": [ - { - "pattern": "\\b(CFrameWnd|CMDIFrameWnd|CView|CWnd|stdafx\\.h|winafx\\.h|afx\\.h)\\b", - "type": "regex", - "modifiers": null, - "scopes": [ - "code" - ], - "confidence": "medium" - } - ], - "conditions": [] - }, - { - "name": "Development Framework: Microsoft ADO", - "id": "AI022900", - "description": "Development Framework: Microsoft ADO", - "applies_to": [ - "csharp" - ], - "tags": [ - "Framework.Development.Microsoft.ADO", - "Data.DBMS.SQL.ADO" - ], - "severity": "moderate", - "overrides": null, - "patterns": [ - { - "pattern": "System\\.Data\\.(SqlClient|OleDb|OracleClient|Odbc|EntityClient)", - "type": "regex", - "modifiers": [ - "i" - ], - "scopes": [ - "code" - ], - "confidence": "high" - } - ], - "conditions": [] - }, - { - "name": "Development Framework: Microsoft Linq", - "id": "AI023000", - "description": "Development Framework: Microsoft Linq", - "applies_to": [ - "csharp" - ], - "tags": [ - "Framework.Development.Microsoft.Linq" - ], - "severity": "moderate", - "overrides": null, - "patterns": [ - { - "pattern": "\\b(linq)\\b", - "type": "regex", - "modifiers": [ - "i" - ], - "scopes": [ - "code" - ], - "confidence": "high" - } - ], - "conditions": [] - }, - { - "name": "Development Framework: Windows SDK", - "id": "AI023100", - "description": "Development Framework: Windows SDK", - "applies_to": [ - "c", - "cpp", - "csharp" - ], - "tags": [ - "Framework.Development.Microsoft.WindowsSDK", - "Metadata.Application.Type.Client.Windows" - ], - "severity": "moderate", - "overrides": null, - "patterns": [ - { - "pattern": "winsdk", - "type": "regex", - "modifiers": [ - "i" - ], - "scopes": [ - "code" - ], - "confidence": "high" - } - ], - "conditions": [] - }, - { - "name": "Development Framework: Microsoft Dynamics", - "id": "AI023200", - "description": "Development Framework: Microsoft Dynamics", - "applies_to": null, - "tags": [ - "Framework.Development.Microsoft.Server.Dynamics" - ], - "severity": "moderate", - "overrides": null, - "patterns": [ - { - "pattern": "\\b(Microsoft\\ Dynamics\\|dynamics\\.com)\\b", - "type": "regex", - "modifiers": [ - "i" - ], - "scopes": [ - "code", - "comment" - ], - "confidence": "medium" - } - ], - "conditions": [] - }, - { - "name": "Development Framework: Microsoft Exchange", - "id": "AI023300", - "description": "Development Framework: Microsoft Exchange", - "applies_to": null, - "tags": [ - "Framework.Development.Microsoft.Server.Exchange" - ], - "severity": "moderate", - "overrides": null, - "patterns": [ - { - "pattern": "\\b(Microsoft\\ Exchange)\\b", - "type": "regex", - "modifiers": [ - "i" - ], - "scopes": [ - "code", - "comment" - ], - "confidence": "medium" - } - ], - "conditions": [] - }, - { - "name": "Development Framework: Microsoft IIS", - "id": "AI023400", - "description": "Development Framework: Microsoft IIS", - "applies_to": null, - "tags": [ - "Framework.Development.Microsoft.Server.IIS", - "Metadata.Application.Type.Web.Application" - ], - "severity": "moderate", - "overrides": null, - "patterns": [ - { - "pattern": "\\b(IIS)\\b", - "type": "regex", - "modifiers": null, - "scopes": [ - "code" - ], - "confidence": "medium" - } - ], - "conditions": [] - }, - { - "name": "Development Framework: Microsoft ASP.NET", - "id": "AI023500", - "description": "Development Framework: Microsoft ASP.NET", - "applies_to": null, - "tags": [ - "Framework.Development.Microsoft.NET.ASP", - "Metadata.Application.Type.Web.Application" - ], - "severity": "moderate", - "overrides": null, - "patterns": [ - { - "pattern": "ASP\\.NET|\\b\\.MVC\\b", - "type": "regex", - "modifiers": [ - "i" - ], - "scopes": [ - "code" - ], - "confidence": "medium" - } - ], - "conditions": [] - }, - { - "name": "Component: COM", - "id": "AI023600", - "description": "Component: COM", - "applies_to": [ - "c", - "cpp", - "csharp" - ], - "tags": [ - "Framework.Development.Microsoft.COM", - "Component.Executable.Microsoft.COM" - ], - "severity": "moderate", - "overrides": null, - "patterns": [ - { - "pattern": "\\b(CLSCTX_INPROC_SERVER|CLSCTX_INPROC_HANDLER|CLSCTX_LOCAL_SERVER|CoCreateInstance)\\b", - "type": "regex", - "modifiers": null, - "scopes": [ - "code" - ], - "confidence": "high" - } - ], - "conditions": [] - }, - { - "name": "Cryptography: x.509 Certificate Use", - "id": "AI006200", - "description": "Cryptography: x.509 Certificate Use", - "applies_to": null, - "tags": [ - "Cryptography.X509Certificates.Use" - ], - "severity": "moderate", - "overrides": null, - "patterns": [ - { - "pattern": "\\b(x509|\\.(crt|cer|spc|p7b|p7s|p7r|ca-bundle))\\b", - "type": "regex", - "modifiers": [ - "i" - ], - "scopes": [ - "code" - ], - "confidence": "high" - }, - { - "pattern": "PKCS|PaddingMode|SubjectIdentifier|Certificate", - "type": "regex", - "modifiers": [ - "i" - ], - "scopes": [ - "code" - ], - "confidence": "high" - } - ], - "conditions": [] - }, - { - "name": "Cryptography: x.509 Certificate Use", - "id": "AI006300", - "description": "Cryptography: x.509 Certificate Use", - "applies_to": [ - "c", - "cpp", - "csharp" - ], - "tags": [ - "Cryptography.X509Certificates.Use" - ], - "severity": "moderate", - "overrides": null, - "patterns": [ - { - "pattern": "_CERT|CERT_", - "type": "regex", - "modifiers": [ - "i" - ], - "scopes": [ - "code" - ], - "confidence": "high" - } - ], - "conditions": [] - }, - { - "name": "Cryptography: x.509 Certificate ClientAuth", - "id": "AI006400", - "description": "Cryptography: x.509 Certificate ClientAuth", - "applies_to": null, - "tags": [ - "Cryptography.X509Certificates.ClientAuth", - "Cryptography.X509Certificates.Keyfile" - ], - "severity": "moderate", - "overrides": null, - "patterns": [ - { - "pattern": "\\b(\\.(pem|pfx))\\b", - "type": "regex", - "modifiers": [ - "i" - ], - "scopes": [ - "code" - ], - "confidence": "high" - } - ], - "conditions": [] - }, - { - "name": "Cryptography: x.509 Certificate ClientAuth", - "id": "AI006410", - "description": "Cryptography: x.509 Certificate ClientAuth", - "applies_to": null, - "tags": [ - "Cryptography.X509Certificates.ClientAuth" - ], - "severity": "moderate", - "overrides": null, - "patterns": [ - { - "pattern": "\\b(\\.WithClientClaims\\(.*cert.*\\)|\\.WithCertificate\\()\\b", - "type": "regex", - "modifiers": [ - "i" - ], - "scopes": [ - "code" - ], - "confidence": "high" - } - ], - "conditions": [ - { - "pattern": { - "pattern": "AcquireTokenForClient|ConfidentialClientApplicationBuilder", - "type": "regex", - "modifiers": [ - "i" - ], - "scopes": [ - "code" - ], - "confidence": "medium" - }, - "search_in": "finding-region(-10,10)", - "negate_finding": false - } - ] - }, - { - "name": "Cryptography: x.509 Certificate Create", - "id": "AI006500", - "description": "Cryptography: x.509 Create Certificate", - "applies_to": null, - "tags": [ - "Cryptography.X509Certificates.Create" - ], - "severity": "moderate", - "overrides": null, - "patterns": [ - { - "pattern": "\\b(genrsa|-keyout|-x509toreq|csr)\\b", - "type": "regex", - "modifiers": [], - "scopes": [ - "code" - ], - "confidence": "high" - }, - { - "pattern": "\\b(---BEGIN CERTIFICATE---)\\b", - "type": "regex", - "modifiers": [ - "i" - ], - "scopes": [ - "code" - ], - "confidence": "high" - }, - { - "pattern": "---BEGIN PKCS", - "type": "regex", - "modifiers": [ - "i" - ], - "scopes": [ - "code" - ], - "confidence": "high" - }, - { - "pattern": "(create|generate) (cert|certificate)", - "type": "regex", - "modifiers": [], - "scopes": [ - "comment" - ], - "confidence": "high" - } - ], - "conditions": [] - }, - { - "name": "Cryptography: Digital Signature or DSA", - "id": "AI006600", - "description": "Cryptography: Digital Signature or DSA", - "applies_to": [ - "csharp" - ], - "tags": [ - "Cryptography.Signing.Data" - ], - "severity": "moderate", - "overrides": null, - "patterns": [ - { - "pattern": "DSACng|SignData|CreateSignature|DSACryptoServiceProvider|DSASignatureDeformatter|DSASignatureFormatter|DSAKeyValue", - "type": "regex", - "modifiers": [ - "" - ], - "scopes": [ - "code" - ], - "confidence": "high" - }, - { - "pattern": "DSAParameters", - "type": "regex", - "modifiers": [ - "" - ], - "scopes": [ - "code" - ], - "confidence": "high" - } - ], - "conditions": [] - }, - { - "name": "Cryptography: Digital Signature", - "id": "AI006700", - "description": "Cryptography: Digital Signature", - "applies_to": null, - "tags": [ - "Cryptography.Signing.Data" - ], - "severity": "moderate", - "overrides": null, - "patterns": [ - { - "pattern": "\\b(sign(ing)*.?key|signature.?key|valid.?signature|data.?sign|sign.?data)\\b", - "type": "regex", - "modifiers": [ - "i" - ], - "scopes": [ - "code", - "comment" - ], - "confidence": "high" - }, - { - "pattern": "\\b(DSA)\\b", - "type": "regex", - "modifiers": [ - "i" - ], - "scopes": [ - "code" - ], - "confidence": "medium" - } - ], - "conditions": [] - }, - { - "name": "Cryptography: CodeSign", - "id": "AI006800", - "description": "Cryptography: CodeSign", - "applies_to": null, - "tags": [ - "Cryptography.Signing.Code" - ], - "severity": "moderate", - "overrides": null, - "patterns": [ - { - "pattern": "code.?sign|authenticode|sign.?code", - "type": "regex", - "modifiers": [ - "i" - ], - "scopes": [ - "code" - ], - "confidence": "high" - } - ], - "conditions": [ - { - "pattern": { - "pattern": "shared access|SAS", - "type": "regex", - "modifiers": [ - "i" - ], - "scopes": [ - "code" - ], - "confidence": "medium" - }, - "search_in": "finding-region(-30,30)", - "negate_finding": true - } - ] - }, - { - "name": "Cryptography: Encoding (Base-64)", - "id": "AI007800", - "description": "Cryptography: Encoding (Base-64)", - "applies_to": [], - "tags": [ - "Cryptography.Encoding.Base64" - ], - "severity": "moderate", - "overrides": null, - "patterns": [ - { - "pattern": "base64", - "type": "regex", - "modifiers": [ - "i" - ], - "scopes": [ - "code" - ], - "confidence": "high" - } - ], - "conditions": [] - }, - { - "name": "Detect Weak Cryptography", - "id": "AI010500", - "description": "Detect use of cryptography", - "applies_to": [ - "c", - "cpp", - "csharp" - ], - "tags": [ - "Cryptography.Protocol.TLS.WeakSSL" - ], - "severity": "critical", - "overrides": null, - "patterns": [ - { - "pattern": "^iv.*=| +iv.*=", - "type": "regex", - "modifiers": [ - "" - ], - "scopes": [ - "code" - ], - "confidence": "high" - }, - { - "pattern": "SECURITY_FLAG_IGNORE_", - "type": "regex", - "modifiers": [ - "" - ], - "scopes": [ - "code" - ], - "confidence": "high" - }, - { - "pattern": "SP_PROT_PCT1_", - "type": "regex", - "modifiers": [ - "" - ], - "scopes": [ - "code" - ], - "confidence": "high" - }, - { - "pattern": "kSSLProtocol", - "type": "regex", - "modifiers": [ - "" - ], - "scopes": [ - "code" - ], - "confidence": "high" - }, - { - "pattern": "CryptUnprotectData", - "type": "regex", - "modifiers": [ - "" - ], - "scopes": [ - "code" - ], - "confidence": "high" - }, - { - "pattern": "mwc1616", - "type": "regex", - "modifiers": [ - "" - ], - "scopes": [ - "code" - ], - "confidence": "high" - }, - { - "pattern": "32969|18273", - "type": "regex", - "modifiers": [ - "" - ], - "scopes": [ - "code" - ], - "confidence": "high" - }, - { - "pattern": "StoreName\\.Root", - "type": "regex", - "modifiers": [ - "" - ], - "scopes": [ - "code" - ], - "confidence": "high" - }, - { - "pattern": "OAUTHLIB_INSECURE_TRANSPORT", - "type": "regex", - "modifiers": [ - "" - ], - "scopes": [ - "code" - ], - "confidence": "high" - }, - { - "pattern": "\\.trustAllCerts\\(\\)", - "type": "regex", - "modifiers": [ - "" - ], - "scopes": [ - "code" - ], - "confidence": "high" - }, - { - "pattern": "\\.trustAllHosts\\(\\)", - "type": "regex", - "modifiers": [ - "" - ], - "scopes": [ - "code" - ], - "confidence": "high" - }, - { - "pattern": "NXOAuth2TrustModeAnyCertificate", - "type": "regex", - "modifiers": [ - "" - ], - "scopes": [ - "code" - ], - "confidence": "high" - }, - { - "pattern": "--no-check-certificate", - "type": "regex", - "modifiers": [ - "" - ], - "scopes": [ - "code" - ], - "confidence": "high" - }, - { - "pattern": "--insecure", - "type": "regex", - "modifiers": [ - "" - ], - "scopes": [ - "code" - ], - "confidence": "high" - }, - { - "pattern": "encrypt=false", - "type": "regex", - "modifiers": [ - "" - ], - "scopes": [ - "code" - ], - "confidence": "high" - }, - { - "pattern": "encryption=false", - "type": "regex", - "modifiers": [ - "" - ], - "scopes": [ - "code" - ], - "confidence": "high" - }, - { - "pattern": "OpenSSL::SSL::VERIFY_NONE", - "type": "regex", - "modifiers": [ - "" - ], - "scopes": [ - "code" - ], - "confidence": "high" - }, - { - "pattern": "RelaxSSLCertificateValidation", - "type": "regex", - "modifiers": [ - "" - ], - "scopes": [ - "code" - ], - "confidence": "high" - }, - { - "pattern": "setAllowsAnyHTTPSCertificate", - "type": "regex", - "modifiers": [ - "" - ], - "scopes": [ - "code" - ], - "confidence": "high" - }, - { - "pattern": "continueWithoutCredentialForAuthenticationChallenge", - "type": "regex", - "modifiers": [ - "" - ], - "scopes": [ - "code" - ], - "confidence": "high" - }, - { - "pattern": "disable_ssl_certificate_validation", - "type": "regex", - "modifiers": [ - "" - ], - "scopes": [ - "code" - ], - "confidence": "high" - }, - { - "pattern": "CERT_NONE", - "type": "regex", - "modifiers": [ - "" - ], - "scopes": [ - "code" - ], - "confidence": "high" - }, - { - "pattern": "\\.ServerCertificateValidationCallback", - "type": "regex", - "modifiers": [ - "" - ], - "scopes": [ - "code" - ], - "confidence": "high" - }, - { - "pattern": "IgnorableServerCertificateErrors", - "type": "regex", - "modifiers": [ - "" - ], - "scopes": [ - "code" - ], - "confidence": "high" - }, - { - "pattern": "certificateValidationMode", - "type": "regex", - "modifiers": [ - "" - ], - "scopes": [ - "code" - ], - "confidence": "high" - }, - { - "pattern": "CERT_CHAIN_POLICY_IGNORE_", - "type": "regex", - "modifiers": [ - "" - ], - "scopes": [ - "code" - ], - "confidence": "high" - }, - { - "pattern": "WINHTTP_ENABLE_SSL_REVOCATION", - "type": "regex", - "modifiers": [ - "" - ], - "scopes": [ - "code" - ], - "confidence": "high" - }, - { - "pattern": "CERT_CHAIN_REVOCATION_ACCUMULATIVE_TIMEOUT", - "type": "regex", - "modifiers": [ - "" - ], - "scopes": [ - "code" - ], - "confidence": "high" - }, - { - "pattern": "ISC_REQ_MANUAL_CRED_VALIDATION", - "type": "regex", - "modifiers": [ - "" - ], - "scopes": [ - "code" - ], - "confidence": "high" - }, - { - "pattern": "SECPKG_ATTR_REMOTE_CERT_CONTEXT", - "type": "regex", - "modifiers": [ - "" - ], - "scopes": [ - "code" - ], - "confidence": "high" - }, - { - "pattern": "disable_ssl_certificate_validation", - "type": "regex", - "modifiers": [ - "i" - ], - "scopes": [ - "code" - ], - "confidence": "high" - } - ], - "conditions": [] - }, - { - "name": "Cryptography: PRNG", - "id": "AI010000", - "description": "Cryptography: PRNG", - "applies_to": [ - "c", - "cpp" - ], - "tags": [ - "Cryptography.Randomness.PRNG" - ], - "severity": "critical", - "overrides": null, - "patterns": [ - { - "pattern": "\\b(DUAL_EC_DRBG)\\b", - "type": "regex", - "modifiers": null, - "scopes": [ - "code" - ], - "confidence": "high" - }, - { - "pattern": "\\b(pseudoRandomBytes)\\b", - "type": "regex", - "modifiers": null, - "scopes": [ - "code" - ], - "confidence": "high" - }, - { - "pattern": "\\b(rand|srand)\\b", - "type": "regex", - "modifiers": null, - "scopes": [ - "code" - ], - "confidence": "low" - } - ], - "conditions": [] - }, - { - "name": "Cryptography: PRNG", - "id": "AI010100", - "description": "Cryptography: PRNG", - "applies_to": [ - "javascript" - ], - "tags": [ - "Cryptography.Randomness.PRNG" - ], - "severity": "critical", - "overrides": null, - "patterns": [ - { - "pattern": "\\b(\\(pseudo\\)\\?randombytes)\\b", - "type": "regex", - "modifiers": [ - "i" - ], - "scopes": [ - "code" - ], - "confidence": "high" - } - ], - "conditions": [] - }, - { - "name": "Cryptography: PRNG", - "id": "AI010200", - "description": "Cryptography: PRNG", - "applies_to": [ - "java" - ], - "tags": [ - "Cryptography.Randomness.PRNG" - ], - "severity": "critical", - "overrides": null, - "patterns": [ - { - "pattern": "\\b(SecureRandom)\\b", - "type": "regex", - "modifiers": null, - "scopes": [ - "code" - ], - "confidence": "high" - } - ], - "conditions": [] - }, - { - "name": "Cryptography: PRNG", - "id": "AI010300", - "description": "Cryptography: PRNG", - "applies_to": [ - "csharp" - ], - "tags": [ - "Cryptography.Randomness.PRNG" - ], - "severity": "critical", - "overrides": null, - "patterns": [ - { - "pattern": "\\b(RandomNumberGenerator)\\b", - "type": "regex", - "modifiers": null, - "scopes": [ - "code" - ], - "confidence": "high" - } - ], - "conditions": [] - }, - { - "name": "Cryptography: PRNG", - "id": "AI010400", - "description": "Cryptography: PRNG", - "applies_to": null, - "tags": [ - "Cryptography.Randomness.PRNG" - ], - "severity": "critical", - "overrides": null, - "patterns": [ - { - "pattern": "\\b(random)\\b", - "type": "regex", - "modifiers": null, - "scopes": [ - "code" - ], - "confidence": "low" - } - ], - "conditions": [] - }, - { - "name": "Cryptography: Encryption (AES)", - "id": "AI006900", - "description": "Cryptography: Encryption (AES)", - "applies_to": null, - "tags": [ - "Cryptography.Cipher.AES" - ], - "severity": "moderate", - "overrides": null, - "patterns": [ - { - "pattern": "\\b(AES)\\b", - "type": "regex", - "modifiers": null, - "scopes": [ - "code" - ], - "confidence": "high" - }, - { - "pattern": "\\b(AES-?(128|192|256)|Rijndael)\\b", - "type": "regex", - "modifiers": null, - "scopes": [ - "code" - ], - "confidence": "high" - } - ], - "conditions": [] - }, - { - "name": "Cryptography: Encryption (3DES)", - "id": "AI007000", - "description": "Cryptography: Encryption (3DES)", - "applies_to": null, - "tags": [ - "Cryptography.Cipher.3DES" - ], - "severity": "moderate", - "overrides": null, - "patterns": [ - { - "pattern": "\\b(3DES|TripleDES)\\b", - "type": "regex", - "modifiers": null, - "scopes": [ - "code" - ], - "confidence": "high" - } - ], - "conditions": [] - }, - { - "name": "Cryptography: Encryption (RC)", - "id": "AI007100", - "description": "Cryptography: Encryption (RC)", - "applies_to": null, - "tags": [ - "Cryptography.Cipher.RC" - ], - "severity": "moderate", - "overrides": null, - "patterns": [ - { - "pattern": "\\b(RC([2456]))\\b", - "type": "regex", - "modifiers": null, - "scopes": [ - "code" - ], - "confidence": "high" - }, - { - "pattern": "\\b(arc4random)\\b", - "type": "regex", - "modifiers": null, - "scopes": [ - "code" - ], - "confidence": "high" - } - ], - "conditions": [] - }, - { - "name": "Encryption: Cipher Mode", - "id": "AI007200", - "description": "Encryption: Cipher Mode", - "applies_to": null, - "tags": [ - "Cryptography.Cipher.CipherMode" - ], - "severity": "critical", - "overrides": null, - "patterns": [ - { - "pattern": "\\b(CBC|CTR|ECB|OFB|CFB|CTS|PCBC|GMAC|XCBC|IACBC|IAPM|EAX|OCB|CWC|AEAD|LRW|XEX|XTS|CMC|EME|CBCMAC|OMAC|PMAC)\\b", - "type": "regex", - "modifiers": null, - "scopes": [ - "code" - ], - "confidence": "high" - } - ], - "conditions": [] - }, - { - "name": "Cryptography: Encryption (RSA)", - "id": "AI007300", - "description": "Cryptography: Encryption", - "applies_to": [ - "csharp" - ], - "tags": [ - "Cryptography.Cipher.RSA" - ], - "severity": "moderate", - "overrides": null, - "patterns": [ - { - "pattern": "\\b(RSACng|RSACryptoServiceProvider|RSAEncryptionPadding|RSAOAEPKeyExchangeDeformatter|X509AsymmetricSecurityKey)\\b", - "type": "regex", - "modifiers": [ - "" - ], - "scopes": [ - "code" - ], - "confidence": "high" - }, - { - "pattern": "\\b(RSAOAEPKeyExchangeFormatter|RSAPKCS1KeyExchangeDeformatter|RSAPKCS1)\\b", - "type": "regex", - "modifiers": [ - "" - ], - "scopes": [ - "code" - ], - "confidence": "high" - }, - { - "pattern": "\\b(RSASignaturePadding|RsaProtectedConfigurationProvider|RSACertificateExtensions)\\b", - "type": "regex", - "modifiers": [ - "" - ], - "scopes": [ - "code" - ], - "confidence": "high" - } - ], - "conditions": [] - }, - { - "name": "Cryptography: Encryption (RSA)", - "id": "AI007400", - "description": "Cryptography: Encryption", - "applies_to": null, - "tags": [ - "Cryptography.Cipher.RSA" - ], - "severity": "moderate", - "overrides": null, - "patterns": [ - { - "pattern": "RSA.*encrypt|RSA.*decrypt|public.?key|private.?key|privkey|pubkey", - "type": "regex", - "modifiers": null, - "scopes": [ - "code", - "comment" - ], - "confidence": "high" - }, - { - "pattern": "\\b(rsa)\\b", - "type": "regex", - "modifiers": null, - "scopes": [ - "code" - ], - "confidence": "low" - } - ], - "conditions": [] - }, - { - "name": "Cryptography: Encryption (RSA)", - "id": "AI007500", - "description": "Cryptography: Encryption", - "applies_to": null, - "tags": [ - "Cryptography.Cipher.RSA" - ], - "severity": "moderate", - "overrides": null, - "patterns": [ - { - "pattern": "\\b(asymmetric)\\b", - "type": "regex", - "modifiers": null, - "scopes": [ - "code", - "comment" - ], - "confidence": "medium" - } - ], - "conditions": [] - }, - { - "name": "Cryptography: Encryption (General)", - "id": "AI007600", - "description": "Cryptography: Encryption", - "applies_to": null, - "tags": [ - "Cryptography.Encryption.General" - ], - "severity": "moderate", - "overrides": null, - "patterns": [ - { - "pattern": "encrypt|decrypt|cipher|crypt|symmmetric", - "type": "regex", - "modifiers": null, - "scopes": [ - "code", - "comment" - ], - "confidence": "high" - } - ], - "conditions": [] - }, - { - "name": "Cryptography: Encryption (General)", - "id": "AI007900", - "description": "Detect use of cryptography", - "applies_to": [ - "csharp", - "vb" - ], - "tags": [ - "Cryptography.Encryption.General" - ], - "severity": "critical", - "overrides": null, - "patterns": [ - { - "pattern": "AsnEncodedData", - "type": "regex", - "modifiers": [ - "" - ], - "scopes": [ - "code" - ], - "confidence": "high" - }, - { - "pattern": "\\b(Cng(Algorithm|Key|Property|Provider|UIPolicy))\\b", - "type": "regex", - "modifiers": [ - "" - ], - "scopes": [ - "code" - ], - "confidence": "high" - }, - { - "pattern": "CspKeyContainerInfo", - "type": "regex", - "modifiers": [ - "" - ], - "scopes": [ - "code" - ], - "confidence": "high" - }, - { - "pattern": "CspParameters", - "type": "regex", - "modifiers": [ - "" - ], - "scopes": [ - "code" - ], - "confidence": "high" - }, - { - "pattern": "DataProtector", - "type": "regex", - "modifiers": [ - "" - ], - "scopes": [ - "code" - ], - "confidence": "high" - }, - { - "pattern": "DeriveBytes", - "type": "regex", - "modifiers": [ - "" - ], - "scopes": [ - "code" - ], - "confidence": "high" - }, - { - "pattern": "KeySizes", - "type": "regex", - "modifiers": [ - "" - ], - "scopes": [ - "code" - ], - "confidence": "high" - }, - { - "pattern": "MaskGenerationMethod", - "type": "regex", - "modifiers": [ - "" - ], - "scopes": [ - "code" - ], - "confidence": "high" - }, - { - "pattern": "\\b(Oid)\\b", - "type": "regex", - "modifiers": [ - "" - ], - "scopes": [ - "code" - ], - "confidence": "high" - }, - { - "pattern": "\\b(OidCollection)\\b", - "type": "regex", - "modifiers": [ - "" - ], - "scopes": [ - "code" - ], - "confidence": "high" - }, - { - "pattern": "\\b(OidEnumerator)\\b", - "type": "regex", - "modifiers": [ - "" - ], - "scopes": [ - "code" - ], - "confidence": "high" - }, - { - "pattern": "ProtectedMemory", - "type": "regex", - "modifiers": [ - "" - ], - "scopes": [ - "code" - ], - "confidence": "medium" - }, - { - "pattern": "RIPEMD160", - "type": "regex", - "modifiers": [ - "" - ], - "scopes": [ - "code" - ], - "confidence": "high" - }, - { - "pattern": "CngProperty|CngExportPolicies|CngKey|CngUI|CndProvider", - "type": "regex", - "modifiers": [ - "" - ], - "scopes": [ - "code" - ], - "confidence": "high" - }, - { - "pattern": "DataProtectionScope", - "type": "regex", - "modifiers": [ - "" - ], - "scopes": [ - "code" - ], - "confidence": "high" - }, - { - "pattern": "ECKeyXmlFormat", - "type": "regex", - "modifiers": [ - "" - ], - "scopes": [ - "code" - ], - "confidence": "high" - }, - { - "pattern": "MemoryProtectionScope", - "type": "regex", - "modifiers": [ - "" - ], - "scopes": [ - "code" - ], - "confidence": "high" - }, - { - "pattern": "OidGroup", - "type": "regex", - "modifiers": [ - "" - ], - "scopes": [ - "code" - ], - "confidence": "high" - }, - { - "pattern": "KeyAgreeKeyChoice", - "type": "regex", - "modifiers": [ - "" - ], - "scopes": [ - "code" - ], - "confidence": "high" - }, - { - "pattern": "AlgorithmIdentifier", - "type": "regex", - "modifiers": [ - "" - ], - "scopes": [ - "code" - ], - "confidence": "high" - }, - { - "pattern": "CmsRecipient", - "type": "regex", - "modifiers": [ - "" - ], - "scopes": [ - "code" - ], - "confidence": "high" - }, - { - "pattern": "CmsSigner", - "type": "regex", - "modifiers": [ - "" - ], - "scopes": [ - "code" - ], - "confidence": "high" - }, - { - "pattern": "EnvelopedCms", - "type": "regex", - "modifiers": [ - "" - ], - "scopes": [ - "code" - ], - "confidence": "high" - }, - { - "pattern": "\\b(KeyAgreeRecipientInfo|KeyTransRecipientInfo)\\b", - "type": "regex", - "modifiers": [ - "" - ], - "scopes": [ - "code" - ], - "confidence": "high" - }, - { - "pattern": "X500DistinguishedName", - "type": "regex", - "modifiers": [ - "" - ], - "scopes": [ - "code" - ], - "confidence": "high" - }, - { - "pattern": "OpenFlags", - "type": "regex", - "modifiers": [ - "" - ], - "scopes": [ - "code" - ], - "confidence": "high" - }, - { - "pattern": "KeyInfo", - "type": "regex", - "modifiers": [ - "" - ], - "scopes": [ - "code" - ], - "confidence": "high" - }, - { - "pattern": "TransformChain", - "type": "regex", - "modifiers": [ - "" - ], - "scopes": [ - "code" - ], - "confidence": "high" - }, - { - "pattern": "XmlDsig", - "type": "regex", - "modifiers": [ - "" - ], - "scopes": [ - "code" - ], - "confidence": "high" - }, - { - "pattern": "XmlLicenseTransform", - "type": "regex", - "modifiers": [ - "" - ], - "scopes": [ - "code" - ], - "confidence": "high" - }, - { - "pattern": "IRelDecryptor", - "type": "regex", - "modifiers": [ - "" - ], - "scopes": [ - "code" - ], - "confidence": "high" - }, - { - "pattern": "ProtectionLevel\\.None", - "type": "regex", - "modifiers": [ - "" - ], - "scopes": [ - "code" - ], - "confidence": "high" - }, - { - "pattern": "ProtectionLevel\\.Sign", - "type": "regex", - "modifiers": [ - "" - ], - "scopes": [ - "code" - ], - "confidence": "high" - }, - { - "pattern": "TsCertCompareCertContext", - "type": "regex", - "modifiers": [ - "" - ], - "scopes": [ - "code" - ], - "confidence": "high" - } - ], - "conditions": [] - }, - { - "name": "Cryptography: CryptoCurrency", - "id": "AI007700", - "description": "Cryptography: CryptoCurrency", - "applies_to": null, - "tags": [ - "Cryptography.CryptoCurrency" - ], - "severity": "moderate", - "overrides": null, - "patterns": [ - { - "pattern": "\\b(cardano|ethereum|cryptocurrency)\\b", - "type": "regex", - "modifiers": [ - "i" - ], - "scopes": [ - "code" - ], - "confidence": "high" - }, - { - "pattern": "\\b(p2pool|miner|ripple|nxt|zcash|tether|ether|btc|monero|merkleroot|xmr|eth)\\b", - "type": "regex", - "modifiers": [ - "i" - ], - "scopes": [ - "code" - ], - "confidence": "medium" - }, - { - "pattern": "(bit|lite|name|peer|doge|grid|prim|vert|tit|pot)coin", - "type": "regex", - "modifiers": [ - "i" - ], - "scopes": [ - "code" - ], - "confidence": "high" - } - ], - "conditions": [] - }, - { - "name": "Cryptography: SSL/TLS Protocol", - "id": "AI009600", - "description": "Cryptography: SSL/TLS Protocol", - "applies_to": [ - "csharp" - ], - "tags": [ - "Cryptography.Protocol.TLS" - ], - "severity": "moderate", - "overrides": null, - "patterns": [ - { - "pattern": "(SSL|TLS)(v)?([123]{1,2})", - "type": "regex", - "modifiers": null, - "scopes": [ - "code" - ], - "confidence": "high" - }, - { - "pattern": "SslStream|SecurityProtocolType\\.(Ssl|Tls)|SslPolicyErrors|onReceivedSslError|SslContext", - "type": "regex", - "modifiers": [ - "" - ], - "scopes": [ - "code" - ], - "confidence": "high" - } - ], - "conditions": [] - }, - { - "name": "Cryptography: SSL/TLS Protocol", - "id": "AI009700", - "description": "Cryptography: SSL/TLS Protocol", - "applies_to": [ - "c", - "cpp" - ], - "tags": [ - "Cryptography.Protocol.TLS" - ], - "severity": "moderate", - "overrides": null, - "patterns": [ - { - "pattern": "SECURITY_FLAG_", - "type": "regex", - "modifiers": null, - "scopes": [ - "code" - ], - "confidence": "high" - } - ], - "conditions": [ - { - "pattern": { - "pattern": "SECURITY_FLAG_IGNORE", - "type": "regex", - "modifiers": [ - "i" - ], - "scopes": [ - "code" - ], - "confidence": "medium" - }, - "search_in": "finding-region(-1,1)", - "negate_finding": true - } - ] - }, - { - "name": "Cryptography: SSL/TLS Protocol", - "id": "AI009800", - "description": "Cryptography: SSL/TLS Protocol", - "applies_to": [ - "c", - "objective-c", - "swift" - ], - "tags": [ - "Cryptography.Protocol.TLS" - ], - "severity": "moderate", - "overrides": null, - "patterns": [ - { - "pattern": "\\b((kCF|NS)StreamSocketSecurityLevel(None|SSLv2|SSLv3|TLSv1|NegotiatedSSL))\\b", - "type": "regex", - "modifiers": null, - "scopes": [ - "code" - ], - "confidence": "high" - }, - { - "pattern": "kSSLProtocol(2|3Only|All|Unknown)", - "type": "regex", - "modifiers": null, - "scopes": [ - "code" - ], - "confidence": "high" - }, - { - "pattern": "k(D)?(SSL|TLS)Protocol(1|1Only|2|3Only|All)", - "type": "regex", - "modifiers": null, - "scopes": [ - "code" - ], - "confidence": "high" - }, - { - "pattern": "\\b(ssl)\\b", - "type": "regex", - "modifiers": null, - "scopes": [ - "code" - ], - "confidence": "high" - }, - { - "pattern": "SSLCADNRequest|SSLCARevocation|SSLCompression|SSLEngine|SSLFIPS|SSLInsecureRenegotiation", - "type": "regex", - "modifiers": [ - "" - ], - "scopes": [ - "code" - ], - "confidence": "high" - }, - { - "pattern": "SSLOCSP(DefaultResponder|Enable|OverrideResponder|ProxyURL|ResponderTimeout|ResponseMaxAge|ResponseTimeSkew|UseRequestNonce)", - "type": "regex", - "modifiers": [ - "" - ], - "scopes": [ - "code" - ], - "confidence": "high" - }, - { - "pattern": "SSLOpenSSLConfCmd|SSLOptions|SSLPassPhraseDialog|SSLProtocol|SSLProxy", - "type": "regex", - "modifiers": [ - "" - ], - "scopes": [ - "code" - ], - "confidence": "high" - }, - { - "pattern": "SSLRandomSeed|SSLRenegBufferSize|SSLRequire|SSLSessionCache|SSLSRPUnknownUserSeed|SSLSRPVerifierFile|SSLStapling", - "type": "regex", - "modifiers": [ - "" - ], - "scopes": [ - "code" - ], - "confidence": "high" - }, - { - "pattern": "SSLStrictSNIVHostCheck|SSLUserName|SSLUseStapling|SSLVerify", - "type": "regex", - "modifiers": [ - "" - ], - "scopes": [ - "code" - ], - "confidence": "high" - } - ], - "conditions": [] - }, - { - "name": "Cryptography: SSH Protocol", - "id": "AI009900", - "description": "Cryptography: SSH Protocol", - "applies_to": null, - "tags": [ - "Cryptography.Protocol.SSH" - ], - "severity": "moderate", - "overrides": null, - "patterns": [ - { - "pattern": "\\b(ssh)\\b", - "type": "regex", - "modifiers": null, - "scopes": [ - "code" - ], - "confidence": "high" - } - ], - "conditions": [] - }, - { - "name": "Cryptography: SSH Protocol", - "id": "AI009910", - "description": "Cryptography: SSH Protocol", - "applies_to": null, - "tags": [ - "Cryptography.Protocol.KeyExchange" - ], - "severity": "moderate", - "overrides": null, - "patterns": [ - { - "pattern": "DiffieHellman|ECDsa", - "type": "regex", - "modifiers": [ - "i", - "comment" - ], - "scopes": [ - "code" - ], - "confidence": "high" - } - ], - "conditions": [] - }, - { - "name": "Cryptography: Key Derivation", - "id": "AI009300", - "description": "Cryptography: Key Derivation", - "applies_to": null, - "tags": [ - "Cryptography.KeyDerivation.General" - ], - "severity": "moderate", - "overrides": null, - "patterns": [ - { - "pattern": "KeyDerivationAlgorithmNames|SampleDeriveKeyMaterialPbkdf|RNGCryptoServiceProvider|Rfc2898DeriveBytes|KeyDerivation|DeriveKey|PasswordDeriveBytes", - "type": "regex", - "modifiers": [ - "i" - ], - "scopes": [ - "code" - ], - "confidence": "high" - } - ], - "conditions": [] - }, - { - "name": "Cryptography: Key Derivation (PBKDF1)", - "id": "AI009400", - "description": "Cryptography: Key Derivation (PBKDF1)", - "applies_to": null, - "tags": [ - "Cryptography.KeyDerivation.PBKDF1", - "Cryptography.HashAlgorithm.PBKDF1" - ], - "severity": "moderate", - "overrides": null, - "patterns": [ - { - "pattern": "pbkdf1", - "type": "regex", - "modifiers": [ - "i" - ], - "scopes": [ - "code" - ], - "confidence": "high" - } - ], - "conditions": [] - }, - { - "name": "Cryptography: Key Derivation (PBKDF2)", - "id": "AI009500", - "description": "Cryptography: Key Derivation (PBKDF2)", - "applies_to": null, - "tags": [ - "Cryptography.KeyDerivation.PBKDF2", - "Cryptography.HashAlgorithm.PBKDF1" - ], - "severity": "moderate", - "overrides": null, - "patterns": [ - { - "pattern": "\\b(pbkdf2)\\b", - "type": "regex", - "modifiers": [ - "i" - ], - "scopes": [ - "code" - ], - "confidence": "high" - } - ], - "conditions": [] - }, - { - "name": "Cryptographic Library: BouncyCastle", - "id": "AI008000", - "description": "Cryptographic Library: BouncyCastle", - "applies_to": [ - "csharp", - "java", - "kotlin", - "scala" - ], - "tags": [ - "Cryptography.Library.TLS.BouncyCastle" - ], - "severity": "moderate", - "overrides": null, - "patterns": [ - { - "pattern": "bouncycastle|spongycastle", - "type": "regex", - "modifiers": [ - "i" - ], - "scopes": [ - "code" - ], - "confidence": "high" - } - ], - "conditions": [] - }, - { - "name": "Cryptographic Library: mbed TLS", - "id": "AI008100", - "description": "Cryptographic Library: mbed TLS", - "applies_to": [], - "tags": [ - "Cryptography.Library.TLS.mbedTLS" - ], - "severity": "moderate", - "overrides": null, - "patterns": [ - { - "pattern": "\\b(mbedtls)\\b", - "type": "regex", - "modifiers": [ - "i" - ], - "scopes": [ - "code" - ], - "confidence": "high" - } - ], - "conditions": [] - }, - { - "name": "Cryptographic Library: OpenSSL", - "id": "AI008200", - "description": "Cryptographic Library: OpenSSL", - "applies_to": [], - "tags": [ - "Cryptography.Library.TLS.OpenSSL" - ], - "severity": "moderate", - "overrides": null, - "patterns": [ - { - "pattern": "openssl|SSL_CTX_new", - "type": "regex", - "modifiers": [ - "i" - ], - "scopes": [ - "code" - ], - "confidence": "high" - } - ], - "conditions": [] - }, - { - "name": "Cryptographic Library: BoringSSL", - "id": "AI008300", - "description": "Cryptographic Library: BoringSSL", - "applies_to": [], - "tags": [ - "Cryptography.Library.TLS.BoringSSL" - ], - "severity": "moderate", - "overrides": null, - "patterns": [ - { - "pattern": "\\b(boringssl)\\b", - "type": "regex", - "modifiers": [ - "i" - ], - "scopes": [ - "code" - ], - "confidence": "high" - } - ], - "conditions": [] - }, - { - "name": "Cryptographic Library: LibreSSL", - "id": "AI008400", - "description": "Cryptographic Library: LibreSSL", - "applies_to": [], - "tags": [ - "Cryptography.Library.TLS.LibreSSL" - ], - "severity": "moderate", - "overrides": null, - "patterns": [ - { - "pattern": "\\b(libressl)\\b", - "type": "regex", - "modifiers": [ - "i" - ], - "scopes": [ - "code" - ], - "confidence": "high" - } - ], - "conditions": [] - }, - { - "name": "Cryptographic Library: Win32", - "id": "AI008500", - "description": "Cryptographic Library: Win32", - "applies_to": [], - "tags": [ - "Cryptography.Library.Win32" - ], - "severity": "moderate", - "overrides": null, - "patterns": [ - { - "pattern": "\\b(wincrypt|cryptxml|wintrust|dpapi|bcrypt|cryptdlg|ncrypt|cryptxml|ncryptprotect)\\.h", - "type": "regex", - "modifiers": [ - "i" - ], - "scopes": [ - "code" - ], - "confidence": "high" - } - ], - "conditions": [] - }, - { - "name": "Cryptographic Library: .NET", - "id": "AI008600", - "description": "Cryptographic Library: .NET", - "applies_to": [ - "c", - "cpp", - "csharp" - ], - "tags": [ - "Cryptography.Library.Microsoft.NET" - ], - "severity": "moderate", - "overrides": null, - "patterns": [ - { - "pattern": "\\b(ProtectedData)\\b", - "type": "regex", - "modifiers": null, - "scopes": [ - "code" - ], - "confidence": "medium" - }, - { - "pattern": "\\b(DPAPI)\\b", - "type": "regex", - "modifiers": null, - "scopes": [ - "code" - ], - "confidence": "high" - } - ], - "conditions": [] - }, - { - "name": "Cryptography: Hash Algorithm (SHA-256)", - "id": "AI008700", - "description": "Cryptography: Hash Algorithm Usage (SHA-256)", - "applies_to": null, - "tags": [ - "Cryptography.HashAlgorithm.SHA2" - ], - "severity": "moderate", - "overrides": null, - "patterns": [ - { - "pattern": "SHA-*(2|224|256|384|512)", - "type": "regex", - "modifiers": [ - "i" - ], - "scopes": [ - "code" - ], - "confidence": "high" - } - ], - "conditions": [] - }, - { - "name": "Cryptography: Hash Algorithm (Legacy)", - "id": "AI008800", - "description": "Cryptography: Hash Algorithm (Legacy)", - "applies_to": null, - "tags": [ - "Cryptography.HashAlgorithm.Legacy" - ], - "severity": "moderate", - "overrides": null, - "patterns": [ - { - "pattern": "\\b(MD2|MD4|MD5|SHA-*(0|1))\\b", - "type": "regex", - "modifiers": [ - "i" - ], - "scopes": [ - "code", - "comment" - ], - "confidence": "high" - } - ], - "conditions": [] - }, - { - "name": "Cryptography: Hash Algorithm (SHA-3)", - "id": "AI008900", - "description": "Cryptography: Hash Algorithm Usage (SHA-3)", - "applies_to": null, - "tags": [ - "Cryptography.HashAlgorithm.SHA3" - ], - "severity": "moderate", - "overrides": null, - "patterns": [ - { - "pattern": "SHA-*3|Keccak", - "type": "regex", - "modifiers": [ - "i" - ], - "scopes": [ - "code" - ], - "confidence": "high" - } - ], - "conditions": [] - }, - { - "name": "Cryptography: Hash Algorithm (Misc)", - "id": "AI009000", - "description": "Cryptography: Hash Algorithm (Misc)", - "applies_to": null, - "tags": [ - "Cryptography.HashAlgorithm.Misc" - ], - "severity": "moderate", - "overrides": null, - "patterns": [ - { - "pattern": "RIPEMD|Blowfish|Twofish|Threefish|Serpent|HMAC|KeyedHashAlgorithm", - "type": "regex", - "modifiers": [ - "i" - ], - "scopes": [ - "code", - "comment" - ], - "confidence": "high" - } - ], - "conditions": [] - }, - { - "name": "Cryptography: Hash Algorithm", - "id": "AI009100", - "description": "Cryptography: Hash Algorithm Usage", - "applies_to": null, - "tags": [ - "Cryptography.HashAlgorithm.Other" - ], - "severity": "moderate", - "overrides": null, - "patterns": [ - { - "pattern": "HashAlgorithm|MessageDigest|DigestUtils", - "type": "regex", - "modifiers": [ - "i" - ], - "scopes": [ - "code" - ], - "confidence": "high" - } - ], - "conditions": [] - }, - { - "name": "Cryptography: Hash Algorithm (General)", - "id": "AI009200", - "description": "Cryptography: Hash Algorithm (General)", - "applies_to": null, - "tags": [ - "Cryptography.HashAlgorithm.General" - ], - "severity": "moderate", - "overrides": null, - "patterns": [ - { - "pattern": "hash", - "type": "regex", - "modifiers": [ - "i" - ], - "scopes": [ - "code", - "comment" - ], - "confidence": "medium" - } - ], - "conditions": [] - }, - { - "name": "Cryptography: Algorithm Implementation (SHA1)", - "id": "AI005800", - "description": "Cryptography: Algorithm Implementation (SHA1)", - "applies_to": null, - "tags": [ - "Cryptography.Implementation.SHA1" - ], - "severity": "important", - "overrides": null, - "patterns": [ - { - "pattern": "\\b(5a827999)\\b", - "type": "regex", - "modifiers": [ - "i" - ], - "scopes": [ - "code" - ], - "confidence": "high" - } - ], - "conditions": [] - }, - { - "name": "Cryptography: Algorithm Implementation (MD5)", - "id": "AI005900", - "description": "Cryptography: Algorithm Implementation (MD5)", - "applies_to": null, - "tags": [ - "Cryptography.Implementation.MD5" - ], - "severity": "important", - "overrides": null, - "patterns": [ - { - "pattern": "\\b(242070db)\\b", - "type": "regex", - "modifiers": [ - "i" - ], - "scopes": [ - "code" - ], - "confidence": "high" - } - ], - "conditions": [] - }, - { - "name": "Cryptography: Algorithm Implementation (SHA-256)", - "id": "AI006000", - "description": "Cryptography: Algorithm Implementation (SHA-256)", - "applies_to": null, - "tags": [ - "Cryptography.Implementation.SHA256" - ], - "severity": "important", - "overrides": null, - "patterns": [ - { - "pattern": "\\b(d807aa98)\\b", - "type": "regex", - "modifiers": [ - "i" - ], - "scopes": [ - "code" - ], - "confidence": "high" - } - ], - "conditions": [] - }, - { - "name": "Cryptography: Algorithm Implementation (Keccak)", - "id": "AI006100", - "description": "Cryptography: Algorithm Implementation (Keccak)", - "applies_to": null, - "tags": [ - "Cryptography.Implementation.SHA256" - ], - "severity": "important", - "overrides": null, - "patterns": [ - { - "pattern": "\\b(800000000000808A)\\b", - "type": "regex", - "modifiers": [ - "i" - ], - "scopes": [ - "code" - ], - "confidence": "high" - } - ], - "conditions": [] - }, - { - "name": "Component: Adobe Flash", - "id": "AI004900", - "description": "Component: Adobe Flash", - "applies_to": [], - "tags": [ - "Component.Executable.Adobe.Flash" - ], - "severity": "moderate", - "overrides": null, - "patterns": [ - { - "pattern": "\\.(swf|flv)", - "type": "regex", - "modifiers": [ - "i" - ], - "scopes": [ - "code", - "comment" - ], - "confidence": "high" - }, - { - "pattern": "\\b(adobe\\ flash)\\b", - "type": "regex", - "modifiers": [ - "i" - ], - "scopes": [ - "code", - "comment" - ], - "confidence": "medium" - }, - { - "pattern": "\\b(flash)\\b", - "type": "regex", - "modifiers": [ - "i" - ], - "scopes": [ - "code", - "comment" - ], - "confidence": "low" - } - ], - "conditions": [] - }, - { - "name": "Component: Active-X", - "id": "AI005000", - "description": "Component: Active-X", - "applies_to": [ - "c", - "cpp", - "csharp", - "vb" - ], - "tags": [ - "Component.Executable.Microsoft.ActiveX" - ], - "severity": "moderate", - "overrides": null, - "patterns": [ - { - "pattern": "\\b(CoInitialize|CoCreateInstance|comClassInterface|CLSCTX_INPROC_SERVER|ProgId|COleControlModule|ComDefaultInterface|IOleInPlaceObject|IOleControl|IOleObjective)\\b", - "type": "regex", - "modifiers": [ - "i" - ], - "scopes": [ - "code", - "comment" - ], - "confidence": "high" - }, - { - "pattern": "active-?x|CreateObject", - "type": "regex", - "modifiers": [ - "i" - ], - "scopes": [ - "code", - "comment" - ], - "confidence": "medium" - } - ], - "conditions": [] - }, - { - "name": "Component: Active-X", - "id": "AI005010", - "description": "Component: Active-X", - "applies_to": [ - "javascript", - "typescript" - ], - "tags": [ - "Component.Executable.Microsoft.ActiveX" - ], - "severity": "moderate", - "overrides": null, - "patterns": [ - { - "pattern": "\\b(new\\ ActiveXObject)\\b", - "type": "regex", - "modifiers": [ - "i" - ], - "scopes": [ - "code" - ], - "confidence": "high" - } - ], - "conditions": [] - }, - { - "name": "Component: COM", - "id": "AI005100", - "description": "Component: COM", - "applies_to": [ - "c", - "cpp", - "csharp" - ], - "tags": [ - "Component.Executable.Microsoft.COM" - ], - "severity": "moderate", - "overrides": null, - "patterns": [ - { - "pattern": "\\b(CLSCTX_INPROC_SERVER|CLSCTX_INPROC_HANDLER|CLSCTX_LOCAL_SERVER|CoCreateInstance)\\b", - "type": "regex", - "modifiers": null, - "scopes": [ - "code" - ], - "confidence": "high" - } - ], - "conditions": [] - }, - { - "name": "Component: PDF", - "id": "AI005200", - "description": "Component: PDF", - "applies_to": [ - "c", - "cpp", - "csharp" - ], - "tags": [ - "Component.Executable.Adobe.PDF" - ], - "severity": "moderate", - "overrides": null, - "patterns": [ - { - "pattern": "\\b(\\.pdf)\\b", - "type": "regex", - "modifiers": null, - "scopes": [ - "code" - ], - "confidence": "high" - } - ], - "conditions": [] - }, - { - "name": "Component: Microsoft Silverlight", - "id": "AI005300", - "description": "Component: Microsoft Silverlight", - "applies_to": null, - "tags": [ - "Component.Executable.Microsoft.Silverlight" - ], - "severity": "moderate", - "overrides": null, - "patterns": [ - { - "pattern": "\\b(silverlight\\|\\\\\\.xap)\\b", - "type": "regex", - "modifiers": [ - "i" - ], - "scopes": [ - "code" - ], - "confidence": "high" - } - ], - "conditions": [] - }, - { - "name": "Component: Windows DLL", - "id": "AI005400", - "description": "Component: Windows DLL", - "applies_to": [ - "csharp" - ], - "tags": [ - "Component.Executable.Microsoft.DLL" - ], - "severity": "moderate", - "overrides": null, - "patterns": [ - { - "pattern": "DllImport|Assembly\\.LoadFile|Assembly\\.LoadFrom", - "type": "regex", - "modifiers": [ - "i" - ], - "scopes": [ - "code" - ], - "confidence": "high" - } - ], - "conditions": [] - }, - { - "name": "Component: Windows DLL", - "id": "AI005500", - "description": "Component: Windows DLL", - "applies_to": [ - "c", - "cpp" - ], - "tags": [ - "Component.Executable.Microsoft.DLL" - ], - "severity": "moderate", - "overrides": null, - "patterns": [ - { - "pattern": "\\b(LoadLibrary)\\b", - "type": "regex", - "modifiers": [ - "i" - ], - "scopes": [ - "code" - ], - "confidence": "high" - } - ], - "conditions": [] - }, - { - "name": "Component: Windows DLL", - "id": "AI005600", - "description": "Component: Windows DLL", - "applies_to": [ - "python", - "java" - ], - "tags": [ - "Component.Executable.Microsoft.DLL" - ], - "severity": "moderate", - "overrides": null, - "patterns": [ - { - "pattern": "System\\.Load|ctypes\\.WinDLL", - "type": "regex", - "modifiers": [ - "i" - ], - "scopes": [ - "code" - ], - "confidence": "high" - } - ], - "conditions": [] - }, - { - "name": "Testing Framework: AceUnit", - "id": "AI040700", - "description": "Testing Framework: AceUnit", - "applies_to": [ - "c", - "cpp" - ], - "tags": [ - "Framework.Testing.AceUnit" - ], - "severity": "moderate", - "overrides": null, - "patterns": [ - { - "pattern": "\\b(aceunit)\\b", - "type": "regex", - "modifiers": [ - "i" - ], - "scopes": [ - "code", - "comment" - ], - "confidence": "high" - } - ], - "conditions": [] - }, - { - "name": "Testing Framework: Eryn", - "id": "AI040800", - "description": "Testing Framework: Eryn", - "applies_to": [ - "c", - "cpp" - ], - "tags": [ - "Framework.Testing.Eryn" - ], - "severity": "moderate", - "overrides": null, - "patterns": [ - { - "pattern": "\\b(eryn)\\b", - "type": "regex", - "modifiers": [ - "i" - ], - "scopes": [ - "code" - ], - "confidence": "high" - } - ], - "conditions": [] - }, - { - "name": "Testing Framework: Autounit", - "id": "AI040900", - "description": "Testing Framework: Autounit", - "applies_to": [ - "c", - "cpp" - ], - "tags": [ - "Framework.Testing.Autounit" - ], - "severity": "moderate", - "overrides": null, - "patterns": [ - { - "pattern": "\\b(autounit)\\b", - "type": "regex", - "modifiers": [ - "i" - ], - "scopes": [ - "code" - ], - "confidence": "high" - } - ], - "conditions": [] - }, - { - "name": "Testing Framework: Andit", - "id": "AI041000", - "description": "Testing Framework: Andit", - "applies_to": [ - "c", - "cpp" - ], - "tags": [ - "Framework.Testing.Andit" - ], - "severity": "moderate", - "overrides": null, - "patterns": [ - { - "pattern": "\\b(andit)\\b", - "type": "regex", - "modifiers": [ - "i" - ], - "scopes": [ - "code" - ], - "confidence": "high" - } - ], - "conditions": [] - }, - { - "name": "Testing Framework: Boost", - "id": "AI041100", - "description": "Testing Framework: Boost", - "applies_to": [ - "c", - "cpp" - ], - "tags": [ - "Framework.Testing.Boost" - ], - "severity": "moderate", - "overrides": null, - "patterns": [ - { - "pattern": "\\b(boost/test)\\b", - "type": "regex", - "modifiers": [ - "i" - ], - "scopes": [ - "code" - ], - "confidence": "high" - } - ], - "conditions": [] - }, - { - "name": "Testing Framework: BugEye", - "id": "AI041200", - "description": "Testing Framework: BugEye", - "applies_to": [ - "c", - "cpp" - ], - "tags": [ - "Framework.Testing.BugEye" - ], - "severity": "moderate", - "overrides": null, - "patterns": [ - { - "pattern": "\\b(bugeye)\\b", - "type": "regex", - "modifiers": [ - "i" - ], - "scopes": [ - "code" - ], - "confidence": "high" - } - ], - "conditions": [] - }, - { - "name": "Testing Framework: Catch2", - "id": "AI041300", - "description": "Testing Framework: Catch2", - "applies_to": [ - "c", - "cpp" - ], - "tags": [ - "Framework.Testing.Catch2" - ], - "severity": "moderate", - "overrides": null, - "patterns": [ - { - "pattern": "\\b(catch\\.hpp)\\b", - "type": "regex", - "modifiers": [ - "i" - ], - "scopes": [ - "code" - ], - "confidence": "high" - } - ], - "conditions": [] - }, - { - "name": "Testing Framework: Catsrunner", - "id": "AI041400", - "description": "Testing Framework: Catsrunner", - "applies_to": [ - "c", - "cpp" - ], - "tags": [ - "Framework.Testing.Catsrunner" - ], - "severity": "moderate", - "overrides": null, - "patterns": [ - { - "pattern": "\\b(catsrunner)\\b", - "type": "regex", - "modifiers": [ - "i" - ], - "scopes": [ - "code" - ], - "confidence": "high" - } - ], - "conditions": [] - }, - { - "name": "Testing Framework: cfix ", - "id": "AI041500", - "description": "Testing Framework: cfix ", - "applies_to": [ - "c", - "cpp" - ], - "tags": [ - "Framework.Testing.Cfix" - ], - "severity": "moderate", - "overrides": null, - "patterns": [ - { - "pattern": "\\b(cfix)\\b", - "type": "regex", - "modifiers": [ - "i" - ], - "scopes": [ - "code" - ], - "confidence": "high" - } - ], - "conditions": [] - }, - { - "name": "Testing Framework: Cgreen", - "id": "AI041600", - "description": "Testing Framework: Cgreen", - "applies_to": [ - "c", - "cpp" - ], - "tags": [ - "Framework.Testing.Cgreen" - ], - "severity": "moderate", - "overrides": null, - "patterns": [ - { - "pattern": "\\b(cgreen)\\b", - "type": "regex", - "modifiers": [ - "i" - ], - "scopes": [ - "code" - ], - "confidence": "high" - } - ], - "conditions": [] - }, - { - "name": "Testing Framework: Pester", - "id": "AI051800", - "description": "Testing Framework: Pester", - "applies_to": [ - "powershell" - ], - "tags": [ - "Framework.Testing.Pester" - ], - "severity": "moderate", - "overrides": null, - "patterns": [ - { - "pattern": "\\b(ester)\\b", - "type": "regex", - "modifiers": [ - "i" - ], - "scopes": [ - "code", - "comment" - ], - "confidence": "medium" - } - ], - "conditions": [] - }, - { - "name": "Testing Framework: AutoTest", - "id": "AI051900", - "description": "Testing Framework: AutoTest", - "applies_to": [ - "python" - ], - "tags": [ - "Framework.Testing.AutoTest" - ], - "severity": "moderate", - "overrides": null, - "patterns": [ - { - "pattern": "\\b(autotest)\\b", - "type": "regex", - "modifiers": [ - "i" - ], - "scopes": [ - "code" - ], - "confidence": "high" - } - ], - "conditions": [] - }, - { - "name": "Testing Framework: UnitTest", - "id": "AI052000", - "description": "Testing Framework: UnitTest", - "applies_to": [ - "python" - ], - "tags": [ - "Framework.Testing.unittest" - ], - "severity": "moderate", - "overrides": null, - "patterns": [ - { - "pattern": "\\b(unittest)\\b", - "type": "regex", - "modifiers": null, - "scopes": [ - "code" - ], - "confidence": "high" - } - ], - "conditions": [] - }, - { - "name": "Testing Framework: XPyUnit", - "id": "AI052100", - "description": "Testing Framework: XPyUnit", - "applies_to": [ - "python" - ], - "tags": [ - "Framework.Testing.XPyUnit" - ], - "severity": "moderate", - "overrides": null, - "patterns": [ - { - "pattern": "\\b(xpyunit)\\b", - "type": "regex", - "modifiers": null, - "scopes": [ - "code" - ], - "confidence": "high" - } - ], - "conditions": [] - }, - { - "name": "Testing Framework: DocTest", - "id": "AI052200", - "description": "Testing Framework: DocTest", - "applies_to": [ - "python" - ], - "tags": [ - "Framework.Testing.Doctest" - ], - "severity": "moderate", - "overrides": null, - "patterns": [ - { - "pattern": "\\b(doctest)\\b", - "type": "regex", - "modifiers": null, - "scopes": [ - "code" - ], - "confidence": "high" - } - ], - "conditions": [] - }, - { - "name": "Testing Framework: Nose", - "id": "AI052300", - "description": "Testing Framework: Nose", - "applies_to": [ - "python" - ], - "tags": [ - "Framework.Testing.Nose" - ], - "severity": "moderate", - "overrides": null, - "patterns": [ - { - "pattern": "import .*nose|nosetests|nose\\.run", - "type": "regex", - "modifiers": null, - "scopes": [ - "code" - ], - "confidence": "high" - } - ], - "conditions": [] - }, - { - "name": "Testing Framework: PyTest", - "id": "AI052400", - "description": "Testing Framework: PyTest", - "applies_to": [ - "python" - ], - "tags": [ - "Framework.Testing.PyTest" - ], - "severity": "moderate", - "overrides": null, - "patterns": [ - { - "pattern": "\\b(pytest)\\b", - "type": "regex", - "modifiers": null, - "scopes": [ - "code" - ], - "confidence": "high" - } - ], - "conditions": [] - }, - { - "name": "Testing Framework: Should DSL", - "id": "AI052500", - "description": "Testing Framework: Should DSL", - "applies_to": [ - "python" - ], - "tags": [ - "Framework.Testing.ShouldDSL" - ], - "severity": "moderate", - "overrides": null, - "patterns": [ - { - "pattern": "\\b(should_dsl)\\b", - "type": "regex", - "modifiers": null, - "scopes": [ - "code" - ], - "confidence": "high" - } - ], - "conditions": [] - }, - { - "name": "Testing Framework: Artos", - "id": "AI046300", - "description": "Testing Framework: Artos", - "applies_to": [ - "java" - ], - "tags": [ - "Framework.Testing.Artos" - ], - "severity": "moderate", - "overrides": null, - "patterns": [ - { - "pattern": "\\b(artos)\\b", - "type": "regex", - "modifiers": [ - "i" - ], - "scopes": [ - "code" - ], - "confidence": "high" - } - ], - "conditions": [] - }, - { - "name": "Testing Framework: Arquillian", - "id": "AI046400", - "description": "Testing Framework: Arquillian", - "applies_to": [ - "java" - ], - "tags": [ - "Framework.Testing.Arquillian" - ], - "severity": "moderate", - "overrides": null, - "patterns": [ - { - "pattern": "\\b(Arquillian)\\b", - "type": "regex", - "modifiers": [ - "i" - ], - "scopes": [ - "code" - ], - "confidence": "high" - } - ], - "conditions": [] - }, - { - "name": "Testing Framework: AssertJ", - "id": "AI046500", - "description": "Testing Framework: AssertJ", - "applies_to": [ - "java" - ], - "tags": [ - "Framework.Testing.AssertJ" - ], - "severity": "moderate", - "overrides": null, - "patterns": [ - { - "pattern": "\\b(AssertJ)\\b", - "type": "regex", - "modifiers": [ - "i" - ], - "scopes": [ - "code" - ], - "confidence": "high" - } - ], - "conditions": [] - }, - { - "name": "Testing Framework: BeanSpec", - "id": "AI046600", - "description": "Testing Framework: BeanSpec", - "applies_to": [ - "java" - ], - "tags": [ - "Framework.Testing.BeanSpec" - ], - "severity": "moderate", - "overrides": null, - "patterns": [ - { - "pattern": "\\b(beanspec)\\b", - "type": "regex", - "modifiers": [ - "i" - ], - "scopes": [ - "code" - ], - "confidence": "high" - } - ], - "conditions": [] - }, - { - "name": "Testing Framework: BeanTest", - "id": "AI046700", - "description": "Testing Framework: BeanTest", - "applies_to": [ - "java" - ], - "tags": [ - "Framework.Testing.BeanTest" - ], - "severity": "moderate", - "overrides": null, - "patterns": [ - { - "pattern": "\\b(BeanTest)\\b", - "type": "regex", - "modifiers": [ - "i" - ], - "scopes": [ - "code" - ], - "confidence": "high" - } - ], - "conditions": [] - }, - { - "name": "Testing Framework: Cactus", - "id": "AI046800", - "description": "Testing Framework: Cactus", - "applies_to": [ - "java" - ], - "tags": [ - "Framework.Testing.Cactus" - ], - "severity": "moderate", - "overrides": null, - "patterns": [ - { - "pattern": "\\b(Cactus)\\b", - "type": "regex", - "modifiers": [ - "i" - ], - "scopes": [ - "code" - ], - "confidence": "high" - } - ], - "conditions": [] - }, - { - "name": "Testing Framework: Concordion", - "id": "AI046900", - "description": "Testing Framework: Concordion", - "applies_to": [ - "java" - ], - "tags": [ - "Framework.Testing.Concordion" - ], - "severity": "moderate", - "overrides": null, - "patterns": [ - { - "pattern": "\\b(Concordion)\\b", - "type": "regex", - "modifiers": [ - "i" - ], - "scopes": [ - "code" - ], - "confidence": "high" - } - ], - "conditions": [] - }, - { - "name": "Testing Framework: Concutest", - "id": "AI047000", - "description": "Testing Framework: Concutest", - "applies_to": [ - "java" - ], - "tags": [ - "Framework.Testing.Concutest" - ], - "severity": "moderate", - "overrides": null, - "patterns": [ - { - "pattern": "\\b(Concutest)\\b", - "type": "regex", - "modifiers": [ - "i" - ], - "scopes": [ - "code" - ], - "confidence": "high" - } - ], - "conditions": [] - }, - { - "name": "Testing Framework: Cucumber", - "id": "AI047100", - "description": "Testing Framework: Cucumber", - "applies_to": [ - "java" - ], - "tags": [ - "Framework.Testing.Cucumber" - ], - "severity": "moderate", - "overrides": null, - "patterns": [ - { - "pattern": "\\b(io\\.cucumber)\\b", - "type": "regex", - "modifiers": [ - "i" - ], - "scopes": [ - "code" - ], - "confidence": "high" - } - ], - "conditions": [] - }, - { - "name": "Testing Framework: Cuppa", - "id": "AI047200", - "description": "Testing Framework: Cuppa", - "applies_to": [ - "java" - ], - "tags": [ - "Framework.Testing.Cuppa" - ], - "severity": "moderate", - "overrides": null, - "patterns": [ - { - "pattern": "\\b(Cuppa)\\b", - "type": "regex", - "modifiers": [ - "i" - ], - "scopes": [ - "code" - ], - "confidence": "high" - } - ], - "conditions": [] - }, - { - "name": "Testing Framework: DbUnit", - "id": "AI047300", - "description": "Testing Framework: DbUnit", - "applies_to": [ - "java" - ], - "tags": [ - "Framework.Testing.DbUnit" - ], - "severity": "moderate", - "overrides": null, - "patterns": [ - { - "pattern": "\\b(DbUnit)\\b", - "type": "regex", - "modifiers": [ - "i" - ], - "scopes": [ - "code" - ], - "confidence": "high" - } - ], - "conditions": [] - }, - { - "name": "Testing Framework: EasyMock", - "id": "AI047400", - "description": "Testing Framework: EasyMock", - "applies_to": [ - "java" - ], - "tags": [ - "Framework.Testing.EasyMock" - ], - "severity": "moderate", - "overrides": null, - "patterns": [ - { - "pattern": "\\b(EasyMock)\\b", - "type": "regex", - "modifiers": [ - "i" - ], - "scopes": [ - "code" - ], - "confidence": "high" - } - ], - "conditions": [] - }, - { - "name": "Testing Framework: EtlUnit", - "id": "AI047500", - "description": "Testing Framework: EtlUnit", - "applies_to": [ - "java" - ], - "tags": [ - "Framework.Testing.EtlUnit" - ], - "severity": "moderate", - "overrides": null, - "patterns": [ - { - "pattern": "\\b(EtlUnit)\\b", - "type": "regex", - "modifiers": [ - "i" - ], - "scopes": [ - "code" - ], - "confidence": "high" - } - ], - "conditions": [] - }, - { - "name": "Testing Framework: EvoSuite", - "id": "AI047600", - "description": "Testing Framework: EvoSuite", - "applies_to": [ - "java" - ], - "tags": [ - "Framework.Testing.EvoSuite" - ], - "severity": "moderate", - "overrides": null, - "patterns": [ - { - "pattern": "\\b(EvoSuite)\\b", - "type": "regex", - "modifiers": [ - "i" - ], - "scopes": [ - "code" - ], - "confidence": "high" - } - ], - "conditions": [] - }, - { - "name": "Testing Framework: GrandTestAuto", - "id": "AI047700", - "description": "Testing Framework: GrandTestAuto", - "applies_to": [ - "java" - ], - "tags": [ - "Framework.Testing.GrandTestAuto" - ], - "severity": "moderate", - "overrides": null, - "patterns": [ - { - "pattern": "\\b(GrandTestAuto)\\b", - "type": "regex", - "modifiers": [ - "i" - ], - "scopes": [ - "code", - "comment" - ], - "confidence": "high" - } - ], - "conditions": [] - }, - { - "name": "Testing Framework: GroboUtils", - "id": "AI047800", - "description": "Testing Framework: GroboUtils", - "applies_to": [ - "java" - ], - "tags": [ - "Framework.Testing.GroboUtils" - ], - "severity": "moderate", - "overrides": null, - "patterns": [ - { - "pattern": "\\b(GroboUtils)\\b", - "type": "regex", - "modifiers": [ - "i" - ], - "scopes": [ - "code" - ], - "confidence": "high" - } - ], - "conditions": [] - }, - { - "name": "Testing Framework: HavaRunner", - "id": "AI047900", - "description": "Testing Framework: HavaRunner", - "applies_to": [ - "java" - ], - "tags": [ - "Framework.Testing.HavaRunner" - ], - "severity": "moderate", - "overrides": null, - "patterns": [ - { - "pattern": "\\b(HavaRunner)\\b", - "type": "regex", - "modifiers": [ - "i" - ], - "scopes": [ - "code" - ], - "confidence": "high" - } - ], - "conditions": [] - }, - { - "name": "Testing Framework: Instinct", - "id": "AI048000", - "description": "Testing Framework: Instinct", - "applies_to": [ - "java" - ], - "tags": [ - "Framework.Testing.Instinct" - ], - "severity": "moderate", - "overrides": null, - "patterns": [ - { - "pattern": "\\b(Instinct)\\b", - "type": "regex", - "modifiers": [ - "i" - ], - "scopes": [ - "code" - ], - "confidence": "low" - } - ], - "conditions": [] - }, - { - "name": "Testing Framework: JSST", - "id": "AI048100", - "description": "Testing Framework: JSST", - "applies_to": [ - "java" - ], - "tags": [ - "Framework.Testing.JSST" - ], - "severity": "moderate", - "overrides": null, - "patterns": [ - { - "pattern": "\\b(JSST)\\b", - "type": "regex", - "modifiers": [ - "i" - ], - "scopes": [ - "code", - "comment" - ], - "confidence": "high" - } - ], - "conditions": [] - }, - { - "name": "Testing Framework: JBehave", - "id": "AI048200", - "description": "Testing Framework: JBehave", - "applies_to": [ - "java" - ], - "tags": [ - "Framework.Testing.JBehave" - ], - "severity": "moderate", - "overrides": null, - "patterns": [ - { - "pattern": "\\b(JBehave)\\b", - "type": "regex", - "modifiers": [ - "i" - ], - "scopes": [ - "code", - "comment" - ], - "confidence": "high" - } - ], - "conditions": [] - }, - { - "name": "Testing Framework: JDave", - "id": "AI048300", - "description": "Testing Framework: JDave", - "applies_to": [ - "java" - ], - "tags": [ - "Framework.Testing.JDave" - ], - "severity": "moderate", - "overrides": null, - "patterns": [ - { - "pattern": "\\b(JDave)\\b", - "type": "regex", - "modifiers": [ - "i" - ], - "scopes": [ - "code" - ], - "confidence": "high" - } - ], - "conditions": [] - }, - { - "name": "Testing Framework: JExample", - "id": "AI048400", - "description": "Testing Framework: JExample", - "applies_to": [ - "java" - ], - "tags": [ - "Framework.Testing.JExample" - ], - "severity": "moderate", - "overrides": null, - "patterns": [ - { - "pattern": "\\b(jexample)\\b", - "type": "regex", - "modifiers": [ - "i" - ], - "scopes": [ - "code" - ], - "confidence": "high" - } - ], - "conditions": [] - }, - { - "name": "Testing Framework: JGiven", - "id": "AI048500", - "description": "Testing Framework: JGiven", - "applies_to": [ - "java" - ], - "tags": [ - "Framework.Testing.JGiven" - ], - "severity": "moderate", - "overrides": null, - "patterns": [ - { - "pattern": "\\b(jgiven)\\b", - "type": "regex", - "modifiers": [ - "i" - ], - "scopes": [ - "code" - ], - "confidence": "high" - } - ], - "conditions": [] - }, - { - "name": "Testing Framework: JMock", - "id": "AI048600", - "description": "Testing Framework: JMock", - "applies_to": [ - "java" - ], - "tags": [ - "Framework.Testing.JMock" - ], - "severity": "moderate", - "overrides": null, - "patterns": [ - { - "pattern": "\\b(jmock)\\b", - "type": "regex", - "modifiers": [ - "i" - ], - "scopes": [ - "code" - ], - "confidence": "high" - } - ], - "conditions": [] - }, - { - "name": "Testing Framework: JMockit", - "id": "AI048700", - "description": "Testing Framework: JMockit", - "applies_to": [ - "java" - ], - "tags": [ - "Framework.Testing.JMockit" - ], - "severity": "moderate", - "overrides": null, - "patterns": [ - { - "pattern": "\\b(jmockit)\\b", - "type": "regex", - "modifiers": [ - "i" - ], - "scopes": [ - "code" - ], - "confidence": "high" - } - ], - "conditions": [] - }, - { - "name": "Testing Framework: Jnario", - "id": "AI048800", - "description": "Testing Framework: Jnario", - "applies_to": [ - "java" - ], - "tags": [ - "Framework.Testing.Jnario" - ], - "severity": "moderate", - "overrides": null, - "patterns": [ - { - "pattern": "\\b(Jnario)\\b", - "type": "regex", - "modifiers": [ - "i" - ], - "scopes": [ - "code" - ], - "confidence": "high" - } - ], - "conditions": [] - }, - { - "name": "Testing Framework: Jtest", - "id": "AI048900", - "description": "Testing Framework: Jtest", - "applies_to": [ - "java" - ], - "tags": [ - "Framework.Testing.Jtest" - ], - "severity": "moderate", - "overrides": null, - "patterns": [ - { - "pattern": "\\b(jtest)\\b", - "type": "regex", - "modifiers": [ - "i" - ], - "scopes": [ - "code" - ], - "confidence": "high" - } - ], - "conditions": [] - }, - { - "name": "Testing Framework: Jukito", - "id": "AI049000", - "description": "Testing Framework: Jukito", - "applies_to": [ - "java" - ], - "tags": [ - "Framework.Testing.Jukito" - ], - "severity": "moderate", - "overrides": null, - "patterns": [ - { - "pattern": "\\b(jukito)\\b", - "type": "regex", - "modifiers": [ - "i" - ], - "scopes": [ - "code" - ], - "confidence": "high" - } - ], - "conditions": [] - }, - { - "name": "Testing Framework: JUnit", - "id": "AI049100", - "description": "Testing Framework: JUnit", - "applies_to": [ - "java" - ], - "tags": [ - "Framework.Testing.JUnit" - ], - "severity": "moderate", - "overrides": null, - "patterns": [ - { - "pattern": "\\b(junit)\\b", - "type": "regex", - "modifiers": [ - "i" - ], - "scopes": [ - "code", - "comment" - ], - "confidence": "high" - } - ], - "conditions": [] - }, - { - "name": "Testing Framework: JUnitEE", - "id": "AI049200", - "description": "Testing Framework: JUnitEE", - "applies_to": [ - "java" - ], - "tags": [ - "Framework.Testing.JUnitEE" - ], - "severity": "moderate", - "overrides": null, - "patterns": [ - { - "pattern": "\\b(junitee)\\b", - "type": "regex", - "modifiers": [ - "i" - ], - "scopes": [ - "code" - ], - "confidence": "high" - } - ], - "conditions": [] - }, - { - "name": "Testing Framework: JWalk", - "id": "AI049300", - "description": "Testing Framework: JWalk", - "applies_to": [ - "java" - ], - "tags": [ - "Framework.Testing.JWalk" - ], - "severity": "moderate", - "overrides": null, - "patterns": [ - { - "pattern": "\\b(jwalk)\\b", - "type": "regex", - "modifiers": [ - "i" - ], - "scopes": [ - "code" - ], - "confidence": "high" - } - ], - "conditions": [] - }, - { - "name": "Testing Framework: Mockito", - "id": "AI049400", - "description": "Testing Framework: Mockito", - "applies_to": [ - "java" - ], - "tags": [ - "Framework.Testing.Mockito" - ], - "severity": "moderate", - "overrides": null, - "patterns": [ - { - "pattern": "\\b(mockito)\\b", - "type": "regex", - "modifiers": [ - "i" - ], - "scopes": [ - "code" - ], - "confidence": "high" - } - ], - "conditions": [] - }, - { - "name": "Testing Framework: Mockrunner", - "id": "AI049500", - "description": "Testing Framework: Mockrunner", - "applies_to": [ - "java" - ], - "tags": [ - "Framework.Testing.Mockrunner" - ], - "severity": "moderate", - "overrides": null, - "patterns": [ - { - "pattern": "\\b(mockrunner)\\b", - "type": "regex", - "modifiers": [ - "i" - ], - "scopes": [ - "code" - ], - "confidence": "high" - } - ], - "conditions": [] - }, - { - "name": "Testing Framework: Needle", - "id": "AI049600", - "description": "Testing Framework: Needle", - "applies_to": [ - "java" - ], - "tags": [ - "Framework.Testing.Needle" - ], - "severity": "moderate", - "overrides": null, - "patterns": [ - { - "pattern": "\\b(needle)\\b", - "type": "regex", - "modifiers": [ - "i" - ], - "scopes": [ - "code" - ], - "confidence": "high" - } - ], - "conditions": [] - }, - { - "name": "Testing Framework: NUTester", - "id": "AI049700", - "description": "Testing Framework: NUTester", - "applies_to": [ - "java" - ], - "tags": [ - "Framework.Testing.NUTester" - ], - "severity": "moderate", - "overrides": null, - "patterns": [ - { - "pattern": "\\b(NUTester)\\b", - "type": "regex", - "modifiers": [ - "i" - ], - "scopes": [ - "code" - ], - "confidence": "high" - } - ], - "conditions": [] - }, - { - "name": "Testing Framework: OpenPojo", - "id": "AI049800", - "description": "Testing Framework: OpenPojo", - "applies_to": [ - "java" - ], - "tags": [ - "Framework.Testing.OpenPojo" - ], - "severity": "moderate", - "overrides": null, - "patterns": [ - { - "pattern": "\\b(openpojo)\\b", - "type": "regex", - "modifiers": [ - "i" - ], - "scopes": [ - "code" - ], - "confidence": "high" - } - ], - "conditions": [] - }, - { - "name": "Testing Framework: PowerMock", - "id": "AI049900", - "description": "Testing Framework: PowerMock", - "applies_to": [ - "java" - ], - "tags": [ - "Framework.Testing.PowerMock" - ], - "severity": "moderate", - "overrides": null, - "patterns": [ - { - "pattern": "\\b(powermock)\\b", - "type": "regex", - "modifiers": [ - "i" - ], - "scopes": [ - "code" - ], - "confidence": "high" - } - ], - "conditions": [] - }, - { - "name": "Testing Framework: Randoop", - "id": "AI050000", - "description": "Testing Framework: Randoop", - "applies_to": [ - "java" - ], - "tags": [ - "Framework.Testing.Randoop" - ], - "severity": "moderate", - "overrides": null, - "patterns": [ - { - "pattern": "\\b(randoop)\\b", - "type": "regex", - "modifiers": [ - "i" - ], - "scopes": [ - "code" - ], - "confidence": "high" - } - ], - "conditions": [] - }, - { - "name": "Testing Framework: Spock", - "id": "AI050100", - "description": "Testing Framework: Spock", - "applies_to": [ - "java" - ], - "tags": [ - "Framework.Testing.Spock" - ], - "severity": "moderate", - "overrides": null, - "patterns": [ - { - "pattern": "\\b(spock)\\b", - "type": "regex", - "modifiers": [ - "i" - ], - "scopes": [ - "code" - ], - "confidence": "low" - } - ], - "conditions": [] - }, - { - "name": "Testing Framework: SpryTest", - "id": "AI050200", - "description": "Testing Framework: SpryTest", - "applies_to": [ - "java" - ], - "tags": [ - "Framework.Testing.SpryTest" - ], - "severity": "moderate", - "overrides": null, - "patterns": [ - { - "pattern": "\\b(sprytest)\\b", - "type": "regex", - "modifiers": [ - "i" - ], - "scopes": [ - "code" - ], - "confidence": "high" - } - ], - "conditions": [] - }, - { - "name": "Testing Framework:SureAssert ", - "id": "AI050300", - "description": "Testing Framework: SureAssert", - "applies_to": [ - "java" - ], - "tags": [ - "Framework.Testing.SureAssert" - ], - "severity": "moderate", - "overrides": null, - "patterns": [ - { - "pattern": "\\b(sureassert)\\b", - "type": "regex", - "modifiers": [ - "i" - ], - "scopes": [ - "code" - ], - "confidence": "high" - } - ], - "conditions": [] - }, - { - "name": "Testing Framework: Tacinga", - "id": "AI050400", - "description": "Testing Framework: Tacinga", - "applies_to": [ - "java" - ], - "tags": [ - "Framework.Testing.Tacinga" - ], - "severity": "moderate", - "overrides": null, - "patterns": [ - { - "pattern": "\\b(tacinga)\\b", - "type": "regex", - "modifiers": [ - "i" - ], - "scopes": [ - "code" - ], - "confidence": "high" - } - ], - "conditions": [] - }, - { - "name": "Testing Framework: TestNG", - "id": "AI050500", - "description": "Testing Framework: TestNG", - "applies_to": [ - "java" - ], - "tags": [ - "Framework.Testing.TestNG" - ], - "severity": "moderate", - "overrides": null, - "patterns": [ - { - "pattern": "\\b(testng)\\b", - "type": "regex", - "modifiers": [ - "i" - ], - "scopes": [ - "code" - ], - "confidence": "high" - } - ], - "conditions": [] - }, - { - "name": "Testing Framework: Unitils", - "id": "AI050600", - "description": "Testing Framework: Unitils", - "applies_to": [ - "java" - ], - "tags": [ - "Framework.Testing.Unitils" - ], - "severity": "moderate", - "overrides": null, - "patterns": [ - { - "pattern": "\\b(unitils)\\b", - "type": "regex", - "modifiers": [ - "i" - ], - "scopes": [ - "code" - ], - "confidence": "high" - } - ], - "conditions": [] - }, - { - "name": "Testing Framework: XMLUnit", - "id": "AI050700", - "description": "Testing Framework: XMLUnit", - "applies_to": [ - "java" - ], - "tags": [ - "Framework.Testing.XMLUnit" - ], - "severity": "moderate", - "overrides": null, - "patterns": [ - { - "pattern": "\\b(xmunit)\\b", - "type": "regex", - "modifiers": [ - "i" - ], - "scopes": [ - "code" - ], - "confidence": "high" - } - ], - "conditions": [] - }, - { - "name": "Testing Framework: GHUnit", - "id": "AI050800", - "description": "Testing Framework: GHUnit", - "applies_to": [ - "objective-c" - ], - "tags": [ - "Framework.Testing.GHUnit" - ], - "severity": "moderate", - "overrides": null, - "patterns": [ - { - "pattern": "\\b(GHUnit)\\b", - "type": "regex", - "modifiers": [ - "i" - ], - "scopes": [ - "code" - ], - "confidence": "high" - } - ], - "conditions": [] - }, - { - "name": "Testing Framework: Catch", - "id": "AI050900", - "description": "Testing Framework: Catch", - "applies_to": [ - "objective-c" - ], - "tags": [ - "Framework.Testing.Catch" - ], - "severity": "moderate", - "overrides": null, - "patterns": [ - { - "pattern": "catch", - "type": "regex", - "modifiers": [ - "i" - ], - "scopes": [ - "code" - ], - "confidence": "low" - } - ], - "conditions": [] - }, - { - "name": "Testing Framework: Cedar", - "id": "AI051000", - "description": "Testing Framework: Cedar", - "applies_to": [ - "objective-c" - ], - "tags": [ - "Framework.Testing.Cedar" - ], - "severity": "moderate", - "overrides": null, - "patterns": [ - { - "pattern": "\\b(Cedar)\\b", - "type": "regex", - "modifiers": [ - "i" - ], - "scopes": [ - "code" - ], - "confidence": "high" - } - ], - "conditions": [] - }, - { - "name": "Testing Framework: Kiwi", - "id": "AI051100", - "description": "Testing Framework: Kiwi", - "applies_to": [ - "objective-c" - ], - "tags": [ - "Framework.Testing.Kiwi" - ], - "severity": "moderate", - "overrides": null, - "patterns": [ - { - "pattern": "\\b(kiwi)\\b", - "type": "regex", - "modifiers": [ - "i" - ], - "scopes": [ - "code" - ], - "confidence": "high" - } - ], - "conditions": [] - }, - { - "name": "Testing Framework: Specta", - "id": "AI051200", - "description": "Testing Framework: Specta", - "applies_to": [ - "objective-c" - ], - "tags": [ - "Framework.Testing.Specta" - ], - "severity": "moderate", - "overrides": null, - "patterns": [ - { - "pattern": "\\b(specta)\\b", - "type": "regex", - "modifiers": [ - "i" - ], - "scopes": [ - "code", - "comment" - ], - "confidence": "high" - } - ], - "conditions": [] - }, - { - "name": "Testing Framework: Quick", - "id": "AI051300", - "description": "Testing Framework: Quick", - "applies_to": [ - "objective-c" - ], - "tags": [ - "Framework.Testing.quick" - ], - "severity": "moderate", - "overrides": null, - "patterns": [ - { - "pattern": "Quick", - "type": "regex", - "modifiers": [ - "i" - ], - "scopes": [ - "code" - ], - "confidence": "high" - } - ], - "conditions": [] - }, - { - "name": "Testing Framework: ObjcUnit", - "id": "AI051400", - "description": "Testing Framework: ObjcUnit", - "applies_to": [ - "objective-c" - ], - "tags": [ - "Framework.Testing.ObjcUnit" - ], - "severity": "moderate", - "overrides": null, - "patterns": [ - { - "pattern": "\\b(objcunit)\\b", - "type": "regex", - "modifiers": [ - "i" - ], - "scopes": [ - "code" - ], - "confidence": "high" - } - ], - "conditions": [] - }, - { - "name": "Testing Framework: OCUnit", - "id": "AI051500", - "description": "Testing Framework: OCUnit", - "applies_to": [ - "objective-c" - ], - "tags": [ - "Framework.Testing.OCUnit" - ], - "severity": "moderate", - "overrides": null, - "patterns": [ - { - "pattern": "\\b(ocunit)\\b", - "type": "regex", - "modifiers": [ - "i" - ], - "scopes": [ - "code" - ], - "confidence": "high" - } - ], - "conditions": [] - }, - { - "name": "Testing Framework: WOTest", - "id": "AI051600", - "description": "Testing Framework: WOTest", - "applies_to": [ - "objective-c" - ], - "tags": [ - "Framework.Testing.WOTest" - ], - "severity": "moderate", - "overrides": null, - "patterns": [ - { - "pattern": "\\b(wotest)\\b", - "type": "regex", - "modifiers": [ - "i" - ], - "scopes": [ - "code" - ], - "confidence": "high" - } - ], - "conditions": [] - }, - { - "name": "Testing Framework: XCTest", - "id": "AI051700", - "description": "Testing Framework: XCTest", - "applies_to": [ - "objective-c" - ], - "tags": [ - "Framework.Testing.XCTest" - ], - "severity": "moderate", - "overrides": null, - "patterns": [ - { - "pattern": "\\b(xctest)\\b", - "type": "regex", - "modifiers": [ - "i" - ], - "scopes": [ - "code", - "comment" - ], - "confidence": "high" - } - ], - "conditions": [] - }, - { - "name": "Testing Framework: TestUnit", - "id": "AI052600", - "description": "Testing Framework: TestUnit", - "applies_to": [ - "ruby" - ], - "tags": [ - "Framework.Testing.TestUnit" - ], - "severity": "moderate", - "overrides": null, - "patterns": [ - { - "pattern": "\\b(test::unit)\\b", - "type": "regex", - "modifiers": [ - "i" - ], - "scopes": [ - "code" - ], - "confidence": "high" - } - ], - "conditions": [] - }, - { - "name": "Testing Framework: RSpec", - "id": "AI052700", - "description": "Testing Framework: RSpec", - "applies_to": [ - "ruby" - ], - "tags": [ - "Framework.Testing.RSpec" - ], - "severity": "moderate", - "overrides": null, - "patterns": [ - { - "pattern": "\\b(rspec)\\b", - "type": "regex", - "modifiers": [ - "i" - ], - "scopes": [ - "code", - "comment" - ], - "confidence": "high" - } - ], - "conditions": [] - }, - { - "name": "Testing Framework: Shoulda", - "id": "AI052800", - "description": "Testing Framework: Shoulda", - "applies_to": [ - "ruby" - ], - "tags": [ - "Framework.Testing.Shoulda" - ], - "severity": "moderate", - "overrides": null, - "patterns": [ - { - "pattern": "\\b(shoulda)\\b", - "type": "regex", - "modifiers": [ - "i" - ], - "scopes": [ - "code", - "comment" - ], - "confidence": "high" - } - ], - "conditions": [] - }, - { - "name": "Testing Framework: MicroTest", - "id": "AI052900", - "description": "Testing Framework: MicroTest", - "applies_to": [ - "ruby" - ], - "tags": [ - "Framework.Testing.Microtest" - ], - "severity": "moderate", - "overrides": null, - "patterns": [ - { - "pattern": "\\b(microtest)\\b", - "type": "regex", - "modifiers": [ - "i" - ], - "scopes": [ - "code", - "comment" - ], - "confidence": "high" - } - ], - "conditions": [] - }, - { - "name": "Testing Framework: Bacon", - "id": "AI053000", - "description": "Testing Framework: Bacon", - "applies_to": [ - "ruby" - ], - "tags": [ - "Framework.Testing.Bacon" - ], - "severity": "moderate", - "overrides": null, - "patterns": [ - { - "pattern": "\\b(bacon)\\b", - "type": "regex", - "modifiers": [ - "i" - ], - "scopes": [ - "code", - "comment" - ], - "confidence": "high" - } - ], - "conditions": [] - }, - { - "name": "Testing Framework: MiniTest", - "id": "AI053100", - "description": "Testing Framework: MiniTest", - "applies_to": [ - "ruby" - ], - "tags": [ - "Framework.Testing.Minitest" - ], - "severity": "moderate", - "overrides": null, - "patterns": [ - { - "pattern": "\\b(minitest)\\b", - "type": "regex", - "modifiers": [ - "i" - ], - "scopes": [ - "code", - "comment" - ], - "confidence": "high" - } - ], - "conditions": [] - }, - { - "name": "Testing Framework: TMF", - "id": "AI053200", - "description": "Testing Framework: TMF", - "applies_to": [ - "ruby" - ], - "tags": [ - "Framework.Testing.TMF" - ], - "severity": "moderate", - "overrides": null, - "patterns": [ - { - "pattern": "\\b(TMF)\\b", - "type": "regex", - "modifiers": [ - "i" - ], - "scopes": [ - "code", - "comment" - ], - "confidence": "high" - } - ], - "conditions": [] - }, - { - "name": "Testing Framework: Gmock", - "id": "AI041700", - "description": "Testing Framework: Gmock", - "applies_to": [ - "go" - ], - "tags": [ - "Framework.Testing.Gmock" - ], - "severity": "moderate", - "overrides": null, - "patterns": [ - { - "pattern": "\\b(Gmock)\\b", - "type": "regex", - "modifiers": [ - "i" - ], - "scopes": [ - "code" - ], - "confidence": "high" - } - ], - "conditions": [] - }, - { - "name": "Testing Framework: Ava", - "id": "AI041800", - "description": "Testing Framework: Ava", - "applies_to": [ - "package.json", - "yarn.lock" - ], - "tags": [ - "Framework.Testing.Ava" - ], - "severity": "moderate", - "overrides": null, - "patterns": [ - { - "pattern": "(^|\")ava[@\"]", - "type": "regex", - "modifiers": [], - "scopes": [ - "code" - ], - "confidence": "high" - } - ], - "conditions": [] - }, - { - "name": "Testing Framework: DOH", - "id": "AI041900", - "description": "Testing Framework: DOH", - "applies_to": [ - "javascript" - ], - "tags": [ - "Framework.Testing.DOH" - ], - "severity": "moderate", - "overrides": null, - "patterns": [ - { - "pattern": "\\b(require\\\\\\(\\['\\\\\"]doh\\['\\\\\"]\\\\\\))\\b", - "type": "regex", - "modifiers": [ - "i" - ], - "scopes": [ - "code", - "comment" - ], - "confidence": "high" - } - ], - "conditions": [] - }, - { - "name": "Testing Framework: JSUnit", - "id": "AI042000", - "description": "Testing Framework: JSUnit", - "applies_to": [ - "javascript" - ], - "tags": [ - "Framework.Testing.JSUnit" - ], - "severity": "moderate", - "overrides": null, - "patterns": [ - { - "pattern": "\\b(jsunit)\\b", - "type": "regex", - "modifiers": [ - "i" - ], - "scopes": [ - "code", - "comment" - ], - "confidence": "high" - } - ], - "conditions": [] - }, - { - "name": "Testing Framework: EnhanceJS", - "id": "AI042100", - "description": "Testing Framework: EnhanceJS", - "applies_to": [ - "javascript" - ], - "tags": [ - "Framework.Testing.EnhanceJS" - ], - "severity": "moderate", - "overrides": null, - "patterns": [ - { - "pattern": "\\b(enhancejs)\\b", - "type": "regex", - "modifiers": [ - "i" - ], - "scopes": [ - "code", - "comment" - ], - "confidence": "high" - } - ], - "conditions": [] - }, - { - "name": "Testing Framework: QUnit", - "id": "AI042200", - "description": "Testing Framework: QUnit", - "applies_to": [ - "javascript" - ], - "tags": [ - "Framework.Testing.QUnit" - ], - "severity": "moderate", - "overrides": null, - "patterns": [ - { - "pattern": "\\b(qunit)\\b", - "type": "regex", - "modifiers": [ - "i" - ], - "scopes": [ - "code", - "comment" - ], - "confidence": "high" - } - ], - "conditions": [] - }, - { - "name": "Testing Framework: UnitJS", - "id": "AI042300", - "description": "Testing Framework: UnitJS", - "applies_to": [ - "javascript" - ], - "tags": [ - "Framework.Testing.UnitJS" - ], - "severity": "moderate", - "overrides": null, - "patterns": [ - { - "pattern": "\\b(unit\\.js)\\b", - "type": "regex", - "modifiers": [ - "i" - ], - "scopes": [ - "code", - "comment" - ], - "confidence": "high" - } - ], - "conditions": [] - }, - { - "name": "Testing Framework: RHUnit", - "id": "AI042400", - "description": "Testing Framework: RHUnit", - "applies_to": [ - "javascript" - ], - "tags": [ - "Framework.Testing.RhUnit" - ], - "severity": "moderate", - "overrides": null, - "patterns": [ - { - "pattern": "\\b(rhunit)\\b", - "type": "regex", - "modifiers": [ - "i" - ], - "scopes": [ - "code", - "comment" - ], - "confidence": "high" - } - ], - "conditions": [] - }, - { - "name": "Testing Framework: Crosscheck", - "id": "AI042500", - "description": "Testing Framework: Crosscheck", - "applies_to": [ - "javascript" - ], - "tags": [ - "Framework.Testing.Crosscheck" - ], - "severity": "moderate", - "overrides": null, - "patterns": [ - { - "pattern": "\\b(crosscheck)\\b", - "type": "regex", - "modifiers": [ - "i" - ], - "scopes": [ - "code", - "comment" - ], - "confidence": "high" - } - ], - "conditions": [] - }, - { - "name": "Testing Framework: J3Unit", - "id": "AI042600", - "description": "Testing Framework: J3Unit", - "applies_to": [ - "javascript" - ], - "tags": [ - "Framework.Testing.J3Unit" - ], - "severity": "moderate", - "overrides": null, - "patterns": [ - { - "pattern": "\\b(j3unit)\\b", - "type": "regex", - "modifiers": [ - "i" - ], - "scopes": [ - "code", - "comment" - ], - "confidence": "high" - } - ], - "conditions": [] - }, - { - "name": "Testing Framework: Mocha", - "id": "AI042700", - "description": "Testing Framework: Mocha", - "applies_to": [ - "javascript" - ], - "tags": [ - "Framework.Testing.Mocha" - ], - "severity": "moderate", - "overrides": null, - "patterns": [ - { - "pattern": "\\b(mocha)\\b", - "type": "regex", - "modifiers": [ - "i" - ], - "scopes": [ - "code", - "comment" - ], - "confidence": "high" - } - ], - "conditions": [] - }, - { - "name": "Testing Framework: Intern", - "id": "AI042800", - "description": "Testing Framework: Intern", - "applies_to": [ - "javascript" - ], - "tags": [ - "Framework.Testing.Intern" - ], - "severity": "moderate", - "overrides": null, - "patterns": [ - { - "pattern": "\\b(intern)\\b", - "type": "regex", - "modifiers": [ - "i" - ], - "scopes": [ - "code", - "comment" - ], - "confidence": "high" - } - ], - "conditions": [] - }, - { - "name": "Testing Framework: JSNUnit", - "id": "AI042900", - "description": "Testing Framework: JSNUnit", - "applies_to": [ - "javascript" - ], - "tags": [ - "Framework.Testing.JSNUnit" - ], - "severity": "moderate", - "overrides": null, - "patterns": [ - { - "pattern": "\\b(jsnunit)\\b", - "type": "regex", - "modifiers": [ - "i" - ], - "scopes": [ - "code", - "comment" - ], - "confidence": "high" - } - ], - "conditions": [] - }, - { - "name": "Testing Framework: YUITest", - "id": "AI043000", - "description": "Testing Framework: YUITest", - "applies_to": [ - "javascript" - ], - "tags": [ - "Framework.Testing.YUITest" - ], - "severity": "moderate", - "overrides": null, - "patterns": [ - { - "pattern": "\\b(yuitest)\\b", - "type": "regex", - "modifiers": [ - "i" - ], - "scopes": [ - "code", - "comment" - ], - "confidence": "high" - } - ], - "conditions": [] - }, - { - "name": "Testing Framework: JSSpec", - "id": "AI043100", - "description": "Testing Framework: JSSpec", - "applies_to": [ - "javascript" - ], - "tags": [ - "Framework.Testing.JSSpec" - ], - "severity": "moderate", - "overrides": null, - "patterns": [ - { - "pattern": "\\b(jsspec)\\b", - "type": "regex", - "modifiers": [ - "i" - ], - "scopes": [ - "code", - "comment" - ], - "confidence": "high" - } - ], - "conditions": [] - }, - { - "name": "Testing Framework: UnitTesting", - "id": "AI043200", - "description": "Testing Framework: UnitTesting", - "applies_to": [ - "javascript" - ], - "tags": [ - "Framework.Testing.UnitTesting" - ], - "severity": "moderate", - "overrides": null, - "patterns": [ - { - "pattern": "\\b(unittesting)\\b", - "type": "regex", - "modifiers": [ - "i" - ], - "scopes": [ - "code", - "comment" - ], - "confidence": "high" - } - ], - "conditions": [] - }, - { - "name": "Testing Framework: JSpec", - "id": "AI043300", - "description": "Testing Framework: JSpec", - "applies_to": [ - "javascript" - ], - "tags": [ - "Framework.Testing.JSpec" - ], - "severity": "moderate", - "overrides": null, - "patterns": [ - { - "pattern": "\\b(jspec)\\b", - "type": "regex", - "modifiers": [ - "i" - ], - "scopes": [ - "code", - "comment" - ], - "confidence": "high" - } - ], - "conditions": [] - }, - { - "name": "Testing Framework: Jasmine", - "id": "AI043400", - "description": "Testing Framework: Jasmine", - "applies_to": [ - "javascript" - ], - "tags": [ - "Framework.Testing.Jasmine" - ], - "severity": "moderate", - "overrides": null, - "patterns": [ - { - "pattern": "\\b(jasmine)\\b", - "type": "regex", - "modifiers": [ - "i" - ], - "scopes": [ - "code", - "comment" - ], - "confidence": "high" - } - ], - "conditions": [] - }, - { - "name": "Testing Framework: Screw.Unit", - "id": "AI043500", - "description": "Testing Framework: Screw.Unit", - "applies_to": [ - "javascript" - ], - "tags": [ - "Framework.Testing.screw-unit" - ], - "severity": "moderate", - "overrides": null, - "patterns": [ - { - "pattern": "\\b(screw-unit)\\b", - "type": "regex", - "modifiers": [ - "i" - ], - "scopes": [ - "code", - "comment" - ], - "confidence": "high" - } - ], - "conditions": [] - }, - { - "name": "Testing Framework: Tape", - "id": "AI043600", - "description": "Testing Framework: Tape", - "applies_to": [ - "javascript" - ], - "tags": [ - "Framework.Testing.Tape" - ], - "severity": "moderate", - "overrides": null, - "patterns": [ - { - "pattern": "require\\s*\\(\\s*['\\\"]tape['\\\"]\\)", - "type": "regex", - "modifiers": [ - "i" - ], - "scopes": [ - "code", - "comment" - ], - "confidence": "high" - } - ], - "conditions": [] - }, - { - "name": "Testing Framework: Teenytest", - "id": "AI043700", - "description": "Testing Framework: Teenytest", - "applies_to": [ - "javascript" - ], - "tags": [ - "Framework.Testing.Teenytest" - ], - "severity": "moderate", - "overrides": null, - "patterns": [ - { - "pattern": "\\b(teenytest)\\b", - "type": "regex", - "modifiers": [ - "i" - ], - "scopes": [ - "code", - "comment" - ], - "confidence": "high" - } - ], - "conditions": [] - }, - { - "name": "Testing Framework: Simple", - "id": "AI043800", - "description": "Testing Framework: Simple", - "applies_to": [ - "javascript" - ], - "tags": [ - "Framework.Testing.Test.Simple" - ], - "severity": "moderate", - "overrides": null, - "patterns": [ - { - "pattern": "\\b(test\\.simple)\\b", - "type": "regex", - "modifiers": [ - "i" - ], - "scopes": [ - "code", - "comment" - ], - "confidence": "high" - } - ], - "conditions": [] - }, - { - "name": "Testing Framework: TestCase", - "id": "AI043900", - "description": "Testing Framework: TestCase", - "applies_to": [ - "javascript" - ], - "tags": [ - "Framework.Testing.TestCase" - ], - "severity": "moderate", - "overrides": null, - "patterns": [ - { - "pattern": "\\b(testcase)\\b", - "type": "regex", - "modifiers": [ - "i" - ], - "scopes": [ - "code", - "comment" - ], - "confidence": "high" - } - ], - "conditions": [] - }, - { - "name": "Testing Framework: TestIt", - "id": "AI044000", - "description": "Testing Framework: TestIt", - "applies_to": [ - "javascript" - ], - "tags": [ - "Framework.Testing.TestIt" - ], - "severity": "moderate", - "overrides": null, - "patterns": [ - { - "pattern": "\\b(testit)\\b", - "type": "regex", - "modifiers": [ - "i" - ], - "scopes": [ - "code", - "comment" - ], - "confidence": "high" - } - ], - "conditions": [] - }, - { - "name": "Testing Framework: testdouble.js", - "id": "AI044100", - "description": "Testing Framework: testdouble.js", - "applies_to": [ - "javascript" - ], - "tags": [ - "Framework.Testing.testdouble.js" - ], - "severity": "moderate", - "overrides": null, - "patterns": [ - { - "pattern": "\\b(testdouble\\.js)\\b", - "type": "regex", - "modifiers": [ - "i" - ], - "scopes": [ - "code", - "comment" - ], - "confidence": "high" - } - ], - "conditions": [] - }, - { - "name": "Testing Framework: jsUnitTest", - "id": "AI044200", - "description": "Testing Framework: jsUnitTest", - "applies_to": [ - "javascript" - ], - "tags": [ - "Framework.Testing.jsUnitTest" - ], - "severity": "moderate", - "overrides": null, - "patterns": [ - { - "pattern": "\\b(jsunittest)\\b", - "type": "regex", - "modifiers": [ - "i" - ], - "scopes": [ - "code", - "comment" - ], - "confidence": "high" - } - ], - "conditions": [] - }, - { - "name": "Testing Framework: JSTest", - "id": "AI044300", - "description": "Testing Framework: JSTest", - "applies_to": [ - "javascript" - ], - "tags": [ - "Framework.Testing.JSTest" - ], - "severity": "moderate", - "overrides": null, - "patterns": [ - { - "pattern": "JSTest\\.net", - "type": "regex", - "modifiers": [ - "i" - ], - "scopes": [ - "code", - "comment" - ], - "confidence": "high" - } - ], - "conditions": [] - }, - { - "name": "Testing Framework: jsUnity", - "id": "AI044400", - "description": "Testing Framework: jsUnity", - "applies_to": [ - "javascript" - ], - "tags": [ - "Framework.Testing.jsUnity" - ], - "severity": "moderate", - "overrides": null, - "patterns": [ - { - "pattern": "\\b(jsunity)\\b", - "type": "regex", - "modifiers": [ - "i" - ], - "scopes": [ - "code", - "comment" - ], - "confidence": "high" - } - ], - "conditions": [] - }, - { - "name": "Testing Framework: RhinoUnit", - "id": "AI044500", - "description": "Testing Framework: RhinoUnit", - "applies_to": [ - "javascript" - ], - "tags": [ - "Framework.Testing.RhinoUnit" - ], - "severity": "moderate", - "overrides": null, - "patterns": [ - { - "pattern": "\\b(rhinounit)\\b", - "type": "regex", - "modifiers": [ - "i" - ], - "scopes": [ - "code", - "comment" - ], - "confidence": "high" - } - ], - "conditions": [] - }, - { - "name": "Testing Framework: JasUnit", - "id": "AI044600", - "description": "Testing Framework: JasUnit", - "applies_to": [ - "javascript" - ], - "tags": [ - "Framework.Testing.JasUnit" - ], - "severity": "moderate", - "overrides": null, - "patterns": [ - { - "pattern": "\\b(jasunit)\\b", - "type": "regex", - "modifiers": [ - "i" - ], - "scopes": [ - "code", - "comment" - ], - "confidence": "high" - } - ], - "conditions": [] - }, - { - "name": "Testing Framework: FireUnit", - "id": "AI044700", - "description": "Testing Framework: FireUnit", - "applies_to": [ - "javascript" - ], - "tags": [ - "Framework.Testing.FireUnit" - ], - "severity": "moderate", - "overrides": null, - "patterns": [ - { - "pattern": "\\b(fireunit)\\b", - "type": "regex", - "modifiers": [ - "i" - ], - "scopes": [ - "code" - ], - "confidence": "high" - } - ], - "conditions": [] - }, - { - "name": "Testing Framework: JSTestDriver", - "id": "AI044800", - "description": "Testing Framework: JSTestDriver", - "applies_to": [ - "javascript" - ], - "tags": [ - "Framework.Testing.JSTestDriver" - ], - "severity": "moderate", - "overrides": null, - "patterns": [ - { - "pattern": "\\b(js-test-driver)\\b", - "type": "regex", - "modifiers": [ - "i" - ], - "scopes": [ - "code", - "comment" - ], - "confidence": "high" - } - ], - "conditions": [] - }, - { - "name": "Testing Framework: JS Test Runner", - "id": "AI044900", - "description": "Testing Framework: JS Test Runner", - "applies_to": [ - "javascript" - ], - "tags": [ - "Framework.Testing.Js-test-runner" - ], - "severity": "moderate", - "overrides": null, - "patterns": [ - { - "pattern": "\\b(js-test-runner)\\b", - "type": "regex", - "modifiers": [ - "i" - ], - "scopes": [ - "code", - "comment" - ], - "confidence": "high" - } - ], - "conditions": [] - }, - { - "name": "Testing Framework: SinonJS", - "id": "AI045000", - "description": "Testing Framework: SinonJS", - "applies_to": [ - "javascript" - ], - "tags": [ - "Framework.Testing.SinonJS" - ], - "severity": "moderate", - "overrides": null, - "patterns": [ - { - "pattern": "\\b(sinon\\.js)\\b", - "type": "regex", - "modifiers": [ - "i" - ], - "scopes": [ - "code", - "comment" - ], - "confidence": "high" - } - ], - "conditions": [] - }, - { - "name": "Testing Framework: SOAtest", - "id": "AI045100", - "description": "Testing Framework: SOAtest", - "applies_to": [ - "javascript" - ], - "tags": [ - "Framework.Testing.SOAtest" - ], - "severity": "moderate", - "overrides": null, - "patterns": [ - { - "pattern": "\\b(soatest)\\b", - "type": "regex", - "modifiers": [ - "i" - ], - "scopes": [ - "code", - "comment" - ], - "confidence": "high" - } - ], - "conditions": [] - }, - { - "name": "Testing Framework: Vows", - "id": "AI045200", - "description": "Testing Framework: Vows", - "applies_to": [ - "javascript" - ], - "tags": [ - "Framework.Testing.Vows" - ], - "severity": "moderate", - "overrides": null, - "patterns": [ - { - "pattern": "\\b(vows)\\b", - "type": "regex", - "modifiers": [ - "i" - ], - "scopes": [ - "code", - "comment" - ], - "confidence": "high" - } - ], - "conditions": [] - }, - { - "name": "Testing Framework: Nodeunit", - "id": "AI045300", - "description": "Testing Framework: Nodeunit", - "applies_to": [ - "javascript" - ], - "tags": [ - "Framework.Testing.Nodeunit" - ], - "severity": "moderate", - "overrides": null, - "patterns": [ - { - "pattern": "\\b(nodeunit)\\b", - "type": "regex", - "modifiers": [ - "i" - ], - "scopes": [ - "code", - "comment" - ], - "confidence": "high" - } - ], - "conditions": [] - }, - { - "name": "Testing Framework: Tyrtle", - "id": "AI045400", - "description": "Testing Framework: Tyrtle", - "applies_to": [ - "javascript" - ], - "tags": [ - "Framework.Testing.Tyrtle" - ], - "severity": "moderate", - "overrides": null, - "patterns": [ - { - "pattern": "\\b(tyrtle)\\b", - "type": "regex", - "modifiers": [ - "i" - ], - "scopes": [ - "code", - "comment" - ], - "confidence": "high" - } - ], - "conditions": [] - }, - { - "name": "Testing Framework: WRU", - "id": "AI045500", - "description": "Testing Framework: WRU", - "applies_to": [ - "javascript" - ], - "tags": [ - "Framework.Testing.wru" - ], - "severity": "moderate", - "overrides": null, - "patterns": [ - { - "pattern": "\\b(wru)\\b", - "type": "regex", - "modifiers": [ - "i" - ], - "scopes": [ - "code", - "comment" - ], - "confidence": "high" - } - ], - "conditions": [] - }, - { - "name": "Testing Framework: BusterJS", - "id": "AI045600", - "description": "Testing Framework: BusterJS", - "applies_to": [ - "javascript" - ], - "tags": [ - "Framework.Testing.BusterJS" - ], - "severity": "moderate", - "overrides": null, - "patterns": [ - { - "pattern": "\\b(buster\\.js)\\b", - "type": "regex", - "modifiers": [ - "i" - ], - "scopes": [ - "code", - "comment" - ], - "confidence": "high" - } - ], - "conditions": [] - }, - { - "name": "Testing Framework: Lighttest", - "id": "AI045700", - "description": "Testing Framework: Lighttest", - "applies_to": [ - "javascript" - ], - "tags": [ - "Framework.Testing.Lighttest" - ], - "severity": "moderate", - "overrides": null, - "patterns": [ - { - "pattern": "\\b(lighttest)\\b", - "type": "regex", - "modifiers": [ - "i" - ], - "scopes": [ - "code", - "comment" - ], - "confidence": "high" - } - ], - "conditions": [] - }, - { - "name": "Testing Framework: Chai", - "id": "AI045800", - "description": "Testing Framework: Chai", - "applies_to": [ - "javascript" - ], - "tags": [ - "Framework.Testing.Chai" - ], - "severity": "moderate", - "overrides": null, - "patterns": [ - { - "pattern": "\\b(chai)\\b", - "type": "regex", - "modifiers": [ - "i" - ], - "scopes": [ - "code", - "comment" - ], - "confidence": "high" - } - ], - "conditions": [] - }, - { - "name": "Testing Framework: JSUS", - "id": "AI045900", - "description": "Testing Framework: JSUS", - "applies_to": [ - "javascript" - ], - "tags": [ - "Framework.Testing.JSUS" - ], - "severity": "moderate", - "overrides": null, - "patterns": [ - { - "pattern": "\\b(jsus)\\b", - "type": "regex", - "modifiers": [ - "i" - ], - "scopes": [ - "code", - "comment" - ], - "confidence": "high" - } - ], - "conditions": [] - }, - { - "name": "Testing Framework: WallabyJS", - "id": "AI046000", - "description": "Testing Framework: WallabyJS", - "applies_to": [ - "javascript" - ], - "tags": [ - "Framework.Testing.WallabyJS" - ], - "severity": "moderate", - "overrides": null, - "patterns": [ - { - "pattern": "\\b(wallaby\\.js)\\b", - "type": "regex", - "modifiers": [ - "i" - ], - "scopes": [ - "code", - "comment" - ], - "confidence": "high" - } - ], - "conditions": [] - }, - { - "name": "Testing Framework: Fast-Check", - "id": "AI046100", - "description": "Testing Framework: Fast-Check", - "applies_to": [ - "javascript" - ], - "tags": [ - "Framework.Testing.fast-check" - ], - "severity": "moderate", - "overrides": null, - "patterns": [ - { - "pattern": "\\b(fast-check)\\b", - "type": "regex", - "modifiers": [ - "i" - ], - "scopes": [ - "code", - "comment" - ], - "confidence": "high" - } - ], - "conditions": [] - }, - { - "name": "Testing Framework: Jest", - "id": "AI046200", - "description": "Testing Framework: Jest", - "applies_to": [ - "javascript" - ], - "tags": [ - "Framework.Testing.Jest" - ], - "severity": "moderate", - "overrides": null, - "patterns": [ - { - "pattern": "\\b(jest)\\b", - "type": "regex", - "modifiers": [ - "i" - ], - "scopes": [ - "code", - "comment" - ], - "confidence": "high" - } - ], - "conditions": [] - } -] \ No newline at end of file diff --git a/Benchmarks/AnalyzeBenchmark.cs b/Benchmarks/AnalyzeBenchmark.cs new file mode 100644 index 00000000..6e89e395 --- /dev/null +++ b/Benchmarks/AnalyzeBenchmark.cs @@ -0,0 +1,56 @@ +using System; +using System.IO; +using System.Reflection; +using ApplicationInspector.Unitprocess.Misc; +using BenchmarkDotNet.Attributes; +using BenchmarkDotNet.Columns; +using BenchmarkDotNet.Diagnostics.Windows.Configs; +using Microsoft.ApplicationInspector.Commands; + +namespace Benchmarks +{ + //[ConcurrencyVisualizerProfiler] + public class AnalyzeBenchmark + { + // Manually put the file you want to benchmark. But don't put this in a path with "Test" in the name ;) + private const string path = "D:\\runtime-master.zip"; + + public AnalyzeBenchmark() + { + } + + [Benchmark(Baseline = true)] + public void AnalyzeSingleThreaded() + { + AnalyzeCommand command = new AnalyzeCommand(new AnalyzeOptions() + { + SourcePath = path, + AllowDupTags = false, + SingleThread = true, + IgnoreDefaultRules = false + }); + + AnalyzeResult analyzeResult = command.GetResult(); + } + + [Benchmark] + public void AnalyzeMultiThread() + { + AnalyzeCommand command = new AnalyzeCommand(new AnalyzeOptions() + { + SourcePath = path, + AllowDupTags = false, + SingleThread = false, + IgnoreDefaultRules = false + }); + + AnalyzeResult analyzeResult = command.GetResult(); + } + + public static string GetExecutingDirectoryName() + { + var location = new Uri(Assembly.GetEntryAssembly().GetName().CodeBase); + return new FileInfo(location.AbsolutePath).Directory.FullName; + } + } +} diff --git a/Benchmarks/Benchmarks.csproj b/Benchmarks/Benchmarks.csproj new file mode 100644 index 00000000..42db16d8 --- /dev/null +++ b/Benchmarks/Benchmarks.csproj @@ -0,0 +1,21 @@ + + + + Exe + netcoreapp3.1 + + + + + + + + + + + + + PreserveNewest + + + diff --git a/Benchmarks/Program.cs b/Benchmarks/Program.cs new file mode 100644 index 00000000..70eedd7f --- /dev/null +++ b/Benchmarks/Program.cs @@ -0,0 +1,19 @@ +using System; +using System.IO; +using ApplicationInspector.Unitprocess.Misc; +using BenchmarkDotNet.Configs; +using BenchmarkDotNet.Running; +using Benchmarks; + +namespace ApplicationInspector.Benchmarks +{ + public class Program + { + public static void Main(string[] args) + { + // new DebugInProcessConfig() + BenchmarkSwitcher.FromAssembly(typeof(Program).Assembly).Run(args, new DebugInProcessConfig()); + //var summary = BenchmarkRunner.Run(); + } + } +} diff --git a/MultiExtractor/ArFile.cs b/MultiExtractor/ArFile.cs new file mode 100644 index 00000000..07433710 --- /dev/null +++ b/MultiExtractor/ArFile.cs @@ -0,0 +1,302 @@ +// Copyright (c) Microsoft Corporation. +// Licensed under the MIT License. + +using System; +using System.Collections.Generic; +using System.IO; +using System.Text; + +namespace Microsoft.CST.OpenSource.MultiExtractor +{ + /** + * Gnu Ar file parser. Supports SystemV style lookup tables in both 32 and 64 bit mode as well as BSD and GNU formatted .ars. + */ + public static class ArFile + { + private static NLog.Logger Logger = NLog.LogManager.GetCurrentClassLogger(); + + // Simple method which returns a the file entries. We can't make this a continuation because + // we're using spans. + public static IEnumerable GetFileEntries(FileEntry fileEntry) + { + if (fileEntry == null) + { + yield break; + } + // First, cut out the file signature (8 bytes) + fileEntry.Content.Position = 8; + var filenameLookup = new Dictionary(); + byte[] headerBuffer = new byte[60]; + while (true) + { + if (fileEntry.Content.Length - fileEntry.Content.Position < 60) // The header for each file is 60 bytes + { + break; + } + + fileEntry.Content.Read(headerBuffer, 0, 60); + + if (long.TryParse(Encoding.ASCII.GetString(headerBuffer[48..58]), out long size))// header size in bytes + { + var filename = Encoding.ASCII.GetString(headerBuffer[0..16]).Trim(); + + // Header with list of file names + if (filename.StartsWith("//")) + { + // This should just be a list of names, size should be safe to load in memory and cast to int + var fileNamesBytes = new byte[size]; + fileEntry.Content.Read(fileNamesBytes, 0, (int)size); + + var name = new StringBuilder(); + var index = 0; + for (int i = 0; i < fileNamesBytes.Length; i++) + { + if (fileNamesBytes[i] == '/') + { + filenameLookup.Add(index, name.ToString()); + name.Clear(); + } + else if (fileNamesBytes[i] == '\n') + { + // The next filename would start on the next line + index = i + 1; + } + else + { + name.Append((char)fileNamesBytes[i]); + } + } + } + else if (filename.StartsWith("#1/")) + { + // We should be positioned right after the header + if (int.TryParse(filename.Substring(3), out int nameLength)) + { + Span nameSpan = stackalloc byte[nameLength]; + // This should move us right to the file + fileEntry.Content.Read(nameSpan); + + var entryStream = new FileStream(Path.GetTempFileName(), FileMode.Create, FileAccess.ReadWrite, FileShare.ReadWrite, 4096, FileOptions.DeleteOnClose); + + // The name length is included in the total size reported in the header + CopyStreamBytes(fileEntry.Content, entryStream, size - nameLength); + + yield return new FileEntry(Encoding.ASCII.GetString(nameSpan), entryStream, fileEntry, true); + } + } + else if (filename.Equals('/')) + { + // System V symbol lookup table + // N = 32 bit big endian integers (entries in table) + // then N 32 bit big endian integers representing prositions in archive + // then N \0 terminated strings "symbol name" (possibly filename) + + var tableContents = new Span(new byte[size]); + fileEntry.Content.Read(tableContents); + + var numEntries = IntFromBigEndianBytes(tableContents.Slice(0, 4).ToArray()); + var filePositions = new int[numEntries]; + for (int i = 0; i < numEntries; i++) + { + filePositions[i] = IntFromBigEndianBytes(tableContents.Slice((i + 1) * 4, 4).ToArray()); + } + + var index = 0; + var sb = new StringBuilder(); + var fileEntries = new List<(int, string)>(); + + for (int i = 0; i< tableContents.Length; i++) + { + if (tableContents.Slice(i, 1)[0] == '\0') + { + fileEntries.Add((filePositions[index++], sb.ToString())); + sb.Clear(); + } + else + { + sb.Append(tableContents.Slice(i, 1)[0]); + } + } + + foreach (var entry in fileEntries) + { + fileEntry.Content.Position = entry.Item1; + fileEntry.Content.Read(headerBuffer, 0, 60); + + if (long.TryParse(Encoding.ASCII.GetString(headerBuffer[48..58]), out long innerSize))// header size in bytes + { + if (filename.StartsWith('/')) + { + if (int.TryParse(filename[1..], out int innerIndex)) + { + try + { + filename = filenameLookup[innerIndex]; + } + catch (Exception) + { + Logger.Debug("Expected to find a filename at index {0}", innerIndex); + } + } + } + else + { + filename = entry.Item2; + } + + var entryStream = new FileStream(Path.GetTempFileName(), FileMode.Create, FileAccess.ReadWrite, FileShare.ReadWrite, 4096, FileOptions.DeleteOnClose); + CopyStreamBytes(fileEntry.Content, entryStream, innerSize); + yield return new FileEntry(filename, entryStream, fileEntry); + } + } + fileEntry.Content.Position = fileEntry.Content.Length - 1; + } + else if (filename.Equals("/SYM64/")) + { + // https://en.wikipedia.org/wiki/Ar_(Unix)#System_V_(or_GNU)_variant + // GNU lookup table (archives larger than 4GB) + // N = 64 bit big endian integers (entries in table) + // then N 64 bit big endian integers representing positions in archive + // then N \0 terminated strings "symbol name" (possibly filename) + + var buffer = new byte[8]; + fileEntry.Content.Read(buffer, 0, 8); + + var numEntries = Int64FromBigEndianBytes(buffer); + var filePositions = new long[numEntries]; + + for (int i = 0; i < numEntries; i++) + { + fileEntry.Content.Read(buffer, 0, 8); + filePositions[i] = Int64FromBigEndianBytes(buffer); + } + + var index = 0; + var sb = new StringBuilder(); + var fileEntries = new List<(long, string)>(); + + while (fileEntry.Content.Position < size) + { + fileEntry.Content.Read(buffer, 0, 1); + if (buffer[0] == '\0') + { + fileEntries.Add((filePositions[index++], sb.ToString())); + sb.Clear(); + } + else + { + sb.Append(buffer[0]); + } + } + + foreach (var innerEntry in fileEntries) + { + fileEntry.Content.Position = innerEntry.Item1; + + fileEntry.Content.Read(headerBuffer, 0, 60); + + if (long.TryParse(Encoding.ASCII.GetString(headerBuffer[48..58]), out long innerSize))// header size in bytes + { + if (filename.StartsWith('/')) + { + if (int.TryParse(filename[1..], out int innerIndex)) + { + try + { + filename = filenameLookup[innerIndex]; + } + catch (Exception) + { + Logger.Debug("Expected to find a filename at index {0}", innerIndex); + } + } + } + else + { + filename = innerEntry.Item2; + } + var entryStream = new FileStream(Path.GetTempFileName(), FileMode.Create, FileAccess.ReadWrite, FileShare.ReadWrite, 4096, FileOptions.DeleteOnClose); + CopyStreamBytes(fileEntry.Content, entryStream, innerSize); + yield return new FileEntry(filename, entryStream, fileEntry); + } + } + fileEntry.Content.Position = fileEntry.Content.Length - 1; + } + else if (filename.StartsWith('/')) + { + if (int.TryParse(filename[1..], out int index)) + { + try + { + filename = filenameLookup[index]; + } + catch (Exception) + { + Logger.Debug("Expected to find a filename at index {0}", index); + } + } + + var entryStream = new FileStream(Path.GetTempFileName(), FileMode.Create, FileAccess.ReadWrite, FileShare.ReadWrite, 4096, FileOptions.DeleteOnClose); + CopyStreamBytes(fileEntry.Content, entryStream, size); + + yield return new FileEntry(filename, entryStream, fileEntry, true); + } + else + { + var entryStream = new FileStream(Path.GetTempFileName(), FileMode.Create, FileAccess.ReadWrite, FileShare.ReadWrite, 4096, FileOptions.DeleteOnClose); + CopyStreamBytes(fileEntry.Content, entryStream, size); + + yield return new FileEntry(filename, entryStream, fileEntry, true); + } + } + else + { + // Not a valid header, we couldn't parse the file size. + yield break; + } + + // Entries are padded on even byte boundaries + // https://docs.oracle.com/cd/E36784_01/html/E36873/ar.h-3head.html + fileEntry.Content.Position = fileEntry.Content.Position % 2 == 1 ? fileEntry.Content.Position + 1 : fileEntry.Content.Position; + } + } + + internal static void CopyStreamBytes(Stream input, Stream output, long bytes) + { + byte[] buffer = new byte[32768]; + long read; + while (bytes > 0 && + (read = input.Read(buffer, 0, (int)Math.Min(buffer.Length, bytes))) > 0) + { + output.Write(buffer, 0, (int)read); + bytes -= read; + } + } + + public static int IntFromBigEndianBytes(byte[] value) + { + if (value.Length == 4) + { + if (BitConverter.IsLittleEndian) + { + Array.Reverse(value); + } + return BitConverter.ToInt32(value); + } + return -1; + } + + public static long Int64FromBigEndianBytes(byte[] value) + { + if (value.Length == 8) + { + if (BitConverter.IsLittleEndian) + { + Array.Reverse(value); + } + return BitConverter.ToInt64(value); + } + return -1; + } + } +} \ No newline at end of file diff --git a/MultiExtractor/DebArchiveFile.cs b/MultiExtractor/DebArchiveFile.cs new file mode 100644 index 00000000..ed1fa6ef --- /dev/null +++ b/MultiExtractor/DebArchiveFile.cs @@ -0,0 +1,47 @@ +using System.Collections.Generic; +using System.IO; +using System.Text; + +namespace Microsoft.CST.OpenSource.MultiExtractor +{ + /** + * Very simple implementation of an .Deb format parser, needed for Debian .deb archives. + * See: https://en.wikipedia.org/wiki/Deb_(file_format)#/media/File:Deb_File_Structure.svg + */ + public static class DebArchiveFile + { + public static IEnumerable GetFileEntries(FileEntry fileEntry) + { + if (fileEntry == null) + { + yield break; + } + + // First, cut out the file signature (8 bytes) and global header (64 bytes) + fileEntry.Content.Position = 72; + var headerBytes = new byte[60]; + + while (true) + { + if (fileEntry.Content.Length - fileEntry.Content.Position < 60) // The header for each file is 60 bytes + { + break; + } + fileEntry.Content.Read(headerBytes, 0, 60); + var filename = Encoding.ASCII.GetString(headerBytes[0..16]).Trim(); // filename is 16 bytes + var fileSizeBytes = headerBytes[48..58]; // File size is decimal-encoded, 10 bytes long + if (int.TryParse(Encoding.ASCII.GetString(fileSizeBytes).Trim(), out int fileSize)) + { + var entryContent = new byte[fileSize]; + fileEntry.Content.Read(entryContent, 0, fileSize); + using var stream = new MemoryStream(entryContent); + yield return new FileEntry(filename, stream, fileEntry); + } + else + { + break; + } + } + } + } +} diff --git a/MultiExtractor/Extractor.cs b/MultiExtractor/Extractor.cs index 620e025f..697959dc 100644 --- a/MultiExtractor/Extractor.cs +++ b/MultiExtractor/Extractor.cs @@ -1,289 +1,1486 @@ -using ICSharpCode.SharpZipLib.Core; -using ICSharpCode.SharpZipLib.GZip; +// Copyright (c) Microsoft Corporation. +// Licensed under the MIT License. + +using System; +using System.Collections.Generic; +using System.Diagnostics; +using System.IO; +using System.Linq; +using DiscUtils; +using DiscUtils.Btrfs; +using DiscUtils.Ext; +using DiscUtils.HfsPlus; +using DiscUtils.Fat; +using DiscUtils.Iso9660; +using DiscUtils.Ntfs; +using DiscUtils.Setup; +using DiscUtils.Streams; +using DiscUtils.Xfs; +using ICSharpCode.SharpZipLib.Core; using ICSharpCode.SharpZipLib.Tar; using ICSharpCode.SharpZipLib.Zip; +using SharpCompress.Archives.GZip; using SharpCompress.Archives.Rar; +using SharpCompress.Archives.SevenZip; using SharpCompress.Compressors.BZip2; using SharpCompress.Compressors.Xz; -using System; -using System.Collections.Generic; -using System.IO; -using System.Linq; -using System.Threading.Tasks; +using System.Collections.Concurrent; -namespace MultiExtractor +namespace Microsoft.CST.OpenSource.MultiExtractor { - public static class Extractor + public class Extractor { - private const int BUFFER_SIZE = 4096; + /// + /// Internal buffer size for extraction + /// + private const int BUFFER_SIZE = 32768; + + private const string DEBUG_STRING = "Failed parsing archive of type {0} {1}:{2} ({3})"; + + /// + /// The maximum number of items to take at once in the parallel extractors + /// + private const int MAX_BATCH_SIZE = 50; + + /// + /// By default, stop extracting if the total number of bytes + /// seen is greater than this multiple of the original archive + /// size. Used to avoid denial of service (zip bombs and the like). + /// + private const double DEFAULT_MAX_EXTRACTED_BYTES_RATIO = 60.0; + + /// + /// By default, stop processing after this time span. Used to avoid + /// denial of service (zip bombs and the like). + /// + public TimeSpan Timeout { get; set; } = TimeSpan.FromSeconds(300); + + /// + /// The maximum number of bytes to extract from the archive and + /// all embedded archives. Set to 0 to remove limit. Note that + /// MaxExpansionRatio may also apply. Defaults to 0. + /// + public long MaxExtractedBytes { get; set; } = 0; + + /// + /// Backing store for MaxExtractedBytesRatio. + /// + private double _MaxExtractedBytesRatio; + + /// + /// The maximum number of bytes to extract from the archive and + /// all embedded archives, relative to the size of the initial + /// archive. The default value of 100 means if the archive is 5k + /// in size, stop processing after 500k bytes are extracted. Set + /// this to 0 to mean, 'no limit'. Not that MaxExtractedBytes + /// may also apply. + /// + public double MaxExtractedBytesRatio { + get + { + return _MaxExtractedBytesRatio; + } + + set + { + _MaxExtractedBytesRatio = Math.Max(value, 0); + } + } + + /// + /// Logger for interesting events. + /// + private readonly NLog.Logger Logger = NLog.LogManager.GetCurrentClassLogger(); + private readonly string IS_QUINE_STRING = "Detected Quine {0} in {1}. Aborting Extraction."; + + /// + /// Times extraction operations to avoid denial of service. + /// + private Stopwatch GovernorStopwatch; + + public bool EnableTiming { get; } + + /// + /// Stores the number of bytes left before we abort (denial of service). + /// + private long CurrentOperationProcessedBytesLeft = -1; + + public Extractor(bool enableTiming = false) + { + MaxExtractedBytesRatio = DEFAULT_MAX_EXTRACTED_BYTES_RATIO; + GovernorStopwatch = new Stopwatch(); + EnableTiming = enableTiming; + SetupHelper.RegisterAssembly(typeof(BtrfsFileSystem).Assembly); + SetupHelper.RegisterAssembly(typeof(ExtFileSystem).Assembly); + SetupHelper.RegisterAssembly(typeof(FatFileSystem).Assembly); + SetupHelper.RegisterAssembly(typeof(HfsPlusFileSystem).Assembly); + SetupHelper.RegisterAssembly(typeof(NtfsFileSystem).Assembly); + SetupHelper.RegisterAssembly(typeof(XfsFileSystem).Assembly); + } - public static bool IsSupportedFormat(string filename) + private void ResetResourceGovernor() { - ArchiveFileType archiveFileType = MiniMagic.DetectFileType(filename); - return (archiveFileType != ArchiveFileType.UNKNOWN); + Logger.Trace("ResetResourceGovernor()"); + GovernorStopwatch.Reset(); + CurrentOperationProcessedBytesLeft = -1; } - public static IEnumerable ExtractFile(string filename) + private void ResetResourceGovernor(Stream stream) { - try + Logger.Trace("ResetResourceGovernor()"); + + if (stream == null) { - if (!File.OpenRead(filename).CanRead) + throw new ArgumentNullException(nameof(stream), "Stream must not be null."); + } + + GovernorStopwatch = Stopwatch.StartNew(); + + // Default value is we take MaxExtractedBytes (meaning, ratio is not defined) + CurrentOperationProcessedBytesLeft = MaxExtractedBytes; + if (MaxExtractedBytesRatio > 0) + { + long streamLength; + try + { + streamLength = stream.Length; + } + catch (Exception) { - throw new IOException($"ExtractFile called, but {filename} cannot be read."); + throw new ArgumentException("Unable to get length of stream."); } + + // Ratio *is* defined, so the max value would be based on the stream length + var maxViaRatio = (long)(MaxExtractedBytesRatio * streamLength); + // Assign the samller of the two, accounting for MaxExtractedBytes == 0 means, 'no limit'. + CurrentOperationProcessedBytesLeft = Math.Min(maxViaRatio, MaxExtractedBytes > 0 ? MaxExtractedBytes : long.MaxValue); } - catch (Exception) + } + + /// + /// Checks to ensure we haven't extracted too many bytes, or taken too long. + /// This exists primarily to mitigate the risks of quines (archives that + /// contain themselves) and zip bombs (specially constructed to expand to huge + /// sizes). + /// Ref: https://alf.nu/ZipQuine + /// + /// + private void CheckResourceGovernor(long additionalBytes = 0) + { + Logger.ConditionalTrace("CheckResourceGovernor(duration={0}, bytes={1})", GovernorStopwatch.Elapsed.TotalMilliseconds, CurrentOperationProcessedBytesLeft); + + if (EnableTiming && GovernorStopwatch.Elapsed > Timeout) { - //Logger.Trace("File {0} cannot be read, ignoring.", filename); - return Array.Empty(); + throw new TimeoutException(string.Format($"Processing timeout exceeded: {GovernorStopwatch.Elapsed.TotalMilliseconds} ms.")); } - using var stream = new MemoryStream(File.ReadAllBytes(filename)); - return ExtractFile(new FileEntry(filename, "", stream)); + if (CurrentOperationProcessedBytesLeft - additionalBytes <= 0) + { + throw new OverflowException("Too many bytes extracted, exceeding limit."); + } } - public static IEnumerable ExtractFile(string filename, ArchiveFileType archiveFileType) + + /// + /// Extracts files from the file 'filename'. + /// + /// FileEntry to extract + /// Extracted files + public IEnumerable ExtractFile(string filename, bool parallel = false) { + Console.Write(parallel); + if (!File.Exists(filename)) + { + Logger.Warn("ExtractFile called, but {0} does not exist.", filename); + yield break; + } + FileEntry? fileEntry = null; try { - if (!File.OpenRead(filename).CanRead) + using var fs = new FileStream(filename,FileMode.Open); + // We give it a parent so we can give it a shortname. This is useful for Quine detection later. + fileEntry = new FileEntry(Path.GetFileName(filename), fs, new FileEntry(filename, new MemoryStream())); + ResetResourceGovernor(fs); + } + catch (Exception ex) + { + Logger.Debug(ex, "Failed to extract file {0}", filename); + } + + if (fileEntry != null) + { + foreach (var result in ExtractFile(fileEntry, parallel)) { - throw new IOException($"ExtractFile called, but {filename} cannot be read."); + GovernorStopwatch.Stop(); + yield return result; + GovernorStopwatch.Start(); } } - catch (Exception) + GovernorStopwatch.Stop(); + } + + /// + /// Extracts files from the file, identified by 'filename', but with + /// contents passed through 'archiveBytes'. Note that 'filename' does not + /// have to exist; it will only be used to identify files extracted. + /// + /// FileEntry to extract + /// Extracted files + public IEnumerable ExtractFile(string filename, byte[] archiveBytes, bool parallel = false) + { + using var ms = new MemoryStream(archiveBytes); + ResetResourceGovernor(ms); + var result = ExtractFile(new FileEntry(filename, ms),parallel); + return result; + } + + /// + /// Extracts files from the given FileEntry, using the appropriate + /// extractors, recursively. + /// + /// FileEntry to extract + /// Extracted files + private IEnumerable ExtractFile(FileEntry fileEntry, bool parallel = false) + { + Logger.Trace("ExtractFile({0})", fileEntry.FullPath); + CurrentOperationProcessedBytesLeft -= fileEntry.Content.Length; + CheckResourceGovernor(); + IEnumerable result; + bool useRaw = false; + + try + { + var fileEntryType = MiniMagic.DetectFileType(fileEntry); + switch (fileEntryType) + { + case ArchiveFileType.ZIP: + result = ExtractZipFile(fileEntry, parallel); + break; + case ArchiveFileType.RAR: + result = ExtractRarFile(fileEntry, parallel); + break; + case ArchiveFileType.P7ZIP: + result = Extract7ZipFile(fileEntry, parallel); + break; + case ArchiveFileType.DEB: + result = ExtractDebFile(fileEntry, parallel); + break; + case ArchiveFileType.GZIP: + result = ExtractGZipFile(fileEntry, parallel); + break; + case ArchiveFileType.TAR: + result = ExtractTarFile(fileEntry, parallel); + break; + case ArchiveFileType.XZ: + result = ExtractXZFile(fileEntry, parallel); + break; + case ArchiveFileType.BZIP2: + result = ExtractBZip2File(fileEntry, parallel); + break; + case ArchiveFileType.AR: + result = ExtractGnuArFile(fileEntry, parallel); + break; + case ArchiveFileType.ISO_9660: + result = ExtractIsoFile(fileEntry, parallel); + break; + case ArchiveFileType.VHDX: + result = ExtractVHDXFile(fileEntry, parallel); + break; + case ArchiveFileType.VHD: + result = ExtractVHDFile(fileEntry, parallel); + break; + case ArchiveFileType.WIM: + result = ExtractWimFile(fileEntry, parallel); + break; + case ArchiveFileType.VMDK: + result = ExtractVMDKFile(fileEntry, parallel); + break; + default: + useRaw = true; + result = new[] { fileEntry }; + break; + } + } + catch (Exception ex) + { + Logger.Debug(ex, "Error extracting {0}: {1}", fileEntry.FullPath, ex.Message); + useRaw = true; + result = new[] { fileEntry }; // Default is to not try to extract. + } + + // After we are done with an archive subtract its bytes. Contents have been counted now separately + if (!useRaw) { - //Logger.Trace("File {0} cannot be read, ignoring.", filename); - return Array.Empty(); + CurrentOperationProcessedBytesLeft += fileEntry.Content.Length; } - using var memoryStream = new FileStream(filename, FileMode.Open); - return ExtractFile(new FileEntry(filename, "", memoryStream), archiveFileType); + return result; } - public static IEnumerable ExtractFile(string filename, byte[] archiveBytes) + /// + /// Extracts an a Wim file + /// + /// + /// + private IEnumerable ExtractWimFile(FileEntry fileEntry, bool parallel) { - using var memoryStream = new MemoryStream(archiveBytes); - return ExtractFile(new FileEntry(filename, "", memoryStream)); + if (parallel) + { + foreach (var entry in ParallelExtractWimFile(fileEntry)) + { + yield return entry; + } + yield break; + } + DiscUtils.Wim.WimFile? baseFile = null; + try + { + baseFile = new DiscUtils.Wim.WimFile(fileEntry.Content); + } + catch(Exception e) + { + Logger.Debug(e, "Failed to init WIM image."); + } + if (baseFile != null) + { + for (int i = 0; i < baseFile.ImageCount; i++) + { + var image = baseFile.GetImage(i); + var files = image.GetFiles(image.Root.FullName, "*.*", SearchOption.AllDirectories); + foreach (var file in files) + { + Stream? stream = null; + try + { + var info = image.GetFileInfo(file); + CheckResourceGovernor(info.Length); + stream = info.OpenRead(); + } + catch (Exception e) + { + Logger.Debug("Error reading {0} from WIM {1} ({2}:{3})", file, image.FriendlyName, e.GetType(), e.Message); + } + if (stream != null) + { + var newFileEntry = new FileEntry($"{image.FriendlyName}\\{file}", stream, fileEntry); + var entries = ExtractFile(newFileEntry, parallel); + foreach (var entry in entries) + { + yield return entry; + } + stream.Dispose(); + } + } + } + } } - #region internal + /// + /// Extracts an a VMDK file + /// + /// + /// + private IEnumerable ExtractVMDKFile(FileEntry fileEntry, bool parallel) + { + using var disk = new DiscUtils.Vmdk.Disk(fileEntry.Content, Ownership.None); + var manager = new VolumeManager(disk); + var logicalVolumes = manager.GetLogicalVolumes(); + foreach (var volume in logicalVolumes) + { + foreach (var entry in DumpLogicalVolume(volume, fileEntry.FullPath, parallel, fileEntry)) + { + yield return entry; + } + } + } - private static IEnumerable ExtractFile(FileEntry fileEntry) + /// + /// Extracts an a VHDX file + /// + /// + /// + private IEnumerable ExtractVHDXFile(FileEntry fileEntry, bool parallel) { - return ExtractFile(fileEntry, MiniMagic.DetectFileType(fileEntry)); + using var disk = new DiscUtils.Vhdx.Disk(fileEntry.Content, Ownership.None); + var manager = new VolumeManager(disk); + var logicalVolumes = manager.GetLogicalVolumes(); + foreach(var volume in logicalVolumes) + { + foreach(var entry in DumpLogicalVolume(volume, fileEntry.FullPath, parallel, fileEntry)) + { + yield return entry; + } + } + } + + /// + /// Extracts an a VHD file + /// + /// + /// + private IEnumerable ExtractVHDFile(FileEntry fileEntry, bool parallel) + { + using var disk = new DiscUtils.Vhd.Disk(fileEntry.Content, Ownership.None); + var manager = new VolumeManager(disk); + var logicalVolumes = manager.GetLogicalVolumes(); + foreach (var volume in logicalVolumes) + { + foreach (var entry in DumpLogicalVolume(volume, fileEntry.FullPath, parallel, fileEntry)) + { + yield return entry; + } + } } - private static IEnumerable ExtractFile(FileEntry fileEntry, ArchiveFileType archiveFileType) + /// + /// Extracts an an ISO file + /// + /// + /// + private IEnumerable ExtractIsoFile(FileEntry fileEntry, bool parallel) { - switch (archiveFileType) + if (parallel) { - case ArchiveFileType.ZIP: - return ExtractZipFile(fileEntry); + foreach (var entry in ParallelExtractIsoFile(fileEntry)) + { + yield return entry; + } + yield break; + } + using CDReader cd = new CDReader(fileEntry.Content, true); + + foreach(var file in cd.GetFiles(cd.Root.FullName,"*.*", SearchOption.AllDirectories)) + { + var fileInfo = cd.GetFileInfo(file); + CheckResourceGovernor(fileInfo.Length); + Stream? stream = null; + try + { + stream = fileInfo.OpenRead(); + } + catch (Exception e) + { + Logger.Debug("Failed to extract {0} from ISO {1}. ({2}:{3})", fileInfo.Name, fileEntry.FullPath, e.GetType(), e.Message); + } + if (stream != null) + { + var newFileEntry = new FileEntry(fileInfo.Name, stream, fileEntry); + var entries = ExtractFile(newFileEntry, parallel); + foreach (var entry in entries) + { + yield return entry; + } + } + } + } - case ArchiveFileType.GZIP: - return ExtractGZipFile(fileEntry); + /// + /// Extracts an archive file created with GNU ar + /// + /// + /// + private IEnumerable ExtractGnuArFile(FileEntry fileEntry, bool parallel) + { + IEnumerable? fileEntries = null; + try + { + fileEntries = ArFile.GetFileEntries(fileEntry); + } + catch (Exception e) + { + Logger.Debug(DEBUG_STRING, ArchiveFileType.AR, fileEntry.FullPath, string.Empty, e.GetType()); + } + if (fileEntries != null) + { + foreach (var entry in fileEntries) + { + CheckResourceGovernor(entry.Content.Length); + foreach (var extractedFile in ExtractFile(entry)) + { + yield return extractedFile; + } + } + } + } - case ArchiveFileType.TAR: - return ExtractTarFile(fileEntry); + /// + /// Extracts an zip file contained in fileEntry. + /// + /// FileEntry to extract + /// Extracted files + private IEnumerable ExtractZipFile(FileEntry fileEntry, bool parallel) + { + if (parallel) + { + foreach (var entry in ParallelExtractZipFile(fileEntry)) + { + yield return entry; + } + yield break; + } + ZipFile? zipFile = null; + try + { + zipFile = new ZipFile(fileEntry.Content); + } + catch(Exception e) + { + Logger.Debug(DEBUG_STRING, ArchiveFileType.ZIP, fileEntry.FullPath, string.Empty, e.GetType()); + } + if (zipFile != null) + { + foreach (ZipEntry? zipEntry in zipFile) + { + if (zipEntry is null || + zipEntry.IsDirectory || + zipEntry.IsCrypted || + !zipEntry.CanDecompress) + { + continue; + } - case ArchiveFileType.XZ: - return ExtractXZFile(fileEntry); + CheckResourceGovernor(zipEntry.Size); - case ArchiveFileType.BZIP2: - return ExtractBZip2File(fileEntry); + using var fs = new FileStream(Path.GetTempFileName(), FileMode.Create, FileAccess.ReadWrite, FileShare.ReadWrite, 4096, FileOptions.DeleteOnClose); + try + { + byte[] buffer = new byte[BUFFER_SIZE]; + var zipStream = zipFile.GetInputStream(zipEntry); + StreamUtils.Copy(zipStream, fs, buffer); + } + catch (Exception e) + { + Logger.Debug(DEBUG_STRING, ArchiveFileType.ZIP, fileEntry.FullPath, zipEntry.Name, e.GetType()); + } - case ArchiveFileType.RAR: - return ExtractRarFile(fileEntry); + var newFileEntry = new FileEntry(zipEntry.Name, fs, fileEntry); - case ArchiveFileType.P7ZIP: - return Extract7ZipFile(fileEntry); + if (IsQuine(newFileEntry)) + { + Logger.Info(IS_QUINE_STRING, fileEntry.Name, fileEntry.FullPath); + throw new OverflowException(); + } - case ArchiveFileType.UNKNOWN: - default: - return new[] { fileEntry }; + foreach (var extractedFile in ExtractFile(newFileEntry, parallel)) + { + yield return extractedFile; + } + } } } - private static IEnumerable ExtractZipFile(FileEntry fileEntry) + /// + /// Extracts an Gzip file contained in fileEntry. + /// Since this function is recursive, even though Gzip only supports a single + /// compressed file, that inner file could itself contain multiple others. + /// + /// FileEntry to extract + /// Extracted files + private IEnumerable ExtractGZipFile(FileEntry fileEntry, bool parallel) { - List files = new List(); - - ZipFile zipFile = null; + GZipArchive? gzipArchive = null; try { - zipFile = new ZipFile(fileEntry.Content); + gzipArchive = GZipArchive.Open(fileEntry.Content); } catch (Exception e) { - Console.WriteLine($"Failed to read from {fileEntry.FullPath} {e.Message} {e.StackTrace}"); + Logger.Debug(DEBUG_STRING, ArchiveFileType.GZIP, fileEntry.FullPath, string.Empty, e.GetType()); } - if (zipFile != null) + if (gzipArchive != null) { - List entries = new List(); - foreach (ZipEntry zipEntry in zipFile) + foreach (var entry in gzipArchive.Entries) { - entries.Add(zipEntry); + if (entry.IsDirectory) + { + continue; + } + CheckResourceGovernor(entry.Size); + + var newFilename = Path.GetFileNameWithoutExtension(fileEntry.Name); + if (fileEntry.Name.EndsWith(".tgz", StringComparison.InvariantCultureIgnoreCase)) + { + newFilename = newFilename[0..^4] + ".tar"; + } + + FileEntry? newFileEntry = null; + try + { + using var stream = entry.OpenEntryStream(); + newFileEntry = new FileEntry(newFilename, stream, fileEntry); + } + catch (Exception e) + { + Logger.Debug(DEBUG_STRING, ArchiveFileType.GZIP, fileEntry.FullPath, newFilename, e.GetType()); + } + if (newFileEntry != null) + { + foreach (var extractedFile in ExtractFile(newFileEntry, parallel)) + { + yield return extractedFile; + } + } } - entries.AsParallel().ForAll(zipEntry => + } + gzipArchive?.Dispose(); + } + + /// + /// Extracts a tar file contained in fileEntry. + /// + /// FileEntry to extract + /// Extracted files + private IEnumerable ExtractTarFile(FileEntry fileEntry, bool parallel) + { + TarEntry tarEntry; + TarInputStream? tarStream = null; + try + { + tarStream = new TarInputStream(fileEntry.Content); + } + catch(Exception e) + { + Logger.Debug(DEBUG_STRING, ArchiveFileType.TAR, fileEntry.FullPath, string.Empty, e.GetType()); + } + if (tarStream != null) + { + while ((tarEntry = tarStream.GetNextEntry()) != null) { - if (!zipEntry.IsDirectory && - !zipEntry.IsCrypted && - zipEntry.CanDecompress) + if (tarEntry.IsDirectory) { - using var memoryStream = new MemoryStream(); - byte[] buffer = new byte[BUFFER_SIZE]; - var zipStream = zipFile.GetInputStream(zipEntry); - StreamUtils.Copy(zipStream, memoryStream, buffer); + continue; + } + var fs = new FileStream(Path.GetTempFileName(), FileMode.Create, FileAccess.ReadWrite, FileShare.ReadWrite, 4096, FileOptions.DeleteOnClose); + CheckResourceGovernor(tarStream.Length); + try + { + tarStream.CopyEntryContents(fs); + } + catch (Exception e) + { + Logger.Debug(DEBUG_STRING, ArchiveFileType.TAR, fileEntry.FullPath, tarEntry.Name, e.GetType()); + } - var newFileEntry = new FileEntry(zipEntry.Name, fileEntry.FullPath, memoryStream); - files.AddRange(ExtractFile(newFileEntry)); + var newFileEntry = new FileEntry(tarEntry.Name, fs, fileEntry, true); + + if (IsQuine(newFileEntry)) + { + Logger.Info(IS_QUINE_STRING, fileEntry.Name, fileEntry.FullPath); + throw new OverflowException(); } - }); - } - return files; + foreach (var extractedFile in ExtractFile(newFileEntry, parallel)) + { + yield return extractedFile; + } + } + tarStream.Dispose(); + } + else + { + // If we couldn't parse it just return it + yield return fileEntry; + } } - private static IEnumerable ExtractGZipFile(FileEntry fileEntry) + /// + /// Extracts an .XZ file contained in fileEntry. + /// + /// FileEntry to extract + /// Extracted files + private IEnumerable ExtractXZFile(FileEntry fileEntry, bool parallel) { - using var memoryStream = new MemoryStream(); + XZStream? xzStream = null; + try + { + xzStream = new XZStream(fileEntry.Content); + } + catch(Exception e) + { + Logger.Debug(DEBUG_STRING, ArchiveFileType.XZ, fileEntry.FullPath, string.Empty, e.GetType()); + } + if (xzStream != null) + { + var newFilename = Path.GetFileNameWithoutExtension(fileEntry.Name); + var newFileEntry = new FileEntry(newFilename, xzStream, fileEntry); + + // SharpCompress does not expose metadata without a full read, + // so we need to decompress first, and then abort if the bytes + // exceeded the governor's capacity. - try{ - using var gzipStream = new GZipInputStream(fileEntry.Content); - gzipStream.CopyTo(memoryStream); + var streamLength = xzStream.Index.Records?.Select(r => r.UncompressedSize) + .Aggregate((ulong?)0, (a, b) => a + b); + + // BUG: Technically, we're casting a ulong to a long, but we don't expect + // 9 exabyte steams, so low risk. + if (streamLength.HasValue) + { + CheckResourceGovernor((long)streamLength.Value); + } + + if (IsQuine(newFileEntry)) + { + Logger.Info(IS_QUINE_STRING, fileEntry.Name, fileEntry.FullPath); + throw new OverflowException(); + } + + foreach (var extractedFile in ExtractFile(newFileEntry, parallel)) + { + yield return extractedFile; + } } - catch(Exception) + else { - Console.WriteLine($"Failed to extract {fileEntry.FullPath}"); + yield return fileEntry; } + xzStream?.Dispose(); + } - var newFilename = Path.GetFileNameWithoutExtension(fileEntry.Name); - if (fileEntry.Name.EndsWith(".tgz", System.StringComparison.CurrentCultureIgnoreCase)) + /// + /// Extracts an BZip2 file contained in fileEntry. + /// + /// FileEntry to extract + /// Extracted files + private IEnumerable ExtractBZip2File(FileEntry fileEntry, bool parallel) + { + BZip2Stream? bzip2Stream = null; + try + { + bzip2Stream = new BZip2Stream(fileEntry.Content, SharpCompress.Compressors.CompressionMode.Decompress, false); + CheckResourceGovernor(bzip2Stream.Length); + } + catch (Exception e) { - if (newFilename.Length >= 3) //fix #191 short names e.g. a.tgz exception + Logger.Debug(DEBUG_STRING, ArchiveFileType.BZIP2, fileEntry.FullPath, string.Empty, e.GetType()); + } + if (bzip2Stream != null) + { + var newFilename = Path.GetFileNameWithoutExtension(fileEntry.Name); + var newFileEntry = new FileEntry(newFilename, bzip2Stream, fileEntry); + + if (IsQuine(newFileEntry)) { - newFilename = newFilename[0..^4] + ".tar"; + Logger.Info(IS_QUINE_STRING, fileEntry.Name, fileEntry.FullPath); + bzip2Stream.Dispose(); + throw new OverflowException(); } - else + + foreach (var extractedFile in ExtractFile(newFileEntry, parallel)) { - newFilename += ".tar"; + yield return extractedFile; } + bzip2Stream.Dispose(); + } + else + { + yield return fileEntry; } + } - var newFileEntry = new FileEntry(newFilename, fileEntry.FullPath, memoryStream); + /// + /// Extracts a RAR file contained in fileEntry. + /// + /// FileEntry to extract + /// Extracted files + private IEnumerable ExtractRarFile(FileEntry fileEntry, bool parallel) + { + // TODO: This produces unpredictable results when run on Azure Pipelines, but cannot reproduce locally + if (parallel) + { + foreach (var entry in ParallelExtractRarFile(fileEntry)) + { + yield return entry; + } + yield break; + } + RarArchive? rarArchive = null; + try + { + rarArchive = RarArchive.Open(fileEntry.Content); + } + catch (Exception e) + { + Logger.Debug(DEBUG_STRING, ArchiveFileType.RAR, fileEntry.FullPath, string.Empty, e.GetType()); + } - return ExtractFile(newFileEntry); + if (rarArchive != null) + { + foreach (var entry in rarArchive.Entries) + { + if (entry.IsDirectory) + { + continue; + } + CheckResourceGovernor(entry.Size); + FileEntry? newFileEntry = null; + try + { + newFileEntry = new FileEntry(entry.Key, entry.OpenEntryStream(), fileEntry); + } + catch (Exception e) + { + Logger.Debug(DEBUG_STRING, ArchiveFileType.RAR, fileEntry.FullPath, entry.Key, e.GetType()); + } + if (newFileEntry != null) + { + if (IsQuine(newFileEntry)) + { + Logger.Info(IS_QUINE_STRING, fileEntry.Name, fileEntry.FullPath); + throw new OverflowException(); + } + foreach (var extractedFile in ExtractFile(newFileEntry, parallel)) + { + yield return extractedFile; + } + } + } + } + else + { + yield return fileEntry; + } } - private static IEnumerable ExtractTarFile(FileEntry fileEntry) + /// + /// Extracts a 7-Zip file contained in fileEntry. + /// + /// FileEntry to extract + /// Extracted files + private IEnumerable Extract7ZipFile(FileEntry fileEntry, bool parallel) { - List files = new List(); - TarEntry tarEntry; + if (parallel) + { + foreach (var entry in ParallelExtract7ZipFile(fileEntry)) + { + yield return entry; + } + yield break; + } + SevenZipArchive? sevenZipArchive = null; try { - using var tarStream = new TarInputStream(fileEntry.Content); - while ((tarEntry = tarStream.GetNextEntry()) != null) + sevenZipArchive = SevenZipArchive.Open(fileEntry.Content); + } + catch (Exception e) + { + Logger.Debug(DEBUG_STRING, ArchiveFileType.P7ZIP, fileEntry.FullPath, string.Empty, e.GetType()); + } + if (sevenZipArchive != null) + { + foreach (var entry in sevenZipArchive.Entries) { - if (!tarEntry.IsDirectory) + if (entry.IsDirectory) + { + continue; + } + CheckResourceGovernor(entry.Size); + FileEntry? newFileEntry = null; + try + { + newFileEntry = new FileEntry(entry.Key, entry.OpenEntryStream(), fileEntry); + } + catch (Exception e) + { + Logger.Debug(DEBUG_STRING, ArchiveFileType.P7ZIP, fileEntry.FullPath, entry.Key, e.GetType()); + } + if (newFileEntry != null) { - using var memoryStream = new MemoryStream(); - tarStream.CopyEntryContents(memoryStream); + if (IsQuine(newFileEntry)) + { + Logger.Info(IS_QUINE_STRING, fileEntry.Name, fileEntry.FullPath); + throw new OverflowException(); + } + foreach (var extractedFile in ExtractFile(newFileEntry, parallel)) + { + yield return extractedFile; + } + } + } + } + else + { + yield return fileEntry; + } + } - var newFileEntry = new FileEntry(tarEntry.Name, fileEntry.FullPath, memoryStream); - files.AddRange(ExtractFile(newFileEntry)); + /// + /// Extracts a .deb file contained in fileEntry. + /// + /// FileEntry to extract + /// Extracted files + private IEnumerable ExtractDebFile(FileEntry fileEntry, bool parallel) + { + if (parallel) + { + foreach (var entry in ParallelExtractDebFile(fileEntry)) + { + yield return entry; + } + yield break; + } + IEnumerable? fileEntries = null; + try + { + fileEntries = DebArchiveFile.GetFileEntries(fileEntry); + } + catch (Exception e) + { + Logger.Debug(DEBUG_STRING, ArchiveFileType.DEB, fileEntry.FullPath, string.Empty, e.GetType()); + } + if (fileEntries != null) + { + foreach (var entry in fileEntries) + { + if (entry.Name == "control.tar.xz") + { + // This is control information for debian and not part of the actual files + continue; + } + CheckResourceGovernor(entry.Content.Length); + foreach (var extractedFile in ExtractFile(entry, parallel)) + { + yield return extractedFile; } } } - catch (Exception) + else { - Console.WriteLine($"Failed to extract {fileEntry.FullPath}"); + yield return fileEntry; } - - return files; } - private static IEnumerable ExtractXZFile(FileEntry fileEntry) + /// + /// Extracts a RAR file contained in fileEntry. + /// + /// FileEntry to extract + /// Extracted files + private IEnumerable ParallelExtractRarFile(FileEntry fileEntry) { - using var memoryStream = new MemoryStream(); + ConcurrentStack files = new ConcurrentStack(); + RarArchive? rarArchive = null; + List entries = new List(); try { - using var xzStream = new XZStream(fileEntry.Content); - xzStream.CopyTo(memoryStream); + rarArchive = RarArchive.Open(fileEntry.Content); + entries.AddRange(rarArchive.Entries.Where(entry => !entry.IsDirectory && !entry.IsEncrypted && entry.IsComplete)); + } + catch (Exception e) + { + Logger.Debug(DEBUG_STRING, ArchiveFileType.RAR, fileEntry.FullPath, string.Empty, e.GetType()); } - catch (Exception) + + if (!entries.Any()) { - Console.WriteLine($"Failed to extract {fileEntry.FullPath}"); + yield return fileEntry; + } + while (entries.Any()) + { + int batchSize = Math.Min(MAX_BATCH_SIZE, entries.Count()); + + var streams = entries.Take(batchSize).Select(entry => (entry, entry.OpenEntryStream())).ToList(); + + CheckResourceGovernor(streams.Sum(x => x.Item2.Length)); + + streams.AsParallel().ForAll(streampair => + { + try + { + var newFileEntry = new FileEntry(streampair.entry.Key, streampair.Item2, fileEntry); + if (IsQuine(newFileEntry)) + { + Logger.Info(IS_QUINE_STRING, fileEntry.Name, fileEntry.FullPath); + CurrentOperationProcessedBytesLeft = -1; + } + else + { + files.PushRange(ExtractFile(newFileEntry, true).ToArray()); + } + } + catch (Exception e) + { + Logger.Debug(DEBUG_STRING, ArchiveFileType.RAR, fileEntry.FullPath, streampair.entry.Key, e.GetType()); + } + }); + CheckResourceGovernor(0); + + entries.RemoveRange(0, batchSize); + + while (files.TryPop(out FileEntry? result)) + { + if (result != null) + yield return result; + } } - var newFilename = Path.GetFileNameWithoutExtension(fileEntry.Name); - var newFileEntry = new FileEntry(newFilename, fileEntry.FullPath, memoryStream); - return ExtractFile(newFileEntry); } - private static IEnumerable ExtractBZip2File(FileEntry fileEntry) - { - using var memoryStream = new MemoryStream(); - try{ - using var bzip2Stream = new BZip2Stream(fileEntry.Content, SharpCompress.Compressors.CompressionMode.Decompress, false); - bzip2Stream.CopyTo(memoryStream); + /// + /// Extracts an zip file contained in fileEntry. + /// + /// FileEntry to extract + /// Extracted files + private IEnumerable ParallelExtractZipFile(FileEntry fileEntry) + { + ConcurrentStack files = new ConcurrentStack(); + + ZipFile? zipFile = null; + try + { + zipFile = new ZipFile(fileEntry.Content); } - catch (Exception) + catch (Exception e) { - Console.WriteLine($"Failed to extract {fileEntry.FullPath}"); + Logger.Debug(DEBUG_STRING, ArchiveFileType.ZIP, fileEntry.FullPath, string.Empty, e.GetType()); } + if (zipFile != null) + { + var zipEntries = new List(); + foreach (ZipEntry? zipEntry in zipFile) + { + if (zipEntry is null || + zipEntry.IsDirectory || + zipEntry.IsCrypted || + !zipEntry.CanDecompress) + { + continue; + } + zipEntries.Add(zipEntry); + } + + while (zipEntries.Count > 0) + { + int batchSize = Math.Min(MAX_BATCH_SIZE, zipEntries.Count); + var selectedEntries = zipEntries.GetRange(0, batchSize); + CheckResourceGovernor(selectedEntries.Sum(x => x.Size)); + try + { + selectedEntries.AsParallel().ForAll(zipEntry => + { + try + { + var zipStream = zipFile.GetInputStream(zipEntry); + var newFileEntry = new FileEntry(zipEntry.Name, zipStream, fileEntry); + if (IsQuine(newFileEntry)) + { + Logger.Info(IS_QUINE_STRING, fileEntry.Name, fileEntry.FullPath); + CurrentOperationProcessedBytesLeft = -1; + } + else + { + files.PushRange(ExtractFile(newFileEntry, true).ToArray()); + } + } + catch (Exception e) when (e is OverflowException) + { + Logger.Debug(DEBUG_STRING, ArchiveFileType.ZIP, fileEntry.FullPath, zipEntry.Name, e.GetType()); + throw; + } + catch (Exception e) + { + Logger.Debug(DEBUG_STRING, ArchiveFileType.ZIP, fileEntry.FullPath, zipEntry.Name, e.GetType()); + } + }); + } + catch (Exception e) when (e is AggregateException) + { + if (e.InnerException?.GetType() == typeof(OverflowException)) + { + throw e.InnerException; + } + throw; + } - var newFilename = Path.GetFileNameWithoutExtension(fileEntry.Name); - var newFileEntry = new FileEntry(newFilename, fileEntry.FullPath, memoryStream); - return ExtractFile(newFileEntry); + CheckResourceGovernor(0); + zipEntries.RemoveRange(0, batchSize); + + while (files.TryPop(out FileEntry? result)) + { + if (result != null) + yield return result; + } + } + } + else + { + yield return fileEntry; + } } - private static IEnumerable ExtractRarFile(FileEntry fileEntry) + /// + /// Extracts a 7-Zip file contained in fileEntry. + /// + /// FileEntry to extract + /// Extracted files + private IEnumerable ParallelExtract7ZipFile(FileEntry fileEntry) { - List files = new List(); + SevenZipArchive? sevenZipArchive = null; + ConcurrentStack files = new ConcurrentStack(); try { - using var rarArchive = RarArchive.Open(fileEntry.Content); + sevenZipArchive = SevenZipArchive.Open(fileEntry.Content); + } + catch (Exception e) + { + Logger.Debug(DEBUG_STRING, ArchiveFileType.P7ZIP, fileEntry.FullPath, string.Empty, e.GetType()); + } + if (sevenZipArchive != null) + { + var entries = sevenZipArchive.Entries.Where(x => !x.IsDirectory && !x.IsEncrypted && x.IsComplete).ToList(); + while (entries.Count() > 0) + { + int batchSize = Math.Min(MAX_BATCH_SIZE, entries.Count()); + var selectedEntries = entries.GetRange(0, batchSize).Select(entry => (entry, entry.OpenEntryStream())); + CheckResourceGovernor(selectedEntries.Sum(x => x.entry.Size)); - Parallel.ForEach(rarArchive.Entries, entry => + try + { + selectedEntries.AsParallel().ForAll(entry => + { + try + { + var newFileEntry = new FileEntry(entry.entry.Key, entry.Item2, fileEntry); + if (IsQuine(newFileEntry)) + { + Logger.Info(IS_QUINE_STRING, fileEntry.Name, fileEntry.FullPath); + CurrentOperationProcessedBytesLeft = -1; + } + else + { + files.PushRange(ExtractFile(newFileEntry, true).ToArray()); + } + } + catch (Exception e) when (e is OverflowException) + { + Logger.Debug(DEBUG_STRING, ArchiveFileType.P7ZIP, fileEntry.FullPath, entry.entry.Key, e.GetType()); + throw; + } + catch (Exception e) + { + Logger.Debug(DEBUG_STRING, ArchiveFileType.P7ZIP, fileEntry.FullPath, entry.entry.Key, e.GetType()); + } + }); + } + catch(Exception e) when (e is AggregateException) + { + if (e.InnerException?.GetType() == typeof(OverflowException)) + { + throw e.InnerException; + } + throw; + } + + CheckResourceGovernor(0); + entries.RemoveRange(0, batchSize); + + while (files.TryPop(out FileEntry? result)) + { + if (result != null) + yield return result; + } + } + } + else + { + yield return fileEntry; + } + } + + /// + /// Extracts a .deb file contained in fileEntry. + /// + /// FileEntry to extract + /// Extracted files + private IEnumerable ParallelExtractDebFile(FileEntry fileEntry) + { + ConcurrentStack files = new ConcurrentStack(); + IEnumerable? fileEntries = null; + try + { + fileEntries = DebArchiveFile.GetFileEntries(fileEntry); + } + catch (Exception e) + { + Logger.Debug(DEBUG_STRING, ArchiveFileType.DEB, fileEntry.FullPath, string.Empty, e.GetType()); + } + if (fileEntries != null) + { + // This is control information for Debian's installer wizardy and not part of the actual files + var entries = fileEntries.Where(x => x.Name != "control.tar.xz"); + while (entries.Any()) { - if (!entry.IsDirectory) + int batchSize = Math.Min(MAX_BATCH_SIZE, entries.Count()); + var selectedEntries = entries.Take(batchSize); + + CheckResourceGovernor(selectedEntries.Sum(x => x.Content.Length)); + + selectedEntries.AsParallel().ForAll(entry => { - var newFileEntry = new FileEntry(entry.Key, fileEntry.FullPath, entry.OpenEntryStream()); - files.AddRange(ExtractFile(newFileEntry)); + files.PushRange(ExtractFile(entry, true).ToArray()); + }); + + entries = entries.Skip(batchSize); + + while (files.TryPop(out FileEntry? result)) + { + if (result != null) + yield return result; } - }); + } } - catch (Exception) + else + { + yield return fileEntry; + } + } + + /// + /// Extracts an iso file contained in fileEntry. + /// + /// FileEntry to extract + /// Extracted files + private IEnumerable ParallelExtractIsoFile(FileEntry fileEntry) + { + ConcurrentStack files = new ConcurrentStack(); + + using CDReader cd = new CDReader(fileEntry.Content, true); + var cdFiles = cd.GetFiles(cd.Root.FullName, "*.*", SearchOption.AllDirectories).ToList(); + while (cdFiles.Count > 0) { - Console.WriteLine($"Failed to extract {fileEntry.FullPath}"); + int batchSize = Math.Min(MAX_BATCH_SIZE, cdFiles.Count); + var selectedFileNames = cdFiles.GetRange(0, batchSize); + var fileInfoTuples = new List<(DiscFileInfo, Stream)>(); + + foreach (var selectedFileName in selectedFileNames) { + try + { + var fileInfo = cd.GetFileInfo(selectedFileName); + var stream = fileInfo.OpenRead(); + fileInfoTuples.Add((fileInfo, stream)); + } + catch(Exception e) + { + Logger.Debug("Failed to get FileInfo or OpenStream from {0} in ISO {1} ({2}:{3})", selectedFileName, fileEntry.FullPath, e.GetType(), e.Message); + } + } + CheckResourceGovernor(fileInfoTuples.Sum(x => x.Item1.Length)); + + fileInfoTuples.AsParallel().ForAll(cdFile => + { + var newFileEntry = new FileEntry(cdFile.Item1.Name, cdFile.Item2, fileEntry); + var entries = ExtractFile(newFileEntry, true); + files.PushRange(entries.ToArray()); + }); + + cdFiles.RemoveRange(0, batchSize); + + while (files.TryPop(out FileEntry? result)) + { + if (result != null) + yield return result; + } } + } - return files; + /// + /// + /// + /// + /// + private IEnumerable DumpLogicalVolume(LogicalVolumeInfo volume, string parentPath, bool parallel, FileEntry? parent = null) + { + var fsInfos = FileSystemManager.DetectFileSystems(volume); + foreach (var fsInfo in fsInfos) + { + using var fs = fsInfo.Open(volume); + var diskFiles = fs.GetFiles(fs.Root.FullName, "*.*", SearchOption.AllDirectories).ToList(); + if (parallel) + { + ConcurrentStack files = new ConcurrentStack(); + + while (diskFiles.Any()) + { + int batchSize = Math.Min(MAX_BATCH_SIZE, diskFiles.Count); + var range = diskFiles.GetRange(0, batchSize); + var fileinfos = new List<(DiscFileInfo,Stream)>(); + long totalLength = 0; + foreach (var r in range) + { + try + { + var fi = fs.GetFileInfo(r); + totalLength += fi.Length; + fileinfos.Add((fi,fi.OpenRead())); + } + catch (Exception e) + { + Logger.Debug("Failed to get FileInfo from {0} in Volume {1} @ {2} ({3}:{4})", r, volume.Identity, parentPath, e.GetType(), e.Message); + } + } + + CheckResourceGovernor(totalLength); + + fileinfos.AsParallel().ForAll(file => + { + if (file.Item2 != null) + { + var newFileEntry = new FileEntry($"{volume.Identity}\\{file.Item1.FullName}", file.Item2, parent); + var entries = ExtractFile(newFileEntry, true); + files.PushRange(entries.ToArray()); + } + }); + diskFiles.RemoveRange(0, batchSize); + + while (files.TryPop(out FileEntry? result)) + { + if (result != null) + yield return result; + } + } + } + else + { + foreach (var file in diskFiles) + { + Stream? fileStream = null; + try + { + var fi = fs.GetFileInfo(file); + CheckResourceGovernor(fi.Length); + fileStream = fi.OpenRead(); + } + catch (Exception e) + { + Logger.Debug(e, "Failed to open {0} in volume {1}", file, volume.Identity); + } + if (fileStream != null) + { + var newFileEntry = new FileEntry($"{volume.Identity}\\{file}", fileStream, parent); + var entries = ExtractFile(newFileEntry, parallel); + foreach (var entry in entries) + { + yield return entry; + } + } + } + } + } } - private static IEnumerable Extract7ZipFile(FileEntry fileEntry) + /// + /// Extracts an a Wim file + /// + /// + /// + private IEnumerable ParallelExtractWimFile(FileEntry fileEntry) { - List files = new List(); - try { - using var rarArchive = RarArchive.Open(fileEntry.Content); + ConcurrentStack files = new ConcurrentStack(); - Parallel.ForEach(rarArchive.Entries, entry => + DiscUtils.Wim.WimFile baseFile = new DiscUtils.Wim.WimFile(fileEntry.Content); + for (int i = 0; i < baseFile.ImageCount; i++) + { + var image = baseFile.GetImage(i); + var fileList = image.GetFiles(image.Root.FullName, "*.*", SearchOption.AllDirectories).ToList(); + while (fileList.Any()) { - if (!entry.IsDirectory) + int batchSize = Math.Min(MAX_BATCH_SIZE, fileList.Count); + var range = fileList.Take(batchSize); + var streamsAndNames = new List<(DiscFileInfo, Stream)>(); + foreach(var file in range) { - var newFileEntry = new FileEntry(entry.Key, fileEntry.FullPath, entry.OpenEntryStream()); - files.AddRange(ExtractFile(newFileEntry)); + try + { + var info = image.GetFileInfo(file); + streamsAndNames.Add((info, info.OpenRead())); + } + catch (Exception e) + { + Logger.Debug("Error reading {0} from WIM {1} ({2}:{3})", file, image.FriendlyName, e.GetType(), e.Message); + } } - }); + CheckResourceGovernor(streamsAndNames.Sum(x => x.Item1.Length)); + streamsAndNames.AsParallel().ForAll(file => + { + var newFileEntry = new FileEntry($"{image.FriendlyName}\\{file.Item1.FullName}", file.Item2, fileEntry); + var entries = ExtractFile(newFileEntry, true); + files.PushRange(entries.ToArray()); + }); + fileList.RemoveRange(0, batchSize); + + while (files.TryPop(out FileEntry? result)) + { + if (result != null) + yield return result; + } + } } - catch(Exception) + } + + /// + /// Check if the fileEntry is a quine + /// + /// + /// + public static bool IsQuine(FileEntry fileEntry) + { + var next = fileEntry.Parent; + var current = fileEntry; + + while(next != null) { - Console.WriteLine($"Failed to extract {fileEntry.FullPath}"); + if (AreIdentical(current, next)) + { + return true; + } + current = next; + next = next.Parent; } + + return false; + } - return files; + /// + /// Check if the two files are identical (i.e. Extraction is a quine) + /// + /// + /// + /// + public static bool AreIdentical(FileEntry fileEntry1, FileEntry fileEntry2) + { + var stream1 = fileEntry1.Content; + var stream2 = fileEntry2.Content; + lock (stream1) + { + lock (stream2) + { + if (stream1.CanRead && stream2.CanRead && stream1.Length == stream2.Length && fileEntry1.Name == fileEntry2.Name) + { + Span buffer1 = stackalloc byte[1024]; + Span buffer2 = stackalloc byte[1024]; + + var position1 = fileEntry1.Content.Position; + var position2 = fileEntry2.Content.Position; + stream1.Position = 0; + stream2.Position = 0; + var bytesRemaining = stream2.Length; + while (bytesRemaining > 0) + { + stream1.Read(buffer1); + stream2.Read(buffer2); + if (!buffer1.SequenceEqual(buffer2)) + { + stream1.Position = position1; + stream2.Position = position2; + return false; + } + bytesRemaining = stream2.Length - stream2.Position; + } + stream1.Position = position1; + stream2.Position = position2; + return true; + } + + return false; + } + } } } - - #endregion internal } diff --git a/MultiExtractor/FileEntry.cs b/MultiExtractor/FileEntry.cs index e498d4e7..e2a6ad48 100644 --- a/MultiExtractor/FileEntry.cs +++ b/MultiExtractor/FileEntry.cs @@ -1,38 +1,95 @@ -// Copyright (C) Microsoft. All rights reserved. -// Licensed under the MIT License. See LICENSE.txt in the project root for license information. +// Copyright (c) Microsoft Corporation. +// Licensed under the MIT License. using System; using System.IO; -namespace MultiExtractor +namespace Microsoft.CST.OpenSource.MultiExtractor { public class FileEntry { - public FileEntry(string name, string parentPath, Stream content) + /// + /// Constructs a FileEntry object from a Stream. + /// If passthroughStream is set to true, and the stream is seekable, it will directly use inputStream. + /// If passthroughStream is false or it is not seekable, it will copy the full contents of inputStream + /// to a new internal FileStream and attempt to reset the position of inputstream. + /// The finalizer for this class Disposes the contained Stream. + /// + /// + /// + /// + /// + /// + public FileEntry(string name, Stream inputStream, FileEntry? parent = null, bool passthroughStream = false) { + Parent = parent; Name = name; - if (string.IsNullOrEmpty(parentPath)) + Passthrough = passthroughStream; + + if (parent == null) { + ParentPath = null; FullPath = Name; } else { - FullPath = $"{parentPath}:{name}"; + ParentPath = parent.FullPath; + FullPath = $"{ParentPath}:{Name}"; } - if (content == null) + + if (inputStream == null) { - throw new ArgumentNullException(nameof(content)); + throw new ArgumentNullException(nameof(inputStream)); } - Content = new MemoryStream(); - if (content.CanSeek) + + // We want to be able to seek, so ensure any passthrough stream is Seekable + if (passthroughStream && inputStream.CanSeek) { - content.Position = 0; + Content = inputStream; + } + else + { + // Back with a temporary filestream, this is optimized to be cached in memory when possible automatically by .NET + Content = new FileStream(Path.GetTempFileName(), FileMode.Create, FileAccess.ReadWrite, FileShare.ReadWrite, 4096, FileOptions.DeleteOnClose); + + long? initialPosition = null; + + if (inputStream.CanSeek) + { + // SharpZipLib doesn't allow you to check .Length, but if .Length is 0 you cannot set position to 0; + initialPosition = inputStream.Position; + + if (inputStream.Position != 0) + { + inputStream.Position = 0; + } + + } + inputStream.CopyTo(Content); + if (inputStream.CanSeek) + { + if (inputStream.Position != 0) + { + inputStream.Position = initialPosition ?? 0; + } + } } - content.CopyTo(Content); + + Content.Position = 0; } + public string? ParentPath { get; set; } public string FullPath { get; set; } + public FileEntry? Parent { get; set; } public string Name { get; set; } - public MemoryStream Content { get; set; } + public Stream Content { get; set; } + private bool Passthrough { get; } + ~FileEntry() + { + if (!Passthrough) + { + Content?.Dispose(); + } + } } } \ No newline at end of file diff --git a/MultiExtractor/MiniMagic.cs b/MultiExtractor/MiniMagic.cs index f6a7bd09..d8312698 100644 --- a/MultiExtractor/MiniMagic.cs +++ b/MultiExtractor/MiniMagic.cs @@ -1,11 +1,16 @@ -// Copyright (C) Microsoft. All rights reserved. -// Licensed under the MIT License. See LICENSE.txt in the project root for license information. +// Copyright (c) Microsoft Corporation. +// Licensed under the MIT License. +using System; using System.Collections.Generic; using System.IO; +using System.Text; -namespace MultiExtractor +namespace Microsoft.CST.OpenSource.MultiExtractor { + /// + /// ArchiveTypes are the kinds of archive files that this module can process. + /// public enum ArchiveFileType { UNKNOWN, @@ -15,54 +20,94 @@ public enum ArchiveFileType GZIP, BZIP2, RAR, - P7ZIP + P7ZIP, + DEB, + AR, + ISO_9660, + VHDX, + VHD, + WIM, + VMDK } + /// + /// MiniMagic is a tiny implementation of a file type identifier based on binary signatures. + /// public static class MiniMagic { + /// + /// Fallback using file extensions in case the binary signature doesn't match. + /// private static readonly Dictionary FileExtensionMap = new Dictionary() { - {"zip", ArchiveFileType.ZIP }, - {"apk", ArchiveFileType.ZIP }, - {"ipa", ArchiveFileType.ZIP }, - {"jar", ArchiveFileType.ZIP }, - {"ear", ArchiveFileType.ZIP }, - {"war", ArchiveFileType.ZIP }, + {"ZIP", ArchiveFileType.ZIP }, + {"APK", ArchiveFileType.ZIP }, + {"IPA", ArchiveFileType.ZIP }, + {"JAR", ArchiveFileType.ZIP }, + {"EAR", ArchiveFileType.ZIP }, + {"WAR", ArchiveFileType.ZIP }, - {"gz", ArchiveFileType.GZIP }, - {"tgz", ArchiveFileType.GZIP }, + {"GZ", ArchiveFileType.GZIP }, + {"TGZ", ArchiveFileType.GZIP }, - {"tar", ArchiveFileType.TAR }, - {"gem", ArchiveFileType.TAR }, + {"TAR", ArchiveFileType.TAR }, + {"GEM", ArchiveFileType.TAR }, - {"xz", ArchiveFileType.XZ }, + {"XZ", ArchiveFileType.XZ }, - {"bz2", ArchiveFileType.BZIP2 }, + {"BZ2", ArchiveFileType.BZIP2 }, - {"rar", ArchiveFileType.RAR }, + {"RAR", ArchiveFileType.RAR }, + {"RAR4", ArchiveFileType.RAR }, - {"7z", ArchiveFileType.P7ZIP } + {"7Z", ArchiveFileType.P7ZIP }, + + {"DEB", ArchiveFileType.DEB }, + + {"AR", ArchiveFileType.AR }, + + {"ISO", ArchiveFileType.ISO_9660 }, + + {"VHDX", ArchiveFileType.VHDX }, + + {"VHD", ArchiveFileType.VHD }, + + {"WIM", ArchiveFileType.WIM }, + + {"VMDK", ArchiveFileType.VMDK } }; public static ArchiveFileType DetectFileType(string filename) { - using var memoryStream = new MemoryStream(File.ReadAllBytes(filename)); - return MiniMagic.DetectFileType(new FileEntry(filename, "", memoryStream)); + #pragma warning disable SEC0116 // Path Tampering Unvalidated File Path + using var fs = new FileStream(filename,FileMode.Open); + #pragma warning restore SEC0116 // Path Tampering Unvalidated File Path + + // If you don't pass passthroughStream: true here it will read the entire file into the stream in FileEntry + // This way it will only read the bytes minimagic uses + var fileEntry = new FileEntry(filename, fs, null, passthroughStream: true); + return DetectFileType(fileEntry); } + /// + /// Detects the type of a file. + /// + /// FileEntry containing the file data. + /// public static ArchiveFileType DetectFileType(FileEntry fileEntry) { if (fileEntry == null) { return ArchiveFileType.UNKNOWN; } - - var buffer = new byte[8]; - if (fileEntry.Content.Length >= 8) + var initialPosition = fileEntry.Content.Position; + Span buffer = stackalloc byte[9]; + if (fileEntry.Content.Length >= 9) { fileEntry.Content.Position = 0; - fileEntry.Content.Read(buffer, 0, 8); - fileEntry.Content.Position = 0; + fileEntry.Content.Read(buffer); + fileEntry.Content.Position = initialPosition; + if (buffer[0] == 0x50 && buffer[1] == 0x4B && buffer[2] == 0x03 && buffer[3] == 0x04) { return ArchiveFileType.ZIP; @@ -90,32 +135,119 @@ public static ArchiveFileType DetectFileType(FileEntry fileEntry) { return ArchiveFileType.P7ZIP; } + if (Encoding.ASCII.GetString(buffer.Slice(0,8)) == "MSWIM\0\0\0" || Encoding.ASCII.GetString(buffer.Slice(0, 8)) == "WLPWM\0\0\0") + { + return ArchiveFileType.WIM; + } + if (Encoding.ASCII.GetString(buffer.Slice(0,4)) == "KDMV") + { + fileEntry.Content.Position = 512; + Span secondToken = stackalloc byte[21]; + fileEntry.Content.Read(secondToken); + fileEntry.Content.Position = initialPosition; + + if (Encoding.ASCII.GetString(secondToken) == "# Disk DescriptorFile") + { + return ArchiveFileType.VMDK; + } + } + // some kind of unix Archive https://en.wikipedia.org/wiki/Ar_(Unix) + if (buffer[0] == 0x21 && buffer[1] == 0x3c && buffer[2] == 0x61 && buffer[3] == 0x72 && buffer[4] == 0x63 && buffer[5] == 0x68 && buffer[6] == 0x3e) + { + // .deb https://manpages.debian.org/unstable/dpkg-dev/deb.5.en.html + fileEntry.Content.Position = 68; + fileEntry.Content.Read(buffer.Slice(0, 4)); + fileEntry.Content.Position = initialPosition; + + var encoding = new ASCIIEncoding(); + if (encoding.GetString(buffer.Slice(0,4)) == "2.0\n") + { + return ArchiveFileType.DEB; + } + else + { + Span headerBuffer = stackalloc byte[60]; + + // Created by GNU ar https://en.wikipedia.org/wiki/Ar_(Unix)#System_V_(or_GNU)_variant + fileEntry.Content.Position = 8; + fileEntry.Content.Read(headerBuffer); + fileEntry.Content.Position = initialPosition; + + var size = int.Parse(Encoding.ASCII.GetString(headerBuffer.Slice(48, 10))); // header size in bytes + + if (size > 0) + { + // Defined ending characters for a header + if (headerBuffer[58]=='`' && headerBuffer[59] == '\n') + { + return ArchiveFileType.AR; + } + } + } + } + // https://winprotocoldoc.blob.core.windows.net/productionwindowsarchives/MS-VHDX/%5bMS-VHDX%5d.pdf + if (Encoding.UTF8.GetString(buffer.Slice(0,8)).Equals("vhdxfile")) + { + return ArchiveFileType.VHDX; + } } if (fileEntry.Content.Length >= 262) { fileEntry.Content.Position = 257; - fileEntry.Content.Read(buffer, 0, 5); - fileEntry.Content.Position = 0; + fileEntry.Content.Read(buffer.Slice(0,5)); + fileEntry.Content.Position = initialPosition; + if (buffer[0] == 0x75 && buffer[1] == 0x73 && buffer[2] == 0x74 && buffer[3] == 0x61 && buffer[4] == 0x72) { return ArchiveFileType.TAR; } } + // ISO Format https://en.wikipedia.org/wiki/ISO_9660#Overall_structure + // Reserved space + 1 header + if (fileEntry.Content.Length > 32768 + 2048) + { + fileEntry.Content.Position = 32769; + fileEntry.Content.Read(buffer.Slice(0, 5)); + fileEntry.Content.Position = initialPosition; + + if (buffer[0] == 'C' && buffer[1] == 'D' && buffer[2] == '0' && buffer[3] == '0' && buffer[4] == '1') + { + return ArchiveFileType.ISO_9660; + } + } + + //https://www.microsoft.com/en-us/download/details.aspx?id=23850 - 'Hard Disk Footer Format' + // Unlike other formats the magic string is stored in the footer, which is either the last 511 or 512 bytes + // The magic string is Magic string "conectix" (63 6F 6E 65 63 74 69 78) + if (fileEntry.Content.Length > 512) + { + Span vhdFooterCookie = stackalloc byte[] { 0x63, 0x6F, 0x6E, 0x65, 0x63, 0x74, 0x69, 0x78 }; + + fileEntry.Content.Position = fileEntry.Content.Length - 0x200; // Footer position + fileEntry.Content.Read(buffer); + fileEntry.Content.Position = initialPosition; + + if (vhdFooterCookie.SequenceEqual(buffer.Slice(0, 8)) + || vhdFooterCookie.SequenceEqual(buffer.Slice(1)))//If created on legacy platform + { + return ArchiveFileType.VHD; + } + } + // Fall back to file extensions -#pragma warning disable CA1308 // Normalize strings to uppercase - string fileExtension = Path.GetExtension(fileEntry.Name.ToLowerInvariant()); -#pragma warning restore CA1308 // Normalize strings to uppercase + string fileExtension = Path.GetExtension(fileEntry.Name.ToUpperInvariant()); + if (fileExtension.StartsWith('.')) { fileExtension = fileExtension.Substring(1); } - if (!MiniMagic.FileExtensionMap.TryGetValue(fileExtension, out ArchiveFileType fileType)) + if (!FileExtensionMap.TryGetValue(fileExtension, out ArchiveFileType fileType)) { fileType = ArchiveFileType.UNKNOWN; } return fileType; } } -} \ No newline at end of file +} diff --git a/MultiExtractor/MultiExtractor.csproj b/MultiExtractor/MultiExtractor.csproj deleted file mode 100644 index 725bdee8..00000000 --- a/MultiExtractor/MultiExtractor.csproj +++ /dev/null @@ -1,24 +0,0 @@ - - - - netcoreapp3.1 - Microsoft.MultiExtractor - Microsoft - Microsoft - MultiExtractor is a library for performing file extraction from many different types of file archives, recursively. - © Microsoft Corporation. All rights reserved. - MIT - false - - - - false - - - - - - - - - diff --git a/MultiExtractor/Shared.MultiExtractor.csproj b/MultiExtractor/Shared.MultiExtractor.csproj new file mode 100644 index 00000000..805a433a --- /dev/null +++ b/MultiExtractor/Shared.MultiExtractor.csproj @@ -0,0 +1,37 @@ + + + + netcoreapp3.1 + Microsoft.CST.OpenSource + Microsoft Corporation + OSS Gadget - Recursive Multi-Format Extractor + Michael Scovetta + GitHub + https://github.com/Microsoft/OSSGadget + Debug;Release + 8.0 + Enable + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/RulesEngine/RuleProcessor.cs b/RulesEngine/RuleProcessor.cs index c88ec08d..d5742cb8 100644 --- a/RulesEngine/RuleProcessor.cs +++ b/RulesEngine/RuleProcessor.cs @@ -3,6 +3,7 @@ using NLog; using System; +using System.Collections.Concurrent; using System.Collections.Generic; using System.Linq; @@ -18,7 +19,7 @@ public class RuleProcessor private Confidence ConfidenceLevelFilter { get; set; } private readonly bool _stopAfterFirstPatternMatch; private readonly bool _uniqueTagMatchesOnly; - private readonly HashSet _uniqueTagHashes; + private readonly ConcurrentDictionary _uniqueTagHashes; private readonly Logger _logger; private RuleSet _ruleset; private Dictionary> _rulesCache; @@ -43,7 +44,7 @@ public class RuleProcessor /// public RuleProcessor(RuleSet rules, Confidence confidence, bool uniqueTagMatches = false, bool stopAfterFirstPatternMatch = false, Logger logger = null) { - _uniqueTagHashes = new HashSet(); + _uniqueTagHashes = new ConcurrentDictionary(); _stopAfterFirstPatternMatch = stopAfterFirstPatternMatch; _uniqueTagMatchesOnly = uniqueTagMatches; _logger = logger; @@ -321,7 +322,7 @@ private bool UniqueTagsCheck(string[] ruleTags) foreach (string tag in ruleTags) { - if (!_uniqueTagHashes.Contains(tag)) + if (_uniqueTagHashes.TryAdd(tag, 0)) { approved = true; break; @@ -356,8 +357,7 @@ private void AddRuleTagHashes(string[] ruleTags) { foreach (string t in ruleTags) { - bool added = _uniqueTagHashes.Add(t); - if (_logger != null && added) + if (_uniqueTagHashes.TryAdd(t,0) && _logger != null) { _logger.Debug(string.Format("Unique tag {0} added", t)); } diff --git a/UnitTest.Commands/Tests_NuGet/TestAnalyzeCmd.cs b/UnitTest.Commands/Tests_NuGet/TestAnalyzeCmd.cs index 242256e3..8341c145 100644 --- a/UnitTest.Commands/Tests_NuGet/TestAnalyzeCmd.cs +++ b/UnitTest.Commands/Tests_NuGet/TestAnalyzeCmd.cs @@ -250,8 +250,8 @@ public void DefaultAndCustomRulesMatched_Pass() { AnalyzeCommand command = new AnalyzeCommand(options); AnalyzeResult result = command.GetResult(); - if (result.Metadata.UniqueTags.Any(v => v.Contains("Authentication.General")) && - result.Metadata.UniqueTags.Any(v => v.Contains("Data.Custom1"))) + if (result.Metadata.UniqueTags.Keys.Any(v => v.Contains("Authentication.General")) && + result.Metadata.UniqueTags.Keys.Any(v => v.Contains("Data.Custom1"))) { exitCode = AnalyzeResult.ExitCode.Success; } diff --git a/UnitTest.Commands/UnitTest.Commands.csproj b/UnitTest.Commands/UnitTest.Commands.csproj index 95ed6d7c..9f4831d6 100644 --- a/UnitTest.Commands/UnitTest.Commands.csproj +++ b/UnitTest.Commands/UnitTest.Commands.csproj @@ -23,7 +23,6 @@ -