Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

ExternalRefCategory 'PACKAGE_MANAGER' is not compliant with SPDX 2.2 specification #267

Open
wterpstra opened this issue Nov 1, 2023 · 5 comments · May be fixed by #268 or #269
Open

ExternalRefCategory 'PACKAGE_MANAGER' is not compliant with SPDX 2.2 specification #267

wterpstra opened this issue Nov 1, 2023 · 5 comments · May be fixed by #268 or #269

Comments

@wterpstra
Copy link

According to the SPDX 2.2 specification the referenceCategory of an ExternalReference can be SECURITY, PACKAGE-MANAGER , PERSISTENT-ID or OTHER.

However, in the ExternalRefCategory enum it is PACKAGE_MANAGER which uses an underscore instead of a dash.

public enum ExternalRefCategory
{
OTHER,
SECURITY,
PACKAGE_MANAGER,
}

When trying to convert a valid SPDX SBOM it will result in this exception:

Unhandled exception: System.Text.Json.JsonException: The JSON value could not be converted to CycloneDX.Spdx.Models.v2_2.ExternalRefCategory. Path: $.packages[0].externalRefs[0].referenceCategory | LineNumber: 14 | BytePositionInLine: 48.
   at System.Text.Json.ThrowHelper.ThrowJsonException(String message)
   at System.Text.Json.Serialization.Converters.EnumConverter`1.ReadEnumUsingNamingPolicy(String enumString)
   at System.Text.Json.Serialization.Converters.EnumConverter`1.Read(Utf8JsonReader& reader, Type typeToConvert, JsonSerializerOptions options)
   at System.Text.Json.Serialization.Metadata.JsonPropertyInfo`1.ReadJsonAndSetMember(Object obj, ReadStack& state, Utf8JsonReader& reader)
   at System.Text.Json.Serialization.Converters.ObjectDefaultConverter`1.OnTryRead(Utf8JsonReader& reader, Type typeToConvert, JsonSerializerOptions options, ReadStack& state, T& value)
   at System.Text.Json.Serialization.JsonConverter`1.TryRead(Utf8JsonReader& reader, Type typeToConvert, JsonSerializerOptions options, ReadStack& state, T& value)
   at System.Text.Json.Serialization.JsonCollectionConverter`2.OnTryRead(Utf8JsonReader& reader, Type typeToConvert, JsonSerializerOptions options, ReadStack& state, TCollection& value)
   at System.Text.Json.Serialization.JsonConverter`1.TryRead(Utf8JsonReader& reader, Type typeToConvert, JsonSerializerOptions options, ReadStack& state, T& value)
   at System.Text.Json.Serialization.Metadata.JsonPropertyInfo`1.ReadJsonAndSetMember(Object obj, ReadStack& state, Utf8JsonReader& reader)
   at System.Text.Json.Serialization.Converters.ObjectDefaultConverter`1.OnTryRead(Utf8JsonReader& reader, Type typeToConvert, JsonSerializerOptions options, ReadStack& state, T& value)
   at System.Text.Json.Serialization.JsonConverter`1.TryRead(Utf8JsonReader& reader, Type typeToConvert, JsonSerializerOptions options, ReadStack& state, T& value)
   at System.Text.Json.Serialization.JsonCollectionConverter`2.OnTryRead(Utf8JsonReader& reader, Type typeToConvert, JsonSerializerOptions options, ReadStack& state, TCollection& value)
   at System.Text.Json.Serialization.JsonConverter`1.TryRead(Utf8JsonReader& reader, Type typeToConvert, JsonSerializerOptions options, ReadStack& state, T& value)
   at System.Text.Json.Serialization.Metadata.JsonPropertyInfo`1.ReadJsonAndSetMember(Object obj, ReadStack& state, Utf8JsonReader& reader)
   at System.Text.Json.Serialization.Converters.ObjectDefaultConverter`1.OnTryRead(Utf8JsonReader& reader, Type typeToConvert, JsonSerializerOptions options, ReadStack& state, T& value)
   at System.Text.Json.Serialization.JsonConverter`1.TryRead(Utf8JsonReader& reader, Type typeToConvert, JsonSerializerOptions options, ReadStack& state, T& value)
   at System.Text.Json.Serialization.JsonConverter`1.ReadCore(Utf8JsonReader& reader, JsonSerializerOptions options, ReadStack& state)
   at System.Text.Json.JsonSerializer.ReadCore[TValue](Utf8JsonReader& reader, JsonTypeInfo jsonTypeInfo, ReadStack& state)
   at System.Text.Json.JsonSerializer.ContinueDeserialize[TValue](ReadBufferState& bufferState, JsonReaderState& jsonReaderState, ReadStack& readStack, JsonTypeInfo jsonTypeInfo)
   at System.Text.Json.JsonSerializer.ReadFromStreamAsync[TValue](Stream utf8Json, JsonTypeInfo jsonTypeInfo, CancellationToken cancellationToken)
   at CycloneDX.Spdx.Serialization.JsonSerializer.DeserializeAsync(Stream jsonStream)
   at CycloneDX.Cli.CliUtils.InputBomHelper(String filename, ConvertFormat format)
   at CycloneDX.Cli.Commands.ConvertCommand.Convert(ConvertCommandOptions options)
   at System.CommandLine.Invocation.CommandHandler.GetExitCodeAsync(Object value, InvocationContext context)
   at System.CommandLine.Invocation.ModelBindingCommandHandler.InvokeAsync(InvocationContext context)
   at System.CommandLine.Invocation.InvocationPipeline.<>c__DisplayClass4_0.<<BuildInvocationChain>b__0>d.MoveNext()
