/
githubmirror
/
trivy
Обзор
Документация
Войти
/
githubmirror
/
trivy
Код
Задачи
Вики
Пакеты
0
Релизы
0
Аналитика
Безопасность
main
pkg/licensing/normalize_test.go
408 строк
14 KB
DmitriyLewen
fix: use canonical SPDX license IDs from embeded licenses.json (#10053)
19 янв 2026, 12:31
Не верифицирован
19 янв 2026, 12:31
c233735
Код
Авторство
О чём код?
package licensing_test import ( "testing" "github.com/stretchr/testify/assert" "github.com/aquasecurity/trivy/pkg/licensing" "github.com/aquasecurity/trivy/pkg/licensing/expression" ) func TestSplitLicenses(t *testing.T) { tests := []struct { name string license string licenses []string }{ { "simple list comma-separated", "GPL-1+,GPL-2", []string{ "GPL-1+", "GPL-2", }, }, { "simple list comma-separated", "GPL-1+,GPL-2,GPL-3", []string{ "GPL-1+", "GPL-2", "GPL-3", }, }, { "3 licenses 'or'-separated", "GPL-1+ or Artistic or Artistic-dist", []string{ "GPL-1+", "Artistic", "Artistic-dist", }, }, { "two licenses _or_ separated", "LGPLv3+_or_GPLv2+", []string{ "LGPLv3+", "GPLv2+", }, }, { "licenses `and`-separated", "BSD-3-CLAUSE and GPL-2", []string{ "BSD-3-CLAUSE", "GPL-2", }, }, { "three licenses and/or separated", "GPL-1+ or Artistic, and BSD-4-clause-POWERDOG", []string{ "GPL-1+", "Artistic", "BSD-4-clause-POWERDOG", }, }, { "two licenses with version", "Apache License,Version 2.0, OSET Public License version 2.1", []string{ "Apache License, Version 2.0", "OSET Public License version 2.1", }, }, { "the license starts with `ver`", "verbatim and BSD-4-clause", []string{ "verbatim", "BSD-4-clause", }, }, { "the license with `or later`", "GNU Affero General Public License v3 or later (AGPLv3+)", []string{ "GNU Affero General Public License v3 or later (AGPLv3+)", }, }, { "Python license exceptions", "GNU Library or Lesser General Public License (LGPL), Common Development and Distribution License 1.0 (CDDL-1.0), Historical Permission Notice and Disclaimer (HPND)", []string{ "GNU Library or Lesser General Public License (LGPL)", "Common Development and Distribution License 1.0 (CDDL-1.0)", "Historical Permission Notice and Disclaimer (HPND)", }, }, { name: "License text", license: "* Permission to use this software in any way is granted without", licenses: []string{ "text://* Permission to use this software in any way is granted without", }, }, } for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { res := licensing.SplitLicenses(tt.license) assert.Equal(t, tt.licenses, res) }) } } func TestLaxSplitLicense(t *testing.T) { var tests = []struct { license string wantLicenses []string }{ { license: "ASL 2.0", wantLicenses: []string{"Apache-2.0"}, }, { license: "MPL 2.0 GPL2+", wantLicenses: []string{ "MPL-2.0", "GPL-2.0-or-later", }, }, { license: "GPL-2.0-only WITH Classpath-exception-2.0", wantLicenses: []string{ "GPL-2.0-only WITH Classpath-exception-2.0", }, }, { license: "BSD-3-CLAUSE OR GPL-2.0-only WITH Classpath-exception-2.0 AND MPL-2.0 ASL 2.0", wantLicenses: []string{ "BSD-3-Clause", "GPL-2.0-only WITH Classpath-exception-2.0", "MPL-2.0", "Apache-2.0", }, }, } for _, tt := range tests { t.Run(tt.license, func(t *testing.T) { parsed := licensing.LaxSplitLicenses(tt.license) assert.Equal(t, tt.wantLicenses, parsed) }) } } // All map keys must be standardized to be matched // (uppercase, no common suffixes, standardized version, etc.) func TestMap(t *testing.T) { for key := range licensing.Mapping() { t.Run(key, func(t *testing.T) { standardized := licensing.StandardizeKeyAndSuffix(key) assert.Equal(t, standardized.License, key) }) } } func TestNormalize(t *testing.T) { tests := []struct { licenses []expression.Expression want string wantLicense expression.Expression }{ { licenses: []expression.Expression{ expression.SimpleExpr{License: " the apache license "}, expression.SimpleExpr{License: " the\tapache \r\nlicense \r\n "}, expression.SimpleExpr{License: " apache "}, expression.SimpleExpr{License: "ApacheLicence"}, expression.SimpleExpr{License: "ApacheLicense"}, expression.SimpleExpr{License: "al-2"}, expression.SimpleExpr{License: "al-v2"}, expression.SimpleExpr{License: "al2"}, expression.SimpleExpr{License: "alv2"}, expression.SimpleExpr{License: "apache - v 2.0"}, expression.SimpleExpr{License: "apache - v. 2.0"}, expression.SimpleExpr{License: "apache - ver 2.0"}, expression.SimpleExpr{License: "apache - version 2.0"}, expression.SimpleExpr{License: "apache 2"}, expression.SimpleExpr{License: "apache 2.0"}, expression.SimpleExpr{License: "apache license (2.0)"}, expression.SimpleExpr{License: "apache license (v. 2)"}, expression.SimpleExpr{License: "apache license (v. 2.0)"}, expression.SimpleExpr{License: "apache license (v2)"}, expression.SimpleExpr{License: "apache license (v2.0)"}, expression.SimpleExpr{License: "apache license (version 2.0)"}, expression.SimpleExpr{License: "apache license 2"}, expression.SimpleExpr{License: "apache license 2.0"}, expression.SimpleExpr{License: "apache license v2"}, expression.SimpleExpr{License: "apache license v2.0"}, expression.SimpleExpr{License: "apache license version 2"}, expression.SimpleExpr{License: "apache license version 2.0"}, expression.SimpleExpr{License: "apache license"}, expression.SimpleExpr{License: "apache license, 2.0"}, expression.SimpleExpr{License: "apache license, asl version 2.0"}, expression.SimpleExpr{License: "apache license, version 2"}, expression.SimpleExpr{License: "apache license, version 2.0 (http://www.apache.org/licenses/license-2.0)"}, expression.SimpleExpr{License: "apache license, version 2.0"}, expression.SimpleExpr{License: "apache license,version 2.0"}, expression.SimpleExpr{License: "apache license,version-2.0"}, expression.SimpleExpr{License: "apache license-2.0"}, expression.SimpleExpr{License: "apache public 2.0"}, expression.SimpleExpr{License: "apache public license 2.0"}, expression.SimpleExpr{License: "apache public license-2.0"}, expression.SimpleExpr{License: "apache public-2"}, expression.SimpleExpr{License: "apache public-2.0"}, expression.SimpleExpr{License: "apache software license (apache-2.0)"}, expression.SimpleExpr{License: "apache software license - version 2.0"}, expression.SimpleExpr{License: "apache software license 2.0"}, expression.SimpleExpr{License: "apache software license, version 2"}, expression.SimpleExpr{License: "apache software license, version 2.0"}, expression.SimpleExpr{License: "apache software-2.0"}, expression.SimpleExpr{License: "apache v 2.0"}, expression.SimpleExpr{License: "apache v. 2.0"}, expression.SimpleExpr{License: "apache v2"}, expression.SimpleExpr{License: "apache v2.0"}, expression.SimpleExpr{License: "apache ver 2.0"}, expression.SimpleExpr{License: "apache ver. 2.0"}, expression.SimpleExpr{License: "apache version 2.0"}, expression.SimpleExpr{License: "apache version 2.0, january 2004"}, expression.SimpleExpr{License: "apache version-2"}, expression.SimpleExpr{License: "apache version-2.0"}, expression.SimpleExpr{License: "apache"}, expression.SimpleExpr{License: "apache, 2"}, expression.SimpleExpr{License: "apache, v2.0"}, expression.SimpleExpr{License: "apache, version 2"}, expression.SimpleExpr{License: "apache, version 2.0"}, expression.SimpleExpr{License: "apache-2"}, expression.SimpleExpr{License: "apache-2.0"}, expression.SimpleExpr{License: "apache-licence"}, expression.SimpleExpr{License: "apache-license"}, expression.SimpleExpr{License: "apache-licensed"}, expression.SimpleExpr{License: "apache-licensed"}, expression.SimpleExpr{License: "asf 2.0"}, expression.SimpleExpr{License: "asl 2"}, expression.SimpleExpr{License: "asl, version 2"}, expression.SimpleExpr{License: "asl2.0"}, expression.SimpleExpr{License: "the apache license"}, expression.SimpleExpr{License: "the apache license"}, }, want: "Apache-2.0", wantLicense: expression.SimpleExpr{License: "Apache-2.0"}, }, { licenses: []expression.Expression{ expression.SimpleExpr{License: "Apache+"}, }, want: "Apache-2.0+", wantLicense: expression.SimpleExpr{License: "Apache-2.0", HasPlus: true}, }, { licenses: []expression.Expression{ expression.SimpleExpr{License: "COMMON DEVELOPMENT AND DISTRIBUTION LICENSE (CDDL) V1.1"}, expression.SimpleExpr{License: "COMMON DEVELOPMENT AND DISTRIBUTION LICENSE (CDDL) VERSION 1.1"}, expression.SimpleExpr{License: "COMMON DEVELOPMENT AND DISTRIBUTION LICENSE (CDDL), VERSION 1.1"}, expression.SimpleExpr{License: "COMMON DEVELOPMENT AND DISTRIBUTION LICENSE 1.1 (CDDL-1.1)"}, }, want: "CDDL-1.1", wantLicense: expression.SimpleExpr{License: "CDDL-1.1"}, }, { licenses: []expression.Expression{ expression.SimpleExpr{License: "ECLIPSE PUBLIC LICENSE (EPL) 1.0"}, expression.SimpleExpr{License: "ECLIPSE PUBLIC LICENSE (EPL), VERSION 1.0"}, expression.SimpleExpr{License: "ECLIPSE PUBLIC LICENSE - V 1.0"}, expression.SimpleExpr{License: "ECLIPSE PUBLIC LICENSE - V1.0"}, expression.SimpleExpr{License: "ECLIPSE PUBLIC LICENSE - VERSION 1.0"}, expression.SimpleExpr{License: "ECLIPSE PUBLIC LICENSE 1.0 (EPL-1.0)"}, expression.SimpleExpr{License: "ECLIPSE PUBLIC LICENSE 1.0"}, expression.SimpleExpr{License: "ECLIPSE PUBLIC LICENSE V. 1.0"}, expression.SimpleExpr{License: "ECLIPSE PUBLIC LICENSE V1.0"}, expression.SimpleExpr{License: "ECLIPSE PUBLIC LICENSE VERSION 1.0"}, expression.SimpleExpr{License: "ECLIPSE PUBLIC LICENSE, VERSION 1.0"}, expression.SimpleExpr{License: "ECLIPSE PUBLIC"}, }, want: "EPL-1.0", wantLicense: expression.SimpleExpr{License: "EPL-1.0"}, }, { licenses: []expression.Expression{ expression.SimpleExpr{License: "EUROPEAN UNION PUBLIC LICENSE (EUPL V.1.1)"}, expression.SimpleExpr{License: "EUROPEAN UNION PUBLIC LICENSE 1.1 (EUPL 1.1)"}, expression.SimpleExpr{License: "EUROPEAN UNION PUBLIC LICENSE 1.1"}, expression.SimpleExpr{License: "EUROPEAN UNION PUBLIC LICENSE, VERSION 1.1"}, }, want: "EUPL-1.1", wantLicense: expression.SimpleExpr{License: "EUPL-1.1"}, }, { licenses: []expression.Expression{ expression.SimpleExpr{License: "GPL-or-later"}, expression.SimpleExpr{License: "GPL+"}, expression.SimpleExpr{License: "GPL-2.0-only+"}, }, want: "GPL-2.0-or-later", wantLicense: expression.SimpleExpr{License: "GPL-2.0", HasPlus: true}, }, { licenses: []expression.Expression{ expression.SimpleExpr{License: "GPL (≥ 3)"}, expression.SimpleExpr{License: "GPL3+"}, expression.SimpleExpr{License: "GPL3-or-later"}, expression.SimpleExpr{License: "GPL3 or later licence"}, }, want: "GPL-3.0-or-later", wantLicense: expression.SimpleExpr{License: "GPL-3.0", HasPlus: true}, }, { licenses: []expression.Expression{ expression.SimpleExpr{License: "GNU GENERAL PUBLIC LICENSE 3"}, expression.SimpleExpr{License: "GNU GENERAL PUBLIC LICENSE (GPL) V. 3"}, expression.SimpleExpr{License: "GNU GENERAL PUBLIC LICENSE VERSION 3 (GPL V3)"}, }, want: "GPL-3.0-only", wantLicense: expression.SimpleExpr{License: "GPL-3.0"}, }, { licenses: []expression.Expression{ expression.SimpleExpr{License: "LGPL LICENSE-3"}, expression.SimpleExpr{License: "GNU LESSER GENERAL PUBLIC LICENSE V3"}, expression.SimpleExpr{License: "GNU LESSER GENERAL PUBLIC LICENSE V3.0"}, expression.SimpleExpr{License: "GNU LESSER GENERAL PUBLIC LICENSE VERSION 3"}, expression.SimpleExpr{License: "GNU LESSER GENERAL PUBLIC LICENSE VERSION 3.0"}, expression.SimpleExpr{License: "GNU LESSER GENERAL PUBLIC LICENSE, VERSION 3.0"}, expression.SimpleExpr{License: "GNU LIBRARY OR LESSER GENERAL PUBLIC LICENSE VERSION 3.0 (LGPLV3)"}, expression.SimpleExpr{License: "GNU GENERAL LESSER PUBLIC LICENSE (LGPL) VERSION 3.0"}, expression.SimpleExpr{License: "GNU LESSER GENERAL PUBLIC LICENSE (LGPL), VERSION 3"}, }, want: "LGPL-3.0-only", wantLicense: expression.SimpleExpr{License: "LGPL-3.0"}, }, { licenses: []expression.Expression{ expression.SimpleExpr{License: "The Unlicense"}, expression.SimpleExpr{License: "Unlicense"}, expression.SimpleExpr{License: "UNLICENSE"}, }, want: "Unlicense", wantLicense: expression.SimpleExpr{License: "Unlicense"}, }, { licenses: []expression.Expression{ expression.SimpleExpr{License: "MIT License"}, expression.SimpleExpr{License: "http://json.codeplex.com/license"}, }, want: "MIT", wantLicense: expression.SimpleExpr{License: "MIT"}, }, { licenses: []expression.Expression{ expression.SimpleExpr{License: " The unmapped license "}, }, want: "The unmapped license", wantLicense: expression.SimpleExpr{License: "The unmapped license"}, }, { licenses: []expression.Expression{ expression.SimpleExpr{License: "Universal Permissive License, Version 1.0"}, }, want: "UPL-1.0", wantLicense: expression.SimpleExpr{License: "UPL-1.0"}, }, { licenses: []expression.Expression{ expression.SimpleExpr{License: "GPLv2 WITH EXCEPTIONS"}, expression.NewCompoundExpr( // "GPLv2 WITH EXCEPTIONS" expression.SimpleExpr{License: "GPLv2"}, expression.TokenWith, expression.SimpleExpr{License: "EXCEPTIONS"}, ), }, want: "GPL-2.0-with-classpath-exception", wantLicense: expression.SimpleExpr{License: "GPL-2.0-with-classpath-exception"}, }, // Test canonical SPDX license casing { licenses: []expression.Expression{ expression.SimpleExpr{License: "Tcl"}, expression.SimpleExpr{License: "tcl"}, expression.SimpleExpr{License: "TCL"}, }, want: "TCL", wantLicense: expression.SimpleExpr{License: "TCL"}, }, } for _, tt := range tests { t.Run(tt.want, func(t *testing.T) { for _, ll := range tt.licenses { got := licensing.NormalizeLicense(ll.String()) gotLicense := licensing.NormalizeLicenseExpression(ll) assert.Equal(t, tt.want, got) assert.Equal(t, tt.wantLicense, gotLicense) } }) } }