more audit work
This commit is contained in:
@@ -29,9 +29,18 @@ public sealed class DeltaComputationEngine : IDeltaComputationEngine
|
||||
var headComponents = headVerdict.Components
|
||||
.ToDictionary(c => c.Purl, c => c, StringComparer.Ordinal);
|
||||
|
||||
var addedComponents = ComputeAddedComponents(baseComponents, headComponents);
|
||||
var removedComponents = ComputeRemovedComponents(baseComponents, headComponents);
|
||||
var changedComponents = ComputeChangedComponents(baseComponents, headComponents);
|
||||
var changedPairs = FindChangedComponentPairs(baseComponents, headComponents);
|
||||
var changedComponents = BuildChangedComponents(changedPairs);
|
||||
|
||||
var changedBasePurls = changedPairs
|
||||
.Select(pair => pair.Base.Purl)
|
||||
.ToHashSet(StringComparer.Ordinal);
|
||||
var changedHeadPurls = changedPairs
|
||||
.Select(pair => pair.Head.Purl)
|
||||
.ToHashSet(StringComparer.Ordinal);
|
||||
|
||||
var addedComponents = ComputeAddedComponents(baseComponents, headComponents, changedHeadPurls);
|
||||
var removedComponents = ComputeRemovedComponents(baseComponents, headComponents, changedBasePurls);
|
||||
|
||||
var baseVulns = baseVerdict.Vulnerabilities
|
||||
.ToDictionary(v => v.Id, v => v, StringComparer.Ordinal);
|
||||
@@ -77,10 +86,11 @@ public sealed class DeltaComputationEngine : IDeltaComputationEngine
|
||||
|
||||
private static ImmutableArray<ComponentDelta> ComputeAddedComponents(
|
||||
IReadOnlyDictionary<string, Component> baseComponents,
|
||||
IReadOnlyDictionary<string, Component> headComponents)
|
||||
IReadOnlyDictionary<string, Component> headComponents,
|
||||
ISet<string> excludedPurls)
|
||||
{
|
||||
return headComponents
|
||||
.Where(kv => !baseComponents.ContainsKey(kv.Key))
|
||||
.Where(kv => !baseComponents.ContainsKey(kv.Key) && !excludedPurls.Contains(kv.Key))
|
||||
.OrderBy(kv => kv.Key, StringComparer.Ordinal)
|
||||
.Select(kv => new ComponentDelta(
|
||||
kv.Value.Purl,
|
||||
@@ -93,10 +103,11 @@ public sealed class DeltaComputationEngine : IDeltaComputationEngine
|
||||
|
||||
private static ImmutableArray<ComponentDelta> ComputeRemovedComponents(
|
||||
IReadOnlyDictionary<string, Component> baseComponents,
|
||||
IReadOnlyDictionary<string, Component> headComponents)
|
||||
IReadOnlyDictionary<string, Component> headComponents,
|
||||
ISet<string> excludedPurls)
|
||||
{
|
||||
return baseComponents
|
||||
.Where(kv => !headComponents.ContainsKey(kv.Key))
|
||||
.Where(kv => !headComponents.ContainsKey(kv.Key) && !excludedPurls.Contains(kv.Key))
|
||||
.OrderBy(kv => kv.Key, StringComparer.Ordinal)
|
||||
.Select(kv => new ComponentDelta(
|
||||
kv.Value.Purl,
|
||||
@@ -107,18 +118,15 @@ public sealed class DeltaComputationEngine : IDeltaComputationEngine
|
||||
.ToImmutableArray();
|
||||
}
|
||||
|
||||
private static ImmutableArray<ComponentVersionDelta> ComputeChangedComponents(
|
||||
IReadOnlyDictionary<string, Component> baseComponents,
|
||||
IReadOnlyDictionary<string, Component> headComponents)
|
||||
private static ImmutableArray<ComponentVersionDelta> BuildChangedComponents(
|
||||
IReadOnlyCollection<(Component Base, Component Head)> pairs)
|
||||
{
|
||||
return baseComponents
|
||||
.Where(kv => headComponents.TryGetValue(kv.Key, out var head)
|
||||
&& !string.Equals(kv.Value.Version, head.Version, StringComparison.Ordinal))
|
||||
.OrderBy(kv => kv.Key, StringComparer.Ordinal)
|
||||
.Select(kv =>
|
||||
return pairs
|
||||
.OrderBy(pair => pair.Base.Purl, StringComparer.Ordinal)
|
||||
.Select(pair =>
|
||||
{
|
||||
var baseComponent = kv.Value;
|
||||
var headComponent = headComponents[kv.Key];
|
||||
var baseComponent = pair.Base;
|
||||
var headComponent = pair.Head;
|
||||
var fixedVulns = baseComponent.Vulnerabilities
|
||||
.Except(headComponent.Vulnerabilities, StringComparer.Ordinal)
|
||||
.OrderBy(v => v, StringComparer.Ordinal)
|
||||
@@ -139,6 +147,60 @@ public sealed class DeltaComputationEngine : IDeltaComputationEngine
|
||||
.ToImmutableArray();
|
||||
}
|
||||
|
||||
private static IReadOnlyCollection<(Component Base, Component Head)> FindChangedComponentPairs(
|
||||
IReadOnlyDictionary<string, Component> baseComponents,
|
||||
IReadOnlyDictionary<string, Component> headComponents)
|
||||
{
|
||||
var pairs = new List<(Component Base, Component Head)>();
|
||||
var matchedBase = new HashSet<string>(StringComparer.Ordinal);
|
||||
var matchedHead = new HashSet<string>(StringComparer.Ordinal);
|
||||
|
||||
foreach (var baseComponent in baseComponents.Values.OrderBy(c => c.Purl, StringComparer.Ordinal))
|
||||
{
|
||||
if (headComponents.TryGetValue(baseComponent.Purl, out var headComponent)
|
||||
&& !string.Equals(baseComponent.Version, headComponent.Version, StringComparison.Ordinal))
|
||||
{
|
||||
pairs.Add((baseComponent, headComponent));
|
||||
matchedBase.Add(baseComponent.Purl);
|
||||
matchedHead.Add(headComponent.Purl);
|
||||
}
|
||||
}
|
||||
|
||||
var baseByIdentity = baseComponents.Values
|
||||
.Where(c => !matchedBase.Contains(c.Purl))
|
||||
.GroupBy(GetComponentIdentity, StringComparer.Ordinal)
|
||||
.Where(g => g.Count() == 1)
|
||||
.ToDictionary(g => g.Key, g => g.First(), StringComparer.Ordinal);
|
||||
|
||||
var headByIdentity = headComponents.Values
|
||||
.Where(c => !matchedHead.Contains(c.Purl))
|
||||
.GroupBy(GetComponentIdentity, StringComparer.Ordinal)
|
||||
.Where(g => g.Count() == 1)
|
||||
.ToDictionary(g => g.Key, g => g.First(), StringComparer.Ordinal);
|
||||
|
||||
foreach (var (identity, baseComponent) in baseByIdentity.OrderBy(kv => kv.Key, StringComparer.Ordinal))
|
||||
{
|
||||
if (!headByIdentity.TryGetValue(identity, out var headComponent))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
if (string.Equals(baseComponent.Version, headComponent.Version, StringComparison.Ordinal))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
pairs.Add((baseComponent, headComponent));
|
||||
matchedBase.Add(baseComponent.Purl);
|
||||
matchedHead.Add(headComponent.Purl);
|
||||
}
|
||||
|
||||
return pairs;
|
||||
}
|
||||
|
||||
private static string GetComponentIdentity(Component component)
|
||||
=> $"{component.Type}:{component.Name}";
|
||||
|
||||
private static ImmutableArray<VulnerabilityDelta> ComputeAddedVulnerabilities(
|
||||
IReadOnlyDictionary<string, Vulnerability> baseVulns,
|
||||
IReadOnlyDictionary<string, Vulnerability> headVulns)
|
||||
|
||||
Reference in New Issue
Block a user