mirror of
https://github.com/aquasecurity/trivy.git
synced 2025-12-11 07:10:49 -08:00
Compare commits
16 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
936f06a578 | ||
|
|
f72d2bce8d | ||
|
|
289636758e | ||
|
|
b733ecc7bc | ||
|
|
7326db14af | ||
|
|
03160e4fd1 | ||
|
|
8b930816bc | ||
|
|
18cd1a59cb | ||
|
|
1bde3df0ee | ||
|
|
90f9e884fd | ||
|
|
33818e121f | ||
|
|
89b341f0c6 | ||
|
|
f842fe1675 | ||
|
|
d52542f3b5 | ||
|
|
9a56e7cd69 | ||
|
|
4278a09f59 |
@@ -1 +1 @@
|
||||
{".":"0.58.0"}
|
||||
{".":"0.58.2"}
|
||||
|
||||
23
CHANGELOG.md
23
CHANGELOG.md
@@ -1,5 +1,28 @@
|
||||
# Changelog
|
||||
|
||||
## [0.58.2](https://github.com/aquasecurity/trivy/compare/v0.58.1...v0.58.2) (2025-01-13)
|
||||
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* CVE-2025-21613 and CVE-2025-21614 : go-git: argument injection via the URL field [backport: release/v0.58] ([#8215](https://github.com/aquasecurity/trivy/issues/8215)) ([b733ecc](https://github.com/aquasecurity/trivy/commit/b733ecc7bc752d61837d08f2650bd480b645bb1d))
|
||||
* **misconf:** allow null values only for tf variables [backport: release/v0.58] ([#8238](https://github.com/aquasecurity/trivy/issues/8238)) ([f72d2bc](https://github.com/aquasecurity/trivy/commit/f72d2bce8d3418dbcb670434bc15bb857b421f98))
|
||||
* **suse:** SUSE - update OSType constants and references for compatility [backport: release/v0.58] ([#8237](https://github.com/aquasecurity/trivy/issues/8237)) ([2896367](https://github.com/aquasecurity/trivy/commit/289636758eccf990f36ea2be34f6db2c02cfab6b))
|
||||
|
||||
## [0.58.1](https://github.com/aquasecurity/trivy/compare/v0.58.0...v0.58.1) (2024-12-24)
|
||||
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* handle `BLOW_UNKNOWN` error to download DBs [backport: release/v0.58] ([#8121](https://github.com/aquasecurity/trivy/issues/8121)) ([9a56e7c](https://github.com/aquasecurity/trivy/commit/9a56e7cd6964ffd4187a8e44a36d49b54587db56))
|
||||
* **java:** correctly overwrite version from depManagement if dependency uses `project.*` props [backport: release/v0.58] ([#8119](https://github.com/aquasecurity/trivy/issues/8119)) ([4278a09](https://github.com/aquasecurity/trivy/commit/4278a09f59590ee16494e0a1ad31fb374f2e243f))
|
||||
* **oracle:** add architectures support for advisories [backport: release/v0.58] ([#8125](https://github.com/aquasecurity/trivy/issues/8125)) ([89b341f](https://github.com/aquasecurity/trivy/commit/89b341f0c6dc7f24239f9a9e4809524ec289a864))
|
||||
* **python:** skip dev group's deps for poetry [backport: release/v0.58] ([#8158](https://github.com/aquasecurity/trivy/issues/8158)) ([8b93081](https://github.com/aquasecurity/trivy/commit/8b930816bc527166ced5d57754ad7fccb1cef832))
|
||||
* **redhat:** correct rewriting of recommendations for the same vulnerability [backport: release/v0.58] ([#8135](https://github.com/aquasecurity/trivy/issues/8135)) ([33818e1](https://github.com/aquasecurity/trivy/commit/33818e121f989fd12c15aa65affd2d01b867db61))
|
||||
* **sbom:** attach nested packages to Application [backport: release/v0.58] ([#8168](https://github.com/aquasecurity/trivy/issues/8168)) ([03160e4](https://github.com/aquasecurity/trivy/commit/03160e4fd1b0a6aef8c4f3d96529e68fed7e70ee))
|
||||
* **sbom:** fix wrong overwriting of applications obtained from different sbom files but having same app type [backport: release/v0.58] ([#8124](https://github.com/aquasecurity/trivy/issues/8124)) ([f842fe1](https://github.com/aquasecurity/trivy/commit/f842fe1675b434e72a8194628525c42fd3e155af))
|
||||
* **sbom:** use root package for `unknown` dependencies (if exists) [backport: release/v0.58] ([#8156](https://github.com/aquasecurity/trivy/issues/8156)) ([18cd1a5](https://github.com/aquasecurity/trivy/commit/18cd1a59cbb32d87371fe8ab24497f06855e0c80))
|
||||
|
||||
## [0.58.0](https://github.com/aquasecurity/trivy/compare/v0.57.0...v0.58.0) (2024-12-02)
|
||||
|
||||
|
||||
|
||||
26
go.mod
26
go.mod
@@ -7,7 +7,7 @@ require (
|
||||
github.com/Azure/azure-sdk-for-go/sdk/azcore v1.16.0
|
||||
github.com/Azure/azure-sdk-for-go/sdk/azidentity v1.8.0
|
||||
github.com/BurntSushi/toml v1.4.0
|
||||
github.com/CycloneDX/cyclonedx-go v0.9.1
|
||||
github.com/CycloneDX/cyclonedx-go v0.9.2
|
||||
github.com/GoogleCloudPlatform/docker-credential-gcr v2.0.5+incompatible
|
||||
github.com/Masterminds/sprig/v3 v3.3.0
|
||||
github.com/NYTimes/gziphandler v1.1.1
|
||||
@@ -24,7 +24,7 @@ require (
|
||||
github.com/aquasecurity/testdocker v0.0.0-20240730042311-4642e94c7fc8
|
||||
github.com/aquasecurity/tml v0.6.1
|
||||
github.com/aquasecurity/trivy-checks v1.4.0
|
||||
github.com/aquasecurity/trivy-db v0.0.0-20241120092622-333d808d7e45
|
||||
github.com/aquasecurity/trivy-db v0.0.0-20241209111357-8c398f13db0e
|
||||
github.com/aquasecurity/trivy-java-db v0.0.0-20240109071736-184bd7481d48
|
||||
github.com/aquasecurity/trivy-kubernetes v0.6.7-0.20241101182546-89bffc3932bc
|
||||
github.com/aws/aws-sdk-go-v2 v1.32.5
|
||||
@@ -46,7 +46,7 @@ require (
|
||||
github.com/docker/docker v27.3.1+incompatible
|
||||
github.com/docker/go-connections v0.5.0
|
||||
github.com/fatih/color v1.18.0
|
||||
github.com/go-git/go-git/v5 v5.12.0
|
||||
github.com/go-git/go-git/v5 v5.13.1
|
||||
github.com/go-openapi/runtime v0.28.0 // indirect
|
||||
github.com/go-openapi/strfmt v0.23.0 // indirect
|
||||
github.com/go-redis/redis/v8 v8.11.5
|
||||
@@ -119,13 +119,13 @@ require (
|
||||
github.com/zclconf/go-cty v1.15.0
|
||||
github.com/zclconf/go-cty-yaml v1.1.0
|
||||
go.etcd.io/bbolt v1.3.11
|
||||
golang.org/x/crypto v0.29.0
|
||||
golang.org/x/crypto v0.31.0
|
||||
golang.org/x/exp v0.0.0-20241009180824-f66d83c29e7c // indirect
|
||||
golang.org/x/mod v0.22.0
|
||||
golang.org/x/net v0.31.0
|
||||
golang.org/x/sync v0.9.0
|
||||
golang.org/x/term v0.26.0
|
||||
golang.org/x/text v0.20.0
|
||||
golang.org/x/net v0.33.0
|
||||
golang.org/x/sync v0.10.0
|
||||
golang.org/x/term v0.27.0
|
||||
golang.org/x/text v0.21.0
|
||||
golang.org/x/vuln v1.1.3
|
||||
golang.org/x/xerrors v0.0.0-20231012003039-104605ab7028
|
||||
google.golang.org/protobuf v1.35.2
|
||||
@@ -164,7 +164,7 @@ require (
|
||||
github.com/Microsoft/go-winio v0.6.2 // indirect
|
||||
github.com/Microsoft/hcsshim v0.12.9 // indirect
|
||||
github.com/OneOfOne/xxhash v1.2.8 // indirect
|
||||
github.com/ProtonMail/go-crypto v1.1.0-alpha.2 // indirect
|
||||
github.com/ProtonMail/go-crypto v1.1.3 // indirect
|
||||
github.com/VividCortex/ewma v1.2.0 // indirect
|
||||
github.com/agext/levenshtein v1.2.3 // indirect
|
||||
github.com/agnivade/levenshtein v1.2.0 // indirect
|
||||
@@ -206,7 +206,7 @@ require (
|
||||
github.com/cpuguy83/dockercfg v0.3.2 // indirect
|
||||
github.com/cpuguy83/go-md2man/v2 v2.0.5 // indirect
|
||||
github.com/cyberphone/json-canonicalization v0.0.0-20231011164504-785e29786b46 // indirect
|
||||
github.com/cyphar/filepath-securejoin v0.3.4 // indirect
|
||||
github.com/cyphar/filepath-securejoin v0.3.6 // indirect
|
||||
github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc // indirect
|
||||
github.com/dgryski/go-rendezvous v0.0.0-20200823014737-9f7001d12a5f // indirect
|
||||
github.com/digitorus/pkcs7 v0.0.0-20230818184609-3a137a874352 // indirect
|
||||
@@ -229,7 +229,7 @@ require (
|
||||
github.com/go-chi/chi v4.1.2+incompatible // indirect
|
||||
github.com/go-errors/errors v1.4.2 // indirect
|
||||
github.com/go-git/gcfg v1.5.1-0.20230307220236-3a3c6141e376 // indirect
|
||||
github.com/go-git/go-billy/v5 v5.6.0 // indirect
|
||||
github.com/go-git/go-billy/v5 v5.6.1 // indirect
|
||||
github.com/go-gorp/gorp/v3 v3.1.0 // indirect
|
||||
github.com/go-ini/ini v1.67.0 // indirect
|
||||
github.com/go-logr/logr v1.4.2 // indirect
|
||||
@@ -350,7 +350,7 @@ require (
|
||||
github.com/sigstore/cosign/v2 v2.2.4 // indirect
|
||||
github.com/sigstore/sigstore v1.8.3 // indirect
|
||||
github.com/sigstore/timestamp-authority v1.2.2 // indirect
|
||||
github.com/skeema/knownhosts v1.2.2 // indirect
|
||||
github.com/skeema/knownhosts v1.3.0 // indirect
|
||||
github.com/sourcegraph/conc v0.3.0 // indirect
|
||||
github.com/spf13/afero v1.11.0 // indirect
|
||||
github.com/stretchr/objx v0.5.2 // indirect
|
||||
@@ -388,7 +388,7 @@ require (
|
||||
go.uber.org/multierr v1.11.0 // indirect
|
||||
go.uber.org/zap v1.27.0 // indirect
|
||||
golang.org/x/oauth2 v0.22.0 // indirect
|
||||
golang.org/x/sys v0.27.0 // indirect
|
||||
golang.org/x/sys v0.28.0 // indirect
|
||||
golang.org/x/telemetry v0.0.0-20240522233618-39ace7a40ae7 // indirect
|
||||
golang.org/x/time v0.7.0 // indirect
|
||||
golang.org/x/tools v0.26.0 // indirect
|
||||
|
||||
64
go.sum
64
go.sum
@@ -245,8 +245,8 @@ github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03
|
||||
github.com/BurntSushi/toml v1.4.0 h1:kuoIxZQy2WRRk1pttg9asf+WVv6tWQuBNVmK8+nqPr0=
|
||||
github.com/BurntSushi/toml v1.4.0/go.mod h1:ukJfTF/6rtPPRCnwkur4qwRxa8vTRFBF0uk2lLoLwho=
|
||||
github.com/BurntSushi/xgb v0.0.0-20160522181843-27f122750802/go.mod h1:IVnqGOEym/WlBOVXweHU+Q+/VP0lqqI8lqeDx9IjBqo=
|
||||
github.com/CycloneDX/cyclonedx-go v0.9.1 h1:yffaWOZsv77oTJa/SdVZYdgAgFioCeycBUKkqS2qzQM=
|
||||
github.com/CycloneDX/cyclonedx-go v0.9.1/go.mod h1:NE/EWvzELOFlG6+ljX/QeMlVt9VKcTwu8u0ccsACEsw=
|
||||
github.com/CycloneDX/cyclonedx-go v0.9.2 h1:688QHn2X/5nRezKe2ueIVCt+NRqf7fl3AVQk+vaFcIo=
|
||||
github.com/CycloneDX/cyclonedx-go v0.9.2/go.mod h1:vcK6pKgO1WanCdd61qx4bFnSsDJQ6SbM2ZuMIgq86Jg=
|
||||
github.com/DATA-DOG/go-sqlmock v1.5.2 h1:OcvFkGmslmlZibjAjaHm3L//6LiuBgolP7OputlJIzU=
|
||||
github.com/DATA-DOG/go-sqlmock v1.5.2/go.mod h1:88MAG/4G7SMwSE3CeA0ZKzrT5CiOU3OJ+JlNzwDqpNU=
|
||||
github.com/DataDog/zstd v1.5.5 h1:oWf5W7GtOLgp6bciQYDmhHHjdhYkALu6S/5Ni9ZgSvQ=
|
||||
@@ -277,8 +277,8 @@ github.com/NYTimes/gziphandler v1.1.1/go.mod h1:n/CVRwUEOgIxrgPvAQhUUr9oeUtvrhMo
|
||||
github.com/OneOfOne/xxhash v1.2.2/go.mod h1:HSdplMjZKSmBqAxg5vPj2TmRDmfkzw+cTzAElWljhcU=
|
||||
github.com/OneOfOne/xxhash v1.2.8 h1:31czK/TI9sNkxIKfaUfGlU47BAxQ0ztGgd9vPyqimf8=
|
||||
github.com/OneOfOne/xxhash v1.2.8/go.mod h1:eZbhyaAYD41SGSSsnmcpxVoRiQ/MPUTjUdIIOT9Um7Q=
|
||||
github.com/ProtonMail/go-crypto v1.1.0-alpha.2 h1:bkyFVUP+ROOARdgCiJzNQo2V2kiB97LyUpzH9P6Hrlg=
|
||||
github.com/ProtonMail/go-crypto v1.1.0-alpha.2/go.mod h1:rA3QumHc/FZ8pAHreoekgiAbzpNsfQAosU5td4SnOrE=
|
||||
github.com/ProtonMail/go-crypto v1.1.3 h1:nRBOetoydLeUb4nHajyO2bKqMLfWQ/ZPwkXqXxPxCFk=
|
||||
github.com/ProtonMail/go-crypto v1.1.3/go.mod h1:rA3QumHc/FZ8pAHreoekgiAbzpNsfQAosU5td4SnOrE=
|
||||
github.com/Shopify/logrus-bugsnag v0.0.0-20171204204709-577dee27f20d h1:UrqY+r/OJnIp5u0s1SbQ8dVfLCZJsnvazdBP5hS4iRs=
|
||||
github.com/Shopify/logrus-bugsnag v0.0.0-20171204204709-577dee27f20d/go.mod h1:HI8ITrYtUY+O+ZhtlqUnD8+KwNPOyugEhfP9fdUIaEQ=
|
||||
github.com/ThalesIgnite/crypto11 v1.2.5 h1:1IiIIEqYmBvUYFeMnHqRft4bwf/O36jryEUpY+9ef8E=
|
||||
@@ -355,8 +355,8 @@ github.com/aquasecurity/tml v0.6.1 h1:y2ZlGSfrhnn7t4ZJ/0rotuH+v5Jgv6BDDO5jB6A9gw
|
||||
github.com/aquasecurity/tml v0.6.1/go.mod h1:OnYMWY5lvI9ejU7yH9LCberWaaTBW7hBFsITiIMY2yY=
|
||||
github.com/aquasecurity/trivy-checks v1.4.0 h1:XFGPuA8C4f31GO9g7xOkubHq4W87y9iXrWnulsIoZFs=
|
||||
github.com/aquasecurity/trivy-checks v1.4.0/go.mod h1:TSUbI3wBy9jgQl5lRUCR+B5pNiOxp6M26Jep8VCL/eM=
|
||||
github.com/aquasecurity/trivy-db v0.0.0-20241120092622-333d808d7e45 h1:ljinbg7JTQvdnzuRsPYS6btA51SyGYWKCQInxSIwbRw=
|
||||
github.com/aquasecurity/trivy-db v0.0.0-20241120092622-333d808d7e45/go.mod h1:Lg2avQhFy5qeGA0eMysI/61REVvWpEltverCarGc3l0=
|
||||
github.com/aquasecurity/trivy-db v0.0.0-20241209111357-8c398f13db0e h1:O5j5SeCNBrXApgBTOobO06q4LMxJxIhcSGE7H6Y154E=
|
||||
github.com/aquasecurity/trivy-db v0.0.0-20241209111357-8c398f13db0e/go.mod h1:gS8VhlNxhraiq60BBnJw9kGtjeMspQ9E8pX24jCL4jg=
|
||||
github.com/aquasecurity/trivy-java-db v0.0.0-20240109071736-184bd7481d48 h1:JVgBIuIYbwG+ekC5lUHUpGJboPYiCcxiz06RCtz8neI=
|
||||
github.com/aquasecurity/trivy-java-db v0.0.0-20240109071736-184bd7481d48/go.mod h1:Ldya37FLi0e/5Cjq2T5Bty7cFkzUDwTcPeQua+2M8i8=
|
||||
github.com/aquasecurity/trivy-kubernetes v0.6.7-0.20241101182546-89bffc3932bc h1:/mFBYIK9RY+L8s1CIbQbJ5B3v0YmoDSu5eAzavvMa+Y=
|
||||
@@ -525,8 +525,8 @@ github.com/creack/pty v1.1.23 h1:4M6+isWdcStXEf15G/RbrMPOQj1dZ7HPZCGwE4kOeP0=
|
||||
github.com/creack/pty v1.1.23/go.mod h1:08sCNb52WyoAwi2QDyzUCTgcvVFhUzewun7wtTfvcwE=
|
||||
github.com/cyberphone/json-canonicalization v0.0.0-20231011164504-785e29786b46 h1:2Dx4IHfC1yHWI12AxQDJM1QbRCDfk6M+blLzlZCXdrc=
|
||||
github.com/cyberphone/json-canonicalization v0.0.0-20231011164504-785e29786b46/go.mod h1:uzvlm1mxhHkdfqitSA92i7Se+S9ksOn3a3qmv/kyOCw=
|
||||
github.com/cyphar/filepath-securejoin v0.3.4 h1:VBWugsJh2ZxJmLFSM06/0qzQyiQX2Qs0ViKrUAcqdZ8=
|
||||
github.com/cyphar/filepath-securejoin v0.3.4/go.mod h1:8s/MCNJREmFK0H02MF6Ihv1nakJe4L/w3WZLHNkvlYM=
|
||||
github.com/cyphar/filepath-securejoin v0.3.6 h1:4d9N5ykBnSp5Xn2JkhocYDkOpURL/18CYMpo6xB9uWM=
|
||||
github.com/cyphar/filepath-securejoin v0.3.6/go.mod h1:Sdj7gXlvMcPZsbhwhQ33GguGLDGQL7h7bg04C/+u9jI=
|
||||
github.com/danieljoos/wincred v1.2.1 h1:dl9cBrupW8+r5250DYkYxocLeZ1Y4vB1kxgtjxw8GQs=
|
||||
github.com/danieljoos/wincred v1.2.1/go.mod h1:uGaFL9fDn3OLTvzCGulzE+SzjEe5NGlh5FdCcyfPwps=
|
||||
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
||||
@@ -577,8 +577,8 @@ github.com/dsnet/compress v0.0.1/go.mod h1:Aw8dCMJ7RioblQeTqt88akK31OvO8Dhf5Jflh
|
||||
github.com/dsnet/golib v0.0.0-20171103203638-1ea166775780/go.mod h1:Lj+Z9rebOhdfkVLjJ8T6VcRQv3SXugXy999NBtR9aFY=
|
||||
github.com/dustin/go-humanize v1.0.1 h1:GzkhY7T5VNhEkwH0PVJgjz+fX1rhBrR7pRT3mDkpeCY=
|
||||
github.com/dustin/go-humanize v1.0.1/go.mod h1:Mu1zIs6XwVuF/gI1OepvI0qD18qycQx+mFykh5fBlto=
|
||||
github.com/elazarl/goproxy v0.0.0-20230808193330-2592e75ae04a h1:mATvB/9r/3gvcejNsXKSkQ6lcIaNec2nyfOdlTBR2lU=
|
||||
github.com/elazarl/goproxy v0.0.0-20230808193330-2592e75ae04a/go.mod h1:Ro8st/ElPeALwNFlcTpWmkr6IoMFfkjXAvTHpevnDsM=
|
||||
github.com/elazarl/goproxy v1.2.3 h1:xwIyKHbaP5yfT6O9KIeYJR5549MXRQkoQMRXGztz8YQ=
|
||||
github.com/elazarl/goproxy v1.2.3/go.mod h1:YfEbZtqP4AetfO6d40vWchF3znWX7C7Vd6ZMfdL8z64=
|
||||
github.com/emicklei/go-restful/v3 v3.11.0 h1:rAQeMHw1c7zTmncogyy8VvRZwtkmkZ4FxERmMY4rD+g=
|
||||
github.com/emicklei/go-restful/v3 v3.11.0/go.mod h1:6n3XBCmQQb25CM2LCACGz8ukIrRry+4bhvbpWn3mrbc=
|
||||
github.com/emicklei/proto v1.12.1 h1:6n/Z2pZAnBwuhU66Gs8160B8rrrYKo7h2F2sCOnNceE=
|
||||
@@ -624,20 +624,20 @@ github.com/gabriel-vasile/mimetype v1.4.3/go.mod h1:d8uq/6HKRL6CGdk+aubisF/M5GcP
|
||||
github.com/ghodss/yaml v1.0.0/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeMEF04=
|
||||
github.com/glebarez/go-sqlite v1.20.3 h1:89BkqGOXR9oRmG58ZrzgoY/Fhy5x0M+/WV48U5zVrZ4=
|
||||
github.com/glebarez/go-sqlite v1.20.3/go.mod h1:u3N6D/wftiAzIOJtZl6BmedqxmmkDfH3q+ihjqxC9u0=
|
||||
github.com/gliderlabs/ssh v0.3.7 h1:iV3Bqi942d9huXnzEF2Mt+CY9gLu8DNM4Obd+8bODRE=
|
||||
github.com/gliderlabs/ssh v0.3.7/go.mod h1:zpHEXBstFnQYtGnB8k8kQLol82umzn/2/snG7alWVD8=
|
||||
github.com/gliderlabs/ssh v0.3.8 h1:a4YXD1V7xMF9g5nTkdfnja3Sxy1PVDCj1Zg4Wb8vY6c=
|
||||
github.com/gliderlabs/ssh v0.3.8/go.mod h1:xYoytBv1sV0aL3CavoDuJIQNURXkkfPA/wxQ1pL1fAU=
|
||||
github.com/go-chi/chi v4.1.2+incompatible h1:fGFk2Gmi/YKXk0OmGfBh0WgmN3XB8lVnEyNz34tQRec=
|
||||
github.com/go-chi/chi v4.1.2+incompatible/go.mod h1:eB3wogJHnLi3x/kFX2A+IbTBlXxmMeXJVKy9tTv1XzQ=
|
||||
github.com/go-errors/errors v1.4.2 h1:J6MZopCL4uSllY1OfXM374weqZFFItUbrImctkmUxIA=
|
||||
github.com/go-errors/errors v1.4.2/go.mod h1:sIVyrIiJhuEF+Pj9Ebtd6P/rEYROXFi3BopGUQ5a5Og=
|
||||
github.com/go-git/gcfg v1.5.1-0.20230307220236-3a3c6141e376 h1:+zs/tPmkDkHx3U66DAb0lQFJrpS6731Oaa12ikc+DiI=
|
||||
github.com/go-git/gcfg v1.5.1-0.20230307220236-3a3c6141e376/go.mod h1:an3vInlBmSxCcxctByoQdvwPiA7DTK7jaaFDBTtu0ic=
|
||||
github.com/go-git/go-billy/v5 v5.6.0 h1:w2hPNtoehvJIxR00Vb4xX94qHQi/ApZfX+nBE2Cjio8=
|
||||
github.com/go-git/go-billy/v5 v5.6.0/go.mod h1:sFDq7xD3fn3E0GOwUSZqHo9lrkmx8xJhA0ZrfvjBRGM=
|
||||
github.com/go-git/go-billy/v5 v5.6.1 h1:u+dcrgaguSSkbjzHwelEjc0Yj300NUevrrPphk/SoRA=
|
||||
github.com/go-git/go-billy/v5 v5.6.1/go.mod h1:0AsLr1z2+Uksi4NlElmMblP5rPcDZNRCD8ujZCRR2BE=
|
||||
github.com/go-git/go-git-fixtures/v4 v4.3.2-0.20231010084843-55a94097c399 h1:eMje31YglSBqCdIqdhKBW8lokaMrL3uTkpGYlE2OOT4=
|
||||
github.com/go-git/go-git-fixtures/v4 v4.3.2-0.20231010084843-55a94097c399/go.mod h1:1OCfN199q1Jm3HZlxleg+Dw/mwps2Wbk9frAWm+4FII=
|
||||
github.com/go-git/go-git/v5 v5.12.0 h1:7Md+ndsjrzZxbddRDZjF14qK+NN56sy6wkqaVrjZtys=
|
||||
github.com/go-git/go-git/v5 v5.12.0/go.mod h1:FTM9VKtnI2m65hNI/TenDDDnUf2Q9FHnXYjuz9i5OEY=
|
||||
github.com/go-git/go-git/v5 v5.13.1 h1:DAQ9APonnlvSWpvolXWIuV6Q6zXy2wHbN4cVlNR5Q+M=
|
||||
github.com/go-git/go-git/v5 v5.13.1/go.mod h1:qryJB4cSBoq3FRoBRf5A77joojuBcmPJ0qu3XXXVixc=
|
||||
github.com/go-gl/glfw v0.0.0-20190409004039-e6da0acd62b1/go.mod h1:vR7hzQXu2zJy9AVAgeJqvqgH9Q5CA+iKCZ2gyEVpxRU=
|
||||
github.com/go-gl/glfw/v3.3/glfw v0.0.0-20191125211704-12ad95a8df72/go.mod h1:tQ2UAYgL5IevRw8kRxooKSPJfGvJ9fJQFa0TUsXzTg8=
|
||||
github.com/go-gl/glfw/v3.3/glfw v0.0.0-20200222043503-6f7a984d4dc4/go.mod h1:tQ2UAYgL5IevRw8kRxooKSPJfGvJ9fJQFa0TUsXzTg8=
|
||||
@@ -1295,8 +1295,8 @@ github.com/sirupsen/logrus v1.7.0/go.mod h1:yWOB1SBYBC5VeMP7gHvWumXLIWorT60ONWic
|
||||
github.com/sirupsen/logrus v1.8.1/go.mod h1:yWOB1SBYBC5VeMP7gHvWumXLIWorT60ONWic61uBYv0=
|
||||
github.com/sirupsen/logrus v1.9.3 h1:dueUQJ1C2q9oE3F7wvmSGAaVtTmUizReu6fjN8uqzbQ=
|
||||
github.com/sirupsen/logrus v1.9.3/go.mod h1:naHLuLoDiP4jHNo9R0sCBMtWGeIprob74mVsIT4qYEQ=
|
||||
github.com/skeema/knownhosts v1.2.2 h1:Iug2P4fLmDw9f41PB6thxUkNUkJzB5i+1/exaj40L3A=
|
||||
github.com/skeema/knownhosts v1.2.2/go.mod h1:xYbVRSPxqBZFrdmDyMmsOs+uX1UZC3nTN3ThzgDxUwo=
|
||||
github.com/skeema/knownhosts v1.3.0 h1:AM+y0rI04VksttfwjkSTNQorvGqmwATnvnAHpSgc0LY=
|
||||
github.com/skeema/knownhosts v1.3.0/go.mod h1:sPINvnADmT/qYH1kfv+ePMmOBTH6Tbl7b5LvTDjFK7M=
|
||||
github.com/skratchdot/open-golang v0.0.0-20200116055534-eef842397966 h1:JIAuq3EEf9cgbU6AtGPK4CTG3Zf6CKMNqf0MHTggAUA=
|
||||
github.com/skratchdot/open-golang v0.0.0-20200116055534-eef842397966/go.mod h1:sUM3LWHvSMaG192sy56D9F7CNvL7jUJVXoqM1QKLnog=
|
||||
github.com/sosedoff/gitkit v0.4.0 h1:opyQJ/h9xMRLsz2ca/2CRXtstePcpldiZN8DpLLF8Os=
|
||||
@@ -1348,8 +1348,8 @@ github.com/syndtr/goleveldb v1.0.1-0.20220721030215-126854af5e6d h1:vfofYNRScrDd
|
||||
github.com/syndtr/goleveldb v1.0.1-0.20220721030215-126854af5e6d/go.mod h1:RRCYJbIwD5jmqPI9XoAFR0OcDxqUctll6zUj/+B4S48=
|
||||
github.com/tchap/go-patricia/v2 v2.3.1 h1:6rQp39lgIYZ+MHmdEq4xzuk1t7OdC35z/xm0BGhTkes=
|
||||
github.com/tchap/go-patricia/v2 v2.3.1/go.mod h1:VZRHKAb53DLaG+nA9EaYYiaEx6YztwDlLElMsnSHD4k=
|
||||
github.com/terminalstatic/go-xsd-validate v0.1.5 h1:RqpJnf6HGE2CB/lZB1A8BYguk8uRtcvYAPLCF15qguo=
|
||||
github.com/terminalstatic/go-xsd-validate v0.1.5/go.mod h1:18lsvYFofBflqCrvo1umpABZ99+GneNTw2kEEc8UPJw=
|
||||
github.com/terminalstatic/go-xsd-validate v0.1.6 h1:TenYeQ3eY631qNi1/cTmLH/s2slHPRKTTHT+XSHkepo=
|
||||
github.com/terminalstatic/go-xsd-validate v0.1.6/go.mod h1:18lsvYFofBflqCrvo1umpABZ99+GneNTw2kEEc8UPJw=
|
||||
github.com/testcontainers/testcontainers-go v0.34.0 h1:5fbgF0vIN5u+nD3IWabQwRybuB4GY8G2HHgCkbMzMHo=
|
||||
github.com/testcontainers/testcontainers-go v0.34.0/go.mod h1:6P/kMkQe8yqPHfPWNulFGdFHTD8HB2vLq/231xY2iPQ=
|
||||
github.com/testcontainers/testcontainers-go/modules/localstack v0.34.0 h1:WkjVmea0XQyGTY10Er8fOsVjHQ77iJCmTExnx6fC3Tw=
|
||||
@@ -1494,8 +1494,8 @@ golang.org/x/crypto v0.0.0-20220722155217-630584e8d5aa/go.mod h1:IxCIyHEi3zRg3s0
|
||||
golang.org/x/crypto v0.6.0/go.mod h1:OFC/31mSvZgRz0V1QTNCzfAI1aIRzbiufJtkMIlEp58=
|
||||
golang.org/x/crypto v0.13.0/go.mod h1:y6Z2r+Rw4iayiXXAIxJIDAJ1zMW4yaTpebo8fPOliYc=
|
||||
golang.org/x/crypto v0.18.0/go.mod h1:R0j02AL6hcrfOiy9T4ZYp/rcWeMxM3L6QYxlOuEG1mg=
|
||||
golang.org/x/crypto v0.29.0 h1:L5SG1JTTXupVV3n6sUqMTeWbjAyfPwoda2DLX8J8FrQ=
|
||||
golang.org/x/crypto v0.29.0/go.mod h1:+F4F4N5hv6v38hfeYwTdx20oUvLLc+QfrE9Ax9HtgRg=
|
||||
golang.org/x/crypto v0.31.0 h1:ihbySMvVjLAeSH1IbfcRTkD/iNscyz8rGzjF/E5hV6U=
|
||||
golang.org/x/crypto v0.31.0/go.mod h1:kDsLvtWBEx7MV9tJOj9bnXsPbxwJQ6csT/x4KIN4Ssk=
|
||||
golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
|
||||
golang.org/x/exp v0.0.0-20190306152737-a1d7652674e8/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
|
||||
golang.org/x/exp v0.0.0-20190510132918-efd6b22b2522/go.mod h1:ZjyILWgesfNpC6sMxTJOJm9Kp84zZh5NQWvqDGG3Qr8=
|
||||
@@ -1597,8 +1597,8 @@ golang.org/x/net v0.7.0/go.mod h1:2Tu9+aMcznHK/AK1HMvgo6xiTLG5rD5rZLDS+rp2Bjs=
|
||||
golang.org/x/net v0.10.0/go.mod h1:0qNGK6F8kojg2nk9dLZ2mShWaEBan6FAoqfSigmmuDg=
|
||||
golang.org/x/net v0.15.0/go.mod h1:idbUs1IY1+zTqbi8yxTbhexhEEk5ur9LInksu6HrEpk=
|
||||
golang.org/x/net v0.20.0/go.mod h1:z8BVo6PvndSri0LbOE3hAn0apkU+1YvI6E70E9jsnvY=
|
||||
golang.org/x/net v0.31.0 h1:68CPQngjLL0r2AlUKiSxtQFKvzRVbnzLwMUn5SzcLHo=
|
||||
golang.org/x/net v0.31.0/go.mod h1:P4fl1q7dY2hnZFxEk4pPSkDHF+QqjitcnDjUQyMM+pM=
|
||||
golang.org/x/net v0.33.0 h1:74SYHlV8BIgHIFC/LrYkOGIwL19eTYXQ5wc6TBuO36I=
|
||||
golang.org/x/net v0.33.0/go.mod h1:HXLR5J+9DxmrqMwG9qjGCxZ+zKXxBru04zlTvWlWuN4=
|
||||
golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U=
|
||||
golang.org/x/oauth2 v0.0.0-20190226205417-e64efc72b421/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
|
||||
golang.org/x/oauth2 v0.0.0-20190604053449-0f29369cfe45/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
|
||||
@@ -1643,8 +1643,8 @@ golang.org/x/sync v0.0.0-20220929204114-8fcdb60fdcc0/go.mod h1:RxMgew5VJxzue5/jJ
|
||||
golang.org/x/sync v0.1.0/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sync v0.3.0/go.mod h1:FU7BRWz2tNW+3quACPkgCx/L+uEAv1htQ0V83Z9Rj+Y=
|
||||
golang.org/x/sync v0.6.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk=
|
||||
golang.org/x/sync v0.9.0 h1:fEo0HyrW1GIgZdpbhCRO0PkJajUS5H9IFUztCgEo2jQ=
|
||||
golang.org/x/sync v0.9.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk=
|
||||
golang.org/x/sync v0.10.0 h1:3NQrjDixjgGwUOCaF8w2+VYHv0Ve/vGYSbdkTa98gmQ=
|
||||
golang.org/x/sync v0.10.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk=
|
||||
golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||
golang.org/x/sys v0.0.0-20180905080454-ebe1bf3edb33/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||
golang.org/x/sys v0.0.0-20180909124046-d0be0721c37e/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||
@@ -1735,8 +1735,8 @@ golang.org/x/sys v0.11.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.12.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.16.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
|
||||
golang.org/x/sys v0.17.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
|
||||
golang.org/x/sys v0.27.0 h1:wBqf8DvsY9Y/2P8gAfPDEYNuS30J4lPHJxXSb/nJZ+s=
|
||||
golang.org/x/sys v0.27.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
|
||||
golang.org/x/sys v0.28.0 h1:Fksou7UEQUWlKvIdsqzJmUmCX3cZuD2+P3XyyzwMhlA=
|
||||
golang.org/x/sys v0.28.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
|
||||
golang.org/x/telemetry v0.0.0-20240522233618-39ace7a40ae7 h1:FemxDzfMUcK2f3YY4H+05K9CDzbSVr2+q/JKN45pey0=
|
||||
golang.org/x/telemetry v0.0.0-20240522233618-39ace7a40ae7/go.mod h1:pRgIJT+bRLFKnoM1ldnzKoxTIn14Yxz928LQRYYgIN0=
|
||||
golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
|
||||
@@ -1747,8 +1747,8 @@ golang.org/x/term v0.5.0/go.mod h1:jMB1sMXY+tzblOD4FWmEbocvup2/aLOaQEp7JmGp78k=
|
||||
golang.org/x/term v0.8.0/go.mod h1:xPskH00ivmX89bAKVGSKKtLOWNx2+17Eiy94tnKShWo=
|
||||
golang.org/x/term v0.12.0/go.mod h1:owVbMEjm3cBLCHdkQu9b1opXd4ETQWc3BhuQGKgXgvU=
|
||||
golang.org/x/term v0.16.0/go.mod h1:yn7UURbUtPyrVJPGPq404EukNFxcm/foM+bV/bfcDsY=
|
||||
golang.org/x/term v0.26.0 h1:WEQa6V3Gja/BhNxg540hBip/kkaYtRg3cxg4oXSw4AU=
|
||||
golang.org/x/term v0.26.0/go.mod h1:Si5m1o57C5nBNQo5z1iq+XDijt21BDBDp2bK0QI8e3E=
|
||||
golang.org/x/term v0.27.0 h1:WP60Sv1nlK1T6SupCHbXzSaN0b9wUmsPoRS9b61A23Q=
|
||||
golang.org/x/term v0.27.0/go.mod h1:iMsnZpn0cago0GOrHO2+Y7u7JPn5AylBrcoWkElMTSM=
|
||||
golang.org/x/text v0.0.0-20170915032832-14c0d48ead0c/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
|
||||
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
|
||||
golang.org/x/text v0.3.1-0.20180807135948-17ff2d5776d2/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
|
||||
@@ -1763,8 +1763,8 @@ golang.org/x/text v0.7.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8=
|
||||
golang.org/x/text v0.9.0/go.mod h1:e1OnstbJyHTd6l/uOt8jFFHp6TRDWZR/bV3emEE/zU8=
|
||||
golang.org/x/text v0.13.0/go.mod h1:TvPlkZtksWOMsz7fbANvkp4WM8x/WCo/om8BMLbz+aE=
|
||||
golang.org/x/text v0.14.0/go.mod h1:18ZOQIKpY8NJVqYksKHtTdi31H5itFRjB5/qKTNYzSU=
|
||||
golang.org/x/text v0.20.0 h1:gK/Kv2otX8gz+wn7Rmb3vT96ZwuoxnQlY+HlJVj7Qug=
|
||||
golang.org/x/text v0.20.0/go.mod h1:D4IsuqiFMhST5bX19pQ9ikHC2GsaKyk/oF+pn3ducp4=
|
||||
golang.org/x/text v0.21.0 h1:zyQAAkrwaneQ066sspRyJaG9VNi/YJ1NfzcGB3hZ/qo=
|
||||
golang.org/x/text v0.21.0/go.mod h1:4IBbMaMmOPCJ8SecivzSH54+73PCFmPWxNTLm+vZkEQ=
|
||||
golang.org/x/time v0.0.0-20181108054448-85acf8d2951c/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
|
||||
golang.org/x/time v0.0.0-20190308202827-9d24e82272b4/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
|
||||
golang.org/x/time v0.0.0-20191024005414-555d28b269f0/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
|
||||
|
||||
6
integration/testdata/fixtures/db/oracle.yaml
vendored
6
integration/testdata/fixtures/db/oracle.yaml
vendored
@@ -7,8 +7,14 @@
|
||||
FixedVersion: "7.61.1-11.el8"
|
||||
Entries:
|
||||
- FixedVersion: "7.61.1-11.el8"
|
||||
Arches:
|
||||
- x86_64
|
||||
- aarch64
|
||||
- key: CVE-2019-5436
|
||||
value:
|
||||
FixedVersion: "7.61.1-12.el8"
|
||||
Entries:
|
||||
- FixedVersion: "7.61.1-12.el8"
|
||||
Arches:
|
||||
- x86_64
|
||||
- aarch64
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
5
integration/testdata/julia-spdx.json.golden
vendored
5
integration/testdata/julia-spdx.json.golden
vendored
@@ -154,11 +154,6 @@
|
||||
"relatedSpdxElement": "SPDXRef-Package-7784b00da0cb0cb0",
|
||||
"relationshipType": "CONTAINS"
|
||||
},
|
||||
{
|
||||
"spdxElementId": "SPDXRef-Application-18fc3597717a3e56",
|
||||
"relatedSpdxElement": "SPDXRef-Package-960543ac5c5f7e10",
|
||||
"relationshipType": "CONTAINS"
|
||||
},
|
||||
{
|
||||
"spdxElementId": "SPDXRef-Application-18fc3597717a3e56",
|
||||
"relatedSpdxElement": "SPDXRef-Package-a4705eb108e4f15c",
|
||||
|
||||
10
integration/testdata/npm-cyclonedx.json.golden
vendored
10
integration/testdata/npm-cyclonedx.json.golden
vendored
@@ -294,18 +294,10 @@
|
||||
{
|
||||
"ref": "3ff14136-e09f-4df9-80ea-000000000002",
|
||||
"dependsOn": [
|
||||
"pkg:npm/asap@2.0.6",
|
||||
"pkg:npm/jquery@3.3.9",
|
||||
"pkg:npm/js-tokens@4.0.0",
|
||||
"pkg:npm/loose-envify@1.4.0",
|
||||
"pkg:npm/object-assign@4.1.1",
|
||||
"pkg:npm/promise@8.0.3",
|
||||
"pkg:npm/prop-types@15.7.2",
|
||||
"pkg:npm/react-is@16.8.6",
|
||||
"pkg:npm/react@16.8.6",
|
||||
"pkg:npm/redux@4.0.1",
|
||||
"pkg:npm/scheduler@0.13.6",
|
||||
"pkg:npm/symbol-observable@1.2.0"
|
||||
"pkg:npm/redux@4.0.1"
|
||||
]
|
||||
},
|
||||
{
|
||||
|
||||
@@ -1470,6 +1470,52 @@ func TestPom_Parse(t *testing.T) {
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "overwrite artifact version from dependencyManagement in the root POM when dependency uses `project.*` props",
|
||||
inputFile: filepath.Join("testdata", "root-pom-dep-management-for-deps-with-project-props", "pom.xml"),
|
||||
local: true,
|
||||
want: []ftypes.Package{
|
||||
{
|
||||
ID: "com.example:root-pom-dep-management-for-deps-with-project-props:1.0.0",
|
||||
Name: "com.example:root-pom-dep-management-for-deps-with-project-props",
|
||||
Version: "1.0.0",
|
||||
Relationship: ftypes.RelationshipRoot,
|
||||
},
|
||||
{
|
||||
ID: "org.example:example-dependency:1.7.30",
|
||||
Name: "org.example:example-dependency",
|
||||
Version: "1.7.30",
|
||||
Relationship: ftypes.RelationshipDirect,
|
||||
Locations: ftypes.Locations{
|
||||
{
|
||||
StartLine: 21,
|
||||
EndLine: 25,
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
ID: "org.example:example-api:2.0.0",
|
||||
Name: "org.example:example-api",
|
||||
Version: "2.0.0",
|
||||
Licenses: []string{"The Apache Software License, Version 2.0"},
|
||||
Relationship: ftypes.RelationshipIndirect,
|
||||
},
|
||||
},
|
||||
wantDeps: []ftypes.Dependency{
|
||||
{
|
||||
ID: "com.example:root-pom-dep-management-for-deps-with-project-props:1.0.0",
|
||||
DependsOn: []string{
|
||||
"org.example:example-dependency:1.7.30",
|
||||
},
|
||||
},
|
||||
{
|
||||
ID: "org.example:example-dependency:1.7.30",
|
||||
DependsOn: []string{
|
||||
"org.example:example-api:2.0.0",
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "transitive dependencyManagement should not be inherited",
|
||||
inputFile: filepath.Join("testdata", "transitive-dependency-management", "pom.xml"),
|
||||
|
||||
@@ -245,7 +245,7 @@ func (d pomDependency) Resolve(props map[string]string, depManagement, rootDepMa
|
||||
|
||||
// If this dependency is managed in the root POM,
|
||||
// we need to overwrite fields according to the managed dependency.
|
||||
if managed, found := findDep(d.Name(), rootDepManagement); found { // dependencyManagement from the root POM
|
||||
if managed, found := findDep(dep.Name(), rootDepManagement); found { // dependencyManagement from the root POM
|
||||
if managed.Version != "" {
|
||||
dep.Version = evaluateVariable(managed.Version, props, nil)
|
||||
}
|
||||
@@ -264,7 +264,7 @@ func (d pomDependency) Resolve(props map[string]string, depManagement, rootDepMa
|
||||
}
|
||||
|
||||
// Inherit version, scope and optional from dependencyManagement if empty
|
||||
if managed, found := findDep(d.Name(), depManagement); found { // dependencyManagement from parent
|
||||
if managed, found := findDep(dep.Name(), depManagement); found { // dependencyManagement from parent
|
||||
if dep.Version == "" {
|
||||
dep.Version = evaluateVariable(managed.Version, props, nil)
|
||||
}
|
||||
|
||||
@@ -0,0 +1,18 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
<groupId>org.example</groupId>
|
||||
<artifactId>example-dependency</artifactId>
|
||||
<version>1.7.30</version>
|
||||
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>${project.groupId}</groupId>
|
||||
<artifactId>example-api</artifactId>
|
||||
<version>${project.version}</version>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
|
||||
</project>
|
||||
@@ -0,0 +1,28 @@
|
||||
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
<groupId>com.example</groupId>
|
||||
<artifactId>root-pom-dep-management-for-deps-with-project-props</artifactId>
|
||||
<version>1.0.0</version>
|
||||
<packaging>pom</packaging>
|
||||
|
||||
<dependencyManagement>
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>org.example</groupId>
|
||||
<artifactId>example-api</artifactId>
|
||||
<version>2.0.0</version>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
</dependencyManagement>
|
||||
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>org.example</groupId>
|
||||
<artifactId>example-dependency</artifactId>
|
||||
<version>1.7.30</version>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
|
||||
</project>
|
||||
@@ -2,13 +2,13 @@ package poetry
|
||||
|
||||
import (
|
||||
"sort"
|
||||
"strings"
|
||||
|
||||
"github.com/BurntSushi/toml"
|
||||
"golang.org/x/xerrors"
|
||||
|
||||
version "github.com/aquasecurity/go-pep440-version"
|
||||
"github.com/aquasecurity/trivy/pkg/dependency"
|
||||
"github.com/aquasecurity/trivy/pkg/dependency/parser/python"
|
||||
ftypes "github.com/aquasecurity/trivy/pkg/fanal/types"
|
||||
"github.com/aquasecurity/trivy/pkg/log"
|
||||
xio "github.com/aquasecurity/trivy/pkg/x/io"
|
||||
@@ -105,7 +105,7 @@ func (p *Parser) parseDependencies(deps map[string]any, pkgVersions map[string][
|
||||
}
|
||||
|
||||
func (p *Parser) parseDependency(name string, versRange any, pkgVersions map[string][]string) (string, error) {
|
||||
name = NormalizePkgName(name)
|
||||
name = python.NormalizePkgName(name)
|
||||
vers, ok := pkgVersions[name]
|
||||
if !ok {
|
||||
return "", xerrors.Errorf("no version found for %q", name)
|
||||
@@ -149,17 +149,6 @@ func matchVersion(currentVersion, constraint string) (bool, error) {
|
||||
return c.Check(v), nil
|
||||
}
|
||||
|
||||
// NormalizePkgName normalizes the package name based on pep-0426
|
||||
func NormalizePkgName(name string) string {
|
||||
// The package names don't use `_`, `.` or upper case, but dependency names can contain them.
|
||||
// We need to normalize those names.
|
||||
// cf. https://peps.python.org/pep-0426/#name
|
||||
name = strings.ToLower(name) // e.g. https://github.com/python-poetry/poetry/blob/c8945eb110aeda611cc6721565d7ad0c657d453a/poetry.lock#L819
|
||||
name = strings.ReplaceAll(name, "_", "-") // e.g. https://github.com/python-poetry/poetry/blob/c8945eb110aeda611cc6721565d7ad0c657d453a/poetry.lock#L50
|
||||
name = strings.ReplaceAll(name, ".", "-") // e.g. https://github.com/python-poetry/poetry/blob/c8945eb110aeda611cc6721565d7ad0c657d453a/poetry.lock#L816
|
||||
return name
|
||||
}
|
||||
|
||||
func packageID(name, ver string) string {
|
||||
return dependency.ID(ftypes.Poetry, name, ver)
|
||||
}
|
||||
|
||||
@@ -3,9 +3,9 @@ package poetry
|
||||
import ftypes "github.com/aquasecurity/trivy/pkg/fanal/types"
|
||||
|
||||
var (
|
||||
// docker run --name pipenv --rm -it python@sha256:e1141f10176d74d1a0e87a7c0a0a5a98dd98ec5ac12ce867768f40c6feae2fd9 sh
|
||||
// docker run --name poetry --rm -it python@sha256:e1141f10176d74d1a0e87a7c0a0a5a98dd98ec5ac12ce867768f40c6feae2fd9 sh
|
||||
// apk add curl
|
||||
// curl -sSL https://install.python-poetry.org | python3 -
|
||||
// curl -sSL https://install.python-poetry.org | POETRY_VERSION=1.1.7 python3 -
|
||||
// export PATH=/root/.local/bin:$PATH
|
||||
// poetry new normal && cd normal
|
||||
// poetry add pypi@2.1
|
||||
@@ -14,9 +14,9 @@ var (
|
||||
{ID: "pypi@2.1", Name: "pypi", Version: "2.1"},
|
||||
}
|
||||
|
||||
// docker run --name pipenv --rm -it python@sha256:e1141f10176d74d1a0e87a7c0a0a5a98dd98ec5ac12ce867768f40c6feae2fd9 sh
|
||||
// docker run --name poetry --rm -it python@sha256:e1141f10176d74d1a0e87a7c0a0a5a98dd98ec5ac12ce867768f40c6feae2fd9 sh
|
||||
// apk add curl
|
||||
// curl -sSL https://install.python-poetry.org | python3 -
|
||||
// curl -sSL https://install.python-poetry.org | POETRY_VERSION=1.1.7 python3 -
|
||||
// export PATH=/root/.local/bin:$PATH
|
||||
// poetry new many && cd many
|
||||
// curl -o poetry.lock https://raw.githubusercontent.com/python-poetry/poetry/c8945eb110aeda611cc6721565d7ad0c657d453a/poetry.lock
|
||||
@@ -108,9 +108,9 @@ var (
|
||||
{ID: "xattr@0.10.1", DependsOn: []string{"cffi@1.15.1"}},
|
||||
}
|
||||
|
||||
// docker run --name pipenv --rm -it python@sha256:e1141f10176d74d1a0e87a7c0a0a5a98dd98ec5ac12ce867768f40c6feae2fd9 sh
|
||||
// docker run --name poetry --rm -it python@sha256:e1141f10176d74d1a0e87a7c0a0a5a98dd98ec5ac12ce867768f40c6feae2fd9 sh
|
||||
// apk add curl
|
||||
// curl -sSL https://install.python-poetry.org | python3 -
|
||||
// curl -sSL https://install.python-poetry.org | POETRY_VERSION=1.1.7 python3 -
|
||||
// export PATH=/root/.local/bin:$PATH
|
||||
// poetry new web && cd web
|
||||
// poetry add flask@1.0.3
|
||||
|
||||
@@ -4,7 +4,10 @@ import (
|
||||
"io"
|
||||
|
||||
"github.com/BurntSushi/toml"
|
||||
"github.com/samber/lo"
|
||||
"golang.org/x/xerrors"
|
||||
|
||||
"github.com/aquasecurity/trivy/pkg/dependency/parser/python"
|
||||
)
|
||||
|
||||
type PyProject struct {
|
||||
@@ -16,7 +19,26 @@ type Tool struct {
|
||||
}
|
||||
|
||||
type Poetry struct {
|
||||
Dependencies map[string]any `toml:"dependencies"`
|
||||
Dependencies dependencies `toml:"dependencies"`
|
||||
Groups map[string]Group `toml:"group"`
|
||||
}
|
||||
|
||||
type Group struct {
|
||||
Dependencies dependencies `toml:"dependencies"`
|
||||
}
|
||||
|
||||
type dependencies map[string]struct{}
|
||||
|
||||
func (d *dependencies) UnmarshalTOML(data any) error {
|
||||
m, ok := data.(map[string]any)
|
||||
if !ok {
|
||||
return xerrors.Errorf("dependencies must be map, but got: %T", data)
|
||||
}
|
||||
|
||||
*d = lo.MapEntries(m, func(pkgName string, _ any) (string, struct{}) {
|
||||
return python.NormalizePkgName(pkgName), struct{}{}
|
||||
})
|
||||
return nil
|
||||
}
|
||||
|
||||
// Parser parses pyproject.toml defined in PEP518.
|
||||
@@ -28,10 +50,10 @@ func NewParser() *Parser {
|
||||
return &Parser{}
|
||||
}
|
||||
|
||||
func (p *Parser) Parse(r io.Reader) (map[string]any, error) {
|
||||
func (p *Parser) Parse(r io.Reader) (PyProject, error) {
|
||||
var conf PyProject
|
||||
if _, err := toml.NewDecoder(r).Decode(&conf); err != nil {
|
||||
return nil, xerrors.Errorf("toml decode error: %w", err)
|
||||
return PyProject{}, xerrors.Errorf("toml decode error: %w", err)
|
||||
}
|
||||
return conf.Tool.Poetry.Dependencies, nil
|
||||
return conf, nil
|
||||
}
|
||||
|
||||
@@ -15,26 +15,33 @@ func TestParser_Parse(t *testing.T) {
|
||||
tests := []struct {
|
||||
name string
|
||||
file string
|
||||
want map[string]any
|
||||
want pyproject.PyProject
|
||||
wantErr assert.ErrorAssertionFunc
|
||||
}{
|
||||
{
|
||||
name: "happy path",
|
||||
file: "testdata/happy.toml",
|
||||
want: map[string]any{
|
||||
"flask": "^1.0",
|
||||
"python": "^3.9",
|
||||
"requests": map[string]any{
|
||||
"version": "2.28.1",
|
||||
"optional": true,
|
||||
},
|
||||
"virtualenv": []any{
|
||||
map[string]any{
|
||||
"version": "^20.4.3,!=20.4.5,!=20.4.6",
|
||||
},
|
||||
map[string]any{
|
||||
"version": "<20.16.6",
|
||||
"markers": "sys_platform == 'win32' and python_version == '3.9'",
|
||||
want: pyproject.PyProject{
|
||||
Tool: pyproject.Tool{
|
||||
Poetry: pyproject.Poetry{
|
||||
Dependencies: map[string]struct{}{
|
||||
"flask": {},
|
||||
"python": {},
|
||||
"requests": {},
|
||||
"virtualenv": {},
|
||||
},
|
||||
Groups: map[string]pyproject.Group{
|
||||
"dev": {
|
||||
Dependencies: map[string]struct{}{
|
||||
"pytest": {},
|
||||
},
|
||||
},
|
||||
"lint": {
|
||||
Dependencies: map[string]struct{}{
|
||||
"ruff": {},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
|
||||
@@ -14,6 +14,13 @@ virtualenv = [
|
||||
|
||||
[tool.poetry.dev-dependencies]
|
||||
|
||||
[tool.poetry.group.dev.dependencies]
|
||||
pytest = "8.3.4"
|
||||
|
||||
|
||||
[tool.poetry.group.lint.dependencies]
|
||||
ruff = "0.8.3"
|
||||
|
||||
[build-system]
|
||||
requires = ["poetry-core>=1.0.0"]
|
||||
build-backend = "poetry.core.masonry.api"
|
||||
|
||||
14
pkg/dependency/parser/python/python.go
Normal file
14
pkg/dependency/parser/python/python.go
Normal file
@@ -0,0 +1,14 @@
|
||||
package python
|
||||
|
||||
import "strings"
|
||||
|
||||
// NormalizePkgName normalizes the package name based on pep-0426
|
||||
func NormalizePkgName(name string) string {
|
||||
// The package names don't use `_`, `.` or upper case, but dependency names can contain them.
|
||||
// We need to normalize those names.
|
||||
// cf. https://peps.python.org/pep-0426/#name
|
||||
name = strings.ToLower(name) // e.g. https://github.com/python-poetry/poetry/blob/c8945eb110aeda611cc6721565d7ad0c657d453a/poetry.lock#L819
|
||||
name = strings.ReplaceAll(name, "_", "-") // e.g. https://github.com/python-poetry/poetry/blob/c8945eb110aeda611cc6721565d7ad0c657d453a/poetry.lock#L50
|
||||
name = strings.ReplaceAll(name, ".", "-") // e.g. https://github.com/python-poetry/poetry/blob/c8945eb110aeda611cc6721565d7ad0c657d453a/poetry.lock#L816
|
||||
return name
|
||||
}
|
||||
39
pkg/dependency/parser/python/python_test.go
Normal file
39
pkg/dependency/parser/python/python_test.go
Normal file
@@ -0,0 +1,39 @@
|
||||
package python_test
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"github.com/stretchr/testify/assert"
|
||||
|
||||
"github.com/aquasecurity/trivy/pkg/dependency/parser/python"
|
||||
)
|
||||
|
||||
func Test_NormalizePkgName(t *testing.T) {
|
||||
tests := []struct {
|
||||
pkgName string
|
||||
expected string
|
||||
}{
|
||||
{
|
||||
pkgName: "SecretStorage",
|
||||
expected: "secretstorage",
|
||||
},
|
||||
{
|
||||
pkgName: "pywin32-ctypes",
|
||||
expected: "pywin32-ctypes",
|
||||
},
|
||||
{
|
||||
pkgName: "jaraco.classes",
|
||||
expected: "jaraco-classes",
|
||||
},
|
||||
{
|
||||
pkgName: "green_gdk",
|
||||
expected: "green-gdk",
|
||||
},
|
||||
}
|
||||
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.pkgName, func(t *testing.T) {
|
||||
assert.Equal(t, tt.expected, python.NormalizePkgName(tt.pkgName))
|
||||
})
|
||||
}
|
||||
}
|
||||
@@ -50,7 +50,7 @@ func (s *Scanner) Detect(ctx context.Context, osVer string, _ *ftypes.Repository
|
||||
|
||||
var vulns []types.DetectedVulnerability
|
||||
for _, pkg := range pkgs {
|
||||
advisories, err := s.vs.Get(osVer, pkg.Name)
|
||||
advisories, err := s.vs.Get(osVer, pkg.Name, pkg.Arch)
|
||||
if err != nil {
|
||||
return nil, xerrors.Errorf("failed to get Oracle Linux advisory: %w", err)
|
||||
}
|
||||
|
||||
@@ -139,6 +139,60 @@ func TestScanner_Detect(t *testing.T) {
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "different fixed versions for different arches",
|
||||
fixtures: []string{
|
||||
"testdata/fixtures/oracle7.yaml",
|
||||
"testdata/fixtures/data-source.yaml",
|
||||
},
|
||||
args: args{
|
||||
osVer: "7",
|
||||
pkgs: []ftypes.Package{
|
||||
{
|
||||
Name: "rsyslog",
|
||||
Version: "8.24.0",
|
||||
Release: "57.0.0.el7",
|
||||
Arch: "x86_64",
|
||||
SrcName: "rsyslog",
|
||||
SrcVersion: "8.24.0",
|
||||
SrcRelease: "57.0.0.el7",
|
||||
},
|
||||
{
|
||||
Name: "rsyslog",
|
||||
Version: "8.24.0",
|
||||
Release: "57.0.0.el7",
|
||||
Arch: "aarch64",
|
||||
SrcName: "rsyslog",
|
||||
SrcVersion: "8.24.0",
|
||||
SrcRelease: "57.0.0.el7",
|
||||
},
|
||||
},
|
||||
},
|
||||
want: []types.DetectedVulnerability{
|
||||
{
|
||||
VulnerabilityID: "CVE-2022-24903",
|
||||
PkgName: "rsyslog",
|
||||
InstalledVersion: "8.24.0-57.0.0.el7",
|
||||
FixedVersion: "8.24.0-57.0.1.el7_9.3",
|
||||
DataSource: &dbTypes.DataSource{
|
||||
ID: vulnerability.OracleOVAL,
|
||||
Name: "Oracle Linux OVAL definitions",
|
||||
URL: "https://linux.oracle.com/security/oval/",
|
||||
},
|
||||
},
|
||||
{
|
||||
VulnerabilityID: "CVE-2022-24903",
|
||||
PkgName: "rsyslog",
|
||||
InstalledVersion: "8.24.0-57.0.0.el7",
|
||||
FixedVersion: "8.24.0-57.0.4.el7_9.3",
|
||||
DataSource: &dbTypes.DataSource{
|
||||
ID: vulnerability.OracleOVAL,
|
||||
Name: "Oracle Linux OVAL definitions",
|
||||
URL: "https://linux.oracle.com/security/oval/",
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "without ksplice",
|
||||
fixtures: []string{
|
||||
|
||||
@@ -7,6 +7,9 @@
|
||||
FixedVersion: "7.29.0-59.0.1.el7_9.1"
|
||||
Entries:
|
||||
- FixedVersion: "7.29.0-59.0.1.el7_9.1"
|
||||
Arches:
|
||||
- x86_64
|
||||
- aarch64
|
||||
- bucket: glibc
|
||||
pairs:
|
||||
- key: CVE-2017-1000364
|
||||
@@ -14,6 +17,9 @@
|
||||
FixedVersion: "2:2.17-157.ksplice1.el7_3.4"
|
||||
Entries:
|
||||
- FixedVersion: "2:2.17-157.ksplice1.el7_3.4"
|
||||
Arches:
|
||||
- x86_64
|
||||
- aarch64
|
||||
- bucket: gnutls
|
||||
pairs:
|
||||
- key: CVE-2021-20232
|
||||
@@ -21,5 +27,20 @@
|
||||
FixedVersion: "3.6.16-4.el8"
|
||||
Entries:
|
||||
- FixedVersion: "10:3.6.16-4.0.1.el8_fips"
|
||||
Arches:
|
||||
- x86_64
|
||||
- FixedVersion: "3.6.16-4.el8"
|
||||
|
||||
Arches:
|
||||
- x86_64
|
||||
- bucket: rsyslog
|
||||
pairs:
|
||||
- key: CVE-2022-24903
|
||||
value:
|
||||
FixedVersion: "8.24.0-57.0.1.el7_9.3"
|
||||
Entries:
|
||||
- FixedVersion: "8.24.0-57.0.1.el7_9.3"
|
||||
Arches:
|
||||
- x86_64
|
||||
- FixedVersion: "8.24.0-57.0.4.el7_9.3"
|
||||
Arches:
|
||||
- aarch64
|
||||
|
||||
@@ -9,11 +9,9 @@ import (
|
||||
"time"
|
||||
|
||||
version "github.com/knqyf263/go-rpm-version"
|
||||
"github.com/samber/lo"
|
||||
"golang.org/x/xerrors"
|
||||
|
||||
dbTypes "github.com/aquasecurity/trivy-db/pkg/types"
|
||||
ustrings "github.com/aquasecurity/trivy-db/pkg/utils/strings"
|
||||
redhat "github.com/aquasecurity/trivy-db/pkg/vulnsrc/redhat-oval"
|
||||
"github.com/aquasecurity/trivy-db/pkg/vulnsrc/vulnerability"
|
||||
osver "github.com/aquasecurity/trivy/pkg/detector/ospkg/version"
|
||||
@@ -116,24 +114,35 @@ func (s *Scanner) detect(osVer string, pkg ftypes.Package) ([]types.DetectedVuln
|
||||
return nil, xerrors.Errorf("failed to get Red Hat advisories: %w", err)
|
||||
}
|
||||
|
||||
installed := utils.FormatVersion(pkg)
|
||||
installedVersion := version.NewVersion(installed)
|
||||
|
||||
uniqVulns := make(map[string]types.DetectedVulnerability)
|
||||
// Choose the latest fixed version for each CVE-ID (empty for unpatched vulns).
|
||||
// Take the single RHSA-ID with the latest fixed version (for patched vulns).
|
||||
uniqAdvisories := make(map[string]dbTypes.Advisory)
|
||||
for _, adv := range advisories {
|
||||
// if Arches for advisory is empty or pkg.Arch is "noarch", then any Arches are affected
|
||||
// If Arches for advisory are empty or pkg.Arch is "noarch", then any Arches are affected
|
||||
if len(adv.Arches) != 0 && pkg.Arch != "noarch" {
|
||||
if !slices.Contains(adv.Arches, pkg.Arch) {
|
||||
continue
|
||||
}
|
||||
}
|
||||
|
||||
vulnID := adv.VulnerabilityID
|
||||
if a, ok := uniqAdvisories[adv.VulnerabilityID]; ok {
|
||||
if version.NewVersion(a.FixedVersion).LessThan(version.NewVersion(adv.FixedVersion)) {
|
||||
uniqAdvisories[adv.VulnerabilityID] = adv
|
||||
}
|
||||
} else {
|
||||
uniqAdvisories[adv.VulnerabilityID] = adv
|
||||
}
|
||||
}
|
||||
|
||||
var vulns []types.DetectedVulnerability
|
||||
for _, adv := range uniqAdvisories {
|
||||
vuln := types.DetectedVulnerability{
|
||||
VulnerabilityID: vulnID,
|
||||
VulnerabilityID: adv.VulnerabilityID,
|
||||
VendorIDs: adv.VendorIDs, // Will be empty for unpatched vulnerabilities
|
||||
PkgID: pkg.ID,
|
||||
PkgName: pkg.Name,
|
||||
InstalledVersion: utils.FormatVersion(pkg),
|
||||
FixedVersion: version.NewVersion(adv.FixedVersion).String(), // Will be empty for unpatched vulnerabilities
|
||||
PkgIdentifier: pkg.Identifier,
|
||||
Status: adv.Status,
|
||||
Layer: pkg.Layer,
|
||||
@@ -144,43 +153,15 @@ func (s *Scanner) detect(osVer string, pkg ftypes.Package) ([]types.DetectedVuln
|
||||
Custom: adv.Custom,
|
||||
}
|
||||
|
||||
// unpatched vulnerabilities
|
||||
if adv.FixedVersion == "" {
|
||||
// Red Hat may contain several advisories for the same vulnerability (RHSA advisories).
|
||||
// To avoid overwriting the fixed version by mistake, we should skip unpatched vulnerabilities if they were added earlier
|
||||
if _, ok := uniqVulns[vulnID]; !ok {
|
||||
uniqVulns[vulnID] = vuln
|
||||
}
|
||||
continue
|
||||
}
|
||||
|
||||
// patched vulnerabilities
|
||||
fixedVersion := version.NewVersion(adv.FixedVersion)
|
||||
if installedVersion.LessThan(fixedVersion) {
|
||||
vuln.VendorIDs = adv.VendorIDs
|
||||
vuln.FixedVersion = fixedVersion.String()
|
||||
|
||||
if v, ok := uniqVulns[vulnID]; ok {
|
||||
// In case two advisories resolve the same CVE-ID.
|
||||
// e.g. The first fix might be incomplete.
|
||||
v.VendorIDs = ustrings.Unique(append(v.VendorIDs, vuln.VendorIDs...))
|
||||
|
||||
// The newer fixed version should be taken.
|
||||
if version.NewVersion(v.FixedVersion).LessThan(fixedVersion) {
|
||||
v.FixedVersion = vuln.FixedVersion
|
||||
}
|
||||
uniqVulns[vulnID] = v
|
||||
} else {
|
||||
uniqVulns[vulnID] = vuln
|
||||
}
|
||||
// Keep unpatched and affected vulnerabilities
|
||||
if adv.FixedVersion == "" || version.NewVersion(vuln.InstalledVersion).LessThan(version.NewVersion(adv.FixedVersion)) {
|
||||
vulns = append(vulns, vuln)
|
||||
}
|
||||
}
|
||||
|
||||
vulns := lo.Values(uniqVulns)
|
||||
sort.Slice(vulns, func(i, j int) bool {
|
||||
return vulns[i].VulnerabilityID < vulns[j].VulnerabilityID
|
||||
})
|
||||
|
||||
return vulns, nil
|
||||
}
|
||||
|
||||
|
||||
@@ -79,8 +79,10 @@ func TestScanner_Detect(t *testing.T) {
|
||||
},
|
||||
},
|
||||
{
|
||||
VulnerabilityID: "CVE-2019-12735",
|
||||
VendorIDs: []string{"RHSA-2019:1619"},
|
||||
VulnerabilityID: "CVE-2019-12735",
|
||||
VendorIDs: []string{
|
||||
"RHSA-2019:1619",
|
||||
},
|
||||
PkgName: "vim-minimal",
|
||||
InstalledVersion: "2:7.4.160-5.el7",
|
||||
FixedVersion: "2:7.4.160-6.el7_6",
|
||||
@@ -124,8 +126,10 @@ func TestScanner_Detect(t *testing.T) {
|
||||
},
|
||||
want: []types.DetectedVulnerability{
|
||||
{
|
||||
VulnerabilityID: "CVE-2019-17007",
|
||||
VendorIDs: []string{"RHSA-2021:0876"},
|
||||
VulnerabilityID: "CVE-2019-17007",
|
||||
VendorIDs: []string{
|
||||
"RHSA-2021:0876",
|
||||
},
|
||||
PkgName: "nss",
|
||||
InstalledVersion: "3.36.0-7.1.el7_6",
|
||||
FixedVersion: "3.36.0-9.el7_6",
|
||||
@@ -141,7 +145,6 @@ func TestScanner_Detect(t *testing.T) {
|
||||
VulnerabilityID: "CVE-2020-12403",
|
||||
VendorIDs: []string{
|
||||
"RHSA-2021:0538",
|
||||
"RHSA-2021:0876",
|
||||
},
|
||||
PkgName: "nss",
|
||||
InstalledVersion: "3.36.0-7.1.el7_6",
|
||||
@@ -156,6 +159,53 @@ func TestScanner_Detect(t *testing.T) {
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "happy path: CVE-ID and RHSA-ID for same vulnerability",
|
||||
fixtures: []string{
|
||||
"testdata/fixtures/redhat.yaml",
|
||||
"testdata/fixtures/cpe.yaml",
|
||||
},
|
||||
args: args{
|
||||
osVer: "8.3",
|
||||
pkgs: []ftypes.Package{
|
||||
{
|
||||
Name: "expat",
|
||||
Version: "2.2.5",
|
||||
Release: "16.el8_10",
|
||||
Epoch: 0,
|
||||
Arch: "x86_64",
|
||||
SrcName: "expat",
|
||||
SrcVersion: "2.2.5",
|
||||
SrcRelease: "16.el8_10",
|
||||
SrcEpoch: 0,
|
||||
Layer: ftypes.Layer{
|
||||
DiffID: "sha256:932da51564135c98a49a34a193d6cd363d8fa4184d957fde16c9d8527b3f3b02",
|
||||
},
|
||||
BuildInfo: &ftypes.BuildInfo{
|
||||
ContentSets: []string{"rhel-8-for-x86_64-baseos-rpms"},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
want: []types.DetectedVulnerability{
|
||||
{
|
||||
VulnerabilityID: "CVE-2024-45490",
|
||||
VendorIDs: []string{
|
||||
"RHSA-2024:6989-3",
|
||||
},
|
||||
PkgName: "expat",
|
||||
InstalledVersion: "2.2.5-16.el8_10",
|
||||
FixedVersion: "2.2.5-18.el8_10",
|
||||
SeveritySource: vulnerability.RedHat,
|
||||
Vulnerability: dbTypes.Vulnerability{
|
||||
Severity: dbTypes.SeverityMedium.String(),
|
||||
},
|
||||
Layer: ftypes.Layer{
|
||||
DiffID: "sha256:932da51564135c98a49a34a193d6cd363d8fa4184d957fde16c9d8527b3f3b02",
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "happy path: package without architecture",
|
||||
fixtures: []string{
|
||||
@@ -186,8 +236,10 @@ func TestScanner_Detect(t *testing.T) {
|
||||
},
|
||||
want: []types.DetectedVulnerability{
|
||||
{
|
||||
VulnerabilityID: "CVE-2016-5195",
|
||||
VendorIDs: []string{"RHSA-2017:0372"},
|
||||
VulnerabilityID: "CVE-2016-5195",
|
||||
VendorIDs: []string{
|
||||
"RHSA-2017:0372",
|
||||
},
|
||||
PkgName: "kernel-headers",
|
||||
InstalledVersion: "3.10.0-1127.19-1.el7",
|
||||
FixedVersion: "4.5.0-15.2.1.el7",
|
||||
@@ -231,8 +283,10 @@ func TestScanner_Detect(t *testing.T) {
|
||||
},
|
||||
want: []types.DetectedVulnerability{
|
||||
{
|
||||
VulnerabilityID: "CVE-2016-5195",
|
||||
VendorIDs: []string{"RHSA-2016:2098"},
|
||||
VulnerabilityID: "CVE-2016-5195",
|
||||
VendorIDs: []string{
|
||||
"RHSA-2016:2098",
|
||||
},
|
||||
PkgName: "kernel-headers",
|
||||
InstalledVersion: "3.10.0-326.36-3.el7",
|
||||
FixedVersion: "3.10.0-327.36.3.el7",
|
||||
@@ -266,8 +320,10 @@ func TestScanner_Detect(t *testing.T) {
|
||||
},
|
||||
want: []types.DetectedVulnerability{
|
||||
{
|
||||
VulnerabilityID: "CVE-2019-12735",
|
||||
VendorIDs: []string{"RHSA-2019:1619"},
|
||||
VulnerabilityID: "CVE-2019-12735",
|
||||
VendorIDs: []string{
|
||||
"RHSA-2019:1619",
|
||||
},
|
||||
PkgName: "vim-minimal",
|
||||
InstalledVersion: "2:7.4.160-5.el8",
|
||||
FixedVersion: "2:7.4.160-7.el8_7",
|
||||
@@ -308,8 +364,10 @@ func TestScanner_Detect(t *testing.T) {
|
||||
},
|
||||
want: []types.DetectedVulnerability{
|
||||
{
|
||||
VulnerabilityID: "CVE-2019-11043",
|
||||
VendorIDs: []string{"RHSA-2020:0322"},
|
||||
VulnerabilityID: "CVE-2019-11043",
|
||||
VendorIDs: []string{
|
||||
"RHSA-2020:0322",
|
||||
},
|
||||
PkgName: "php",
|
||||
InstalledVersion: "7.2.10-1.module_el8.2.0+313+b04d0a66",
|
||||
FixedVersion: "7.2.11-1.1.module+el8.0.0+4664+17bd8d65",
|
||||
|
||||
@@ -104,4 +104,67 @@
|
||||
- ID: CVE-2016-5195
|
||||
Severity: 3
|
||||
Arches:
|
||||
- aarch64
|
||||
- aarch64
|
||||
- bucket: expat
|
||||
pairs:
|
||||
- key: RHSA-2024:6989-2 # created for test only
|
||||
value:
|
||||
Entries:
|
||||
- FixedVersion: 0:2.2.5-17.el8_10
|
||||
Affected:
|
||||
- 4
|
||||
Arches:
|
||||
- x86_64
|
||||
Cves:
|
||||
- ID: CVE-2024-45490
|
||||
Severity: 2
|
||||
- key: RHSA-2024:6989-3 # created for test only
|
||||
value:
|
||||
Entries:
|
||||
- FixedVersion: 0:2.2.5-18.el8_10
|
||||
Affected:
|
||||
- 4
|
||||
Arches:
|
||||
- x86_64
|
||||
Cves:
|
||||
- ID: CVE-2024-45490
|
||||
Severity: 2
|
||||
- key: CVE-2024-45490
|
||||
value:
|
||||
Entries:
|
||||
- Affected:
|
||||
- 4
|
||||
Cves:
|
||||
- Severity: 2
|
||||
Status: 5
|
||||
- key: CVE-2024-45491
|
||||
value:
|
||||
Entries:
|
||||
- Affected:
|
||||
- 4
|
||||
Cves:
|
||||
- Severity: 2
|
||||
Status: 5
|
||||
- key: RHSA-2024:6989
|
||||
value:
|
||||
Entries:
|
||||
- FixedVersion: 0:2.2.5-15.el8_10
|
||||
Affected:
|
||||
- 4
|
||||
Arches:
|
||||
- x86_64
|
||||
Cves:
|
||||
- ID: CVE-2024-45490
|
||||
Severity: 2
|
||||
- ID: CVE-2024-45491
|
||||
Severity: 2
|
||||
- ID: CVE-2024-45492
|
||||
Severity: 2
|
||||
- key: CVE-2024-45492
|
||||
value:
|
||||
Entries:
|
||||
- Affected:
|
||||
- 4
|
||||
Cves:
|
||||
- Severity: 2
|
||||
Status: 5
|
||||
@@ -94,7 +94,7 @@ func (a poetryAnalyzer) parsePoetryLock(path string, r io.Reader) (*types.Applic
|
||||
func (a poetryAnalyzer) mergePyProject(fsys fs.FS, dir string, app *types.Application) error {
|
||||
// Parse pyproject.toml to identify the direct dependencies
|
||||
path := filepath.Join(dir, types.PyProject)
|
||||
p, err := a.parsePyProject(fsys, path)
|
||||
project, err := a.parsePyProject(fsys, path)
|
||||
if errors.Is(err, fs.ErrNotExist) {
|
||||
// Assume all the packages are direct dependencies as it cannot identify them from poetry.lock
|
||||
a.logger.Debug("pyproject.toml not found", log.FilePath(path))
|
||||
@@ -105,7 +105,7 @@ func (a poetryAnalyzer) mergePyProject(fsys fs.FS, dir string, app *types.Applic
|
||||
|
||||
// Identify the direct/transitive dependencies
|
||||
for i, pkg := range app.Packages {
|
||||
if _, ok := p[pkg.Name]; ok {
|
||||
if _, ok := project.Tool.Poetry.Dependencies[pkg.Name]; ok {
|
||||
app.Packages[i].Relationship = types.RelationshipDirect
|
||||
} else {
|
||||
app.Packages[i].Indirect = true
|
||||
@@ -113,26 +113,60 @@ func (a poetryAnalyzer) mergePyProject(fsys fs.FS, dir string, app *types.Applic
|
||||
}
|
||||
}
|
||||
|
||||
filterProdPackages(project, app)
|
||||
return nil
|
||||
}
|
||||
|
||||
func (a poetryAnalyzer) parsePyProject(fsys fs.FS, path string) (map[string]any, error) {
|
||||
func filterProdPackages(project pyproject.PyProject, app *types.Application) {
|
||||
packages := lo.SliceToMap(app.Packages, func(pkg types.Package) (string, types.Package) {
|
||||
return pkg.ID, pkg
|
||||
})
|
||||
|
||||
visited := make(map[string]struct{})
|
||||
deps := project.Tool.Poetry.Dependencies
|
||||
|
||||
for group, groupDeps := range project.Tool.Poetry.Groups {
|
||||
if group == "dev" {
|
||||
continue
|
||||
}
|
||||
deps = lo.Assign(deps, groupDeps.Dependencies)
|
||||
}
|
||||
|
||||
for _, pkg := range packages {
|
||||
if _, prodDep := deps[pkg.Name]; !prodDep {
|
||||
continue
|
||||
}
|
||||
walkPackageDeps(pkg.ID, packages, visited)
|
||||
}
|
||||
|
||||
app.Packages = lo.Filter(app.Packages, func(pkg types.Package, _ int) bool {
|
||||
_, ok := visited[pkg.ID]
|
||||
return ok
|
||||
})
|
||||
}
|
||||
|
||||
func walkPackageDeps(pkgID string, packages map[string]types.Package, visited map[string]struct{}) {
|
||||
if _, ok := visited[pkgID]; ok {
|
||||
return
|
||||
}
|
||||
visited[pkgID] = struct{}{}
|
||||
for _, dep := range packages[pkgID].DependsOn {
|
||||
walkPackageDeps(dep, packages, visited)
|
||||
}
|
||||
}
|
||||
|
||||
func (a poetryAnalyzer) parsePyProject(fsys fs.FS, path string) (pyproject.PyProject, error) {
|
||||
// Parse pyproject.toml
|
||||
f, err := fsys.Open(path)
|
||||
if err != nil {
|
||||
return nil, xerrors.Errorf("file open error: %w", err)
|
||||
return pyproject.PyProject{}, xerrors.Errorf("file open error: %w", err)
|
||||
}
|
||||
defer f.Close()
|
||||
|
||||
parsed, err := a.pyprojectParser.Parse(f)
|
||||
project, err := a.pyprojectParser.Parse(f)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
return pyproject.PyProject{}, err
|
||||
}
|
||||
|
||||
// Packages from `pyproject.toml` can use uppercase characters, `.` and `_`.
|
||||
parsed = lo.MapKeys(parsed, func(_ any, pkgName string) string {
|
||||
return poetry.NormalizePkgName(pkgName)
|
||||
})
|
||||
|
||||
return parsed, nil
|
||||
return project, nil
|
||||
}
|
||||
|
||||
@@ -181,6 +181,99 @@ func Test_poetryLibraryAnalyzer_Analyze(t *testing.T) {
|
||||
dir: "testdata/sad",
|
||||
want: &analyzer.AnalysisResult{},
|
||||
},
|
||||
{
|
||||
// docker run --name poetry --rm -it python@sha256:e1141f10176d74d1a0e87a7c0a0a5a98dd98ec5ac12ce867768f40c6feae2fd9 sh
|
||||
// wget -qO- https://install.python-poetry.org | POETRY_VERSION=1.8.5 python3 -
|
||||
// export PATH="/root/.local/bin:$PATH"
|
||||
// poetry new groups && cd groups
|
||||
// poetry add requests@2.32.3
|
||||
// poetry add --group dev pytest@8.3.4
|
||||
// poetry add --group lint ruff@0.8.3
|
||||
// poetry add --optional typing-inspect@0.9.0
|
||||
name: "skip deps from groups",
|
||||
dir: "testdata/with-groups",
|
||||
want: &analyzer.AnalysisResult{
|
||||
Applications: []types.Application{
|
||||
{
|
||||
Type: types.Poetry,
|
||||
FilePath: "poetry.lock",
|
||||
Packages: types.Packages{
|
||||
{
|
||||
ID: "certifi@2024.12.14",
|
||||
Name: "certifi",
|
||||
Version: "2024.12.14",
|
||||
Indirect: true,
|
||||
Relationship: types.RelationshipIndirect,
|
||||
},
|
||||
{
|
||||
ID: "charset-normalizer@3.4.0",
|
||||
Name: "charset-normalizer",
|
||||
Version: "3.4.0",
|
||||
Indirect: true,
|
||||
Relationship: types.RelationshipIndirect,
|
||||
},
|
||||
{
|
||||
ID: "idna@3.10",
|
||||
Name: "idna",
|
||||
Version: "3.10",
|
||||
Indirect: true,
|
||||
Relationship: types.RelationshipIndirect,
|
||||
},
|
||||
{
|
||||
ID: "mypy-extensions@1.0.0",
|
||||
Name: "mypy-extensions",
|
||||
Version: "1.0.0",
|
||||
Indirect: true,
|
||||
Relationship: types.RelationshipIndirect,
|
||||
},
|
||||
{
|
||||
ID: "requests@2.32.3",
|
||||
Name: "requests",
|
||||
Version: "2.32.3",
|
||||
DependsOn: []string{
|
||||
"certifi@2024.12.14",
|
||||
"charset-normalizer@3.4.0",
|
||||
"idna@3.10",
|
||||
"urllib3@2.2.3",
|
||||
},
|
||||
Relationship: types.RelationshipDirect,
|
||||
},
|
||||
{
|
||||
ID: "ruff@0.8.3",
|
||||
Name: "ruff",
|
||||
Version: "0.8.3",
|
||||
Indirect: true,
|
||||
Relationship: types.RelationshipIndirect,
|
||||
},
|
||||
{
|
||||
ID: "typing-extensions@4.12.2",
|
||||
Name: "typing-extensions",
|
||||
Version: "4.12.2",
|
||||
Indirect: true,
|
||||
Relationship: types.RelationshipIndirect,
|
||||
},
|
||||
{
|
||||
ID: "typing-inspect@0.9.0",
|
||||
Name: "typing-inspect",
|
||||
Version: "0.9.0",
|
||||
DependsOn: []string{
|
||||
"mypy-extensions@1.0.0",
|
||||
"typing-extensions@4.12.2",
|
||||
},
|
||||
Relationship: types.RelationshipDirect,
|
||||
},
|
||||
{
|
||||
ID: "urllib3@2.2.3",
|
||||
Name: "urllib3",
|
||||
Version: "2.2.3",
|
||||
Indirect: true,
|
||||
Relationship: types.RelationshipIndirect,
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
for _, tt := range tests {
|
||||
|
||||
372
pkg/fanal/analyzer/language/python/poetry/testdata/with-groups/poetry.lock
generated
vendored
Normal file
372
pkg/fanal/analyzer/language/python/poetry/testdata/with-groups/poetry.lock
generated
vendored
Normal file
@@ -0,0 +1,372 @@
|
||||
# This file is automatically @generated by Poetry 1.8.5 and should not be changed by hand.
|
||||
|
||||
[[package]]
|
||||
name = "certifi"
|
||||
version = "2024.12.14"
|
||||
description = "Python package for providing Mozilla's CA Bundle."
|
||||
optional = false
|
||||
python-versions = ">=3.6"
|
||||
files = [
|
||||
{file = "certifi-2024.12.14-py3-none-any.whl", hash = "sha256:1275f7a45be9464efc1173084eaa30f866fe2e47d389406136d332ed4967ec56"},
|
||||
{file = "certifi-2024.12.14.tar.gz", hash = "sha256:b650d30f370c2b724812bee08008be0c4163b163ddaec3f2546c1caf65f191db"},
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "charset-normalizer"
|
||||
version = "3.4.0"
|
||||
description = "The Real First Universal Charset Detector. Open, modern and actively maintained alternative to Chardet."
|
||||
optional = false
|
||||
python-versions = ">=3.7.0"
|
||||
files = [
|
||||
{file = "charset_normalizer-3.4.0-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:4f9fc98dad6c2eaa32fc3af1417d95b5e3d08aff968df0cd320066def971f9a6"},
|
||||
{file = "charset_normalizer-3.4.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:0de7b687289d3c1b3e8660d0741874abe7888100efe14bd0f9fd7141bcbda92b"},
|
||||
{file = "charset_normalizer-3.4.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:5ed2e36c3e9b4f21dd9422f6893dec0abf2cca553af509b10cd630f878d3eb99"},
|
||||
{file = "charset_normalizer-3.4.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:40d3ff7fc90b98c637bda91c89d51264a3dcf210cade3a2c6f838c7268d7a4ca"},
|
||||
{file = "charset_normalizer-3.4.0-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:1110e22af8ca26b90bd6364fe4c763329b0ebf1ee213ba32b68c73de5752323d"},
|
||||
{file = "charset_normalizer-3.4.0-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:86f4e8cca779080f66ff4f191a685ced73d2f72d50216f7112185dc02b90b9b7"},
|
||||
{file = "charset_normalizer-3.4.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:7f683ddc7eedd742e2889d2bfb96d69573fde1d92fcb811979cdb7165bb9c7d3"},
|
||||
{file = "charset_normalizer-3.4.0-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:27623ba66c183eca01bf9ff833875b459cad267aeeb044477fedac35e19ba907"},
|
||||
{file = "charset_normalizer-3.4.0-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:f606a1881d2663630ea5b8ce2efe2111740df4b687bd78b34a8131baa007f79b"},
|
||||
{file = "charset_normalizer-3.4.0-cp310-cp310-musllinux_1_2_i686.whl", hash = "sha256:0b309d1747110feb25d7ed6b01afdec269c647d382c857ef4663bbe6ad95a912"},
|
||||
{file = "charset_normalizer-3.4.0-cp310-cp310-musllinux_1_2_ppc64le.whl", hash = "sha256:136815f06a3ae311fae551c3df1f998a1ebd01ddd424aa5603a4336997629e95"},
|
||||
{file = "charset_normalizer-3.4.0-cp310-cp310-musllinux_1_2_s390x.whl", hash = "sha256:14215b71a762336254351b00ec720a8e85cada43b987da5a042e4ce3e82bd68e"},
|
||||
{file = "charset_normalizer-3.4.0-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:79983512b108e4a164b9c8d34de3992f76d48cadc9554c9e60b43f308988aabe"},
|
||||
{file = "charset_normalizer-3.4.0-cp310-cp310-win32.whl", hash = "sha256:c94057af19bc953643a33581844649a7fdab902624d2eb739738a30e2b3e60fc"},
|
||||
{file = "charset_normalizer-3.4.0-cp310-cp310-win_amd64.whl", hash = "sha256:55f56e2ebd4e3bc50442fbc0888c9d8c94e4e06a933804e2af3e89e2f9c1c749"},
|
||||
{file = "charset_normalizer-3.4.0-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:0d99dd8ff461990f12d6e42c7347fd9ab2532fb70e9621ba520f9e8637161d7c"},
|
||||
{file = "charset_normalizer-3.4.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:c57516e58fd17d03ebe67e181a4e4e2ccab1168f8c2976c6a334d4f819fe5944"},
|
||||
{file = "charset_normalizer-3.4.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:6dba5d19c4dfab08e58d5b36304b3f92f3bd5d42c1a3fa37b5ba5cdf6dfcbcee"},
|
||||
{file = "charset_normalizer-3.4.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:bf4475b82be41b07cc5e5ff94810e6a01f276e37c2d55571e3fe175e467a1a1c"},
|
||||
{file = "charset_normalizer-3.4.0-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:ce031db0408e487fd2775d745ce30a7cd2923667cf3b69d48d219f1d8f5ddeb6"},
|
||||
{file = "charset_normalizer-3.4.0-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:8ff4e7cdfdb1ab5698e675ca622e72d58a6fa2a8aa58195de0c0061288e6e3ea"},
|
||||
{file = "charset_normalizer-3.4.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:3710a9751938947e6327ea9f3ea6332a09bf0ba0c09cae9cb1f250bd1f1549bc"},
|
||||
{file = "charset_normalizer-3.4.0-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:82357d85de703176b5587dbe6ade8ff67f9f69a41c0733cf2425378b49954de5"},
|
||||
{file = "charset_normalizer-3.4.0-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:47334db71978b23ebcf3c0f9f5ee98b8d65992b65c9c4f2d34c2eaf5bcaf0594"},
|
||||
{file = "charset_normalizer-3.4.0-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:8ce7fd6767a1cc5a92a639b391891bf1c268b03ec7e021c7d6d902285259685c"},
|
||||
{file = "charset_normalizer-3.4.0-cp311-cp311-musllinux_1_2_ppc64le.whl", hash = "sha256:f1a2f519ae173b5b6a2c9d5fa3116ce16e48b3462c8b96dfdded11055e3d6365"},
|
||||
{file = "charset_normalizer-3.4.0-cp311-cp311-musllinux_1_2_s390x.whl", hash = "sha256:63bc5c4ae26e4bc6be6469943b8253c0fd4e4186c43ad46e713ea61a0ba49129"},
|
||||
{file = "charset_normalizer-3.4.0-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:bcb4f8ea87d03bc51ad04add8ceaf9b0f085ac045ab4d74e73bbc2dc033f0236"},
|
||||
{file = "charset_normalizer-3.4.0-cp311-cp311-win32.whl", hash = "sha256:9ae4ef0b3f6b41bad6366fb0ea4fc1d7ed051528e113a60fa2a65a9abb5b1d99"},
|
||||
{file = "charset_normalizer-3.4.0-cp311-cp311-win_amd64.whl", hash = "sha256:cee4373f4d3ad28f1ab6290684d8e2ebdb9e7a1b74fdc39e4c211995f77bec27"},
|
||||
{file = "charset_normalizer-3.4.0-cp312-cp312-macosx_10_13_universal2.whl", hash = "sha256:0713f3adb9d03d49d365b70b84775d0a0d18e4ab08d12bc46baa6132ba78aaf6"},
|
||||
{file = "charset_normalizer-3.4.0-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:de7376c29d95d6719048c194a9cf1a1b0393fbe8488a22008610b0361d834ecf"},
|
||||
{file = "charset_normalizer-3.4.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:4a51b48f42d9358460b78725283f04bddaf44a9358197b889657deba38f329db"},
|
||||
{file = "charset_normalizer-3.4.0-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:b295729485b06c1a0683af02a9e42d2caa9db04a373dc38a6a58cdd1e8abddf1"},
|
||||
{file = "charset_normalizer-3.4.0-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:ee803480535c44e7f5ad00788526da7d85525cfefaf8acf8ab9a310000be4b03"},
|
||||
{file = "charset_normalizer-3.4.0-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:3d59d125ffbd6d552765510e3f31ed75ebac2c7470c7274195b9161a32350284"},
|
||||
{file = "charset_normalizer-3.4.0-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:8cda06946eac330cbe6598f77bb54e690b4ca93f593dee1568ad22b04f347c15"},
|
||||
{file = "charset_normalizer-3.4.0-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:07afec21bbbbf8a5cc3651aa96b980afe2526e7f048fdfb7f1014d84acc8b6d8"},
|
||||
{file = "charset_normalizer-3.4.0-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:6b40e8d38afe634559e398cc32b1472f376a4099c75fe6299ae607e404c033b2"},
|
||||
{file = "charset_normalizer-3.4.0-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:b8dcd239c743aa2f9c22ce674a145e0a25cb1566c495928440a181ca1ccf6719"},
|
||||
{file = "charset_normalizer-3.4.0-cp312-cp312-musllinux_1_2_ppc64le.whl", hash = "sha256:84450ba661fb96e9fd67629b93d2941c871ca86fc38d835d19d4225ff946a631"},
|
||||
{file = "charset_normalizer-3.4.0-cp312-cp312-musllinux_1_2_s390x.whl", hash = "sha256:44aeb140295a2f0659e113b31cfe92c9061622cadbc9e2a2f7b8ef6b1e29ef4b"},
|
||||
{file = "charset_normalizer-3.4.0-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:1db4e7fefefd0f548d73e2e2e041f9df5c59e178b4c72fbac4cc6f535cfb1565"},
|
||||
{file = "charset_normalizer-3.4.0-cp312-cp312-win32.whl", hash = "sha256:5726cf76c982532c1863fb64d8c6dd0e4c90b6ece9feb06c9f202417a31f7dd7"},
|
||||
{file = "charset_normalizer-3.4.0-cp312-cp312-win_amd64.whl", hash = "sha256:b197e7094f232959f8f20541ead1d9862ac5ebea1d58e9849c1bf979255dfac9"},
|
||||
{file = "charset_normalizer-3.4.0-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:dd4eda173a9fcccb5f2e2bd2a9f423d180194b1bf17cf59e3269899235b2a114"},
|
||||
{file = "charset_normalizer-3.4.0-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:e9e3c4c9e1ed40ea53acf11e2a386383c3304212c965773704e4603d589343ed"},
|
||||
{file = "charset_normalizer-3.4.0-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:92a7e36b000bf022ef3dbb9c46bfe2d52c047d5e3f3343f43204263c5addc250"},
|
||||
{file = "charset_normalizer-3.4.0-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:54b6a92d009cbe2fb11054ba694bc9e284dad30a26757b1e372a1fdddaf21920"},
|
||||
{file = "charset_normalizer-3.4.0-cp313-cp313-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:1ffd9493de4c922f2a38c2bf62b831dcec90ac673ed1ca182fe11b4d8e9f2a64"},
|
||||
{file = "charset_normalizer-3.4.0-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:35c404d74c2926d0287fbd63ed5d27eb911eb9e4a3bb2c6d294f3cfd4a9e0c23"},
|
||||
{file = "charset_normalizer-3.4.0-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:4796efc4faf6b53a18e3d46343535caed491776a22af773f366534056c4e1fbc"},
|
||||
{file = "charset_normalizer-3.4.0-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:e7fdd52961feb4c96507aa649550ec2a0d527c086d284749b2f582f2d40a2e0d"},
|
||||
{file = "charset_normalizer-3.4.0-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:92db3c28b5b2a273346bebb24857fda45601aef6ae1c011c0a997106581e8a88"},
|
||||
{file = "charset_normalizer-3.4.0-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:ab973df98fc99ab39080bfb0eb3a925181454d7c3ac8a1e695fddfae696d9e90"},
|
||||
{file = "charset_normalizer-3.4.0-cp313-cp313-musllinux_1_2_ppc64le.whl", hash = "sha256:4b67fdab07fdd3c10bb21edab3cbfe8cf5696f453afce75d815d9d7223fbe88b"},
|
||||
{file = "charset_normalizer-3.4.0-cp313-cp313-musllinux_1_2_s390x.whl", hash = "sha256:aa41e526a5d4a9dfcfbab0716c7e8a1b215abd3f3df5a45cf18a12721d31cb5d"},
|
||||
{file = "charset_normalizer-3.4.0-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:ffc519621dce0c767e96b9c53f09c5d215578e10b02c285809f76509a3931482"},
|
||||
{file = "charset_normalizer-3.4.0-cp313-cp313-win32.whl", hash = "sha256:f19c1585933c82098c2a520f8ec1227f20e339e33aca8fa6f956f6691b784e67"},
|
||||
{file = "charset_normalizer-3.4.0-cp313-cp313-win_amd64.whl", hash = "sha256:707b82d19e65c9bd28b81dde95249b07bf9f5b90ebe1ef17d9b57473f8a64b7b"},
|
||||
{file = "charset_normalizer-3.4.0-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:dbe03226baf438ac4fda9e2d0715022fd579cb641c4cf639fa40d53b2fe6f3e2"},
|
||||
{file = "charset_normalizer-3.4.0-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:dd9a8bd8900e65504a305bf8ae6fa9fbc66de94178c420791d0293702fce2df7"},
|
||||
{file = "charset_normalizer-3.4.0-cp37-cp37m-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:b8831399554b92b72af5932cdbbd4ddc55c55f631bb13ff8fe4e6536a06c5c51"},
|
||||
{file = "charset_normalizer-3.4.0-cp37-cp37m-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:a14969b8691f7998e74663b77b4c36c0337cb1df552da83d5c9004a93afdb574"},
|
||||
{file = "charset_normalizer-3.4.0-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:dcaf7c1524c0542ee2fc82cc8ec337f7a9f7edee2532421ab200d2b920fc97cf"},
|
||||
{file = "charset_normalizer-3.4.0-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:425c5f215d0eecee9a56cdb703203dda90423247421bf0d67125add85d0c4455"},
|
||||
{file = "charset_normalizer-3.4.0-cp37-cp37m-musllinux_1_2_aarch64.whl", hash = "sha256:d5b054862739d276e09928de37c79ddeec42a6e1bfc55863be96a36ba22926f6"},
|
||||
{file = "charset_normalizer-3.4.0-cp37-cp37m-musllinux_1_2_i686.whl", hash = "sha256:f3e73a4255342d4eb26ef6df01e3962e73aa29baa3124a8e824c5d3364a65748"},
|
||||
{file = "charset_normalizer-3.4.0-cp37-cp37m-musllinux_1_2_ppc64le.whl", hash = "sha256:2f6c34da58ea9c1a9515621f4d9ac379871a8f21168ba1b5e09d74250de5ad62"},
|
||||
{file = "charset_normalizer-3.4.0-cp37-cp37m-musllinux_1_2_s390x.whl", hash = "sha256:f09cb5a7bbe1ecae6e87901a2eb23e0256bb524a79ccc53eb0b7629fbe7677c4"},
|
||||
{file = "charset_normalizer-3.4.0-cp37-cp37m-musllinux_1_2_x86_64.whl", hash = "sha256:0099d79bdfcf5c1f0c2c72f91516702ebf8b0b8ddd8905f97a8aecf49712c621"},
|
||||
{file = "charset_normalizer-3.4.0-cp37-cp37m-win32.whl", hash = "sha256:9c98230f5042f4945f957d006edccc2af1e03ed5e37ce7c373f00a5a4daa6149"},
|
||||
{file = "charset_normalizer-3.4.0-cp37-cp37m-win_amd64.whl", hash = "sha256:62f60aebecfc7f4b82e3f639a7d1433a20ec32824db2199a11ad4f5e146ef5ee"},
|
||||
{file = "charset_normalizer-3.4.0-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:af73657b7a68211996527dbfeffbb0864e043d270580c5aef06dc4b659a4b578"},
|
||||
{file = "charset_normalizer-3.4.0-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:cab5d0b79d987c67f3b9e9c53f54a61360422a5a0bc075f43cab5621d530c3b6"},
|
||||
{file = "charset_normalizer-3.4.0-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:9289fd5dddcf57bab41d044f1756550f9e7cf0c8e373b8cdf0ce8773dc4bd417"},
|
||||
{file = "charset_normalizer-3.4.0-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:6b493a043635eb376e50eedf7818f2f322eabbaa974e948bd8bdd29eb7ef2a51"},
|
||||
{file = "charset_normalizer-3.4.0-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:9fa2566ca27d67c86569e8c85297aaf413ffab85a8960500f12ea34ff98e4c41"},
|
||||
{file = "charset_normalizer-3.4.0-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:a8e538f46104c815be19c975572d74afb53f29650ea2025bbfaef359d2de2f7f"},
|
||||
{file = "charset_normalizer-3.4.0-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6fd30dc99682dc2c603c2b315bded2799019cea829f8bf57dc6b61efde6611c8"},
|
||||
{file = "charset_normalizer-3.4.0-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:2006769bd1640bdf4d5641c69a3d63b71b81445473cac5ded39740a226fa88ab"},
|
||||
{file = "charset_normalizer-3.4.0-cp38-cp38-musllinux_1_2_aarch64.whl", hash = "sha256:dc15e99b2d8a656f8e666854404f1ba54765871104e50c8e9813af8a7db07f12"},
|
||||
{file = "charset_normalizer-3.4.0-cp38-cp38-musllinux_1_2_i686.whl", hash = "sha256:ab2e5bef076f5a235c3774b4f4028a680432cded7cad37bba0fd90d64b187d19"},
|
||||
{file = "charset_normalizer-3.4.0-cp38-cp38-musllinux_1_2_ppc64le.whl", hash = "sha256:4ec9dd88a5b71abfc74e9df5ebe7921c35cbb3b641181a531ca65cdb5e8e4dea"},
|
||||
{file = "charset_normalizer-3.4.0-cp38-cp38-musllinux_1_2_s390x.whl", hash = "sha256:43193c5cda5d612f247172016c4bb71251c784d7a4d9314677186a838ad34858"},
|
||||
{file = "charset_normalizer-3.4.0-cp38-cp38-musllinux_1_2_x86_64.whl", hash = "sha256:aa693779a8b50cd97570e5a0f343538a8dbd3e496fa5dcb87e29406ad0299654"},
|
||||
{file = "charset_normalizer-3.4.0-cp38-cp38-win32.whl", hash = "sha256:7706f5850360ac01d80c89bcef1640683cc12ed87f42579dab6c5d3ed6888613"},
|
||||
{file = "charset_normalizer-3.4.0-cp38-cp38-win_amd64.whl", hash = "sha256:c3e446d253bd88f6377260d07c895816ebf33ffffd56c1c792b13bff9c3e1ade"},
|
||||
{file = "charset_normalizer-3.4.0-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:980b4f289d1d90ca5efcf07958d3eb38ed9c0b7676bf2831a54d4f66f9c27dfa"},
|
||||
{file = "charset_normalizer-3.4.0-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:f28f891ccd15c514a0981f3b9db9aa23d62fe1a99997512b0491d2ed323d229a"},
|
||||
{file = "charset_normalizer-3.4.0-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:a8aacce6e2e1edcb6ac625fb0f8c3a9570ccc7bfba1f63419b3769ccf6a00ed0"},
|
||||
{file = "charset_normalizer-3.4.0-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:bd7af3717683bea4c87acd8c0d3d5b44d56120b26fd3f8a692bdd2d5260c620a"},
|
||||
{file = "charset_normalizer-3.4.0-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:5ff2ed8194587faf56555927b3aa10e6fb69d931e33953943bc4f837dfee2242"},
|
||||
{file = "charset_normalizer-3.4.0-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:e91f541a85298cf35433bf66f3fab2a4a2cff05c127eeca4af174f6d497f0d4b"},
|
||||
{file = "charset_normalizer-3.4.0-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:309a7de0a0ff3040acaebb35ec45d18db4b28232f21998851cfa709eeff49d62"},
|
||||
{file = "charset_normalizer-3.4.0-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:285e96d9d53422efc0d7a17c60e59f37fbf3dfa942073f666db4ac71e8d726d0"},
|
||||
{file = "charset_normalizer-3.4.0-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:5d447056e2ca60382d460a604b6302d8db69476fd2015c81e7c35417cfabe4cd"},
|
||||
{file = "charset_normalizer-3.4.0-cp39-cp39-musllinux_1_2_i686.whl", hash = "sha256:20587d20f557fe189b7947d8e7ec5afa110ccf72a3128d61a2a387c3313f46be"},
|
||||
{file = "charset_normalizer-3.4.0-cp39-cp39-musllinux_1_2_ppc64le.whl", hash = "sha256:130272c698667a982a5d0e626851ceff662565379baf0ff2cc58067b81d4f11d"},
|
||||
{file = "charset_normalizer-3.4.0-cp39-cp39-musllinux_1_2_s390x.whl", hash = "sha256:ab22fbd9765e6954bc0bcff24c25ff71dcbfdb185fcdaca49e81bac68fe724d3"},
|
||||
{file = "charset_normalizer-3.4.0-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:7782afc9b6b42200f7362858f9e73b1f8316afb276d316336c0ec3bd73312742"},
|
||||
{file = "charset_normalizer-3.4.0-cp39-cp39-win32.whl", hash = "sha256:2de62e8801ddfff069cd5c504ce3bc9672b23266597d4e4f50eda28846c322f2"},
|
||||
{file = "charset_normalizer-3.4.0-cp39-cp39-win_amd64.whl", hash = "sha256:95c3c157765b031331dd4db3c775e58deaee050a3042fcad72cbc4189d7c8dca"},
|
||||
{file = "charset_normalizer-3.4.0-py3-none-any.whl", hash = "sha256:fe9f97feb71aa9896b81973a7bbada8c49501dc73e58a10fcef6663af95e5079"},
|
||||
{file = "charset_normalizer-3.4.0.tar.gz", hash = "sha256:223217c3d4f82c3ac5e29032b3f1c2eb0fb591b72161f86d93f5719079dae93e"},
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "colorama"
|
||||
version = "0.4.6"
|
||||
description = "Cross-platform colored terminal text."
|
||||
optional = false
|
||||
python-versions = "!=3.0.*,!=3.1.*,!=3.2.*,!=3.3.*,!=3.4.*,!=3.5.*,!=3.6.*,>=2.7"
|
||||
files = [
|
||||
{file = "colorama-0.4.6-py2.py3-none-any.whl", hash = "sha256:4f1d9991f5acc0ca119f9d443620b77f9d6b33703e51011c16baf57afb285fc6"},
|
||||
{file = "colorama-0.4.6.tar.gz", hash = "sha256:08695f5cb7ed6e0531a20572697297273c47b8cae5a63ffc6d6ed5c201be6e44"},
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "exceptiongroup"
|
||||
version = "1.2.2"
|
||||
description = "Backport of PEP 654 (exception groups)"
|
||||
optional = false
|
||||
python-versions = ">=3.7"
|
||||
files = [
|
||||
{file = "exceptiongroup-1.2.2-py3-none-any.whl", hash = "sha256:3111b9d131c238bec2f8f516e123e14ba243563fb135d3fe885990585aa7795b"},
|
||||
{file = "exceptiongroup-1.2.2.tar.gz", hash = "sha256:47c2edf7c6738fafb49fd34290706d1a1a2f4d1c6df275526b62cbb4aa5393cc"},
|
||||
]
|
||||
|
||||
[package.extras]
|
||||
test = ["pytest (>=6)"]
|
||||
|
||||
[[package]]
|
||||
name = "idna"
|
||||
version = "3.10"
|
||||
description = "Internationalized Domain Names in Applications (IDNA)"
|
||||
optional = false
|
||||
python-versions = ">=3.6"
|
||||
files = [
|
||||
{file = "idna-3.10-py3-none-any.whl", hash = "sha256:946d195a0d259cbba61165e88e65941f16e9b36ea6ddb97f00452bae8b1287d3"},
|
||||
{file = "idna-3.10.tar.gz", hash = "sha256:12f65c9b470abda6dc35cf8e63cc574b1c52b11df2c86030af0ac09b01b13ea9"},
|
||||
]
|
||||
|
||||
[package.extras]
|
||||
all = ["flake8 (>=7.1.1)", "mypy (>=1.11.2)", "pytest (>=8.3.2)", "ruff (>=0.6.2)"]
|
||||
|
||||
[[package]]
|
||||
name = "iniconfig"
|
||||
version = "2.0.0"
|
||||
description = "brain-dead simple config-ini parsing"
|
||||
optional = false
|
||||
python-versions = ">=3.7"
|
||||
files = [
|
||||
{file = "iniconfig-2.0.0-py3-none-any.whl", hash = "sha256:b6a85871a79d2e3b22d2d1b94ac2824226a63c6b741c88f7ae975f18b6778374"},
|
||||
{file = "iniconfig-2.0.0.tar.gz", hash = "sha256:2d91e135bf72d31a410b17c16da610a82cb55f6b0477d1a902134b24a455b8b3"},
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "mypy-extensions"
|
||||
version = "1.0.0"
|
||||
description = "Type system extensions for programs checked with the mypy type checker."
|
||||
optional = true
|
||||
python-versions = ">=3.5"
|
||||
files = [
|
||||
{file = "mypy_extensions-1.0.0-py3-none-any.whl", hash = "sha256:4392f6c0eb8a5668a69e23d168ffa70f0be9ccfd32b5cc2d26a34ae5b844552d"},
|
||||
{file = "mypy_extensions-1.0.0.tar.gz", hash = "sha256:75dbf8955dc00442a438fc4d0666508a9a97b6bd41aa2f0ffe9d2f2725af0782"},
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "packaging"
|
||||
version = "24.2"
|
||||
description = "Core utilities for Python packages"
|
||||
optional = false
|
||||
python-versions = ">=3.8"
|
||||
files = [
|
||||
{file = "packaging-24.2-py3-none-any.whl", hash = "sha256:09abb1bccd265c01f4a3aa3f7a7db064b36514d2cba19a2f694fe6150451a759"},
|
||||
{file = "packaging-24.2.tar.gz", hash = "sha256:c228a6dc5e932d346bc5739379109d49e8853dd8223571c7c5b55260edc0b97f"},
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "pluggy"
|
||||
version = "1.5.0"
|
||||
description = "plugin and hook calling mechanisms for python"
|
||||
optional = false
|
||||
python-versions = ">=3.8"
|
||||
files = [
|
||||
{file = "pluggy-1.5.0-py3-none-any.whl", hash = "sha256:44e1ad92c8ca002de6377e165f3e0f1be63266ab4d554740532335b9d75ea669"},
|
||||
{file = "pluggy-1.5.0.tar.gz", hash = "sha256:2cffa88e94fdc978c4c574f15f9e59b7f4201d439195c3715ca9e2486f1d0cf1"},
|
||||
]
|
||||
|
||||
[package.extras]
|
||||
dev = ["pre-commit", "tox"]
|
||||
testing = ["pytest", "pytest-benchmark"]
|
||||
|
||||
[[package]]
|
||||
name = "pytest"
|
||||
version = "8.3.4"
|
||||
description = "pytest: simple powerful testing with Python"
|
||||
optional = false
|
||||
python-versions = ">=3.8"
|
||||
files = [
|
||||
{file = "pytest-8.3.4-py3-none-any.whl", hash = "sha256:50e16d954148559c9a74109af1eaf0c945ba2d8f30f0a3d3335edde19788b6f6"},
|
||||
{file = "pytest-8.3.4.tar.gz", hash = "sha256:965370d062bce11e73868e0335abac31b4d3de0e82f4007408d242b4f8610761"},
|
||||
]
|
||||
|
||||
[package.dependencies]
|
||||
colorama = {version = "*", markers = "sys_platform == \"win32\""}
|
||||
exceptiongroup = {version = ">=1.0.0rc8", markers = "python_version < \"3.11\""}
|
||||
iniconfig = "*"
|
||||
packaging = "*"
|
||||
pluggy = ">=1.5,<2"
|
||||
tomli = {version = ">=1", markers = "python_version < \"3.11\""}
|
||||
|
||||
[package.extras]
|
||||
dev = ["argcomplete", "attrs (>=19.2)", "hypothesis (>=3.56)", "mock", "pygments (>=2.7.2)", "requests", "setuptools", "xmlschema"]
|
||||
|
||||
[[package]]
|
||||
name = "requests"
|
||||
version = "2.32.3"
|
||||
description = "Python HTTP for Humans."
|
||||
optional = false
|
||||
python-versions = ">=3.8"
|
||||
files = [
|
||||
{file = "requests-2.32.3-py3-none-any.whl", hash = "sha256:70761cfe03c773ceb22aa2f671b4757976145175cdfca038c02654d061d6dcc6"},
|
||||
{file = "requests-2.32.3.tar.gz", hash = "sha256:55365417734eb18255590a9ff9eb97e9e1da868d4ccd6402399eaf68af20a760"},
|
||||
]
|
||||
|
||||
[package.dependencies]
|
||||
certifi = ">=2017.4.17"
|
||||
charset-normalizer = ">=2,<4"
|
||||
idna = ">=2.5,<4"
|
||||
urllib3 = ">=1.21.1,<3"
|
||||
|
||||
[package.extras]
|
||||
socks = ["PySocks (>=1.5.6,!=1.5.7)"]
|
||||
use-chardet-on-py3 = ["chardet (>=3.0.2,<6)"]
|
||||
|
||||
[[package]]
|
||||
name = "ruff"
|
||||
version = "0.8.3"
|
||||
description = "An extremely fast Python linter and code formatter, written in Rust."
|
||||
optional = false
|
||||
python-versions = ">=3.7"
|
||||
files = [
|
||||
{file = "ruff-0.8.3-py3-none-linux_armv6l.whl", hash = "sha256:8d5d273ffffff0acd3db5bf626d4b131aa5a5ada1276126231c4174543ce20d6"},
|
||||
{file = "ruff-0.8.3-py3-none-macosx_10_12_x86_64.whl", hash = "sha256:e4d66a21de39f15c9757d00c50c8cdd20ac84f55684ca56def7891a025d7e939"},
|
||||
{file = "ruff-0.8.3-py3-none-macosx_11_0_arm64.whl", hash = "sha256:c356e770811858bd20832af696ff6c7e884701115094f427b64b25093d6d932d"},
|
||||
{file = "ruff-0.8.3-py3-none-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:9c0a60a825e3e177116c84009d5ebaa90cf40dfab56e1358d1df4e29a9a14b13"},
|
||||
{file = "ruff-0.8.3-py3-none-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:75fb782f4db39501210ac093c79c3de581d306624575eddd7e4e13747e61ba18"},
|
||||
{file = "ruff-0.8.3-py3-none-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:7f26bc76a133ecb09a38b7868737eded6941b70a6d34ef53a4027e83913b6502"},
|
||||
{file = "ruff-0.8.3-py3-none-manylinux_2_17_ppc64.manylinux2014_ppc64.whl", hash = "sha256:01b14b2f72a37390c1b13477c1c02d53184f728be2f3ffc3ace5b44e9e87b90d"},
|
||||
{file = "ruff-0.8.3-py3-none-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:53babd6e63e31f4e96ec95ea0d962298f9f0d9cc5990a1bbb023a6baf2503a82"},
|
||||
{file = "ruff-0.8.3-py3-none-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:1ae441ce4cf925b7f363d33cd6570c51435972d697e3e58928973994e56e1452"},
|
||||
{file = "ruff-0.8.3-py3-none-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:d7c65bc0cadce32255e93c57d57ecc2cca23149edd52714c0c5d6fa11ec328cd"},
|
||||
{file = "ruff-0.8.3-py3-none-musllinux_1_2_aarch64.whl", hash = "sha256:5be450bb18f23f0edc5a4e5585c17a56ba88920d598f04a06bd9fd76d324cb20"},
|
||||
{file = "ruff-0.8.3-py3-none-musllinux_1_2_armv7l.whl", hash = "sha256:8faeae3827eaa77f5721f09b9472a18c749139c891dbc17f45e72d8f2ca1f8fc"},
|
||||
{file = "ruff-0.8.3-py3-none-musllinux_1_2_i686.whl", hash = "sha256:db503486e1cf074b9808403991663e4277f5c664d3fe237ee0d994d1305bb060"},
|
||||
{file = "ruff-0.8.3-py3-none-musllinux_1_2_x86_64.whl", hash = "sha256:6567be9fb62fbd7a099209257fef4ad2c3153b60579818b31a23c886ed4147ea"},
|
||||
{file = "ruff-0.8.3-py3-none-win32.whl", hash = "sha256:19048f2f878f3ee4583fc6cb23fb636e48c2635e30fb2022b3a1cd293402f964"},
|
||||
{file = "ruff-0.8.3-py3-none-win_amd64.whl", hash = "sha256:f7df94f57d7418fa7c3ffb650757e0c2b96cf2501a0b192c18e4fb5571dfada9"},
|
||||
{file = "ruff-0.8.3-py3-none-win_arm64.whl", hash = "sha256:fe2756edf68ea79707c8d68b78ca9a58ed9af22e430430491ee03e718b5e4936"},
|
||||
{file = "ruff-0.8.3.tar.gz", hash = "sha256:5e7558304353b84279042fc584a4f4cb8a07ae79b2bf3da1a7551d960b5626d3"},
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "tomli"
|
||||
version = "2.2.1"
|
||||
description = "A lil' TOML parser"
|
||||
optional = false
|
||||
python-versions = ">=3.8"
|
||||
files = [
|
||||
{file = "tomli-2.2.1-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:678e4fa69e4575eb77d103de3df8a895e1591b48e740211bd1067378c69e8249"},
|
||||
{file = "tomli-2.2.1-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:023aa114dd824ade0100497eb2318602af309e5a55595f76b626d6d9f3b7b0a6"},
|
||||
{file = "tomli-2.2.1-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:ece47d672db52ac607a3d9599a9d48dcb2f2f735c6c2d1f34130085bb12b112a"},
|
||||
{file = "tomli-2.2.1-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6972ca9c9cc9f0acaa56a8ca1ff51e7af152a9f87fb64623e31d5c83700080ee"},
|
||||
{file = "tomli-2.2.1-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:c954d2250168d28797dd4e3ac5cf812a406cd5a92674ee4c8f123c889786aa8e"},
|
||||
{file = "tomli-2.2.1-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:8dd28b3e155b80f4d54beb40a441d366adcfe740969820caf156c019fb5c7ec4"},
|
||||
{file = "tomli-2.2.1-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:e59e304978767a54663af13c07b3d1af22ddee3bb2fb0618ca1593e4f593a106"},
|
||||
{file = "tomli-2.2.1-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:33580bccab0338d00994d7f16f4c4ec25b776af3ffaac1ed74e0b3fc95e885a8"},
|
||||
{file = "tomli-2.2.1-cp311-cp311-win32.whl", hash = "sha256:465af0e0875402f1d226519c9904f37254b3045fc5084697cefb9bdde1ff99ff"},
|
||||
{file = "tomli-2.2.1-cp311-cp311-win_amd64.whl", hash = "sha256:2d0f2fdd22b02c6d81637a3c95f8cd77f995846af7414c5c4b8d0545afa1bc4b"},
|
||||
{file = "tomli-2.2.1-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:4a8f6e44de52d5e6c657c9fe83b562f5f4256d8ebbfe4ff922c495620a7f6cea"},
|
||||
{file = "tomli-2.2.1-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:8d57ca8095a641b8237d5b079147646153d22552f1c637fd3ba7f4b0b29167a8"},
|
||||
{file = "tomli-2.2.1-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:4e340144ad7ae1533cb897d406382b4b6fede8890a03738ff1683af800d54192"},
|
||||
{file = "tomli-2.2.1-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:db2b95f9de79181805df90bedc5a5ab4c165e6ec3fe99f970d0e302f384ad222"},
|
||||
{file = "tomli-2.2.1-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:40741994320b232529c802f8bc86da4e1aa9f413db394617b9a256ae0f9a7f77"},
|
||||
{file = "tomli-2.2.1-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:400e720fe168c0f8521520190686ef8ef033fb19fc493da09779e592861b78c6"},
|
||||
{file = "tomli-2.2.1-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:02abe224de6ae62c19f090f68da4e27b10af2b93213d36cf44e6e1c5abd19fdd"},
|
||||
{file = "tomli-2.2.1-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:b82ebccc8c8a36f2094e969560a1b836758481f3dc360ce9a3277c65f374285e"},
|
||||
{file = "tomli-2.2.1-cp312-cp312-win32.whl", hash = "sha256:889f80ef92701b9dbb224e49ec87c645ce5df3fa2cc548664eb8a25e03127a98"},
|
||||
{file = "tomli-2.2.1-cp312-cp312-win_amd64.whl", hash = "sha256:7fc04e92e1d624a4a63c76474610238576942d6b8950a2d7f908a340494e67e4"},
|
||||
{file = "tomli-2.2.1-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:f4039b9cbc3048b2416cc57ab3bda989a6fcf9b36cf8937f01a6e731b64f80d7"},
|
||||
{file = "tomli-2.2.1-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:286f0ca2ffeeb5b9bd4fcc8d6c330534323ec51b2f52da063b11c502da16f30c"},
|
||||
{file = "tomli-2.2.1-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a92ef1a44547e894e2a17d24e7557a5e85a9e1d0048b0b5e7541f76c5032cb13"},
|
||||
{file = "tomli-2.2.1-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:9316dc65bed1684c9a98ee68759ceaed29d229e985297003e494aa825ebb0281"},
|
||||
{file = "tomli-2.2.1-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:e85e99945e688e32d5a35c1ff38ed0b3f41f43fad8df0bdf79f72b2ba7bc5272"},
|
||||
{file = "tomli-2.2.1-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:ac065718db92ca818f8d6141b5f66369833d4a80a9d74435a268c52bdfa73140"},
|
||||
{file = "tomli-2.2.1-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:d920f33822747519673ee656a4b6ac33e382eca9d331c87770faa3eef562aeb2"},
|
||||
{file = "tomli-2.2.1-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:a198f10c4d1b1375d7687bc25294306e551bf1abfa4eace6650070a5c1ae2744"},
|
||||
{file = "tomli-2.2.1-cp313-cp313-win32.whl", hash = "sha256:d3f5614314d758649ab2ab3a62d4f2004c825922f9e370b29416484086b264ec"},
|
||||
{file = "tomli-2.2.1-cp313-cp313-win_amd64.whl", hash = "sha256:a38aa0308e754b0e3c67e344754dff64999ff9b513e691d0e786265c93583c69"},
|
||||
{file = "tomli-2.2.1-py3-none-any.whl", hash = "sha256:cb55c73c5f4408779d0cf3eef9f762b9c9f147a77de7b258bef0a5628adc85cc"},
|
||||
{file = "tomli-2.2.1.tar.gz", hash = "sha256:cd45e1dc79c835ce60f7404ec8119f2eb06d38b1deba146f07ced3bbc44505ff"},
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "typing-extensions"
|
||||
version = "4.12.2"
|
||||
description = "Backported and Experimental Type Hints for Python 3.8+"
|
||||
optional = true
|
||||
python-versions = ">=3.8"
|
||||
files = [
|
||||
{file = "typing_extensions-4.12.2-py3-none-any.whl", hash = "sha256:04e5ca0351e0f3f85c6853954072df659d0d13fac324d0072316b67d7794700d"},
|
||||
{file = "typing_extensions-4.12.2.tar.gz", hash = "sha256:1a7ead55c7e559dd4dee8856e3a88b41225abfe1ce8df57b7c13915fe121ffb8"},
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "typing-inspect"
|
||||
version = "0.9.0"
|
||||
description = "Runtime inspection utilities for typing module."
|
||||
optional = true
|
||||
python-versions = "*"
|
||||
files = [
|
||||
{file = "typing_inspect-0.9.0-py3-none-any.whl", hash = "sha256:9ee6fc59062311ef8547596ab6b955e1b8aa46242d854bfc78f4f6b0eff35f9f"},
|
||||
{file = "typing_inspect-0.9.0.tar.gz", hash = "sha256:b23fc42ff6f6ef6954e4852c1fb512cdd18dbea03134f91f856a95ccc9461f78"},
|
||||
]
|
||||
|
||||
[package.dependencies]
|
||||
mypy-extensions = ">=0.3.0"
|
||||
typing-extensions = ">=3.7.4"
|
||||
|
||||
[[package]]
|
||||
name = "urllib3"
|
||||
version = "2.2.3"
|
||||
description = "HTTP library with thread-safe connection pooling, file post, and more."
|
||||
optional = false
|
||||
python-versions = ">=3.8"
|
||||
files = [
|
||||
{file = "urllib3-2.2.3-py3-none-any.whl", hash = "sha256:ca899ca043dcb1bafa3e262d73aa25c465bfb49e0bd9dd5d59f1d0acba2f8fac"},
|
||||
{file = "urllib3-2.2.3.tar.gz", hash = "sha256:e7d814a81dad81e6caf2ec9fdedb284ecc9c73076b62654547cc64ccdcae26e9"},
|
||||
]
|
||||
|
||||
[package.extras]
|
||||
brotli = ["brotli (>=1.0.9)", "brotlicffi (>=0.8.0)"]
|
||||
h2 = ["h2 (>=4,<5)"]
|
||||
socks = ["pysocks (>=1.5.6,!=1.5.7,<2.0)"]
|
||||
zstd = ["zstandard (>=0.18.0)"]
|
||||
|
||||
[metadata]
|
||||
lock-version = "2.0"
|
||||
python-versions = "^3.9"
|
||||
content-hash = "fd0e5fc1dfc09e39acec1d9fe304fecccbdff1ca85271ab1f15a19d008db23cf"
|
||||
23
pkg/fanal/analyzer/language/python/poetry/testdata/with-groups/pyproject.toml
vendored
Normal file
23
pkg/fanal/analyzer/language/python/poetry/testdata/with-groups/pyproject.toml
vendored
Normal file
@@ -0,0 +1,23 @@
|
||||
[tool.poetry]
|
||||
name = "groups"
|
||||
version = "0.1.0"
|
||||
description = ""
|
||||
authors = ["Your Name <you@example.com>"]
|
||||
readme = "README.md"
|
||||
|
||||
[tool.poetry.dependencies]
|
||||
python = "^3.9"
|
||||
requests = "2.32.3"
|
||||
typing-inspect = {version = "0.9.0", optional = true}
|
||||
|
||||
|
||||
[tool.poetry.group.dev.dependencies]
|
||||
pytest = "8.3.4"
|
||||
|
||||
|
||||
[tool.poetry.group.lint.dependencies]
|
||||
ruff = "0.8.3"
|
||||
|
||||
[build-system]
|
||||
requires = ["poetry-core"]
|
||||
build-backend = "poetry.core.masonry.api"
|
||||
@@ -4,6 +4,7 @@ import (
|
||||
"context"
|
||||
"os"
|
||||
"path"
|
||||
"slices"
|
||||
"strings"
|
||||
|
||||
"golang.org/x/xerrors"
|
||||
@@ -51,6 +52,14 @@ func (a sbomAnalyzer) Analyze(ctx context.Context, input analyzer.AnalysisInput)
|
||||
handleBitnamiImages(path.Dir(input.FilePath), bom)
|
||||
}
|
||||
|
||||
// FilePath for apps with aggregatingTypes is empty.
|
||||
// Set the SBOM file path as Application.FilePath to correctly overwrite applications when merging layers.
|
||||
for i, app := range bom.Applications {
|
||||
if slices.Contains(ftypes.AggregatingTypes, app.Type) && app.FilePath == "" {
|
||||
bom.Applications[i].FilePath = input.FilePath
|
||||
}
|
||||
}
|
||||
|
||||
return &analyzer.AnalysisResult{
|
||||
PackageInfos: bom.Packages,
|
||||
Applications: bom.Applications,
|
||||
|
||||
@@ -28,7 +28,34 @@ func Test_sbomAnalyzer_Analyze(t *testing.T) {
|
||||
want: &analyzer.AnalysisResult{
|
||||
Applications: []types.Application{
|
||||
{
|
||||
Type: types.Jar,
|
||||
Type: types.Bitnami,
|
||||
FilePath: "opt/bitnami/elasticsearch",
|
||||
Packages: types.Packages{
|
||||
{
|
||||
ID: "elasticsearch@8.9.1",
|
||||
Name: "elasticsearch",
|
||||
Version: "8.9.1",
|
||||
Arch: "arm64",
|
||||
Licenses: []string{"Elastic-2.0"},
|
||||
Identifier: types.PkgIdentifier{
|
||||
PURL: &packageurl.PackageURL{
|
||||
Type: packageurl.TypeBitnami,
|
||||
Name: "elasticsearch",
|
||||
Version: "8.9.1",
|
||||
Qualifiers: packageurl.Qualifiers{
|
||||
{
|
||||
Key: "arch",
|
||||
Value: "arm64",
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
Type: types.Jar,
|
||||
FilePath: "opt/bitnami/elasticsearch/.spdx-elasticsearch.spdx",
|
||||
Packages: types.Packages{
|
||||
{
|
||||
ID: "co.elastic.apm:apm-agent:1.36.0",
|
||||
@@ -88,32 +115,6 @@ func Test_sbomAnalyzer_Analyze(t *testing.T) {
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
Type: types.Bitnami,
|
||||
FilePath: "opt/bitnami/elasticsearch",
|
||||
Packages: types.Packages{
|
||||
{
|
||||
ID: "elasticsearch@8.9.1",
|
||||
Name: "elasticsearch",
|
||||
Version: "8.9.1",
|
||||
Arch: "arm64",
|
||||
Licenses: []string{"Elastic-2.0"},
|
||||
Identifier: types.PkgIdentifier{
|
||||
PURL: &packageurl.PackageURL{
|
||||
Type: packageurl.TypeBitnami,
|
||||
Name: "elasticsearch",
|
||||
Version: "8.9.1",
|
||||
Qualifiers: packageurl.Qualifiers{
|
||||
{
|
||||
Key: "arch",
|
||||
Value: "arm64",
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
wantErr: require.NoError,
|
||||
@@ -125,7 +126,8 @@ func Test_sbomAnalyzer_Analyze(t *testing.T) {
|
||||
want: &analyzer.AnalysisResult{
|
||||
Applications: []types.Application{
|
||||
{
|
||||
Type: types.Jar,
|
||||
Type: types.Jar,
|
||||
FilePath: "opt/bitnami/elasticsearch/.spdx-elasticsearch.cdx",
|
||||
Packages: types.Packages{
|
||||
{
|
||||
FilePath: "opt/bitnami/elasticsearch/modules/apm/elastic-apm-agent-1.36.0.jar",
|
||||
|
||||
@@ -961,6 +961,91 @@ func TestApplier_ApplyLayers(t *testing.T) {
|
||||
},
|
||||
wantErr: "unknown OS",
|
||||
},
|
||||
{
|
||||
name: "SUSE images - legacy OS name with backward compatibility",
|
||||
args: args{
|
||||
imageID: "sha256:fb44d01953611ba18d43d88e158c25579d18eff42db671182245010620a283f3",
|
||||
layerIDs: []string{
|
||||
"sha256:2615f175cf3da67c48c6542914744943ee5e9c253547b03e3cfe8aae605c3199",
|
||||
},
|
||||
},
|
||||
getLayerExpectations: []cache.LocalArtifactCacheGetBlobExpectation{
|
||||
{
|
||||
Args: cache.LocalArtifactCacheGetBlobArgs{
|
||||
BlobID: "sha256:2615f175cf3da67c48c6542914744943ee5e9c253547b03e3cfe8aae605c3199",
|
||||
},
|
||||
Returns: cache.LocalArtifactCacheGetBlobReturns{
|
||||
BlobInfo: types.BlobInfo{
|
||||
SchemaVersion: 1,
|
||||
Digest: "sha256:fb44d01953611ba18d43d88e158c25579d18eff42db671182245010620a283f3",
|
||||
DiffID: "sha256:d555e1b0b42f21a1cf198e52bcb12fe66aa015348e4390d2d5acddd327d79073",
|
||||
OS: types.OS{
|
||||
Family: "suse linux enterprise server",
|
||||
Name: "15.4",
|
||||
},
|
||||
PackageInfos: []types.PackageInfo{
|
||||
{
|
||||
FilePath: "usr/lib/sysimage/rpm/Packages.db",
|
||||
Packages: types.Packages{
|
||||
{
|
||||
Name: "curl",
|
||||
Version: "7.79.1",
|
||||
SrcName: "curl",
|
||||
SrcVersion: "7.79.1",
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
getArtifactExpectations: []cache.LocalArtifactCacheGetArtifactExpectation{
|
||||
{
|
||||
Args: cache.LocalArtifactCacheGetArtifactArgs{
|
||||
ArtifactID: "sha256:fb44d01953611ba18d43d88e158c25579d18eff42db671182245010620a283f3",
|
||||
},
|
||||
Returns: cache.LocalArtifactCacheGetArtifactReturns{
|
||||
ArtifactInfo: types.ArtifactInfo{
|
||||
SchemaVersion: 1,
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
want: types.ArtifactDetail{
|
||||
OS: types.OS{
|
||||
Family: "sles",
|
||||
Name: "15.4",
|
||||
},
|
||||
Packages: types.Packages{
|
||||
{
|
||||
Name: "curl",
|
||||
Version: "7.79.1",
|
||||
SrcName: "curl",
|
||||
SrcVersion: "7.79.1",
|
||||
Identifier: types.PkgIdentifier{
|
||||
UID: "1e9b3d3a73785651",
|
||||
PURL: &packageurl.PackageURL{
|
||||
Type: packageurl.TypeRPM,
|
||||
Namespace: "suse",
|
||||
Name: "curl",
|
||||
Version: "7.79.1",
|
||||
Qualifiers: packageurl.Qualifiers{
|
||||
{
|
||||
Key: "distro",
|
||||
Value: "sles-15.4",
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
Layer: types.Layer{
|
||||
Digest: "sha256:fb44d01953611ba18d43d88e158c25579d18eff42db671182245010620a283f3",
|
||||
DiffID: "sha256:d555e1b0b42f21a1cf198e52bcb12fe66aa015348e4390d2d5acddd327d79073",
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
|
||||
@@ -19,6 +19,13 @@ func (o *OS) Detected() bool {
|
||||
return o.Family != ""
|
||||
}
|
||||
|
||||
// Normalize normalizes OS family names for backward compatibility
|
||||
func (o *OS) Normalize() {
|
||||
if alias, ok := OSTypeAliases[o.Family]; ok {
|
||||
o.Family = alias
|
||||
}
|
||||
}
|
||||
|
||||
// Merge merges OS version and enhanced security maintenance programs
|
||||
func (o *OS) Merge(newOS OS) {
|
||||
if lo.IsEmpty(newOS) {
|
||||
@@ -45,6 +52,11 @@ func (o *OS) Merge(newOS OS) {
|
||||
o.Extended = true
|
||||
}
|
||||
}
|
||||
// When merging layers, there are cases when a layer contains an OS with an old name:
|
||||
// - Cache contains a layer derived from an old version of Trivy.
|
||||
// - `client` uses an old version of Trivy, but `server` is a new version of Trivy (for `client/server` mode).
|
||||
// So we need to normalize the OS name for backward compatibility.
|
||||
o.Normalize()
|
||||
}
|
||||
|
||||
type Repository struct {
|
||||
|
||||
@@ -43,6 +43,15 @@ const (
|
||||
Wolfi OSType = "wolfi"
|
||||
)
|
||||
|
||||
// OSTypeAliases is a map of aliases for operating systems.
|
||||
// This is used to map the old family names to the new ones for backward compatibility.
|
||||
var OSTypeAliases = map[OSType]OSType{
|
||||
"opensuse.leap": OpenSUSELeap,
|
||||
"opensuse.tumbleweed": OpenSUSETumbleweed,
|
||||
"suse linux enterprise micro": SLEMicro,
|
||||
"suse linux enterprise server": SLES,
|
||||
}
|
||||
|
||||
// Programming language dependencies
|
||||
const (
|
||||
Bundler LangType = "bundler"
|
||||
|
||||
@@ -24,7 +24,7 @@ type ModuleDefinition struct {
|
||||
}
|
||||
|
||||
func (d *ModuleDefinition) inputVars() map[string]cty.Value {
|
||||
inputs := d.Definition.Values().AsValueMap()
|
||||
inputs := d.Definition.NullableValues().AsValueMap()
|
||||
if inputs == nil {
|
||||
return make(map[string]cty.Value)
|
||||
}
|
||||
|
||||
@@ -2161,3 +2161,29 @@ resource "foo" "this" {
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func TestAttrRefToNullVariable(t *testing.T) {
|
||||
fsys := fstest.MapFS{
|
||||
"main.tf": &fstest.MapFile{Data: []byte(`variable "name" {
|
||||
type = string
|
||||
default = null
|
||||
}
|
||||
|
||||
resource "aws_s3_bucket" "example" {
|
||||
bucket = var.name
|
||||
}`)},
|
||||
}
|
||||
|
||||
parser := New(fsys, "", OptionStopOnHCLError(true))
|
||||
|
||||
require.NoError(t, parser.ParseFS(context.TODO(), "."))
|
||||
|
||||
_, err := parser.Load(context.TODO())
|
||||
require.NoError(t, err)
|
||||
|
||||
modules, _, err := parser.EvaluateAll(context.TODO())
|
||||
require.NoError(t, err)
|
||||
|
||||
val := modules.GetResourcesByType("aws_s3_bucket")[0].GetAttribute("bucket").GetRawValue()
|
||||
assert.Nil(t, val)
|
||||
}
|
||||
|
||||
@@ -569,13 +569,25 @@ func (b *Block) Attributes() map[string]*Attribute {
|
||||
return attributes
|
||||
}
|
||||
|
||||
func (b *Block) NullableValues() cty.Value {
|
||||
return b.values(true)
|
||||
}
|
||||
|
||||
func (b *Block) Values() cty.Value {
|
||||
return b.values(false)
|
||||
}
|
||||
|
||||
func (b *Block) values(allowNull bool) cty.Value {
|
||||
values := createPresetValues(b)
|
||||
for _, attribute := range b.GetAttributes() {
|
||||
if attribute.Name() == "for_each" {
|
||||
continue
|
||||
}
|
||||
values[attribute.Name()] = attribute.NullableValue()
|
||||
if allowNull {
|
||||
values[attribute.Name()] = attribute.NullableValue()
|
||||
} else {
|
||||
values[attribute.Name()] = attribute.Value()
|
||||
}
|
||||
}
|
||||
return cty.ObjectVal(postProcessValues(b, values))
|
||||
}
|
||||
|
||||
@@ -262,6 +262,19 @@ func shouldTryOtherRepo(err error) bool {
|
||||
}
|
||||
}
|
||||
|
||||
// try the following artifact only if a temporary error occurs
|
||||
return terr.Temporary()
|
||||
// try the following artifact if a temporary error occurs
|
||||
if terr.Temporary() {
|
||||
return true
|
||||
}
|
||||
|
||||
// `GCR` periodically returns `BLOB_UNKNOWN` error.
|
||||
// cf. https://github.com/aquasecurity/trivy/discussions/8020
|
||||
// In this case we need to check other repositories.
|
||||
for _, e := range terr.Errors {
|
||||
if e.Code == transport.BlobUnknownErrorCode {
|
||||
return true
|
||||
}
|
||||
}
|
||||
|
||||
return false
|
||||
}
|
||||
|
||||
@@ -559,7 +559,6 @@ func TestMarshaler_MarshalReport(t *testing.T) {
|
||||
{
|
||||
Ref: "3ff14136-e09f-4df9-80ea-000000000004",
|
||||
Dependencies: &[]string{
|
||||
"3ff14136-e09f-4df9-80ea-000000000005",
|
||||
"pkg:gem/actioncontroller@7.0.0",
|
||||
},
|
||||
},
|
||||
@@ -1123,8 +1122,6 @@ func TestMarshaler_MarshalReport(t *testing.T) {
|
||||
Ref: "3ff14136-e09f-4df9-80ea-000000000002",
|
||||
Dependencies: &[]string{
|
||||
"pkg:rpm/centos/acl@2.2.53-1.el8?arch=aarch64&distro=centos-8.3.2011&epoch=1",
|
||||
// Trivy is unable to identify the direct OS packages as of today.
|
||||
"pkg:rpm/centos/glibc@2.28-151.el8?arch=aarch64&distro=centos-8.3.2011",
|
||||
},
|
||||
},
|
||||
{
|
||||
|
||||
172
pkg/sbom/cyclonedx/testdata/happy/nested-packages-bom.json
vendored
Normal file
172
pkg/sbom/cyclonedx/testdata/happy/nested-packages-bom.json
vendored
Normal file
@@ -0,0 +1,172 @@
|
||||
{
|
||||
"$schema": "http://cyclonedx.org/schema/bom-1.6.schema.json",
|
||||
"bomFormat": "CycloneDX",
|
||||
"specVersion": "1.6",
|
||||
"serialNumber": "urn:uuid:12346a7a-5819-43bf-9411-5c146304f023",
|
||||
"version": 1,
|
||||
"metadata": {
|
||||
"timestamp": "2024-12-20T10:57:13+00:00",
|
||||
"tools": {
|
||||
"components": [
|
||||
{
|
||||
"type": "application",
|
||||
"group": "aquasecurity",
|
||||
"name": "trivy",
|
||||
"version": "0.38.7-764-g30c7cb137"
|
||||
}
|
||||
]
|
||||
},
|
||||
"component": {
|
||||
"bom-ref": "1cb40520-a22c-481f-ad77-6bc6960430c5",
|
||||
"type": "application",
|
||||
"name": "/test",
|
||||
"properties": [
|
||||
{
|
||||
"name": "aquasecurity:trivy:SchemaVersion",
|
||||
"value": "2"
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
"components": [
|
||||
{
|
||||
"bom-ref": "4021d631-e242-4e69-8a93-928665810a27",
|
||||
"type": "application",
|
||||
"name": "foo/bar/test.elf",
|
||||
"properties": [
|
||||
{
|
||||
"name": "aquasecurity:trivy:Class",
|
||||
"value": "lang-pkgs"
|
||||
},
|
||||
{
|
||||
"name": "aquasecurity:trivy:Type",
|
||||
"value": "gobinary"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"bom-ref": "pkg:golang/github.com/aquasecurity/go-pep440-version@v0.0.0-20210121094942-22b2f8951d46",
|
||||
"type": "library",
|
||||
"name": "github.com/aquasecurity/go-pep440-version",
|
||||
"version": "v0.0.0-20210121094942-22b2f8951d46",
|
||||
"purl": "pkg:golang/github.com/aquasecurity/go-pep440-version@v0.0.0-20210121094942-22b2f8951d46",
|
||||
"properties": [
|
||||
{
|
||||
"name": "aquasecurity:trivy:PkgID",
|
||||
"value": "github.com/aquasecurity/go-pep440-version@v0.0.0-20210121094942-22b2f8951d46"
|
||||
},
|
||||
{
|
||||
"name": "aquasecurity:trivy:PkgType",
|
||||
"value": "gobinary"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"bom-ref": "pkg:golang/github.com/aquasecurity/go-version@v0.0.0-20210121072130-637058cfe492",
|
||||
"type": "library",
|
||||
"name": "github.com/aquasecurity/go-version",
|
||||
"version": "v0.0.0-20210121072130-637058cfe492",
|
||||
"purl": "pkg:golang/github.com/aquasecurity/go-version@v0.0.0-20210121072130-637058cfe492",
|
||||
"properties": [
|
||||
{
|
||||
"name": "aquasecurity:trivy:PkgID",
|
||||
"value": "github.com/aquasecurity/go-version@v0.0.0-20210121072130-637058cfe492"
|
||||
},
|
||||
{
|
||||
"name": "aquasecurity:trivy:PkgType",
|
||||
"value": "gobinary"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"bom-ref": "pkg:golang/github.com/aquasecurity/test",
|
||||
"type": "library",
|
||||
"name": "github.com/aquasecurity/test",
|
||||
"purl": "pkg:golang/github.com/aquasecurity/test",
|
||||
"properties": [
|
||||
{
|
||||
"name": "aquasecurity:trivy:PkgID",
|
||||
"value": "github.com/aquasecurity/test"
|
||||
},
|
||||
{
|
||||
"name": "aquasecurity:trivy:PkgType",
|
||||
"value": "gobinary"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"bom-ref": "pkg:golang/golang.org/x/xerrors@v0.0.0-20200804184101-5ec99f83aff1",
|
||||
"type": "library",
|
||||
"name": "golang.org/x/xerrors",
|
||||
"version": "v0.0.0-20200804184101-5ec99f83aff1",
|
||||
"purl": "pkg:golang/golang.org/x/xerrors@v0.0.0-20200804184101-5ec99f83aff1",
|
||||
"properties": [
|
||||
{
|
||||
"name": "aquasecurity:trivy:PkgID",
|
||||
"value": "golang.org/x/xerrors@v0.0.0-20200804184101-5ec99f83aff1"
|
||||
},
|
||||
{
|
||||
"name": "aquasecurity:trivy:PkgType",
|
||||
"value": "gobinary"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"bom-ref": "pkg:golang/stdlib@v1.15.2",
|
||||
"type": "library",
|
||||
"name": "stdlib",
|
||||
"version": "v1.15.2",
|
||||
"purl": "pkg:golang/stdlib@v1.15.2",
|
||||
"properties": [
|
||||
{
|
||||
"name": "aquasecurity:trivy:PkgID",
|
||||
"value": "stdlib@v1.15.2"
|
||||
},
|
||||
{
|
||||
"name": "aquasecurity:trivy:PkgType",
|
||||
"value": "gobinary"
|
||||
}
|
||||
]
|
||||
}
|
||||
],
|
||||
"dependencies": [
|
||||
{
|
||||
"ref": "1cb40520-a22c-481f-ad77-6bc6960430c5",
|
||||
"dependsOn": [
|
||||
"4021d631-e242-4e69-8a93-928665810a27"
|
||||
]
|
||||
},
|
||||
{
|
||||
"ref": "4021d631-e242-4e69-8a93-928665810a27",
|
||||
"dependsOn": [
|
||||
"pkg:golang/github.com/aquasecurity/test"
|
||||
]
|
||||
},
|
||||
{
|
||||
"ref": "pkg:golang/github.com/aquasecurity/go-pep440-version@v0.0.0-20210121094942-22b2f8951d46",
|
||||
"dependsOn": []
|
||||
},
|
||||
{
|
||||
"ref": "pkg:golang/github.com/aquasecurity/go-version@v0.0.0-20210121072130-637058cfe492",
|
||||
"dependsOn": []
|
||||
},
|
||||
{
|
||||
"ref": "pkg:golang/github.com/aquasecurity/test",
|
||||
"dependsOn": [
|
||||
"pkg:golang/github.com/aquasecurity/go-pep440-version@v0.0.0-20210121094942-22b2f8951d46",
|
||||
"pkg:golang/github.com/aquasecurity/go-version@v0.0.0-20210121072130-637058cfe492",
|
||||
"pkg:golang/golang.org/x/xerrors@v0.0.0-20200804184101-5ec99f83aff1",
|
||||
"pkg:golang/stdlib@v1.15.2"
|
||||
]
|
||||
},
|
||||
{
|
||||
"ref": "pkg:golang/golang.org/x/xerrors@v0.0.0-20200804184101-5ec99f83aff1",
|
||||
"dependsOn": []
|
||||
},
|
||||
{
|
||||
"ref": "pkg:golang/stdlib@v1.15.2",
|
||||
"dependsOn": []
|
||||
}
|
||||
],
|
||||
"vulnerabilities": []
|
||||
}
|
||||
@@ -668,6 +668,93 @@ func TestUnmarshaler_Unmarshal(t *testing.T) {
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "happy path for BOM with nested packages",
|
||||
inputFile: "testdata/happy/nested-packages-bom.json",
|
||||
want: types.SBOM{
|
||||
Applications: []ftypes.Application{
|
||||
{
|
||||
Type: "gobinary",
|
||||
FilePath: "foo/bar/test.elf",
|
||||
Packages: ftypes.Packages{
|
||||
{
|
||||
ID: "github.com/aquasecurity/test",
|
||||
Name: "github.com/aquasecurity/test",
|
||||
Identifier: ftypes.PkgIdentifier{
|
||||
PURL: &packageurl.PackageURL{
|
||||
Type: packageurl.TypeGolang,
|
||||
Namespace: "github.com/aquasecurity",
|
||||
Name: "test",
|
||||
},
|
||||
BOMRef: "pkg:golang/github.com/aquasecurity/test",
|
||||
},
|
||||
DependsOn: []string{
|
||||
"github.com/aquasecurity/go-pep440-version@v0.0.0-20210121094942-22b2f8951d46",
|
||||
"github.com/aquasecurity/go-version@v0.0.0-20210121072130-637058cfe492",
|
||||
"golang.org/x/xerrors@v0.0.0-20200804184101-5ec99f83aff1",
|
||||
"stdlib@v1.15.2",
|
||||
},
|
||||
},
|
||||
{
|
||||
ID: "github.com/aquasecurity/go-pep440-version@v0.0.0-20210121094942-22b2f8951d46",
|
||||
Name: "github.com/aquasecurity/go-pep440-version",
|
||||
Version: "v0.0.0-20210121094942-22b2f8951d46",
|
||||
Identifier: ftypes.PkgIdentifier{
|
||||
PURL: &packageurl.PackageURL{
|
||||
Type: packageurl.TypeGolang,
|
||||
Namespace: "github.com/aquasecurity",
|
||||
Name: "go-pep440-version",
|
||||
Version: "v0.0.0-20210121094942-22b2f8951d46",
|
||||
},
|
||||
BOMRef: "pkg:golang/github.com/aquasecurity/go-pep440-version@v0.0.0-20210121094942-22b2f8951d46",
|
||||
},
|
||||
},
|
||||
{
|
||||
ID: "github.com/aquasecurity/go-version@v0.0.0-20210121072130-637058cfe492",
|
||||
Name: "github.com/aquasecurity/go-version",
|
||||
Version: "v0.0.0-20210121072130-637058cfe492",
|
||||
Identifier: ftypes.PkgIdentifier{
|
||||
PURL: &packageurl.PackageURL{
|
||||
Type: packageurl.TypeGolang,
|
||||
Namespace: "github.com/aquasecurity",
|
||||
Name: "go-version",
|
||||
Version: "v0.0.0-20210121072130-637058cfe492",
|
||||
},
|
||||
BOMRef: "pkg:golang/github.com/aquasecurity/go-version@v0.0.0-20210121072130-637058cfe492",
|
||||
},
|
||||
},
|
||||
{
|
||||
ID: "golang.org/x/xerrors@v0.0.0-20200804184101-5ec99f83aff1",
|
||||
Name: "golang.org/x/xerrors",
|
||||
Version: "v0.0.0-20200804184101-5ec99f83aff1",
|
||||
Identifier: ftypes.PkgIdentifier{
|
||||
PURL: &packageurl.PackageURL{
|
||||
Type: packageurl.TypeGolang,
|
||||
Namespace: "golang.org/x",
|
||||
Name: "xerrors",
|
||||
Version: "v0.0.0-20200804184101-5ec99f83aff1",
|
||||
},
|
||||
BOMRef: "pkg:golang/golang.org/x/xerrors@v0.0.0-20200804184101-5ec99f83aff1",
|
||||
},
|
||||
},
|
||||
{
|
||||
ID: "stdlib@v1.15.2",
|
||||
Name: "stdlib",
|
||||
Version: "v1.15.2",
|
||||
Identifier: ftypes.PkgIdentifier{
|
||||
PURL: &packageurl.PackageURL{
|
||||
Type: packageurl.TypeGolang,
|
||||
Name: "stdlib",
|
||||
Version: "v1.15.2",
|
||||
},
|
||||
BOMRef: "pkg:golang/stdlib@v1.15.2",
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "happy path only os component",
|
||||
inputFile: "testdata/happy/os-only-bom.json",
|
||||
|
||||
@@ -330,15 +330,7 @@ func (m *Decoder) parseSrcVersion(ctx context.Context, pkg *ftypes.Package, ver
|
||||
|
||||
// addOSPkgs traverses relationships and adds OS packages
|
||||
func (m *Decoder) addOSPkgs(sbom *types.SBOM) {
|
||||
var pkgs []ftypes.Package
|
||||
for _, rel := range m.bom.Relationships()[m.osID] {
|
||||
pkg, ok := m.pkgs[rel.Dependency]
|
||||
if !ok {
|
||||
continue
|
||||
}
|
||||
pkgs = append(pkgs, *pkg)
|
||||
delete(m.pkgs, rel.Dependency) // Delete the added package
|
||||
}
|
||||
pkgs := m.traverseDependencies(m.osID)
|
||||
if len(pkgs) == 0 {
|
||||
return
|
||||
}
|
||||
@@ -348,18 +340,33 @@ func (m *Decoder) addOSPkgs(sbom *types.SBOM) {
|
||||
// addLangPkgs traverses relationships and adds language-specific packages
|
||||
func (m *Decoder) addLangPkgs(sbom *types.SBOM) {
|
||||
for id, app := range m.apps {
|
||||
for _, rel := range m.bom.Relationships()[id] {
|
||||
pkg, ok := m.pkgs[rel.Dependency]
|
||||
if !ok {
|
||||
continue
|
||||
}
|
||||
app.Packages = append(app.Packages, *pkg)
|
||||
delete(m.pkgs, rel.Dependency) // Delete the added package
|
||||
}
|
||||
app.Packages = append(app.Packages, m.traverseDependencies(id)...)
|
||||
sbom.Applications = append(sbom.Applications, *app)
|
||||
}
|
||||
}
|
||||
|
||||
// traverseDependencies recursively retrieves all packages that the specified component depends on.
|
||||
// It starts from the given component ID and traverses the dependency tree, collecting all
|
||||
// dependent packages. The collected packages are removed from m.pkgs to prevent duplicate
|
||||
// processing. This ensures that all dependencies, including transitive ones, are properly
|
||||
// captured and associated with their parent component.
|
||||
func (m *Decoder) traverseDependencies(id uuid.UUID) ftypes.Packages {
|
||||
var pkgs ftypes.Packages
|
||||
for _, rel := range m.bom.Relationships()[id] {
|
||||
pkg, ok := m.pkgs[rel.Dependency]
|
||||
if !ok {
|
||||
continue
|
||||
}
|
||||
// Add the current package
|
||||
pkgs = append(pkgs, *pkg)
|
||||
delete(m.pkgs, rel.Dependency) // Delete the added package
|
||||
|
||||
// Add the nested packages
|
||||
pkgs = append(pkgs, m.traverseDependencies(rel.Dependency)...)
|
||||
}
|
||||
return pkgs
|
||||
}
|
||||
|
||||
// addOrphanPkgs adds orphan packages.
|
||||
// Orphan packages are packages that are not related to any components.
|
||||
func (m *Decoder) addOrphanPkgs(ctx context.Context, sbom *types.SBOM) error {
|
||||
|
||||
@@ -417,18 +417,10 @@ func (*Encoder) belongToParent(pkg ftypes.Package, parents map[string]ftypes.Pac
|
||||
// All packages are included in the parent
|
||||
// Case 3: Relationship: known , DependsOn: unknown (e.g., go.mod without $GOPATH)
|
||||
// All packages are included in the parent
|
||||
// Case 4: Relationship: unknown, DependsOn: known (e.g., OS packages)
|
||||
// All packages are included in the parent even if they have parents
|
||||
switch {
|
||||
// Case 1, 2 and 3
|
||||
case len(parents[pkg.ID]) == 0:
|
||||
return true
|
||||
// Case 4
|
||||
case pkg.Relationship == ftypes.RelationshipUnknown:
|
||||
return true
|
||||
default:
|
||||
return false
|
||||
}
|
||||
// Case 4: Relationship: unknown, DependsOn: known (e.g., GoBinaries, OS packages)
|
||||
// - Packages with parents: false. These packages are included in the packages from `parents` (e.g. GoBinaries deps and root package).
|
||||
// - Packages without parents: true. These packages are included in the parent (e.g. OS packages without parents).
|
||||
return len(parents[pkg.ID]) == 0
|
||||
}
|
||||
|
||||
func filterProperties(props []core.Property) []core.Property {
|
||||
|
||||
@@ -171,6 +171,61 @@ func TestEncoder_Encode(t *testing.T) {
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
Target: "trivy",
|
||||
Type: ftypes.GoBinary,
|
||||
Class: types.ClassLangPkg,
|
||||
Packages: []ftypes.Package{
|
||||
{
|
||||
ID: "github.com/aquasecurity/trivy@v0.57.1",
|
||||
Name: "github.com/aquasecurity/trivy",
|
||||
Version: "v0.57.1",
|
||||
Identifier: ftypes.PkgIdentifier{
|
||||
UID: "106fee7e57f0b952",
|
||||
PURL: &packageurl.PackageURL{
|
||||
Type: packageurl.TypeGolang,
|
||||
Namespace: "github.com/aquasecurity",
|
||||
Name: "trivy",
|
||||
Version: "v0.57.1",
|
||||
},
|
||||
},
|
||||
Relationship: ftypes.RelationshipRoot,
|
||||
DependsOn: []string{
|
||||
"github.com/aquasecurity/go-version@v0.0.0-20240603093900-cf8a8d29271d",
|
||||
"stdlib@v1.22.9",
|
||||
},
|
||||
},
|
||||
{
|
||||
ID: "stdlib@v1.22.9",
|
||||
Name: "stdlib",
|
||||
Version: "v1.22.9",
|
||||
Identifier: ftypes.PkgIdentifier{
|
||||
UID: "62e7c8aaebd94b1e",
|
||||
PURL: &packageurl.PackageURL{
|
||||
Type: packageurl.TypeGolang,
|
||||
Name: "stdlib",
|
||||
Version: "v1.22.9",
|
||||
},
|
||||
},
|
||||
Relationship: ftypes.RelationshipDirect,
|
||||
},
|
||||
{
|
||||
ID: "github.com/aquasecurity/go-version@v0.0.0-20240603093900-cf8a8d29271d",
|
||||
Name: "github.com/aquasecurity/go-version",
|
||||
Version: "v0.0.0-20240603093900-cf8a8d29271d",
|
||||
Identifier: ftypes.PkgIdentifier{
|
||||
UID: "350aed171d8ebed5",
|
||||
PURL: &packageurl.PackageURL{
|
||||
Type: packageurl.TypeGolang,
|
||||
Namespace: "github.com/aquasecurity",
|
||||
Name: "go-version",
|
||||
Version: "v0.0.0-20240603093900-cf8a8d29271d",
|
||||
},
|
||||
},
|
||||
Relationship: ftypes.RelationshipUnknown,
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
wantComponents: map[uuid.UUID]*core.Component{
|
||||
@@ -351,6 +406,100 @@ func TestEncoder_Encode(t *testing.T) {
|
||||
BOMRef: "3ff14136-e09f-4df9-80ea-000000000006",
|
||||
},
|
||||
},
|
||||
uuid.MustParse("3ff14136-e09f-4df9-80ea-000000000007"): {
|
||||
Type: core.TypeApplication,
|
||||
Name: "trivy",
|
||||
Properties: []core.Property{
|
||||
{
|
||||
Name: core.PropertyClass,
|
||||
Value: "lang-pkgs",
|
||||
},
|
||||
{
|
||||
Name: core.PropertyType,
|
||||
Value: "gobinary",
|
||||
},
|
||||
},
|
||||
PkgIdentifier: ftypes.PkgIdentifier{
|
||||
BOMRef: "3ff14136-e09f-4df9-80ea-000000000007",
|
||||
},
|
||||
},
|
||||
uuid.MustParse("3ff14136-e09f-4df9-80ea-000000000008"): {
|
||||
Type: core.TypeLibrary,
|
||||
Name: "github.com/aquasecurity/trivy",
|
||||
Version: "v0.57.1",
|
||||
SrcFile: "trivy",
|
||||
Properties: []core.Property{
|
||||
{
|
||||
Name: core.PropertyPkgID,
|
||||
Value: "github.com/aquasecurity/trivy@v0.57.1",
|
||||
},
|
||||
{
|
||||
Name: core.PropertyPkgType,
|
||||
Value: "gobinary",
|
||||
},
|
||||
},
|
||||
PkgIdentifier: ftypes.PkgIdentifier{
|
||||
UID: "106fee7e57f0b952",
|
||||
PURL: &packageurl.PackageURL{
|
||||
Type: packageurl.TypeGolang,
|
||||
Namespace: "github.com/aquasecurity",
|
||||
Name: "trivy",
|
||||
Version: "v0.57.1",
|
||||
},
|
||||
BOMRef: "pkg:golang/github.com/aquasecurity/trivy@v0.57.1",
|
||||
},
|
||||
},
|
||||
uuid.MustParse("3ff14136-e09f-4df9-80ea-000000000009"): {
|
||||
Type: core.TypeLibrary,
|
||||
Name: "stdlib",
|
||||
Version: "v1.22.9",
|
||||
SrcFile: "trivy",
|
||||
Properties: []core.Property{
|
||||
{
|
||||
Name: core.PropertyPkgID,
|
||||
Value: "stdlib@v1.22.9",
|
||||
},
|
||||
{
|
||||
Name: core.PropertyPkgType,
|
||||
Value: "gobinary",
|
||||
},
|
||||
},
|
||||
PkgIdentifier: ftypes.PkgIdentifier{
|
||||
UID: "62e7c8aaebd94b1e",
|
||||
PURL: &packageurl.PackageURL{
|
||||
Type: packageurl.TypeGolang,
|
||||
Name: "stdlib",
|
||||
Version: "v1.22.9",
|
||||
},
|
||||
BOMRef: "pkg:golang/stdlib@v1.22.9",
|
||||
},
|
||||
},
|
||||
uuid.MustParse("3ff14136-e09f-4df9-80ea-000000000010"): {
|
||||
Type: core.TypeLibrary,
|
||||
Name: "github.com/aquasecurity/go-version",
|
||||
Version: "v0.0.0-20240603093900-cf8a8d29271d",
|
||||
SrcFile: "trivy",
|
||||
Properties: []core.Property{
|
||||
{
|
||||
Name: core.PropertyPkgID,
|
||||
Value: "github.com/aquasecurity/go-version@v0.0.0-20240603093900-cf8a8d29271d",
|
||||
},
|
||||
{
|
||||
Name: core.PropertyPkgType,
|
||||
Value: "gobinary",
|
||||
},
|
||||
},
|
||||
PkgIdentifier: ftypes.PkgIdentifier{
|
||||
UID: "350aed171d8ebed5",
|
||||
PURL: &packageurl.PackageURL{
|
||||
Type: packageurl.TypeGolang,
|
||||
Namespace: "github.com/aquasecurity",
|
||||
Name: "go-version",
|
||||
Version: "v0.0.0-20240603093900-cf8a8d29271d",
|
||||
},
|
||||
BOMRef: "pkg:golang/github.com/aquasecurity/go-version@v0.0.0-20240603093900-cf8a8d29271d",
|
||||
},
|
||||
},
|
||||
},
|
||||
wantRels: map[uuid.UUID][]core.Relationship{
|
||||
uuid.MustParse("3ff14136-e09f-4df9-80ea-000000000001"): {
|
||||
@@ -366,12 +515,12 @@ func TestEncoder_Encode(t *testing.T) {
|
||||
Dependency: uuid.MustParse("3ff14136-e09f-4df9-80ea-000000000006"),
|
||||
Type: core.RelationshipContains,
|
||||
},
|
||||
},
|
||||
uuid.MustParse("3ff14136-e09f-4df9-80ea-000000000002"): {
|
||||
{
|
||||
Dependency: uuid.MustParse("3ff14136-e09f-4df9-80ea-000000000003"),
|
||||
Dependency: uuid.MustParse("3ff14136-e09f-4df9-80ea-000000000007"),
|
||||
Type: core.RelationshipContains,
|
||||
},
|
||||
},
|
||||
uuid.MustParse("3ff14136-e09f-4df9-80ea-000000000002"): {
|
||||
{
|
||||
Dependency: uuid.MustParse("3ff14136-e09f-4df9-80ea-000000000004"),
|
||||
Type: core.RelationshipContains,
|
||||
@@ -386,6 +535,24 @@ func TestEncoder_Encode(t *testing.T) {
|
||||
},
|
||||
uuid.MustParse("3ff14136-e09f-4df9-80ea-000000000005"): nil,
|
||||
uuid.MustParse("3ff14136-e09f-4df9-80ea-000000000006"): nil,
|
||||
uuid.MustParse("3ff14136-e09f-4df9-80ea-000000000007"): {
|
||||
{
|
||||
Dependency: uuid.MustParse("3ff14136-e09f-4df9-80ea-000000000008"),
|
||||
Type: core.RelationshipContains,
|
||||
},
|
||||
},
|
||||
uuid.MustParse("3ff14136-e09f-4df9-80ea-000000000008"): {
|
||||
{
|
||||
Dependency: uuid.MustParse("3ff14136-e09f-4df9-80ea-000000000010"),
|
||||
Type: core.RelationshipDependsOn,
|
||||
},
|
||||
{
|
||||
Dependency: uuid.MustParse("3ff14136-e09f-4df9-80ea-000000000009"),
|
||||
Type: core.RelationshipDependsOn,
|
||||
},
|
||||
},
|
||||
uuid.MustParse("3ff14136-e09f-4df9-80ea-000000000009"): nil,
|
||||
uuid.MustParse("3ff14136-e09f-4df9-80ea-000000000010"): nil,
|
||||
},
|
||||
wantVulns: map[uuid.UUID][]core.Vulnerability{
|
||||
uuid.MustParse("3ff14136-e09f-4df9-80ea-000000000004"): {
|
||||
|
||||
Reference in New Issue
Block a user