This commit is contained in:
Gabe Stocco 2023-06-21 22:08:07 -07:00 коммит произвёл GitHub
Родитель bd25052fd2
Коммит b830cf902b
Не найден ключ, соответствующий данной подписи
Идентификатор ключа GPG: 4AEE18F83AFDEB23
4 изменённых файлов: 98 добавлений и 60 удалений

1
.gitignore поставляемый
Просмотреть файл

@ -270,3 +270,4 @@ output.html
result.json
AppInspector.Tests/logs/
RulesPacker/appinspector.log.txt
AppInspector.CLI/out.sarif

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

@ -67,7 +67,7 @@
<ItemGroup>
<PackageReference Include="DotLiquid" Version="2.2.692" />
<PackageReference Include="Sarif.Sdk" Version="4.1.0" />
<PackageReference Include="Sarif.Sdk" Version="4.2.0" />
<PackageReference Include="Serilog" Version="2.12.0" />
<PackageReference Include="Serilog.Extensions.Logging" Version="7.0.0" />
<PackageReference Include="Serilog.Sinks.Console" Version="4.1.0" />

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

@ -55,12 +55,45 @@ public class AnalyzeSarifWriter : CommandResultsWriter
if (result is AnalyzeResult analyzeResult)
{
SarifLog log = new();
var sarifVersion = SarifVersion.Current;
log.SchemaUri = sarifVersion.ConvertToSchemaUri();
log.Version = sarifVersion;
SarifLog log = new()
{
Version = SarifVersion.Current
};
log.Runs = new List<Run>();
var run = new Run();
// Convert Base Path to Forward Slashes to be a valid URI
var run = new Run()
{
Tool = new Tool
{
Driver = new ToolComponent
{
Name = "Application Inspector",
InformationUri = new Uri("https://github.com/microsoft/ApplicationInspector/"),
Organization = "Microsoft",
Version = Helpers.GetVersionString()
}
}
};
if (!string.IsNullOrEmpty(basePath))
{
if (Path.DirectorySeparatorChar == '\\')
{
basePath = basePath.Replace("\\","/");
if (!basePath.EndsWith("/"))
{
basePath = $"{basePath}/";
}
}
run.OriginalUriBaseIds = new Dictionary<string, ArtifactLocation>()
{
{ "ROOT", new ArtifactLocation() { Uri = new Uri($"file://{basePath}") } }
};
}
if (Uri.TryCreate(cliAnalyzeCmdOptions.RepositoryUri, UriKind.RelativeOrAbsolute, out var uri))
{
@ -69,7 +102,11 @@ public class AnalyzeSarifWriter : CommandResultsWriter
new()
{
RepositoryUri = uri,
RevisionId = cliAnalyzeCmdOptions.CommitHash
RevisionId = cliAnalyzeCmdOptions.CommitHash,
MappedTo = new ArtifactLocation()
{
UriBaseId = "ROOT"
}
}
};
}
@ -81,22 +118,17 @@ public class AnalyzeSarifWriter : CommandResultsWriter
{
RepositoryUri = analyzeResult.Metadata.RepositoryUri,
RevisionId = analyzeResult.Metadata.CommitHash ?? string.Empty,
Branch = analyzeResult.Metadata.Branch ?? string.Empty
Branch = analyzeResult.Metadata.Branch ?? string.Empty,
MappedTo = new ArtifactLocation()
{
UriBaseId = "ROOT"
}
}
};
}
var artifacts = new List<Artifact>();
run.Tool = new Tool
{
Driver = new ToolComponent
{
Name = "Application Inspector",
InformationUri = new Uri("https://github.com/microsoft/ApplicationInspector/"),
Organization = "Microsoft",
Version = Helpers.GetVersionString()
}
};
var reportingDescriptors = new List<ReportingDescriptor>();
run.Results = new List<CodeAnalysis.Sarif.Result>();
foreach (var match in analyzeResult.Metadata.Matches)
@ -114,14 +146,15 @@ public class AnalyzeSarifWriter : CommandResultsWriter
Name = match.Rule.Name,
DefaultConfiguration = new ReportingConfiguration
{
Level = GetSarifFailureLevel(match.Rule.Severity)
Level = FailureLevel.Note
}
};
reportingDescriptor.Tags.AddRange(match.Rule.Tags);
reportingDescriptor.SetProperty("AppInspector:Severity", match.Rule.Severity.ToString());
reportingDescriptors.Add(reportingDescriptor);
}
sarifResult.Level = GetSarifFailureLevel(match.Rule.Severity);
sarifResult.Level = FailureLevel.Note;
sarifResult.RuleId = match.Rule.Id;
sarifResult.Tags.AddRange(match.Rule.Tags);
sarifResult.Message = new Message
@ -134,7 +167,7 @@ public class AnalyzeSarifWriter : CommandResultsWriter
var fileName = match.FileName;
if (basePath is not null)
{
fileName = Path.GetRelativePath(basePath, fileName);
fileName = Path.GetRelativePath(basePath, fileName).Replace("\\","/");
}
if (Uri.TryCreate(fileName, UriKind.RelativeOrAbsolute, out var outUri))
@ -150,6 +183,10 @@ public class AnalyzeSarifWriter : CommandResultsWriter
Uri = outUri
}
};
if (basePath != null)
{
artifact.Location.UriBaseId = "ROOT";
}
artifactIndex = artifact.Location.Index;
artifact.Tags.AddRange(match.Rule.Tags);
if (match.LanguageInfo is { } languageInfo)
@ -164,30 +201,37 @@ public class AnalyzeSarifWriter : CommandResultsWriter
artifacts[artifactIndex].Tags.AddRange(match.Rule.Tags);
}
sarifResult.Locations = new List<Location>
Location location = new()
{
new()
PhysicalLocation = new PhysicalLocation
{
PhysicalLocation = new PhysicalLocation
ArtifactLocation = new ArtifactLocation
{
ArtifactLocation = new ArtifactLocation
Index = artifactIndex,
Uri = outUri
},
Region = new Region
{
StartLine = match.StartLocationLine,
StartColumn = match.StartLocationColumn,
EndLine = match.EndLocationLine,
EndColumn = match.EndLocationColumn,
Snippet = new ArtifactContent
{
Index = artifactIndex
},
Region = new Region
{
StartLine = match.StartLocationLine,
StartColumn = match.StartLocationColumn,
EndLine = match.EndLocationLine,
EndColumn = match.EndLocationColumn,
Snippet = new ArtifactContent
{
Text = match.Sample
}
Text = match.Sample
}
}
}
};
if (basePath != null)
{
location.PhysicalLocation.ArtifactLocation.UriBaseId = "ROOT";
}
sarifResult.SetProperty("AppInspector:Severity", match.Rule.Severity.ToString());
sarifResult.Locations = new List<Location>
{
location
};
}
}
}
@ -200,7 +244,7 @@ public class AnalyzeSarifWriter : CommandResultsWriter
log.Runs.Add(run);
try
{
JsonSerializer.Serialize(StreamWriter.BaseStream, log);
log.Save(StreamWriter.BaseStream);
}
catch (Exception e)
{

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

@ -181,7 +181,7 @@ public class RuleProcessor
EndLocationColumn = endLocation.Column,
MatchingPattern = oatRule.AppInspectorRule.Patterns[patternIndex],
Excerpt = numLinesContext > 0
? ExtractExcerpt(textContainer, startLocation.Line, numLinesContext)
? ExtractExcerpt(textContainer, startLocation, endLocation, boundary, numLinesContext)
: string.Empty,
Sample = numLinesContext > -1
? ExtractTextSample(textContainer.FullContent, boundary.Index, boundary.Length)
@ -399,7 +399,7 @@ public class RuleProcessor
: startLocation.Line + 1, //match is on last line
MatchingPattern = oatRule.AppInspectorRule.Patterns[patternIndex],
Excerpt = numLinesContext > 0
? ExtractExcerpt(textContainer, startLocation.Line, numLinesContext)
? ExtractExcerpt(textContainer, startLocation, endLocation, boundary, numLinesContext)
: string.Empty,
Sample = numLinesContext > -1
? ExtractTextSample(textContainer.FullContent, boundary.Index, boundary.Length)
@ -554,37 +554,30 @@ public class RuleProcessor
/// from the template
/// </summary>
/// <returns></returns>
private static string ExtractExcerpt(TextContainer text, int startLineNumber, int context = 3)
private static string ExtractExcerpt(TextContainer text, Location start, Location end, Boundary matchBoundary, int context = 3)
{
if (context == 0)
{
return string.Empty;
}
if (startLineNumber < 0)
{
startLineNumber = 0;
}
if (startLineNumber >= text.LineEnds.Count)
{
startLineNumber = text.LineEnds.Count - 1;
}
int startLineNumber =
start.Line < 0 ? 0 : start.Line > text.LineEnds.Count ? text.LineEnds.Count - 1 : start.Line;
int endLineNUmber =
end.Line < 0 ? 0 : end.Line > text.LineEnds.Count ? text.LineEnds.Count - 1 : end.Line;
// First we try to include the number of lines of context requested
var excerptStartLine = Math.Max(0, startLineNumber - context);
var excerptEndLine = Math.Min(text.LineEnds.Count - 1, startLineNumber + context);
var excerptEndLine = Math.Min(text.LineEnds.Count - 1, endLineNUmber + context);
var startIndex = text.LineStarts[excerptStartLine];
var endIndex = text.LineEnds[excerptEndLine] + 1;
// Maximum number of characters to capture on each side
var maxCharacterContext = context * 100;
// Only gather 100*lines context characters to avoid gathering super long lines
if (text.LineStarts[startLineNumber] - startIndex > maxCharacterContext)
// If the number of characters captured for context is larger than 100*number of lines,
// instead gather an appropriate number of characters
if (endIndex - startIndex - matchBoundary.Length > maxCharacterContext * 2)
{
startIndex = Math.Max(0, startIndex - maxCharacterContext);
}
if (endIndex - text.LineEnds[startLineNumber] > maxCharacterContext)
{
endIndex = Math.Min(text.FullContent.Length - 1, endIndex + maxCharacterContext);
startIndex = Math.Max(0, matchBoundary.Index - maxCharacterContext);
endIndex = Math.Max(0, matchBoundary.Index + matchBoundary.Length + maxCharacterContext);
}
return text.FullContent[startIndex..endIndex];