Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Extensions support #2611

Merged
merged 6 commits into from
Jan 27, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
819 changes: 406 additions & 413 deletions src/ReleaseHistory.md

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion src/Samples/Sarif.Sdk.Sample/Program.cs
Original file line number Diff line number Diff line change
Expand Up @@ -351,7 +351,7 @@ private static void SerializeSarifResult(string filePath, int numResult, bool us
region,
fixes[i]))
{
sarifLogger.Log(rule, result);
sarifLogger.Log(rule, result, extensionIndex: null);
}
}
}
Expand Down
2 changes: 1 addition & 1 deletion src/Samples/SarifTrim/Program.cs
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,7 @@ private static void Main(string[] args)
foreach (Result result in run.Results)
{
consolidator.Trim(result);
logger.Log(result.GetRule(run), result);
logger.Log(result.GetRule(run), result, extensionIndex: null);
}
}

Expand Down
4 changes: 2 additions & 2 deletions src/Sarif.Driver/Sdk/AggregatingLogger.cs
Original file line number Diff line number Diff line change
Expand Up @@ -53,11 +53,11 @@ public void AnalyzingTarget(IAnalysisContext context)
}
}

public void Log(ReportingDescriptor rule, Result result)
public void Log(ReportingDescriptor rule, Result result, int? extensionIndex)
{
foreach (IAnalysisLogger logger in Loggers)
{
logger.Log(rule, result);
logger.Log(rule, result, extensionIndex);
}
}

