Skip to content

Original license operator not preserved in one case of a declared_license_mapping being specified #11054

@daniel-kr

Description

@daniel-kr

Describe the bug

This is a follow-up to #10721. While the fix correctly preserves the original license operator (OR) when applying package curations to packages that already have a compound SPDX expression, there's an edge case that still fails:

When a package has two declared licenses where one is a valid SPDX expression and one is not (requiring a declared_license_mapping), the licenses are still incorrectly combined with AND instead of OR after applying the curation.

To Reproduce

A unit test demonstrating this issue has been added in PR #10995:

  1. Create a gradle or NPM package with two declared licenses:
    • One valid SPDX: "Apache-2.0"
    • One invalid requiring mapping: "GNU Lesser General Public License v2.1 only"
  2. The initial processing creates:
    • declaredLicensesProcessed.spdxExpression = "Apache-2.0"
    • declaredLicensesProcessed.unmapped = ["GNU Lesser General Public License v2.1 only"]
  3. Apply a curation with declared_license_mapping that maps the invalid license to "LGPL-2.1-only"
  4. Observe the result

Expected behavior

The licenses should be combined with OR (dual-licensing): "Apache-2.0 OR LGPL-2.1-only"

This represents the original intent of the respective package managers GradleInspector/Node: the package offers a choice between two licenses.

Console / log output

Actual processed declared license expression: "Apache-2.0 AND LGPL-2.1-only"
Expected processed declared license expression: "Apache-2.0 OR LGPL-2.1-only"

Environment

  • ORT version: 70.1.0 (stock Docker image)

Additional context

The fix for #10721 handles the case where packages already have a compound expression with the correct operator. However, when packages initially have only a simple expression (because some licenses couldn't be parsed), the operator information is lost.

The issue occurs because the initial DeclaredLicenseProcessor.process() only creates a simple (non-compound) SPDX expression for the valid license, leaving the invalid one unmapped. When the curation with declared_license_mapping is later applied, the code in PackageCurationData.apply() checks if the existing expression is a SpdxCompoundExpression (lines 151-162 in PackageCurationData.kt). Since it's not, it falls back to the default AND operator instead of recognizing that multiple licenses should be combined with OR.

Metadata

Metadata

Assignees

No one assigned

    Labels

    to triageIssues that need triaging

    Type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions