Skip to content

Commit

Permalink
fix(spdx): adds support for reading ReferenceCategories with hyphens (f…
Browse files Browse the repository at this point in the history
…ixes CycloneDX#267)

Signed-off-by: Wessel Terpstra <wessel@wesselterpstra.com>
  • Loading branch information
wterpstra committed Nov 6, 2023
1 parent 1e3886b commit 7e6f223
Show file tree
Hide file tree
Showing 13 changed files with 2,224 additions and 2 deletions.
29 changes: 28 additions & 1 deletion src/CycloneDX.Spdx/Models/v2_2/ExternalRef.cs
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@
// Copyright (c) OWASP Foundation. All Rights Reserved.

using System;
using System.Text.Json.Serialization;
using System.Xml.Serialization;

namespace CycloneDX.Spdx.Models.v2_2
Expand All @@ -28,8 +29,34 @@ public class ExternalRef
/// <summary>
/// Category for the external reference
/// </summary>
[XmlElement("referenceCategory")]
[XmlIgnore]
public ExternalRefCategory ReferenceCategory { get; set; }

/// <summary>
/// Category for the external reference, adjusted to allow values with hyphens and underscores
/// </summary>
[XmlElement("referenceCategory")]
[JsonIgnore]
public string ReferenceCategoryAsString
{
get => ReferenceCategory.ToString();
set
{
switch (value.ToUpperInvariant())
{
case "OTHER":
ReferenceCategory = ExternalRefCategory.OTHER;
break;
case "SECURITY":
ReferenceCategory = ExternalRefCategory.SECURITY;
break;
case "PACKAGE_MANAGER":
case "PACKAGE-MANAGER":
ReferenceCategory = ExternalRefCategory.PACKAGE_MANAGER;
break;
}
}
}

/// <summary>
/// The unique string with no spaces necessary to access the package-specific information, metadata, or content within the target location. The format of the locator is subject to constraints defined by the &lt;type&gt;.
Expand Down
2 changes: 1 addition & 1 deletion src/CycloneDX.Spdx/Schemas/spdx-2.2.schema.json
Original file line number Diff line number Diff line change
Expand Up @@ -317,7 +317,7 @@
"referenceCategory" : {
"description" : "Category for the external reference",
"type" : "string",
"enum" : [ "OTHER", "PERSISTENT_ID", "SECURITY", "PACKAGE_MANAGER" ]
"enum" : [ "OTHER", "PERSISTENT_ID", "SECURITY", "PACKAGE_MANAGER", "PACKAGE-MANAGER", "PERSISTENT-ID" ]
},
"referenceLocator" : {
"description" : "The unique string with no spaces necessary to access the package-specific information, metadata, or content within the target location. The format of the locator is subject to constraints defined by the <type>.",
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
// 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.Diagnostics.Contracts;
using System.Text.Json;
using System.Text.Json.Serialization;

namespace CycloneDX.Spdx.Serialization.Converters
{

public class HyphenToUnderscoreEnumConverter<T> : JsonConverter<T> where T: struct
{
public override T Read(
ref Utf8JsonReader reader,
Type typeToConvert,
JsonSerializerOptions options)
{
if (reader.TokenType == JsonTokenType.Null
|| reader.TokenType != JsonTokenType.String)
{
throw new JsonException();
}

var enumString = reader.GetString();

T enumValue;
var success = Enum.TryParse<T>(enumString.Replace("-", "_"), ignoreCase: true, out enumValue);
if (success)
{
return enumValue;
}
else
{
throw new JsonException();
}
}

public override void Write(
Utf8JsonWriter writer,
T value,
JsonSerializerOptions options)
{
Contract.Requires(writer != null);
writer.WriteStringValue(value.ToString());
}
}
}
3 changes: 3 additions & 0 deletions src/CycloneDX.Spdx/Serialization/JsonSerializer.cs
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,8 @@
using System.Text.Json;
using System.Text.Json.Serialization;
using System.Threading.Tasks;
using CycloneDX.Spdx.Models.v2_2;
using CycloneDX.Spdx.Serialization.Converters;

namespace CycloneDX.Spdx.Serialization
{
Expand All @@ -38,6 +40,7 @@ public static JsonSerializerOptions GetJsonSerializerOptions_v2_2()
PropertyNamingPolicy = JsonNamingPolicy.CamelCase,
DefaultIgnoreCondition = JsonIgnoreCondition.WhenWritingNull,
};
options.Converters.Add(new HyphenToUnderscoreEnumConverter<ExternalRefCategory>());
options.Converters.Add(new JsonStringEnumConverter());
return options;
}
Expand Down
2 changes: 2 additions & 0 deletions tests/CycloneDX.Spdx.Tests/JsonSerializerTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ public class JsonSerializerTests
{
[Theory]
[InlineData("document")]
[InlineData("document-with-hyphens-in-external-reference-category")]
public void JsonRoundTripTest(string baseFilename)
{
var resourceFilename = Path.Join("Resources", "v2.2", baseFilename + ".json");
Expand All @@ -42,6 +43,7 @@ public void JsonRoundTripTest(string baseFilename)

[Theory]
[InlineData("document")]
[InlineData("document-with-hyphens-in-external-reference-category")]
public async Task JsonAsyncRoundTripTest(string baseFilename)
{
var resourceFilename = Path.Join("Resources", "v2.2", baseFilename + ".json");
Expand Down
2 changes: 2 additions & 0 deletions tests/CycloneDX.Spdx.Tests/JsonValidatorTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ public class JsonValidatorTests
{
[Theory]
[InlineData("document")]
[InlineData("document-with-hyphens-in-external-reference-category")]
public void ValidateJsonStringTest(string baseFilename)
{
var resourceFilename = Path.Join("Resources", "v2.2", baseFilename + ".json");
Expand All @@ -41,6 +42,7 @@ public void ValidateJsonStringTest(string baseFilename)

[Theory]
[InlineData("document")]
[InlineData("document-with-hyphens-in-external-reference-category")]
public async Task ValidateJsonStreamTest(string baseFilename)
{
var resourceFilename = Path.Join("Resources", "v2.2", baseFilename + ".json");
Expand Down
Loading

0 comments on commit 7e6f223

Please sign in to comment.