Expand Down
6 changes: 3 additions & 3 deletions src/Sarif.Driver/Sdk/AnalyzeCommandBase.cs
Original file line number Diff line number Diff line change
Expand Up @@ -631,7 +631,7 @@ protected virtual TContext DetermineApplicabilityAndAnalyze(

if ((options.DataToInsert.ToFlags() & OptionallyEmittedData.Hashes) != 0)
{
_cacheByFileHashLogger.HashToResultsMap.TryGetValue(context.Hashes.Sha256, out List<Tuple<ReportingDescriptor, Result>> cachedResultTuples);
_cacheByFileHashLogger.HashToResultsMap.TryGetValue(context.Hashes.Sha256, out List<Tuple<ReportingDescriptor, Result, int?>> cachedResultTuples);
_cacheByFileHashLogger.HashToNotificationsMap.TryGetValue(context.Hashes.Sha256, out List<Notification> cachedNotifications);

bool replayCachedData = (cachedResultTuples != null || cachedNotifications != null);
Expand All @@ -642,13 +642,13 @@ protected virtual TContext DetermineApplicabilityAndAnalyze(

if (cachedResultTuples != null)
{
foreach (Tuple<ReportingDescriptor, Result> cachedResultTuple in cachedResultTuples)
foreach (Tuple<ReportingDescriptor, Result, int?> cachedResultTuple in cachedResultTuples)
{
Result clonedResult = cachedResultTuple.Item2.DeepClone();
ReportingDescriptor cachedReportingDescriptor = cachedResultTuple.Item1;

UpdateLocationsAndMessageWithCurrentUri(clonedResult.Locations, clonedResult.Message, context.TargetUri);
context.Logger.Log(cachedReportingDescriptor, clonedResult);
context.Logger.Log(cachedReportingDescriptor, clonedResult, cachedResultTuple.Item3);
}
}

Expand Down
34 changes: 20 additions & 14 deletions src/Sarif.Driver/Sdk/MultithreadedAnalyzeCommandBase.cs
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,6 @@ public abstract class MultithreadedAnalyzeCommandBase<TContext, TOptions> : Plug
internal ConsoleLogger _consoleLogger;

private Run _run;
private Tool _tool;
private bool _computeHashes;
internal TContext _rootContext;
private int _fileContextsCount;
Expand All @@ -48,6 +47,8 @@ public abstract class MultithreadedAnalyzeCommandBase<TContext, TOptions> : Plug

public static bool RaiseUnhandledExceptionInDriverCode { get; set; }

protected virtual Tool Tool { get; set; }

public virtual FileFormat ConfigurationFormat => FileFormat.Json;

protected MultithreadedAnalyzeCommandBase(IFileSystem fileSystem = null)
Expand Down Expand Up @@ -153,12 +154,16 @@ private void Analyze(TOptions analyzeOptions, AggregatingLogger logger)
// the command line parser library is capable of.
ValidateOptions(analyzeOptions, _rootContext);

// 5. Initialize report file, if configured.
InitializeOutputFile(analyzeOptions, _rootContext);

// 6. Instantiate skimmers.
// 5. Instantiate skimmers. We need to do this before initializing
// the output file so that we can preconstruct the tool
// extensions data written to the SARIF file. Due to this ordering,
// we won't emit any failures or notifications in this operation
// to the log file itself: it will only appear in console output.
ISet<Skimmer<TContext>> skimmers = CreateSkimmers(analyzeOptions, _rootContext);

// 6. Initialize report file, if configured.
InitializeOutputFile(analyzeOptions, _rootContext);

// 7. Initialize configuration. This step must be done after initializing
// the skimmers, as rules define their specific context objects and
// so those assemblies must be loaded.
Expand Down Expand Up @@ -328,14 +333,15 @@ private async Task<bool> LogScanResultsAsync(TContext rootContext)
private static void LogCachingLogger(TContext rootContext, TContext context, bool clone = false)
{
var cachingLogger = (CachingLogger)context.Logger;
IDictionary<ReportingDescriptor, IList<Result>> results = cachingLogger.Results;
IDictionary<ReportingDescriptor, IList<Tuple<Result, int?>>> results = cachingLogger.Results;

if (results?.Count > 0)
{
foreach (KeyValuePair<ReportingDescriptor, IList<Result>> kv in results)
foreach (KeyValuePair<ReportingDescriptor, IList<Tuple<Result, int?>>> kv in results)
{
foreach (Result result in kv.Value)
foreach (Tuple<Result, int?> tuple in kv.Value)
{
Result result = tuple.Item1;
Result currentResult = result;
if (clone)
{
Expand All @@ -346,7 +352,7 @@ private static void LogCachingLogger(TContext rootContext, TContext context, boo
currentResult = clonedResult;
}

rootContext.Logger.Log(kv.Key, currentResult);
rootContext.Logger.Log(kv.Key, currentResult, tuple.Item2);
}
}
}
Expand Down Expand Up @@ -641,13 +647,13 @@ protected virtual void ValidateOptions(TOptions options, TContext context)

internal AggregatingLogger InitializeLogger(AnalyzeOptionsBase analyzeOptions)
{
_tool = Tool.CreateFromAssemblyData();
Tool ??= Tool.CreateFromAssemblyData();

var logger = new AggregatingLogger();

if (!analyzeOptions.Quiet)
{
_consoleLogger = new ConsoleLogger(analyzeOptions.Quiet, _tool.Driver.Name, analyzeOptions.Level, analyzeOptions.Kind) { CaptureOutput = _captureConsoleOutput };
_consoleLogger = new ConsoleLogger(analyzeOptions.Quiet, Tool.Driver.Name, analyzeOptions.Level, analyzeOptions.Kind) { CaptureOutput = _captureConsoleOutput };
logger.Loggers.Add(_consoleLogger);
}

Expand Down Expand Up @@ -740,7 +746,7 @@ protected virtual void InitializeConfiguration(TOptions options, TContext contex
}
}

private void InitializeOutputFile(TOptions analyzeOptions, TContext context)
public virtual void InitializeOutputFile(TOptions analyzeOptions, TContext context)
{
string filePath = analyzeOptions.OutputFilePath;
var aggregatingLogger = (AggregatingLogger)context.Logger;
Expand Down Expand Up @@ -773,7 +779,7 @@ private void InitializeOutputFile(TOptions analyzeOptions, TContext context)
logFilePersistenceOptions,
dataToInsert,
dataToRemove,
tool: _tool,
tool: Tool,
run: _run,
analysisTargets: null,
quiet: analyzeOptions.Quiet,
Expand All @@ -789,7 +795,7 @@ private void InitializeOutputFile(TOptions analyzeOptions, TContext context)
logFilePersistenceOptions,
dataToInsert,
dataToRemove,
tool: _tool,
tool: Tool,
run: _run,
analysisTargets: null,
invocationTokensToRedact: GenerateSensitiveTokensList(),
Expand Down
4 changes: 4 additions & 0 deletions src/Sarif.Driver/Sdk/Skimmer.cs
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,8 @@ public Skimmer()

public virtual bool EnabledByDefault => true;

public virtual ReportingDescriptorReference ReportingDescriptorReference { get; set; }

public virtual ISet<string> IncompatibleRuleIds { get; internal set; }

public override IDictionary<string, MultiformatMessageString> MessageStrings
Expand All @@ -47,6 +49,8 @@ private Dictionary<string, MultiformatMessageString> InitializeMultiformatMessag
: RuleUtilities.BuildDictionary(ResourceManager, MessageResourceNames, ruleId: Id);
}

public int ExtensionIndex { get; set; }

public override string Id => throw new InvalidOperationException($"The {nameof(Id)} property must be overridden in the SkimmerBase-derived class.");

public override MultiformatMessageString FullDescription => throw new InvalidOperationException($"The {nameof(FullDescription)} property must be overridden in the SkimmerBase-derived class.");
Expand Down
7 changes: 7 additions & 0 deletions src/Sarif/Core/Result.cs
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,13 @@ public partial class Result
/// </remarks>
public Run Run { get; set; }

public bool ShouldSerializeRuleId()
{
return
this.Rule == null || string.IsNullOrEmpty(this.Rule.Id);
}


public bool ShouldSerializeWorkItemUris()
{
return this.WorkItemUris != null && this.WorkItemUris.Any((s) => s != null);
Expand Down
17 changes: 10 additions & 7 deletions src/Sarif/Core/Tool.cs
Original file line number Diff line number Diff line change
Expand Up @@ -20,29 +20,32 @@ public partial class Tool

private static readonly Regex dottedQuadFileVersionRegex = new Regex(DottedQuadFileVersionPattern, RegexOptions.Compiled | RegexOptions.CultureInvariant);

public static Tool CreateFromAssemblyData(Assembly assembly = null, string prereleaseInfo = null)
public static Tool CreateFromAssemblyData(Assembly assembly = null,
bool omitSemanticVersion = false,
IFileSystem fileSystem = null)
{
assembly = assembly ?? Assembly.GetEntryAssembly() ?? Assembly.GetExecutingAssembly();
fileSystem ??= FileSystem.Instance;
assembly ??= Assembly.GetEntryAssembly() ?? Assembly.GetExecutingAssembly();
string name = Path.GetFileNameWithoutExtension(assembly.Location);
Version version = assembly.GetName().Version;

string dottedQuadFileVersion = null;

FileVersionInfo fileVersion = FileVersionInfo.GetVersionInfo(assembly.Location);
FileVersionInfo fileVersion = fileSystem.FileVersionInfoGetVersionInfo(assembly.Location);
if (fileVersion.FileVersion != version.ToString())
{
dottedQuadFileVersion = ParseFileVersion(fileVersion.FileVersion);
dottedQuadFileVersion = ParseFileVersion(version.ToString());
}

Tool tool = new Tool
{
Driver = new ToolComponent
{
Name = name,
FullName = name + " " + version.ToString() + (prereleaseInfo ?? ""),
Version = version.ToString(),
FullName = name + " " + version.ToString(),
Version = fileVersion.FileVersion,
DottedQuadFileVersion = dottedQuadFileVersion,
SemanticVersion = version.Major.ToString() + "." + version.Minor.ToString() + "." + version.Build.ToString(),
SemanticVersion = omitSemanticVersion ? null : fileVersion.ProductVersion,
Organization = string.IsNullOrEmpty(fileVersion.CompanyName) ? null : fileVersion.CompanyName,
Product = string.IsNullOrEmpty(fileVersion.ProductName) ? null : fileVersion.ProductName,
}
Expand Down
13 changes: 13 additions & 0 deletions src/Sarif/FileSystem.cs
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@

using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Reflection;
using System.Text;
Expand Down Expand Up @@ -398,5 +399,17 @@ public long FileInfoLength(string path)
FileInfo fileInfo = new FileInfo(path);
return fileInfo.Length;
}

/// <summary>
/// Returns a <see cref="FileVersionInfo"/> representing the version information associated with the specified file.
/// </summary>
/// <param name="path">The fully qualified path and name of the file to retrieve the version information for.</param>
/// <returns>A <see cref="FileVersionInfo"/> containing information about the file. If the file did not
/// contain version information, the FileVersionInfo contains only the name of the file requested.</returns>
public FileVersionInfo FileVersionInfoGetVersionInfo(string fileName)
{
FileVersionInfo fileVersionInfo = FileVersionInfo.GetVersionInfo(fileName);
return fileVersionInfo;
}
}
}
2 changes: 1 addition & 1 deletion src/Sarif/IAnalysisLogger.cs
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ public interface IAnalysisLogger
/// </summary>
/// <param name="rule"></param>
/// <param name="result"></param>
void Log(ReportingDescriptor rule, Result result);
void Log(ReportingDescriptor rule, Result result, int? extensionIndex = null);

/// <summary>
/// Log a notification that describes a runtime condition detected by the tool.
Expand Down
9 changes: 9 additions & 0 deletions src/Sarif/IFileSystem.cs
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@

using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Reflection;
using System.Text;
Expand Down Expand Up @@ -321,5 +322,13 @@ public interface IFileSystem
/// A long representing the size of the file in bytes.
/// </returns>
long FileInfoLength(string path);

/// <summary>
/// Returns a <see cref="FileVersionInfo"/> representing the version information associated with the specified file.
/// </summary>
/// <param name="path">The fully qualified path and name of the file to retrieve the version information for.</param>
/// <returns>A <see cref="FileVersionInfo"/> containing information about the file. If the file did not
/// contain version information, the FileVersionInfo contains only the name of the file requested.</returns>
FileVersionInfo FileVersionInfoGetVersionInfo(string fileName);
}
}
18 changes: 9 additions & 9 deletions src/Sarif/Writers/CacheByFileHashLogger.cs
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ public class CacheByFileHashLogger : BaseLogger, IAnalysisLogger
private string currentFileHash;

public Dictionary<string, List<Notification>> HashToNotificationsMap { get; private set; }
public Dictionary<string, List<Tuple<ReportingDescriptor, Result>>> HashToResultsMap { get; private set; }
public Dictionary<string, List<Tuple<ReportingDescriptor, Result, int?>>> HashToResultsMap { get; private set; }

public CacheByFileHashLogger(IEnumerable<FailureLevel> levels, IEnumerable<ResultKind> kinds) : base(levels, kinds)
{
Expand All @@ -30,7 +30,7 @@ public CacheByFileHashLogger(IEnumerable<FailureLevel> levels, IEnumerable<Resul
public void AnalysisStarted()
{
HashToNotificationsMap = new Dictionary<string, List<Notification>>();
HashToResultsMap = new Dictionary<string, List<Tuple<ReportingDescriptor, Result>>>();
HashToResultsMap = new Dictionary<string, List<Tuple<ReportingDescriptor, Result, int?>>>();
}

public void AnalysisStopped(RuntimeConditions runtimeConditions)
Expand All @@ -52,11 +52,11 @@ public void AnalyzingTarget(IAnalysisContext context)
{
cacheLoggingData = true;
HashToNotificationsMap[currentFileHash] = new List<Notification>();
HashToResultsMap[currentFileHash] = new List<Tuple<ReportingDescriptor, Result>>();
HashToResultsMap[currentFileHash] = new List<Tuple<ReportingDescriptor, Result, int?>>();
}
}

public void Log(ReportingDescriptor rule, Result result)
public void Log(ReportingDescriptor rule, Result result, int? extensionIndex = null)
{
if (!cacheLoggingData) { return; }

Expand All @@ -65,16 +65,16 @@ public void Log(ReportingDescriptor rule, Result result)
return;
}

CacheResult(rule, result);
CacheResult(rule, result, extensionIndex);
}

private void CacheResult(ReportingDescriptor rule, Result result)
private void CacheResult(ReportingDescriptor rule, Result result, int? extensionIndex)
{
if (!HashToResultsMap.TryGetValue(currentFileHash, out List<Tuple<ReportingDescriptor, Result>> results))
if (!HashToResultsMap.TryGetValue(currentFileHash, out List<Tuple<ReportingDescriptor, Result, int?>> results))
{
results = HashToResultsMap[currentFileHash] = new List<Tuple<ReportingDescriptor, Result>>();
results = HashToResultsMap[currentFileHash] = new List<Tuple<ReportingDescriptor, Result, int?>>();
}
results.Add(new Tuple<ReportingDescriptor, Result>(rule, result));
results.Add(new Tuple<ReportingDescriptor, Result, int?>(rule, result, extensionIndex));
}

public void LogConfigurationNotification(Notification notification)
Expand Down
12 changes: 6 additions & 6 deletions src/Sarif/Writers/CachingLogger.cs
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ public CachingLogger(IEnumerable<FailureLevel> levels, IEnumerable<ResultKind> k
_semaphore = new SemaphoreSlim(initialCount: 1, maxCount: 1);
}

public IDictionary<ReportingDescriptor, IList<Result>> Results { get; set; }
public IDictionary<ReportingDescriptor, IList<Tuple<Result, int?>>> Results { get; set; }

public IList<Notification> ConfigurationNotifications { get; set; }

Expand All @@ -49,7 +49,7 @@ public void AnalyzingTarget(IAnalysisContext context)
_semaphore.Wait();
}

public void Log(ReportingDescriptor rule, Result result)
public void Log(ReportingDescriptor rule, Result result, int? extensionIndex)
{
if (rule == null)
{
Expand All @@ -76,13 +76,13 @@ public void Log(ReportingDescriptor rule, Result result)
throw new ArgumentException($"rule.Id is not equal to result.RuleId ({rule.Id} != {result.RuleId})");
}

Results ??= new Dictionary<ReportingDescriptor, IList<Result>>();
Results ??= new Dictionary<ReportingDescriptor, IList<Tuple<Result, int?>>>();

if (!Results.TryGetValue(rule, out IList<Result> results))
if (!Results.TryGetValue(rule, out IList<Tuple<Result, int?>> results))
{
results = Results[rule] = new List<Result>();
results = Results[rule] = new List<Tuple<Result, int?>>();
}
results.Add(result);
results.Add(new Tuple<Result, int?>(result, extensionIndex));
}

public void LogConfigurationNotification(Notification notification)
Expand Down
Loading