--- End of stack trace from previous location ---
   at System.CommandLine.Builder.CommandLineBuilderExtensions.<>c__DisplayClass23_0.<<UseParseErrorReporting>b__0>d.MoveNext()
--- End of stack trace from previous location ---
   at System.CommandLine.Builder.CommandLineBuilderExtensions.<>c__DisplayClass16_0.<<UseHelp>b__0>d.MoveNext()
--- End of stack trace from previous location ---
   at System.CommandLine.Builder.CommandLineBuilderExtensions.<>c__DisplayClass27_0.<<UseVersionOption>b__1>d.MoveNext()
--- End of stack trace from previous location ---
   at System.CommandLine.Builder.CommandLineBuilderExtensions.<>c__DisplayClass25_0.<<UseTypoCorrections>b__0>d.MoveNext()
--- End of stack trace from previous location ---
   at System.CommandLine.Builder.CommandLineBuilderExtensions.<>c.<<UseSuggestDirective>b__24_0>d.MoveNext()
--- End of stack trace from previous location ---
   at System.CommandLine.Builder.CommandLineBuilderExtensions.<>c__DisplayClass22_0.<<UseParseDirective>b__0>d.MoveNext()
--- End of stack trace from previous location ---
   at System.CommandLine.Builder.CommandLineBuilderExtensions.<>c__DisplayClass11_0.<<UseDebugDirective>b__0>d.MoveNext()
--- End of stack trace from previous location ---
   at System.CommandLine.Builder.CommandLineBuilderExtensions.<>c.<<RegisterWithDotnetSuggest>b__10_0>d.MoveNext()
--- End of stack trace from previous location ---
   at System.CommandLine.Builder.CommandLineBuilderExtensions.<>c__DisplayClass14_0.<<UseExceptionHandler>b__0>d.MoveNext()

My current workaround is just string replacing PACKAGE-MANAGER to PACKAGE_MANAGER before passing it to the cyclonedx-cli:
cat manifest.spdx.json | sed 's/PACKAGE-MANAGER/PACKAGE_MANAGER/g' | ./cyclonedx-linux-x64 convert --input-format spdxjson --output-format json > cyclonedx.json

I'm happy to contribute a solution for this, but changing an enum field or its (de)serialization is breaking to the current behavior. Should the old behavior still be supported? What should be the default?

@andreas-hilti
Copy link
Contributor

I picked the "development" instead of the release branches. The proper links would be:
https://github.com/spdx/spdx-spec/blob/v2.2/schemas/spdx-schema.json
and
https://github.com/spdx/spdx-spec/blob/v2.2.2/schemas/spdx-schema.json
And there are no changes.

Only for 2.3 it seemed to be changed. Thus, I wonder whether
https://spdx.github.io/spdx-spec/v2.2.2/package-information/#7211-description
is wrong.

@wterpstra
Copy link
Author

Ah good catch! I raised an issue in the SPDX repo for clarification.

@wterpstra
Copy link
Author

wterpstra commented Nov 2, 2023

I found some other information in spdx/spdx-spec#792 and spdx/spdx-spec#618. From what I understand both values should be supported but the way in the documentation is preferred.

So when reading it should support both values, but when writing it should use the dash instead of the underscore. That would be a breaking change though, so maybe for now I can cook up a JSON converter that reads both dashes and underscores but writes underscores so not to break current behavior.

Then for the next major release a change can be made to move from underscores to dashes.

wterpstra added a commit to wterpstra/cyclonedx-dotnet-library that referenced this issue Nov 6, 2023
wterpstra added a commit to wterpstra/cyclonedx-dotnet-library that referenced this issue Nov 6, 2023
…ixes CycloneDX#267)

Signed-off-by: Wessel Terpstra <wessel@wesselterpstra.com>
wterpstra added a commit to wterpstra/cyclonedx-dotnet-library that referenced this issue Nov 6, 2023
…ixes CycloneDX#267)

Signed-off-by: Wessel Terpstra <wessel@wesselterpstra.com>
sschuberth added a commit to oss-review-toolkit/ort that referenced this issue Nov 9, 2023
Note that this changes serialization of reference categories to use
dashes instead of underscores [1]. Continue to accept underscores when
deserializing for backward-compatibility, also see the discussion at
[2]. Generally, deserialization of SPDX 2.2 is still supported.

The diff of `spdx-schema.json` nicely resembles the code changes.

Resolves #5445.

[1]: https://github.com/spdx/spdx-spec/blob/v2.3/schemas/spdx-schema.json#L325
[2]: CycloneDX/cyclonedx-dotnet-library#267

Signed-off-by: Sebastian Schuberth <sebastian@doubleopen.org>
sschuberth added a commit to oss-review-toolkit/ort that referenced this issue Nov 17, 2023
Note that this changes serialization of reference categories to use
dashes instead of underscores [1]. Continue to accept underscores when
deserializing for backward-compatibility, also see the discussion at
[2]. Generally, deserialization of SPDX 2.2 is still supported.

The diff of `spdx-schema.json` nicely resembles the code changes.

Resolves #5445.

[1]: https://github.com/spdx/spdx-spec/blob/v2.3/schemas/spdx-schema.json#L325
[2]: CycloneDX/cyclonedx-dotnet-library#267

Signed-off-by: Sebastian Schuberth <sebastian@doubleopen.org>
@JuanJTorres11
Copy link

@wterpstra is there an update on this fix?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
3 participants