using System; using System.Text.RegularExpressions; using CycloneDX; using CycloneDX.Models; namespace StellaOps.Scanner.Emit.Composition; /// /// Helpers and media type constants for CycloneDX 1.7. /// /// /// Sprint: SPRINT_5000_0001_0001 - Advisory Alignment (CycloneDX 1.7 Upgrade) /// Keep upgrade helpers for backward-compatibility with 1.6 inputs. /// public static class CycloneDx17Extensions { /// /// CycloneDX 1.7 media types. /// public static class MediaTypes { public const string InventoryJson = "application/vnd.cyclonedx+json; version=1.7"; public const string UsageJson = "application/vnd.cyclonedx+json; version=1.7; view=usage"; public const string InventoryProtobuf = "application/vnd.cyclonedx+protobuf; version=1.7"; public const string UsageProtobuf = "application/vnd.cyclonedx+protobuf; version=1.7; view=usage"; } // Regex patterns for version replacement in serialized output private static readonly Regex JsonSpecVersionPattern = new( @"""specVersion""\s*:\s*""1\.6""", RegexOptions.Compiled); private static readonly Regex XmlSpecVersionPattern = new( @"specVersion=""1\.6""", RegexOptions.Compiled); /// /// Upgrades a CycloneDX 1.6 JSON string to 1.7 format. /// /// The JSON serialized with v1_6. /// The JSON with specVersion updated to 1.7. public static string UpgradeJsonTo17(string json1_6) { if (string.IsNullOrEmpty(json1_6)) { return json1_6; } return JsonSpecVersionPattern.Replace(json1_6, @"""specVersion"": ""1.7"""); } /// /// Upgrades a CycloneDX 1.6 XML string to 1.7 format. /// /// The XML serialized with v1_6. /// The XML with specVersion updated to 1.7. public static string UpgradeXmlTo17(string xml1_6) { if (string.IsNullOrEmpty(xml1_6)) { return xml1_6; } return XmlSpecVersionPattern.Replace(xml1_6, @"specVersion=""1.7"""); } /// /// Upgrades a media type string from 1.6 to 1.7. /// public static string UpgradeMediaTypeTo17(string mediaType) { if (string.IsNullOrEmpty(mediaType)) { return mediaType; } return mediaType.Replace("version=1.6", "version=1.7", StringComparison.OrdinalIgnoreCase); } /// /// Checks if CycloneDX.Core supports v1_7 natively. /// Returns true when the library is updated and this workaround can be removed. /// public static bool IsNativeV17Supported() { // Check if v1_7 enum value exists via reflection var values = Enum.GetNames(typeof(SpecificationVersion)); foreach (var value in values) { if (value.Equals("v1_7", StringComparison.OrdinalIgnoreCase)) { return true; } } return false; } }