diff --git a/.github/workflows/dotnetcore.yml b/.github/workflows/dotnetcore.yml index ae976b2e..cde4e86c 100644 --- a/.github/workflows/dotnetcore.yml +++ b/.github/workflows/dotnetcore.yml @@ -3,6 +3,9 @@ name: .NET Core CI on: [pull_request, workflow_dispatch] +env: + SNAPSHOOTER_STRICT_MODE: true + jobs: # Fail if there are build warnings # @@ -30,11 +33,21 @@ jobs: strategy: fail-fast: false matrix: - os: [ubuntu-latest, windows-latest, macos-latest] +# os: [ubuntu-latest, windows-latest, macos-latest] +# macos currently disabled. see issue #285 for more info. + os: [ubuntu-latest, windows-latest] timeout-minutes: 30 steps: - uses: actions/checkout@v3 + - name: SnapshooterHotfixSymlinkLinux + if: matrix.os == 'ubuntu-latest' + run: sudo ln -s "$GITHUB_WORKSPACE" /_ + shell: bash + - name: SnapshooterHotfixSymlinkWindows + if: matrix.os == 'windows-latest' + run: New-Item -ItemType SymbolicLink -Path "/_" -Target "$env:GITHUB_WORKSPACE" + shell: pwsh - uses: actions/setup-dotnet@v3 with: dotnet-version: '6.0.x' diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 38ff3190..ea733475 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -41,6 +41,11 @@ jobs: export PATH="$PATH:$HOME/.local/bin" # The tests should have already been run during the PR workflow, so this is really just a sanity check + # See issue #285 for info why the symlink is necessary. + - name: SnapshooterHotfixSymlinkLinux + run: sudo ln -s "$GITHUB_WORKSPACE" /_ + shell: bash + - name: Tests run: dotnet test diff --git a/semver.txt b/semver.txt index 09b254e9..a3fcc712 100755 --- a/semver.txt +++ b/semver.txt @@ -1 +1 @@ -6.0.0 +7.1.0 diff --git a/src/CycloneDX.Core/CycloneDX.Core.csproj b/src/CycloneDX.Core/CycloneDX.Core.csproj index 3ea6180f..65fc47a0 100644 --- a/src/CycloneDX.Core/CycloneDX.Core.csproj +++ b/src/CycloneDX.Core/CycloneDX.Core.csproj @@ -12,10 +12,10 @@ runtime; build; native; contentfiles; analyzers; buildtransitive all - + - + diff --git a/src/CycloneDX.Core/Json/Converters/DateTimeConverter.cs b/src/CycloneDX.Core/Json/Converters/DateTimeConverter.cs index f48077e4..eb92d9e7 100644 --- a/src/CycloneDX.Core/Json/Converters/DateTimeConverter.cs +++ b/src/CycloneDX.Core/Json/Converters/DateTimeConverter.cs @@ -17,6 +17,7 @@ using System; using System.Diagnostics.Contracts; +using System.Globalization; using System.Text.Json; using System.Text.Json.Serialization; @@ -40,7 +41,7 @@ public class DateTimeConverter : JsonConverter } var valueString = reader.GetString(); - var value = DateTime.Parse(valueString); + var value = DateTime.Parse(valueString, CultureInfo.InvariantCulture); return value; } @@ -51,7 +52,7 @@ public override void Write( { Contract.Requires(writer != null); - writer.WriteStringValue(value?.ToUniversalTime().ToString("yyyy-MM-ddTHH:mm:ssZ")); + writer.WriteStringValue(value?.ToUniversalTime().ToString("yyyy-MM-ddTHH:mm:ssZ", CultureInfo.InvariantCulture)); } } } diff --git a/src/CycloneDX.Core/Json/Converters/ScoreMethodConverter.cs b/src/CycloneDX.Core/Json/Converters/ScoreMethodConverter.cs index 85a92815..899390b0 100644 --- a/src/CycloneDX.Core/Json/Converters/ScoreMethodConverter.cs +++ b/src/CycloneDX.Core/Json/Converters/ScoreMethodConverter.cs @@ -61,10 +61,6 @@ public override void Write( { writer.WriteStringValue("other"); } - else if (value == ScoreMethod.CVSSV31) - { - writer.WriteStringValue("CVSSv3.1"); - } else if (value.ToString().StartsWith("CVSSV")) { writer.WriteStringValue("CVSSv" + value.ToString().Substring(5)); diff --git a/src/CycloneDX.Core/Json/Converters/ToolChoicesConverter.cs b/src/CycloneDX.Core/Json/Converters/ToolChoicesConverter.cs index e2a7f110..d08b29f3 100644 --- a/src/CycloneDX.Core/Json/Converters/ToolChoicesConverter.cs +++ b/src/CycloneDX.Core/Json/Converters/ToolChoicesConverter.cs @@ -73,16 +73,19 @@ public override void Write( Contract.Requires(writer != null); Contract.Requires(value != null); - if (value.Tools != null) + if (value.Tools != null || value.SpecVersion < SpecificationVersion.v1_5) { writer.WriteStartArray(); - foreach (var tool in value.Tools) + if (value.Tools != null) { - JsonSerializer.Serialize(writer, tool, options); + foreach (var tool in value.Tools) + { + JsonSerializer.Serialize(writer, tool, options); + } } writer.WriteEndArray(); } - else if (value.Components != null || value.Services != null) + else { writer.WriteStartObject(); if (value.Components != null) @@ -97,10 +100,6 @@ public override void Write( } writer.WriteEndObject(); } - else - { - writer.WriteNullValue(); - } } } } diff --git a/src/CycloneDX.Core/Json/Serializer.Serialization.cs b/src/CycloneDX.Core/Json/Serializer.Serialization.cs index 921d96ca..d4cd2063 100644 --- a/src/CycloneDX.Core/Json/Serializer.Serialization.cs +++ b/src/CycloneDX.Core/Json/Serializer.Serialization.cs @@ -89,5 +89,18 @@ internal static string Serialize(Models.Vulnerabilities.Vulnerability vulnerabil Contract.Requires(vulnerability != null); return JsonSerializer.Serialize(vulnerability, _options); } + + internal static string Serialize(Models.Composition composition) + { + Contract.Requires(composition != null); + return JsonSerializer.Serialize(composition, _options); + } + + internal static string Serialize(Models.ExternalReference externalReference) + { + Contract.Requires(externalReference != null); + return JsonSerializer.Serialize(externalReference, _options); + } + } } diff --git a/src/CycloneDX.Core/Json/Utils.cs b/src/CycloneDX.Core/Json/Utils.cs index b8beb2f8..7091024c 100644 --- a/src/CycloneDX.Core/Json/Utils.cs +++ b/src/CycloneDX.Core/Json/Utils.cs @@ -67,16 +67,18 @@ public static JsonSerializerOptions GetJsonSerializerOptions() options.Converters.Add(new EnvironmentVarChoiceConverter()); options.Converters.Add(new ToolChoicesConverter()); - + + options.Converters.Add(new HyphenEnumConverter()); options.Converters.Add(new HyphenEnumConverter()); options.Converters.Add(new ScoreMethodConverter()); options.Converters.Add(new HyphenEnumConverter()); options.Converters.Add(new HyphenEnumConverter()); options.Converters.Add(new HyphenEnumConverter()); - options.Converters.Add(new HyphenEnumConverter()); options.Converters.Add(new HyphenEnumConverter()); options.Converters.Add(new HyphenEnumConverter()); options.Converters.Add(new UnderscoreEnumConverter()); + options.Converters.Add(new HyphenEnumConverter()); + options.Converters.Add(new HyphenEnumConverter()); options.Converters.Add(new JsonStringEnumConverter()); diff --git a/src/CycloneDX.Core/Json/Validator.cs b/src/CycloneDX.Core/Json/Validator.cs index 205c5290..cad2c29e 100644 --- a/src/CycloneDX.Core/Json/Validator.cs +++ b/src/CycloneDX.Core/Json/Validator.cs @@ -173,13 +173,13 @@ public static ValidationResult Validate(string jsonString, SpecificationVersion private static ValidationResult Validate(JsonSchema schema, JsonDocument jsonDocument, string schemaVersionString) { var validationMessages = new List(); - var validationOptions = new ValidationOptions + var validationOptions = new EvaluationOptions { - OutputFormat = OutputFormat.Detailed, + OutputFormat = OutputFormat.List, RequireFormatValidation = true }; - var result = schema.Validate(jsonDocument.RootElement, validationOptions); + var result = schema.Evaluate(jsonDocument.RootElement, validationOptions); if (result.IsValid) { @@ -197,34 +197,20 @@ private static ValidationResult Validate(JsonSchema schema, JsonDocument jsonDoc } else { - validationMessages.Add($"Validation failed: {result.Message}"); - validationMessages.Add(result.SchemaLocation.ToString()); - validationMessages.Add($"On instance: {result.InstanceLocation}:"); - validationMessages.Add(result.InstanceLocation.Evaluate(jsonDocument.RootElement).ToString()); - - if (result.NestedResults != null) + validationMessages.Add("Validation failed:"); + // because we requested the results as a flat list + // there will be no nested results + foreach (var detail in result.Details) { - var nestedResults = new Queue(result.NestedResults); - - while (nestedResults.Count > 0) + if (detail.HasErrors) { - var nestedResult = nestedResults.Dequeue(); - - if ( - !string.IsNullOrEmpty(nestedResult.Message) - && nestedResult.NestedResults != null - && nestedResult.NestedResults.Count > 0) - { - validationMessages.Add($"{nestedResult.InstanceLocation}: {nestedResult.Message}"); - } - - if (nestedResult.NestedResults != null) + foreach (var error in detail.Errors) { - foreach (var newNestedResult in nestedResult.NestedResults) - { - nestedResults.Enqueue(newNestedResult); - } + validationMessages.Add(error.Value); } + validationMessages.Add(detail.SchemaLocation.ToString()); + validationMessages.Add($"On instance: {detail.InstanceLocation}:"); + validationMessages.Add(detail.InstanceLocation.Evaluate(jsonDocument.RootElement).ToString()); } } } diff --git a/src/CycloneDX.Core/Models/Component.cs b/src/CycloneDX.Core/Models/Component.cs index 1bb67c40..66a43367 100644 --- a/src/CycloneDX.Core/Models/Component.cs +++ b/src/CycloneDX.Core/Models/Component.cs @@ -17,7 +17,9 @@ using System; using System.Collections.Generic; +using System.ComponentModel; using System.Diagnostics.CodeAnalysis; +using System.Net; using System.Text.Json.Serialization; using System.Xml.Serialization; using CycloneDX.Core.Models; @@ -141,10 +143,23 @@ public ComponentScope NonNullableScope public List Hashes { get; set; } public bool ShouldSerializeHashes() { return Hashes?.Count > 0; } - [XmlElement("licenses")] + [XmlIgnore] [ProtoMember(13)] public List Licenses { get; set; } + + [XmlElement("licenses")] + [JsonIgnore, ProtoIgnore] + [EditorBrowsable(EditorBrowsableState.Never)] + // This is a serialization workaround + public LicenseChoiceList LicensesSerialized + { + get { return Licenses != null ? new LicenseChoiceList(Licenses) : null; } + set { Licenses = value.Licenses; } + } + [EditorBrowsable(EditorBrowsableState.Never)] + public bool ShouldSerializeLicensesSerialized() { return Licenses?.Count > 0; } + [XmlElement("copyright")] [ProtoMember(14)] public string Copyright { get; set; } @@ -190,9 +205,8 @@ public bool NonNullableModified public List ExternalReferences { get; set; } public bool ShouldSerializeExternalReferences() { return ExternalReferences?.Count > 0; } - [XmlArray("components")] - [ProtoMember(21)] - public List Components { get; set; } + //In the xml format, Properties is in front of Components. + //XML serialization uses the member order unless explicitly specified differently. public bool ShouldSerializeComponents() { return Components?.Count > 0; } [XmlArray("properties")] @@ -200,6 +214,10 @@ public bool NonNullableModified [ProtoMember(22)] public List Properties { get; set; } public bool ShouldSerializeProperties() { return Properties?.Count > 0; } + + [XmlArray("components")] + [ProtoMember(21)] + public List Components { get; set; } [XmlElement("evidence")] [ProtoMember(23)] @@ -223,6 +241,17 @@ public bool NonNullableModified public CryptoProperties CryptoProperties { get; set; } + public override bool Equals(object obj) + { + var other = obj as Component; + if (other == null) + { + return false; + } + + return Json.Serializer.Serialize(this) == Json.Serializer.Serialize(other); + } + public bool Equals(Component obj) { return Json.Serializer.Serialize(this) == Json.Serializer.Serialize(obj); diff --git a/src/CycloneDX.Core/Models/Composition.cs b/src/CycloneDX.Core/Models/Composition.cs index 8b3140d4..cf5cb654 100644 --- a/src/CycloneDX.Core/Models/Composition.cs +++ b/src/CycloneDX.Core/Models/Composition.cs @@ -25,7 +25,7 @@ namespace CycloneDX.Models { [ProtoContract] - public class Composition : IXmlSerializable + public class Composition : IXmlSerializable, IEquatable { [ProtoContract] public enum AggregateType @@ -194,5 +194,26 @@ public void WriteXml(System.Xml.XmlWriter writer) { writer.WriteEndElement(); } } + + public override bool Equals(object obj) + { + var other = obj as Composition; + if (other == null) + { + return false; + } + + return Json.Serializer.Serialize(this) == Json.Serializer.Serialize(other); + } + + public bool Equals(Composition obj) + { + return CycloneDX.Json.Serializer.Serialize(this) == CycloneDX.Json.Serializer.Serialize(obj); + } + + public override int GetHashCode() + { + return CycloneDX.Json.Serializer.Serialize(this).GetHashCode(); + } } } \ No newline at end of file diff --git a/src/CycloneDX.Core/Models/Dependency.cs b/src/CycloneDX.Core/Models/Dependency.cs index e2d3ec7c..6277acf4 100644 --- a/src/CycloneDX.Core/Models/Dependency.cs +++ b/src/CycloneDX.Core/Models/Dependency.cs @@ -40,6 +40,17 @@ public class Dependency: IEquatable [ProtoMember(3)] public List Provides { get; set; } + public override bool Equals(object obj) + { + var other = obj as Dependency; + if (other == null) + { + return false; + } + + return Json.Serializer.Serialize(this) == Json.Serializer.Serialize(other); + } + public bool Equals(Dependency obj) { return CycloneDX.Json.Serializer.Serialize(this) == CycloneDX.Json.Serializer.Serialize(obj); diff --git a/src/CycloneDX.Core/Models/Evidence.cs b/src/CycloneDX.Core/Models/Evidence.cs index f48cbafa..cead04c9 100644 --- a/src/CycloneDX.Core/Models/Evidence.cs +++ b/src/CycloneDX.Core/Models/Evidence.cs @@ -17,6 +17,7 @@ using System; using System.Collections.Generic; +using System.ComponentModel; using System.Diagnostics.CodeAnalysis; using System.Linq.Expressions; using System.Text.Json.Serialization; @@ -30,9 +31,20 @@ namespace CycloneDX.Models [ProtoContract] public class Evidence { - [XmlElement("licenses", Order = 3)] + [XmlIgnore] [ProtoMember(1)] public List Licenses { get; set; } + + [XmlElement("licenses", Order = 3)] + [JsonIgnore, ProtoIgnore] + [EditorBrowsable(EditorBrowsableState.Never)] + public LicenseChoiceList LicensesSerialized + { + get { return Licenses != null ? new LicenseChoiceList(Licenses) : null; } + set { Licenses = value.Licenses; } + } + [EditorBrowsable(EditorBrowsableState.Never)] + public bool ShouldSerializeLicensesSerialized() { return Licenses?.Count > 0; } [XmlArray("copyright", Order = 4)] [XmlArrayItem("text")] diff --git a/src/CycloneDX.Core/Models/ExternalReference.cs b/src/CycloneDX.Core/Models/ExternalReference.cs index e84ef997..69204fca 100644 --- a/src/CycloneDX.Core/Models/ExternalReference.cs +++ b/src/CycloneDX.Core/Models/ExternalReference.cs @@ -15,8 +15,10 @@ // SPDX-License-Identifier: Apache-2.0 // Copyright (c) OWASP Foundation. All Rights Reserved. +using System; using System.Collections.Generic; using System.Diagnostics.CodeAnalysis; +using System.Text.Json.Serialization; using System.Xml.Serialization; using ProtoBuf; @@ -24,7 +26,7 @@ namespace CycloneDX.Models { [SuppressMessage("Microsoft.Naming", "CA1707:IdentifiersShouldNotContainUnderscores")] [ProtoContract] - public class ExternalReference + public class ExternalReference : IEquatable { [ProtoContract] public enum ExternalReferenceType @@ -125,5 +127,26 @@ public enum ExternalReferenceType [ProtoMember(4)] public List Hashes { get; set; } public bool ShouldSerializeHashes() { return Hashes?.Count > 0; } + + public override bool Equals(object obj) + { + var other = obj as ExternalReference; + if (other == null) + { + return false; + } + + return Json.Serializer.Serialize(this) == Json.Serializer.Serialize(other); + } + + public bool Equals(ExternalReference obj) + { + return CycloneDX.Json.Serializer.Serialize(this) == CycloneDX.Json.Serializer.Serialize(obj); + } + + public override int GetHashCode() + { + return CycloneDX.Json.Serializer.Serialize(this).GetHashCode(); + } } } diff --git a/src/CycloneDX.Core/Models/LicenseChoice.cs b/src/CycloneDX.Core/Models/LicenseChoice.cs index 558003ea..47639ed5 100644 --- a/src/CycloneDX.Core/Models/LicenseChoice.cs +++ b/src/CycloneDX.Core/Models/LicenseChoice.cs @@ -15,12 +15,16 @@ // SPDX-License-Identifier: Apache-2.0 // Copyright (c) OWASP Foundation. All Rights Reserved. +using System; +using System.Collections.Generic; +using System.Linq.Expressions; using System.Text.Json.Serialization; using System.Xml.Serialization; using ProtoBuf; namespace CycloneDX.Models { + [ProtoContract] public class LicenseChoice { @@ -37,4 +41,87 @@ public class LicenseChoice [ProtoMember(3)] public string BomRef { get; set; } } + + // This is a workaround to serialize licenses correctly + public class LicenseChoiceList : IXmlSerializable + { + public LicenseChoiceList(List licenses) + { + Licenses = licenses; + } + + public LicenseChoiceList() { } + + public List Licenses { get; set; } + + public System.Xml.Schema.XmlSchema GetSchema() + { + return (null); + } + + public void ReadXml(System.Xml.XmlReader reader) + { + + bool isEmptyElement = reader.IsEmptyElement; + reader.ReadStartElement(); + + if (!isEmptyElement) + { + XmlSerializer licenseSerializer = new XmlSerializer(typeof(License), reader.NamespaceURI); + + Licenses = new List(); + + bool finished = false; + while (!finished) + { + finished = true; + if (licenseSerializer.CanDeserialize(reader)) + { + var license = (License)licenseSerializer.Deserialize(reader); + Licenses.Add(new LicenseChoice { License = license }); + finished = false; + } + if (reader.Name == "expression") + { + reader.ReadStartElement(); + var expression = reader.ReadContentAsString(); + Licenses.Add(new LicenseChoice { Expression = expression }); + finished = false; + reader.ReadEndElement(); + } + + + } + + reader.ReadEndElement(); + } + } + + public void WriteXml(System.Xml.XmlWriter writer) + { + + if (Licenses != null) + { + // todo: is there a way to feed in the namespace with having to introduce WriterToNamespace? + string defaultNamespace; + defaultNamespace = CycloneDX.Xml.Serializer.GetNamespace(writer); + XmlSerializer licenseSerializer = new XmlSerializer(typeof(License), defaultNamespace); + + foreach (var license in Licenses) + { + if (license.License != null) + { + licenseSerializer.Serialize(writer, license.License, new XmlSerializerNamespaces()); + } + if (license.Expression != null) + { + writer.WriteStartElement("expression"); + writer.WriteString(license.Expression); + writer.WriteEndElement(); + } + } + } + + } + } } diff --git a/src/CycloneDX.Core/Models/Metadata.cs b/src/CycloneDX.Core/Models/Metadata.cs index 8c6bba22..fad8b4e3 100644 --- a/src/CycloneDX.Core/Models/Metadata.cs +++ b/src/CycloneDX.Core/Models/Metadata.cs @@ -17,6 +17,7 @@ using System; using System.Collections.Generic; +using System.ComponentModel; using System.Text.Json.Serialization; using System.Xml.Serialization; using ProtoBuf; @@ -80,12 +81,25 @@ public List ProtobufTools [XmlElement("supplier")] [ProtoMember(6)] public OrganizationalEntity Supplier { get; set; } - - [XmlElement("licenses")] + + [XmlIgnore] [ProtoMember(7)] public List Licenses { get; set; } public bool ShouldSerializeLicenses() { return Licenses?.Count > 0; } - + + + [XmlElement("licenses")] + [JsonIgnore, ProtoIgnore] + [EditorBrowsable(EditorBrowsableState.Never)] + // This is a serialization workaround + public LicenseChoiceList LicensesSerialized + { + get { return Licenses != null ? new LicenseChoiceList(Licenses) : null; } + set { Licenses = value.Licenses; } + } + [EditorBrowsable(EditorBrowsableState.Never)] + public bool ShouldSerializeLicensesSerialized() { return Licenses?.Count > 0; } + [XmlArray("properties")] [XmlArrayItem("property")] [ProtoMember(8)] diff --git a/src/CycloneDX.Core/Models/Service.cs b/src/CycloneDX.Core/Models/Service.cs index fda223f7..d27c1df1 100644 --- a/src/CycloneDX.Core/Models/Service.cs +++ b/src/CycloneDX.Core/Models/Service.cs @@ -17,6 +17,7 @@ using System; using System.Collections.Generic; +using System.ComponentModel; using System.Text.Json.Serialization; using System.Xml.Serialization; using ProtoBuf; @@ -165,11 +166,23 @@ public ServiceDataChoices XmlData } } public bool ShouldSerializeXmlData() => ShouldSerializeData(); - - [XmlElement("licenses")] + + [XmlIgnore] [ProtoMember(11)] public List Licenses { get; set; } + [XmlElement("licenses")] + [JsonIgnore, ProtoIgnore] + [EditorBrowsable(EditorBrowsableState.Never)] + // This is a serialization workaround + public LicenseChoiceList LicensesSerialized + { + get { return Licenses != null ? new LicenseChoiceList(Licenses) : null; } + set { Licenses = value.Licenses; } + } + [EditorBrowsable(EditorBrowsableState.Never)] + public bool ShouldSerializeLicensesSerialized() { return Licenses?.Count > 0; } + [XmlArray("externalReferences")] [XmlArrayItem("reference")] [ProtoMember(12)] @@ -194,6 +207,17 @@ public ServiceDataChoices XmlData public bool ShouldSerializeProperties() => Properties?.Count > 0; + public override bool Equals(object obj) + { + var other = obj as Service; + if (other == null) + { + return false; + } + + return Json.Serializer.Serialize(this) == Json.Serializer.Serialize(other); + } + public bool Equals(Service obj) { return CycloneDX.Json.Serializer.Serialize(this) == CycloneDX.Json.Serializer.Serialize(obj); diff --git a/src/CycloneDX.Core/Models/Tool.cs b/src/CycloneDX.Core/Models/Tool.cs index 98349490..48282a17 100644 --- a/src/CycloneDX.Core/Models/Tool.cs +++ b/src/CycloneDX.Core/Models/Tool.cs @@ -48,6 +48,17 @@ public class Tool: IEquatable public List ExternalReferences { get; set; } public bool ShouldSerializeExternalReferences() { return ExternalReferences?.Count > 0; } + public override bool Equals(object obj) + { + var other = obj as Tool; + if (other == null) + { + return false; + } + + return Json.Serializer.Serialize(this) == Json.Serializer.Serialize(other); + } + public bool Equals(Tool obj) { return CycloneDX.Json.Serializer.Serialize(this) == CycloneDX.Json.Serializer.Serialize(obj); diff --git a/src/CycloneDX.Core/Models/Vulnerabilities/ScoreMethod.cs b/src/CycloneDX.Core/Models/Vulnerabilities/ScoreMethod.cs index e31ac372..e1b43635 100644 --- a/src/CycloneDX.Core/Models/Vulnerabilities/ScoreMethod.cs +++ b/src/CycloneDX.Core/Models/Vulnerabilities/ScoreMethod.cs @@ -30,7 +30,7 @@ public enum ScoreMethod CVSSV2, [XmlEnum(Name = "CVSSv3")] CVSSV3, - [XmlEnum(Name = "CVSSv3.1")] + [XmlEnum(Name = "CVSSv31")] CVSSV31, [XmlEnum(Name = "OWASP")] OWASP, diff --git a/src/CycloneDX.Core/Models/Vulnerabilities/Vulnerability.cs b/src/CycloneDX.Core/Models/Vulnerabilities/Vulnerability.cs index 205d263d..83b6b68b 100644 --- a/src/CycloneDX.Core/Models/Vulnerabilities/Vulnerability.cs +++ b/src/CycloneDX.Core/Models/Vulnerabilities/Vulnerability.cs @@ -143,7 +143,18 @@ public DateTime? Rejected [ProtoMember(18)] public List Properties { get; set; } public bool ShouldSerializeProperties() { return Properties?.Count > 0; } - + + public override bool Equals(object obj) + { + var other = obj as Vulnerability; + if (other == null) + { + return false; + } + + return Json.Serializer.Serialize(this) == Json.Serializer.Serialize(other); + } + public bool Equals(Vulnerability obj) { return CycloneDX.Json.Serializer.Serialize(this) == CycloneDX.Json.Serializer.Serialize(obj); diff --git a/src/CycloneDX.Core/Models/Workflow.cs b/src/CycloneDX.Core/Models/Workflow.cs index b74a9cd2..88d630e3 100644 --- a/src/CycloneDX.Core/Models/Workflow.cs +++ b/src/CycloneDX.Core/Models/Workflow.cs @@ -62,7 +62,7 @@ public class Workflow [XmlArray("taskTypes")] [XmlArrayItem("taskType")] [ProtoMember(9)] - public List TaskTypes { get; set; } + public List TaskTypes { get; set; } [XmlElement("trigger")] [ProtoMember(10)] diff --git a/src/CycloneDX.Core/Models/WorkflowTaskType.cs b/src/CycloneDX.Core/Models/WorkflowTaskType.cs deleted file mode 100644 index 7222b973..00000000 --- a/src/CycloneDX.Core/Models/WorkflowTaskType.cs +++ /dev/null @@ -1,55 +0,0 @@ -// This file is part of CycloneDX Library for .NET -// -// Licensed under the Apache License, Version 2.0 (the “License”); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an “AS IS” BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. -// -// SPDX-License-Identifier: Apache-2.0 -// Copyright (c) OWASP Foundation. All Rights Reserved. - -using System; -using System.Collections.Generic; -using System.Diagnostics.CodeAnalysis; -using System.Text.Json.Serialization; -using System.Xml.Serialization; -using ProtoBuf; - -namespace CycloneDX.Models -{ - [ProtoContract] - public enum WorkflowTaskType - { - [XmlEnum(Name = "copy")] - Copy, - [XmlEnum(Name = "clone")] - Clone, - [XmlEnum(Name = "lint")] - Lint, - [XmlEnum(Name = "scan")] - Scan, - [XmlEnum(Name = "merge")] - Merge, - [XmlEnum(Name = "build")] - Build, - [XmlEnum(Name = "test")] - Test, - [XmlEnum(Name = "deliver")] - Deliver, - [XmlEnum(Name = "deploy")] - Deploy, - [XmlEnum(Name = "release")] - Release, - [XmlEnum(Name = "clean")] - Clean, - [XmlEnum(Name = "other")] - Other, - } -} \ No newline at end of file diff --git a/src/CycloneDX.Core/Schemas/spdx.schema.json b/src/CycloneDX.Core/Schemas/spdx.schema.json index d081ef97..3406c45c 100644 --- a/src/CycloneDX.Core/Schemas/spdx.schema.json +++ b/src/CycloneDX.Core/Schemas/spdx.schema.json @@ -1,10 +1,11 @@ { "$schema": "http://json-schema.org/draft-07/schema#", "$id": "http://cyclonedx.org/schema/spdx.schema.json", - "$comment": "v1.0-3.23", + "$comment": "v1.0-3.24.0", "type": "string", "enum": [ "0BSD", + "3D-Slicer-1.0", "AAL", "Abstyles", "AdaCore-doc", @@ -26,12 +27,14 @@ "AGPL-3.0-only", "AGPL-3.0-or-later", "Aladdin", + "AMD-newlib", "AMDPLPA", "AML", "AML-glslang", "AMPAS", "ANTLR-PD", "ANTLR-PD-fallback", + "any-OSI", "Apache-1.0", "Apache-1.1", "Apache-2.0", @@ -67,6 +70,7 @@ "BSD-1-Clause", "BSD-2-Clause", "BSD-2-Clause-Darwin", + "BSD-2-Clause-first-lines", "BSD-2-Clause-FreeBSD", "BSD-2-Clause-NetBSD", "BSD-2-Clause-Patent", @@ -107,6 +111,7 @@ "CAL-1.0-Combined-Work-Exception", "Caldera", "Caldera-no-preamble", + "Catharon", "CATOSL-1.1", "CC-BY-1.0", "CC-BY-2.0", @@ -203,6 +208,7 @@ "CUA-OPL-1.0", "Cube", "curl", + "cve-tou", "D-FSL-1.0", "DEC-3-Clause", "diffmark", @@ -299,6 +305,7 @@ "Graphics-Gems", "gSOAP-1.3b", "gtkbook", + "Gutmann", "HaskellReport", "hdparm", "Hippocratic-2.1", @@ -309,18 +316,24 @@ "HPND-doc", "HPND-doc-sell", "HPND-export-US", + "HPND-export-US-acknowledgement", "HPND-export-US-modify", + "HPND-export2-US", "HPND-Fenneberg-Livingston", "HPND-INRIA-IMAG", + "HPND-Intel", "HPND-Kevlin-Henney", "HPND-Markus-Kuhn", + "HPND-merchantability-variant", "HPND-MIT-disclaimer", "HPND-Pbmplus", "HPND-sell-MIT-disclaimer-xserver", "HPND-sell-regexpr", "HPND-sell-variant", "HPND-sell-variant-MIT-disclaimer", + "HPND-sell-variant-MIT-disclaimer-rev", "HPND-UC", + "HPND-UC-export-US", "HTMLTIDY", "IBM-pibs", "ICU", @@ -408,6 +421,7 @@ "MIT-enna", "MIT-feh", "MIT-Festival", + "MIT-Khronos-old", "MIT-Modern-Variant", "MIT-open-group", "MIT-testregex", @@ -435,7 +449,9 @@ "NASA-1.3", "Naumen", "NBPL-1.0", + "NCBI-PD", "NCGL-UK-2.0", + "NCL", "NCSA", "Net-SNMP", "NetCDF", @@ -459,6 +475,7 @@ "NTP-0", "Nunit", "O-UDA-1.0", + "OAR", "OCCT-PL", "OCLC-2.0", "ODbL-1.0", @@ -515,11 +532,13 @@ "PHP-3.0", "PHP-3.01", "Pixar", + "pkgconf", "Plexus", "pnmstitch", "PolyForm-Noncommercial-1.0.0", "PolyForm-Small-Business-1.0.0", "PostgreSQL", + "PPL", "PSF-2.0", "psfrag", "psutils", @@ -575,6 +594,7 @@ "StandardML-NJ", "SugarCRM-1.1.3", "Sun-PPP", + "Sun-PPP-2000", "SunPro", "SWL", "swrule", @@ -584,6 +604,7 @@ "TCP-wrappers", "TermReadKey", "TGPPL-1.0", + "threeparttable", "TMate", "TORQUE-1.1", "TOSL", @@ -629,6 +650,7 @@ "Xnet", "xpp", "XSkat", + "xzoom", "YPL-1.0", "YPL-1.1", "Zed", @@ -643,6 +665,7 @@ "ZPL-2.1", "389-exception", "Asterisk-exception", + "Asterisk-linking-protocols-exception", "Autoconf-exception-2.0", "Autoconf-exception-3.0", "Autoconf-exception-generic", @@ -690,11 +713,13 @@ "OCCT-exception-1.0", "OpenJDK-assembly-exception-1.0", "openvpn-openssl-exception", + "PCRE2-exception", "PS-or-PDF-font-exception-20170817", "QPL-1.0-INRIA-2004-exception", "Qt-GPL-exception-1.0", "Qt-LGPL-exception-1.1", "Qwt-exception-1.0", + "RRDtool-FLOSS-exception-2.0", "SANE-exception", "SHL-2.0", "SHL-2.1", diff --git a/src/CycloneDX.Core/Schemas/spdx.xsd b/src/CycloneDX.Core/Schemas/spdx.xsd index 1365ed71..a339a085 100644 --- a/src/CycloneDX.Core/Schemas/spdx.xsd +++ b/src/CycloneDX.Core/Schemas/spdx.xsd @@ -2,7 +2,7 @@ + version="1.0-3.24.0"> @@ -12,6 +12,11 @@ BSD Zero Clause License + + + 3D Slicer License v1.0 + + Attribution Assurance License @@ -117,6 +122,11 @@ Aladdin Free Public License + + + AMD newlib License + + AMD's plpa_map.c License @@ -147,6 +157,11 @@ ANTLR Software Rights Notice with license fallback + + + Any OSI License + + Apache License 1.0 @@ -322,6 +337,11 @@ BSD 2-Clause - Ian Darwin variant + + + BSD 2-Clause - first lines requirement + + BSD 2-Clause FreeBSD License @@ -522,6 +542,11 @@ Caldera License (without preamble) + + + Catharon License + + Computer Associates Trusted Open Source License 1.1 @@ -1002,6 +1027,11 @@ curl License + + + Common Vulnerability Enumeration ToU License + + Deutsche Freie Software Lizenz @@ -1482,6 +1512,11 @@ gtkbook License + + + Gutmann License + + Haskell Language Report License @@ -1532,11 +1567,21 @@ HPND with US Government export control warning + + + HPND with US Government export control warning and acknowledgment + + HPND with US Government export control warning and modification rqmt + + + HPND with US Government export control and 2 disclaimers + + Historical Permission Notice and Disclaimer - Fenneberg-Livingston variant @@ -1547,6 +1592,11 @@ Historical Permission Notice and Disclaimer - INRIA-IMAG variant + + + Historical Permission Notice and Disclaimer - Intel variant + + Historical Permission Notice and Disclaimer - Kevlin Henney variant @@ -1557,6 +1607,11 @@ Historical Permission Notice and Disclaimer - Markus Kuhn variant + + + Historical Permission Notice and Disclaimer - merchantability variant + + Historical Permission Notice and Disclaimer with MIT disclaimer @@ -1587,11 +1642,21 @@ HPND sell variant with MIT disclaimer + + + HPND sell variant with MIT disclaimer - reverse + + Historical Permission Notice and Disclaimer - University of California variant + + + Historical Permission Notice and Disclaimer - University of California, US export warning + + HTML Tidy License @@ -2027,6 +2092,11 @@ MIT Festival Variant + + + MIT Khronos - old variant + + MIT License Modern Variant @@ -2162,11 +2232,21 @@ Net Boolean Public License v1 + + + NCBI Public Domain Notice + + Non-Commercial Government Licence + + + NCL Source Code License + + University of Illinois/NCSA Open Source License @@ -2282,6 +2362,11 @@ Open Use of Data Agreement v1.0 + + + OAR License + + Open CASCADE Technology Public License @@ -2562,6 +2647,11 @@ Pixar License + + + pkgconf License + + Plexus Classworlds License @@ -2587,6 +2677,11 @@ PostgreSQL License + + + Peer Production License + + Python Software Foundation License 2.0 @@ -2862,6 +2957,11 @@ Sun PPP License + + + Sun PPP License (2000) + + SunPro License @@ -2907,6 +3007,11 @@ Transitive Grace Period Public Licence 1.0 + + + threeparttable License + + TMate Open Source License @@ -3132,6 +3237,11 @@ XSkat License + + + xzoom License + + Yahoo! Public License v1.0 @@ -3203,6 +3313,11 @@ Asterisk exception + + + Asterisk linking protocols exception + + Autoconf exception 2.0 @@ -3438,6 +3553,11 @@ OpenVPN OpenSSL Exception + + + PCRE2 exception + + PS/PDF font exception (2017-08-17) @@ -3463,6 +3583,11 @@ Qwt exception 1.0 + + + RRDtool FLOSS exception 2.0 + + SANE Exception diff --git a/src/CycloneDX.Core/Xml/Serializer.Serialization.cs b/src/CycloneDX.Core/Xml/Serializer.Serialization.cs index 25ed3aa2..d59f360e 100644 --- a/src/CycloneDX.Core/Xml/Serializer.Serialization.cs +++ b/src/CycloneDX.Core/Xml/Serializer.Serialization.cs @@ -81,7 +81,20 @@ private static XmlSerializer GetXmlSerializer(SpecificationVersion specification return _serializers[specificationVersion]; } } - + + // Todo: this is a workaround to set the correct namespace + // when writing licenses. Can this be avoided? + private readonly static Dictionary WriterToNamespace = new Dictionary(); + + public static string GetNamespace(XmlWriter writer) + { + string namespaceStr; + lock (WriterToNamespace) { + namespaceStr = WriterToNamespace[writer]; + } + return namespaceStr; + } + /// /// Serializes a CycloneDX BOM writing the output to a stream. /// @@ -94,7 +107,15 @@ public static void Serialize(Bom bom, Stream outputStream) var serializer = GetXmlSerializer(bom.SpecVersion); using (var xmlWriter = XmlWriter.Create(outputStream, WriterSettings)) { + lock (WriterToNamespace) + { + WriterToNamespace[xmlWriter] = SpecificationVersionHelpers.XmlNamespace(bom.SpecVersion); + } serializer.Serialize(xmlWriter, BomUtils.GetBomForSerialization(bom)); + lock (WriterToNamespace) + { + WriterToNamespace.Remove(xmlWriter); + } } } diff --git a/src/CycloneDX.Spdx/CycloneDX.Spdx.csproj b/src/CycloneDX.Spdx/CycloneDX.Spdx.csproj index e5ecdacc..17fb1270 100644 --- a/src/CycloneDX.Spdx/CycloneDX.Spdx.csproj +++ b/src/CycloneDX.Spdx/CycloneDX.Spdx.csproj @@ -12,8 +12,8 @@ runtime; build; native; contentfiles; analyzers; buildtransitive all - - + + diff --git a/src/CycloneDX.Spdx/Validation/JsonValidator.cs b/src/CycloneDX.Spdx/Validation/JsonValidator.cs index 953c116c..46e37031 100644 --- a/src/CycloneDX.Spdx/Validation/JsonValidator.cs +++ b/src/CycloneDX.Spdx/Validation/JsonValidator.cs @@ -78,42 +78,30 @@ public static ValidationResult Validate(string jsonString) private static ValidationResult Validate(JsonSchema schema, JsonDocument jsonDocument) { var validationMessages = new List(); - var validationOptions = new ValidationOptions + var validationOptions = new EvaluationOptions { - OutputFormat = OutputFormat.Detailed, + OutputFormat = OutputFormat.List, RequireFormatValidation = true }; - var result = schema.Validate(jsonDocument.RootElement, validationOptions); + var result = schema.Evaluate(jsonDocument.RootElement, validationOptions); if (!result.IsValid) { - validationMessages.Add($"Validation failed: {result.Message}"); - validationMessages.Add(result.SchemaLocation.ToString()); - - if (result.NestedResults != null) + validationMessages.Add("Validation failed:"); + // because we requested the results as a flat list + // there will be no nested results + foreach (var detail in result.Details) { - var nestedResults = new Queue(result.NestedResults); - - while (nestedResults.Count > 0) + if (detail.HasErrors) { - var nestedResult = nestedResults.Dequeue(); - - if ( - !string.IsNullOrEmpty(nestedResult.Message) - && nestedResult.NestedResults != null - && nestedResult.NestedResults.Count > 0) - { - validationMessages.Add($"{nestedResult.InstanceLocation}: {nestedResult.Message}"); - } - - if (nestedResult.NestedResults != null) + foreach (var error in detail.Errors) { - foreach (var newNestedResult in nestedResult.NestedResults) - { - nestedResults.Enqueue(newNestedResult); - } + validationMessages.Add(error.Value); } + validationMessages.Add(detail.SchemaLocation.ToString()); + validationMessages.Add($"On instance: {detail.InstanceLocation}:"); + validationMessages.Add(detail.InstanceLocation.Evaluate(jsonDocument.RootElement).ToString()); } } } diff --git a/src/CycloneDX.Utils/Merge.cs b/src/CycloneDX.Utils/Merge.cs index da18352c..3c8c40da 100644 --- a/src/CycloneDX.Utils/Merge.cs +++ b/src/CycloneDX.Utils/Merge.cs @@ -23,7 +23,7 @@ namespace CycloneDX.Utils { - class ListMergeHelper + class ListMergeHelper where T : IEquatable { public List Merge(List list1, List list2) { @@ -31,12 +31,36 @@ public List Merge(List list1, List list2) if (list2 is null) return list1; var result = new List(list1); + // We want to avoid the costly computation of the hashes if possible. + // Therefore, we use a nullable type. + var resultHashes = new List(list1.Count); + for (int i = 0; i < list1.Count; i++) + { + resultHashes.Add(null); + } foreach (var item in list2) { - if (!(result.Contains(item))) + int hash = item.GetHashCode(); + bool found = false; + for (int i = 0; i < result.Count; i++) + { + var resultItem = result[i]; + if (resultHashes[i] == null) + { + resultHashes[i] = resultItem.GetHashCode(); + } + int resultHash = resultHashes[i].Value; + if (hash == resultHash && item.Equals(resultItem)) + { + found = true; + break; + } + } + if (!found) { result.Add(item); + resultHashes.Add(hash); } } @@ -67,13 +91,19 @@ public static Bom FlatMerge(Bom bom1, Bom bom2) var toolsMerger = new ListMergeHelper(); #pragma warning restore 618 var tools = toolsMerger.Merge(bom1.Metadata?.Tools?.Tools, bom2.Metadata?.Tools?.Tools); - if (tools != null) + var toolsComponentsMerger = new ListMergeHelper(); + var toolsComponents = toolsComponentsMerger.Merge(bom1.Metadata?.Tools?.Components, bom2.Metadata?.Tools?.Components); + var toolsServicesMerger = new ListMergeHelper(); + var toolsServices = toolsServicesMerger.Merge(bom1.Metadata?.Tools?.Services, bom2.Metadata?.Tools?.Services); + if (tools != null || toolsComponents != null || toolsServices != null) { result.Metadata = new Metadata { Tools = new ToolChoices { Tools = tools, + Components = toolsComponents, + Services = toolsServices, } }; } @@ -230,6 +260,36 @@ bom.SerialNumber is null { result.Metadata.Tools.Tools.AddRange(bom.Metadata.Tools.Tools); } + if (bom.Metadata?.Tools?.Components?.Count > 0) + { + if (result.Metadata.Tools.Components == null) + { + result.Metadata.Tools.Components = new List(); + } + foreach (var component in bom.Metadata.Tools.Components) + { + NamespaceComponentBomRefs(ComponentBomRefNamespace(bom.Metadata.Component), component); + if (!result.Metadata.Tools.Components.Contains(component)) + { + result.Metadata.Tools.Components.Add(component); + } + } + } + if (bom.Metadata?.Tools?.Services?.Count > 0) + { + if (result.Metadata.Tools.Services == null) + { + result.Metadata.Tools.Services = new List(); + } + foreach (var service in bom.Metadata.Tools.Services) + { + service.BomRef = NamespacedBomRef(bom.Metadata.Component, service.BomRef); + if (!result.Metadata.Tools.Services.Contains(service)) + { + result.Metadata.Tools.Services.Add(service); + } + } + } var thisComponent = bom.Metadata.Component; if (thisComponent.Components is null) bom.Metadata.Component.Components = new List(); @@ -320,6 +380,11 @@ private static string ComponentBomRefNamespace(Component component) } private static void NamespaceComponentBomRefs(Component topComponent) + { + NamespaceComponentBomRefs(ComponentBomRefNamespace(topComponent), topComponent); + } + + private static void NamespaceComponentBomRefs(string bomRefNamespace, Component topComponent) { var components = new Stack(); components.Push(topComponent); @@ -329,12 +394,14 @@ private static void NamespaceComponentBomRefs(Component topComponent) var currentComponent = components.Pop(); if (currentComponent.Components != null) - foreach (var subComponent in currentComponent.Components) { - components.Push(subComponent); + foreach (var subComponent in currentComponent.Components) + { + components.Push(subComponent); + } } - currentComponent.BomRef = NamespacedBomRef(topComponent, currentComponent.BomRef); + currentComponent.BomRef = NamespacedBomRef(bomRefNamespace, currentComponent.BomRef); } } diff --git a/tests/CycloneDX.Core.Tests/CycloneDX.Core.Tests.csproj b/tests/CycloneDX.Core.Tests/CycloneDX.Core.Tests.csproj index 78ebca9c..e27e4125 100644 --- a/tests/CycloneDX.Core.Tests/CycloneDX.Core.Tests.csproj +++ b/tests/CycloneDX.Core.Tests/CycloneDX.Core.Tests.csproj @@ -1,4 +1,4 @@ - + net6 @@ -11,10 +11,10 @@ runtime; build; native; contentfiles; analyzers; buildtransitive all - + - + runtime; build; native; contentfiles; analyzers; buildtransitive all diff --git a/tests/CycloneDX.Core.Tests/Json/v1.5/SerializationTests.cs b/tests/CycloneDX.Core.Tests/Json/v1.5/SerializationTests.cs index 196a9bbd..0fa6a86b 100644 --- a/tests/CycloneDX.Core.Tests/Json/v1.5/SerializationTests.cs +++ b/tests/CycloneDX.Core.Tests/Json/v1.5/SerializationTests.cs @@ -162,9 +162,7 @@ public async Task JsonRoundTripAsyncTest(string filename) [InlineData("valid-service-1.5.json")] [InlineData("valid-service-empty-objects-1.5.json")] [InlineData("valid-signatures-1.5.json")] - //TODO - I do not know why this particular one is failing - //Validating it with other tools works, maybe an obscure STJ bug??? - //[InlineData("valid-vulnerability-1.5.json")] + [InlineData("valid-vulnerability-1.5.json")] public void JsonDowngradeTest(string filename) { var resourceFilename = Path.Join("Resources", "v1.5", filename); diff --git a/tests/CycloneDX.Core.Tests/Json/v1.5/ValidationTests.cs b/tests/CycloneDX.Core.Tests/Json/v1.5/ValidationTests.cs index 121f1900..0310f610 100644 --- a/tests/CycloneDX.Core.Tests/Json/v1.5/ValidationTests.cs +++ b/tests/CycloneDX.Core.Tests/Json/v1.5/ValidationTests.cs @@ -51,6 +51,7 @@ public class ValidationTests [InlineData("valid-metadata-manufacture-1.5.json")] [InlineData("valid-metadata-supplier-1.5.json")] [InlineData("valid-metadata-timestamp-1.5.json")] + [InlineData("valid-metadata-timestamp-higher-precision-1.5.json")] [InlineData("valid-metadata-tool-1.5.json")] [InlineData("valid-metadata-tool-deprecated-1.5.json")] [InlineData("valid-minimal-viable-1.5.json")] @@ -152,5 +153,55 @@ public void InvalidJsonTest(string filename) Assert.False(validationResult.Valid); } + + [Theory] + [InlineData("valid-annotation-1.5.json")] + [InlineData("valid-assembly-1.5.json")] + [InlineData("valid-bom-1.5.json")] + [InlineData("valid-component-hashes-1.5.json")] + [InlineData("valid-component-ref-1.5.json")] + [InlineData("valid-component-swid-1.5.json")] + [InlineData("valid-component-swid-full-1.5.json")] + [InlineData("valid-component-types-1.5.json")] + [InlineData("valid-compositions-1.5.json")] + [InlineData("valid-dependency-1.5.json")] + [InlineData("valid-empty-components-1.5.json")] + [InlineData("valid-evidence-1.5.json")] + [InlineData("valid-external-reference-1.5.json")] + [InlineData("valid-formulation-1.5.json")] + [InlineData("valid-license-expression-1.5.json")] + [InlineData("valid-license-id-1.5.json")] + [InlineData("valid-license-licensing-1.5.json")] + [InlineData("valid-license-name-1.5.json")] + [InlineData("valid-machine-learning-1.5.json")] + [InlineData("valid-metadata-author-1.5.json")] + [InlineData("valid-metadata-license-1.5.json")] + [InlineData("valid-metadata-lifecycle-1.5.json")] + [InlineData("valid-metadata-manufacture-1.5.json")] + [InlineData("valid-metadata-supplier-1.5.json")] + [InlineData("valid-metadata-timestamp-1.5.json")] + [InlineData("valid-metadata-tool-1.5.json")] + [InlineData("valid-metadata-tool-deprecated-1.5.json")] + [InlineData("valid-minimal-viable-1.5.json")] + [InlineData("valid-patch-1.5.json")] + [InlineData("valid-properties-1.5.json")] + [InlineData("valid-release-notes-1.5.json")] + [InlineData("valid-saasbom-1.5.json")] + [InlineData("valid-service-1.5.json")] + [InlineData("valid-service-empty-objects-1.5.json")] + [InlineData("valid-signatures-1.5.json")] + [InlineData("valid-vulnerability-1.5.json")] + public void ValidateRoundTripTest(string filename) + { + var resourceFilename = Path.Join("Resources", "v1.5", filename); + var jsonBom = File.ReadAllText(resourceFilename); + + var bom = Serializer.Deserialize(jsonBom); + jsonBom = Serializer.Serialize(bom); + + var validationResult = Validator.Validate(jsonBom, SpecificationVersion.v1_5); + + Assert.True(validationResult.Valid, string.Join(Environment.NewLine, validationResult.Messages)); + } } } diff --git a/tests/CycloneDX.Core.Tests/Json/v1.5/__snapshots__/SerializationTests.JsonRoundTripAsyncTest_valid-dependency-1.5.json.snap b/tests/CycloneDX.Core.Tests/Json/v1.5/__snapshots__/SerializationTests.JsonRoundTripAsyncTest_valid-dependency-1.5.json.snap index 441daaeb..faf55cd8 100644 --- a/tests/CycloneDX.Core.Tests/Json/v1.5/__snapshots__/SerializationTests.JsonRoundTripAsyncTest_valid-dependency-1.5.json.snap +++ b/tests/CycloneDX.Core.Tests/Json/v1.5/__snapshots__/SerializationTests.JsonRoundTripAsyncTest_valid-dependency-1.5.json.snap @@ -25,8 +25,7 @@ ], "dependencies": [ { - "ref": "library-a", - "dependsOn": [] + "ref": "library-a" }, { "ref": "library-b", diff --git a/tests/CycloneDX.Core.Tests/Json/v1.5/__snapshots__/SerializationTests.JsonRoundTripAsyncTest_valid-empty-components-1.5.json.snap b/tests/CycloneDX.Core.Tests/Json/v1.5/__snapshots__/SerializationTests.JsonRoundTripAsyncTest_valid-empty-components-1.5.json.snap index 0cca5461..bfcbc4a4 100644 --- a/tests/CycloneDX.Core.Tests/Json/v1.5/__snapshots__/SerializationTests.JsonRoundTripAsyncTest_valid-empty-components-1.5.json.snap +++ b/tests/CycloneDX.Core.Tests/Json/v1.5/__snapshots__/SerializationTests.JsonRoundTripAsyncTest_valid-empty-components-1.5.json.snap @@ -2,6 +2,5 @@ "bomFormat": "CycloneDX", "specVersion": "1.5", "serialNumber": "urn:uuid:3e671687-395b-41f5-a30f-a58921a69b79", - "version": 1, - "components": [] + "version": 1 } diff --git a/tests/CycloneDX.Core.Tests/Json/v1.5/__snapshots__/SerializationTests.JsonRoundTripAsyncTest_valid-evidence-1.5.json.snap b/tests/CycloneDX.Core.Tests/Json/v1.5/__snapshots__/SerializationTests.JsonRoundTripAsyncTest_valid-evidence-1.5.json.snap index 35ffd8bd..b9bcf3ca 100644 --- a/tests/CycloneDX.Core.Tests/Json/v1.5/__snapshots__/SerializationTests.JsonRoundTripAsyncTest_valid-evidence-1.5.json.snap +++ b/tests/CycloneDX.Core.Tests/Json/v1.5/__snapshots__/SerializationTests.JsonRoundTripAsyncTest_valid-evidence-1.5.json.snap @@ -48,7 +48,7 @@ } ], "identity": { - "field": "Purl", + "field": "purl", "confidence": 1, "methods": [ { diff --git a/tests/CycloneDX.Core.Tests/Json/v1.5/__snapshots__/SerializationTests.JsonRoundTripAsyncTest_valid-formulation-1.5.json.snap b/tests/CycloneDX.Core.Tests/Json/v1.5/__snapshots__/SerializationTests.JsonRoundTripAsyncTest_valid-formulation-1.5.json.snap index 07d453e8..354f0ecd 100644 --- a/tests/CycloneDX.Core.Tests/Json/v1.5/__snapshots__/SerializationTests.JsonRoundTripAsyncTest_valid-formulation-1.5.json.snap +++ b/tests/CycloneDX.Core.Tests/Json/v1.5/__snapshots__/SerializationTests.JsonRoundTripAsyncTest_valid-formulation-1.5.json.snap @@ -269,7 +269,7 @@ "volume": { "uid": "volume-1", "name": "My volume", - "mode": "Filesystem", + "mode": "filesystem", "path": "/", "sizeAllocated": "10GB", "persistent": true, diff --git a/tests/CycloneDX.Core.Tests/Json/v1.5/__snapshots__/SerializationTests.JsonRoundTripAsyncTest_valid-metadata-author-1.5.json.snap b/tests/CycloneDX.Core.Tests/Json/v1.5/__snapshots__/SerializationTests.JsonRoundTripAsyncTest_valid-metadata-author-1.5.json.snap index c55bb454..f550087d 100644 --- a/tests/CycloneDX.Core.Tests/Json/v1.5/__snapshots__/SerializationTests.JsonRoundTripAsyncTest_valid-metadata-author-1.5.json.snap +++ b/tests/CycloneDX.Core.Tests/Json/v1.5/__snapshots__/SerializationTests.JsonRoundTripAsyncTest_valid-metadata-author-1.5.json.snap @@ -11,6 +11,5 @@ "phone": "800-555-1212" } ] - }, - "components": [] + } } diff --git a/tests/CycloneDX.Core.Tests/Json/v1.5/__snapshots__/SerializationTests.JsonRoundTripAsyncTest_valid-metadata-license-1.5.json.snap b/tests/CycloneDX.Core.Tests/Json/v1.5/__snapshots__/SerializationTests.JsonRoundTripAsyncTest_valid-metadata-license-1.5.json.snap index 14ec3afd..1659a1e8 100644 --- a/tests/CycloneDX.Core.Tests/Json/v1.5/__snapshots__/SerializationTests.JsonRoundTripAsyncTest_valid-metadata-license-1.5.json.snap +++ b/tests/CycloneDX.Core.Tests/Json/v1.5/__snapshots__/SerializationTests.JsonRoundTripAsyncTest_valid-metadata-license-1.5.json.snap @@ -11,6 +11,5 @@ } } ] - }, - "components": [] + } } diff --git a/tests/CycloneDX.Core.Tests/Json/v1.5/__snapshots__/SerializationTests.JsonRoundTripAsyncTest_valid-metadata-lifecycle-1.5.json.snap b/tests/CycloneDX.Core.Tests/Json/v1.5/__snapshots__/SerializationTests.JsonRoundTripAsyncTest_valid-metadata-lifecycle-1.5.json.snap index 9d6713e8..4a52b38a 100644 --- a/tests/CycloneDX.Core.Tests/Json/v1.5/__snapshots__/SerializationTests.JsonRoundTripAsyncTest_valid-metadata-lifecycle-1.5.json.snap +++ b/tests/CycloneDX.Core.Tests/Json/v1.5/__snapshots__/SerializationTests.JsonRoundTripAsyncTest_valid-metadata-lifecycle-1.5.json.snap @@ -16,6 +16,5 @@ "description": "Integration testing specific to the runtime platform" } ] - }, - "components": [] + } } diff --git a/tests/CycloneDX.Core.Tests/Json/v1.5/__snapshots__/SerializationTests.JsonRoundTripAsyncTest_valid-metadata-manufacture-1.5.json.snap b/tests/CycloneDX.Core.Tests/Json/v1.5/__snapshots__/SerializationTests.JsonRoundTripAsyncTest_valid-metadata-manufacture-1.5.json.snap index 13427e19..ff58a6e5 100644 --- a/tests/CycloneDX.Core.Tests/Json/v1.5/__snapshots__/SerializationTests.JsonRoundTripAsyncTest_valid-metadata-manufacture-1.5.json.snap +++ b/tests/CycloneDX.Core.Tests/Json/v1.5/__snapshots__/SerializationTests.JsonRoundTripAsyncTest_valid-metadata-manufacture-1.5.json.snap @@ -18,6 +18,5 @@ ], "bom-ref": "manufacturer-1" } - }, - "components": [] + } } diff --git a/tests/CycloneDX.Core.Tests/Json/v1.5/__snapshots__/SerializationTests.JsonRoundTripAsyncTest_valid-metadata-supplier-1.5.json.snap b/tests/CycloneDX.Core.Tests/Json/v1.5/__snapshots__/SerializationTests.JsonRoundTripAsyncTest_valid-metadata-supplier-1.5.json.snap index cfb99a44..62336c56 100644 --- a/tests/CycloneDX.Core.Tests/Json/v1.5/__snapshots__/SerializationTests.JsonRoundTripAsyncTest_valid-metadata-supplier-1.5.json.snap +++ b/tests/CycloneDX.Core.Tests/Json/v1.5/__snapshots__/SerializationTests.JsonRoundTripAsyncTest_valid-metadata-supplier-1.5.json.snap @@ -18,6 +18,5 @@ ], "bom-ref": "supplier-1" } - }, - "components": [] + } } diff --git a/tests/CycloneDX.Core.Tests/Json/v1.5/__snapshots__/SerializationTests.JsonRoundTripAsyncTest_valid-metadata-timestamp-1.5.json.snap b/tests/CycloneDX.Core.Tests/Json/v1.5/__snapshots__/SerializationTests.JsonRoundTripAsyncTest_valid-metadata-timestamp-1.5.json.snap index 54a9feae..ecb55030 100644 --- a/tests/CycloneDX.Core.Tests/Json/v1.5/__snapshots__/SerializationTests.JsonRoundTripAsyncTest_valid-metadata-timestamp-1.5.json.snap +++ b/tests/CycloneDX.Core.Tests/Json/v1.5/__snapshots__/SerializationTests.JsonRoundTripAsyncTest_valid-metadata-timestamp-1.5.json.snap @@ -5,6 +5,5 @@ "version": 1, "metadata": { "timestamp": "2020-04-13T20:20:39Z" - }, - "components": [] + } } diff --git a/tests/CycloneDX.Core.Tests/Json/v1.5/__snapshots__/SerializationTests.JsonRoundTripAsyncTest_valid-metadata-tool-deprecated-1.5.json.snap b/tests/CycloneDX.Core.Tests/Json/v1.5/__snapshots__/SerializationTests.JsonRoundTripAsyncTest_valid-metadata-tool-deprecated-1.5.json.snap index 44f99f7a..077f6f74 100644 --- a/tests/CycloneDX.Core.Tests/Json/v1.5/__snapshots__/SerializationTests.JsonRoundTripAsyncTest_valid-metadata-tool-deprecated-1.5.json.snap +++ b/tests/CycloneDX.Core.Tests/Json/v1.5/__snapshots__/SerializationTests.JsonRoundTripAsyncTest_valid-metadata-tool-deprecated-1.5.json.snap @@ -21,6 +21,5 @@ ] } ] - }, - "components": [] + } } diff --git a/tests/CycloneDX.Core.Tests/Json/v1.5/__snapshots__/SerializationTests.JsonRoundTripAsyncTest_valid-saasbom-1.5.json.snap b/tests/CycloneDX.Core.Tests/Json/v1.5/__snapshots__/SerializationTests.JsonRoundTripAsyncTest_valid-saasbom-1.5.json.snap index 8984b2b5..fdcc1d0f 100644 --- a/tests/CycloneDX.Core.Tests/Json/v1.5/__snapshots__/SerializationTests.JsonRoundTripAsyncTest_valid-saasbom-1.5.json.snap +++ b/tests/CycloneDX.Core.Tests/Json/v1.5/__snapshots__/SerializationTests.JsonRoundTripAsyncTest_valid-saasbom-1.5.json.snap @@ -304,8 +304,7 @@ ] }, { - "ref": "ms-2.example.com", - "dependsOn": [] + "ref": "ms-2.example.com" }, { "ref": "ms-3.example.com", diff --git a/tests/CycloneDX.Core.Tests/Json/v1.5/__snapshots__/SerializationTests.JsonRoundTripAsyncTest_valid-service-empty-objects-1.5.json.snap b/tests/CycloneDX.Core.Tests/Json/v1.5/__snapshots__/SerializationTests.JsonRoundTripAsyncTest_valid-service-empty-objects-1.5.json.snap index 3715ea3a..969a1412 100644 --- a/tests/CycloneDX.Core.Tests/Json/v1.5/__snapshots__/SerializationTests.JsonRoundTripAsyncTest_valid-service-empty-objects-1.5.json.snap +++ b/tests/CycloneDX.Core.Tests/Json/v1.5/__snapshots__/SerializationTests.JsonRoundTripAsyncTest_valid-service-empty-objects-1.5.json.snap @@ -6,13 +6,8 @@ "services": [ { "bom-ref": "b2a46a4b-8367-4bae-9820-95557cfe03a8", - "provider": { - "contact": [] - }, - "name": "Stock ticker service", - "endpoints": [], - "data": [], - "externalReferences": [] + "provider": {}, + "name": "Stock ticker service" } ] } diff --git a/tests/CycloneDX.Core.Tests/Json/v1.5/__snapshots__/SerializationTests.JsonRoundTripTest_valid-dependency-1.5.json.snap b/tests/CycloneDX.Core.Tests/Json/v1.5/__snapshots__/SerializationTests.JsonRoundTripTest_valid-dependency-1.5.json.snap index 441daaeb..faf55cd8 100644 --- a/tests/CycloneDX.Core.Tests/Json/v1.5/__snapshots__/SerializationTests.JsonRoundTripTest_valid-dependency-1.5.json.snap +++ b/tests/CycloneDX.Core.Tests/Json/v1.5/__snapshots__/SerializationTests.JsonRoundTripTest_valid-dependency-1.5.json.snap @@ -25,8 +25,7 @@ ], "dependencies": [ { - "ref": "library-a", - "dependsOn": [] + "ref": "library-a" }, { "ref": "library-b", diff --git a/tests/CycloneDX.Core.Tests/Json/v1.5/__snapshots__/SerializationTests.JsonRoundTripTest_valid-empty-components-1.5.json.snap b/tests/CycloneDX.Core.Tests/Json/v1.5/__snapshots__/SerializationTests.JsonRoundTripTest_valid-empty-components-1.5.json.snap index 0cca5461..bfcbc4a4 100644 --- a/tests/CycloneDX.Core.Tests/Json/v1.5/__snapshots__/SerializationTests.JsonRoundTripTest_valid-empty-components-1.5.json.snap +++ b/tests/CycloneDX.Core.Tests/Json/v1.5/__snapshots__/SerializationTests.JsonRoundTripTest_valid-empty-components-1.5.json.snap @@ -2,6 +2,5 @@ "bomFormat": "CycloneDX", "specVersion": "1.5", "serialNumber": "urn:uuid:3e671687-395b-41f5-a30f-a58921a69b79", - "version": 1, - "components": [] + "version": 1 } diff --git a/tests/CycloneDX.Core.Tests/Json/v1.5/__snapshots__/SerializationTests.JsonRoundTripTest_valid-evidence-1.5.json.snap b/tests/CycloneDX.Core.Tests/Json/v1.5/__snapshots__/SerializationTests.JsonRoundTripTest_valid-evidence-1.5.json.snap index 35ffd8bd..b9bcf3ca 100644 --- a/tests/CycloneDX.Core.Tests/Json/v1.5/__snapshots__/SerializationTests.JsonRoundTripTest_valid-evidence-1.5.json.snap +++ b/tests/CycloneDX.Core.Tests/Json/v1.5/__snapshots__/SerializationTests.JsonRoundTripTest_valid-evidence-1.5.json.snap @@ -48,7 +48,7 @@ } ], "identity": { - "field": "Purl", + "field": "purl", "confidence": 1, "methods": [ { diff --git a/tests/CycloneDX.Core.Tests/Json/v1.5/__snapshots__/SerializationTests.JsonRoundTripTest_valid-formulation-1.5.json.snap b/tests/CycloneDX.Core.Tests/Json/v1.5/__snapshots__/SerializationTests.JsonRoundTripTest_valid-formulation-1.5.json.snap index 07d453e8..354f0ecd 100644 --- a/tests/CycloneDX.Core.Tests/Json/v1.5/__snapshots__/SerializationTests.JsonRoundTripTest_valid-formulation-1.5.json.snap +++ b/tests/CycloneDX.Core.Tests/Json/v1.5/__snapshots__/SerializationTests.JsonRoundTripTest_valid-formulation-1.5.json.snap @@ -269,7 +269,7 @@ "volume": { "uid": "volume-1", "name": "My volume", - "mode": "Filesystem", + "mode": "filesystem", "path": "/", "sizeAllocated": "10GB", "persistent": true, diff --git a/tests/CycloneDX.Core.Tests/Json/v1.5/__snapshots__/SerializationTests.JsonRoundTripTest_valid-metadata-author-1.5.json.snap b/tests/CycloneDX.Core.Tests/Json/v1.5/__snapshots__/SerializationTests.JsonRoundTripTest_valid-metadata-author-1.5.json.snap index c55bb454..f550087d 100644 --- a/tests/CycloneDX.Core.Tests/Json/v1.5/__snapshots__/SerializationTests.JsonRoundTripTest_valid-metadata-author-1.5.json.snap +++ b/tests/CycloneDX.Core.Tests/Json/v1.5/__snapshots__/SerializationTests.JsonRoundTripTest_valid-metadata-author-1.5.json.snap @@ -11,6 +11,5 @@ "phone": "800-555-1212" } ] - }, - "components": [] + } } diff --git a/tests/CycloneDX.Core.Tests/Json/v1.5/__snapshots__/SerializationTests.JsonRoundTripTest_valid-metadata-license-1.5.json.snap b/tests/CycloneDX.Core.Tests/Json/v1.5/__snapshots__/SerializationTests.JsonRoundTripTest_valid-metadata-license-1.5.json.snap index 14ec3afd..1659a1e8 100644 --- a/tests/CycloneDX.Core.Tests/Json/v1.5/__snapshots__/SerializationTests.JsonRoundTripTest_valid-metadata-license-1.5.json.snap +++ b/tests/CycloneDX.Core.Tests/Json/v1.5/__snapshots__/SerializationTests.JsonRoundTripTest_valid-metadata-license-1.5.json.snap @@ -11,6 +11,5 @@ } } ] - }, - "components": [] + } } diff --git a/tests/CycloneDX.Core.Tests/Json/v1.5/__snapshots__/SerializationTests.JsonRoundTripTest_valid-metadata-lifecycle-1.5.json.snap b/tests/CycloneDX.Core.Tests/Json/v1.5/__snapshots__/SerializationTests.JsonRoundTripTest_valid-metadata-lifecycle-1.5.json.snap index 9d6713e8..4a52b38a 100644 --- a/tests/CycloneDX.Core.Tests/Json/v1.5/__snapshots__/SerializationTests.JsonRoundTripTest_valid-metadata-lifecycle-1.5.json.snap +++ b/tests/CycloneDX.Core.Tests/Json/v1.5/__snapshots__/SerializationTests.JsonRoundTripTest_valid-metadata-lifecycle-1.5.json.snap @@ -16,6 +16,5 @@ "description": "Integration testing specific to the runtime platform" } ] - }, - "components": [] + } } diff --git a/tests/CycloneDX.Core.Tests/Json/v1.5/__snapshots__/SerializationTests.JsonRoundTripTest_valid-metadata-manufacture-1.5.json.snap b/tests/CycloneDX.Core.Tests/Json/v1.5/__snapshots__/SerializationTests.JsonRoundTripTest_valid-metadata-manufacture-1.5.json.snap index 13427e19..ff58a6e5 100644 --- a/tests/CycloneDX.Core.Tests/Json/v1.5/__snapshots__/SerializationTests.JsonRoundTripTest_valid-metadata-manufacture-1.5.json.snap +++ b/tests/CycloneDX.Core.Tests/Json/v1.5/__snapshots__/SerializationTests.JsonRoundTripTest_valid-metadata-manufacture-1.5.json.snap @@ -18,6 +18,5 @@ ], "bom-ref": "manufacturer-1" } - }, - "components": [] + } } diff --git a/tests/CycloneDX.Core.Tests/Json/v1.5/__snapshots__/SerializationTests.JsonRoundTripTest_valid-metadata-supplier-1.5.json.snap b/tests/CycloneDX.Core.Tests/Json/v1.5/__snapshots__/SerializationTests.JsonRoundTripTest_valid-metadata-supplier-1.5.json.snap index cfb99a44..62336c56 100644 --- a/tests/CycloneDX.Core.Tests/Json/v1.5/__snapshots__/SerializationTests.JsonRoundTripTest_valid-metadata-supplier-1.5.json.snap +++ b/tests/CycloneDX.Core.Tests/Json/v1.5/__snapshots__/SerializationTests.JsonRoundTripTest_valid-metadata-supplier-1.5.json.snap @@ -18,6 +18,5 @@ ], "bom-ref": "supplier-1" } - }, - "components": [] + } } diff --git a/tests/CycloneDX.Core.Tests/Json/v1.5/__snapshots__/SerializationTests.JsonRoundTripTest_valid-metadata-timestamp-1.5.json.snap b/tests/CycloneDX.Core.Tests/Json/v1.5/__snapshots__/SerializationTests.JsonRoundTripTest_valid-metadata-timestamp-1.5.json.snap index 54a9feae..ecb55030 100644 --- a/tests/CycloneDX.Core.Tests/Json/v1.5/__snapshots__/SerializationTests.JsonRoundTripTest_valid-metadata-timestamp-1.5.json.snap +++ b/tests/CycloneDX.Core.Tests/Json/v1.5/__snapshots__/SerializationTests.JsonRoundTripTest_valid-metadata-timestamp-1.5.json.snap @@ -5,6 +5,5 @@ "version": 1, "metadata": { "timestamp": "2020-04-13T20:20:39Z" - }, - "components": [] + } } diff --git a/tests/CycloneDX.Core.Tests/Json/v1.5/__snapshots__/SerializationTests.JsonRoundTripTest_valid-metadata-tool-deprecated-1.5.json.snap b/tests/CycloneDX.Core.Tests/Json/v1.5/__snapshots__/SerializationTests.JsonRoundTripTest_valid-metadata-tool-deprecated-1.5.json.snap index 44f99f7a..077f6f74 100644 --- a/tests/CycloneDX.Core.Tests/Json/v1.5/__snapshots__/SerializationTests.JsonRoundTripTest_valid-metadata-tool-deprecated-1.5.json.snap +++ b/tests/CycloneDX.Core.Tests/Json/v1.5/__snapshots__/SerializationTests.JsonRoundTripTest_valid-metadata-tool-deprecated-1.5.json.snap @@ -21,6 +21,5 @@ ] } ] - }, - "components": [] + } } diff --git a/tests/CycloneDX.Core.Tests/Json/v1.5/__snapshots__/SerializationTests.JsonRoundTripTest_valid-saasbom-1.5.json.snap b/tests/CycloneDX.Core.Tests/Json/v1.5/__snapshots__/SerializationTests.JsonRoundTripTest_valid-saasbom-1.5.json.snap index 8984b2b5..fdcc1d0f 100644 --- a/tests/CycloneDX.Core.Tests/Json/v1.5/__snapshots__/SerializationTests.JsonRoundTripTest_valid-saasbom-1.5.json.snap +++ b/tests/CycloneDX.Core.Tests/Json/v1.5/__snapshots__/SerializationTests.JsonRoundTripTest_valid-saasbom-1.5.json.snap @@ -304,8 +304,7 @@ ] }, { - "ref": "ms-2.example.com", - "dependsOn": [] + "ref": "ms-2.example.com" }, { "ref": "ms-3.example.com", diff --git a/tests/CycloneDX.Core.Tests/Json/v1.5/__snapshots__/SerializationTests.JsonRoundTripTest_valid-service-empty-objects-1.5.json.snap b/tests/CycloneDX.Core.Tests/Json/v1.5/__snapshots__/SerializationTests.JsonRoundTripTest_valid-service-empty-objects-1.5.json.snap index 3715ea3a..969a1412 100644 --- a/tests/CycloneDX.Core.Tests/Json/v1.5/__snapshots__/SerializationTests.JsonRoundTripTest_valid-service-empty-objects-1.5.json.snap +++ b/tests/CycloneDX.Core.Tests/Json/v1.5/__snapshots__/SerializationTests.JsonRoundTripTest_valid-service-empty-objects-1.5.json.snap @@ -6,13 +6,8 @@ "services": [ { "bom-ref": "b2a46a4b-8367-4bae-9820-95557cfe03a8", - "provider": { - "contact": [] - }, - "name": "Stock ticker service", - "endpoints": [], - "data": [], - "externalReferences": [] + "provider": {}, + "name": "Stock ticker service" } ] } diff --git a/tests/CycloneDX.Core.Tests/Protobuf/v1.3/__snapshots__/SerializationTests.ProtobufRoundTripTest_valid-service-empty-objects-1.3.xml.snap b/tests/CycloneDX.Core.Tests/Protobuf/v1.3/__snapshots__/SerializationTests.ProtobufRoundTripTest_valid-service-empty-objects-1.3.xml.snap index 8632f403..2aec32a5 100644 --- a/tests/CycloneDX.Core.Tests/Protobuf/v1.3/__snapshots__/SerializationTests.ProtobufRoundTripTest_valid-service-empty-objects-1.3.xml.snap +++ b/tests/CycloneDX.Core.Tests/Protobuf/v1.3/__snapshots__/SerializationTests.ProtobufRoundTripTest_valid-service-empty-objects-1.3.xml.snap @@ -4,7 +4,6 @@ Stock ticker service - diff --git a/tests/CycloneDX.Core.Tests/Resources/v1.4/valid-properties-components-1.4.xml b/tests/CycloneDX.Core.Tests/Resources/v1.4/valid-properties-components-1.4.xml new file mode 100644 index 00000000..ea0926e4 --- /dev/null +++ b/tests/CycloneDX.Core.Tests/Resources/v1.4/valid-properties-components-1.4.xml @@ -0,0 +1,31 @@ + + + + + Bar + You + Two + Foo + + + + + acme-library + 1.0.0 + + Bar + Foo + + + + acme-sub-library + 1.0.0 + + Bar + Foo + + + + + + diff --git a/tests/CycloneDX.Core.Tests/Resources/v1.5/valid-metadata-timestamp-higher-precision-1.5.json b/tests/CycloneDX.Core.Tests/Resources/v1.5/valid-metadata-timestamp-higher-precision-1.5.json new file mode 100644 index 00000000..df9d017c --- /dev/null +++ b/tests/CycloneDX.Core.Tests/Resources/v1.5/valid-metadata-timestamp-higher-precision-1.5.json @@ -0,0 +1,10 @@ +{ + "bomFormat": "CycloneDX", + "specVersion": "1.5", + "serialNumber": "urn:uuid:3e671687-395b-41f5-a30f-a58921a69b79", + "version": 1, + "metadata": { + "timestamp": "2022-12-21T23:54:20.218381200Z" + }, + "components": [] +} diff --git a/tests/CycloneDX.Core.Tests/Xml/v1.2/__snapshots__/SerializationTests.XmlRoundTripStreamTest_valid-service-empty-objects-1.2.xml.snap b/tests/CycloneDX.Core.Tests/Xml/v1.2/__snapshots__/SerializationTests.XmlRoundTripStreamTest_valid-service-empty-objects-1.2.xml.snap index 592524ef..943d2d62 100644 --- a/tests/CycloneDX.Core.Tests/Xml/v1.2/__snapshots__/SerializationTests.XmlRoundTripStreamTest_valid-service-empty-objects-1.2.xml.snap +++ b/tests/CycloneDX.Core.Tests/Xml/v1.2/__snapshots__/SerializationTests.XmlRoundTripStreamTest_valid-service-empty-objects-1.2.xml.snap @@ -4,7 +4,6 @@ Stock ticker service - diff --git a/tests/CycloneDX.Core.Tests/Xml/v1.2/__snapshots__/SerializationTests.XmlRoundTripTest_valid-service-empty-objects-1.2.xml.snap b/tests/CycloneDX.Core.Tests/Xml/v1.2/__snapshots__/SerializationTests.XmlRoundTripTest_valid-service-empty-objects-1.2.xml.snap index 592524ef..943d2d62 100644 --- a/tests/CycloneDX.Core.Tests/Xml/v1.2/__snapshots__/SerializationTests.XmlRoundTripTest_valid-service-empty-objects-1.2.xml.snap +++ b/tests/CycloneDX.Core.Tests/Xml/v1.2/__snapshots__/SerializationTests.XmlRoundTripTest_valid-service-empty-objects-1.2.xml.snap @@ -4,7 +4,6 @@ Stock ticker service - diff --git a/tests/CycloneDX.Core.Tests/Xml/v1.3/__snapshots__/SerializationTests.XmlRoundTripStreamTest_valid-service-empty-objects-1.3.xml.snap b/tests/CycloneDX.Core.Tests/Xml/v1.3/__snapshots__/SerializationTests.XmlRoundTripStreamTest_valid-service-empty-objects-1.3.xml.snap index 8632f403..2aec32a5 100644 --- a/tests/CycloneDX.Core.Tests/Xml/v1.3/__snapshots__/SerializationTests.XmlRoundTripStreamTest_valid-service-empty-objects-1.3.xml.snap +++ b/tests/CycloneDX.Core.Tests/Xml/v1.3/__snapshots__/SerializationTests.XmlRoundTripStreamTest_valid-service-empty-objects-1.3.xml.snap @@ -4,7 +4,6 @@ Stock ticker service - diff --git a/tests/CycloneDX.Core.Tests/Xml/v1.3/__snapshots__/SerializationTests.XmlRoundTripTest_valid-service-empty-objects-1.3.xml.snap b/tests/CycloneDX.Core.Tests/Xml/v1.3/__snapshots__/SerializationTests.XmlRoundTripTest_valid-service-empty-objects-1.3.xml.snap index 8632f403..2aec32a5 100644 --- a/tests/CycloneDX.Core.Tests/Xml/v1.3/__snapshots__/SerializationTests.XmlRoundTripTest_valid-service-empty-objects-1.3.xml.snap +++ b/tests/CycloneDX.Core.Tests/Xml/v1.3/__snapshots__/SerializationTests.XmlRoundTripTest_valid-service-empty-objects-1.3.xml.snap @@ -4,7 +4,6 @@ Stock ticker service - diff --git a/tests/CycloneDX.Core.Tests/Xml/v1.4/SerializationTests.cs b/tests/CycloneDX.Core.Tests/Xml/v1.4/SerializationTests.cs index c34d8c69..b245e1fc 100644 --- a/tests/CycloneDX.Core.Tests/Xml/v1.4/SerializationTests.cs +++ b/tests/CycloneDX.Core.Tests/Xml/v1.4/SerializationTests.cs @@ -54,6 +54,7 @@ public class SerializationTests [InlineData("valid-minimal-viable-1.4.xml")] [InlineData("valid-patch-1.4.xml")] [InlineData("valid-properties-1.4.xml")] + [InlineData("valid-properties-components-1.4.xml")] // [InlineData("valid-random-attributes-1.4.xml")] [InlineData("valid-release-notes-1.4.xml")] [InlineData("valid-service-1.4.xml")] diff --git a/tests/CycloneDX.Core.Tests/Xml/v1.4/__snapshots__/SerializationTests.XmlRoundTripStreamTest_valid-evidence-1.4.xml.snap b/tests/CycloneDX.Core.Tests/Xml/v1.4/__snapshots__/SerializationTests.XmlRoundTripStreamTest_valid-evidence-1.4.xml.snap index 98aff001..1d412c45 100644 --- a/tests/CycloneDX.Core.Tests/Xml/v1.4/__snapshots__/SerializationTests.XmlRoundTripStreamTest_valid-evidence-1.4.xml.snap +++ b/tests/CycloneDX.Core.Tests/Xml/v1.4/__snapshots__/SerializationTests.XmlRoundTripStreamTest_valid-evidence-1.4.xml.snap @@ -18,6 +18,10 @@ Apache-2.0 http://www.apache.org/licenses/LICENSE-2.0 + + LGPL-2.1-only + https://opensource.org/licenses/LGPL-2.1 + Copyright 2012 Google Inc. All Rights Reserved. diff --git a/tests/CycloneDX.Core.Tests/Xml/v1.4/__snapshots__/SerializationTests.XmlRoundTripStreamTest_valid-service-empty-objects-1.4.xml.snap b/tests/CycloneDX.Core.Tests/Xml/v1.4/__snapshots__/SerializationTests.XmlRoundTripStreamTest_valid-service-empty-objects-1.4.xml.snap index 3050d63d..28f54d70 100644 --- a/tests/CycloneDX.Core.Tests/Xml/v1.4/__snapshots__/SerializationTests.XmlRoundTripStreamTest_valid-service-empty-objects-1.4.xml.snap +++ b/tests/CycloneDX.Core.Tests/Xml/v1.4/__snapshots__/SerializationTests.XmlRoundTripStreamTest_valid-service-empty-objects-1.4.xml.snap @@ -4,7 +4,6 @@ Stock ticker service - diff --git a/tests/CycloneDX.Core.Tests/Xml/v1.4/__snapshots__/SerializationTests.XmlRoundTripTest_valid-evidence-1.4.xml.snap b/tests/CycloneDX.Core.Tests/Xml/v1.4/__snapshots__/SerializationTests.XmlRoundTripTest_valid-evidence-1.4.xml.snap index 98aff001..1d412c45 100644 --- a/tests/CycloneDX.Core.Tests/Xml/v1.4/__snapshots__/SerializationTests.XmlRoundTripTest_valid-evidence-1.4.xml.snap +++ b/tests/CycloneDX.Core.Tests/Xml/v1.4/__snapshots__/SerializationTests.XmlRoundTripTest_valid-evidence-1.4.xml.snap @@ -18,6 +18,10 @@ Apache-2.0 http://www.apache.org/licenses/LICENSE-2.0 + + LGPL-2.1-only + https://opensource.org/licenses/LGPL-2.1 + Copyright 2012 Google Inc. All Rights Reserved. diff --git a/tests/CycloneDX.Core.Tests/Xml/v1.4/__snapshots__/SerializationTests.XmlRoundTripTest_valid-properties-components-1.4.xml.snap b/tests/CycloneDX.Core.Tests/Xml/v1.4/__snapshots__/SerializationTests.XmlRoundTripTest_valid-properties-components-1.4.xml.snap new file mode 100644 index 00000000..f4b7d37d --- /dev/null +++ b/tests/CycloneDX.Core.Tests/Xml/v1.4/__snapshots__/SerializationTests.XmlRoundTripTest_valid-properties-components-1.4.xml.snap @@ -0,0 +1,31 @@ + + + + + Bar + You + Two + Foo + + + + + acme-library + 1.0.0 + + Bar + Foo + + + + acme-sub-library + 1.0.0 + + Bar + Foo + + + + + + diff --git a/tests/CycloneDX.Core.Tests/Xml/v1.4/__snapshots__/SerializationTests.XmlRoundTripTest_valid-service-empty-objects-1.4.xml.snap b/tests/CycloneDX.Core.Tests/Xml/v1.4/__snapshots__/SerializationTests.XmlRoundTripTest_valid-service-empty-objects-1.4.xml.snap index 3050d63d..28f54d70 100644 --- a/tests/CycloneDX.Core.Tests/Xml/v1.4/__snapshots__/SerializationTests.XmlRoundTripTest_valid-service-empty-objects-1.4.xml.snap +++ b/tests/CycloneDX.Core.Tests/Xml/v1.4/__snapshots__/SerializationTests.XmlRoundTripTest_valid-service-empty-objects-1.4.xml.snap @@ -4,7 +4,6 @@ Stock ticker service - diff --git a/tests/CycloneDX.Core.Tests/Xml/v1.5/SerializationTests.cs b/tests/CycloneDX.Core.Tests/Xml/v1.5/SerializationTests.cs index 42bc7ed3..893369a1 100644 --- a/tests/CycloneDX.Core.Tests/Xml/v1.5/SerializationTests.cs +++ b/tests/CycloneDX.Core.Tests/Xml/v1.5/SerializationTests.cs @@ -76,7 +76,7 @@ public void XmlRoundTripTest(string filename) var bom = Serializer.Deserialize(xmlBom); xmlBom = Serializer.Serialize(bom); - File.WriteAllText("C:/temp/testedBom.xml", xmlBom.ToString()); + //File.WriteAllText("C:/temp/testedBom.xml", xmlBom.ToString()); var validationResult = Validator.Validate(xmlBom, SpecificationVersion.v1_5); diff --git a/tests/CycloneDX.Core.Tests/Xml/v1.5/ValidationTests.cs b/tests/CycloneDX.Core.Tests/Xml/v1.5/ValidationTests.cs index 1737370a..ec0b4960 100644 --- a/tests/CycloneDX.Core.Tests/Xml/v1.5/ValidationTests.cs +++ b/tests/CycloneDX.Core.Tests/Xml/v1.5/ValidationTests.cs @@ -109,5 +109,57 @@ public void InvalidXmlTest(string filename) Assert.False(validationResult.Valid); } + [Theory] + [InlineData("valid-annotation-1.5.xml")] + [InlineData("valid-assembly-1.5.xml")] + [InlineData("valid-bom-1.5.xml")] + [InlineData("valid-component-hashes-1.5.xml")] + [InlineData("valid-component-ref-1.5.xml")] + [InlineData("valid-component-swid-1.5.xml")] + [InlineData("valid-component-swid-full-1.5.xml")] + [InlineData("valid-component-types-1.5.xml")] + [InlineData("valid-compositions-1.5.xml")] + [InlineData("valid-dependency-1.5.xml")] + [InlineData("valid-empty-components-1.5.xml")] + [InlineData("valid-evidence-1.5.xml")] + [InlineData("valid-external-elements-1.5.xml")] + [InlineData("valid-external-reference-1.5.xml")] + [InlineData("valid-formulation-1.5.xml")] + [InlineData("valid-license-expression-1.5.xml")] + [InlineData("valid-license-id-1.5.xml")] + [InlineData("valid-license-licensing-1.5.xml")] + [InlineData("valid-license-name-1.5.xml")] + [InlineData("valid-machine-learning-1.5.xml")] + [InlineData("valid-metadata-author-1.5.xml")] + [InlineData("valid-metadata-license-1.5.xml")] + [InlineData("valid-metadata-lifecycle-1.5.xml")] + [InlineData("valid-metadata-manufacture-1.5.xml")] + [InlineData("valid-metadata-supplier-1.5.xml")] + [InlineData("valid-metadata-timestamp-1.5.xml")] + [InlineData("valid-metadata-tool-1.5.xml")] + [InlineData("valid-metadata-tool-deprecated-1.5.xml")] + [InlineData("valid-minimal-viable-1.5.xml")] + [InlineData("valid-patch-1.5.xml")] + [InlineData("valid-properties-1.5.xml")] + [InlineData("valid-random-attributes-1.5.xml")] + [InlineData("valid-release-notes-1.5.xml")] + [InlineData("valid-saasbom-1.5.xml")] + [InlineData("valid-service-1.5.xml")] + [InlineData("valid-service-empty-objects-1.5.xml")] + [InlineData("valid-vulnerability-1.5.xml")] + [InlineData("valid-xml-signature-1.5.xml")] + public void ValidateRoundTripTest(string filename) + { + var resourceFilename = Path.Join("Resources", "v1.5", filename); + var xmlBom = File.ReadAllText(resourceFilename); + + var bom = Serializer.Deserialize(xmlBom); + xmlBom = Serializer.Serialize(bom); + + var validationResult = Validator.Validate(xmlBom, SpecificationVersion.v1_5); + + Assert.True(validationResult.Valid, string.Join(Environment.NewLine, validationResult.Messages)); + } + } } diff --git a/tests/CycloneDX.Core.Tests/Xml/v1.5/__snapshots__/SerializationTests.XmlRoundTripStreamTest_valid-assembly-1.5.xml.snap b/tests/CycloneDX.Core.Tests/Xml/v1.5/__snapshots__/SerializationTests.XmlRoundTripStreamTest_valid-assembly-1.5.xml.snap new file mode 100644 index 00000000..8becff3e --- /dev/null +++ b/tests/CycloneDX.Core.Tests/Xml/v1.5/__snapshots__/SerializationTests.XmlRoundTripStreamTest_valid-assembly-1.5.xml.snap @@ -0,0 +1,25 @@ + + + + + acme-library-a + 1.0.0 + + + acme-library-b + 2.0.0 + + + + + + + acme-service-a + + + acme-service-b + + + + + diff --git a/tests/CycloneDX.Core.Tests/Xml/v1.5/__snapshots__/SerializationTests.XmlRoundTripStreamTest_valid-compositions-1.5.xml.snap b/tests/CycloneDX.Core.Tests/Xml/v1.5/__snapshots__/SerializationTests.XmlRoundTripStreamTest_valid-compositions-1.5.xml.snap new file mode 100644 index 00000000..f494fb3c --- /dev/null +++ b/tests/CycloneDX.Core.Tests/Xml/v1.5/__snapshots__/SerializationTests.XmlRoundTripStreamTest_valid-compositions-1.5.xml.snap @@ -0,0 +1,65 @@ + + + + + Acme Application + 1.0 + + + + + Partner Shaded Library + 1.0 + pkg:maven/partner/shaded-library@1.0 + + + Some Opensource Library + 2.0 + pkg:maven/ossproject/library@2.0 + + + + + Acme Library + 2.0 + pkg:maven/acme/library@3.0 + + + + + + + + + + + complete + + + + + + + + + unknown + + + + + + incomplete_first_party_only + + + + + + + + ACME-12345 + + Acme Inc + + + + diff --git a/tests/CycloneDX.Core.Tests/Xml/v1.5/__snapshots__/SerializationTests.XmlRoundTripStreamTest_valid-evidence-1.5.xml.snap b/tests/CycloneDX.Core.Tests/Xml/v1.5/__snapshots__/SerializationTests.XmlRoundTripStreamTest_valid-evidence-1.5.xml.snap new file mode 100644 index 00000000..6f0d3831 --- /dev/null +++ b/tests/CycloneDX.Core.Tests/Xml/v1.5/__snapshots__/SerializationTests.XmlRoundTripStreamTest_valid-evidence-1.5.xml.snap @@ -0,0 +1,92 @@ + + + + + com.google.code.findbugs + findbugs-project + 3.0.0 + + + LGPL-3.0-or-later + https://www.gnu.org/licenses/lgpl-3.0-standalone.html + + + pkg:maven/com.google.code.findbugs/findbugs-project@3.0.0 + + + purl + 1 + + + filename + 0.1 + findbugs-project-3.0.0.jar + + + ast-fingerprint + 0.9 + 61e4bc08251761c3a73b606b9110a65899cb7d44f3b14c81ebc1e67c98e1d9ab + + + hash-comparison + 0.7 + 7c547a9d67cc7bc315c93b6e2ff8e4b6b41ae5be454ac249655ecb5ca2a85abf + + + + + + + + + /path/to/component + + + /another/path/to/component + + + + + + com.apache.logging.log4j.core + Logger.class + logMessage + + com.acme.HelloWorld + Level.INFO + null + Hello World + + 150 + 17 + /path/to/log4j-core-2.14.0.jar!/org/apache/logging/log4j/core/Logger.class + + + HelloWorld.class + main + 20 + 12 + /path/to/HelloWorld.class + + + + + + Apache-2.0 + http://www.apache.org/licenses/LICENSE-2.0 + + + LGPL-2.1-only + https://opensource.org/licenses/LGPL-2.1 + + + + Copyright 2012 Google Inc. All Rights Reserved. + Copyright (C) 2004,2005 Dave Brosius <dbrosius@users.sourceforge.net> + Copyright (C) 2005 William Pugh + Copyright (C) 2004,2005 University of Maryland + + + + + diff --git a/tests/CycloneDX.Core.Tests/Xml/v1.5/__snapshots__/SerializationTests.XmlRoundTripStreamTest_valid-patch-1.5.xml.snap b/tests/CycloneDX.Core.Tests/Xml/v1.5/__snapshots__/SerializationTests.XmlRoundTripStreamTest_valid-patch-1.5.xml.snap index 969ad57b..e91a631f 100644 --- a/tests/CycloneDX.Core.Tests/Xml/v1.5/__snapshots__/SerializationTests.XmlRoundTripStreamTest_valid-patch-1.5.xml.snap +++ b/tests/CycloneDX.Core.Tests/Xml/v1.5/__snapshots__/SerializationTests.XmlRoundTripStreamTest_valid-patch-1.5.xml.snap @@ -27,7 +27,6 @@ Acme Org https://issues.acme.org/17240 - diff --git a/tests/CycloneDX.Core.Tests/Xml/v1.5/__snapshots__/SerializationTests.XmlRoundTripStreamTest_valid-release-notes-1.5.xml.snap b/tests/CycloneDX.Core.Tests/Xml/v1.5/__snapshots__/SerializationTests.XmlRoundTripStreamTest_valid-release-notes-1.5.xml.snap index 8fec55e2..70c7a77f 100644 --- a/tests/CycloneDX.Core.Tests/Xml/v1.5/__snapshots__/SerializationTests.XmlRoundTripStreamTest_valid-release-notes-1.5.xml.snap +++ b/tests/CycloneDX.Core.Tests/Xml/v1.5/__snapshots__/SerializationTests.XmlRoundTripStreamTest_valid-release-notes-1.5.xml.snap @@ -27,7 +27,6 @@ Acme Org https://issues.example.com/17240 - CVE-2019-9997 @@ -53,7 +52,6 @@ PGgxPk15IG5ldyByZWxlYXNlPGgxPgo8cD5Ob3RhcyBkZSBsYSB2ZXJzacOzbiBhcXXDrTwvcD4= - @@ -128,7 +126,6 @@ Acme Org https://issues.example.com/17240 - CVE-2019-9997 @@ -154,7 +151,6 @@ PGgxPk15IG5ldyByZWxlYXNlPGgxPgo8cD5Ob3RhcyBkZSBsYSB2ZXJzacOzbiBhcXXDrTwvcD4= - diff --git a/tests/CycloneDX.Core.Tests/Xml/v1.5/__snapshots__/SerializationTests.XmlRoundTripStreamTest_valid-service-empty-objects-1.5.xml.snap b/tests/CycloneDX.Core.Tests/Xml/v1.5/__snapshots__/SerializationTests.XmlRoundTripStreamTest_valid-service-empty-objects-1.5.xml.snap index fe043f9a..fbda86f8 100644 --- a/tests/CycloneDX.Core.Tests/Xml/v1.5/__snapshots__/SerializationTests.XmlRoundTripStreamTest_valid-service-empty-objects-1.5.xml.snap +++ b/tests/CycloneDX.Core.Tests/Xml/v1.5/__snapshots__/SerializationTests.XmlRoundTripStreamTest_valid-service-empty-objects-1.5.xml.snap @@ -4,8 +4,6 @@ Stock ticker service - - diff --git a/tests/CycloneDX.Core.Tests/Xml/v1.5/__snapshots__/SerializationTests.XmlRoundTripTest_valid-evidence-1.5.xml.snap b/tests/CycloneDX.Core.Tests/Xml/v1.5/__snapshots__/SerializationTests.XmlRoundTripTest_valid-evidence-1.5.xml.snap index 73f2d219..6f0d3831 100644 --- a/tests/CycloneDX.Core.Tests/Xml/v1.5/__snapshots__/SerializationTests.XmlRoundTripTest_valid-evidence-1.5.xml.snap +++ b/tests/CycloneDX.Core.Tests/Xml/v1.5/__snapshots__/SerializationTests.XmlRoundTripTest_valid-evidence-1.5.xml.snap @@ -71,8 +71,14 @@ - - + + Apache-2.0 + http://www.apache.org/licenses/LICENSE-2.0 + + + LGPL-2.1-only + https://opensource.org/licenses/LGPL-2.1 + Copyright 2012 Google Inc. All Rights Reserved. diff --git a/tests/CycloneDX.Core.Tests/Xml/v1.5/__snapshots__/SerializationTests.XmlRoundTripTest_valid-patch-1.5.xml.snap b/tests/CycloneDX.Core.Tests/Xml/v1.5/__snapshots__/SerializationTests.XmlRoundTripTest_valid-patch-1.5.xml.snap index 969ad57b..e91a631f 100644 --- a/tests/CycloneDX.Core.Tests/Xml/v1.5/__snapshots__/SerializationTests.XmlRoundTripTest_valid-patch-1.5.xml.snap +++ b/tests/CycloneDX.Core.Tests/Xml/v1.5/__snapshots__/SerializationTests.XmlRoundTripTest_valid-patch-1.5.xml.snap @@ -27,7 +27,6 @@ Acme Org https://issues.acme.org/17240 - diff --git a/tests/CycloneDX.Core.Tests/Xml/v1.5/__snapshots__/SerializationTests.XmlRoundTripTest_valid-release-notes-1.5.xml.snap b/tests/CycloneDX.Core.Tests/Xml/v1.5/__snapshots__/SerializationTests.XmlRoundTripTest_valid-release-notes-1.5.xml.snap index 8fec55e2..70c7a77f 100644 --- a/tests/CycloneDX.Core.Tests/Xml/v1.5/__snapshots__/SerializationTests.XmlRoundTripTest_valid-release-notes-1.5.xml.snap +++ b/tests/CycloneDX.Core.Tests/Xml/v1.5/__snapshots__/SerializationTests.XmlRoundTripTest_valid-release-notes-1.5.xml.snap @@ -27,7 +27,6 @@ Acme Org https://issues.example.com/17240 - CVE-2019-9997 @@ -53,7 +52,6 @@ PGgxPk15IG5ldyByZWxlYXNlPGgxPgo8cD5Ob3RhcyBkZSBsYSB2ZXJzacOzbiBhcXXDrTwvcD4= - @@ -128,7 +126,6 @@ Acme Org https://issues.example.com/17240 - CVE-2019-9997 @@ -154,7 +151,6 @@ PGgxPk15IG5ldyByZWxlYXNlPGgxPgo8cD5Ob3RhcyBkZSBsYSB2ZXJzacOzbiBhcXXDrTwvcD4= - diff --git a/tests/CycloneDX.Core.Tests/Xml/v1.5/__snapshots__/SerializationTests.XmlRoundTripTest_valid-service-empty-objects-1.5.xml.snap b/tests/CycloneDX.Core.Tests/Xml/v1.5/__snapshots__/SerializationTests.XmlRoundTripTest_valid-service-empty-objects-1.5.xml.snap index fe043f9a..fbda86f8 100644 --- a/tests/CycloneDX.Core.Tests/Xml/v1.5/__snapshots__/SerializationTests.XmlRoundTripTest_valid-service-empty-objects-1.5.xml.snap +++ b/tests/CycloneDX.Core.Tests/Xml/v1.5/__snapshots__/SerializationTests.XmlRoundTripTest_valid-service-empty-objects-1.5.xml.snap @@ -4,8 +4,6 @@ Stock ticker service - - diff --git a/tests/CycloneDX.Core.Tests/Xml/v1.6/SerializationTests.cs b/tests/CycloneDX.Core.Tests/Xml/v1.6/SerializationTests.cs index 8436070e..b91c2ab9 100644 --- a/tests/CycloneDX.Core.Tests/Xml/v1.6/SerializationTests.cs +++ b/tests/CycloneDX.Core.Tests/Xml/v1.6/SerializationTests.cs @@ -86,7 +86,7 @@ public void XmlRoundTripTest(string filename) - File.WriteAllText("C:/temp/testedBom.xml", xmlBom.ToString()); + //File.WriteAllText("C:/temp/testedBom.xml", xmlBom.ToString()); var validationResult = Validator.Validate(xmlBom, SpecificationVersion.v1_6); Assert.True(validationResult.Valid, validationResult.Messages?.FirstOrDefault()); @@ -209,7 +209,7 @@ public void XmlDowngradeTest(string filename) xmlBom = Serializer.Serialize(bom); - File.WriteAllText("C:/temp/testedBom.xml", xmlBom.ToString()); + //File.WriteAllText("C:/temp/testedBom.xml", xmlBom.ToString()); var result = Validator.Validate(xmlBom, SpecificationVersion.v1_5); Assert.True(result.Valid, $"BOM version downgrade failed validation: Validation failed: {result}"); diff --git a/tests/CycloneDX.Core.Tests/Xml/v1.6/__snapshots__/SerializationTests.XmlRoundTripStreamTest_valid-evidence-1.6.xml.snap b/tests/CycloneDX.Core.Tests/Xml/v1.6/__snapshots__/SerializationTests.XmlRoundTripStreamTest_valid-evidence-1.6.xml.snap index 533dd1af..33780ede 100644 --- a/tests/CycloneDX.Core.Tests/Xml/v1.6/__snapshots__/SerializationTests.XmlRoundTripStreamTest_valid-evidence-1.6.xml.snap +++ b/tests/CycloneDX.Core.Tests/Xml/v1.6/__snapshots__/SerializationTests.XmlRoundTripStreamTest_valid-evidence-1.6.xml.snap @@ -75,6 +75,10 @@ Apache-2.0 http://www.apache.org/licenses/LICENSE-2.0 + + LGPL-2.1-only + https://opensource.org/licenses/LGPL-2.1 + Copyright 2012 Google Inc. All Rights Reserved. diff --git a/tests/CycloneDX.Core.Tests/Xml/v1.6/__snapshots__/SerializationTests.XmlRoundTripStreamTest_valid-metadata-license-1.6.xml.snap b/tests/CycloneDX.Core.Tests/Xml/v1.6/__snapshots__/SerializationTests.XmlRoundTripStreamTest_valid-metadata-license-1.6.xml.snap index 23f9cb5c..a74dc7a6 100644 --- a/tests/CycloneDX.Core.Tests/Xml/v1.6/__snapshots__/SerializationTests.XmlRoundTripStreamTest_valid-metadata-license-1.6.xml.snap +++ b/tests/CycloneDX.Core.Tests/Xml/v1.6/__snapshots__/SerializationTests.XmlRoundTripStreamTest_valid-metadata-license-1.6.xml.snap @@ -5,6 +5,10 @@ Apache-2.0 + + My License + My License Text + diff --git a/tests/CycloneDX.Core.Tests/Xml/v1.6/__snapshots__/SerializationTests.XmlRoundTripStreamTest_valid-service-empty-objects-1.6.xml.snap b/tests/CycloneDX.Core.Tests/Xml/v1.6/__snapshots__/SerializationTests.XmlRoundTripStreamTest_valid-service-empty-objects-1.6.xml.snap index 85f66cc6..ffd02878 100644 --- a/tests/CycloneDX.Core.Tests/Xml/v1.6/__snapshots__/SerializationTests.XmlRoundTripStreamTest_valid-service-empty-objects-1.6.xml.snap +++ b/tests/CycloneDX.Core.Tests/Xml/v1.6/__snapshots__/SerializationTests.XmlRoundTripStreamTest_valid-service-empty-objects-1.6.xml.snap @@ -5,7 +5,6 @@ Stock ticker service - diff --git a/tests/CycloneDX.Core.Tests/Xml/v1.6/__snapshots__/SerializationTests.XmlRoundTripTest_valid-evidence-1.6.xml.snap b/tests/CycloneDX.Core.Tests/Xml/v1.6/__snapshots__/SerializationTests.XmlRoundTripTest_valid-evidence-1.6.xml.snap index 533dd1af..33780ede 100644 --- a/tests/CycloneDX.Core.Tests/Xml/v1.6/__snapshots__/SerializationTests.XmlRoundTripTest_valid-evidence-1.6.xml.snap +++ b/tests/CycloneDX.Core.Tests/Xml/v1.6/__snapshots__/SerializationTests.XmlRoundTripTest_valid-evidence-1.6.xml.snap @@ -75,6 +75,10 @@ Apache-2.0 http://www.apache.org/licenses/LICENSE-2.0 + + LGPL-2.1-only + https://opensource.org/licenses/LGPL-2.1 + Copyright 2012 Google Inc. All Rights Reserved. diff --git a/tests/CycloneDX.Core.Tests/Xml/v1.6/__snapshots__/SerializationTests.XmlRoundTripTest_valid-metadata-license-1.6.xml.snap b/tests/CycloneDX.Core.Tests/Xml/v1.6/__snapshots__/SerializationTests.XmlRoundTripTest_valid-metadata-license-1.6.xml.snap index 23f9cb5c..a74dc7a6 100644 --- a/tests/CycloneDX.Core.Tests/Xml/v1.6/__snapshots__/SerializationTests.XmlRoundTripTest_valid-metadata-license-1.6.xml.snap +++ b/tests/CycloneDX.Core.Tests/Xml/v1.6/__snapshots__/SerializationTests.XmlRoundTripTest_valid-metadata-license-1.6.xml.snap @@ -5,6 +5,10 @@ Apache-2.0 + + My License + My License Text + diff --git a/tests/CycloneDX.Core.Tests/Xml/v1.6/__snapshots__/SerializationTests.XmlRoundTripTest_valid-service-empty-objects-1.6.xml.snap b/tests/CycloneDX.Core.Tests/Xml/v1.6/__snapshots__/SerializationTests.XmlRoundTripTest_valid-service-empty-objects-1.6.xml.snap index 85f66cc6..ffd02878 100644 --- a/tests/CycloneDX.Core.Tests/Xml/v1.6/__snapshots__/SerializationTests.XmlRoundTripTest_valid-service-empty-objects-1.6.xml.snap +++ b/tests/CycloneDX.Core.Tests/Xml/v1.6/__snapshots__/SerializationTests.XmlRoundTripTest_valid-service-empty-objects-1.6.xml.snap @@ -5,7 +5,6 @@ Stock ticker service - diff --git a/tests/CycloneDX.Spdx.Interop.Tests/CycloneDX.Spdx.Interop.Tests.csproj b/tests/CycloneDX.Spdx.Interop.Tests/CycloneDX.Spdx.Interop.Tests.csproj index 3b54b3c8..02c103d1 100644 --- a/tests/CycloneDX.Spdx.Interop.Tests/CycloneDX.Spdx.Interop.Tests.csproj +++ b/tests/CycloneDX.Spdx.Interop.Tests/CycloneDX.Spdx.Interop.Tests.csproj @@ -1,33 +1,33 @@ - - - - net6 - - false - - - - - - - - runtime; build; native; contentfiles; analyzers; buildtransitive - all - - - runtime; build; native; contentfiles; analyzers; buildtransitive - all - - - - - - - - - - - - - - + + + + net6 + + false + + + + + + + + runtime; build; native; contentfiles; analyzers; buildtransitive + all + + + runtime; build; native; contentfiles; analyzers; buildtransitive + all + + + + + + + + + + + + + + diff --git a/tests/CycloneDX.Spdx.Interop.Tests/__snapshots__/ConverterTests.FromCDXToSpdxToCDXRoundTripTest_assembly.snap b/tests/CycloneDX.Spdx.Interop.Tests/__snapshots__/ConverterTests.FromCDXToSpdxToCDXRoundTripTest_assembly.snap index c1bf746f..6db3981b 100644 --- a/tests/CycloneDX.Spdx.Interop.Tests/__snapshots__/ConverterTests.FromCDXToSpdxToCDXRoundTripTest_assembly.snap +++ b/tests/CycloneDX.Spdx.Interop.Tests/__snapshots__/ConverterTests.FromCDXToSpdxToCDXRoundTripTest_assembly.snap @@ -1,6 +1,6 @@ { "bomFormat": "CycloneDX", - "specVersion": "1.5", + "specVersion": "1.6", "metadata": { "timestamp": "2021-12-24T12:00:00Z", "properties": [ diff --git a/tests/CycloneDX.Spdx.Interop.Tests/__snapshots__/ConverterTests.FromCDXToSpdxToCDXRoundTripTest_bom.snap b/tests/CycloneDX.Spdx.Interop.Tests/__snapshots__/ConverterTests.FromCDXToSpdxToCDXRoundTripTest_bom.snap index 5df37b42..998c892b 100644 --- a/tests/CycloneDX.Spdx.Interop.Tests/__snapshots__/ConverterTests.FromCDXToSpdxToCDXRoundTripTest_bom.snap +++ b/tests/CycloneDX.Spdx.Interop.Tests/__snapshots__/ConverterTests.FromCDXToSpdxToCDXRoundTripTest_bom.snap @@ -1,6 +1,6 @@ { "bomFormat": "CycloneDX", - "specVersion": "1.5", + "specVersion": "1.6", "metadata": { "timestamp": "2020-04-13T20:20:39Z", "tools": [ diff --git a/tests/CycloneDX.Spdx.Interop.Tests/__snapshots__/ConverterTests.FromCDXToSpdxToCDXRoundTripTest_component-hashes.snap b/tests/CycloneDX.Spdx.Interop.Tests/__snapshots__/ConverterTests.FromCDXToSpdxToCDXRoundTripTest_component-hashes.snap index 4ef8bc75..72d2b766 100644 --- a/tests/CycloneDX.Spdx.Interop.Tests/__snapshots__/ConverterTests.FromCDXToSpdxToCDXRoundTripTest_component-hashes.snap +++ b/tests/CycloneDX.Spdx.Interop.Tests/__snapshots__/ConverterTests.FromCDXToSpdxToCDXRoundTripTest_component-hashes.snap @@ -1,6 +1,6 @@ { "bomFormat": "CycloneDX", - "specVersion": "1.5", + "specVersion": "1.6", "metadata": { "timestamp": "2021-12-24T12:00:00Z", "properties": [ diff --git a/tests/CycloneDX.Spdx.Interop.Tests/__snapshots__/ConverterTests.FromCDXToSpdxToCDXRoundTripTest_component-ref.snap b/tests/CycloneDX.Spdx.Interop.Tests/__snapshots__/ConverterTests.FromCDXToSpdxToCDXRoundTripTest_component-ref.snap index 5886406b..0ae7e375 100644 --- a/tests/CycloneDX.Spdx.Interop.Tests/__snapshots__/ConverterTests.FromCDXToSpdxToCDXRoundTripTest_component-ref.snap +++ b/tests/CycloneDX.Spdx.Interop.Tests/__snapshots__/ConverterTests.FromCDXToSpdxToCDXRoundTripTest_component-ref.snap @@ -1,6 +1,6 @@ { "bomFormat": "CycloneDX", - "specVersion": "1.5", + "specVersion": "1.6", "metadata": { "timestamp": "2021-12-24T12:00:00Z", "properties": [ diff --git a/tests/CycloneDX.Spdx.Interop.Tests/__snapshots__/ConverterTests.FromCDXToSpdxToCDXRoundTripTest_component-swid-full.snap b/tests/CycloneDX.Spdx.Interop.Tests/__snapshots__/ConverterTests.FromCDXToSpdxToCDXRoundTripTest_component-swid-full.snap index 833df6df..defab87e 100644 --- a/tests/CycloneDX.Spdx.Interop.Tests/__snapshots__/ConverterTests.FromCDXToSpdxToCDXRoundTripTest_component-swid-full.snap +++ b/tests/CycloneDX.Spdx.Interop.Tests/__snapshots__/ConverterTests.FromCDXToSpdxToCDXRoundTripTest_component-swid-full.snap @@ -1,6 +1,6 @@ { "bomFormat": "CycloneDX", - "specVersion": "1.5", + "specVersion": "1.6", "metadata": { "timestamp": "2021-12-24T12:00:00Z", "properties": [ diff --git a/tests/CycloneDX.Spdx.Interop.Tests/__snapshots__/ConverterTests.FromCDXToSpdxToCDXRoundTripTest_component-swid.snap b/tests/CycloneDX.Spdx.Interop.Tests/__snapshots__/ConverterTests.FromCDXToSpdxToCDXRoundTripTest_component-swid.snap index 833df6df..defab87e 100644 --- a/tests/CycloneDX.Spdx.Interop.Tests/__snapshots__/ConverterTests.FromCDXToSpdxToCDXRoundTripTest_component-swid.snap +++ b/tests/CycloneDX.Spdx.Interop.Tests/__snapshots__/ConverterTests.FromCDXToSpdxToCDXRoundTripTest_component-swid.snap @@ -1,6 +1,6 @@ { "bomFormat": "CycloneDX", - "specVersion": "1.5", + "specVersion": "1.6", "metadata": { "timestamp": "2021-12-24T12:00:00Z", "properties": [ diff --git a/tests/CycloneDX.Spdx.Interop.Tests/__snapshots__/ConverterTests.FromCDXToSpdxToCDXRoundTripTest_component-types.snap b/tests/CycloneDX.Spdx.Interop.Tests/__snapshots__/ConverterTests.FromCDXToSpdxToCDXRoundTripTest_component-types.snap index b34ba3bc..c41fa5f6 100644 --- a/tests/CycloneDX.Spdx.Interop.Tests/__snapshots__/ConverterTests.FromCDXToSpdxToCDXRoundTripTest_component-types.snap +++ b/tests/CycloneDX.Spdx.Interop.Tests/__snapshots__/ConverterTests.FromCDXToSpdxToCDXRoundTripTest_component-types.snap @@ -1,6 +1,6 @@ { "bomFormat": "CycloneDX", - "specVersion": "1.5", + "specVersion": "1.6", "metadata": { "timestamp": "2021-12-24T12:00:00Z", "properties": [ diff --git a/tests/CycloneDX.Spdx.Interop.Tests/__snapshots__/ConverterTests.FromCDXToSpdxToCDXRoundTripTest_compositions.snap b/tests/CycloneDX.Spdx.Interop.Tests/__snapshots__/ConverterTests.FromCDXToSpdxToCDXRoundTripTest_compositions.snap index fa4b7425..96262181 100644 --- a/tests/CycloneDX.Spdx.Interop.Tests/__snapshots__/ConverterTests.FromCDXToSpdxToCDXRoundTripTest_compositions.snap +++ b/tests/CycloneDX.Spdx.Interop.Tests/__snapshots__/ConverterTests.FromCDXToSpdxToCDXRoundTripTest_compositions.snap @@ -1,6 +1,6 @@ { "bomFormat": "CycloneDX", - "specVersion": "1.5", + "specVersion": "1.6", "metadata": { "timestamp": "2021-12-24T12:00:00Z", "properties": [ diff --git a/tests/CycloneDX.Spdx.Interop.Tests/__snapshots__/ConverterTests.FromCDXToSpdxToCDXRoundTripTest_dependency.snap b/tests/CycloneDX.Spdx.Interop.Tests/__snapshots__/ConverterTests.FromCDXToSpdxToCDXRoundTripTest_dependency.snap index 0bde22f7..7bada5ff 100644 --- a/tests/CycloneDX.Spdx.Interop.Tests/__snapshots__/ConverterTests.FromCDXToSpdxToCDXRoundTripTest_dependency.snap +++ b/tests/CycloneDX.Spdx.Interop.Tests/__snapshots__/ConverterTests.FromCDXToSpdxToCDXRoundTripTest_dependency.snap @@ -1,6 +1,6 @@ { "bomFormat": "CycloneDX", - "specVersion": "1.5", + "specVersion": "1.6", "metadata": { "timestamp": "2021-12-24T12:00:00Z", "properties": [ diff --git a/tests/CycloneDX.Spdx.Interop.Tests/__snapshots__/ConverterTests.FromCDXToSpdxToCDXRoundTripTest_empty-components.snap b/tests/CycloneDX.Spdx.Interop.Tests/__snapshots__/ConverterTests.FromCDXToSpdxToCDXRoundTripTest_empty-components.snap index 4db24d4e..ce58aaa2 100644 --- a/tests/CycloneDX.Spdx.Interop.Tests/__snapshots__/ConverterTests.FromCDXToSpdxToCDXRoundTripTest_empty-components.snap +++ b/tests/CycloneDX.Spdx.Interop.Tests/__snapshots__/ConverterTests.FromCDXToSpdxToCDXRoundTripTest_empty-components.snap @@ -1,6 +1,6 @@ { "bomFormat": "CycloneDX", - "specVersion": "1.5", + "specVersion": "1.6", "metadata": { "timestamp": "2021-12-24T12:00:00Z", "properties": [ diff --git a/tests/CycloneDX.Spdx.Interop.Tests/__snapshots__/ConverterTests.FromCDXToSpdxToCDXRoundTripTest_evidence.snap b/tests/CycloneDX.Spdx.Interop.Tests/__snapshots__/ConverterTests.FromCDXToSpdxToCDXRoundTripTest_evidence.snap index 722cff14..1978fa7b 100644 --- a/tests/CycloneDX.Spdx.Interop.Tests/__snapshots__/ConverterTests.FromCDXToSpdxToCDXRoundTripTest_evidence.snap +++ b/tests/CycloneDX.Spdx.Interop.Tests/__snapshots__/ConverterTests.FromCDXToSpdxToCDXRoundTripTest_evidence.snap @@ -1,6 +1,6 @@ { "bomFormat": "CycloneDX", - "specVersion": "1.5", + "specVersion": "1.6", "metadata": { "timestamp": "2021-12-24T12:00:00Z", "properties": [ diff --git a/tests/CycloneDX.Spdx.Interop.Tests/__snapshots__/ConverterTests.FromCDXToSpdxToCDXRoundTripTest_external-reference.snap b/tests/CycloneDX.Spdx.Interop.Tests/__snapshots__/ConverterTests.FromCDXToSpdxToCDXRoundTripTest_external-reference.snap index 429ffa00..63afee4a 100644 --- a/tests/CycloneDX.Spdx.Interop.Tests/__snapshots__/ConverterTests.FromCDXToSpdxToCDXRoundTripTest_external-reference.snap +++ b/tests/CycloneDX.Spdx.Interop.Tests/__snapshots__/ConverterTests.FromCDXToSpdxToCDXRoundTripTest_external-reference.snap @@ -1,6 +1,6 @@ { "bomFormat": "CycloneDX", - "specVersion": "1.5", + "specVersion": "1.6", "metadata": { "timestamp": "2021-12-24T12:00:00Z", "properties": [ diff --git a/tests/CycloneDX.Spdx.Interop.Tests/__snapshots__/ConverterTests.FromCDXToSpdxToCDXRoundTripTest_license-expression.snap b/tests/CycloneDX.Spdx.Interop.Tests/__snapshots__/ConverterTests.FromCDXToSpdxToCDXRoundTripTest_license-expression.snap index 7658e8e1..ebb7a639 100644 --- a/tests/CycloneDX.Spdx.Interop.Tests/__snapshots__/ConverterTests.FromCDXToSpdxToCDXRoundTripTest_license-expression.snap +++ b/tests/CycloneDX.Spdx.Interop.Tests/__snapshots__/ConverterTests.FromCDXToSpdxToCDXRoundTripTest_license-expression.snap @@ -1,6 +1,6 @@ { "bomFormat": "CycloneDX", - "specVersion": "1.5", + "specVersion": "1.6", "metadata": { "timestamp": "2021-12-24T12:00:00Z", "properties": [ diff --git a/tests/CycloneDX.Spdx.Interop.Tests/__snapshots__/ConverterTests.FromCDXToSpdxToCDXRoundTripTest_license-id.snap b/tests/CycloneDX.Spdx.Interop.Tests/__snapshots__/ConverterTests.FromCDXToSpdxToCDXRoundTripTest_license-id.snap index bf3e0762..8aec8085 100644 --- a/tests/CycloneDX.Spdx.Interop.Tests/__snapshots__/ConverterTests.FromCDXToSpdxToCDXRoundTripTest_license-id.snap +++ b/tests/CycloneDX.Spdx.Interop.Tests/__snapshots__/ConverterTests.FromCDXToSpdxToCDXRoundTripTest_license-id.snap @@ -1,6 +1,6 @@ { "bomFormat": "CycloneDX", - "specVersion": "1.5", + "specVersion": "1.6", "metadata": { "timestamp": "2021-12-24T12:00:00Z", "properties": [ diff --git a/tests/CycloneDX.Spdx.Interop.Tests/__snapshots__/ConverterTests.FromCDXToSpdxToCDXRoundTripTest_license-name.snap b/tests/CycloneDX.Spdx.Interop.Tests/__snapshots__/ConverterTests.FromCDXToSpdxToCDXRoundTripTest_license-name.snap index fe530f55..9e3615e2 100644 --- a/tests/CycloneDX.Spdx.Interop.Tests/__snapshots__/ConverterTests.FromCDXToSpdxToCDXRoundTripTest_license-name.snap +++ b/tests/CycloneDX.Spdx.Interop.Tests/__snapshots__/ConverterTests.FromCDXToSpdxToCDXRoundTripTest_license-name.snap @@ -1,6 +1,6 @@ { "bomFormat": "CycloneDX", - "specVersion": "1.5", + "specVersion": "1.6", "metadata": { "timestamp": "2021-12-24T12:00:00Z", "properties": [ diff --git a/tests/CycloneDX.Spdx.Interop.Tests/__snapshots__/ConverterTests.FromCDXToSpdxToCDXRoundTripTest_metadata-author.snap b/tests/CycloneDX.Spdx.Interop.Tests/__snapshots__/ConverterTests.FromCDXToSpdxToCDXRoundTripTest_metadata-author.snap index 02236c30..2f838ba7 100644 --- a/tests/CycloneDX.Spdx.Interop.Tests/__snapshots__/ConverterTests.FromCDXToSpdxToCDXRoundTripTest_metadata-author.snap +++ b/tests/CycloneDX.Spdx.Interop.Tests/__snapshots__/ConverterTests.FromCDXToSpdxToCDXRoundTripTest_metadata-author.snap @@ -1,6 +1,6 @@ { "bomFormat": "CycloneDX", - "specVersion": "1.5", + "specVersion": "1.6", "metadata": { "timestamp": "2021-12-24T12:00:00Z", "authors": [ diff --git a/tests/CycloneDX.Spdx.Interop.Tests/__snapshots__/ConverterTests.FromCDXToSpdxToCDXRoundTripTest_metadata-license.snap b/tests/CycloneDX.Spdx.Interop.Tests/__snapshots__/ConverterTests.FromCDXToSpdxToCDXRoundTripTest_metadata-license.snap index 4db24d4e..ce58aaa2 100644 --- a/tests/CycloneDX.Spdx.Interop.Tests/__snapshots__/ConverterTests.FromCDXToSpdxToCDXRoundTripTest_metadata-license.snap +++ b/tests/CycloneDX.Spdx.Interop.Tests/__snapshots__/ConverterTests.FromCDXToSpdxToCDXRoundTripTest_metadata-license.snap @@ -1,6 +1,6 @@ { "bomFormat": "CycloneDX", - "specVersion": "1.5", + "specVersion": "1.6", "metadata": { "timestamp": "2021-12-24T12:00:00Z", "properties": [ diff --git a/tests/CycloneDX.Spdx.Interop.Tests/__snapshots__/ConverterTests.FromCDXToSpdxToCDXRoundTripTest_metadata-manufacture.snap b/tests/CycloneDX.Spdx.Interop.Tests/__snapshots__/ConverterTests.FromCDXToSpdxToCDXRoundTripTest_metadata-manufacture.snap index 4db24d4e..ce58aaa2 100644 --- a/tests/CycloneDX.Spdx.Interop.Tests/__snapshots__/ConverterTests.FromCDXToSpdxToCDXRoundTripTest_metadata-manufacture.snap +++ b/tests/CycloneDX.Spdx.Interop.Tests/__snapshots__/ConverterTests.FromCDXToSpdxToCDXRoundTripTest_metadata-manufacture.snap @@ -1,6 +1,6 @@ { "bomFormat": "CycloneDX", - "specVersion": "1.5", + "specVersion": "1.6", "metadata": { "timestamp": "2021-12-24T12:00:00Z", "properties": [ diff --git a/tests/CycloneDX.Spdx.Interop.Tests/__snapshots__/ConverterTests.FromCDXToSpdxToCDXRoundTripTest_metadata-supplier.snap b/tests/CycloneDX.Spdx.Interop.Tests/__snapshots__/ConverterTests.FromCDXToSpdxToCDXRoundTripTest_metadata-supplier.snap index 4db24d4e..ce58aaa2 100644 --- a/tests/CycloneDX.Spdx.Interop.Tests/__snapshots__/ConverterTests.FromCDXToSpdxToCDXRoundTripTest_metadata-supplier.snap +++ b/tests/CycloneDX.Spdx.Interop.Tests/__snapshots__/ConverterTests.FromCDXToSpdxToCDXRoundTripTest_metadata-supplier.snap @@ -1,6 +1,6 @@ { "bomFormat": "CycloneDX", - "specVersion": "1.5", + "specVersion": "1.6", "metadata": { "timestamp": "2021-12-24T12:00:00Z", "properties": [ diff --git a/tests/CycloneDX.Spdx.Interop.Tests/__snapshots__/ConverterTests.FromCDXToSpdxToCDXRoundTripTest_metadata-timestamp.snap b/tests/CycloneDX.Spdx.Interop.Tests/__snapshots__/ConverterTests.FromCDXToSpdxToCDXRoundTripTest_metadata-timestamp.snap index 97687ff7..acffd1e5 100644 --- a/tests/CycloneDX.Spdx.Interop.Tests/__snapshots__/ConverterTests.FromCDXToSpdxToCDXRoundTripTest_metadata-timestamp.snap +++ b/tests/CycloneDX.Spdx.Interop.Tests/__snapshots__/ConverterTests.FromCDXToSpdxToCDXRoundTripTest_metadata-timestamp.snap @@ -1,6 +1,6 @@ { "bomFormat": "CycloneDX", - "specVersion": "1.5", + "specVersion": "1.6", "metadata": { "timestamp": "2020-04-13T20:20:39Z", "properties": [ diff --git a/tests/CycloneDX.Spdx.Interop.Tests/__snapshots__/ConverterTests.FromCDXToSpdxToCDXRoundTripTest_metadata-tool.snap b/tests/CycloneDX.Spdx.Interop.Tests/__snapshots__/ConverterTests.FromCDXToSpdxToCDXRoundTripTest_metadata-tool.snap index 7deaebf9..ab653b43 100644 --- a/tests/CycloneDX.Spdx.Interop.Tests/__snapshots__/ConverterTests.FromCDXToSpdxToCDXRoundTripTest_metadata-tool.snap +++ b/tests/CycloneDX.Spdx.Interop.Tests/__snapshots__/ConverterTests.FromCDXToSpdxToCDXRoundTripTest_metadata-tool.snap @@ -1,6 +1,6 @@ { "bomFormat": "CycloneDX", - "specVersion": "1.5", + "specVersion": "1.6", "metadata": { "timestamp": "2021-12-24T12:00:00Z", "tools": [ diff --git a/tests/CycloneDX.Spdx.Interop.Tests/__snapshots__/ConverterTests.FromCDXToSpdxToCDXRoundTripTest_minimal-viable.snap b/tests/CycloneDX.Spdx.Interop.Tests/__snapshots__/ConverterTests.FromCDXToSpdxToCDXRoundTripTest_minimal-viable.snap index 6960b203..7b97d207 100644 --- a/tests/CycloneDX.Spdx.Interop.Tests/__snapshots__/ConverterTests.FromCDXToSpdxToCDXRoundTripTest_minimal-viable.snap +++ b/tests/CycloneDX.Spdx.Interop.Tests/__snapshots__/ConverterTests.FromCDXToSpdxToCDXRoundTripTest_minimal-viable.snap @@ -1,6 +1,6 @@ { "bomFormat": "CycloneDX", - "specVersion": "1.5", + "specVersion": "1.6", "metadata": { "timestamp": "2021-12-24T12:00:00Z", "properties": [ diff --git a/tests/CycloneDX.Spdx.Interop.Tests/__snapshots__/ConverterTests.FromCDXToSpdxToCDXRoundTripTest_patch.snap b/tests/CycloneDX.Spdx.Interop.Tests/__snapshots__/ConverterTests.FromCDXToSpdxToCDXRoundTripTest_patch.snap index b4d2b6a4..6ee97859 100644 --- a/tests/CycloneDX.Spdx.Interop.Tests/__snapshots__/ConverterTests.FromCDXToSpdxToCDXRoundTripTest_patch.snap +++ b/tests/CycloneDX.Spdx.Interop.Tests/__snapshots__/ConverterTests.FromCDXToSpdxToCDXRoundTripTest_patch.snap @@ -1,6 +1,6 @@ { "bomFormat": "CycloneDX", - "specVersion": "1.5", + "specVersion": "1.6", "metadata": { "timestamp": "2021-12-24T12:00:00Z", "properties": [ diff --git a/tests/CycloneDX.Spdx.Interop.Tests/__snapshots__/ConverterTests.FromCDXToSpdxToCDXRoundTripTest_properties.snap b/tests/CycloneDX.Spdx.Interop.Tests/__snapshots__/ConverterTests.FromCDXToSpdxToCDXRoundTripTest_properties.snap index 6960b203..7b97d207 100644 --- a/tests/CycloneDX.Spdx.Interop.Tests/__snapshots__/ConverterTests.FromCDXToSpdxToCDXRoundTripTest_properties.snap +++ b/tests/CycloneDX.Spdx.Interop.Tests/__snapshots__/ConverterTests.FromCDXToSpdxToCDXRoundTripTest_properties.snap @@ -1,6 +1,6 @@ { "bomFormat": "CycloneDX", - "specVersion": "1.5", + "specVersion": "1.6", "metadata": { "timestamp": "2021-12-24T12:00:00Z", "properties": [ diff --git a/tests/CycloneDX.Spdx.Interop.Tests/__snapshots__/ConverterTests.FromCDXToSpdxToCDXRoundTripTest_service-empty-objects.snap b/tests/CycloneDX.Spdx.Interop.Tests/__snapshots__/ConverterTests.FromCDXToSpdxToCDXRoundTripTest_service-empty-objects.snap index 4db24d4e..ce58aaa2 100644 --- a/tests/CycloneDX.Spdx.Interop.Tests/__snapshots__/ConverterTests.FromCDXToSpdxToCDXRoundTripTest_service-empty-objects.snap +++ b/tests/CycloneDX.Spdx.Interop.Tests/__snapshots__/ConverterTests.FromCDXToSpdxToCDXRoundTripTest_service-empty-objects.snap @@ -1,6 +1,6 @@ { "bomFormat": "CycloneDX", - "specVersion": "1.5", + "specVersion": "1.6", "metadata": { "timestamp": "2021-12-24T12:00:00Z", "properties": [ diff --git a/tests/CycloneDX.Spdx.Interop.Tests/__snapshots__/ConverterTests.FromCDXToSpdxToCDXRoundTripTest_service.snap b/tests/CycloneDX.Spdx.Interop.Tests/__snapshots__/ConverterTests.FromCDXToSpdxToCDXRoundTripTest_service.snap index 13faf2de..01643775 100644 --- a/tests/CycloneDX.Spdx.Interop.Tests/__snapshots__/ConverterTests.FromCDXToSpdxToCDXRoundTripTest_service.snap +++ b/tests/CycloneDX.Spdx.Interop.Tests/__snapshots__/ConverterTests.FromCDXToSpdxToCDXRoundTripTest_service.snap @@ -1,6 +1,6 @@ { "bomFormat": "CycloneDX", - "specVersion": "1.5", + "specVersion": "1.6", "metadata": { "timestamp": "2021-12-24T12:00:00Z", "properties": [ diff --git a/tests/CycloneDX.Spdx.Interop.Tests/__snapshots__/ConverterTests.FromSpdxToCDXTest_document.snap b/tests/CycloneDX.Spdx.Interop.Tests/__snapshots__/ConverterTests.FromSpdxToCDXTest_document.snap index a4d208b3..db0d6abd 100644 --- a/tests/CycloneDX.Spdx.Interop.Tests/__snapshots__/ConverterTests.FromSpdxToCDXTest_document.snap +++ b/tests/CycloneDX.Spdx.Interop.Tests/__snapshots__/ConverterTests.FromSpdxToCDXTest_document.snap @@ -1,6 +1,6 @@ { "bomFormat": "CycloneDX", - "specVersion": "1.5", + "specVersion": "1.6", "metadata": { "timestamp": "2010-01-29T18:30:22Z", "tools": [ diff --git a/tests/CycloneDX.Spdx.Tests/CycloneDX.Spdx.Tests.csproj b/tests/CycloneDX.Spdx.Tests/CycloneDX.Spdx.Tests.csproj index 8d3896a4..6a055336 100644 --- a/tests/CycloneDX.Spdx.Tests/CycloneDX.Spdx.Tests.csproj +++ b/tests/CycloneDX.Spdx.Tests/CycloneDX.Spdx.Tests.csproj @@ -1,36 +1,36 @@ - - - - net6 - - false - - - - - - - - runtime; build; native; contentfiles; analyzers; buildtransitive - all - - - runtime; build; native; contentfiles; analyzers; buildtransitive - all - - - - - - - - - - - - - - - - - + + + + net6 + + false + + + + + + + + runtime; build; native; contentfiles; analyzers; buildtransitive + all + + + runtime; build; native; contentfiles; analyzers; buildtransitive + all + + + + + + + + + + + + + + + + + diff --git a/tests/CycloneDX.Utils.Tests/CycloneDX.Utils.Tests.csproj b/tests/CycloneDX.Utils.Tests/CycloneDX.Utils.Tests.csproj index 6fd75c66..7ccb06c6 100644 --- a/tests/CycloneDX.Utils.Tests/CycloneDX.Utils.Tests.csproj +++ b/tests/CycloneDX.Utils.Tests/CycloneDX.Utils.Tests.csproj @@ -1,28 +1,28 @@ - - - - net6 - - false - - - - - - - - runtime; build; native; contentfiles; analyzers; buildtransitive - all - - - runtime; build; native; contentfiles; analyzers; buildtransitive - all - - - - - - - - - + + + + net6 + + false + + + + + + + + runtime; build; native; contentfiles; analyzers; buildtransitive + all + + + runtime; build; native; contentfiles; analyzers; buildtransitive + all + + + + + + + + + diff --git a/tests/CycloneDX.Utils.Tests/MergeTests.cs b/tests/CycloneDX.Utils.Tests/MergeTests.cs index 7564ff18..c559e18f 100644 --- a/tests/CycloneDX.Utils.Tests/MergeTests.cs +++ b/tests/CycloneDX.Utils.Tests/MergeTests.cs @@ -105,6 +105,31 @@ public void FlatMergeComponentsTest() Snapshot.Match(result); } + [Fact] + public void FlatMergeDuplicatedComponentsTest() + { + var sboms = new List(); + for (int i = 0; i < 3; i++) + { + var bom = new Bom + { + Components = new List + { + new Component + { + Name = "Component1", + Version = "1" + } + } + }; + sboms.Add(bom); + } + var result = CycloneDXUtils.FlatMerge(sboms); + + Assert.Single(result.Components); + } + + [Fact] public void FlatMergeVulnerabilitiesTest() { @@ -263,6 +288,222 @@ public void HierarchicalMergeComponentsTest() Snapshot.Match(result); } + [Fact] + public void HierarchicalMergeToolsComponentsTest() + { + var subject = new Component + { + Name = "Thing", + Version = "1", + }; + + var sbom1 = new Bom + { + Metadata = new Metadata + { + Component = new Component + { + Name = "System1", + Version = "1", + BomRef = "System1@1" + }, + Tools = new ToolChoices + { + Components = new List + { + new Component + { + Name = "ToolComponent1", + Version = "1", + BomRef = "ToolComponent1@1", + } + } + } + }, + Components = new List + { + new Component + { + Name = "Component1", + Version = "1", + BomRef = "Component1@1" + } + }, + Dependencies = new List + { + new Dependency + { + Ref = "System1@1", + Dependencies = new List + { + new Dependency + { + Ref = "Component1@1" + } + } + } + }, + }; + var sbom2 = new Bom + { + Metadata = new Metadata + { + Component = new Component + { + Name = "System2", + Version = "1", + BomRef = "System2@1" + }, + Tools = new ToolChoices + { + Components = new List + { + new Component + { + Name = "ToolComponent2", + Version = "1", + BomRef = "ToolComponent2@1", + } + } + } + }, + Components = new List + { + new Component + { + Name = "Component2", + Version = "1", + BomRef = "Component2@1" + } + }, + Dependencies = new List + { + new Dependency + { + Ref = "System2@1", + Dependencies = new List + { + new Dependency + { + Ref = "Component2@1" + } + } + } + }, + }; + + var result = CycloneDXUtils.HierarchicalMerge(new[] { sbom1, sbom2 }, subject); + + Snapshot.Match(result); + } + + [Fact] + public void HierarchicalMergeDuplicatedToolsComponentsTest() + { + var subject = new Component + { + Name = "Thing", + Version = "1", + }; + + var sbom1 = new Bom + { + Metadata = new Metadata + { + Component = new Component + { + Name = "System1", + Version = "1", + BomRef = "System1@1" + }, + Tools = new ToolChoices + { + Components = new List + { + new Component + { + Name = "ToolComponent1", + Version = "1", + } + } + } + }, + Components = new List + { + new Component + { + Name = "Component1", + Version = "1", + BomRef = "Component1@1" + } + }, + Dependencies = new List + { + new Dependency + { + Ref = "System1@1", + Dependencies = new List + { + new Dependency + { + Ref = "Component1@1" + } + } + } + }, + }; + var sbom2 = new Bom + { + Metadata = new Metadata + { + Component = new Component + { + Name = "System2", + Version = "1", + BomRef = "System2@1" + }, + Tools = new ToolChoices + { + Components = new List + { + new Component + { + Name = "ToolComponent1", + Version = "1", + } + } + } + }, + Components = new List + { + new Component + { + Name = "Component2", + Version = "1", + BomRef = "Component2@1" + } + }, + Dependencies = new List + { + new Dependency + { + Ref = "System2@1", + Dependencies = new List + { + new Dependency + { + Ref = "Component2@1" + } + } + } + }, + }; + + var result = CycloneDXUtils.HierarchicalMerge(new[] { sbom1, sbom2 }, subject); + + Snapshot.Match(result); + } + [Fact] public void HierarchicalMergeVulnerabilitiesTest() { diff --git a/tests/CycloneDX.Utils.Tests/__snapshots__/MergeTests.FlatMergeComponentsTest.snap b/tests/CycloneDX.Utils.Tests/__snapshots__/MergeTests.FlatMergeComponentsTest.snap index 84750f41..233ac493 100644 --- a/tests/CycloneDX.Utils.Tests/__snapshots__/MergeTests.FlatMergeComponentsTest.snap +++ b/tests/CycloneDX.Utils.Tests/__snapshots__/MergeTests.FlatMergeComponentsTest.snap @@ -1,7 +1,7 @@ { "BomFormat": "CycloneDX", - "SpecVersion": "v1_5", - "SpecVersionString": "1.5", + "SpecVersion": "v1_6", + "SpecVersionString": "1.6", "SerialNumber": null, "Version": null, "Metadata": null, @@ -27,7 +27,8 @@ "Pedigree": null, "Evidence": null, "ModelCard": null, - "Data": null + "Data": null, + "CryptoProperties": null }, { "Type": "Null", @@ -50,7 +51,8 @@ "Pedigree": null, "Evidence": null, "ModelCard": null, - "Data": null + "Data": null, + "CryptoProperties": null } ], "Compositions": null diff --git a/tests/CycloneDX.Utils.Tests/__snapshots__/MergeTests.FlatMergeToolsTest.snap b/tests/CycloneDX.Utils.Tests/__snapshots__/MergeTests.FlatMergeToolsTest.snap index 68455c7d..b3c51bcb 100644 --- a/tests/CycloneDX.Utils.Tests/__snapshots__/MergeTests.FlatMergeToolsTest.snap +++ b/tests/CycloneDX.Utils.Tests/__snapshots__/MergeTests.FlatMergeToolsTest.snap @@ -1,7 +1,7 @@ { "BomFormat": "CycloneDX", - "SpecVersion": "v1_5", - "SpecVersionString": "1.5", + "SpecVersion": "v1_6", + "SpecVersionString": "1.6", "SerialNumber": null, "Version": null, "Metadata": { diff --git a/tests/CycloneDX.Utils.Tests/__snapshots__/MergeTests.FlatMergeVulnerabilitiesTest.snap b/tests/CycloneDX.Utils.Tests/__snapshots__/MergeTests.FlatMergeVulnerabilitiesTest.snap index 38075f1a..d40f9503 100644 --- a/tests/CycloneDX.Utils.Tests/__snapshots__/MergeTests.FlatMergeVulnerabilitiesTest.snap +++ b/tests/CycloneDX.Utils.Tests/__snapshots__/MergeTests.FlatMergeVulnerabilitiesTest.snap @@ -1,7 +1,7 @@ { "BomFormat": "CycloneDX", - "SpecVersion": "v1_5", - "SpecVersionString": "1.5", + "SpecVersion": "v1_6", + "SpecVersionString": "1.6", "SerialNumber": null, "Version": null, "Metadata": null, diff --git a/tests/CycloneDX.Utils.Tests/__snapshots__/MergeTests.HierarchicalMergeComponentsTest.snap b/tests/CycloneDX.Utils.Tests/__snapshots__/MergeTests.HierarchicalMergeComponentsTest.snap index 01b1ae34..2deb2daf 100644 --- a/tests/CycloneDX.Utils.Tests/__snapshots__/MergeTests.HierarchicalMergeComponentsTest.snap +++ b/tests/CycloneDX.Utils.Tests/__snapshots__/MergeTests.HierarchicalMergeComponentsTest.snap @@ -1,7 +1,7 @@ { "BomFormat": "CycloneDX", - "SpecVersion": "v1_5", - "SpecVersionString": "1.5", + "SpecVersion": "v1_6", + "SpecVersionString": "1.6", "SerialNumber": null, "Version": null, "Metadata": { @@ -31,7 +31,8 @@ "Pedigree": null, "Evidence": null, "ModelCard": null, - "Data": null + "Data": null, + "CryptoProperties": null }, "Manufacture": null, "Supplier": null @@ -78,12 +79,14 @@ "Pedigree": null, "Evidence": null, "ModelCard": null, - "Data": null + "Data": null, + "CryptoProperties": null } ], "Evidence": null, "ModelCard": null, - "Data": null + "Data": null, + "CryptoProperties": null }, { "Type": "Null", @@ -126,12 +129,14 @@ "Pedigree": null, "Evidence": null, "ModelCard": null, - "Data": null + "Data": null, + "CryptoProperties": null } ], "Evidence": null, "ModelCard": null, - "Data": null + "Data": null, + "CryptoProperties": null } ], "Dependencies": [ @@ -140,31 +145,38 @@ "Dependencies": [ { "Ref": "System1@1:Component1@1", - "Dependencies": null + "Dependencies": null, + "Provides": null } - ] + ], + "Provides": null }, { "Ref": "System2@1:System2@1", "Dependencies": [ { "Ref": "System2@1:Component2@1", - "Dependencies": null + "Dependencies": null, + "Provides": null } - ] + ], + "Provides": null }, { "Ref": "Thing@1", "Dependencies": [ { "Ref": "System1@1:System1@1", - "Dependencies": null + "Dependencies": null, + "Provides": null }, { "Ref": "System2@1:System2@1", - "Dependencies": null + "Dependencies": null, + "Provides": null } - ] + ], + "Provides": null } ], "Compositions": [ diff --git a/tests/CycloneDX.Utils.Tests/__snapshots__/MergeTests.HierarchicalMergeDuplicatedToolsComponentsTest.snap b/tests/CycloneDX.Utils.Tests/__snapshots__/MergeTests.HierarchicalMergeDuplicatedToolsComponentsTest.snap new file mode 100644 index 00000000..a7e3841f --- /dev/null +++ b/tests/CycloneDX.Utils.Tests/__snapshots__/MergeTests.HierarchicalMergeDuplicatedToolsComponentsTest.snap @@ -0,0 +1,209 @@ +{ + "BomFormat": "CycloneDX", + "SpecVersion": "v1_6", + "SpecVersionString": "1.6", + "SerialNumber": null, + "Version": null, + "Metadata": { + "Tools": { + "Tools": null, + "Components": [ + { + "Type": "Null", + "MimeType": null, + "BomRef": null, + "Supplier": null, + "Author": null, + "Publisher": null, + "Group": null, + "Name": "ToolComponent1", + "Version": "1", + "Description": null, + "Scope": null, + "Licenses": null, + "Copyright": null, + "Cpe": null, + "Purl": null, + "Swid": null, + "Modified": null, + "Pedigree": null, + "Evidence": null, + "ModelCard": null, + "Data": null, + "CryptoProperties": null + } + ] + }, + "ProtobufTools": null, + "Authors": null, + "Component": { + "Type": "Null", + "MimeType": null, + "BomRef": "Thing@1", + "Supplier": null, + "Author": null, + "Publisher": null, + "Group": null, + "Name": "Thing", + "Version": "1", + "Description": null, + "Scope": null, + "Licenses": null, + "Copyright": null, + "Cpe": null, + "Purl": null, + "Swid": null, + "Modified": null, + "Pedigree": null, + "Evidence": null, + "ModelCard": null, + "Data": null, + "CryptoProperties": null + }, + "Manufacture": null, + "Supplier": null + }, + "Components": [ + { + "Type": "Null", + "MimeType": null, + "BomRef": "System1@1:System1@1", + "Supplier": null, + "Author": null, + "Publisher": null, + "Group": null, + "Name": "System1", + "Version": "1", + "Description": null, + "Scope": null, + "Licenses": null, + "Copyright": null, + "Cpe": null, + "Purl": null, + "Swid": null, + "Modified": null, + "Pedigree": null, + "Components": [ + { + "Type": "Null", + "MimeType": null, + "BomRef": "System1@1:Component1@1", + "Supplier": null, + "Author": null, + "Publisher": null, + "Group": null, + "Name": "Component1", + "Version": "1", + "Description": null, + "Scope": null, + "Licenses": null, + "Copyright": null, + "Cpe": null, + "Purl": null, + "Swid": null, + "Modified": null, + "Pedigree": null, + "Evidence": null, + "ModelCard": null, + "Data": null, + "CryptoProperties": null + } + ], + "Evidence": null, + "ModelCard": null, + "Data": null, + "CryptoProperties": null + }, + { + "Type": "Null", + "MimeType": null, + "BomRef": "System2@1:System2@1", + "Supplier": null, + "Author": null, + "Publisher": null, + "Group": null, + "Name": "System2", + "Version": "1", + "Description": null, + "Scope": null, + "Licenses": null, + "Copyright": null, + "Cpe": null, + "Purl": null, + "Swid": null, + "Modified": null, + "Pedigree": null, + "Components": [ + { + "Type": "Null", + "MimeType": null, + "BomRef": "System2@1:Component2@1", + "Supplier": null, + "Author": null, + "Publisher": null, + "Group": null, + "Name": "Component2", + "Version": "1", + "Description": null, + "Scope": null, + "Licenses": null, + "Copyright": null, + "Cpe": null, + "Purl": null, + "Swid": null, + "Modified": null, + "Pedigree": null, + "Evidence": null, + "ModelCard": null, + "Data": null, + "CryptoProperties": null + } + ], + "Evidence": null, + "ModelCard": null, + "Data": null, + "CryptoProperties": null + } + ], + "Dependencies": [ + { + "Ref": "System1@1:System1@1", + "Dependencies": [ + { + "Ref": "System1@1:Component1@1", + "Dependencies": null, + "Provides": null + } + ], + "Provides": null + }, + { + "Ref": "System2@1:System2@1", + "Dependencies": [ + { + "Ref": "System2@1:Component2@1", + "Dependencies": null, + "Provides": null + } + ], + "Provides": null + }, + { + "Ref": "Thing@1", + "Dependencies": [ + { + "Ref": "System1@1:System1@1", + "Dependencies": null, + "Provides": null + }, + { + "Ref": "System2@1:System2@1", + "Dependencies": null, + "Provides": null + } + ], + "Provides": null + } + ], + "Compositions": null +} diff --git a/tests/CycloneDX.Utils.Tests/__snapshots__/MergeTests.HierarchicalMergeToolsComponentsTest.snap b/tests/CycloneDX.Utils.Tests/__snapshots__/MergeTests.HierarchicalMergeToolsComponentsTest.snap new file mode 100644 index 00000000..7adf11ec --- /dev/null +++ b/tests/CycloneDX.Utils.Tests/__snapshots__/MergeTests.HierarchicalMergeToolsComponentsTest.snap @@ -0,0 +1,233 @@ +{ + "BomFormat": "CycloneDX", + "SpecVersion": "v1_6", + "SpecVersionString": "1.6", + "SerialNumber": null, + "Version": null, + "Metadata": { + "Tools": { + "Tools": null, + "Components": [ + { + "Type": "Null", + "MimeType": null, + "BomRef": "System1@1:ToolComponent1@1", + "Supplier": null, + "Author": null, + "Publisher": null, + "Group": null, + "Name": "ToolComponent1", + "Version": "1", + "Description": null, + "Scope": null, + "Licenses": null, + "Copyright": null, + "Cpe": null, + "Purl": null, + "Swid": null, + "Modified": null, + "Pedigree": null, + "Evidence": null, + "ModelCard": null, + "Data": null, + "CryptoProperties": null + }, + { + "Type": "Null", + "MimeType": null, + "BomRef": "System2@1:ToolComponent2@1", + "Supplier": null, + "Author": null, + "Publisher": null, + "Group": null, + "Name": "ToolComponent2", + "Version": "1", + "Description": null, + "Scope": null, + "Licenses": null, + "Copyright": null, + "Cpe": null, + "Purl": null, + "Swid": null, + "Modified": null, + "Pedigree": null, + "Evidence": null, + "ModelCard": null, + "Data": null, + "CryptoProperties": null + } + ] + }, + "ProtobufTools": null, + "Authors": null, + "Component": { + "Type": "Null", + "MimeType": null, + "BomRef": "Thing@1", + "Supplier": null, + "Author": null, + "Publisher": null, + "Group": null, + "Name": "Thing", + "Version": "1", + "Description": null, + "Scope": null, + "Licenses": null, + "Copyright": null, + "Cpe": null, + "Purl": null, + "Swid": null, + "Modified": null, + "Pedigree": null, + "Evidence": null, + "ModelCard": null, + "Data": null, + "CryptoProperties": null + }, + "Manufacture": null, + "Supplier": null + }, + "Components": [ + { + "Type": "Null", + "MimeType": null, + "BomRef": "System1@1:System1@1", + "Supplier": null, + "Author": null, + "Publisher": null, + "Group": null, + "Name": "System1", + "Version": "1", + "Description": null, + "Scope": null, + "Licenses": null, + "Copyright": null, + "Cpe": null, + "Purl": null, + "Swid": null, + "Modified": null, + "Pedigree": null, + "Components": [ + { + "Type": "Null", + "MimeType": null, + "BomRef": "System1@1:Component1@1", + "Supplier": null, + "Author": null, + "Publisher": null, + "Group": null, + "Name": "Component1", + "Version": "1", + "Description": null, + "Scope": null, + "Licenses": null, + "Copyright": null, + "Cpe": null, + "Purl": null, + "Swid": null, + "Modified": null, + "Pedigree": null, + "Evidence": null, + "ModelCard": null, + "Data": null, + "CryptoProperties": null + } + ], + "Evidence": null, + "ModelCard": null, + "Data": null, + "CryptoProperties": null + }, + { + "Type": "Null", + "MimeType": null, + "BomRef": "System2@1:System2@1", + "Supplier": null, + "Author": null, + "Publisher": null, + "Group": null, + "Name": "System2", + "Version": "1", + "Description": null, + "Scope": null, + "Licenses": null, + "Copyright": null, + "Cpe": null, + "Purl": null, + "Swid": null, + "Modified": null, + "Pedigree": null, + "Components": [ + { + "Type": "Null", + "MimeType": null, + "BomRef": "System2@1:Component2@1", + "Supplier": null, + "Author": null, + "Publisher": null, + "Group": null, + "Name": "Component2", + "Version": "1", + "Description": null, + "Scope": null, + "Licenses": null, + "Copyright": null, + "Cpe": null, + "Purl": null, + "Swid": null, + "Modified": null, + "Pedigree": null, + "Evidence": null, + "ModelCard": null, + "Data": null, + "CryptoProperties": null + } + ], + "Evidence": null, + "ModelCard": null, + "Data": null, + "CryptoProperties": null + } + ], + "Dependencies": [ + { + "Ref": "System1@1:System1@1", + "Dependencies": [ + { + "Ref": "System1@1:Component1@1", + "Dependencies": null, + "Provides": null + } + ], + "Provides": null + }, + { + "Ref": "System2@1:System2@1", + "Dependencies": [ + { + "Ref": "System2@1:Component2@1", + "Dependencies": null, + "Provides": null + } + ], + "Provides": null + }, + { + "Ref": "Thing@1", + "Dependencies": [ + { + "Ref": "System1@1:System1@1", + "Dependencies": null, + "Provides": null + }, + { + "Ref": "System2@1:System2@1", + "Dependencies": null, + "Provides": null + } + ], + "Provides": null + } + ], + "Compositions": null +} diff --git a/tests/CycloneDX.Utils.Tests/__snapshots__/MergeTests.HierarchicalMergeVulnerabilitiesTest.snap b/tests/CycloneDX.Utils.Tests/__snapshots__/MergeTests.HierarchicalMergeVulnerabilitiesTest.snap index 48791aa7..c380f750 100644 --- a/tests/CycloneDX.Utils.Tests/__snapshots__/MergeTests.HierarchicalMergeVulnerabilitiesTest.snap +++ b/tests/CycloneDX.Utils.Tests/__snapshots__/MergeTests.HierarchicalMergeVulnerabilitiesTest.snap @@ -1,7 +1,7 @@ { "BomFormat": "CycloneDX", - "SpecVersion": "v1_5", - "SpecVersionString": "1.5", + "SpecVersion": "v1_6", + "SpecVersionString": "1.6", "SerialNumber": null, "Version": null, "Metadata": { @@ -31,7 +31,8 @@ "Pedigree": null, "Evidence": null, "ModelCard": null, - "Data": null + "Data": null, + "CryptoProperties": null }, "Manufacture": null, "Supplier": null @@ -58,7 +59,8 @@ "Pedigree": null, "Evidence": null, "ModelCard": null, - "Data": null + "Data": null, + "CryptoProperties": null }, { "Type": "Null", @@ -81,7 +83,8 @@ "Pedigree": null, "Evidence": null, "ModelCard": null, - "Data": null + "Data": null, + "CryptoProperties": null } ], "Dependencies": [ @@ -90,13 +93,16 @@ "Dependencies": [ { "Ref": "System1@1:System1@1", - "Dependencies": null + "Dependencies": null, + "Provides": null }, { "Ref": "System2@1:System2@1", - "Dependencies": null + "Dependencies": null, + "Provides": null } - ] + ], + "Provides": null } ], "Compositions": null,