Skip to content

Commit

Permalink
Add new visitor to get deterministic SARIF log by sorting results (#2422
Browse files Browse the repository at this point in the history
)

* Add new visitor to get deterministic SARIF log by sorting results

* Fix dotnet format issue

* updating format

* remove unnecessary using

Format & minor fixes

* Add Run Comparer to support sorting logs with multiple runs.

* Add command argument unit tests

fix dotnet format

* use ContainsKey to avoid allocating variable

* Fixing `AnalyzeCommandBase` and `MultithreadedAnalyzeCommandBase` artifacts generation (#2433)

* Fixing multithreaded artifacts generation

* Fixing tests and flags

* Loosing precision.

* Applying fix for AnalyzeCommandBase

* Enabling tests

* Updating test case and release history

* Creating const to prevent magical numbers everywhere

* Rebaselining tests

* Creating Artifacts flag to keep previous behavior

* Addressing PR feedback.

* Rollback changes

* Update SARIF2012.ProvideRuleProperties_Invalid.sarif

* updating back

* Ordering deprecated names

* `SarifLogger` now emits an artifacts table entry if `artifactLocation` is not null for tool configuration and tool execution notifications. (#2437)

* Fixing artifacts generation when logging notifications

* Updating release history.

* Updating ReleaseHistory

* Fix `ArgumentException` when recurse is enabled and two file target specifiers generates the same file paths (#2438)

* Fixing ArgumentException when passing two filePaths that generates duplicated file analysis

* Fixing dotnet-format issues and updating releasehistory

* Removing comments

* Addressing PR feedback

* Addressing PR feedback

* Addressing PR review issues

Add suppression support (#2435)

* Add suppression support

* Add incompatibility check and make suppressions non-null

Co-authored-by: Eddy Nakamura <eddynaka@gmail.com>

Update releasehistory

fix couple test cases

* Fix issues in PR review

* Add xml comments

* Fix test issues

* fix dotnet format

* Addressing review feedbacks

* Fix tests

* Update extension methods names

* Change xml doc comments to normal comments

Co-authored-by: Eddy Nakamura <eddynaka@gmail.com>
Co-authored-by: Michael C. Fanning <michael.fanning@microsoft.com>
  • Loading branch information
3 people committed Mar 2, 2022
1 parent bedc46e commit 839537f
Show file tree
Hide file tree
Showing 27 changed files with 2,903 additions and 9 deletions.
1 change: 1 addition & 0 deletions src/ReleaseHistory.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
* BUGFIX: Fix `ArgumentException` when `--recurse` is enabled and two file target specifiers generates the same file path. [#2438](https://github.com/microsoft/sarif-sdk/pull/2438)
* BUGFIX: Fix 'InvalidOperationException' with message `Collection was modified; enumeration operation may not execute` in `MultithreadedAnalyzeCommandBase`, which is raised when analyzing with the `--hashes` switch. [#2447](https://github.com/microsoft/sarif-sdk/pull/2447)
* BUGFIX: Fix `Merge` command produces empty SARIF file in Linux when providing file name only without path. [#2408](https://github.com/microsoft/sarif-sdk/pull/2408)
* FEATURE: Add `--sort-results` argument to the `rewrite` command to get sorted SARIF results. [#2422](https://github.com/microsoft/sarif-sdk/pull/2422)
* BUGFIX: Fix `NullReferenceException` when filing work item with a SARIF file which has no filable results. [#2412](https://github.com/microsoft/sarif-sdk/pull/2412)
* BUGFIX: Fix missing `endLine` and `endColumn` properties and remove vulnerable packages for ESLint SARIF formatter. [#2458](https://github.com/microsoft/sarif-sdk/pull/2458)

Expand Down
5 changes: 5 additions & 0 deletions src/Sarif.Multitool.Library/RewriteCommand.cs
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,11 @@ public int Run(RewriteOptions options)
SarifLog reformattedLog = new RemoveOptionalDataVisitor(dataToRemove).VisitSarifLog(actualLog);
reformattedLog = new InsertOptionalDataVisitor(dataToInsert, originalUriBaseIds, insertProperties: options.InsertProperties).VisitSarifLog(reformattedLog);

if (options.SortResults)
{
reformattedLog = new SortingVisitor().VisitSarifLog(reformattedLog);
}

if (options.SarifOutputVersion == SarifVersion.OneZeroZero)
{
var visitor = new SarifCurrentToVersionOneVisitor();
Expand Down
6 changes: 6 additions & 0 deletions src/Sarif.Multitool.Library/RewriteOptions.cs
Original file line number Diff line number Diff line change
Expand Up @@ -10,5 +10,11 @@ namespace Microsoft.CodeAnalysis.Sarif.Multitool
[Verb("rewrite", HelpText = "Enrich a SARIF file with additional data.")]
public class RewriteOptions : SingleFileOptionsBase
{
[Option(
's',
"sort-results",
Default = false,
HelpText = "Sort results in the final output file.")]
public bool SortResults { get; set; }
}
}
114 changes: 114 additions & 0 deletions src/Sarif/Comparers/ArtifactComparer.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,114 @@
// Copyright (c) Microsoft. All rights reserved.
// Licensed under the MIT license. See LICENSE file in the project root for full license information.

using System.Collections.Generic;

/// <summary>
/// Note: This comparer may not have all properties compared. Will be replaced by a comprehensive
/// comparer generated by JSchema as part of EqualityComparer in a planned comprehensive solution.
/// Tracking by issue: https://github.com/microsoft/jschema/issues/141
/// </summary>
namespace Microsoft.CodeAnalysis.Sarif.Comparers
{
internal class ArtifactComparer : IComparer<Artifact>
{
internal static readonly ArtifactComparer Instance = new ArtifactComparer();

public int Compare(Artifact left, Artifact right)
{
int compareResult = 0;

if (left.TryReferenceCompares(right, out compareResult))
{
return compareResult;
}

compareResult = MessageComparer.Instance.Compare(left.Description, right.Description);

if (compareResult != 0)
{
return compareResult;
}

compareResult = ArtifactLocationComparer.Instance.Compare(left.Location, right.Location);

if (compareResult != 0)
{
return compareResult;
}

compareResult = left.ParentIndex.CompareTo(right.ParentIndex);

if (compareResult != 0)
{
return compareResult;
}

compareResult = left.Offset.CompareTo(right.Offset);

if (compareResult != 0)
{
return compareResult;
}

compareResult = left.Length.CompareTo(right.Length);

if (compareResult != 0)
{
return compareResult;
}

compareResult = left.Roles.CompareTo(right.Roles);

if (compareResult != 0)
{
return compareResult;
}

compareResult = string.Compare(left.MimeType, right.MimeType);

if (compareResult != 0)
{
return compareResult;
}

compareResult = ArtifactContentComparer.Instance.Compare(left.Contents, right.Contents);

if (compareResult != 0)
{
return compareResult;
}

compareResult = string.Compare(left.Encoding, right.Encoding);

if (compareResult != 0)
{
return compareResult;
}

compareResult = string.Compare(left.SourceLanguage, right.SourceLanguage);

if (compareResult != 0)
{
return compareResult;
}

compareResult = left.Hashes.DictionaryCompares(right.Hashes);

if (compareResult != 0)
{
return compareResult;
}

compareResult = left.LastModifiedTimeUtc.CompareTo(right.LastModifiedTimeUtc);

if (compareResult != 0)
{
return compareResult;
}

// Note: There may be other properties are not compared.
return compareResult;
}
}
}
51 changes: 51 additions & 0 deletions src/Sarif/Comparers/ArtifactContentComparer.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
// Copyright (c) Microsoft. All rights reserved.
// Licensed under the MIT license. See LICENSE file in the project root for full license information.

using System.Collections.Generic;

/// <summary>
/// Note: This comparer may not have all properties compared. Will be replaced by a comprehensive
/// comparer generated by JSchema as part of EqualityComparer in a planned comprehensive solution.
/// Tracking by issue: https://github.com/microsoft/jschema/issues/141
/// </summary>
namespace Microsoft.CodeAnalysis.Sarif.Comparers
{
internal class ArtifactContentComparer : IComparer<ArtifactContent>
{
internal static readonly ArtifactContentComparer Instance = new ArtifactContentComparer();

public int Compare(ArtifactContent left, ArtifactContent right)
{
int compareResult = 0;

if (left.TryReferenceCompares(right, out compareResult))
{
return compareResult;
}

compareResult = string.Compare(left.Text, right.Text);

if (compareResult != 0)
{
return compareResult;
}

compareResult = string.Compare(left.Binary, right.Binary);

if (compareResult != 0)
{
return compareResult;
}

compareResult = MultiformatMessageStringComparer.Instance.Compare(left.Rendered, right.Rendered);

if (compareResult != 0)
{
return compareResult;
}

// Note: There may be other properties are not compared.
return compareResult;
}
}
}
58 changes: 58 additions & 0 deletions src/Sarif/Comparers/ArtifactLocationComparer.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
// Copyright (c) Microsoft. All rights reserved.
// Licensed under the MIT license. See LICENSE file in the project root for full license information.

using System.Collections.Generic;

/// <summary>
/// Note: This comparer may not have all properties compared. Will be replaced by a comprehensive
/// comparer generated by JSchema as part of EqualityComparer in a planned comprehensive solution.
/// Tracking by issue: https://github.com/microsoft/jschema/issues/141
/// </summary>
namespace Microsoft.CodeAnalysis.Sarif.Comparers
{
internal class ArtifactLocationComparer : IComparer<ArtifactLocation>
{
internal static readonly ArtifactLocationComparer Instance = new ArtifactLocationComparer();

public int Compare(ArtifactLocation left, ArtifactLocation right)
{
int compareResult = 0;

if (left.TryReferenceCompares(right, out compareResult))
{
return compareResult;
}

compareResult = left.Uri.UriCompares(right.Uri);

if (compareResult != 0)
{
return compareResult;
}

compareResult = string.Compare(left.UriBaseId, right.UriBaseId);

if (compareResult != 0)
{
return compareResult;
}

compareResult = left.Index.CompareTo(right.Index);

if (compareResult != 0)
{
return compareResult;
}

compareResult = MessageComparer.Instance.Compare(left.Description, right.Description);

if (compareResult != 0)
{
return compareResult;
}

// Note: There may be other properties are not compared.
return compareResult;
}
}
}
44 changes: 44 additions & 0 deletions src/Sarif/Comparers/CodeFlowComparer.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
// Copyright (c) Microsoft. All rights reserved.
// Licensed under the MIT license. See LICENSE file in the project root for full license information.

using System.Collections.Generic;

/// <summary>
/// Note: This comparer may not have all properties compared. Will be replaced by a comprehensive
/// comparer generated by JSchema as part of EqualityComparer in a planned comprehensive solution.
/// Tracking by issue: https://github.com/microsoft/jschema/issues/141
/// </summary>
namespace Microsoft.CodeAnalysis.Sarif.Comparers
{
internal class CodeFlowComparer : IComparer<CodeFlow>
{
internal static readonly CodeFlowComparer Instance = new CodeFlowComparer();

public int Compare(CodeFlow left, CodeFlow right)
{
int compareResult = 0;

if (left.TryReferenceCompares(right, out compareResult))
{
return compareResult;
}

compareResult = MessageComparer.Instance.Compare(left.Message, right.Message);

if (compareResult != 0)
{
return compareResult;
}

compareResult = left.ThreadFlows.ListCompares(right.ThreadFlows, ThreadFlowComparer.Instance);

if (compareResult != 0)
{
return compareResult;
}

// Note: There may be other properties are not compared.
return compareResult;
}
}
}
Loading

0 comments on commit 839537f

Please sign in to comment.