From 863793a3ccd71c8c009f9a11e97e207173584b2b Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Thu, 11 Jul 2024 10:19:14 -0700 Subject: [PATCH 001/122] chore(deps): bump github.com/charmbracelet/lipgloss (#3028) Bumps [github.com/charmbracelet/lipgloss](https://github.com/charmbracelet/lipgloss) from 0.11.0 to 0.11.1. - [Release notes](https://github.com/charmbracelet/lipgloss/releases) - [Changelog](https://github.com/charmbracelet/lipgloss/blob/master/.goreleaser.yml) - [Commits](https://github.com/charmbracelet/lipgloss/compare/v0.11.0...v0.11.1) --- updated-dependencies: - dependency-name: github.com/charmbracelet/lipgloss dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- go.mod | 4 ++-- go.sum | 8 ++++---- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/go.mod b/go.mod index 7817206cc2b..62345421e77 100644 --- a/go.mod +++ b/go.mod @@ -25,7 +25,7 @@ require ( github.com/bmatcuk/doublestar/v4 v4.6.1 github.com/charmbracelet/bubbles v0.18.0 github.com/charmbracelet/bubbletea v0.26.6 - github.com/charmbracelet/lipgloss v0.11.0 + github.com/charmbracelet/lipgloss v0.11.1 github.com/dave/jennifer v1.7.0 github.com/deitch/magic v0.0.0-20230404182410-1ff89d7342da github.com/distribution/reference v0.6.0 @@ -109,7 +109,7 @@ require ( github.com/aymanbagabas/go-osc52/v2 v2.0.1 // indirect github.com/becheran/wildmatch-go v1.0.0 // indirect github.com/charmbracelet/harmonica v0.2.0 // indirect - github.com/charmbracelet/x/ansi v0.1.2 // indirect + github.com/charmbracelet/x/ansi v0.1.3 // indirect github.com/charmbracelet/x/input v0.1.0 // indirect github.com/charmbracelet/x/term v0.1.1 // indirect github.com/charmbracelet/x/windows v0.1.0 // indirect diff --git a/go.sum b/go.sum index a5e50ecb73b..208364ae4b4 100644 --- a/go.sum +++ b/go.sum @@ -161,10 +161,10 @@ github.com/charmbracelet/bubbletea v0.26.6 h1:zTCWSuST+3yZYZnVSvbXwKOPRSNZceVeqp github.com/charmbracelet/bubbletea v0.26.6/go.mod h1:dz8CWPlfCCGLFbBlTY4N7bjLiyOGDJEnd2Muu7pOWhk= github.com/charmbracelet/harmonica v0.2.0 h1:8NxJWRWg/bzKqqEaaeFNipOu77YR5t8aSwG4pgaUBiQ= github.com/charmbracelet/harmonica v0.2.0/go.mod h1:KSri/1RMQOZLbw7AHqgcBycp8pgJnQMYYT8QZRqZ1Ao= -github.com/charmbracelet/lipgloss v0.11.0 h1:UoAcbQ6Qml8hDwSWs0Y1cB5TEQuZkDPH/ZqwWWYTG4g= -github.com/charmbracelet/lipgloss v0.11.0/go.mod h1:1UdRTH9gYgpcdNN5oBtjbu/IzNKtzVtb7sqN1t9LNn8= -github.com/charmbracelet/x/ansi v0.1.2 h1:6+LR39uG8DE6zAmbu023YlqjJHkYXDF1z36ZwzO4xZY= -github.com/charmbracelet/x/ansi v0.1.2/go.mod h1:dk73KoMTT5AX5BsX0KrqhsTqAnhZZoCBjs7dGWp4Ktw= +github.com/charmbracelet/lipgloss v0.11.1 h1:a8KgVPHa7kOoP95vm2tQQrjD2AKhbWmfr4uJ2RW6kNk= +github.com/charmbracelet/lipgloss v0.11.1/go.mod h1:beLlcmkF7MWA+5UrKKIRo/VJ21xGXr7YJ9miWfdMRIU= +github.com/charmbracelet/x/ansi v0.1.3 h1:RBh/eleNWML5R524mjUF0yVRePTwqN9tPtV+DPgO5Lw= +github.com/charmbracelet/x/ansi v0.1.3/go.mod h1:dk73KoMTT5AX5BsX0KrqhsTqAnhZZoCBjs7dGWp4Ktw= github.com/charmbracelet/x/input v0.1.0 h1:TEsGSfZYQyOtp+STIjyBq6tpRaorH0qpwZUj8DavAhQ= github.com/charmbracelet/x/input v0.1.0/go.mod h1:ZZwaBxPF7IG8gWWzPUVqHEtWhc1+HXJPNuerJGRGZ28= github.com/charmbracelet/x/term v0.1.1 h1:3cosVAiPOig+EV4X9U+3LDgtwwAoEzJjNdwbXDjF6yI= From 4e09908ba124dca7e6f1f6e7dc4f4663fae658ca Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Thu, 11 Jul 2024 10:19:48 -0700 Subject: [PATCH 002/122] chore(deps): bump actions/setup-go from 5.0.1 to 5.0.2 (#3027) Bumps [actions/setup-go](https://github.com/actions/setup-go) from 5.0.1 to 5.0.2. - [Release notes](https://github.com/actions/setup-go/releases) - [Commits](https://github.com/actions/setup-go/compare/cdcb36043654635271a94b9a6d1392de5bb323a7...0a12ed9d6a96ab950c8f026ed9f722fe0da7ef32) --- updated-dependencies: - dependency-name: actions/setup-go dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- .github/workflows/codeql-analysis.yml | 2 +- .github/workflows/update-stereoscope-release.yml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/codeql-analysis.yml b/.github/workflows/codeql-analysis.yml index 0d39a417cc2..422eeefa54d 100644 --- a/.github/workflows/codeql-analysis.yml +++ b/.github/workflows/codeql-analysis.yml @@ -39,7 +39,7 @@ jobs: uses: actions/checkout@692973e3d937129bcbf40652eb9f2f61becf3332 #v4.1.7 - name: Install Go - uses: actions/setup-go@cdcb36043654635271a94b9a6d1392de5bb323a7 #v5.0.1 + uses: actions/setup-go@0a12ed9d6a96ab950c8f026ed9f722fe0da7ef32 #v5.0.2 with: go-version-file: go.mod diff --git a/.github/workflows/update-stereoscope-release.yml b/.github/workflows/update-stereoscope-release.yml index 894d04c7f73..94ea0ee1b71 100644 --- a/.github/workflows/update-stereoscope-release.yml +++ b/.github/workflows/update-stereoscope-release.yml @@ -19,7 +19,7 @@ jobs: steps: - uses: actions/checkout@692973e3d937129bcbf40652eb9f2f61becf3332 #v4.1.7 - - uses: actions/setup-go@cdcb36043654635271a94b9a6d1392de5bb323a7 #v5.0.1 + - uses: actions/setup-go@0a12ed9d6a96ab950c8f026ed9f722fe0da7ef32 #v5.0.2 with: go-version: ${{ env.GO_VERSION }} stable: ${{ env.GO_STABLE_VERSION }} From e2fe955262cad2386d66ecaef69c80ae5ce668b1 Mon Sep 17 00:00:00 2001 From: "anchore-actions-token-generator[bot]" <102182147+anchore-actions-token-generator[bot]@users.noreply.github.com> Date: Thu, 11 Jul 2024 10:38:10 -0700 Subject: [PATCH 003/122] chore(deps): update stereoscope to 27b66b76fc6686fcf6bde656aa09e1f0e047fec1 (#3026) Signed-off-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com> Co-authored-by: kzantow <3009477+kzantow@users.noreply.github.com> --- go.mod | 4 ++-- go.sum | 9 ++++----- 2 files changed, 6 insertions(+), 7 deletions(-) diff --git a/go.mod b/go.mod index 62345421e77..3f6589f18ac 100644 --- a/go.mod +++ b/go.mod @@ -17,7 +17,7 @@ require ( github.com/anchore/go-testutils v0.0.0-20200925183923-d5f45b0d3c04 github.com/anchore/go-version v1.2.2-0.20200701162849-18adb9c92b9b github.com/anchore/packageurl-go v0.1.1-0.20240507183024-848e011fc24f - github.com/anchore/stereoscope v0.0.3-0.20240705165118-e46739e21796 + github.com/anchore/stereoscope v0.0.3-0.20240710175110-27b66b76fc66 github.com/anmitsu/go-shlex v0.0.0-20200514113438-38f4b401e2be // we are hinting brotli to latest due to warning when installing archiver v3: // go: warning: github.com/andybalholm/brotli@v1.0.1: retracted by module author: occasional panics and data corruption @@ -137,7 +137,7 @@ require ( github.com/felixge/fgprof v0.9.3 // indirect github.com/felixge/httpsnoop v1.0.3 // indirect github.com/fsnotify/fsnotify v1.7.0 // indirect - github.com/gabriel-vasile/mimetype v1.4.0 // indirect + github.com/gabriel-vasile/mimetype v1.4.4 // indirect github.com/gkampitakis/ciinfo v0.3.0 // indirect github.com/gkampitakis/go-diff v1.3.2 // indirect github.com/go-git/gcfg v1.5.1-0.20230307220236-3a3c6141e376 // indirect diff --git a/go.sum b/go.sum index 208364ae4b4..fe588d4844a 100644 --- a/go.sum +++ b/go.sum @@ -113,8 +113,8 @@ github.com/anchore/go-version v1.2.2-0.20200701162849-18adb9c92b9b h1:e1bmaoJfZV github.com/anchore/go-version v1.2.2-0.20200701162849-18adb9c92b9b/go.mod h1:Bkc+JYWjMCF8OyZ340IMSIi2Ebf3uwByOk6ho4wne1E= github.com/anchore/packageurl-go v0.1.1-0.20240507183024-848e011fc24f h1:B/E9ixKNCasntpoch61NDaQyGPDXLEJlL+B9B/PbdbA= github.com/anchore/packageurl-go v0.1.1-0.20240507183024-848e011fc24f/go.mod h1:Blo6OgJNiYF41ufcgHKkbCKF2MDOMlrqhXv/ij6ocR4= -github.com/anchore/stereoscope v0.0.3-0.20240705165118-e46739e21796 h1:mb2i23zBKaSloS4RHMwBCKTCB3X5HnObcRvjxrvvMr8= -github.com/anchore/stereoscope v0.0.3-0.20240705165118-e46739e21796/go.mod h1:6r8piaIGsYZuVkFw+fAXYtEGFI58dZuni/jNdvK+IxQ= +github.com/anchore/stereoscope v0.0.3-0.20240710175110-27b66b76fc66 h1:Z/yFalhLPfmE1MmIDKpE4GIVcWI0r7WpYX+7nLONRj0= +github.com/anchore/stereoscope v0.0.3-0.20240710175110-27b66b76fc66/go.mod h1:Ttqzw15V5ku7hITQNH4t6Nc+naBNAfSTDagmhSNPwJo= github.com/andreyvit/diff v0.0.0-20170406064948-c7f18ee00883/go.mod h1:rCTlJbsFo29Kk6CurOXKm700vrz8f0KW0JNfpkRJY/8= github.com/andybalholm/brotli v1.0.1/go.mod h1:loMXtMfwqflxFJPmdbJO0a3KNoPuLBgiu3qAvBg8x/Y= github.com/andybalholm/brotli v1.0.4 h1:V7DdXeJtZscaqfNuAdSRuRFzuiKlHSC/Zh3zl9qY3JY= @@ -284,8 +284,8 @@ github.com/frankban/quicktest v1.14.6/go.mod h1:4ptaffx2x8+WTWXmUCuVU6aPUX1/Mz7z github.com/fsnotify/fsnotify v1.5.1/go.mod h1:T3375wBYaZdLLcVNkcVbzGHY7f1l/uK5T5Ai1i3InKU= github.com/fsnotify/fsnotify v1.7.0 h1:8JEhPFa5W2WU7YfeZzPNqzMP6Lwt7L2715Ggo0nosvA= github.com/fsnotify/fsnotify v1.7.0/go.mod h1:40Bi/Hjc2AVfZrqy+aj+yEI+/bRxZnMJyTJwOpGvigM= -github.com/gabriel-vasile/mimetype v1.4.0 h1:Cn9dkdYsMIu56tGho+fqzh7XmvY2YyGU0FnbhiOsEro= -github.com/gabriel-vasile/mimetype v1.4.0/go.mod h1:fA8fi6KUiG7MgQQ+mEWotXoEOvmxRtOJlERCzSmRvr8= +github.com/gabriel-vasile/mimetype v1.4.4 h1:QjV6pZ7/XZ7ryI2KuyeEDE8wnh7fHP9YnQy+R0LnH8I= +github.com/gabriel-vasile/mimetype v1.4.4/go.mod h1:JwLei5XPtWdGiMFB5Pjle1oEeoSeEuJfJE+TtfvdB/s= github.com/ghodss/yaml v1.0.0/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeMEF04= github.com/github/go-spdx/v2 v2.3.1 h1:ffGuHTbHuHzWPt53n8f9o8clGutuLPObo3zB4JAjxU8= github.com/github/go-spdx/v2 v2.3.1/go.mod h1:2ZxKsOhvBp+OYBDlsGnUMcchLeo2mrpEBn2L1C+U3IQ= @@ -961,7 +961,6 @@ golang.org/x/net v0.0.0-20210316092652-d523dce5a7f4/go.mod h1:RBQZq4jEuRlivfhVLd golang.org/x/net v0.0.0-20210405180319-a5a99cb37ef4/go.mod h1:p54w0d4576C0XHj96bSt6lcn1PtDYWL6XObtHCRCNQM= golang.org/x/net v0.0.0-20210410081132-afb366fc7cd1/go.mod h1:9tjilg8BloeKEkVJvy7fQ90B1CfIiPueXVOjqfkSzI8= golang.org/x/net v0.0.0-20210503060351-7fd8e65b6420/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= -golang.org/x/net v0.0.0-20210505024714-0287a6fb4125/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= golang.org/x/net v0.0.0-20210813160813-60bc85c4be6d/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= golang.org/x/net v0.0.0-20211112202133-69e39bad7dc2/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c= From 37245a21ccb99d4195b414beb06b0c8433bfa97b Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Thu, 11 Jul 2024 14:50:48 -0400 Subject: [PATCH 004/122] chore(deps): bump anchore/sbom-action from 0.16.0 to 0.16.1 (#3023) Bumps [anchore/sbom-action](https://github.com/anchore/sbom-action) from 0.16.0 to 0.16.1. - [Release notes](https://github.com/anchore/sbom-action/releases) - [Commits](https://github.com/anchore/sbom-action/compare/e8d2a6937ecead383dfe75190d104edd1f9c5751...95b086ac308035dc0850b3853be5b7ab108236a8) --- updated-dependencies: - dependency-name: anchore/sbom-action dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- .github/workflows/release.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/release.yaml b/.github/workflows/release.yaml index 1e2d26f4bc4..9b1887860a2 100644 --- a/.github/workflows/release.yaml +++ b/.github/workflows/release.yaml @@ -148,7 +148,7 @@ jobs: # for updating brew formula in anchore/homebrew-syft GITHUB_BREW_TOKEN: ${{ secrets.ANCHOREOPS_GITHUB_OSS_WRITE_TOKEN }} - - uses: anchore/sbom-action@e8d2a6937ecead383dfe75190d104edd1f9c5751 #v0.16.0 + - uses: anchore/sbom-action@95b086ac308035dc0850b3853be5b7ab108236a8 #v0.16.1 continue-on-error: true with: artifact-name: sbom.spdx.json From 278b72d39b0d983de1d2937c8b905c27540235b0 Mon Sep 17 00:00:00 2001 From: Keith Zantow Date: Mon, 15 Jul 2024 12:37:09 -0400 Subject: [PATCH 005/122] chore: pin fedora image for elf binary test (#3041) Signed-off-by: Keith Zantow --- syft/pkg/cataloger/binary/elf_package_cataloger_test.go | 4 ++-- .../binary/test-fixtures/image-fedora-64bit/Dockerfile | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/syft/pkg/cataloger/binary/elf_package_cataloger_test.go b/syft/pkg/cataloger/binary/elf_package_cataloger_test.go index 4ec6bd61f05..d9a97cc6476 100644 --- a/syft/pkg/cataloger/binary/elf_package_cataloger_test.go +++ b/syft/pkg/cataloger/binary/elf_package_cataloger_test.go @@ -70,8 +70,8 @@ func Test_ELF_Package_Cataloger(t *testing.T) { expected: []pkg.Package{ { Name: "coreutils", - Version: "9.5-1.fc41", - PURL: "pkg:rpm/fedora/coreutils@9.5-1.fc41?distro=fedora-40", + Version: "9.5-3.fc41", + PURL: "pkg:rpm/fedora/coreutils@9.5-3.fc41?distro=fedora-40", Locations: file.NewLocationSet( file.NewLocation("/sha256sum").WithAnnotation(pkg.EvidenceAnnotationKey, pkg.PrimaryEvidenceAnnotation), file.NewLocation("/sha1sum").WithAnnotation(pkg.EvidenceAnnotationKey, pkg.PrimaryEvidenceAnnotation), diff --git a/syft/pkg/cataloger/binary/test-fixtures/image-fedora-64bit/Dockerfile b/syft/pkg/cataloger/binary/test-fixtures/image-fedora-64bit/Dockerfile index 14dc99c4463..e1c508b854a 100644 --- a/syft/pkg/cataloger/binary/test-fixtures/image-fedora-64bit/Dockerfile +++ b/syft/pkg/cataloger/binary/test-fixtures/image-fedora-64bit/Dockerfile @@ -1,4 +1,4 @@ -FROM --platform=linux/amd64 fedora:41 as build +FROM --platform=linux/amd64 fedora:41@sha256:c05bf79137835bf5c521c58f8252d6031780ae865a0379ab57f412e0ac6b42aa as build FROM scratch COPY --from=build /bin/sha256sum /sha256sum From 75902b0540b6c7c701ea14ed0f32163e6ced2da2 Mon Sep 17 00:00:00 2001 From: William Murphy Date: Tue, 16 Jul 2024 09:51:14 -0400 Subject: [PATCH 006/122] fix: stop panicking on "devel" version go stdlib (#3043) Previously, if a Go binary was cataloged with build info indicating that the go compiler version used was "deve", syft would panic on a nil pointer dereference. Instead, skip creating a Go stdlib reference and relationship for such a package. Signed-off-by: Will Murphy --- syft/pkg/cataloger/golang/stdlib_package.go | 7 ++++--- syft/pkg/cataloger/golang/stdlib_package_test.go | 16 ++++++++++++++++ 2 files changed, 20 insertions(+), 3 deletions(-) diff --git a/syft/pkg/cataloger/golang/stdlib_package.go b/syft/pkg/cataloger/golang/stdlib_package.go index 19d37fe89f4..6e480e8c897 100644 --- a/syft/pkg/cataloger/golang/stdlib_package.go +++ b/syft/pkg/cataloger/golang/stdlib_package.go @@ -33,10 +33,11 @@ func stdlibPackageAndRelationships(pkgs []pkg.Package) ([]pkg.Package, []artifac } stdLibPkg := newGoStdLib(mValue.GoCompiledVersion, goPkg.Locations) - if stdLibPkg != nil { - goCompilerPkgs = append(goCompilerPkgs, *stdLibPkg) - totalLocations.Add(location) + if stdLibPkg == nil { + continue } + goCompilerPkgs = append(goCompilerPkgs, *stdLibPkg) + totalLocations.Add(location) relationships = append(relationships, artifact.Relationship{ From: *stdLibPkg, diff --git a/syft/pkg/cataloger/golang/stdlib_package_test.go b/syft/pkg/cataloger/golang/stdlib_package_test.go index 44653f82b3d..295266d33b4 100644 --- a/syft/pkg/cataloger/golang/stdlib_package_test.go +++ b/syft/pkg/cataloger/golang/stdlib_package_test.go @@ -68,6 +68,22 @@ func Test_stdlibPackageAndRelationships(t *testing.T) { wantPkgs: 1, wantRels: 1, }, + { + name: "go binary package with devel stdlib", + pkgs: []pkg.Package{ + { + Name: "github.com/something/go", + Version: "1.0.0", + Locations: file.NewLocationSet(file.NewLocation("/bin/my-app")), + Metadata: pkg.GolangBinaryBuildinfoEntry{ + GoCompiledVersion: "devel", + MainModule: "github.com/something/go", + }, + }, + }, + wantPkgs: 0, + wantRels: 0, + }, } for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { From 77c300d617260bc3ca7b5129da9e2f674d2fd729 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 16 Jul 2024 06:58:07 -0700 Subject: [PATCH 007/122] chore(deps): bump anchore/sbom-action from 0.16.1 to 0.17.0 (#3044) Bumps [anchore/sbom-action](https://github.com/anchore/sbom-action) from 0.16.1 to 0.17.0. - [Release notes](https://github.com/anchore/sbom-action/releases) - [Commits](https://github.com/anchore/sbom-action/compare/95b086ac308035dc0850b3853be5b7ab108236a8...d94f46e13c6c62f59525ac9a1e147a99dc0b9bf5) --- updated-dependencies: - dependency-name: anchore/sbom-action dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- .github/workflows/release.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/release.yaml b/.github/workflows/release.yaml index 9b1887860a2..3c644a62c28 100644 --- a/.github/workflows/release.yaml +++ b/.github/workflows/release.yaml @@ -148,7 +148,7 @@ jobs: # for updating brew formula in anchore/homebrew-syft GITHUB_BREW_TOKEN: ${{ secrets.ANCHOREOPS_GITHUB_OSS_WRITE_TOKEN }} - - uses: anchore/sbom-action@95b086ac308035dc0850b3853be5b7ab108236a8 #v0.16.1 + - uses: anchore/sbom-action@d94f46e13c6c62f59525ac9a1e147a99dc0b9bf5 #v0.17.0 continue-on-error: true with: artifact-name: sbom.spdx.json From 6bf91a410dabfd33d96e7849e51bb105b7a0125a Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 16 Jul 2024 06:58:18 -0700 Subject: [PATCH 008/122] chore(deps): bump github/codeql-action from 3.25.11 to 3.25.12 (#3034) Bumps [github/codeql-action](https://github.com/github/codeql-action) from 3.25.11 to 3.25.12. - [Release notes](https://github.com/github/codeql-action/releases) - [Changelog](https://github.com/github/codeql-action/blob/main/CHANGELOG.md) - [Commits](https://github.com/github/codeql-action/compare/b611370bb5703a7efb587f9d136a52ea24c5c38c...4fa2a7953630fd2f3fb380f21be14ede0169dd4f) --- updated-dependencies: - dependency-name: github/codeql-action dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- .github/workflows/codeql-analysis.yml | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/.github/workflows/codeql-analysis.yml b/.github/workflows/codeql-analysis.yml index 422eeefa54d..d1791caf9b6 100644 --- a/.github/workflows/codeql-analysis.yml +++ b/.github/workflows/codeql-analysis.yml @@ -45,7 +45,7 @@ jobs: # Initializes the CodeQL tools for scanning. - name: Initialize CodeQL - uses: github/codeql-action/init@b611370bb5703a7efb587f9d136a52ea24c5c38c #v3.25.11 + uses: github/codeql-action/init@4fa2a7953630fd2f3fb380f21be14ede0169dd4f #v3.25.12 with: languages: ${{ matrix.language }} # If you wish to specify custom queries, you can do so here or in a config file. @@ -56,7 +56,7 @@ jobs: # Autobuild attempts to build any compiled languages (C/C++, C#, or Java). # If this step fails, then you should remove it and run the build manually (see below) - name: Autobuild - uses: github/codeql-action/autobuild@b611370bb5703a7efb587f9d136a52ea24c5c38c #v3.25.11 + uses: github/codeql-action/autobuild@4fa2a7953630fd2f3fb380f21be14ede0169dd4f #v3.25.12 # ℹī¸ Command-line programs to run using the OS shell. # 📚 https://git.io/JvXDl @@ -70,4 +70,4 @@ jobs: # make release - name: Perform CodeQL Analysis - uses: github/codeql-action/analyze@b611370bb5703a7efb587f9d136a52ea24c5c38c #v3.25.11 + uses: github/codeql-action/analyze@4fa2a7953630fd2f3fb380f21be14ede0169dd4f #v3.25.12 From d4d4e003e9f023098e0051cca25185c560eec20e Mon Sep 17 00:00:00 2001 From: "anchore-actions-token-generator[bot]" <102182147+anchore-actions-token-generator[bot]@users.noreply.github.com> Date: Tue, 16 Jul 2024 06:58:33 -0700 Subject: [PATCH 009/122] chore(deps): update tools to latest versions (#3031) Signed-off-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com> Co-authored-by: spiffcs <32073428+spiffcs@users.noreply.github.com> --- .binny.yaml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.binny.yaml b/.binny.yaml index fc2bc32ad4f..38b0c470480 100644 --- a/.binny.yaml +++ b/.binny.yaml @@ -18,7 +18,7 @@ tools: # used to sign mac binaries at release - name: quill version: - want: v0.4.1 + want: v0.4.2 method: github-release with: repo: anchore/quill @@ -58,7 +58,7 @@ tools: # used to release all artifacts - name: goreleaser version: - want: v2.0.1 + want: v2.1.0 method: github-release with: repo: goreleaser/goreleaser From d4fa61e0a2a730370979b98f01babba482454f4f Mon Sep 17 00:00:00 2001 From: Adam McClenaghan Date: Tue, 16 Jul 2024 14:59:14 +0100 Subject: [PATCH 010/122] chore: Fix apache shield in readme (#3021) Signed-off-by: Adam McClenaghan --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 141257be59f..3d22f2a02b6 100644 --- a/README.md +++ b/README.md @@ -11,7 +11,7 @@  Go Report Card   GitHub release   GitHub go.mod Go version  -  License: Apache-2.0  +  License: Apache-2.0   Slack 

From 4d23990dd41fc0c62e4b8a7b52c4888848437c80 Mon Sep 17 00:00:00 2001 From: Bradley Jones Date: Tue, 16 Jul 2024 14:59:31 +0100 Subject: [PATCH 011/122] docs: link to contrib/dev docs in readme (#3029) These docs are full of great information so make them easily accessible from the README so they aren't overlooked. Signed-off-by: Bradley Jones --- README.md | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/README.md b/README.md index 3d22f2a02b6..4a714210c17 100644 --- a/README.md +++ b/README.md @@ -168,6 +168,10 @@ Our [wiki](https://github.com/anchore/syft/wiki) contains further details on the * [Adding an SBOM to an image as an attestation using Syft](https://github.com/anchore/syft/wiki/attestation#adding-an-sbom-to-an-image-as-an-attestation-using-syft) * [Configuration](https://github.com/anchore/syft/wiki/configuration) +## Contributing + +Check out our [contributing](/CONTRIBUTING.md) guide and [developer](/DEVELOPING.md) docs. + ## Syft Team Meetings The Syft Team hold regular community meetings online. All are welcome to join to bring topics for discussion. From cca9a06a6439289da22dc901940160b3b6124a32 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 17 Jul 2024 09:10:34 -0400 Subject: [PATCH 012/122] chore(deps): bump modernc.org/sqlite from 1.30.1 to 1.30.2 (#3039) Bumps [modernc.org/sqlite](https://gitlab.com/cznic/sqlite) from 1.30.1 to 1.30.2. - [Commits](https://gitlab.com/cznic/sqlite/compare/v1.30.1...v1.30.2) --- updated-dependencies: - dependency-name: modernc.org/sqlite dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- go.mod | 2 +- go.sum | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/go.mod b/go.mod index 3f6589f18ac..1f75c96ce64 100644 --- a/go.mod +++ b/go.mod @@ -81,7 +81,7 @@ require ( golang.org/x/mod v0.19.0 golang.org/x/net v0.27.0 gopkg.in/yaml.v3 v3.0.1 - modernc.org/sqlite v1.30.1 + modernc.org/sqlite v1.30.2 ) require google.golang.org/genproto v0.0.0-20231106174013-bbf56f31fb17 // indirect diff --git a/go.sum b/go.sum index fe588d4844a..b640f76f3e2 100644 --- a/go.sum +++ b/go.sum @@ -1378,8 +1378,8 @@ modernc.org/opt v0.1.3 h1:3XOZf2yznlhC+ibLltsDGzABUGVx8J6pnFMS3E4dcq4= modernc.org/opt v0.1.3/go.mod h1:WdSiB5evDcignE70guQKxYUl14mgWtbClRi5wmkkTX0= modernc.org/sortutil v1.2.0 h1:jQiD3PfS2REGJNzNCMMaLSp/wdMNieTbKX920Cqdgqc= modernc.org/sortutil v1.2.0/go.mod h1:TKU2s7kJMf1AE84OoiGppNHJwvB753OYfNl2WRb++Ss= -modernc.org/sqlite v1.30.1 h1:YFhPVfu2iIgUf9kuA1CR7iiHdcEEsI2i+yjRYHscyxk= -modernc.org/sqlite v1.30.1/go.mod h1:DUmsiWQDaAvU4abhc/N+djlom/L2o8f7gZ95RCvyoLU= +modernc.org/sqlite v1.30.2 h1:IPVVkhLu5mMVnS1dQgh3h0SAACRWcVk7aoLP9Us3UCk= +modernc.org/sqlite v1.30.2/go.mod h1:DUmsiWQDaAvU4abhc/N+djlom/L2o8f7gZ95RCvyoLU= modernc.org/strutil v1.2.0 h1:agBi9dp1I+eOnxXeiZawM8F4LawKv4NzGWSaLfyeNZA= modernc.org/strutil v1.2.0/go.mod h1:/mdcBmfOibveCTBxUl5B5l6W+TTH1FXPLHZE6bTosX0= modernc.org/token v1.1.0 h1:Xl7Ap9dKaEs5kLoOQeQmPWevfnk/DM5qcLcYlA8ys6Y= From 276df9576827b066f84576f88d4b75b37538bac4 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 17 Jul 2024 11:21:14 -0700 Subject: [PATCH 013/122] chore(deps): bump github.com/moby/sys/mountinfo from 0.7.1 to 0.7.2 (#3048) Bumps [github.com/moby/sys/mountinfo](https://github.com/moby/sys) from 0.7.1 to 0.7.2. - [Release notes](https://github.com/moby/sys/releases) - [Commits](https://github.com/moby/sys/compare/signal/v0.7.1...mountinfo/v0.7.2) --- updated-dependencies: - dependency-name: github.com/moby/sys/mountinfo dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- go.mod | 2 +- go.sum | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/go.mod b/go.mod index 1f75c96ce64..a0fb50cebb9 100644 --- a/go.mod +++ b/go.mod @@ -55,7 +55,7 @@ require ( github.com/mitchellh/go-homedir v1.1.0 github.com/mitchellh/hashstructure/v2 v2.0.2 github.com/mitchellh/mapstructure v1.5.0 - github.com/moby/sys/mountinfo v0.7.1 + github.com/moby/sys/mountinfo v0.7.2 github.com/olekukonko/tablewriter v0.0.5 github.com/opencontainers/go-digest v1.0.0 github.com/pelletier/go-toml v1.9.5 diff --git a/go.sum b/go.sum index b640f76f3e2..947a8c99890 100644 --- a/go.sum +++ b/go.sum @@ -583,8 +583,8 @@ github.com/moby/docker-image-spec v1.3.1 h1:jMKff3w6PgbfSa69GfNg+zN/XLhfXJGnEx3N github.com/moby/docker-image-spec v1.3.1/go.mod h1:eKmb5VW8vQEh/BAr2yvVNvuiJuY6UIocYsFu/DxxRpo= github.com/moby/locker v1.0.1 h1:fOXqR41zeveg4fFODix+1Ch4mj/gT0NE1XJbp/epuBg= github.com/moby/locker v1.0.1/go.mod h1:S7SDdo5zpBK84bzzVlKr2V0hz+7x9hWbYC/kq7oQppc= -github.com/moby/sys/mountinfo v0.7.1 h1:/tTvQaSJRr2FshkhXiIpux6fQ2Zvc4j7tAhMTStAG2g= -github.com/moby/sys/mountinfo v0.7.1/go.mod h1:IJb6JQeOklcdMU9F5xQ8ZALD+CUr5VlGpwtX+VE0rpI= +github.com/moby/sys/mountinfo v0.7.2 h1:1shs6aH5s4o5H2zQLn796ADW1wMrIwHsyJ2v9KouLrg= +github.com/moby/sys/mountinfo v0.7.2/go.mod h1:1YOa8w8Ih7uW0wALDUgT1dTTSBrZ+HiBLGws92L2RU4= github.com/moby/sys/sequential v0.5.0 h1:OPvI35Lzn9K04PBbCLW0g4LcFAJgHsvXsRyewg5lXtc= github.com/moby/sys/sequential v0.5.0/go.mod h1:tH2cOOs5V9MlPiXcQzRC+eEyab644PWKGRYaaV5ZZlo= github.com/moby/sys/signal v0.7.0 h1:25RW3d5TnQEoKvRbEKUGay6DCQ46IxAVTT9CUMgmsSI= From 5d729a5e9e4e18d4587350ce7c602d5af5c01b21 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 17 Jul 2024 11:21:23 -0700 Subject: [PATCH 014/122] chore(deps): bump github.com/google/go-containerregistry (#3047) Bumps [github.com/google/go-containerregistry](https://github.com/google/go-containerregistry) from 0.20.0 to 0.20.1. - [Release notes](https://github.com/google/go-containerregistry/releases) - [Changelog](https://github.com/google/go-containerregistry/blob/main/.goreleaser.yml) - [Commits](https://github.com/google/go-containerregistry/compare/v0.20.0...v0.20.1) --- updated-dependencies: - dependency-name: github.com/google/go-containerregistry dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- go.mod | 2 +- go.sum | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/go.mod b/go.mod index a0fb50cebb9..54a5d378bc5 100644 --- a/go.mod +++ b/go.mod @@ -39,7 +39,7 @@ require ( github.com/go-git/go-git/v5 v5.12.0 github.com/go-test/deep v1.1.1 github.com/google/go-cmp v0.6.0 - github.com/google/go-containerregistry v0.20.0 + github.com/google/go-containerregistry v0.20.1 github.com/google/licensecheck v0.3.1 github.com/google/uuid v1.6.0 github.com/gookit/color v1.5.4 diff --git a/go.sum b/go.sum index 947a8c99890..7f3199fdea7 100644 --- a/go.sum +++ b/go.sum @@ -384,8 +384,8 @@ github.com/google/go-cmp v0.5.6/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/ github.com/google/go-cmp v0.5.9/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= github.com/google/go-cmp v0.6.0 h1:ofyhxvXcZhMsU5ulbFiLKl/XBFqE1GSq7atu8tAmTRI= github.com/google/go-cmp v0.6.0/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= -github.com/google/go-containerregistry v0.20.0 h1:wRqHpOeVh3DnenOrPy9xDOLdnLatiGuuNRVelR2gSbg= -github.com/google/go-containerregistry v0.20.0/go.mod h1:YCMFNQeeXeLF+dnhhWkqDItx/JSkH01j1Kis4PsjzFI= +github.com/google/go-containerregistry v0.20.1 h1:eTgx9QNYugV4DN5mz4U8hiAGTi1ybXn0TPi4Smd8du0= +github.com/google/go-containerregistry v0.20.1/go.mod h1:YCMFNQeeXeLF+dnhhWkqDItx/JSkH01j1Kis4PsjzFI= github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg= github.com/google/licensecheck v0.3.1 h1:QoxgoDkaeC4nFrtGN1jV7IPmDCHFNIVh54e5hSt6sPs= github.com/google/licensecheck v0.3.1/go.mod h1:ORkR35t/JjW+emNKtfJDII0zlciG9JgbT7SmsohlHmY= From ba31c2f1ae28d264c0222c43ccf839721d636db9 Mon Sep 17 00:00:00 2001 From: Keith Zantow Date: Wed, 17 Jul 2024 14:23:58 -0400 Subject: [PATCH 015/122] fix: include CPEs with Maven groupId as vendor (#3045) Signed-off-by: Keith Zantow --- .../internal/cpegenerate/generate_test.go | 16 ++++++++++++++++ syft/pkg/cataloger/internal/cpegenerate/java.go | 7 +++++++ .../cataloger/internal/cpegenerate/java_test.go | 2 +- 3 files changed, 24 insertions(+), 1 deletion(-) diff --git a/syft/pkg/cataloger/internal/cpegenerate/generate_test.go b/syft/pkg/cataloger/internal/cpegenerate/generate_test.go index e0b9af6cb6f..bd407085269 100644 --- a/syft/pkg/cataloger/internal/cpegenerate/generate_test.go +++ b/syft/pkg/cataloger/internal/cpegenerate/generate_test.go @@ -203,6 +203,8 @@ func TestGeneratePackageCPEs(t *testing.T) { "cpe:2.3:a:nexus:nexus:3.2:*:*:*:*:*:*:*", "cpe:2.3:a:sonatype:name:3.2:*:*:*:*:*:*:*", "cpe:2.3:a:sonatype:nexus:3.2:*:*:*:*:*:*:*", + "cpe:2.3:a:org.sonatype.nexus:name:3.2:*:*:*:*:*:*:*", + "cpe:2.3:a:org.sonatype.nexus:nexus:3.2:*:*:*:*:*:*:*", }, }, { @@ -371,6 +373,7 @@ func TestGeneratePackageCPEs(t *testing.T) { "cpe:2.3:a:name:name:3.2:*:*:*:*:*:*:*", "cpe:2.3:a:jenkins:name:3.2:*:*:*:*:*:*:*", "cpe:2.3:a:cloudbees:name:3.2:*:*:*:*:*:*:*", + "cpe:2.3:a:com.cloudbees.jenkins.plugins:name:3.2:*:*:*:*:*:*:*", }, }, { @@ -394,6 +397,8 @@ func TestGeneratePackageCPEs(t *testing.T) { "cpe:2.3:a:something:something:3.2:*:*:*:*:*:*:*", "cpe:2.3:a:jenkins:name:3.2:*:*:*:*:*:*:*", "cpe:2.3:a:jenkins:something:3.2:*:*:*:*:*:*:*", + "cpe:2.3:a:io.jenkins.plugins.name.something:name:3.2:*:*:*:*:*:*:*", + "cpe:2.3:a:io.jenkins.plugins.name.something:something:3.2:*:*:*:*:*:*:*", }, }, { @@ -413,6 +418,7 @@ func TestGeneratePackageCPEs(t *testing.T) { expected: []string{ "cpe:2.3:a:name:name:3.2:*:*:*:*:*:*:*", "cpe:2.3:a:jenkins:name:3.2:*:*:*:*:*:*:*", + "cpe:2.3:a:io.jenkins.plugins:name:3.2:*:*:*:*:*:*:*", }, }, { @@ -434,6 +440,7 @@ func TestGeneratePackageCPEs(t *testing.T) { "cpe:2.3:a:jenkins-ci:name:3.2:*:*:*:*:*:*:*", "cpe:2.3:a:jenkins:name:3.2:*:*:*:*:*:*:*", "cpe:2.3:a:jenkins_ci:name:3.2:*:*:*:*:*:*:*", + "cpe:2.3:a:io.jenkins-ci.plugins:name:3.2:*:*:*:*:*:*:*", }, }, { @@ -455,6 +462,7 @@ func TestGeneratePackageCPEs(t *testing.T) { "cpe:2.3:a:jenkins-ci:name:3.2:*:*:*:*:*:*:*", "cpe:2.3:a:jenkins:name:3.2:*:*:*:*:*:*:*", "cpe:2.3:a:jenkins_ci:name:3.2:*:*:*:*:*:*:*", + "cpe:2.3:a:org.jenkins-ci.plugins:name:3.2:*:*:*:*:*:*:*", }, }, { @@ -489,6 +497,9 @@ func TestGeneratePackageCPEs(t *testing.T) { "cpe:2.3:a:jira_client_core:jira-client-core:3.2:*:*:*:*:*:*:*", "cpe:2.3:a:jira_client_core:jira:3.2:*:*:*:*:*:*:*", "cpe:2.3:a:jira_client_core:jira_client_core:3.2:*:*:*:*:*:*:*", + "cpe:2.3:a:org.atlassian.jira:jira:3.2:*:*:*:*:*:*:*", + "cpe:2.3:a:org.atlassian.jira:jira_client_core:3.2:*:*:*:*:*:*:*", + "cpe:2.3:a:org.atlassian.jira:jira-client-core:3.2:*:*:*:*:*:*:*", }, }, { @@ -521,6 +532,8 @@ func TestGeneratePackageCPEs(t *testing.T) { "cpe:2.3:a:jenkins:cloudbees_installation_manager:2.89.0.33:*:*:*:*:*:*:*", "cpe:2.3:a:modules:cloudbees-installation-manager:2.89.0.33:*:*:*:*:*:*:*", "cpe:2.3:a:modules:cloudbees_installation_manager:2.89.0.33:*:*:*:*:*:*:*", + "cpe:2.3:a:com.cloudbees.jenkins.modules:cloudbees_installation_manager:2.89.0.33:*:*:*:*:*:*:*", + "cpe:2.3:a:com.cloudbees.jenkins.modules:cloudbees-installation-manager:2.89.0.33:*:*:*:*:*:*:*", }, }, { @@ -594,6 +607,7 @@ func TestGeneratePackageCPEs(t *testing.T) { "cpe:2.3:a:jenkins:handlebars:3.0.8:*:*:*:*:*:*:*", "cpe:2.3:a:jenkins_ci:handlebars:3.0.8:*:*:*:*:*:*:*", "cpe:2.3:a:ui:handlebars:3.0.8:*:*:*:*:*:*:*", + "cpe:2.3:a:org.jenkins-ci.ui:handlebars:3.0.8:*:*:*:*:*:*:*", }, }, { @@ -631,6 +645,8 @@ func TestGeneratePackageCPEs(t *testing.T) { "cpe:2.3:a:jenkins:active_directory:2.25.1:*:*:*:*:*:*:*", // important! "cpe:2.3:a:jenkins_ci:active-directory:2.25.1:*:*:*:*:*:*:*", "cpe:2.3:a:jenkins_ci:active_directory:2.25.1:*:*:*:*:*:*:*", + "cpe:2.3:a:org.jenkins-ci.plugins:active-directory:2.25.1:*:*:*:*:*:*:*", + "cpe:2.3:a:org.jenkins-ci.plugins:active_directory:2.25.1:*:*:*:*:*:*:*", }, }, { diff --git a/syft/pkg/cataloger/internal/cpegenerate/java.go b/syft/pkg/cataloger/internal/cpegenerate/java.go index 7de85c9e641..8ccd38059f2 100644 --- a/syft/pkg/cataloger/internal/cpegenerate/java.go +++ b/syft/pkg/cataloger/internal/cpegenerate/java.go @@ -98,6 +98,13 @@ func vendorsFromJavaManifestNames(p pkg.Package) fieldCandidateSet { func vendorsFromGroupIDs(groupIDs []string) fieldCandidateSet { vendors := newFieldCandidateSet() for _, groupID := range groupIDs { + // always include the groupId as a vendor -- the Grype database may include alternate matches with these + vendors.add(fieldCandidate{ + value: groupID, + disallowSubSelections: true, + disallowDelimiterVariations: true, + }) + for i, field := range strings.Split(groupID, ".") { field = strings.TrimSpace(field) diff --git a/syft/pkg/cataloger/internal/cpegenerate/java_test.go b/syft/pkg/cataloger/internal/cpegenerate/java_test.go index a08c0fec9ec..3573b8c9b6f 100644 --- a/syft/pkg/cataloger/internal/cpegenerate/java_test.go +++ b/syft/pkg/cataloger/internal/cpegenerate/java_test.go @@ -139,7 +139,7 @@ func Test_vendorsFromGroupIDs(t *testing.T) { } for _, test := range tests { t.Run(test.groupID, func(t *testing.T) { - assert.ElementsMatch(t, test.expected, vendorsFromGroupIDs([]string{test.groupID}).values(), "different vendors") + assert.ElementsMatch(t, append(test.expected, test.groupID), vendorsFromGroupIDs([]string{test.groupID}).values(), "different vendors") }) } } From 761a161e7f28030dda209803c12cd1c8484b4f3d Mon Sep 17 00:00:00 2001 From: Alan Pope Date: Wed, 17 Jul 2024 22:33:17 +0100 Subject: [PATCH 016/122] docs: CODE_OF_CONDUCT.md (#3046) This PR adds a code of conduct document to the repo, as agreed at our recent OSS team catch up. Signed-off-by: Alan Pope --- CODE_OF_CONDUCT.md | 128 +++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 128 insertions(+) create mode 100644 CODE_OF_CONDUCT.md diff --git a/CODE_OF_CONDUCT.md b/CODE_OF_CONDUCT.md new file mode 100644 index 00000000000..5d19a3c266d --- /dev/null +++ b/CODE_OF_CONDUCT.md @@ -0,0 +1,128 @@ +# Contributor Covenant Code of Conduct + +## Our Pledge + +We as members, contributors, and leaders pledge to make participation in our +community a harassment-free experience for everyone, regardless of age, body +size, visible or invisible disability, ethnicity, sex characteristics, gender +identity and expression, level of experience, education, socio-economic status, +nationality, personal appearance, race, religion, or sexual identity +and orientation. + +We pledge to act and interact in ways that contribute to an open, welcoming, +diverse, inclusive, and healthy community. + +## Our Standards + +Examples of behavior that contributes to a positive environment for our +community include: + +* Demonstrating empathy and kindness toward other people +* Being respectful of differing opinions, viewpoints, and experiences +* Giving and gracefully accepting constructive feedback +* Accepting responsibility and apologizing to those affected by our mistakes, + and learning from the experience +* Focusing on what is best not just for us as individuals, but for the + overall community + +Examples of unacceptable behavior include: + +* The use of sexualized language or imagery, and sexual attention or + advances of any kind +* Trolling, insulting or derogatory comments, and personal or political attacks +* Public or private harassment +* Publishing others' private information, such as a physical or email + address, without their explicit permission +* Other conduct which could reasonably be considered inappropriate in a + professional setting + +## Enforcement Responsibilities + +Community leaders are responsible for clarifying and enforcing our standards of +acceptable behavior and will take appropriate and fair corrective action in +response to any behavior that they deem inappropriate, threatening, offensive, +or harmful. + +Community leaders have the right and responsibility to remove, edit, or reject +comments, commits, code, wiki edits, issues, and other contributions that are +not aligned to this Code of Conduct, and will communicate reasons for moderation +decisions when appropriate. + +## Scope + +This Code of Conduct applies within all community spaces, and also applies when +an individual is officially representing the community in public spaces. +Examples of representing our community include using an official e-mail address, +posting via an official social media account, or acting as an appointed +representative at an online or offline event. + +## Enforcement + +Instances of abusive, harassing, or otherwise unacceptable behavior may be +reported to the community leaders responsible for enforcement at +[opensource@anchore.com](mailto:opensource@anchore.com). +All complaints will be reviewed and investigated promptly and fairly. + +All community leaders are obligated to respect the privacy and security of the +reporter of any incident. + +## Enforcement Guidelines + +Community leaders will follow these Community Impact Guidelines in determining +the consequences for any action they deem in violation of this Code of Conduct: + +### 1. Correction + +**Community Impact**: Use of inappropriate language or other behavior deemed +unprofessional or unwelcome in the community. + +**Consequence**: A private, written warning from community leaders, providing +clarity around the nature of the violation and an explanation of why the +behavior was inappropriate. A public apology may be requested. + +### 2. Warning + +**Community Impact**: A violation through a single incident or series +of actions. + +**Consequence**: A warning with consequences for continued behavior. No +interaction with the people involved, including unsolicited interaction with +those enforcing the Code of Conduct, for a specified period of time. This +includes avoiding interactions in community spaces as well as external channels +like social media. Violating these terms may lead to a temporary or +permanent ban. + +### 3. Temporary Ban + +**Community Impact**: A serious violation of community standards, including +sustained inappropriate behavior. + +**Consequence**: A temporary ban from any sort of interaction or public +communication with the community for a specified period of time. No public or +private interaction with the people involved, including unsolicited interaction +with those enforcing the Code of Conduct, is allowed during this period. +Violating these terms may lead to a permanent ban. + +### 4. Permanent Ban + +**Community Impact**: Demonstrating a pattern of violation of community +standards, including sustained inappropriate behavior, harassment of an +individual, or aggression toward or disparagement of classes of individuals. + +**Consequence**: A permanent ban from any sort of public interaction within +the community. + +## Attribution + +This Code of Conduct is adapted from the [Contributor Covenant][homepage], +version 2.0, available at +https://www.contributor-covenant.org/version/2/0/code_of_conduct.html. + +Community Impact Guidelines were inspired by [Mozilla's code of conduct +enforcement ladder](https://github.com/mozilla/diversity). + +[homepage]: https://www.contributor-covenant.org + +For answers to common questions about this code of conduct, see the FAQ at +https://www.contributor-covenant.org/faq. Translations are available at +https://www.contributor-covenant.org/translations. From 69031b064664981fba4a77b719228605593b8a90 Mon Sep 17 00:00:00 2001 From: "anchore-actions-token-generator[bot]" <102182147+anchore-actions-token-generator[bot]@users.noreply.github.com> Date: Thu, 18 Jul 2024 08:21:31 -0700 Subject: [PATCH 017/122] chore(deps): update tools to latest versions (#3050) Signed-off-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com> Co-authored-by: spiffcs <32073428+spiffcs@users.noreply.github.com> --- .binny.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.binny.yaml b/.binny.yaml index 38b0c470480..0a1dafff55f 100644 --- a/.binny.yaml +++ b/.binny.yaml @@ -111,7 +111,7 @@ tools: # used for triggering a release - name: gh version: - want: v2.52.0 + want: v2.53.0 method: github-release with: repo: cli/cli From 034a98f02972e94cbf3dddfdd116b94176a9d56e Mon Sep 17 00:00:00 2001 From: "anchore-actions-token-generator[bot]" <102182147+anchore-actions-token-generator[bot]@users.noreply.github.com> Date: Thu, 18 Jul 2024 09:26:01 -0700 Subject: [PATCH 018/122] chore(deps): update stereoscope to 487b11e5ba2622d976acda10c605da63b4fbbb0a (#3032) * chore(deps): update stereoscope to 487b11e5ba2622d976acda10c605da63b4fbbb0a Signed-off-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com> * chore: allow unlicense Signed-off-by: Christopher Phillips <32073428+spiffcs@users.noreply.github.com> --------- Signed-off-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com> Signed-off-by: Christopher Phillips <32073428+spiffcs@users.noreply.github.com> Co-authored-by: kzantow <3009477+kzantow@users.noreply.github.com> Co-authored-by: Christopher Phillips <32073428+spiffcs@users.noreply.github.com> --- .bouncer.yaml | 1 + go.mod | 8 ++++---- go.sum | 15 ++++++++------- 3 files changed, 13 insertions(+), 11 deletions(-) diff --git a/.bouncer.yaml b/.bouncer.yaml index b27baa6eab2..5360418ef1b 100644 --- a/.bouncer.yaml +++ b/.bouncer.yaml @@ -6,6 +6,7 @@ permit: - MPL.* - ISC - WTFPL + - Unlicense ignore-packages: # packageurl-go is released under the MIT license located in the root of the repo at /mit.LICENSE diff --git a/go.mod b/go.mod index 54a5d378bc5..65d42acfb11 100644 --- a/go.mod +++ b/go.mod @@ -17,7 +17,7 @@ require ( github.com/anchore/go-testutils v0.0.0-20200925183923-d5f45b0d3c04 github.com/anchore/go-version v1.2.2-0.20200701162849-18adb9c92b9b github.com/anchore/packageurl-go v0.1.1-0.20240507183024-848e011fc24f - github.com/anchore/stereoscope v0.0.3-0.20240710175110-27b66b76fc66 + github.com/anchore/stereoscope v0.0.3-0.20240711134149-487b11e5ba26 github.com/anmitsu/go-shlex v0.0.0-20200514113438-38f4b401e2be // we are hinting brotli to latest due to warning when installing archiver v3: // go: warning: github.com/andybalholm/brotli@v1.0.1: retracted by module author: occasional panics and data corruption @@ -162,7 +162,7 @@ require ( github.com/klauspost/pgzip v1.2.5 // indirect github.com/kr/pretty v0.3.1 // indirect github.com/kr/text v0.2.0 // indirect - github.com/logrusorgru/aurora v0.0.0-20200102142835-e9ef32dff381 // indirect + github.com/logrusorgru/aurora v2.0.3+incompatible // indirect github.com/lucasb-eyer/go-colorful v1.2.0 // indirect github.com/maruel/natural v1.1.1 // indirect github.com/mattn/go-colorable v0.1.13 // indirect @@ -188,7 +188,7 @@ require ( github.com/opencontainers/selinux v1.11.0 // indirect github.com/pborman/indent v1.2.1 // indirect github.com/pelletier/go-toml/v2 v2.1.0 // indirect - github.com/pierrec/lz4/v4 v4.1.15 // indirect + github.com/pierrec/lz4/v4 v4.1.19 // indirect github.com/pjbgf/sha1cd v0.3.0 // indirect github.com/pkg/errors v0.9.1 // indirect github.com/pkg/profile v1.7.0 // indirect @@ -209,7 +209,7 @@ require ( github.com/spf13/viper v1.18.2 // indirect github.com/subosito/gotenv v1.6.0 // indirect github.com/sylabs/sif/v2 v2.17.1 // indirect - github.com/sylabs/squashfs v0.6.1 // indirect + github.com/sylabs/squashfs v1.0.0 // indirect github.com/therootcompany/xz v1.0.1 // indirect github.com/tidwall/gjson v1.17.0 // indirect github.com/tidwall/match v1.1.1 // indirect diff --git a/go.sum b/go.sum index 7f3199fdea7..f94a26c1deb 100644 --- a/go.sum +++ b/go.sum @@ -113,8 +113,8 @@ github.com/anchore/go-version v1.2.2-0.20200701162849-18adb9c92b9b h1:e1bmaoJfZV github.com/anchore/go-version v1.2.2-0.20200701162849-18adb9c92b9b/go.mod h1:Bkc+JYWjMCF8OyZ340IMSIi2Ebf3uwByOk6ho4wne1E= github.com/anchore/packageurl-go v0.1.1-0.20240507183024-848e011fc24f h1:B/E9ixKNCasntpoch61NDaQyGPDXLEJlL+B9B/PbdbA= github.com/anchore/packageurl-go v0.1.1-0.20240507183024-848e011fc24f/go.mod h1:Blo6OgJNiYF41ufcgHKkbCKF2MDOMlrqhXv/ij6ocR4= -github.com/anchore/stereoscope v0.0.3-0.20240710175110-27b66b76fc66 h1:Z/yFalhLPfmE1MmIDKpE4GIVcWI0r7WpYX+7nLONRj0= -github.com/anchore/stereoscope v0.0.3-0.20240710175110-27b66b76fc66/go.mod h1:Ttqzw15V5ku7hITQNH4t6Nc+naBNAfSTDagmhSNPwJo= +github.com/anchore/stereoscope v0.0.3-0.20240711134149-487b11e5ba26 h1:nOTfmXionIzGtg487nREmvDNr7QbR9vf6HbC2Z6n1ZE= +github.com/anchore/stereoscope v0.0.3-0.20240711134149-487b11e5ba26/go.mod h1:DcQdMes8SwpFli3rDH0v+Vd9qU9Jariq7JSHNJV5X/A= github.com/andreyvit/diff v0.0.0-20170406064948-c7f18ee00883/go.mod h1:rCTlJbsFo29Kk6CurOXKm700vrz8f0KW0JNfpkRJY/8= github.com/andybalholm/brotli v1.0.1/go.mod h1:loMXtMfwqflxFJPmdbJO0a3KNoPuLBgiu3qAvBg8x/Y= github.com/andybalholm/brotli v1.0.4 h1:V7DdXeJtZscaqfNuAdSRuRFzuiKlHSC/Zh3zl9qY3JY= @@ -522,8 +522,9 @@ github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY= github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE= github.com/kylelemons/godebug v1.1.0 h1:RPNrshWIDI6G2gRW9EHilWtl7Z6Sb1BR0xunSBf0SNc= github.com/kylelemons/godebug v1.1.0/go.mod h1:9/0rRGxNHcop5bhtWyNeEfOS8JIWk580+fNqagV/RAw= -github.com/logrusorgru/aurora v0.0.0-20200102142835-e9ef32dff381 h1:bqDmpDG49ZRnB5PcgP0RXtQvnMSgIF14M7CBd2shtXs= github.com/logrusorgru/aurora v0.0.0-20200102142835-e9ef32dff381/go.mod h1:7rIyQOR62GCctdiQpZ/zOJlFyk6y+94wXzv6RNZgaR4= +github.com/logrusorgru/aurora v2.0.3+incompatible h1:tOpm7WcpBTn4fjmVfgpQq0EfczGlG91VSDkswnjF5A8= +github.com/logrusorgru/aurora v2.0.3+incompatible/go.mod h1:7rIyQOR62GCctdiQpZ/zOJlFyk6y+94wXzv6RNZgaR4= github.com/lucasb-eyer/go-colorful v1.2.0 h1:1nnpGOrhyZZuNyfu1QjKiUICQ74+3FNCN69Aj6K7nkY= github.com/lucasb-eyer/go-colorful v1.2.0/go.mod h1:R4dSotOR9KMtayYi1e77YzuveK+i7ruzyGqttikkLy0= github.com/lyft/protoc-gen-star v0.5.3/go.mod h1:V0xaHgaf5oCCqmcxYcWiDfTiKsZsRc87/1qhoTACD8w= @@ -635,8 +636,8 @@ github.com/pelletier/go-toml v1.9.5/go.mod h1:u1nR/EPcESfeI/szUZKdtJ0xRNbUoANCko github.com/pelletier/go-toml/v2 v2.1.0 h1:FnwAJ4oYMvbT/34k9zzHuZNrhlz48GB3/s6at6/MHO4= github.com/pelletier/go-toml/v2 v2.1.0/go.mod h1:tJU2Z3ZkXwnxa4DPO899bsyIoywizdUvyaeZurnPPDc= github.com/pierrec/lz4/v4 v4.1.2/go.mod h1:gZWDp/Ze/IJXGXf23ltt2EXimqmTUXEy0GFuRQyBid4= -github.com/pierrec/lz4/v4 v4.1.15 h1:MO0/ucJhngq7299dKLwIMtgTfbkoSPF6AoMYDd8Q4q0= -github.com/pierrec/lz4/v4 v4.1.15/go.mod h1:gZWDp/Ze/IJXGXf23ltt2EXimqmTUXEy0GFuRQyBid4= +github.com/pierrec/lz4/v4 v4.1.19 h1:tYLzDnjDXh9qIxSTKHwXwOYmm9d887Y7Y1ZkyXYHAN4= +github.com/pierrec/lz4/v4 v4.1.19/go.mod h1:gZWDp/Ze/IJXGXf23ltt2EXimqmTUXEy0GFuRQyBid4= github.com/pjbgf/sha1cd v0.3.0 h1:4D5XXmUUBUl/xQ6IjCkEAbqXskkq/4O7LmGn0AqMDs4= github.com/pjbgf/sha1cd v0.3.0/go.mod h1:nZ1rrWOcGJ5uZgEEVL1VUM9iRQiZvWdbZjkKyFzPPsI= github.com/pkg/diff v0.0.0-20210226163009-20ebb0f2a09e/go.mod h1:pJLUxLENpZxwdsKMEsNbx1VGcRFpLqf3715MtcvvzbA= @@ -770,8 +771,8 @@ github.com/subosito/gotenv v1.6.0 h1:9NlTDc1FTs4qu0DDq7AEtTPNw6SVm7uBMsUCUjABIf8 github.com/subosito/gotenv v1.6.0/go.mod h1:Dk4QP5c2W3ibzajGcXpNraDfq2IrhjMIvMSWPKKo0FU= github.com/sylabs/sif/v2 v2.17.1 h1:p6Sl0LWyShXBj2SBsS1dMOMIMrZHe8pwBnBrYt6uo4M= github.com/sylabs/sif/v2 v2.17.1/go.mod h1:XUGB6AQUXGkms3qPOPdevctT3lBLRLWZNWHVnt5HMKE= -github.com/sylabs/squashfs v0.6.1 h1:4hgvHnD9JGlYWwT0bPYNt9zaz23mAV3Js+VEgQoRGYQ= -github.com/sylabs/squashfs v0.6.1/go.mod h1:ZwpbPCj0ocIvMy2br6KZmix6Gzh6fsGQcCnydMF+Kx8= +github.com/sylabs/squashfs v1.0.0 h1:xAyMS21ogglkuR5HaY55PCfqY3H32ma9GkasTYo28Zg= +github.com/sylabs/squashfs v1.0.0/go.mod h1:rhWzvgefq1X+R+LZdts10hfMsTg3g74OfGunW8tvg/4= 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/therootcompany/xz v1.0.1 h1:CmOtsn1CbtmyYiusbfmhmkpAAETj0wBIH6kCYaX+xzw= From b263b1ec1f8af615c8ee01d13b8120464d293140 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 22 Jul 2024 10:55:55 -0400 Subject: [PATCH 019/122] chore(deps): bump github/codeql-action from 3.25.12 to 3.25.13 (#3059) Bumps [github/codeql-action](https://github.com/github/codeql-action) from 3.25.12 to 3.25.13. - [Release notes](https://github.com/github/codeql-action/releases) - [Changelog](https://github.com/github/codeql-action/blob/main/CHANGELOG.md) - [Commits](https://github.com/github/codeql-action/compare/4fa2a7953630fd2f3fb380f21be14ede0169dd4f...2d790406f505036ef40ecba973cc774a50395aac) --- updated-dependencies: - dependency-name: github/codeql-action dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- .github/workflows/codeql-analysis.yml | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/.github/workflows/codeql-analysis.yml b/.github/workflows/codeql-analysis.yml index d1791caf9b6..e92c3d4fced 100644 --- a/.github/workflows/codeql-analysis.yml +++ b/.github/workflows/codeql-analysis.yml @@ -45,7 +45,7 @@ jobs: # Initializes the CodeQL tools for scanning. - name: Initialize CodeQL - uses: github/codeql-action/init@4fa2a7953630fd2f3fb380f21be14ede0169dd4f #v3.25.12 + uses: github/codeql-action/init@2d790406f505036ef40ecba973cc774a50395aac #v3.25.13 with: languages: ${{ matrix.language }} # If you wish to specify custom queries, you can do so here or in a config file. @@ -56,7 +56,7 @@ jobs: # Autobuild attempts to build any compiled languages (C/C++, C#, or Java). # If this step fails, then you should remove it and run the build manually (see below) - name: Autobuild - uses: github/codeql-action/autobuild@4fa2a7953630fd2f3fb380f21be14ede0169dd4f #v3.25.12 + uses: github/codeql-action/autobuild@2d790406f505036ef40ecba973cc774a50395aac #v3.25.13 # ℹī¸ Command-line programs to run using the OS shell. # 📚 https://git.io/JvXDl @@ -70,4 +70,4 @@ jobs: # make release - name: Perform CodeQL Analysis - uses: github/codeql-action/analyze@4fa2a7953630fd2f3fb380f21be14ede0169dd4f #v3.25.12 + uses: github/codeql-action/analyze@2d790406f505036ef40ecba973cc774a50395aac #v3.25.13 From 0c53a087f0a14bdf54bdcaa1170dbcb79c4a0136 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 22 Jul 2024 08:44:06 -0700 Subject: [PATCH 020/122] chore(deps): bump docker/login-action from 3.2.0 to 3.3.0 (#3058) Bumps [docker/login-action](https://github.com/docker/login-action) from 3.2.0 to 3.3.0. - [Release notes](https://github.com/docker/login-action/releases) - [Commits](https://github.com/docker/login-action/compare/0d4c9c5ea7693da7b068278f7b52bda2a190a446...9780b0c442fbb1117ed29e0efdff1e18412f7567) --- updated-dependencies: - dependency-name: docker/login-action dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- .github/workflows/release.yaml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/release.yaml b/.github/workflows/release.yaml index 3c644a62c28..734fc7a3284 100644 --- a/.github/workflows/release.yaml +++ b/.github/workflows/release.yaml @@ -113,13 +113,13 @@ jobs: uses: ./.github/actions/bootstrap - name: Login to Docker Hub - uses: docker/login-action@0d4c9c5ea7693da7b068278f7b52bda2a190a446 #v3.2.0 + uses: docker/login-action@9780b0c442fbb1117ed29e0efdff1e18412f7567 #v3.3.0 with: username: ${{ secrets.ANCHOREOSSWRITE_DH_USERNAME }} password: ${{ secrets.ANCHOREOSSWRITE_DH_PAT }} - name: Login to GitHub Container Registry - uses: docker/login-action@0d4c9c5ea7693da7b068278f7b52bda2a190a446 #v3.2.0 + uses: docker/login-action@9780b0c442fbb1117ed29e0efdff1e18412f7567 #v3.3.0 with: registry: ghcr.io username: ${{ github.actor }} From d0a7d4c43edc2f57a96ff2b2ced15f51d5ee4a42 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 22 Jul 2024 08:45:01 -0700 Subject: [PATCH 021/122] chore(deps): bump modernc.org/sqlite from 1.30.2 to 1.31.1 (#3057) Bumps [modernc.org/sqlite](https://gitlab.com/cznic/sqlite) from 1.30.2 to 1.31.1. - [Commits](https://gitlab.com/cznic/sqlite/compare/v1.30.2...v1.31.1) --- updated-dependencies: - dependency-name: modernc.org/sqlite dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- go.mod | 4 ++-- go.sum | 16 ++++++++-------- 2 files changed, 10 insertions(+), 10 deletions(-) diff --git a/go.mod b/go.mod index 65d42acfb11..a4544554178 100644 --- a/go.mod +++ b/go.mod @@ -81,7 +81,7 @@ require ( golang.org/x/mod v0.19.0 golang.org/x/net v0.27.0 gopkg.in/yaml.v3 v3.0.1 - modernc.org/sqlite v1.30.2 + modernc.org/sqlite v1.31.1 ) require google.golang.org/genproto v0.0.0-20231106174013-bbf56f31fb17 // indirect @@ -243,7 +243,7 @@ require ( gopkg.in/ini.v1 v1.67.0 // indirect gopkg.in/warnings.v0 v0.1.2 // indirect modernc.org/gc/v3 v3.0.0-20240107210532-573471604cb6 // indirect - modernc.org/libc v1.52.1 // indirect + modernc.org/libc v1.55.3 // indirect modernc.org/mathutil v1.6.0 // indirect modernc.org/memory v1.8.0 // indirect modernc.org/strutil v1.2.0 // indirect diff --git a/go.sum b/go.sum index f94a26c1deb..6258f54a2d8 100644 --- a/go.sum +++ b/go.sum @@ -1359,18 +1359,18 @@ honnef.co/go/tools v0.0.0-20190523083050-ea95bdfd59fc/go.mod h1:rf3lG4BRIbNafJWh honnef.co/go/tools v0.0.1-2019.2.3/go.mod h1:a3bituU0lyd329TUQxRnasdCoJDkEUEAqEt0JzvZhAg= honnef.co/go/tools v0.0.1-2020.1.3/go.mod h1:X/FiERA/W4tHapMX5mGpAtMSVEeEUOyHaw9vFzvIQ3k= honnef.co/go/tools v0.0.1-2020.1.4/go.mod h1:X/FiERA/W4tHapMX5mGpAtMSVEeEUOyHaw9vFzvIQ3k= -modernc.org/cc/v4 v4.21.2 h1:dycHFB/jDc3IyacKipCNSDrjIC0Lm1hyoWOZTRR20Lk= -modernc.org/cc/v4 v4.21.2/go.mod h1:HM7VJTZbUCR3rV8EYBi9wxnJ0ZBRiGE5OeGXNA0IsLQ= -modernc.org/ccgo/v4 v4.17.10 h1:6wrtRozgrhCxieCeJh85QsxkX/2FFrT9hdaWPlbn4Zo= -modernc.org/ccgo/v4 v4.17.10/go.mod h1:0NBHgsqTTpm9cA5z2ccErvGZmtntSM9qD2kFAs6pjXM= +modernc.org/cc/v4 v4.21.4 h1:3Be/Rdo1fpr8GrQ7IVw9OHtplU4gWbb+wNgeoBMmGLQ= +modernc.org/cc/v4 v4.21.4/go.mod h1:HM7VJTZbUCR3rV8EYBi9wxnJ0ZBRiGE5OeGXNA0IsLQ= +modernc.org/ccgo/v4 v4.19.2 h1:lwQZgvboKD0jBwdaeVCTouxhxAyN6iawF3STraAal8Y= +modernc.org/ccgo/v4 v4.19.2/go.mod h1:ysS3mxiMV38XGRTTcgo0DQTeTmAO4oCmJl1nX9VFI3s= modernc.org/fileutil v1.3.0 h1:gQ5SIzK3H9kdfai/5x41oQiKValumqNTDXMvKo62HvE= modernc.org/fileutil v1.3.0/go.mod h1:XatxS8fZi3pS8/hKG2GH/ArUogfxjpEKs3Ku3aK4JyQ= modernc.org/gc/v2 v2.4.1 h1:9cNzOqPyMJBvrUipmynX0ZohMhcxPtMccYgGOJdOiBw= modernc.org/gc/v2 v2.4.1/go.mod h1:wzN5dK1AzVGoH6XOzc3YZ+ey/jPgYHLuVckd62P0GYU= modernc.org/gc/v3 v3.0.0-20240107210532-573471604cb6 h1:5D53IMaUuA5InSeMu9eJtlQXS2NxAhyWQvkKEgXZhHI= modernc.org/gc/v3 v3.0.0-20240107210532-573471604cb6/go.mod h1:Qz0X07sNOR1jWYCrJMEnbW/X55x206Q7Vt4mz6/wHp4= -modernc.org/libc v1.52.1 h1:uau0VoiT5hnR+SpoWekCKbLqm7v6dhRL3hI+NQhgN3M= -modernc.org/libc v1.52.1/go.mod h1:HR4nVzFDSDizP620zcMCgjb1/8xk2lg5p/8yjfGv1IQ= +modernc.org/libc v1.55.3 h1:AzcW1mhlPNrRtjS5sS+eW2ISCgSOLLNyFzRh/V3Qj/U= +modernc.org/libc v1.55.3/go.mod h1:qFXepLhz+JjFThQ4kzwzOjA/y/artDeg+pcYnY+Q83w= modernc.org/mathutil v1.6.0 h1:fRe9+AmYlaej+64JsEEhoWuAYBkOtQiMEU7n/XgfYi4= modernc.org/mathutil v1.6.0/go.mod h1:Ui5Q9q1TR2gFm0AQRqQUaBWFLAhQpCwNcuhBOSedWPo= modernc.org/memory v1.8.0 h1:IqGTL6eFMaDZZhEWwcREgeMXYwmW83LYW8cROZYkg+E= @@ -1379,8 +1379,8 @@ modernc.org/opt v0.1.3 h1:3XOZf2yznlhC+ibLltsDGzABUGVx8J6pnFMS3E4dcq4= modernc.org/opt v0.1.3/go.mod h1:WdSiB5evDcignE70guQKxYUl14mgWtbClRi5wmkkTX0= modernc.org/sortutil v1.2.0 h1:jQiD3PfS2REGJNzNCMMaLSp/wdMNieTbKX920Cqdgqc= modernc.org/sortutil v1.2.0/go.mod h1:TKU2s7kJMf1AE84OoiGppNHJwvB753OYfNl2WRb++Ss= -modernc.org/sqlite v1.30.2 h1:IPVVkhLu5mMVnS1dQgh3h0SAACRWcVk7aoLP9Us3UCk= -modernc.org/sqlite v1.30.2/go.mod h1:DUmsiWQDaAvU4abhc/N+djlom/L2o8f7gZ95RCvyoLU= +modernc.org/sqlite v1.31.1 h1:XVU0VyzxrYHlBhIs1DiEgSl0ZtdnPtbLVy8hSkzxGrs= +modernc.org/sqlite v1.31.1/go.mod h1:UqoylwmTb9F+IqXERT8bW9zzOWN8qwAIcLdzeBZs4hA= modernc.org/strutil v1.2.0 h1:agBi9dp1I+eOnxXeiZawM8F4LawKv4NzGWSaLfyeNZA= modernc.org/strutil v1.2.0/go.mod h1:/mdcBmfOibveCTBxUl5B5l6W+TTH1FXPLHZE6bTosX0= modernc.org/token v1.1.0 h1:Xl7Ap9dKaEs5kLoOQeQmPWevfnk/DM5qcLcYlA8ys6Y= From 536611fa2554e487fa94c0b9c6d0fc07209694b9 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 22 Jul 2024 08:45:25 -0700 Subject: [PATCH 022/122] chore(deps): bump github.com/gkampitakis/go-snaps from 0.5.4 to 0.5.5 (#3056) Bumps [github.com/gkampitakis/go-snaps](https://github.com/gkampitakis/go-snaps) from 0.5.4 to 0.5.5. - [Release notes](https://github.com/gkampitakis/go-snaps/releases) - [Commits](https://github.com/gkampitakis/go-snaps/compare/v0.5.4...v0.5.5) --- updated-dependencies: - dependency-name: github.com/gkampitakis/go-snaps dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- go.mod | 2 +- go.sum | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/go.mod b/go.mod index a4544554178..783900ba4de 100644 --- a/go.mod +++ b/go.mod @@ -34,7 +34,7 @@ require ( github.com/elliotchance/phpserialize v1.4.0 github.com/facebookincubator/nvdtools v0.1.5 github.com/github/go-spdx/v2 v2.3.1 - github.com/gkampitakis/go-snaps v0.5.4 + github.com/gkampitakis/go-snaps v0.5.5 github.com/go-git/go-billy/v5 v5.5.0 github.com/go-git/go-git/v5 v5.12.0 github.com/go-test/deep v1.1.1 diff --git a/go.sum b/go.sum index 6258f54a2d8..2a9c328568e 100644 --- a/go.sum +++ b/go.sum @@ -293,8 +293,8 @@ github.com/gkampitakis/ciinfo v0.3.0 h1:gWZlOC2+RYYttL0hBqcoQhM7h1qNkVqvRCV1fOvp github.com/gkampitakis/ciinfo v0.3.0/go.mod h1:1NIwaOcFChN4fa/B0hEBdAb6npDlFL8Bwx4dfRLRqAo= github.com/gkampitakis/go-diff v1.3.2 h1:Qyn0J9XJSDTgnsgHRdz9Zp24RaJeKMUHg2+PDZZdC4M= github.com/gkampitakis/go-diff v1.3.2/go.mod h1:LLgOrpqleQe26cte8s36HTWcTmMEur6OPYerdAAS9tk= -github.com/gkampitakis/go-snaps v0.5.4 h1:GX+dkKmVsRenz7SoTbdIEL4KQARZctkMiZ8ZKprRwT8= -github.com/gkampitakis/go-snaps v0.5.4/go.mod h1:ZABkO14uCuVxBHAXAfKG+bqNz+aa1bGPAg8jkI0Nk8Y= +github.com/gkampitakis/go-snaps v0.5.5 h1:FZ01SXOE/uIsD8lZGUjUAxTevz9tf7c1QGIgezv2KNM= +github.com/gkampitakis/go-snaps v0.5.5/go.mod h1:ZABkO14uCuVxBHAXAfKG+bqNz+aa1bGPAg8jkI0Nk8Y= 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= From aead40e1de387a1a520d440dcebbd205f460b023 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 22 Jul 2024 08:56:01 -0700 Subject: [PATCH 023/122] chore(deps): bump github.com/docker/docker (#3055) Bumps [github.com/docker/docker](https://github.com/docker/docker) from 27.0.3+incompatible to 27.1.0+incompatible. - [Release notes](https://github.com/docker/docker/releases) - [Commits](https://github.com/docker/docker/compare/v27.0.3...v27.1.0) --- updated-dependencies: - dependency-name: github.com/docker/docker dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- go.mod | 2 +- go.sum | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/go.mod b/go.mod index 783900ba4de..dcdc4d5a8b9 100644 --- a/go.mod +++ b/go.mod @@ -29,7 +29,7 @@ require ( github.com/dave/jennifer v1.7.0 github.com/deitch/magic v0.0.0-20230404182410-1ff89d7342da github.com/distribution/reference v0.6.0 - github.com/docker/docker v27.0.3+incompatible + github.com/docker/docker v27.1.0+incompatible github.com/dustin/go-humanize v1.0.1 github.com/elliotchance/phpserialize v1.4.0 github.com/facebookincubator/nvdtools v0.1.5 diff --git a/go.sum b/go.sum index 2a9c328568e..f023a58a69e 100644 --- a/go.sum +++ b/go.sum @@ -231,8 +231,8 @@ github.com/docker/cli v27.0.3+incompatible h1:usGs0/BoBW8MWxGeEtqPMkzOY56jZ6kYlS github.com/docker/cli v27.0.3+incompatible/go.mod h1:JLrzqnKDaYBop7H2jaqPtU4hHvMKP+vjCwu2uszcLI8= github.com/docker/distribution v2.8.3+incompatible h1:AtKxIZ36LoNK51+Z6RpzLpddBirtxJnzDrHLEKxTAYk= github.com/docker/distribution v2.8.3+incompatible/go.mod h1:J2gT2udsDAN96Uj4KfcMRqY0/ypR+oyYUYmja8H+y+w= -github.com/docker/docker v27.0.3+incompatible h1:aBGI9TeQ4MPlhquTQKq9XbK79rKFVwXNUAYz9aXyEBE= -github.com/docker/docker v27.0.3+incompatible/go.mod h1:eEKB0N0r5NX/I1kEveEz05bcu8tLC/8azJZsviup8Sk= +github.com/docker/docker v27.1.0+incompatible h1:rEHVQc4GZ0MIQKifQPHSFGV/dVgaZafgRf8fCPtDYBs= +github.com/docker/docker v27.1.0+incompatible/go.mod h1:eEKB0N0r5NX/I1kEveEz05bcu8tLC/8azJZsviup8Sk= github.com/docker/docker-credential-helpers v0.7.0 h1:xtCHsjxogADNZcdv1pKUHXryefjlVRqWqIhk/uXJp0A= github.com/docker/docker-credential-helpers v0.7.0/go.mod h1:rETQfLdHNT3foU5kuNkFR1R1V12OJRRO5lzt2D1b5X0= github.com/docker/go-connections v0.4.0 h1:El9xVISelRB7BuFusrZozjnkIM5YnzCViNKohAFqRJQ= From bfe6f5204aa5e848fd8466f3c92de10383b98ee5 Mon Sep 17 00:00:00 2001 From: "anchore-actions-token-generator[bot]" <102182147+anchore-actions-token-generator[bot]@users.noreply.github.com> Date: Mon, 22 Jul 2024 08:56:58 -0700 Subject: [PATCH 024/122] chore(deps): update CPE dictionary index (#3035) Signed-off-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com> Co-authored-by: wagoodman <590471+wagoodman@users.noreply.github.com> --- .../dictionary/data/cpe-index.json | 39 +++++++++++++++++++ 1 file changed, 39 insertions(+) diff --git a/syft/pkg/cataloger/internal/cpegenerate/dictionary/data/cpe-index.json b/syft/pkg/cataloger/internal/cpegenerate/dictionary/data/cpe-index.json index 37cdae870ea..361a897e2a6 100644 --- a/syft/pkg/cataloger/internal/cpegenerate/dictionary/data/cpe-index.json +++ b/syft/pkg/cataloger/internal/cpegenerate/dictionary/data/cpe-index.json @@ -6980,6 +6980,9 @@ "99fy-core": [ "cpe:2.3:a:hasthemes:free_woocommerce_theme_99fy_extension:*:*:*:*:*:wordpress:*:*" ], + "Ultimate_VC_Addons": [ + "cpe:2.3:a:brainstormforce:ultimate_addons_for_wpbakery_page_builder:*:*:*:*:*:wordpress:*:*" + ], "a-forms": [ "cpe:2.3:a:a-forms_project:a-forms:*:*:*:*:*:wordpress:*:*" ], @@ -9471,6 +9474,9 @@ "digital-publications-by-supsystic": [ "cpe:2.3:a:supsystic:digital_publications_by_supsystic:*:*:*:*:*:wordpress:*:*" ], + "dimage-360": [ + "cpe:2.3:a:darteweb:dimage_360:*:*:*:*:*:wordpress:*:*" + ], "directorist": [ "cpe:2.3:a:wpwax:directorist:*:*:*:*:*:wordpress:*:*" ], @@ -10323,6 +10329,9 @@ "feedburner-alternative-and-rss-redirect": [ "cpe:2.3:a:inisev:rss_redirect_\\\u0026_feedburner_alternative:*:*:*:*:*:wordpress:*:*" ], + "feeds-for-youtube": [ + "cpe:2.3:a:smashballoon:feeds_for_youtube:*:*:*:*:*:wordpress:*:*" + ], "feedwordpress": [ "cpe:2.3:a:feedwordpress_project:feedwordpress:*:*:*:*:*:wordpress:*:*" ], @@ -11398,6 +11407,9 @@ "imdb-widget": [ "cpe:2.3:a:imdb-widget_project:imdb-widget:*:*:*:*:*:wordpress:*:*" ], + "imgspider": [ + "cpe:2.3:a:wbolt:imgspider:*:*:*:*:*:wordpress:*:*" + ], "import-legacy-media": [ "cpe:2.3:a:import_legacy_media_project:import_legacy_media:*:*:*:*:*:wordpress:*:*" ], @@ -11692,6 +11704,9 @@ "jsmol2wp": [ "cpe:2.3:a:jsmol2wp_project:jsmol2wp:*:*:*:*:*:wordpress:*:*" ], + "json-api-user": [ + "cpe:2.3:a:parorrey:json_api_user:*:*:*:*:*:wordpress:*:*" + ], "json-content-importer": [ "cpe:2.3:a:json-content-importer:json_content_importer:*:*:*:*:*:wordpress:*:*" ], @@ -12925,6 +12940,9 @@ "one-click-demo-import": [ "cpe:2.3:a:ocdi:one_click_demo_import:*:*:*:*:*:wordpress:*:*" ], + "one-click-order-reorder": [ + "cpe:2.3:a:cedcommerce:one_click_order_re-order:*:*:*:*:*:wordpress:*:*" + ], "one-click-plugin-updater": [ "cpe:2.3:a:one_click_plugin_updater_project:one_click_plugin_updater:*:*:*:*:*:wordpress:*:*" ], @@ -13103,6 +13121,9 @@ "paid-memberships-pro": [ "cpe:2.3:a:strangerstudios:paid_memberships_pro:*:*:*:*:*:wordpress:*:*" ], + "pandavideo": [ + "cpe:2.3:a:pandavideo:panda_video:*:*:*:*:*:wordpress:*:*" + ], "parallax-image": [ "cpe:2.3:a:howardehrenberg:parallax_image:*:*:*:*:*:wordpress:*:*" ], @@ -13690,6 +13711,9 @@ "project-status": [ "cpe:2.3:a:3.7designs:project_status:*:*:*:*:*:wordpress:*:*" ], + "projecthuddle-child-site": [ + "cpe:2.3:a:brainstormforce:surefeedback:*:*:*:*:*:wordpress:*:*" + ], "promobar": [ "cpe:2.3:a:bestwebsoft:promobar:*:*:*:*:*:wordpress:*:*" ], @@ -14263,6 +14287,9 @@ "schedulicity-online-appointment-booking": [ "cpe:2.3:a:schedulicity:schedulicity:*:*:*:*:*:wordpress:*:*" ], + "schema-and-structured-data-for-wp": [ + "cpe:2.3:a:magazine3:schema_\\\u0026_structured_data_for_wp_\\\u0026_amp:*:*:*:*:*:wordpress:*:*" + ], "school-management-system": [ "cpe:2.3:a:weblizar:school_management_-_education_\\\u0026_learning_management:*:*:*:*:*:wordpress:*:*" ], @@ -14497,6 +14524,9 @@ "shortcode-to-display-post-and-user-data": [ "cpe:2.3:a:vegacorp:display_custom_fields_in_the_frontend_-_post_and_user_profile_fields:*:*:*:*:*:wordpress:*:*" ], + "shortcode-variables": [ + "cpe:2.3:a:yeken:snippet_shortcodes:*:*:*:*:*:wordpress:*:*" + ], "shortcodes-finder": [ "cpe:2.3:a:scribit:shortcodes_finder:*:*:*:*:*:wordpress:*:*" ], @@ -15467,6 +15497,9 @@ "the-holiday-calendar": [ "cpe:2.3:a:theholidaycalendar:the_holiday_calendar:*:*:*:*:*:wordpress:*:*" ], + "the-moneytizer": [ + "cpe:2.3:a:themoneytizer:the_moneytizer:*:*:*:*:*:wordpress:*:*" + ], "the-plus-addons-for-elementor-page-builder": [ "cpe:2.3:a:posimyth:the_plus_addons_for_elementor:*:*:*:*:free:wordpress:*:*", "cpe:2.3:a:posimyth:the_plus_addons_for_elementor_page_builder_lite:*:*:*:*:*:wordpress:*:*" @@ -15833,6 +15866,9 @@ "ultra-companion": [ "cpe:2.3:a:wpoperation:ultra_companion:*:*:*:*:*:wordpress:*:*" ], + "ultraaddons-elementor-lite": [ + "cpe:2.3:a:codeastrology:ultraaddons:*:*:*:*:*:*:*:*" + ], "uncanny-automator": [ "cpe:2.3:a:uncannyowl:uncanny_automator:*:*:*:*:*:wordpress:*:*" ], @@ -18244,6 +18280,9 @@ "yith-woocommerce-product-add-ons": [ "cpe:2.3:a:yithemes:yith_woocommerce_product_add-ons:*:*:*:*:free:wordpress:*:*" ], + "ymc-smart-filter": [ + "cpe:2.3:a:ymc-22:filter_\\\u0026_grids:*:*:*:*:*:wordpress:*:*" + ], "yookassa": [ "cpe:2.3:a:yookassa:yukassa_for_woocommerce:*:*:*:*:*:wordpress:*:*" ], From 125c787e40abec0daa83a50cdaf2d6afd7f40c9f Mon Sep 17 00:00:00 2001 From: Keith Zantow Date: Mon, 22 Jul 2024 13:05:04 -0400 Subject: [PATCH 025/122] chore: add debug logging for errors reading RPM files (#3051) Signed-off-by: Keith Zantow --- .../pkg/cataloger/redhat/parse_rpm_archive.go | 39 ++++++++++++++----- 1 file changed, 30 insertions(+), 9 deletions(-) diff --git a/syft/pkg/cataloger/redhat/parse_rpm_archive.go b/syft/pkg/cataloger/redhat/parse_rpm_archive.go index 349db949294..8c4b395a76a 100644 --- a/syft/pkg/cataloger/redhat/parse_rpm_archive.go +++ b/syft/pkg/cataloger/redhat/parse_rpm_archive.go @@ -8,6 +8,7 @@ import ( rpmdb "github.com/knqyf263/go-rpmdb/pkg" "github.com/sassoftware/go-rpmutils" + "github.com/anchore/syft/internal/log" "github.com/anchore/syft/syft/artifact" "github.com/anchore/syft/syft/file" "github.com/anchore/syft/syft/pkg" @@ -26,12 +27,22 @@ func parseRpmArchive(_ context.Context, _ file.Resolver, _ *generic.Environment, return nil, nil, err } - licenses, _ := rpm.Header.GetStrings(rpmutils.LICENSE) - sourceRpm, _ := rpm.Header.GetString(rpmutils.SOURCERPM) - vendor, _ := rpm.Header.GetString(rpmutils.VENDOR) - digestAlgorithm := getDigestAlgorithm(rpm.Header) - size, _ := rpm.Header.InstalledSize() - files, _ := rpm.Header.GetFiles() + licenses, err := rpm.Header.GetStrings(rpmutils.LICENSE) + logRpmArchiveErr(reader.Location, "license", err) + + sourceRpm, err := rpm.Header.GetString(rpmutils.SOURCERPM) + logRpmArchiveErr(reader.Location, "sourcerpm", err) + + vendor, err := rpm.Header.GetString(rpmutils.VENDOR) + logRpmArchiveErr(reader.Location, "vendor", err) + + digestAlgorithm := getDigestAlgorithm(reader.Location, rpm.Header) + + size, err := rpm.Header.InstalledSize() + logRpmArchiveErr(reader.Location, "size", err) + + files, err := rpm.Header.GetFiles() + logRpmArchiveErr(reader.Location, "files", err) metadata := pkg.RpmArchive{ Name: nevra.Name, @@ -48,12 +59,16 @@ func parseRpmArchive(_ context.Context, _ file.Resolver, _ *generic.Environment, return []pkg.Package{newArchivePackage(reader.Location, metadata, licenses)}, nil, nil } -func getDigestAlgorithm(header *rpmutils.RpmHeader) string { - digestAlgorithm, _ := header.GetString(rpmutils.FILEDIGESTALGO) +func getDigestAlgorithm(location file.Location, header *rpmutils.RpmHeader) string { + digestAlgorithm, err := header.GetString(rpmutils.FILEDIGESTALGO) + logRpmArchiveErr(location, "file digest algo", err) + if digestAlgorithm != "" { return digestAlgorithm } - digestAlgorithms, _ := header.GetUint32s(rpmutils.FILEDIGESTALGO) + digestAlgorithms, err := header.GetUint32s(rpmutils.FILEDIGESTALGO) + logRpmArchiveErr(location, "file digest algo 32-bit", err) + if len(digestAlgorithms) > 0 { digestAlgo := int(digestAlgorithms[0]) return rpmutils.GetFileAlgoName(digestAlgo) @@ -91,3 +106,9 @@ func parseEpoch(epoch string) *int { } return &i } + +func logRpmArchiveErr(location file.Location, operation string, err error) { + if err != nil { + log.Debugf("ERROR in parse_rpm_archive %s file: %s: %v", operation, location.RealPath, err) + } +} From fe7c5a71740d8ddf0af14215447f8a7fe934b34f Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 22 Jul 2024 10:43:17 -0700 Subject: [PATCH 026/122] chore(deps): bump github.com/charmbracelet/lipgloss from 0.11.1 to 0.12.1 (#3040) * chore(deps): bump github.com/charmbracelet/lipgloss Bumps [github.com/charmbracelet/lipgloss](https://github.com/charmbracelet/lipgloss) from 0.11.1 to 0.12.1. - [Release notes](https://github.com/charmbracelet/lipgloss/releases) - [Changelog](https://github.com/charmbracelet/lipgloss/blob/master/.goreleaser.yml) - [Commits](https://github.com/charmbracelet/lipgloss/compare/v0.11.1...v0.12.1) --- updated-dependencies: - dependency-name: github.com/charmbracelet/lipgloss dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] * chore: pin fedora linux/amd64 to sha Signed-off-by: Christopher Phillips <32073428+spiffcs@users.noreply.github.com> --------- Signed-off-by: dependabot[bot] Signed-off-by: Christopher Phillips <32073428+spiffcs@users.noreply.github.com> Signed-off-by: Christopher Angelo Phillips <32073428+spiffcs@users.noreply.github.com> Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> Co-authored-by: Christopher Phillips <32073428+spiffcs@users.noreply.github.com> --- go.mod | 4 ++-- go.sum | 8 ++++---- .../binary/test-fixtures/image-fedora-64bit/Dockerfile | 1 + 3 files changed, 7 insertions(+), 6 deletions(-) diff --git a/go.mod b/go.mod index dcdc4d5a8b9..8f0a9cef69e 100644 --- a/go.mod +++ b/go.mod @@ -25,7 +25,7 @@ require ( github.com/bmatcuk/doublestar/v4 v4.6.1 github.com/charmbracelet/bubbles v0.18.0 github.com/charmbracelet/bubbletea v0.26.6 - github.com/charmbracelet/lipgloss v0.11.1 + github.com/charmbracelet/lipgloss v0.12.1 github.com/dave/jennifer v1.7.0 github.com/deitch/magic v0.0.0-20230404182410-1ff89d7342da github.com/distribution/reference v0.6.0 @@ -109,7 +109,7 @@ require ( github.com/aymanbagabas/go-osc52/v2 v2.0.1 // indirect github.com/becheran/wildmatch-go v1.0.0 // indirect github.com/charmbracelet/harmonica v0.2.0 // indirect - github.com/charmbracelet/x/ansi v0.1.3 // indirect + github.com/charmbracelet/x/ansi v0.1.4 // indirect github.com/charmbracelet/x/input v0.1.0 // indirect github.com/charmbracelet/x/term v0.1.1 // indirect github.com/charmbracelet/x/windows v0.1.0 // indirect diff --git a/go.sum b/go.sum index f023a58a69e..4eea6a29ef8 100644 --- a/go.sum +++ b/go.sum @@ -161,10 +161,10 @@ github.com/charmbracelet/bubbletea v0.26.6 h1:zTCWSuST+3yZYZnVSvbXwKOPRSNZceVeqp github.com/charmbracelet/bubbletea v0.26.6/go.mod h1:dz8CWPlfCCGLFbBlTY4N7bjLiyOGDJEnd2Muu7pOWhk= github.com/charmbracelet/harmonica v0.2.0 h1:8NxJWRWg/bzKqqEaaeFNipOu77YR5t8aSwG4pgaUBiQ= github.com/charmbracelet/harmonica v0.2.0/go.mod h1:KSri/1RMQOZLbw7AHqgcBycp8pgJnQMYYT8QZRqZ1Ao= -github.com/charmbracelet/lipgloss v0.11.1 h1:a8KgVPHa7kOoP95vm2tQQrjD2AKhbWmfr4uJ2RW6kNk= -github.com/charmbracelet/lipgloss v0.11.1/go.mod h1:beLlcmkF7MWA+5UrKKIRo/VJ21xGXr7YJ9miWfdMRIU= -github.com/charmbracelet/x/ansi v0.1.3 h1:RBh/eleNWML5R524mjUF0yVRePTwqN9tPtV+DPgO5Lw= -github.com/charmbracelet/x/ansi v0.1.3/go.mod h1:dk73KoMTT5AX5BsX0KrqhsTqAnhZZoCBjs7dGWp4Ktw= +github.com/charmbracelet/lipgloss v0.12.1 h1:/gmzszl+pedQpjCOH+wFkZr/N90Snz40J/NR7A0zQcs= +github.com/charmbracelet/lipgloss v0.12.1/go.mod h1:V2CiwIuhx9S1S1ZlADfOj9HmxeMAORuz5izHb0zGbB8= +github.com/charmbracelet/x/ansi v0.1.4 h1:IEU3D6+dWwPSgZ6HBH+v6oUuZ/nVawMiWj5831KfiLM= +github.com/charmbracelet/x/ansi v0.1.4/go.mod h1:dk73KoMTT5AX5BsX0KrqhsTqAnhZZoCBjs7dGWp4Ktw= github.com/charmbracelet/x/input v0.1.0 h1:TEsGSfZYQyOtp+STIjyBq6tpRaorH0qpwZUj8DavAhQ= github.com/charmbracelet/x/input v0.1.0/go.mod h1:ZZwaBxPF7IG8gWWzPUVqHEtWhc1+HXJPNuerJGRGZ28= github.com/charmbracelet/x/term v0.1.1 h1:3cosVAiPOig+EV4X9U+3LDgtwwAoEzJjNdwbXDjF6yI= diff --git a/syft/pkg/cataloger/binary/test-fixtures/image-fedora-64bit/Dockerfile b/syft/pkg/cataloger/binary/test-fixtures/image-fedora-64bit/Dockerfile index e1c508b854a..0d65e734110 100644 --- a/syft/pkg/cataloger/binary/test-fixtures/image-fedora-64bit/Dockerfile +++ b/syft/pkg/cataloger/binary/test-fixtures/image-fedora-64bit/Dockerfile @@ -1,5 +1,6 @@ FROM --platform=linux/amd64 fedora:41@sha256:c05bf79137835bf5c521c58f8252d6031780ae865a0379ab57f412e0ac6b42aa as build + FROM scratch COPY --from=build /bin/sha256sum /sha256sum COPY --from=build /bin/sha1sum /sha1sum From ca945d16e0949a41aa8786f55d21908242b224c8 Mon Sep 17 00:00:00 2001 From: "anchore-actions-token-generator[bot]" <102182147+anchore-actions-token-generator[bot]@users.noreply.github.com> Date: Tue, 23 Jul 2024 10:16:25 -0400 Subject: [PATCH 027/122] chore(deps): update tools to latest versions (#3061) Signed-off-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com> Co-authored-by: spiffcs <32073428+spiffcs@users.noreply.github.com> --- .binny.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.binny.yaml b/.binny.yaml index 0a1dafff55f..c5f5aeb436a 100644 --- a/.binny.yaml +++ b/.binny.yaml @@ -42,7 +42,7 @@ tools: # used for signing the checksums file at release - name: cosign version: - want: v2.2.4 + want: v2.3.0 method: github-release with: repo: sigstore/cosign From 9573f557d12756f8c873b98a6af476835f611055 Mon Sep 17 00:00:00 2001 From: Alex Goodman Date: Wed, 24 Jul 2024 09:34:40 -0400 Subject: [PATCH 028/122] better go mod detection from partial package builds (#3060) Signed-off-by: Alex Goodman --- syft/pkg/cataloger/golang/parse_go_binary.go | 54 +++++++++-- .../cataloger/golang/parse_go_binary_test.go | 97 ++++++++++++++++++- syft/pkg/cataloger/golang/scan_binary.go | 2 +- 3 files changed, 141 insertions(+), 12 deletions(-) diff --git a/syft/pkg/cataloger/golang/parse_go_binary.go b/syft/pkg/cataloger/golang/parse_go_binary.go index 88600355cc7..4b496283029 100644 --- a/syft/pkg/cataloger/golang/parse_go_binary.go +++ b/syft/pkg/cataloger/golang/parse_go_binary.go @@ -11,6 +11,7 @@ import ( "io" "regexp" "runtime/debug" + "slices" "strings" "time" @@ -97,17 +98,19 @@ func createModuleRelationships(main pkg.Package, deps []pkg.Package) []artifact. return relationships } +var emptyModule debug.Module +var moduleFromPartialPackageBuild = debug.Module{Path: "command-line-arguments"} + func (c *goBinaryCataloger) buildGoPkgInfo(resolver file.Resolver, location file.Location, mod *extendedBuildInfo, arch string, reader io.ReadSeekCloser) (*pkg.Package, []pkg.Package) { - var pkgs []pkg.Package if mod == nil { - return nil, pkgs + return nil, nil } - var empty debug.Module - if mod.Main == empty && mod.Path != "" { - mod.Main = createMainModuleFromPath(mod.Path) + if missingMainModule(mod) { + mod.Main = createMainModuleFromPath(mod) } + var pkgs []pkg.Package for _, dep := range mod.Deps { if dep == nil { continue @@ -130,7 +133,7 @@ func (c *goBinaryCataloger) buildGoPkgInfo(resolver file.Resolver, location file } } - if mod.Main == empty { + if mod.Main == emptyModule { return nil, pkgs } @@ -139,6 +142,16 @@ func (c *goBinaryCataloger) buildGoPkgInfo(resolver file.Resolver, location file return &main, pkgs } +func missingMainModule(mod *extendedBuildInfo) bool { + if mod.Main == emptyModule && mod.Path != "" { + return true + } + // special case: when invoking go build with a source file and not a package (directory) then you will + // see "command-line-arguments" as the main module path... even though that's not the main module. In this + // circumstance, we should treat the main module as missing and search for it within the dependencies. + return mod.Main == moduleFromPartialPackageBuild +} + func (c *goBinaryCataloger) makeGoMainPackage(resolver file.Resolver, mod *extendedBuildInfo, arch string, location file.Location, reader io.ReadSeekCloser) pkg.Package { gbs := getBuildSettings(mod.Settings) gover, experiments := getExperimentsFromVersion(mod.GoVersion) @@ -358,8 +371,29 @@ func getExperimentsFromVersion(version string) (string, []string) { return version, experiments } -func createMainModuleFromPath(path string) (mod debug.Module) { - mod.Path = path - mod.Version = devel - return +func createMainModuleFromPath(existing *extendedBuildInfo) debug.Module { + // search for a main module candidate within the dependencies + var mainModuleCandidates []debug.Module + var usedIndex int + for i, dep := range existing.Deps { + if dep == nil { + continue + } + + if dep.Version == devel { + usedIndex = i + mainModuleCandidates = append(mainModuleCandidates, *dep) + } + } + if len(mainModuleCandidates) == 1 { + // we need to prune the dependency from module list + existing.Deps = slices.Delete(existing.Deps, usedIndex, usedIndex+1) + return mainModuleCandidates[0] + } + + // otherwise craft a main module from the path (a bit of a cop out, but allows us to have a main module) + return debug.Module{ + Path: existing.Path, + Version: devel, + } } diff --git a/syft/pkg/cataloger/golang/parse_go_binary_test.go b/syft/pkg/cataloger/golang/parse_go_binary_test.go index 0346324fedc..8b88b9e12c9 100644 --- a/syft/pkg/cataloger/golang/parse_go_binary_test.go +++ b/syft/pkg/cataloger/golang/parse_go_binary_test.go @@ -210,7 +210,7 @@ func TestBuildGoPkgInfo(t *testing.T) { }, { name: "buildGoPkgInfo parses a blank mod and returns no packages", - mod: &extendedBuildInfo{&debug.BuildInfo{}, nil, ""}, + mod: &extendedBuildInfo{BuildInfo: &debug.BuildInfo{}, cryptoSettings: nil, arch: ""}, expected: []pkg.Package(nil), }, { @@ -946,6 +946,95 @@ func TestBuildGoPkgInfo(t *testing.T) { }, }}, }, + { + name: "parse a mod from path (partial build of package)", + mod: &extendedBuildInfo{ + BuildInfo: &debug.BuildInfo{ + GoVersion: "go1.22.2", + Main: debug.Module{Path: "command-line-arguments"}, + Settings: []debug.BuildSetting{ + { + Key: "-ldflags", + Value: `build -ldflags="-w -s -X github.com/kuskoman/logstash-exporter/config.Version=v1.7.0 -X github.com/kuskoman/logstash-exporter/config.GitCommit=db696dbcfe5a91d288d5ad44ce8ccbea97e65978 -X github.com/kuskoman/logstash-exporter/config.BuildDate=2024-07-17T08:12:17Z"`, + }, + {Key: "GOARCH", Value: archDetails}, + {Key: "GOOS", Value: "darwin"}, + {Key: "GOAMD64", Value: "v1"}, + }, + Deps: []*debug.Module{ + { + Path: "github.com/kuskoman/something-else", + Version: "v1.2.3", + }, + { + Path: "github.com/kuskoman/logstash-exporter", + Version: "(devel)", + }, + }, + }, + arch: archDetails, + }, + expected: []pkg.Package{ + { + Name: "github.com/kuskoman/something-else", + Language: pkg.Go, + Type: pkg.GoModulePkg, + Version: "v1.2.3", + PURL: "pkg:golang/github.com/kuskoman/something-else@v1.2.3", + Locations: file.NewLocationSet( + file.NewLocationFromCoordinates( + file.Coordinates{ + RealPath: "/a-path", + FileSystemID: "layer-id", + }, + ).WithAnnotation(pkg.EvidenceAnnotationKey, pkg.PrimaryEvidenceAnnotation), + ), + Metadata: pkg.GolangBinaryBuildinfoEntry{ + GoCompiledVersion: "go1.22.2", + Architecture: archDetails, + MainModule: "github.com/kuskoman/logstash-exporter", // correctly attached the main module + }, + }, + { + Name: "github.com/kuskoman/logstash-exporter", + Language: pkg.Go, + Type: pkg.GoModulePkg, + Version: "v1.7.0", + PURL: "pkg:golang/github.com/kuskoman/logstash-exporter@v1.7.0", + Locations: file.NewLocationSet( + file.NewLocationFromCoordinates( + file.Coordinates{ + RealPath: "/a-path", + FileSystemID: "layer-id", + }, + ).WithAnnotation(pkg.EvidenceAnnotationKey, pkg.PrimaryEvidenceAnnotation), + ), + Metadata: pkg.GolangBinaryBuildinfoEntry{ + GoCompiledVersion: "go1.22.2", + BuildSettings: []pkg.KeyValue{ + { + Key: "-ldflags", + Value: `build -ldflags="-w -s -X github.com/kuskoman/logstash-exporter/config.Version=v1.7.0 -X github.com/kuskoman/logstash-exporter/config.GitCommit=db696dbcfe5a91d288d5ad44ce8ccbea97e65978 -X github.com/kuskoman/logstash-exporter/config.BuildDate=2024-07-17T08:12:17Z"`, + }, + { + Key: "GOARCH", + Value: "amd64", + }, + { + Key: "GOOS", + Value: "darwin", + }, + { + Key: "GOAMD64", + Value: "v1", + }, + }, + Architecture: archDetails, + MainModule: "github.com/kuskoman/logstash-exporter", + }, + }, + }, + }, } for _, test := range tests { @@ -1092,6 +1181,12 @@ func Test_extractVersionFromLDFlags(t *testing.T) { wantMajorVersion: "6", wantFullVersion: "v6.1.7", }, + { + name: "logstash-exporter", + ldflags: `build -ldflags="-w -s -X github.com/kuskoman/logstash-exporter/config.Version=v1.7.0 -X github.com/kuskoman/logstash-exporter/config.GitCommit=db696dbcfe5a91d288d5ad44ce8ccbea97e65978 -X github.com/kuskoman/logstash-exporter/config.BuildDate=2024-07-17T08:12:17Z"`, + wantMajorVersion: "1", + wantFullVersion: "v1.7.0", + }, ////////////////////////////////////////////////////////////////// // negative cases { diff --git a/syft/pkg/cataloger/golang/scan_binary.go b/syft/pkg/cataloger/golang/scan_binary.go index 846e34a11b4..720008045a8 100644 --- a/syft/pkg/cataloger/golang/scan_binary.go +++ b/syft/pkg/cataloger/golang/scan_binary.go @@ -56,7 +56,7 @@ func scanFile(reader unionreader.UnionReader, filename string) []*extendedBuildI } } - builds = append(builds, &extendedBuildInfo{bi, v, arch}) + builds = append(builds, &extendedBuildInfo{BuildInfo: bi, cryptoSettings: v, arch: arch}) } return builds } From 741c8fb9bd0cbe1f8b7cf8fdd59709641d21fedd Mon Sep 17 00:00:00 2001 From: Keith Zantow Date: Wed, 24 Jul 2024 10:14:20 -0400 Subject: [PATCH 029/122] fix: SPDX output performance with many relationships (#3053) --- .../package_binary_elf_relationships_test.go | 4 +- .../binary/binary_dependencies.go | 35 +- .../binary/binary_dependencies_test.go | 16 +- internal/relationship/index.go | 193 ++++++--- internal/relationship/index_test.go | 404 +++++++++--------- .../common/spdxhelpers/to_format_model.go | 20 +- .../spdxhelpers/to_format_model_test.go | 3 +- syft/pkg/cataloger/python/dependency.go | 8 +- syft/sbom/sbom.go | 4 + 9 files changed, 403 insertions(+), 284 deletions(-) diff --git a/cmd/syft/internal/test/integration/package_binary_elf_relationships_test.go b/cmd/syft/internal/test/integration/package_binary_elf_relationships_test.go index 354c7fba8ef..a76a30e1e5d 100644 --- a/cmd/syft/internal/test/integration/package_binary_elf_relationships_test.go +++ b/cmd/syft/internal/test/integration/package_binary_elf_relationships_test.go @@ -5,6 +5,7 @@ import ( "github.com/stretchr/testify/require" + "github.com/anchore/syft/internal/relationship" "github.com/anchore/syft/syft/artifact" "github.com/anchore/syft/syft/source" ) @@ -44,12 +45,13 @@ func TestBinaryElfRelationships(t *testing.T) { } } + relationshipIndex := relationship.NewIndex(sbom.Relationships...) for name, expectedDepNames := range expectedGraph { pkgId := nameToId[name] p := sbom.Artifacts.Packages.Package(pkgId) require.NotNil(t, p, "expected package %q to be present in the SBOM", name) - rels := sbom.RelationshipsForPackage(*p, artifact.DependencyOfRelationship) + rels := relationshipIndex.References(*p, artifact.DependencyOfRelationship) require.NotEmpty(t, rels, "expected package %q to have relationships", name) toIds := map[artifact.ID]struct{}{} diff --git a/internal/relationship/binary/binary_dependencies.go b/internal/relationship/binary/binary_dependencies.go index e30b64282e6..b23b42b9a42 100644 --- a/internal/relationship/binary/binary_dependencies.go +++ b/internal/relationship/binary/binary_dependencies.go @@ -21,27 +21,22 @@ func NewDependencyRelationships(resolver file.Resolver, accessor sbomsync.Access // 3. craft package-to-package relationships for each binary that represent shared library dependencies //note: we only care about package-to-package relationships - var relIndex *relationship.Index - accessor.ReadFromSBOM(func(s *sbom.SBOM) { - relIndex = relationship.NewIndex(s.Relationships...) - }) - - return generateRelationships(resolver, accessor, index, relIndex) + return generateRelationships(resolver, accessor, index) } -func generateRelationships(resolver file.Resolver, accessor sbomsync.Accessor, index *sharedLibraryIndex, relIndex *relationship.Index) []artifact.Relationship { - // read all existing dependencyOf relationships +func generateRelationships(resolver file.Resolver, accessor sbomsync.Accessor, index *sharedLibraryIndex) []artifact.Relationship { + newRelationships := relationship.NewIndex() + + // find all package-to-package relationships for shared library dependencies accessor.ReadFromSBOM(func(s *sbom.SBOM) { - for _, r := range s.Relationships { - if r.Type != artifact.DependencyOfRelationship { - continue + relIndex := relationship.NewIndex(s.Relationships...) + + addRelationship := func(r artifact.Relationship) { + if !relIndex.Contains(r) { + newRelationships.Add(r) } - relIndex.Track(r) } - }) - // find all package-to-package relationships for shared library dependencies - accessor.ReadFromSBOM(func(s *sbom.SBOM) { for _, parentPkg := range s.Artifacts.Packages.Sorted(pkg.BinaryPkg) { for _, evidentLocation := range parentPkg.Locations.ToSlice() { if evidentLocation.Annotations[pkg.EvidenceAnnotationKey] != pkg.PrimaryEvidenceAnnotation { @@ -54,12 +49,12 @@ func generateRelationships(resolver file.Resolver, accessor sbomsync.Accessor, i continue } - populateRelationships(exec, parentPkg, resolver, relIndex, index) + populateRelationships(exec, parentPkg, resolver, addRelationship, index) } } }) - return relIndex.NewRelationships() + return newRelationships.All() } // PackagesToRemove returns a list of binary packages (resolved by the ELF cataloger) that should be removed from the SBOM @@ -147,7 +142,7 @@ func getBinaryPackagesToDelete(resolver file.Resolver, s *sbom.SBOM) []artifact. return pkgsToDelete } -func populateRelationships(exec file.Executable, parentPkg pkg.Package, resolver file.Resolver, relIndex *relationship.Index, index *sharedLibraryIndex) { +func populateRelationships(exec file.Executable, parentPkg pkg.Package, resolver file.Resolver, addRelationship func(artifact.Relationship), index *sharedLibraryIndex) { for _, libReference := range exec.ImportedLibraries { // for each library reference, check s.Artifacts.Packages.Sorted(pkg.BinaryPkg) for a binary package that represents that library // if found, create a relationship between the parent package and the library package @@ -167,7 +162,7 @@ func populateRelationships(exec file.Executable, parentPkg pkg.Package, resolver realBaseName := path.Base(loc.RealPath) pkgCollection := index.owningLibraryPackage(realBaseName) if pkgCollection.PackageCount() < 1 { - relIndex.Add( + addRelationship( artifact.Relationship{ From: loc.Coordinates, To: parentPkg, @@ -176,7 +171,7 @@ func populateRelationships(exec file.Executable, parentPkg pkg.Package, resolver ) } for _, p := range pkgCollection.Sorted() { - relIndex.Add( + addRelationship( artifact.Relationship{ From: p, To: parentPkg, diff --git a/internal/relationship/binary/binary_dependencies_test.go b/internal/relationship/binary/binary_dependencies_test.go index 8696b82b476..33c6436c351 100644 --- a/internal/relationship/binary/binary_dependencies_test.go +++ b/internal/relationship/binary/binary_dependencies_test.go @@ -2,6 +2,7 @@ package binary import ( "path" + "strings" "testing" "github.com/google/go-cmp/cmp" @@ -328,7 +329,20 @@ func relationshipComparer(x, y []artifact.Relationship) string { artifact.Relationship{}, file.LocationSet{}, pkg.LicenseSet{}, - )) + ), cmpopts.SortSlices(lessRelationships)) +} + +func lessRelationships(r1, r2 artifact.Relationship) bool { + c := strings.Compare(string(r1.Type), string(r2.Type)) + if c != 0 { + return c < 0 + } + c = strings.Compare(string(r1.From.ID()), string(r2.From.ID())) + if c != 0 { + return c < 0 + } + c = strings.Compare(string(r1.To.ID()), string(r2.To.ID())) + return c < 0 } func newAccessor(pkgs []pkg.Package, coordinateIndex map[file.Coordinates]file.Executable, preexistingRelationships []artifact.Relationship) sbomsync.Accessor { diff --git a/internal/relationship/index.go b/internal/relationship/index.go index e992116065b..a94c84f8537 100644 --- a/internal/relationship/index.go +++ b/internal/relationship/index.go @@ -1,88 +1,181 @@ package relationship import ( - "github.com/scylladb/go-set/strset" + "slices" + "strings" "github.com/anchore/syft/syft/artifact" + "github.com/anchore/syft/syft/file" ) +// Index indexes relationships, preventing duplicates type Index struct { - typesByFromTo map[artifact.ID]map[artifact.ID]*strset.Set - existing []artifact.Relationship - additional []artifact.Relationship + all []*sortableRelationship + fromID map[artifact.ID]*mappedRelationships + toID map[artifact.ID]*mappedRelationships } -func NewIndex(existing ...artifact.Relationship) *Index { - r := &Index{ - typesByFromTo: make(map[artifact.ID]map[artifact.ID]*strset.Set), - } - r.TrackAll(existing...) - return r +// NewIndex returns a new relationship Index +func NewIndex(relationships ...artifact.Relationship) *Index { + out := Index{} + out.Add(relationships...) + return &out } -func (i *Index) track(r artifact.Relationship) bool { - fromID := r.From.ID() - if _, ok := i.typesByFromTo[fromID]; !ok { - i.typesByFromTo[fromID] = make(map[artifact.ID]*strset.Set) +// Add adds all the given relationships to the index, without adding duplicates +func (i *Index) Add(relationships ...artifact.Relationship) { + if i.fromID == nil { + i.fromID = map[artifact.ID]*mappedRelationships{} } - - toID := r.To.ID() - if _, ok := i.typesByFromTo[fromID][toID]; !ok { - i.typesByFromTo[fromID][toID] = strset.New() + if i.toID == nil { + i.toID = map[artifact.ID]*mappedRelationships{} } - var exists bool - if i.typesByFromTo[fromID][toID].Has(string(r.Type)) { - exists = true + // store appropriate indexes for stable ordering to minimize ID() calls + for _, r := range relationships { + // prevent duplicates + if i.Contains(r) { + continue + } + + fromID := r.From.ID() + toID := r.To.ID() + + relationship := &sortableRelationship{ + from: fromID, + to: toID, + relationship: r, + } + + // add to all relationships + i.all = append(i.all, relationship) + + // add from -> to mapping + mapped := i.fromID[fromID] + if mapped == nil { + mapped = &mappedRelationships{} + i.fromID[fromID] = mapped + } + mapped.add(toID, relationship) + + // add to -> from mapping + mapped = i.toID[toID] + if mapped == nil { + mapped = &mappedRelationships{} + i.toID[toID] = mapped + } + mapped.add(fromID, relationship) } +} - i.typesByFromTo[fromID][toID].Add(string(r.Type)) +// From returns all relationships from the given identifiable, with specified types +func (i *Index) From(identifiable artifact.Identifiable, types ...artifact.RelationshipType) []artifact.Relationship { + return toSortedSlice(fromMapped(i.fromID, identifiable), types) +} + +// To returns all relationships to the given identifiable, with specified types +func (i *Index) To(identifiable artifact.Identifiable, types ...artifact.RelationshipType) []artifact.Relationship { + return toSortedSlice(fromMapped(i.toID, identifiable), types) +} - return !exists +// References returns all relationships that reference to or from the given identifiable +func (i *Index) References(identifiable artifact.Identifiable, types ...artifact.RelationshipType) []artifact.Relationship { + return toSortedSlice(append(fromMapped(i.fromID, identifiable), fromMapped(i.toID, identifiable)...), types) } -// Track this relationship as "exists" in the index (this is used to prevent duplicate relationships from being added). -// returns true if the relationship is new to the index, false otherwise. -func (i *Index) Track(r artifact.Relationship) bool { - unique := i.track(r) - if unique { - i.existing = append(i.existing, r) +// Coordinates returns all coordinates for the provided identifiable for provided relationship types +// If no types are provided, all relationship types are considered. +func (i *Index) Coordinates(identifiable artifact.Identifiable, types ...artifact.RelationshipType) []file.Coordinates { + var coordinates []file.Coordinates + for _, relationship := range i.References(identifiable, types...) { + cords := extractCoordinates(relationship) + coordinates = append(coordinates, cords...) } - return unique + return coordinates } -// Add a new relationship to the index, returning true if the relationship is new to the index, false otherwise (thus is a duplicate). -func (i *Index) Add(r artifact.Relationship) bool { - if i.track(r) { - i.additional = append(i.additional, r) - return true +// Contains indicates the relationship is present in this index +func (i *Index) Contains(r artifact.Relationship) bool { + if mapped := i.fromID[r.From.ID()]; mapped != nil { + if ids := mapped.typeMap[r.Type]; ids != nil { + return ids[r.To.ID()] != nil + } } return false } -func (i *Index) TrackAll(rs ...artifact.Relationship) { - for _, r := range rs { - i.Track(r) +// All returns a sorted set of relationships matching all types, or all relationships if no types specified +func (i *Index) All(types ...artifact.RelationshipType) []artifact.Relationship { + return toSortedSlice(i.all, types) +} + +func fromMapped(idMap map[artifact.ID]*mappedRelationships, identifiable artifact.Identifiable) []*sortableRelationship { + if identifiable == nil || idMap == nil { + return nil + } + mapped := idMap[identifiable.ID()] + if mapped == nil { + return nil } + return mapped.allRelated } -func (i *Index) AddAll(rs ...artifact.Relationship) { - for _, r := range rs { - i.Add(r) +func toSortedSlice(relationships []*sortableRelationship, types []artifact.RelationshipType) []artifact.Relationship { + // always return sorted for SBOM stability + slices.SortFunc(relationships, sortFunc) + var out []artifact.Relationship + for _, r := range relationships { + if len(types) == 0 || slices.Contains(types, r.relationship.Type) { + out = append(out, r.relationship) + } } + return out } -func (i *Index) NewRelationships() []artifact.Relationship { - return i.additional +func extractCoordinates(relationship artifact.Relationship) (results []file.Coordinates) { + if coordinates, exists := relationship.From.(file.Coordinates); exists { + results = append(results, coordinates) + } + + if coordinates, exists := relationship.To.(file.Coordinates); exists { + results = append(results, coordinates) + } + + return results +} + +type mappedRelationships struct { + typeMap map[artifact.RelationshipType]map[artifact.ID]*sortableRelationship + allRelated []*sortableRelationship +} + +func (m *mappedRelationships) add(id artifact.ID, newRelationship *sortableRelationship) { + m.allRelated = append(m.allRelated, newRelationship) + if m.typeMap == nil { + m.typeMap = map[artifact.RelationshipType]map[artifact.ID]*sortableRelationship{} + } + typeMap := m.typeMap[newRelationship.relationship.Type] + if typeMap == nil { + typeMap = map[artifact.ID]*sortableRelationship{} + m.typeMap[newRelationship.relationship.Type] = typeMap + } + typeMap[id] = newRelationship } -func (i *Index) ExistingRelationships() []artifact.Relationship { - return i.existing +type sortableRelationship struct { + from artifact.ID + to artifact.ID + relationship artifact.Relationship } -func (i *Index) AllUniqueRelationships() []artifact.Relationship { - var all []artifact.Relationship - all = append(all, i.existing...) - all = append(all, i.additional...) - return all +func sortFunc(a, b *sortableRelationship) int { + cmp := strings.Compare(string(a.relationship.Type), string(b.relationship.Type)) + if cmp != 0 { + return cmp + } + cmp = strings.Compare(string(a.from), string(b.from)) + if cmp != 0 { + return cmp + } + return strings.Compare(string(a.to), string(b.to)) } diff --git a/internal/relationship/index_test.go b/internal/relationship/index_test.go index b1acbc21463..1f4e66c27af 100644 --- a/internal/relationship/index_test.go +++ b/internal/relationship/index_test.go @@ -3,223 +3,231 @@ package relationship import ( "testing" - "github.com/google/go-cmp/cmp" + "github.com/stretchr/testify/require" "github.com/anchore/syft/syft/artifact" + "github.com/anchore/syft/syft/file" + "github.com/anchore/syft/syft/pkg" ) -func Test_newRelationshipIndex(t *testing.T) { - from := fakeIdentifiable{id: "from"} - to := fakeIdentifiable{id: "to"} - tests := []struct { - name string - given []artifact.Relationship - track []artifact.Relationship - add []artifact.Relationship - wantExisting []string - wantAdditional []string - }{ - { - name: "empty", - }, - { - name: "tracks existing relationships", - given: []artifact.Relationship{ - { - From: from, - To: to, - Type: artifact.EvidentByRelationship, - }, - }, - wantExisting: []string{"from [evident-by] to"}, - }, - { - name: "deduplicate tracked relationships", - given: []artifact.Relationship{ - { - From: from, - To: to, - Type: artifact.EvidentByRelationship, - }, - { - From: from, - To: to, - Type: artifact.EvidentByRelationship, - }, - { - From: from, - To: to, - Type: artifact.EvidentByRelationship, - }, - }, - track: []artifact.Relationship{ - { - From: from, - To: to, - Type: artifact.EvidentByRelationship, - }, - { - From: from, - To: to, - Type: artifact.EvidentByRelationship, - }, - }, - wantExisting: []string{"from [evident-by] to"}, - }, - { - name: "deduplicate any input relationships", - given: []artifact.Relationship{ - { - From: from, - To: to, - Type: artifact.EvidentByRelationship, - }, - { - From: from, - To: to, - Type: artifact.EvidentByRelationship, - }, - }, - track: []artifact.Relationship{ - { - From: from, - To: to, - Type: artifact.EvidentByRelationship, - }, - { - From: from, - To: to, - Type: artifact.EvidentByRelationship, - }, - }, - add: []artifact.Relationship{ - { - From: from, - To: to, - Type: artifact.EvidentByRelationship, - }, - { - From: from, - To: to, - Type: artifact.EvidentByRelationship, - }, - }, - wantExisting: []string{"from [evident-by] to"}, - }, - { - name: "deduplicate any added relationships", - add: []artifact.Relationship{ - { - From: from, - To: to, - Type: artifact.EvidentByRelationship, - }, - { - From: from, - To: to, - Type: artifact.EvidentByRelationship, - }, - }, - wantAdditional: []string{"from [evident-by] to"}, - }, - } - for _, tt := range tests { - t.Run(tt.name, func(t *testing.T) { - idx := NewIndex(tt.given...) - idx.TrackAll(tt.track...) - idx.AddAll(tt.add...) - diffRelationships(t, tt.wantExisting, idx.existing) - diffRelationships(t, tt.wantAdditional, idx.additional) - }) +func Test_Index(t *testing.T) { + p1 := pkg.Package{ + Name: "pkg-1", + } + p2 := pkg.Package{ + Name: "pkg-2", + } + p3 := pkg.Package{ + Name: "pkg-3", + } + c1 := file.Coordinates{ + RealPath: "/coords/1", + } + c2 := file.Coordinates{ + RealPath: "/coords/2", } -} -func diffRelationships(t *testing.T, expected []string, actual []artifact.Relationship) { - if d := cmp.Diff(expected, stringRelationships(actual)); d != "" { - t.Errorf("unexpected relationships (-want, +got): %s", d) + for _, p := range []*pkg.Package{&p1, &p2, &p3} { + p.SetID() + } + + r1 := artifact.Relationship{ + From: p1, + To: p2, + Type: artifact.DependencyOfRelationship, + } + r2 := artifact.Relationship{ + From: p1, + To: p3, + Type: artifact.DependencyOfRelationship, + } + r3 := artifact.Relationship{ + From: p1, + To: c1, + Type: artifact.ContainsRelationship, + } + r4 := artifact.Relationship{ + From: p2, + To: c2, + Type: artifact.ContainsRelationship, + } + r5 := artifact.Relationship{ + From: p3, + To: c2, + Type: artifact.ContainsRelationship, } -} -func stringRelationships(relationships []artifact.Relationship) []string { - var result []string - for _, r := range relationships { - result = append(result, string(r.From.ID())+" ["+string(r.Type)+"] "+string(r.To.ID())) + dup := artifact.Relationship{ + From: p3, + To: c2, + Type: artifact.ContainsRelationship, } - return result + idx := NewIndex(r1, r2, r3, r4, r5, dup) + require.ElementsMatch(t, slice(r1, r2, r3, r4, r5), idx.All()) + + require.ElementsMatch(t, slice(r1, r4), idx.References(p2)) + require.ElementsMatch(t, slice(r4), idx.References(p2, artifact.ContainsRelationship)) + + require.ElementsMatch(t, slice(r1), idx.To(p2)) + require.ElementsMatch(t, []artifact.Relationship(nil), idx.To(p2, artifact.ContainsRelationship)) + + require.ElementsMatch(t, slice(r4), idx.From(p2)) + require.ElementsMatch(t, slice(r4), idx.From(p2, artifact.ContainsRelationship)) } -func Test_relationshipIndex_track(t *testing.T) { - from := fakeIdentifiable{id: "from"} - to := fakeIdentifiable{id: "to"} - relationship := artifact.Relationship{From: from, To: to, Type: artifact.EvidentByRelationship} - tests := []struct { - name string - existing []artifact.Relationship - given artifact.Relationship - want bool - }{ - { - name: "track returns true for a new relationship", - existing: []artifact.Relationship{}, - given: relationship, - want: true, - }, - { - name: "track returns false for an existing relationship", - existing: []artifact.Relationship{relationship}, - given: relationship, - want: false, - }, - } - for _, tt := range tests { - t.Run(tt.name, func(t *testing.T) { - i := NewIndex(tt.existing...) - if got := i.Track(tt.given); got != tt.want { - t.Errorf("track() = %v, want %v", got, tt.want) - } - }) +func Test_sortOrder(t *testing.T) { + r1 := artifact.Relationship{ + From: id("1"), + To: id("2"), + Type: "1", + } + r2 := artifact.Relationship{ + From: id("2"), + To: id("3"), + Type: "1", + } + r3 := artifact.Relationship{ + From: id("3"), + To: id("4"), + Type: "1", + } + r4 := artifact.Relationship{ + From: id("1"), + To: id("2"), + Type: "2", + } + r5 := artifact.Relationship{ + From: id("2"), + To: id("3"), + Type: "2", + } + dup := artifact.Relationship{ + From: id("2"), + To: id("3"), + Type: "2", + } + r6 := artifact.Relationship{ + From: id("2"), + To: id("3"), + Type: "3", } + + idx := NewIndex(r5, r2, r6, r4, r1, r3, dup) + require.EqualValues(t, slice(r1, r2, r3, r4, r5, r6), idx.All()) + + require.EqualValues(t, slice(r1, r4), idx.From(id("1"))) + + require.EqualValues(t, slice(r2, r5, r6), idx.To(id("3"))) + + rLast := artifact.Relationship{ + From: id("0"), + To: id("3"), + Type: "9999", + } + + rFirst := artifact.Relationship{ + From: id("0"), + To: id("3"), + Type: "1", + } + + rMid := artifact.Relationship{ + From: id("0"), + To: id("1"), + Type: "2", + } + + idx.Add(rLast, rFirst, rMid) + + require.EqualValues(t, slice(rFirst, r1, r2, r3, rMid, r4, r5, r6, rLast), idx.All()) + + require.EqualValues(t, slice(rFirst, r2, r5, r6, rLast), idx.To(id("3"))) } -func Test_relationshipIndex_add(t *testing.T) { - from := fakeIdentifiable{id: "from"} - to := fakeIdentifiable{id: "to"} - relationship := artifact.Relationship{From: from, To: to, Type: artifact.EvidentByRelationship} - tests := []struct { - name string - existing []artifact.Relationship - given artifact.Relationship - want bool - }{ - { - name: "add returns true for a new relationship", - existing: []artifact.Relationship{}, - given: relationship, - want: true, - }, - { - name: "add returns false for an existing relationship", - existing: []artifact.Relationship{relationship}, - given: relationship, - want: false, - }, - } - for _, tt := range tests { - t.Run(tt.name, func(t *testing.T) { - i := NewIndex(tt.existing...) - if got := i.Add(tt.given); got != tt.want { - t.Errorf("add() = %v, want %v", got, tt.want) - } - }) +func Test_Coordinates(t *testing.T) { + p1 := pkg.Package{ + Name: "pkg-1", + } + p2 := pkg.Package{ + Name: "pkg-2", + } + p3 := pkg.Package{ + Name: "pkg-3", + } + c1 := file.Coordinates{ + RealPath: "/coords/1", + } + c2 := file.Coordinates{ + RealPath: "/coords/2", + } + c3 := file.Coordinates{ + RealPath: "/coords/3", + } + c4 := file.Coordinates{ + RealPath: "/coords/4", + } + + for _, p := range []*pkg.Package{&p1, &p2, &p3} { + p.SetID() } + r1 := artifact.Relationship{ + From: p1, + To: p2, + Type: artifact.DependencyOfRelationship, + } + r2 := artifact.Relationship{ + From: p1, + To: p3, + Type: artifact.DependencyOfRelationship, + } + r3 := artifact.Relationship{ + From: p1, + To: c1, + Type: artifact.ContainsRelationship, + } + r4 := artifact.Relationship{ + From: p2, + To: c2, + Type: artifact.ContainsRelationship, + } + r5 := artifact.Relationship{ + From: p3, + To: c1, + Type: artifact.ContainsRelationship, + } + r6 := artifact.Relationship{ + From: p3, + To: c2, + Type: artifact.ContainsRelationship, + } + r7 := artifact.Relationship{ + From: c1, + To: c3, + Type: artifact.ContainsRelationship, + } + r8 := artifact.Relationship{ + From: c3, + To: c4, + Type: artifact.ContainsRelationship, + } + + idx := NewIndex(r1, r2, r3, r4, r5, r6, r7, r8) + + got := idx.Coordinates(p1) + require.ElementsMatch(t, slice(c1), got) + + got = idx.Coordinates(p3) + require.ElementsMatch(t, slice(c1, c2), got) } -type fakeIdentifiable struct { - id string +type id string + +func (i id) ID() artifact.ID { + return artifact.ID(i) } -func (f fakeIdentifiable) ID() artifact.ID { - return artifact.ID(f.id) +func slice[T any](values ...T) []T { + return values } diff --git a/syft/format/common/spdxhelpers/to_format_model.go b/syft/format/common/spdxhelpers/to_format_model.go index 767ffdcbe62..3fd136e84df 100644 --- a/syft/format/common/spdxhelpers/to_format_model.go +++ b/syft/format/common/spdxhelpers/to_format_model.go @@ -16,6 +16,7 @@ import ( "github.com/anchore/packageurl-go" "github.com/anchore/syft/internal/log" "github.com/anchore/syft/internal/mimetype" + "github.com/anchore/syft/internal/relationship" "github.com/anchore/syft/internal/spdxlicense" "github.com/anchore/syft/syft/artifact" "github.com/anchore/syft/syft/file" @@ -45,9 +46,10 @@ const ( func ToFormatModel(s sbom.SBOM) *spdx.Document { name, namespace := helpers.DocumentNameAndNamespace(s.Source, s.Descriptor) - packages := toPackages(s.Artifacts.Packages, s) + rels := relationship.NewIndex(s.Relationships...) + packages := toPackages(rels, s.Artifacts.Packages, s) - relationships := toRelationships(s.RelationshipsSorted()) + allRelationships := toRelationships(rels.All()) // for valid SPDX we need a document describes relationship describesID := spdx.ElementID("DOCUMENT") @@ -57,7 +59,7 @@ func ToFormatModel(s sbom.SBOM) *spdx.Document { describesID = rootPackage.PackageSPDXIdentifier // add all relationships from the document root to all other packages - relationships = append(relationships, toRootRelationships(rootPackage, packages)...) + allRelationships = append(allRelationships, toRootRelationships(rootPackage, packages)...) // append the root package packages = append(packages, rootPackage) @@ -75,7 +77,7 @@ func ToFormatModel(s sbom.SBOM) *spdx.Document { } // add the root document relationship - relationships = append(relationships, documentDescribesRelationship) + allRelationships = append(allRelationships, documentDescribesRelationship) return &spdx.Document{ // 6.1: SPDX Version; should be in the format "SPDX-x.x" @@ -150,7 +152,7 @@ func ToFormatModel(s sbom.SBOM) *spdx.Document { }, Packages: packages, Files: toFiles(s), - Relationships: relationships, + Relationships: allRelationships, OtherLicenses: toOtherLicenses(s.Artifacts.Packages), } } @@ -302,7 +304,7 @@ func toSPDXID(identifiable artifact.Identifiable) spdx.ElementID { // packages populates all Package Information from the package Collection (see https://spdx.github.io/spdx-spec/3-package-information/) // //nolint:funlen -func toPackages(catalog *pkg.Collection, sbom sbom.SBOM) (results []*spdx.Package) { +func toPackages(rels *relationship.Index, catalog *pkg.Collection, sbom sbom.SBOM) (results []*spdx.Package) { for _, p := range catalog.Sorted() { // name should be guaranteed to be unique, but semantically useful and stable id := toSPDXID(p) @@ -318,7 +320,7 @@ func toPackages(catalog *pkg.Collection, sbom sbom.SBOM) (results []*spdx.Packag // 2. syft has generated a sha1 digest for the package's contents packageChecksums, filesAnalyzed := toPackageChecksums(p) - packageVerificationCode := newPackageVerificationCode(p, sbom) + packageVerificationCode := newPackageVerificationCode(rels, p, sbom) if packageVerificationCode != nil { filesAnalyzed = true } @@ -744,12 +746,12 @@ func toOtherLicenses(catalog *pkg.Collection) []*spdx.OtherLicense { // f file is an "excludes" file, skip it /* exclude SPDX analysis file(s) */ // see: https://spdx.github.io/spdx-spec/v2.3/package-information/#79-package-verification-code-field // the above link contains the SPDX algorithm for a package verification code -func newPackageVerificationCode(p pkg.Package, sbom sbom.SBOM) *spdx.PackageVerificationCode { +func newPackageVerificationCode(rels *relationship.Index, p pkg.Package, sbom sbom.SBOM) *spdx.PackageVerificationCode { // key off of the contains relationship; // spdx validator will fail if a package claims to contain a file but no sha1 provided // if a sha1 for a file is provided then the validator will fail if the package does not have // a package verification code - coordinates := sbom.CoordinatesForPackage(p, artifact.ContainsRelationship) + coordinates := rels.Coordinates(p, artifact.ContainsRelationship) var digests []file.Digest for _, c := range coordinates { digest := sbom.Artifacts.FileDigests[c] diff --git a/syft/format/common/spdxhelpers/to_format_model_test.go b/syft/format/common/spdxhelpers/to_format_model_test.go index c2f181f0d89..e986069bb3a 100644 --- a/syft/format/common/spdxhelpers/to_format_model_test.go +++ b/syft/format/common/spdxhelpers/to_format_model_test.go @@ -12,6 +12,7 @@ import ( "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" + "github.com/anchore/syft/internal/relationship" "github.com/anchore/syft/syft/artifact" "github.com/anchore/syft/syft/file" "github.com/anchore/syft/syft/format/internal/spdxutil/helpers" @@ -665,7 +666,7 @@ func Test_H1Digest(t *testing.T) { for _, test := range tests { t.Run(test.name, func(t *testing.T) { catalog := pkg.NewCollection(test.pkg) - pkgs := toPackages(catalog, s) + pkgs := toPackages(relationship.NewIndex(), catalog, s) require.Len(t, pkgs, 1) for _, p := range pkgs { if test.expectedDigest == "" { diff --git a/syft/pkg/cataloger/python/dependency.go b/syft/pkg/cataloger/python/dependency.go index 7479649d062..6110281e902 100644 --- a/syft/pkg/cataloger/python/dependency.go +++ b/syft/pkg/cataloger/python/dependency.go @@ -167,7 +167,7 @@ func wheelEggRelationships(ctx context.Context, resolver file.Resolver, pkgs []p if err != nil { return nil, nil, fmt.Errorf("failed to resolve relationships for global site package %q: %w", globalSitePackage, err) } - relationshipIndex.AddAll(siteRels...) + relationshipIndex.Add(siteRels...) } // create relationships between packages within each virtual env site package directory (that doesn't link to a global site-packages directory) @@ -180,7 +180,7 @@ func wheelEggRelationships(ctx context.Context, resolver file.Resolver, pkgs []p if err != nil { return nil, nil, fmt.Errorf("failed to resolve relationships for virtualenv site package %q: %w", venv.SitePackagesPath, err) } - relationshipIndex.AddAll(siteRels...) + relationshipIndex.Add(siteRels...) } // create relationships between packages within each virtual env site package directory (that links to a global site package directory) @@ -197,10 +197,10 @@ func wheelEggRelationships(ctx context.Context, resolver file.Resolver, pkgs []p return nil, nil, fmt.Errorf("failed to resolve relationships for virtualenv + global site package path %q + %q: %w", venv.SitePackagesPath, globalSitePackage, err) } - relationshipIndex.AddAll(siteRels...) + relationshipIndex.Add(siteRels...) } - return pkgs, relationshipIndex.AllUniqueRelationships(), err + return pkgs, relationshipIndex.All(), err } func collectPackages(pkgsBySitePackageAndName map[string]map[string]pkg.Package, sites []string) []pkg.Package { diff --git a/syft/sbom/sbom.go b/syft/sbom/sbom.go index b3f3cd74ff9..ba3f95f3d46 100644 --- a/syft/sbom/sbom.go +++ b/syft/sbom/sbom.go @@ -35,6 +35,8 @@ type Descriptor struct { Configuration interface{} } +// RelationshipsSorted returns a sorted slice of all relationships +// Deprecated -- use relationship.Index func (s SBOM) RelationshipsSorted() []artifact.Relationship { relationships := s.Relationships sort.SliceStable(relationships, func(i, j int) bool { @@ -70,6 +72,7 @@ func (s SBOM) AllCoordinates() []file.Coordinates { // RelationshipsForPackage returns all relationships for the provided types. // If no types are provided, all relationships for the package are returned. +// Deprecated -- use relationship.Index func (s SBOM) RelationshipsForPackage(p pkg.Package, rt ...artifact.RelationshipType) []artifact.Relationship { if len(rt) == 0 { rt = artifact.AllRelationshipTypes() @@ -103,6 +106,7 @@ func (s SBOM) RelationshipsForPackage(p pkg.Package, rt ...artifact.Relationship // CoordinatesForPackage returns all coordinates for the provided package for provided relationship types // If no types are provided, all relationship types are considered. +// Deprecated -- use relationship.Index func (s SBOM) CoordinatesForPackage(p pkg.Package, rt ...artifact.RelationshipType) []file.Coordinates { var coordinates []file.Coordinates for _, relationship := range s.RelationshipsForPackage(p, rt...) { From 3917989f864ea5645b0d96467637332a198f1fb0 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Thu, 25 Jul 2024 13:50:06 -0400 Subject: [PATCH 030/122] chore(deps): bump github/codeql-action from 3.25.13 to 3.25.14 (#3072) Bumps [github/codeql-action](https://github.com/github/codeql-action) from 3.25.13 to 3.25.14. - [Release notes](https://github.com/github/codeql-action/releases) - [Changelog](https://github.com/github/codeql-action/blob/main/CHANGELOG.md) - [Commits](https://github.com/github/codeql-action/compare/2d790406f505036ef40ecba973cc774a50395aac...5cf07d8b700b67e235fbb65cbc84f69c0cf10464) --- updated-dependencies: - dependency-name: github/codeql-action dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- .github/workflows/codeql-analysis.yml | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/.github/workflows/codeql-analysis.yml b/.github/workflows/codeql-analysis.yml index e92c3d4fced..58c2ae72ae5 100644 --- a/.github/workflows/codeql-analysis.yml +++ b/.github/workflows/codeql-analysis.yml @@ -45,7 +45,7 @@ jobs: # Initializes the CodeQL tools for scanning. - name: Initialize CodeQL - uses: github/codeql-action/init@2d790406f505036ef40ecba973cc774a50395aac #v3.25.13 + uses: github/codeql-action/init@5cf07d8b700b67e235fbb65cbc84f69c0cf10464 #v3.25.14 with: languages: ${{ matrix.language }} # If you wish to specify custom queries, you can do so here or in a config file. @@ -56,7 +56,7 @@ jobs: # Autobuild attempts to build any compiled languages (C/C++, C#, or Java). # If this step fails, then you should remove it and run the build manually (see below) - name: Autobuild - uses: github/codeql-action/autobuild@2d790406f505036ef40ecba973cc774a50395aac #v3.25.13 + uses: github/codeql-action/autobuild@5cf07d8b700b67e235fbb65cbc84f69c0cf10464 #v3.25.14 # ℹī¸ Command-line programs to run using the OS shell. # 📚 https://git.io/JvXDl @@ -70,4 +70,4 @@ jobs: # make release - name: Perform CodeQL Analysis - uses: github/codeql-action/analyze@2d790406f505036ef40ecba973cc774a50395aac #v3.25.13 + uses: github/codeql-action/analyze@5cf07d8b700b67e235fbb65cbc84f69c0cf10464 #v3.25.14 From 68b96ae444d5b46cf552728aab307b7d7e70c1b5 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Thu, 25 Jul 2024 13:50:33 -0400 Subject: [PATCH 031/122] chore(deps): bump github.com/docker/docker (#3066) Bumps [github.com/docker/docker](https://github.com/docker/docker) from 27.1.0+incompatible to 27.1.1+incompatible. - [Release notes](https://github.com/docker/docker/releases) - [Commits](https://github.com/docker/docker/compare/v27.1.0...v27.1.1) --- updated-dependencies: - dependency-name: github.com/docker/docker dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- go.mod | 2 +- go.sum | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/go.mod b/go.mod index 8f0a9cef69e..ec2085c73cd 100644 --- a/go.mod +++ b/go.mod @@ -29,7 +29,7 @@ require ( github.com/dave/jennifer v1.7.0 github.com/deitch/magic v0.0.0-20230404182410-1ff89d7342da github.com/distribution/reference v0.6.0 - github.com/docker/docker v27.1.0+incompatible + github.com/docker/docker v27.1.1+incompatible github.com/dustin/go-humanize v1.0.1 github.com/elliotchance/phpserialize v1.4.0 github.com/facebookincubator/nvdtools v0.1.5 diff --git a/go.sum b/go.sum index 4eea6a29ef8..c129b300fb2 100644 --- a/go.sum +++ b/go.sum @@ -231,8 +231,8 @@ github.com/docker/cli v27.0.3+incompatible h1:usGs0/BoBW8MWxGeEtqPMkzOY56jZ6kYlS github.com/docker/cli v27.0.3+incompatible/go.mod h1:JLrzqnKDaYBop7H2jaqPtU4hHvMKP+vjCwu2uszcLI8= github.com/docker/distribution v2.8.3+incompatible h1:AtKxIZ36LoNK51+Z6RpzLpddBirtxJnzDrHLEKxTAYk= github.com/docker/distribution v2.8.3+incompatible/go.mod h1:J2gT2udsDAN96Uj4KfcMRqY0/ypR+oyYUYmja8H+y+w= -github.com/docker/docker v27.1.0+incompatible h1:rEHVQc4GZ0MIQKifQPHSFGV/dVgaZafgRf8fCPtDYBs= -github.com/docker/docker v27.1.0+incompatible/go.mod h1:eEKB0N0r5NX/I1kEveEz05bcu8tLC/8azJZsviup8Sk= +github.com/docker/docker v27.1.1+incompatible h1:hO/M4MtV36kzKldqnA37IWhebRA+LnqqcqDja6kVaKY= +github.com/docker/docker v27.1.1+incompatible/go.mod h1:eEKB0N0r5NX/I1kEveEz05bcu8tLC/8azJZsviup8Sk= github.com/docker/docker-credential-helpers v0.7.0 h1:xtCHsjxogADNZcdv1pKUHXryefjlVRqWqIhk/uXJp0A= github.com/docker/docker-credential-helpers v0.7.0/go.mod h1:rETQfLdHNT3foU5kuNkFR1R1V12OJRRO5lzt2D1b5X0= github.com/docker/go-connections v0.4.0 h1:El9xVISelRB7BuFusrZozjnkIM5YnzCViNKohAFqRJQ= From 36f95d682895c1a95d949fc9328260861e116c00 Mon Sep 17 00:00:00 2001 From: mikcl <43545032+Mikcl@users.noreply.github.com> Date: Thu, 25 Jul 2024 18:54:13 +0100 Subject: [PATCH 032/122] python-cataloger: normalize package names (#3069) Signed-off-by: mikcl --- .../catalog_packages_cases_test.go | 4 ++-- syft/pkg/cataloger/python/cataloger_test.go | 16 ++++++------- syft/pkg/cataloger/python/package.go | 21 ++++++++++++++-- syft/pkg/cataloger/python/package_test.go | 18 ++++++++++++++ .../python/parse_requirements_test.go | 24 ++++++++++++++----- .../test-fixtures/requires/requirements.txt | 1 + 6 files changed, 66 insertions(+), 18 deletions(-) diff --git a/cmd/syft/internal/test/integration/catalog_packages_cases_test.go b/cmd/syft/internal/test/integration/catalog_packages_cases_test.go index 188b4ae455a..ff21bd1c116 100644 --- a/cmd/syft/internal/test/integration/catalog_packages_cases_test.go +++ b/cmd/syft/internal/test/integration/catalog_packages_cases_test.go @@ -35,7 +35,7 @@ var imageOnlyTestCases = []testCase{ pkgType: pkg.PythonPkg, pkgLanguage: pkg.Python, pkgInfo: map[string]string{ - "Pygments": "2.6.1", + "pygments": "2.6.1", "requests": "2.22.0", "somerequests": "3.22.0", "someotherpkg": "3.19.0", @@ -172,7 +172,7 @@ var dirOnlyTestCases = []testCase{ "passlib": "1.7.2", "mypy": "v0.770", // common to image and directory - "Pygments": "2.6.1", + "pygments": "2.6.1", "requests": "2.22.0", "somerequests": "3.22.0", "someotherpkg": "3.19.0", diff --git a/syft/pkg/cataloger/python/cataloger_test.go b/syft/pkg/cataloger/python/cataloger_test.go index e1093a55aed..f3fc060172e 100644 --- a/syft/pkg/cataloger/python/cataloger_test.go +++ b/syft/pkg/cataloger/python/cataloger_test.go @@ -119,9 +119,9 @@ func Test_PackageCataloger(t *testing.T) { "test-fixtures/dist-info/direct_url.json", }, expectedPackage: pkg.Package{ - Name: "Pygments", + Name: "pygments", Version: "2.6.1", - PURL: "pkg:pypi/Pygments@2.6.1?vcs_url=git%2Bhttps://github.com/python-test/test.git%40aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa", + PURL: "pkg:pypi/pygments@2.6.1?vcs_url=git%2Bhttps://github.com/python-test/test.git%40aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa", Type: pkg.PythonPkg, Language: pkg.Python, Licenses: pkg.NewLicenseSet( @@ -161,9 +161,9 @@ func Test_PackageCataloger(t *testing.T) { "test-fixtures/casesensitive/DIST-INFO/direct_url.json", }, expectedPackage: pkg.Package{ - Name: "Pygments", + Name: "pygments", Version: "2.6.1", - PURL: "pkg:pypi/Pygments@2.6.1?vcs_url=git%2Bhttps://github.com/python-test/test.git%40aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa", + PURL: "pkg:pypi/pygments@2.6.1?vcs_url=git%2Bhttps://github.com/python-test/test.git%40aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa", Type: pkg.PythonPkg, Language: pkg.Python, Licenses: pkg.NewLicenseSet( @@ -199,9 +199,9 @@ func Test_PackageCataloger(t *testing.T) { "test-fixtures/malformed-record/dist-info/RECORD", }, expectedPackage: pkg.Package{ - Name: "Pygments", + Name: "pygments", Version: "2.6.1", - PURL: "pkg:pypi/Pygments@2.6.1", + PURL: "pkg:pypi/pygments@2.6.1", Type: pkg.PythonPkg, Language: pkg.Python, Licenses: pkg.NewLicenseSet( @@ -231,9 +231,9 @@ func Test_PackageCataloger(t *testing.T) { name: "partial dist-info directory", fixtures: []string{"test-fixtures/partial.dist-info/METADATA"}, expectedPackage: pkg.Package{ - Name: "Pygments", + Name: "pygments", Version: "2.6.1", - PURL: "pkg:pypi/Pygments@2.6.1", + PURL: "pkg:pypi/pygments@2.6.1", Type: pkg.PythonPkg, Language: pkg.Python, Licenses: pkg.NewLicenseSet( diff --git a/syft/pkg/cataloger/python/package.go b/syft/pkg/cataloger/python/package.go index f2d51ac3225..e574d583a14 100644 --- a/syft/pkg/cataloger/python/package.go +++ b/syft/pkg/cataloger/python/package.go @@ -2,6 +2,8 @@ package python import ( "fmt" + "regexp" + "strings" "github.com/anchore/packageurl-go" "github.com/anchore/syft/internal/licenses" @@ -10,7 +12,16 @@ import ( "github.com/anchore/syft/syft/pkg" ) +func normalize(name string) string { + // https://packaging.python.org/en/latest/specifications/name-normalization/ + re := regexp.MustCompile(`[-_.]+`) + normalized := re.ReplaceAllString(name, "-") + return strings.ToLower(normalized) +} + func newPackageForIndex(name, version string, locations ...file.Location) pkg.Package { + name = normalize(name) + p := pkg.Package{ Name: name, Version: version, @@ -26,6 +37,8 @@ func newPackageForIndex(name, version string, locations ...file.Location) pkg.Pa } func newPackageForIndexWithMetadata(name, version string, metadata interface{}, locations ...file.Location) pkg.Package { + name = normalize(name) + p := pkg.Package{ Name: name, Version: version, @@ -42,6 +55,8 @@ func newPackageForIndexWithMetadata(name, version string, metadata interface{}, } func newPackageForRequirementsWithMetadata(name, version string, metadata pkg.PythonRequirementsEntry, locations ...file.Location) pkg.Package { + name = normalize(name) + p := pkg.Package{ Name: name, Version: version, @@ -87,10 +102,12 @@ func newPackageForPackage(resolver file.Resolver, m parsedData, sources ...file. } } + name := normalize(m.Name) + p := pkg.Package{ - Name: m.Name, + Name: name, Version: m.Version, - PURL: packageURL(m.Name, m.Version, &m.PythonPackage), + PURL: packageURL(name, m.Version, &m.PythonPackage), Locations: file.NewLocationSet(sources...), Licenses: licenseSet, Language: pkg.Python, diff --git a/syft/pkg/cataloger/python/package_test.go b/syft/pkg/cataloger/python/package_test.go index 0b88336a7f1..a9b9238abdd 100644 --- a/syft/pkg/cataloger/python/package_test.go +++ b/syft/pkg/cataloger/python/package_test.go @@ -44,3 +44,21 @@ func Test_packageURL(t *testing.T) { }) } } + +func Test_normalization(t *testing.T) { + normalForm := "friendly-bard" + tests := []string{ + normalForm, + "Friendly-Bard", + "FRIENDLY-BARD", + "friendly.bard", + "friendly_bard", + "friendly--bard", + "FrIeNdLy-._.-bArD", + } + for _, tt := range tests { + t.Run(tt, func(t *testing.T) { + assert.Equal(t, normalForm, normalize(tt)) + }) + } +} diff --git a/syft/pkg/cataloger/python/parse_requirements_test.go b/syft/pkg/cataloger/python/parse_requirements_test.go index fe6d8c343ee..ebd67549a16 100644 --- a/syft/pkg/cataloger/python/parse_requirements_test.go +++ b/syft/pkg/cataloger/python/parse_requirements_test.go @@ -41,9 +41,9 @@ func TestParseRequirementsTxt(t *testing.T) { }, }, { - Name: "SomeProject", + Name: "someproject", Version: "5.4", - PURL: "pkg:pypi/SomeProject@5.4", + PURL: "pkg:pypi/someproject@5.4", Locations: locations, Language: pkg.Python, Type: pkg.PythonPkg, @@ -91,9 +91,9 @@ func TestParseRequirementsTxt(t *testing.T) { }, }, { - Name: "GithubSampleProject", + Name: "githubsampleproject", Version: "3.7.1", - PURL: "pkg:pypi/GithubSampleProject@3.7.1", + PURL: "pkg:pypi/githubsampleproject@3.7.1", Locations: locations, Language: pkg.Python, Type: pkg.PythonPkg, @@ -103,6 +103,18 @@ func TestParseRequirementsTxt(t *testing.T) { URL: "git+https://github.com/owner/repo@releases/tag/v3.7.1", }, }, + { + Name: "friendly-bard", + Version: "1.0.0", + PURL: "pkg:pypi/friendly-bard@1.0.0", + Locations: locations, + Language: pkg.Python, + Type: pkg.PythonPkg, + Metadata: pkg.PythonRequirementsEntry{ + Name: "FrIeNdLy-_-bArD", + VersionConstraint: "== 1.0.0", + }, + }, } var testCases = []struct { @@ -128,9 +140,9 @@ func TestParseRequirementsTxt(t *testing.T) { }, expectedPkgs: append([]pkg.Package{ { - Name: "Mopidy-Dirble", + Name: "mopidy-dirble", Version: "1.1", - PURL: "pkg:pypi/Mopidy-Dirble@1.1", + PURL: "pkg:pypi/mopidy-dirble@1.1", Locations: locations, Language: pkg.Python, Type: pkg.PythonPkg, diff --git a/syft/pkg/cataloger/python/test-fixtures/requires/requirements.txt b/syft/pkg/cataloger/python/test-fixtures/requires/requirements.txt index 188258bb7cc..15d60947a3c 100644 --- a/syft/pkg/cataloger/python/test-fixtures/requires/requirements.txt +++ b/syft/pkg/cataloger/python/test-fixtures/requires/requirements.txt @@ -22,3 +22,4 @@ argh==0.26.3 --hash=sha256:a9b3aaa1904eeb78e32394cd46c6f37ac0fb4af6dc488daa58971 celery[redis, pytest] == 4.4.7 # should remove [redis, pytest] requests[security] == 2.8.* ; python_version < "2.7" and sys_platform == "linux" GithubSampleProject == 3.7.1 @ git+https://github.com/owner/repo@releases/tag/v3.7.1 +FrIeNdLy-_-bArD == 1.0.0 From b3848f780f74e45b405053e2e9ec5448aa12faa9 Mon Sep 17 00:00:00 2001 From: mikcl <43545032+Mikcl@users.noreply.github.com> Date: Thu, 25 Jul 2024 18:56:10 +0100 Subject: [PATCH 033/122] python cataloger: allow dots in python package names (#3070) Signed-off-by: mikcl --- syft/pkg/cataloger/python/parse_requirements.go | 2 +- syft/pkg/cataloger/python/parse_requirements_test.go | 12 ++++++++++++ .../python/test-fixtures/requires/requirements.txt | 1 + 3 files changed, 14 insertions(+), 1 deletion(-) diff --git a/syft/pkg/cataloger/python/parse_requirements.go b/syft/pkg/cataloger/python/parse_requirements.go index 7ef49f6627c..38bbde3e83b 100644 --- a/syft/pkg/cataloger/python/parse_requirements.go +++ b/syft/pkg/cataloger/python/parse_requirements.go @@ -26,7 +26,7 @@ const ( // --hash=sha256:e9535b8c84dc9571a48999094fda7f33e63c3f1b74f3e5f3ac0105a58405bb65 # some comment // namePattern matches: requests[security] - namePattern = `(?P\w[\w\[\],\s-_]+)` + namePattern = `(?P\w[\w\[\],\s-_\.]+)` // versionConstraintPattern matches: == 2.8.* versionConstraintPattern = `(?P([^\S\r\n]*[~=>!<]+\s*[0-9a-zA-Z.*]+[^\S\r\n]*,?)+)?(@[^\S\r\n]*(?P[^;]*))?` diff --git a/syft/pkg/cataloger/python/parse_requirements_test.go b/syft/pkg/cataloger/python/parse_requirements_test.go index ebd67549a16..139b0b62a08 100644 --- a/syft/pkg/cataloger/python/parse_requirements_test.go +++ b/syft/pkg/cataloger/python/parse_requirements_test.go @@ -53,6 +53,18 @@ func TestParseRequirementsTxt(t *testing.T) { Markers: "python_version < '3.8'", }, }, + { + Name: "dots-._allowed", + Version: "1.0.0", + PURL: "pkg:pypi/dots-._allowed@1.0.0", + Locations: locations, + Language: pkg.Python, + Type: pkg.PythonPkg, + Metadata: pkg.PythonRequirementsEntry{ + Name: "dots-._allowed", + VersionConstraint: "== 1.0.0", + }, + }, { Name: "argh", Version: "0.26.2", diff --git a/syft/pkg/cataloger/python/test-fixtures/requires/requirements.txt b/syft/pkg/cataloger/python/test-fixtures/requires/requirements.txt index 15d60947a3c..a238ccdcff3 100644 --- a/syft/pkg/cataloger/python/test-fixtures/requires/requirements.txt +++ b/syft/pkg/cataloger/python/test-fixtures/requires/requirements.txt @@ -8,6 +8,7 @@ bar >= 1.0.0, <= 2.0.0, \ -r other-requirements.txt --requirements super-secretrequirements.txt SomeProject ==5.4 ; python_version < '3.8' +dots-._allowed == 1.0.0 coverage != 3.5 # Version Exclusion. Anything except version 3.5 numpyNew; sys_platform == 'win32' numpy >= 3.4.1; sys_platform == 'win32' From 4882d2e8ce73657100bc1f464f8e6bf6f8a96d07 Mon Sep 17 00:00:00 2001 From: Laurent Goderre Date: Thu, 25 Jul 2024 13:56:55 -0400 Subject: [PATCH 034/122] Only match ldflag version if it matches the main module or targets main.version (#3062) Signed-off-by: Laurent Goderre --- syft/pkg/cataloger/golang/parse_go_binary.go | 7 +-- .../cataloger/golang/parse_go_binary_test.go | 51 +++++++++++++++---- 2 files changed, 44 insertions(+), 14 deletions(-) diff --git a/syft/pkg/cataloger/golang/parse_go_binary.go b/syft/pkg/cataloger/golang/parse_go_binary.go index 4b496283029..7f186ecbab7 100644 --- a/syft/pkg/cataloger/golang/parse_go_binary.go +++ b/syft/pkg/cataloger/golang/parse_go_binary.go @@ -208,7 +208,7 @@ func (c *goBinaryCataloger) findMainModuleVersion(metadata *pkg.GolangBinaryBuil // version of the package. ldflags, _ = metadata.BuildSettings.Get("-ldflags") - majorVersion, fullVersion = extractVersionFromLDFlags(ldflags) + majorVersion, fullVersion = extractVersionFromLDFlags(ldflags, metadata.MainModule) if fullVersion != "" { return fullVersion } @@ -258,13 +258,14 @@ func extractVersionFromContents(reader io.Reader) string { return "" } -func extractVersionFromLDFlags(ldflags string) (majorVersion string, fullVersion string) { +func extractVersionFromLDFlags(ldflags string, maimModule string) (majorVersion string, fullVersion string) { if ldflags == "" { return "", "" } for _, pattern := range knownBuildFlagPatterns { - groups := internal.MatchNamedCaptureGroups(pattern, ldflags) + newPattern := regexp.MustCompile(fmt.Sprintf(`(main|%s\/[^\s]*)%s`, strings.ReplaceAll(maimModule, "/", "\\/"), pattern.String())) + groups := internal.MatchNamedCaptureGroups(newPattern, ldflags) v, ok := groups["version"] if !ok { diff --git a/syft/pkg/cataloger/golang/parse_go_binary_test.go b/syft/pkg/cataloger/golang/parse_go_binary_test.go index 8b88b9e12c9..75659ae65da 100644 --- a/syft/pkg/cataloger/golang/parse_go_binary_test.go +++ b/syft/pkg/cataloger/golang/parse_go_binary_test.go @@ -1068,6 +1068,7 @@ func TestBuildGoPkgInfo(t *testing.T) { func Test_extractVersionFromLDFlags(t *testing.T) { tests := []struct { name string + mainModule string ldflags string wantMajorVersion string wantFullVersion string @@ -1078,12 +1079,14 @@ func Test_extractVersionFromLDFlags(t *testing.T) { }, { name: "syft ldflags", + mainModule: "github.com/anchore/syft", ldflags: ` build -ldflags="-w -s -extldflags '-static' -X github.com/anchore/syft/internal/version.version=0.79.0 -X github.com/anchore/syft/internal/version.gitCommit=b2b332e8b2b66af0905e98b54ebd713a922be1a8 -X github.com/anchore/syft/internal/version.buildDate=2023-04-21T16:20:25Z -X github.com/anchore/syft/internal/version.gitDescription=v0.79.0 "`, wantMajorVersion: "0", wantFullVersion: "v0.79.0", }, { - name: "kubectl ldflags", + name: "kubectl ldflags", + mainModule: "k8s.io/kubernetes/vendor/k8s.io/client-go", ldflags: ` build -asmflags=all=-trimpath=/workspace/src/k8s.io/kubernetes/_output/dockerized/go/src/k8s.io/kubernetes build -compiler=gc build -gcflags="all=-trimpath=/workspace/src/k8s.io/kubernetes/_output/dockerized/go/src/k8s.io/kubernetes " @@ -1093,24 +1096,28 @@ func Test_extractVersionFromLDFlags(t *testing.T) { }, { name: "nerdctl ldflags", + mainModule: "github.com/containerd/nerdctl", ldflags: ` build -ldflags="-s -w -X github.com/containerd/nerdctl/pkg/version.Version=v1.3.1 -X github.com/containerd/nerdctl/pkg/version.Revision=b224b280ff3086516763c7335fc0e0997aca617a"`, wantMajorVersion: "1", wantFullVersion: "v1.3.1", }, { name: "limactl ldflags", + mainModule: "github.com/lima-vm/lima", ldflags: ` build -ldflags="-s -w -X github.com/lima-vm/lima/pkg/version.Version=v0.15.1"`, wantMajorVersion: "0", wantFullVersion: "v0.15.1", }, { name: "terraform ldflags", + mainModule: "github.com/hashicorp/terraform", ldflags: ` build -ldflags="-w -s -X 'github.com/hashicorp/terraform/version.Version=1.4.6' -X 'github.com/hashicorp/terraform/version.Prerelease='"`, wantMajorVersion: "1", wantFullVersion: "v1.4.6", }, { - name: "kube-apiserver ldflags", + name: "kube-apiserver ldflags", + mainModule: "k8s.io/kubernetes/vendor/k8s.io/client-go", ldflags: ` build -asmflags=all=-trimpath=/workspace/src/k8s.io/kubernetes/_output/dockerized/go/src/k8s.io/kubernetes build -buildmode=exe build -compiler=gc @@ -1120,14 +1127,16 @@ func Test_extractVersionFromLDFlags(t *testing.T) { wantFullVersion: "v1.27.1", }, { - name: "prometheus ldflags", + name: "prometheus ldflags", + mainModule: "github.com/prometheus/common", ldflags: ` build -ldflags="-X github.com/prometheus/common/version.Version=2.44.0 -X github.com/prometheus/common/version.Revision=1ac5131f698ebc60f13fe2727f89b115a41f6558 -X github.com/prometheus/common/version.Branch=HEAD -X github.com/prometheus/common/version.BuildUser=root@739e8181c5db -X github.com/prometheus/common/version.BuildDate=20230514-06:18:11 -extldflags '-static'" build -tags=netgo,builtinassets,stringlabels`, wantMajorVersion: "2", wantFullVersion: "v2.44.0", }, { - name: "influxdb ldflags", + name: "influxdb ldflags", + mainModule: "github.com/influxdata/influxdb-client-go/v2", ldflags: ` build -ldflags="-s -w -X main.version=v2.7.1 -X main.commit=407fa622e9 -X main.date=2023-04-28T13:24:27Z -linkmode=external -extld=/musl/x86_64/bin/musl-gcc -extldflags '-fno-PIC -static-pie -Wl,-z,stack-size=8388608'" build -tags=assets,sqlite_foreign_keys,sqlite_json,static_build,noasm`, wantMajorVersion: "2", @@ -1135,48 +1144,56 @@ func Test_extractVersionFromLDFlags(t *testing.T) { }, { name: "gitea ldflags", + mainModule: "code.gitea.io/gitea", ldflags: ` build -ldflags=" -X \"main.MakeVersion=GNU Make 4.1\" -X \"main.Version=1.19.3\" -X \"main.Tags=bindata sqlite sqlite_unlock_notify\" "`, wantMajorVersion: "1", wantFullVersion: "v1.19.3", }, { name: "docker sbom cli ldflags", + mainModule: "github.com/docker/sbom-cli-plugin", ldflags: ` build -ldflags="-w -s -extldflags '-static' -X github.com/docker/sbom-cli-plugin/internal/version.version=0.6.1-SNAPSHOT-02cf1c8 -X github.com/docker/sbom-cli-plugin/internal/version.gitCommit=02cf1c888ad6662109ac6e3be618392514a56316 -X github.com/docker/sbom-cli-plugin/internal/version.gitDescription=v0.6.1-dirty "`, wantMajorVersion: "0", wantFullVersion: "v0.6.1-SNAPSHOT-02cf1c8", }, { name: "docker scout ldflags", + mainModule: "github.com/docker/scout-cli-plugin", ldflags: ` build -ldflags="-w -s -extldflags '-static' -X github.com/docker/scout-cli-plugin/internal.version=0.10.0 "`, wantMajorVersion: "0", wantFullVersion: "v0.10.0", }, { name: "influx telegraf ldflags", + mainModule: "github.com/influxdata/telegraf", ldflags: ` build -ldflags="-w -s -X github.com/influxdata/telegraf/internal.Commit=a3a884a1 -X github.com/influxdata/telegraf/internal.Branch=HEAD -X github.com/influxdata/telegraf/internal.Version=1.26.2"`, wantMajorVersion: "1", wantFullVersion: "v1.26.2", }, { name: "argocd ldflags", + mainModule: "github.com/argoproj/argo-cd/v2", ldflags: ` build -ldflags="-X github.com/argoproj/argo-cd/v2/common.version=2.7.2 -X github.com/argoproj/argo-cd/v2/common.buildDate=2023-05-12T14:06:49Z -X github.com/argoproj/argo-cd/v2/common.gitCommit=cbee7e6011407ed2d1066c482db74e97e0cc6bdb -X github.com/argoproj/argo-cd/v2/common.gitTreeState=clean -X github.com/argoproj/argo-cd/v2/common.kubectlVersion=v0.24.2 -extldflags=\"-static\""`, wantMajorVersion: "2", wantFullVersion: "v2.7.2", }, { name: "kustomize ldflags", + mainModule: "sigs.k8s.io/kustomize/api", ldflags: ` build -ldflags="-s -X sigs.k8s.io/kustomize/api/provenance.version=kustomize/v4.5.7 -X sigs.k8s.io/kustomize/api/provenance.gitCommit=56d82a8378dfc8dc3b3b1085e5a6e67b82966bd7 -X sigs.k8s.io/kustomize/api/provenance.buildDate=2022-08-02T16:35:54Z "`, wantMajorVersion: "4", wantFullVersion: "v4.5.7", }, { name: "TiDB 7.5.0 ldflags", + mainModule: "github.com/pingcap/tidb", ldflags: `build -ldflags="-X \"github.com/pingcap/tidb/pkg/parser/mysql.TiDBReleaseVersion=v7.5.0\" -X \"github.com/pingcap/tidb/pkg/util/versioninfo.TiDBBuildTS=2023-11-24 08:51:04\" -X \"github.com/pingcap/tidb/pkg/util/versioninfo.TiDBGitHash=069631e2ecfedc000ffb92c67207bea81380f020\" -X \"github.com/pingcap/tidb/pkg/util/versioninfo.TiDBGitBranch=heads/refs/tags/v7.5.0\" -X \"github.com/pingcap/tidb/pkg/util/versioninfo.TiDBEdition=Community\" "`, wantMajorVersion: "7", wantFullVersion: "v7.5.0", }, { name: "TiDB 6.1.7 ldflags", + mainModule: "github.com/pingcap/tidb", ldflags: `build -ldflags="-X \"github.com/pingcap/tidb/parser/mysql.TiDBReleaseVersion=v6.1.7\" -X \"github.com/pingcap/tidb/util/versioninfo.TiDBBuildTS=2023-07-04 12:06:03\" -X \"github.com/pingcap/tidb/util/versioninfo.TiDBGitHash=613ecc5f731b2843e1d53a43915e2cd8da795936\" -X \"github.com/pingcap/tidb/util/versioninfo.TiDBGitBranch=heads/refs/tags/v6.1.7\" -X \"github.com/pingcap/tidb/util/versioninfo.TiDBEdition=Community\" "`, wantMajorVersion: "6", wantFullVersion: "v6.1.7", @@ -1190,31 +1207,43 @@ func Test_extractVersionFromLDFlags(t *testing.T) { ////////////////////////////////////////////////////////////////// // negative cases { - name: "hugo ldflags", - ldflags: ` build -ldflags="-s -w -X github.com/gohugoio/hugo/common/hugo.vendorInfo=gohugoio"`, + name: "hugo ldflags", + mainModule: "github.com/gohugoio/hugo", + ldflags: ` build -ldflags="-s -w -X github.com/gohugoio/hugo/common/hugo.vendorInfo=gohugoio"`, }, { - name: "ghostunnel ldflags", - ldflags: ` build -ldflags="-X main.version=77d9aaa"`, + name: "ghostunnel ldflags", + mainModule: "github.com/ghostunnel/ghostunnel", + ldflags: ` build -ldflags="-X main.version=77d9aaa"`, }, { - name: "opa ldflags", - ldflags: `build -ldflags=" -X github.com/open-policy-agent/opa/version.Hostname=9549178459bc"`, + name: "opa ldflags", + mainModule: "github.com/open-policy-agent/opa", + ldflags: `build -ldflags=" -X github.com/open-policy-agent/opa/version.Hostname=9549178459bc"`, }, /////////////////////////////////////////////////////////////////// // trickier cases { name: "macvlan plugin for cri-o ldflags", + mainModule: "github.com/containernetworking/plugins", ldflags: ` build -ldflags="-extldflags -static -X github.com/containernetworking/plugins/pkg/utils/buildversion.BuildVersion=v1.2.0"`, wantMajorVersion: "1", wantFullVersion: "v1.2.0", }, { name: "coder ldflags", + mainModule: "github.com/coder/coder", ldflags: ` build -ldflags="-s -w -X 'github.com/coder/coder/buildinfo.tag=0.23.4'"`, wantMajorVersion: "0", wantFullVersion: "v0.23.4", }, + { + name: "hypothetical multiple versions in ldflags", + mainModule: "github.com/foo/baz", + ldflags: ` build -ldflags="-extldflags -static -X github.com/foo/bar/buildversion.BuildVersion=v1.2.0 -X github.com/foo/baz/buildversion.BuildVersion=v2.4.5"`, + wantMajorVersion: "2", + wantFullVersion: "v2.4.5", + }, /////////////////////////////////////////////////////////////////// // don't know how to handle these... yet //{ @@ -1234,7 +1263,7 @@ func Test_extractVersionFromLDFlags(t *testing.T) { } for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { - gotMajorVersion, gotFullVersion := extractVersionFromLDFlags(tt.ldflags) + gotMajorVersion, gotFullVersion := extractVersionFromLDFlags(tt.ldflags, tt.mainModule) assert.Equal(t, tt.wantMajorVersion, gotMajorVersion, "unexpected major version") assert.Equal(t, tt.wantFullVersion, gotFullVersion, "unexpected full version") }) From 1cd75b7d685c84f6fcae2db36b7da277425f8098 Mon Sep 17 00:00:00 2001 From: mikcl <43545032+Mikcl@users.noreply.github.com> Date: Thu, 25 Jul 2024 20:45:14 +0100 Subject: [PATCH 035/122] python-cataloger: fix normalization test (#3073) Signed-off-by: mikcl --- syft/pkg/cataloger/python/parse_requirements_test.go | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/syft/pkg/cataloger/python/parse_requirements_test.go b/syft/pkg/cataloger/python/parse_requirements_test.go index 139b0b62a08..cd796955c80 100644 --- a/syft/pkg/cataloger/python/parse_requirements_test.go +++ b/syft/pkg/cataloger/python/parse_requirements_test.go @@ -54,9 +54,9 @@ func TestParseRequirementsTxt(t *testing.T) { }, }, { - Name: "dots-._allowed", + Name: "dots-allowed", Version: "1.0.0", - PURL: "pkg:pypi/dots-._allowed@1.0.0", + PURL: "pkg:pypi/dots-allowed@1.0.0", Locations: locations, Language: pkg.Python, Type: pkg.PythonPkg, From 490e05adb20744ab3d71b745046a9cf65d454952 Mon Sep 17 00:00:00 2001 From: witchcraze <67056980+witchcraze@users.noreply.github.com> Date: Mon, 29 Jul 2024 22:46:51 +0900 Subject: [PATCH 036/122] fix: traefik classifier (#3077) Signed-off-by: witchcraze --- .../pkg/cataloger/binary/classifier_cataloger_test.go | 11 +++++++++++ syft/pkg/cataloger/binary/classifiers.go | 3 ++- syft/pkg/cataloger/binary/test-fixtures/config.yaml | 6 ++++++ 3 files changed, 19 insertions(+), 1 deletion(-) diff --git a/syft/pkg/cataloger/binary/classifier_cataloger_test.go b/syft/pkg/cataloger/binary/classifier_cataloger_test.go index 978e457554c..9876df49649 100644 --- a/syft/pkg/cataloger/binary/classifier_cataloger_test.go +++ b/syft/pkg/cataloger/binary/classifier_cataloger_test.go @@ -204,6 +204,17 @@ func Test_Cataloger_PositiveCases(t *testing.T) { Metadata: metadata("traefik-binary"), }, }, + { + logicalFixture: "traefik/3.0.4/linux-riscv64", + expected: pkg.Package{ + Name: "traefik", + Version: "3.0.4", + Type: "binary", + PURL: "pkg:generic/traefik@3.0.4", + Locations: locations("traefik"), + Metadata: metadata("traefik-binary"), + }, + }, { logicalFixture: "memcached/1.6.18/linux-amd64", expected: pkg.Package{ diff --git a/syft/pkg/cataloger/binary/classifiers.go b/syft/pkg/cataloger/binary/classifiers.go index e11cd2a7fa2..e2797b0471c 100644 --- a/syft/pkg/cataloger/binary/classifiers.go +++ b/syft/pkg/cataloger/binary/classifiers.go @@ -263,7 +263,8 @@ func DefaultClassifiers() []Classifier { EvidenceMatcher: FileContentsVersionMatcher( // [NUL]v1.7.34[NUL] // [NUL]2.9.6[NUL] - `(?m)(\x00|\x{FFFD})v?(?P[0-9]+\.[0-9]+\.[0-9]+(-alpha[0-9]|-beta[0-9]|-rc[0-9])?)\x00`), + // 3.0.4[NUL] + `(?m)(\x00|\x{FFFD})?v?(?P[0-9]+\.[0-9]+\.[0-9]+(-alpha[0-9]|-beta[0-9]|-rc[0-9])?)\x00`), Package: "traefik", PURL: mustPURL("pkg:generic/traefik@version"), CPEs: singleCPE("cpe:2.3:a:traefik:traefik:*:*:*:*:*:*:*:*"), diff --git a/syft/pkg/cataloger/binary/test-fixtures/config.yaml b/syft/pkg/cataloger/binary/test-fixtures/config.yaml index e14c050c5a3..b00fd210336 100644 --- a/syft/pkg/cataloger/binary/test-fixtures/config.yaml +++ b/syft/pkg/cataloger/binary/test-fixtures/config.yaml @@ -448,6 +448,12 @@ from-images: paths: - /usr/local/bin/traefik + - version: 3.0.4 + images: + - ref: traefik:3.0.4@sha256:12a7cc4232b5b7fe027673da8c096144525f59a8eabc87e52260aac0ec5a1219 + platform: linux/riscv64 + paths: + - /usr/local/bin/traefik # from the original dynamic fixtures... From 8dd7c9c0b9614a78ecff964a8fb283a97a9a34fd Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 29 Jul 2024 10:03:35 -0400 Subject: [PATCH 037/122] chore(deps): bump github/codeql-action from 3.25.14 to 3.25.15 (#3083) Bumps [github/codeql-action](https://github.com/github/codeql-action) from 3.25.14 to 3.25.15. - [Release notes](https://github.com/github/codeql-action/releases) - [Changelog](https://github.com/github/codeql-action/blob/main/CHANGELOG.md) - [Commits](https://github.com/github/codeql-action/compare/5cf07d8b700b67e235fbb65cbc84f69c0cf10464...afb54ba388a7dca6ecae48f608c4ff05ff4cc77a) --- updated-dependencies: - dependency-name: github/codeql-action dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- .github/workflows/codeql-analysis.yml | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/.github/workflows/codeql-analysis.yml b/.github/workflows/codeql-analysis.yml index 58c2ae72ae5..d15a2c99703 100644 --- a/.github/workflows/codeql-analysis.yml +++ b/.github/workflows/codeql-analysis.yml @@ -45,7 +45,7 @@ jobs: # Initializes the CodeQL tools for scanning. - name: Initialize CodeQL - uses: github/codeql-action/init@5cf07d8b700b67e235fbb65cbc84f69c0cf10464 #v3.25.14 + uses: github/codeql-action/init@afb54ba388a7dca6ecae48f608c4ff05ff4cc77a #v3.25.15 with: languages: ${{ matrix.language }} # If you wish to specify custom queries, you can do so here or in a config file. @@ -56,7 +56,7 @@ jobs: # Autobuild attempts to build any compiled languages (C/C++, C#, or Java). # If this step fails, then you should remove it and run the build manually (see below) - name: Autobuild - uses: github/codeql-action/autobuild@5cf07d8b700b67e235fbb65cbc84f69c0cf10464 #v3.25.14 + uses: github/codeql-action/autobuild@afb54ba388a7dca6ecae48f608c4ff05ff4cc77a #v3.25.15 # ℹī¸ Command-line programs to run using the OS shell. # 📚 https://git.io/JvXDl @@ -70,4 +70,4 @@ jobs: # make release - name: Perform CodeQL Analysis - uses: github/codeql-action/analyze@5cf07d8b700b67e235fbb65cbc84f69c0cf10464 #v3.25.14 + uses: github/codeql-action/analyze@afb54ba388a7dca6ecae48f608c4ff05ff4cc77a #v3.25.15 From a35e410c75841dafb4ed1d9c2d89782f936c7fcd Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 29 Jul 2024 10:03:44 -0400 Subject: [PATCH 038/122] chore(deps): bump github.com/gkampitakis/go-snaps from 0.5.5 to 0.5.6 (#3082) Bumps [github.com/gkampitakis/go-snaps](https://github.com/gkampitakis/go-snaps) from 0.5.5 to 0.5.6. - [Release notes](https://github.com/gkampitakis/go-snaps/releases) - [Commits](https://github.com/gkampitakis/go-snaps/compare/v0.5.5...v0.5.6) --- updated-dependencies: - dependency-name: github.com/gkampitakis/go-snaps dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- go.mod | 2 +- go.sum | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/go.mod b/go.mod index ec2085c73cd..9071bcc2af3 100644 --- a/go.mod +++ b/go.mod @@ -34,7 +34,7 @@ require ( github.com/elliotchance/phpserialize v1.4.0 github.com/facebookincubator/nvdtools v0.1.5 github.com/github/go-spdx/v2 v2.3.1 - github.com/gkampitakis/go-snaps v0.5.5 + github.com/gkampitakis/go-snaps v0.5.6 github.com/go-git/go-billy/v5 v5.5.0 github.com/go-git/go-git/v5 v5.12.0 github.com/go-test/deep v1.1.1 diff --git a/go.sum b/go.sum index c129b300fb2..7ced08bbe7c 100644 --- a/go.sum +++ b/go.sum @@ -293,8 +293,8 @@ github.com/gkampitakis/ciinfo v0.3.0 h1:gWZlOC2+RYYttL0hBqcoQhM7h1qNkVqvRCV1fOvp github.com/gkampitakis/ciinfo v0.3.0/go.mod h1:1NIwaOcFChN4fa/B0hEBdAb6npDlFL8Bwx4dfRLRqAo= github.com/gkampitakis/go-diff v1.3.2 h1:Qyn0J9XJSDTgnsgHRdz9Zp24RaJeKMUHg2+PDZZdC4M= github.com/gkampitakis/go-diff v1.3.2/go.mod h1:LLgOrpqleQe26cte8s36HTWcTmMEur6OPYerdAAS9tk= -github.com/gkampitakis/go-snaps v0.5.5 h1:FZ01SXOE/uIsD8lZGUjUAxTevz9tf7c1QGIgezv2KNM= -github.com/gkampitakis/go-snaps v0.5.5/go.mod h1:ZABkO14uCuVxBHAXAfKG+bqNz+aa1bGPAg8jkI0Nk8Y= +github.com/gkampitakis/go-snaps v0.5.6 h1:kAal5JbqTycI+6xeS3K0nPqvNDAxqKX5W3dRXKxIJpA= +github.com/gkampitakis/go-snaps v0.5.6/go.mod h1:ZABkO14uCuVxBHAXAfKG+bqNz+aa1bGPAg8jkI0Nk8Y= 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= From a2042e629c38d8799d624915d6c4030978f3d7b8 Mon Sep 17 00:00:00 2001 From: "anchore-actions-token-generator[bot]" <102182147+anchore-actions-token-generator[bot]@users.noreply.github.com> Date: Mon, 29 Jul 2024 10:03:59 -0400 Subject: [PATCH 039/122] chore(deps): update CPE dictionary index (#3079) Signed-off-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com> Co-authored-by: wagoodman <590471+wagoodman@users.noreply.github.com> --- .../dictionary/data/cpe-index.json | 186 +++++++++++++++++- 1 file changed, 180 insertions(+), 6 deletions(-) diff --git a/syft/pkg/cataloger/internal/cpegenerate/dictionary/data/cpe-index.json b/syft/pkg/cataloger/internal/cpegenerate/dictionary/data/cpe-index.json index 361a897e2a6..b7226416a45 100644 --- a/syft/pkg/cataloger/internal/cpegenerate/dictionary/data/cpe-index.json +++ b/syft/pkg/cataloger/internal/cpegenerate/dictionary/data/cpe-index.json @@ -7017,7 +7017,8 @@ "cpe:2.3:a:ab-wp:simple_counter:*:*:*:*:*:wordpress:*:*" ], "academy": [ - "cpe:2.3:a:creativeitem:academy_lms:*:*:*:*:*:*:*:*" + "cpe:2.3:a:creativeitem:academy_lms:*:*:*:*:*:*:*:*", + "cpe:2.3:a:kodezen:academy_lms:*:*:*:*:*:wordpress:*:*" ], "accelerated-mobile-pages": [ "cpe:2.3:a:ampforwp:accelerated_mobile_pages:*:*:*:*:*:wordpress:*:*", @@ -7214,6 +7215,9 @@ "addon-elements-for-elementor-page-builder": [ "cpe:2.3:a:webtechstreet:elementor_addon_elements:*:*:*:*:*:wordpress:*:*" ], + "addons-for-beaver-builder": [ + "cpe:2.3:a:livemesh:livemesh_addons_for_beaver_builder:*:*:*:*:*:wordpress:*:*" + ], "addons-for-elementor": [ "cpe:2.3:a:livemesh:elementor_addons:*:*:*:*:*:wordpress:*:*", "cpe:2.3:a:livemeshelementor:addons_for_elementor:*:*:*:*:*:wordpress:*:*" @@ -7441,7 +7445,8 @@ "cpe:2.3:a:alfred24_click_\\\u0026_collect_project:alfred24_click_\\\u0026_collect:*:*:*:*:*:wordpress:*:*" ], "ali2woo-lite": [ - "cpe:2.3:a:ali2woo:ali2woo:*:*:*:*:lite:wordpress:*:*" + "cpe:2.3:a:ali2woo:ali2woo:*:*:*:*:lite:wordpress:*:*", + "cpe:2.3:a:ali2woo:aliexpress_dropshipping_with_alinext:*:*:*:*:lite:wordpress:*:*" ], "alipay": [ "cpe:2.3:a:alipay_project:alipay:*:*:*:*:*:wordpress:*:*" @@ -7800,6 +7805,9 @@ "auxin-elements": [ "cpe:2.3:a:averta:shortcodes_and_extra_features_for_phlox_theme:*:*:*:*:*:wordpress:*:*" ], + "auxin-portfolio": [ + "cpe:2.3:a:averta:auxinportfolio:*:*:*:*:*:wordpress:*:*" + ], "auyautochat-for-wp": [ "cpe:2.3:a:autochat:automatic_conversation:*:*:*:*:*:wordpress:*:*" ], @@ -7913,6 +7921,9 @@ "batch-cat": [ "cpe:2.3:a:batch_cat_project:batch_cat:*:*:*:*:*:wordpress:*:*" ], + "bb-bootstrap-cards": [ + "cpe:2.3:a:brainstormforce:cards_for_beaver_builder:*:*:*:*:*:wordpress:*:*" + ], "bbp-move-topics": [ "cpe:2.3:a:bbpress_move_topics_project:bbpress_move_topics:*:*:*:*:*:wordpress:*:*" ], @@ -7929,9 +7940,15 @@ "bbpress": [ "cpe:2.3:a:bbpress:bbpress:*:*:*:*:*:wordpress:*:*" ], + "bbpress-notify-nospam": [ + "cpe:2.3:a:usestrict:bbpress_notify:*:*:*:*:*:wordpress:*:*" + ], "bcorp-shortcodes": [ "cpe:2.3:a:bcorp_shortcodes_project:bcorp_shortcodes:*:*:*:*:*:wordpress:*:*" ], + "bdthemes-element-pack-lite": [ + "cpe:2.3:a:bdthemes:element_pack_elementor_addons:*:*:*:*:*:wordpress:*:*" + ], "bdvs-password-reset": [ "cpe:2.3:a:bedevious:password_reset_with_code_for_wordpress_rest_api:*:*:*:*:*:wordpress:*:*" ], @@ -8050,12 +8067,18 @@ "blog-in-blog": [ "cpe:2.3:a:blog-in-blog_project:blog-in-blog:*:*:*:*:*:wordpress:*:*" ], + "blog-posts-and-category-for-elementor": [ + "cpe:2.3:a:plugin-devs:blog\\,_posts_and_category_filter_for_elementor:*:*:*:*:*:wordpress:*:*" + ], "blog2social": [ "cpe:2.3:a:adenion:blog2social:*:*:*:*:*:wordpress:*:*" ], "blogger-importer": [ "cpe:2.3:a:wordpress:blogger_importer:*:*:*:*:*:wordpress:*:*" ], + "blogmentor": [ + "cpe:2.3:a:auburnforest:blogmentor:*:*:*:*:*:wordpress:*:*" + ], "blue-admin": [ "cpe:2.3:a:blue-admin_project:blue-admin:*:*:*:*:*:wordpress:*:*" ], @@ -8334,7 +8357,11 @@ "cache-images": [ "cpe:2.3:a:cache_images_project:cache_images:*:*:*:*:*:wordpress:*:*" ], + "caddy": [ + "cpe:2.3:a:madebytribe:caddy:*:*:*:*:*:wordpress:*:*" + ], "cafe-lite": [ + "cpe:2.3:a:clever-soft:clever_addons_for_elementor:*:*:*:*:*:wordpress:*:*", "cpe:2.3:a:cleversoft:clever_addons_for_elementor:*:*:*:*:*:wordpress:*:*", "cpe:2.3:a:download_clever_addons_for_elementor_project:download_clever_addons_for_elementor:*:*:*:*:*:wordpress:*:*" ], @@ -8382,6 +8409,9 @@ "candidate-application-form": [ "cpe:2.3:a:candidate-application-form_project:candidate-application-form:*:*:*:*:*:wordpress:*:*" ], + "canto": [ + "cpe:2.3:a:canto:canto:*:*:*:*:*:wordpress:*:*" + ], "canvasio3d-light": [ "cpe:2.3:a:virtuellwerk:canvasio3d_light:*:*:*:*:*:wordpress:*:*" ], @@ -8544,6 +8574,9 @@ "chatbot": [ "cpe:2.3:a:quantumcloud:ai_chatbot:*:*:*:*:*:wordpress:*:*" ], + "chatbot-chatgpt": [ + "cpe:2.3:a:kognetics:kognetiks_chatbot:*:*:*:*:*:wordpress:*:*" + ], "chaty": [ "cpe:2.3:a:premio:chaty:*:*:*:*:*:wordpress:*:*", "cpe:2.3:a:premio:floating_chat_widget:*:*:*:*:*:wordpress:*:*" @@ -8855,7 +8888,8 @@ "cpe:2.3:a:ciphercoin:contact_form_7_database_addon:*:*:*:*:*:wordpress:*:*" ], "contact-form-entries": [ - "cpe:2.3:a:crmperks:database_for_contact_form_7\\,_wpforms\\,_elementor_forms:*:*:*:*:*:*:*:*" + "cpe:2.3:a:crmperks:database_for_contact_form_7\\,_wpforms\\,_elementor_forms:*:*:*:*:*:*:*:*", + "cpe:2.3:a:crmperks:database_for_contact_form_7\\,_wpforms\\,_elementor_forms:*:*:*:*:*:wordpress:*:*" ], "contact-form-generator": [ "cpe:2.3:a:creative-solutions:contact_form_generator:*:*:*:*:*:wordpress:*:*" @@ -8946,6 +8980,9 @@ "content-views-query-and-display-post-page": [ "cpe:2.3:a:contentviewspro:content_views:*:*:*:*:*:wordpress:*:*" ], + "contentlock": [ + "cpe:2.3:a:adamsolymosi:contentlock:*:*:*:*:*:wordpress:*:*" + ], "contentstudio": [ "cpe:2.3:a:contentstudio:contentstudio:*:*:*:*:*:wordpress:*:*" ], @@ -9031,6 +9068,9 @@ "copy-the-code": [ "cpe:2.3:a:maheshwaghmare:copy_anything_to_clipboard:*:*:*:*:*:wordpress:*:*" ], + "copymatic": [ + "cpe:2.3:a:copymatic:copymatic:*:*:*:*:*:wordpress:*:*" + ], "core-control": [ "cpe:2.3:a:dd32:core_control:*:*:*:*:*:wordpress:*:*" ], @@ -9168,6 +9208,9 @@ "css-javascript-toolbox": [ "cpe:2.3:a:wipeoutmedia:css_\\\u0026_javascript_toolbox:*:*:*:*:*:wordpress:*:*" ], + "cssable-countdown": [ + "cpe:2.3:a:dmonnier:cssable_countdown:*:*:*:*:*:wordpress:*:*" + ], "csv-import-export": [ "cpe:2.3:a:csv-import-export_project:csv-import-export:*:*:*:*:*:wordpress:*:*" ], @@ -9443,6 +9486,9 @@ "delhivery-logistics-courier": [ "cpe:2.3:a:delhivery:logistics_courier:*:*:*:*:*:wordpress:*:*" ], + "delucks-seo": [ + "cpe:2.3:a:delucks:delucks_seo:*:*:*:*:*:wordpress:*:*" + ], "democracy-poll": [ "cpe:2.3:a:wp-kama:democracy_poll:*:*:*:*:*:wordpress:*:*" ], @@ -9460,7 +9506,8 @@ "cpe:2.3:a:depicter:depicter:*:*:*:*:*:wordpress:*:*" ], "dethemekit-for-elementor": [ - "cpe:2.3:a:detheme:dethemekit_for_elementor:*:*:*:*:*:wordpress:*:*" + "cpe:2.3:a:detheme:dethemekit_for_elementor:*:*:*:*:*:wordpress:*:*", + "cpe:2.3:a:dethemekit_for_elementor_project:dethemekit_for_elementor:*:*:*:*:*:wordpress:*:*" ], "diary-availability-calendar": [ "cpe:2.3:a:roosty:diary-availability-calendar:*:*:*:*:*:wordpress:*:*" @@ -9480,6 +9527,9 @@ "directorist": [ "cpe:2.3:a:wpwax:directorist:*:*:*:*:*:wordpress:*:*" ], + "directorypress": [ + "cpe:2.3:a:designinvento:directorypress:*:*:*:*:*:wordpress:*:*" + ], "disable-comments": [ "cpe:2.3:a:disable_comments:disable_comments_project:*:*:*:*:*:wordpress:*:*" ], @@ -9531,6 +9581,9 @@ "dokan-lite": [ "cpe:2.3:a:wedevs:dokan:*:*:*:*:*:wordpress:*:*" ], + "dokan-pro": [ + "cpe:2.3:a:dokan:dokan_pro_plugin:*:*:*:*:*:wordpress:*:*" + ], "dologin": [ "cpe:2.3:a:wpdo:dologin_security:*:*:*:*:*:wordpress:*:*" ], @@ -9561,6 +9614,9 @@ "doofinder-for-woocommerce": [ "cpe:2.3:a:doofinder:doofinder:*:*:*:*:*:wordpress:*:*" ], + "dop-shortcodes": [ + "cpe:2.3:a:dotonpaper:dot_on_paper_shortcodes:*:*:*:*:*:wordpress:*:*" + ], "double-opt-in-for-download": [ "cpe:2.3:a:labwebdevelopment:double_opt-in_for_download:*:*:*:*:*:wordpress:*:*" ], @@ -9894,6 +9950,9 @@ "elegant-custom-fonts": [ "cpe:2.3:a:breakdance:elegant_custom_fonts:*:*:*:*:*:wordpress:*:*" ], + "element-ready-lite": [ + "cpe:2.3:a:quomodosoft:elementsready:*:*:*:*:*:wordpress:*:*" + ], "elementor": [ "cpe:2.3:a:elementor:elementor_page_builder:*:*:*:*:*:wordpress:*:*", "cpe:2.3:a:elementor:elementor_page_builder:*:*:*:*:pro:wordpress:*:*", @@ -9904,7 +9963,8 @@ "cpe:2.3:a:elementor:elementor_pro:*:*:*:*:*:wordpress:*:*" ], "elementskit-lite": [ - "cpe:2.3:a:wpmet:elements_kit_elementor_addons:*:*:*:*:*:wordpress:*:*" + "cpe:2.3:a:wpmet:elements_kit_elementor_addons:*:*:*:*:*:wordpress:*:*", + "cpe:2.3:a:wpmet:elementskit_elementor_addons:*:*:*:*:*:wordpress:*:*" ], "elespare": [ "cpe:2.3:a:elespare:elespare:*:*:*:*:*:wordpress:*:*" @@ -10175,6 +10235,9 @@ "expand-maker": [ "cpe:2.3:a:edmonsoft:read_more_\\\u0026_accordion:*:*:*:*:*:wordpress:*:*" ], + "expert-invoice": [ + "cpe:2.3:a:expert_invoice_project:expert_invoice:*:*:*:*:*:wordpress:*:*" + ], "export-all-urls": [ "cpe:2.3:a:atlasgondal:export_all_urls:*:*:*:*:*:wordpress:*:*" ], @@ -10355,6 +10418,9 @@ "file-manager-advanced": [ "cpe:2.3:a:advancedfilemanager:advanced_file_manager:*:*:*:*:*:wordpress:*:*" ], + "file-manager-advanced-shortcode-2": [ + "cpe:2.3:a:advancedfilemanager:file_manager_advanced_shortcode:*:*:*:*:*:wordpress:*:*" + ], "filebird": [ "cpe:2.3:a:ninjateam:filebird:*:*:*:*:*:wordpress:*:*" ], @@ -10561,6 +10627,9 @@ "forminator": [ "cpe:2.3:a:incsub:forminator:*:*:*:*:*:wordpress:*:*" ], + "formlift": [ + "cpe:2.3:a:formlift:formlift_for_infusionsoft_web_forms:*:*:*:*:*:wordpress:*:*" + ], "forms-ada-form-builder": [ "cpe:2.3:a:monitorclick:forms_ada:*:*:*:*:*:wordpress:*:*" ], @@ -11058,6 +11127,9 @@ "gutenslider": [ "cpe:2.3:a:gutenslider:gutenslider:*:*:*:*:*:wordpress:*:*" ], + "gutenverse": [ + "cpe:2.3:a:jegstudio:gutenverse:*:*:*:*:*:wordpress:*:*" + ], "gwa-autoresponder": [ "cpe:2.3:a:\\[gwa\\]_autoresponder_project:\\[gwa\\]_autoresponder:*:*:*:*:*:wordpress:*:*" ], @@ -11767,6 +11839,9 @@ "keyword-meta": [ "cpe:2.3:a:keyword_meta_project:keyword_meta:*:*:*:*:*:wordpress:*:*" ], + "kimili-flash-embed": [ + "cpe:2.3:a:kimili:kimili_flash_embed:*:*:*:*:*:wordpress:*:*" + ], "kitestudio-core": [ "cpe:2.3:a:kitestudio:core_plugin_for_kitestudio_themes:*:*:*:*:*:wordpress:*:*" ], @@ -12118,6 +12193,9 @@ "magic-post-thumbnail": [ "cpe:2.3:a:magic-post-thumbnail:magic_post_thumbnail:*:*:*:*:*:wordpress:*:*" ], + "magical-addons-for-elementor": [ + "cpe:2.3:a:wpthemespace:magical_addons_for_elementor:*:*:*:*:*:wordpress:*:*" + ], "mail-control": [ "cpe:2.3:a:instareza:mail_control:*:*:*:*:*:wordpress:*:*" ], @@ -12262,6 +12340,9 @@ "material-design-icons-for-elementor": [ "cpe:2.3:a:material_design_icons_for_page_builders_project:material_design_icons_for_page_builders:*:*:*:*:*:wordpress:*:*" ], + "materialis-companion": [ + "cpe:2.3:a:extendthemes:materialis_companion:*:*:*:*:*:wordpress:*:*" + ], "matrix-pre-loader": [ "cpe:2.3:a:nkb-bd:preloader_matrix:*:*:*:*:*:wordpress:*:*" ], @@ -12324,6 +12405,9 @@ "mega-addons-for-visual-composer": [ "cpe:2.3:a:topdigitaltrends:mega_addons_for_wpbakery_page_builder:*:*:*:*:*:wordpress:*:*" ], + "mega-elements-addons-for-elementor": [ + "cpe:2.3:a:kraftplugins:mega_elements:*:*:*:*:*:wordpress:*:*" + ], "megamenu": [ "cpe:2.3:a:megamenu:max_mega_menu:*:*:*:*:*:wordpress:*:*" ], @@ -12649,6 +12733,9 @@ "my-content-management": [ "cpe:2.3:a:joedolson:my_content_management:*:*:*:*:*:wordpress:*:*" ], + "my-favorites": [ + "cpe:2.3:a:takashimatsuyama:my_favorites:*:*:*:*:*:wordpress:*:*" + ], "my-tickets": [ "cpe:2.3:a:my_tickets_project:my_tickets:*:*:*:*:*:wordpress:*:*" ], @@ -12824,6 +12911,9 @@ "cpe:2.3:a:wpconcern:coming_soon_\\\u0026_maintenance_mode_page:*:*:*:*:*:wordpress:*:*", "cpe:2.3:a:wpconcern:nifty_coming_soon_\\\u0026_maintenance_mode_page:*:*:*:*:*:wordpress:*:*" ], + "ninja-beaver-lite-addons-for-beaver-builder": [ + "cpe:2.3:a:ninjateam:ninja_beaver_add-ons_for_beaver_builder:*:*:*:*:*:wordpress:*:*" + ], "ninja-forms": [ "cpe:2.3:a:ninjaforms:contact_form:*:*:*:*:*:wordpress:*:*", "cpe:2.3:a:ninjaforms:ninja_forms:*:*:*:*:*:wordpress:*:*" @@ -13058,6 +13148,10 @@ "osmapper": [ "cpe:2.3:a:b4after:osmapper:*:*:*:*:*:wordpress:*:*" ], + "otter-blocks": [ + "cpe:2.3:a:themeisle:otter_blocks:*:*:*:*:*:*:*:*", + "cpe:2.3:a:themeisle:otter_blocks:*:*:*:*:*:wordpress:*:*" + ], "our-team-enhanced": [ "cpe:2.3:a:smartcat:our_team_showcase:*:*:*:*:*:wordpress:*:*" ], @@ -13085,6 +13179,9 @@ "page-builder-by-azexo": [ "cpe:2.3:a:azexo:page_builder_with_image_map_by_azexo:*:*:*:*:*:wordpress:*:*" ], + "page-builder-sandwich": [ + "cpe:2.3:a:pagebuildersandwich:page_builder_sandwich:*:*:*:*:*:wordpress:*:*" + ], "page-generator": [ "cpe:2.3:a:wpzinc:page_generator:*:*:*:*:*:wordpress:*:*" ], @@ -13170,6 +13267,9 @@ "paypal-payment-button-by-vcita": [ "cpe:2.3:a:vcita:online_payments_-_get_paid_with_paypal\\,_square_\\\u0026_stripe:*:*:*:*:*:wordpress:*:*" ], + "payplus-payment-gateway": [ + "cpe:2.3:a:payplus:payplus_payment_gateway:*:*:*:*:*:wordpress:*:*" + ], "paytium": [ "cpe:2.3:a:paytium:paytium:*:*:*:*:*:wordpress:*:*" ], @@ -13849,6 +13949,9 @@ "quotes-collection": [ "cpe:2.3:a:quotes_collection_project:quotes_collection:*:*:*:*:*:wordpress:*:*" ], + "quotes-for-woocommerce": [ + "cpe:2.3:a:technovama:quotes_for_woocommerce:*:*:*:*:*:wordpress:*:*" + ], "quotes-llama": [ "cpe:2.3:a:quotes_llama_project:quotes_llama:*:*:*:*:*:wordpress:*:*" ], @@ -14117,6 +14220,9 @@ "restrict-content": [ "cpe:2.3:a:liquidweb:restrict_content:*:*:*:*:*:wordpress:*:*" ], + "restrict-for-elementor": [ + "cpe:2.3:a:tickera:restrict_for_elementor:*:*:*:*:*:wordpress:*:*" + ], "restrict-usernames-emails-characters": [ "cpe:2.3:a:benaceur-php:restrict_usernames_emails_characters:*:*:*:*:*:wordpress:*:*" ], @@ -14336,6 +14442,9 @@ "searchiq": [ "cpe:2.3:a:searchiq:searchiq:*:*:*:*:*:wordpress:*:*" ], + "searchpro": [ + "cpe:2.3:a:berqier:berqwp:*:*:*:*:*:wordpress:*:*" + ], "searchterms-tagging-2": [ "cpe:2.3:a:seo_searchterms_tagging_2_project:seo_searchterms_tagging_2:*:*:*:*:*:wordpress:*:*" ], @@ -14375,6 +14484,12 @@ "sell-media": [ "cpe:2.3:a:graphpaperpress:sell_media:*:*:*:*:*:wordpress:*:*" ], + "sellkit": [ + "cpe:2.3:a:artbees:sellkit:*:*:*:*:*:wordpress:*:*" + ], + "send-emails-with-mandrill": [ + "cpe:2.3:a:millermedia:mandrill:*:*:*:*:*:wordpress:*:*" + ], "send-users-email": [ "cpe:2.3:a:sumanbhattarai:send_users_email:*:*:*:*:*:wordpress:*:*" ], @@ -14860,6 +14975,9 @@ "skaut-bazar": [ "cpe:2.3:a:skaut-bazar_project:skaut-bazar:*:*:*:*:*:wordpress:*:*" ], + "sketchfab-oembed": [ + "cpe:2.3:a:generatewp:sketchfab_embed:*:*:*:*:*:wordpress:*:*" + ], "sliced-invoices": [ "cpe:2.3:a:slicedinvoices:sliced_invoices:*:*:*:*:*:wordpress:*:*" ], @@ -15631,6 +15749,9 @@ "toolbar-to-share": [ "cpe:2.3:a:toolbar_to_share_project:toolbar_to_share:*:*:*:*:*:wordpress:*:*" ], + "tooltip-ck": [ + "cpe:2.3:a:ceikay:tooltip_ck:*:*:*:*:*:wordpress:*:*" + ], "top-10": [ "cpe:2.3:a:top_10_project:top_10:*:*:*:*:*:wordpress:*:*", "cpe:2.3:a:webberzone:top_10:*:*:*:*:*:wordpress:*:*" @@ -15677,6 +15798,9 @@ "transbank-webpay-plus-rest": [ "cpe:2.3:a:transbank:transbank_webpay_rest:*:*:*:*:*:wordpress:*:*" ], + "transition-slider-lite": [ + "cpe:2.3:a:creativeinteractivemedia:transition_slider:*:*:*:*:*:wordpress:*:*" + ], "translatepress-multilingual": [ "cpe:2.3:a:cozmoslabs:translatepress:*:*:*:*:*:wordpress:*:*" ], @@ -15765,6 +15889,9 @@ "ucontext-for-amazon": [ "cpe:2.3:a:summitmediaconcepts:ucontext_for_amazon:*:*:*:*:*:wordpress:*:*" ], + "uipress-lite": [ + "cpe:2.3:a:uipress:uipress_lite:*:*:*:*:*:wordpress:*:*" + ], "uji-countdown": [ "cpe:2.3:a:wpmanage:uji_countdown:*:*:*:*:*:wordpress:*:*" ], @@ -16039,6 +16166,9 @@ "vaultpress": [ "cpe:2.3:a:automattic:vaultpress:*:*:*:*:*:wordpress:*:*" ], + "vc-tabs": [ + "cpe:2.3:a:oxilab:responsive_tabs:*:*:*:*:*:wordpress:*:*" + ], "verge3d": [ "cpe:2.3:a:soft8soft:verge3d:*:*:*:*:*:wordpress:*:*" ], @@ -16344,6 +16474,9 @@ "weixin-robot-advanced": [ "cpe:2.3:a:wpjam:wechat_robot:*:*:*:*:premium:wordpress:*:*" ], + "wemail": [ + "cpe:2.3:a:wedevs:wemail:*:*:*:*:*:wordpress:*:*" + ], "wf-cookie-consent": [ "cpe:2.3:a:wunderfarm:wf_cookie_consent:*:*:*:*:*:wordpress:*:*" ], @@ -16851,6 +16984,9 @@ "wp-bitly": [ "cpe:2.3:a:bitly:bitly:*:*:*:*:*:wordpress:*:*" ], + "wp-blog-post-layouts": [ + "cpe:2.3:a:codevibrant:wp_blog_post_layouts:*:*:*:*:*:wordpress:*:*" + ], "wp-blogs-planetarium": [ "cpe:2.3:a:wp-blogs-planetarium_project:wp-blogs-planetarium:*:*:*:*:*:wordpress:*:*" ], @@ -16881,6 +17017,9 @@ "wp-cachecom": [ "cpe:2.3:a:kenthhagstrom:wp-cachecom:*:*:*:*:*:wordpress:*:*" ], + "wp-cafe": [ + "cpe:2.3:a:themewinter:wpcafe:*:*:*:*:*:wordpress:*:*" + ], "wp-calendar": [ "cpe:2.3:a:wp_calendar_project:wp_calendar:*:*:*:*:*:wordpress:*:*" ], @@ -17173,6 +17312,9 @@ "wp-file-manager": [ "cpe:2.3:a:webdesi9:file_manager:*:*:*:*:*:wordpress:*:*" ], + "wp-file-manager-pro": [ + "cpe:2.3:a:filemanagerpro:file_manager_pro:*:*:*:*:*:wordpress:*:*" + ], "wp-file-upload": [ "cpe:2.3:a:iptanus:wordpress_file_upload:*:*:*:*:*:wordpress:*:*" ], @@ -17526,7 +17668,8 @@ ], "wp-photo-album-plus": [ "cpe:2.3:a:wp_photo_album_plus_project:wp_photo_album_plus:*:*:*:*:*:wordpress:*:*", - "cpe:2.3:a:wppa.opajaap:wp-photo-album-plus:*:*:*:*:*:wordpress:*:*" + "cpe:2.3:a:wppa.opajaap:wp-photo-album-plus:*:*:*:*:*:wordpress:*:*", + "cpe:2.3:a:wppa:wp_photo_album_plus:*:*:*:*:*:wordpress:*:*" ], "wp-photo-text-slider-50": [ "cpe:2.3:a:gopiplus:wp_photo_text_slider_50:*:*:*:*:*:wordpress:*:*" @@ -17571,6 +17714,9 @@ "wp-popups-lite": [ "cpe:2.3:a:timersys:wp_popups:*:*:*:*:*:wordpress:*:*" ], + "wp-post-author": [ + "cpe:2.3:a:afthemes:wp_post_author:*:*:*:*:*:wordpress:*:*" + ], "wp-post-columns": [ "cpe:2.3:a:wp_post_columns_project:wp_post_columns:*:*:*:*:*:wordpress:*:*" ], @@ -17607,6 +17753,9 @@ "wp-reactions-lite": [ "cpe:2.3:a:wpreactions:wp_reactions_lite:*:*:*:*:*:wordpress:*:*" ], + "wp-recall": [ + "cpe:2.3:a:plechevandrey:wp-recall:*:*:*:*:*:wordpress:*:*" + ], "wp-recipe-maker": [ "cpe:2.3:a:bootstrapped:wp_recipe_maker:*:*:*:*:*:wordpress:*:*" ], @@ -17961,6 +18110,9 @@ "wp-whois-domain": [ "cpe:2.3:a:netattingo:wp-whois-domain:*:*:*:*:*:wordpress:*:*" ], + "wp-widget-bundle": [ + "cpe:2.3:a:devnath_verma:widget_bundle:*:*:*:*:*:wordpress:*:*" + ], "wp-woocommerce-quickbooks": [ "cpe:2.3:a:crmperks:integration_for_woocommerce_and_quickbooks:*:*:*:*:*:wordpress:*:*" ], @@ -18270,6 +18422,9 @@ "yith-desktop-notifications-for-woocommerce": [ "cpe:2.3:a:yithemes:yith_desktop_notifications_for_woocommerce:*:*:*:*:*:wordpress:*:*" ], + "yith-essential-kit-for-woocommerce-1": [ + "cpe:2.3:a:yithemes:yith_essential_kit_for_woocommerce:*:*:*:*:*:wordpress:*:*" + ], "yith-maintenance-mode": [ "cpe:2.3:a:yithemes:yith_maintenance_mode:*:*:*:*:*:wordpress:*:*" ], @@ -18396,6 +18551,9 @@ "zoho-forms": [ "cpe:2.3:a:zohocorp:zoho_forms:*:*:*:*:*:wordpress:*:*" ], + "zoho-marketinghub": [ + "cpe:2.3:a:zoho:zoho_marketing_automation:*:*:*:*:*:wordpress:*:*" + ], "zoho-salesiq": [ "cpe:2.3:a:zoho:salesiq:*:*:*:*:*:wordpress:*:*" ], @@ -18449,6 +18607,9 @@ "auberge": [ "cpe:2.3:a:webmandesign:auberge_theme:*:*:*:*:*:wordpress:*:*" ], + "author": [ + "cpe:2.3:a:sinatrateam:sinatra:*:*:*:*:*:wordpress:*:*" + ], "big-store": [ "cpe:2.3:a:themehunk:big_store:*:*:*:*:*:wordpress:*:*" ], @@ -18483,6 +18644,9 @@ "construction-lite": [ "cpe:2.3:a:accesspressthemes:construction_lite:*:*:*:*:*:wordpress:*:*" ], + "cozipress": [ + "cpe:2.3:a:burgersoftwares:cozipress:*:*:*:*:*:wordpress:*:*" + ], "customizr": [ "cpe:2.3:a:presscustomizr:customizr:*:*:*:*:*:wordpress:*:*" ], @@ -18507,6 +18671,10 @@ "enlighten": [ "cpe:2.3:a:accesspressthemes:enlighten:*:*:*:*:*:wordpress:*:*" ], + "esteem": [ + "cpe:2.3:a:themegrill:esteem:*:*:*:*:*:wordpress:*:*", + "cpe:2.3:a:themegrill:esteem:*:*:*:*:free:wordpress:*:*" + ], "everest-news": [ "cpe:2.3:a:everestthemes:everest_news:*:*:*:*:*:wordpress:*:*" ], @@ -18591,12 +18759,18 @@ "responsive": [ "cpe:2.3:a:cyberchimps:responsive:*:*:*:*:*:wordpress:*:*" ], + "rife-free": [ + "cpe:2.3:a:apollo13themes:rife_free:*:*:*:*:*:wordpress:*:*" + ], "royal-elementor-kit": [ "cpe:2.3:a:royal-elementor-addons:royal_elementor_kit:*:*:*:*:*:wordpress:*:*" ], "shapely": [ "cpe:2.3:a:colorlib:shapely:*:*:*:*:*:wordpress:*:*" ], + "sinatra": [ + "cpe:2.3:a:sinatrateam:sinatra:*:*:*:*:*:wordpress:*:*" + ], "sparkling": [ "cpe:2.3:a:colorlib:sparklinkg:*:*:*:*:*:wordpress:*:*" ], From 06526e29315a87b2016c52d0e6f01e351ba1f2be Mon Sep 17 00:00:00 2001 From: "anchore-actions-token-generator[bot]" <102182147+anchore-actions-token-generator[bot]@users.noreply.github.com> Date: Mon, 29 Jul 2024 10:04:46 -0400 Subject: [PATCH 040/122] chore(deps): update stereoscope to 50ce3be7aa1fb8829234ae648215e7907196bfa5 (#3075) Signed-off-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com> Co-authored-by: kzantow <3009477+kzantow@users.noreply.github.com> --- go.mod | 2 +- go.sum | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/go.mod b/go.mod index 9071bcc2af3..82cea45b0ea 100644 --- a/go.mod +++ b/go.mod @@ -17,7 +17,7 @@ require ( github.com/anchore/go-testutils v0.0.0-20200925183923-d5f45b0d3c04 github.com/anchore/go-version v1.2.2-0.20200701162849-18adb9c92b9b github.com/anchore/packageurl-go v0.1.1-0.20240507183024-848e011fc24f - github.com/anchore/stereoscope v0.0.3-0.20240711134149-487b11e5ba26 + github.com/anchore/stereoscope v0.0.3-0.20240725180315-50ce3be7aa1f github.com/anmitsu/go-shlex v0.0.0-20200514113438-38f4b401e2be // we are hinting brotli to latest due to warning when installing archiver v3: // go: warning: github.com/andybalholm/brotli@v1.0.1: retracted by module author: occasional panics and data corruption diff --git a/go.sum b/go.sum index 7ced08bbe7c..bd5319c94ad 100644 --- a/go.sum +++ b/go.sum @@ -113,8 +113,8 @@ github.com/anchore/go-version v1.2.2-0.20200701162849-18adb9c92b9b h1:e1bmaoJfZV github.com/anchore/go-version v1.2.2-0.20200701162849-18adb9c92b9b/go.mod h1:Bkc+JYWjMCF8OyZ340IMSIi2Ebf3uwByOk6ho4wne1E= github.com/anchore/packageurl-go v0.1.1-0.20240507183024-848e011fc24f h1:B/E9ixKNCasntpoch61NDaQyGPDXLEJlL+B9B/PbdbA= github.com/anchore/packageurl-go v0.1.1-0.20240507183024-848e011fc24f/go.mod h1:Blo6OgJNiYF41ufcgHKkbCKF2MDOMlrqhXv/ij6ocR4= -github.com/anchore/stereoscope v0.0.3-0.20240711134149-487b11e5ba26 h1:nOTfmXionIzGtg487nREmvDNr7QbR9vf6HbC2Z6n1ZE= -github.com/anchore/stereoscope v0.0.3-0.20240711134149-487b11e5ba26/go.mod h1:DcQdMes8SwpFli3rDH0v+Vd9qU9Jariq7JSHNJV5X/A= +github.com/anchore/stereoscope v0.0.3-0.20240725180315-50ce3be7aa1f h1:xuBvotcht1Ns8IdaC4UuYV1U8MFln9c5ELeo5bzDEO8= +github.com/anchore/stereoscope v0.0.3-0.20240725180315-50ce3be7aa1f/go.mod h1:DcQdMes8SwpFli3rDH0v+Vd9qU9Jariq7JSHNJV5X/A= github.com/andreyvit/diff v0.0.0-20170406064948-c7f18ee00883/go.mod h1:rCTlJbsFo29Kk6CurOXKm700vrz8f0KW0JNfpkRJY/8= github.com/andybalholm/brotli v1.0.1/go.mod h1:loMXtMfwqflxFJPmdbJO0a3KNoPuLBgiu3qAvBg8x/Y= github.com/andybalholm/brotli v1.0.4 h1:V7DdXeJtZscaqfNuAdSRuRFzuiKlHSC/Zh3zl9qY3JY= From a4b5dcd0df80f6a58c8610e25104647710c1da5d Mon Sep 17 00:00:00 2001 From: Keith Zantow Date: Tue, 30 Jul 2024 12:02:52 -0400 Subject: [PATCH 041/122] fix: improve determinism in java archive identification (#3085) Signed-off-by: Keith Zantow --- go.mod | 2 +- syft/pkg/cataloger/java/archive_parser.go | 8 +++- .../pkg/cataloger/java/archive_parser_test.go | 38 +++++++++++++++++++ .../java/test-fixtures/jar-metadata/Makefile | 4 ++ .../META-INF/MANIFEST.MF | 2 + .../multiple-matching-1/pom.properties | 3 ++ .../org.multiple/multiple-matching-1/pom.xml | 8 ++++ .../multiple-matching-2/pom.properties | 3 ++ .../org.multiple/multiple-matching-2/pom.xml | 8 ++++ .../multiple-matching-3/pom.properties | 3 ++ .../org.multiple/multiple-matching-3/pom.xml | 8 ++++ 11 files changed, 85 insertions(+), 2 deletions(-) create mode 100644 syft/pkg/cataloger/java/test-fixtures/jar-metadata/multiple-matching-2.11.5/META-INF/MANIFEST.MF create mode 100644 syft/pkg/cataloger/java/test-fixtures/jar-metadata/multiple-matching-2.11.5/META-INF/maven/org.multiple/multiple-matching-1/pom.properties create mode 100644 syft/pkg/cataloger/java/test-fixtures/jar-metadata/multiple-matching-2.11.5/META-INF/maven/org.multiple/multiple-matching-1/pom.xml create mode 100644 syft/pkg/cataloger/java/test-fixtures/jar-metadata/multiple-matching-2.11.5/META-INF/maven/org.multiple/multiple-matching-2/pom.properties create mode 100644 syft/pkg/cataloger/java/test-fixtures/jar-metadata/multiple-matching-2.11.5/META-INF/maven/org.multiple/multiple-matching-2/pom.xml create mode 100644 syft/pkg/cataloger/java/test-fixtures/jar-metadata/multiple-matching-2.11.5/META-INF/maven/org.multiple/multiple-matching-3/pom.properties create mode 100644 syft/pkg/cataloger/java/test-fixtures/jar-metadata/multiple-matching-2.11.5/META-INF/maven/org.multiple/multiple-matching-3/pom.xml diff --git a/go.mod b/go.mod index 82cea45b0ea..87692a0f38c 100644 --- a/go.mod +++ b/go.mod @@ -90,6 +90,7 @@ require ( github.com/BurntSushi/toml v1.4.0 github.com/adrg/xdg v0.5.0 github.com/magiconair/properties v1.8.7 + golang.org/x/exp v0.0.0-20231108232855-2478ac86f678 ) require ( @@ -230,7 +231,6 @@ require ( go.uber.org/atomic v1.9.0 // indirect go.uber.org/multierr v1.9.0 // indirect golang.org/x/crypto v0.25.0 // indirect - golang.org/x/exp v0.0.0-20231108232855-2478ac86f678 // indirect golang.org/x/sync v0.7.0 // indirect golang.org/x/sys v0.22.0 // indirect golang.org/x/term v0.22.0 // indirect diff --git a/syft/pkg/cataloger/java/archive_parser.go b/syft/pkg/cataloger/java/archive_parser.go index 134e8f18af3..2262d79fb7c 100644 --- a/syft/pkg/cataloger/java/archive_parser.go +++ b/syft/pkg/cataloger/java/archive_parser.go @@ -6,8 +6,11 @@ import ( "fmt" "os" "path" + "slices" "strings" + "golang.org/x/exp/maps" + intFile "github.com/anchore/syft/internal/file" "github.com/anchore/syft/internal/licenses" "github.com/anchore/syft/internal/log" @@ -298,7 +301,10 @@ func (j *archiveParser) guessMainPackageNameAndVersionFromPomInfo(ctx context.Co properties, _ := pomPropertiesByParentPath(j.archivePath, j.location, pomPropertyMatches) projects, _ := pomProjectByParentPath(j.archivePath, j.location, pomMatches) - for parentPath, propertiesObj := range properties { + parentPaths := maps.Keys(properties) + slices.Sort(parentPaths) + for _, parentPath := range parentPaths { + propertiesObj := properties[parentPath] if artifactIDMatchesFilename(propertiesObj.ArtifactID, j.fileInfo.name) { pomPropertiesObject = propertiesObj if proj, exists := projects[parentPath]; exists { diff --git a/syft/pkg/cataloger/java/archive_parser_test.go b/syft/pkg/cataloger/java/archive_parser_test.go index 7d7164196c3..968be857862 100644 --- a/syft/pkg/cataloger/java/archive_parser_test.go +++ b/syft/pkg/cataloger/java/archive_parser_test.go @@ -1386,6 +1386,44 @@ func Test_parseJavaArchive_regressions(t *testing.T) { } } +func Test_deterministicMatchingPomProperties(t *testing.T) { + tests := []struct { + fixture string + expectedName string + expectedVersion string + }{ + { + fixture: "multiple-matching-2.11.5", + expectedName: "multiple-matching-1", + expectedVersion: "2.11.5", + }, + } + + for _, test := range tests { + t.Run(test.fixture, func(t *testing.T) { + fixturePath := generateJavaMetadataJarFixture(t, test.fixture) + + for i := 0; i < 5; i++ { + func() { + fixture, err := os.Open(fixturePath) + require.NoError(t, err) + + parser, cleanupFn, err := newJavaArchiveParser(file.LocationReadCloser{ + Location: file.NewLocation(fixture.Name()), + ReadCloser: fixture, + }, false, ArchiveCatalogerConfig{UseNetwork: false}) + defer cleanupFn() + require.NoError(t, err) + + name, version, _ := parser.guessMainPackageNameAndVersionFromPomInfo(context.TODO()) + require.Equal(t, test.expectedName, name) + require.Equal(t, test.expectedVersion, version) + }() + } + }) + } +} + func assignParent(parent *pkg.Package, childPackages ...pkg.Package) { for i, jp := range childPackages { if v, ok := jp.Metadata.(pkg.JavaArchive); ok { diff --git a/syft/pkg/cataloger/java/test-fixtures/jar-metadata/Makefile b/syft/pkg/cataloger/java/test-fixtures/jar-metadata/Makefile index b6533f1471c..c5d3c52a3af 100644 --- a/syft/pkg/cataloger/java/test-fixtures/jar-metadata/Makefile +++ b/syft/pkg/cataloger/java/test-fixtures/jar-metadata/Makefile @@ -6,6 +6,7 @@ SBT_JACKSON_CORE = com.fasterxml.jackson.core.jackson-core-2.15.2 OPENSAML_CORE = opensaml-core-3.4.6 API_ALL_SOURCES = api-all-2.0.0-sources SPRING_INSTRUMENTATION = spring-instrumentation-4.3.0-1.0 +MULTIPLE_MATCHING = multiple-matching-2.11.5 $(CACHE_DIR): mkdir -p $(CACHE_DIR) @@ -24,3 +25,6 @@ $(CACHE_DIR)/$(API_ALL_SOURCES).jar: $(CACHE_DIR) $(CACHE_DIR)/$(SPRING_INSTRUMENTATION).jar: $(CACHE_DIR) cd $(SPRING_INSTRUMENTATION) && zip -r $(CACHE_PATH)/$(SPRING_INSTRUMENTATION).jar . + +$(CACHE_DIR)/$(MULTIPLE_MATCHING).jar: $(CACHE_DIR) + cd $(MULTIPLE_MATCHING) && zip -r $(CACHE_PATH)/$(MULTIPLE_MATCHING).jar . diff --git a/syft/pkg/cataloger/java/test-fixtures/jar-metadata/multiple-matching-2.11.5/META-INF/MANIFEST.MF b/syft/pkg/cataloger/java/test-fixtures/jar-metadata/multiple-matching-2.11.5/META-INF/MANIFEST.MF new file mode 100644 index 00000000000..525109c7337 --- /dev/null +++ b/syft/pkg/cataloger/java/test-fixtures/jar-metadata/multiple-matching-2.11.5/META-INF/MANIFEST.MF @@ -0,0 +1,2 @@ +Manifest-Version: 1.0 +Created-By: Multi diff --git a/syft/pkg/cataloger/java/test-fixtures/jar-metadata/multiple-matching-2.11.5/META-INF/maven/org.multiple/multiple-matching-1/pom.properties b/syft/pkg/cataloger/java/test-fixtures/jar-metadata/multiple-matching-2.11.5/META-INF/maven/org.multiple/multiple-matching-1/pom.properties new file mode 100644 index 00000000000..43e0d811b73 --- /dev/null +++ b/syft/pkg/cataloger/java/test-fixtures/jar-metadata/multiple-matching-2.11.5/META-INF/maven/org.multiple/multiple-matching-1/pom.properties @@ -0,0 +1,3 @@ +version=2.11.5 +groupId=org.multiple +artifactId=multiple-matching-1 diff --git a/syft/pkg/cataloger/java/test-fixtures/jar-metadata/multiple-matching-2.11.5/META-INF/maven/org.multiple/multiple-matching-1/pom.xml b/syft/pkg/cataloger/java/test-fixtures/jar-metadata/multiple-matching-2.11.5/META-INF/maven/org.multiple/multiple-matching-1/pom.xml new file mode 100644 index 00000000000..1c359dd9aa2 --- /dev/null +++ b/syft/pkg/cataloger/java/test-fixtures/jar-metadata/multiple-matching-2.11.5/META-INF/maven/org.multiple/multiple-matching-1/pom.xml @@ -0,0 +1,8 @@ + + + 4.0.0 + + org.multiple + multiple-matching-1 + 2.11.5 + diff --git a/syft/pkg/cataloger/java/test-fixtures/jar-metadata/multiple-matching-2.11.5/META-INF/maven/org.multiple/multiple-matching-2/pom.properties b/syft/pkg/cataloger/java/test-fixtures/jar-metadata/multiple-matching-2.11.5/META-INF/maven/org.multiple/multiple-matching-2/pom.properties new file mode 100644 index 00000000000..6be2acfbd13 --- /dev/null +++ b/syft/pkg/cataloger/java/test-fixtures/jar-metadata/multiple-matching-2.11.5/META-INF/maven/org.multiple/multiple-matching-2/pom.properties @@ -0,0 +1,3 @@ +version=2.11.5 +groupId=org.multiple +artifactId=multiple-matching-2 \ No newline at end of file diff --git a/syft/pkg/cataloger/java/test-fixtures/jar-metadata/multiple-matching-2.11.5/META-INF/maven/org.multiple/multiple-matching-2/pom.xml b/syft/pkg/cataloger/java/test-fixtures/jar-metadata/multiple-matching-2.11.5/META-INF/maven/org.multiple/multiple-matching-2/pom.xml new file mode 100644 index 00000000000..343c49d303d --- /dev/null +++ b/syft/pkg/cataloger/java/test-fixtures/jar-metadata/multiple-matching-2.11.5/META-INF/maven/org.multiple/multiple-matching-2/pom.xml @@ -0,0 +1,8 @@ + + + 4.0.0 + + org.multiple + multiple-matching-2 + 2.11.5 + diff --git a/syft/pkg/cataloger/java/test-fixtures/jar-metadata/multiple-matching-2.11.5/META-INF/maven/org.multiple/multiple-matching-3/pom.properties b/syft/pkg/cataloger/java/test-fixtures/jar-metadata/multiple-matching-2.11.5/META-INF/maven/org.multiple/multiple-matching-3/pom.properties new file mode 100644 index 00000000000..187215b293d --- /dev/null +++ b/syft/pkg/cataloger/java/test-fixtures/jar-metadata/multiple-matching-2.11.5/META-INF/maven/org.multiple/multiple-matching-3/pom.properties @@ -0,0 +1,3 @@ +version=2.11.5 +groupId=org.multiple +artifactId=multiple-matching-3 diff --git a/syft/pkg/cataloger/java/test-fixtures/jar-metadata/multiple-matching-2.11.5/META-INF/maven/org.multiple/multiple-matching-3/pom.xml b/syft/pkg/cataloger/java/test-fixtures/jar-metadata/multiple-matching-2.11.5/META-INF/maven/org.multiple/multiple-matching-3/pom.xml new file mode 100644 index 00000000000..b428bd69bbd --- /dev/null +++ b/syft/pkg/cataloger/java/test-fixtures/jar-metadata/multiple-matching-2.11.5/META-INF/maven/org.multiple/multiple-matching-3/pom.xml @@ -0,0 +1,8 @@ + + + 4.0.0 + + org.multiple + multiple-matching-3 + 2.11.5 + From 92d63df6f55cf875204ccce9a7bdb27f23a40f64 Mon Sep 17 00:00:00 2001 From: Laurent Goderre Date: Wed, 31 Jul 2024 16:13:26 -0400 Subject: [PATCH 042/122] Added the SWI Prolog (swipl) ecosystem (#3076) * Add binary classifier for swipl Signed-off-by: Laurent Goderre * Added cataloger for SWI Prolog Pack packages Signed-off-by: Laurent Goderre --------- Signed-off-by: Laurent Goderre --- .../catalog_packages_cases_test.go | 8 + .../test/integration/catalog_packages_test.go | 2 + .../image-pkg-coverage/swipl/pack/hdt/pack.pl | 10 + internal/constants.go | 2 +- internal/task/package_tasks.go | 2 + schema/json/schema-16.0.15.json | 2582 +++++++++++++++++ schema/json/schema-latest.json | 47 +- .../spdxutil/helpers/originator_supplier.go | 6 + .../helpers/originator_supplier_test.go | 14 + .../internal/spdxutil/helpers/source_info.go | 2 + .../spdxutil/helpers/source_info_test.go | 8 + syft/internal/packagemetadata/generated.go | 1 + syft/internal/packagemetadata/names.go | 1 + syft/internal/packagemetadata/names_test.go | 6 - .../binary/classifier_cataloger_test.go | 11 + syft/pkg/cataloger/binary/classifiers.go | 10 + .../snippets/erlang/27.0/linux-amd64/beam.smp | 9 + .../snippets/swipl/9.3.8/linux-amd64/swipl | Bin 0 -> 347 bytes .../binary/test-fixtures/config.yaml | 7 + syft/pkg/cataloger/swipl/cataloger.go | 15 + syft/pkg/cataloger/swipl/cataloger_test.go | 32 + syft/pkg/cataloger/swipl/package.go | 38 + syft/pkg/cataloger/swipl/package_test.go | 33 + syft/pkg/cataloger/swipl/parse_pack.go | 70 + syft/pkg/cataloger/swipl/parse_pack_test.go | 39 + .../swipl/test-fixtures/glob-paths/pack.pl | 1 + .../pkg/cataloger/swipl/test-fixtures/pack.pl | 10 + syft/pkg/language.go | 4 + syft/pkg/language_test.go | 8 + syft/pkg/swipl.go | 12 + syft/pkg/type.go | 6 + syft/pkg/type_test.go | 4 + 32 files changed, 2992 insertions(+), 8 deletions(-) create mode 100644 cmd/syft/internal/test/integration/test-fixtures/image-pkg-coverage/swipl/pack/hdt/pack.pl create mode 100644 schema/json/schema-16.0.15.json create mode 100644 syft/pkg/cataloger/binary/test-fixtures/classifiers/snippets/erlang/27.0/linux-amd64/beam.smp create mode 100644 syft/pkg/cataloger/binary/test-fixtures/classifiers/snippets/swipl/9.3.8/linux-amd64/swipl create mode 100644 syft/pkg/cataloger/swipl/cataloger.go create mode 100644 syft/pkg/cataloger/swipl/cataloger_test.go create mode 100644 syft/pkg/cataloger/swipl/package.go create mode 100644 syft/pkg/cataloger/swipl/package_test.go create mode 100644 syft/pkg/cataloger/swipl/parse_pack.go create mode 100644 syft/pkg/cataloger/swipl/parse_pack_test.go create mode 100644 syft/pkg/cataloger/swipl/test-fixtures/glob-paths/pack.pl create mode 100644 syft/pkg/cataloger/swipl/test-fixtures/pack.pl create mode 100644 syft/pkg/swipl.go diff --git a/cmd/syft/internal/test/integration/catalog_packages_cases_test.go b/cmd/syft/internal/test/integration/catalog_packages_cases_test.go index ff21bd1c116..55822043ec0 100644 --- a/cmd/syft/internal/test/integration/catalog_packages_cases_test.go +++ b/cmd/syft/internal/test/integration/catalog_packages_cases_test.go @@ -388,6 +388,14 @@ var dirOnlyTestCases = []testCase{ "swift-numerics": "1.0.2", }, }, + { + name: "find swipl pack package manager packages", + pkgType: pkg.SwiplPackPkg, + pkgLanguage: pkg.Swipl, + pkgInfo: map[string]string{ + "hdt": "0.5.2", + }, + }, { name: "find github action packages (from usage in workflow files and composite actions)", pkgType: pkg.GithubActionPkg, diff --git a/cmd/syft/internal/test/integration/catalog_packages_test.go b/cmd/syft/internal/test/integration/catalog_packages_test.go index 4ba5e3b5227..e84d578391b 100644 --- a/cmd/syft/internal/test/integration/catalog_packages_test.go +++ b/cmd/syft/internal/test/integration/catalog_packages_test.go @@ -51,6 +51,7 @@ func TestPkgCoverageImage(t *testing.T) { definedLanguages.Remove(pkg.Rust.String()) definedLanguages.Remove(pkg.Dart.String()) definedLanguages.Remove(pkg.Swift.String()) + definedLanguages.Remove(pkg.Swipl.String()) definedLanguages.Remove(pkg.CPP.String()) definedLanguages.Remove(pkg.Haskell.String()) definedLanguages.Remove(pkg.Elixir.String()) @@ -76,6 +77,7 @@ func TestPkgCoverageImage(t *testing.T) { definedPkgs.Remove(string(pkg.LinuxKernelPkg)) definedPkgs.Remove(string(pkg.LinuxKernelModulePkg)) definedPkgs.Remove(string(pkg.SwiftPkg)) + definedPkgs.Remove(string(pkg.SwiplPackPkg)) definedPkgs.Remove(string(pkg.GithubActionPkg)) definedPkgs.Remove(string(pkg.GithubActionWorkflowPkg)) diff --git a/cmd/syft/internal/test/integration/test-fixtures/image-pkg-coverage/swipl/pack/hdt/pack.pl b/cmd/syft/internal/test/integration/test-fixtures/image-pkg-coverage/swipl/pack/hdt/pack.pl new file mode 100644 index 00000000000..5e706f8d049 --- /dev/null +++ b/cmd/syft/internal/test/integration/test-fixtures/image-pkg-coverage/swipl/pack/hdt/pack.pl @@ -0,0 +1,10 @@ +name(hdt). +version('0.5.2'). +% TODO: swipl_version([90121]). +title('Access RDF HDT files'). +keywords(['RDF']). +author( 'Jan Wielemaker', 'J.Wielemaker@vu.nl' ). +packager( 'Jan Wielemaker', 'J.Wielemaker@vu.nl' ). +maintainer( 'Jan Wielemaker', 'J.Wielemaker@vu.nl' ). +home( 'https://github.com/JanWielemaker/hdt' ). +download( 'https://github.com/JanWielemaker/hdt/archive/V*.zip' ). diff --git a/internal/constants.go b/internal/constants.go index 478556fdb4f..6d1dd197439 100644 --- a/internal/constants.go +++ b/internal/constants.go @@ -3,5 +3,5 @@ package internal const ( // JSONSchemaVersion is the current schema version output by the JSON encoder // This is roughly following the "SchemaVer" guidelines for versioning the JSON schema. Please see schema/json/README.md for details on how to increment. - JSONSchemaVersion = "16.0.14" + JSONSchemaVersion = "16.0.15" ) diff --git a/internal/task/package_tasks.go b/internal/task/package_tasks.go index d9eca298f34..88ce35345b4 100644 --- a/internal/task/package_tasks.go +++ b/internal/task/package_tasks.go @@ -29,6 +29,7 @@ import ( "github.com/anchore/syft/syft/pkg/cataloger/rust" sbomCataloger "github.com/anchore/syft/syft/pkg/cataloger/sbom" "github.com/anchore/syft/syft/pkg/cataloger/swift" + "github.com/anchore/syft/syft/pkg/cataloger/swipl" "github.com/anchore/syft/syft/pkg/cataloger/wordpress" ) @@ -93,6 +94,7 @@ func DefaultPackageTaskFactories() PackageTaskFactories { newSimplePackageTaskFactory(rust.NewCargoLockCataloger, pkgcataloging.DeclaredTag, pkgcataloging.DirectoryTag, pkgcataloging.LanguageTag, "rust", "cargo"), newSimplePackageTaskFactory(swift.NewCocoapodsCataloger, pkgcataloging.DeclaredTag, pkgcataloging.DirectoryTag, pkgcataloging.LanguageTag, "swift", "cocoapods"), newSimplePackageTaskFactory(swift.NewSwiftPackageManagerCataloger, pkgcataloging.DeclaredTag, pkgcataloging.DirectoryTag, pkgcataloging.LanguageTag, "swift", "spm"), + newSimplePackageTaskFactory(swipl.NewSwiplPackCataloger, pkgcataloging.DeclaredTag, pkgcataloging.DirectoryTag, pkgcataloging.LanguageTag, "swipl", "pack"), // language-specific package for both image and directory scans (but not necessarily declared) //////////////////////////////////////// newSimplePackageTaskFactory(dotnet.NewDotnetPortableExecutableCataloger, pkgcataloging.DirectoryTag, pkgcataloging.InstalledTag, pkgcataloging.ImageTag, pkgcataloging.LanguageTag, "dotnet", "c#", "binary"), diff --git a/schema/json/schema-16.0.15.json b/schema/json/schema-16.0.15.json new file mode 100644 index 00000000000..1bab78aa6ba --- /dev/null +++ b/schema/json/schema-16.0.15.json @@ -0,0 +1,2582 @@ +{ + "$schema": "https://json-schema.org/draft/2020-12/schema", + "$id": "anchore.io/schema/syft/json/16.0.15/document", + "$ref": "#/$defs/Document", + "$defs": { + "AlpmDbEntry": { + "properties": { + "basepackage": { + "type": "string" + }, + "package": { + "type": "string" + }, + "version": { + "type": "string" + }, + "description": { + "type": "string" + }, + "architecture": { + "type": "string" + }, + "size": { + "type": "integer" + }, + "packager": { + "type": "string" + }, + "url": { + "type": "string" + }, + "validation": { + "type": "string" + }, + "reason": { + "type": "integer" + }, + "files": { + "items": { + "$ref": "#/$defs/AlpmFileRecord" + }, + "type": "array" + }, + "backup": { + "items": { + "$ref": "#/$defs/AlpmFileRecord" + }, + "type": "array" + }, + "provides": { + "items": { + "type": "string" + }, + "type": "array" + }, + "depends": { + "items": { + "type": "string" + }, + "type": "array" + } + }, + "type": "object", + "required": [ + "basepackage", + "package", + "version", + "description", + "architecture", + "size", + "packager", + "url", + "validation", + "reason", + "files", + "backup" + ] + }, + "AlpmFileRecord": { + "properties": { + "path": { + "type": "string" + }, + "type": { + "type": "string" + }, + "uid": { + "type": "string" + }, + "gid": { + "type": "string" + }, + "time": { + "type": "string", + "format": "date-time" + }, + "size": { + "type": "string" + }, + "link": { + "type": "string" + }, + "digest": { + "items": { + "$ref": "#/$defs/Digest" + }, + "type": "array" + } + }, + "type": "object" + }, + "ApkDbEntry": { + "properties": { + "package": { + "type": "string" + }, + "originPackage": { + "type": "string" + }, + "maintainer": { + "type": "string" + }, + "version": { + "type": "string" + }, + "architecture": { + "type": "string" + }, + "url": { + "type": "string" + }, + "description": { + "type": "string" + }, + "size": { + "type": "integer" + }, + "installedSize": { + "type": "integer" + }, + "pullDependencies": { + "items": { + "type": "string" + }, + "type": "array" + }, + "provides": { + "items": { + "type": "string" + }, + "type": "array" + }, + "pullChecksum": { + "type": "string" + }, + "gitCommitOfApkPort": { + "type": "string" + }, + "files": { + "items": { + "$ref": "#/$defs/ApkFileRecord" + }, + "type": "array" + } + }, + "type": "object", + "required": [ + "package", + "originPackage", + "maintainer", + "version", + "architecture", + "url", + "description", + "size", + "installedSize", + "pullDependencies", + "provides", + "pullChecksum", + "gitCommitOfApkPort", + "files" + ] + }, + "ApkFileRecord": { + "properties": { + "path": { + "type": "string" + }, + "ownerUid": { + "type": "string" + }, + "ownerGid": { + "type": "string" + }, + "permissions": { + "type": "string" + }, + "digest": { + "$ref": "#/$defs/Digest" + } + }, + "type": "object", + "required": [ + "path" + ] + }, + "BinarySignature": { + "properties": { + "matches": { + "items": { + "$ref": "#/$defs/ClassifierMatch" + }, + "type": "array" + } + }, + "type": "object", + "required": [ + "matches" + ] + }, + "CConanFileEntry": { + "properties": { + "ref": { + "type": "string" + } + }, + "type": "object", + "required": [ + "ref" + ] + }, + "CConanInfoEntry": { + "properties": { + "ref": { + "type": "string" + }, + "package_id": { + "type": "string" + } + }, + "type": "object", + "required": [ + "ref" + ] + }, + "CConanLockEntry": { + "properties": { + "ref": { + "type": "string" + }, + "package_id": { + "type": "string" + }, + "prev": { + "type": "string" + }, + "requires": { + "items": { + "type": "string" + }, + "type": "array" + }, + "build_requires": { + "items": { + "type": "string" + }, + "type": "array" + }, + "py_requires": { + "items": { + "type": "string" + }, + "type": "array" + }, + "options": { + "$ref": "#/$defs/KeyValues" + }, + "path": { + "type": "string" + }, + "context": { + "type": "string" + } + }, + "type": "object", + "required": [ + "ref" + ] + }, + "CConanLockV2Entry": { + "properties": { + "ref": { + "type": "string" + }, + "packageID": { + "type": "string" + }, + "username": { + "type": "string" + }, + "channel": { + "type": "string" + }, + "recipeRevision": { + "type": "string" + }, + "packageRevision": { + "type": "string" + }, + "timestamp": { + "type": "string" + } + }, + "type": "object", + "required": [ + "ref" + ] + }, + "CPE": { + "properties": { + "cpe": { + "type": "string" + }, + "source": { + "type": "string" + } + }, + "type": "object", + "required": [ + "cpe" + ] + }, + "ClassifierMatch": { + "properties": { + "classifier": { + "type": "string" + }, + "location": { + "$ref": "#/$defs/Location" + } + }, + "type": "object", + "required": [ + "classifier", + "location" + ] + }, + "CocoaPodfileLockEntry": { + "properties": { + "checksum": { + "type": "string" + } + }, + "type": "object", + "required": [ + "checksum" + ] + }, + "Coordinates": { + "properties": { + "path": { + "type": "string" + }, + "layerID": { + "type": "string" + } + }, + "type": "object", + "required": [ + "path" + ] + }, + "DartPubspecLockEntry": { + "properties": { + "name": { + "type": "string" + }, + "version": { + "type": "string" + }, + "hosted_url": { + "type": "string" + }, + "vcs_url": { + "type": "string" + } + }, + "type": "object", + "required": [ + "name", + "version" + ] + }, + "Descriptor": { + "properties": { + "name": { + "type": "string" + }, + "version": { + "type": "string" + }, + "configuration": true + }, + "type": "object", + "required": [ + "name", + "version" + ] + }, + "Digest": { + "properties": { + "algorithm": { + "type": "string" + }, + "value": { + "type": "string" + } + }, + "type": "object", + "required": [ + "algorithm", + "value" + ] + }, + "Document": { + "properties": { + "artifacts": { + "items": { + "$ref": "#/$defs/Package" + }, + "type": "array" + }, + "artifactRelationships": { + "items": { + "$ref": "#/$defs/Relationship" + }, + "type": "array" + }, + "files": { + "items": { + "$ref": "#/$defs/File" + }, + "type": "array" + }, + "source": { + "$ref": "#/$defs/Source" + }, + "distro": { + "$ref": "#/$defs/LinuxRelease" + }, + "descriptor": { + "$ref": "#/$defs/Descriptor" + }, + "schema": { + "$ref": "#/$defs/Schema" + } + }, + "type": "object", + "required": [ + "artifacts", + "artifactRelationships", + "source", + "distro", + "descriptor", + "schema" + ] + }, + "DotnetDepsEntry": { + "properties": { + "name": { + "type": "string" + }, + "version": { + "type": "string" + }, + "path": { + "type": "string" + }, + "sha512": { + "type": "string" + }, + "hashPath": { + "type": "string" + } + }, + "type": "object", + "required": [ + "name", + "version", + "path", + "sha512", + "hashPath" + ] + }, + "DotnetPortableExecutableEntry": { + "properties": { + "assemblyVersion": { + "type": "string" + }, + "legalCopyright": { + "type": "string" + }, + "comments": { + "type": "string" + }, + "internalName": { + "type": "string" + }, + "companyName": { + "type": "string" + }, + "productName": { + "type": "string" + }, + "productVersion": { + "type": "string" + } + }, + "type": "object", + "required": [ + "assemblyVersion", + "legalCopyright", + "companyName", + "productName", + "productVersion" + ] + }, + "DpkgDbEntry": { + "properties": { + "package": { + "type": "string" + }, + "source": { + "type": "string" + }, + "version": { + "type": "string" + }, + "sourceVersion": { + "type": "string" + }, + "architecture": { + "type": "string" + }, + "maintainer": { + "type": "string" + }, + "installedSize": { + "type": "integer" + }, + "provides": { + "items": { + "type": "string" + }, + "type": "array" + }, + "depends": { + "items": { + "type": "string" + }, + "type": "array" + }, + "preDepends": { + "items": { + "type": "string" + }, + "type": "array" + }, + "files": { + "items": { + "$ref": "#/$defs/DpkgFileRecord" + }, + "type": "array" + } + }, + "type": "object", + "required": [ + "package", + "source", + "version", + "sourceVersion", + "architecture", + "maintainer", + "installedSize", + "files" + ] + }, + "DpkgFileRecord": { + "properties": { + "path": { + "type": "string" + }, + "digest": { + "$ref": "#/$defs/Digest" + }, + "isConfigFile": { + "type": "boolean" + } + }, + "type": "object", + "required": [ + "path", + "isConfigFile" + ] + }, + "ELFSecurityFeatures": { + "properties": { + "symbolTableStripped": { + "type": "boolean" + }, + "stackCanary": { + "type": "boolean" + }, + "nx": { + "type": "boolean" + }, + "relRO": { + "type": "string" + }, + "pie": { + "type": "boolean" + }, + "dso": { + "type": "boolean" + }, + "safeStack": { + "type": "boolean" + }, + "cfi": { + "type": "boolean" + }, + "fortify": { + "type": "boolean" + } + }, + "type": "object", + "required": [ + "symbolTableStripped", + "nx", + "relRO", + "pie", + "dso" + ] + }, + "ElfBinaryPackageNoteJsonPayload": { + "properties": { + "type": { + "type": "string" + }, + "architecture": { + "type": "string" + }, + "osCPE": { + "type": "string" + }, + "os": { + "type": "string" + }, + "osVersion": { + "type": "string" + }, + "system": { + "type": "string" + }, + "vendor": { + "type": "string" + }, + "sourceRepo": { + "type": "string" + }, + "commit": { + "type": "string" + } + }, + "type": "object" + }, + "ElixirMixLockEntry": { + "properties": { + "name": { + "type": "string" + }, + "version": { + "type": "string" + }, + "pkgHash": { + "type": "string" + }, + "pkgHashExt": { + "type": "string" + } + }, + "type": "object", + "required": [ + "name", + "version", + "pkgHash", + "pkgHashExt" + ] + }, + "ErlangRebarLockEntry": { + "properties": { + "name": { + "type": "string" + }, + "version": { + "type": "string" + }, + "pkgHash": { + "type": "string" + }, + "pkgHashExt": { + "type": "string" + } + }, + "type": "object", + "required": [ + "name", + "version", + "pkgHash", + "pkgHashExt" + ] + }, + "Executable": { + "properties": { + "format": { + "type": "string" + }, + "hasExports": { + "type": "boolean" + }, + "hasEntrypoint": { + "type": "boolean" + }, + "importedLibraries": { + "items": { + "type": "string" + }, + "type": "array" + }, + "elfSecurityFeatures": { + "$ref": "#/$defs/ELFSecurityFeatures" + } + }, + "type": "object", + "required": [ + "format", + "hasExports", + "hasEntrypoint", + "importedLibraries" + ] + }, + "File": { + "properties": { + "id": { + "type": "string" + }, + "location": { + "$ref": "#/$defs/Coordinates" + }, + "metadata": { + "$ref": "#/$defs/FileMetadataEntry" + }, + "contents": { + "type": "string" + }, + "digests": { + "items": { + "$ref": "#/$defs/Digest" + }, + "type": "array" + }, + "licenses": { + "items": { + "$ref": "#/$defs/FileLicense" + }, + "type": "array" + }, + "executable": { + "$ref": "#/$defs/Executable" + } + }, + "type": "object", + "required": [ + "id", + "location" + ] + }, + "FileLicense": { + "properties": { + "value": { + "type": "string" + }, + "spdxExpression": { + "type": "string" + }, + "type": { + "type": "string" + }, + "evidence": { + "$ref": "#/$defs/FileLicenseEvidence" + } + }, + "type": "object", + "required": [ + "value", + "spdxExpression", + "type" + ] + }, + "FileLicenseEvidence": { + "properties": { + "confidence": { + "type": "integer" + }, + "offset": { + "type": "integer" + }, + "extent": { + "type": "integer" + } + }, + "type": "object", + "required": [ + "confidence", + "offset", + "extent" + ] + }, + "FileMetadataEntry": { + "properties": { + "mode": { + "type": "integer" + }, + "type": { + "type": "string" + }, + "linkDestination": { + "type": "string" + }, + "userID": { + "type": "integer" + }, + "groupID": { + "type": "integer" + }, + "mimeType": { + "type": "string" + }, + "size": { + "type": "integer" + } + }, + "type": "object", + "required": [ + "mode", + "type", + "userID", + "groupID", + "mimeType", + "size" + ] + }, + "GoModuleBuildinfoEntry": { + "properties": { + "goBuildSettings": { + "$ref": "#/$defs/KeyValues" + }, + "goCompiledVersion": { + "type": "string" + }, + "architecture": { + "type": "string" + }, + "h1Digest": { + "type": "string" + }, + "mainModule": { + "type": "string" + }, + "goCryptoSettings": { + "items": { + "type": "string" + }, + "type": "array" + }, + "goExperiments": { + "items": { + "type": "string" + }, + "type": "array" + } + }, + "type": "object", + "required": [ + "goCompiledVersion", + "architecture" + ] + }, + "GoModuleEntry": { + "properties": { + "h1Digest": { + "type": "string" + } + }, + "type": "object" + }, + "HaskellHackageStackEntry": { + "properties": { + "pkgHash": { + "type": "string" + } + }, + "type": "object" + }, + "HaskellHackageStackLockEntry": { + "properties": { + "pkgHash": { + "type": "string" + }, + "snapshotURL": { + "type": "string" + } + }, + "type": "object" + }, + "IDLikes": { + "items": { + "type": "string" + }, + "type": "array" + }, + "JavaArchive": { + "properties": { + "virtualPath": { + "type": "string" + }, + "manifest": { + "$ref": "#/$defs/JavaManifest" + }, + "pomProperties": { + "$ref": "#/$defs/JavaPomProperties" + }, + "pomProject": { + "$ref": "#/$defs/JavaPomProject" + }, + "digest": { + "items": { + "$ref": "#/$defs/Digest" + }, + "type": "array" + } + }, + "type": "object", + "required": [ + "virtualPath" + ] + }, + "JavaManifest": { + "properties": { + "main": { + "$ref": "#/$defs/KeyValues" + }, + "sections": { + "items": { + "$ref": "#/$defs/KeyValues" + }, + "type": "array" + } + }, + "type": "object" + }, + "JavaPomParent": { + "properties": { + "groupId": { + "type": "string" + }, + "artifactId": { + "type": "string" + }, + "version": { + "type": "string" + } + }, + "type": "object", + "required": [ + "groupId", + "artifactId", + "version" + ] + }, + "JavaPomProject": { + "properties": { + "path": { + "type": "string" + }, + "parent": { + "$ref": "#/$defs/JavaPomParent" + }, + "groupId": { + "type": "string" + }, + "artifactId": { + "type": "string" + }, + "version": { + "type": "string" + }, + "name": { + "type": "string" + }, + "description": { + "type": "string" + }, + "url": { + "type": "string" + } + }, + "type": "object", + "required": [ + "path", + "groupId", + "artifactId", + "version", + "name" + ] + }, + "JavaPomProperties": { + "properties": { + "path": { + "type": "string" + }, + "name": { + "type": "string" + }, + "groupId": { + "type": "string" + }, + "artifactId": { + "type": "string" + }, + "version": { + "type": "string" + }, + "scope": { + "type": "string" + }, + "extraFields": { + "patternProperties": { + ".*": { + "type": "string" + } + }, + "type": "object" + } + }, + "type": "object", + "required": [ + "path", + "name", + "groupId", + "artifactId", + "version" + ] + }, + "JavascriptNpmPackage": { + "properties": { + "name": { + "type": "string" + }, + "version": { + "type": "string" + }, + "author": { + "type": "string" + }, + "homepage": { + "type": "string" + }, + "description": { + "type": "string" + }, + "url": { + "type": "string" + }, + "private": { + "type": "boolean" + } + }, + "type": "object", + "required": [ + "name", + "version", + "author", + "homepage", + "description", + "url", + "private" + ] + }, + "JavascriptNpmPackageLockEntry": { + "properties": { + "resolved": { + "type": "string" + }, + "integrity": { + "type": "string" + } + }, + "type": "object", + "required": [ + "resolved", + "integrity" + ] + }, + "JavascriptYarnLockEntry": { + "properties": { + "resolved": { + "type": "string" + }, + "integrity": { + "type": "string" + } + }, + "type": "object", + "required": [ + "resolved", + "integrity" + ] + }, + "KeyValue": { + "properties": { + "key": { + "type": "string" + }, + "value": { + "type": "string" + } + }, + "type": "object", + "required": [ + "key", + "value" + ] + }, + "KeyValues": { + "items": { + "$ref": "#/$defs/KeyValue" + }, + "type": "array" + }, + "License": { + "properties": { + "value": { + "type": "string" + }, + "spdxExpression": { + "type": "string" + }, + "type": { + "type": "string" + }, + "urls": { + "items": { + "type": "string" + }, + "type": "array" + }, + "locations": { + "items": { + "$ref": "#/$defs/Location" + }, + "type": "array" + } + }, + "type": "object", + "required": [ + "value", + "spdxExpression", + "type", + "urls", + "locations" + ] + }, + "LinuxKernelArchive": { + "properties": { + "name": { + "type": "string" + }, + "architecture": { + "type": "string" + }, + "version": { + "type": "string" + }, + "extendedVersion": { + "type": "string" + }, + "buildTime": { + "type": "string" + }, + "author": { + "type": "string" + }, + "format": { + "type": "string" + }, + "rwRootFS": { + "type": "boolean" + }, + "swapDevice": { + "type": "integer" + }, + "rootDevice": { + "type": "integer" + }, + "videoMode": { + "type": "string" + } + }, + "type": "object", + "required": [ + "name", + "architecture", + "version" + ] + }, + "LinuxKernelModule": { + "properties": { + "name": { + "type": "string" + }, + "version": { + "type": "string" + }, + "sourceVersion": { + "type": "string" + }, + "path": { + "type": "string" + }, + "description": { + "type": "string" + }, + "author": { + "type": "string" + }, + "license": { + "type": "string" + }, + "kernelVersion": { + "type": "string" + }, + "versionMagic": { + "type": "string" + }, + "parameters": { + "patternProperties": { + ".*": { + "$ref": "#/$defs/LinuxKernelModuleParameter" + } + }, + "type": "object" + } + }, + "type": "object" + }, + "LinuxKernelModuleParameter": { + "properties": { + "type": { + "type": "string" + }, + "description": { + "type": "string" + } + }, + "type": "object" + }, + "LinuxRelease": { + "properties": { + "prettyName": { + "type": "string" + }, + "name": { + "type": "string" + }, + "id": { + "type": "string" + }, + "idLike": { + "$ref": "#/$defs/IDLikes" + }, + "version": { + "type": "string" + }, + "versionID": { + "type": "string" + }, + "versionCodename": { + "type": "string" + }, + "buildID": { + "type": "string" + }, + "imageID": { + "type": "string" + }, + "imageVersion": { + "type": "string" + }, + "variant": { + "type": "string" + }, + "variantID": { + "type": "string" + }, + "homeURL": { + "type": "string" + }, + "supportURL": { + "type": "string" + }, + "bugReportURL": { + "type": "string" + }, + "privacyPolicyURL": { + "type": "string" + }, + "cpeName": { + "type": "string" + }, + "supportEnd": { + "type": "string" + } + }, + "type": "object" + }, + "Location": { + "properties": { + "path": { + "type": "string" + }, + "layerID": { + "type": "string" + }, + "accessPath": { + "type": "string" + }, + "annotations": { + "patternProperties": { + ".*": { + "type": "string" + } + }, + "type": "object" + } + }, + "type": "object", + "required": [ + "path", + "accessPath" + ] + }, + "LuarocksPackage": { + "properties": { + "name": { + "type": "string" + }, + "version": { + "type": "string" + }, + "license": { + "type": "string" + }, + "homepage": { + "type": "string" + }, + "description": { + "type": "string" + }, + "url": { + "type": "string" + }, + "dependencies": { + "patternProperties": { + ".*": { + "type": "string" + } + }, + "type": "object" + } + }, + "type": "object", + "required": [ + "name", + "version", + "license", + "homepage", + "description", + "url", + "dependencies" + ] + }, + "MicrosoftKbPatch": { + "properties": { + "product_id": { + "type": "string" + }, + "kb": { + "type": "string" + } + }, + "type": "object", + "required": [ + "product_id", + "kb" + ] + }, + "NixStoreEntry": { + "properties": { + "outputHash": { + "type": "string" + }, + "output": { + "type": "string" + }, + "files": { + "items": { + "type": "string" + }, + "type": "array" + } + }, + "type": "object", + "required": [ + "outputHash", + "files" + ] + }, + "Package": { + "properties": { + "id": { + "type": "string" + }, + "name": { + "type": "string" + }, + "version": { + "type": "string" + }, + "type": { + "type": "string" + }, + "foundBy": { + "type": "string" + }, + "locations": { + "items": { + "$ref": "#/$defs/Location" + }, + "type": "array" + }, + "licenses": { + "$ref": "#/$defs/licenses" + }, + "language": { + "type": "string" + }, + "cpes": { + "$ref": "#/$defs/cpes" + }, + "purl": { + "type": "string" + }, + "metadataType": { + "type": "string" + }, + "metadata": { + "anyOf": [ + { + "type": "null" + }, + { + "$ref": "#/$defs/AlpmDbEntry" + }, + { + "$ref": "#/$defs/ApkDbEntry" + }, + { + "$ref": "#/$defs/BinarySignature" + }, + { + "$ref": "#/$defs/CConanFileEntry" + }, + { + "$ref": "#/$defs/CConanInfoEntry" + }, + { + "$ref": "#/$defs/CConanLockEntry" + }, + { + "$ref": "#/$defs/CConanLockV2Entry" + }, + { + "$ref": "#/$defs/CocoaPodfileLockEntry" + }, + { + "$ref": "#/$defs/DartPubspecLockEntry" + }, + { + "$ref": "#/$defs/DotnetDepsEntry" + }, + { + "$ref": "#/$defs/DotnetPortableExecutableEntry" + }, + { + "$ref": "#/$defs/DpkgDbEntry" + }, + { + "$ref": "#/$defs/ElfBinaryPackageNoteJsonPayload" + }, + { + "$ref": "#/$defs/ElixirMixLockEntry" + }, + { + "$ref": "#/$defs/ErlangRebarLockEntry" + }, + { + "$ref": "#/$defs/GoModuleBuildinfoEntry" + }, + { + "$ref": "#/$defs/GoModuleEntry" + }, + { + "$ref": "#/$defs/HaskellHackageStackEntry" + }, + { + "$ref": "#/$defs/HaskellHackageStackLockEntry" + }, + { + "$ref": "#/$defs/JavaArchive" + }, + { + "$ref": "#/$defs/JavascriptNpmPackage" + }, + { + "$ref": "#/$defs/JavascriptNpmPackageLockEntry" + }, + { + "$ref": "#/$defs/JavascriptYarnLockEntry" + }, + { + "$ref": "#/$defs/LinuxKernelArchive" + }, + { + "$ref": "#/$defs/LinuxKernelModule" + }, + { + "$ref": "#/$defs/LuarocksPackage" + }, + { + "$ref": "#/$defs/MicrosoftKbPatch" + }, + { + "$ref": "#/$defs/NixStoreEntry" + }, + { + "$ref": "#/$defs/PhpComposerInstalledEntry" + }, + { + "$ref": "#/$defs/PhpComposerLockEntry" + }, + { + "$ref": "#/$defs/PhpPeclEntry" + }, + { + "$ref": "#/$defs/PortageDbEntry" + }, + { + "$ref": "#/$defs/PythonPackage" + }, + { + "$ref": "#/$defs/PythonPipRequirementsEntry" + }, + { + "$ref": "#/$defs/PythonPipfileLockEntry" + }, + { + "$ref": "#/$defs/PythonPoetryLockEntry" + }, + { + "$ref": "#/$defs/RDescription" + }, + { + "$ref": "#/$defs/RpmArchive" + }, + { + "$ref": "#/$defs/RpmDbEntry" + }, + { + "$ref": "#/$defs/RubyGemspec" + }, + { + "$ref": "#/$defs/RustCargoAuditEntry" + }, + { + "$ref": "#/$defs/RustCargoLockEntry" + }, + { + "$ref": "#/$defs/SwiftPackageManagerLockEntry" + }, + { + "$ref": "#/$defs/SwiplpackPackage" + }, + { + "$ref": "#/$defs/WordpressPluginEntry" + } + ] + } + }, + "type": "object", + "required": [ + "id", + "name", + "version", + "type", + "foundBy", + "locations", + "licenses", + "language", + "cpes", + "purl" + ] + }, + "PhpComposerAuthors": { + "properties": { + "name": { + "type": "string" + }, + "email": { + "type": "string" + }, + "homepage": { + "type": "string" + } + }, + "type": "object", + "required": [ + "name" + ] + }, + "PhpComposerExternalReference": { + "properties": { + "type": { + "type": "string" + }, + "url": { + "type": "string" + }, + "reference": { + "type": "string" + }, + "shasum": { + "type": "string" + } + }, + "type": "object", + "required": [ + "type", + "url", + "reference" + ] + }, + "PhpComposerInstalledEntry": { + "properties": { + "name": { + "type": "string" + }, + "version": { + "type": "string" + }, + "source": { + "$ref": "#/$defs/PhpComposerExternalReference" + }, + "dist": { + "$ref": "#/$defs/PhpComposerExternalReference" + }, + "require": { + "patternProperties": { + ".*": { + "type": "string" + } + }, + "type": "object" + }, + "provide": { + "patternProperties": { + ".*": { + "type": "string" + } + }, + "type": "object" + }, + "require-dev": { + "patternProperties": { + ".*": { + "type": "string" + } + }, + "type": "object" + }, + "suggest": { + "patternProperties": { + ".*": { + "type": "string" + } + }, + "type": "object" + }, + "license": { + "items": { + "type": "string" + }, + "type": "array" + }, + "type": { + "type": "string" + }, + "notification-url": { + "type": "string" + }, + "bin": { + "items": { + "type": "string" + }, + "type": "array" + }, + "authors": { + "items": { + "$ref": "#/$defs/PhpComposerAuthors" + }, + "type": "array" + }, + "description": { + "type": "string" + }, + "homepage": { + "type": "string" + }, + "keywords": { + "items": { + "type": "string" + }, + "type": "array" + }, + "time": { + "type": "string" + } + }, + "type": "object", + "required": [ + "name", + "version", + "source", + "dist" + ] + }, + "PhpComposerLockEntry": { + "properties": { + "name": { + "type": "string" + }, + "version": { + "type": "string" + }, + "source": { + "$ref": "#/$defs/PhpComposerExternalReference" + }, + "dist": { + "$ref": "#/$defs/PhpComposerExternalReference" + }, + "require": { + "patternProperties": { + ".*": { + "type": "string" + } + }, + "type": "object" + }, + "provide": { + "patternProperties": { + ".*": { + "type": "string" + } + }, + "type": "object" + }, + "require-dev": { + "patternProperties": { + ".*": { + "type": "string" + } + }, + "type": "object" + }, + "suggest": { + "patternProperties": { + ".*": { + "type": "string" + } + }, + "type": "object" + }, + "license": { + "items": { + "type": "string" + }, + "type": "array" + }, + "type": { + "type": "string" + }, + "notification-url": { + "type": "string" + }, + "bin": { + "items": { + "type": "string" + }, + "type": "array" + }, + "authors": { + "items": { + "$ref": "#/$defs/PhpComposerAuthors" + }, + "type": "array" + }, + "description": { + "type": "string" + }, + "homepage": { + "type": "string" + }, + "keywords": { + "items": { + "type": "string" + }, + "type": "array" + }, + "time": { + "type": "string" + } + }, + "type": "object", + "required": [ + "name", + "version", + "source", + "dist" + ] + }, + "PhpPeclEntry": { + "properties": { + "name": { + "type": "string" + }, + "version": { + "type": "string" + }, + "license": { + "items": { + "type": "string" + }, + "type": "array" + } + }, + "type": "object", + "required": [ + "name", + "version" + ] + }, + "PortageDbEntry": { + "properties": { + "installedSize": { + "type": "integer" + }, + "files": { + "items": { + "$ref": "#/$defs/PortageFileRecord" + }, + "type": "array" + } + }, + "type": "object", + "required": [ + "installedSize", + "files" + ] + }, + "PortageFileRecord": { + "properties": { + "path": { + "type": "string" + }, + "digest": { + "$ref": "#/$defs/Digest" + } + }, + "type": "object", + "required": [ + "path" + ] + }, + "PythonDirectURLOriginInfo": { + "properties": { + "url": { + "type": "string" + }, + "commitId": { + "type": "string" + }, + "vcs": { + "type": "string" + } + }, + "type": "object", + "required": [ + "url" + ] + }, + "PythonFileDigest": { + "properties": { + "algorithm": { + "type": "string" + }, + "value": { + "type": "string" + } + }, + "type": "object", + "required": [ + "algorithm", + "value" + ] + }, + "PythonFileRecord": { + "properties": { + "path": { + "type": "string" + }, + "digest": { + "$ref": "#/$defs/PythonFileDigest" + }, + "size": { + "type": "string" + } + }, + "type": "object", + "required": [ + "path" + ] + }, + "PythonPackage": { + "properties": { + "name": { + "type": "string" + }, + "version": { + "type": "string" + }, + "author": { + "type": "string" + }, + "authorEmail": { + "type": "string" + }, + "platform": { + "type": "string" + }, + "files": { + "items": { + "$ref": "#/$defs/PythonFileRecord" + }, + "type": "array" + }, + "sitePackagesRootPath": { + "type": "string" + }, + "topLevelPackages": { + "items": { + "type": "string" + }, + "type": "array" + }, + "directUrlOrigin": { + "$ref": "#/$defs/PythonDirectURLOriginInfo" + }, + "requiresPython": { + "type": "string" + }, + "requiresDist": { + "items": { + "type": "string" + }, + "type": "array" + }, + "providesExtra": { + "items": { + "type": "string" + }, + "type": "array" + } + }, + "type": "object", + "required": [ + "name", + "version", + "author", + "authorEmail", + "platform", + "sitePackagesRootPath" + ] + }, + "PythonPipRequirementsEntry": { + "properties": { + "name": { + "type": "string" + }, + "extras": { + "items": { + "type": "string" + }, + "type": "array" + }, + "versionConstraint": { + "type": "string" + }, + "url": { + "type": "string" + }, + "markers": { + "type": "string" + } + }, + "type": "object", + "required": [ + "name", + "versionConstraint" + ] + }, + "PythonPipfileLockEntry": { + "properties": { + "hashes": { + "items": { + "type": "string" + }, + "type": "array" + }, + "index": { + "type": "string" + } + }, + "type": "object", + "required": [ + "hashes", + "index" + ] + }, + "PythonPoetryLockDependencyEntry": { + "properties": { + "name": { + "type": "string" + }, + "version": { + "type": "string" + }, + "optional": { + "type": "boolean" + }, + "markers": { + "type": "string" + }, + "extras": { + "items": { + "type": "string" + }, + "type": "array" + } + }, + "type": "object", + "required": [ + "name", + "version", + "optional" + ] + }, + "PythonPoetryLockEntry": { + "properties": { + "index": { + "type": "string" + }, + "dependencies": { + "items": { + "$ref": "#/$defs/PythonPoetryLockDependencyEntry" + }, + "type": "array" + }, + "extras": { + "items": { + "$ref": "#/$defs/PythonPoetryLockExtraEntry" + }, + "type": "array" + } + }, + "type": "object", + "required": [ + "index", + "dependencies" + ] + }, + "PythonPoetryLockExtraEntry": { + "properties": { + "name": { + "type": "string" + }, + "dependencies": { + "items": { + "type": "string" + }, + "type": "array" + } + }, + "type": "object", + "required": [ + "name", + "dependencies" + ] + }, + "RDescription": { + "properties": { + "title": { + "type": "string" + }, + "description": { + "type": "string" + }, + "author": { + "type": "string" + }, + "maintainer": { + "type": "string" + }, + "url": { + "items": { + "type": "string" + }, + "type": "array" + }, + "repository": { + "type": "string" + }, + "built": { + "type": "string" + }, + "needsCompilation": { + "type": "boolean" + }, + "imports": { + "items": { + "type": "string" + }, + "type": "array" + }, + "depends": { + "items": { + "type": "string" + }, + "type": "array" + }, + "suggests": { + "items": { + "type": "string" + }, + "type": "array" + } + }, + "type": "object" + }, + "Relationship": { + "properties": { + "parent": { + "type": "string" + }, + "child": { + "type": "string" + }, + "type": { + "type": "string" + }, + "metadata": true + }, + "type": "object", + "required": [ + "parent", + "child", + "type" + ] + }, + "RpmArchive": { + "properties": { + "name": { + "type": "string" + }, + "version": { + "type": "string" + }, + "epoch": { + "oneOf": [ + { + "type": "integer" + }, + { + "type": "null" + } + ] + }, + "architecture": { + "type": "string" + }, + "release": { + "type": "string" + }, + "sourceRpm": { + "type": "string" + }, + "size": { + "type": "integer" + }, + "vendor": { + "type": "string" + }, + "modularityLabel": { + "type": "string" + }, + "provides": { + "items": { + "type": "string" + }, + "type": "array" + }, + "requires": { + "items": { + "type": "string" + }, + "type": "array" + }, + "files": { + "items": { + "$ref": "#/$defs/RpmFileRecord" + }, + "type": "array" + } + }, + "type": "object", + "required": [ + "name", + "version", + "epoch", + "architecture", + "release", + "sourceRpm", + "size", + "vendor", + "files" + ] + }, + "RpmDbEntry": { + "properties": { + "name": { + "type": "string" + }, + "version": { + "type": "string" + }, + "epoch": { + "oneOf": [ + { + "type": "integer" + }, + { + "type": "null" + } + ] + }, + "architecture": { + "type": "string" + }, + "release": { + "type": "string" + }, + "sourceRpm": { + "type": "string" + }, + "size": { + "type": "integer" + }, + "vendor": { + "type": "string" + }, + "modularityLabel": { + "type": "string" + }, + "provides": { + "items": { + "type": "string" + }, + "type": "array" + }, + "requires": { + "items": { + "type": "string" + }, + "type": "array" + }, + "files": { + "items": { + "$ref": "#/$defs/RpmFileRecord" + }, + "type": "array" + } + }, + "type": "object", + "required": [ + "name", + "version", + "epoch", + "architecture", + "release", + "sourceRpm", + "size", + "vendor", + "files" + ] + }, + "RpmFileRecord": { + "properties": { + "path": { + "type": "string" + }, + "mode": { + "type": "integer" + }, + "size": { + "type": "integer" + }, + "digest": { + "$ref": "#/$defs/Digest" + }, + "userName": { + "type": "string" + }, + "groupName": { + "type": "string" + }, + "flags": { + "type": "string" + } + }, + "type": "object", + "required": [ + "path", + "mode", + "size", + "digest", + "userName", + "groupName", + "flags" + ] + }, + "RubyGemspec": { + "properties": { + "name": { + "type": "string" + }, + "version": { + "type": "string" + }, + "files": { + "items": { + "type": "string" + }, + "type": "array" + }, + "authors": { + "items": { + "type": "string" + }, + "type": "array" + }, + "homepage": { + "type": "string" + } + }, + "type": "object", + "required": [ + "name", + "version" + ] + }, + "RustCargoAuditEntry": { + "properties": { + "name": { + "type": "string" + }, + "version": { + "type": "string" + }, + "source": { + "type": "string" + } + }, + "type": "object", + "required": [ + "name", + "version", + "source" + ] + }, + "RustCargoLockEntry": { + "properties": { + "name": { + "type": "string" + }, + "version": { + "type": "string" + }, + "source": { + "type": "string" + }, + "checksum": { + "type": "string" + }, + "dependencies": { + "items": { + "type": "string" + }, + "type": "array" + } + }, + "type": "object", + "required": [ + "name", + "version", + "source", + "checksum", + "dependencies" + ] + }, + "Schema": { + "properties": { + "version": { + "type": "string" + }, + "url": { + "type": "string" + } + }, + "type": "object", + "required": [ + "version", + "url" + ] + }, + "Source": { + "properties": { + "id": { + "type": "string" + }, + "name": { + "type": "string" + }, + "version": { + "type": "string" + }, + "type": { + "type": "string" + }, + "metadata": true + }, + "type": "object", + "required": [ + "id", + "name", + "version", + "type", + "metadata" + ] + }, + "SwiftPackageManagerLockEntry": { + "properties": { + "revision": { + "type": "string" + } + }, + "type": "object", + "required": [ + "revision" + ] + }, + "SwiplpackPackage": { + "properties": { + "name": { + "type": "string" + }, + "version": { + "type": "string" + }, + "author": { + "type": "string" + }, + "authorEmail": { + "type": "string" + }, + "packager": { + "type": "string" + }, + "packagerEmail": { + "type": "string" + }, + "homepage": { + "type": "string" + }, + "dependencies": { + "items": { + "type": "string" + }, + "type": "array" + } + }, + "type": "object", + "required": [ + "name", + "version", + "author", + "authorEmail", + "packager", + "packagerEmail", + "homepage", + "dependencies" + ] + }, + "WordpressPluginEntry": { + "properties": { + "pluginInstallDirectory": { + "type": "string" + }, + "author": { + "type": "string" + }, + "authorUri": { + "type": "string" + } + }, + "type": "object", + "required": [ + "pluginInstallDirectory" + ] + }, + "cpes": { + "items": { + "$ref": "#/$defs/CPE" + }, + "type": "array" + }, + "licenses": { + "items": { + "$ref": "#/$defs/License" + }, + "type": "array" + } + } +} diff --git a/schema/json/schema-latest.json b/schema/json/schema-latest.json index 028f3004b6d..1bab78aa6ba 100644 --- a/schema/json/schema-latest.json +++ b/schema/json/schema-latest.json @@ -1,6 +1,6 @@ { "$schema": "https://json-schema.org/draft/2020-12/schema", - "$id": "anchore.io/schema/syft/json/16.0.14/document", + "$id": "anchore.io/schema/syft/json/16.0.15/document", "$ref": "#/$defs/Document", "$defs": { "AlpmDbEntry": { @@ -1608,6 +1608,9 @@ { "$ref": "#/$defs/SwiftPackageManagerLockEntry" }, + { + "$ref": "#/$defs/SwiplpackPackage" + }, { "$ref": "#/$defs/WordpressPluginEntry" } @@ -2504,6 +2507,48 @@ "revision" ] }, + "SwiplpackPackage": { + "properties": { + "name": { + "type": "string" + }, + "version": { + "type": "string" + }, + "author": { + "type": "string" + }, + "authorEmail": { + "type": "string" + }, + "packager": { + "type": "string" + }, + "packagerEmail": { + "type": "string" + }, + "homepage": { + "type": "string" + }, + "dependencies": { + "items": { + "type": "string" + }, + "type": "array" + } + }, + "type": "object", + "required": [ + "name", + "version", + "author", + "authorEmail", + "packager", + "packagerEmail", + "homepage", + "dependencies" + ] + }, "WordpressPluginEntry": { "properties": { "pluginInstallDirectory": { diff --git a/syft/format/internal/spdxutil/helpers/originator_supplier.go b/syft/format/internal/spdxutil/helpers/originator_supplier.go index 5840b6bae5d..61ebf36753b 100644 --- a/syft/format/internal/spdxutil/helpers/originator_supplier.go +++ b/syft/format/internal/spdxutil/helpers/originator_supplier.go @@ -103,6 +103,8 @@ func Originator(p pkg.Package) (typ string, author string) { // nolint: funlen // it seems that the vast majority of the time the author is an org, not a person typ = orgType author = metadata.Author + case pkg.SwiplPackEntry: + author = formatPersonOrOrg(metadata.Author, metadata.AuthorEmail) } if typ == "" && author != "" { @@ -144,6 +146,10 @@ func Supplier(p pkg.Package) (typ string, author string) { author = metadata.Packager } + if metadata, ok := p.Metadata.(pkg.SwiplPackEntry); ok { + author = formatPersonOrOrg(metadata.Packager, metadata.PackagerEmail) + } + if author == "" { // TODO: this uses the Originator function for now until a better distinction can be made for supplier return Originator(p) diff --git a/syft/format/internal/spdxutil/helpers/originator_supplier_test.go b/syft/format/internal/spdxutil/helpers/originator_supplier_test.go index 705d0ab9891..5c46685f2bf 100644 --- a/syft/format/internal/spdxutil/helpers/originator_supplier_test.go +++ b/syft/format/internal/spdxutil/helpers/originator_supplier_test.go @@ -40,6 +40,7 @@ func Test_OriginatorSupplier(t *testing.T) { pkg.RustBinaryAuditEntry{}, pkg.RustCargoLockEntry{}, pkg.SwiftPackageManagerResolvedEntry{}, + pkg.SwiplPackEntry{}, pkg.YarnLockEntry{}, ) tests := []struct { @@ -336,6 +337,19 @@ func Test_OriginatorSupplier(t *testing.T) { originator: "Organization: auth", supplier: "Organization: auth", }, + { + name: "from swipl pack", + input: pkg.Package{ + Metadata: pkg.SwiplPackEntry{ + Author: "auth", + AuthorEmail: "auth@auth.gov", + Packager: "me", + PackagerEmail: "me@auth.com", + }, + }, + originator: "Person: auth (auth@auth.gov)", + supplier: "Person: me (me@auth.com)", + }, } for _, test := range tests { t.Run(test.name, func(t *testing.T) { diff --git a/syft/format/internal/spdxutil/helpers/source_info.go b/syft/format/internal/spdxutil/helpers/source_info.go index a4970943a48..77057711264 100644 --- a/syft/format/internal/spdxutil/helpers/source_info.go +++ b/syft/format/internal/spdxutil/helpers/source_info.go @@ -62,6 +62,8 @@ func SourceInfo(p pkg.Package) string { answer = "acquired package info from Rockspec package file" case pkg.SwiftPkg: answer = "acquired package info from resolved Swift package manifest" + case pkg.SwiplPackPkg: + answer = "acquired package info from SWI Prolo pack package file" case pkg.GithubActionPkg, pkg.GithubActionWorkflowPkg: answer = "acquired package info from GitHub Actions workflow file or composite action file" case pkg.WordpressPluginPkg: diff --git a/syft/format/internal/spdxutil/helpers/source_info_test.go b/syft/format/internal/spdxutil/helpers/source_info_test.go index 82f89a0eaaa..df76ac7ebf4 100644 --- a/syft/format/internal/spdxutil/helpers/source_info_test.go +++ b/syft/format/internal/spdxutil/helpers/source_info_test.go @@ -263,6 +263,14 @@ func Test_SourceInfo(t *testing.T) { "from resolved Swift package manifest", }, }, + { + input: pkg.Package{ + Type: pkg.SwiplPackPkg, + }, + expected: []string{ + "acquired package info from SWI Prolo pack package file", + }, + }, { input: pkg.Package{ Type: pkg.GithubActionPkg, diff --git a/syft/internal/packagemetadata/generated.go b/syft/internal/packagemetadata/generated.go index 07d53474458..db843261cd6 100644 --- a/syft/internal/packagemetadata/generated.go +++ b/syft/internal/packagemetadata/generated.go @@ -49,6 +49,7 @@ func AllTypes() []any { pkg.RustBinaryAuditEntry{}, pkg.RustCargoLockEntry{}, pkg.SwiftPackageManagerResolvedEntry{}, + pkg.SwiplPackEntry{}, pkg.WordpressPluginEntry{}, pkg.YarnLockEntry{}, } diff --git a/syft/internal/packagemetadata/names.go b/syft/internal/packagemetadata/names.go index 97ba0a958e2..52deebce022 100644 --- a/syft/internal/packagemetadata/names.go +++ b/syft/internal/packagemetadata/names.go @@ -102,6 +102,7 @@ var jsonTypes = makeJSONTypes( jsonNames(pkg.RpmDBEntry{}, "rpm-db-entry", "RpmMetadata", "RpmdbMetadata"), jsonNamesWithoutLookup(pkg.RpmArchive{}, "rpm-archive", "RpmMetadata"), // the legacy value is split into two types, where the other is preferred jsonNames(pkg.SwiftPackageManagerResolvedEntry{}, "swift-package-manager-lock-entry", "SwiftPackageManagerMetadata"), + jsonNames(pkg.SwiplPackEntry{}, "swiplpack-package"), jsonNames(pkg.RustCargoLockEntry{}, "rust-cargo-lock-entry", "RustCargoPackageMetadata"), jsonNamesWithoutLookup(pkg.RustBinaryAuditEntry{}, "rust-cargo-audit-entry", "RustCargoPackageMetadata"), // the legacy value is split into two types, where the other is preferred jsonNames(pkg.WordpressPluginEntry{}, "wordpress-plugin-entry", "WordpressMetadata"), diff --git a/syft/internal/packagemetadata/names_test.go b/syft/internal/packagemetadata/names_test.go index 72bd3b7907d..ee73d843740 100644 --- a/syft/internal/packagemetadata/names_test.go +++ b/syft/internal/packagemetadata/names_test.go @@ -473,12 +473,6 @@ func Test_JSONName_JSONLegacyName(t *testing.T) { expectedJSONName: "rpm-archive", expectedLegacyName: "RpmMetadata", // note: conflicts with <=v11.x schema for "rpm-db-entry" metadata type }, - { - name: "SwiftPackageManagerMetadata", - metadata: pkg.SwiftPackageManagerResolvedEntry{}, - expectedJSONName: "swift-package-manager-lock-entry", - expectedLegacyName: "SwiftPackageManagerMetadata", - }, { name: "CargoPackageMetadata", metadata: pkg.RustCargoLockEntry{}, diff --git a/syft/pkg/cataloger/binary/classifier_cataloger_test.go b/syft/pkg/cataloger/binary/classifier_cataloger_test.go index 9876df49649..dcc9849c675 100644 --- a/syft/pkg/cataloger/binary/classifier_cataloger_test.go +++ b/syft/pkg/cataloger/binary/classifier_cataloger_test.go @@ -929,6 +929,17 @@ func Test_Cataloger_PositiveCases(t *testing.T) { Metadata: metadata("erlang-alpine-binary"), }, }, + { + logicalFixture: "swipl/9.3.8/linux-amd64", + expected: pkg.Package{ + Name: "swipl", + Version: "9.3.8", + Type: "binary", + PURL: "pkg:generic/swipl@9.3.8", + Locations: locations("swipl"), + Metadata: metadata("swipl-binary"), + }, + }, { logicalFixture: "nginx/1.25.1/linux-amd64", expected: pkg.Package{ diff --git a/syft/pkg/cataloger/binary/classifiers.go b/syft/pkg/cataloger/binary/classifiers.go index e2797b0471c..0d491f25feb 100644 --- a/syft/pkg/cataloger/binary/classifiers.go +++ b/syft/pkg/cataloger/binary/classifiers.go @@ -428,6 +428,16 @@ func DefaultClassifiers() []Classifier { PURL: mustPURL("pkg:generic/erlang@version"), CPEs: singleCPE("cpe:2.3:a:erlang:erlang\\/otp:*:*:*:*:*:*:*:*"), }, + { + Class: "swipl-binary", + FileGlob: "**/swipl", + EvidenceMatcher: FileContentsVersionMatcher( + `(?m)swipl-(?P[0-9]+\.[0-9]+\.[0-9]+)\/`, + ), + Package: "swipl", + PURL: mustPURL("pkg:generic/swipl@version"), + CPEs: singleCPE("cpe:2.3:a:erlang:erlang\\/otp:*:*:*:*:*:*:*:*"), + }, { Class: "consul-binary", FileGlob: "**/consul", diff --git a/syft/pkg/cataloger/binary/test-fixtures/classifiers/snippets/erlang/27.0/linux-amd64/beam.smp b/syft/pkg/cataloger/binary/test-fixtures/classifiers/snippets/erlang/27.0/linux-amd64/beam.smp new file mode 100644 index 00000000000..473d28684c1 --- /dev/null +++ b/syft/pkg/cataloger/binary/test-fixtures/classifiers/snippets/erlang/27.0/linux-amd64/beam.smp @@ -0,0 +1,9 @@ +name: beam.smp +offset: 6378906 +length: 140 +snippetSha256: 186c882decc4160bfcfbdddaee08e8364675c795d3e85697422fbd7218452ee2 +fileSha256: f84f0ffc2e397abcf5f081b865e241017b1793c2ec38f5136bff4e5e21ffdad7 + +### byte snippet to follow ### +ied by configure */ +#define ERTS_EMU_CMDLINE_FLAGS " -fno-strict-aliasing -fno-common -g -O2 -I/usr/src/otp_src_27.0/erts/x86_64-pc-linux-mu \ No newline at end of file diff --git a/syft/pkg/cataloger/binary/test-fixtures/classifiers/snippets/swipl/9.3.8/linux-amd64/swipl b/syft/pkg/cataloger/binary/test-fixtures/classifiers/snippets/swipl/9.3.8/linux-amd64/swipl new file mode 100644 index 0000000000000000000000000000000000000000..422996cd32bf2ea9a46480c03d54fab76b510b29 GIT binary patch literal 347 zcmZvXO=`n15Jqk2O3c(&*hf+NaC{ s-*<=R;6J%i>wH!HKxIw*4W*CjM5OK>-_Y($KdkrtX;_suf5rcFA8K=BVgLXD literal 0 HcmV?d00001 diff --git a/syft/pkg/cataloger/binary/test-fixtures/config.yaml b/syft/pkg/cataloger/binary/test-fixtures/config.yaml index b00fd210336..50dd6bcc8ed 100644 --- a/syft/pkg/cataloger/binary/test-fixtures/config.yaml +++ b/syft/pkg/cataloger/binary/test-fixtures/config.yaml @@ -71,6 +71,13 @@ from-images: paths: - /usr/local/lib/erlang/erts-15.0/bin/beam.smp + - version: 9.3.8 + images: + - ref: swipl:9.3.8@sha256:6a15e6a03afe943228924a5502ba763e653ff28d9b3391e2b3e1fc3e991f37d4 + platform: linux/amd64 + paths: + - /usr/lib/swipl/bin/x86_64-linux/swipl + - version: 1.21.3 images: - ref: golang:1.21.3@sha256:3ce8313c3513515040870c55e0c041a2b94f3576a58cfd3948633604214aa811 diff --git a/syft/pkg/cataloger/swipl/cataloger.go b/syft/pkg/cataloger/swipl/cataloger.go new file mode 100644 index 00000000000..be714e3c653 --- /dev/null +++ b/syft/pkg/cataloger/swipl/cataloger.go @@ -0,0 +1,15 @@ +/* +Package swipl provides a Cataloger implementation relating to packages within the SWI Prolog language ecosystem. +*/ +package swipl + +import ( + "github.com/anchore/syft/syft/pkg" + "github.com/anchore/syft/syft/pkg/cataloger/generic" +) + +// NewSwiplPackCataloger returns a new SWI Prolog Pack package manager cataloger object. +func NewSwiplPackCataloger() pkg.Cataloger { + return generic.NewCataloger("swipl-pack-cataloger"). + WithParserByGlobs(parsePackPackage, "**/pack.pl") +} diff --git a/syft/pkg/cataloger/swipl/cataloger_test.go b/syft/pkg/cataloger/swipl/cataloger_test.go new file mode 100644 index 00000000000..dbe53b4f0e1 --- /dev/null +++ b/syft/pkg/cataloger/swipl/cataloger_test.go @@ -0,0 +1,32 @@ +package swipl + +import ( + "testing" + + "github.com/anchore/syft/syft/pkg/cataloger/internal/pkgtest" +) + +func Test_Cataloger_Globs(t *testing.T) { + tests := []struct { + name string + fixture string + expected []string + }{ + { + name: "obtain swipl pack files", + fixture: "test-fixtures/glob-paths", + expected: []string{ + "pack.pl", + }, + }, + } + + for _, test := range tests { + t.Run(test.name, func(t *testing.T) { + pkgtest.NewCatalogTester(). + FromDirectory(t, test.fixture). + ExpectsResolverContentQueries(test.expected). + TestCataloger(t, NewSwiplPackCataloger()) + }) + } +} diff --git a/syft/pkg/cataloger/swipl/package.go b/syft/pkg/cataloger/swipl/package.go new file mode 100644 index 00000000000..252dda56b7f --- /dev/null +++ b/syft/pkg/cataloger/swipl/package.go @@ -0,0 +1,38 @@ +package swipl + +import ( + // "strings" + + "github.com/anchore/packageurl-go" + "github.com/anchore/syft/syft/file" + "github.com/anchore/syft/syft/pkg" +) + +func newSwiplPackPackage(m pkg.SwiplPackEntry, locations ...file.Location) pkg.Package { + p := pkg.Package{ + Name: m.Name, + Version: m.Version, + PURL: swiplpackPackageURL(m.Name, m.Version), + Locations: file.NewLocationSet(locations...), + Type: pkg.SwiplPackPkg, + Language: pkg.Swipl, + Metadata: m, + } + + p.SetID() + + return p +} + +func swiplpackPackageURL(name, version string) string { + var qualifiers packageurl.Qualifiers + + return packageurl.NewPackageURL( + "swiplpack", + "", + name, + version, + qualifiers, + "", + ).ToString() +} diff --git a/syft/pkg/cataloger/swipl/package_test.go b/syft/pkg/cataloger/swipl/package_test.go new file mode 100644 index 00000000000..a4bd0ae2d18 --- /dev/null +++ b/syft/pkg/cataloger/swipl/package_test.go @@ -0,0 +1,33 @@ +package swipl + +import ( + "testing" + + "github.com/stretchr/testify/assert" +) + +func Test_swiplpackPackageURL(t *testing.T) { + type args struct { + name string + version string + } + tests := []struct { + name string + args args + want string + }{ + { + name: "go case", + args: args{ + name: "name", + version: "v0.1.0", + }, + want: "pkg:swiplpack/name@v0.1.0", + }, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + assert.Equal(t, tt.want, swiplpackPackageURL(tt.args.name, tt.args.version)) + }) + } +} diff --git a/syft/pkg/cataloger/swipl/parse_pack.go b/syft/pkg/cataloger/swipl/parse_pack.go new file mode 100644 index 00000000000..e062da96301 --- /dev/null +++ b/syft/pkg/cataloger/swipl/parse_pack.go @@ -0,0 +1,70 @@ +package swipl + +import ( + "context" + "io" + "regexp" + + "github.com/anchore/syft/internal/log" + "github.com/anchore/syft/syft/artifact" + "github.com/anchore/syft/syft/file" + "github.com/anchore/syft/syft/pkg" + "github.com/anchore/syft/syft/pkg/cataloger/generic" +) + +func parsePackPackage(_ context.Context, _ file.Resolver, _ *generic.Environment, reader file.LocationReadCloser) ([]pkg.Package, []artifact.Relationship, error) { + var pkgs []pkg.Package + + nameRe := regexp.MustCompile(`name\(\s*'?([^')]+)'?\s*\)`) + versionRe := regexp.MustCompile(`version\('([^']+)'\)`) + homeRe := regexp.MustCompile(`home\(\s*'([^']+)'\s*\)`) + authorRe := regexp.MustCompile(`(author|packager)\(\s*'([^']+)'\s*(?:,\s*'([^']+)'\s*)?\)`) + + data, err := io.ReadAll(reader) + if err != nil { + log.WithFields("error", err).Trace("unable to parse Rockspec app") + return nil, nil, nil + } + + name := nameRe.FindSubmatch(data) + version := versionRe.FindSubmatch(data) + + if name == nil || version == nil { + log.Debugf("encountered pack.pl file without a name and/or version field, ignoring (path=%q)", reader.Path()) + return nil, nil, nil + } + + entry := pkg.SwiplPackEntry{ + Name: string(name[1]), + Version: string(version[1]), + } + + home := homeRe.FindSubmatch(data) + + if home != nil { + entry.Homepage = string(home[1]) + } + + authors := authorRe.FindAllSubmatch(data, -1) + + for _, a := range authors { + switch string(a[1]) { + case "author": + entry.Author = string(a[2]) + entry.AuthorEmail = string(a[3]) + case "packager": + entry.Packager = string(a[2]) + entry.PackagerEmail = string(a[3]) + } + } + + pkgs = append( + pkgs, + newSwiplPackPackage( + entry, + reader.Location.WithAnnotation(pkg.EvidenceAnnotationKey, pkg.PrimaryEvidenceAnnotation), + ), + ) + + return pkgs, nil, nil +} diff --git a/syft/pkg/cataloger/swipl/parse_pack_test.go b/syft/pkg/cataloger/swipl/parse_pack_test.go new file mode 100644 index 00000000000..28feb769044 --- /dev/null +++ b/syft/pkg/cataloger/swipl/parse_pack_test.go @@ -0,0 +1,39 @@ +package swipl + +import ( + "testing" + + "github.com/anchore/syft/syft/artifact" + "github.com/anchore/syft/syft/file" + "github.com/anchore/syft/syft/pkg" + "github.com/anchore/syft/syft/pkg/cataloger/internal/pkgtest" +) + +func TestParsePackPackage(t *testing.T) { + fixture := "test-fixtures/pack.pl" + locations := file.NewLocationSet(file.NewLocation(fixture)) + expectedPkgs := []pkg.Package{ + { + Name: "hdt", + Version: "0.5.2", + PURL: "pkg:swiplpack/hdt@0.5.2", + Locations: locations, + Language: pkg.Swipl, + Type: pkg.SwiplPackPkg, + Metadata: pkg.SwiplPackEntry{ + Name: "hdt", + Version: "0.5.2", + Author: "Jan Wielemaker", + AuthorEmail: "J.Wielemaker@vu.nl", + Packager: "Jan Wielemaker", + PackagerEmail: "J.Wielemaker@vu.nl", + Homepage: "https://github.com/JanWielemaker/hdt", + }, + }, + } + + // TODO: no relationships are under test yet + var expectedRelationships []artifact.Relationship + + pkgtest.TestFileParser(t, fixture, parsePackPackage, expectedPkgs, expectedRelationships) +} diff --git a/syft/pkg/cataloger/swipl/test-fixtures/glob-paths/pack.pl b/syft/pkg/cataloger/swipl/test-fixtures/glob-paths/pack.pl new file mode 100644 index 00000000000..882b6040c5d --- /dev/null +++ b/syft/pkg/cataloger/swipl/test-fixtures/glob-paths/pack.pl @@ -0,0 +1 @@ +bogus \ No newline at end of file diff --git a/syft/pkg/cataloger/swipl/test-fixtures/pack.pl b/syft/pkg/cataloger/swipl/test-fixtures/pack.pl new file mode 100644 index 00000000000..5e706f8d049 --- /dev/null +++ b/syft/pkg/cataloger/swipl/test-fixtures/pack.pl @@ -0,0 +1,10 @@ +name(hdt). +version('0.5.2'). +% TODO: swipl_version([90121]). +title('Access RDF HDT files'). +keywords(['RDF']). +author( 'Jan Wielemaker', 'J.Wielemaker@vu.nl' ). +packager( 'Jan Wielemaker', 'J.Wielemaker@vu.nl' ). +maintainer( 'Jan Wielemaker', 'J.Wielemaker@vu.nl' ). +home( 'https://github.com/JanWielemaker/hdt' ). +download( 'https://github.com/JanWielemaker/hdt/archive/V*.zip' ). diff --git a/syft/pkg/language.go b/syft/pkg/language.go index cbde8de350e..24e2de35f42 100644 --- a/syft/pkg/language.go +++ b/syft/pkg/language.go @@ -28,6 +28,7 @@ const ( Ruby Language = "ruby" Rust Language = "rust" Swift Language = "swift" + Swipl Language = "swipl" ) // AllLanguages is a set of all programming languages detected by syft. @@ -48,6 +49,7 @@ var AllLanguages = []Language{ Ruby, Rust, Swift, + Swipl, } // String returns the string representation of the language. @@ -88,6 +90,8 @@ func LanguageByName(name string) Language { return Dotnet case packageurl.TypeCocoapods, packageurl.TypeSwift, string(CocoapodsPkg): return Swift + case "swipl", string(SwiplPackPkg): + return Swipl case packageurl.TypeConan, string(CPP): return CPP case packageurl.TypeHackage, string(Haskell): diff --git a/syft/pkg/language_test.go b/syft/pkg/language_test.go index 9504c0a55d0..5519a332bbd 100644 --- a/syft/pkg/language_test.go +++ b/syft/pkg/language_test.go @@ -78,6 +78,10 @@ func TestLanguageFromPURL(t *testing.T) { purl: "pkg:swift/github.com/apple/swift-numerics/swift-numerics@1.0.2", want: Swift, }, + { + purl: "pkg:swiplpack/conditon@0.1.1", + want: Swipl, + }, { purl: "pkg:luarocks/kong@3.7.0", want: Lua, @@ -219,6 +223,10 @@ func TestLanguageByName(t *testing.T) { name: "swift", language: Swift, }, + { + name: "swiplpack", + language: Swipl, + }, { name: "pod", language: Swift, diff --git a/syft/pkg/swipl.go b/syft/pkg/swipl.go new file mode 100644 index 00000000000..b5413afb05d --- /dev/null +++ b/syft/pkg/swipl.go @@ -0,0 +1,12 @@ +package pkg + +type SwiplPackEntry struct { + Name string `toml:"name" json:"name"` + Version string `toml:"version" json:"version"` + Author string `json:"author" mapstruct:"Author"` + AuthorEmail string `json:"authorEmail" mapstruct:"Authoremail"` + Packager string `json:"packager" mapstructure:"Packager"` + PackagerEmail string `json:"packagerEmail" mapstruct:"Packageremail"` + Homepage string `json:"homepage"` + Dependencies []string `toml:"dependencies" json:"dependencies"` +} diff --git a/syft/pkg/type.go b/syft/pkg/type.go index 8b01af08bce..cdb06382863 100644 --- a/syft/pkg/type.go +++ b/syft/pkg/type.go @@ -42,6 +42,7 @@ const ( RpmPkg Type = "rpm" RustPkg Type = "rust-crate" SwiftPkg Type = "swift" + SwiplPackPkg Type = "swiplpack" WordpressPluginPkg Type = "wordpress-plugin" ) @@ -78,6 +79,7 @@ var AllPkgs = []Type{ RpmPkg, RustPkg, SwiftPkg, + SwiplPackPkg, WordpressPluginPkg, } @@ -141,6 +143,8 @@ func (t Type) PackageURLType() string { return "cargo" case SwiftPkg: return packageurl.TypeSwift + case SwiplPackPkg: + return "swiplpack" case WordpressPluginPkg: return "wordpress-plugin" default: @@ -217,6 +221,8 @@ func TypeByName(name string) Type { return Rpkg case packageurl.TypeSwift: return SwiftPkg + case "swiplpack": + return SwiplPackPkg case "wordpress-plugin": return WordpressPluginPkg default: diff --git a/syft/pkg/type_test.go b/syft/pkg/type_test.go index f1e7b275b4e..b79ad772dd1 100644 --- a/syft/pkg/type_test.go +++ b/syft/pkg/type_test.go @@ -111,6 +111,10 @@ func TestTypeFromPURL(t *testing.T) { purl: "pkg:swift/github.com/apple/swift-numerics/swift-numerics@1.0.2", expected: SwiftPkg, }, + { + purl: "pkg:swiplpack/condition@0.1.1", + expected: SwiplPackPkg, + }, } var pkgTypes []string From 05a10e8bed24d924e5e2550a394a0f837940013a Mon Sep 17 00:00:00 2001 From: Keith Zantow Date: Wed, 31 Jul 2024 20:10:17 -0400 Subject: [PATCH 043/122] chore: update release script to use gh from binny (#3084) Signed-off-by: Keith Zantow --- .github/scripts/trigger-release.sh | 21 ++++++++++++++------- 1 file changed, 14 insertions(+), 7 deletions(-) diff --git a/.github/scripts/trigger-release.sh b/.github/scripts/trigger-release.sh index c1a5432efa0..8684585b7ff 100755 --- a/.github/scripts/trigger-release.sh +++ b/.github/scripts/trigger-release.sh @@ -4,12 +4,19 @@ set -eu bold=$(tput bold) normal=$(tput sgr0) -if ! [ -x "$(command -v gh)" ]; then - echo "The GitHub CLI could not be found. To continue follow the instructions at https://github.com/cli/cli#installation" +GH_CLI=.tool/gh + +if ! [ -x "$(command -v $GH_CLI)" ]; then + echo "The GitHub CLI could not be found. run: make bootstrap" exit 1 fi -gh auth status +$GH_CLI auth status + +# set the default repo in cases where multiple remotes are defined +$GH_CLI repo set-default anchore/syft + +export GITHUB_TOKEN="${GITHUB_TOKEN-"$($GH_CLI auth token)"}" # we need all of the git state to determine the next version. Since tagging is done by # the release pipeline it is possible to not have all of the tags from previous releases. @@ -37,7 +44,7 @@ done echo "${bold}Kicking off release for ${NEXT_VERSION}${normal}..." echo -gh workflow run release.yaml -f version=${NEXT_VERSION} +$GH_CLI workflow run release.yaml -f version=${NEXT_VERSION} echo echo "${bold}Waiting for release to start...${normal}" @@ -45,6 +52,6 @@ sleep 10 set +e -echo "${bold}Head to the release workflow to monitor the release:${normal} $(gh run list --workflow=release.yaml --limit=1 --json url --jq '.[].url')" -id=$(gh run list --workflow=release.yaml --limit=1 --json databaseId --jq '.[].databaseId') -gh run watch $id --exit-status || (echo ; echo "${bold}Logs of failed step:${normal}" && GH_PAGER="" gh run view $id --log-failed) +echo "${bold}Head to the release workflow to monitor the release:${normal} $($GH_CLI run list --workflow=release.yaml --limit=1 --json url --jq '.[].url')" +id=$($GH_CLI run list --workflow=release.yaml --limit=1 --json databaseId --jq '.[].databaseId') +$GH_CLI run watch $id --exit-status || (echo ; echo "${bold}Logs of failed step:${normal}" && GH_PAGER="" $GH_CLI run view $id --log-failed) From c84cb2cf84f7b442558eb6f6e4c28141fc5f7db3 Mon Sep 17 00:00:00 2001 From: Christopher Angelo Phillips <32073428+spiffcs@users.noreply.github.com> Date: Thu, 1 Aug 2024 11:29:07 -0400 Subject: [PATCH 044/122] fix: update mainModuleVersion function to always prefix `v` to findings (#3087) * chore: basic fix Signed-off-by: Christopher Phillips <32073428+spiffcs@users.noreply.github.com> * test: make sure ldflags are prefixed with v --------- Signed-off-by: Christopher Phillips <32073428+spiffcs@users.noreply.github.com> --- syft/pkg/cataloger/golang/cataloger_test.go | 24 +++++++++---------- syft/pkg/cataloger/golang/parse_go_binary.go | 11 +++++++++ .../test-fixtures/image-small/Dockerfile | 3 +-- 3 files changed, 24 insertions(+), 14 deletions(-) diff --git a/syft/pkg/cataloger/golang/cataloger_test.go b/syft/pkg/cataloger/golang/cataloger_test.go index 0e15266586a..f958aa6577a 100644 --- a/syft/pkg/cataloger/golang/cataloger_test.go +++ b/syft/pkg/cataloger/golang/cataloger_test.go @@ -20,7 +20,7 @@ func Test_PackageCataloger_Binary(t *testing.T) { name: "simple module with dependencies", fixture: "image-small", expectedPkgs: []string{ - "anchore.io/not/real @ (devel) (/run-me)", + "anchore.io/not/real @ v1.0.0 (/run-me)", "github.com/andybalholm/brotli @ v1.0.1 (/run-me)", "github.com/dsnet/compress @ v0.0.2-0.20210315054119-f66993602bf5 (/run-me)", "github.com/golang/snappy @ v0.0.2 (/run-me)", @@ -34,17 +34,17 @@ func Test_PackageCataloger_Binary(t *testing.T) { "stdlib @ go1.22.4 (/run-me)", }, expectedRels: []string{ - "github.com/andybalholm/brotli @ v1.0.1 (/run-me) [dependency-of] anchore.io/not/real @ (devel) (/run-me)", - "github.com/dsnet/compress @ v0.0.2-0.20210315054119-f66993602bf5 (/run-me) [dependency-of] anchore.io/not/real @ (devel) (/run-me)", - "github.com/golang/snappy @ v0.0.2 (/run-me) [dependency-of] anchore.io/not/real @ (devel) (/run-me)", - "github.com/klauspost/compress @ v1.11.4 (/run-me) [dependency-of] anchore.io/not/real @ (devel) (/run-me)", - "github.com/klauspost/pgzip @ v1.2.5 (/run-me) [dependency-of] anchore.io/not/real @ (devel) (/run-me)", - "github.com/mholt/archiver/v3 @ v3.5.1 (/run-me) [dependency-of] anchore.io/not/real @ (devel) (/run-me)", - "github.com/nwaples/rardecode @ v1.1.0 (/run-me) [dependency-of] anchore.io/not/real @ (devel) (/run-me)", - "github.com/pierrec/lz4/v4 @ v4.1.2 (/run-me) [dependency-of] anchore.io/not/real @ (devel) (/run-me)", - "github.com/ulikunitz/xz @ v0.5.9 (/run-me) [dependency-of] anchore.io/not/real @ (devel) (/run-me)", - "github.com/xi2/xz @ v0.0.0-20171230120015-48954b6210f8 (/run-me) [dependency-of] anchore.io/not/real @ (devel) (/run-me)", - "stdlib @ go1.22.4 (/run-me) [dependency-of] anchore.io/not/real @ (devel) (/run-me)", + "github.com/andybalholm/brotli @ v1.0.1 (/run-me) [dependency-of] anchore.io/not/real @ v1.0.0 (/run-me)", + "github.com/dsnet/compress @ v0.0.2-0.20210315054119-f66993602bf5 (/run-me) [dependency-of] anchore.io/not/real @ v1.0.0 (/run-me)", + "github.com/golang/snappy @ v0.0.2 (/run-me) [dependency-of] anchore.io/not/real @ v1.0.0 (/run-me)", + "github.com/klauspost/compress @ v1.11.4 (/run-me) [dependency-of] anchore.io/not/real @ v1.0.0 (/run-me)", + "github.com/klauspost/pgzip @ v1.2.5 (/run-me) [dependency-of] anchore.io/not/real @ v1.0.0 (/run-me)", + "github.com/mholt/archiver/v3 @ v3.5.1 (/run-me) [dependency-of] anchore.io/not/real @ v1.0.0 (/run-me)", + "github.com/nwaples/rardecode @ v1.1.0 (/run-me) [dependency-of] anchore.io/not/real @ v1.0.0 (/run-me)", + "github.com/pierrec/lz4/v4 @ v4.1.2 (/run-me) [dependency-of] anchore.io/not/real @ v1.0.0 (/run-me)", + "github.com/ulikunitz/xz @ v0.5.9 (/run-me) [dependency-of] anchore.io/not/real @ v1.0.0 (/run-me)", + "github.com/xi2/xz @ v0.0.0-20171230120015-48954b6210f8 (/run-me) [dependency-of] anchore.io/not/real @ v1.0.0 (/run-me)", + "stdlib @ go1.22.4 (/run-me) [dependency-of] anchore.io/not/real @ v1.0.0 (/run-me)", }, }, { diff --git a/syft/pkg/cataloger/golang/parse_go_binary.go b/syft/pkg/cataloger/golang/parse_go_binary.go index 7f186ecbab7..3f62ea4d876 100644 --- a/syft/pkg/cataloger/golang/parse_go_binary.go +++ b/syft/pkg/cataloger/golang/parse_go_binary.go @@ -180,6 +180,10 @@ func (c *goBinaryCataloger) makeGoMainPackage(resolver file.Resolver, mod *exten version := c.findMainModuleVersion(metadata, gbs, reader) if version != "" { + // make sure version is prefixed with v as some build systems parsed + // during `findMainModuleVersion` can include incomplete semver + // vx.x.x is correct + version = ensurePrefix(version, "v") main.Version = version main.PURL = packageURL(main.Name, main.Version) @@ -398,3 +402,10 @@ func createMainModuleFromPath(existing *extendedBuildInfo) debug.Module { Version: devel, } } + +func ensurePrefix(s, prefix string) string { + if !strings.HasPrefix(s, prefix) { + return prefix + s + } + return s +} diff --git a/syft/pkg/cataloger/golang/test-fixtures/image-small/Dockerfile b/syft/pkg/cataloger/golang/test-fixtures/image-small/Dockerfile index be8d9378094..9bf5794dc37 100644 --- a/syft/pkg/cataloger/golang/test-fixtures/image-small/Dockerfile +++ b/syft/pkg/cataloger/golang/test-fixtures/image-small/Dockerfile @@ -7,8 +7,7 @@ COPY go.mod go.sum ./ RUN go mod download COPY main.go main.go -RUN CGO_ENABLED=0 GOOS=linux go build -o run-me . - +RUN CGO_ENABLED=0 GOOS=linux go build -ldflags "-X main.Version=1.0.0" -o run-me . FROM scratch From 48f1e975f05183390d7c01718865f5f66e3f9012 Mon Sep 17 00:00:00 2001 From: Dor Hayun <94103962+dor-hayun@users.noreply.github.com> Date: Thu, 1 Aug 2024 20:47:15 +0300 Subject: [PATCH 045/122] fix: update 'guessMainPackageNameAndVersionFromPomInfo' and 'artifactIDMatchesFilename' (#3054) - Correct retrieval of package name when main POM file exists - Address issue where wrong package name was retrieved for certain jars - Example case: 'jansi' jar containing multiple jars like 'jansi-win32' - Ensure true is returned when filename matches the artifact ID, prevent random retrieval by checking prefix and suffix - Use fallback check with suffix and prefix if no POM properties file matches the exact artifact name Signed-off-by: dor-hayun Co-authored-by: dor-hayun --- syft/pkg/cataloger/java/archive_parser.go | 15 +++++++++++++-- syft/pkg/cataloger/java/archive_parser_test.go | 2 +- 2 files changed, 14 insertions(+), 3 deletions(-) diff --git a/syft/pkg/cataloger/java/archive_parser.go b/syft/pkg/cataloger/java/archive_parser.go index 2262d79fb7c..789b3b9d3f1 100644 --- a/syft/pkg/cataloger/java/archive_parser.go +++ b/syft/pkg/cataloger/java/archive_parser.go @@ -301,11 +301,17 @@ func (j *archiveParser) guessMainPackageNameAndVersionFromPomInfo(ctx context.Co properties, _ := pomPropertiesByParentPath(j.archivePath, j.location, pomPropertyMatches) projects, _ := pomProjectByParentPath(j.archivePath, j.location, pomMatches) + // map of all the artifacts in the pom properties, in order to chek exact match with the filename + artifactsMap := make(map[string]bool) + for _, propertiesObj := range properties { + artifactsMap[propertiesObj.ArtifactID] = true + } + parentPaths := maps.Keys(properties) slices.Sort(parentPaths) for _, parentPath := range parentPaths { propertiesObj := properties[parentPath] - if artifactIDMatchesFilename(propertiesObj.ArtifactID, j.fileInfo.name) { + if artifactIDMatchesFilename(propertiesObj.ArtifactID, j.fileInfo.name, artifactsMap) { pomPropertiesObject = propertiesObj if proj, exists := projects[parentPath]; exists { pomProjectObject = proj @@ -343,10 +349,15 @@ func (j *archiveParser) guessMainPackageNameAndVersionFromPomInfo(ctx context.Co return name, version, licenses } -func artifactIDMatchesFilename(artifactID, fileName string) bool { +func artifactIDMatchesFilename(artifactID, fileName string, artifactsMap map[string]bool) bool { if artifactID == "" || fileName == "" { return false } + // Ensure true is returned when filename matches the artifact ID, prevent random retrieval by checking prefix and suffix + if _, exists := artifactsMap[fileName]; exists { + return artifactID == fileName + } + // Use fallback check with suffix and prefix if no POM properties file matches the exact artifact name return strings.HasPrefix(artifactID, fileName) || strings.HasSuffix(fileName, artifactID) } diff --git a/syft/pkg/cataloger/java/archive_parser_test.go b/syft/pkg/cataloger/java/archive_parser_test.go index 968be857862..74a2195e392 100644 --- a/syft/pkg/cataloger/java/archive_parser_test.go +++ b/syft/pkg/cataloger/java/archive_parser_test.go @@ -1156,7 +1156,7 @@ func Test_artifactIDMatchesFilename(t *testing.T) { } for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { - assert.Equal(t, tt.want, artifactIDMatchesFilename(tt.artifactID, tt.fileName)) + assert.Equal(t, tt.want, artifactIDMatchesFilename(tt.artifactID, tt.fileName, nil)) }) } } From 623532e3ed100a4d84022ea2dc94947855f2f270 Mon Sep 17 00:00:00 2001 From: "anchore-actions-token-generator[bot]" <102182147+anchore-actions-token-generator[bot]@users.noreply.github.com> Date: Fri, 2 Aug 2024 13:25:09 -0400 Subject: [PATCH 046/122] chore(deps): update tools to latest versions (#3091) Signed-off-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com> Co-authored-by: spiffcs <32073428+spiffcs@users.noreply.github.com> --- .binny.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.binny.yaml b/.binny.yaml index c5f5aeb436a..ac2f4cc10f5 100644 --- a/.binny.yaml +++ b/.binny.yaml @@ -111,7 +111,7 @@ tools: # used for triggering a release - name: gh version: - want: v2.53.0 + want: v2.54.0 method: github-release with: repo: cli/cli From cc15edca622175e89c1675a659bfa021f152cdd4 Mon Sep 17 00:00:00 2001 From: Harippriya Sivapatham <33924695+harippriyas@users.noreply.github.com> Date: Sun, 4 Aug 2024 01:30:55 +0530 Subject: [PATCH 047/122] fix: use organization for package supplier when reading Java vendor fields (#3093) Signed-off-by: Harippriya Sivapatham --- .../internal/spdxutil/helpers/originator_supplier.go | 4 ++++ .../internal/spdxutil/helpers/originator_supplier_test.go | 8 ++++---- 2 files changed, 8 insertions(+), 4 deletions(-) diff --git a/syft/format/internal/spdxutil/helpers/originator_supplier.go b/syft/format/internal/spdxutil/helpers/originator_supplier.go index 61ebf36753b..d2af96971b3 100644 --- a/syft/format/internal/spdxutil/helpers/originator_supplier.go +++ b/syft/format/internal/spdxutil/helpers/originator_supplier.go @@ -56,6 +56,10 @@ func Originator(p pkg.Package) (typ string, author string) { // nolint: funlen if author == "" { author = metadata.Manifest.Main.MustGet("Implementation-Vendor") } + // Vendor is specified, hence set 'Organization' as the PackageSupplier + if author != "" { + typ = orgType + } } case pkg.LinuxKernelModule: diff --git a/syft/format/internal/spdxutil/helpers/originator_supplier_test.go b/syft/format/internal/spdxutil/helpers/originator_supplier_test.go index 5c46685f2bf..51965925d1c 100644 --- a/syft/format/internal/spdxutil/helpers/originator_supplier_test.go +++ b/syft/format/internal/spdxutil/helpers/originator_supplier_test.go @@ -138,8 +138,8 @@ func Test_OriginatorSupplier(t *testing.T) { }, }, }, - originator: "Person: auth-spec", - supplier: "Person: auth-spec", + originator: "Organization: auth-spec", + supplier: "Organization: auth-spec", }, { name: "from java -- fallback to impl vendor in main manifest section", @@ -155,8 +155,8 @@ func Test_OriginatorSupplier(t *testing.T) { }, }, }, - originator: "Person: auth-impl", - supplier: "Person: auth-impl", + originator: "Organization: auth-impl", + supplier: "Organization: auth-impl", }, { name: "from java -- non-main manifest sections ignored", From 9d40d1152e91fd520602f159e5d02a8736cb16ac Mon Sep 17 00:00:00 2001 From: Gijs Calis <51088038+GijsCalis@users.noreply.github.com> Date: Mon, 5 Aug 2024 17:30:47 +0200 Subject: [PATCH 048/122] feat: improved java maven property resolution (#2769) Signed-off-by: Gijs Calis <51088038+GijsCalis@users.noreply.github.com> Signed-off-by: Keith Zantow Co-authored-by: Keith Zantow --- cmd/syft/internal/options/catalog.go | 3 + cmd/syft/internal/options/java.go | 38 +- syft/file/license.go | 2 +- .../internal/pkgtest/test_generic_parser.go | 5 + syft/pkg/cataloger/java/archive_parser.go | 209 +++-- .../pkg/cataloger/java/archive_parser_test.go | 211 ++--- syft/pkg/cataloger/java/cataloger.go | 7 +- syft/pkg/cataloger/java/config.go | 20 +- syft/pkg/cataloger/java/maven_repo_utils.go | 136 ---- syft/pkg/cataloger/java/maven_resolver.go | 624 +++++++++++++++ .../pkg/cataloger/java/maven_resolver_test.go | 359 +++++++++ syft/pkg/cataloger/java/maven_utils.go | 74 ++ syft/pkg/cataloger/java/maven_utils_test.go | 103 +++ syft/pkg/cataloger/java/parse_pom_xml.go | 313 +++----- syft/pkg/cataloger/java/parse_pom_xml_test.go | 738 ++++++++++-------- .../.m2/settings.xml | 4 + .../test-fixtures/pom/commons-text.pom.xml | 575 -------------- .../test-fixtures/pom/local/child-1/pom.xml | 42 + .../pom/local/commons-text-1.10.0/pom.xml | 263 +++++++ .../pom/local/contains-child-1/pom.xml | 27 + .../example-java-app-maven}/pom.xml | 0 .../test-fixtures/pom/local/parent-1/pom.xml | 51 ++ .../test-fixtures/pom/local/parent-2/pom.xml | 67 ++ .../org/child-one/1.3.6/child-one-1.3.6.pom | 41 + .../org/child-two/2.1.90/child-two-2.1.90.pom | 53 ++ .../parent-one/3.11.0/parent-one-3.11.0.pom | 51 ++ .../parent-two/13.7.8/parent-two-13.7.8.pom | 67 ++ .../parent/7.11.2}/parent-7.11.2.pom | 0 .../commons-parent/54/commons-parent-54.pom | 132 ++++ .../junit/junit-bom/5.9.0/junit-bom-5.9.0.pom | 151 ++++ .../junit/junit-bom/5.9.1/junit-bom-5.9.1.pom | 152 ++++ .../3.4.6}/opensaml-parent-3.4.6.pom | 0 syft/pkg/cataloger/swipl/package.go | 2 - syft/pkg/license.go | 2 +- 34 files changed, 3006 insertions(+), 1516 deletions(-) delete mode 100644 syft/pkg/cataloger/java/maven_repo_utils.go create mode 100644 syft/pkg/cataloger/java/maven_resolver.go create mode 100644 syft/pkg/cataloger/java/maven_resolver_test.go create mode 100644 syft/pkg/cataloger/java/maven_utils.go create mode 100644 syft/pkg/cataloger/java/maven_utils_test.go create mode 100644 syft/pkg/cataloger/java/test-fixtures/local-repository-settings/.m2/settings.xml delete mode 100644 syft/pkg/cataloger/java/test-fixtures/pom/commons-text.pom.xml create mode 100644 syft/pkg/cataloger/java/test-fixtures/pom/local/child-1/pom.xml create mode 100644 syft/pkg/cataloger/java/test-fixtures/pom/local/commons-text-1.10.0/pom.xml create mode 100644 syft/pkg/cataloger/java/test-fixtures/pom/local/contains-child-1/pom.xml rename syft/pkg/cataloger/java/test-fixtures/pom/{ => local/example-java-app-maven}/pom.xml (100%) create mode 100644 syft/pkg/cataloger/java/test-fixtures/pom/local/parent-1/pom.xml create mode 100644 syft/pkg/cataloger/java/test-fixtures/pom/local/parent-2/pom.xml create mode 100644 syft/pkg/cataloger/java/test-fixtures/pom/maven-repo/my/org/child-one/1.3.6/child-one-1.3.6.pom create mode 100644 syft/pkg/cataloger/java/test-fixtures/pom/maven-repo/my/org/child-two/2.1.90/child-two-2.1.90.pom create mode 100644 syft/pkg/cataloger/java/test-fixtures/pom/maven-repo/my/org/parent-one/3.11.0/parent-one-3.11.0.pom create mode 100644 syft/pkg/cataloger/java/test-fixtures/pom/maven-repo/my/org/parent-two/13.7.8/parent-two-13.7.8.pom rename syft/pkg/cataloger/java/test-fixtures/{maven-xml-responses => pom/maven-repo/net/shibboleth/parent/7.11.2}/parent-7.11.2.pom (100%) create mode 100644 syft/pkg/cataloger/java/test-fixtures/pom/maven-repo/org/apache/commons/commons-parent/54/commons-parent-54.pom create mode 100644 syft/pkg/cataloger/java/test-fixtures/pom/maven-repo/org/junit/junit-bom/5.9.0/junit-bom-5.9.0.pom create mode 100644 syft/pkg/cataloger/java/test-fixtures/pom/maven-repo/org/junit/junit-bom/5.9.1/junit-bom-5.9.1.pom rename syft/pkg/cataloger/java/test-fixtures/{maven-xml-responses => pom/maven-repo/org/opensaml/opensaml-parent/3.4.6}/opensaml-parent-3.4.6.pom (100%) diff --git a/cmd/syft/internal/options/catalog.go b/cmd/syft/internal/options/catalog.go index 290a1d28e70..99359abec51 100644 --- a/cmd/syft/internal/options/catalog.go +++ b/cmd/syft/internal/options/catalog.go @@ -64,6 +64,7 @@ func DefaultCatalog() Catalog { Package: defaultPackageConfig(), LinuxKernel: defaultLinuxKernelConfig(), Golang: defaultGolangConfig(), + Java: defaultJavaConfig(), File: defaultFileConfig(), Relationships: defaultRelationshipsConfig(), Source: defaultSourceConfig(), @@ -150,6 +151,8 @@ func (cfg Catalog) ToPackagesConfig() pkgcataloging.Config { GuessUnpinnedRequirements: cfg.Python.GuessUnpinnedRequirements, }, JavaArchive: java.DefaultArchiveCatalogerConfig(). + WithUseMavenLocalRepository(cfg.Java.UseMavenLocalRepository). + WithMavenLocalRepositoryDir(cfg.Java.MavenLocalRepositoryDir). WithUseNetwork(cfg.Java.UseNetwork). WithMavenBaseURL(cfg.Java.MavenURL). WithArchiveTraversal(archiveSearch, cfg.Java.MaxParentRecursiveDepth), diff --git a/cmd/syft/internal/options/java.go b/cmd/syft/internal/options/java.go index 79b0fd12771..8894c760b75 100644 --- a/cmd/syft/internal/options/java.go +++ b/cmd/syft/internal/options/java.go @@ -1,24 +1,46 @@ package options -import "github.com/anchore/clio" +import ( + "github.com/anchore/clio" + "github.com/anchore/syft/syft/pkg/cataloger/java" +) type javaConfig struct { UseNetwork bool `yaml:"use-network" json:"use-network" mapstructure:"use-network"` + UseMavenLocalRepository bool `yaml:"use-maven-local-repository" json:"use-maven-local-repository" mapstructure:"use-maven-local-repository"` + MavenLocalRepositoryDir string `yaml:"maven-local-repository-dir" json:"maven-local-repository-dir" mapstructure:"maven-local-repository-dir"` MavenURL string `yaml:"maven-url" json:"maven-url" mapstructure:"maven-url"` MaxParentRecursiveDepth int `yaml:"max-parent-recursive-depth" json:"max-parent-recursive-depth" mapstructure:"max-parent-recursive-depth"` } +func defaultJavaConfig() javaConfig { + def := java.DefaultArchiveCatalogerConfig() + + return javaConfig{ + UseNetwork: def.UseNetwork, + MaxParentRecursiveDepth: def.MaxParentRecursiveDepth, + UseMavenLocalRepository: def.UseMavenLocalRepository, + MavenLocalRepositoryDir: def.MavenLocalRepositoryDir, + MavenURL: def.MavenBaseURL, + } +} + var _ interface { clio.FieldDescriber } = (*javaConfig)(nil) func (o *javaConfig) DescribeFields(descriptions clio.FieldDescriptionSet) { - descriptions.Add(&o.UseNetwork, `enables Syft to use the network to fill in more detailed information about artifacts -currently this enables searching maven-url for license data -when running across pom.xml files that could have more information, syft will -explicitly search maven for license information by querying the online pom when this is true -this option is helpful for when the parent pom has more data, -that is not accessible from within the final built artifact`) + descriptions.Add(&o.UseNetwork, `enables Syft to use the network to fetch version and license information for packages when +a parent or imported pom file is not found in the local maven repository. +the pom files are downloaded from the remote Maven repository at 'maven-url'`) descriptions.Add(&o.MavenURL, `maven repository to use, defaults to Maven central`) - descriptions.Add(&o.MaxParentRecursiveDepth, `depth to recursively resolve parent POMs`) + descriptions.Add(&o.MaxParentRecursiveDepth, `depth to recursively resolve parent POMs, no limit if <= 0`) + descriptions.Add(&o.UseMavenLocalRepository, `use the local Maven repository to retrieve pom files. When Maven is installed and was previously used +for building the software that is being scanned, then most pom files will be available in this +repository on the local file system. this greatly speeds up scans. when all pom files are available +in the local repository, then 'use-network' is not needed. +TIP: If you want to download all required pom files to the local repository without running a full +build, run 'mvn help:effective-pom' before performing the scan with syft.`) + descriptions.Add(&o.MavenLocalRepositoryDir, `override the default location of the local Maven repository. +the default is the subdirectory '.m2/repository' in your home directory`) } diff --git a/syft/file/license.go b/syft/file/license.go index 12d487d540c..08d77e052e8 100644 --- a/syft/file/license.go +++ b/syft/file/license.go @@ -21,7 +21,7 @@ type LicenseEvidence struct { func NewLicense(value string) License { spdxExpression, err := license.ParseExpression(value) if err != nil { - log.Trace("unable to parse license expression: %s, %w", value, err) + log.WithFields("error", err, "value", value).Trace("unable to parse license expression") } return License{ diff --git a/syft/pkg/cataloger/internal/pkgtest/test_generic_parser.go b/syft/pkg/cataloger/internal/pkgtest/test_generic_parser.go index a3cf11dece8..2dcbb7f8bec 100644 --- a/syft/pkg/cataloger/internal/pkgtest/test_generic_parser.go +++ b/syft/pkg/cataloger/internal/pkgtest/test_generic_parser.go @@ -310,6 +310,11 @@ func TestFileParser(t *testing.T, fixturePath string, parser generic.Parser, exp NewCatalogTester().FromFile(t, fixturePath).Expects(expectedPkgs, expectedRelationships).TestParser(t, parser) } +func TestCataloger(t *testing.T, fixtureDir string, cataloger pkg.Cataloger, expectedPkgs []pkg.Package, expectedRelationships []artifact.Relationship) { + t.Helper() + NewCatalogTester().FromDirectory(t, fixtureDir).Expects(expectedPkgs, expectedRelationships).TestCataloger(t, cataloger) +} + func TestFileParserWithEnv(t *testing.T, fixturePath string, parser generic.Parser, env *generic.Environment, expectedPkgs []pkg.Package, expectedRelationships []artifact.Relationship) { t.Helper() diff --git a/syft/pkg/cataloger/java/archive_parser.go b/syft/pkg/cataloger/java/archive_parser.go index 789b3b9d3f1..663563c613d 100644 --- a/syft/pkg/cataloger/java/archive_parser.go +++ b/syft/pkg/cataloger/java/archive_parser.go @@ -9,8 +9,10 @@ import ( "slices" "strings" + "github.com/vifraa/gopom" "golang.org/x/exp/maps" + "github.com/anchore/syft/internal" intFile "github.com/anchore/syft/internal/file" "github.com/anchore/syft/internal/licenses" "github.com/anchore/syft/internal/log" @@ -52,6 +54,7 @@ type archiveParser struct { fileInfo archiveFilename detectNested bool cfg ArchiveCatalogerConfig + maven *mavenResolver } type genericArchiveParserAdapter struct { @@ -106,6 +109,7 @@ func newJavaArchiveParser(reader file.LocationReadCloser, detectNested bool, cfg fileInfo: newJavaArchiveFilename(currentFilepath), detectNested: detectNested, cfg: cfg, + maven: newMavenResolver(nil, cfg), }, cleanupFn, nil } @@ -197,7 +201,7 @@ func (j *archiveParser) discoverMainPackage(ctx context.Context) (*pkg.Package, return nil, err } - licenses, name, version, err := j.parseLicenses(ctx, manifest) + name, version, licenses, err := j.discoverNameVersionLicense(ctx, manifest) if err != nil { return nil, err } @@ -220,7 +224,7 @@ func (j *archiveParser) discoverMainPackage(ctx context.Context) (*pkg.Package, }, nil } -func (j *archiveParser) parseLicenses(ctx context.Context, manifest *pkg.JavaManifest) ([]pkg.License, string, string, error) { +func (j *archiveParser) discoverNameVersionLicense(ctx context.Context, manifest *pkg.JavaManifest) (string, string, []pkg.License, error) { // we use j.location because we want to associate the license declaration with where we discovered the contents in the manifest // TODO: when we support locations of paths within archives we should start passing the specific manifest location object instead of the top jar licenses := pkg.NewLicensesFromLocation(j.location, selectLicenses(manifest)...) @@ -231,24 +235,18 @@ func (j *archiveParser) parseLicenses(ctx context.Context, manifest *pkg.JavaMan 3. manifest 4. filename */ - name, version, pomLicenses := j.guessMainPackageNameAndVersionFromPomInfo(ctx) - if name == "" { - name = selectName(manifest, j.fileInfo) + groupID, artifactID, version, parsedPom := j.discoverMainPackageFromPomInfo(ctx) + if artifactID == "" { + artifactID = selectName(manifest, j.fileInfo) } if version == "" { version = selectVersion(manifest, j.fileInfo) } - if len(licenses) == 0 { - // Today we don't have a way to distinguish between licenses from the manifest and licenses from the pom.xml - // until the file.Location object can support sub-paths (i.e. paths within archives, recursively; issue https://github.com/anchore/syft/issues/2211). - // Until then it's less confusing to use the licenses from the pom.xml only if the manifest did not list any. - licenses = append(licenses, pomLicenses...) - } if len(licenses) == 0 { fileLicenses, err := j.getLicenseFromFileInArchive() if err != nil { - return nil, "", "", err + return "", "", nil, err } if fileLicenses != nil { licenses = append(licenses, fileLicenses...) @@ -256,50 +254,73 @@ func (j *archiveParser) parseLicenses(ctx context.Context, manifest *pkg.JavaMan } // If we didn't find any licenses in the archive so far, we'll try again in Maven Central using groupIDFromJavaMetadata - if len(licenses) == 0 && j.cfg.UseNetwork { - licenses = findLicenseFromJavaMetadata(ctx, name, manifest, version, j, licenses) + if len(licenses) == 0 { + // Today we don't have a way to distinguish between licenses from the manifest and licenses from the pom.xml + // until the file.Location object can support sub-paths (i.e. paths within archives, recursively; issue https://github.com/anchore/syft/issues/2211). + // Until then it's less confusing to use the licenses from the pom.xml only if the manifest did not list any. + licenses = j.findLicenseFromJavaMetadata(ctx, groupID, artifactID, version, parsedPom, manifest) } - return licenses, name, version, nil + return artifactID, version, licenses, nil } -func findLicenseFromJavaMetadata(ctx context.Context, name string, manifest *pkg.JavaManifest, version string, j *archiveParser, licenses []pkg.License) []pkg.License { - var groupID = name - if gID := groupIDFromJavaMetadata(name, pkg.JavaArchive{Manifest: manifest}); gID != "" { - groupID = gID +// findLicenseFromJavaMetadata attempts to find license information from all available maven metadata properties and pom info +func (j *archiveParser) findLicenseFromJavaMetadata(ctx context.Context, groupID, artifactID, version string, parsedPom *parsedPomProject, manifest *pkg.JavaManifest) []pkg.License { + if groupID == "" { + if gID := groupIDFromJavaMetadata(artifactID, pkg.JavaArchive{Manifest: manifest}); gID != "" { + groupID = gID + } + } + + var err error + var pomLicenses []gopom.License + if parsedPom != nil { + pomLicenses, err = j.maven.resolveLicenses(ctx, parsedPom.project) + if err != nil { + log.WithFields("error", err, "mavenID", j.maven.resolveMavenID(ctx, parsedPom.project)).Debug("error attempting to resolve pom licenses") + } + } + + if err == nil && len(pomLicenses) == 0 { + pomLicenses, err = j.maven.findLicenses(ctx, groupID, artifactID, version) + if err != nil { + log.WithFields("error", err, "mavenID", mavenID{groupID, artifactID, version}).Debug("error attempting to find licenses") + } } - pomLicenses := recursivelyFindLicensesFromParentPom(ctx, groupID, name, version, j.cfg) if len(pomLicenses) == 0 { // Try removing the last part of the groupId, as sometimes it duplicates the artifactId packages := strings.Split(groupID, ".") groupID = strings.Join(packages[:len(packages)-1], ".") - pomLicenses = recursivelyFindLicensesFromParentPom(ctx, groupID, name, version, j.cfg) + pomLicenses, err = j.maven.findLicenses(ctx, groupID, artifactID, version) + if err != nil { + log.WithFields("error", err, "mavenID", mavenID{groupID, artifactID, version}).Debug("error attempting to find sub-group licenses") + } } - if len(pomLicenses) > 0 { - pkgLicenses := pkg.NewLicensesFromLocation(j.location, pomLicenses...) - if pkgLicenses != nil { - licenses = append(licenses, pkgLicenses...) - } + return toPkgLicenses(&j.location, pomLicenses) +} + +func toPkgLicenses(location *file.Location, licenses []gopom.License) []pkg.License { + var out []pkg.License + for _, license := range licenses { + out = append(out, pkg.NewLicenseFromFields(deref(license.Name), deref(license.URL), location)) } - return licenses + return out } type parsedPomProject struct { - *pkg.JavaPomProject - Licenses []pkg.License + path string + project *gopom.Project } -func (j *archiveParser) guessMainPackageNameAndVersionFromPomInfo(ctx context.Context) (name, version string, licenses []pkg.License) { - pomPropertyMatches := j.fileManifest.GlobMatch(false, pomPropertiesGlob) - pomMatches := j.fileManifest.GlobMatch(false, pomXMLGlob) - var pomPropertiesObject pkg.JavaPomProperties - var pomProjectObject *parsedPomProject +// discoverMainPackageFromPomInfo attempts to resolve maven groupId, artifactId, version and other info from found pom information +func (j *archiveParser) discoverMainPackageFromPomInfo(ctx context.Context) (group, name, version string, parsedPom *parsedPomProject) { + var pomProperties pkg.JavaPomProperties // Find the pom.properties/pom.xml if the names seem like a plausible match - properties, _ := pomPropertiesByParentPath(j.archivePath, j.location, pomPropertyMatches) - projects, _ := pomProjectByParentPath(j.archivePath, j.location, pomMatches) + properties, _ := pomPropertiesByParentPath(j.archivePath, j.location, j.fileManifest.GlobMatch(false, pomPropertiesGlob)) + projects, _ := pomProjectByParentPath(j.archivePath, j.location, j.fileManifest.GlobMatch(false, pomXMLGlob)) // map of all the artifacts in the pom properties, in order to chek exact match with the filename artifactsMap := make(map[string]bool) @@ -312,41 +333,32 @@ func (j *archiveParser) guessMainPackageNameAndVersionFromPomInfo(ctx context.Co for _, parentPath := range parentPaths { propertiesObj := properties[parentPath] if artifactIDMatchesFilename(propertiesObj.ArtifactID, j.fileInfo.name, artifactsMap) { - pomPropertiesObject = propertiesObj + pomProperties = propertiesObj if proj, exists := projects[parentPath]; exists { - pomProjectObject = proj + parsedPom = proj break } } } - name = pomPropertiesObject.ArtifactID - if name == "" && pomProjectObject != nil { - name = pomProjectObject.ArtifactID - } - version = pomPropertiesObject.Version - if version == "" && pomProjectObject != nil { - version = pomProjectObject.Version - } - if j.cfg.UseNetwork { - if pomProjectObject == nil { - // If we have no pom.xml, check maven central using pom.properties - parentLicenses := recursivelyFindLicensesFromParentPom(ctx, pomPropertiesObject.GroupID, pomPropertiesObject.ArtifactID, pomPropertiesObject.Version, j.cfg) - if len(parentLicenses) > 0 { - for _, licenseName := range parentLicenses { - licenses = append(licenses, pkg.NewLicenseFromFields(licenseName, "", nil)) - } - } - } else { - findPomLicenses(ctx, pomProjectObject, j.cfg) - } - } + group = pomProperties.GroupID + name = pomProperties.ArtifactID + version = pomProperties.Version - if pomProjectObject != nil { - licenses = pomProjectObject.Licenses + if parsedPom != nil && parsedPom.project != nil { + id := j.maven.resolveMavenID(ctx, parsedPom.project) + if group == "" { + group = id.GroupID + } + if name == "" { + name = id.ArtifactID + } + if version == "" { + version = id.Version + } } - return name, version, licenses + return group, name, version, parsedPom } func artifactIDMatchesFilename(artifactID, fileName string, artifactsMap map[string]bool) bool { @@ -361,24 +373,6 @@ func artifactIDMatchesFilename(artifactID, fileName string, artifactsMap map[str return strings.HasPrefix(artifactID, fileName) || strings.HasSuffix(fileName, artifactID) } -func findPomLicenses(ctx context.Context, pomProjectObject *parsedPomProject, cfg ArchiveCatalogerConfig) { - // If we don't have any licenses until now, and if we have a parent Pom, then we'll check the parent pom in maven central for licenses. - if pomProjectObject != nil && pomProjectObject.Parent != nil && len(pomProjectObject.Licenses) == 0 { - parentLicenses := recursivelyFindLicensesFromParentPom( - ctx, - pomProjectObject.Parent.GroupID, - pomProjectObject.Parent.ArtifactID, - pomProjectObject.Parent.Version, - cfg) - - if len(parentLicenses) > 0 { - for _, licenseName := range parentLicenses { - pomProjectObject.Licenses = append(pomProjectObject.Licenses, pkg.NewLicenseFromFields(licenseName, "", nil)) - } - } - } -} - // discoverPkgsFromAllMavenFiles parses Maven POM properties/xml for a given // parent package, returning all listed Java packages found for each pom // properties discovered and potentially updating the given parentPkg with new @@ -403,12 +397,12 @@ func (j *archiveParser) discoverPkgsFromAllMavenFiles(ctx context.Context, paren } for parentPath, propertiesObj := range properties { - var pomProject *parsedPomProject + var parsedPom *parsedPomProject if proj, exists := projects[parentPath]; exists { - pomProject = proj + parsedPom = proj } - pkgFromPom := newPackageFromMavenData(ctx, propertiesObj, pomProject, parentPkg, j.location, j.cfg) + pkgFromPom := newPackageFromMavenData(ctx, j.maven, propertiesObj, parsedPom, parentPkg, j.location) if pkgFromPom != nil { pkgs = append(pkgs, *pkgFromPom) } @@ -422,7 +416,7 @@ func getDigestsFromArchive(archivePath string) ([]file.Digest, error) { if err != nil { return nil, fmt.Errorf("unable to open archive path (%s): %w", archivePath, err) } - defer archiveCloser.Close() + defer internal.CloseAndLogError(archiveCloser, archivePath) // grab and assign digest for the entire archive digests, err := intFile.NewDigestsFromFile(archiveCloser, javaArchiveHashes) @@ -576,30 +570,26 @@ func pomProjectByParentPath(archivePath string, location file.Location, extractP projectByParentPath := make(map[string]*parsedPomProject) for filePath, fileContents := range contentsOfMavenProjectFiles { // TODO: when we support locations of paths within archives we should start passing the specific pom.xml location object instead of the top jar - pomProject, err := parsePomXMLProject(filePath, strings.NewReader(fileContents), location) + pom, err := decodePomXML(strings.NewReader(fileContents)) if err != nil { log.WithFields("contents-path", filePath, "location", location.Path()).Warnf("failed to parse pom.xml: %+v", err) continue } - - if pomProject == nil { + if pom == nil { continue } - // If we don't have a version, then maybe the parent pom has it... - if (pomProject.Parent == nil && pomProject.Version == "") || pomProject.ArtifactID == "" { - // TODO: if there is no parentPkg (no java manifest) one of these poms could be the parent. We should discover the right parent and attach the correct info accordingly to each discovered package - continue + projectByParentPath[path.Dir(filePath)] = &parsedPomProject{ + path: filePath, + project: pom, } - - projectByParentPath[path.Dir(filePath)] = pomProject } return projectByParentPath, nil } // newPackageFromMavenData processes a single Maven POM properties for a given parent package, returning all listed Java packages found and // associating each discovered package to the given parent package. Note the pom.xml is optional, the pom.properties is not. -func newPackageFromMavenData(ctx context.Context, pomProperties pkg.JavaPomProperties, parsedPomProject *parsedPomProject, parentPkg *pkg.Package, location file.Location, cfg ArchiveCatalogerConfig) *pkg.Package { +func newPackageFromMavenData(ctx context.Context, r *mavenResolver, pomProperties pkg.JavaPomProperties, parsedPom *parsedPomProject, parentPkg *pkg.Package, location file.Location) *pkg.Package { // keep the artifact name within the virtual path if this package does not match the parent package vPathSuffix := "" groupID := "" @@ -622,25 +612,24 @@ func newPackageFromMavenData(ctx context.Context, pomProperties pkg.JavaPomPrope virtualPath := location.Path() + vPathSuffix var pkgPomProject *pkg.JavaPomProject - licenses := make([]pkg.License, 0) - if cfg.UseNetwork { - if parsedPomProject == nil { - // If we have no pom.xml, check maven central using pom.properties - parentLicenses := recursivelyFindLicensesFromParentPom(ctx, pomProperties.GroupID, pomProperties.ArtifactID, pomProperties.Version, cfg) - if len(parentLicenses) > 0 { - for _, licenseName := range parentLicenses { - licenses = append(licenses, pkg.NewLicenseFromFields(licenseName, "", nil)) - } - } - } else { - findPomLicenses(ctx, parsedPomProject, cfg) - } + var err error + var pomLicenses []gopom.License + if parsedPom == nil { + // If we have no pom.xml, check maven central using pom.properties + pomLicenses, err = r.findLicenses(ctx, pomProperties.GroupID, pomProperties.ArtifactID, pomProperties.Version) + } else { + pkgPomProject = newPomProject(ctx, r, parsedPom.path, parsedPom.project) + pomLicenses, err = r.resolveLicenses(ctx, parsedPom.project) + } + + if err != nil { + log.WithFields("error", err, "mavenID", mavenID{pomProperties.GroupID, pomProperties.ArtifactID, pomProperties.Version}).Debug("error attempting to resolve licenses") } - if parsedPomProject != nil { - pkgPomProject = parsedPomProject.JavaPomProject - licenses = append(licenses, parsedPomProject.Licenses...) + licenses := make([]pkg.License, 0) + for _, license := range pomLicenses { + licenses = append(licenses, pkg.NewLicenseFromFields(deref(license.Name), deref(license.URL), &location)) } p := pkg.Package{ diff --git a/syft/pkg/cataloger/java/archive_parser_test.go b/syft/pkg/cataloger/java/archive_parser_test.go index 74a2195e392..ccddc8c7528 100644 --- a/syft/pkg/cataloger/java/archive_parser_test.go +++ b/syft/pkg/cataloger/java/archive_parser_test.go @@ -5,8 +5,6 @@ import ( "context" "fmt" "io" - "net/http" - "net/http/httptest" "os" "os/exec" "path/filepath" @@ -20,6 +18,7 @@ import ( "github.com/scylladb/go-set/strset" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" + "github.com/vifraa/gopom" "github.com/anchore/syft/syft/artifact" "github.com/anchore/syft/syft/file" @@ -28,61 +27,14 @@ import ( "github.com/anchore/syft/syft/pkg/cataloger/internal/pkgtest" ) -func generateJavaBuildFixture(t *testing.T, fixturePath string) { - if _, err := os.Stat(fixturePath); !os.IsNotExist(err) { - // fixture already exists... - return - } - - makeTask := strings.TrimPrefix(fixturePath, "test-fixtures/java-builds/") - t.Logf(color.Bold.Sprintf("Generating Fixture from 'make %s'", makeTask)) - - cwd, err := os.Getwd() - if err != nil { - t.Errorf("unable to get cwd: %+v", err) - } - - cmd := exec.Command("make", makeTask) - cmd.Dir = filepath.Join(cwd, "test-fixtures/java-builds/") - - run(t, cmd) -} - -func generateMockMavenHandler(responseFixture string) func(w http.ResponseWriter, r *http.Request) { - return func(w http.ResponseWriter, r *http.Request) { - w.WriteHeader(http.StatusOK) - // Set the Content-Type header to indicate that the response is XML - w.Header().Set("Content-Type", "application/xml") - // Copy the file's content to the response writer - file, err := os.Open(responseFixture) - if err != nil { - http.Error(w, err.Error(), http.StatusInternalServerError) - return - } - defer file.Close() - _, err = io.Copy(w, file) - if err != nil { - http.Error(w, err.Error(), http.StatusInternalServerError) - return - } - } -} - -type handlerPath struct { - path string - handler func(w http.ResponseWriter, r *http.Request) -} - func TestSearchMavenForLicenses(t *testing.T) { - mux, url, teardown := setup() - defer teardown() + url := mockMavenRepo(t) + tests := []struct { name string fixture string detectNested bool config ArchiveCatalogerConfig - requestPath string - requestHandlers []handlerPath expectedLicenses []pkg.License }{ { @@ -91,23 +43,16 @@ func TestSearchMavenForLicenses(t *testing.T) { detectNested: false, config: ArchiveCatalogerConfig{ UseNetwork: true, + UseMavenLocalRepository: false, MavenBaseURL: url, - MaxParentRecursiveDepth: 2, - }, - requestHandlers: []handlerPath{ - { - path: "/org/opensaml/opensaml-parent/3.4.6/opensaml-parent-3.4.6.pom", - handler: generateMockMavenHandler("test-fixtures/maven-xml-responses/opensaml-parent-3.4.6.pom"), - }, - { - path: "/net/shibboleth/parent/7.11.2/parent-7.11.2.pom", - handler: generateMockMavenHandler("test-fixtures/maven-xml-responses/parent-7.11.2.pom"), - }, }, expectedLicenses: []pkg.License{ { - Type: license.Declared, - Value: `The Apache Software License, Version 2.0`, + Type: license.Declared, + Value: `The Apache Software License, Version 2.0`, + URLs: []string{ + "http://www.apache.org/licenses/LICENSE-2.0.txt", + }, SPDXExpression: ``, }, }, @@ -116,11 +61,6 @@ func TestSearchMavenForLicenses(t *testing.T) { for _, tc := range tests { t.Run(tc.name, func(t *testing.T) { - // configure maven central requests - for _, hdlr := range tc.requestHandlers { - mux.HandleFunc(hdlr.path, hdlr.handler) - } - // setup metadata fixture; note: // this fixture has a pomProjectObject and has a parent object // it has no licenses on either which is the condition for testing @@ -138,34 +78,9 @@ func TestSearchMavenForLicenses(t *testing.T) { defer cleanupFn() // assert licenses are discovered from upstream - _, _, licenses := ap.guessMainPackageNameAndVersionFromPomInfo(context.Background()) - assert.Equal(t, tc.expectedLicenses, licenses) - }) - } -} - -func TestFormatMavenURL(t *testing.T) { - tests := []struct { - name string - groupID string - artifactID string - version string - expected string - }{ - { - name: "formatMavenURL correctly assembles the pom URL", - groupID: "org.springframework.boot", - artifactID: "spring-boot-starter-test", - version: "3.1.5", - expected: "https://repo1.maven.org/maven2/org/springframework/boot/spring-boot-starter-test/3.1.5/spring-boot-starter-test-3.1.5.pom", - }, - } - - for _, tc := range tests { - t.Run(tc.name, func(t *testing.T) { - requestURL, err := formatMavenPomURL(tc.groupID, tc.artifactID, tc.version, mavenBaseURL) - assert.NoError(t, err, "expected no err; got %w", err) - assert.Equal(t, tc.expected, requestURL) + _, _, _, parsedPom := ap.discoverMainPackageFromPomInfo(context.Background()) + licenses, _ := ap.maven.resolveLicenses(context.Background(), parsedPom.project) + assert.Equal(t, tc.expectedLicenses, toPkgLicenses(nil, licenses)) }) } } @@ -424,10 +339,14 @@ func TestParseJar(t *testing.T) { test.expected[k] = p } + cfg := ArchiveCatalogerConfig{ + UseNetwork: false, + UseMavenLocalRepository: false, + } parser, cleanupFn, err := newJavaArchiveParser(file.LocationReadCloser{ Location: file.NewLocation(fixture.Name()), ReadCloser: fixture, - }, false, ArchiveCatalogerConfig{UseNetwork: false}) + }, false, cfg) defer cleanupFn() require.NoError(t, err) @@ -843,26 +762,23 @@ func Test_newPackageFromMavenData(t *testing.T) { Version: "1.0", }, project: &parsedPomProject{ - JavaPomProject: &pkg.JavaPomProject{ - Parent: &pkg.JavaPomParent{ - GroupID: "some-parent-group-id", - ArtifactID: "some-parent-artifact-id", - Version: "1.0-parent", + project: &gopom.Project{ + Parent: &gopom.Parent{ + GroupID: ptr("some-parent-group-id"), + ArtifactID: ptr("some-parent-artifact-id"), + Version: ptr("1.0-parent"), }, - Name: "some-name", - GroupID: "some-group-id", - ArtifactID: "some-artifact-id", - Version: "1.0", - Description: "desc", - URL: "aweso.me", - }, - Licenses: []pkg.License{ - { - Value: "MIT", - SPDXExpression: "MIT", - Type: license.Declared, - URLs: []string{"https://opensource.org/licenses/MIT"}, - Locations: file.NewLocationSet(file.NewLocation("some-license-path")), + Name: ptr("some-name"), + GroupID: ptr("some-group-id"), + ArtifactID: ptr("some-artifact-id"), + Version: ptr("1.0"), + Description: ptr("desc"), + URL: ptr("aweso.me"), + Licenses: &[]gopom.License{ + { + Name: ptr("MIT"), + URL: ptr("https://opensource.org/licenses/MIT"), + }, }, }, }, @@ -898,7 +814,7 @@ func Test_newPackageFromMavenData(t *testing.T) { SPDXExpression: "MIT", Type: license.Declared, URLs: []string{"https://opensource.org/licenses/MIT"}, - Locations: file.NewLocationSet(file.NewLocation("some-license-path")), + Locations: file.NewLocationSet(file.NewLocation("given/virtual/path")), }, ), Metadata: pkg.JavaArchive{ @@ -1122,7 +1038,8 @@ func Test_newPackageFromMavenData(t *testing.T) { } test.expectedParent.Locations = locations - actualPackage := newPackageFromMavenData(context.Background(), test.props, test.project, test.parent, file.NewLocation(virtualPath), DefaultArchiveCatalogerConfig()) + r := newMavenResolver(nil, DefaultArchiveCatalogerConfig()) + actualPackage := newPackageFromMavenData(context.Background(), r, test.props, test.project, test.parent, file.NewLocation(virtualPath)) if test.expectedPackage == nil { require.Nil(t, actualPackage) } else { @@ -1337,6 +1254,8 @@ func Test_parseJavaArchive_regressions(t *testing.T) { PomProject: &pkg.JavaPomProject{ Path: "META-INF/maven/org.apache.directory.api/api-asn1-api/pom.xml", ArtifactID: "api-asn1-api", + GroupID: "org.apache.directory.api", + Version: "2.0.0", Name: "Apache Directory API ASN.1 API", Description: "ASN.1 API", Parent: &pkg.JavaPomParent{ @@ -1388,14 +1307,12 @@ func Test_parseJavaArchive_regressions(t *testing.T) { func Test_deterministicMatchingPomProperties(t *testing.T) { tests := []struct { - fixture string - expectedName string - expectedVersion string + fixture string + expected mavenID }{ { - fixture: "multiple-matching-2.11.5", - expectedName: "multiple-matching-1", - expectedVersion: "2.11.5", + fixture: "multiple-matching-2.11.5", + expected: mavenID{"org.multiple", "multiple-matching-1", "2.11.5"}, }, } @@ -1415,9 +1332,8 @@ func Test_deterministicMatchingPomProperties(t *testing.T) { defer cleanupFn() require.NoError(t, err) - name, version, _ := parser.guessMainPackageNameAndVersionFromPomInfo(context.TODO()) - require.Equal(t, test.expectedName, name) - require.Equal(t, test.expectedVersion, version) + groupID, artifactID, version, _ := parser.discoverMainPackageFromPomInfo(context.TODO()) + require.Equal(t, test.expected, mavenID{groupID, artifactID, version}) }() } }) @@ -1436,6 +1352,26 @@ func assignParent(parent *pkg.Package, childPackages ...pkg.Package) { } } +func generateJavaBuildFixture(t *testing.T, fixturePath string) { + if _, err := os.Stat(fixturePath); !os.IsNotExist(err) { + // fixture already exists... + return + } + + makeTask := strings.TrimPrefix(fixturePath, "test-fixtures/java-builds/") + t.Logf(color.Bold.Sprintf("Generating Fixture from 'make %s'", makeTask)) + + cwd, err := os.Getwd() + if err != nil { + t.Errorf("unable to get cwd: %+v", err) + } + + cmd := exec.Command("make", makeTask) + cmd.Dir = filepath.Join(cwd, "test-fixtures/java-builds/") + + run(t, cmd) +} + func generateJavaMetadataJarFixture(t *testing.T, fixtureName string) string { fixturePath := filepath.Join("test-fixtures/jar-metadata/cache/", fixtureName+".jar") if _, err := os.Stat(fixturePath); !os.IsNotExist(err) { @@ -1504,20 +1440,7 @@ func run(t testing.TB, cmd *exec.Cmd) { } } -// setup sets up a test HTTP server for mocking requests to maven central. -// The returned url is injected into the Config so the client uses the test server. -// Tests should register handlers on mux to simulate the expected request/response structure -func setup() (mux *http.ServeMux, serverURL string, teardown func()) { - // mux is the HTTP request multiplexer used with the test server. - mux = http.NewServeMux() - - // We want to ensure that tests catch mistakes where the endpoint URL is - // specified as absolute rather than relative. It only makes a difference - // when there's a non-empty base URL path. So, use that. See issue #752. - apiHandler := http.NewServeMux() - apiHandler.Handle("/", mux) - // server is a test HTTP server used to provide mock API responses. - server := httptest.NewServer(apiHandler) - - return mux, server.URL, server.Close +// ptr returns a pointer to the given value +func ptr[T any](value T) *T { + return &value } diff --git a/syft/pkg/cataloger/java/cataloger.go b/syft/pkg/cataloger/java/cataloger.go index 9552b142ddf..11e48b7f5ad 100644 --- a/syft/pkg/cataloger/java/cataloger.go +++ b/syft/pkg/cataloger/java/cataloger.go @@ -32,10 +32,9 @@ func NewArchiveCataloger(cfg ArchiveCatalogerConfig) pkg.Cataloger { // NewPomCataloger returns a cataloger capable of parsing dependencies from a pom.xml file. // Pom files list dependencies that maybe not be locally installed yet. func NewPomCataloger(cfg ArchiveCatalogerConfig) pkg.Cataloger { - gap := newGenericArchiveParserAdapter(cfg) - - return generic.NewCataloger("java-pom-cataloger"). - WithParserByGlobs(gap.parserPomXML, "**/pom.xml") + return pomXMLCataloger{ + cfg: cfg, + } } // NewGradleLockfileCataloger returns a cataloger capable of parsing dependencies from a gradle.lockfile file. diff --git a/syft/pkg/cataloger/java/config.go b/syft/pkg/cataloger/java/config.go index 14c31d33426..29096d59bff 100644 --- a/syft/pkg/cataloger/java/config.go +++ b/syft/pkg/cataloger/java/config.go @@ -7,6 +7,8 @@ const mavenBaseURL = "https://repo1.maven.org/maven2" type ArchiveCatalogerConfig struct { cataloging.ArchiveSearchConfig `yaml:",inline" json:"" mapstructure:",squash"` UseNetwork bool `yaml:"use-network" json:"use-network" mapstructure:"use-network"` + UseMavenLocalRepository bool `yaml:"use-maven-localrepository" json:"use-maven-localrepository" mapstructure:"use-maven-localrepository"` + MavenLocalRepositoryDir string `yaml:"maven-localrepository-dir" json:"maven-localrepository-dir" mapstructure:"maven-localrepository-dir"` MavenBaseURL string `yaml:"maven-base-url" json:"maven-base-url" mapstructure:"maven-base-url"` MaxParentRecursiveDepth int `yaml:"max-parent-recursive-depth" json:"max-parent-recursive-depth" mapstructure:"max-parent-recursive-depth"` } @@ -15,8 +17,10 @@ func DefaultArchiveCatalogerConfig() ArchiveCatalogerConfig { return ArchiveCatalogerConfig{ ArchiveSearchConfig: cataloging.DefaultArchiveSearchConfig(), UseNetwork: false, + UseMavenLocalRepository: false, + MavenLocalRepositoryDir: defaultMavenLocalRepoDir(), MavenBaseURL: mavenBaseURL, - MaxParentRecursiveDepth: 5, + MaxParentRecursiveDepth: 0, // unlimited } } @@ -25,6 +29,16 @@ func (j ArchiveCatalogerConfig) WithUseNetwork(input bool) ArchiveCatalogerConfi return j } +func (j ArchiveCatalogerConfig) WithUseMavenLocalRepository(input bool) ArchiveCatalogerConfig { + j.UseMavenLocalRepository = input + return j +} + +func (j ArchiveCatalogerConfig) WithMavenLocalRepositoryDir(input string) ArchiveCatalogerConfig { + j.MavenLocalRepositoryDir = input + return j +} + func (j ArchiveCatalogerConfig) WithMavenBaseURL(input string) ArchiveCatalogerConfig { if input != "" { j.MavenBaseURL = input @@ -33,9 +47,7 @@ func (j ArchiveCatalogerConfig) WithMavenBaseURL(input string) ArchiveCatalogerC } func (j ArchiveCatalogerConfig) WithArchiveTraversal(search cataloging.ArchiveSearchConfig, maxDepth int) ArchiveCatalogerConfig { - if maxDepth > 0 { - j.MaxParentRecursiveDepth = maxDepth - } + j.MaxParentRecursiveDepth = maxDepth j.ArchiveSearchConfig = search return j } diff --git a/syft/pkg/cataloger/java/maven_repo_utils.go b/syft/pkg/cataloger/java/maven_repo_utils.go deleted file mode 100644 index e84db154a4f..00000000000 --- a/syft/pkg/cataloger/java/maven_repo_utils.go +++ /dev/null @@ -1,136 +0,0 @@ -package java - -import ( - "context" - "fmt" - "io" - "net/http" - "net/url" - "strings" - "time" - - "github.com/vifraa/gopom" - - "github.com/anchore/syft/internal/log" -) - -func formatMavenPomURL(groupID, artifactID, version, mavenBaseURL string) (requestURL string, err error) { - // groupID needs to go from maven.org -> maven/org - urlPath := strings.Split(groupID, ".") - artifactPom := fmt.Sprintf("%s-%s.pom", artifactID, version) - urlPath = append(urlPath, artifactID, version, artifactPom) - - // ex:"https://repo1.maven.org/maven2/groupID/artifactID/artifactPom - requestURL, err = url.JoinPath(mavenBaseURL, urlPath...) - if err != nil { - return requestURL, fmt.Errorf("could not construct maven url: %w", err) - } - return requestURL, err -} - -// An artifact can have its version defined in a parent's DependencyManagement section -func recursivelyFindVersionFromParentPom(ctx context.Context, groupID, artifactID, parentGroupID, parentArtifactID, parentVersion string, cfg ArchiveCatalogerConfig) string { - // As there can be nested parent poms, we'll recursively check for the version until we reach the max depth - for i := 0; i < cfg.MaxParentRecursiveDepth; i++ { - parentPom, err := getPomFromMavenRepo(ctx, parentGroupID, parentArtifactID, parentVersion, cfg.MavenBaseURL) - if err != nil { - // We don't want to abort here as the parent pom might not exist in Maven Central, we'll just log the error - log.Tracef("unable to get parent pom from Maven central: %v", err) - break - } - if parentPom != nil && parentPom.DependencyManagement != nil { - for _, dependency := range *parentPom.DependencyManagement.Dependencies { - if groupID == *dependency.GroupID && artifactID == *dependency.ArtifactID && dependency.Version != nil { - return *dependency.Version - } - } - } - if parentPom == nil || parentPom.Parent == nil { - break - } - parentGroupID = *parentPom.Parent.GroupID - parentArtifactID = *parentPom.Parent.ArtifactID - parentVersion = *parentPom.Parent.Version - } - return "" -} - -func recursivelyFindLicensesFromParentPom(ctx context.Context, groupID, artifactID, version string, cfg ArchiveCatalogerConfig) []string { - var licenses []string - // As there can be nested parent poms, we'll recursively check for licenses until we reach the max depth - for i := 0; i < cfg.MaxParentRecursiveDepth; i++ { - parentPom, err := getPomFromMavenRepo(ctx, groupID, artifactID, version, cfg.MavenBaseURL) - if err != nil { - // We don't want to abort here as the parent pom might not exist in Maven Central, we'll just log the error - log.Tracef("unable to get parent pom from Maven central: %v", err) - return []string{} - } - parentLicenses := parseLicensesFromPom(parentPom) - if len(parentLicenses) > 0 || parentPom == nil || parentPom.Parent == nil { - licenses = parentLicenses - break - } - - groupID = *parentPom.Parent.GroupID - artifactID = *parentPom.Parent.ArtifactID - version = *parentPom.Parent.Version - } - - return licenses -} - -func getPomFromMavenRepo(ctx context.Context, groupID, artifactID, version, mavenBaseURL string) (*gopom.Project, error) { - requestURL, err := formatMavenPomURL(groupID, artifactID, version, mavenBaseURL) - if err != nil { - return nil, err - } - log.Tracef("trying to fetch parent pom from Maven central %s", requestURL) - - mavenRequest, err := http.NewRequest(http.MethodGet, requestURL, nil) - if err != nil { - return nil, fmt.Errorf("unable to format request for Maven central: %w", err) - } - - httpClient := &http.Client{ - Timeout: time.Second * 10, - } - - mavenRequest = mavenRequest.WithContext(ctx) - - resp, err := httpClient.Do(mavenRequest) - if err != nil { - return nil, fmt.Errorf("unable to get pom from Maven central: %w", err) - } - defer func() { - if err := resp.Body.Close(); err != nil { - log.Errorf("unable to close body: %+v", err) - } - }() - - bytes, err := io.ReadAll(resp.Body) - if err != nil { - return nil, fmt.Errorf("unable to parse pom from Maven central: %w", err) - } - - pom, err := decodePomXML(strings.NewReader(string(bytes))) - if err != nil { - return nil, fmt.Errorf("unable to parse pom from Maven central: %w", err) - } - - return &pom, nil -} - -func parseLicensesFromPom(pom *gopom.Project) []string { - var licenses []string - if pom != nil && pom.Licenses != nil { - for _, license := range *pom.Licenses { - if license.Name != nil { - licenses = append(licenses, *license.Name) - } else if license.URL != nil { - licenses = append(licenses, *license.URL) - } - } - } - - return licenses -} diff --git a/syft/pkg/cataloger/java/maven_resolver.go b/syft/pkg/cataloger/java/maven_resolver.go new file mode 100644 index 00000000000..5fddccc3191 --- /dev/null +++ b/syft/pkg/cataloger/java/maven_resolver.go @@ -0,0 +1,624 @@ +package java + +import ( + "bytes" + "context" + "errors" + "fmt" + "io" + "net/http" + "os" + "path" + "path/filepath" + "reflect" + "regexp" + "slices" + "strings" + "time" + + "github.com/vifraa/gopom" + + "github.com/anchore/syft/internal" + "github.com/anchore/syft/internal/cache" + "github.com/anchore/syft/internal/log" + "github.com/anchore/syft/syft/file" +) + +// mavenID is the unique identifier for a package in Maven +type mavenID struct { + GroupID string + ArtifactID string + Version string +} + +func (m mavenID) String() string { + return fmt.Sprintf("(groupId: %s artifactId: %s version: %s)", m.GroupID, m.ArtifactID, m.Version) +} + +var expressionMatcher = regexp.MustCompile("[$][{][^}]+[}]") + +// mavenResolver is a short-lived utility to resolve maven poms from multiple sources, including: +// the scanned filesystem, local maven cache directories, remote maven repositories, and the syft cache +type mavenResolver struct { + cfg ArchiveCatalogerConfig + cache cache.Cache + resolved map[mavenID]*gopom.Project + remoteRequestTimeout time.Duration + checkedLocalRepo bool + // fileResolver and pomLocations are used to resolve parent poms by relativePath + fileResolver file.Resolver + pomLocations map[*gopom.Project]file.Location +} + +// newMavenResolver constructs a new mavenResolver with the given configuration. +// NOTE: the fileResolver is optional and if provided will be used to resolve parent poms by relative path +func newMavenResolver(fileResolver file.Resolver, cfg ArchiveCatalogerConfig) *mavenResolver { + return &mavenResolver{ + cfg: cfg, + cache: cache.GetManager().GetCache("java/maven/repo", "v1"), + resolved: map[mavenID]*gopom.Project{}, + remoteRequestTimeout: time.Second * 10, + fileResolver: fileResolver, + pomLocations: map[*gopom.Project]file.Location{}, + } +} + +// getPropertyValue gets property values by emulating maven property resolution logic, looking in the project's variables +// as well as supporting the project expressions like ${project.parent.groupId}. +// Properties which are not resolved result in empty string "" +func (r *mavenResolver) getPropertyValue(ctx context.Context, propertyValue *string, resolutionContext ...*gopom.Project) string { + if propertyValue == nil { + return "" + } + resolved, err := r.resolveExpression(ctx, resolutionContext, *propertyValue, nil) + if err != nil { + log.WithFields("error", err, "propertyValue", *propertyValue).Debug("error resolving maven property") + return "" + } + return resolved +} + +// resolveExpression resolves an expression, which may be a plain string or a string with ${ property.references } +func (r *mavenResolver) resolveExpression(ctx context.Context, resolutionContext []*gopom.Project, expression string, resolving []string) (string, error) { + var err error + return expressionMatcher.ReplaceAllStringFunc(expression, func(match string) string { + propertyExpression := strings.TrimSpace(match[2 : len(match)-1]) // remove leading ${ and trailing } + resolved, e := r.resolveProperty(ctx, resolutionContext, propertyExpression, resolving) + if e != nil { + err = errors.Join(err, e) + return "" + } + return resolved + }), err +} + +// resolveProperty resolves properties recursively from the root project +func (r *mavenResolver) resolveProperty(ctx context.Context, resolutionContext []*gopom.Project, propertyExpression string, resolving []string) (string, error) { + // prevent cycles + if slices.Contains(resolving, propertyExpression) { + return "", fmt.Errorf("cycle detected resolving: %s", propertyExpression) + } + if len(resolutionContext) == 0 { + return "", fmt.Errorf("no project variable resolution context provided for expression: '%s'", propertyExpression) + } + resolving = append(resolving, propertyExpression) + + // only resolve project. properties in the context of the current project pom + value, err := r.resolveProjectProperty(ctx, resolutionContext, resolutionContext[len(resolutionContext)-1], propertyExpression, resolving) + if err != nil { + return value, err + } + if value != "" { + return value, nil + } + + for _, pom := range resolutionContext { + current := pom + for parentDepth := 0; current != nil; parentDepth++ { + if r.cfg.MaxParentRecursiveDepth > 0 && parentDepth > r.cfg.MaxParentRecursiveDepth { + return "", fmt.Errorf("maximum parent recursive depth (%v) reached resolving property: %v", r.cfg.MaxParentRecursiveDepth, propertyExpression) + } + if current.Properties != nil && current.Properties.Entries != nil { + if value, ok := current.Properties.Entries[propertyExpression]; ok { + return r.resolveExpression(ctx, resolutionContext, value, resolving) // property values can contain expressions + } + } + current, err = r.resolveParent(ctx, current) + if err != nil { + return "", err + } + } + } + + return "", fmt.Errorf("unable to resolve property: %s", propertyExpression) +} + +// resolveProjectProperty resolves properties on the project +// +//nolint:gocognit +func (r *mavenResolver) resolveProjectProperty(ctx context.Context, resolutionContext []*gopom.Project, pom *gopom.Project, propertyExpression string, resolving []string) (string, error) { + // see if we have a project.x expression and process this based + // on the xml tags in gopom + parts := strings.Split(propertyExpression, ".") + numParts := len(parts) + if numParts > 1 && strings.TrimSpace(parts[0]) == "project" { + pomValue := reflect.ValueOf(pom).Elem() + pomValueType := pomValue.Type() + for partNum := 1; partNum < numParts; partNum++ { + if pomValueType.Kind() != reflect.Struct { + break + } + + part := parts[partNum] + // these two fields are directly inherited from the pom parent values + if partNum == 1 && pom.Parent != nil { + switch part { + case "version": + if pom.Version == nil && pom.Parent.Version != nil { + return r.resolveExpression(ctx, resolutionContext, *pom.Parent.Version, resolving) + } + case "groupID": + if pom.GroupID == nil && pom.Parent.GroupID != nil { + return r.resolveExpression(ctx, resolutionContext, *pom.Parent.GroupID, resolving) + } + } + } + for fieldNum := 0; fieldNum < pomValueType.NumField(); fieldNum++ { + f := pomValueType.Field(fieldNum) + tag := f.Tag.Get("xml") + tag = strings.Split(tag, ",")[0] + // a segment of the property name matches the xml tag for the field, + // so we need to recurse down the nested structs or return a match + // if we're done. + if part != tag { + continue + } + + pomValue = pomValue.Field(fieldNum) + pomValueType = pomValue.Type() + if pomValueType.Kind() == reflect.Ptr { + // we were recursing down the nested structs, but one of the steps + // we need to take is a nil pointer, so give up + if pomValue.IsNil() { + return "", fmt.Errorf("property undefined: %s", propertyExpression) + } + pomValue = pomValue.Elem() + if !pomValue.IsZero() { + // we found a non-zero value whose tag matches this part of the property name + pomValueType = pomValue.Type() + } + } + // If this was the last part of the property name, return the value + if partNum == numParts-1 { + value := fmt.Sprintf("%v", pomValue.Interface()) + return r.resolveExpression(ctx, resolutionContext, value, resolving) + } + break + } + } + } + return "", nil +} + +// resolveMavenID creates a new mavenID from a pom, resolving parent information as necessary +func (r *mavenResolver) resolveMavenID(ctx context.Context, pom *gopom.Project) mavenID { + if pom == nil { + return mavenID{} + } + groupID := r.getPropertyValue(ctx, pom.GroupID, pom) + artifactID := r.getPropertyValue(ctx, pom.ArtifactID, pom) + version := r.getPropertyValue(ctx, pom.Version, pom) + if pom.Parent != nil { + if groupID == "" { + groupID = r.getPropertyValue(ctx, pom.Parent.GroupID, pom) + } + if artifactID == "" { + artifactID = r.getPropertyValue(ctx, pom.Parent.ArtifactID, pom) + } + if version == "" { + version = r.getPropertyValue(ctx, pom.Parent.Version, pom) + } + } + return mavenID{groupID, artifactID, version} +} + +// resolveDependencyID creates a new mavenID from a dependency element in a pom, resolving information as necessary +func (r *mavenResolver) resolveDependencyID(ctx context.Context, pom *gopom.Project, dep gopom.Dependency) mavenID { + if pom == nil { + return mavenID{} + } + + groupID := r.getPropertyValue(ctx, dep.GroupID, pom) + artifactID := r.getPropertyValue(ctx, dep.ArtifactID, pom) + version := r.getPropertyValue(ctx, dep.Version, pom) + + var err error + if version == "" { + version, err = r.findInheritedVersion(ctx, pom, groupID, artifactID) + } + + depID := mavenID{groupID, artifactID, version} + + if err != nil { + log.WithFields("error", err, "mavenID", r.resolveMavenID(ctx, pom), "dependencyID", depID) + } + + return depID +} + +// findPom gets a pom from cache, local repository, or from a remote Maven repository depending on configuration +func (r *mavenResolver) findPom(ctx context.Context, groupID, artifactID, version string) (*gopom.Project, error) { + if groupID == "" || artifactID == "" || version == "" { + return nil, fmt.Errorf("invalid maven pom specification, require non-empty values for groupID: '%s', artifactID: '%s', version: '%s'", groupID, artifactID, version) + } + + id := mavenID{groupID, artifactID, version} + pom := r.resolved[id] + + if pom != nil { + return pom, nil + } + + var errs error + + // try to resolve first from local maven repo + if r.cfg.UseMavenLocalRepository { + pom, err := r.findPomInLocalRepository(groupID, artifactID, version) + if pom != nil { + r.resolved[id] = pom + return pom, nil + } + errs = errors.Join(errs, err) + } + + // resolve via network maven repository + if pom == nil && r.cfg.UseNetwork { + pom, err := r.findPomInRemoteRepository(ctx, groupID, artifactID, version) + if pom != nil { + r.resolved[id] = pom + return pom, nil + } + errs = errors.Join(errs, err) + } + + return nil, fmt.Errorf("unable to resolve pom %s %s %s: %w", groupID, artifactID, version, errs) +} + +// findPomInLocalRepository attempts to get the POM from the users local maven repository +func (r *mavenResolver) findPomInLocalRepository(groupID, artifactID, version string) (*gopom.Project, error) { + groupPath := filepath.Join(strings.Split(groupID, ".")...) + pomFilePath := filepath.Join(r.cfg.MavenLocalRepositoryDir, groupPath, artifactID, version, artifactID+"-"+version+".pom") + pomFile, err := os.Open(pomFilePath) + if err != nil { + if !r.checkedLocalRepo && errors.Is(err, os.ErrNotExist) { + r.checkedLocalRepo = true + // check if the directory exists at all, and if not just stop trying to resolve local maven files + fi, err := os.Stat(r.cfg.MavenLocalRepositoryDir) + if errors.Is(err, os.ErrNotExist) || !fi.IsDir() { + log.WithFields("error", err, "repositoryDir", r.cfg.MavenLocalRepositoryDir). + Info("local maven repository is not a readable directory, stopping local resolution") + r.cfg.UseMavenLocalRepository = false + } + } + return nil, err + } + defer internal.CloseAndLogError(pomFile, pomFilePath) + + return decodePomXML(pomFile) +} + +// findPomInRemoteRepository download the pom file from a (remote) Maven repository over HTTP +func (r *mavenResolver) findPomInRemoteRepository(ctx context.Context, groupID, artifactID, version string) (*gopom.Project, error) { + if groupID == "" || artifactID == "" || version == "" { + return nil, fmt.Errorf("missing/incomplete maven artifact coordinates -- groupId: '%s' artifactId: '%s', version: '%s'", groupID, artifactID, version) + } + + requestURL, err := remotePomURL(r.cfg.MavenBaseURL, groupID, artifactID, version) + if err != nil { + return nil, fmt.Errorf("unable to find pom in remote due to: %w", err) + } + + // Downloading snapshots requires additional steps to determine the latest snapshot version. + // See: https://maven.apache.org/ref/3-LATEST/maven-repository-metadata/ + if strings.HasSuffix(version, "-SNAPSHOT") { + return nil, fmt.Errorf("downloading snapshot artifacts is not supported, got: %s", requestURL) + } + + cacheKey := strings.TrimPrefix(strings.TrimPrefix(requestURL, "http://"), "https://") + reader, err := r.cacheResolveReader(cacheKey, func() (io.ReadCloser, error) { + if err != nil { + return nil, err + } + log.WithFields("url", requestURL).Info("fetching parent pom from remote maven repository") + + req, err := http.NewRequest(http.MethodGet, requestURL, nil) + if err != nil { + return nil, fmt.Errorf("unable to create request for Maven central: %w", err) + } + + req = req.WithContext(ctx) + + client := http.Client{ + Timeout: r.remoteRequestTimeout, + } + + resp, err := client.Do(req) //nolint:bodyclose + if err != nil { + return nil, fmt.Errorf("unable to get pom from Maven repository %v: %w", requestURL, err) + } + if resp.StatusCode == http.StatusNotFound { + return nil, fmt.Errorf("pom not found in Maven repository at: %v", requestURL) + } + return resp.Body, err + }) + if err != nil { + return nil, err + } + if reader, ok := reader.(io.Closer); ok { + defer internal.CloseAndLogError(reader, requestURL) + } + pom, err := decodePomXML(reader) + if err != nil { + return nil, fmt.Errorf("unable to parse pom from Maven repository url %v: %w", requestURL, err) + } + return pom, nil +} + +// cacheResolveReader attempts to get a reader from cache, otherwise caches the contents of the resolve() function. +// this function is guaranteed to return an unread reader for the correct contents. +// NOTE: this could be promoted to the internal cache package as a specialized version of the cache.Resolver +// if there are more users of this functionality +func (r *mavenResolver) cacheResolveReader(key string, resolve func() (io.ReadCloser, error)) (io.Reader, error) { + reader, err := r.cache.Read(key) + if err == nil && reader != nil { + return reader, err + } + + contentReader, err := resolve() + if err != nil { + return nil, err + } + defer internal.CloseAndLogError(contentReader, key) + + // store the contents to return a new reader with the same content + contents, err := io.ReadAll(contentReader) + if err != nil { + return nil, err + } + err = r.cache.Write(key, bytes.NewBuffer(contents)) + return bytes.NewBuffer(contents), err +} + +// resolveParent attempts to resolve the parent for the given pom +func (r *mavenResolver) resolveParent(ctx context.Context, pom *gopom.Project) (*gopom.Project, error) { + if pom == nil || pom.Parent == nil { + return nil, nil + } + parent := pom.Parent + pomWithoutParent := *pom + pomWithoutParent.Parent = nil + groupID := r.getPropertyValue(ctx, parent.GroupID, &pomWithoutParent) + artifactID := r.getPropertyValue(ctx, parent.ArtifactID, &pomWithoutParent) + version := r.getPropertyValue(ctx, parent.Version, &pomWithoutParent) + + // check cache before resolving + parentID := mavenID{groupID, artifactID, version} + if resolvedParent, ok := r.resolved[parentID]; ok { + return resolvedParent, nil + } + + // check if the pom exists in the fileResolver + parentPom := r.findParentPomByRelativePath(ctx, pom, parentID) + if parentPom != nil { + return parentPom, nil + } + + // find POM normally + return r.findPom(ctx, groupID, artifactID, version) +} + +// findInheritedVersion attempts to find the version of a dependency (groupID, artifactID) by searching all parent poms and imported managed dependencies +// +//nolint:gocognit,funlen +func (r *mavenResolver) findInheritedVersion(ctx context.Context, pom *gopom.Project, groupID, artifactID string, resolutionContext ...*gopom.Project) (string, error) { + if pom == nil { + return "", fmt.Errorf("nil pom provided to findInheritedVersion") + } + if r.cfg.MaxParentRecursiveDepth > 0 && len(resolutionContext) > r.cfg.MaxParentRecursiveDepth { + return "", fmt.Errorf("maximum depth reached attempting to resolve version for: %s:%s at: %v", groupID, artifactID, r.resolveMavenID(ctx, pom)) + } + if slices.Contains(resolutionContext, pom) { + return "", fmt.Errorf("cycle detected attempting to resolve version for: %s:%s at: %v", groupID, artifactID, r.resolveMavenID(ctx, pom)) + } + resolutionContext = append(resolutionContext, pom) + + var err error + var version string + + // check for entries in dependencyManagement first + for _, dep := range pomManagedDependencies(pom) { + depGroupID := r.getPropertyValue(ctx, dep.GroupID, resolutionContext...) + depArtifactID := r.getPropertyValue(ctx, dep.ArtifactID, resolutionContext...) + if depGroupID == groupID && depArtifactID == artifactID { + version = r.getPropertyValue(ctx, dep.Version, resolutionContext...) + if version != "" { + return version, nil + } + } + + // imported pom files should be treated just like parent poms, they are used to define versions of dependencies + if deref(dep.Type) == "pom" && deref(dep.Scope) == "import" { + depVersion := r.getPropertyValue(ctx, dep.Version, resolutionContext...) + + depPom, err := r.findPom(ctx, depGroupID, depArtifactID, depVersion) + if err != nil || depPom == nil { + log.WithFields("error", err, "mavenID", r.resolveMavenID(ctx, pom), "dependencyID", mavenID{depGroupID, depArtifactID, depVersion}). + Debug("unable to find imported pom looking for managed dependencies") + continue + } + version, err = r.findInheritedVersion(ctx, depPom, groupID, artifactID, resolutionContext...) + if err != nil { + log.WithFields("error", err, "mavenID", r.resolveMavenID(ctx, pom), "dependencyID", mavenID{depGroupID, depArtifactID, depVersion}). + Debug("error during findInheritedVersion") + } + if version != "" { + return version, nil + } + } + } + + // recursively check parents + parent, err := r.resolveParent(ctx, pom) + if err != nil { + return "", err + } + if parent != nil { + version, err = r.findInheritedVersion(ctx, parent, groupID, artifactID, resolutionContext...) + if err != nil { + return "", err + } + if version != "" { + return version, nil + } + } + + // check for inherited dependencies + for _, dep := range pomDependencies(pom) { + depGroupID := r.getPropertyValue(ctx, dep.GroupID, resolutionContext...) + depArtifactID := r.getPropertyValue(ctx, dep.ArtifactID, resolutionContext...) + if depGroupID == groupID && depArtifactID == artifactID { + version = r.getPropertyValue(ctx, dep.Version, resolutionContext...) + if version != "" { + return version, nil + } + } + } + + return "", nil +} + +// findLicenses search pom for license, traversing parent poms if needed +func (r *mavenResolver) findLicenses(ctx context.Context, groupID, artifactID, version string) ([]gopom.License, error) { + pom, err := r.findPom(ctx, groupID, artifactID, version) + if pom == nil || err != nil { + return nil, err + } + return r.resolveLicenses(ctx, pom) +} + +// resolveLicenses searches the pom for license, traversing parent poms if needed +func (r *mavenResolver) resolveLicenses(ctx context.Context, pom *gopom.Project, processing ...mavenID) ([]gopom.License, error) { + id := r.resolveMavenID(ctx, pom) + if slices.Contains(processing, id) { + return nil, fmt.Errorf("cycle detected resolving licenses for: %v", id) + } + if r.cfg.MaxParentRecursiveDepth > 0 && len(processing) > r.cfg.MaxParentRecursiveDepth { + return nil, fmt.Errorf("maximum parent recursive depth (%v) reached: %v", r.cfg.MaxParentRecursiveDepth, processing) + } + + directLicenses := r.pomLicenses(ctx, pom) + if len(directLicenses) > 0 { + return directLicenses, nil + } + + parent, err := r.resolveParent(ctx, pom) + if err != nil { + return nil, err + } + if parent == nil { + return nil, nil + } + return r.resolveLicenses(ctx, parent, append(processing, id)...) +} + +// pomLicenses appends the directly specified licenses with non-empty name or url +func (r *mavenResolver) pomLicenses(ctx context.Context, pom *gopom.Project) []gopom.License { + var out []gopom.License + for _, license := range deref(pom.Licenses) { + // if we find non-empty licenses, return them + name := r.getPropertyValue(ctx, license.Name, pom) + url := r.getPropertyValue(ctx, license.URL, pom) + if name != "" || url != "" { + out = append(out, license) + } + } + return out +} + +func (r *mavenResolver) findParentPomByRelativePath(ctx context.Context, pom *gopom.Project, parentID mavenID) *gopom.Project { + // don't resolve if no resolver + if r.fileResolver == nil { + return nil + } + + pomLocation, hasPomLocation := r.pomLocations[pom] + if !hasPomLocation || pom == nil || pom.Parent == nil { + return nil + } + relativePath := r.getPropertyValue(ctx, pom.Parent.RelativePath, pom) + if relativePath == "" { + return nil + } + p := pomLocation.Path() + p = path.Dir(p) + p = path.Join(p, relativePath) + p = path.Clean(p) + parentLocations, err := r.fileResolver.FilesByPath(p) + if err != nil || len(parentLocations) == 0 { + log.WithFields("error", err, "mavenID", r.resolveMavenID(ctx, pom), "parentID", parentID, "relativePath", relativePath). + Trace("parent pom not found by relative path") + return nil + } + parentLocation := parentLocations[0] + + parentContents, err := r.fileResolver.FileContentsByLocation(parentLocation) + if err != nil || parentContents == nil { + log.WithFields("error", err, "mavenID", r.resolveMavenID(ctx, pom), "parentID", parentID, "parentLocation", parentLocation). + Debug("unable to get contents of parent pom by relative path") + return nil + } + defer internal.CloseAndLogError(parentContents, parentLocation.RealPath) + parentPom, err := decodePomXML(parentContents) + if err != nil || parentPom == nil { + log.WithFields("error", err, "mavenID", r.resolveMavenID(ctx, pom), "parentID", parentID, "parentLocation", parentLocation). + Debug("unable to parse parent pom") + return nil + } + // ensure parent matches + newParentID := r.resolveMavenID(ctx, parentPom) + if newParentID.ArtifactID != parentID.ArtifactID { + log.WithFields("newParentID", newParentID, "mavenID", r.resolveMavenID(ctx, pom), "parentID", parentID, "parentLocation", parentLocation). + Debug("parent IDs do not match resolving parent by relative path") + return nil + } + + r.resolved[parentID] = parentPom + r.pomLocations[parentPom] = parentLocation // for any future parent relativepath lookups + + return parentPom +} + +// pomDependencies returns all dependencies directly defined in a project, including all defined in profiles. +// does not resolve parent dependencies +func pomDependencies(pom *gopom.Project) []gopom.Dependency { + dependencies := deref(pom.Dependencies) + for _, profile := range deref(pom.Profiles) { + dependencies = append(dependencies, deref(profile.Dependencies)...) + } + return dependencies +} + +// pomManagedDependencies returns all directly defined managed dependencies in a project pom, including all defined in profiles. +// does not resolve parent managed dependencies +func pomManagedDependencies(pom *gopom.Project) []gopom.Dependency { + var dependencies []gopom.Dependency + if pom.DependencyManagement != nil { + dependencies = append(dependencies, deref(pom.DependencyManagement.Dependencies)...) + } + for _, profile := range deref(pom.Profiles) { + if profile.DependencyManagement != nil { + dependencies = append(dependencies, deref(profile.DependencyManagement.Dependencies)...) + } + } + return dependencies +} diff --git a/syft/pkg/cataloger/java/maven_resolver_test.go b/syft/pkg/cataloger/java/maven_resolver_test.go new file mode 100644 index 00000000000..d778efb6991 --- /dev/null +++ b/syft/pkg/cataloger/java/maven_resolver_test.go @@ -0,0 +1,359 @@ +package java + +import ( + "context" + "io" + "net/http" + "net/http/httptest" + "os" + "path/filepath" + "testing" + + "github.com/bmatcuk/doublestar/v4" + "github.com/stretchr/testify/require" + "github.com/vifraa/gopom" + + "github.com/anchore/syft/internal" + "github.com/anchore/syft/syft/internal/fileresolver" +) + +func Test_resolveProperty(t *testing.T) { + tests := []struct { + name string + property string + pom gopom.Project + expected string + }{ + { + name: "property", + property: "${version.number}", + pom: gopom.Project{ + Properties: &gopom.Properties{ + Entries: map[string]string{ + "version.number": "12.5.0", + }, + }, + }, + expected: "12.5.0", + }, + { + name: "groupId", + property: "${project.groupId}", + pom: gopom.Project{ + GroupID: ptr("org.some.group"), + }, + expected: "org.some.group", + }, + { + name: "parent groupId", + property: "${project.parent.groupId}", + pom: gopom.Project{ + Parent: &gopom.Parent{ + GroupID: ptr("org.some.parent"), + }, + }, + expected: "org.some.parent", + }, + { + name: "nil pointer halts search", + property: "${project.parent.groupId}", + pom: gopom.Project{ + Parent: nil, + }, + expected: "", + }, + { + name: "nil string pointer halts search", + property: "${project.parent.groupId}", + pom: gopom.Project{ + Parent: &gopom.Parent{ + GroupID: nil, + }, + }, + expected: "", + }, + { + name: "double dereference", + property: "${springboot.version}", + pom: gopom.Project{ + Parent: &gopom.Parent{ + Version: ptr("1.2.3"), + }, + Properties: &gopom.Properties{ + Entries: map[string]string{ + "springboot.version": "${project.parent.version}", + }, + }, + }, + expected: "1.2.3", + }, + { + name: "map missing stops double dereference", + property: "${springboot.version}", + pom: gopom.Project{ + Parent: &gopom.Parent{ + Version: ptr("1.2.3"), + }, + }, + expected: "", + }, + { + name: "resolution halts even if it resolves to a variable", + property: "${springboot.version}", + pom: gopom.Project{ + Parent: &gopom.Parent{ + Version: ptr("${undefined.version}"), + }, + Properties: &gopom.Properties{ + Entries: map[string]string{ + "springboot.version": "${project.parent.version}", + }, + }, + }, + expected: "", + }, + { + name: "resolution halts even if cyclic", + property: "${springboot.version}", + pom: gopom.Project{ + Properties: &gopom.Properties{ + Entries: map[string]string{ + "springboot.version": "${springboot.version}", + }, + }, + }, + expected: "", + }, + { + name: "resolution halts even if cyclic more steps", + property: "${cyclic.version}", + pom: gopom.Project{ + Properties: &gopom.Properties{ + Entries: map[string]string{ + "other.version": "${cyclic.version}", + "springboot.version": "${other.version}", + "cyclic.version": "${springboot.version}", + }, + }, + }, + expected: "", + }, + { + name: "resolution halts even if cyclic involving parent", + property: "${cyclic.version}", + pom: gopom.Project{ + Parent: &gopom.Parent{ + Version: ptr("${cyclic.version}"), + }, + Properties: &gopom.Properties{ + Entries: map[string]string{ + "other.version": "${parent.version}", + "springboot.version": "${other.version}", + "cyclic.version": "${springboot.version}", + }, + }, + }, + expected: "", + }, + } + + for _, test := range tests { + t.Run(test.name, func(t *testing.T) { + r := newMavenResolver(nil, DefaultArchiveCatalogerConfig()) + resolved := r.getPropertyValue(context.Background(), ptr(test.property), &test.pom) + require.Equal(t, test.expected, resolved) + }) + } +} + +func Test_mavenResolverLocal(t *testing.T) { + dir, err := filepath.Abs("test-fixtures/pom/maven-repo") + require.NoError(t, err) + + tests := []struct { + name string + groupID string + artifactID string + version string + maxDepth int + expression string + expected string + wantErr require.ErrorAssertionFunc + }{ + { + name: "artifact id with variable from 2nd parent", + groupID: "my.org", + artifactID: "child-one", + version: "1.3.6", + expression: "${project.one}", + expected: "1", + }, + { + name: "depth limited large enough", + groupID: "my.org", + artifactID: "child-one", + version: "1.3.6", + expression: "${project.one}", + expected: "1", + maxDepth: 2, + }, + { + name: "depth limited should not resolve", + groupID: "my.org", + artifactID: "child-one", + version: "1.3.6", + expression: "${project.one}", + expected: "", + maxDepth: 1, + }, + } + + for _, test := range tests { + t.Run(test.name, func(t *testing.T) { + ctx := context.Background() + r := newMavenResolver(nil, ArchiveCatalogerConfig{ + UseNetwork: false, + UseMavenLocalRepository: true, + MavenLocalRepositoryDir: dir, + MaxParentRecursiveDepth: test.maxDepth, + }) + pom, err := r.findPom(ctx, test.groupID, test.artifactID, test.version) + if test.wantErr != nil { + test.wantErr(t, err) + } else { + require.NoError(t, err) + } + got := r.getPropertyValue(context.Background(), &test.expression, pom) + require.Equal(t, test.expected, got) + }) + } +} + +func Test_mavenResolverRemote(t *testing.T) { + url := mockMavenRepo(t) + + tests := []struct { + groupID string + artifactID string + version string + expression string + expected string + wantErr require.ErrorAssertionFunc + }{ + { + groupID: "my.org", + artifactID: "child-one", + version: "1.3.6", + expression: "${project.one}", + expected: "1", + }, + } + + for _, test := range tests { + t.Run(test.artifactID, func(t *testing.T) { + ctx := context.Background() + r := newMavenResolver(nil, ArchiveCatalogerConfig{ + UseNetwork: true, + UseMavenLocalRepository: false, + MavenBaseURL: url, + }) + pom, err := r.findPom(ctx, test.groupID, test.artifactID, test.version) + if test.wantErr != nil { + test.wantErr(t, err) + } else { + require.NoError(t, err) + } + got := r.getPropertyValue(context.Background(), &test.expression, pom) + require.Equal(t, test.expected, got) + }) + } +} + +func Test_relativePathParent(t *testing.T) { + resolver, err := fileresolver.NewFromDirectory("test-fixtures/pom/local", "") + require.NoError(t, err) + + r := newMavenResolver(resolver, DefaultArchiveCatalogerConfig()) + locs, err := resolver.FilesByPath("child-1/pom.xml") + require.NoError(t, err) + require.Len(t, locs, 1) + + loc := locs[0] + contents, err := resolver.FileContentsByLocation(loc) + require.NoError(t, err) + defer internal.CloseAndLogError(contents, loc.RealPath) + + pom, err := decodePomXML(contents) + require.NoError(t, err) + + r.pomLocations[pom] = loc + + ctx := context.Background() + parent, err := r.resolveParent(ctx, pom) + require.NoError(t, err) + require.Contains(t, r.pomLocations, parent) + + parent, err = r.resolveParent(ctx, parent) + require.NoError(t, err) + require.Contains(t, r.pomLocations, parent) + + got := r.getPropertyValue(ctx, ptr("${commons-exec_subversion}"), pom) + require.Equal(t, "3", got) +} + +// mockMavenRepo starts a remote maven repo serving all the pom files found in test-fixtures/pom/maven-repo +func mockMavenRepo(t *testing.T) (url string) { + t.Helper() + + return mockMavenRepoAt(t, "test-fixtures/pom/maven-repo") +} + +// mockMavenRepoAt starts a remote maven repo serving all the pom files found in the given directory +func mockMavenRepoAt(t *testing.T, dir string) (url string) { + t.Helper() + + // mux is the HTTP request multiplexer used with the test server. + mux := http.NewServeMux() + + // We want to ensure that tests catch mistakes where the endpoint URL is + // specified as absolute rather than relative. It only makes a difference + // when there's a non-empty base URL path. So, use that. See issue #752. + apiHandler := http.NewServeMux() + apiHandler.Handle("/", mux) + // server is a test HTTP server used to provide mock API responses. + server := httptest.NewServer(apiHandler) + + t.Cleanup(server.Close) + + matches, err := doublestar.Glob(os.DirFS(dir), filepath.Join("**", "*.pom")) + require.NoError(t, err) + + for _, match := range matches { + fullPath, err := filepath.Abs(filepath.Join(dir, match)) + require.NoError(t, err) + match = "/" + filepath.ToSlash(match) + mux.HandleFunc(match, mockMavenHandler(fullPath)) + } + + return server.URL +} + +func mockMavenHandler(responseFixture string) func(w http.ResponseWriter, r *http.Request) { + return func(w http.ResponseWriter, r *http.Request) { + w.WriteHeader(http.StatusOK) + // Set the Content-Type header to indicate that the response is XML + w.Header().Set("Content-Type", "application/xml") + // Copy the file's content to the response writer + f, err := os.Open(responseFixture) + if err != nil { + http.Error(w, err.Error(), http.StatusInternalServerError) + return + } + defer internal.CloseAndLogError(f, responseFixture) + _, err = io.Copy(w, f) + if err != nil { + http.Error(w, err.Error(), http.StatusInternalServerError) + return + } + } +} diff --git a/syft/pkg/cataloger/java/maven_utils.go b/syft/pkg/cataloger/java/maven_utils.go new file mode 100644 index 00000000000..9d365e151d6 --- /dev/null +++ b/syft/pkg/cataloger/java/maven_utils.go @@ -0,0 +1,74 @@ +package java + +import ( + "encoding/xml" + "fmt" + "io" + "net/url" + "os" + "path/filepath" + "strings" + + "github.com/mitchellh/go-homedir" + + "github.com/anchore/syft/internal" + "github.com/anchore/syft/internal/log" +) + +// defaultMavenLocalRepoDir gets default location of the Maven local repository, generally at /.m2/repository +func defaultMavenLocalRepoDir() string { + homeDir, err := homedir.Dir() + if err != nil { + return "" + } + + mavenHome := filepath.Join(homeDir, ".m2") + + settingsXML := filepath.Join(mavenHome, "settings.xml") + settings, err := os.Open(settingsXML) + if err == nil && settings != nil { + defer internal.CloseAndLogError(settings, settingsXML) + localRepository := getSettingsXMLLocalRepository(settings) + if localRepository != "" { + return localRepository + } + } + return filepath.Join(mavenHome, "repository") +} + +// getSettingsXMLLocalRepository reads the provided settings.xml and parses the localRepository, if present +func getSettingsXMLLocalRepository(settingsXML io.Reader) string { + type settings struct { + LocalRepository string `xml:"localRepository"` + } + s := settings{} + err := xml.NewDecoder(settingsXML).Decode(&s) + if err != nil { + log.WithFields("error", err).Debug("unable to read maven settings.xml") + } + return s.LocalRepository +} + +// deref dereferences ptr if not nil, or returns the type default value if ptr is nil +func deref[T any](ptr *T) T { + if ptr == nil { + var t T + return t + } + return *ptr +} + +// remotePomURL returns a URL to download a POM from a remote repository +func remotePomURL(repoURL, groupID, artifactID, version string) (requestURL string, err error) { + // groupID needs to go from maven.org -> maven/org + urlPath := strings.Split(groupID, ".") + artifactPom := fmt.Sprintf("%s-%s.pom", artifactID, version) + urlPath = append(urlPath, artifactID, version, artifactPom) + + // ex: https://repo1.maven.org/maven2/groupID/artifactID/artifactPom + requestURL, err = url.JoinPath(repoURL, urlPath...) + if err != nil { + return requestURL, fmt.Errorf("could not construct maven url: %w", err) + } + return requestURL, err +} diff --git a/syft/pkg/cataloger/java/maven_utils_test.go b/syft/pkg/cataloger/java/maven_utils_test.go new file mode 100644 index 00000000000..8d599b501af --- /dev/null +++ b/syft/pkg/cataloger/java/maven_utils_test.go @@ -0,0 +1,103 @@ +package java + +import ( + "os" + "path/filepath" + "testing" + + "github.com/mitchellh/go-homedir" + "github.com/stretchr/testify/require" +) + +func Test_defaultMavenLocalRepoDir(t *testing.T) { + home, err := homedir.Dir() + require.NoError(t, err) + + fixtures, err := filepath.Abs("test-fixtures") + require.NoError(t, err) + + tests := []struct { + name string + home string + expected string + }{ + { + name: "default", + expected: filepath.Join(home, ".m2", "repository"), + home: "", + }, + { + name: "alternate dir", + expected: "/some/other/repo", + home: "test-fixtures/local-repository-settings", + }, + { + name: "explicit home", + expected: filepath.Join(fixtures, ".m2", "repository"), + home: "test-fixtures", + }, + } + for _, test := range tests { + t.Run(test.name, func(t *testing.T) { + homedir.Reset() + defer homedir.Reset() + if test.home != "" { + home, err := filepath.Abs(test.home) + require.NoError(t, err) + t.Setenv("HOME", home) + } + got := defaultMavenLocalRepoDir() + require.Equal(t, test.expected, got) + }) + } +} + +func Test_getSettingsXmlLocalRepository(t *testing.T) { + tests := []struct { + file string + expected string + }{ + { + expected: "/some/other/repo", + file: "test-fixtures/local-repository-settings/.m2/settings.xml", + }, + { + expected: "", + file: "invalid", + }, + } + for _, test := range tests { + t.Run(test.expected, func(t *testing.T) { + f, _ := os.Open(test.file) + defer f.Close() + got := getSettingsXMLLocalRepository(f) + require.Equal(t, test.expected, got) + }) + } +} + +func Test_remotePomURL(t *testing.T) { + tests := []struct { + name string + groupID string + artifactID string + version string + expected string + }{ + { + name: "formatMavenURL correctly assembles the pom URL", + groupID: "org.springframework.boot", + artifactID: "spring-boot-starter-test", + version: "3.1.5", + expected: "https://repo1.maven.org/maven2/org/springframework/boot/spring-boot-starter-test/3.1.5/spring-boot-starter-test-3.1.5.pom", + }, + } + + for _, tc := range tests { + t.Run(tc.name, func(t *testing.T) { + requestURL, err := remotePomURL(mavenBaseURL, tc.groupID, tc.artifactID, tc.version) + require.NoError(t, err, "expected no err; got %w", err) + require.Equal(t, tc.expected, requestURL) + }) + } +} diff --git a/syft/pkg/cataloger/java/parse_pom_xml.go b/syft/pkg/cataloger/java/parse_pom_xml.go index 5fe1f34d191..d9fe4b2c25a 100644 --- a/syft/pkg/cataloger/java/parse_pom_xml.go +++ b/syft/pkg/cataloger/java/parse_pom_xml.go @@ -4,164 +4,175 @@ import ( "bytes" "context" "encoding/xml" + "errors" "fmt" "io" - "reflect" - "regexp" "strings" "github.com/saintfish/chardet" "github.com/vifraa/gopom" "golang.org/x/net/html/charset" + "github.com/anchore/syft/internal" "github.com/anchore/syft/internal/log" "github.com/anchore/syft/syft/artifact" "github.com/anchore/syft/syft/file" "github.com/anchore/syft/syft/pkg" - "github.com/anchore/syft/syft/pkg/cataloger/generic" ) -const pomXMLGlob = "*pom.xml" +const ( + pomXMLGlob = "*pom.xml" + pomCatalogerName = "java-pom-cataloger" +) + +type pomXMLCataloger struct { + cfg ArchiveCatalogerConfig +} -var propertyMatcher = regexp.MustCompile("[$][{][^}]+[}]") +func (p pomXMLCataloger) Name() string { + return pomCatalogerName +} -func (gap genericArchiveParserAdapter) parserPomXML(ctx context.Context, _ file.Resolver, _ *generic.Environment, reader file.LocationReadCloser) ([]pkg.Package, []artifact.Relationship, error) { - pom, err := decodePomXML(reader) +func (p pomXMLCataloger) Catalog(ctx context.Context, fileResolver file.Resolver) ([]pkg.Package, []artifact.Relationship, error) { + locations, err := fileResolver.FilesByGlob("**/pom.xml") if err != nil { return nil, nil, err } - var pkgs []pkg.Package - if pom.Dependencies != nil { - for _, dep := range *pom.Dependencies { - p := newPackageFromPom( - ctx, - pom, - dep, - gap.cfg, - reader.Location.WithAnnotation(pkg.EvidenceAnnotationKey, pkg.PrimaryEvidenceAnnotation), - ) - if p.Name == "" { - continue - } + r := newMavenResolver(fileResolver, p.cfg) - pkgs = append(pkgs, p) + var poms []*gopom.Project + for _, pomLocation := range locations { + pom, err := readPomFromLocation(fileResolver, pomLocation) + if err != nil || pom == nil { + log.WithFields("error", err, "pomLocation", pomLocation).Debug("error while reading pom") + continue } + + poms = append(poms, pom) + + // store information about this pom for future lookups + r.pomLocations[pom] = pomLocation + r.resolved[r.resolveMavenID(ctx, pom)] = pom } + var pkgs []pkg.Package + for _, pom := range poms { + pkgs = append(pkgs, processPomXML(ctx, r, pom, r.pomLocations[pom])...) + } return pkgs, nil, nil } -func parsePomXMLProject(path string, reader io.Reader, location file.Location) (*parsedPomProject, error) { - project, err := decodePomXML(reader) +func readPomFromLocation(fileResolver file.Resolver, pomLocation file.Location) (*gopom.Project, error) { + contents, err := fileResolver.FileContentsByLocation(pomLocation) if err != nil { return nil, err } - return newPomProject(path, project, location), nil + defer internal.CloseAndLogError(contents, pomLocation.RealPath) + return decodePomXML(contents) } -func newPomProject(path string, p gopom.Project, location file.Location) *parsedPomProject { - artifactID := safeString(p.ArtifactID) - name := safeString(p.Name) - projectURL := safeString(p.URL) - - var licenses []pkg.License - if p.Licenses != nil { - for _, license := range *p.Licenses { - var licenseName, licenseURL string - if license.Name != nil { - licenseName = *license.Name - } - if license.URL != nil { - licenseURL = *license.URL - } - - if licenseName == "" && licenseURL == "" { - continue - } +func processPomXML(ctx context.Context, r *mavenResolver, pom *gopom.Project, loc file.Location) []pkg.Package { + var pkgs []pkg.Package - licenses = append(licenses, pkg.NewLicenseFromFields(licenseName, licenseURL, &location)) + pomID := r.resolveMavenID(ctx, pom) + for _, dep := range pomDependencies(pom) { + depID := r.resolveDependencyID(ctx, pom, dep) + log.WithFields("pomLocation", loc, "mavenID", pomID, "dependencyID", depID).Trace("adding maven pom dependency") + + p, err := newPackageFromDependency( + ctx, + r, + pom, + dep, + loc.WithAnnotation(pkg.EvidenceAnnotationKey, pkg.PrimaryEvidenceAnnotation), + ) + if err != nil { + log.WithFields("error", err, "pomLocation", loc, "mavenID", pomID, "dependencyID", depID).Debugf("error adding dependency") + } + if p == nil { + continue } + pkgs = append(pkgs, *p) } - log.WithFields("path", path, "artifactID", artifactID, "name", name, "projectURL", projectURL).Trace("parsing pom.xml") - return &parsedPomProject{ - JavaPomProject: &pkg.JavaPomProject{ - Path: path, - Parent: pomParent(p, p.Parent), - GroupID: resolveProperty(p, p.GroupID, "groupId"), - ArtifactID: artifactID, - Version: resolveProperty(p, p.Version, "version"), - Name: name, - Description: cleanDescription(p.Description), - URL: projectURL, - }, - Licenses: licenses, + return pkgs +} + +func newPomProject(ctx context.Context, r *mavenResolver, path string, pom *gopom.Project) *pkg.JavaPomProject { + id := r.resolveMavenID(ctx, pom) + name := r.getPropertyValue(ctx, pom.Name, pom) + projectURL := r.getPropertyValue(ctx, pom.URL, pom) + + log.WithFields("path", path, "artifactID", id.ArtifactID, "name", name, "projectURL", projectURL).Trace("parsing pom.xml") + return &pkg.JavaPomProject{ + Path: path, + Parent: pomParent(ctx, r, pom), + GroupID: id.GroupID, + ArtifactID: id.ArtifactID, + Version: id.Version, + Name: name, + Description: cleanDescription(r.getPropertyValue(ctx, pom.Description, pom)), + URL: projectURL, } } -func newPackageFromPom(ctx context.Context, pom gopom.Project, dep gopom.Dependency, cfg ArchiveCatalogerConfig, locations ...file.Location) pkg.Package { +func newPackageFromDependency(ctx context.Context, r *mavenResolver, pom *gopom.Project, dep gopom.Dependency, locations ...file.Location) (*pkg.Package, error) { + id := r.resolveDependencyID(ctx, pom, dep) + m := pkg.JavaArchive{ PomProperties: &pkg.JavaPomProperties{ - GroupID: resolveProperty(pom, dep.GroupID, "groupId"), - ArtifactID: resolveProperty(pom, dep.ArtifactID, "artifactId"), - Scope: resolveProperty(pom, dep.Scope, "scope"), + GroupID: id.GroupID, + ArtifactID: id.ArtifactID, + Scope: r.getPropertyValue(ctx, dep.Scope, pom), }, } - name := safeString(dep.ArtifactID) - version := resolveProperty(pom, dep.Version, "version") + var err error + var licenses []pkg.License + dependencyPom, depErr := r.findPom(ctx, id.GroupID, id.ArtifactID, id.Version) + if depErr != nil { + err = errors.Join(err, depErr) + } - licenses := make([]pkg.License, 0) - if cfg.UseNetwork { - if version == "" { - // If we have no version then let's try to get it from a parent pom DependencyManagement section - version = recursivelyFindVersionFromParentPom(ctx, *dep.GroupID, *dep.ArtifactID, *pom.Parent.GroupID, *pom.Parent.ArtifactID, *pom.Parent.Version, cfg) - } - if version != "" { - parentLicenses := recursivelyFindLicensesFromParentPom( - ctx, - m.PomProperties.GroupID, - m.PomProperties.ArtifactID, - version, - cfg) - - if len(parentLicenses) > 0 { - for _, licenseName := range parentLicenses { - licenses = append(licenses, pkg.NewLicenseFromFields(licenseName, "", nil)) - } - } + if dependencyPom != nil { + depLicenses, _ := r.resolveLicenses(ctx, dependencyPom) + for _, license := range depLicenses { + licenses = append(licenses, pkg.NewLicenseFromFields(deref(license.Name), deref(license.URL), nil)) } } - p := pkg.Package{ - Name: name, - Version: version, + p := &pkg.Package{ + Name: id.ArtifactID, + Version: id.Version, Locations: file.NewLocationSet(locations...), Licenses: pkg.NewLicenseSet(licenses...), - PURL: packageURL(name, version, m), + PURL: packageURL(id.ArtifactID, id.Version, m), Language: pkg.Java, Type: pkg.JavaPkg, // TODO: should we differentiate between packages from jar/war/zip versus packages from a pom.xml that were not installed yet? + FoundBy: pomCatalogerName, Metadata: m, } p.SetID() - return p + return p, err } -func decodePomXML(content io.Reader) (project gopom.Project, err error) { +// decodePomXML decodes a pom XML file, detecting and converting non-UTF-8 charsets. this DOES NOT perform any logic to resolve properties such as groupID, artifactID, and version +func decodePomXML(content io.Reader) (project *gopom.Project, err error) { inputReader, err := getUtf8Reader(content) if err != nil { - return project, fmt.Errorf("unable to read pom.xml: %w", err) + return nil, fmt.Errorf("unable to read pom.xml: %w", err) } decoder := xml.NewDecoder(inputReader) // when an xml file has a character set declaration (e.g. '') read that and use the correct decoder decoder.CharsetReader = charset.NewReaderLabel - if err := decoder.Decode(&project); err != nil { - return project, fmt.Errorf("unable to unmarshal pom.xml: %w", err) + project = &gopom.Project{} + if err := decoder.Decode(project); err != nil { + return nil, fmt.Errorf("unable to unmarshal pom.xml: %w", err) } return project, nil @@ -194,29 +205,28 @@ func getUtf8Reader(content io.Reader) (io.Reader, error) { return inputReader, nil } -func pomParent(pom gopom.Project, parent *gopom.Parent) (result *pkg.JavaPomParent) { - if parent == nil { +func pomParent(ctx context.Context, r *mavenResolver, pom *gopom.Project) *pkg.JavaPomParent { + if pom == nil || pom.Parent == nil { return nil } - artifactID := safeString(parent.ArtifactID) - result = &pkg.JavaPomParent{ - GroupID: resolveProperty(pom, parent.GroupID, "groupId"), - ArtifactID: artifactID, - Version: resolveProperty(pom, parent.Version, "version"), - } + groupID := r.getPropertyValue(ctx, pom.Parent.GroupID, pom) + artifactID := r.getPropertyValue(ctx, pom.Parent.ArtifactID, pom) + version := r.getPropertyValue(ctx, pom.Parent.Version, pom) - if result.GroupID == "" && result.ArtifactID == "" && result.Version == "" { + if groupID == "" && artifactID == "" && version == "" { return nil } - return result -} -func cleanDescription(original *string) (cleaned string) { - if original == nil { - return "" + return &pkg.JavaPomParent{ + GroupID: groupID, + ArtifactID: artifactID, + Version: version, } - descriptionLines := strings.Split(*original, "\n") +} + +func cleanDescription(original string) (cleaned string) { + descriptionLines := strings.Split(original, "\n") for _, line := range descriptionLines { line = strings.TrimSpace(line) if len(line) == 0 { @@ -226,94 +236,3 @@ func cleanDescription(original *string) (cleaned string) { } return strings.TrimSpace(cleaned) } - -// resolveProperty emulates some maven property resolution logic by looking in the project's variables -// as well as supporting the project expressions like ${project.parent.groupId}. -// If no match is found, the entire expression including ${} is returned -func resolveProperty(pom gopom.Project, property *string, propertyName string) string { - propertyCase := safeString(property) - log.WithFields("existingPropertyValue", propertyCase, "propertyName", propertyName).Trace("resolving property") - seenBeforePropertyNames := map[string]struct{}{ - propertyName: {}, - } - result := recursiveResolveProperty(pom, propertyCase, seenBeforePropertyNames) - if propertyMatcher.MatchString(result) { - return "" // dereferencing variable failed; fall back to empty string - } - return result -} - -//nolint:gocognit -func recursiveResolveProperty(pom gopom.Project, propertyCase string, seenPropertyNames map[string]struct{}) string { - return propertyMatcher.ReplaceAllStringFunc(propertyCase, func(match string) string { - propertyName := strings.TrimSpace(match[2 : len(match)-1]) // remove leading ${ and trailing } - if _, seen := seenPropertyNames[propertyName]; seen { - return propertyCase - } - entries := pomProperties(pom) - if value, ok := entries[propertyName]; ok { - seenPropertyNames[propertyName] = struct{}{} - return recursiveResolveProperty(pom, value, seenPropertyNames) // recursively resolve in case a variable points to a variable. - } - - // if we don't find anything directly in the pom properties, - // see if we have a project.x expression and process this based - // on the xml tags in gopom - parts := strings.Split(propertyName, ".") - numParts := len(parts) - if numParts > 1 && strings.TrimSpace(parts[0]) == "project" { - pomValue := reflect.ValueOf(pom) - pomValueType := pomValue.Type() - for partNum := 1; partNum < numParts; partNum++ { - if pomValueType.Kind() != reflect.Struct { - break - } - part := parts[partNum] - for fieldNum := 0; fieldNum < pomValueType.NumField(); fieldNum++ { - f := pomValueType.Field(fieldNum) - tag := f.Tag.Get("xml") - tag = strings.Split(tag, ",")[0] - // a segment of the property name matches the xml tag for the field, - // so we need to recurse down the nested structs or return a match - // if we're done. - if part == tag { - pomValue = pomValue.Field(fieldNum) - pomValueType = pomValue.Type() - if pomValueType.Kind() == reflect.Ptr { - // we were recursing down the nested structs, but one of the steps - // we need to take is a nil pointer, so give up and return the original match - if pomValue.IsNil() { - return match - } - pomValue = pomValue.Elem() - if !pomValue.IsZero() { - // we found a non-zero value whose tag matches this part of the property name - pomValueType = pomValue.Type() - } - } - // If this was the last part of the property name, return the value - if partNum == numParts-1 { - return fmt.Sprintf("%v", pomValue.Interface()) - } - break - } - } - } - } - return match - }) -} - -func pomProperties(p gopom.Project) map[string]string { - if p.Properties != nil { - return p.Properties.Entries - } - return map[string]string{} -} - -func safeString(s *string) string { - if s == nil { - return "" - } - return *s -} diff --git a/syft/pkg/cataloger/java/parse_pom_xml_test.go b/syft/pkg/cataloger/java/parse_pom_xml_test.go index 66ebb521609..45650049072 100644 --- a/syft/pkg/cataloger/java/parse_pom_xml_test.go +++ b/syft/pkg/cataloger/java/parse_pom_xml_test.go @@ -1,6 +1,7 @@ package java import ( + "context" "encoding/base64" "io" "os" @@ -16,15 +17,17 @@ import ( "github.com/anchore/syft/syft/license" "github.com/anchore/syft/syft/pkg" "github.com/anchore/syft/syft/pkg/cataloger/internal/pkgtest" + "github.com/anchore/syft/syft/source" + "github.com/anchore/syft/syft/source/directorysource" ) -func Test_parserPomXML(t *testing.T) { +func Test_parsePomXML(t *testing.T) { tests := []struct { - input string + dir string expected []pkg.Package }{ { - input: "test-fixtures/pom/pom.xml", + dir: "test-fixtures/pom/local/example-java-app-maven", expected: []pkg.Package{ { Name: "joda-time", @@ -32,6 +35,7 @@ func Test_parserPomXML(t *testing.T) { PURL: "pkg:maven/com.joda/joda-time@2.9.2", Language: pkg.Java, Type: pkg.JavaPkg, + FoundBy: pomCatalogerName, Metadata: pkg.JavaArchive{ PomProperties: &pkg.JavaPomProperties{ GroupID: "com.joda", @@ -45,6 +49,7 @@ func Test_parserPomXML(t *testing.T) { PURL: "pkg:maven/junit/junit@4.12", Language: pkg.Java, Type: pkg.JavaPkg, + FoundBy: pomCatalogerName, Metadata: pkg.JavaArchive{ PomProperties: &pkg.JavaPomProperties{ GroupID: "junit", @@ -58,19 +63,19 @@ func Test_parserPomXML(t *testing.T) { } for _, test := range tests { - t.Run(test.input, func(t *testing.T) { + t.Run(test.dir, func(t *testing.T) { for i := range test.expected { - test.expected[i].Locations.Add(file.NewLocation(test.input)) + test.expected[i].Locations.Add(file.NewLocation("pom.xml")) } - gap := newGenericArchiveParserAdapter(ArchiveCatalogerConfig{ + cat := NewPomCataloger(ArchiveCatalogerConfig{ ArchiveSearchConfig: cataloging.ArchiveSearchConfig{ IncludeIndexedArchives: true, IncludeUnindexedArchives: true, }, }) - pkgtest.TestFileParser(t, test.input, gap.parserPomXML, test.expected, nil) + pkgtest.TestCataloger(t, test.dir, cat, test.expected, nil) }) } } @@ -131,168 +136,129 @@ func Test_decodePomXML_surviveNonUtf8Encoding(t *testing.T) { func Test_parseCommonsTextPomXMLProject(t *testing.T) { tests := []struct { - input string + dir string expected []pkg.Package }{ { - input: "test-fixtures/pom/commons-text.pom.xml", - expected: []pkg.Package{ - { - Name: "commons-lang3", - Version: "3.12.0", - PURL: "pkg:maven/org.apache.commons/commons-lang3@3.12.0", - Language: pkg.Java, - Type: pkg.JavaPkg, - Metadata: pkg.JavaArchive{ - PomProperties: &pkg.JavaPomProperties{ - GroupID: "org.apache.commons", - ArtifactID: "commons-lang3", - }, - }, - }, - { - Name: "junit-jupiter", - Version: "", - PURL: "pkg:maven/org.junit.jupiter/junit-jupiter", - Language: pkg.Java, - Type: pkg.JavaPkg, - Metadata: pkg.JavaArchive{ - PomProperties: &pkg.JavaPomProperties{ - GroupID: "org.junit.jupiter", - ArtifactID: "junit-jupiter", - Scope: "test", - }, - }, - }, - { - Name: "assertj-core", - Version: "3.23.1", - PURL: "pkg:maven/org.assertj/assertj-core@3.23.1", - Language: pkg.Java, - Type: pkg.JavaPkg, - Metadata: pkg.JavaArchive{ - PomProperties: &pkg.JavaPomProperties{ - GroupID: "org.assertj", - ArtifactID: "assertj-core", - Scope: "test", - }, - }, - }, - { - Name: "commons-io", - Version: "2.11.0", - PURL: "pkg:maven/commons-io/commons-io@2.11.0", - Language: pkg.Java, - Type: pkg.JavaPkg, - Metadata: pkg.JavaArchive{ - PomProperties: &pkg.JavaPomProperties{ - GroupID: "commons-io", - ArtifactID: "commons-io", - Scope: "test", - }, - }, - }, - { - Name: "mockito-inline", - Version: "4.8.0", - PURL: "pkg:maven/org.mockito/mockito-inline@4.8.0", - Language: pkg.Java, - Type: pkg.JavaPkg, - Metadata: pkg.JavaArchive{ - PomProperties: &pkg.JavaPomProperties{ - GroupID: "org.mockito", - ArtifactID: "mockito-inline", - Scope: "test", - }, - }, - }, - { - Name: "js", - Version: "22.0.0.2", - PURL: "pkg:maven/org.graalvm.js/js@22.0.0.2", - Language: pkg.Java, - Type: pkg.JavaPkg, - Metadata: pkg.JavaArchive{ - PomProperties: &pkg.JavaPomProperties{ - GroupID: "org.graalvm.js", - ArtifactID: "js", - Scope: "test", - }, - }, - }, - { - Name: "js-scriptengine", - Version: "22.0.0.2", - PURL: "pkg:maven/org.graalvm.js/js-scriptengine@22.0.0.2", - Language: pkg.Java, - Type: pkg.JavaPkg, - Metadata: pkg.JavaArchive{ - PomProperties: &pkg.JavaPomProperties{ - GroupID: "org.graalvm.js", - ArtifactID: "js-scriptengine", - Scope: "test", - }, - }, + dir: "test-fixtures/pom/local/commons-text-1.10.0", + + expected: getCommonsTextExpectedPackages(), + }, + } + + for _, test := range tests { + t.Run(test.dir, func(t *testing.T) { + for i := range test.expected { + test.expected[i].Locations.Add(file.NewLocation("pom.xml")) + } + + cat := NewPomCataloger(ArchiveCatalogerConfig{ + ArchiveSearchConfig: cataloging.ArchiveSearchConfig{ + IncludeIndexedArchives: true, + IncludeUnindexedArchives: true, }, - { - Name: "commons-rng-simple", - Version: "1.4", - PURL: "pkg:maven/org.apache.commons/commons-rng-simple@1.4", - Language: pkg.Java, - Type: pkg.JavaPkg, - Metadata: pkg.JavaArchive{ - PomProperties: &pkg.JavaPomProperties{ - GroupID: "org.apache.commons", - ArtifactID: "commons-rng-simple", - Scope: "test", - }, - }, + UseMavenLocalRepository: false, + }) + pkgtest.TestCataloger(t, test.dir, cat, test.expected, nil) + }) + } +} + +func Test_parseCommonsTextPomXMLProjectWithLocalRepository(t *testing.T) { + // Using the local repository, the version of junit-jupiter will be resolved + expectedPackages := getCommonsTextExpectedPackages() + + for i := 0; i < len(expectedPackages); i++ { + if expectedPackages[i].Name == "junit-jupiter" { + expPkg := &expectedPackages[i] + expPkg.Version = "5.9.1" + expPkg.PURL = "pkg:maven/org.junit.jupiter/junit-jupiter@5.9.1" + expPkg.Metadata = pkg.JavaArchive{ + PomProperties: &pkg.JavaPomProperties{ + GroupID: "org.junit.jupiter", + ArtifactID: "junit-jupiter", + Scope: "test", }, - { - Name: "jmh-core", - Version: "1.35", - PURL: "pkg:maven/org.openjdk.jmh/jmh-core@1.35", - Language: pkg.Java, - Type: pkg.JavaPkg, - Metadata: pkg.JavaArchive{ - PomProperties: &pkg.JavaPomProperties{ - GroupID: "org.openjdk.jmh", - ArtifactID: "jmh-core", - Scope: "test", - }, - }, + } + } + } + + tests := []struct { + dir string + expected []pkg.Package + }{ + { + dir: "test-fixtures/pom/local/commons-text-1.10.0", + expected: expectedPackages, + }, + } + + for _, test := range tests { + t.Run(test.dir, func(t *testing.T) { + for i := range test.expected { + test.expected[i].Locations.Add(file.NewLocation("pom.xml")) + } + + cat := NewPomCataloger(ArchiveCatalogerConfig{ + ArchiveSearchConfig: cataloging.ArchiveSearchConfig{ + IncludeIndexedArchives: true, + IncludeUnindexedArchives: true, }, - { - Name: "jmh-generator-annprocess", - Version: "1.35", - PURL: "pkg:maven/org.openjdk.jmh/jmh-generator-annprocess@1.35", - Language: pkg.Java, - Type: pkg.JavaPkg, - Metadata: pkg.JavaArchive{ - PomProperties: &pkg.JavaPomProperties{ - GroupID: "org.openjdk.jmh", - ArtifactID: "jmh-generator-annprocess", - Scope: "test", - }, - }, + UseMavenLocalRepository: true, + MavenLocalRepositoryDir: "test-fixtures/pom/maven-repo", + }) + pkgtest.TestCataloger(t, test.dir, cat, test.expected, nil) + }) + } +} + +func Test_parseCommonsTextPomXMLProjectWithNetwork(t *testing.T) { + url := mockMavenRepo(t) + + // Using the local repository, the version of junit-jupiter will be resolved + expectedPackages := getCommonsTextExpectedPackages() + + for i := 0; i < len(expectedPackages); i++ { + if expectedPackages[i].Name == "junit-jupiter" { + expPkg := &expectedPackages[i] + expPkg.Version = "5.9.1" + expPkg.PURL = "pkg:maven/org.junit.jupiter/junit-jupiter@5.9.1" + expPkg.Metadata = pkg.JavaArchive{ + PomProperties: &pkg.JavaPomProperties{ + GroupID: "org.junit.jupiter", + ArtifactID: "junit-jupiter", + Scope: "test", }, - }, + } + } + } + + tests := []struct { + dir string + expected []pkg.Package + }{ + { + dir: "test-fixtures/pom/local/commons-text-1.10.0", + expected: expectedPackages, }, } for _, test := range tests { - t.Run(test.input, func(t *testing.T) { + t.Run(test.dir, func(t *testing.T) { for i := range test.expected { - test.expected[i].Locations.Add(file.NewLocation(test.input)) + test.expected[i].Locations.Add(file.NewLocation("pom.xml")) } - gap := newGenericArchiveParserAdapter(ArchiveCatalogerConfig{ + cat := NewPomCataloger(ArchiveCatalogerConfig{ ArchiveSearchConfig: cataloging.ArchiveSearchConfig{ IncludeIndexedArchives: true, IncludeUnindexedArchives: true, }, + UseNetwork: true, + MavenBaseURL: url, + UseMavenLocalRepository: false, }) - pkgtest.TestFileParser(t, test.input, gap.parserPomXML, test.expected, nil) + pkgtest.TestCataloger(t, test.dir, cat, test.expected, nil) }) } } @@ -302,63 +268,60 @@ func Test_parsePomXMLProject(t *testing.T) { jarLocation := file.NewLocation("path/to/archive.jar") tests := []struct { name string - expected parsedPomProject + project *pkg.JavaPomProject + licenses []pkg.License }{ { name: "go case", - expected: parsedPomProject{ - JavaPomProject: &pkg.JavaPomProject{ - Path: "test-fixtures/pom/commons-codec.pom.xml", - Parent: &pkg.JavaPomParent{ - GroupID: "org.apache.commons", - ArtifactID: "commons-parent", - Version: "42", - }, - GroupID: "commons-codec", - ArtifactID: "commons-codec", - Version: "1.11", - Name: "Apache Commons Codec", - Description: "The Apache Commons Codec package contains simple encoder and decoders for various formats such as Base64 and Hexadecimal. In addition to these widely used encoders and decoders, the codec package also maintains a collection of phonetic encoding utilities.", - URL: "http://commons.apache.org/proper/commons-codec/", + project: &pkg.JavaPomProject{ + Path: "test-fixtures/pom/commons-codec.pom.xml", + Parent: &pkg.JavaPomParent{ + GroupID: "org.apache.commons", + ArtifactID: "commons-parent", + Version: "42", }, + GroupID: "commons-codec", + ArtifactID: "commons-codec", + Version: "1.11", + Name: "Apache Commons Codec", + Description: "The Apache Commons Codec package contains simple encoder and decoders for various formats such as Base64 and Hexadecimal. In addition to these widely used encoders and decoders, the codec package also maintains a collection of phonetic encoding utilities.", + URL: "http://commons.apache.org/proper/commons-codec/", }, }, { name: "with license data", - expected: parsedPomProject{ - JavaPomProject: &pkg.JavaPomProject{ - Path: "test-fixtures/pom/neo4j-license-maven-plugin.pom.xml", - Parent: &pkg.JavaPomParent{ - GroupID: "org.sonatype.oss", - ArtifactID: "oss-parent", - Version: "7", - }, - GroupID: "org.neo4j.build.plugins", - ArtifactID: "license-maven-plugin", - Version: "4-SNAPSHOT", - Name: "${project.artifactId}", // TODO: this is not an ideal answer - Description: "Maven 2 plugin to check and update license headers in source files", - URL: "http://components.neo4j.org/${project.artifactId}/${project.version}", // TODO: this is not an ideal answer + project: &pkg.JavaPomProject{ + Path: "test-fixtures/pom/neo4j-license-maven-plugin.pom.xml", + Parent: &pkg.JavaPomParent{ + GroupID: "org.sonatype.oss", + ArtifactID: "oss-parent", + Version: "7", }, - Licenses: []pkg.License{ - { - Value: "The Apache Software License, Version 2.0", - SPDXExpression: "", // TODO: ideally we would parse this title to get Apache-2.0 (created issue #2210 https://github.com/anchore/syft/issues/2210) - Type: license.Declared, - URLs: []string{"http://www.apache.org/licenses/LICENSE-2.0.txt"}, - Locations: file.NewLocationSet(jarLocation), - }, - { - Value: "MIT", - SPDXExpression: "MIT", - Type: license.Declared, - Locations: file.NewLocationSet(jarLocation), - }, - { - Type: license.Declared, - URLs: []string{"https://opensource.org/license/unlicense/"}, - Locations: file.NewLocationSet(jarLocation), - }, + GroupID: "org.neo4j.build.plugins", + ArtifactID: "license-maven-plugin", + Version: "4-SNAPSHOT", + Name: "license-maven-plugin", + Description: "Maven 2 plugin to check and update license headers in source files", + URL: "http://components.neo4j.org/license-maven-plugin/4-SNAPSHOT", + }, + licenses: []pkg.License{ + { + Value: "The Apache Software License, Version 2.0", + SPDXExpression: "", // TODO: ideally we would parse this title to get Apache-2.0 (created issue #2210 https://github.com/anchore/syft/issues/2210) + Type: license.Declared, + URLs: []string{"http://www.apache.org/licenses/LICENSE-2.0.txt"}, + Locations: file.NewLocationSet(jarLocation), + }, + { + Value: "MIT", + SPDXExpression: "MIT", + Type: license.Declared, + Locations: file.NewLocationSet(jarLocation), + }, + { + Type: license.Declared, + URLs: []string{"https://opensource.org/license/unlicense/"}, + Locations: file.NewLocationSet(jarLocation), }, }, }, @@ -366,13 +329,20 @@ func Test_parsePomXMLProject(t *testing.T) { for _, test := range tests { t.Run(test.name, func(t *testing.T) { - fixture, err := os.Open(test.expected.Path) + fixture, err := os.Open(test.project.Path) assert.NoError(t, err) + r := newMavenResolver(nil, ArchiveCatalogerConfig{}) + + pom, err := gopom.ParseFromReader(fixture) + require.NoError(t, err) - actual, err := parsePomXMLProject(fixture.Name(), fixture, jarLocation) + actual := newPomProject(context.Background(), r, fixture.Name(), pom) assert.NoError(t, err) + assert.Equal(t, test.project, actual) - assert.Equal(t, &test.expected, actual) + licenses := r.pomLicenses(context.Background(), pom) + assert.NoError(t, err) + assert.Equal(t, test.licenses, toPkgLicenses(&jarLocation, licenses)) }) } } @@ -386,7 +356,7 @@ func Test_pomParent(t *testing.T) { { name: "only group ID", input: &gopom.Parent{ - GroupID: stringPointer("org.something"), + GroupID: ptr("org.something"), }, expected: &pkg.JavaPomParent{ GroupID: "org.something", @@ -395,7 +365,7 @@ func Test_pomParent(t *testing.T) { { name: "only artifact ID", input: &gopom.Parent{ - ArtifactID: stringPointer("something"), + ArtifactID: ptr("something"), }, expected: &pkg.JavaPomParent{ ArtifactID: "something", @@ -404,7 +374,7 @@ func Test_pomParent(t *testing.T) { { name: "only Version", input: &gopom.Parent{ - Version: stringPointer("something"), + Version: ptr("something"), }, expected: &pkg.JavaPomParent{ Version: "something", @@ -423,7 +393,7 @@ func Test_pomParent(t *testing.T) { { name: "unused field", input: &gopom.Parent{ - RelativePath: stringPointer("something"), + RelativePath: ptr("something"), }, expected: nil, }, @@ -431,7 +401,8 @@ func Test_pomParent(t *testing.T) { for _, test := range tests { t.Run(test.name, func(t *testing.T) { - assert.Equal(t, test.expected, pomParent(gopom.Project{}, test.input)) + r := newMavenResolver(nil, DefaultArchiveCatalogerConfig()) + assert.Equal(t, test.expected, pomParent(context.Background(), r, &gopom.Project{Parent: test.input})) }) } } @@ -454,184 +425,283 @@ func Test_cleanDescription(t *testing.T) { for _, test := range tests { t.Run(test.name, func(t *testing.T) { - assert.Equal(t, test.expected, cleanDescription(stringPointer(test.input))) + assert.Equal(t, test.expected, cleanDescription(test.input)) }) } } -func Test_resolveProperty(t *testing.T) { +func Test_resolveLicenses(t *testing.T) { + mavenURL := mockMavenRepo(t) + localM2 := "test-fixtures/pom/maven-repo" + localDir := "test-fixtures/pom/local" + containingDir := "test-fixtures/pom/local/contains-child-1" + + expectedLicenses := []pkg.License{ + { + Value: "Eclipse Public License v2.0", + SPDXExpression: "", + Type: license.Declared, + URLs: []string{"https://www.eclipse.org/legal/epl-v20.html"}, + }, + } + tests := []struct { name string - property string - pom gopom.Project - expected string + scanDir string + cfg ArchiveCatalogerConfig + expected []pkg.License }{ { - name: "property", - property: "${version.number}", - pom: gopom.Project{ - Properties: &gopom.Properties{ - Entries: map[string]string{ - "version.number": "12.5.0", - }, - }, + name: "local no resolution", + scanDir: containingDir, + cfg: ArchiveCatalogerConfig{ + UseMavenLocalRepository: false, + UseNetwork: false, + MavenLocalRepositoryDir: "", + MavenBaseURL: "", }, - expected: "12.5.0", + expected: nil, }, { - name: "groupId", - property: "${project.groupId}", - pom: gopom.Project{ - GroupID: stringPointer("org.some.group"), + name: "local all poms", + scanDir: localDir, + cfg: ArchiveCatalogerConfig{ + UseMavenLocalRepository: false, + UseNetwork: false, }, - expected: "org.some.group", + expected: expectedLicenses, }, { - name: "parent groupId", - property: "${project.parent.groupId}", - pom: gopom.Project{ - Parent: &gopom.Parent{ - GroupID: stringPointer("org.some.parent"), - }, + name: "local m2 cache", + scanDir: containingDir, + cfg: ArchiveCatalogerConfig{ + UseMavenLocalRepository: true, + MavenLocalRepositoryDir: localM2, + UseNetwork: false, + MavenBaseURL: "", }, - expected: "org.some.parent", + expected: expectedLicenses, }, { - name: "nil pointer halts search", - property: "${project.parent.groupId}", - pom: gopom.Project{ - Parent: nil, + name: "local with network", + scanDir: containingDir, + cfg: ArchiveCatalogerConfig{ + UseMavenLocalRepository: false, + UseNetwork: true, + MavenBaseURL: mavenURL, }, - expected: "", + expected: expectedLicenses, + }, + } + + for _, test := range tests { + t.Run(test.name, func(t *testing.T) { + cat := NewPomCataloger(test.cfg) + + ds, err := directorysource.NewFromPath(test.scanDir) + require.NoError(t, err) + + fr, err := ds.FileResolver(source.AllLayersScope) + require.NoError(t, err) + + ctx := context.TODO() + pkgs, _, err := cat.Catalog(ctx, fr) + require.NoError(t, err) + + var child1 pkg.Package + for _, p := range pkgs { + if p.Name == "child-one" { + child1 = p + break + } + } + require.Equal(t, "child-one", child1.Name) + + got := child1.Licenses.ToSlice() + for i := 0; i < len(got); i++ { + // ignore locations, just check license text + (&got[i]).Locations = file.LocationSet{} + } + require.ElementsMatch(t, test.expected, got) + }) + } +} + +func Test_getUtf8Reader(t *testing.T) { + tests := []struct { + name string + contents string + }{ + { + name: "unknown encoding", + // random binary contents + contents: "BkiJz02JyEWE0nXR6TH///9NicpJweEETIucJIgAAABJicxPjQwhTY1JCE05WQh0BU2J0eunTYshTIusJIAAAAAPHwBNOeV1BUUx2+tWTIlUJDhMiUwkSEyJRCQgSIl8JFBMiQ==", }, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + decoder := base64.NewDecoder(base64.StdEncoding, strings.NewReader(tt.contents)) + + got, err := getUtf8Reader(decoder) + require.NoError(t, err) + gotBytes, err := io.ReadAll(got) + require.NoError(t, err) + // if we couldn't decode the section as UTF-8, we should get a replacement character + assert.Contains(t, string(gotBytes), "īŋŊ") + }) + } +} + +func getCommonsTextExpectedPackages() []pkg.Package { + return []pkg.Package{ { - name: "nil string pointer halts search", - property: "${project.parent.groupId}", - pom: gopom.Project{ - Parent: &gopom.Parent{ - GroupID: nil, + Name: "commons-lang3", + Version: "3.12.0", + PURL: "pkg:maven/org.apache.commons/commons-lang3@3.12.0", + Language: pkg.Java, + Type: pkg.JavaPkg, + FoundBy: pomCatalogerName, + Metadata: pkg.JavaArchive{ + PomProperties: &pkg.JavaPomProperties{ + GroupID: "org.apache.commons", + ArtifactID: "commons-lang3", }, }, - expected: "", }, { - name: "double dereference", - property: "${springboot.version}", - pom: gopom.Project{ - Parent: &gopom.Parent{ - Version: stringPointer("1.2.3"), - }, - Properties: &gopom.Properties{ - Entries: map[string]string{ - "springboot.version": "${project.parent.version}", - }, + Name: "junit-jupiter", + Version: "", + PURL: "pkg:maven/org.junit.jupiter/junit-jupiter", + Language: pkg.Java, + Type: pkg.JavaPkg, + FoundBy: pomCatalogerName, + Metadata: pkg.JavaArchive{ + PomProperties: &pkg.JavaPomProperties{ + GroupID: "org.junit.jupiter", + ArtifactID: "junit-jupiter", + Scope: "test", }, }, - expected: "1.2.3", }, { - name: "map missing stops double dereference", - property: "${springboot.version}", - pom: gopom.Project{ - Parent: &gopom.Parent{ - Version: stringPointer("1.2.3"), + Name: "assertj-core", + Version: "3.23.1", + PURL: "pkg:maven/org.assertj/assertj-core@3.23.1", + Language: pkg.Java, + Type: pkg.JavaPkg, + FoundBy: pomCatalogerName, + Metadata: pkg.JavaArchive{ + PomProperties: &pkg.JavaPomProperties{ + GroupID: "org.assertj", + ArtifactID: "assertj-core", + Scope: "test", }, }, - expected: "", }, { - name: "resolution halts even if it resolves to a variable", - property: "${springboot.version}", - pom: gopom.Project{ - Parent: &gopom.Parent{ - Version: stringPointer("${undefined.version}"), + Name: "commons-io", + Version: "2.11.0", + PURL: "pkg:maven/commons-io/commons-io@2.11.0", + Language: pkg.Java, + Type: pkg.JavaPkg, + FoundBy: pomCatalogerName, + Metadata: pkg.JavaArchive{ + PomProperties: &pkg.JavaPomProperties{ + GroupID: "commons-io", + ArtifactID: "commons-io", + Scope: "test", }, - Properties: &gopom.Properties{ - Entries: map[string]string{ - "springboot.version": "${project.parent.version}", - }, + }, + }, + { + Name: "mockito-inline", + Version: "4.8.0", + PURL: "pkg:maven/org.mockito/mockito-inline@4.8.0", + Language: pkg.Java, + Type: pkg.JavaPkg, + FoundBy: pomCatalogerName, + Metadata: pkg.JavaArchive{ + PomProperties: &pkg.JavaPomProperties{ + GroupID: "org.mockito", + ArtifactID: "mockito-inline", + Scope: "test", }, }, - expected: "", }, { - name: "resolution halts even if cyclic", - property: "${springboot.version}", - pom: gopom.Project{ - Properties: &gopom.Properties{ - Entries: map[string]string{ - "springboot.version": "${springboot.version}", - }, + Name: "js", + Version: "22.0.0.2", + PURL: "pkg:maven/org.graalvm.js/js@22.0.0.2", + Language: pkg.Java, + Type: pkg.JavaPkg, + FoundBy: pomCatalogerName, + Metadata: pkg.JavaArchive{ + PomProperties: &pkg.JavaPomProperties{ + GroupID: "org.graalvm.js", + ArtifactID: "js", + Scope: "test", }, }, - expected: "", }, { - name: "resolution halts even if cyclic more steps", - property: "${cyclic.version}", - pom: gopom.Project{ - Properties: &gopom.Properties{ - Entries: map[string]string{ - "other.version": "${cyclic.version}", - "springboot.version": "${other.version}", - "cyclic.version": "${springboot.version}", - }, + Name: "js-scriptengine", + Version: "22.0.0.2", + PURL: "pkg:maven/org.graalvm.js/js-scriptengine@22.0.0.2", + Language: pkg.Java, + Type: pkg.JavaPkg, + FoundBy: pomCatalogerName, + Metadata: pkg.JavaArchive{ + PomProperties: &pkg.JavaPomProperties{ + GroupID: "org.graalvm.js", + ArtifactID: "js-scriptengine", + Scope: "test", }, }, - expected: "", }, { - name: "resolution halts even if cyclic involving parent", - property: "${cyclic.version}", - pom: gopom.Project{ - Parent: &gopom.Parent{ - Version: stringPointer("${cyclic.version}"), + Name: "commons-rng-simple", + Version: "1.4", + PURL: "pkg:maven/org.apache.commons/commons-rng-simple@1.4", + Language: pkg.Java, + Type: pkg.JavaPkg, + FoundBy: pomCatalogerName, + Metadata: pkg.JavaArchive{ + PomProperties: &pkg.JavaPomProperties{ + GroupID: "org.apache.commons", + ArtifactID: "commons-rng-simple", + Scope: "test", }, - Properties: &gopom.Properties{ - Entries: map[string]string{ - "other.version": "${parent.version}", - "springboot.version": "${other.version}", - "cyclic.version": "${springboot.version}", - }, + }, + }, + { + Name: "jmh-core", + Version: "1.35", + PURL: "pkg:maven/org.openjdk.jmh/jmh-core@1.35", + Language: pkg.Java, + Type: pkg.JavaPkg, + FoundBy: pomCatalogerName, + Metadata: pkg.JavaArchive{ + PomProperties: &pkg.JavaPomProperties{ + GroupID: "org.openjdk.jmh", + ArtifactID: "jmh-core", + Scope: "test", }, }, - expected: "", }, - } - - for _, test := range tests { - t.Run(test.name, func(t *testing.T) { - resolved := resolveProperty(test.pom, stringPointer(test.property), test.name) - assert.Equal(t, test.expected, resolved) - }) - } -} - -func stringPointer(s string) *string { - return &s -} - -func Test_getUtf8Reader(t *testing.T) { - tests := []struct { - name string - contents string - }{ { - name: "unknown encoding", - // random binary contents - contents: "BkiJz02JyEWE0nXR6TH///9NicpJweEETIucJIgAAABJicxPjQwhTY1JCE05WQh0BU2J0eunTYshTIusJIAAAAAPHwBNOeV1BUUx2+tWTIlUJDhMiUwkSEyJRCQgSIl8JFBMiQ==", + Name: "jmh-generator-annprocess", + Version: "1.35", + PURL: "pkg:maven/org.openjdk.jmh/jmh-generator-annprocess@1.35", + Language: pkg.Java, + Type: pkg.JavaPkg, + FoundBy: pomCatalogerName, + Metadata: pkg.JavaArchive{ + PomProperties: &pkg.JavaPomProperties{ + GroupID: "org.openjdk.jmh", + ArtifactID: "jmh-generator-annprocess", + Scope: "test", + }, + }, }, } - for _, tt := range tests { - t.Run(tt.name, func(t *testing.T) { - decoder := base64.NewDecoder(base64.StdEncoding, strings.NewReader(tt.contents)) - - got, err := getUtf8Reader(decoder) - require.NoError(t, err) - gotBytes, err := io.ReadAll(got) - require.NoError(t, err) - // if we couldn't decode the section as UTF-8, we should get a replacement character - assert.Contains(t, string(gotBytes), "īŋŊ") - }) - } } diff --git a/syft/pkg/cataloger/java/test-fixtures/local-repository-settings/.m2/settings.xml b/syft/pkg/cataloger/java/test-fixtures/local-repository-settings/.m2/settings.xml new file mode 100644 index 00000000000..f8b9552a4b7 --- /dev/null +++ b/syft/pkg/cataloger/java/test-fixtures/local-repository-settings/.m2/settings.xml @@ -0,0 +1,4 @@ + + /some/other/repo + \ No newline at end of file diff --git a/syft/pkg/cataloger/java/test-fixtures/pom/commons-text.pom.xml b/syft/pkg/cataloger/java/test-fixtures/pom/commons-text.pom.xml deleted file mode 100644 index 6f54a6ed6b1..00000000000 --- a/syft/pkg/cataloger/java/test-fixtures/pom/commons-text.pom.xml +++ /dev/null @@ -1,575 +0,0 @@ - - - - 4.0.0 - - org.apache.commons - commons-parent - 54 - - commons-text - 1.10.0 - Apache Commons Text - Apache Commons Text is a library focused on algorithms working on strings. - https://commons.apache.org/proper/commons-text - - - ISO-8859-1 - UTF-8 - 1.8 - 1.8 - - text - org.apache.commons.text - - 1.10.0 - (Java 8+) - - TEXT - 12318221 - - text - https://svn.apache.org/repos/infra/websites/production/commons/content/proper/commons-text - site-content - - 5.9.1 - 3.2.0 - 9.3 - - 4.7.2.0 - 4.7.2 - 3.19.0 - 6.49.0 - - 4.8.0 - 0.8.8 - - - 3.10.0 - 3.4.1 - - - 22.0.0.2 - 1.4 - - 0.16.0 - false - - 1.35 - 3.1.2 - - - 1.9 - RC1 - true - scm:svn:https://dist.apache.org/repos/dist/dev/commons/${commons.componentid} - Gary Gregory - 86fdc7e2a11262cb - - - - - org.apache.commons - commons-lang3 - 3.12.0 - - - - org.junit.jupiter - junit-jupiter - test - - - org.assertj - assertj-core - 3.23.1 - test - - - commons-io - commons-io - 2.11.0 - test - - - org.mockito - - mockito-inline - ${commons.mockito.version} - test - - - org.graalvm.js - js - ${graalvm.version} - test - - - org.graalvm.js - js-scriptengine - ${graalvm.version} - test - - - org.apache.commons - commons-rng-simple - ${commons.rng.version} - test - - - org.openjdk.jmh - jmh-core - ${jmh.version} - test - - - org.openjdk.jmh - jmh-generator-annprocess - ${jmh.version} - test - - - - - clean verify apache-rat:check japicmp:cmp checkstyle:check spotbugs:check javadoc:javadoc - - - - org.apache.rat - apache-rat-plugin - - - site-content/** - src/site/resources/download_lang.cgi - src/test/resources/org/apache/commons/text/stringEscapeUtilsTestData.txt - src/test/resources/org/apache/commons/text/lcs-perf-analysis-inputs.csv - src/site/resources/release-notes/RELEASE-NOTES-*.txt - - - - - maven-pmd-plugin - ${commons.pmd.version} - - ${maven.compiler.target} - - - - net.sourceforge.pmd - pmd-core - ${commons.pmd-impl.version} - - - net.sourceforge.pmd - pmd-java - ${commons.pmd-impl.version} - - - net.sourceforge.pmd - pmd-javascript - ${commons.pmd-impl.version} - - - net.sourceforge.pmd - pmd-jsp - ${commons.pmd-impl.version} - - - - - - - - maven-checkstyle-plugin - ${checkstyle.plugin.version} - - false - src/conf/checkstyle.xml - src/conf/checkstyle-header.txt - src/conf/checkstyle-suppressions.xml - src/conf/checkstyle-suppressions.xml - true - **/generated/**.java,**/jmh_generated/**.java - - - - com.puppycrawl.tools - checkstyle - ${checkstyle.version} - - - - - com.github.spotbugs - spotbugs-maven-plugin - ${commons.spotbugs.plugin.version} - - - com.github.spotbugs - spotbugs - ${commons.spotbugs.impl.version} - - - - src/conf/spotbugs-exclude-filter.xml - - - - maven-assembly-plugin - - - src/assembly/bin.xml - src/assembly/src.xml - - gnu - - - - org.apache.maven.plugins - maven-jar-plugin - - - - test-jar - - - - - - - ${commons.module.name} - - - - - - org.apache.maven.plugins - maven-scm-publish-plugin - - - javadocs - - - - - org.apache.maven.plugins - maven-javadoc-plugin - - ${maven.compiler.source} - - - - - - - - - maven-checkstyle-plugin - ${checkstyle.plugin.version} - - false - src/conf/checkstyle.xml - src/conf/checkstyle-header.txt - src/conf/checkstyle-suppressions.xml - src/conf/checkstyle-suppressions.xml - true - **/generated/**.java,**/jmh_generated/**.java - - - - - checkstyle - - - - - - - com.github.spotbugs - spotbugs-maven-plugin - ${commons.spotbugs.plugin.version} - - src/conf/spotbugs-exclude-filter.xml - - - - com.github.siom79.japicmp - japicmp-maven-plugin - - - maven-pmd-plugin - 3.19.0 - - ${maven.compiler.target} - - - - - pmd - cpd - - - - - - org.codehaus.mojo - taglist-maven-plugin - 3.0.0 - - - - - Needs Work - - - TODO - exact - - - FIXME - exact - - - XXX - exact - - - - - Noteable Markers - - - NOTE - exact - - - NOPMD - exact - - - NOSONAR - exact - - - - - - - - - - - 2014 - - - - kinow - Bruno P. Kinoshita - kinow@apache.org - - - britter - Benedikt Ritter - britter@apache.org - - - chtompki - Rob Tompkins - chtompki@apache.org - - - ggregory - Gary Gregory - ggregory at apache.org - https://www.garygregory.com - The Apache Software Foundation - https://www.apache.org/ - - PMC Member - - America/New_York - - https://people.apache.org/~ggregory/img/garydgregory80.png - - - - djones - Duncan Jones - djones@apache.org - - - - - - Don Jeba - donjeba@yahoo.com - - - Sampanna Kahu - - - Jarek Strzelecki - - - Lee Adcock - - - Amey Jadiye - ameyjadiye@gmail.com - - - Arun Vinud S S - - - Ioannis Sermetziadis - - - Jostein Tveit - - - Luciano Medallia - - - Jan Martin Keil - - - Nandor Kollar - - - Nick Wong - - - Ali Ghanbari - https://ali-ghanbari.github.io/ - - - - - scm:git:https://gitbox.apache.org/repos/asf/commons-text - scm:git:https://gitbox.apache.org/repos/asf/commons-text - https://gitbox.apache.org/repos/asf?p=commons-text.git - - - - jira - https://issues.apache.org/jira/browse/TEXT - - - - - apache.website - Apache Commons Site - scm:svn:https://svn.apache.org/repos/infra/websites/production/commons/content/proper/commons-text/ - - - - - - setup-checkout - - - site-content - - - - - - org.apache.maven.plugins - maven-antrun-plugin - - - prepare-checkout - - run - - pre-site - - - - - - - - - - - - - - - - - - - - - - - - java9+ - - [9,) - - - - true - - - - benchmark - - true - org.apache - - - - - org.codehaus.mojo - exec-maven-plugin - 3.1.0 - - - benchmark - test - - exec - - - test - java - - -classpath - - org.openjdk.jmh.Main - -rf - json - -rff - target/jmh-result.${benchmark}.json - ${benchmark} - - - - - - - - - - \ No newline at end of file diff --git a/syft/pkg/cataloger/java/test-fixtures/pom/local/child-1/pom.xml b/syft/pkg/cataloger/java/test-fixtures/pom/local/child-1/pom.xml new file mode 100644 index 00000000000..63ed7d474dd --- /dev/null +++ b/syft/pkg/cataloger/java/test-fixtures/pom/local/child-1/pom.xml @@ -0,0 +1,42 @@ + + + 4.0.0 + + + + + my.org + parent-one + 3.11.0 + ../parent-1/pom.xml + + + child-one + + ${project.one}.3.6 + jar + + + 3.12.0 + 4.2 + 4.12 + + + + + org.apache.commons + commons-lang3 + + + + diff --git a/syft/pkg/cataloger/java/test-fixtures/pom/local/commons-text-1.10.0/pom.xml b/syft/pkg/cataloger/java/test-fixtures/pom/local/commons-text-1.10.0/pom.xml new file mode 100644 index 00000000000..e4ad83f1596 --- /dev/null +++ b/syft/pkg/cataloger/java/test-fixtures/pom/local/commons-text-1.10.0/pom.xml @@ -0,0 +1,263 @@ + + + + 4.0.0 + + org.apache.commons + commons-parent + 54 + + commons-text + 1.10.0 + Apache Commons Text + Apache Commons Text is a library focused on algorithms working on strings. + https://commons.apache.org/proper/commons-text + + + ISO-8859-1 + UTF-8 + 1.8 + 1.8 + + text + org.apache.commons.text + + 1.10.0 + (Java 8+) + + TEXT + 12318221 + + text + https://svn.apache.org/repos/infra/websites/production/commons/content/proper/commons-text + site-content + + 5.9.1 + 3.2.0 + 9.3 + + 4.7.2.0 + 4.7.2 + 3.19.0 + 6.49.0 + + 4.8.0 + 0.8.8 + + + 3.10.0 + 3.4.1 + + + 22.0.0.2 + 1.4 + + 0.16.0 + false + + 1.35 + 3.1.2 + + + 1.9 + RC1 + true + scm:svn:https://dist.apache.org/repos/dist/dev/commons/${commons.componentid} + Gary Gregory + 86fdc7e2a11262cb + + + + + org.apache.commons + commons-lang3 + 3.12.0 + + + + org.junit.jupiter + junit-jupiter + test + + + org.assertj + assertj-core + 3.23.1 + test + + + commons-io + commons-io + 2.11.0 + test + + + org.mockito + + mockito-inline + ${commons.mockito.version} + test + + + org.graalvm.js + js + ${graalvm.version} + test + + + org.graalvm.js + js-scriptengine + ${graalvm.version} + test + + + org.apache.commons + commons-rng-simple + ${commons.rng.version} + test + + + org.openjdk.jmh + jmh-core + ${jmh.version} + test + + + org.openjdk.jmh + jmh-generator-annprocess + ${jmh.version} + test + + + + 2014 + + + scm:git:https://gitbox.apache.org/repos/asf/commons-text + scm:git:https://gitbox.apache.org/repos/asf/commons-text + https://gitbox.apache.org/repos/asf?p=commons-text.git + + + + jira + https://issues.apache.org/jira/browse/TEXT + + + + + apache.website + Apache Commons Site + scm:svn:https://svn.apache.org/repos/infra/websites/production/commons/content/proper/commons-text/ + + + + + + setup-checkout + + + site-content + + + + + + org.apache.maven.plugins + maven-antrun-plugin + + + prepare-checkout + + run + + pre-site + + + + + + + + + + + + + + + + + + + + + + + + java9+ + + [9,) + + + + true + + + + benchmark + + true + org.apache + + + + + org.codehaus.mojo + exec-maven-plugin + 3.1.0 + + + benchmark + test + + exec + + + test + java + + -classpath + + org.openjdk.jmh.Main + -rf + json + -rff + target/jmh-result.${benchmark}.json + ${benchmark} + + + + + + + + + + \ No newline at end of file diff --git a/syft/pkg/cataloger/java/test-fixtures/pom/local/contains-child-1/pom.xml b/syft/pkg/cataloger/java/test-fixtures/pom/local/contains-child-1/pom.xml new file mode 100644 index 00000000000..18dcd8c4bbf --- /dev/null +++ b/syft/pkg/cataloger/java/test-fixtures/pom/local/contains-child-1/pom.xml @@ -0,0 +1,27 @@ + + + 4.0.0 + + contains-child-one + 5 + jar + + + + + my.org + child-one + 1.3.6 + + + + + + + my.org + child-one + + + + diff --git a/syft/pkg/cataloger/java/test-fixtures/pom/pom.xml b/syft/pkg/cataloger/java/test-fixtures/pom/local/example-java-app-maven/pom.xml similarity index 100% rename from syft/pkg/cataloger/java/test-fixtures/pom/pom.xml rename to syft/pkg/cataloger/java/test-fixtures/pom/local/example-java-app-maven/pom.xml diff --git a/syft/pkg/cataloger/java/test-fixtures/pom/local/parent-1/pom.xml b/syft/pkg/cataloger/java/test-fixtures/pom/local/parent-1/pom.xml new file mode 100644 index 00000000000..4a6d1f323c2 --- /dev/null +++ b/syft/pkg/cataloger/java/test-fixtures/pom/local/parent-1/pom.xml @@ -0,0 +1,51 @@ + + + 4.0.0 + + my.org + parent-two + 13.7.8 + ../parent-2/pom.xml + + + parent-one + 3.11.0 + pom + + + + 3.1${project.parent.version}.0 + 4.3 + + + + + + org.apache.commons + commons-lang3 + ${commons.lang3.version} + + + + + + + org.apache.commons + commons-text + ${commons.text.version} + + + org.apache.commons + commons-collections4 + ${commons.collections4.version} + + + junit + junit + ${commons.junit.version} + test + + + + diff --git a/syft/pkg/cataloger/java/test-fixtures/pom/local/parent-2/pom.xml b/syft/pkg/cataloger/java/test-fixtures/pom/local/parent-2/pom.xml new file mode 100644 index 00000000000..5ca8cc4a202 --- /dev/null +++ b/syft/pkg/cataloger/java/test-fixtures/pom/local/parent-2/pom.xml @@ -0,0 +1,67 @@ + + + 4.0.0 + + my.org + parent-two + 13.7.8 + pom + + + 3.14.0 + 4.4 + 1.12.0 + 4.13.2 + 3 + 1 + + + + + Eclipse Public License v2.0 + https://www.eclipse.org/legal/epl-v20.html + + + + + + + org.apache.commons + commons-lang3 + ${commons.lang3.version} + + + org.apache.commons + commons-text + ${commons.text.version} + + + junit + junit + ${commons.junit.version} + test + + + + + + + org.apache.commons + commons-text + ${commons.text.version} + + + org.apache.commons + commons-collections4 + ${commons.collections4.version} + + + junit + junit + ${commons.junit.version} + test + + + + diff --git a/syft/pkg/cataloger/java/test-fixtures/pom/maven-repo/my/org/child-one/1.3.6/child-one-1.3.6.pom b/syft/pkg/cataloger/java/test-fixtures/pom/maven-repo/my/org/child-one/1.3.6/child-one-1.3.6.pom new file mode 100644 index 00000000000..6a72f2fd56d --- /dev/null +++ b/syft/pkg/cataloger/java/test-fixtures/pom/maven-repo/my/org/child-one/1.3.6/child-one-1.3.6.pom @@ -0,0 +1,41 @@ + + + 4.0.0 + + + + + my.org + parent-one + 3.11.0 + + + child-one + + ${project.one}.3.6 + jar + + + 3.12.0 + 4.2 + 4.12 + + + + + org.apache.commons + commons-lang3 + + + + diff --git a/syft/pkg/cataloger/java/test-fixtures/pom/maven-repo/my/org/child-two/2.1.90/child-two-2.1.90.pom b/syft/pkg/cataloger/java/test-fixtures/pom/maven-repo/my/org/child-two/2.1.90/child-two-2.1.90.pom new file mode 100644 index 00000000000..62a3592d181 --- /dev/null +++ b/syft/pkg/cataloger/java/test-fixtures/pom/maven-repo/my/org/child-two/2.1.90/child-two-2.1.90.pom @@ -0,0 +1,53 @@ + + + 4.0.0 + + + + + my.org + parent-one + 3.11.0 + + + ${project.parent.groupId} + child-two + 2.1.90 + jar + + + 4.2 + 4.12 + my.other.org + + + + + org.apache.commons + commons-lang3 + + + org.apache.commons + commons-math${project.parent.version} + 3.5 + + + org.apache.commons + commons-exec + 1.${commons-exec_subversion} + + + + diff --git a/syft/pkg/cataloger/java/test-fixtures/pom/maven-repo/my/org/parent-one/3.11.0/parent-one-3.11.0.pom b/syft/pkg/cataloger/java/test-fixtures/pom/maven-repo/my/org/parent-one/3.11.0/parent-one-3.11.0.pom new file mode 100644 index 00000000000..4dd7d533f73 --- /dev/null +++ b/syft/pkg/cataloger/java/test-fixtures/pom/maven-repo/my/org/parent-one/3.11.0/parent-one-3.11.0.pom @@ -0,0 +1,51 @@ + + + 4.0.0 + + my.org + parent-two + 13.7.8 + + + my.org + parent-one + 3.11.0 + pom + + + + 3.1${project.parent.version}.0 + 4.3 + + + + + + org.apache.commons + commons-lang3 + ${commons.lang3.version} + + + + + + + org.apache.commons + commons-text + ${commons.text.version} + + + org.apache.commons + commons-collections4 + ${commons.collections4.version} + + + junit + junit + ${commons.junit.version} + test + + + + diff --git a/syft/pkg/cataloger/java/test-fixtures/pom/maven-repo/my/org/parent-two/13.7.8/parent-two-13.7.8.pom b/syft/pkg/cataloger/java/test-fixtures/pom/maven-repo/my/org/parent-two/13.7.8/parent-two-13.7.8.pom new file mode 100644 index 00000000000..3341e805ce9 --- /dev/null +++ b/syft/pkg/cataloger/java/test-fixtures/pom/maven-repo/my/org/parent-two/13.7.8/parent-two-13.7.8.pom @@ -0,0 +1,67 @@ + + + 4.0.0 + + my.org + parent-two + 13.7.8 + pom + + + + Eclipse Public License v2.0 + https://www.eclipse.org/legal/epl-v20.html + + + + + 3.14.0 + 4.4 + 1.12.0 + 4.13.2 + 3 + 1 + + + + + + org.apache.commons + commons-lang3 + ${commons.lang3.version} + + + org.apache.commons + commons-text + ${commons.text.version} + + + junit + junit + ${commons.junit.version} + test + + + + + + + org.apache.commons + commons-text + ${commons.text.version} + + + org.apache.commons + commons-collections4 + ${commons.collections4.version} + + + junit + junit + ${commons.junit.version} + test + + + + diff --git a/syft/pkg/cataloger/java/test-fixtures/maven-xml-responses/parent-7.11.2.pom b/syft/pkg/cataloger/java/test-fixtures/pom/maven-repo/net/shibboleth/parent/7.11.2/parent-7.11.2.pom similarity index 100% rename from syft/pkg/cataloger/java/test-fixtures/maven-xml-responses/parent-7.11.2.pom rename to syft/pkg/cataloger/java/test-fixtures/pom/maven-repo/net/shibboleth/parent/7.11.2/parent-7.11.2.pom diff --git a/syft/pkg/cataloger/java/test-fixtures/pom/maven-repo/org/apache/commons/commons-parent/54/commons-parent-54.pom b/syft/pkg/cataloger/java/test-fixtures/pom/maven-repo/org/apache/commons/commons-parent/54/commons-parent-54.pom new file mode 100644 index 00000000000..3fd66f094f4 --- /dev/null +++ b/syft/pkg/cataloger/java/test-fixtures/pom/maven-repo/org/apache/commons/commons-parent/54/commons-parent-54.pom @@ -0,0 +1,132 @@ + + + + 4.0.0 + + org.apache + apache + 27 + + org.apache.commons + commons-parent + 54 + pom + Apache Commons Parent + The Apache Commons Parent POM provides common settings for all Apache Commons components. + 2006 + https://commons.apache.org/commons-parent-pom.html + + + 3.3.9 + ${project.version} + true + Gary Gregory + 86fdc7e2a11262cb + + 1.3 + 1.3 + false + + + + + 1.22 + 1.0 + 3.4.2 + 3.3.0 + 1.12 + 2.12.1 + 3.2.0 + 9.3 + 2.7 + 3.10.1 + 4.3.0 + EpochMillis + 2.7.1 + 0.5.5 + 5.9.0 + + 3.12.1 + 3.2.1 + 4.7.2.0 + 3.5.2 + + + ${project.artifactId}-${commons.release.version} + + -bin + ${project.artifactId}-${commons.release.2.version} + + -bin + ${project.artifactId}-${commons.release.3.version} + + -bin + + -bin + + + 1.00 + 0.90 + 0.95 + 0.85 + 0.85 + 0.90 + false + + ${project.artifactId} + + ${project.artifactId} + + + org.apache.commons.${commons.packageId} + org.apache.commons.*;version=${project.version};-noimport:=true + * + + + true + + + ${project.build.directory}/osgi/MANIFEST.MF + + scp + + iso-8859-1 + ${commons.encoding} + ${commons.encoding} + ${commons.encoding} + yyyy-MM-dd HH:mm:ssZ + ${scmBranch}@r${buildNumber}; ${maven.build.timestamp} + + + + + + org.junit + junit-bom + ${commons.junit.version} + pom + import + + + + + + + site-basic + + true + true + true + true + true + true + true + true + + + + diff --git a/syft/pkg/cataloger/java/test-fixtures/pom/maven-repo/org/junit/junit-bom/5.9.0/junit-bom-5.9.0.pom b/syft/pkg/cataloger/java/test-fixtures/pom/maven-repo/org/junit/junit-bom/5.9.0/junit-bom-5.9.0.pom new file mode 100644 index 00000000000..eb1b959bc86 --- /dev/null +++ b/syft/pkg/cataloger/java/test-fixtures/pom/maven-repo/org/junit/junit-bom/5.9.0/junit-bom-5.9.0.pom @@ -0,0 +1,151 @@ + + + 4.0.0 + org.junit + junit-bom + 5.9.0 + pom + + + Eclipse Public License v2.0 + https://www.eclipse.org/legal/epl-v20.html + + + + + bechte + Stefan Bechtold + stefan.bechtold@me.com + + + jlink + Johannes Link + business@johanneslink.net + + + marcphilipp + Marc Philipp + mail@marcphilipp.de + + + mmerdes + Matthias Merdes + matthias.merdes@heidelpay.com + + + sbrannen + Sam Brannen + sam@sambrannen.com + + + sormuras + Christian Stein + sormuras@gmail.com + + + juliette-derancourt + Juliette de Rancourt + derancourt.juliette@gmail.com + + + + scm:git:git://github.com/junit-team/junit5.git + scm:git:git://github.com/junit-team/junit5.git + https://github.com/junit-team/junit5 + + + + + org.junit.jupiter + junit-jupiter + 5.9.0 + + + org.junit.jupiter + junit-jupiter-api + 5.9.0 + + + org.junit.jupiter + junit-jupiter-engine + 5.9.0 + + + org.junit.jupiter + junit-jupiter-migrationsupport + 5.9.0 + + + org.junit.jupiter + junit-jupiter-params + 5.9.0 + + + org.junit.platform + junit-platform-commons + 1.9.0 + + + org.junit.platform + junit-platform-console + 1.9.0 + + + org.junit.platform + junit-platform-engine + 1.9.0 + + + org.junit.platform + junit-platform-jfr + 1.9.0 + + + org.junit.platform + junit-platform-launcher + 1.9.0 + + + org.junit.platform + junit-platform-reporting + 1.9.0 + + + org.junit.platform + junit-platform-runner + 1.9.0 + + + org.junit.platform + junit-platform-suite + 1.9.0 + + + org.junit.platform + junit-platform-suite-api + 1.9.0 + + + org.junit.platform + junit-platform-suite-commons + 1.9.0 + + + org.junit.platform + junit-platform-suite-engine + 1.9.0 + + + org.junit.platform + junit-platform-testkit + 1.9.0 + + + org.junit.vintage + junit-vintage-engine + 5.9.0 + + + + diff --git a/syft/pkg/cataloger/java/test-fixtures/pom/maven-repo/org/junit/junit-bom/5.9.1/junit-bom-5.9.1.pom b/syft/pkg/cataloger/java/test-fixtures/pom/maven-repo/org/junit/junit-bom/5.9.1/junit-bom-5.9.1.pom new file mode 100644 index 00000000000..c21518a394c --- /dev/null +++ b/syft/pkg/cataloger/java/test-fixtures/pom/maven-repo/org/junit/junit-bom/5.9.1/junit-bom-5.9.1.pom @@ -0,0 +1,152 @@ + + + 4.0.0 + org.junit + junit-bom + 5.9.1 + pom + JUnit 5 (Bill of Materials) + + + Eclipse Public License v2.0 + https://www.eclipse.org/legal/epl-v20.html + + + + + bechte + Stefan Bechtold + stefan.bechtold@me.com + + + jlink + Johannes Link + business@johanneslink.net + + + marcphilipp + Marc Philipp + mail@marcphilipp.de + + + mmerdes + Matthias Merdes + matthias.merdes@heidelpay.com + + + sbrannen + Sam Brannen + sam@sambrannen.com + + + sormuras + Christian Stein + sormuras@gmail.com + + + juliette-derancourt + Juliette de Rancourt + derancourt.juliette@gmail.com + + + + scm:git:git://github.com/junit-team/junit5.git + scm:git:git://github.com/junit-team/junit5.git + https://github.com/junit-team/junit5 + + + + + org.junit.jupiter + junit-jupiter + 5.9.1 + + + org.junit.jupiter + junit-jupiter-api + 5.9.1 + + + org.junit.jupiter + junit-jupiter-engine + 5.9.1 + + + org.junit.jupiter + junit-jupiter-migrationsupport + 5.9.1 + + + org.junit.jupiter + junit-jupiter-params + 5.9.1 + + + org.junit.platform + junit-platform-commons + 1.9.1 + + + org.junit.platform + junit-platform-console + 1.9.1 + + + org.junit.platform + junit-platform-engine + 1.9.1 + + + org.junit.platform + junit-platform-jfr + 1.9.1 + + + org.junit.platform + junit-platform-launcher + 1.9.1 + + + org.junit.platform + junit-platform-reporting + 1.9.1 + + + org.junit.platform + junit-platform-runner + 1.9.1 + + + org.junit.platform + junit-platform-suite + 1.9.1 + + + org.junit.platform + junit-platform-suite-api + 1.9.1 + + + org.junit.platform + junit-platform-suite-commons + 1.9.1 + + + org.junit.platform + junit-platform-suite-engine + 1.9.1 + + + org.junit.platform + junit-platform-testkit + 1.9.1 + + + org.junit.vintage + junit-vintage-engine + 5.9.1 + + + + diff --git a/syft/pkg/cataloger/java/test-fixtures/maven-xml-responses/opensaml-parent-3.4.6.pom b/syft/pkg/cataloger/java/test-fixtures/pom/maven-repo/org/opensaml/opensaml-parent/3.4.6/opensaml-parent-3.4.6.pom similarity index 100% rename from syft/pkg/cataloger/java/test-fixtures/maven-xml-responses/opensaml-parent-3.4.6.pom rename to syft/pkg/cataloger/java/test-fixtures/pom/maven-repo/org/opensaml/opensaml-parent/3.4.6/opensaml-parent-3.4.6.pom diff --git a/syft/pkg/cataloger/swipl/package.go b/syft/pkg/cataloger/swipl/package.go index 252dda56b7f..6421ede70b6 100644 --- a/syft/pkg/cataloger/swipl/package.go +++ b/syft/pkg/cataloger/swipl/package.go @@ -1,8 +1,6 @@ package swipl import ( - // "strings" - "github.com/anchore/packageurl-go" "github.com/anchore/syft/syft/file" "github.com/anchore/syft/syft/pkg" diff --git a/syft/pkg/license.go b/syft/pkg/license.go index fb79028cee5..ae311a13c35 100644 --- a/syft/pkg/license.go +++ b/syft/pkg/license.go @@ -70,7 +70,7 @@ func NewLicenseFromType(value string, t license.Type) License { var err error spdxExpression, err = license.ParseExpression(value) if err != nil { - log.Trace("unable to parse license expression: %w", err) + log.WithFields("error", err, "expression", value).Trace("unable to parse license expression") } } From 703330abd0c72b79702601dacf342c5f47d2340e Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 6 Aug 2024 13:07:21 -0400 Subject: [PATCH 049/122] chore(deps): bump github.com/gkampitakis/go-snaps from 0.5.6 to 0.5.7 (#3097) Bumps [github.com/gkampitakis/go-snaps](https://github.com/gkampitakis/go-snaps) from 0.5.6 to 0.5.7. - [Release notes](https://github.com/gkampitakis/go-snaps/releases) - [Commits](https://github.com/gkampitakis/go-snaps/compare/v0.5.6...v0.5.7) --- updated-dependencies: - dependency-name: github.com/gkampitakis/go-snaps dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- go.mod | 2 +- go.sum | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/go.mod b/go.mod index 87692a0f38c..0c2e947553d 100644 --- a/go.mod +++ b/go.mod @@ -34,7 +34,7 @@ require ( github.com/elliotchance/phpserialize v1.4.0 github.com/facebookincubator/nvdtools v0.1.5 github.com/github/go-spdx/v2 v2.3.1 - github.com/gkampitakis/go-snaps v0.5.6 + github.com/gkampitakis/go-snaps v0.5.7 github.com/go-git/go-billy/v5 v5.5.0 github.com/go-git/go-git/v5 v5.12.0 github.com/go-test/deep v1.1.1 diff --git a/go.sum b/go.sum index bd5319c94ad..5a56059cb7b 100644 --- a/go.sum +++ b/go.sum @@ -293,8 +293,8 @@ github.com/gkampitakis/ciinfo v0.3.0 h1:gWZlOC2+RYYttL0hBqcoQhM7h1qNkVqvRCV1fOvp github.com/gkampitakis/ciinfo v0.3.0/go.mod h1:1NIwaOcFChN4fa/B0hEBdAb6npDlFL8Bwx4dfRLRqAo= github.com/gkampitakis/go-diff v1.3.2 h1:Qyn0J9XJSDTgnsgHRdz9Zp24RaJeKMUHg2+PDZZdC4M= github.com/gkampitakis/go-diff v1.3.2/go.mod h1:LLgOrpqleQe26cte8s36HTWcTmMEur6OPYerdAAS9tk= -github.com/gkampitakis/go-snaps v0.5.6 h1:kAal5JbqTycI+6xeS3K0nPqvNDAxqKX5W3dRXKxIJpA= -github.com/gkampitakis/go-snaps v0.5.6/go.mod h1:ZABkO14uCuVxBHAXAfKG+bqNz+aa1bGPAg8jkI0Nk8Y= +github.com/gkampitakis/go-snaps v0.5.7 h1:uVGjHR4t4pPHU944udMx7VKHpwepZXmvDMF+yDmI0rg= +github.com/gkampitakis/go-snaps v0.5.7/go.mod h1:ZABkO14uCuVxBHAXAfKG+bqNz+aa1bGPAg8jkI0Nk8Y= 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= From 0f9df805c195c4e32db4d3f141210737ae1c300b Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 6 Aug 2024 13:07:33 -0400 Subject: [PATCH 050/122] chore(deps): bump golang.org/x/mod from 0.19.0 to 0.20.0 (#3096) Bumps [golang.org/x/mod](https://github.com/golang/mod) from 0.19.0 to 0.20.0. - [Commits](https://github.com/golang/mod/compare/v0.19.0...v0.20.0) --- updated-dependencies: - dependency-name: golang.org/x/mod dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- go.mod | 2 +- go.sum | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/go.mod b/go.mod index 0c2e947553d..f99fd1c2880 100644 --- a/go.mod +++ b/go.mod @@ -78,7 +78,7 @@ require ( github.com/xeipuuv/gojsonschema v1.2.0 github.com/zyedidia/generic v1.2.2-0.20230320175451-4410d2372cb1 go.uber.org/goleak v1.3.0 - golang.org/x/mod v0.19.0 + golang.org/x/mod v0.20.0 golang.org/x/net v0.27.0 gopkg.in/yaml.v3 v3.0.1 modernc.org/sqlite v1.31.1 diff --git a/go.sum b/go.sum index 5a56059cb7b..b4ee9adca03 100644 --- a/go.sum +++ b/go.sum @@ -920,8 +920,8 @@ golang.org/x/mod v0.4.2/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/mod v0.5.0/go.mod h1:5OXOZSfqPIIbmVBIIKWRFfZjPR0E5r58TLhUjH0a2Ro= golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4= golang.org/x/mod v0.8.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs= -golang.org/x/mod v0.19.0 h1:fEdghXQSo20giMthA7cd28ZC+jts4amQ3YMXiP5oMQ8= -golang.org/x/mod v0.19.0/go.mod h1:hTbmBsO62+eylJbnUtE2MGJUyE7QWk4xUqPFrRgJ+7c= +golang.org/x/mod v0.20.0 h1:utOm6MM3R3dnawAiJgn0y+xvuYRsm1RKM/4giyfDgV0= +golang.org/x/mod v0.20.0/go.mod h1:hTbmBsO62+eylJbnUtE2MGJUyE7QWk4xUqPFrRgJ+7c= golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20181023162649-9b4f9f5ad519/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= From 214a0498e03ac1e855a0a96ebddbf198ee6ec634 Mon Sep 17 00:00:00 2001 From: "anchore-actions-token-generator[bot]" <102182147+anchore-actions-token-generator[bot]@users.noreply.github.com> Date: Tue, 6 Aug 2024 13:07:48 -0400 Subject: [PATCH 051/122] chore(deps): update CPE dictionary index (#3094) Signed-off-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com> Co-authored-by: wagoodman <590471+wagoodman@users.noreply.github.com> --- .../dictionary/data/cpe-index.json | 137 +++++++++++++++++- 1 file changed, 131 insertions(+), 6 deletions(-) diff --git a/syft/pkg/cataloger/internal/cpegenerate/dictionary/data/cpe-index.json b/syft/pkg/cataloger/internal/cpegenerate/dictionary/data/cpe-index.json index b7226416a45..54ec320a881 100644 --- a/syft/pkg/cataloger/internal/cpegenerate/dictionary/data/cpe-index.json +++ b/syft/pkg/cataloger/internal/cpegenerate/dictionary/data/cpe-index.json @@ -4070,6 +4070,9 @@ "netmask": [ "cpe:2.3:a:netmask_project:netmask:*:*:*:*:*:node.js:*:*" ], + "network": [ + "cpe:2.3:a:forkhq:network:*:*:*:*:*:node.js:*:*" + ], "network-manager": [ "cpe:2.3:a:network-manager_project:network-manager:*:*:*:*:*:node.js:*:*" ], @@ -7531,6 +7534,9 @@ "ameliabooking": [ "cpe:2.3:a:tms-outsource:amelia:*:*:*:*:*:wordpress:*:*" ], + "amen": [ + "cpe:2.3:a:amen_project:amen:*:*:*:*:*:*:wordpress:*" + ], "amministrazione-aperta": [ "cpe:2.3:a:amministrazione_aperta_project:amministrazione_aperta:*:*:*:*:*:wordpress:*:*" ], @@ -7579,6 +7585,9 @@ "animated-counters": [ "cpe:2.3:a:eralion:animated_counters:*:*:*:*:*:wordpress:*:*" ], + "anonymous-restricted-content": [ + "cpe:2.3:a:tarassych:anonymous_restricted_content:*:*:*:*:*:wordpress:*:*" + ], "another-wordpress-classifieds-plugin": [ "cpe:2.3:a:awpcp:another_wordpress_classifieds_plugin:*:*:*:*:*:wordpress:*:*" ], @@ -7922,7 +7931,8 @@ "cpe:2.3:a:batch_cat_project:batch_cat:*:*:*:*:*:wordpress:*:*" ], "bb-bootstrap-cards": [ - "cpe:2.3:a:brainstormforce:cards_for_beaver_builder:*:*:*:*:*:wordpress:*:*" + "cpe:2.3:a:brainstormforce:cards_for_beaver_builder:*:*:*:*:*:wordpress:*:*", + "cpe:2.3:a:ultimateaddons:cards_for_beaver_builder:*:*:*:*:*:wordpress:*:*" ], "bbp-move-topics": [ "cpe:2.3:a:bbpress_move_topics_project:bbpress_move_topics:*:*:*:*:*:wordpress:*:*" @@ -7980,6 +7990,9 @@ "bestbooks": [ "cpe:2.3:a:presspage:bestbooks:*:*:*:*:*:wordpress:*:*" ], + "better-anchor-links": [ + "cpe:2.3:a:ludek:better_anchor_links:*:*:*:*:*:wordpress:*:*" + ], "better-font-awesome": [ "cpe:2.3:a:better_font_awesome_project:better_font_awesome:*:*:*:*:*:wordpress:*:*" ], @@ -8256,6 +8269,9 @@ "buddypress-media": [ "cpe:2.3:a:rtcamp:rtmedia:*:*:*:*:*:wordpress:*:*" ], + "buddypress-members-only": [ + "cpe:2.3:a:membersonly:buddypress_members_only:*:*:*:*:*:wordpress:*:*" + ], "bug-library": [ "cpe:2.3:a:bug_library_project:bug_library:*:*:*:*:*:wordpress:*:*" ], @@ -8371,6 +8387,9 @@ "calculator-builder": [ "cpe:2.3:a:wow-company:calculator-builder:*:*:*:*:*:wordpress:*:*" ], + "calculatorpro-calculators": [ + "cpe:2.3:a:jgadbois:calculatorpro_calculators:*:*:*:*:*:wordpress:*:*" + ], "caldera-forms": [ "cpe:2.3:a:calderaforms:caldera_forms:*:*:*:*:*:wordpress:*:*", "cpe:2.3:a:calderalabs:caldera_forms:*:*:*:*:*:wordpress:*:*" @@ -8379,11 +8398,15 @@ "cpe:2.3:a:kieranoshea:calendar:*:*:*:*:*:wordpress:*:*" ], "calendar-booking": [ - "cpe:2.3:a:startbooking:scheduling_plugin:*:*:*:*:*:wordpress:*:*" + "cpe:2.3:a:startbooking:scheduling_plugin:*:*:*:*:*:wordpress:*:*", + "cpe:2.3:a:startbooking:scheduling_plugin_-_online_booking:*:*:*:*:*:wordpress:*:*" ], "calendar-plugin": [ "cpe:2.3:a:calendar_plugin_project:calendar_plugin:*:*:*:*:*:wordpress:*:*" ], + "calendarista-basic-edition": [ + "cpe:2.3:a:typps:calendarista:*:*:*:*:basic:wordpress:*:*" + ], "call-now-button": [ "cpe:2.3:a:callnowbutton:call_now_button:*:*:*:*:*:wordpress:*:*" ], @@ -8944,6 +8967,9 @@ "contact-forms-builder": [ "cpe:2.3:a:wpdevart:contact_form_builder:*:*:*:*:*:wordpress:*:*" ], + "contact-list": [ + "cpe:2.3:a:contactlistpro:contact_list:*:*:*:*:*:wordpress:*:*" + ], "contact-us-page-contact-people": [ "cpe:2.3:a:a3rev:contact_us_page_-_contact_people:*:*:*:*:*:wordpress:*:*" ], @@ -9108,7 +9134,8 @@ "cpe:2.3:a:hasthemes:coupon_zen:*:*:*:*:*:wordpress:*:*" ], "cowidgets-elementor-addons": [ - "cpe:2.3:a:codeless:cowidgets_-_elementor:*:*:*:*:*:wordpress:*:*" + "cpe:2.3:a:codeless:cowidgets_-_elementor:*:*:*:*:*:wordpress:*:*", + "cpe:2.3:a:codeless:cowidgets_elementor_addons:*:*:*:*:*:wordpress:*:*" ], "cp-appointment-calendar": [ "cpe:2.3:a:codepeople:cp_appointment_calendar:*:*:*:*:*:wordpress:*:*" @@ -9489,6 +9516,9 @@ "delucks-seo": [ "cpe:2.3:a:delucks:delucks_seo:*:*:*:*:*:wordpress:*:*" ], + "demo-awesome": [ + "cpe:2.3:a:theme4press:demo_awesome:*:*:*:*:*:wordpress:*:*" + ], "democracy-poll": [ "cpe:2.3:a:wp-kama:democracy_poll:*:*:*:*:*:wordpress:*:*" ], @@ -9878,6 +9908,10 @@ "easyappointments": [ "cpe:2.3:a:easyappointments:easy\\!appointments:*:*:*:*:*:wordpress:*:*" ], + "easyazon": [ + "cpe:2.3:a:flowdee:easyazon:*:*:*:*:*:*:*:*", + "cpe:2.3:a:getaawp:easyazon:*:*:*:*:*:wordpress:*:*" + ], "easyjobs": [ "cpe:2.3:a:easy.jobs:easy.jobs:*:*:*:*:*:wordpress:*:*" ], @@ -9950,6 +9984,9 @@ "elegant-custom-fonts": [ "cpe:2.3:a:breakdance:elegant_custom_fonts:*:*:*:*:*:wordpress:*:*" ], + "elegant-themes-icons": [ + "cpe:2.3:a:wpai:elegant_themes_icons:*:*:*:*:*:wordpress:*:*" + ], "element-ready-lite": [ "cpe:2.3:a:quomodosoft:elementsready:*:*:*:*:*:wordpress:*:*" ], @@ -10178,6 +10215,7 @@ "cpe:2.3:a:e-dynamics:events_made_easy:*:*:*:*:*:wordpress:*:*" ], "events-manager": [ + "cpe:2.3:a:pixelite:events_manager:*:*:*:*:*:wordpress:*:*", "cpe:2.3:a:wp-events-plugin:events_manager:*:*:*:*:*:wordpress:*:*" ], "ever-compare": [ @@ -10224,7 +10262,8 @@ "cpe:2.3:a:ithemes:ithemes_exchange:*:*:*:*:*:wordpress:*:*" ], "exclusive-addons-for-elementor": [ - "cpe:2.3:a:devscred:exclusive_addons_for_elementor:*:*:*:*:*:wordpress:*:*" + "cpe:2.3:a:devscred:exclusive_addons_for_elementor:*:*:*:*:*:wordpress:*:*", + "cpe:2.3:a:exclusiveaddons:exclusive_addons_for_elementor:*:*:*:*:*:wordpress:*:*" ], "exit-intent-popups-by-optimonk": [ "cpe:2.3:a:optimonk:optimonk\\:popups\\,_personalization_\\\u0026_a\\/b_testing:*:*:*:*:*:wordpress:*:*" @@ -10271,6 +10310,9 @@ "extensions-for-cf7": [ "cpe:2.3:a:hasthemes:extensions_for_cf7:*:*:*:*:*:wordpress:*:*" ], + "extensions-for-elementor": [ + "cpe:2.3:a:idioweb:extensions_for_elementor:*:*:*:*:*:wordpress:*:*" + ], "extensive-vc-addon": [ "cpe:2.3:a:wprealize:extensive_vc_addons_for_wpbakery_page_builder:*:*:*:*:*:wordpress:*:*" ], @@ -11379,6 +11421,9 @@ "iframe": [ "cpe:2.3:a:iframe_project:iframe:*:*:*:*:*:wordpress:*:*" ], + "iframe-forms": [ + "cpe:2.3:a:jrbecart:iframe_forms:*:*:*:*:*:wordpress:*:*" + ], "iframe-shortcode": [ "cpe:2.3:a:jacksonwhelan:iframe_shortcode:*:*:*:*:*:wordpress:*:*" ], @@ -11471,7 +11516,8 @@ "cpe:2.3:a:imagestowebp_project:images_to_webp:*:*:*:*:*:wordpress:*:*" ], "imageseo": [ - "cpe:2.3:a:imageseo:optimize_images_alt_text_\\(alt_tag\\)_\\\u0026_names_for_seo_using_ai:*:*:*:*:*:wordpress:*:*" + "cpe:2.3:a:imageseo:optimize_images_alt_text_\\(alt_tag\\)_\\\u0026_names_for_seo_using_ai:*:*:*:*:*:wordpress:*:*", + "cpe:2.3:a:wpchill:optimize_images_alt_text_\\(alt_tag\\)_\\\u0026_names_for_seo_using_ai:*:*:*:*:*:wordpress:*:*" ], "imdb-info-box": [ "cpe:2.3:a:99webtools:imdb_info_box:*:*:*:*:*:wordpress:*:*" @@ -11592,7 +11638,8 @@ "cpe:2.3:a:getnet_argentina_para_woocommerce_project:getnet_argentina_para_woocommerce:*:*:*:*:*:wordpress:*:*" ], "integrate-google-drive": [ - "cpe:2.3:a:softlabbd:integrate_google_drive:*:*:*:*:*:wordpress:*:*" + "cpe:2.3:a:softlabbd:integrate_google_drive:*:*:*:*:*:wordpress:*:*", + "cpe:2.3:a:softlabdb:integrate_google_drive:*:*:*:*:*:wordpress:*:*" ], "integration-for-billingo-gravity-forms": [ "cpe:2.3:a:integration_for_billingo_\\\u0026_gravity_forms_project:integration_for_billingo_\\\u0026_gravity_forms:*:*:*:*:*:wordpress:*:*" @@ -11603,6 +11650,9 @@ "integration-for-szamlazzhu-woocommerce": [ "cpe:2.3:a:visztpeter:integration_for_szamlazz.hu_\\\u0026_woocommerce:*:*:*:*:*:wordpress:*:*" ], + "intelly-related-posts": [ + "cpe:2.3:a:data443:inline_related_posts:*:*:*:*:*:wordpress:*:*" + ], "interactive-3d-flipbook-powered-physics-engine": [ "cpe:2.3:a:3dflipbook:3d_flipbook:*:*:*:*:*:wordpress:*:*" ], @@ -12013,6 +12063,9 @@ "license-manager-for-woocommerce": [ "cpe:2.3:a:wpexperts:license_manager_for_woocommerce:*:*:*:*:*:wordpress:*:*" ], + "lifeline-donation": [ + "cpe:2.3:a:webinane:lifeline_donation:*:*:*:*:*:wordpress:*:*" + ], "lifterlms": [ "cpe:2.3:a:lifterlms:lifterlms:*:*:*:*:*:wordpress:*:*" ], @@ -13300,6 +13353,9 @@ "pdf-viewer-block": [ "cpe:2.3:a:gutenberg_pdf_viewer_block_project:gutenberg_pdf_viewer_block:*:*:*:*:*:wordpress:*:*" ], + "pdf-viewer-for-elementor": [ + "cpe:2.3:a:redlettuce:pdf_viewer_for_elementor:*:*:*:*:*:wordpress:*:*" + ], "pdf24-posts-to-pdf": [ "cpe:2.3:a:pdf24_articles_to_pdf_project:pdf24_articles_to_pdf:*:*:*:*:*:wordpress:*:*" ], @@ -13678,6 +13734,9 @@ "powerpress": [ "cpe:2.3:a:blubrry:powerpress:*:*:*:*:*:wordpress:*:*" ], + "pray-for-me": [ + "cpe:2.3:a:projectcaruso:pray_for_me:*:*:*:*:*:wordpress:*:*" + ], "pre-orders-for-woocommerce": [ "cpe:2.3:a:brightplugins:pre-orders_for_woocommerce:*:*:*:*:*:wordpress:*:*" ], @@ -13704,6 +13763,9 @@ "pressforward": [ "cpe:2.3:a:pressforward:pressforward:*:*:*:*:*:wordpress:*:*" ], + "prettyphoto": [ + "cpe:2.3:a:master-addons:prettyphoto:*:*:*:*:*:wordpress:*:*" + ], "preview-link-generator": [ "cpe:2.3:a:hasthemes:preview_link_generator:*:*:*:*:*:wordpress:*:*" ], @@ -13817,6 +13879,9 @@ "promobar": [ "cpe:2.3:a:bestwebsoft:promobar:*:*:*:*:*:wordpress:*:*" ], + "promolayer-popup-builder": [ + "cpe:2.3:a:promolayer:popup_builder:*:*:*:*:*:wordpress:*:*" + ], "promotion-slider": [ "cpe:2.3:a:promotion_slider_project:promotion_slider:*:*:*:*:*:wordpress:*:*" ], @@ -14295,6 +14360,9 @@ "roomcloud": [ "cpe:2.3:a:roomcloud:roomcloud:*:*:*:*:*:wordpress:*:*" ], + "rotatingtweets": [ + "cpe:2.3:a:martintod:rotating_tweets:*:*:*:*:*:wordpress:*:*" + ], "rough-chart": [ "cpe:2.3:a:rough_chart_project:rough_chart:*:*:*:*:*:wordpress:*:*" ], @@ -14666,6 +14734,9 @@ "show-posts": [ "cpe:2.3:a:weavertheme:weaver_show_posts:*:*:*:*:*:wordpress:*:*" ], + "show-website-content-in-wordpress-page-or-post": [ + "cpe:2.3:a:matteoenna:website_content_in_page_or_post:*:*:*:*:*:wordpress:*:*" + ], "si-contact-form": [ "cpe:2.3:a:fast_secure_contact_form_project:fast_secure_contact_form:*:*:*:*:*:wordpress:*:*" ], @@ -14694,6 +14765,9 @@ "similar-posts": [ "cpe:2.3:a:shareaholic:similar_posts:*:*:*:*:*:wordpress:*:*" ], + "similarity": [ + "cpe:2.3:a:davidjmiller:similarity:*:*:*:*:*:wordpress:*:*" + ], "simple-301-redirects-addon-bulk-uploader": [ "cpe:2.3:a:webcraftic:simple_301_redirects-addon-bulk_uploader:*:*:*:*:*:wordpress:*:*", "cpe:2.3:a:webcraftic:simple_301_redirects:*:*:*:*:*:wordpress:*:*" @@ -14776,6 +14850,9 @@ "simple-image-manipulator": [ "cpe:2.3:a:simple-image-manipulator_project:simple-image-manipulator:*:*:*:*:*:wordpress:*:*" ], + "simple-image-popup-shortcode": [ + "cpe:2.3:a:purvabathe:simple_image_popup_shortcode:*:*:*:*:*:wordpress:*:*" + ], "simple-ip-ban": [ "cpe:2.3:a:ip_ban_project:ip_ban:*:*:*:*:*:wordpress:*:*" ], @@ -14801,6 +14878,9 @@ "simple-matted-thumbnails": [ "cpe:2.3:a:devondev:simple_matted_thumbnails:*:*:*:*:*:wordpress:*:*" ], + "simple-media-directory": [ + "cpe:2.3:a:quantumcloud:simple_video_directory:*:*:*:*:*:wordpress:*:*" + ], "simple-membership": [ "cpe:2.3:a:simple-membership-plugin:simple_membership:*:*:*:*:*:wordpress:*:*" ], @@ -14899,6 +14979,9 @@ "simple-youtube-responsive": [ "cpe:2.3:a:simple_youtube_responsive_project:simple_youtube_responsive:*:*:*:*:*:wordpress:*:*" ], + "simplemap": [ + "cpe:2.3:a:simplemap-plugin:simplemap_store_locator:*:*:*:*:*:wordpress:*:*" + ], "simplemodal-contact-form-smcf": [ "cpe:2.3:a:simplemodal_contact_form_project:simplemodal_contact_form:*:*:*:*:*:wordpress:*:*" ], @@ -14978,6 +15061,9 @@ "sketchfab-oembed": [ "cpe:2.3:a:generatewp:sketchfab_embed:*:*:*:*:*:wordpress:*:*" ], + "skype-online-status": [ + "cpe:2.3:a:ravanh:skype_legacy_buttons:*:*:*:*:*:wordpress:*:*" + ], "sliced-invoices": [ "cpe:2.3:a:slicedinvoices:sliced_invoices:*:*:*:*:*:wordpress:*:*" ], @@ -15068,6 +15154,9 @@ "smart-slider-3": [ "cpe:2.3:a:nextendweb:smart_slider_3:*:*:*:*:*:wordpress:*:*" ], + "smart-wishlist-for-more-convert": [ + "cpe:2.3:a:moreconvert:woocommerce_wishlist:*:*:*:*:*:wordpress:*:*" + ], "smart-youtube": [ "cpe:2.3:a:smart_youtube_pro_project:smart_youtube_pro:*:*:*:*:*:wordpress:*:*" ], @@ -15143,6 +15232,9 @@ "social-photo-gallery": [ "cpe:2.3:a:infoway:social_photo_gallery:*:*:*:*:*:wordpress:*:*" ], + "social-pixel": [ + "cpe:2.3:a:labschool:social_pixel:*:*:*:*:*:*:wordpress:*" + ], "social-proof-testimonials-slider": [ "cpe:2.3:a:brandid:social_proof_\\(testimonial\\)_slider:*:*:*:*:*:wordpress:*:*" ], @@ -15291,12 +15383,18 @@ "stars-rating": [ "cpe:2.3:a:stars_rating_project:stars_rating:*:*:*:*:*:wordpress:*:*" ], + "startklar-elmentor-forms-extwidgets": [ + "cpe:2.3:a:web-shop-host:startklar_elmentor_addons:*:*:*:*:*:wordpress:*:*" + ], "stats-counter": [ "cpe:2.3:a:analytics_stats_counter_statistics_project:analytics_stats_counter_statistics:*:*:*:*:*:wordpress:*:*" ], "stax-addons-for-elementor": [ "cpe:2.3:a:staxwp:stax:*:*:*:*:*:wordpress:*:*" ], + "stellissimo-text-box": [ + "cpe:2.3:a:overclokk:stellissimo_text_box:*:*:*:*:*:wordpress:*:*" + ], "stetic": [ "cpe:2.3:a:stetic:stetic:*:*:*:*:*:wordpress:*:*" ], @@ -15454,6 +15552,9 @@ "svg-vector-icon-plugin": [ "cpe:2.3:a:wp_svg_icons_project:wp_svg_icons:*:*:*:*:*:wordpress:*:*" ], + "svgmagic": [ + "cpe:2.3:a:andibauer:svgmagic:*:*:*:*:*:wordpress:*:*" + ], "swatchly": [ "cpe:2.3:a:hasthemes:swatchly:*:*:*:*:*:wordpress:*:*" ], @@ -16211,6 +16312,9 @@ "video-thumbnails": [ "cpe:2.3:a:video_thumbnails_project:video_thumbnails:*:*:*:*:*:wordpress:*:*" ], + "video-widget": [ + "cpe:2.3:a:nikodev:video_widget:*:*:*:*:*:wordpress:*:*" + ], "videojs-html5-player": [ "cpe:2.3:a:wphowto:videojs_html5_player:*:*:*:*:*:wordpress:*:*" ], @@ -16394,6 +16498,9 @@ "weather-effect": [ "cpe:2.3:a:awplife:weather_effect:*:*:*:*:*:wordpress:*:*" ], + "weather-in-any-city-widget": [ + "cpe:2.3:a:eltiempoen:weather_widget_pro:*:*:*:*:*:wordpress:*:*" + ], "weaverx-theme-support": [ "cpe:2.3:a:weavertheme:weaver_xtreme_theme_support:*:*:*:*:*:wordpress:*:*" ], @@ -16492,6 +16599,9 @@ "whatshelp-chat-button": [ "cpe:2.3:a:getbutton:chat_button:*:*:*:*:*:wordpress:*:*" ], + "wheel-of-life": [ + "cpe:2.3:a:kraftplugins:wheel_of_life:*:*:*:*:*:wordpress:*:*" + ], "which-template-file": [ "cpe:2.3:a:gillesdumas:which_template_file:*:*:*:*:*:wordpress:*:*" ], @@ -16573,6 +16683,9 @@ "woo-altcoin-payment-gateway": [ "cpe:2.3:a:coinmarketstats:bitcoin_\\/_altcoin_payment_gateway_for_woocommerce:*:*:*:*:*:wordpress:*:*" ], + "woo-auto-coupons": [ + "cpe:2.3:a:richardlerma:auto_coupons_for_woocommerce:*:*:*:*:*:wordpress:*:*" + ], "woo-badge-designer-lite": [ "cpe:2.3:a:accesspressthemes:badge_designer_lite_for_woocommerce:*:*:*:*:*:wordpress:*:*" ], @@ -17544,6 +17657,9 @@ "wp-logo-showcase": [ "cpe:2.3:a:radiustheme:logo_slider_and_showcase:*:*:*:*:*:wordpress:*:*" ], + "wp-logs-book": [ + "cpe:2.3:a:onetarek:wp_logs_book:*:*:*:*:*:wordpress:*:*" + ], "wp-mail": [ "cpe:2.3:a:wp_mail_project:wp_mail:*:*:*:*:*:wordpress:*:*" ], @@ -17747,6 +17863,9 @@ "wp-publications": [ "cpe:2.3:a:wp-publications_project:wp-publications:*:*:*:*:*:wordpress:*:*" ], + "wp-quicklatex": [ + "cpe:2.3:a:holoborodko:wp_quicklatex:*:*:*:*:*:wordpress:*:*" + ], "wp-radio": [ "cpe:2.3:a:wpmilitary:wp_radio:*:*:*:*:*:wordpress:*:*" ], @@ -17809,6 +17928,9 @@ "wp-scrippets": [ "cpe:2.3:a:wp_scrippets_project:wp_scrippets:*:*:*:*:*:wordpress:*:*" ], + "wp-secure-maintainance": [ + "cpe:2.3:a:wpexperts:wp_secure_maintenance:*:*:*:*:*:wordpress:*:*" + ], "wp-security-hardening": [ "cpe:2.3:a:getastra:wp_hardening:*:*:*:*:*:wordpress:*:*" ], @@ -18735,6 +18857,9 @@ "newsmag": [ "cpe:2.3:a:machothemes:newsmag:*:*:*:*:*:wordpress:*:*" ], + "newspaper": [ + "cpe:2.3:a:tagdiv:newspaper:*:*:*:*:*:wordpress:*:*" + ], "newspaper-x": [ "cpe:2.3:a:colorlib:newspaper_x:*:*:*:*:*:wordpress:*:*" ], From dcd87d1fef4083285f23831ef384469f0a5f625b Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 6 Aug 2024 13:17:36 -0400 Subject: [PATCH 052/122] chore(deps): bump actions/upload-artifact from 4.3.4 to 4.3.5 (#3095) Bumps [actions/upload-artifact](https://github.com/actions/upload-artifact) from 4.3.4 to 4.3.5. - [Release notes](https://github.com/actions/upload-artifact/releases) - [Commits](https://github.com/actions/upload-artifact/compare/0b2256b8c012f0828dc542b3febcab082c67f72b...89ef406dd8d7e03cfd12d9e0a4a378f454709029) --- updated-dependencies: - dependency-name: actions/upload-artifact dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- .github/workflows/benchmark-testing.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/benchmark-testing.yaml b/.github/workflows/benchmark-testing.yaml index 7cdf9b4b8da..c47908195b9 100644 --- a/.github/workflows/benchmark-testing.yaml +++ b/.github/workflows/benchmark-testing.yaml @@ -39,7 +39,7 @@ jobs: OUTPUT="${OUTPUT//$'\r'/'%0D'}" # URL encode all '\r' characters echo "result=$OUTPUT" >> $GITHUB_OUTPUT - - uses: actions/upload-artifact@0b2256b8c012f0828dc542b3febcab082c67f72b # v4.3.4 + - uses: actions/upload-artifact@89ef406dd8d7e03cfd12d9e0a4a378f454709029 # v4.3.5 with: name: benchmark-test-results path: test/results/**/* From 040b683da8489e9bb6317775ef74f888ab13d8b2 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 7 Aug 2024 14:25:28 -0400 Subject: [PATCH 053/122] chore(deps): bump golang.org/x/net from 0.27.0 to 0.28.0 (#3104) Bumps [golang.org/x/net](https://github.com/golang/net) from 0.27.0 to 0.28.0. - [Commits](https://github.com/golang/net/compare/v0.27.0...v0.28.0) --- updated-dependencies: - dependency-name: golang.org/x/net dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- go.mod | 12 ++++++------ go.sum | 24 ++++++++++++------------ 2 files changed, 18 insertions(+), 18 deletions(-) diff --git a/go.mod b/go.mod index f99fd1c2880..87e95130b63 100644 --- a/go.mod +++ b/go.mod @@ -79,7 +79,7 @@ require ( github.com/zyedidia/generic v1.2.2-0.20230320175451-4410d2372cb1 go.uber.org/goleak v1.3.0 golang.org/x/mod v0.20.0 - golang.org/x/net v0.27.0 + golang.org/x/net v0.28.0 gopkg.in/yaml.v3 v3.0.1 modernc.org/sqlite v1.31.1 ) @@ -230,11 +230,11 @@ require ( go.opentelemetry.io/otel/trace v1.19.0 // indirect go.uber.org/atomic v1.9.0 // indirect go.uber.org/multierr v1.9.0 // indirect - golang.org/x/crypto v0.25.0 // indirect - golang.org/x/sync v0.7.0 // indirect - golang.org/x/sys v0.22.0 // indirect - golang.org/x/term v0.22.0 // indirect - golang.org/x/text v0.16.0 // indirect + golang.org/x/crypto v0.26.0 // indirect + golang.org/x/sync v0.8.0 // indirect + golang.org/x/sys v0.23.0 // indirect + golang.org/x/term v0.23.0 // indirect + golang.org/x/text v0.17.0 // indirect golang.org/x/tools v0.21.1-0.20240508182429-e35e4ccd0d2d // indirect golang.org/x/xerrors v0.0.0-20220907171357-04be3eba64a2 // indirect google.golang.org/genproto/googleapis/rpc v0.0.0-20231120223509-83a465c0220f // indirect diff --git a/go.sum b/go.sum index b4ee9adca03..246f0d27090 100644 --- a/go.sum +++ b/go.sum @@ -878,8 +878,8 @@ golang.org/x/crypto v0.0.0-20220622213112-05595931fe9d/go.mod h1:IxCIyHEi3zRg3s0 golang.org/x/crypto v0.3.0/go.mod h1:hebNnKkNXi2UzZN1eVRvBB7co0a+JxK6XbPiWVs/3J4= golang.org/x/crypto v0.3.1-0.20221117191849-2c476679df9a/go.mod h1:hebNnKkNXi2UzZN1eVRvBB7co0a+JxK6XbPiWVs/3J4= golang.org/x/crypto v0.7.0/go.mod h1:pYwdfH91IfpZVANVyUOhSIPZaFoJGxTFbZhFTx+dXZU= -golang.org/x/crypto v0.25.0 h1:ypSNr+bnYL2YhwoMt2zPxHFmbAN1KZs/njMG3hxUp30= -golang.org/x/crypto v0.25.0/go.mod h1:T+wALwcMOSE0kXgUAnPAHqTLW+XHgcELELW8VaDgm/M= +golang.org/x/crypto v0.26.0 h1:RrRspgV4mU+YwB4FYnuBoKsUapNIL5cohGAmSH3azsw= +golang.org/x/crypto v0.26.0/go.mod h1:GY7jblb9wI+FOo5y8/S2oY4zWP07AkOJ4+jxCqdqn54= 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= @@ -968,8 +968,8 @@ golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug golang.org/x/net v0.2.0/go.mod h1:KqCZLdyyvdV855qA2rE3GC2aiw5xGR5TEjj8smXukLY= golang.org/x/net v0.6.0/go.mod h1:2Tu9+aMcznHK/AK1HMvgo6xiTLG5rD5rZLDS+rp2Bjs= golang.org/x/net v0.8.0/go.mod h1:QVkue5JL9kW//ek3r6jTKnTFis1tRmNAW2P1shuFdJc= -golang.org/x/net v0.27.0 h1:5K3Njcw06/l2y9vpGCSdcxWOYHOUk3dVNGDXN+FvAys= -golang.org/x/net v0.27.0/go.mod h1:dDi0PyhWNoiUOrAS8uXv/vnScO4wnHQO4mj9fn/RytE= +golang.org/x/net v0.28.0 h1:a9JDOJc5GMUJ0+UDqmLT86WiEy7iWyIhz8gz8E4e5hE= +golang.org/x/net v0.28.0/go.mod h1:yqtgsTWOOnlGLG9GFRrK3++bGOUEkNBoHZc8MEDWPNg= 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= @@ -1000,8 +1000,8 @@ golang.org/x/sync v0.0.0-20201207232520-09787c993a3a/go.mod h1:RxMgew5VJxzue5/jJ golang.org/x/sync v0.0.0-20210220032951-036812b2e83c/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.1.0/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sync v0.7.0 h1:YsImfSBoP9QPYL0xyKJPq0gcaJdG3rInoqxTWbfQu9M= -golang.org/x/sync v0.7.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk= +golang.org/x/sync v0.8.0 h1:3NFvSEYkUoMifnESzZl15y791HH1qU2xm6eCJU5ZPXQ= +golang.org/x/sync v0.8.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk= golang.org/x/sys v0.0.0-20180823144017-11551d06cbcc/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= 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= @@ -1081,15 +1081,15 @@ golang.org/x/sys v0.2.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.3.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.5.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.22.0 h1:RI27ohtqKCnwULzJLqkv897zojh5/DwS/ENaMzUOaWI= -golang.org/x/sys v0.22.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= +golang.org/x/sys v0.23.0 h1:YfKFowiIMvtgl1UERQoTPPToxltDeZfbj4H7dVUCwmM= +golang.org/x/sys v0.23.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= golang.org/x/term v0.2.0/go.mod h1:TVmDHMZPmdnySmBfhjOoOdhjzdE1h4u1VwSiw2l1Nuc= golang.org/x/term v0.5.0/go.mod h1:jMB1sMXY+tzblOD4FWmEbocvup2/aLOaQEp7JmGp78k= golang.org/x/term v0.6.0/go.mod h1:m6U89DPEgQRMq3DNkDClhWw02AUbt2daBVO4cn4Hv9U= -golang.org/x/term v0.22.0 h1:BbsgPEJULsl2fV/AT3v15Mjva5yXKQDyKf+TbDz7QJk= -golang.org/x/term v0.22.0/go.mod h1:F3qCibpT5AMpCRfhfT53vVJwhLtIVHhB9XDjfFvnMI4= +golang.org/x/term v0.23.0 h1:F6D4vR+EHoL9/sWAWgAR1H2DcHr4PareCbAaCo1RpuU= +golang.org/x/term v0.23.0/go.mod h1:DgV24QBUrK6jhZXl+20l6UWznPlwAHm1Q1mGHtydmSk= 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= @@ -1102,8 +1102,8 @@ golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ= golang.org/x/text v0.4.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8= golang.org/x/text v0.7.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8= golang.org/x/text v0.8.0/go.mod h1:e1OnstbJyHTd6l/uOt8jFFHp6TRDWZR/bV3emEE/zU8= -golang.org/x/text v0.16.0 h1:a94ExnEXNtEwYLGJSIUxnWoxoRz/ZcCsV63ROupILh4= -golang.org/x/text v0.16.0/go.mod h1:GhwF1Be+LQoKShO3cGOHzqOgRrGaYc9AvblQOmPVHnI= +golang.org/x/text v0.17.0 h1:XtiM5bkSOt+ewxlOE/aE/AKEHibwj/6gvWMl9Rsh0Qc= +golang.org/x/text v0.17.0/go.mod h1:BuEKDfySbSR4drPmRPG/7iBdf8hvFMuRexcpahXilzY= 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= From 47d192d79b3e8e12a81d200fe3143795243e7f6c Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 7 Aug 2024 14:25:36 -0400 Subject: [PATCH 054/122] chore(deps): bump github.com/google/go-containerregistry (#3103) Bumps [github.com/google/go-containerregistry](https://github.com/google/go-containerregistry) from 0.20.1 to 0.20.2. - [Release notes](https://github.com/google/go-containerregistry/releases) - [Changelog](https://github.com/google/go-containerregistry/blob/main/.goreleaser.yml) - [Commits](https://github.com/google/go-containerregistry/compare/v0.20.1...v0.20.2) --- updated-dependencies: - dependency-name: github.com/google/go-containerregistry dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- go.mod | 4 ++-- go.sum | 8 ++++---- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/go.mod b/go.mod index 87e95130b63..9616db0416b 100644 --- a/go.mod +++ b/go.mod @@ -39,7 +39,7 @@ require ( github.com/go-git/go-git/v5 v5.12.0 github.com/go-test/deep v1.1.1 github.com/google/go-cmp v0.6.0 - github.com/google/go-containerregistry v0.20.1 + github.com/google/go-containerregistry v0.20.2 github.com/google/licensecheck v0.3.1 github.com/google/uuid v1.6.0 github.com/gookit/color v1.5.4 @@ -125,7 +125,7 @@ require ( github.com/containerd/typeurl/v2 v2.1.1 // indirect github.com/cyphar/filepath-securejoin v0.2.4 // indirect github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc // indirect - github.com/docker/cli v27.0.3+incompatible // indirect + github.com/docker/cli v27.1.1+incompatible // indirect github.com/docker/distribution v2.8.3+incompatible // indirect github.com/docker/docker-credential-helpers v0.7.0 // indirect github.com/docker/go-connections v0.4.0 // indirect diff --git a/go.sum b/go.sum index 246f0d27090..45ffa2b0df2 100644 --- a/go.sum +++ b/go.sum @@ -227,8 +227,8 @@ github.com/deitch/magic v0.0.0-20230404182410-1ff89d7342da/go.mod h1:B3tI9iGHi4i github.com/dgrijalva/jwt-go/v4 v4.0.0-preview1/go.mod h1:+hnT3ywWDTAFrW5aE+u2Sa/wT555ZqwoCS+pk3p6ry4= github.com/distribution/reference v0.6.0 h1:0IXCQ5g4/QMHHkarYzh5l+u8T3t73zM5QvfrDyIgxBk= github.com/distribution/reference v0.6.0/go.mod h1:BbU0aIcezP1/5jX/8MP0YiH4SdvB5Y4f/wlDRiLyi3E= -github.com/docker/cli v27.0.3+incompatible h1:usGs0/BoBW8MWxGeEtqPMkzOY56jZ6kYlSN5BLDioCQ= -github.com/docker/cli v27.0.3+incompatible/go.mod h1:JLrzqnKDaYBop7H2jaqPtU4hHvMKP+vjCwu2uszcLI8= +github.com/docker/cli v27.1.1+incompatible h1:goaZxOqs4QKxznZjjBWKONQci/MywhtRv2oNn0GkeZE= +github.com/docker/cli v27.1.1+incompatible/go.mod h1:JLrzqnKDaYBop7H2jaqPtU4hHvMKP+vjCwu2uszcLI8= github.com/docker/distribution v2.8.3+incompatible h1:AtKxIZ36LoNK51+Z6RpzLpddBirtxJnzDrHLEKxTAYk= github.com/docker/distribution v2.8.3+incompatible/go.mod h1:J2gT2udsDAN96Uj4KfcMRqY0/ypR+oyYUYmja8H+y+w= github.com/docker/docker v27.1.1+incompatible h1:hO/M4MtV36kzKldqnA37IWhebRA+LnqqcqDja6kVaKY= @@ -384,8 +384,8 @@ github.com/google/go-cmp v0.5.6/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/ github.com/google/go-cmp v0.5.9/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= github.com/google/go-cmp v0.6.0 h1:ofyhxvXcZhMsU5ulbFiLKl/XBFqE1GSq7atu8tAmTRI= github.com/google/go-cmp v0.6.0/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= -github.com/google/go-containerregistry v0.20.1 h1:eTgx9QNYugV4DN5mz4U8hiAGTi1ybXn0TPi4Smd8du0= -github.com/google/go-containerregistry v0.20.1/go.mod h1:YCMFNQeeXeLF+dnhhWkqDItx/JSkH01j1Kis4PsjzFI= +github.com/google/go-containerregistry v0.20.2 h1:B1wPJ1SN/S7pB+ZAimcciVD+r+yV/l/DSArMxlbwseo= +github.com/google/go-containerregistry v0.20.2/go.mod h1:z38EKdKh4h7IP2gSfUUqEvalZBqs6AoLeWfUy34nQC8= github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg= github.com/google/licensecheck v0.3.1 h1:QoxgoDkaeC4nFrtGN1jV7IPmDCHFNIVh54e5hSt6sPs= github.com/google/licensecheck v0.3.1/go.mod h1:ORkR35t/JjW+emNKtfJDII0zlciG9JgbT7SmsohlHmY= From 903159264954148fdefa125c45b0a0709555dcf3 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 7 Aug 2024 14:25:44 -0400 Subject: [PATCH 055/122] chore(deps): bump actions/upload-artifact from 4.3.5 to 4.3.6 (#3102) Bumps [actions/upload-artifact](https://github.com/actions/upload-artifact) from 4.3.5 to 4.3.6. - [Release notes](https://github.com/actions/upload-artifact/releases) - [Commits](https://github.com/actions/upload-artifact/compare/89ef406dd8d7e03cfd12d9e0a4a378f454709029...834a144ee995460fba8ed112a2fc961b36a5ec5a) --- updated-dependencies: - dependency-name: actions/upload-artifact dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- .github/workflows/benchmark-testing.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/benchmark-testing.yaml b/.github/workflows/benchmark-testing.yaml index c47908195b9..8284d8264eb 100644 --- a/.github/workflows/benchmark-testing.yaml +++ b/.github/workflows/benchmark-testing.yaml @@ -39,7 +39,7 @@ jobs: OUTPUT="${OUTPUT//$'\r'/'%0D'}" # URL encode all '\r' characters echo "result=$OUTPUT" >> $GITHUB_OUTPUT - - uses: actions/upload-artifact@89ef406dd8d7e03cfd12d9e0a4a378f454709029 # v4.3.5 + - uses: actions/upload-artifact@834a144ee995460fba8ed112a2fc961b36a5ec5a # v4.3.6 with: name: benchmark-test-results path: test/results/**/* From 2339743c8cb6c455d07449e399efeb67c5729d25 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 7 Aug 2024 14:25:52 -0400 Subject: [PATCH 056/122] chore(deps): bump github/codeql-action from 3.25.15 to 3.26.0 (#3101) Bumps [github/codeql-action](https://github.com/github/codeql-action) from 3.25.15 to 3.26.0. - [Release notes](https://github.com/github/codeql-action/releases) - [Changelog](https://github.com/github/codeql-action/blob/main/CHANGELOG.md) - [Commits](https://github.com/github/codeql-action/compare/afb54ba388a7dca6ecae48f608c4ff05ff4cc77a...eb055d739abdc2e8de2e5f4ba1a8b246daa779aa) --- updated-dependencies: - dependency-name: github/codeql-action dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- .github/workflows/codeql-analysis.yml | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/.github/workflows/codeql-analysis.yml b/.github/workflows/codeql-analysis.yml index d15a2c99703..46fc8496331 100644 --- a/.github/workflows/codeql-analysis.yml +++ b/.github/workflows/codeql-analysis.yml @@ -45,7 +45,7 @@ jobs: # Initializes the CodeQL tools for scanning. - name: Initialize CodeQL - uses: github/codeql-action/init@afb54ba388a7dca6ecae48f608c4ff05ff4cc77a #v3.25.15 + uses: github/codeql-action/init@eb055d739abdc2e8de2e5f4ba1a8b246daa779aa #v3.26.0 with: languages: ${{ matrix.language }} # If you wish to specify custom queries, you can do so here or in a config file. @@ -56,7 +56,7 @@ jobs: # Autobuild attempts to build any compiled languages (C/C++, C#, or Java). # If this step fails, then you should remove it and run the build manually (see below) - name: Autobuild - uses: github/codeql-action/autobuild@afb54ba388a7dca6ecae48f608c4ff05ff4cc77a #v3.25.15 + uses: github/codeql-action/autobuild@eb055d739abdc2e8de2e5f4ba1a8b246daa779aa #v3.26.0 # ℹī¸ Command-line programs to run using the OS shell. # 📚 https://git.io/JvXDl @@ -70,4 +70,4 @@ jobs: # make release - name: Perform CodeQL Analysis - uses: github/codeql-action/analyze@afb54ba388a7dca6ecae48f608c4ff05ff4cc77a #v3.25.15 + uses: github/codeql-action/analyze@eb055d739abdc2e8de2e5f4ba1a8b246daa779aa #v3.26.0 From 1fb47d908eb0ac353a7395c3269291f02b13135e Mon Sep 17 00:00:00 2001 From: "anchore-actions-token-generator[bot]" <102182147+anchore-actions-token-generator[bot]@users.noreply.github.com> Date: Wed, 7 Aug 2024 14:26:05 -0400 Subject: [PATCH 057/122] chore(deps): update tools to latest versions (#3099) Signed-off-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com> Co-authored-by: spiffcs <32073428+spiffcs@users.noreply.github.com> --- .binny.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.binny.yaml b/.binny.yaml index ac2f4cc10f5..42ea5c760d2 100644 --- a/.binny.yaml +++ b/.binny.yaml @@ -42,7 +42,7 @@ tools: # used for signing the checksums file at release - name: cosign version: - want: v2.3.0 + want: v2.4.0 method: github-release with: repo: sigstore/cosign From 6267d69930aec2b66524f83a6a2a04525846c425 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Thu, 8 Aug 2024 15:49:37 -0400 Subject: [PATCH 058/122] chore(deps): bump sigstore/cosign-installer from 3.5.0 to 3.6.0 (#3107) Bumps [sigstore/cosign-installer](https://github.com/sigstore/cosign-installer) from 3.5.0 to 3.6.0. - [Release notes](https://github.com/sigstore/cosign-installer/releases) - [Commits](https://github.com/sigstore/cosign-installer/compare/v3.5.0...v3.6.0) --- updated-dependencies: - dependency-name: sigstore/cosign-installer dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- .github/workflows/validations.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/validations.yaml b/.github/workflows/validations.yaml index f54771d9b2c..669d8b8c5c4 100644 --- a/.github/workflows/validations.yaml +++ b/.github/workflows/validations.yaml @@ -188,7 +188,7 @@ jobs: runs-on: macos-latest steps: - name: Install Cosign - uses: sigstore/cosign-installer@v3.5.0 + uses: sigstore/cosign-installer@v3.6.0 - uses: actions/checkout@692973e3d937129bcbf40652eb9f2f61becf3332 #v4.1.7 From 64a9ecbf7a94336710f2fa886ebd66fcc819b8df Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Thu, 8 Aug 2024 15:49:45 -0400 Subject: [PATCH 059/122] chore(deps): bump modernc.org/sqlite from 1.31.1 to 1.32.0 (#3106) Bumps [modernc.org/sqlite](https://gitlab.com/cznic/sqlite) from 1.31.1 to 1.32.0. - [Commits](https://gitlab.com/cznic/sqlite/compare/v1.31.1...v1.32.0) --- updated-dependencies: - dependency-name: modernc.org/sqlite dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- go.mod | 2 +- go.sum | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/go.mod b/go.mod index 9616db0416b..56b075e10ed 100644 --- a/go.mod +++ b/go.mod @@ -81,7 +81,7 @@ require ( golang.org/x/mod v0.20.0 golang.org/x/net v0.28.0 gopkg.in/yaml.v3 v3.0.1 - modernc.org/sqlite v1.31.1 + modernc.org/sqlite v1.32.0 ) require google.golang.org/genproto v0.0.0-20231106174013-bbf56f31fb17 // indirect diff --git a/go.sum b/go.sum index 45ffa2b0df2..15800d2ab63 100644 --- a/go.sum +++ b/go.sum @@ -1379,8 +1379,8 @@ modernc.org/opt v0.1.3 h1:3XOZf2yznlhC+ibLltsDGzABUGVx8J6pnFMS3E4dcq4= modernc.org/opt v0.1.3/go.mod h1:WdSiB5evDcignE70guQKxYUl14mgWtbClRi5wmkkTX0= modernc.org/sortutil v1.2.0 h1:jQiD3PfS2REGJNzNCMMaLSp/wdMNieTbKX920Cqdgqc= modernc.org/sortutil v1.2.0/go.mod h1:TKU2s7kJMf1AE84OoiGppNHJwvB753OYfNl2WRb++Ss= -modernc.org/sqlite v1.31.1 h1:XVU0VyzxrYHlBhIs1DiEgSl0ZtdnPtbLVy8hSkzxGrs= -modernc.org/sqlite v1.31.1/go.mod h1:UqoylwmTb9F+IqXERT8bW9zzOWN8qwAIcLdzeBZs4hA= +modernc.org/sqlite v1.32.0 h1:6BM4uGza7bWypsw4fdLRsLxut6bHe4c58VeqjRgST8s= +modernc.org/sqlite v1.32.0/go.mod h1:UqoylwmTb9F+IqXERT8bW9zzOWN8qwAIcLdzeBZs4hA= modernc.org/strutil v1.2.0 h1:agBi9dp1I+eOnxXeiZawM8F4LawKv4NzGWSaLfyeNZA= modernc.org/strutil v1.2.0/go.mod h1:/mdcBmfOibveCTBxUl5B5l6W+TTH1FXPLHZE6bTosX0= modernc.org/token v1.1.0 h1:Xl7Ap9dKaEs5kLoOQeQmPWevfnk/DM5qcLcYlA8ys6Y= From 19cc664cf8e7020dd692a62efcbba98ab670bde9 Mon Sep 17 00:00:00 2001 From: Weston Steimel Date: Fri, 9 Aug 2024 10:14:10 +0000 Subject: [PATCH 060/122] test: increase java purl generation test coverage (#3110) ensures correct package url generation for more java packages now that syft has more deterministic results per https://github.com/anchore/syft/pull/3085 Signed-off-by: Weston Steimel --- .../test/integration/java_purl_test.go | 198 +++++++----------- 1 file changed, 72 insertions(+), 126 deletions(-) diff --git a/cmd/syft/internal/test/integration/java_purl_test.go b/cmd/syft/internal/test/integration/java_purl_test.go index a7adbc396c2..d6367522285 100644 --- a/cmd/syft/internal/test/integration/java_purl_test.go +++ b/cmd/syft/internal/test/integration/java_purl_test.go @@ -51,138 +51,84 @@ var noAssertion = map[string]string{ "/packages/TwilioNotifier.hpi:WEB-INF/lib/sdk-3.0.jar": "pkg:maven/sdk/sdk@3.0", // syft generates incorrect purls - "/packages/akka-actor_2.13-2.6.6.jar": "pkg:maven/com.typesafe.akka/akka-actor_2.13@2.6.6", - "/packages/akka-management-cluster-bootstrap_2.13-1.2.0.jar": "pkg:maven/com.lightbend.akka.management/akka-management-cluster-bootstrap_2.13@1.2.0", - "/packages/hudson.war:WEB-INF/lib/asm-2.2.3.jar": "pkg:maven/asm/asm@2.2.3", - "/packages/hudson.war:WEB-INF/lib/asm-commons-2.2.3.jar": "pkg:maven/asm/asm-commons@2.2.3", - "/packages/hudson.war:WEB-INF/lib/asm-tree-2.2.3.jar": "pkg:maven/asm/asm-tree@2.2.3", - "/packages/hudson.war:WEB-INF/slave.jar": "pkg:maven/org.jvnet.hudson.main/remoting@1.390", - "/packages/hudson.war:WEB-INF/lib/xpp3_min-1.1.4c.jar": "pkg:maven/xpp3_min/xpp3_min@1.1.4c", - "/packages/hudson.war:WEB-INF/lib/xpp3-1.1.4c.jar": "pkg:maven/xpp3/xpp3@1.1.4c", - "/packages/hudson.war:WEB-INF/hudson-cli.jar": "pkg:maven/org.jvnet.hudson.main/hudson-cli@1.390", - "/packages/hudson.war:WEB-INF/lib/dom4j-1.6.1-hudson-3.jar": "pkg:maven/org.jvnet.hudson.dom4j/dom4j@1.6.1-hudson-3", - "/packages/xpp3_min-1.1.4c.jar": "pkg:maven/xpp3/xpp3_min@1.1.4c", - - // syft generates an unstable purl - "/packages/dubbo-3.1.4.jar:org.apache.dubbo:dubbo-auth": "pkg:maven/org.apache.dubbo/dubbo-auth@3.1.4", - "/packages/dubbo-3.1.4.jar:org.apache.dubbo:dubbo-cluster": "pkg:maven/org.apache.dubbo/dubbo-cluster@3.1.4", - "/packages/dubbo-3.1.4.jar:org.apache.dubbo:dubbo-common": "pkg:maven/org.apache.dubbo/dubbo-common@3.1.4", - "/packages/dubbo-3.1.4.jar:org.apache.dubbo:dubbo-compatible": "pkg:maven/org.apache.dubbo/dubbo-compatible@3.1.4", - "/packages/dubbo-3.1.4.jar:org.apache.dubbo:dubbo-config-api": "pkg:maven/org.apache.dubbo/dubbo-config-api@3.1.4", - "/packages/dubbo-3.1.4.jar:org.apache.dubbo:dubbo-config-spring": "pkg:maven/org.apache.dubbo/dubbo-config-spring@3.1.4", - "/packages/dubbo-3.1.4.jar:org.apache.dubbo:dubbo-configcenter-apollo": "pkg:maven/org.apache.dubbo/dubbo-configcenter-apollo@3.1.4", - "/packages/dubbo-3.1.4.jar:org.apache.dubbo:dubbo-configcenter-nacos": "pkg:maven/org.apache.dubbo/dubbo-configcenter-nacos@3.1.4", - "/packages/dubbo-3.1.4.jar:org.apache.dubbo:dubbo-configcenter-zookeeper": "pkg:maven/org.apache.dubbo/dubbo-configcenter-zookeeper@3.1.4", - "/packages/dubbo-3.1.4.jar:org.apache.dubbo:dubbo-container-api": "pkg:maven/org.apache.dubbo/dubbo-container-api@3.1.4", - "/packages/dubbo-3.1.4.jar:org.apache.dubbo:dubbo-container-spring": "pkg:maven/org.apache.dubbo/dubbo-container-spring@3.1.4", - "/packages/dubbo-3.1.4.jar:org.apache.dubbo:dubbo-filter-cache": "pkg:maven/org.apache.dubbo/dubbo-filter-cache@3.1.4", - "/packages/dubbo-3.1.4.jar:org.apache.dubbo:dubbo-filter-validation": "pkg:maven/org.apache.dubbo/dubbo-filter-validation@3.1.4", - "/packages/dubbo-3.1.4.jar:org.apache.dubbo:dubbo-kubernetes": "pkg:maven/org.apache.dubbo/dubbo-kubernetes@3.1.4", - "/packages/dubbo-3.1.4.jar:org.apache.dubbo:dubbo-metadata-api": "pkg:maven/org.apache.dubbo/dubbo-metadata-api@3.1.4", - "/packages/dubbo-3.1.4.jar:org.apache.dubbo:dubbo-metadata-definition-protobuf": "pkg:maven/org.apache.dubbo/dubbo-metadata-definition-protobuf@3.1.4", - "/packages/dubbo-3.1.4.jar:org.apache.dubbo:dubbo-metadata-report-nacos": "pkg:maven/org.apache.dubbo/dubbo-metadata-report-nacos@3.1.4", - "/packages/dubbo-3.1.4.jar:org.apache.dubbo:dubbo-metadata-report-redis": "pkg:maven/org.apache.dubbo/dubbo-metadata-report-redis@3.1.4", - "/packages/dubbo-3.1.4.jar:org.apache.dubbo:dubbo-metadata-report-zookeeper": "pkg:maven/org.apache.dubbo/dubbo-metadata-report-zookeeper@3.1.4", - "/packages/dubbo-3.1.4.jar:org.apache.dubbo:dubbo-metrics-api": "pkg:maven/org.apache.dubbo/dubbo-metrics-api@3.1.4", - "/packages/dubbo-3.1.4.jar:org.apache.dubbo:dubbo-metrics-prometheus": "pkg:maven/org.apache.dubbo/dubbo-metrics-prometheus@3.1.4", - "/packages/dubbo-3.1.4.jar:org.apache.dubbo:dubbo-monitor-api": "pkg:maven/org.apache.dubbo/dubbo-monitor-api@3.1.4", - "/packages/dubbo-3.1.4.jar:org.apache.dubbo:dubbo-monitor-default": "pkg:maven/org.apache.dubbo/dubbo-monitor-default@3.1.4", - "/packages/dubbo-3.1.4.jar:org.apache.dubbo:dubbo-qos": "pkg:maven/org.apache.dubbo/dubbo-qos@3.1.4", - "/packages/dubbo-3.1.4.jar:org.apache.dubbo:dubbo-reactive": "pkg:maven/org.apache.dubbo/dubbo-reactive@3.1.4", - "/packages/dubbo-3.1.4.jar:org.apache.dubbo:dubbo-registry-api": "pkg:maven/org.apache.dubbo/dubbo-registry-api@3.1.4", - "/packages/dubbo-3.1.4.jar:org.apache.dubbo:dubbo-registry-multicast": "pkg:maven/org.apache.dubbo/dubbo-registry-multicast@3.1.4", - "/packages/dubbo-3.1.4.jar:org.apache.dubbo:dubbo-registry-multiple": "pkg:maven/org.apache.dubbo/dubbo-registry-multiple@3.1.4", - "/packages/dubbo-3.1.4.jar:org.apache.dubbo:dubbo-registry-nacos": "pkg:maven/org.apache.dubbo/dubbo-registry-nacos@3.1.4", - "/packages/dubbo-3.1.4.jar:org.apache.dubbo:dubbo-registry-zookeeper": "pkg:maven/org.apache.dubbo/dubbo-registry-zookeeper@3.1.4", - "/packages/dubbo-3.1.4.jar:org.apache.dubbo:dubbo-remoting-api": "pkg:maven/org.apache.dubbo/dubbo-remoting-api@3.1.4", - "/packages/dubbo-3.1.4.jar:org.apache.dubbo:dubbo-remoting-http": "pkg:maven/org.apache.dubbo/dubbo-remoting-http@3.1.4", - "/packages/dubbo-3.1.4.jar:org.apache.dubbo:dubbo-remoting-netty": "pkg:maven/org.apache.dubbo/dubbo-remoting-netty@3.1.4", - "/packages/dubbo-3.1.4.jar:org.apache.dubbo:dubbo-remoting-netty4": "pkg:maven/org.apache.dubbo/dubbo-remoting-netty4@3.1.4", - "/packages/dubbo-3.1.4.jar:org.apache.dubbo:dubbo-remoting-zookeeper": "pkg:maven/org.apache.dubbo/dubbo-remoting-zookeeper@3.1.4", - "/packages/dubbo-3.1.4.jar:org.apache.dubbo:dubbo-remoting-zookeeper-curator5": "pkg:maven/org.apache.dubbo/dubbo-remoting-zookeeper-curator5@3.1.4", - "/packages/dubbo-3.1.4.jar:org.apache.dubbo:dubbo-rpc-api": "pkg:maven/org.apache.dubbo/dubbo-rpc-api@3.1.4", - "/packages/dubbo-3.1.4.jar:org.apache.dubbo:dubbo-rpc-dubbo": "pkg:maven/org.apache.dubbo/dubbo-rpc-dubbo@3.1.4", - "/packages/dubbo-3.1.4.jar:org.apache.dubbo:dubbo-rpc-grpc": "pkg:maven/org.apache.dubbo/dubbo-rpc-grpc@3.1.4", - "/packages/dubbo-3.1.4.jar:org.apache.dubbo:dubbo-rpc-injvm": "pkg:maven/org.apache.dubbo/dubbo-rpc-injvm@3.1.4", - "/packages/dubbo-3.1.4.jar:org.apache.dubbo:dubbo-rpc-rest": "pkg:maven/org.apache.dubbo/dubbo-rpc-rest@3.1.4", - "/packages/dubbo-3.1.4.jar:org.apache.dubbo:dubbo-rpc-triple": "pkg:maven/org.apache.dubbo/dubbo-rpc-triple@3.1.4", - "/packages/dubbo-3.1.4.jar:org.apache.dubbo:dubbo-serialization-api": "pkg:maven/org.apache.dubbo/dubbo-serialization-api@3.1.4", - "/packages/dubbo-3.1.4.jar:org.apache.dubbo:dubbo-serialization-fastjson2": "pkg:maven/org.apache.dubbo/dubbo-serialization-fastjson2@3.1.4", - "/packages/dubbo-3.1.4.jar:org.apache.dubbo:dubbo-serialization-hessian2": "pkg:maven/org.apache.dubbo/dubbo-serialization-hessian2@3.1.4", - "/packages/dubbo-3.1.4.jar:org.apache.dubbo:dubbo-serialization-jdk": "pkg:maven/org.apache.dubbo/dubbo-serialization-jdk@3.1.4", - "/packages/dubbo-3.1.4.jar:org.apache.dubbo:dubbo-xds": "pkg:maven/org.apache.dubbo/dubbo-xds@3.1.4", - "/packages/dubbo-3.1.4.jar:org.apache.dubbo:dubbo": "pkg:maven/org.apache.dubbo/dubbo@3.1.4", - "/packages/dubbo-3.1.4.jar": "pkg:maven/org.apache.dubbo/dubbo@3.1.4", + "/packages/hudson.war:WEB-INF/lib/asm-2.2.3.jar": "pkg:maven/asm/asm@2.2.3", + "/packages/hudson.war:WEB-INF/lib/asm-commons-2.2.3.jar": "pkg:maven/asm/asm-commons@2.2.3", + "/packages/hudson.war:WEB-INF/lib/asm-tree-2.2.3.jar": "pkg:maven/asm/asm-tree@2.2.3", + "/packages/hudson.war:WEB-INF/slave.jar": "pkg:maven/org.jvnet.hudson.main/remoting@1.390", + "/packages/hudson.war:WEB-INF/lib/xpp3_min-1.1.4c.jar": "pkg:maven/xpp3_min/xpp3_min@1.1.4c", + "/packages/hudson.war:WEB-INF/lib/xpp3-1.1.4c.jar": "pkg:maven/xpp3/xpp3@1.1.4c", + "/packages/hudson.war:WEB-INF/hudson-cli.jar": "pkg:maven/org.jvnet.hudson.main/hudson-cli@1.390", + "/packages/hudson.war:WEB-INF/lib/dom4j-1.6.1-hudson-3.jar": "pkg:maven/org.jvnet.hudson.dom4j/dom4j@1.6.1-hudson-3", + "/packages/xpp3_min-1.1.4c.jar": "pkg:maven/xpp3/xpp3_min@1.1.4c", } // Constructed by: // syft anchore/test_images:java-1abc58f -o json | jq -r '.artifacts.[] | [.metadata.virtualPath, .purl, ""] | @csv' | grep 'pkg:maven' | sort | uniq >> /tmp/java_artifacts_mapping.txt // The map was then hand-edited for correctness by comparing to Maven Central. var expectedPURLs = map[string]string{ - "/packages/activemq-client-5.18.2.jar": "pkg:maven/org.apache.activemq/activemq-client@5.18.2", - "/packages/activemq-protobuf-1.1.jar": "pkg:maven/org.apache.activemq.protobuf/activemq-protobuf@1.1", - // "/packages/akka-actor_2.13-2.6.6.jar": "pkg:maven/com.typesafe.akka/akka-actor_2.13@2.6.6", - // "/packages/akka-management-cluster-bootstrap_2.13-1.2.0.jar": "pkg:maven/com.lightbend.akka.management/akka-management-cluster-bootstrap_2.13@1.2.0", - "/packages/ant-1.10.3.jar": "pkg:maven/org.apache.ant/ant@1.10.3", - "/packages/apache-chainsaw-2.1.0.jar": "pkg:maven/log4j/apache-chainsaw@2.1.0", - "/packages/apache-log4j-extras-1.1.jar": "pkg:maven/log4j/apache-log4j-extras@1.1", - "/packages/apoc-4.4.0.11.jar": "pkg:maven/org.neo4j.procedure/apoc@4.4.0.11", - "/packages/bc-fips-1.0.2.3.jar": "pkg:maven/org.bouncycastle/bc-fips@1.0.2.3", - "/packages/camel-core-3.1.0.jar": "pkg:maven/org.apache.camel/camel-core@3.1.0", - "/packages/cassandra-all-4.1.1.jar": "pkg:maven/org.apache.cassandra/cassandra-all@4.1.1", - "/packages/commons-logging-1.1.1.jar": "pkg:maven/commons-logging/commons-logging@1.1.1", - "/packages/commons-vfs-1.0.jar": "pkg:maven/commons-vfs/commons-vfs@1.0", - "/packages/cxf-rt-transports-http-2.7.3.jar": "pkg:maven/org.apache.cxf/cxf-rt-transports-http@2.7.3", - "/packages/dubbo-3.1.4.jar:com.alibaba:hessian-lite": "pkg:maven/com.alibaba/hessian-lite@3.2.13", - // "/packages/dubbo-3.1.4.jar:org.apache.dubbo:dubbo-auth": "pkg:maven/org.apache.dubbo/dubbo-auth@3.1.4", - // "/packages/dubbo-3.1.4.jar:org.apache.dubbo:dubbo-cluster": "pkg:maven/org.apache.dubbo/dubbo-cluster@3.1.4", - // "/packages/dubbo-3.1.4.jar:org.apache.dubbo:dubbo-common": "pkg:maven/org.apache.dubbo/dubbo-common@3.1.4", - // "/packages/dubbo-3.1.4.jar:org.apache.dubbo:dubbo-compatible": "pkg:maven/org.apache.dubbo/dubbo-compatible@3.1.4", - // "/packages/dubbo-3.1.4.jar:org.apache.dubbo:dubbo-config-api": "pkg:maven/org.apache.dubbo/dubbo-config-api@3.1.4", - // "/packages/dubbo-3.1.4.jar:org.apache.dubbo:dubbo-config-spring": "pkg:maven/org.apache.dubbo/dubbo-config-spring@3.1.4", - // "/packages/dubbo-3.1.4.jar:org.apache.dubbo:dubbo-configcenter-apollo": "pkg:maven/org.apache.dubbo/dubbo-configcenter-apollo@3.1.4", - // "/packages/dubbo-3.1.4.jar:org.apache.dubbo:dubbo-configcenter-nacos": "pkg:maven/org.apache.dubbo/dubbo-configcenter-nacos@3.1.4", - // "/packages/dubbo-3.1.4.jar:org.apache.dubbo:dubbo-configcenter-zookeeper": "pkg:maven/org.apache.dubbo/dubbo-configcenter-zookeeper@3.1.4", - // "/packages/dubbo-3.1.4.jar:org.apache.dubbo:dubbo-container-api": "pkg:maven/org.apache.dubbo/dubbo-container-api@3.1.4", - // "/packages/dubbo-3.1.4.jar:org.apache.dubbo:dubbo-container-spring": "pkg:maven/org.apache.dubbo/dubbo-container-spring@3.1.4", - // "/packages/dubbo-3.1.4.jar:org.apache.dubbo:dubbo-filter-cache": "pkg:maven/org.apache.dubbo/dubbo-filter-cache@3.1.4", - // "/packages/dubbo-3.1.4.jar:org.apache.dubbo:dubbo-filter-validation": "pkg:maven/org.apache.dubbo/dubbo-filter-validation@3.1.4", - // "/packages/dubbo-3.1.4.jar:org.apache.dubbo:dubbo-kubernetes": "pkg:maven/org.apache.dubbo/dubbo-kubernetes@3.1.4", - // "/packages/dubbo-3.1.4.jar:org.apache.dubbo:dubbo-metadata-api": "pkg:maven/org.apache.dubbo/dubbo-metadata-api@3.1.4", - // "/packages/dubbo-3.1.4.jar:org.apache.dubbo:dubbo-metadata-definition-protobuf": "pkg:maven/org.apache.dubbo/dubbo-metadata-definition-protobuf@3.1.4", - // "/packages/dubbo-3.1.4.jar:org.apache.dubbo:dubbo-metadata-report-nacos": "pkg:maven/org.apache.dubbo/dubbo-metadata-report-nacos@3.1.4", - // "/packages/dubbo-3.1.4.jar:org.apache.dubbo:dubbo-metadata-report-redis": "pkg:maven/org.apache.dubbo/dubbo-metadata-report-redis@3.1.4", - // "/packages/dubbo-3.1.4.jar:org.apache.dubbo:dubbo-metadata-report-zookeeper": "pkg:maven/org.apache.dubbo/dubbo-metadata-report-zookeeper@3.1.4", - // "/packages/dubbo-3.1.4.jar:org.apache.dubbo:dubbo-metrics-api": "pkg:maven/org.apache.dubbo/dubbo-metrics-api@3.1.4", - // "/packages/dubbo-3.1.4.jar:org.apache.dubbo:dubbo-metrics-prometheus": "pkg:maven/org.apache.dubbo/dubbo-metrics-prometheus@3.1.4", - // "/packages/dubbo-3.1.4.jar:org.apache.dubbo:dubbo-monitor-api": "pkg:maven/org.apache.dubbo/dubbo-monitor-api@3.1.4", - // "/packages/dubbo-3.1.4.jar:org.apache.dubbo:dubbo-monitor-default": "pkg:maven/org.apache.dubbo/dubbo-monitor-default@3.1.4", - // "/packages/dubbo-3.1.4.jar:org.apache.dubbo:dubbo-qos": "pkg:maven/org.apache.dubbo/dubbo-qos@3.1.4", - // "/packages/dubbo-3.1.4.jar:org.apache.dubbo:dubbo-reactive": "pkg:maven/org.apache.dubbo/dubbo-reactive@3.1.4", - // "/packages/dubbo-3.1.4.jar:org.apache.dubbo:dubbo-registry-api": "pkg:maven/org.apache.dubbo/dubbo-registry-api@3.1.4", - // "/packages/dubbo-3.1.4.jar:org.apache.dubbo:dubbo-registry-multicast": "pkg:maven/org.apache.dubbo/dubbo-registry-multicast@3.1.4", - // "/packages/dubbo-3.1.4.jar:org.apache.dubbo:dubbo-registry-multiple": "pkg:maven/org.apache.dubbo/dubbo-registry-multiple@3.1.4", - // "/packages/dubbo-3.1.4.jar:org.apache.dubbo:dubbo-registry-nacos": "pkg:maven/org.apache.dubbo/dubbo-registry-nacos@3.1.4", - // "/packages/dubbo-3.1.4.jar:org.apache.dubbo:dubbo-registry-zookeeper": "pkg:maven/org.apache.dubbo/dubbo-registry-zookeeper@3.1.4", - // "/packages/dubbo-3.1.4.jar:org.apache.dubbo:dubbo-remoting-api": "pkg:maven/org.apache.dubbo/dubbo-remoting-api@3.1.4", - // "/packages/dubbo-3.1.4.jar:org.apache.dubbo:dubbo-remoting-http": "pkg:maven/org.apache.dubbo/dubbo-remoting-http@3.1.4", - // "/packages/dubbo-3.1.4.jar:org.apache.dubbo:dubbo-remoting-netty": "pkg:maven/org.apache.dubbo/dubbo-remoting-netty@3.1.4", - // "/packages/dubbo-3.1.4.jar:org.apache.dubbo:dubbo-remoting-netty4": "pkg:maven/org.apache.dubbo/dubbo-remoting-netty4@3.1.4", - // "/packages/dubbo-3.1.4.jar:org.apache.dubbo:dubbo-remoting-zookeeper": "pkg:maven/org.apache.dubbo/dubbo-remoting-zookeeper@3.1.4", - // "/packages/dubbo-3.1.4.jar:org.apache.dubbo:dubbo-remoting-zookeeper-curator5": "pkg:maven/org.apache.dubbo/dubbo-remoting-zookeeper-curator5@3.1.4", - // "/packages/dubbo-3.1.4.jar:org.apache.dubbo:dubbo-rpc-api": "pkg:maven/org.apache.dubbo/dubbo-rpc-api@3.1.4", - // "/packages/dubbo-3.1.4.jar:org.apache.dubbo:dubbo-rpc-dubbo": "pkg:maven/org.apache.dubbo/dubbo-rpc-dubbo@3.1.4", - // "/packages/dubbo-3.1.4.jar:org.apache.dubbo:dubbo-rpc-grpc": "pkg:maven/org.apache.dubbo/dubbo-rpc-grpc@3.1.4", - // "/packages/dubbo-3.1.4.jar:org.apache.dubbo:dubbo-rpc-injvm": "pkg:maven/org.apache.dubbo/dubbo-rpc-injvm@3.1.4", - // "/packages/dubbo-3.1.4.jar:org.apache.dubbo:dubbo-rpc-rest": "pkg:maven/org.apache.dubbo/dubbo-rpc-rest@3.1.4", - // "/packages/dubbo-3.1.4.jar:org.apache.dubbo:dubbo-rpc-triple": "pkg:maven/org.apache.dubbo/dubbo-rpc-triple@3.1.4", - // "/packages/dubbo-3.1.4.jar:org.apache.dubbo:dubbo-serialization-api": "pkg:maven/org.apache.dubbo/dubbo-serialization-api@3.1.4", - // "/packages/dubbo-3.1.4.jar:org.apache.dubbo:dubbo-serialization-fastjson2": "pkg:maven/org.apache.dubbo/dubbo-serialization-fastjson2@3.1.4", - // "/packages/dubbo-3.1.4.jar:org.apache.dubbo:dubbo-serialization-hessian2": "pkg:maven/org.apache.dubbo/dubbo-serialization-hessian2@3.1.4", - // "/packages/dubbo-3.1.4.jar:org.apache.dubbo:dubbo-serialization-jdk": "pkg:maven/org.apache.dubbo/dubbo-serialization-jdk@3.1.4", - // "/packages/dubbo-3.1.4.jar:org.apache.dubbo:dubbo-xds": "pkg:maven/org.apache.dubbo/dubbo-xds@3.1.4", - // "/packages/dubbo-3.1.4.jar:org.apache.dubbo:dubbo": "pkg:maven/org.apache.dubbo/dubbo@3.1.4", - // "/packages/dubbo-3.1.4.jar": "pkg:maven/org.apache.dubbo/dubbo@3.1.4", + "/packages/activemq-client-5.18.2.jar": "pkg:maven/org.apache.activemq/activemq-client@5.18.2", + "/packages/activemq-protobuf-1.1.jar": "pkg:maven/org.apache.activemq.protobuf/activemq-protobuf@1.1", + "/packages/akka-actor_2.13-2.6.6.jar": "pkg:maven/com.typesafe.akka/akka-actor_2.13@2.6.6", + "/packages/akka-management-cluster-bootstrap_2.13-1.2.0.jar": "pkg:maven/com.lightbend.akka.management/akka-management-cluster-bootstrap_2.13@1.2.0", + "/packages/ant-1.10.3.jar": "pkg:maven/org.apache.ant/ant@1.10.3", + "/packages/apache-chainsaw-2.1.0.jar": "pkg:maven/log4j/apache-chainsaw@2.1.0", + "/packages/apache-log4j-extras-1.1.jar": "pkg:maven/log4j/apache-log4j-extras@1.1", + "/packages/apoc-4.4.0.11.jar": "pkg:maven/org.neo4j.procedure/apoc@4.4.0.11", + "/packages/bc-fips-1.0.2.3.jar": "pkg:maven/org.bouncycastle/bc-fips@1.0.2.3", + "/packages/camel-core-3.1.0.jar": "pkg:maven/org.apache.camel/camel-core@3.1.0", + "/packages/cassandra-all-4.1.1.jar": "pkg:maven/org.apache.cassandra/cassandra-all@4.1.1", + "/packages/commons-logging-1.1.1.jar": "pkg:maven/commons-logging/commons-logging@1.1.1", + "/packages/commons-vfs-1.0.jar": "pkg:maven/commons-vfs/commons-vfs@1.0", + "/packages/cxf-rt-transports-http-2.7.3.jar": "pkg:maven/org.apache.cxf/cxf-rt-transports-http@2.7.3", + "/packages/dubbo-3.1.4.jar:com.alibaba:hessian-lite": "pkg:maven/com.alibaba/hessian-lite@3.2.13", + "/packages/dubbo-3.1.4.jar:org.apache.dubbo:dubbo-auth": "pkg:maven/org.apache.dubbo/dubbo-auth@3.1.4", + "/packages/dubbo-3.1.4.jar:org.apache.dubbo:dubbo-cluster": "pkg:maven/org.apache.dubbo/dubbo-cluster@3.1.4", + "/packages/dubbo-3.1.4.jar:org.apache.dubbo:dubbo-common": "pkg:maven/org.apache.dubbo/dubbo-common@3.1.4", + "/packages/dubbo-3.1.4.jar:org.apache.dubbo:dubbo-compatible": "pkg:maven/org.apache.dubbo/dubbo-compatible@3.1.4", + "/packages/dubbo-3.1.4.jar:org.apache.dubbo:dubbo-config-api": "pkg:maven/org.apache.dubbo/dubbo-config-api@3.1.4", + "/packages/dubbo-3.1.4.jar:org.apache.dubbo:dubbo-config-spring": "pkg:maven/org.apache.dubbo/dubbo-config-spring@3.1.4", + "/packages/dubbo-3.1.4.jar:org.apache.dubbo:dubbo-configcenter-apollo": "pkg:maven/org.apache.dubbo/dubbo-configcenter-apollo@3.1.4", + "/packages/dubbo-3.1.4.jar:org.apache.dubbo:dubbo-configcenter-nacos": "pkg:maven/org.apache.dubbo/dubbo-configcenter-nacos@3.1.4", + "/packages/dubbo-3.1.4.jar:org.apache.dubbo:dubbo-configcenter-zookeeper": "pkg:maven/org.apache.dubbo/dubbo-configcenter-zookeeper@3.1.4", + "/packages/dubbo-3.1.4.jar:org.apache.dubbo:dubbo-container-api": "pkg:maven/org.apache.dubbo/dubbo-container-api@3.1.4", + "/packages/dubbo-3.1.4.jar:org.apache.dubbo:dubbo-container-spring": "pkg:maven/org.apache.dubbo/dubbo-container-spring@3.1.4", + "/packages/dubbo-3.1.4.jar:org.apache.dubbo:dubbo-filter-cache": "pkg:maven/org.apache.dubbo/dubbo-filter-cache@3.1.4", + "/packages/dubbo-3.1.4.jar:org.apache.dubbo:dubbo-filter-validation": "pkg:maven/org.apache.dubbo/dubbo-filter-validation@3.1.4", + "/packages/dubbo-3.1.4.jar:org.apache.dubbo:dubbo-kubernetes": "pkg:maven/org.apache.dubbo/dubbo-kubernetes@3.1.4", + "/packages/dubbo-3.1.4.jar:org.apache.dubbo:dubbo-metadata-api": "pkg:maven/org.apache.dubbo/dubbo-metadata-api@3.1.4", + "/packages/dubbo-3.1.4.jar:org.apache.dubbo:dubbo-metadata-definition-protobuf": "pkg:maven/org.apache.dubbo/dubbo-metadata-definition-protobuf@3.1.4", + "/packages/dubbo-3.1.4.jar:org.apache.dubbo:dubbo-metadata-report-nacos": "pkg:maven/org.apache.dubbo/dubbo-metadata-report-nacos@3.1.4", + "/packages/dubbo-3.1.4.jar:org.apache.dubbo:dubbo-metadata-report-redis": "pkg:maven/org.apache.dubbo/dubbo-metadata-report-redis@3.1.4", + "/packages/dubbo-3.1.4.jar:org.apache.dubbo:dubbo-metadata-report-zookeeper": "pkg:maven/org.apache.dubbo/dubbo-metadata-report-zookeeper@3.1.4", + "/packages/dubbo-3.1.4.jar:org.apache.dubbo:dubbo-metrics-api": "pkg:maven/org.apache.dubbo/dubbo-metrics-api@3.1.4", + "/packages/dubbo-3.1.4.jar:org.apache.dubbo:dubbo-metrics-prometheus": "pkg:maven/org.apache.dubbo/dubbo-metrics-prometheus@3.1.4", + "/packages/dubbo-3.1.4.jar:org.apache.dubbo:dubbo-monitor-api": "pkg:maven/org.apache.dubbo/dubbo-monitor-api@3.1.4", + "/packages/dubbo-3.1.4.jar:org.apache.dubbo:dubbo-monitor-default": "pkg:maven/org.apache.dubbo/dubbo-monitor-default@3.1.4", + "/packages/dubbo-3.1.4.jar:org.apache.dubbo:dubbo-qos": "pkg:maven/org.apache.dubbo/dubbo-qos@3.1.4", + "/packages/dubbo-3.1.4.jar:org.apache.dubbo:dubbo-reactive": "pkg:maven/org.apache.dubbo/dubbo-reactive@3.1.4", + "/packages/dubbo-3.1.4.jar:org.apache.dubbo:dubbo-registry-api": "pkg:maven/org.apache.dubbo/dubbo-registry-api@3.1.4", + "/packages/dubbo-3.1.4.jar:org.apache.dubbo:dubbo-registry-multicast": "pkg:maven/org.apache.dubbo/dubbo-registry-multicast@3.1.4", + "/packages/dubbo-3.1.4.jar:org.apache.dubbo:dubbo-registry-multiple": "pkg:maven/org.apache.dubbo/dubbo-registry-multiple@3.1.4", + "/packages/dubbo-3.1.4.jar:org.apache.dubbo:dubbo-registry-nacos": "pkg:maven/org.apache.dubbo/dubbo-registry-nacos@3.1.4", + "/packages/dubbo-3.1.4.jar:org.apache.dubbo:dubbo-registry-zookeeper": "pkg:maven/org.apache.dubbo/dubbo-registry-zookeeper@3.1.4", + "/packages/dubbo-3.1.4.jar:org.apache.dubbo:dubbo-remoting-api": "pkg:maven/org.apache.dubbo/dubbo-remoting-api@3.1.4", + "/packages/dubbo-3.1.4.jar:org.apache.dubbo:dubbo-remoting-http": "pkg:maven/org.apache.dubbo/dubbo-remoting-http@3.1.4", + "/packages/dubbo-3.1.4.jar:org.apache.dubbo:dubbo-remoting-netty": "pkg:maven/org.apache.dubbo/dubbo-remoting-netty@3.1.4", + "/packages/dubbo-3.1.4.jar:org.apache.dubbo:dubbo-remoting-netty4": "pkg:maven/org.apache.dubbo/dubbo-remoting-netty4@3.1.4", + "/packages/dubbo-3.1.4.jar:org.apache.dubbo:dubbo-remoting-zookeeper": "pkg:maven/org.apache.dubbo/dubbo-remoting-zookeeper@3.1.4", + "/packages/dubbo-3.1.4.jar:org.apache.dubbo:dubbo-remoting-zookeeper-curator5": "pkg:maven/org.apache.dubbo/dubbo-remoting-zookeeper-curator5@3.1.4", + "/packages/dubbo-3.1.4.jar:org.apache.dubbo:dubbo-rpc-api": "pkg:maven/org.apache.dubbo/dubbo-rpc-api@3.1.4", + "/packages/dubbo-3.1.4.jar:org.apache.dubbo:dubbo-rpc-dubbo": "pkg:maven/org.apache.dubbo/dubbo-rpc-dubbo@3.1.4", + "/packages/dubbo-3.1.4.jar:org.apache.dubbo:dubbo-rpc-grpc": "pkg:maven/org.apache.dubbo/dubbo-rpc-grpc@3.1.4", + "/packages/dubbo-3.1.4.jar:org.apache.dubbo:dubbo-rpc-injvm": "pkg:maven/org.apache.dubbo/dubbo-rpc-injvm@3.1.4", + "/packages/dubbo-3.1.4.jar:org.apache.dubbo:dubbo-rpc-rest": "pkg:maven/org.apache.dubbo/dubbo-rpc-rest@3.1.4", + "/packages/dubbo-3.1.4.jar:org.apache.dubbo:dubbo-rpc-triple": "pkg:maven/org.apache.dubbo/dubbo-rpc-triple@3.1.4", + "/packages/dubbo-3.1.4.jar:org.apache.dubbo:dubbo-serialization-api": "pkg:maven/org.apache.dubbo/dubbo-serialization-api@3.1.4", + "/packages/dubbo-3.1.4.jar:org.apache.dubbo:dubbo-serialization-fastjson2": "pkg:maven/org.apache.dubbo/dubbo-serialization-fastjson2@3.1.4", + "/packages/dubbo-3.1.4.jar:org.apache.dubbo:dubbo-serialization-hessian2": "pkg:maven/org.apache.dubbo/dubbo-serialization-hessian2@3.1.4", + "/packages/dubbo-3.1.4.jar:org.apache.dubbo:dubbo-serialization-jdk": "pkg:maven/org.apache.dubbo/dubbo-serialization-jdk@3.1.4", + "/packages/dubbo-3.1.4.jar:org.apache.dubbo:dubbo-xds": "pkg:maven/org.apache.dubbo/dubbo-xds@3.1.4", + "/packages/dubbo-3.1.4.jar": "pkg:maven/org.apache.dubbo/dubbo@3.1.4", "/packages/elasticsearch-8.10.2.jar": "pkg:maven/org.elasticsearch/elasticsearch@8.10.2", "/packages/elasticsearch-rest-client-sniffer-7.17.11.jar": "pkg:maven/org.elasticsearch.client/elasticsearch-rest-client-sniffer@7.17.11", "/packages/example-java-app-gradle-0.1.0.ear": "pkg:maven/example-java-app-gradle/example-java-app-gradle@0.1.0", From 49d4e32241fc3025fd87515ad4ce37196871d2f2 Mon Sep 17 00:00:00 2001 From: Alan Pope Date: Mon, 12 Aug 2024 11:49:10 +0100 Subject: [PATCH 061/122] update-slack-to-discourse (#3111) Signed-off-by: Alan Pope --- .github/ISSUE_TEMPLATE/config.yml | 6 +++--- DEVELOPING.md | 2 +- README.md | 2 +- 3 files changed, 5 insertions(+), 5 deletions(-) diff --git a/.github/ISSUE_TEMPLATE/config.yml b/.github/ISSUE_TEMPLATE/config.yml index edd71d50485..3009b9c0cc0 100644 --- a/.github/ISSUE_TEMPLATE/config.yml +++ b/.github/ISSUE_TEMPLATE/config.yml @@ -1,6 +1,6 @@ contact_links: - - name: Join the Slack community đŸ’Ŧ - # link to our community Slack registration page - url: https://anchore.com/slack + - name: Join our Discourse community đŸ’Ŧ + # link to our community Discourse site + url: https://anchore.com/discourse about: 'Come chat with us! Ask for help, join our software development efforts, or just give us feedback!' diff --git a/DEVELOPING.md b/DEVELOPING.md index 2308c51b123..3d1e5ff1870 100644 --- a/DEVELOPING.md +++ b/DEVELOPING.md @@ -212,7 +212,7 @@ Finally, here is an example of where the package construction is done within the - [The APK package constructor itself](https://github.com/anchore/syft/tree/v0.70.0/syft/pkg/cataloger/apkdb/package.go#L12-L27) Interested in building a new cataloger? Checkout the [list of issues with the `new-cataloger` label](https://github.com/anchore/syft/issues?q=is%3Aopen+is%3Aissue+label%3Anew-cataloger+no%3Aassignee)! -If you have questions about implementing a cataloger feel free to file an issue or reach out to us [on slack](https://anchore.com/slack)! +If you have questions about implementing a cataloger feel free to file an issue or reach out to us [on discourse](https://anchore.com/discourse)! #### Searching for files diff --git a/README.md b/README.md index 4a714210c17..cf4d361c58d 100644 --- a/README.md +++ b/README.md @@ -12,7 +12,7 @@  GitHub release   GitHub go.mod Go version   License: Apache-2.0  -  Slack  +  Join our Discourse 

![syft-demo](https://user-images.githubusercontent.com/590471/90277200-2a253000-de33-11ea-893f-32c219eea11a.gif) From cf85450e08da80f940c21f977e9e061844648904 Mon Sep 17 00:00:00 2001 From: Keith Zantow Date: Mon, 12 Aug 2024 12:07:47 -0400 Subject: [PATCH 062/122] chore: fix failing python relationship test (#3117) Signed-off-by: Keith Zantow --- syft/pkg/cataloger/python/cataloger_test.go | 2 +- .../python/test-fixtures/image-multi-site-package/Dockerfile | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/syft/pkg/cataloger/python/cataloger_test.go b/syft/pkg/cataloger/python/cataloger_test.go index f3fc060172e..8e827322ebf 100644 --- a/syft/pkg/cataloger/python/cataloger_test.go +++ b/syft/pkg/cataloger/python/cataloger_test.go @@ -643,7 +643,7 @@ func Test_PackageCataloger_SitePackageRelationships(t *testing.T) { // Note: we'll only see new relationships, so any relationship where there is at least one new player (in FROM or TO) "blessed @ 1.20.0 (/usr/local/lib/python3.9/dist-packages) [dependency-of] inquirer @ 3.0.0 (/app/project1/venv/lib/python3.9/site-packages)", // note: depends on global site package! "python-editor @ 1.0.4 (/usr/local/lib/python3.9/dist-packages) [dependency-of] inquirer @ 3.0.0 (/app/project1/venv/lib/python3.9/site-packages)", // note: depends on global site package! - "readchar @ 4.1.0 (/app/project1/venv/lib/python3.9/site-packages) [dependency-of] inquirer @ 3.0.0 (/app/project1/venv/lib/python3.9/site-packages)", + "readchar @ 4.2.0 (/app/project1/venv/lib/python3.9/site-packages) [dependency-of] inquirer @ 3.0.0 (/app/project1/venv/lib/python3.9/site-packages)", "soupsieve @ 2.3 (/app/project1/venv/lib/python3.9/site-packages) [dependency-of] beautifulsoup4 @ 4.10.0 (/app/project1/venv/lib/python3.9/site-packages)", // project 2 virtual env diff --git a/syft/pkg/cataloger/python/test-fixtures/image-multi-site-package/Dockerfile b/syft/pkg/cataloger/python/test-fixtures/image-multi-site-package/Dockerfile index dcc27e38cbd..3895cebbd96 100644 --- a/syft/pkg/cataloger/python/test-fixtures/image-multi-site-package/Dockerfile +++ b/syft/pkg/cataloger/python/test-fixtures/image-multi-site-package/Dockerfile @@ -17,7 +17,7 @@ RUN python3.9 -m pip install requests==2.25.0 certifi==2020.12.5 chardet==3.0.4 RUN python3.8 -m pip install click==8.0.2 beautifulsoup4==4.9.2 soupsieve==2.2.0 requests==2.25.0 RUN python3.8 -m pip install runs==1.2.2 xmod==1.8.1 # partial dependencies for inquirer in project2 (which is a red herring) RUN python3.8 -m pip install requests==2.25.0 certifi==2020.12.5 chardet==3.0.4 idna==2.10 urllib3==1.26.18 # total dependencies for requests -RUN python3.8 -m pip install readchar==4.1.0 +RUN python3.8 -m pip install readchar==4.2.0 # create directories for the two projects RUN mkdir -p /app/project1 /app/project2 From c19cf626abf2319a3cf0e2687cd4ee761425c962 Mon Sep 17 00:00:00 2001 From: luozexuan Date: Tue, 13 Aug 2024 00:08:04 +0800 Subject: [PATCH 063/122] chore: fix some comments (#3114) Signed-off-by: luozexuan --- DEVELOPING.md | 2 +- cmd/syft/internal/options/format.go | 2 +- internal/cache/README.md | 2 +- test/cli/cyclonedx_valid_test.go | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/DEVELOPING.md b/DEVELOPING.md index 3d1e5ff1870..5dd88e2746e 100644 --- a/DEVELOPING.md +++ b/DEVELOPING.md @@ -83,7 +83,7 @@ Syft's core library is implemented in the `syft` package and subpackages, where - the `syft` package contains a single function that can take a `source.Source` object and catalog it, producing an `sbom.SBOM` object - the `syft/format` package contains the ability to encode and decode SBOMs to and from different SBOM formats (such as SPDX and CycloneDX) -The `cmd` pacakge at the highest level execution flow wires up [`spf13/cobra`](https://github.com/spf13/cobra) commands for execution in the main application: +The `cmd` package at the highest level execution flow wires up [`spf13/cobra`](https://github.com/spf13/cobra) commands for execution in the main application: ```mermaid sequenceDiagram participant main as cmd/syft/main diff --git a/cmd/syft/internal/options/format.go b/cmd/syft/internal/options/format.go index 4ff1e9934a9..4540b5fee46 100644 --- a/cmd/syft/internal/options/format.go +++ b/cmd/syft/internal/options/format.go @@ -50,7 +50,7 @@ if false, uses the syft-json output for templating (which follows the syft JSON Note: long term support for this option is not guaranteed (it may change or break at any time)`) - prettyDescription := `include space indention and newlines + prettyDescription := `include space indentation and newlines note: inherits default value from 'format.pretty' or 'false' if parent is unset` descriptions.Add(&o.SyftJSON.Pretty, prettyDescription) descriptions.Add(&o.SPDXJSON.Pretty, prettyDescription) diff --git a/internal/cache/README.md b/internal/cache/README.md index 174e03b9e2c..b24a6f93408 100644 --- a/internal/cache/README.md +++ b/internal/cache/README.md @@ -1,6 +1,6 @@ # Caching -All caches are created from a global `manager`. By defaut this is a `bypassedCache`, which performs no caching. +All caches are created from a global `manager`. By default this is a `bypassedCache`, which performs no caching. One benefit of this is that tests don't need to worry about caching causing issues unless they explicitly need to test the cache and can opt-in using the `cache.TestCache(t)` helper. diff --git a/test/cli/cyclonedx_valid_test.go b/test/cli/cyclonedx_valid_test.go index 1feca08d9e6..49755f0bc5e 100644 --- a/test/cli/cyclonedx_valid_test.go +++ b/test/cli/cyclonedx_valid_test.go @@ -12,7 +12,7 @@ import ( "github.com/anchore/syft/syft/format/cyclonedxjson" ) -// We have schema validation mechanims in schema/cyclonedx/ +// We have schema validation mechanisms in schema/cyclonedx/ // This test allows us to double check that validation against the cyclonedx-cli tool func TestValidCycloneDX(t *testing.T) { imageFixture := func(t *testing.T) string { From 91cf066db6ff4fc9be4a7e15ff086a811ca449fa Mon Sep 17 00:00:00 2001 From: GGMU <49076226+tomersein@users.noreply.github.com> Date: Mon, 12 Aug 2024 19:10:03 +0300 Subject: [PATCH 064/122] support .kar files (#3113) * add kar Signed-off-by: tomersein --- syft/pkg/cataloger/java/archive_filename.go | 2 +- syft/pkg/cataloger/java/archive_filename_test.go | 7 +++++++ syft/pkg/cataloger/java/archive_parser.go | 1 + syft/pkg/cataloger/java/cataloger_test.go | 1 + .../test-fixtures/glob-paths/java-archives/example.kar | 1 + 5 files changed, 11 insertions(+), 1 deletion(-) create mode 100644 syft/pkg/cataloger/java/test-fixtures/glob-paths/java-archives/example.kar diff --git a/syft/pkg/cataloger/java/archive_filename.go b/syft/pkg/cataloger/java/archive_filename.go index 084371499d9..cc377e43874 100644 --- a/syft/pkg/cataloger/java/archive_filename.go +++ b/syft/pkg/cataloger/java/archive_filename.go @@ -108,7 +108,7 @@ func (a archiveFilename) extension() string { func (a archiveFilename) pkgType() pkg.Type { switch strings.ToLower(a.extension()) { - case "jar", "war", "ear", "lpkg", "par", "sar", "nar": + case "jar", "war", "ear", "lpkg", "par", "sar", "nar", "kar": return pkg.JavaPkg case "jpi", "hpi": return pkg.JenkinsPluginPkg diff --git a/syft/pkg/cataloger/java/archive_filename_test.go b/syft/pkg/cataloger/java/archive_filename_test.go index 5752e7d1ad3..98560491261 100644 --- a/syft/pkg/cataloger/java/archive_filename_test.go +++ b/syft/pkg/cataloger/java/archive_filename_test.go @@ -86,6 +86,13 @@ func TestExtractInfoFromJavaArchiveFilename(t *testing.T) { name: "pkg-extra-field-maven", ty: pkg.JavaPkg, }, + { + filename: "pkg-extra-field-maven-4.3.2-rc1.kar", + version: "4.3.2-rc1", + extension: "kar", + name: "pkg-extra-field-maven", + ty: pkg.JavaPkg, + }, { filename: "/some/path/pkg-extra-field-maven-4.3.2-rc1.jpi", version: "4.3.2-rc1", diff --git a/syft/pkg/cataloger/java/archive_parser.go b/syft/pkg/cataloger/java/archive_parser.go index 663563c613d..1de3ab80abe 100644 --- a/syft/pkg/cataloger/java/archive_parser.go +++ b/syft/pkg/cataloger/java/archive_parser.go @@ -31,6 +31,7 @@ var archiveFormatGlobs = []string{ "**/*.nar", "**/*.jpi", "**/*.hpi", + "**/*.kar", "**/*.lpkg", // Zip-compressed package used to deploy applications // (aka plugins) to Liferay Portal server. Those files contains .JAR(s) and a .PROPERTIES file, the latter // has information about the application and installation requirements. diff --git a/syft/pkg/cataloger/java/cataloger_test.go b/syft/pkg/cataloger/java/cataloger_test.go index da524fc5ba3..84ba1ea91db 100644 --- a/syft/pkg/cataloger/java/cataloger_test.go +++ b/syft/pkg/cataloger/java/cataloger_test.go @@ -23,6 +23,7 @@ func Test_ArchiveCataloger_Globs(t *testing.T) { "java-archives/example.par", "java-archives/example.sar", "java-archives/example.nar", + "java-archives/example.kar", "java-archives/example.jpi", "java-archives/example.hpi", "java-archives/example.lpkg", diff --git a/syft/pkg/cataloger/java/test-fixtures/glob-paths/java-archives/example.kar b/syft/pkg/cataloger/java/test-fixtures/glob-paths/java-archives/example.kar new file mode 100644 index 00000000000..0b3d595db9f --- /dev/null +++ b/syft/pkg/cataloger/java/test-fixtures/glob-paths/java-archives/example.kar @@ -0,0 +1 @@ +example archive \ No newline at end of file From d2b33f1acb34fd75782032e519f804efd90aecae Mon Sep 17 00:00:00 2001 From: "anchore-actions-token-generator[bot]" <102182147+anchore-actions-token-generator[bot]@users.noreply.github.com> Date: Mon, 12 Aug 2024 16:57:47 +0000 Subject: [PATCH 065/122] chore(deps): update CPE dictionary index (#3116) Signed-off-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com> Co-authored-by: wagoodman <590471+wagoodman@users.noreply.github.com> Co-authored-by: Christopher Phillips <32073428+spiffcs@users.noreply.github.com> --- .../dictionary/data/cpe-index.json | 47 ++++++++++++++++++- 1 file changed, 46 insertions(+), 1 deletion(-) diff --git a/syft/pkg/cataloger/internal/cpegenerate/dictionary/data/cpe-index.json b/syft/pkg/cataloger/internal/cpegenerate/dictionary/data/cpe-index.json index 54ec320a881..586be8f3e5a 100644 --- a/syft/pkg/cataloger/internal/cpegenerate/dictionary/data/cpe-index.json +++ b/syft/pkg/cataloger/internal/cpegenerate/dictionary/data/cpe-index.json @@ -1464,6 +1464,9 @@ "quality-gates": [ "cpe:2.3:a:jenkins:quality_gates:*:*:*:*:*:jenkins:*:*" ], + "qualys-pc": [ + "cpe:2.3:a:qualys:policy_compliance:*:*:*:*:*:jenkins:*:*" + ], "quayio-trigger": [ "cpe:2.3:a:jenkins:quay.io_trigger:*:*:*:*:*:jenkins:*:*" ], @@ -7219,6 +7222,7 @@ "cpe:2.3:a:webtechstreet:elementor_addon_elements:*:*:*:*:*:wordpress:*:*" ], "addons-for-beaver-builder": [ + "cpe:2.3:a:livemesh:beaver_builder_addons:*:*:*:*:*:wordpress:*:*", "cpe:2.3:a:livemesh:livemesh_addons_for_beaver_builder:*:*:*:*:*:wordpress:*:*" ], "addons-for-elementor": [ @@ -8598,7 +8602,8 @@ "cpe:2.3:a:quantumcloud:ai_chatbot:*:*:*:*:*:wordpress:*:*" ], "chatbot-chatgpt": [ - "cpe:2.3:a:kognetics:kognetiks_chatbot:*:*:*:*:*:wordpress:*:*" + "cpe:2.3:a:kognetics:kognetiks_chatbot:*:*:*:*:*:wordpress:*:*", + "cpe:2.3:a:kognetiks:chatbot:*:*:*:*:*:wordpress:*:*" ], "chaty": [ "cpe:2.3:a:premio:chaty:*:*:*:*:*:wordpress:*:*", @@ -8690,6 +8695,9 @@ "clockwork-two-factor-authentication": [ "cpe:2.3:a:mediaburst:two-factor_authentication:*:*:*:*:*:wordpress:*:*" ], + "clone-menu": [ + "cpe:2.3:a:afzalmultani:wp_clone_menu:*:*:*:*:*:wordpress:*:*" + ], "cloudnet-sync": [ "cpe:2.3:a:cloudnet360:cloudnet360:*:*:*:*:*:wordpress:*:*" ], @@ -10099,6 +10107,9 @@ "enquiry-quotation-for-woocommerce": [ "cpe:2.3:a:piwebsolution:product_enquiry_for_woocommerce:*:*:*:*:*:wordpress:*:*" ], + "enteraddons": [ + "cpe:2.3:a:themelooks:enter_addons:*:*:*:*:*:wordpress:*:*" + ], "envato-elements": [ "cpe:2.3:a:envato:envato_elements:*:*:*:*:*:wordpress:*:*" ], @@ -10854,6 +10865,9 @@ "generatepress-premium": [ "cpe:2.3:a:generatepress:generatepress:*:*:*:*:premium:wordpress:*:*" ], + "genesis-blocks": [ + "cpe:2.3:a:wpengine:genesis_blocks:*:*:*:*:*:wordpress:*:*" + ], "genesis-columns-advanced": [ "cpe:2.3:a:genesis_columns_advanced_project:genesis_columns_advanced:*:*:*:*:*:wordpress:*:*" ], @@ -11601,6 +11615,7 @@ "cpe:2.3:a:insert_pages_project:insert_pages:*:*:*:*:*:wordpress:*:*" ], "insert-php": [ + "cpe:2.3:a:cm-wp:woody_ad_snippets:*:*:*:*:*:wordpress:*:*", "cpe:2.3:a:cm-wp:woody_code_snippets:*:*:*:*:*:wordpress:*:*", "cpe:2.3:a:webcraftic:woody_ad_snippets:*:*:*:*:*:wordpress:*:*" ], @@ -13244,6 +13259,9 @@ "page-list": [ "cpe:2.3:a:page-list_project:page-list:*:*:*:*:*:wordpress:*:*" ], + "page-or-post-clone": [ + "cpe:2.3:a:carlosfazenda:page_and_post_clone:*:*:*:*:*:wordpress:*:*" + ], "page-scroll-to-id": [ "cpe:2.3:a:page_scroll_to_id_project:page_scroll_to_id:*:*:*:*:*:wordpress:*:*" ], @@ -13317,6 +13335,9 @@ "paypal-donations": [ "cpe:2.3:a:tipsandtricks-hq:donations_via_paypal:*:*:*:*:*:wordpress:*:*" ], + "paypal-pay-buy-donation-and-cart-buttons-shortcode": [ + "cpe:2.3:a:mohsinrasool:paypal_pay_now\\,_buy_now\\,_donation_and_cart_buttons_shortcode:*:*:*:*:*:wordpress:*:*" + ], "paypal-payment-button-by-vcita": [ "cpe:2.3:a:vcita:online_payments_-_get_paid_with_paypal\\,_square_\\\u0026_stripe:*:*:*:*:*:wordpress:*:*" ], @@ -13719,6 +13740,9 @@ "postmatic": [ "cpe:2.3:a:gopostmatic:replyable:*:*:*:*:*:wordpress:*:*" ], + "posts-and-users-stats": [ + "cpe:2.3:a:patrick-robrecht:posts_and_user_stats:*:*:*:*:*:wordpress:*:*" + ], "posts-in-page": [ "cpe:2.3:a:ivycat:posts_in_page:*:*:*:*:*:wordpress:*:*" ], @@ -13921,6 +13945,9 @@ "pwa-for-wp": [ "cpe:2.3:a:magazine3:pwa_for_wp_\\\u0026_amp:*:*:*:*:*:wordpress:*:*" ], + "pz-frontend-manager": [ + "cpe:2.3:a:projectzealous:pz_frontend_manager:*:*:*:*:*:wordpress:*:*" + ], "pz-linkcard": [ "cpe:2.3:a:popozure:pz-linkcard:*:*:*:*:*:wordpress:*:*" ], @@ -14803,6 +14830,9 @@ "simple-cod-fee-for-woocommerce": [ "cpe:2.3:a:83pixel:simple_cod_fees_for_woocommerce:*:*:*:*:*:wordpress:*:*" ], + "simple-csv-xls-exporter": [ + "cpe:2.3:a:shambix:simple_csv\\/xls_exporter:*:*:*:*:*:wordpress:*:*" + ], "simple-custom-author-profiles": [ "cpe:2.3:a:usbmemorydirect:simple_custom_author_profiles:*:*:*:*:*:wordpress:*:*" ], @@ -15525,6 +15555,9 @@ "superb-social-share-and-follow-buttons": [ "cpe:2.3:a:superbthemes:superb_social_media_share_buttons_and_follow_buttons_for_wordpress:*:*:*:*:*:wordpress:*:*" ], + "supersaas-appointment-scheduling": [ + "cpe:2.3:a:supersaas:supersaas:*:*:*:*:*:wordpress:*:*" + ], "supportcandy": [ "cpe:2.3:a:supportcandy:supportcandy:*:*:*:*:*:wordpress:*:*" ], @@ -15984,6 +16017,9 @@ "typofr": [ "cpe:2.3:a:typofr_project:typofr:*:*:*:*:*:wordpress:*:*" ], + "ubermenu": [ + "cpe:2.3:a:sevenspark:ubermenu:*:*:*:*:*:wordpress:*:*" + ], "ucontext": [ "cpe:2.3:a:summitmediaconcepts:ucontext_for_clickbank:*:*:*:*:*:wordpress:*:*" ], @@ -17637,6 +17673,9 @@ "wp-links-page": [ "cpe:2.3:a:wplinkspage:wp_links_page:*:*:*:*:*:wordpress:*:*" ], + "wp-lister-for-amazon": [ + "cpe:2.3:a:wplab:wp-lister_lite_for_amazon:*:*:*:*:*:wordpress:*:*" + ], "wp-lister-for-ebay": [ "cpe:2.3:a:wplab:wp-lister_lite_for_ebay:*:*:*:*:*:wordpress:*:*" ], @@ -17746,6 +17785,9 @@ "wp-open-graph": [ "cpe:2.3:a:custom4web:wp_open_graph:*:*:*:*:*:wordpress:*:*" ], + "wp-open-street-map": [ + "cpe:2.3:a:info-d-74:open_street_map:*:*:*:*:*:wordpress:*:*" + ], "wp-opt-in": [ "cpe:2.3:a:wp_opt-in_project:wp_opt-in:*:*:*:*:*:wordpress:*:*" ], @@ -18325,6 +18367,9 @@ "wpematico": [ "cpe:2.3:a:etruel:wpematico_rss_feed_fetcher:*:*:*:*:*:wordpress:*:*" ], + "wpextended": [ + "cpe:2.3:a:wpextended:wp_extended:*:*:*:*:*:wordpress:*:*" + ], "wpforms": [ "cpe:2.3:a:wpforms:wpforms:*:*:*:*:pro:wordpress:*:*" ], From df1e5b57fe94b67312762262d4361b1b9b762813 Mon Sep 17 00:00:00 2001 From: Weston Steimel Date: Mon, 12 Aug 2024 17:01:44 +0000 Subject: [PATCH 066/122] fix: improve groupid extraction for Jenkins plugins (#2815) * fix: improve groupid extraction for Jenkins plugins Consider the `Group-Id` java manifest property as this is typically set for Jenkins plugins if there is no pom file Signed-off-by: Weston Steimel * test: update java purl integration test image Signed-off-by: Weston Steimel --------- Signed-off-by: Weston Steimel --- .../test/integration/java_purl_test.go | 965 ++++++++++++------ .../image-test-java-purls/Dockerfile | 4 +- .../cataloger/internal/cpegenerate/java.go | 1 + syft/pkg/cataloger/java/archive_parser.go | 5 + .../pkg/cataloger/java/archive_parser_test.go | 56 +- .../java/test-fixtures/jar-metadata/Makefile | 5 + .../gradle/2.11/META-INF/MANIFEST.MF | 13 + 7 files changed, 748 insertions(+), 301 deletions(-) create mode 100644 syft/pkg/cataloger/java/test-fixtures/jar-metadata/jenkins-plugins/gradle/2.11/META-INF/MANIFEST.MF diff --git a/cmd/syft/internal/test/integration/java_purl_test.go b/cmd/syft/internal/test/integration/java_purl_test.go index d6367522285..5dab545d686 100644 --- a/cmd/syft/internal/test/integration/java_purl_test.go +++ b/cmd/syft/internal/test/integration/java_purl_test.go @@ -41,105 +41,396 @@ func TestJavaPURLs(t *testing.T) { // generating the incorrect PURL var noAssertion = map[string]string{ // These are not known to exist on any public maven repo, so no real PURL should be asserted - "/packages/jruby-stdlib-9.1.15.0.jar:META-INF/jruby.home/lib/ruby/stdlib/jopenssl.jar": "pkg:maven/jopenssl/jopenssl", - "/packages/jruby-stdlib-9.1.15.0.jar:META-INF/jruby.home/lib/ruby/stdlib/json/ext/generator.jar": "pkg:maven/generator/generator", - "/packages/jruby-stdlib-9.1.15.0.jar:META-INF/jruby.home/lib/ruby/stdlib/json/ext/parser.jar": "pkg:maven/parser/parser", - "/packages/jruby-stdlib-9.1.15.0.jar:META-INF/jruby.home/lib/ruby/stdlib/psych.jar": "pkg:maven/psych/psych", - "/packages/jruby-stdlib-9.1.15.0.jar:META-INF/jruby.home/lib/ruby/stdlib/racc/cparse-jruby.jar": "pkg:maven/cparse-jruby/cparse-jruby", - "/packages/jruby-stdlib-9.1.15.0.jar:META-INF/jruby.home/lib/ruby/stdlib/readline.jar": "pkg:maven/readline/readline", - "/packages/org.eclipse.ant.core-3.7.0.jar:lib/antsupportlib.jar": "pkg:maven/antsupportlib/antsupportlib", - "/packages/TwilioNotifier.hpi:WEB-INF/lib/sdk-3.0.jar": "pkg:maven/sdk/sdk@3.0", + "/packages/atlassian-bitbucket-server-integration.hpi:WEB-INF/lib/trilead-ssh2-build-217-jenkins-27.jar": "pkg:maven/trilead-ssh2-build/trilead-ssh2-build@217-jenkins-27", + // possibly org.gradle as groupid for these, but unclear + "/packages/gradle-7.1.1/lib/gradle-api-metadata-7.1.1.jar": "pkg:maven/gradle-api-metadata/gradle-api-metadata@7.1.1", + "/packages/gradle-7.1.1/lib/gradle-base-annotations-7.1.1.jar": "pkg:maven/gradle-base-annotations/gradle-base-annotations@7.1.1", + "/packages/gradle-7.1.1/lib/gradle-base-services-7.1.1.jar": "pkg:maven/gradle-base-services/gradle-base-services@7.1.1", + "/packages/gradle-7.1.1/lib/gradle-base-services-groovy-7.1.1.jar": "pkg:maven/gradle-base-services-groovy/gradle-base-services-groovy@7.1.1", + "/packages/gradle-7.1.1/lib/gradle-bootstrap-7.1.1.jar": "pkg:maven/gradle-bootstrap/gradle-bootstrap@7.1.1", + "/packages/gradle-7.1.1/lib/gradle-build-cache-7.1.1.jar": "pkg:maven/gradle-build-cache/gradle-build-cache@7.1.1", + "/packages/gradle-7.1.1/lib/gradle-build-cache-base-7.1.1.jar": "pkg:maven/gradle-build-cache-base/gradle-build-cache-base@7.1.1", + "/packages/gradle-7.1.1/lib/gradle-build-cache-packaging-7.1.1.jar": "pkg:maven/gradle-build-cache-packaging/gradle-build-cache-packaging@7.1.1", + "/packages/gradle-7.1.1/lib/gradle-build-events-7.1.1.jar": "pkg:maven/gradle-build-events/gradle-build-events@7.1.1", + "/packages/gradle-7.1.1/lib/gradle-build-operations-7.1.1.jar": "pkg:maven/gradle-build-operations/gradle-build-operations@7.1.1", + "/packages/gradle-7.1.1/lib/gradle-build-option-7.1.1.jar": "pkg:maven/gradle-build-option/gradle-build-option@7.1.1", + "/packages/gradle-7.1.1/lib/gradle-cli-7.1.1.jar": "pkg:maven/gradle-cli/gradle-cli@7.1.1", + "/packages/gradle-7.1.1/lib/gradle-core-7.1.1.jar": "pkg:maven/gradle-core/gradle-core@7.1.1", + "/packages/gradle-7.1.1/lib/gradle-core-api-7.1.1.jar": "pkg:maven/gradle-core-api/gradle-core-api@7.1.1", + "/packages/gradle-7.1.1/lib/gradle-data-structures-7.1.1.jar": "pkg:maven/gradle-data-structures/gradle-data-structures@7.1.1", + "/packages/gradle-7.1.1/lib/gradle-execution-7.1.1.jar": "pkg:maven/gradle-execution/gradle-execution@7.1.1", + "/packages/gradle-7.1.1/lib/gradle-file-collections-7.1.1.jar": "pkg:maven/gradle-file-collections/gradle-file-collections@7.1.1", + "/packages/gradle-7.1.1/lib/gradle-file-temp-7.1.1.jar": "pkg:maven/gradle-file-temp/gradle-file-temp@7.1.1", + "/packages/gradle-7.1.1/lib/gradle-file-watching-7.1.1.jar": "pkg:maven/gradle-file-watching/gradle-file-watching@7.1.1", + "/packages/gradle-7.1.1/lib/gradle-files-7.1.1.jar": "pkg:maven/gradle-files/gradle-files@7.1.1", + "/packages/gradle-7.1.1/lib/gradle-hashing-7.1.1.jar": "pkg:maven/gradle-hashing/gradle-hashing@7.1.1", + "/packages/gradle-7.1.1/lib/gradle-installation-beacon-7.1.1.jar": "pkg:maven/gradle-installation-beacon/gradle-installation-beacon@7.1.1", + "/packages/gradle-7.1.1/lib/gradle-jvm-services-7.1.1.jar": "pkg:maven/gradle-jvm-services/gradle-jvm-services@7.1.1", + "/packages/gradle-7.1.1/lib/gradle-kotlin-dsl-7.1.1.jar": "pkg:maven/gradle-kotlin-dsl/gradle-kotlin-dsl@7.1.1", + "/packages/gradle-7.1.1/lib/gradle-kotlin-dsl-tooling-models-7.1.1.jar": "pkg:maven/gradle-kotlin-dsl-tooling-models/gradle-kotlin-dsl-tooling-models@7.1.1", + "/packages/gradle-7.1.1/lib/gradle-launcher-7.1.1.jar": "pkg:maven/org.gradle.launcher.GradleMain/gradle-launcher@7.1.1", + "/packages/gradle-7.1.1/lib/gradle-logging-7.1.1.jar": "pkg:maven/gradle-logging/gradle-logging@7.1.1", + "/packages/gradle-7.1.1/lib/gradle-messaging-7.1.1.jar": "pkg:maven/gradle-messaging/gradle-messaging@7.1.1", + "/packages/gradle-7.1.1/lib/gradle-model-core-7.1.1.jar": "pkg:maven/gradle-model-core/gradle-model-core@7.1.1", + "/packages/gradle-7.1.1/lib/gradle-model-groovy-7.1.1.jar": "pkg:maven/gradle-model-groovy/gradle-model-groovy@7.1.1", + "/packages/gradle-7.1.1/lib/gradle-native-7.1.1.jar": "pkg:maven/gradle-native/gradle-native@7.1.1", + "/packages/gradle-7.1.1/lib/gradle-normalization-java-7.1.1.jar": "pkg:maven/gradle-normalization-java/gradle-normalization-java@7.1.1", + "/packages/gradle-7.1.1/lib/gradle-persistent-cache-7.1.1.jar": "pkg:maven/gradle-persistent-cache/gradle-persistent-cache@7.1.1", + "/packages/gradle-7.1.1/lib/gradle-problems-7.1.1.jar": "pkg:maven/gradle-problems/gradle-problems@7.1.1", + "/packages/gradle-7.1.1/lib/gradle-process-services-7.1.1.jar": "pkg:maven/gradle-process-services/gradle-process-services@7.1.1", + "/packages/gradle-7.1.1/lib/gradle-resources-7.1.1.jar": "pkg:maven/gradle-resources/gradle-resources@7.1.1", + "/packages/gradle-7.1.1/lib/gradle-runtime-api-info-7.1.1.jar": "pkg:maven/gradle-runtime-api-info/gradle-runtime-api-info@7.1.1", + "/packages/gradle-7.1.1/lib/gradle-snapshots-7.1.1.jar": "pkg:maven/gradle-snapshots/gradle-snapshots@7.1.1", + "/packages/gradle-7.1.1/lib/gradle-tooling-api-7.1.1.jar": "pkg:maven/gradle-tooling-api/gradle-tooling-api@7.1.1", + "/packages/gradle-7.1.1/lib/gradle-worker-processes-7.1.1.jar": "pkg:maven/gradle-worker-processes/gradle-worker-processes@7.1.1", + "/packages/gradle-7.1.1/lib/gradle-wrapper-7.1.1.jar": "pkg:maven/gradle-wrapper/gradle-wrapper@7.1.1", + "/packages/gradle-7.1.1/lib/gradle-wrapper-7.1.1.jar:gradle-wrapper.jar": "pkg:maven/gradle-wrapper/gradle-wrapper", + "/packages/gradle-7.1.1/lib/plugins/gradle-antlr-7.1.1.jar": "pkg:maven/gradle-antlr/gradle-antlr@7.1.1", + "/packages/gradle-7.1.1/lib/plugins/gradle-build-cache-http-7.1.1.jar": "pkg:maven/gradle-build-cache-http/gradle-build-cache-http@7.1.1", + "/packages/gradle-7.1.1/lib/plugins/gradle-build-init-7.1.1.jar": "pkg:maven/gradle-build-init/gradle-build-init@7.1.1", + "/packages/gradle-7.1.1/lib/plugins/gradle-build-profile-7.1.1.jar": "pkg:maven/gradle-build-profile/gradle-build-profile@7.1.1", + "/packages/gradle-7.1.1/lib/plugins/gradle-code-quality-7.1.1.jar": "pkg:maven/gradle-code-quality/gradle-code-quality@7.1.1", + "/packages/gradle-7.1.1/lib/plugins/gradle-composite-builds-7.1.1.jar": "pkg:maven/gradle-composite-builds/gradle-composite-builds@7.1.1", + "/packages/gradle-7.1.1/lib/plugins/gradle-configuration-cache-7.1.1.jar": "pkg:maven/gradle-configuration-cache/gradle-configuration-cache@7.1.1", + "/packages/gradle-7.1.1/lib/plugins/gradle-dependency-management-7.1.1.jar": "pkg:maven/gradle-dependency-management/gradle-dependency-management@7.1.1", + "/packages/gradle-7.1.1/lib/plugins/gradle-diagnostics-7.1.1.jar": "pkg:maven/gradle-diagnostics/gradle-diagnostics@7.1.1", + "/packages/gradle-7.1.1/lib/plugins/gradle-ear-7.1.1.jar": "pkg:maven/gradle-ear/gradle-ear@7.1.1", + "/packages/gradle-7.1.1/lib/plugins/gradle-enterprise-7.1.1.jar": "pkg:maven/gradle-enterprise/gradle-enterprise@7.1.1", + "/packages/gradle-7.1.1/lib/plugins/gradle-ide-7.1.1.jar": "pkg:maven/gradle-ide/gradle-ide@7.1.1", + "/packages/gradle-7.1.1/lib/plugins/gradle-ide-native-7.1.1.jar": "pkg:maven/gradle-ide-native/gradle-ide-native@7.1.1", + "/packages/gradle-7.1.1/lib/plugins/gradle-ivy-7.1.1.jar": "pkg:maven/gradle-ivy/gradle-ivy@7.1.1", + "/packages/gradle-7.1.1/lib/plugins/gradle-jacoco-7.1.1.jar": "pkg:maven/gradle-jacoco/gradle-jacoco@7.1.1", + "/packages/gradle-7.1.1/lib/plugins/gradle-java-compiler-plugin-7.1.1.jar": "pkg:maven/gradle-java-compiler-plugin/gradle-java-compiler-plugin@7.1.1", + "/packages/gradle-7.1.1/lib/plugins/gradle-kotlin-dsl-provider-plugins-7.1.1.jar": "pkg:maven/gradle-kotlin-dsl-provider-plugins/gradle-kotlin-dsl-provider-plugins@7.1.1", + "/packages/gradle-7.1.1/lib/plugins/gradle-kotlin-dsl-tooling-builders-7.1.1.jar": "pkg:maven/gradle-kotlin-dsl-tooling-builders/gradle-kotlin-dsl-tooling-builders@7.1.1", + "/packages/gradle-7.1.1/lib/plugins/gradle-language-groovy-7.1.1.jar": "pkg:maven/gradle-language-groovy/gradle-language-groovy@7.1.1", + "/packages/gradle-7.1.1/lib/plugins/gradle-language-java-7.1.1.jar": "pkg:maven/gradle-language-java/gradle-language-java@7.1.1", + "/packages/gradle-7.1.1/lib/plugins/gradle-language-jvm-7.1.1.jar": "pkg:maven/gradle-language-jvm/gradle-language-jvm@7.1.1", + "/packages/gradle-7.1.1/lib/plugins/gradle-language-native-7.1.1.jar": "pkg:maven/gradle-language-native/gradle-language-native@7.1.1", + "/packages/gradle-7.1.1/lib/plugins/gradle-maven-7.1.1.jar": "pkg:maven/gradle-maven/gradle-maven@7.1.1", + "/packages/gradle-7.1.1/lib/plugins/gradle-platform-base-7.1.1.jar": "pkg:maven/gradle-platform-base/gradle-platform-base@7.1.1", + "/packages/gradle-7.1.1/lib/plugins/gradle-platform-jvm-7.1.1.jar": "pkg:maven/gradle-platform-jvm/gradle-platform-jvm@7.1.1", + "/packages/gradle-7.1.1/lib/plugins/gradle-platform-native-7.1.1.jar": "pkg:maven/gradle-platform-native/gradle-platform-native@7.1.1", + "/packages/gradle-7.1.1/lib/plugins/gradle-plugin-development-7.1.1.jar": "pkg:maven/gradle-plugin-development/gradle-plugin-development@7.1.1", + "/packages/gradle-7.1.1/lib/plugins/gradle-plugin-use-7.1.1.jar": "pkg:maven/gradle-plugin-use/gradle-plugin-use@7.1.1", + "/packages/gradle-7.1.1/lib/plugins/gradle-plugins-7.1.1.jar": "pkg:maven/gradle-plugins/gradle-plugins@7.1.1", + "/packages/gradle-7.1.1/lib/plugins/gradle-publish-7.1.1.jar": "pkg:maven/gradle-publish/gradle-publish@7.1.1", + "/packages/gradle-7.1.1/lib/plugins/gradle-reporting-7.1.1.jar": "pkg:maven/gradle-reporting/gradle-reporting@7.1.1", + "/packages/gradle-7.1.1/lib/plugins/gradle-resources-gcs-7.1.1.jar": "pkg:maven/gradle-resources-gcs/gradle-resources-gcs@7.1.1", + "/packages/gradle-7.1.1/lib/plugins/gradle-resources-http-7.1.1.jar": "pkg:maven/gradle-resources-http/gradle-resources-http@7.1.1", + "/packages/gradle-7.1.1/lib/plugins/gradle-resources-s3-7.1.1.jar": "pkg:maven/gradle-resources-s3/gradle-resources-s3@7.1.1", + "/packages/gradle-7.1.1/lib/plugins/gradle-resources-sftp-7.1.1.jar": "pkg:maven/gradle-resources-sftp/gradle-resources-sftp@7.1.1", + "/packages/gradle-7.1.1/lib/plugins/gradle-scala-7.1.1.jar": "pkg:maven/gradle-scala/gradle-scala@7.1.1", + "/packages/gradle-7.1.1/lib/plugins/gradle-security-7.1.1.jar": "pkg:maven/gradle-security/gradle-security@7.1.1", + "/packages/gradle-7.1.1/lib/plugins/gradle-signing-7.1.1.jar": "pkg:maven/gradle-signing/gradle-signing@7.1.1", + "/packages/gradle-7.1.1/lib/plugins/gradle-test-kit-7.1.1.jar": "pkg:maven/gradle-test-kit/gradle-test-kit@7.1.1", + "/packages/gradle-7.1.1/lib/plugins/gradle-testing-base-7.1.1.jar": "pkg:maven/gradle-testing-base/gradle-testing-base@7.1.1", + "/packages/gradle-7.1.1/lib/plugins/gradle-testing-junit-platform-7.1.1.jar": "pkg:maven/gradle-testing-junit-platform/gradle-testing-junit-platform@7.1.1", + "/packages/gradle-7.1.1/lib/plugins/gradle-testing-jvm-7.1.1.jar": "pkg:maven/gradle-testing-jvm/gradle-testing-jvm@7.1.1", + "/packages/gradle-7.1.1/lib/plugins/gradle-testing-native-7.1.1.jar": "pkg:maven/gradle-testing-native/gradle-testing-native@7.1.1", + "/packages/gradle-7.1.1/lib/plugins/gradle-tooling-api-builders-7.1.1.jar": "pkg:maven/gradle-tooling-api-builders/gradle-tooling-api-builders@7.1.1", + "/packages/gradle-7.1.1/lib/plugins/gradle-tooling-native-7.1.1.jar": "pkg:maven/gradle-tooling-native/gradle-tooling-native@7.1.1", + "/packages/gradle-7.1.1/lib/plugins/gradle-version-control-7.1.1.jar": "pkg:maven/gradle-version-control/gradle-version-control@7.1.1", + "/packages/gradle-7.1.1/lib/plugins/gradle-workers-7.1.1.jar": "pkg:maven/gradle-workers/gradle-workers@7.1.1", + "/packages/jruby-stdlib-9.1.15.0.jar:META-INF/jruby.home/lib/ruby/stdlib/jopenssl.jar": "pkg:maven/jopenssl/jopenssl", + "/packages/jruby-stdlib-9.1.15.0.jar:META-INF/jruby.home/lib/ruby/stdlib/jopenssl.jar:rubygems:jruby-openssl": "pkg:maven/rubygems/jruby-openssl@0.9.21", + "/packages/jruby-stdlib-9.1.15.0.jar:META-INF/jruby.home/lib/ruby/stdlib/json/ext/parser.jar": "pkg:maven/parser/parser", + "/packages/jruby-stdlib-9.1.15.0.jar:META-INF/jruby.home/lib/ruby/stdlib/json/ext/generator.jar": "pkg:maven/generator/generator", + "/packages/jruby-stdlib-9.1.15.0.jar:META-INF/jruby.home/lib/ruby/stdlib/psych.jar": "pkg:maven/psych/psych", + "/packages/jruby-stdlib-9.1.15.0.jar:META-INF/jruby.home/lib/ruby/stdlib/racc/cparse-jruby.jar": "pkg:maven/cparse-jruby/cparse-jruby", + "/packages/jruby-stdlib-9.1.15.0.jar:META-INF/jruby.home/lib/ruby/stdlib/readline.jar": "pkg:maven/readline/readline", + "/packages/org.eclipse.ant.core-3.7.0.jar:lib/antsupportlib.jar": "pkg:maven/antsupportlib/antsupportlib", + "/packages/TwilioNotifier.hpi:WEB-INF/lib/sdk-3.0.jar": "pkg:maven/sdk/sdk@3.0", // syft generates incorrect purls - "/packages/hudson.war:WEB-INF/lib/asm-2.2.3.jar": "pkg:maven/asm/asm@2.2.3", - "/packages/hudson.war:WEB-INF/lib/asm-commons-2.2.3.jar": "pkg:maven/asm/asm-commons@2.2.3", - "/packages/hudson.war:WEB-INF/lib/asm-tree-2.2.3.jar": "pkg:maven/asm/asm-tree@2.2.3", - "/packages/hudson.war:WEB-INF/slave.jar": "pkg:maven/org.jvnet.hudson.main/remoting@1.390", - "/packages/hudson.war:WEB-INF/lib/xpp3_min-1.1.4c.jar": "pkg:maven/xpp3_min/xpp3_min@1.1.4c", - "/packages/hudson.war:WEB-INF/lib/xpp3-1.1.4c.jar": "pkg:maven/xpp3/xpp3@1.1.4c", - "/packages/hudson.war:WEB-INF/hudson-cli.jar": "pkg:maven/org.jvnet.hudson.main/hudson-cli@1.390", - "/packages/hudson.war:WEB-INF/lib/dom4j-1.6.1-hudson-3.jar": "pkg:maven/org.jvnet.hudson.dom4j/dom4j@1.6.1-hudson-3", - "/packages/xpp3_min-1.1.4c.jar": "pkg:maven/xpp3/xpp3_min@1.1.4c", + "/packages/atlassian-bitbucket-server-integration.hpi:WEB-INF/lib/jbcrypt-1.0.0.jar": "pkg:maven/org.connectbot/jbcrypt@1.0.0", + "/packages/atlassian-bitbucket-server-integration.hpi:WEB-INF/lib/tink-1.5.0.jar": "pkg:maven/com.google.crypto.tink/tink@1.5.0", + "/packages/gradle-7.1.1/lib/fastutil-8.5.2-min.jar": "pkg:maven/it.unimi.dsi/fastutil@8.5.2-min", + "/packages/gradle-7.1.1/lib/file-events-0.22-milestone-16.jar": "pkg:maven/net.rubygrapefruit/file-events@0.22-milestone-16", + "/packages/gradle-7.1.1/lib/file-events-linux-aarch64-0.22-milestone-16.jar": "pkg:maven/net.rubygrapefruit/file-events-linux-aarch64@0.22-milestone-16", + "/packages/gradle-7.1.1/lib/file-events-linux-amd64-0.22-milestone-16.jar": "pkg:maven/net.rubygrapefruit/file-events-linux-amd64@0.22-milestone-16", + "/packages/gradle-7.1.1/lib/file-events-osx-aarch64-0.22-milestone-16.jar": "pkg:maven/net.rubygrapefruit/file-events-osx-aarch64@0.22-milestone-16", + "/packages/gradle-7.1.1/lib/file-events-osx-amd64-0.22-milestone-16.jar": "pkg:maven/net.rubygrapefruit/file-events-osx-amd64@0.22-milestone-16", + "/packages/gradle-7.1.1/lib/file-events-windows-amd64-0.22-milestone-16.jar": "pkg:maven/net.rubygrapefruit/file-events-windows-amd64@0.22-milestone-16", + "/packages/gradle-7.1.1/lib/file-events-windows-amd64-min-0.22-milestone-16.jar": "pkg:maven/net.rubygrapefruit/file-events-windows-amd64-min@0.22-milestone-16", + "/packages/gradle-7.1.1/lib/file-events-windows-i386-0.22-milestone-16.jar": "pkg:maven/net.rubygrapefruit/file-events-windows-i386@0.22-milestone-16", + "/packages/gradle-7.1.1/lib/file-events-windows-i386-min-0.22-milestone-16.jar": "pkg:maven/net.rubygrapefruit/file-events-windows-i386-min@0.22-milestone-16", + "/packages/gradle-7.1.1/lib/hamcrest-core-1.3.jar": "pkg:maven/org.hamcrest/hamcrest-core@1.3", + "/packages/gradle-7.1.1/lib/kotlin-compiler-embeddable-1.4.31-patched-for-gradle-7.1.1.jar": "pkg:maven/org.jetbrains.kotlin/kotlin-compiler-embeddable@1.4.31-patched-for-gradle-7.1.1", + "/packages/gradle-7.1.1/lib/kotlin-daemon-embeddable-1.4.31.jar": "pkg:maven/org.jetbrains.kotlin/kotlin-daemon-embeddable@1.4.31", + "/packages/gradle-7.1.1/lib/kotlin-reflect-1.4.31.jar": "pkg:maven/org.jetbrains.kotlin/kotlin-reflect@1.4.31", + "/packages/gradle-7.1.1/lib/kotlin-sam-with-receiver-compiler-plugin-1.4.31.jar": "pkg:maven/org.jetbrains.kotlin/kotlin-sam-with-receiver-compiler-plugin@1.4.31", + "/packages/gradle-7.1.1/lib/kotlin-script-runtime-1.4.31.jar": "pkg:maven/org.jetbrains.kotlin/kotlin-script-runtime@1.4.31", + "/packages/gradle-7.1.1/lib/kotlin-scripting-common-1.4.31.jar": "pkg:maven/org.jetbrains.kotlin/kotlin-scripting-common@1.4.31", + "/packages/gradle-7.1.1/lib/kotlin-scripting-compiler-embeddable-1.4.31.jar": "pkg:maven/org.jetbrains.kotlin/kotlin-scripting-compiler-embeddable@1.4.31", + "/packages/gradle-7.1.1/lib/kotlin-scripting-compiler-impl-embeddable-1.4.31.jar": "pkg:maven/org.jetbrains.kotlin/kotlin-scripting-compiler-impl-embeddable@1.4.31", + "/packages/gradle-7.1.1/lib/kotlin-scripting-jvm-1.4.31.jar": "pkg:maven/org.jetbrains.kotlin/kotlin-scripting-jvm@1.4.31", + "/packages/gradle-7.1.1/lib/kotlin-scripting-jvm-host-1.4.31.jar": "pkg:maven/org.jetbrains.kotlin/kotlin-scripting-jvm-host@1.4.31", + "/packages/gradle-7.1.1/lib/kotlin-stdlib-1.4.31.jar": "pkg:maven/org.jetbrains.kotlin/kotlin-stdlib@1.4.31", + "/packages/gradle-7.1.1/lib/kotlin-stdlib-common-1.4.31.jar": "pkg:maven/org.jetbrains.kotlin/kotlin-stdlib-common@1.4.31", + "/packages/gradle-7.1.1/lib/kotlin-stdlib-jdk7-1.4.31.jar": "pkg:maven/org.jetbrains.kotlin/kotlin-stdlib-jdk7@1.4.31", + "/packages/gradle-7.1.1/lib/kotlin-stdlib-jdk8-1.4.31.jar": "pkg:maven/org.jetbrains.kotlin/kotlin-stdlib-jdk8@1.4.31", + "/packages/gradle-7.1.1/lib/kotlinx-metadata-jvm-0.2.0.jar": "pkg:maven/org.jetbrains.kotlinx/kotlinx-metadata-jvm@0.2.0", + "/packages/gradle-7.1.1/lib/native-platform-0.22-milestone-16.jar": "pkg:maven/net.rubygrapefruit/native-platform@0.22-milestone-16", + "/packages/gradle-7.1.1/lib/native-platform-freebsd-amd64-libcpp-0.22-milestone-16.jar": "pkg:maven/net.rubygrapefruit/native-platform-freebsd-amd64-libcpp@0.22-milestone-16", + "/packages/gradle-7.1.1/lib/native-platform-linux-aarch64-0.22-milestone-16.jar": "pkg:maven/net.rubygrapefruit/native-platform-linux-aarch64@0.22-milestone-16", + "/packages/gradle-7.1.1/lib/native-platform-linux-aarch64-ncurses5-0.22-milestone-16.jar": "pkg:maven/net.rubygrapefruit/native-platform-linux-aarch64-ncurses5@0.22-milestone-16", + "/packages/gradle-7.1.1/lib/native-platform-linux-aarch64-ncurses6-0.22-milestone-16.jar": "pkg:maven/net.rubygrapefruit/native-platform-linux-aarch64-ncurses6@0.22-milestone-16", + "/packages/gradle-7.1.1/lib/native-platform-linux-amd64-0.22-milestone-16.jar": "pkg:maven/net.rubygrapefruit/native-platform-linux-amd64@0.22-milestone-16", + "/packages/gradle-7.1.1/lib/native-platform-linux-amd64-ncurses5-0.22-milestone-16.jar": "pkg:maven/net.rubygrapefruit/native-platform-linux-amd64-ncurses5@0.22-milestone-16", + "/packages/gradle-7.1.1/lib/native-platform-linux-amd64-ncurses6-0.22-milestone-16.jar": "pkg:maven/net.rubygrapefruit/native-platform-linux-amd64-ncurses6@0.22-milestone-16", + "/packages/gradle-7.1.1/lib/native-platform-osx-aarch64-0.22-milestone-16.jar": "pkg:maven/net.rubygrapefruit/native-platform-osx-aarch64@0.22-milestone-16", + "/packages/gradle-7.1.1/lib/native-platform-osx-amd64-0.22-milestone-16.jar": "pkg:maven/net.rubygrapefruit/native-platform-osx-amd64@0.22-milestone-16", + "/packages/gradle-7.1.1/lib/native-platform-windows-amd64-0.22-milestone-16.jar": "pkg:maven/net.rubygrapefruit/native-platform-windows-amd64@0.22-milestone-16", + "/packages/gradle-7.1.1/lib/native-platform-windows-amd64-min-0.22-milestone-16.jar": "pkg:maven/net.rubygrapefruit/native-platform-windows-amd64-min@0.22-milestone-16", + "/packages/gradle-7.1.1/lib/native-platform-windows-i386-0.22-milestone-16.jar": "pkg:maven/net.rubygrapefruit/native-platform-windows-i386@0.22-milestone-16", + "/packages/gradle-7.1.1/lib/native-platform-windows-i386-min-0.22-milestone-16.jar": "pkg:maven/net.rubygrapefruit/native-platform-windows-i386-min@0.22-milestone-16", + "/packages/gradle-7.1.1/lib/plugins/apiguardian-api-1.1.0.jar": "pkg:maven/org.apiguardian/apiguardian-api@1.1.0", + "/packages/gradle-7.1.1/lib/plugins/bsh-2.0b6.jar": "pkg:maven/org.apache-extras.beanshell/bsh@2.0b6", + "/packages/gradle-7.1.1/lib/plugins/google-api-client-1.25.0.jar": "pkg:maven/com.google.api-client/google-api-client@1.25.0", + "/packages/gradle-7.1.1/lib/plugins/google-api-services-storage-v1-rev171-1.25.0.jar": "pkg:maven/com.google.apis/google-api-services-storage@v1-rev171-1.25.0", + "/packages/gradle-7.1.1/lib/plugins/jcommander-1.78.jar": "pkg:maven/com.beust/jcommander@1.78", + "/packages/gradle-7.1.1/lib/plugins/junit-platform-commons-1.7.2.jar": "pkg:maven/org.junit.platform/junit-platform-commons@1.7.2", + "/packages/gradle-7.1.1/lib/plugins/junit-platform-engine-1.7.2.jar": "pkg:maven/org.junit.platform/junit-platform-engine@1.7.2", + "/packages/gradle-7.1.1/lib/plugins/junit-platform-launcher-1.7.2.jar": "pkg:maven/org.junit.platform/junit-platform-launcher@1.7.2", + "/packages/gradle-7.1.1/lib/plugins/nekohtml-1.9.22.jar": "pkg:maven/net.sourceforge.nekohtml/nekohtml@1.9.22", + "/packages/gradle-7.1.1/lib/tomlj-1.0.0.jar": "pkg:maven/org.tomlj/tomlj@1.0.0", + "/packages/gradle-7.1.1/lib/trove4j-1.0.20181211.jar": "pkg:maven/net.sf.trove4j /trove4j@1.0.20181211", + "/packages/gradle-7.1.1/lib/xml-apis-1.4.01.jar": "pkg:maven/xml-apis/xml-apis@1.4.01", + "/packages/gradle-7.1.1/lib/asm-analysis-9.1.jar": "pkg:maven/org.ow2.asm/asm-analysis@9.1", + "/packages/gradle-7.1.1/lib/asm-commons-9.1.jar": "pkg:maven/org.ow2.asm/asm-commons@9.1", + "/packages/gradle-7.1.1/lib/asm-tree-9.1.jar": "pkg:maven/org.ow2.asm/asm-tree@9.1", + "/packages/gradle-7.1.1/lib/plugins/ivy-2.3.0.jar": "pkg:maven/org.apache.ivy/ivy@2.3.0", + "/packages/hudson.war:WEB-INF/lib/asm-2.2.3.jar": "pkg:maven/asm/asm@2.2.3", + "/packages/hudson.war:WEB-INF/lib/asm-commons-2.2.3.jar": "pkg:maven/asm/asm-commons@2.2.3", + "/packages/hudson.war:WEB-INF/lib/asm-tree-2.2.3.jar": "pkg:maven/asm/asm-tree@2.2.3", + "/packages/hudson.war:WEB-INF/slave.jar": "pkg:maven/org.jvnet.hudson.main/remoting@1.390", + "/packages/hudson.war:WEB-INF/lib/xpp3_min-1.1.4c.jar": "pkg:maven/xpp3_min/xpp3_min@1.1.4c", + "/packages/hudson.war:WEB-INF/lib/xpp3-1.1.4c.jar": "pkg:maven/xpp3/xpp3@1.1.4c", + "/packages/hudson.war:WEB-INF/hudson-cli.jar": "pkg:maven/org.jvnet.hudson.main/hudson-cli@1.390", + "/packages/hudson.war:WEB-INF/lib/dom4j-1.6.1-hudson-3.jar": "pkg:maven/org.jvnet.hudson.dom4j/dom4j@1.6.1-hudson-3", + "/packages/newrelic-agent-8.8.0.jar": "pkg:maven/com.newrelic.bootstrap.BootstrapAgent/newrelic-agent@8.8.0", + "/packages/newrelic-agent-8.8.0.jar:agent-bridge-datastore.jar": "pkg:maven/agent-bridge-datastore/agent-bridge-datastore@8.8.0", + "/packages/newrelic-agent-8.8.0.jar:agent-bridge.jar": "pkg:maven/agent-bridge/agent-bridge@8.8.0", + "/packages/newrelic-agent-8.8.0.jar:newrelic-api.jar": "pkg:maven/newrelic-api/newrelic-api@8.8.0", + "/packages/newrelic-agent-8.8.0.jar:newrelic-security-agent.jar": "pkg:maven/newrelic-security-agent/newrelic-security-agent@1.0.7-public-preview", + "/packages/newrelic-agent-8.8.0.jar:newrelic-security-api.jar": "pkg:maven/newrelic-security-api/newrelic-security-api@1.0.7-public-preview", + "/packages/newrelic-agent-8.8.0.jar:newrelic-weaver-api.jar": "pkg:maven/newrelic-weaver-api/newrelic-weaver-api@8.8.0", + "/packages/newrelic-agent-8.8.0.jar:newrelic-weaver-scala-api.jar": "pkg:maven/newrelic-weaver-scala-api/newrelic-weaver-scala-api@8.8.0", + "/packages/maven-plugin.hpi:WEB-INF/lib/jsr250-api-1.0.jar": "pkg:maven/javax.annotation/jsr250-api@1.0", + "/packages/TwilioNotifier.hpi:WEB-INF/lib/commons-httpclient-3.1.jar": "pkg:maven/commons-httpclient/commons-httpclient@3.1", + "/packages/xpp3_min-1.1.4c.jar": "pkg:maven/xpp3/xpp3_min@1.1.4c", + + // Unclear: groupid might be org.glassfish.jaxb or com.sun.xml.bind + "/packages/gradle-7.1.1/lib/plugins/jaxb-core-3.0.0.jar": "pkg:maven/org.glassfish.jaxb/jaxb-core@3.0.0", } // Constructed by: // syft anchore/test_images:java-1abc58f -o json | jq -r '.artifacts.[] | [.metadata.virtualPath, .purl, ""] | @csv' | grep 'pkg:maven' | sort | uniq >> /tmp/java_artifacts_mapping.txt // The map was then hand-edited for correctness by comparing to Maven Central. var expectedPURLs = map[string]string{ - "/packages/activemq-client-5.18.2.jar": "pkg:maven/org.apache.activemq/activemq-client@5.18.2", - "/packages/activemq-protobuf-1.1.jar": "pkg:maven/org.apache.activemq.protobuf/activemq-protobuf@1.1", - "/packages/akka-actor_2.13-2.6.6.jar": "pkg:maven/com.typesafe.akka/akka-actor_2.13@2.6.6", - "/packages/akka-management-cluster-bootstrap_2.13-1.2.0.jar": "pkg:maven/com.lightbend.akka.management/akka-management-cluster-bootstrap_2.13@1.2.0", - "/packages/ant-1.10.3.jar": "pkg:maven/org.apache.ant/ant@1.10.3", - "/packages/apache-chainsaw-2.1.0.jar": "pkg:maven/log4j/apache-chainsaw@2.1.0", - "/packages/apache-log4j-extras-1.1.jar": "pkg:maven/log4j/apache-log4j-extras@1.1", - "/packages/apoc-4.4.0.11.jar": "pkg:maven/org.neo4j.procedure/apoc@4.4.0.11", - "/packages/bc-fips-1.0.2.3.jar": "pkg:maven/org.bouncycastle/bc-fips@1.0.2.3", - "/packages/camel-core-3.1.0.jar": "pkg:maven/org.apache.camel/camel-core@3.1.0", - "/packages/cassandra-all-4.1.1.jar": "pkg:maven/org.apache.cassandra/cassandra-all@4.1.1", - "/packages/commons-logging-1.1.1.jar": "pkg:maven/commons-logging/commons-logging@1.1.1", - "/packages/commons-vfs-1.0.jar": "pkg:maven/commons-vfs/commons-vfs@1.0", - "/packages/cxf-rt-transports-http-2.7.3.jar": "pkg:maven/org.apache.cxf/cxf-rt-transports-http@2.7.3", - "/packages/dubbo-3.1.4.jar:com.alibaba:hessian-lite": "pkg:maven/com.alibaba/hessian-lite@3.2.13", - "/packages/dubbo-3.1.4.jar:org.apache.dubbo:dubbo-auth": "pkg:maven/org.apache.dubbo/dubbo-auth@3.1.4", - "/packages/dubbo-3.1.4.jar:org.apache.dubbo:dubbo-cluster": "pkg:maven/org.apache.dubbo/dubbo-cluster@3.1.4", - "/packages/dubbo-3.1.4.jar:org.apache.dubbo:dubbo-common": "pkg:maven/org.apache.dubbo/dubbo-common@3.1.4", - "/packages/dubbo-3.1.4.jar:org.apache.dubbo:dubbo-compatible": "pkg:maven/org.apache.dubbo/dubbo-compatible@3.1.4", - "/packages/dubbo-3.1.4.jar:org.apache.dubbo:dubbo-config-api": "pkg:maven/org.apache.dubbo/dubbo-config-api@3.1.4", - "/packages/dubbo-3.1.4.jar:org.apache.dubbo:dubbo-config-spring": "pkg:maven/org.apache.dubbo/dubbo-config-spring@3.1.4", - "/packages/dubbo-3.1.4.jar:org.apache.dubbo:dubbo-configcenter-apollo": "pkg:maven/org.apache.dubbo/dubbo-configcenter-apollo@3.1.4", - "/packages/dubbo-3.1.4.jar:org.apache.dubbo:dubbo-configcenter-nacos": "pkg:maven/org.apache.dubbo/dubbo-configcenter-nacos@3.1.4", - "/packages/dubbo-3.1.4.jar:org.apache.dubbo:dubbo-configcenter-zookeeper": "pkg:maven/org.apache.dubbo/dubbo-configcenter-zookeeper@3.1.4", - "/packages/dubbo-3.1.4.jar:org.apache.dubbo:dubbo-container-api": "pkg:maven/org.apache.dubbo/dubbo-container-api@3.1.4", - "/packages/dubbo-3.1.4.jar:org.apache.dubbo:dubbo-container-spring": "pkg:maven/org.apache.dubbo/dubbo-container-spring@3.1.4", - "/packages/dubbo-3.1.4.jar:org.apache.dubbo:dubbo-filter-cache": "pkg:maven/org.apache.dubbo/dubbo-filter-cache@3.1.4", - "/packages/dubbo-3.1.4.jar:org.apache.dubbo:dubbo-filter-validation": "pkg:maven/org.apache.dubbo/dubbo-filter-validation@3.1.4", - "/packages/dubbo-3.1.4.jar:org.apache.dubbo:dubbo-kubernetes": "pkg:maven/org.apache.dubbo/dubbo-kubernetes@3.1.4", - "/packages/dubbo-3.1.4.jar:org.apache.dubbo:dubbo-metadata-api": "pkg:maven/org.apache.dubbo/dubbo-metadata-api@3.1.4", - "/packages/dubbo-3.1.4.jar:org.apache.dubbo:dubbo-metadata-definition-protobuf": "pkg:maven/org.apache.dubbo/dubbo-metadata-definition-protobuf@3.1.4", - "/packages/dubbo-3.1.4.jar:org.apache.dubbo:dubbo-metadata-report-nacos": "pkg:maven/org.apache.dubbo/dubbo-metadata-report-nacos@3.1.4", - "/packages/dubbo-3.1.4.jar:org.apache.dubbo:dubbo-metadata-report-redis": "pkg:maven/org.apache.dubbo/dubbo-metadata-report-redis@3.1.4", - "/packages/dubbo-3.1.4.jar:org.apache.dubbo:dubbo-metadata-report-zookeeper": "pkg:maven/org.apache.dubbo/dubbo-metadata-report-zookeeper@3.1.4", - "/packages/dubbo-3.1.4.jar:org.apache.dubbo:dubbo-metrics-api": "pkg:maven/org.apache.dubbo/dubbo-metrics-api@3.1.4", - "/packages/dubbo-3.1.4.jar:org.apache.dubbo:dubbo-metrics-prometheus": "pkg:maven/org.apache.dubbo/dubbo-metrics-prometheus@3.1.4", - "/packages/dubbo-3.1.4.jar:org.apache.dubbo:dubbo-monitor-api": "pkg:maven/org.apache.dubbo/dubbo-monitor-api@3.1.4", - "/packages/dubbo-3.1.4.jar:org.apache.dubbo:dubbo-monitor-default": "pkg:maven/org.apache.dubbo/dubbo-monitor-default@3.1.4", - "/packages/dubbo-3.1.4.jar:org.apache.dubbo:dubbo-qos": "pkg:maven/org.apache.dubbo/dubbo-qos@3.1.4", - "/packages/dubbo-3.1.4.jar:org.apache.dubbo:dubbo-reactive": "pkg:maven/org.apache.dubbo/dubbo-reactive@3.1.4", - "/packages/dubbo-3.1.4.jar:org.apache.dubbo:dubbo-registry-api": "pkg:maven/org.apache.dubbo/dubbo-registry-api@3.1.4", - "/packages/dubbo-3.1.4.jar:org.apache.dubbo:dubbo-registry-multicast": "pkg:maven/org.apache.dubbo/dubbo-registry-multicast@3.1.4", - "/packages/dubbo-3.1.4.jar:org.apache.dubbo:dubbo-registry-multiple": "pkg:maven/org.apache.dubbo/dubbo-registry-multiple@3.1.4", - "/packages/dubbo-3.1.4.jar:org.apache.dubbo:dubbo-registry-nacos": "pkg:maven/org.apache.dubbo/dubbo-registry-nacos@3.1.4", - "/packages/dubbo-3.1.4.jar:org.apache.dubbo:dubbo-registry-zookeeper": "pkg:maven/org.apache.dubbo/dubbo-registry-zookeeper@3.1.4", - "/packages/dubbo-3.1.4.jar:org.apache.dubbo:dubbo-remoting-api": "pkg:maven/org.apache.dubbo/dubbo-remoting-api@3.1.4", - "/packages/dubbo-3.1.4.jar:org.apache.dubbo:dubbo-remoting-http": "pkg:maven/org.apache.dubbo/dubbo-remoting-http@3.1.4", - "/packages/dubbo-3.1.4.jar:org.apache.dubbo:dubbo-remoting-netty": "pkg:maven/org.apache.dubbo/dubbo-remoting-netty@3.1.4", - "/packages/dubbo-3.1.4.jar:org.apache.dubbo:dubbo-remoting-netty4": "pkg:maven/org.apache.dubbo/dubbo-remoting-netty4@3.1.4", - "/packages/dubbo-3.1.4.jar:org.apache.dubbo:dubbo-remoting-zookeeper": "pkg:maven/org.apache.dubbo/dubbo-remoting-zookeeper@3.1.4", - "/packages/dubbo-3.1.4.jar:org.apache.dubbo:dubbo-remoting-zookeeper-curator5": "pkg:maven/org.apache.dubbo/dubbo-remoting-zookeeper-curator5@3.1.4", - "/packages/dubbo-3.1.4.jar:org.apache.dubbo:dubbo-rpc-api": "pkg:maven/org.apache.dubbo/dubbo-rpc-api@3.1.4", - "/packages/dubbo-3.1.4.jar:org.apache.dubbo:dubbo-rpc-dubbo": "pkg:maven/org.apache.dubbo/dubbo-rpc-dubbo@3.1.4", - "/packages/dubbo-3.1.4.jar:org.apache.dubbo:dubbo-rpc-grpc": "pkg:maven/org.apache.dubbo/dubbo-rpc-grpc@3.1.4", - "/packages/dubbo-3.1.4.jar:org.apache.dubbo:dubbo-rpc-injvm": "pkg:maven/org.apache.dubbo/dubbo-rpc-injvm@3.1.4", - "/packages/dubbo-3.1.4.jar:org.apache.dubbo:dubbo-rpc-rest": "pkg:maven/org.apache.dubbo/dubbo-rpc-rest@3.1.4", - "/packages/dubbo-3.1.4.jar:org.apache.dubbo:dubbo-rpc-triple": "pkg:maven/org.apache.dubbo/dubbo-rpc-triple@3.1.4", - "/packages/dubbo-3.1.4.jar:org.apache.dubbo:dubbo-serialization-api": "pkg:maven/org.apache.dubbo/dubbo-serialization-api@3.1.4", - "/packages/dubbo-3.1.4.jar:org.apache.dubbo:dubbo-serialization-fastjson2": "pkg:maven/org.apache.dubbo/dubbo-serialization-fastjson2@3.1.4", - "/packages/dubbo-3.1.4.jar:org.apache.dubbo:dubbo-serialization-hessian2": "pkg:maven/org.apache.dubbo/dubbo-serialization-hessian2@3.1.4", - "/packages/dubbo-3.1.4.jar:org.apache.dubbo:dubbo-serialization-jdk": "pkg:maven/org.apache.dubbo/dubbo-serialization-jdk@3.1.4", - "/packages/dubbo-3.1.4.jar:org.apache.dubbo:dubbo-xds": "pkg:maven/org.apache.dubbo/dubbo-xds@3.1.4", - "/packages/dubbo-3.1.4.jar": "pkg:maven/org.apache.dubbo/dubbo@3.1.4", - "/packages/elasticsearch-8.10.2.jar": "pkg:maven/org.elasticsearch/elasticsearch@8.10.2", - "/packages/elasticsearch-rest-client-sniffer-7.17.11.jar": "pkg:maven/org.elasticsearch.client/elasticsearch-rest-client-sniffer@7.17.11", - "/packages/example-java-app-gradle-0.1.0.ear": "pkg:maven/example-java-app-gradle/example-java-app-gradle@0.1.0", - "/packages/geode-core-1.14.3.jar": "pkg:maven/org.apache.geode/geode-core@1.14.3", - "/packages/github-api-1.118.jar": "pkg:maven/org.kohsuke/github-api@1.118", - "/packages/google-oauth-client-1.25.0.jar": "pkg:maven/com.google.oauth-client/google-oauth-client@1.25.0", + "/packages/activemq-client-5.18.2.jar": "pkg:maven/org.apache.activemq/activemq-client@5.18.2", + "/packages/activemq-protobuf-1.1.jar": "pkg:maven/org.apache.activemq.protobuf/activemq-protobuf@1.1", + "/packages/akka-actor_2.13-2.6.6.jar": "pkg:maven/com.typesafe.akka/akka-actor_2.13@2.6.6", + "/packages/akka-management-cluster-bootstrap_2.13-1.2.0.jar": "pkg:maven/com.lightbend.akka.management/akka-management-cluster-bootstrap_2.13@1.2.0", + "/packages/ant-1.10.3.jar": "pkg:maven/org.apache.ant/ant@1.10.3", + "/packages/apache-chainsaw-2.1.0.jar": "pkg:maven/log4j/apache-chainsaw@2.1.0", + "/packages/apache-log4j-extras-1.1.jar": "pkg:maven/log4j/apache-log4j-extras@1.1", + "/packages/apoc-4.4.0.11.jar": "pkg:maven/org.neo4j.procedure/apoc@4.4.0.11", + "/packages/atlassian-bitbucket-server-integration.hpi": "pkg:maven/io.jenkins.plugins/atlassian-bitbucket-server-integration@2.1.2", + "/packages/atlassian-bitbucket-server-integration.hpi:WEB-INF/lib/atlassian-bitbucket-server-integration.jar": "pkg:maven/io.jenkins.plugins/atlassian-bitbucket-server-integration@2.1.2", + "/packages/atlassian-bitbucket-server-integration.hpi:WEB-INF/lib/commons-codec-1.13.jar": "pkg:maven/commons-codec/commons-codec@1.13", + "/packages/atlassian-bitbucket-server-integration.hpi:WEB-INF/lib/commons-lang3-3.9.jar": "pkg:maven/org.apache.commons/commons-lang3@3.9", + "/packages/atlassian-bitbucket-server-integration.hpi:WEB-INF/lib/eddsa-0.3.0.jar": "pkg:maven/net.i2p.crypto/eddsa@0.3.0", + "/packages/atlassian-bitbucket-server-integration.hpi:WEB-INF/lib/httpcore-4.4.9.jar": "pkg:maven/org.apache.httpcomponents/httpcore@4.4.9", + "/packages/atlassian-bitbucket-server-integration.hpi:WEB-INF/lib/jackson-annotations-2.11.2.jar": "pkg:maven/com.fasterxml.jackson.core/jackson-annotations@2.11.2", + "/packages/atlassian-bitbucket-server-integration.hpi:WEB-INF/lib/jackson-core-2.11.2.jar": "pkg:maven/com.fasterxml.jackson.core/jackson-core@2.11.2", + "/packages/atlassian-bitbucket-server-integration.hpi:WEB-INF/lib/jackson-databind-2.9.10.7.jar": "pkg:maven/com.fasterxml.jackson.core/jackson-databind@2.9.10.7", + "/packages/atlassian-bitbucket-server-integration.hpi:WEB-INF/lib/jcommon-1.0.24.jar": "pkg:maven/org.jfree/jcommon@1.0.24", + "/packages/atlassian-bitbucket-server-integration.hpi:WEB-INF/lib/json-20180813.jar": "pkg:maven/org.json/json@20180813", + "/packages/atlassian-bitbucket-server-integration.hpi:WEB-INF/lib/oauth-20100527.jar": "pkg:maven/net.oauth.core/oauth@20100527", + "/packages/atlassian-bitbucket-server-integration.hpi:WEB-INF/lib/oauth-provider-20100527.jar": "pkg:maven/net.oauth.core/oauth-provider@20100527", + "/packages/atlassian-bitbucket-server-integration.hpi:WEB-INF/lib/okhttp-3.14.1.jar": "pkg:maven/com.squareup.okhttp3/okhttp@3.14.1", + "/packages/atlassian-bitbucket-server-integration.hpi:WEB-INF/lib/okio-1.17.2.jar": "pkg:maven/com.squareup.okio/okio@1.17.2", + "/packages/atlassian-bitbucket-server-integration.hpi:WEB-INF/lib/protobuf-java-3.11.1.jar": "pkg:maven/com.google.protobuf/protobuf-java@3.11.1", + "/packages/atlassian-bitbucket-server-integration.hpi:WEB-INF/lib/trilead-putty-extension-1.2.jar": "pkg:maven/org.kohsuke/trilead-putty-extension@1.2", + "/packages/atlassian-bitbucket-server-integration.hpi:WEB-INF/lib/trilead-ssh2-build-217-jenkins-27.jar:org.jenkins-ci:trilead-ssh2": "pkg:maven/org.jenkins-ci/trilead-ssh2@build-217-jenkins-27", + "/packages/aws-sam.hpi": "pkg:maven/io.jenkins.plugins/aws-sam@1.2.2", + "/packages/aws-sam.hpi:WEB-INF/lib/aws-sam.jar": "pkg:maven/io.jenkins.plugins/aws-sam@1.2.2", + "/packages/aws-sam.hpi:WEB-INF/lib/json-20180130.jar": "pkg:maven/org.json/json@20180130", + "/packages/aws-sam.hpi:WEB-INF/lib/snakeyaml-1.21.jar": "pkg:maven/org.yaml/snakeyaml@1.21", + "/packages/bc-fips-1.0.2.3.jar": "pkg:maven/org.bouncycastle/bc-fips@1.0.2.3", + "/packages/camel-core-3.1.0.jar": "pkg:maven/org.apache.camel/camel-core@3.1.0", + "/packages/cassandra-all-4.1.1.jar": "pkg:maven/org.apache.cassandra/cassandra-all@4.1.1", + "/packages/commons-logging-1.1.1.jar": "pkg:maven/commons-logging/commons-logging@1.1.1", + "/packages/commons-vfs-1.0.jar": "pkg:maven/commons-vfs/commons-vfs@1.0", + "/packages/cxf-rt-transports-http-2.7.3.jar": "pkg:maven/org.apache.cxf/cxf-rt-transports-http@2.7.3", + "/packages/dubbo-3.1.4.jar": "pkg:maven/org.apache.dubbo/dubbo@3.1.4", + "/packages/dubbo-3.1.4.jar:com.alibaba:hessian-lite": "pkg:maven/com.alibaba/hessian-lite@3.2.13", + "/packages/dubbo-3.1.4.jar:org.apache.dubbo:dubbo-auth": "pkg:maven/org.apache.dubbo/dubbo-auth@3.1.4", + "/packages/dubbo-3.1.4.jar:org.apache.dubbo:dubbo-cluster": "pkg:maven/org.apache.dubbo/dubbo-cluster@3.1.4", + "/packages/dubbo-3.1.4.jar:org.apache.dubbo:dubbo-common": "pkg:maven/org.apache.dubbo/dubbo-common@3.1.4", + "/packages/dubbo-3.1.4.jar:org.apache.dubbo:dubbo-compatible": "pkg:maven/org.apache.dubbo/dubbo-compatible@3.1.4", + "/packages/dubbo-3.1.4.jar:org.apache.dubbo:dubbo-config-api": "pkg:maven/org.apache.dubbo/dubbo-config-api@3.1.4", + "/packages/dubbo-3.1.4.jar:org.apache.dubbo:dubbo-config-spring": "pkg:maven/org.apache.dubbo/dubbo-config-spring@3.1.4", + "/packages/dubbo-3.1.4.jar:org.apache.dubbo:dubbo-configcenter-apollo": "pkg:maven/org.apache.dubbo/dubbo-configcenter-apollo@3.1.4", + "/packages/dubbo-3.1.4.jar:org.apache.dubbo:dubbo-configcenter-nacos": "pkg:maven/org.apache.dubbo/dubbo-configcenter-nacos@3.1.4", + "/packages/dubbo-3.1.4.jar:org.apache.dubbo:dubbo-configcenter-zookeeper": "pkg:maven/org.apache.dubbo/dubbo-configcenter-zookeeper@3.1.4", + "/packages/dubbo-3.1.4.jar:org.apache.dubbo:dubbo-container-api": "pkg:maven/org.apache.dubbo/dubbo-container-api@3.1.4", + "/packages/dubbo-3.1.4.jar:org.apache.dubbo:dubbo-container-spring": "pkg:maven/org.apache.dubbo/dubbo-container-spring@3.1.4", + "/packages/dubbo-3.1.4.jar:org.apache.dubbo:dubbo-filter-cache": "pkg:maven/org.apache.dubbo/dubbo-filter-cache@3.1.4", + "/packages/dubbo-3.1.4.jar:org.apache.dubbo:dubbo-filter-validation": "pkg:maven/org.apache.dubbo/dubbo-filter-validation@3.1.4", + "/packages/dubbo-3.1.4.jar:org.apache.dubbo:dubbo-kubernetes": "pkg:maven/org.apache.dubbo/dubbo-kubernetes@3.1.4", + "/packages/dubbo-3.1.4.jar:org.apache.dubbo:dubbo-metadata-api": "pkg:maven/org.apache.dubbo/dubbo-metadata-api@3.1.4", + "/packages/dubbo-3.1.4.jar:org.apache.dubbo:dubbo-metadata-definition-protobuf": "pkg:maven/org.apache.dubbo/dubbo-metadata-definition-protobuf@3.1.4", + "/packages/dubbo-3.1.4.jar:org.apache.dubbo:dubbo-metadata-report-nacos": "pkg:maven/org.apache.dubbo/dubbo-metadata-report-nacos@3.1.4", + "/packages/dubbo-3.1.4.jar:org.apache.dubbo:dubbo-metadata-report-redis": "pkg:maven/org.apache.dubbo/dubbo-metadata-report-redis@3.1.4", + "/packages/dubbo-3.1.4.jar:org.apache.dubbo:dubbo-metadata-report-zookeeper": "pkg:maven/org.apache.dubbo/dubbo-metadata-report-zookeeper@3.1.4", + "/packages/dubbo-3.1.4.jar:org.apache.dubbo:dubbo-metrics-api": "pkg:maven/org.apache.dubbo/dubbo-metrics-api@3.1.4", + "/packages/dubbo-3.1.4.jar:org.apache.dubbo:dubbo-metrics-prometheus": "pkg:maven/org.apache.dubbo/dubbo-metrics-prometheus@3.1.4", + "/packages/dubbo-3.1.4.jar:org.apache.dubbo:dubbo-monitor-api": "pkg:maven/org.apache.dubbo/dubbo-monitor-api@3.1.4", + "/packages/dubbo-3.1.4.jar:org.apache.dubbo:dubbo-monitor-default": "pkg:maven/org.apache.dubbo/dubbo-monitor-default@3.1.4", + "/packages/dubbo-3.1.4.jar:org.apache.dubbo:dubbo-qos": "pkg:maven/org.apache.dubbo/dubbo-qos@3.1.4", + "/packages/dubbo-3.1.4.jar:org.apache.dubbo:dubbo-reactive": "pkg:maven/org.apache.dubbo/dubbo-reactive@3.1.4", + "/packages/dubbo-3.1.4.jar:org.apache.dubbo:dubbo-registry-api": "pkg:maven/org.apache.dubbo/dubbo-registry-api@3.1.4", + "/packages/dubbo-3.1.4.jar:org.apache.dubbo:dubbo-registry-multicast": "pkg:maven/org.apache.dubbo/dubbo-registry-multicast@3.1.4", + "/packages/dubbo-3.1.4.jar:org.apache.dubbo:dubbo-registry-multiple": "pkg:maven/org.apache.dubbo/dubbo-registry-multiple@3.1.4", + "/packages/dubbo-3.1.4.jar:org.apache.dubbo:dubbo-registry-nacos": "pkg:maven/org.apache.dubbo/dubbo-registry-nacos@3.1.4", + "/packages/dubbo-3.1.4.jar:org.apache.dubbo:dubbo-registry-zookeeper": "pkg:maven/org.apache.dubbo/dubbo-registry-zookeeper@3.1.4", + "/packages/dubbo-3.1.4.jar:org.apache.dubbo:dubbo-remoting-api": "pkg:maven/org.apache.dubbo/dubbo-remoting-api@3.1.4", + "/packages/dubbo-3.1.4.jar:org.apache.dubbo:dubbo-remoting-http": "pkg:maven/org.apache.dubbo/dubbo-remoting-http@3.1.4", + "/packages/dubbo-3.1.4.jar:org.apache.dubbo:dubbo-remoting-netty": "pkg:maven/org.apache.dubbo/dubbo-remoting-netty@3.1.4", + "/packages/dubbo-3.1.4.jar:org.apache.dubbo:dubbo-remoting-netty4": "pkg:maven/org.apache.dubbo/dubbo-remoting-netty4@3.1.4", + "/packages/dubbo-3.1.4.jar:org.apache.dubbo:dubbo-remoting-zookeeper": "pkg:maven/org.apache.dubbo/dubbo-remoting-zookeeper@3.1.4", + "/packages/dubbo-3.1.4.jar:org.apache.dubbo:dubbo-remoting-zookeeper-curator5": "pkg:maven/org.apache.dubbo/dubbo-remoting-zookeeper-curator5@3.1.4", + "/packages/dubbo-3.1.4.jar:org.apache.dubbo:dubbo-rpc-api": "pkg:maven/org.apache.dubbo/dubbo-rpc-api@3.1.4", + "/packages/dubbo-3.1.4.jar:org.apache.dubbo:dubbo-rpc-dubbo": "pkg:maven/org.apache.dubbo/dubbo-rpc-dubbo@3.1.4", + "/packages/dubbo-3.1.4.jar:org.apache.dubbo:dubbo-rpc-grpc": "pkg:maven/org.apache.dubbo/dubbo-rpc-grpc@3.1.4", + "/packages/dubbo-3.1.4.jar:org.apache.dubbo:dubbo-rpc-injvm": "pkg:maven/org.apache.dubbo/dubbo-rpc-injvm@3.1.4", + "/packages/dubbo-3.1.4.jar:org.apache.dubbo:dubbo-rpc-rest": "pkg:maven/org.apache.dubbo/dubbo-rpc-rest@3.1.4", + "/packages/dubbo-3.1.4.jar:org.apache.dubbo:dubbo-rpc-triple": "pkg:maven/org.apache.dubbo/dubbo-rpc-triple@3.1.4", + "/packages/dubbo-3.1.4.jar:org.apache.dubbo:dubbo-serialization-api": "pkg:maven/org.apache.dubbo/dubbo-serialization-api@3.1.4", + "/packages/dubbo-3.1.4.jar:org.apache.dubbo:dubbo-serialization-fastjson2": "pkg:maven/org.apache.dubbo/dubbo-serialization-fastjson2@3.1.4", + "/packages/dubbo-3.1.4.jar:org.apache.dubbo:dubbo-serialization-hessian2": "pkg:maven/org.apache.dubbo/dubbo-serialization-hessian2@3.1.4", + "/packages/dubbo-3.1.4.jar:org.apache.dubbo:dubbo-serialization-jdk": "pkg:maven/org.apache.dubbo/dubbo-serialization-jdk@3.1.4", + "/packages/dubbo-3.1.4.jar:org.apache.dubbo:dubbo-xds": "pkg:maven/org.apache.dubbo/dubbo-xds@3.1.4", + "/packages/elasticsearch-8.10.2.jar": "pkg:maven/org.elasticsearch/elasticsearch@8.10.2", + "/packages/elasticsearch-rest-client-sniffer-7.17.11.jar": "pkg:maven/org.elasticsearch.client/elasticsearch-rest-client-sniffer@7.17.11", + "/packages/example-java-app-gradle-0.1.0.ear": "pkg:maven/example-java-app-gradle/example-java-app-gradle@0.1.0", + "/packages/generic-webhook-trigger.hpi": "pkg:maven/org.jenkins-ci.plugins/generic-webhook-trigger@1.71", + "/packages/generic-webhook-trigger.hpi:WEB-INF/lib/accessors-smart-1.2.jar": "pkg:maven/net.minidev/accessors-smart@1.2", + "/packages/generic-webhook-trigger.hpi:WEB-INF/lib/asm-5.0.4.jar": "pkg:maven/org.objectweb.asm/asm@5.0.4", + "/packages/generic-webhook-trigger.hpi:WEB-INF/lib/commons-ip-math-1.32.jar": "pkg:maven/com.github.jgonian/commons-ip-math@1.32", + "/packages/generic-webhook-trigger.hpi:WEB-INF/lib/generic-webhook-trigger.jar": "pkg:maven/org.jenkins-ci.plugins/generic-webhook-trigger@1.71", + "/packages/generic-webhook-trigger.hpi:WEB-INF/lib/gson-2.8.2.jar": "pkg:maven/com.google.code.gson/gson@2.8.2", + "/packages/generic-webhook-trigger.hpi:WEB-INF/lib/json-path-2.3.0.jar": "pkg:maven/com.jayway.jsonpath.json-path/json-path@2.3.0", + "/packages/generic-webhook-trigger.hpi:WEB-INF/lib/json-smart-2.3.jar": "pkg:maven/net.minidev/json-smart@2.3", + "/packages/geode-core-1.14.3.jar": "pkg:maven/org.apache.geode/geode-core@1.14.3", + "/packages/github-api-1.118.jar": "pkg:maven/org.kohsuke/github-api@1.118", + "/packages/google-oauth-client-1.25.0.jar": "pkg:maven/com.google.oauth-client/google-oauth-client@1.25.0", + "/packages/gradle-7.1.1/lib/annotations-20.1.0.jar": "pkg:maven/org.jetbrains.annotations/annotations@20.1.0", + "/packages/gradle-7.1.1/lib/ant-1.10.9.jar": "pkg:maven/org.apache.ant/ant@1.10.9", + "/packages/gradle-7.1.1/lib/ant-antlr-1.10.9.jar": "pkg:maven/org.apache.ant/ant-antlr@1.10.9", + "/packages/gradle-7.1.1/lib/ant-junit-1.10.9.jar": "pkg:maven/org.apache.ant/ant-junit@1.10.9", + "/packages/gradle-7.1.1/lib/ant-launcher-1.10.9.jar": "pkg:maven/org.apache.ant/ant-launcher@1.10.9", + "/packages/gradle-7.1.1/lib/antlr4-runtime-4.7.2.jar": "pkg:maven/org.antlr/antlr4-runtime@4.7.2", + "/packages/gradle-7.1.1/lib/asm-9.1.jar": "pkg:maven/org.objectweb.asm/asm@9.1", + "/packages/gradle-7.1.1/lib/commons-compress-1.20.jar": "pkg:maven/org.apache.commons/commons-compress@1.20", + "/packages/gradle-7.1.1/lib/commons-io-2.6.jar": "pkg:maven/commons-io/commons-io@2.6", + "/packages/gradle-7.1.1/lib/commons-lang-2.6.jar": "pkg:maven/commons-lang/commons-lang@2.6", + "/packages/gradle-7.1.1/lib/failureaccess-1.0.1.jar": "pkg:maven/com.google.guava/failureaccess@1.0.1", + "/packages/gradle-7.1.1/lib/groovy-3.0.7.jar": "pkg:maven/org.codehaus.groovy/groovy@3.0.7", + "/packages/gradle-7.1.1/lib/groovy-ant-3.0.7.jar": "pkg:maven/org.codehaus.groovy/groovy-ant@3.0.7", + "/packages/gradle-7.1.1/lib/groovy-astbuilder-3.0.7.jar": "pkg:maven/org.codehaus.groovy/groovy-astbuilder@3.0.7", + "/packages/gradle-7.1.1/lib/groovy-console-3.0.7.jar": "pkg:maven/org.codehaus.groovy/groovy-console@3.0.7", + "/packages/gradle-7.1.1/lib/groovy-datetime-3.0.7.jar": "pkg:maven/org.codehaus.groovy/groovy-datetime@3.0.7", + "/packages/gradle-7.1.1/lib/groovy-dateutil-3.0.7.jar": "pkg:maven/org.codehaus.groovy/groovy-dateutil@3.0.7", + "/packages/gradle-7.1.1/lib/groovy-docgenerator-3.0.7.jar": "pkg:maven/org.codehaus.groovy/groovy-docgenerator@3.0.7", + "/packages/gradle-7.1.1/lib/groovy-groovydoc-3.0.7.jar": "pkg:maven/org.codehaus.groovy/groovy-groovydoc@3.0.7", + "/packages/gradle-7.1.1/lib/groovy-json-3.0.7.jar": "pkg:maven/org.codehaus.groovy/groovy-json@3.0.7", + "/packages/gradle-7.1.1/lib/groovy-nio-3.0.7.jar": "pkg:maven/org.codehaus.groovy/groovy-nio@3.0.7", + "/packages/gradle-7.1.1/lib/groovy-sql-3.0.7.jar": "pkg:maven/org.codehaus.groovy/groovy-sql@3.0.7", + "/packages/gradle-7.1.1/lib/groovy-swing-3.0.7.jar": "pkg:maven/org.codehaus.groovy/groovy-swing@3.0.7", + "/packages/gradle-7.1.1/lib/groovy-templates-3.0.7.jar": "pkg:maven/org.codehaus.groovy/groovy-templates@3.0.7", + "/packages/gradle-7.1.1/lib/groovy-test-3.0.7.jar": "pkg:maven/org.codehaus.groovy/groovy-test@3.0.7", + "/packages/gradle-7.1.1/lib/groovy-xml-3.0.7.jar": "pkg:maven/org.codehaus.groovy/groovy-xml@3.0.7", + "/packages/gradle-7.1.1/lib/guava-27.1-android.jar": "pkg:maven/com.google.guava/guava@27.1-android", + "/packages/gradle-7.1.1/lib/jansi-1.18.jar": "pkg:maven/org.fusesource.jansi/jansi@1.18", + "/packages/gradle-7.1.1/lib/jansi-1.18.jar:org.fusesource.hawtjni:hawtjni-runtime": "pkg:maven/org.fusesource.hawtjni/hawtjni-runtime@1.17", + "/packages/gradle-7.1.1/lib/jansi-1.18.jar:org.fusesource.jansi:jansi-freebsd32": "pkg:maven/org.fusesource.jansi/jansi-freebsd32@1.8", + "/packages/gradle-7.1.1/lib/jansi-1.18.jar:org.fusesource.jansi:jansi-freebsd64": "pkg:maven/org.fusesource.jansi/jansi-freebsd64@1.8", + "/packages/gradle-7.1.1/lib/jansi-1.18.jar:org.fusesource.jansi:jansi-linux32": "pkg:maven/org.fusesource.jansi/jansi-linux32@1.8", + "/packages/gradle-7.1.1/lib/jansi-1.18.jar:org.fusesource.jansi:jansi-linux64": "pkg:maven/org.fusesource.jansi/jansi-linux64@1.8", + "/packages/gradle-7.1.1/lib/jansi-1.18.jar:org.fusesource.jansi:jansi-native": "pkg:maven/org.fusesource.jansi/jansi-native@1.8", + "/packages/gradle-7.1.1/lib/jansi-1.18.jar:org.fusesource.jansi:jansi-osx": "pkg:maven/org.fusesource.jansi/jansi-osx@1.8", + "/packages/gradle-7.1.1/lib/jansi-1.18.jar:org.fusesource.jansi:jansi-windows32": "pkg:maven/org.fusesource.jansi/jansi-windows32@1.8", + "/packages/gradle-7.1.1/lib/jansi-1.18.jar:org.fusesource.jansi:jansi-windows64": "pkg:maven/org.fusesource.jansi/jansi-windows64@1.8", + "/packages/gradle-7.1.1/lib/javaparser-core-3.17.0.jar": "pkg:maven/com.github.javaparser/javaparser-core@3.17.0", + "/packages/gradle-7.1.1/lib/jcl-over-slf4j-1.7.30.jar": "pkg:maven/org.slf4j/jcl-over-slf4j@1.7.30", + "/packages/gradle-7.1.1/lib/jsr305-3.0.2.jar": "pkg:maven/com.google.code.findbugs/jsr305@3.0.2", + "/packages/gradle-7.1.1/lib/jul-to-slf4j-1.7.30.jar": "pkg:maven/org.slf4j/jul-to-slf4j@1.7.30", + "/packages/gradle-7.1.1/lib/junit-4.13.2.jar": "pkg:maven/junit/junit@4.13.2", + "/packages/gradle-7.1.1/lib/kryo-2.24.0.jar": "pkg:maven/com.esotericsoftware.kryo/kryo@2.24.0", + "/packages/gradle-7.1.1/lib/kryo-2.24.0.jar:com.esotericsoftware.reflectasm:reflectasm": "pkg:maven/com.esotericsoftware.reflectasm/reflectasm@1.09", + "/packages/gradle-7.1.1/lib/log4j-over-slf4j-1.7.30.jar": "pkg:maven/org.slf4j/log4j-over-slf4j@1.7.30", + "/packages/gradle-7.1.1/lib/minlog-1.2.jar": "pkg:maven/com.esotericsoftware.minlog/minlog@1.2", + "/packages/gradle-7.1.1/lib/objenesis-2.6.jar": "pkg:maven/org.objenesis/objenesis@2.6", + "/packages/gradle-7.1.1/lib/plugins/aws-java-sdk-core-1.11.948.jar": "pkg:maven/com.amazonaws/aws-java-sdk-core@1.11.948", + "/packages/gradle-7.1.1/lib/plugins/aws-java-sdk-kms-1.11.948.jar": "pkg:maven/com.amazonaws/aws-java-sdk-kms@1.11.948", + "/packages/gradle-7.1.1/lib/plugins/aws-java-sdk-s3-1.11.948.jar": "pkg:maven/com.amazonaws/aws-java-sdk-s3@1.11.948", + "/packages/gradle-7.1.1/lib/plugins/aws-java-sdk-sts-1.11.948.jar": "pkg:maven/com.amazonaws/aws-java-sdk-sts@1.11.948", + "/packages/gradle-7.1.1/lib/plugins/bcpg-jdk15on-1.68.jar": "pkg:maven/org.bouncycastle/bcpg-jdk15on@1.68", + "/packages/gradle-7.1.1/lib/plugins/bcpkix-jdk15on-1.68.jar": "pkg:maven/org.bouncycastle/bcpkix-jdk15on@1.68", + "/packages/gradle-7.1.1/lib/plugins/bcprov-jdk15on-1.68.jar": "pkg:maven/org.bouncycastle/bcprov-jdk15on@1.68", + "/packages/gradle-7.1.1/lib/plugins/commons-codec-1.15.jar": "pkg:maven/commons-codec/commons-codec@1.15", + "/packages/gradle-7.1.1/lib/plugins/dd-plist-1.21.jar": "pkg:maven/com.googlecode.plist/dd-plist@1.21", + "/packages/gradle-7.1.1/lib/plugins/google-api-services-storage-v1-rev171-1.25.0.jar:com.google.apis:google-api-services-storage": "pkg:maven/com.google.apis/google-api-services-storage@v1-rev171-1.25.0", + "/packages/gradle-7.1.1/lib/plugins/google-http-client-1.25.0.jar": "pkg:maven/com.google.http-client/google-http-client@1.25.0", + "/packages/gradle-7.1.1/lib/plugins/google-http-client-jackson2-1.25.0.jar": "pkg:maven/com.google.http-client/google-http-client-jackson2@1.25.0", + "/packages/gradle-7.1.1/lib/plugins/google-oauth-client-1.25.0.jar": "pkg:maven/com.google.oauth-client/google-oauth-client@1.25.0", + "/packages/gradle-7.1.1/lib/plugins/gson-2.8.6.jar": "pkg:maven/com.google.code.gson/gson@2.8.6", + "/packages/gradle-7.1.1/lib/plugins/httpclient-4.5.13.jar": "pkg:maven/org.apache.httpcomponents/httpclient@4.5.13", + "/packages/gradle-7.1.1/lib/plugins/httpcore-4.4.14.jar": "pkg:maven/org.apache.httpcomponents/httpcore@4.4.14", + "/packages/gradle-7.1.1/lib/plugins/ion-java-1.0.2.jar": "pkg:maven/software.amazon.ion/ion-java@1.0.2", + "/packages/gradle-7.1.1/lib/plugins/jackson-annotations-2.12.1.jar": "pkg:maven/com.fasterxml.jackson.core/jackson-annotations@2.12.1", + "/packages/gradle-7.1.1/lib/plugins/jackson-core-2.12.1.jar": "pkg:maven/com.fasterxml.jackson.core/jackson-core@2.12.1", + "/packages/gradle-7.1.1/lib/plugins/jackson-databind-2.12.1.jar": "pkg:maven/com.fasterxml.jackson.core/jackson-databind@2.12.1", + "/packages/gradle-7.1.1/lib/plugins/jakarta.activation-2.0.0.jar": "pkg:maven/com.sun.activation/jakarta.activation@2.0.0", + "/packages/gradle-7.1.1/lib/plugins/jakarta.xml.bind-api-3.0.0.jar": "pkg:maven/jakarta.xml.bind/jakarta.xml.bind-api@3.0.0", + "/packages/gradle-7.1.1/lib/plugins/jatl-0.2.3.jar": "pkg:maven/com.googlecode.jatl/jatl@0.2.3", + "/packages/gradle-7.1.1/lib/plugins/jaxb-core-3.0.0.jar:com.sun.istack:istack-commons-runtime": "pkg:maven/com.sun.istack/istack-commons-runtime@4.0.0", + "/packages/gradle-7.1.1/lib/plugins/jaxb-core-3.0.0.jar:org.glassfish.jaxb:txw2": "pkg:maven/org.glassfish.jaxb/txw2@3.0.0", + "/packages/gradle-7.1.1/lib/plugins/jaxb-impl-3.0.0.jar": "pkg:maven/com.sun.xml.bind/jaxb-impl@3.0.0", + "/packages/gradle-7.1.1/lib/plugins/jaxb-impl-3.0.0.jar:org.glassfish.jaxb:jaxb-runtime": "pkg:maven/org.glassfish.jaxb/jaxb-runtime@3.0.0", + "/packages/gradle-7.1.1/lib/plugins/jcifs-1.3.17.jar": "pkg:maven/jcifs/jcifs@1.3.17", + "/packages/gradle-7.1.1/lib/plugins/jmespath-java-1.11.948.jar": "pkg:maven/com.amazonaws/jmespath-java@1.11.948", + "/packages/gradle-7.1.1/lib/plugins/joda-time-2.10.4.jar": "pkg:maven/joda-time/joda-time@2.10.4", + "/packages/gradle-7.1.1/lib/plugins/jsch-0.1.55.jar": "pkg:maven/com.jcraft/jsch@0.1.55", + "/packages/gradle-7.1.1/lib/plugins/jzlib-1.1.3.jar": "pkg:maven/com.jcraft/jzlib@1.1.3", + "/packages/gradle-7.1.1/lib/plugins/maven-builder-support-3.6.3.jar": "pkg:maven/org.apache.maven/maven-builder-support@3.6.3", + "/packages/gradle-7.1.1/lib/plugins/maven-model-3.6.3.jar": "pkg:maven/org.apache.maven/maven-model@3.6.3", + "/packages/gradle-7.1.1/lib/plugins/maven-repository-metadata-3.6.3.jar": "pkg:maven/org.apache.maven/maven-repository-metadata@3.6.3", + "/packages/gradle-7.1.1/lib/plugins/maven-settings-3.6.3.jar": "pkg:maven/org.apache.maven/maven-settings@3.6.3", + "/packages/gradle-7.1.1/lib/plugins/maven-settings-builder-3.6.3.jar": "pkg:maven/org.apache.maven/maven-settings-builder@3.6.3", + "/packages/gradle-7.1.1/lib/plugins/opentest4j-1.2.0.jar": "pkg:maven/org.opentest4j/opentest4j@1.2.0", + "/packages/gradle-7.1.1/lib/plugins/org.eclipse.jgit-5.7.0.202003110725-r.jar": "pkg:maven/org.eclipse.jgit/org.eclipse.jgit@5.7.0.202003110725-r", + "/packages/gradle-7.1.1/lib/plugins/plexus-cipher-1.7.jar": "pkg:maven/org.sonatype.plexus/plexus-cipher@1.7", + "/packages/gradle-7.1.1/lib/plugins/plexus-interpolation-1.26.jar": "pkg:maven/org.codehaus.plexus/plexus-interpolation@1.26", + "/packages/gradle-7.1.1/lib/plugins/plexus-sec-dispatcher-1.4.jar": "pkg:maven/org.sonatype.plexus/plexus-sec-dispatcher@1.4", + "/packages/gradle-7.1.1/lib/plugins/plexus-utils-3.3.0.jar": "pkg:maven/org.codehaus.plexus/plexus-utils@3.3.0", + "/packages/gradle-7.1.1/lib/plugins/snakeyaml-1.28.jar": "pkg:maven/org.yaml/snakeyaml@1.28", + "/packages/gradle-7.1.1/lib/plugins/testng-6.3.1.jar": "pkg:maven/org.testng/testng@6.3.1", + "/packages/gradle-7.1.1/lib/plugins/xercesImpl-2.12.0.jar": "pkg:maven/org.apache.xerces.impl.Version/xercesImpl@2.12.0", + "/packages/gradle-7.1.1/lib/qdox-1.12.1.jar": "pkg:maven/com.thoughtworks.qdox/qdox@1.12.1", + "/packages/gradle-7.1.1/lib/slf4j-api-1.7.30.jar": "pkg:maven/org.slf4j/slf4j-api@1.7.30", + "/packages/gradle.hpi": "pkg:maven/org.jenkins-ci.plugins/gradle@1.36", + "/packages/gradle.hpi:WEB-INF/lib/gradle-plugin-1.36.jar": "pkg:maven/org.jenkins-ci.plugins/gradle-plugin@1.36", + "/packages/graphql-java-20.0.jar": "pkg:maven/com.graphql-java/graphql-java@20.0", "/packages/graphql-java-20.0.jar:com.google.guava:guava": "pkg:maven/com.google.guava/guava@31.0.1-jre", "/packages/graphql-java-20.0.jar:org.antlr:antlr4-runtime": "pkg:maven/org.antlr/antlr4-runtime@4.9.3", - "/packages/graphql-java-20.0.jar": "pkg:maven/com.graphql-java/graphql-java@20.0", "/packages/guava-29.0-jre.jar": "pkg:maven/com.google.guava/guava@29.0-jre", "/packages/hadoop-common-3.3.2.jar": "pkg:maven/org.apache.hadoop/hadoop-common@3.3.2", + "/packages/hazelcast-5.2.4.jar": "pkg:maven/com.hazelcast/hazelcast@5.2.4", "/packages/hazelcast-5.2.4.jar:com.fasterxml.jackson.core:jackson-core": "pkg:maven/com.fasterxml.jackson.core/jackson-core@2.15.2", "/packages/hazelcast-5.2.4.jar:com.fasterxml.jackson.jr:jackson-jr-annotation-support": "pkg:maven/com.fasterxml.jackson.jr/jackson-jr-annotation-support@2.15.2", "/packages/hazelcast-5.2.4.jar:com.fasterxml.jackson.jr:jackson-jr-objects": "pkg:maven/com.fasterxml.jackson.jr/jackson-jr-objects@2.15.2", @@ -148,7 +439,6 @@ var expectedPURLs = map[string]string{ "/packages/hazelcast-5.2.4.jar:io.github.classgraph:classgraph": "pkg:maven/io.github.classgraph/classgraph@4.8.149", "/packages/hazelcast-5.2.4.jar:org.json:json": "pkg:maven/org.json/json@20230227", "/packages/hazelcast-5.2.4.jar:org.snakeyaml:snakeyaml-engine": "pkg:maven/org.snakeyaml/snakeyaml-engine@2.3", - "/packages/hazelcast-5.2.4.jar": "pkg:maven/com.hazelcast/hazelcast@5.2.4", "/packages/hibernate-validator-6.1.3.Final.jar": "pkg:maven/org.hibernate.validator/hibernate-validator@6.1.3.Final", "/packages/http2-common-11.0.16.jar": "pkg:maven/org.eclipse.jetty.http2/http2-common@11.0.16", "/packages/hudson.war:WEB-INF/hudson-cli.jar:args4j:args4j": "pkg:maven/args4j/args4j@2.0.16", @@ -305,29 +595,105 @@ var expectedPURLs = map[string]string{ "/packages/jetty-server-12.0.0.alpha3.jar": "pkg:maven/org.eclipse.jetty/jetty-server@12.0.0.alpha3", "/packages/jetty-setuid-java-1.0.4.jar": "pkg:maven/org.eclipse.jetty.toolchain.setuid/jetty-setuid-java@1.0.4", "/packages/jmdns-3.4.1.jar": "pkg:maven/javax.jmdns/jmdns@3.4.1", - "/packages/jruby-stdlib-9.1.15.0.jar:META-INF/jruby.home/lib/ruby/stdlib/jopenssl.jar:rubygems:jruby-openssl": "pkg:maven/rubygems/jruby-openssl@0.9.21", + "/packages/jruby-stdlib-9.1.15.0.jar": "pkg:maven/org.jruby/jruby-stdlib@9.1.15.0", "/packages/jruby-stdlib-9.1.15.0.jar:META-INF/jruby.home/lib/ruby/stdlib/org/bouncycastle/bcpkix-jdk15on/1.56/bcpkix-jdk15on-1.56.jar": "pkg:maven/org.bouncycastle/bcpkix-jdk15on@1.56", "/packages/jruby-stdlib-9.1.15.0.jar:META-INF/jruby.home/lib/ruby/stdlib/org/bouncycastle/bcprov-jdk15on/1.56/bcprov-jdk15on-1.56.jar": "pkg:maven/org.bouncycastle/bcprov-jdk15on@1.56", "/packages/jruby-stdlib-9.1.15.0.jar:META-INF/jruby.home/lib/ruby/stdlib/org/yaml/snakeyaml/1.18/snakeyaml-1.18.jar": "pkg:maven/org.yaml/snakeyaml@1.18", - "/packages/jruby-stdlib-9.1.15.0.jar:META-INF/jruby.home/lib/ruby/stdlib/readline.jar:jline:jline": "pkg:maven/jline/jline@2.11", - "/packages/jruby-stdlib-9.1.15.0.jar:META-INF/jruby.home/lib/ruby/stdlib/readline.jar:rubygems:jruby-readline": "pkg:maven/rubygems/jruby-readline@1.2.0", - "/packages/jruby-stdlib-9.1.15.0.jar": "pkg:maven/org.jruby/jruby-stdlib@9.1.15.0", - "/packages/jsch-0.1.55.jar": "pkg:maven/com.jcraft/jsch@0.1.55", - "/packages/junit-4.13.1.jar": "pkg:maven/junit/junit@4.13.1", - "/packages/kafka_2.13-3.2.2.jar": "pkg:maven/org.apache.kafka/kafka_2.13@3.2.2", - "/packages/keycloak-core-22.0.2.jar": "pkg:maven/org.keycloak/keycloak-core@22.0.2", - "/packages/log4j-1.2.16.jar": "pkg:maven/log4j/log4j@1.2.16", - "/packages/log4j-core-2.17.0.jar": "pkg:maven/org.apache.logging.log4j/log4j-core@2.17.0", - "/packages/log4j-over-slf4j-1.7.36.jar": "pkg:maven/org.slf4j/log4j-over-slf4j@1.7.36", - "/packages/manager-pojo-1.8.0.jar": "pkg:maven/org.apache.inlong/manager-pojo@1.8.0", + "/packages/jsch-0.1.55.jar": "pkg:maven/com.jcraft/jsch@0.1.55", + "/packages/junit-4.13.1.jar": "pkg:maven/junit/junit@4.13.1", + "/packages/junit.hpi": "pkg:maven/org.jenkins-ci.plugins/junit@1.25", + "/packages/junit.hpi:WEB-INF/lib/junit.jar": "pkg:maven/org.jenkins-ci.plugins/junit@1.25", + "/packages/kafka_2.13-3.2.2.jar": "pkg:maven/org.apache.kafka/kafka_2.13@3.2.2", + "/packages/keycloak-core-22.0.2.jar": "pkg:maven/org.keycloak/keycloak-core@22.0.2", + "/packages/log4j-1.2.16.jar": "pkg:maven/log4j/log4j@1.2.16", + "/packages/log4j-core-2.17.0.jar": "pkg:maven/org.apache.logging.log4j/log4j-core@2.17.0", + "/packages/log4j-over-slf4j-1.7.36.jar": "pkg:maven/org.slf4j/log4j-over-slf4j@1.7.36", + "/packages/manager-pojo-1.8.0.jar": "pkg:maven/org.apache.inlong/manager-pojo@1.8.0", + "/packages/maven-plugin.hpi": "pkg:maven/org.jenkins-ci.main/maven-plugin@3.10.1", + "/packages/maven-plugin.hpi:WEB-INF/lib/annotations-3.0.1.jar": "pkg:maven/com.google.code.findbugs/annotations@3.0.1", + "/packages/maven-plugin.hpi:WEB-INF/lib/annotations-3.0.1.jar:com.google.code.findbugs:jsr305": "pkg:maven/com.google.code.findbugs/jsr305@3.0.1", + "/packages/maven-plugin.hpi:WEB-INF/lib/cdi-api-1.0.jar": "pkg:maven/javax.enterprise/cdi-api@1.0", + "/packages/maven-plugin.hpi:WEB-INF/lib/commons-cli-1.4.jar": "pkg:maven/commons-cli/commons-cli@1.4", + "/packages/maven-plugin.hpi:WEB-INF/lib/commons-lang3-3.11.jar": "pkg:maven/org.apache.commons/commons-lang3@3.11", + "/packages/maven-plugin.hpi:WEB-INF/lib/commons-net-3.6.jar": "pkg:maven/commons-net/commons-net@3.6", + "/packages/maven-plugin.hpi:WEB-INF/lib/doxia-sink-api-1.0.jar": "pkg:maven/org.apache.maven.doxia/doxia-sink-api@1.0", + "/packages/maven-plugin.hpi:WEB-INF/lib/jackrabbit-webdav-2.14.4.jar": "pkg:maven/org.apache.jackrabbit/jackrabbit-webdav@2.14.4", + "/packages/maven-plugin.hpi:WEB-INF/lib/jcl-over-slf4j-1.7.30.jar": "pkg:maven/org.slf4j/jcl-over-slf4j@1.7.30", + "/packages/maven-plugin.hpi:WEB-INF/lib/jna-platform-4.1.0.jar": "pkg:maven/com.sun.jna.platform/jna-platform@4.1.0", + "/packages/maven-plugin.hpi:WEB-INF/lib/jsch.agentproxy.connector-factory-0.0.9.jar": "pkg:maven/com.jcraft/jsch.agentproxy.connector-factory@0.0.9", + "/packages/maven-plugin.hpi:WEB-INF/lib/jsch.agentproxy.core-0.0.9.jar": "pkg:maven/com.jcraft/jsch.agentproxy.core@0.0.9", + "/packages/maven-plugin.hpi:WEB-INF/lib/jsch.agentproxy.jsch-0.0.9.jar": "pkg:maven/com.jcraft/jsch.agentproxy.jsch@0.0.9", + "/packages/maven-plugin.hpi:WEB-INF/lib/jsch.agentproxy.pageant-0.0.9.jar": "pkg:maven/com.jcraft/jsch.agentproxy.pageant@0.0.9", + "/packages/maven-plugin.hpi:WEB-INF/lib/jsch.agentproxy.sshagent-0.0.9.jar": "pkg:maven/com.jcraft/jsch.agentproxy.sshagent@0.0.9", + "/packages/maven-plugin.hpi:WEB-INF/lib/jsch.agentproxy.usocket-jna-0.0.9.jar": "pkg:maven/com.jcraft/jsch.agentproxy.usocket-jna@0.0.9", + "/packages/maven-plugin.hpi:WEB-INF/lib/jsch.agentproxy.usocket-nc-0.0.9.jar": "pkg:maven/com.jcraft/jsch.agentproxy.usocket-nc@0.0.9", + "/packages/maven-plugin.hpi:WEB-INF/lib/jsoup-1.12.1.jar": "pkg:maven/org.jsoup/jsoup@1.12.1", + "/packages/maven-plugin.hpi:WEB-INF/lib/lib-jenkins-maven-artifact-manager-1.2.jar": "pkg:maven/org.jenkins-ci.lib/lib-jenkins-maven-artifact-manager@1.2", + "/packages/maven-plugin.hpi:WEB-INF/lib/lib-jenkins-maven-embedder-3.15.jar": "pkg:maven/org.jenkins-ci.lib/lib-jenkins-maven-embedder@3.15", + "/packages/maven-plugin.hpi:WEB-INF/lib/maven-agent-1.13.jar": "pkg:maven/org.jenkins-ci.main.maven/maven-agent@1.13", + "/packages/maven-plugin.hpi:WEB-INF/lib/maven-artifact-3.5.4.jar": "pkg:maven/org.apache.maven/maven-artifact@3.5.4", + "/packages/maven-plugin.hpi:WEB-INF/lib/maven-builder-support-3.5.4.jar": "pkg:maven/org.apache.maven/maven-builder-support@3.5.4", + "/packages/maven-plugin.hpi:WEB-INF/lib/maven-compat-3.5.4.jar": "pkg:maven/org.apache.maven/maven-compat@3.5.4", + "/packages/maven-plugin.hpi:WEB-INF/lib/maven-core-3.5.4.jar": "pkg:maven/org.apache.maven/maven-core@3.5.4", + "/packages/maven-plugin.hpi:WEB-INF/lib/maven-embedder-3.5.4.jar": "pkg:maven/org.apache.maven/maven-embedder@3.5.4", + "/packages/maven-plugin.hpi:WEB-INF/lib/maven-interceptor-1.13.jar": "pkg:maven/org.jenkins-ci.main.maven/maven-interceptor@1.13", + "/packages/maven-plugin.hpi:WEB-INF/lib/maven-model-3.5.4.jar": "pkg:maven/org.apache.maven/maven-model@3.5.4", + "/packages/maven-plugin.hpi:WEB-INF/lib/maven-model-builder-3.5.4.jar": "pkg:maven/org.apache.maven/maven-model-builder@3.5.4", + "/packages/maven-plugin.hpi:WEB-INF/lib/maven-plugin-api-3.5.4.jar": "pkg:maven/org.apache.maven/maven-plugin-api@3.5.4", + "/packages/maven-plugin.hpi:WEB-INF/lib/maven-plugin.jar": "pkg:maven/org.jenkins-ci.main/maven-plugin@3.10.1", + "/packages/maven-plugin.hpi:WEB-INF/lib/maven-plugin.jar:classworlds.jar": "pkg:maven/org.codehaus.classworlds/classworlds@1.1", + "/packages/maven-plugin.hpi:WEB-INF/lib/maven-reporting-api-3.0.jar": "pkg:maven/org.apache.maven.reporting/maven-reporting-api@3.0", + "/packages/maven-plugin.hpi:WEB-INF/lib/maven-repository-metadata-3.5.4.jar": "pkg:maven/org.apache.maven/maven-repository-metadata@3.5.4", + "/packages/maven-plugin.hpi:WEB-INF/lib/maven-resolver-api-1.1.1.jar": "pkg:maven/org.apache.maven.resolver/maven-resolver-api@1.1.1", + "/packages/maven-plugin.hpi:WEB-INF/lib/maven-resolver-connector-basic-1.1.1.jar": "pkg:maven/org.apache.maven.resolver/maven-resolver-connector-basic@1.1.1", + "/packages/maven-plugin.hpi:WEB-INF/lib/maven-resolver-impl-1.1.1.jar": "pkg:maven/org.apache.maven.resolver/maven-resolver-impl@1.1.1", + "/packages/maven-plugin.hpi:WEB-INF/lib/maven-resolver-provider-3.5.4.jar": "pkg:maven/org.apache.maven/maven-resolver-provider@3.5.4", + "/packages/maven-plugin.hpi:WEB-INF/lib/maven-resolver-spi-1.1.1.jar": "pkg:maven/org.apache.maven.resolver/maven-resolver-spi@1.1.1", + "/packages/maven-plugin.hpi:WEB-INF/lib/maven-resolver-transport-wagon-1.1.1.jar": "pkg:maven/org.apache.maven.resolver/maven-resolver-transport-wagon@1.1.1", + "/packages/maven-plugin.hpi:WEB-INF/lib/maven-resolver-util-1.1.1.jar": "pkg:maven/org.apache.maven.resolver/maven-resolver-util@1.1.1", + "/packages/maven-plugin.hpi:WEB-INF/lib/maven-settings-3.5.4.jar": "pkg:maven/org.apache.maven/maven-settings@3.5.4", + "/packages/maven-plugin.hpi:WEB-INF/lib/maven-settings-builder-3.5.4.jar": "pkg:maven/org.apache.maven/maven-settings-builder@3.5.4", + "/packages/maven-plugin.hpi:WEB-INF/lib/maven-shared-utils-3.2.1.jar": "pkg:maven/org.apache.maven.shared/maven-shared-utils@3.2.1", + "/packages/maven-plugin.hpi:WEB-INF/lib/maven2.1-interceptor-1.2.jar": "pkg:maven/org.jvnet.hudson/maven2.1-interceptor@1.2", + "/packages/maven-plugin.hpi:WEB-INF/lib/maven3-agent-1.13.jar": "pkg:maven/org.jenkins-ci.main.maven/maven3-agent@1.13", + "/packages/maven-plugin.hpi:WEB-INF/lib/maven3-interceptor-1.13.jar": "pkg:maven/org.jenkins-ci.main.maven/maven3-interceptor@1.13", + "/packages/maven-plugin.hpi:WEB-INF/lib/maven3-interceptor-commons-1.13.jar": "pkg:maven/org.jenkins-ci.main.maven/maven3-interceptor-commons@1.13", + "/packages/maven-plugin.hpi:WEB-INF/lib/maven31-agent-1.13.jar": "pkg:maven/org.jenkins-ci.main.maven/maven31-agent@1.13", + "/packages/maven-plugin.hpi:WEB-INF/lib/maven31-interceptor-1.13.jar": "pkg:maven/org.jenkins-ci.main.maven/maven31-interceptor@1.13", + "/packages/maven-plugin.hpi:WEB-INF/lib/maven32-agent-1.13.jar": "pkg:maven/org.jenkins-ci.main.maven/maven32-agent@1.13", + "/packages/maven-plugin.hpi:WEB-INF/lib/maven32-interceptor-1.13.jar": "pkg:maven/org.jenkins-ci.main.maven/maven32-interceptor@1.13", + "/packages/maven-plugin.hpi:WEB-INF/lib/maven33-agent-1.13.jar": "pkg:maven/org.jenkins-ci.main.maven/maven33-agent@1.13", + "/packages/maven-plugin.hpi:WEB-INF/lib/maven33-interceptor-1.13.jar": "pkg:maven/org.jenkins-ci.main.maven/maven33-interceptor@1.13", + "/packages/maven-plugin.hpi:WEB-INF/lib/maven35-agent-1.13.jar": "pkg:maven/org.jenkins-ci.main.maven/maven35-agent@1.13", + "/packages/maven-plugin.hpi:WEB-INF/lib/maven35-interceptor-1.13.jar": "pkg:maven/org.jenkins-ci.main.maven/maven35-interceptor@1.13", + "/packages/maven-plugin.hpi:WEB-INF/lib/org.eclipse.sisu.inject-0.3.3.jar": "pkg:maven/org.eclipse.sisu.inject/org.eclipse.sisu.inject@0.3.3", + "/packages/maven-plugin.hpi:WEB-INF/lib/org.eclipse.sisu.plexus-0.3.3.jar": "pkg:maven/org.eclipse.sisu.plexus/org.eclipse.sisu.plexus@0.3.3", + "/packages/maven-plugin.hpi:WEB-INF/lib/plexus-cipher-1.8.jar": "pkg:maven/org.codehaus.plexus/plexus-cipher@1.8", + "/packages/maven-plugin.hpi:WEB-INF/lib/plexus-classworlds-2.6.0.jar": "pkg:maven/org.codehaus.plexus/plexus-classworlds@2.6.0", + "/packages/maven-plugin.hpi:WEB-INF/lib/plexus-component-annotations-2.1.0.jar": "pkg:maven/org.codehaus.plexus/plexus-component-annotations@2.1.0", + "/packages/maven-plugin.hpi:WEB-INF/lib/plexus-interactivity-api-1.0.jar": "pkg:maven/org.codehaus.plexus/plexus-interactivity-api@1.0", + "/packages/maven-plugin.hpi:WEB-INF/lib/plexus-interpolation-1.24.jar": "pkg:maven/org.codehaus.plexus/plexus-interpolation@1.24", + "/packages/maven-plugin.hpi:WEB-INF/lib/plexus-sec-dispatcher-1.4.jar": "pkg:maven/org.sonatype.plexus/plexus-sec-dispatcher@1.4", + "/packages/maven-plugin.hpi:WEB-INF/lib/plexus-utils-3.3.0.jar": "pkg:maven/org.codehaus.plexus/plexus-utils@3.3.0", + "/packages/maven-plugin.hpi:WEB-INF/lib/slf4j-api-1.7.30.jar": "pkg:maven/org.slf4j/slf4j-api@1.7.30", + "/packages/maven-plugin.hpi:WEB-INF/lib/wagon-file-3.4.3.jar": "pkg:maven/org.apache.maven.wagon/wagon-file@3.4.3", + "/packages/maven-plugin.hpi:WEB-INF/lib/wagon-ftp-3.4.3.jar": "pkg:maven/org.apache.maven.wagon/wagon-ftp@3.4.3", + "/packages/maven-plugin.hpi:WEB-INF/lib/wagon-http-3.4.3.jar": "pkg:maven/org.apache.maven.wagon/wagon-http@3.4.3", + "/packages/maven-plugin.hpi:WEB-INF/lib/wagon-http-shared-3.4.3.jar": "pkg:maven/org.apache.maven.wagon/wagon-http-shared@3.4.3", + "/packages/maven-plugin.hpi:WEB-INF/lib/wagon-provider-api-3.4.3.jar": "pkg:maven/org.apache.maven.wagon/wagon-provider-api@3.4.3", + "/packages/maven-plugin.hpi:WEB-INF/lib/wagon-ssh-3.4.3.jar": "pkg:maven/org.apache.maven.wagon/wagon-ssh@3.4.3", + "/packages/maven-plugin.hpi:WEB-INF/lib/wagon-ssh-common-3.4.3.jar": "pkg:maven/org.apache.maven.wagon/wagon-ssh-common@3.4.3", + "/packages/maven-plugin.hpi:WEB-INF/lib/wagon-ssh-external-3.4.3.jar": "pkg:maven/org.apache.maven.wagon/wagon-ssh-external@3.4.3", + "/packages/maven-plugin.hpi:WEB-INF/lib/wagon-webdav-jackrabbit-3.4.3.jar": "pkg:maven/org.apache.maven.wagon/wagon-webdav-jackrabbit@3.4.3", "/packages/maven-shared-utils-3.2.1.jar": "pkg:maven/org.apache.maven.shared/maven-shared-utils@3.2.1", "/packages/mesos-1.7.1.jar": "pkg:maven/org.apache.mesos/mesos@1.7.1", "/packages/minio-8.3.8.jar": "pkg:maven/io.minio/minio@8.3.8", "/packages/ms-mcms-5.3.1.jar": "pkg:maven/net.mingsoft/ms-mcms@5.3.1", - "/packages/my-app-1.jar:com.fasterxml:classmate": "pkg:maven/com.fasterxml/classmate@1.5.1", + "/packages/my-app-1.jar": "pkg:maven/com.mycompany.app/my-app@1", "/packages/my-app-1.jar:com.fasterxml.jackson.core:jackson-annotations": "pkg:maven/com.fasterxml.jackson.core/jackson-annotations@2.13.2", "/packages/my-app-1.jar:com.fasterxml.jackson.core:jackson-core": "pkg:maven/com.fasterxml.jackson.core/jackson-core@2.13.2", "/packages/my-app-1.jar:com.fasterxml.jackson.core:jackson-databind": "pkg:maven/com.fasterxml.jackson.core/jackson-databind@2.13.0", + "/packages/my-app-1.jar:com.fasterxml:classmate": "pkg:maven/com.fasterxml/classmate@1.5.1", "/packages/my-app-1.jar:com.google.errorprone:error_prone_annotations": "pkg:maven/com.google.errorprone/error_prone_annotations@2.0.18", "/packages/my-app-1.jar:com.google.guava:guava": "pkg:maven/com.google.guava/guava@23.0", "/packages/my-app-1.jar:com.google.j2objc:j2objc-annotations": "pkg:maven/com.google.j2objc/j2objc-annotations@1.1", @@ -341,23 +707,23 @@ var expectedPURLs = map[string]string{ "/packages/my-app-1.jar:commons-logging:commons-logging": "pkg:maven/commons-logging/commons-logging@1.2", "/packages/my-app-1.jar:commons-validator:commons-validator": "pkg:maven/commons-validator/commons-validator@1.5.1", "/packages/my-app-1.jar:io.netty:netty-buffer": "pkg:maven/io.netty/netty-buffer@4.1.52.Final", + "/packages/my-app-1.jar:io.netty:netty-codec": "pkg:maven/io.netty/netty-codec@4.1.52.Final", "/packages/my-app-1.jar:io.netty:netty-codec-dns": "pkg:maven/io.netty/netty-codec-dns@4.1.63.Final", "/packages/my-app-1.jar:io.netty:netty-codec-http": "pkg:maven/io.netty/netty-codec-http@4.1.63.Final", "/packages/my-app-1.jar:io.netty:netty-codec-socks": "pkg:maven/io.netty/netty-codec-socks@4.1.63.Final", - "/packages/my-app-1.jar:io.netty:netty-codec": "pkg:maven/io.netty/netty-codec@4.1.52.Final", "/packages/my-app-1.jar:io.netty:netty-common": "pkg:maven/io.netty/netty-common@4.1.52.Final", - "/packages/my-app-1.jar:io.netty:netty-handler-proxy": "pkg:maven/io.netty/netty-handler-proxy@4.1.63.Final", "/packages/my-app-1.jar:io.netty:netty-handler": "pkg:maven/io.netty/netty-handler@4.1.52.Final", - "/packages/my-app-1.jar:io.netty:netty-resolver-dns-native-macos": "pkg:maven/io.netty/netty-resolver-dns-native-macos@4.1.63.Final", - "/packages/my-app-1.jar:io.netty:netty-resolver-dns": "pkg:maven/io.netty/netty-resolver-dns@4.1.63.Final", + "/packages/my-app-1.jar:io.netty:netty-handler-proxy": "pkg:maven/io.netty/netty-handler-proxy@4.1.63.Final", "/packages/my-app-1.jar:io.netty:netty-resolver": "pkg:maven/io.netty/netty-resolver@4.1.52.Final", + "/packages/my-app-1.jar:io.netty:netty-resolver-dns": "pkg:maven/io.netty/netty-resolver-dns@4.1.63.Final", + "/packages/my-app-1.jar:io.netty:netty-resolver-dns-native-macos": "pkg:maven/io.netty/netty-resolver-dns-native-macos@4.1.63.Final", + "/packages/my-app-1.jar:io.netty:netty-transport": "pkg:maven/io.netty/netty-transport@4.1.52.Final", "/packages/my-app-1.jar:io.netty:netty-transport-native-epoll": "pkg:maven/io.netty/netty-transport-native-epoll@4.1.63.Final", "/packages/my-app-1.jar:io.netty:netty-transport-native-unix-common": "pkg:maven/io.netty/netty-transport-native-unix-common@4.1.63.Final", - "/packages/my-app-1.jar:io.netty:netty-transport": "pkg:maven/io.netty/netty-transport@4.1.52.Final", - "/packages/my-app-1.jar:io.prometheus:simpleclient_common": "pkg:maven/io.prometheus/simpleclient_common@0.9.0", "/packages/my-app-1.jar:io.prometheus:simpleclient": "pkg:maven/io.prometheus/simpleclient@0.9.0", - "/packages/my-app-1.jar:io.vavr:vavr-match": "pkg:maven/io.vavr/vavr-match@0.10.2", + "/packages/my-app-1.jar:io.prometheus:simpleclient_common": "pkg:maven/io.prometheus/simpleclient_common@0.9.0", "/packages/my-app-1.jar:io.vavr:vavr": "pkg:maven/io.vavr/vavr@0.10.2", + "/packages/my-app-1.jar:io.vavr:vavr-match": "pkg:maven/io.vavr/vavr-match@0.10.2", "/packages/my-app-1.jar:jakarta.validation:jakarta.validation-api": "pkg:maven/jakarta.validation/jakarta.validation-api@2.0.2", "/packages/my-app-1.jar:javax.servlet:javax.servlet-api": "pkg:maven/javax.servlet/javax.servlet-api@3.1.0", "/packages/my-app-1.jar:org.apache.activemq.protobuf:activemq-protobuf": "pkg:maven/org.apache.activemq.protobuf/activemq-protobuf@1.1", @@ -365,14 +731,14 @@ var expectedPURLs = map[string]string{ "/packages/my-app-1.jar:org.apache.commons:commons-lang3": "pkg:maven/org.apache.commons/commons-lang3@3.10", "/packages/my-app-1.jar:org.apache.maven.shared:maven-shared-utils": "pkg:maven/org.apache.maven.shared/maven-shared-utils@3.3.4", "/packages/my-app-1.jar:org.codehaus.mojo:animal-sniffer-annotations": "pkg:maven/org.codehaus.mojo/animal-sniffer-annotations@1.14", + "/packages/my-app-1.jar:org.eclipse.jetty.http2:http2-common": "pkg:maven/org.eclipse.jetty.http2/http2-common@9.4.43.v20210629", + "/packages/my-app-1.jar:org.eclipse.jetty.http2:http2-hpack": "pkg:maven/org.eclipse.jetty.http2/http2-hpack@9.4.43.v20210629", + "/packages/my-app-1.jar:org.eclipse.jetty.toolchain.setuid:jetty-setuid-java": "pkg:maven/org.eclipse.jetty.toolchain.setuid/jetty-setuid-java@1.0.4", "/packages/my-app-1.jar:org.eclipse.jetty:jetty-client": "pkg:maven/org.eclipse.jetty/jetty-client@9.4.43.v20210629", "/packages/my-app-1.jar:org.eclipse.jetty:jetty-http": "pkg:maven/org.eclipse.jetty/jetty-http@9.4.43.v20210629", "/packages/my-app-1.jar:org.eclipse.jetty:jetty-io": "pkg:maven/org.eclipse.jetty/jetty-io@9.4.43.v20210629", "/packages/my-app-1.jar:org.eclipse.jetty:jetty-server": "pkg:maven/org.eclipse.jetty/jetty-server@9.1.0.M0", "/packages/my-app-1.jar:org.eclipse.jetty:jetty-util": "pkg:maven/org.eclipse.jetty/jetty-util@9.4.43.v20210629", - "/packages/my-app-1.jar:org.eclipse.jetty.http2:http2-common": "pkg:maven/org.eclipse.jetty.http2/http2-common@9.4.43.v20210629", - "/packages/my-app-1.jar:org.eclipse.jetty.http2:http2-hpack": "pkg:maven/org.eclipse.jetty.http2/http2-hpack@9.4.43.v20210629", - "/packages/my-app-1.jar:org.eclipse.jetty.toolchain.setuid:jetty-setuid-java": "pkg:maven/org.eclipse.jetty.toolchain.setuid/jetty-setuid-java@1.0.4", "/packages/my-app-1.jar:org.everit.json:org.everit.json.schema": "pkg:maven/org.everit.json/org.everit.json.schema@1.5.1", "/packages/my-app-1.jar:org.hibernate.validator:hibernate-validator": "pkg:maven/org.hibernate.validator/hibernate-validator@6.2.4.Final", "/packages/my-app-1.jar:org.jboss.logging:jboss-logging": "pkg:maven/org.jboss.logging/jboss-logging@3.4.1.Final", @@ -388,9 +754,9 @@ var expectedPURLs = map[string]string{ "/packages/my-app-1.jar:org.sonarsource.python:python-checks": "pkg:maven/org.sonarsource.python/python-checks@3.4.1.8066", "/packages/my-app-1.jar:org.sonarsource.python:python-frontend": "pkg:maven/org.sonarsource.python/python-frontend@3.4.1.8066", "/packages/my-app-1.jar:org.sonarsource.sslr:sslr-core": "pkg:maven/org.sonarsource.sslr/sslr-core@1.24.0.633", - "/packages/my-app-1.jar": "pkg:maven/com.mycompany.app/my-app@1", "/packages/netty-reactive-streams-2.0.6.jar": "pkg:maven/com.typesafe.netty/netty-reactive-streams@2.0.6", "/packages/nifi-utils-1.12.0.jar": "pkg:maven/org.apache.nifi/nifi-utils@1.12.0", + "/packages/nomad.hpi": "pkg:maven/org.jenkins-ci.plugins/nomad@0.7.4", "/packages/nomad.hpi:WEB-INF/lib/annotations-13.0.jar": "pkg:maven/org.jetbrains/annotations@13.0", "/packages/nomad.hpi:WEB-INF/lib/gson-2.8.6.jar": "pkg:maven/com.google.code.gson/gson@2.8.6", "/packages/nomad.hpi:WEB-INF/lib/json-20200518.jar": "pkg:maven/org.json/json@20200518", @@ -399,186 +765,197 @@ var expectedPURLs = map[string]string{ "/packages/nomad.hpi:WEB-INF/lib/nomad.jar": "pkg:maven/org.jenkins-ci.plugins/nomad@0.7.4", "/packages/nomad.hpi:WEB-INF/lib/okhttp-4.5.0.jar": "pkg:maven/com.squareup.okhttp3/okhttp@4.5.0", "/packages/nomad.hpi:WEB-INF/lib/okio-2.5.0.jar": "pkg:maven/com.squareup.okio/okio@2.5.0", - "/packages/nomad.hpi": "pkg:maven/org.jenkins-ci.plugins/nomad@0.7.4", - "/packages/openmeetings-util-4.0.9.jar": "pkg:maven/org.apache.openmeetings/openmeetings-util@4.0.9", - "/packages/org.eclipse.ant.core-3.7.0.jar": "pkg:maven/org.eclipse.platform/org.eclipse.ant.core@3.7.0", - "/packages/org.eclipse.osgi-3.18.0.jar": "pkg:maven/org.eclipse.platform/org.eclipse.osgi@3.18.0", - "/packages/org.everit.json.schema-1.5.1.jar": "pkg:maven/org.everit.json/org.everit.json.schema@1.5.1", - "/packages/original-my-app-1.jar:com.fasterxml:classmate": "pkg:maven/com.fasterxml/classmate@1.5.1", - "/packages/original-my-app-1.jar:com.fasterxml.jackson.core:jackson-annotations": "pkg:maven/com.fasterxml.jackson.core/jackson-annotations@2.13.2", - "/packages/original-my-app-1.jar:com.fasterxml.jackson.core:jackson-core": "pkg:maven/com.fasterxml.jackson.core/jackson-core@2.13.2", - "/packages/original-my-app-1.jar:com.fasterxml.jackson.core:jackson-databind": "pkg:maven/com.fasterxml.jackson.core/jackson-databind@2.13.0", - "/packages/original-my-app-1.jar:com.google.errorprone:error_prone_annotations": "pkg:maven/com.google.errorprone/error_prone_annotations@2.0.18", - "/packages/original-my-app-1.jar:com.google.guava:guava": "pkg:maven/com.google.guava/guava@23.0", - "/packages/original-my-app-1.jar:com.google.j2objc:j2objc-annotations": "pkg:maven/com.google.j2objc/j2objc-annotations@1.1", - "/packages/original-my-app-1.jar:com.hazelcast:hazelcast-kubernetes": "pkg:maven/com.hazelcast/hazelcast-kubernetes@1.5.4", - "/packages/original-my-app-1.jar:com.hierynomus:asn-one": "pkg:maven/com.hierynomus/asn-one@0.5.0", - "/packages/original-my-app-1.jar:com.typesafe.netty:netty-reactive-streams": "pkg:maven/com.typesafe.netty/netty-reactive-streams@2.0.5", - "/packages/original-my-app-1.jar:commons-beanutils:commons-beanutils": "pkg:maven/commons-beanutils/commons-beanutils@1.9.2", - "/packages/original-my-app-1.jar:commons-collections:commons-collections": "pkg:maven/commons-collections/commons-collections@3.2.2", - "/packages/original-my-app-1.jar:commons-digester:commons-digester": "pkg:maven/commons-digester/commons-digester@1.8.1", - "/packages/original-my-app-1.jar:commons-io:commons-io": "pkg:maven/commons-io/commons-io@2.8.0", - "/packages/original-my-app-1.jar:commons-logging:commons-logging": "pkg:maven/commons-logging/commons-logging@1.2", - "/packages/original-my-app-1.jar:commons-validator:commons-validator": "pkg:maven/commons-validator/commons-validator@1.5.1", - "/packages/original-my-app-1.jar:io.netty:netty-buffer": "pkg:maven/io.netty/netty-buffer@4.1.52.Final", - "/packages/original-my-app-1.jar:io.netty:netty-codec-dns": "pkg:maven/io.netty/netty-codec-dns@4.1.63.Final", - "/packages/original-my-app-1.jar:io.netty:netty-codec-http": "pkg:maven/io.netty/netty-codec-http@4.1.63.Final", - "/packages/original-my-app-1.jar:io.netty:netty-codec-socks": "pkg:maven/io.netty/netty-codec-socks@4.1.63.Final", - "/packages/original-my-app-1.jar:io.netty:netty-codec": "pkg:maven/io.netty/netty-codec@4.1.52.Final", - "/packages/original-my-app-1.jar:io.netty:netty-common": "pkg:maven/io.netty/netty-common@4.1.52.Final", - "/packages/original-my-app-1.jar:io.netty:netty-handler-proxy": "pkg:maven/io.netty/netty-handler-proxy@4.1.63.Final", - "/packages/original-my-app-1.jar:io.netty:netty-handler": "pkg:maven/io.netty/netty-handler@4.1.52.Final", - "/packages/original-my-app-1.jar:io.netty:netty-resolver-dns-native-macos": "pkg:maven/io.netty/netty-resolver-dns-native-macos@4.1.63.Final", - "/packages/original-my-app-1.jar:io.netty:netty-resolver-dns": "pkg:maven/io.netty/netty-resolver-dns@4.1.63.Final", - "/packages/original-my-app-1.jar:io.netty:netty-resolver": "pkg:maven/io.netty/netty-resolver@4.1.52.Final", - "/packages/original-my-app-1.jar:io.netty:netty-transport-native-epoll": "pkg:maven/io.netty/netty-transport-native-epoll@4.1.63.Final", - "/packages/original-my-app-1.jar:io.netty:netty-transport-native-unix-common": "pkg:maven/io.netty/netty-transport-native-unix-common@4.1.63.Final", - "/packages/original-my-app-1.jar:io.netty:netty-transport": "pkg:maven/io.netty/netty-transport@4.1.52.Final", - "/packages/original-my-app-1.jar:io.prometheus:simpleclient_common": "pkg:maven/io.prometheus/simpleclient_common@0.9.0", - "/packages/original-my-app-1.jar:io.prometheus:simpleclient": "pkg:maven/io.prometheus/simpleclient@0.9.0", - "/packages/original-my-app-1.jar:io.vavr:vavr-match": "pkg:maven/io.vavr/vavr-match@0.10.2", - "/packages/original-my-app-1.jar:io.vavr:vavr": "pkg:maven/io.vavr/vavr@0.10.2", - "/packages/original-my-app-1.jar:jakarta.validation:jakarta.validation-api": "pkg:maven/jakarta.validation/jakarta.validation-api@2.0.2", - "/packages/original-my-app-1.jar:javax.servlet:javax.servlet-api": "pkg:maven/javax.servlet/javax.servlet-api@3.1.0", - "/packages/original-my-app-1.jar:org.apache.activemq.protobuf:activemq-protobuf": "pkg:maven/org.apache.activemq.protobuf/activemq-protobuf@1.1", - "/packages/original-my-app-1.jar:org.apache.commons:commons-compress": "pkg:maven/org.apache.commons/commons-compress@1.21", - "/packages/original-my-app-1.jar:org.apache.commons:commons-lang3": "pkg:maven/org.apache.commons/commons-lang3@3.10", - "/packages/original-my-app-1.jar:org.apache.maven.shared:maven-shared-utils": "pkg:maven/org.apache.maven.shared/maven-shared-utils@3.3.4", - "/packages/original-my-app-1.jar:org.codehaus.mojo:animal-sniffer-annotations": "pkg:maven/org.codehaus.mojo/animal-sniffer-annotations@1.14", - "/packages/original-my-app-1.jar:org.eclipse.jetty:jetty-client": "pkg:maven/org.eclipse.jetty/jetty-client@9.4.43.v20210629", - "/packages/original-my-app-1.jar:org.eclipse.jetty:jetty-http": "pkg:maven/org.eclipse.jetty/jetty-http@9.4.43.v20210629", - "/packages/original-my-app-1.jar:org.eclipse.jetty:jetty-io": "pkg:maven/org.eclipse.jetty/jetty-io@9.4.43.v20210629", - "/packages/original-my-app-1.jar:org.eclipse.jetty:jetty-server": "pkg:maven/org.eclipse.jetty/jetty-server@9.1.0.M0", - "/packages/original-my-app-1.jar:org.eclipse.jetty:jetty-util": "pkg:maven/org.eclipse.jetty/jetty-util@9.4.43.v20210629", - "/packages/original-my-app-1.jar:org.eclipse.jetty.http2:http2-common": "pkg:maven/org.eclipse.jetty.http2/http2-common@9.4.43.v20210629", - "/packages/original-my-app-1.jar:org.eclipse.jetty.http2:http2-hpack": "pkg:maven/org.eclipse.jetty.http2/http2-hpack@9.4.43.v20210629", - "/packages/original-my-app-1.jar:org.eclipse.jetty.toolchain.setuid:jetty-setuid-java": "pkg:maven/org.eclipse.jetty.toolchain.setuid/jetty-setuid-java@1.0.4", - "/packages/original-my-app-1.jar:org.everit.json:org.everit.json.schema": "pkg:maven/org.everit.json/org.everit.json.schema@1.5.1", - "/packages/original-my-app-1.jar:org.hibernate.validator:hibernate-validator": "pkg:maven/org.hibernate.validator/hibernate-validator@6.2.4.Final", - "/packages/original-my-app-1.jar:org.jboss.logging:jboss-logging": "pkg:maven/org.jboss.logging/jboss-logging@3.4.1.Final", - "/packages/original-my-app-1.jar:org.jctools:jctools-core": "pkg:maven/org.jctools/jctools-core@3.1.0", - "/packages/original-my-app-1.jar:org.jetbrains:annotations": "pkg:maven/org.jetbrains/annotations@13.0", - "/packages/original-my-app-1.jar:org.json:json": "pkg:maven/org.json/json@20160810", - "/packages/original-my-app-1.jar:org.kohsuke:github-api": "pkg:maven/org.kohsuke/github-api@1.301", - "/packages/original-my-app-1.jar:org.slf4j:log4j-over-slf4j": "pkg:maven/org.slf4j/log4j-over-slf4j@1.7.33", - "/packages/original-my-app-1.jar:org.slf4j:slf4j-api": "pkg:maven/org.slf4j/slf4j-api@1.7.33", - "/packages/original-my-app-1.jar:org.sonarsource.analyzer-commons:sonar-analyzer-test-commons": "pkg:maven/org.sonarsource.analyzer-commons/sonar-analyzer-test-commons@1.14.1.690", - "/packages/original-my-app-1.jar:org.sonarsource.php:php-checks": "pkg:maven/org.sonarsource.php/php-checks@3.17.0.7439", - "/packages/original-my-app-1.jar:org.sonarsource.php:php-frontend": "pkg:maven/org.sonarsource.php/php-frontend@3.17.0.7439", - "/packages/original-my-app-1.jar:org.sonarsource.python:python-checks": "pkg:maven/org.sonarsource.python/python-checks@3.4.1.8066", - "/packages/original-my-app-1.jar:org.sonarsource.python:python-frontend": "pkg:maven/org.sonarsource.python/python-frontend@3.4.1.8066", - "/packages/original-my-app-1.jar:org.sonarsource.sslr:sslr-core": "pkg:maven/org.sonarsource.sslr/sslr-core@1.24.0.633", - "/packages/original-my-app-1.jar": "pkg:maven/com.mycompany.app/my-app@1", - "/packages/php-frontend-3.9.0.6331.jar": "pkg:maven/org.sonarsource.php/php-frontend@3.9.0.6331", - "/packages/postgresql-42.5.0.jar": "pkg:maven/org.postgresql/postgresql@42.5.0", - "/packages/protobuf-java-3.21.6.jar": "pkg:maven/com.google.protobuf/protobuf-java@3.21.6", - "/packages/python-frontend-3.24.0.10784.jar": "pkg:maven/org.sonarsource.python/python-frontend@3.24.0.10784", - "/packages/ratpack-core-1.8.2.jar": "pkg:maven/io.ratpack/ratpack-core@1.8.2", - "/packages/reactor-netty-core-1.0.35.jar": "pkg:maven/io.projectreactor.netty/reactor-netty-core@1.0.35", - "/packages/reactor-netty-http-1.1.9.jar": "pkg:maven/io.projectreactor.netty/reactor-netty-http@1.1.9", - "/packages/reactor-netty-incubator-quic-0.1.3.jar": "pkg:maven/io.projectreactor.netty.incubator/reactor-netty-incubator-quic@0.1.3", - "/packages/resilience4j-prometheus-0.17.0.jar": "pkg:maven/io.github.resilience4j.prometheus/resilience4j-prometheus@0.17.0", - "/packages/shiro-core-1.9.1.jar": "pkg:maven/org.apache.shiro/shiro-core@1.9.1", - "/packages/solr-core-8.8.1.jar": "pkg:maven/org.apache.solr/solr-core@8.8.1", - "/packages/spring-amqp-2.4.17.jar": "pkg:maven/org.springframework.amqp/spring-amqp@2.4.17", - "/packages/spring-analytics-2.0.0.RELEASE.jar": "pkg:maven/org.springframework.analytics/spring-analytics@2.0.0.RELEASE", - "/packages/spring-asm-3.0.7.RELEASE.jar": "pkg:maven/org.springframework/spring-asm@3.0.7.RELEASE", - "/packages/spring-batch-core-4.2.1.RELEASE.jar": "pkg:maven/org.springframework.batch/spring-batch-core@4.2.1.RELEASE", - "/packages/spring-boot-3.1.2.jar": "pkg:maven/org.springframework.boot/spring-boot@3.1.2", - "/packages/spring-cloud-app-broker-core-1.6.1.jar": "pkg:maven/org.springframework.cloud/spring-cloud-app-broker-core@1.6.1", - "/packages/spring-cql-1.5.11.RELEASE.jar": "pkg:maven/org.springframework.data/spring-cql@1.5.11.RELEASE", - "/packages/spring-credhub-core-1.0.1.RELEASE.jar": "pkg:maven/org.springframework.credhub/spring-credhub-core@1.0.1.RELEASE", - "/packages/spring-flex-1.0.3.RELEASE.jar": "pkg:maven/org.springframework.flex/spring-flex@1.0.3.RELEASE", - "/packages/spring-graphql-1.2.2.jar": "pkg:maven/org.springframework.graphql/spring-graphql@1.2.2", - "/packages/spring-hateoas-2.1.0.jar": "pkg:maven/org.springframework.hateoas/spring-hateoas@2.1.0", - "/packages/spring-integration-amqp-6.0.5.jar": "pkg:maven/org.springframework.integration/spring-integration-amqp@6.0.5", - "/packages/spring-kafka-3.0.9.jar": "pkg:maven/org.springframework.kafka/spring-kafka@3.0.9", - "/packages/spring-security-core-6.0.2.jar": "pkg:maven/org.springframework.security/spring-security-core@6.0.2", - "/packages/spring-security-kerberos-core-1.0.1.RELEASE.jar": "pkg:maven/org.springframework.security.kerberos/spring-security-kerberos-core@1.0.1.RELEASE", - "/packages/spring-security-oauth-2.5.1.RELEASE.jar": "pkg:maven/org.springframework.security.oauth/spring-security-oauth@2.5.1.RELEASE", - "/packages/spring-security-oauth2-autoconfigure-2.5.9.jar": "pkg:maven/org.springframework.security.oauth.boot/spring-security-oauth2-autoconfigure@2.5.9", - "/packages/spring-security-saml2-core-1.0.10.RELEASE.jar": "pkg:maven/org.springframework.security.extensions/spring-security-saml2-core@1.0.10.RELEASE", - "/packages/spring-session-core-3.0.0.jar": "pkg:maven/org.springframework.session/spring-session-core@3.0.0", - "/packages/spring-social-core-1.1.2.RELEASE.jar": "pkg:maven/org.springframework.social/spring-social-core@1.1.2.RELEASE", - "/packages/spring-vault-core-3.0.1.jar": "pkg:maven/org.springframework.vault/spring-vault-core@3.0.1", - "/packages/spring-webmvc-3.1.4.RELEASE.jar": "pkg:maven/org.springframework/spring-webmvc@3.1.4.RELEASE", - "/packages/spring-xml-3.0.3.RELEASE.jar": "pkg:maven/org.springframework.ws/spring-xml@3.0.3.RELEASE", - "/packages/storm-core-1.2.2.jar:cheshire:cheshire": "pkg:maven/cheshire/cheshire@5.3.1", - "/packages/storm-core-1.2.2.jar:clj-time:clj-time": "pkg:maven/clj-time/clj-time@0.8.0", - "/packages/storm-core-1.2.2.jar:clout:clout": "pkg:maven/clout/clout@1.2.0", - "/packages/storm-core-1.2.2.jar:com.fasterxml.jackson.core:jackson-core": "pkg:maven/com.fasterxml.jackson.core/jackson-core@2.9.4", - "/packages/storm-core-1.2.2.jar:com.fasterxml.jackson.dataformat:jackson-dataformat-smile": "pkg:maven/com.fasterxml.jackson.dataformat/jackson-dataformat-smile@2.9.4", - "/packages/storm-core-1.2.2.jar:com.google.guava:guava": "pkg:maven/com.google.guava/guava@16.0.1", - "/packages/storm-core-1.2.2.jar:com.twitter:carbonite": "pkg:maven/com.twitter/carbonite@1.5.0", - "/packages/storm-core-1.2.2.jar:commons-codec:commons-codec": "pkg:maven/commons-codec/commons-codec@1.6", - "/packages/storm-core-1.2.2.jar:commons-collections:commons-collections": "pkg:maven/commons-collections/commons-collections@3.2.2", - "/packages/storm-core-1.2.2.jar:commons-fileupload:commons-fileupload": "pkg:maven/commons-fileupload/commons-fileupload@1.3.2", - "/packages/storm-core-1.2.2.jar:commons-io:commons-io": "pkg:maven/commons-io/commons-io@2.5", - "/packages/storm-core-1.2.2.jar:commons-lang:commons-lang": "pkg:maven/commons-lang/commons-lang@2.5", - "/packages/storm-core-1.2.2.jar:compojure:compojure": "pkg:maven/compojure/compojure@1.1.9", - "/packages/storm-core-1.2.2.jar:hiccup:hiccup": "pkg:maven/hiccup/hiccup@0.3.6", - "/packages/storm-core-1.2.2.jar:io.netty:netty": "pkg:maven/io.netty/netty@3.9.9.Final", - "/packages/storm-core-1.2.2.jar:joda-time:joda-time": "pkg:maven/joda-time/joda-time@2.3", - "/packages/storm-core-1.2.2.jar:metrics-clojure:metrics-clojure": "pkg:maven/metrics-clojure/metrics-clojure@2.5.1", - "/packages/storm-core-1.2.2.jar:ns-tracker:ns-tracker": "pkg:maven/ns-tracker/ns-tracker@0.2.2", - "/packages/storm-core-1.2.2.jar:org.apache.commons:commons-compress": "pkg:maven/org.apache.commons/commons-compress@1.4.1", - "/packages/storm-core-1.2.2.jar:org.apache.commons:commons-exec": "pkg:maven/org.apache.commons/commons-exec@1.1", - "/packages/storm-core-1.2.2.jar:org.apache.curator:curator-client": "pkg:maven/org.apache.curator/curator-client@4.0.1", - "/packages/storm-core-1.2.2.jar:org.apache.curator:curator-framework": "pkg:maven/org.apache.curator/curator-framework@4.0.1", - "/packages/storm-core-1.2.2.jar:org.apache.curator:curator-recipes": "pkg:maven/org.apache.curator/curator-recipes@4.0.1", - "/packages/storm-core-1.2.2.jar:org.apache.hadoop:hadoop-auth": "pkg:maven/org.apache.hadoop/hadoop-auth@2.6.1", - "/packages/storm-core-1.2.2.jar:org.apache.httpcomponents:httpclient": "pkg:maven/org.apache.httpcomponents/httpclient@4.3.3", - "/packages/storm-core-1.2.2.jar:org.apache.httpcomponents:httpcore": "pkg:maven/org.apache.httpcomponents/httpcore@4.4.1", - "/packages/storm-core-1.2.2.jar:org.clojure:java.jmx": "pkg:maven/org.clojure/java.jmx@0.3.1", - "/packages/storm-core-1.2.2.jar:org.clojure:math.numeric-tower": "pkg:maven/org.clojure/math.numeric-tower@0.0.1", - "/packages/storm-core-1.2.2.jar:org.clojure:tools.cli": "pkg:maven/org.clojure/tools.cli@0.2.4", - "/packages/storm-core-1.2.2.jar:org.clojure:tools.logging": "pkg:maven/org.clojure/tools.logging@0.2.3", - "/packages/storm-core-1.2.2.jar:org.clojure:tools.macro": "pkg:maven/org.clojure/tools.macro@0.1.0", - "/packages/storm-core-1.2.2.jar:org.clojure:tools.namespace": "pkg:maven/org.clojure/tools.namespace@0.2.4", - "/packages/storm-core-1.2.2.jar:org.eclipse.jetty:jetty-client": "pkg:maven/org.eclipse.jetty/jetty-client@7.6.13.v20130916", - "/packages/storm-core-1.2.2.jar:org.eclipse.jetty:jetty-continuation": "pkg:maven/org.eclipse.jetty/jetty-continuation@7.6.13.v20130916", - "/packages/storm-core-1.2.2.jar:org.eclipse.jetty:jetty-http": "pkg:maven/org.eclipse.jetty/jetty-http@7.6.13.v20130916", - "/packages/storm-core-1.2.2.jar:org.eclipse.jetty:jetty-io": "pkg:maven/org.eclipse.jetty/jetty-io@7.6.13.v20130916", - "/packages/storm-core-1.2.2.jar:org.eclipse.jetty:jetty-security": "pkg:maven/org.eclipse.jetty/jetty-security@7.6.13.v20130916", - "/packages/storm-core-1.2.2.jar:org.eclipse.jetty:jetty-server": "pkg:maven/org.eclipse.jetty/jetty-server@7.6.13.v20130916", - "/packages/storm-core-1.2.2.jar:org.eclipse.jetty:jetty-servlet": "pkg:maven/org.eclipse.jetty/jetty-servlet@7.6.13.v20130916", - "/packages/storm-core-1.2.2.jar:org.eclipse.jetty:jetty-servlets": "pkg:maven/org.eclipse.jetty/jetty-servlets@7.6.13.v20130916", - "/packages/storm-core-1.2.2.jar:org.eclipse.jetty:jetty-util": "pkg:maven/org.eclipse.jetty/jetty-util@7.6.13.v20130916", - "/packages/storm-core-1.2.2.jar:org.jgrapht:jgrapht-core": "pkg:maven/org.jgrapht/jgrapht-core@0.9.0", - "/packages/storm-core-1.2.2.jar:org.yaml:snakeyaml": "pkg:maven/org.yaml/snakeyaml@1.11", - "/packages/storm-core-1.2.2.jar:ring:ring-codec": "pkg:maven/ring/ring-codec@1.0.0", - "/packages/storm-core-1.2.2.jar:ring:ring-core": "pkg:maven/ring/ring-core@1.3.1", - "/packages/storm-core-1.2.2.jar:ring:ring-devel": "pkg:maven/ring/ring-devel@1.3.1", - "/packages/storm-core-1.2.2.jar:ring:ring-jetty-adapter": "pkg:maven/ring/ring-jetty-adapter@1.3.1", - "/packages/storm-core-1.2.2.jar:ring:ring-json": "pkg:maven/ring/ring-json@0.3.1", - "/packages/storm-core-1.2.2.jar:ring:ring-servlet": "pkg:maven/ring/ring-servlet@1.3.1", - "/packages/storm-core-1.2.2.jar": "pkg:maven/org.apache.storm/storm-core@1.2.2", - "/packages/tapestry-core-5.8.1.jar": "pkg:maven/org.apache.tapestry/tapestry-core@5.8.1", - "/packages/tika-core-1.26.jar": "pkg:maven/org.apache.tika/tika-core@1.26", - "/packages/tomcat-catalina-11.0.0-M1.jar": "pkg:maven/org.apache.tomcat/tomcat-catalina@11.0.0-M1", - "/packages/tomcat-embed-core-11.0.0-M7.jar": "pkg:maven/org.apache.tomcat.embed/tomcat-embed-core@11.0.0-M7", - "/packages/TwilioNotifier.hpi:WEB-INF/lib/commons-codec-1.2.jar": "pkg:maven/commons-codec/commons-codec@1.2", - "/packages/TwilioNotifier.hpi:WEB-INF/lib/commons-httpclient-3.1.jar": "pkg:maven/org.apache/commons-httpclient@3.1", - "/packages/TwilioNotifier.hpi:WEB-INF/lib/commons-logging-1.0.4.jar": "pkg:maven/commons-logging/commons-logging@1.0.4", - "/packages/TwilioNotifier.hpi:WEB-INF/lib/log4j-1.2.9.jar": "pkg:maven/log4j/log4j@1.2.9", - "/packages/TwilioNotifier.hpi:WEB-INF/lib/sdk-3.0.jar:commons-codec:commons-codec": "pkg:maven/commons-codec/commons-codec@1.4", - "/packages/TwilioNotifier.hpi:WEB-INF/lib/sdk-3.0.jar:commons-lang:commons-lang": "pkg:maven/commons-lang/commons-lang@2.5", - "/packages/TwilioNotifier.hpi:WEB-INF/lib/sdk-3.0.jar:commons-logging:commons-logging": "pkg:maven/commons-logging/commons-logging@1.1.1", - "/packages/TwilioNotifier.hpi:WEB-INF/lib/sdk-3.0.jar:org.apache.httpcomponents:httpclient": "pkg:maven/org.apache.httpcomponents/httpclient@4.1.1", - "/packages/TwilioNotifier.hpi:WEB-INF/lib/sdk-3.0.jar:org.apache.httpcomponents:httpcore": "pkg:maven/org.apache.httpcomponents/httpcore@4.1", - "/packages/TwilioNotifier.hpi:WEB-INF/lib/sdk-3.0.jar:org.easymock:easymock": "pkg:maven/org.easymock/easymock@2.4", - "/packages/TwilioNotifier.hpi": "pkg:maven/com.twilio.jenkins/TwilioNotifier@0.2.1", - "/packages/undertow-core-2.3.4.Final.jar": "pkg:maven/io.undertow/undertow-core@2.3.4.Final", - "/packages/vaadin-client-8.11.3.jar": "pkg:maven/com.vaadin/vaadin-client@8.11.3", - "/packages/velocity-1.7.jar": "pkg:maven/org.apache.velocity/velocity@1.7", - "/packages/vertx-web-4.3.7.jar": "pkg:maven/io.vertx/vertx-web@4.3.7", - "/packages/wicket-core-9.2.0.jar": "pkg:maven/org.apache.wicket/wicket-core@9.2.0", - "/packages/xalan-2.7.2.jar": "pkg:maven/xalan/xalan@2.7.2", - "/packages/xmlpull-1.1.3.1.jar": "pkg:maven/xmlpull/xmlpull@1.1.3.1", - // "/packages/xpp3_min-1.1.4c.jar": "pkg:maven/xpp3/xpp3_min@1.1.4c", - "/packages/xstream-1.4.11.1.jar": "pkg:maven/com.thoughtworks.xstream/xstream@1.4.11.1", - "/packages/xstream-1.4.19.jar": "pkg:maven/com.thoughtworks.xstream/xstream@1.4.19", - "/packages/xwiki-commons-xml-15.1.jar": "pkg:maven/org.xwiki.commons/xwiki-commons-xml@15.1", - "/packages/xwiki-platform-oldcore-15.3.jar": "pkg:maven/org.xwiki.platform/xwiki-platform-oldcore@15.3", - "/packages/zookeeper-3.7.1.jar": "pkg:maven/org.apache.zookeeper/zookeeper@3.7.1", + "/packages/nuget.hpi": "pkg:maven/org.jenkins-ci.plugins/nuget@1.0", + "/packages/nuget.hpi:WEB-INF/lib/envinject-lib-1.19.jar": "pkg:maven/org.jenkins-ci.lib/envinject-lib@1.19", + "/packages/nuget.hpi:WEB-INF/lib/nuget.jar": "pkg:maven/org.jenkins-ci.plugins/nuget@1.0", + "/packages/nuget.hpi:WEB-INF/lib/xtrigger-lib-0.33.jar": "pkg:maven/org.jenkins-ci.lib/xtrigger-lib@0.33", + "/packages/openmeetings-util-4.0.9.jar": "pkg:maven/org.apache.openmeetings/openmeetings-util@4.0.9", + "/packages/org.eclipse.ant.core-3.7.0.jar": "pkg:maven/org.eclipse.platform/org.eclipse.ant.core@3.7.0", + "/packages/org.eclipse.osgi-3.18.0.jar": "pkg:maven/org.eclipse.platform/org.eclipse.osgi@3.18.0", + "/packages/org.everit.json.schema-1.5.1.jar": "pkg:maven/org.everit.json/org.everit.json.schema@1.5.1", + "/packages/original-my-app-1.jar": "pkg:maven/com.mycompany.app/my-app@1", + "/packages/original-my-app-1.jar:com.fasterxml.jackson.core:jackson-annotations": "pkg:maven/com.fasterxml.jackson.core/jackson-annotations@2.13.2", + "/packages/original-my-app-1.jar:com.fasterxml.jackson.core:jackson-core": "pkg:maven/com.fasterxml.jackson.core/jackson-core@2.13.2", + "/packages/original-my-app-1.jar:com.fasterxml.jackson.core:jackson-databind": "pkg:maven/com.fasterxml.jackson.core/jackson-databind@2.13.0", + "/packages/original-my-app-1.jar:com.fasterxml:classmate": "pkg:maven/com.fasterxml/classmate@1.5.1", + "/packages/original-my-app-1.jar:com.google.errorprone:error_prone_annotations": "pkg:maven/com.google.errorprone/error_prone_annotations@2.0.18", + "/packages/original-my-app-1.jar:com.google.guava:guava": "pkg:maven/com.google.guava/guava@23.0", + "/packages/original-my-app-1.jar:com.google.j2objc:j2objc-annotations": "pkg:maven/com.google.j2objc/j2objc-annotations@1.1", + "/packages/original-my-app-1.jar:com.hazelcast:hazelcast-kubernetes": "pkg:maven/com.hazelcast/hazelcast-kubernetes@1.5.4", + "/packages/original-my-app-1.jar:com.hierynomus:asn-one": "pkg:maven/com.hierynomus/asn-one@0.5.0", + "/packages/original-my-app-1.jar:com.typesafe.netty:netty-reactive-streams": "pkg:maven/com.typesafe.netty/netty-reactive-streams@2.0.5", + "/packages/original-my-app-1.jar:commons-beanutils:commons-beanutils": "pkg:maven/commons-beanutils/commons-beanutils@1.9.2", + "/packages/original-my-app-1.jar:commons-collections:commons-collections": "pkg:maven/commons-collections/commons-collections@3.2.2", + "/packages/original-my-app-1.jar:commons-digester:commons-digester": "pkg:maven/commons-digester/commons-digester@1.8.1", + "/packages/original-my-app-1.jar:commons-io:commons-io": "pkg:maven/commons-io/commons-io@2.8.0", + "/packages/original-my-app-1.jar:commons-logging:commons-logging": "pkg:maven/commons-logging/commons-logging@1.2", + "/packages/original-my-app-1.jar:commons-validator:commons-validator": "pkg:maven/commons-validator/commons-validator@1.5.1", + "/packages/original-my-app-1.jar:io.netty:netty-buffer": "pkg:maven/io.netty/netty-buffer@4.1.52.Final", + "/packages/original-my-app-1.jar:io.netty:netty-codec": "pkg:maven/io.netty/netty-codec@4.1.52.Final", + "/packages/original-my-app-1.jar:io.netty:netty-codec-dns": "pkg:maven/io.netty/netty-codec-dns@4.1.63.Final", + "/packages/original-my-app-1.jar:io.netty:netty-codec-http": "pkg:maven/io.netty/netty-codec-http@4.1.63.Final", + "/packages/original-my-app-1.jar:io.netty:netty-codec-socks": "pkg:maven/io.netty/netty-codec-socks@4.1.63.Final", + "/packages/original-my-app-1.jar:io.netty:netty-common": "pkg:maven/io.netty/netty-common@4.1.52.Final", + "/packages/original-my-app-1.jar:io.netty:netty-handler": "pkg:maven/io.netty/netty-handler@4.1.52.Final", + "/packages/original-my-app-1.jar:io.netty:netty-handler-proxy": "pkg:maven/io.netty/netty-handler-proxy@4.1.63.Final", + "/packages/original-my-app-1.jar:io.netty:netty-resolver": "pkg:maven/io.netty/netty-resolver@4.1.52.Final", + "/packages/original-my-app-1.jar:io.netty:netty-resolver-dns": "pkg:maven/io.netty/netty-resolver-dns@4.1.63.Final", + "/packages/original-my-app-1.jar:io.netty:netty-resolver-dns-native-macos": "pkg:maven/io.netty/netty-resolver-dns-native-macos@4.1.63.Final", + "/packages/original-my-app-1.jar:io.netty:netty-transport": "pkg:maven/io.netty/netty-transport@4.1.52.Final", + "/packages/original-my-app-1.jar:io.netty:netty-transport-native-epoll": "pkg:maven/io.netty/netty-transport-native-epoll@4.1.63.Final", + "/packages/original-my-app-1.jar:io.netty:netty-transport-native-unix-common": "pkg:maven/io.netty/netty-transport-native-unix-common@4.1.63.Final", + "/packages/original-my-app-1.jar:io.prometheus:simpleclient": "pkg:maven/io.prometheus/simpleclient@0.9.0", + "/packages/original-my-app-1.jar:io.prometheus:simpleclient_common": "pkg:maven/io.prometheus/simpleclient_common@0.9.0", + "/packages/original-my-app-1.jar:io.vavr:vavr": "pkg:maven/io.vavr/vavr@0.10.2", + "/packages/original-my-app-1.jar:io.vavr:vavr-match": "pkg:maven/io.vavr/vavr-match@0.10.2", + "/packages/original-my-app-1.jar:jakarta.validation:jakarta.validation-api": "pkg:maven/jakarta.validation/jakarta.validation-api@2.0.2", + "/packages/original-my-app-1.jar:javax.servlet:javax.servlet-api": "pkg:maven/javax.servlet/javax.servlet-api@3.1.0", + "/packages/original-my-app-1.jar:org.apache.activemq.protobuf:activemq-protobuf": "pkg:maven/org.apache.activemq.protobuf/activemq-protobuf@1.1", + "/packages/original-my-app-1.jar:org.apache.commons:commons-compress": "pkg:maven/org.apache.commons/commons-compress@1.21", + "/packages/original-my-app-1.jar:org.apache.commons:commons-lang3": "pkg:maven/org.apache.commons/commons-lang3@3.10", + "/packages/original-my-app-1.jar:org.apache.maven.shared:maven-shared-utils": "pkg:maven/org.apache.maven.shared/maven-shared-utils@3.3.4", + "/packages/original-my-app-1.jar:org.codehaus.mojo:animal-sniffer-annotations": "pkg:maven/org.codehaus.mojo/animal-sniffer-annotations@1.14", + "/packages/original-my-app-1.jar:org.eclipse.jetty.http2:http2-common": "pkg:maven/org.eclipse.jetty.http2/http2-common@9.4.43.v20210629", + "/packages/original-my-app-1.jar:org.eclipse.jetty.http2:http2-hpack": "pkg:maven/org.eclipse.jetty.http2/http2-hpack@9.4.43.v20210629", + "/packages/original-my-app-1.jar:org.eclipse.jetty.toolchain.setuid:jetty-setuid-java": "pkg:maven/org.eclipse.jetty.toolchain.setuid/jetty-setuid-java@1.0.4", + "/packages/original-my-app-1.jar:org.eclipse.jetty:jetty-client": "pkg:maven/org.eclipse.jetty/jetty-client@9.4.43.v20210629", + "/packages/original-my-app-1.jar:org.eclipse.jetty:jetty-http": "pkg:maven/org.eclipse.jetty/jetty-http@9.4.43.v20210629", + "/packages/original-my-app-1.jar:org.eclipse.jetty:jetty-io": "pkg:maven/org.eclipse.jetty/jetty-io@9.4.43.v20210629", + "/packages/original-my-app-1.jar:org.eclipse.jetty:jetty-server": "pkg:maven/org.eclipse.jetty/jetty-server@9.1.0.M0", + "/packages/original-my-app-1.jar:org.eclipse.jetty:jetty-util": "pkg:maven/org.eclipse.jetty/jetty-util@9.4.43.v20210629", + "/packages/original-my-app-1.jar:org.everit.json:org.everit.json.schema": "pkg:maven/org.everit.json/org.everit.json.schema@1.5.1", + "/packages/original-my-app-1.jar:org.hibernate.validator:hibernate-validator": "pkg:maven/org.hibernate.validator/hibernate-validator@6.2.4.Final", + "/packages/original-my-app-1.jar:org.jboss.logging:jboss-logging": "pkg:maven/org.jboss.logging/jboss-logging@3.4.1.Final", + "/packages/original-my-app-1.jar:org.jctools:jctools-core": "pkg:maven/org.jctools/jctools-core@3.1.0", + "/packages/original-my-app-1.jar:org.jetbrains:annotations": "pkg:maven/org.jetbrains/annotations@13.0", + "/packages/original-my-app-1.jar:org.json:json": "pkg:maven/org.json/json@20160810", + "/packages/original-my-app-1.jar:org.kohsuke:github-api": "pkg:maven/org.kohsuke/github-api@1.301", + "/packages/original-my-app-1.jar:org.slf4j:log4j-over-slf4j": "pkg:maven/org.slf4j/log4j-over-slf4j@1.7.33", + "/packages/original-my-app-1.jar:org.slf4j:slf4j-api": "pkg:maven/org.slf4j/slf4j-api@1.7.33", + "/packages/original-my-app-1.jar:org.sonarsource.analyzer-commons:sonar-analyzer-test-commons": "pkg:maven/org.sonarsource.analyzer-commons/sonar-analyzer-test-commons@1.14.1.690", + "/packages/original-my-app-1.jar:org.sonarsource.php:php-checks": "pkg:maven/org.sonarsource.php/php-checks@3.17.0.7439", + "/packages/original-my-app-1.jar:org.sonarsource.php:php-frontend": "pkg:maven/org.sonarsource.php/php-frontend@3.17.0.7439", + "/packages/original-my-app-1.jar:org.sonarsource.python:python-checks": "pkg:maven/org.sonarsource.python/python-checks@3.4.1.8066", + "/packages/original-my-app-1.jar:org.sonarsource.python:python-frontend": "pkg:maven/org.sonarsource.python/python-frontend@3.4.1.8066", + "/packages/original-my-app-1.jar:org.sonarsource.sslr:sslr-core": "pkg:maven/org.sonarsource.sslr/sslr-core@1.24.0.633", + "/packages/php-frontend-3.9.0.6331.jar": "pkg:maven/org.sonarsource.php/php-frontend@3.9.0.6331", + "/packages/postgresql-42.5.0.jar": "pkg:maven/org.postgresql/postgresql@42.5.0", + "/packages/protobuf-java-3.21.6.jar": "pkg:maven/com.google.protobuf/protobuf-java@3.21.6", + "/packages/python-frontend-3.24.0.10784.jar": "pkg:maven/org.sonarsource.python/python-frontend@3.24.0.10784", + "/packages/ratpack-core-1.8.2.jar": "pkg:maven/io.ratpack/ratpack-core@1.8.2", + "/packages/reactor-netty-core-1.0.35.jar": "pkg:maven/io.projectreactor.netty/reactor-netty-core@1.0.35", + "/packages/reactor-netty-http-1.1.9.jar": "pkg:maven/io.projectreactor.netty/reactor-netty-http@1.1.9", + "/packages/reactor-netty-incubator-quic-0.1.3.jar": "pkg:maven/io.projectreactor.netty.incubator/reactor-netty-incubator-quic@0.1.3", + "/packages/resilience4j-prometheus-0.17.0.jar": "pkg:maven/io.github.resilience4j.prometheus/resilience4j-prometheus@0.17.0", + "/packages/script-security.hpi": "pkg:maven/org.jenkins-ci.plugins/script-security@1.74", + "/packages/script-security.hpi:WEB-INF/lib/caffeine-2.8.2.jar": "pkg:maven/com.github.ben-manes.caffeine/caffeine@2.8.2", + "/packages/script-security.hpi:WEB-INF/lib/checker-qual-3.3.0.jar": "pkg:maven/org.checkerframework.checker.qual/checker-qual@3.3.0", + "/packages/script-security.hpi:WEB-INF/lib/error_prone_annotations-2.3.4.jar": "pkg:maven/com.google.errorprone/error_prone_annotations@2.3.4", + "/packages/script-security.hpi:WEB-INF/lib/groovy-sandbox-1.26.jar": "pkg:maven/org.kohsuke/groovy-sandbox@1.26", + "/packages/script-security.hpi:WEB-INF/lib/script-security.jar": "pkg:maven/org.jenkins-ci.plugins/script-security@1.74", + "/packages/shiro-core-1.9.1.jar": "pkg:maven/org.apache.shiro/shiro-core@1.9.1", + "/packages/solr-core-8.8.1.jar": "pkg:maven/org.apache.solr/solr-core@8.8.1", + "/packages/spring-amqp-2.4.17.jar": "pkg:maven/org.springframework.amqp/spring-amqp@2.4.17", + "/packages/spring-analytics-2.0.0.RELEASE.jar": "pkg:maven/org.springframework.analytics/spring-analytics@2.0.0.RELEASE", + "/packages/spring-asm-3.0.7.RELEASE.jar": "pkg:maven/org.springframework/spring-asm@3.0.7.RELEASE", + "/packages/spring-batch-core-4.2.1.RELEASE.jar": "pkg:maven/org.springframework.batch/spring-batch-core@4.2.1.RELEASE", + "/packages/spring-boot-3.1.2.jar": "pkg:maven/org.springframework.boot/spring-boot@3.1.2", + "/packages/spring-cloud-app-broker-core-1.6.1.jar": "pkg:maven/org.springframework.cloud/spring-cloud-app-broker-core@1.6.1", + "/packages/spring-cql-1.5.11.RELEASE.jar": "pkg:maven/org.springframework.data/spring-cql@1.5.11.RELEASE", + "/packages/spring-credhub-core-1.0.1.RELEASE.jar": "pkg:maven/org.springframework.credhub/spring-credhub-core@1.0.1.RELEASE", + "/packages/spring-flex-1.0.3.RELEASE.jar": "pkg:maven/org.springframework.flex/spring-flex@1.0.3.RELEASE", + "/packages/spring-graphql-1.2.2.jar": "pkg:maven/org.springframework.graphql/spring-graphql@1.2.2", + "/packages/spring-hateoas-2.1.0.jar": "pkg:maven/org.springframework.hateoas/spring-hateoas@2.1.0", + "/packages/spring-integration-amqp-6.0.5.jar": "pkg:maven/org.springframework.integration/spring-integration-amqp@6.0.5", + "/packages/spring-kafka-3.0.9.jar": "pkg:maven/org.springframework.kafka/spring-kafka@3.0.9", + "/packages/spring-security-core-6.0.2.jar": "pkg:maven/org.springframework.security/spring-security-core@6.0.2", + "/packages/spring-security-kerberos-core-1.0.1.RELEASE.jar": "pkg:maven/org.springframework.security.kerberos/spring-security-kerberos-core@1.0.1.RELEASE", + "/packages/spring-security-oauth-2.5.1.RELEASE.jar": "pkg:maven/org.springframework.security.oauth/spring-security-oauth@2.5.1.RELEASE", + "/packages/spring-security-oauth2-autoconfigure-2.5.9.jar": "pkg:maven/org.springframework.security.oauth.boot/spring-security-oauth2-autoconfigure@2.5.9", + "/packages/spring-security-saml2-core-1.0.10.RELEASE.jar": "pkg:maven/org.springframework.security.extensions/spring-security-saml2-core@1.0.10.RELEASE", + "/packages/spring-session-core-3.0.0.jar": "pkg:maven/org.springframework.session/spring-session-core@3.0.0", + "/packages/spring-social-core-1.1.2.RELEASE.jar": "pkg:maven/org.springframework.social/spring-social-core@1.1.2.RELEASE", + "/packages/spring-vault-core-3.0.1.jar": "pkg:maven/org.springframework.vault/spring-vault-core@3.0.1", + "/packages/spring-webmvc-3.1.4.RELEASE.jar": "pkg:maven/org.springframework/spring-webmvc@3.1.4.RELEASE", + "/packages/spring-xml-3.0.3.RELEASE.jar": "pkg:maven/org.springframework.ws/spring-xml@3.0.3.RELEASE", + "/packages/ssh-credentials.hpi": "pkg:maven/org.jenkins-ci.plugins/ssh-credentials@1.18.1", + "/packages/ssh-credentials.hpi:WEB-INF/lib/ssh-credentials.jar": "pkg:maven/org.jenkins-ci.plugins/ssh-credentials@1.18.1", + "/packages/storm-core-1.2.2.jar": "pkg:maven/org.apache.storm/storm-core@1.2.2", + "/packages/storm-core-1.2.2.jar:cheshire:cheshire": "pkg:maven/cheshire/cheshire@5.3.1", + "/packages/storm-core-1.2.2.jar:clj-time:clj-time": "pkg:maven/clj-time/clj-time@0.8.0", + "/packages/storm-core-1.2.2.jar:clout:clout": "pkg:maven/clout/clout@1.2.0", + "/packages/storm-core-1.2.2.jar:com.fasterxml.jackson.core:jackson-core": "pkg:maven/com.fasterxml.jackson.core/jackson-core@2.9.4", + "/packages/storm-core-1.2.2.jar:com.fasterxml.jackson.dataformat:jackson-dataformat-smile": "pkg:maven/com.fasterxml.jackson.dataformat/jackson-dataformat-smile@2.9.4", + "/packages/storm-core-1.2.2.jar:com.google.guava:guava": "pkg:maven/com.google.guava/guava@16.0.1", + "/packages/storm-core-1.2.2.jar:com.twitter:carbonite": "pkg:maven/com.twitter/carbonite@1.5.0", + "/packages/storm-core-1.2.2.jar:commons-codec:commons-codec": "pkg:maven/commons-codec/commons-codec@1.6", + "/packages/storm-core-1.2.2.jar:commons-collections:commons-collections": "pkg:maven/commons-collections/commons-collections@3.2.2", + "/packages/storm-core-1.2.2.jar:commons-fileupload:commons-fileupload": "pkg:maven/commons-fileupload/commons-fileupload@1.3.2", + "/packages/storm-core-1.2.2.jar:commons-io:commons-io": "pkg:maven/commons-io/commons-io@2.5", + "/packages/storm-core-1.2.2.jar:commons-lang:commons-lang": "pkg:maven/commons-lang/commons-lang@2.5", + "/packages/storm-core-1.2.2.jar:compojure:compojure": "pkg:maven/compojure/compojure@1.1.9", + "/packages/storm-core-1.2.2.jar:hiccup:hiccup": "pkg:maven/hiccup/hiccup@0.3.6", + "/packages/storm-core-1.2.2.jar:io.netty:netty": "pkg:maven/io.netty/netty@3.9.9.Final", + "/packages/storm-core-1.2.2.jar:joda-time:joda-time": "pkg:maven/joda-time/joda-time@2.3", + "/packages/storm-core-1.2.2.jar:metrics-clojure:metrics-clojure": "pkg:maven/metrics-clojure/metrics-clojure@2.5.1", + "/packages/storm-core-1.2.2.jar:ns-tracker:ns-tracker": "pkg:maven/ns-tracker/ns-tracker@0.2.2", + "/packages/storm-core-1.2.2.jar:org.apache.commons:commons-compress": "pkg:maven/org.apache.commons/commons-compress@1.4.1", + "/packages/storm-core-1.2.2.jar:org.apache.commons:commons-exec": "pkg:maven/org.apache.commons/commons-exec@1.1", + "/packages/storm-core-1.2.2.jar:org.apache.curator:curator-client": "pkg:maven/org.apache.curator/curator-client@4.0.1", + "/packages/storm-core-1.2.2.jar:org.apache.curator:curator-framework": "pkg:maven/org.apache.curator/curator-framework@4.0.1", + "/packages/storm-core-1.2.2.jar:org.apache.curator:curator-recipes": "pkg:maven/org.apache.curator/curator-recipes@4.0.1", + "/packages/storm-core-1.2.2.jar:org.apache.hadoop:hadoop-auth": "pkg:maven/org.apache.hadoop/hadoop-auth@2.6.1", + "/packages/storm-core-1.2.2.jar:org.apache.httpcomponents:httpclient": "pkg:maven/org.apache.httpcomponents/httpclient@4.3.3", + "/packages/storm-core-1.2.2.jar:org.apache.httpcomponents:httpcore": "pkg:maven/org.apache.httpcomponents/httpcore@4.4.1", + "/packages/storm-core-1.2.2.jar:org.clojure:java.jmx": "pkg:maven/org.clojure/java.jmx@0.3.1", + "/packages/storm-core-1.2.2.jar:org.clojure:math.numeric-tower": "pkg:maven/org.clojure/math.numeric-tower@0.0.1", + "/packages/storm-core-1.2.2.jar:org.clojure:tools.cli": "pkg:maven/org.clojure/tools.cli@0.2.4", + "/packages/storm-core-1.2.2.jar:org.clojure:tools.logging": "pkg:maven/org.clojure/tools.logging@0.2.3", + "/packages/storm-core-1.2.2.jar:org.clojure:tools.macro": "pkg:maven/org.clojure/tools.macro@0.1.0", + "/packages/storm-core-1.2.2.jar:org.clojure:tools.namespace": "pkg:maven/org.clojure/tools.namespace@0.2.4", + "/packages/storm-core-1.2.2.jar:org.eclipse.jetty:jetty-client": "pkg:maven/org.eclipse.jetty/jetty-client@7.6.13.v20130916", + "/packages/storm-core-1.2.2.jar:org.eclipse.jetty:jetty-continuation": "pkg:maven/org.eclipse.jetty/jetty-continuation@7.6.13.v20130916", + "/packages/storm-core-1.2.2.jar:org.eclipse.jetty:jetty-http": "pkg:maven/org.eclipse.jetty/jetty-http@7.6.13.v20130916", + "/packages/storm-core-1.2.2.jar:org.eclipse.jetty:jetty-io": "pkg:maven/org.eclipse.jetty/jetty-io@7.6.13.v20130916", + "/packages/storm-core-1.2.2.jar:org.eclipse.jetty:jetty-security": "pkg:maven/org.eclipse.jetty/jetty-security@7.6.13.v20130916", + "/packages/storm-core-1.2.2.jar:org.eclipse.jetty:jetty-server": "pkg:maven/org.eclipse.jetty/jetty-server@7.6.13.v20130916", + "/packages/storm-core-1.2.2.jar:org.eclipse.jetty:jetty-servlet": "pkg:maven/org.eclipse.jetty/jetty-servlet@7.6.13.v20130916", + "/packages/storm-core-1.2.2.jar:org.eclipse.jetty:jetty-servlets": "pkg:maven/org.eclipse.jetty/jetty-servlets@7.6.13.v20130916", + "/packages/storm-core-1.2.2.jar:org.eclipse.jetty:jetty-util": "pkg:maven/org.eclipse.jetty/jetty-util@7.6.13.v20130916", + "/packages/storm-core-1.2.2.jar:org.jgrapht:jgrapht-core": "pkg:maven/org.jgrapht/jgrapht-core@0.9.0", + "/packages/storm-core-1.2.2.jar:org.yaml:snakeyaml": "pkg:maven/org.yaml/snakeyaml@1.11", + "/packages/storm-core-1.2.2.jar:ring:ring-codec": "pkg:maven/ring/ring-codec@1.0.0", + "/packages/storm-core-1.2.2.jar:ring:ring-core": "pkg:maven/ring/ring-core@1.3.1", + "/packages/storm-core-1.2.2.jar:ring:ring-devel": "pkg:maven/ring/ring-devel@1.3.1", + "/packages/storm-core-1.2.2.jar:ring:ring-jetty-adapter": "pkg:maven/ring/ring-jetty-adapter@1.3.1", + "/packages/storm-core-1.2.2.jar:ring:ring-json": "pkg:maven/ring/ring-json@0.3.1", + "/packages/storm-core-1.2.2.jar:ring:ring-servlet": "pkg:maven/ring/ring-servlet@1.3.1", + "/packages/tapestry-core-5.8.1.jar": "pkg:maven/org.apache.tapestry/tapestry-core@5.8.1", + "/packages/tika-core-1.26.jar": "pkg:maven/org.apache.tika/tika-core@1.26", + "/packages/tomcat-catalina-11.0.0-M1.jar": "pkg:maven/org.apache.tomcat/tomcat-catalina@11.0.0-M1", + "/packages/tomcat-embed-core-11.0.0-M7.jar": "pkg:maven/org.apache.tomcat.embed/tomcat-embed-core@11.0.0-M7", + "/packages/TwilioNotifier.hpi": "pkg:maven/com.twilio.jenkins/TwilioNotifier@0.2.1", + "/packages/TwilioNotifier.hpi:WEB-INF/lib/commons-codec-1.2.jar": "pkg:maven/commons-codec/commons-codec@1.2", + "/packages/TwilioNotifier.hpi:WEB-INF/lib/commons-logging-1.0.4.jar": "pkg:maven/commons-logging/commons-logging@1.0.4", + "/packages/TwilioNotifier.hpi:WEB-INF/lib/log4j-1.2.9.jar": "pkg:maven/log4j/log4j@1.2.9", + "/packages/TwilioNotifier.hpi:WEB-INF/lib/sdk-3.0.jar:commons-codec:commons-codec": "pkg:maven/commons-codec/commons-codec@1.4", + "/packages/TwilioNotifier.hpi:WEB-INF/lib/sdk-3.0.jar:commons-lang:commons-lang": "pkg:maven/commons-lang/commons-lang@2.5", + "/packages/TwilioNotifier.hpi:WEB-INF/lib/sdk-3.0.jar:commons-logging:commons-logging": "pkg:maven/commons-logging/commons-logging@1.1.1", + "/packages/TwilioNotifier.hpi:WEB-INF/lib/sdk-3.0.jar:org.apache.httpcomponents:httpclient": "pkg:maven/org.apache.httpcomponents/httpclient@4.1.1", + "/packages/TwilioNotifier.hpi:WEB-INF/lib/sdk-3.0.jar:org.apache.httpcomponents:httpcore": "pkg:maven/org.apache.httpcomponents/httpcore@4.1", + "/packages/TwilioNotifier.hpi:WEB-INF/lib/sdk-3.0.jar:org.easymock:easymock": "pkg:maven/org.easymock/easymock@2.4", + "/packages/undertow-core-2.3.4.Final.jar": "pkg:maven/io.undertow/undertow-core@2.3.4.Final", + "/packages/vaadin-client-8.11.3.jar": "pkg:maven/com.vaadin/vaadin-client@8.11.3", + "/packages/velocity-1.7.jar": "pkg:maven/org.apache.velocity/velocity@1.7", + "/packages/vertx-web-4.3.7.jar": "pkg:maven/io.vertx/vertx-web@4.3.7", + "/packages/wicket-core-9.2.0.jar": "pkg:maven/org.apache.wicket/wicket-core@9.2.0", + "/packages/xalan-2.7.2.jar": "pkg:maven/xalan/xalan@2.7.2", + "/packages/xmlpull-1.1.3.1.jar": "pkg:maven/xmlpull/xmlpull@1.1.3.1", + "/packages/xstream-1.4.11.1.jar": "pkg:maven/com.thoughtworks.xstream/xstream@1.4.11.1", + "/packages/xstream-1.4.19.jar": "pkg:maven/com.thoughtworks.xstream/xstream@1.4.19", + "/packages/xwiki-commons-xml-15.1.jar": "pkg:maven/org.xwiki.commons/xwiki-commons-xml@15.1", + "/packages/xwiki-platform-oldcore-15.3.jar": "pkg:maven/org.xwiki.platform/xwiki-platform-oldcore@15.3", + "/packages/zookeeper-3.7.1.jar": "pkg:maven/org.apache.zookeeper/zookeeper@3.7.1", + "/packages/jruby-stdlib-9.1.15.0.jar:META-INF/jruby.home/lib/ruby/stdlib/readline.jar:jline:jline": "pkg:maven/jline/jline@2.11", + "/packages/jruby-stdlib-9.1.15.0.jar:META-INF/jruby.home/lib/ruby/stdlib/readline.jar:rubygems:jruby-readline": "pkg:maven/rubygems/jruby-readline@1.2.0", } diff --git a/cmd/syft/internal/test/integration/test-fixtures/image-test-java-purls/Dockerfile b/cmd/syft/internal/test/integration/test-fixtures/image-test-java-purls/Dockerfile index 9d9b9304164..16f074b362f 100644 --- a/cmd/syft/internal/test/integration/test-fixtures/image-test-java-purls/Dockerfile +++ b/cmd/syft/internal/test/integration/test-fixtures/image-test-java-purls/Dockerfile @@ -1 +1,3 @@ -FROM anchore/test_images:java-1abc58f@sha256:3add9f90e9ed35739cc99b7830767e09eec921052e2412adf4491648c741f066 +FROM docker.io/anchore/test_images:java-88948cc@sha256:dea0e6c24636937f53bdc997d9960c2a18966d1e38bcd8ebd0c395d4e169b806 + +RUN rm /packages/gradle-7.1.1-bin.zip \ No newline at end of file diff --git a/syft/pkg/cataloger/internal/cpegenerate/java.go b/syft/pkg/cataloger/internal/cpegenerate/java.go index 8ccd38059f2..4099effb3b3 100644 --- a/syft/pkg/cataloger/internal/cpegenerate/java.go +++ b/syft/pkg/cataloger/internal/cpegenerate/java.go @@ -23,6 +23,7 @@ var ( } PrimaryJavaManifestGroupIDFields = []string{ + "Group-Id", "Bundle-SymbolicName", "Extension-Name", "Specification-Vendor", diff --git a/syft/pkg/cataloger/java/archive_parser.go b/syft/pkg/cataloger/java/archive_parser.go index 1de3ab80abe..d2e16898c34 100644 --- a/syft/pkg/cataloger/java/archive_parser.go +++ b/syft/pkg/cataloger/java/archive_parser.go @@ -155,9 +155,14 @@ func (j *archiveParser) parse(ctx context.Context) ([]pkg.Package, []artifact.Re p := &pkgs[i] if m, ok := p.Metadata.(pkg.JavaArchive); ok { p.PURL = packageURL(p.Name, p.Version, m) + + if strings.Contains(p.PURL, "io.jenkins.plugins") || strings.Contains(p.PURL, "org.jenkins-ci.plugins") { + p.Type = pkg.JenkinsPluginPkg + } } else { log.WithFields("package", p.String()).Warn("unable to extract java metadata to generate purl") } + p.SetID() } diff --git a/syft/pkg/cataloger/java/archive_parser_test.go b/syft/pkg/cataloger/java/archive_parser_test.go index ccddc8c7528..2faf003d288 100644 --- a/syft/pkg/cataloger/java/archive_parser_test.go +++ b/syft/pkg/cataloger/java/archive_parser_test.go @@ -65,7 +65,7 @@ func TestSearchMavenForLicenses(t *testing.T) { // this fixture has a pomProjectObject and has a parent object // it has no licenses on either which is the condition for testing // the searchMavenForLicenses functionality - jarName := generateJavaMetadataJarFixture(t, tc.fixture) + jarName := generateJavaMetadataJarFixture(t, tc.fixture, "jar") fixture, err := os.Open(jarName) require.NoError(t, err) @@ -1082,6 +1082,7 @@ func Test_parseJavaArchive_regressions(t *testing.T) { tests := []struct { name string fixtureName string + fileExtension string expectedPkgs []pkg.Package expectedRelationships []artifact.Relationship assignParent bool @@ -1274,6 +1275,45 @@ func Test_parseJavaArchive_regressions(t *testing.T) { fixtureName: "spring-instrumentation-4.3.0-1.0", expectedPkgs: nil, // we expect no packages to be discovered when Weave-Classes present in the manifest }, + { + name: "Jenkins plugins assigned jenkins-plugin package type", + fixtureName: "gradle", + fileExtension: "hpi", + expectedPkgs: []pkg.Package{ + { + Name: "gradle", + Version: "2.11", + Type: pkg.JenkinsPluginPkg, + Language: pkg.Java, + PURL: "pkg:maven/org.jenkins-ci.plugins/gradle@2.11", + Locations: file.NewLocationSet(file.NewLocation("test-fixtures/jar-metadata/cache/gradle.hpi")), + Metadata: pkg.JavaArchive{ + VirtualPath: "test-fixtures/jar-metadata/cache/gradle.hpi", + Manifest: &pkg.JavaManifest{ + Main: pkg.KeyValues{ + {Key: "Manifest-Version", Value: "1.0"}, + { + Key: "Plugin-Dependencies", + Value: "maven-plugin:3.14;resolution:=optional...snip", + }, + {Key: "Group-Id", Value: "org.jenkins-ci.plugins"}, + {Key: "Minimum-Java-Version", Value: "1.8"}, + {Key: "Short-Name", Value: "gradle"}, + {Key: "Extension-Name", Value: "gradle"}, + {Key: "Long-Name", Value: "Gradle Plugin"}, + {Key: "Jenkins-Version", Value: "2.303.3"}, + {Key: "Url", Value: "https://github.com/jenkinsci/gradle-plugin"}, + {Key: "Compatible-Since-Version", Value: "1.0"}, + {Key: "Plugin-Version", Value: "2.11"}, + {Key: "Plugin-Developers", Value: "Stefan Wolf:wolfs:"}, + }, + }, + // not under test + //ArchiveDigests: []file.Digest{{Algorithm: "sha1", Value: "d8bc1d9c428c96fe447e2c429fc4304d141024df"}}, + }, + }, + }, + }, } for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { @@ -1285,7 +1325,7 @@ func Test_parseJavaArchive_regressions(t *testing.T) { tt.expectedPkgs[i].SetID() } pkgtest.NewCatalogTester(). - FromFile(t, generateJavaMetadataJarFixture(t, tt.fixtureName)). + FromFile(t, generateJavaMetadataJarFixture(t, tt.fixtureName, tt.fileExtension)). Expects(tt.expectedPkgs, tt.expectedRelationships). WithCompareOptions( cmpopts.IgnoreFields(pkg.JavaArchive{}, "ArchiveDigests"), @@ -1318,7 +1358,7 @@ func Test_deterministicMatchingPomProperties(t *testing.T) { for _, test := range tests { t.Run(test.fixture, func(t *testing.T) { - fixturePath := generateJavaMetadataJarFixture(t, test.fixture) + fixturePath := generateJavaMetadataJarFixture(t, test.fixture, "jar") for i := 0; i < 5; i++ { func() { @@ -1372,14 +1412,18 @@ func generateJavaBuildFixture(t *testing.T, fixturePath string) { run(t, cmd) } -func generateJavaMetadataJarFixture(t *testing.T, fixtureName string) string { - fixturePath := filepath.Join("test-fixtures/jar-metadata/cache/", fixtureName+".jar") +func generateJavaMetadataJarFixture(t *testing.T, fixtureName string, fileExtension string) string { + if fileExtension == "" { + fileExtension = "jar" + } + + fixturePath := filepath.Join("test-fixtures/jar-metadata/cache/", fixtureName+"."+fileExtension) if _, err := os.Stat(fixturePath); !os.IsNotExist(err) { // fixture already exists... return fixturePath } - makeTask := filepath.Join("cache", fixtureName+".jar") + makeTask := filepath.Join("cache", fixtureName+"."+fileExtension) t.Logf(color.Bold.Sprintf("Generating Fixture from 'make %s'", makeTask)) cwd, err := os.Getwd() diff --git a/syft/pkg/cataloger/java/test-fixtures/jar-metadata/Makefile b/syft/pkg/cataloger/java/test-fixtures/jar-metadata/Makefile index c5d3c52a3af..98083904234 100644 --- a/syft/pkg/cataloger/java/test-fixtures/jar-metadata/Makefile +++ b/syft/pkg/cataloger/java/test-fixtures/jar-metadata/Makefile @@ -28,3 +28,8 @@ $(CACHE_DIR)/$(SPRING_INSTRUMENTATION).jar: $(CACHE_DIR) $(CACHE_DIR)/$(MULTIPLE_MATCHING).jar: $(CACHE_DIR) cd $(MULTIPLE_MATCHING) && zip -r $(CACHE_PATH)/$(MULTIPLE_MATCHING).jar . + +# Jenkins plugins typically do not have the version included in the archive name, +# so it is important to not include it in the generated test fixture +$(CACHE_DIR)/gradle.hpi: $(CACHE_DIR) + cd jenkins-plugins/gradle/2.11 && zip -r $(CACHE_PATH)/gradle.hpi . \ No newline at end of file diff --git a/syft/pkg/cataloger/java/test-fixtures/jar-metadata/jenkins-plugins/gradle/2.11/META-INF/MANIFEST.MF b/syft/pkg/cataloger/java/test-fixtures/jar-metadata/jenkins-plugins/gradle/2.11/META-INF/MANIFEST.MF new file mode 100644 index 00000000000..eb2ed217773 --- /dev/null +++ b/syft/pkg/cataloger/java/test-fixtures/jar-metadata/jenkins-plugins/gradle/2.11/META-INF/MANIFEST.MF @@ -0,0 +1,13 @@ +Manifest-Version: 1.0 +Plugin-Dependencies: maven-plugin:3.14;resolution:=optional...snip +Group-Id: org.jenkins-ci.plugins +Minimum-Java-Version: 1.8 +Short-Name: gradle +Extension-Name: gradle +Long-Name: Gradle Plugin +Jenkins-Version: 2.303.3 +Url: https://github.com/jenkinsci/gradle-plugin +Compatible-Since-Version: 1.0 +Plugin-Version: 2.11 +Plugin-Developers: Stefan Wolf:wolfs: + From 3161e1847efab3815b51eceb2f1a81cd8944eb34 Mon Sep 17 00:00:00 2001 From: Lukas Voetmand Date: Mon, 12 Aug 2024 22:37:23 +0200 Subject: [PATCH 067/122] fix: read CycloneDX BOM components from metadata (#3092) Signed-off-by: dervoeti --- .../sbom_metadata_component_test.go | 25 +++++++++++++++ .../image-sbom-metadata-component/Dockerfile | 2 ++ .../test.cdx.json | 32 +++++++++++++++++++ .../internal/cyclonedxutil/helpers/decoder.go | 19 ++++++++--- 4 files changed, 74 insertions(+), 4 deletions(-) create mode 100644 cmd/syft/internal/test/integration/sbom_metadata_component_test.go create mode 100644 cmd/syft/internal/test/integration/test-fixtures/image-sbom-metadata-component/Dockerfile create mode 100644 cmd/syft/internal/test/integration/test-fixtures/image-sbom-metadata-component/test.cdx.json diff --git a/cmd/syft/internal/test/integration/sbom_metadata_component_test.go b/cmd/syft/internal/test/integration/sbom_metadata_component_test.go new file mode 100644 index 00000000000..d45a2f1cd5d --- /dev/null +++ b/cmd/syft/internal/test/integration/sbom_metadata_component_test.go @@ -0,0 +1,25 @@ +package integration + +import ( + "reflect" + "testing" + + "github.com/anchore/syft/syft/pkg" + "github.com/anchore/syft/syft/source" +) + +func TestSbomMetadataComponent(t *testing.T) { + sbom, _ := catalogFixtureImage(t, "image-sbom-metadata-component", source.SquashedScope, "+sbom-cataloger") + + expectedPkgs := []string{"first-subcomponent", "main-component"} + foundPkgs := []string{} + + for sbomPkg := range sbom.Artifacts.Packages.Enumerate(pkg.JavaPkg) { + foundPkgs = append(foundPkgs, sbomPkg.Name) + } + + // check if both the package in `.metadata.component` and the one in `.components` were found + if !reflect.DeepEqual(expectedPkgs, foundPkgs) { + t.Errorf("expected packages %v, got %v", expectedPkgs, foundPkgs) + } +} diff --git a/cmd/syft/internal/test/integration/test-fixtures/image-sbom-metadata-component/Dockerfile b/cmd/syft/internal/test/integration/test-fixtures/image-sbom-metadata-component/Dockerfile new file mode 100644 index 00000000000..6861c4d6352 --- /dev/null +++ b/cmd/syft/internal/test/integration/test-fixtures/image-sbom-metadata-component/Dockerfile @@ -0,0 +1,2 @@ +FROM scratch +COPY test.cdx.json / diff --git a/cmd/syft/internal/test/integration/test-fixtures/image-sbom-metadata-component/test.cdx.json b/cmd/syft/internal/test/integration/test-fixtures/image-sbom-metadata-component/test.cdx.json new file mode 100644 index 00000000000..6695b7c0a75 --- /dev/null +++ b/cmd/syft/internal/test/integration/test-fixtures/image-sbom-metadata-component/test.cdx.json @@ -0,0 +1,32 @@ +{ + "bomFormat" : "CycloneDX", + "specVersion" : "1.5", + "serialNumber" : "urn:uuid:dc807d4b-0415-35ab-ba61-49b5d39bc2d9", + "version" : 1, + "metadata" : { + "component" : { + "name" : "main-component", + "version" : "1.2.3", + "purl" : "pkg:maven/org.example/main-component@1.2.3", + "type" : "library", + "bom-ref" : "pkg:maven/org.example/main-component@1.2.3" + } + }, + "components" : [ + { + "name" : "first-subcomponent", + "version" : "2.3.4", + "purl" : "pkg:maven/org.example/first-subcomponent@2.3.4", + "type" : "library", + "bom-ref" : "pkg:maven/org.example/first-subcomponent@2.3.4" + } + ], + "dependencies" : [ + { + "ref" : "pkg:maven/org.example/main-component-assembly@1.2.3", + "dependsOn" : [ + "pkg:maven/org.example/first-subcomponent@2.3.4" + ] + } + ] +} \ No newline at end of file diff --git a/syft/format/internal/cyclonedxutil/helpers/decoder.go b/syft/format/internal/cyclonedxutil/helpers/decoder.go index fdf8ffe98c1..c4c706e380b 100644 --- a/syft/format/internal/cyclonedxutil/helpers/decoder.go +++ b/syft/format/internal/cyclonedxutil/helpers/decoder.go @@ -39,12 +39,23 @@ func ToSyftModel(bom *cyclonedx.BOM) (*sbom.SBOM, error) { } func collectBomPackages(bom *cyclonedx.BOM, s *sbom.SBOM, idMap map[string]interface{}) error { - if bom.Components == nil { - return fmt.Errorf("no components are defined in the CycloneDX BOM") + componentsPresent := false + if bom.Components != nil { + for i := range *bom.Components { + collectPackages(&(*bom.Components)[i], s, idMap) + } + componentsPresent = true } - for i := range *bom.Components { - collectPackages(&(*bom.Components)[i], s, idMap) + + if bom.Metadata != nil && bom.Metadata.Component != nil { + collectPackages(bom.Metadata.Component, s, idMap) + componentsPresent = true } + + if !componentsPresent { + return fmt.Errorf("no components are defined in the CycloneDX BOM") + } + return nil } From cd3b828905ec2bf0620ceab529c9f3734bcc234a Mon Sep 17 00:00:00 2001 From: Lucas Rodriguez Date: Tue, 13 Aug 2024 15:02:15 -0500 Subject: [PATCH 068/122] fix: add nil check to CycloneDX toBomProperties (#3119) Signed-off-by: Lucas Rodriguez --- .../cyclonedxhelpers/to_format_model.go | 6 +++ .../cyclonedxhelpers/to_format_model_test.go | 47 +++++++++++++++++++ 2 files changed, 53 insertions(+) diff --git a/syft/format/common/cyclonedxhelpers/to_format_model.go b/syft/format/common/cyclonedxhelpers/to_format_model.go index e2f3a285fd5..ba93a367e56 100644 --- a/syft/format/common/cyclonedxhelpers/to_format_model.go +++ b/syft/format/common/cyclonedxhelpers/to_format_model.go @@ -211,6 +211,12 @@ func toBomProperties(srcMetadata source.Description) *[]cyclonedx.Property { metadata, ok := srcMetadata.Metadata.(source.ImageMetadata) if ok { props := helpers.EncodeProperties(metadata.Labels, "syft:image:labels") + // return nil if props is nil to avoid creating a pointer to a nil slice, + // which results in a null JSON value that does not comply with the CycloneDX schema. + // https://github.com/anchore/grype/issues/1759 + if props == nil { + return nil + } return &props } return nil diff --git a/syft/format/common/cyclonedxhelpers/to_format_model_test.go b/syft/format/common/cyclonedxhelpers/to_format_model_test.go index de34080821c..c3ac1f3b8f7 100644 --- a/syft/format/common/cyclonedxhelpers/to_format_model_test.go +++ b/syft/format/common/cyclonedxhelpers/to_format_model_test.go @@ -236,6 +236,53 @@ func Test_toBomDescriptor(t *testing.T) { } } +func Test_toBomProperties(t *testing.T) { + tests := []struct { + name string + srcMetadata source.Description + props *[]cyclonedx.Property + }{ + { + name: "ImageMetadata without labels", + srcMetadata: source.Description{ + Metadata: source.ImageMetadata{ + Labels: map[string]string{}, + }, + }, + props: nil, + }, + { + name: "ImageMetadata with labels", + srcMetadata: source.Description{ + Metadata: source.ImageMetadata{ + Labels: map[string]string{ + "label1": "value1", + "label2": "value2", + }, + }, + }, + props: &[]cyclonedx.Property{ + {Name: "syft:image:labels:label1", Value: "value1"}, + {Name: "syft:image:labels:label2", Value: "value2"}, + }, + }, + { + name: "not ImageMetadata", + srcMetadata: source.Description{ + Metadata: source.FileMetadata{}, + }, + props: nil, + }, + } + for _, test := range tests { + t.Run(test.name, func(t *testing.T) { + t.Parallel() + props := toBomProperties(test.srcMetadata) + require.Equal(t, test.props, props) + }) + } +} + func Test_toOsComponent(t *testing.T) { tests := []struct { name string From a447884084fbdca657cfb25297104675a610a5be Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Thu, 15 Aug 2024 13:16:39 -0400 Subject: [PATCH 069/122] chore(deps): bump github/codeql-action from 3.26.0 to 3.26.2 (#3129) Bumps [github/codeql-action](https://github.com/github/codeql-action) from 3.26.0 to 3.26.2. - [Release notes](https://github.com/github/codeql-action/releases) - [Changelog](https://github.com/github/codeql-action/blob/main/CHANGELOG.md) - [Commits](https://github.com/github/codeql-action/compare/eb055d739abdc2e8de2e5f4ba1a8b246daa779aa...429e1977040da7a23b6822b13c129cd1ba93dbb2) --- updated-dependencies: - dependency-name: github/codeql-action dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- .github/workflows/codeql-analysis.yml | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/.github/workflows/codeql-analysis.yml b/.github/workflows/codeql-analysis.yml index 46fc8496331..54b4633e1b1 100644 --- a/.github/workflows/codeql-analysis.yml +++ b/.github/workflows/codeql-analysis.yml @@ -45,7 +45,7 @@ jobs: # Initializes the CodeQL tools for scanning. - name: Initialize CodeQL - uses: github/codeql-action/init@eb055d739abdc2e8de2e5f4ba1a8b246daa779aa #v3.26.0 + uses: github/codeql-action/init@429e1977040da7a23b6822b13c129cd1ba93dbb2 #v3.26.2 with: languages: ${{ matrix.language }} # If you wish to specify custom queries, you can do so here or in a config file. @@ -56,7 +56,7 @@ jobs: # Autobuild attempts to build any compiled languages (C/C++, C#, or Java). # If this step fails, then you should remove it and run the build manually (see below) - name: Autobuild - uses: github/codeql-action/autobuild@eb055d739abdc2e8de2e5f4ba1a8b246daa779aa #v3.26.0 + uses: github/codeql-action/autobuild@429e1977040da7a23b6822b13c129cd1ba93dbb2 #v3.26.2 # ℹī¸ Command-line programs to run using the OS shell. # 📚 https://git.io/JvXDl @@ -70,4 +70,4 @@ jobs: # make release - name: Perform CodeQL Analysis - uses: github/codeql-action/analyze@eb055d739abdc2e8de2e5f4ba1a8b246daa779aa #v3.26.0 + uses: github/codeql-action/analyze@429e1977040da7a23b6822b13c129cd1ba93dbb2 #v3.26.2 From 965000dcbb86656b6d7b9f7731b0a9065e104d9b Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Thu, 15 Aug 2024 13:16:47 -0400 Subject: [PATCH 070/122] chore(deps): bump anchore/sbom-action from 0.17.0 to 0.17.1 (#3124) Bumps [anchore/sbom-action](https://github.com/anchore/sbom-action) from 0.17.0 to 0.17.1. - [Release notes](https://github.com/anchore/sbom-action/releases) - [Commits](https://github.com/anchore/sbom-action/compare/d94f46e13c6c62f59525ac9a1e147a99dc0b9bf5...ab9d16d4b419c9d1a02df5213fa0ebe965ca5a57) --- updated-dependencies: - dependency-name: anchore/sbom-action dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- .github/workflows/release.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/release.yaml b/.github/workflows/release.yaml index 734fc7a3284..dc79d685f06 100644 --- a/.github/workflows/release.yaml +++ b/.github/workflows/release.yaml @@ -148,7 +148,7 @@ jobs: # for updating brew formula in anchore/homebrew-syft GITHUB_BREW_TOKEN: ${{ secrets.ANCHOREOPS_GITHUB_OSS_WRITE_TOKEN }} - - uses: anchore/sbom-action@d94f46e13c6c62f59525ac9a1e147a99dc0b9bf5 #v0.17.0 + - uses: anchore/sbom-action@ab9d16d4b419c9d1a02df5213fa0ebe965ca5a57 #v0.17.1 continue-on-error: true with: artifact-name: sbom.spdx.json From 4ff60ee83714614272512d8bf9fa174cfd6a4d2f Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Thu, 15 Aug 2024 13:50:51 -0400 Subject: [PATCH 071/122] chore(deps): bump github.com/docker/docker (#3123) Bumps [github.com/docker/docker](https://github.com/docker/docker) from 27.1.1+incompatible to 27.1.2+incompatible. - [Release notes](https://github.com/docker/docker/releases) - [Commits](https://github.com/docker/docker/compare/v27.1.1...v27.1.2) --- updated-dependencies: - dependency-name: github.com/docker/docker dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- go.mod | 2 +- go.sum | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/go.mod b/go.mod index 56b075e10ed..0e7cfbc549a 100644 --- a/go.mod +++ b/go.mod @@ -29,7 +29,7 @@ require ( github.com/dave/jennifer v1.7.0 github.com/deitch/magic v0.0.0-20230404182410-1ff89d7342da github.com/distribution/reference v0.6.0 - github.com/docker/docker v27.1.1+incompatible + github.com/docker/docker v27.1.2+incompatible github.com/dustin/go-humanize v1.0.1 github.com/elliotchance/phpserialize v1.4.0 github.com/facebookincubator/nvdtools v0.1.5 diff --git a/go.sum b/go.sum index 15800d2ab63..6d6bbd4585f 100644 --- a/go.sum +++ b/go.sum @@ -231,8 +231,8 @@ github.com/docker/cli v27.1.1+incompatible h1:goaZxOqs4QKxznZjjBWKONQci/MywhtRv2 github.com/docker/cli v27.1.1+incompatible/go.mod h1:JLrzqnKDaYBop7H2jaqPtU4hHvMKP+vjCwu2uszcLI8= github.com/docker/distribution v2.8.3+incompatible h1:AtKxIZ36LoNK51+Z6RpzLpddBirtxJnzDrHLEKxTAYk= github.com/docker/distribution v2.8.3+incompatible/go.mod h1:J2gT2udsDAN96Uj4KfcMRqY0/ypR+oyYUYmja8H+y+w= -github.com/docker/docker v27.1.1+incompatible h1:hO/M4MtV36kzKldqnA37IWhebRA+LnqqcqDja6kVaKY= -github.com/docker/docker v27.1.1+incompatible/go.mod h1:eEKB0N0r5NX/I1kEveEz05bcu8tLC/8azJZsviup8Sk= +github.com/docker/docker v27.1.2+incompatible h1:AhGzR1xaQIy53qCkxARaFluI00WPGtXn0AJuoQsVYTY= +github.com/docker/docker v27.1.2+incompatible/go.mod h1:eEKB0N0r5NX/I1kEveEz05bcu8tLC/8azJZsviup8Sk= github.com/docker/docker-credential-helpers v0.7.0 h1:xtCHsjxogADNZcdv1pKUHXryefjlVRqWqIhk/uXJp0A= github.com/docker/docker-credential-helpers v0.7.0/go.mod h1:rETQfLdHNT3foU5kuNkFR1R1V12OJRRO5lzt2D1b5X0= github.com/docker/go-connections v0.4.0 h1:El9xVISelRB7BuFusrZozjnkIM5YnzCViNKohAFqRJQ= From 4b7ae0ed3b8f41dbaf03b14c1af4db3d26a8c5bb Mon Sep 17 00:00:00 2001 From: "anchore-actions-token-generator[bot]" <102182147+anchore-actions-token-generator[bot]@users.noreply.github.com> Date: Fri, 16 Aug 2024 17:56:36 +0000 Subject: [PATCH 072/122] chore(deps): update tools to latest versions (#3121) * chore(deps): update tools to latest versions Signed-off-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com> * chore: update code to reflect new linter settings for error messages Signed-off-by: Christopher Phillips <32073428+spiffcs@users.noreply.github.com> --------- Signed-off-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com> Signed-off-by: Christopher Phillips <32073428+spiffcs@users.noreply.github.com> Co-authored-by: spiffcs <32073428+spiffcs@users.noreply.github.com> --- .binny.yaml | 4 ++-- cmd/syft/internal/commands/scan.go | 2 +- internal/cache/error_resolver.go | 2 +- syft/internal/packagemetadata/discover_type_names.go | 3 ++- syft/internal/sourcemetadata/discover_type_names.go | 3 ++- syft/pkg/cataloger/cpp/parse_conanfile.go | 2 +- syft/pkg/cataloger/cpp/parse_conaninfo.go | 2 +- syft/pkg/cataloger/elixir/parse_mix_lock.go | 2 +- syft/pkg/cataloger/haskell/parse_cabal_freeze.go | 2 +- 9 files changed, 12 insertions(+), 10 deletions(-) diff --git a/.binny.yaml b/.binny.yaml index 42ea5c760d2..686e946ecee 100644 --- a/.binny.yaml +++ b/.binny.yaml @@ -26,7 +26,7 @@ tools: # used for linting - name: golangci-lint version: - want: v1.59.1 + want: v1.60.1 method: github-release with: repo: golangci/golangci-lint @@ -58,7 +58,7 @@ tools: # used to release all artifacts - name: goreleaser version: - want: v2.1.0 + want: v2.2.0 method: github-release with: repo: goreleaser/goreleaser diff --git a/cmd/syft/internal/commands/scan.go b/cmd/syft/internal/commands/scan.go index ff5b4254f65..efec9dd5b7d 100644 --- a/cmd/syft/internal/commands/scan.go +++ b/cmd/syft/internal/commands/scan.go @@ -161,7 +161,7 @@ func validateArgs(cmd *cobra.Command, args []string, error string) error { if err := cmd.Help(); err != nil { return fmt.Errorf("unable to display help: %w", err) } - return fmt.Errorf(error) + return fmt.Errorf("%v", error) } return cobra.MaximumNArgs(1)(cmd, args) diff --git a/internal/cache/error_resolver.go b/internal/cache/error_resolver.go index 614d707f1fa..efbf915aa50 100644 --- a/internal/cache/error_resolver.go +++ b/internal/cache/error_resolver.go @@ -34,7 +34,7 @@ func (r *errorResolver[T]) Resolve(key string, resolver resolverFunc[T]) (T, err return v.Value, err } if v.Error != "" { - return v.Value, fmt.Errorf(v.Error) + return v.Value, fmt.Errorf("failed to resolve cache: %s", v.Error) } return v.Value, nil } diff --git a/syft/internal/packagemetadata/discover_type_names.go b/syft/internal/packagemetadata/discover_type_names.go index ca9b2c9ddc5..03f8a4cc62b 100644 --- a/syft/internal/packagemetadata/discover_type_names.go +++ b/syft/internal/packagemetadata/discover_type_names.go @@ -78,7 +78,8 @@ func findMetadataDefinitionNames(paths ...string) ([]string, error) { // note: 35 is a point-in-time gut check. This number could be updated if new metadata definitions are added, but is not required. // it is really intended to catch any major issues with the generation process that would generate, say, 0 definitions. if len(strNames) < 35 { - return nil, fmt.Errorf("not enough metadata definitions found (discovered: " + fmt.Sprintf("%d", len(strNames)) + ")") + msg := fmt.Sprintf("not enough metadata definitions found (discovered %d)", len(strNames)) + return nil, fmt.Errorf("%v", msg) } return strNames, nil diff --git a/syft/internal/sourcemetadata/discover_type_names.go b/syft/internal/sourcemetadata/discover_type_names.go index 9b1ac2f5843..905de200aa4 100644 --- a/syft/internal/sourcemetadata/discover_type_names.go +++ b/syft/internal/sourcemetadata/discover_type_names.go @@ -68,7 +68,8 @@ func findMetadataDefinitionNames(paths ...string) ([]string, error) { // note: 3 is a point-in-time gut check. This number could be updated if new metadata definitions are added, but is not required. // it is really intended to catch any major issues with the generation process that would generate, say, 0 definitions. if len(strNames) < 3 { - return nil, fmt.Errorf("not enough metadata definitions found (discovered: " + fmt.Sprintf("%d", len(strNames)) + ")") + msg := fmt.Sprintf("not enough metadata definitions found (discovered %d)", len(strNames)) + return nil, fmt.Errorf("%v", msg) } return strNames, nil diff --git a/syft/pkg/cataloger/cpp/parse_conanfile.go b/syft/pkg/cataloger/cpp/parse_conanfile.go index dc22f80bdce..622acbdcb3c 100644 --- a/syft/pkg/cataloger/cpp/parse_conanfile.go +++ b/syft/pkg/cataloger/cpp/parse_conanfile.go @@ -24,7 +24,7 @@ func parseConanfile(_ context.Context, _ file.Resolver, _ *generic.Environment, for { line, err := r.ReadString('\n') switch { - case errors.Is(io.EOF, err): + case errors.Is(err, io.EOF): return pkgs, nil, nil case err != nil: return nil, nil, fmt.Errorf("failed to parse conanfile.txt file: %w", err) diff --git a/syft/pkg/cataloger/cpp/parse_conaninfo.go b/syft/pkg/cataloger/cpp/parse_conaninfo.go index 7140e47c980..8094b3406c7 100644 --- a/syft/pkg/cataloger/cpp/parse_conaninfo.go +++ b/syft/pkg/cataloger/cpp/parse_conaninfo.go @@ -99,7 +99,7 @@ func parseConaninfo(_ context.Context, _ file.Resolver, _ *generic.Environment, for { line, err := r.ReadString('\n') switch { - case errors.Is(io.EOF, err): + case errors.Is(err, io.EOF): mainPackage := newConaninfoPackage( mainMetadata, reader.Location.WithAnnotation(pkg.EvidenceAnnotationKey, pkg.PrimaryEvidenceAnnotation), diff --git a/syft/pkg/cataloger/elixir/parse_mix_lock.go b/syft/pkg/cataloger/elixir/parse_mix_lock.go index 28ba38c3d63..dcd4a7858db 100644 --- a/syft/pkg/cataloger/elixir/parse_mix_lock.go +++ b/syft/pkg/cataloger/elixir/parse_mix_lock.go @@ -28,7 +28,7 @@ func parseMixLock(_ context.Context, _ file.Resolver, _ *generic.Environment, re for { line, err := r.ReadString('\n') switch { - case errors.Is(io.EOF, err): + case errors.Is(err, io.EOF): return packages, nil, nil case err != nil: return nil, nil, fmt.Errorf("failed to parse mix.lock file: %w", err) diff --git a/syft/pkg/cataloger/haskell/parse_cabal_freeze.go b/syft/pkg/cataloger/haskell/parse_cabal_freeze.go index 6bedc3e6917..614524cae26 100644 --- a/syft/pkg/cataloger/haskell/parse_cabal_freeze.go +++ b/syft/pkg/cataloger/haskell/parse_cabal_freeze.go @@ -23,7 +23,7 @@ func parseCabalFreeze(_ context.Context, _ file.Resolver, _ *generic.Environment for { line, err := r.ReadString('\n') switch { - case errors.Is(io.EOF, err): + case errors.Is(err, io.EOF): return pkgs, nil, nil case err != nil: return nil, nil, fmt.Errorf("failed to parse cabal.project.freeze file: %w", err) From 360983f75b18d4fbdd42ea05c3d04a2cd4c9836a Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 19 Aug 2024 12:48:24 -0400 Subject: [PATCH 073/122] chore(deps): bump github.com/charmbracelet/bubbletea (#3137) Bumps [github.com/charmbracelet/bubbletea](https://github.com/charmbracelet/bubbletea) from 0.26.6 to 0.27.0. - [Release notes](https://github.com/charmbracelet/bubbletea/releases) - [Changelog](https://github.com/charmbracelet/bubbletea/blob/master/.goreleaser.yml) - [Commits](https://github.com/charmbracelet/bubbletea/compare/v0.26.6...v0.27.0) --- updated-dependencies: - dependency-name: github.com/charmbracelet/bubbletea dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- go.mod | 4 ++-- go.sum | 8 ++++---- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/go.mod b/go.mod index 0e7cfbc549a..d1173d9c1c8 100644 --- a/go.mod +++ b/go.mod @@ -24,7 +24,7 @@ require ( github.com/aquasecurity/go-pep440-version v0.0.0-20210121094942-22b2f8951d46 github.com/bmatcuk/doublestar/v4 v4.6.1 github.com/charmbracelet/bubbles v0.18.0 - github.com/charmbracelet/bubbletea v0.26.6 + github.com/charmbracelet/bubbletea v0.27.0 github.com/charmbracelet/lipgloss v0.12.1 github.com/dave/jennifer v1.7.0 github.com/deitch/magic v0.0.0-20230404182410-1ff89d7342da @@ -232,7 +232,7 @@ require ( go.uber.org/multierr v1.9.0 // indirect golang.org/x/crypto v0.26.0 // indirect golang.org/x/sync v0.8.0 // indirect - golang.org/x/sys v0.23.0 // indirect + golang.org/x/sys v0.24.0 // indirect golang.org/x/term v0.23.0 // indirect golang.org/x/text v0.17.0 // indirect golang.org/x/tools v0.21.1-0.20240508182429-e35e4ccd0d2d // indirect diff --git a/go.sum b/go.sum index 6d6bbd4585f..eda4db73c82 100644 --- a/go.sum +++ b/go.sum @@ -157,8 +157,8 @@ github.com/cespare/xxhash/v2 v2.1.1/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XL github.com/cespare/xxhash/v2 v2.1.2/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs= github.com/charmbracelet/bubbles v0.18.0 h1:PYv1A036luoBGroX6VWjQIE9Syf2Wby2oOl/39KLfy0= github.com/charmbracelet/bubbles v0.18.0/go.mod h1:08qhZhtIwzgrtBjAcJnij1t1H0ZRjwHyGsy6AL11PSw= -github.com/charmbracelet/bubbletea v0.26.6 h1:zTCWSuST+3yZYZnVSvbXwKOPRSNZceVeqpzOLN2zq1s= -github.com/charmbracelet/bubbletea v0.26.6/go.mod h1:dz8CWPlfCCGLFbBlTY4N7bjLiyOGDJEnd2Muu7pOWhk= +github.com/charmbracelet/bubbletea v0.27.0 h1:Mznj+vvYuYagD9Pn2mY7fuelGvP0HAXtZYGgRBCbHvU= +github.com/charmbracelet/bubbletea v0.27.0/go.mod h1:5MdP9XH6MbQkgGhnlxUqCNmBXf9I74KRQ8HIidRxV1Y= github.com/charmbracelet/harmonica v0.2.0 h1:8NxJWRWg/bzKqqEaaeFNipOu77YR5t8aSwG4pgaUBiQ= github.com/charmbracelet/harmonica v0.2.0/go.mod h1:KSri/1RMQOZLbw7AHqgcBycp8pgJnQMYYT8QZRqZ1Ao= github.com/charmbracelet/lipgloss v0.12.1 h1:/gmzszl+pedQpjCOH+wFkZr/N90Snz40J/NR7A0zQcs= @@ -1081,8 +1081,8 @@ golang.org/x/sys v0.2.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.3.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.5.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.23.0 h1:YfKFowiIMvtgl1UERQoTPPToxltDeZfbj4H7dVUCwmM= -golang.org/x/sys v0.23.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= +golang.org/x/sys v0.24.0 h1:Twjiwq9dn6R1fQcyiK+wQyHWfaz/BJB+YIpzU/Cv3Xg= +golang.org/x/sys v0.24.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= golang.org/x/term v0.2.0/go.mod h1:TVmDHMZPmdnySmBfhjOoOdhjzdE1h4u1VwSiw2l1Nuc= From 511cc9c2d5f80a770dc3ec0880cce08e9f80796b Mon Sep 17 00:00:00 2001 From: "anchore-actions-token-generator[bot]" <102182147+anchore-actions-token-generator[bot]@users.noreply.github.com> Date: Mon, 19 Aug 2024 12:49:43 -0400 Subject: [PATCH 074/122] chore(deps): update CPE dictionary index (#3135) Signed-off-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com> Co-authored-by: wagoodman <590471+wagoodman@users.noreply.github.com> --- .../internal/cpegenerate/dictionary/data/cpe-index.json | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/syft/pkg/cataloger/internal/cpegenerate/dictionary/data/cpe-index.json b/syft/pkg/cataloger/internal/cpegenerate/dictionary/data/cpe-index.json index 586be8f3e5a..8fd77ee19f4 100644 --- a/syft/pkg/cataloger/internal/cpegenerate/dictionary/data/cpe-index.json +++ b/syft/pkg/cataloger/internal/cpegenerate/dictionary/data/cpe-index.json @@ -2080,6 +2080,9 @@ "@braintree/sanitize-url": [ "cpe:2.3:a:paypal:braintree\\/sanitize-url:*:*:*:*:*:node.js:*:*" ], + "@builder.io/qwik": [ + "cpe:2.3:a:qwik:qwik:*:*:*:*:*:node.js:*:*" + ], "@chainsafe/libp2p-noise": [ "cpe:2.3:a:chainsafe:js-libp2p-noise:*:*:*:*:*:node.js:*:*" ], @@ -5273,6 +5276,9 @@ "weather.swlyons": [ "cpe:2.3:a:weather.swlyons_project:weather.swlyons:*:*:*:*:*:node.js:*:*" ], + "webcrack": [ + "cpe:2.3:a:j4k0xb:webcrack:*:*:*:*:*:node.js:*:*" + ], "webdriver-launcher": [ "cpe:2.3:a:webdriver-launcher_project:webdriver-launcher:*:*:*:*:*:node.js:*:*" ], @@ -6307,6 +6313,9 @@ "secure_headers": [ "cpe:2.3:a:twitter:secure_headers:*:*:*:*:*:ruby:*:*" ], + "sequenceserver": [ + "cpe:2.3:a:wurmlab:sequenceserver:*:*:*:*:*:ruby:*:*" + ], "sfpagent": [ "cpe:2.3:a:herry:sfpagent:*:*:*:*:*:ruby:*:*" ], From 95b4a88256bddebb91831250f28f602f8c36552a Mon Sep 17 00:00:00 2001 From: Keith Zantow Date: Tue, 20 Aug 2024 11:45:33 -0400 Subject: [PATCH 075/122] fix: logging for remote network calls (#3140) Signed-off-by: Keith Zantow --- internal/spdxlicense/license_list.go | 15 +++++++++++++-- syft/pkg/cataloger/golang/licenses.go | 4 ++++ syft/pkg/cataloger/javascript/package.go | 6 +++--- 3 files changed, 20 insertions(+), 5 deletions(-) diff --git a/internal/spdxlicense/license_list.go b/internal/spdxlicense/license_list.go index 18e2a88cacc..05a78d95cfd 100644 --- a/internal/spdxlicense/license_list.go +++ b/internal/spdxlicense/license_list.go @@ -1,9 +1,9 @@ // Code generated by go generate; DO NOT EDIT. -// This file was generated by robots at 2024-05-23 08:47:23.204981 -0400 EDT m=+0.050881068 +// This file was generated by robots at 2024-08-20 11:33:49.349625 -0400 EDT m=+0.383911876 // using data from https://spdx.org/licenses/licenses.json package spdxlicense -const Version = "3.24.0" +const Version = "3.25.0" var licenseIDs = map[string]string{ "0bsd": "0BSD", @@ -501,6 +501,8 @@ var licenseIDs = map[string]string{ "dldezero2.0": "DL-DE-ZERO-2.0", "dldezero2.0.0": "DL-DE-ZERO-2.0", "doc": "DOC", + "docbookschema": "DocBook-Schema", + "docbookxml": "DocBook-XML", "dotseqn": "Dotseqn", "drl1": "DRL-1.0", "drl1.0": "DRL-1.0", @@ -714,6 +716,7 @@ var licenseIDs = map[string]string{ "gutmann": "Gutmann", "haskellreport": "HaskellReport", "hdparm": "hdparm", + "hidapi": "HIDAPI", "hippocratic2": "Hippocratic-2.1", "hippocratic2.1": "Hippocratic-2.1", "hippocratic2.1.0": "Hippocratic-2.1", @@ -740,6 +743,7 @@ var licenseIDs = map[string]string{ "hpndmarkuskuhn": "HPND-Markus-Kuhn", "hpndmerchantabilityvariant": "HPND-merchantability-variant", "hpndmitdisclaimer": "HPND-MIT-disclaimer", + "hpndnetrek": "HPND-Netrek", "hpndpbmplus": "HPND-Pbmplus", "hpndsellmitdisclaimerxserver": "HPND-sell-MIT-disclaimer-xserver", "hpndsellregexpr": "HPND-sell-regexpr", @@ -1165,6 +1169,7 @@ var licenseIDs = map[string]string{ "rsamd": "RSA-MD", "rscpl": "RSCPL", "ruby": "Ruby", + "rubypty": "Ruby-pty", "saxpath": "Saxpath", "saxpd": "SAX-PD", "saxpd2": "SAX-PD-2.0", @@ -1265,6 +1270,9 @@ var licenseIDs = map[string]string{ "tuberlin2": "TU-Berlin-2.0", "tuberlin2.0": "TU-Berlin-2.0", "tuberlin2.0.0": "TU-Berlin-2.0", + "ubuntufont1": "Ubuntu-font-1.0", + "ubuntufont1.0": "Ubuntu-font-1.0", + "ubuntufont1.0.0": "Ubuntu-font-1.0", "ucar": "UCAR", "ucl1": "UCL-1.0", "ucl1.0": "UCL-1.0", @@ -1315,8 +1323,11 @@ var licenseIDs = map[string]string{ "x11.0": "X11", "x11.0.0": "X11", "x11.0.0distributemodificationsvariant": "X11-distribute-modifications-variant", + "x11.0.0swapped": "X11-swapped", "x11.0distributemodificationsvariant": "X11-distribute-modifications-variant", + "x11.0swapped": "X11-swapped", "x11distributemodificationsvariant": "X11-distribute-modifications-variant", + "x11swapped": "X11-swapped", "xdebug1": "Xdebug-1.03", "xdebug1.03": "Xdebug-1.03", "xdebug1.03.0": "Xdebug-1.03", diff --git a/syft/pkg/cataloger/golang/licenses.go b/syft/pkg/cataloger/golang/licenses.go index f532463147e..0b02c6581c1 100644 --- a/syft/pkg/cataloger/golang/licenses.go +++ b/syft/pkg/cataloger/golang/licenses.go @@ -251,6 +251,7 @@ func getModule(proxies []string, moduleName, moduleVersion string) (urlPrefix st case "file": p := filepath.Join(u.Path, moduleName, "@v", moduleVersion) urlPrefix = path.Join("file://", p) + "/" + log.WithFields("path", p).Info("looking for go module in filesystem") fsys = os.DirFS(p) } if fsys != nil { @@ -264,6 +265,7 @@ func getModuleProxy(proxy string, moduleName string, moduleVersion string) (modu u := fmt.Sprintf("%s/%s/@v/%s.zip", proxy, moduleName, moduleVersion) // get the module zip + log.WithFields("url", u).Info("downloading go module from proxy") resp, err := http.Get(u) //nolint:gosec if err != nil { return "", nil, err @@ -334,6 +336,8 @@ func getModuleRepository(moduleName string, moduleVersion string) (string, fs.FS f := memfs.New() buf := &bytes.Buffer{} repoURL := fmt.Sprintf("https://%s", repoName) + + log.WithFields("repoURL", repoURL, "ref", cloneRefName).Info("cloning go module repository") r, err := git.Clone(memory.NewStorage(), f, &git.CloneOptions{ URL: repoURL, ReferenceName: cloneRefName, diff --git a/syft/pkg/cataloger/javascript/package.go b/syft/pkg/cataloger/javascript/package.go index 57df406b1f1..19114c99f55 100644 --- a/syft/pkg/cataloger/javascript/package.go +++ b/syft/pkg/cataloger/javascript/package.go @@ -178,13 +178,13 @@ func formatNpmRegistryURL(baseURL, packageName, version string) (requestURL stri return requestURL, nil } -func getLicenseFromNpmRegistry(basURL, packageName, version string) (string, error) { +func getLicenseFromNpmRegistry(baseURL, packageName, version string) (string, error) { // "https://registry.npmjs.org/%s/%s", packageName, version - requestURL, err := formatNpmRegistryURL(basURL, packageName, version) + requestURL, err := formatNpmRegistryURL(baseURL, packageName, version) if err != nil { return "", fmt.Errorf("unable to format npm request for pkg:version %s%s; %w", packageName, version, err) } - log.Tracef("trying to fetch remote package %s", requestURL) + log.WithFields("url", requestURL).Info("downloading javascript package from npm") npmRequest, err := http.NewRequest(http.MethodGet, requestURL, nil) if err != nil { From f786233e979a46623c509d38ae3dd57553fbe52c Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 20 Aug 2024 23:04:58 +0000 Subject: [PATCH 076/122] chore(deps): bump github/codeql-action from 3.26.2 to 3.26.3 (#3139) Bumps [github/codeql-action](https://github.com/github/codeql-action) from 3.26.2 to 3.26.3. - [Release notes](https://github.com/github/codeql-action/releases) - [Changelog](https://github.com/github/codeql-action/blob/main/CHANGELOG.md) - [Commits](https://github.com/github/codeql-action/compare/429e1977040da7a23b6822b13c129cd1ba93dbb2...883d8588e56d1753a8a58c1c86e88976f0c23449) --- updated-dependencies: - dependency-name: github/codeql-action dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- .github/workflows/codeql-analysis.yml | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/.github/workflows/codeql-analysis.yml b/.github/workflows/codeql-analysis.yml index 54b4633e1b1..0ef325acd8a 100644 --- a/.github/workflows/codeql-analysis.yml +++ b/.github/workflows/codeql-analysis.yml @@ -45,7 +45,7 @@ jobs: # Initializes the CodeQL tools for scanning. - name: Initialize CodeQL - uses: github/codeql-action/init@429e1977040da7a23b6822b13c129cd1ba93dbb2 #v3.26.2 + uses: github/codeql-action/init@883d8588e56d1753a8a58c1c86e88976f0c23449 #v3.26.3 with: languages: ${{ matrix.language }} # If you wish to specify custom queries, you can do so here or in a config file. @@ -56,7 +56,7 @@ jobs: # Autobuild attempts to build any compiled languages (C/C++, C#, or Java). # If this step fails, then you should remove it and run the build manually (see below) - name: Autobuild - uses: github/codeql-action/autobuild@429e1977040da7a23b6822b13c129cd1ba93dbb2 #v3.26.2 + uses: github/codeql-action/autobuild@883d8588e56d1753a8a58c1c86e88976f0c23449 #v3.26.3 # ℹī¸ Command-line programs to run using the OS shell. # 📚 https://git.io/JvXDl @@ -70,4 +70,4 @@ jobs: # make release - name: Perform CodeQL Analysis - uses: github/codeql-action/analyze@429e1977040da7a23b6822b13c129cd1ba93dbb2 #v3.26.2 + uses: github/codeql-action/analyze@883d8588e56d1753a8a58c1c86e88976f0c23449 #v3.26.3 From 73b9d5aa4262186bd343ffc58f138382a0b5db0f Mon Sep 17 00:00:00 2001 From: Keith Zantow Date: Wed, 21 Aug 2024 09:48:28 -0400 Subject: [PATCH 077/122] fix: mysql 8.0.3x binary detection (#3142) Signed-off-by: Keith Zantow --- .../binary/classifier_cataloger_test.go | 11 +++++++++++ syft/pkg/cataloger/binary/classifiers.go | 8 ++++++-- .../snippets/mysql/8.0.34/linux-amd64/mysql | Bin 329 -> 349 bytes .../snippets/mysql/8.0.37/linux-amd64/mysql | Bin 0 -> 349 bytes .../cataloger/binary/test-fixtures/config.yaml | 7 +++++++ 5 files changed, 24 insertions(+), 2 deletions(-) create mode 100644 syft/pkg/cataloger/binary/test-fixtures/classifiers/snippets/mysql/8.0.37/linux-amd64/mysql diff --git a/syft/pkg/cataloger/binary/classifier_cataloger_test.go b/syft/pkg/cataloger/binary/classifier_cataloger_test.go index dcc9849c675..721ee9ee045 100644 --- a/syft/pkg/cataloger/binary/classifier_cataloger_test.go +++ b/syft/pkg/cataloger/binary/classifier_cataloger_test.go @@ -116,6 +116,17 @@ func Test_Cataloger_PositiveCases(t *testing.T) { Metadata: metadata("mysql-binary"), }, }, + { + logicalFixture: "mysql/8.0.37/linux-amd64", + expected: pkg.Package{ + Name: "mysql", + Version: "8.0.37", + Type: "binary", + PURL: "pkg:generic/mysql@8.0.37", + Locations: locations("mysql"), + Metadata: metadata("mysql-binary"), + }, + }, { logicalFixture: "percona-server/8.0.35/linux-amd64", expected: pkg.Package{ diff --git a/syft/pkg/cataloger/binary/classifiers.go b/syft/pkg/cataloger/binary/classifiers.go index 0d491f25feb..5f4d3aa6651 100644 --- a/syft/pkg/cataloger/binary/classifiers.go +++ b/syft/pkg/cataloger/binary/classifiers.go @@ -294,8 +294,12 @@ func DefaultClassifiers() []Classifier { { Class: "mysql-binary", FileGlob: "**/mysql", - EvidenceMatcher: FileContentsVersionMatcher( - `(?m).*/mysql-(?P[0-9]+(\.[0-9]+)?(\.[0-9]+)?(alpha[0-9]|beta[0-9]|rc[0-9])?)`), + EvidenceMatcher: evidenceMatchers( + // shutdown[NUL]8.0.37[NUL][NUL][NUL][NUL][NUL]mysql_real_esc + FileContentsVersionMatcher(`\x00(?P[0-9]+(\.[0-9]+)?(\.[0-9]+)?(alpha[0-9]|beta[0-9]|rc[0-9])?)\x00+mysql`), + // /export/home/pb2/build/sb_0-26781090-1516292385.58/release/mysql-8.0.4-rc/mysys_ssl/my_default.cc + FileContentsVersionMatcher(`(?m).*/mysql-(?P[0-9]+(\.[0-9]+)?(\.[0-9]+)?(alpha[0-9]|beta[0-9]|rc[0-9])?)`), + ), Package: "mysql", PURL: mustPURL("pkg:generic/mysql@version"), CPEs: singleCPE("cpe:2.3:a:oracle:mysql:*:*:*:*:*:*:*:*"), diff --git a/syft/pkg/cataloger/binary/test-fixtures/classifiers/snippets/mysql/8.0.34/linux-amd64/mysql b/syft/pkg/cataloger/binary/test-fixtures/classifiers/snippets/mysql/8.0.34/linux-amd64/mysql index 571e977876d514a60f30550a982ec3942e92497f..9ff7ddd39cee298be9fcdaf561a6df90cd313d1e 100644 GIT binary patch delta 227 zcmZ{ZOAdlC6aa}!FW{CFkhYXk+`BTtL}Ogm*YXM`SkTs}x6osG2+!eXB^Pj#Sxn|J zdX8?BEzL+VZqe1DnZ}fnv3I+^$FOREWnvmznGp_l2%uW#R01cA5o5Ff0lGqAq())$ z6bsI5Wi(ct7rDiZ<{Z-d*K?VIBP#GVgiU_GmWS{NoB`wL_}*vm z9y}+z1hg5Iq26DL*%YK4we_KC!ew1Jg?2X0fmj8V*Z@SHHA+?<1Co@4o+&4fE-1<& zaB4uK(vE_|)KJDL!RuE0uHOy2{xR-)adl@=9#}N2M9W)<04PCaWCWHHqYYRcODoPz dCFYyuY9Xq7dnzM}WvtCVexDty>R5}c`~v5jKnnl> diff --git a/syft/pkg/cataloger/binary/test-fixtures/classifiers/snippets/mysql/8.0.37/linux-amd64/mysql b/syft/pkg/cataloger/binary/test-fixtures/classifiers/snippets/mysql/8.0.37/linux-amd64/mysql new file mode 100644 index 0000000000000000000000000000000000000000..45109e6f731ebcb52bb16f15e011ad92c23cf834 GIT binary patch literal 349 zcmZ`!O>4t249(fU!q9v1ryS?L)1ZTuv19Ou+yv4%ZCpx!`94lFTgOh5csz+GJ*3$k zv7^V^dYVX1X~oh}u9X31$b|Eu47C@Gtn;`mSoVVx8agUH0|U-8Q3s<*(T5gL3hhne z$~vw&xCkOx6e(KmeJ~20V@c?cWF%>v@Yf7w^k9TmyfvOB00gT8kFHIqICzMxl|jau zCPZ-PqwuXY(rVCJSwc3O4fVHz^nNBSnWj8V`AVxq9(PZ#yZ&YW@Z7A!rNn%ln|8~# r(lkHu{eOQ(H}$v%w_v}P^Ee;+(Cw& literal 0 HcmV?d00001 diff --git a/syft/pkg/cataloger/binary/test-fixtures/config.yaml b/syft/pkg/cataloger/binary/test-fixtures/config.yaml index 50dd6bcc8ed..9ea3c2de71f 100644 --- a/syft/pkg/cataloger/binary/test-fixtures/config.yaml +++ b/syft/pkg/cataloger/binary/test-fixtures/config.yaml @@ -157,6 +157,13 @@ from-images: paths: - /usr/bin/mysql + - version: 8.0.37 + images: + - ref: mysql:8.0.37-bookworm@sha256:bad55a5bb69d6710927792384b5eb55669ee15dc85dca1888874e4a7993eecd8 + platform: linux/amd64 + paths: + - /usr/bin/mysql + - name: percona-server version: 8.0.35 images: From bd80eeafac6457b511a6037ee0934121a79cbdcc Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Thu, 22 Aug 2024 13:51:50 -0400 Subject: [PATCH 078/122] chore(deps): bump github.com/anchore/stereoscope (#3153) Bumps [github.com/anchore/stereoscope](https://github.com/anchore/stereoscope) from 0.0.3-0.20240725180315-50ce3be7aa1f to 0.0.3. - [Release notes](https://github.com/anchore/stereoscope/releases) - [Changelog](https://github.com/anchore/stereoscope/blob/main/.goreleaser.yaml) - [Commits](https://github.com/anchore/stereoscope/commits/v0.0.3) --- updated-dependencies: - dependency-name: github.com/anchore/stereoscope dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- go.mod | 2 +- go.sum | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/go.mod b/go.mod index d1173d9c1c8..da6e60c3d62 100644 --- a/go.mod +++ b/go.mod @@ -17,7 +17,7 @@ require ( github.com/anchore/go-testutils v0.0.0-20200925183923-d5f45b0d3c04 github.com/anchore/go-version v1.2.2-0.20200701162849-18adb9c92b9b github.com/anchore/packageurl-go v0.1.1-0.20240507183024-848e011fc24f - github.com/anchore/stereoscope v0.0.3-0.20240725180315-50ce3be7aa1f + github.com/anchore/stereoscope v0.0.3 github.com/anmitsu/go-shlex v0.0.0-20200514113438-38f4b401e2be // we are hinting brotli to latest due to warning when installing archiver v3: // go: warning: github.com/andybalholm/brotli@v1.0.1: retracted by module author: occasional panics and data corruption diff --git a/go.sum b/go.sum index eda4db73c82..6cbac3fc737 100644 --- a/go.sum +++ b/go.sum @@ -113,8 +113,8 @@ github.com/anchore/go-version v1.2.2-0.20200701162849-18adb9c92b9b h1:e1bmaoJfZV github.com/anchore/go-version v1.2.2-0.20200701162849-18adb9c92b9b/go.mod h1:Bkc+JYWjMCF8OyZ340IMSIi2Ebf3uwByOk6ho4wne1E= github.com/anchore/packageurl-go v0.1.1-0.20240507183024-848e011fc24f h1:B/E9ixKNCasntpoch61NDaQyGPDXLEJlL+B9B/PbdbA= github.com/anchore/packageurl-go v0.1.1-0.20240507183024-848e011fc24f/go.mod h1:Blo6OgJNiYF41ufcgHKkbCKF2MDOMlrqhXv/ij6ocR4= -github.com/anchore/stereoscope v0.0.3-0.20240725180315-50ce3be7aa1f h1:xuBvotcht1Ns8IdaC4UuYV1U8MFln9c5ELeo5bzDEO8= -github.com/anchore/stereoscope v0.0.3-0.20240725180315-50ce3be7aa1f/go.mod h1:DcQdMes8SwpFli3rDH0v+Vd9qU9Jariq7JSHNJV5X/A= +github.com/anchore/stereoscope v0.0.3 h1:JRPHySy8S6P+Ff3IDiQ29ap1i8/laUQxDk9K1eFh/2U= +github.com/anchore/stereoscope v0.0.3/go.mod h1:5DJheGPjVRsSqegTB24Zi6SCHnYQnA519yeIG+RG+I4= github.com/andreyvit/diff v0.0.0-20170406064948-c7f18ee00883/go.mod h1:rCTlJbsFo29Kk6CurOXKm700vrz8f0KW0JNfpkRJY/8= github.com/andybalholm/brotli v1.0.1/go.mod h1:loMXtMfwqflxFJPmdbJO0a3KNoPuLBgiu3qAvBg8x/Y= github.com/andybalholm/brotli v1.0.4 h1:V7DdXeJtZscaqfNuAdSRuRFzuiKlHSC/Zh3zl9qY3JY= From 78d48b420967b23665510d5f86610c64bfdadc82 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Thu, 22 Aug 2024 13:51:57 -0400 Subject: [PATCH 079/122] chore(deps): bump github.com/charmbracelet/lipgloss (#3147) Bumps [github.com/charmbracelet/lipgloss](https://github.com/charmbracelet/lipgloss) from 0.12.1 to 0.13.0. - [Release notes](https://github.com/charmbracelet/lipgloss/releases) - [Changelog](https://github.com/charmbracelet/lipgloss/blob/master/.goreleaser.yml) - [Commits](https://github.com/charmbracelet/lipgloss/compare/v0.12.1...v0.13.0) --- updated-dependencies: - dependency-name: github.com/charmbracelet/lipgloss dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- go.mod | 2 +- go.sum | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/go.mod b/go.mod index da6e60c3d62..a0ff4faab57 100644 --- a/go.mod +++ b/go.mod @@ -25,7 +25,7 @@ require ( github.com/bmatcuk/doublestar/v4 v4.6.1 github.com/charmbracelet/bubbles v0.18.0 github.com/charmbracelet/bubbletea v0.27.0 - github.com/charmbracelet/lipgloss v0.12.1 + github.com/charmbracelet/lipgloss v0.13.0 github.com/dave/jennifer v1.7.0 github.com/deitch/magic v0.0.0-20230404182410-1ff89d7342da github.com/distribution/reference v0.6.0 diff --git a/go.sum b/go.sum index 6cbac3fc737..912862b5a10 100644 --- a/go.sum +++ b/go.sum @@ -161,8 +161,8 @@ github.com/charmbracelet/bubbletea v0.27.0 h1:Mznj+vvYuYagD9Pn2mY7fuelGvP0HAXtZY github.com/charmbracelet/bubbletea v0.27.0/go.mod h1:5MdP9XH6MbQkgGhnlxUqCNmBXf9I74KRQ8HIidRxV1Y= github.com/charmbracelet/harmonica v0.2.0 h1:8NxJWRWg/bzKqqEaaeFNipOu77YR5t8aSwG4pgaUBiQ= github.com/charmbracelet/harmonica v0.2.0/go.mod h1:KSri/1RMQOZLbw7AHqgcBycp8pgJnQMYYT8QZRqZ1Ao= -github.com/charmbracelet/lipgloss v0.12.1 h1:/gmzszl+pedQpjCOH+wFkZr/N90Snz40J/NR7A0zQcs= -github.com/charmbracelet/lipgloss v0.12.1/go.mod h1:V2CiwIuhx9S1S1ZlADfOj9HmxeMAORuz5izHb0zGbB8= +github.com/charmbracelet/lipgloss v0.13.0 h1:4X3PPeoWEDCMvzDvGmTajSyYPcZM4+y8sCA/SsA3cjw= +github.com/charmbracelet/lipgloss v0.13.0/go.mod h1:nw4zy0SBX/F/eAO1cWdcvy6qnkDUxr8Lw7dvFrAIbbY= github.com/charmbracelet/x/ansi v0.1.4 h1:IEU3D6+dWwPSgZ6HBH+v6oUuZ/nVawMiWj5831KfiLM= github.com/charmbracelet/x/ansi v0.1.4/go.mod h1:dk73KoMTT5AX5BsX0KrqhsTqAnhZZoCBjs7dGWp4Ktw= github.com/charmbracelet/x/input v0.1.0 h1:TEsGSfZYQyOtp+STIjyBq6tpRaorH0qpwZUj8DavAhQ= From ac977246c970a93d330cfdd9da9c826a68634420 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Thu, 22 Aug 2024 13:52:06 -0400 Subject: [PATCH 080/122] chore(deps): bump github.com/charmbracelet/bubbles from 0.18.0 to 0.19.0 (#3148) Bumps [github.com/charmbracelet/bubbles](https://github.com/charmbracelet/bubbles) from 0.18.0 to 0.19.0. - [Release notes](https://github.com/charmbracelet/bubbles/releases) - [Changelog](https://github.com/charmbracelet/bubbles/blob/master/.goreleaser.yml) - [Commits](https://github.com/charmbracelet/bubbles/compare/v0.18.0...v0.19.0) --- updated-dependencies: - dependency-name: github.com/charmbracelet/bubbles dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- go.mod | 7 +++---- go.sum | 16 ++++++---------- 2 files changed, 9 insertions(+), 14 deletions(-) diff --git a/go.mod b/go.mod index a0ff4faab57..f6d03ab6c7f 100644 --- a/go.mod +++ b/go.mod @@ -23,7 +23,7 @@ require ( // go: warning: github.com/andybalholm/brotli@v1.0.1: retracted by module author: occasional panics and data corruption github.com/aquasecurity/go-pep440-version v0.0.0-20210121094942-22b2f8951d46 github.com/bmatcuk/doublestar/v4 v4.6.1 - github.com/charmbracelet/bubbles v0.18.0 + github.com/charmbracelet/bubbles v0.19.0 github.com/charmbracelet/bubbletea v0.27.0 github.com/charmbracelet/lipgloss v0.13.0 github.com/dave/jennifer v1.7.0 @@ -169,7 +169,7 @@ require ( github.com/mattn/go-colorable v0.1.13 // indirect github.com/mattn/go-isatty v0.0.20 // indirect github.com/mattn/go-localereader v0.0.2-0.20220822084749-2491eb6c1c75 // indirect - github.com/mattn/go-runewidth v0.0.15 // indirect + github.com/mattn/go-runewidth v0.0.16 // indirect github.com/mgutz/ansi v0.0.0-20200706080929-d51e80ef957d // indirect github.com/mitchellh/copystructure v1.2.0 // indirect github.com/mitchellh/reflectwalk v1.0.2 // indirect @@ -179,7 +179,6 @@ require ( github.com/moby/sys/signal v0.7.0 // indirect github.com/muesli/ansi v0.0.0-20230316100256-276c6243b2f6 // indirect github.com/muesli/cancelreader v0.2.2 // indirect - github.com/muesli/reflow v0.3.0 // indirect github.com/muesli/termenv v0.15.2 // indirect github.com/ncruces/go-strftime v0.1.9 // indirect github.com/nwaples/rardecode v1.1.0 // indirect @@ -199,7 +198,7 @@ require ( github.com/rogpeppe/go-internal v1.12.0 // indirect github.com/sagikazarmark/locafero v0.4.0 // indirect github.com/sagikazarmark/slog-shim v0.1.0 // indirect - github.com/sahilm/fuzzy v0.1.1-0.20230530133925-c48e322e2a8f // indirect + github.com/sahilm/fuzzy v0.1.1 // indirect github.com/secDre4mer/pkcs7 v0.0.0-20240322103146-665324a4461d // indirect github.com/shopspring/decimal v1.2.0 // indirect github.com/sirupsen/logrus v1.9.3 // indirect diff --git a/go.sum b/go.sum index 912862b5a10..a9c8256cfb1 100644 --- a/go.sum +++ b/go.sum @@ -155,8 +155,8 @@ github.com/census-instrumentation/opencensus-proto v0.3.0/go.mod h1:f6KPmirojxKA github.com/cespare/xxhash v1.1.0/go.mod h1:XrSqR1VqqWfGrhpAt58auRo0WTKS1nRRg3ghfAqPWnc= github.com/cespare/xxhash/v2 v2.1.1/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs= github.com/cespare/xxhash/v2 v2.1.2/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs= -github.com/charmbracelet/bubbles v0.18.0 h1:PYv1A036luoBGroX6VWjQIE9Syf2Wby2oOl/39KLfy0= -github.com/charmbracelet/bubbles v0.18.0/go.mod h1:08qhZhtIwzgrtBjAcJnij1t1H0ZRjwHyGsy6AL11PSw= +github.com/charmbracelet/bubbles v0.19.0 h1:gKZkKXPP6GlDk6EcfujDK19PCQqRjaJZQ7QRERx1UF0= +github.com/charmbracelet/bubbles v0.19.0/go.mod h1:WILteEqZ+krG5c3ntGEMeG99nCupcuIk7V0/zOP0tOA= github.com/charmbracelet/bubbletea v0.27.0 h1:Mznj+vvYuYagD9Pn2mY7fuelGvP0HAXtZYGgRBCbHvU= github.com/charmbracelet/bubbletea v0.27.0/go.mod h1:5MdP9XH6MbQkgGhnlxUqCNmBXf9I74KRQ8HIidRxV1Y= github.com/charmbracelet/harmonica v0.2.0 h1:8NxJWRWg/bzKqqEaaeFNipOu77YR5t8aSwG4pgaUBiQ= @@ -552,9 +552,8 @@ github.com/mattn/go-isatty v0.0.20/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D github.com/mattn/go-localereader v0.0.2-0.20220822084749-2491eb6c1c75 h1:P8UmIzZMYDR+NGImiFvErt6VWfIRPuGM+vyjiEdkmIw= github.com/mattn/go-localereader v0.0.2-0.20220822084749-2491eb6c1c75/go.mod h1:8fBrzywKY7BI3czFoHkuzRoWE9C+EiG4R1k4Cjx5p88= github.com/mattn/go-runewidth v0.0.9/go.mod h1:H031xJmbD/WCDINGzjvQ9THkh0rPKHF+m2gUSrubnMI= -github.com/mattn/go-runewidth v0.0.12/go.mod h1:RAqKPSqVFrSLVXbA8x7dzmKdmGzieGRCM46jaSJTDAk= -github.com/mattn/go-runewidth v0.0.15 h1:UNAjwbU9l54TA3KzvqLGxwWjHmMgBUVhBiTjelZgg3U= -github.com/mattn/go-runewidth v0.0.15/go.mod h1:Jdepj2loyihRzMpdS35Xk/zdY8IAYHsh153qUoGf23w= +github.com/mattn/go-runewidth v0.0.16 h1:E5ScNMtiwvlvB5paMFdw9p4kSQzbXFikJ5SQO6TULQc= +github.com/mattn/go-runewidth v0.0.16/go.mod h1:Jdepj2loyihRzMpdS35Xk/zdY8IAYHsh153qUoGf23w= github.com/matttproud/golang_protobuf_extensions v1.0.1/go.mod h1:D8He9yQNgCq6Z5Ld7szi9bcBfOoFv/3dc6xSMkL2PC0= github.com/mgutz/ansi v0.0.0-20200706080929-d51e80ef957d h1:5PJl274Y63IEHC+7izoQE9x6ikvDFZS2mDVS3drnohI= github.com/mgutz/ansi v0.0.0-20200706080929-d51e80ef957d/go.mod h1:01TrycV0kFyexm33Z7vhZRXopbI8J3TDReVlkTgMUxE= @@ -603,8 +602,6 @@ github.com/muesli/ansi v0.0.0-20230316100256-276c6243b2f6 h1:ZK8zHtRHOkbHy6Mmr5D github.com/muesli/ansi v0.0.0-20230316100256-276c6243b2f6/go.mod h1:CJlz5H+gyd6CUWT45Oy4q24RdLyn7Md9Vj2/ldJBSIo= github.com/muesli/cancelreader v0.2.2 h1:3I4Kt4BQjOR54NavqnDogx/MIoWBFa0StPA8ELUXHmA= github.com/muesli/cancelreader v0.2.2/go.mod h1:3XuTXfFS2VjM+HTLZY9Ak0l6eUKfijIfMUZ4EgX0QYo= -github.com/muesli/reflow v0.3.0 h1:IFsN6K9NfGtjeggFP+68I4chLZV2yIKsXJFNZ+eWh6s= -github.com/muesli/reflow v0.3.0/go.mod h1:pbwTDkVPibjO2kyvBQRBxTWEEGDGq0FlB1BIKtnHY/8= github.com/muesli/termenv v0.15.2 h1:GohcuySI0QmI3wN8Ok9PtKGkgkFIk7y6Vpb5PvrY+Wo= github.com/muesli/termenv v0.15.2/go.mod h1:Epx+iuz8sNs7mNKhxzH4fWXGNpZwUaJKRS1noLXviQ8= github.com/mwitkow/go-conntrack v0.0.0-20161129095857-cc309e4a2223/go.mod h1:qRWi+5nqEBWmkhHvq77mSJWrCKwh8bxhgT7d/eI7P4U= @@ -673,7 +670,6 @@ github.com/quasilyte/go-ruleguard/dsl v0.3.22 h1:wd8zkOhSNr+I+8Qeciml08ivDt1pSXe github.com/quasilyte/go-ruleguard/dsl v0.3.22/go.mod h1:KeCP03KrjuSO0H1kTuZQCWlQPulDV6YMIXmpQss17rU= github.com/remyoudompheng/bigfft v0.0.0-20230129092748-24d4a6f8daec h1:W09IVJc94icq4NjY3clb7Lk8O1qJ8BdBEF8z0ibU0rE= github.com/remyoudompheng/bigfft v0.0.0-20230129092748-24d4a6f8daec/go.mod h1:qqbHyh8v60DhA7CoWK5oRCqLrMHRGoxYCSS9EjAz6Eo= -github.com/rivo/uniseg v0.1.0/go.mod h1:J6wj4VEh+S6ZtnVlnTBMWIodfgj8LQOQFoIToxlJtxc= github.com/rivo/uniseg v0.2.0/go.mod h1:J6wj4VEh+S6ZtnVlnTBMWIodfgj8LQOQFoIToxlJtxc= github.com/rivo/uniseg v0.4.7 h1:WUdvkW8uEhrYfLC4ZzdpI2ztxP1I582+49Oc5Mq64VQ= github.com/rivo/uniseg v0.4.7/go.mod h1:FN3SvrM+Zdj16jyLfmOkMNblXMcoc8DfTHruCPUcx88= @@ -692,8 +688,8 @@ github.com/sagikazarmark/locafero v0.4.0 h1:HApY1R9zGo4DBgr7dqsTH/JJxLTTsOt7u6ke github.com/sagikazarmark/locafero v0.4.0/go.mod h1:Pe1W6UlPYUk/+wc/6KFhbORCfqzgYEpgQ3O5fPuL3H4= github.com/sagikazarmark/slog-shim v0.1.0 h1:diDBnUNK9N/354PgrxMywXnAwEr1QZcOr6gto+ugjYE= github.com/sagikazarmark/slog-shim v0.1.0/go.mod h1:SrcSrq8aKtyuqEI1uvTDTK1arOWRIczQRv+GVI1AkeQ= -github.com/sahilm/fuzzy v0.1.1-0.20230530133925-c48e322e2a8f h1:MvTmaQdww/z0Q4wrYjDSCcZ78NoftLQyHBSLW/Cx79Y= -github.com/sahilm/fuzzy v0.1.1-0.20230530133925-c48e322e2a8f/go.mod h1:VFvziUEIMCrT6A6tw2RFIXPXXmzXbOsSHF0DOI8ZK9Y= +github.com/sahilm/fuzzy v0.1.1 h1:ceu5RHF8DGgoi+/dR5PsECjCDH1BE3Fnmpo7aVXOdRA= +github.com/sahilm/fuzzy v0.1.1/go.mod h1:VFvziUEIMCrT6A6tw2RFIXPXXmzXbOsSHF0DOI8ZK9Y= github.com/saintfish/chardet v0.0.0-20230101081208-5e3ef4b5456d h1:hrujxIzL1woJ7AwssoOcM/tq5JjjG2yYOc8odClEiXA= github.com/saintfish/chardet v0.0.0-20230101081208-5e3ef4b5456d/go.mod h1:uugorj2VCxiV1x+LzaIdVa9b4S4qGAcH6cbhh4qVxOU= github.com/sanity-io/litter v1.5.5 h1:iE+sBxPBzoK6uaEP5Lt3fHNgpKcHXc/A2HGETy0uJQo= From 691f34ce278d530997a3af26ee854da24f35511c Mon Sep 17 00:00:00 2001 From: "anchore-actions-token-generator[bot]" <102182147+anchore-actions-token-generator[bot]@users.noreply.github.com> Date: Thu, 22 Aug 2024 13:52:34 -0400 Subject: [PATCH 081/122] chore(deps): update stereoscope to e6d086e8bef5fab4fcfbd60c9a759c4cb229decf (#3152) Signed-off-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com> Co-authored-by: kzantow <3009477+kzantow@users.noreply.github.com> From 6f0230879a385a4708e8431e57a66fd579d07cd2 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Thu, 22 Aug 2024 13:52:48 -0400 Subject: [PATCH 082/122] chore(deps): bump github/codeql-action from 3.26.3 to 3.26.4 (#3154) Bumps [github/codeql-action](https://github.com/github/codeql-action) from 3.26.3 to 3.26.4. - [Release notes](https://github.com/github/codeql-action/releases) - [Changelog](https://github.com/github/codeql-action/blob/main/CHANGELOG.md) - [Commits](https://github.com/github/codeql-action/compare/883d8588e56d1753a8a58c1c86e88976f0c23449...f0f3afee809481da311ca3a6ff1ff51d81dbeb24) --- updated-dependencies: - dependency-name: github/codeql-action dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- .github/workflows/codeql-analysis.yml | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/.github/workflows/codeql-analysis.yml b/.github/workflows/codeql-analysis.yml index 0ef325acd8a..29d639451e8 100644 --- a/.github/workflows/codeql-analysis.yml +++ b/.github/workflows/codeql-analysis.yml @@ -45,7 +45,7 @@ jobs: # Initializes the CodeQL tools for scanning. - name: Initialize CodeQL - uses: github/codeql-action/init@883d8588e56d1753a8a58c1c86e88976f0c23449 #v3.26.3 + uses: github/codeql-action/init@f0f3afee809481da311ca3a6ff1ff51d81dbeb24 #v3.26.4 with: languages: ${{ matrix.language }} # If you wish to specify custom queries, you can do so here or in a config file. @@ -56,7 +56,7 @@ jobs: # Autobuild attempts to build any compiled languages (C/C++, C#, or Java). # If this step fails, then you should remove it and run the build manually (see below) - name: Autobuild - uses: github/codeql-action/autobuild@883d8588e56d1753a8a58c1c86e88976f0c23449 #v3.26.3 + uses: github/codeql-action/autobuild@f0f3afee809481da311ca3a6ff1ff51d81dbeb24 #v3.26.4 # ℹī¸ Command-line programs to run using the OS shell. # 📚 https://git.io/JvXDl @@ -70,4 +70,4 @@ jobs: # make release - name: Perform CodeQL Analysis - uses: github/codeql-action/analyze@883d8588e56d1753a8a58c1c86e88976f0c23449 #v3.26.3 + uses: github/codeql-action/analyze@f0f3afee809481da311ca3a6ff1ff51d81dbeb24 #v3.26.4 From 9ab3de18198f1b86bb2446f983b3d80d7f5b231b Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Thu, 22 Aug 2024 13:52:58 -0400 Subject: [PATCH 083/122] chore(deps): bump anchore/sbom-action from 0.17.1 to 0.17.2 (#3155) Bumps [anchore/sbom-action](https://github.com/anchore/sbom-action) from 0.17.1 to 0.17.2. - [Release notes](https://github.com/anchore/sbom-action/releases) - [Commits](https://github.com/anchore/sbom-action/compare/ab9d16d4b419c9d1a02df5213fa0ebe965ca5a57...61119d458adab75f756bc0b9e4bde25725f86a7a) --- updated-dependencies: - dependency-name: anchore/sbom-action dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- .github/workflows/release.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/release.yaml b/.github/workflows/release.yaml index dc79d685f06..bf3e7db4983 100644 --- a/.github/workflows/release.yaml +++ b/.github/workflows/release.yaml @@ -148,7 +148,7 @@ jobs: # for updating brew formula in anchore/homebrew-syft GITHUB_BREW_TOKEN: ${{ secrets.ANCHOREOPS_GITHUB_OSS_WRITE_TOKEN }} - - uses: anchore/sbom-action@ab9d16d4b419c9d1a02df5213fa0ebe965ca5a57 #v0.17.1 + - uses: anchore/sbom-action@61119d458adab75f756bc0b9e4bde25725f86a7a #v0.17.2 continue-on-error: true with: artifact-name: sbom.spdx.json From cff9d494df431d8ef15c56f72a494bcd0aacfbd0 Mon Sep 17 00:00:00 2001 From: KrysGor <108719245+KrysGor@users.noreply.github.com> Date: Fri, 23 Aug 2024 20:41:08 +0200 Subject: [PATCH 084/122] feat: detect curl binaries (#3146) --- syft/pkg/cataloger/binary/classifiers.go | 10 ++++++++++ syft/pkg/cataloger/binary/test-fixtures/config.yaml | 9 +++++++++ 2 files changed, 19 insertions(+) diff --git a/syft/pkg/cataloger/binary/classifiers.go b/syft/pkg/cataloger/binary/classifiers.go index 5f4d3aa6651..563a39cfafe 100644 --- a/syft/pkg/cataloger/binary/classifiers.go +++ b/syft/pkg/cataloger/binary/classifiers.go @@ -529,6 +529,16 @@ func DefaultClassifiers() []Classifier { PURL: mustPURL("pkg:generic/wp-cli@version"), CPEs: singleCPE("cpe:2.3:a:wp-cli:wp-cli:*:*:*:*:*:*:*:*"), }, + { + Class: "curl-binary", + FileGlob: "**/curl", + EvidenceMatcher: FileContentsVersionMatcher( + `curl/(?P[0-9]+\.[0-9]+\.[0-9]+)`, + ), + Package: "curl", + PURL: mustPURL("pkg:generic/curl@version"), + CPEs: singleCPE("cpe:2.3:a:curl:curl:*:*:*:*:*:*:*:*"), + }, } } diff --git a/syft/pkg/cataloger/binary/test-fixtures/config.yaml b/syft/pkg/cataloger/binary/test-fixtures/config.yaml index 9ea3c2de71f..15273d33d2f 100644 --- a/syft/pkg/cataloger/binary/test-fixtures/config.yaml +++ b/syft/pkg/cataloger/binary/test-fixtures/config.yaml @@ -577,3 +577,12 @@ from-images: platform: linux/arm64 paths: - /usr/local/openresty/openssl/bin/openssl + + - name: curl + version: 8.9.1 + images: + - ref: curlimages/curl:8.9.1@sha256:8addc281f0ea517409209f76832b6ddc2cabc3264feb1ebbec2a2521ffad24e4 + platform: linux/amd64 + paths: + - /usr/bin/curl + From dad253785e40914ad84589fb5b590dad0cbc3560 Mon Sep 17 00:00:00 2001 From: "anchore-actions-token-generator[bot]" <102182147+anchore-actions-token-generator[bot]@users.noreply.github.com> Date: Fri, 23 Aug 2024 14:42:12 -0400 Subject: [PATCH 085/122] chore(deps): update tools to latest versions (#3144) --- .binny.yaml | 4 ++-- .golangci.yaml | 4 ++-- cmd/syft/internal/commands/attest.go | 3 +-- cmd/syft/internal/commands/convert.go | 1 - cmd/syft/internal/commands/scan.go | 7 +++---- internal/file/zip_read_closer.go | 16 ++++++++++------ internal/task/package_task_factory.go | 2 -- syft/file/cataloger/executable/elf.go | 2 +- .../internal/cyclonedxutil/helpers/component.go | 2 +- .../internal/cyclonedxutil/helpers/licenses.go | 1 - .../cyclonedxutil/helpers/property_encoder.go | 2 +- .../spdxutil/helpers/originator_supplier.go | 2 +- syft/format/syftjson/to_syft_model.go | 2 +- .../fileresolver/container_image_all_layers.go | 3 ++- .../fileresolver/container_image_squash.go | 3 ++- syft/pkg/cataloger/alpine/parse_apk_db.go | 2 +- syft/pkg/cataloger/binary/classifier.go | 1 - .../manager/internal/download_from_image.go | 4 ++-- syft/pkg/cataloger/debian/package.go | 2 -- syft/pkg/cataloger/debian/parse_dpkg_db.go | 2 +- .../internal/pkgtest/test_generic_parser.go | 1 - .../java/graalvm_native_image_cataloger.go | 6 +++--- syft/pkg/cataloger/java/maven_resolver.go | 2 +- syft/pkg/cataloger/php/parse_pecl_serialized.go | 4 ++-- syft/pkg/cataloger/redhat/parse_rpm_archive.go | 4 ++-- syft/pkg/cataloger/redhat/parse_rpm_db.go | 3 ++- syft/pkg/cataloger/rust/package.go | 1 - 27 files changed, 41 insertions(+), 45 deletions(-) diff --git a/.binny.yaml b/.binny.yaml index 686e946ecee..2277f197d5c 100644 --- a/.binny.yaml +++ b/.binny.yaml @@ -26,7 +26,7 @@ tools: # used for linting - name: golangci-lint version: - want: v1.60.1 + want: v1.60.3 method: github-release with: repo: golangci/golangci-lint @@ -111,7 +111,7 @@ tools: # used for triggering a release - name: gh version: - want: v2.54.0 + want: v2.55.0 method: github-release with: repo: cli/cli diff --git a/.golangci.yaml b/.golangci.yaml index 50df7cb73f2..3ea4697aea1 100644 --- a/.golangci.yaml +++ b/.golangci.yaml @@ -12,10 +12,10 @@ linters: enable: - asciicheck - bodyclose + - copyloopvar - dogsled - dupl - errcheck - - exportloopref - funlen - gocognit - goconst @@ -30,6 +30,7 @@ linters: - ineffassign - misspell - nakedret + - nolintlint - revive - staticcheck - stylecheck @@ -80,7 +81,6 @@ run: # - lll # without a way to specify per-line exception cases, this is not usable # - maligned # this is an excellent linter, but tricky to optimize and we are not sensitive to memory layout optimizations # - nestif -# - nolintlint # as of go1.19 this conflicts with the behavior of gofmt, which is a deal-breaker (lint-fix will still fail when running lint) # - prealloc # following this rule isn't consistently a good idea, as it sometimes forces unnecessary allocations that result in less idiomatic code # - rowserrcheck # not in a repo with sql, so this is not useful # - scopelint # deprecated diff --git a/cmd/syft/internal/commands/attest.go b/cmd/syft/internal/commands/attest.go index 374945eff3f..fa3b5ceef52 100644 --- a/cmd/syft/internal/commands/attest.go +++ b/cmd/syft/internal/commands/attest.go @@ -93,14 +93,13 @@ func defaultAttestOutputOptions() options.Output { string(spdxtagvalue.ID), }, Outputs: []string{syftjson.ID.String()}, - OutputFile: options.OutputFile{ // nolint:staticcheck + OutputFile: options.OutputFile{ //nolint:staticcheck Enabled: false, // explicitly not allowed }, Format: options.DefaultFormat(), } } -//nolint:funlen func runAttest(ctx context.Context, id clio.Identification, opts *attestOptions, userInput string) error { // TODO: what other validation here besides binary name? if !commandExists(cosignBinName) { diff --git a/cmd/syft/internal/commands/convert.go b/cmd/syft/internal/commands/convert.go index 2a1e6725643..510027ce7f5 100644 --- a/cmd/syft/internal/commands/convert.go +++ b/cmd/syft/internal/commands/convert.go @@ -28,7 +28,6 @@ type ConvertOptions struct { options.UpdateCheck `yaml:",inline" mapstructure:",squash"` } -//nolint:dupl func Convert(app clio.Application) *cobra.Command { id := app.ID() diff --git a/cmd/syft/internal/commands/scan.go b/cmd/syft/internal/commands/scan.go index efec9dd5b7d..48fcc8c1ebc 100644 --- a/cmd/syft/internal/commands/scan.go +++ b/cmd/syft/internal/commands/scan.go @@ -80,7 +80,6 @@ func defaultScanOptions() *scanOptions { } } -//nolint:dupl func Scan(app clio.Application) *cobra.Command { id := app.ID() @@ -396,13 +395,13 @@ func getExplanation(expErr task.ErrInvalidExpression) string { if errors.Is(err, task.ErrNamesNotAllowed) { if expErr.Operation == task.SubSelectOperation { - return "However, " + err.Error() + ".\nIt seems like you are intending to add a cataloger in addition to the default set." // nolint:goconst + return "However, " + err.Error() + ".\nIt seems like you are intending to add a cataloger in addition to the default set." } - return "However, " + err.Error() + "." // nolint:goconst + return "However, " + err.Error() + "." } if errors.Is(err, task.ErrTagsNotAllowed) { - return "However, " + err.Error() + ".\nAdding groups of catalogers may result in surprising behavior (create inaccurate SBOMs)." // nolint:goconst + return "However, " + err.Error() + ".\nAdding groups of catalogers may result in surprising behavior (create inaccurate SBOMs)." } if errors.Is(err, task.ErrAllNotAllowed) { diff --git a/internal/file/zip_read_closer.go b/internal/file/zip_read_closer.go index 5722092dbf4..5f82a2127af 100644 --- a/internal/file/zip_read_closer.go +++ b/internal/file/zip_read_closer.go @@ -6,6 +6,7 @@ import ( "errors" "fmt" "io" + "math" "os" ) @@ -52,9 +53,14 @@ func OpenZip(filepath string) (*ZipReadCloser, error) { return nil, fmt.Errorf("unable to seek to beginning of archive: %w", err) } - size := fi.Size() - int64(offset) + if offset > math.MaxInt64 { + return nil, fmt.Errorf("archive start offset too large: %v", offset) + } + offset64 := int64(offset) //nolint:gosec // lint bug, checked above: https://github.com/securego/gosec/issues/1187 + + size := fi.Size() - offset64 - r, err := zip.NewReader(io.NewSectionReader(f, int64(offset), size), size) + r, err := zip.NewReader(io.NewSectionReader(f, offset64, size), size) if err != nil { return nil, fmt.Errorf("unable to open ZipReadCloser @ %q: %w", filepath, err) } @@ -95,8 +101,6 @@ type directoryEnd struct { } // note: this is derived from readDirectoryEnd within the archive/zip package -// -//nolint:gocognit func findArchiveStartOffset(r io.ReaderAt, size int64) (startOfArchive uint64, err error) { // look for directoryEndSignature in the last 1k, then in the last 65k var buf []byte @@ -150,7 +154,7 @@ func findArchiveStartOffset(r io.ReaderAt, size int64) (startOfArchive uint64, e startOfArchive = uint64(directoryEndOffset) - d.directorySize - d.directoryOffset // Make sure directoryOffset points to somewhere in our file. - if o := int64(d.directoryOffset); o < 0 || o >= size { + if d.directoryOffset >= uint64(size) { return 0, zip.ErrFormat } return startOfArchive, nil @@ -179,7 +183,7 @@ func findDirectory64End(r io.ReaderAt, directoryEndOffset int64) (int64, error) if b.uint32() != 1 { // total number of disks return -1, nil // the file is not a valid zip64-file } - return int64(p), nil + return int64(p), nil //nolint:gosec } // readDirectory64End reads the zip64 directory end and updates the diff --git a/internal/task/package_task_factory.go b/internal/task/package_task_factory.go index 0ee59810f6d..4fdb1121e2b 100644 --- a/internal/task/package_task_factory.go +++ b/internal/task/package_task_factory.go @@ -81,8 +81,6 @@ func (f PackageTaskFactories) Tasks(cfg CatalogingFactoryConfig) ([]Task, error) } // NewPackageTask creates a Task function for a generic pkg.Cataloger, honoring the common configuration options. -// -//nolint:funlen func NewPackageTask(cfg CatalogingFactoryConfig, c pkg.Cataloger, tags ...string) Task { fn := func(ctx context.Context, resolver file.Resolver, sbom sbomsync.Builder) error { catalogerName := c.Name() diff --git a/syft/file/cataloger/executable/elf.go b/syft/file/cataloger/executable/elf.go index dec6abd34ed..9c6ad6151f1 100644 --- a/syft/file/cataloger/executable/elf.go +++ b/syft/file/cataloger/executable/elf.go @@ -175,7 +175,7 @@ func hasElfDynTag(f *elf.File, tag elf.DynTag) bool { t = elf.DynTag(f.ByteOrder.Uint32(d[0:4])) d = d[8:] case elf.ELFCLASS64: - t = elf.DynTag(f.ByteOrder.Uint64(d[0:8])) + t = elf.DynTag(f.ByteOrder.Uint64(d[0:8])) //nolint:gosec d = d[16:] } if t == tag { diff --git a/syft/format/internal/cyclonedxutil/helpers/component.go b/syft/format/internal/cyclonedxutil/helpers/component.go index fa6dd75fabe..526094ac5c3 100644 --- a/syft/format/internal/cyclonedxutil/helpers/component.go +++ b/syft/format/internal/cyclonedxutil/helpers/component.go @@ -124,7 +124,7 @@ func decodePackageMetadata(vals map[string]string, c *cyclonedx.Component, typeN if metadataType == nil { return nil } - metaPtrTyp := reflect.PtrTo(metadataType) + metaPtrTyp := reflect.PointerTo(metadataType) metaPtr := Decode(metaPtrTyp, vals, "syft:metadata", CycloneDXFields) // Map all explicit metadata properties diff --git a/syft/format/internal/cyclonedxutil/helpers/licenses.go b/syft/format/internal/cyclonedxutil/helpers/licenses.go index fb63b651073..a092d3abdf3 100644 --- a/syft/format/internal/cyclonedxutil/helpers/licenses.go +++ b/syft/format/internal/cyclonedxutil/helpers/licenses.go @@ -72,7 +72,6 @@ func decodeLicenses(c *cyclonedx.Component) []pkg.License { return licenses } -// nolint:funlen func separateLicenses(p pkg.Package) (spdx, other cyclonedx.Licenses, expressions []string) { ex := make([]string, 0) spdxc := cyclonedx.Licenses{} diff --git a/syft/format/internal/cyclonedxutil/helpers/property_encoder.go b/syft/format/internal/cyclonedxutil/helpers/property_encoder.go index fb9a201d1aa..79d614e3536 100644 --- a/syft/format/internal/cyclonedxutil/helpers/property_encoder.go +++ b/syft/format/internal/cyclonedxutil/helpers/property_encoder.go @@ -165,7 +165,7 @@ func Decode(typ reflect.Type, values map[string]string, prefix string, fn FieldN isSlice := false if typ.Kind() == reflect.Slice { - typ = reflect.PtrTo(typ) + typ = reflect.PointerTo(typ) isSlice = true } diff --git a/syft/format/internal/spdxutil/helpers/originator_supplier.go b/syft/format/internal/spdxutil/helpers/originator_supplier.go index d2af96971b3..478cef377cf 100644 --- a/syft/format/internal/spdxutil/helpers/originator_supplier.go +++ b/syft/format/internal/spdxutil/helpers/originator_supplier.go @@ -34,7 +34,7 @@ const ( // // Available options are: , NOASSERTION, Person: , Organization: // return values are: , -func Originator(p pkg.Package) (typ string, author string) { // nolint: funlen +func Originator(p pkg.Package) (typ string, author string) { //nolint: funlen if !hasMetadata(p) { return typ, author } diff --git a/syft/format/syftjson/to_syft_model.go b/syft/format/syftjson/to_syft_model.go index b2b1916e26d..289e91fda52 100644 --- a/syft/format/syftjson/to_syft_model.go +++ b/syft/format/syftjson/to_syft_model.go @@ -146,7 +146,7 @@ func safeFileModeConvert(val int) (fs.FileMode, error) { if err != nil { return 0, err } - return os.FileMode(mode), nil + return os.FileMode(mode), nil //nolint:gosec } func toSyftLicenses(m []model.License) (p []pkg.License) { diff --git a/syft/internal/fileresolver/container_image_all_layers.go b/syft/internal/fileresolver/container_image_all_layers.go index c1120956b0d..4bad1ef1ba1 100644 --- a/syft/internal/fileresolver/container_image_all_layers.go +++ b/syft/internal/fileresolver/container_image_all_layers.go @@ -120,7 +120,8 @@ func (r *ContainerImageAllLayers) FilesByPath(paths ...string) ([]file.Location, } // FilesByGlob returns all file.References that match the given path glob pattern from any layer in the image. -// nolint:gocognit +// +//nolint:gocognit func (r *ContainerImageAllLayers) FilesByGlob(patterns ...string) ([]file.Location, error) { uniqueFileIDs := stereoscopeFile.NewFileReferenceSet() uniqueLocations := make([]file.Location, 0) diff --git a/syft/internal/fileresolver/container_image_squash.go b/syft/internal/fileresolver/container_image_squash.go index b3a5ded8914..d3593c9695e 100644 --- a/syft/internal/fileresolver/container_image_squash.go +++ b/syft/internal/fileresolver/container_image_squash.go @@ -79,7 +79,8 @@ func (r *ContainerImageSquash) FilesByPath(paths ...string) ([]file.Location, er } // FilesByGlob returns all file.References that match the given path glob pattern within the squashed representation of the image. -// nolint:gocognit +// +//nolint:gocognit func (r *ContainerImageSquash) FilesByGlob(patterns ...string) ([]file.Location, error) { uniqueFileIDs := stereoscopeFile.NewFileReferenceSet() uniqueLocations := make([]file.Location, 0) diff --git a/syft/pkg/cataloger/alpine/parse_apk_db.go b/syft/pkg/cataloger/alpine/parse_apk_db.go index 5948e303554..227d93bcbb4 100644 --- a/syft/pkg/cataloger/alpine/parse_apk_db.go +++ b/syft/pkg/cataloger/alpine/parse_apk_db.go @@ -34,7 +34,7 @@ type parsedData struct { // parseApkDB parses packages from a given APK "installed" flat-file DB. For more // information on specific fields, see https://wiki.alpinelinux.org/wiki/Apk_spec. // -//nolint:funlen,gocognit +//nolint:funlen func parseApkDB(_ context.Context, resolver file.Resolver, env *generic.Environment, reader file.LocationReadCloser) ([]pkg.Package, []artifact.Relationship, error) { scanner := bufio.NewScanner(reader) diff --git a/syft/pkg/cataloger/binary/classifier.go b/syft/pkg/cataloger/binary/classifier.go index 19630679356..998242b6646 100644 --- a/syft/pkg/cataloger/binary/classifier.go +++ b/syft/pkg/cataloger/binary/classifier.go @@ -196,7 +196,6 @@ func matchExcluding(matcher EvidenceMatcher, contentPatternsToExclude ...string) } } -//nolint:gocognit func sharedLibraryLookup(sharedLibraryPattern string, sharedLibraryMatcher EvidenceMatcher) EvidenceMatcher { pat := regexp.MustCompile(sharedLibraryPattern) return func(classifier Classifier, context matcherContext) (packages []pkg.Package, _ error) { diff --git a/syft/pkg/cataloger/binary/test-fixtures/manager/internal/download_from_image.go b/syft/pkg/cataloger/binary/test-fixtures/manager/internal/download_from_image.go index 49fa7028638..32b9c83d6dd 100644 --- a/syft/pkg/cataloger/binary/test-fixtures/manager/internal/download_from_image.go +++ b/syft/pkg/cataloger/binary/test-fixtures/manager/internal/download_from_image.go @@ -157,7 +157,7 @@ func copyBinariesFromDockerImage(config config.BinaryFromImage, destination stri defer func() { cmd := exec.Command("docker", "rm", containerName) - cmd.Run() // nolint:errcheck + cmd.Run() //nolint:errcheck }() for i, destinationPath := range config.AllStorePathsForImage(image, destination) { @@ -182,7 +182,7 @@ func copyBinaryFromContainer(containerName, containerPath, destinationPath, fing return err } - cmd := exec.Command("docker", "cp", fmt.Sprintf("%s:%s", containerName, containerPath), destinationPath) // nolint:gosec + cmd := exec.Command("docker", "cp", fmt.Sprintf("%s:%s", containerName, containerPath), destinationPath) //nolint:gosec // reason for gosec exception: this is for processing test fixtures only, not used in production if err := cmd.Run(); err != nil { return err diff --git a/syft/pkg/cataloger/debian/package.go b/syft/pkg/cataloger/debian/package.go index bc0db7bcf3b..d31830e87fd 100644 --- a/syft/pkg/cataloger/debian/package.go +++ b/syft/pkg/cataloger/debian/package.go @@ -169,7 +169,6 @@ func getAdditionalFileListing(resolver file.Resolver, dbLocation file.Location, return files, locations } -//nolint:dupl func fetchMd5Contents(resolver file.Resolver, dbLocation file.Location, m pkg.DpkgDBEntry) (io.ReadCloser, *file.Location) { var md5Reader io.ReadCloser var err error @@ -213,7 +212,6 @@ func fetchMd5Contents(resolver file.Resolver, dbLocation file.Location, m pkg.Dp return md5Reader, &l } -//nolint:dupl func fetchConffileContents(resolver file.Resolver, dbLocation file.Location, m pkg.DpkgDBEntry) (io.ReadCloser, *file.Location) { var reader io.ReadCloser var err error diff --git a/syft/pkg/cataloger/debian/parse_dpkg_db.go b/syft/pkg/cataloger/debian/parse_dpkg_db.go index 077e5bef906..87428d608fb 100644 --- a/syft/pkg/cataloger/debian/parse_dpkg_db.go +++ b/syft/pkg/cataloger/debian/parse_dpkg_db.go @@ -230,7 +230,7 @@ func handleNewKeyValue(line string) (key string, val interface{}, err error) { if err != nil { return "", nil, fmt.Errorf("bad installed-size value=%q: %w", val, err) } - return key, int(s), nil + return key, int(s), nil //nolint:gosec default: return key, val, nil } diff --git a/syft/pkg/cataloger/internal/pkgtest/test_generic_parser.go b/syft/pkg/cataloger/internal/pkgtest/test_generic_parser.go index 2dcbb7f8bec..ae26bb6d13b 100644 --- a/syft/pkg/cataloger/internal/pkgtest/test_generic_parser.go +++ b/syft/pkg/cataloger/internal/pkgtest/test_generic_parser.go @@ -264,7 +264,6 @@ func (p *CatalogTester) TestCataloger(t *testing.T, cataloger pkg.Cataloger) { } } -// nolint:funlen func (p *CatalogTester) assertPkgs(t *testing.T, pkgs []pkg.Package, relationships []artifact.Relationship) { t.Helper() diff --git a/syft/pkg/cataloger/java/graalvm_native_image_cataloger.go b/syft/pkg/cataloger/java/graalvm_native_image_cataloger.go index add09a45899..5dd74a65472 100644 --- a/syft/pkg/cataloger/java/graalvm_native_image_cataloger.go +++ b/syft/pkg/cataloger/java/graalvm_native_image_cataloger.go @@ -268,7 +268,7 @@ func newPE(filename string, r io.ReaderAt) (nativeImage, error) { } exportSymbolsOffset := uint64(exportSymbolsDataDirectory.VirtualAddress) exports := make([]byte, exportSymbolsDataDirectory.Size) - _, err = r.ReadAt(exports, int64(exportSymbolsOffset)) + _, err = r.ReadAt(exports, int64(exportSymbolsOffset)) //nolint:gosec if err != nil { return fileError(filename, fmt.Errorf("could not read the exported symbols data directory: %w", err)) } @@ -412,7 +412,7 @@ func (ni nativeImagePE) fetchExportAttribute(i int) (uint32, error) { func (ni nativeImagePE) fetchExportFunctionPointer(functionsBase uint32, i uint32) (uint32, error) { var pointer uint32 - n := uint32(len(ni.exports)) + n := uint32(len(ni.exports)) //nolint:gosec sz := uint32(unsafe.Sizeof(ni.t.functionPointer)) j := functionsBase + i*sz if j+sz >= n { @@ -457,7 +457,7 @@ func (ni nativeImagePE) fetchSbomSymbols(content *exportContentPE) { sbomBytes := []byte(nativeImageSbomSymbol + "\x00") sbomLengthBytes := []byte(nativeImageSbomLengthSymbol + "\x00") svmVersionInfoBytes := []byte(nativeImageSbomVersionSymbol + "\x00") - n := uint32(len(ni.exports)) + n := uint32(len(ni.exports)) //nolint:gosec // Find SBOM, SBOM Length, and SVM Version Symbol for i := uint32(0); i < content.numberOfNames; i++ { diff --git a/syft/pkg/cataloger/java/maven_resolver.go b/syft/pkg/cataloger/java/maven_resolver.go index 5fddccc3191..e7e73b0be80 100644 --- a/syft/pkg/cataloger/java/maven_resolver.go +++ b/syft/pkg/cataloger/java/maven_resolver.go @@ -342,7 +342,7 @@ func (r *mavenResolver) findPomInRemoteRepository(ctx context.Context, groupID, Timeout: r.remoteRequestTimeout, } - resp, err := client.Do(req) //nolint:bodyclose + resp, err := client.Do(req) if err != nil { return nil, fmt.Errorf("unable to get pom from Maven repository %v: %w", requestURL, err) } diff --git a/syft/pkg/cataloger/php/parse_pecl_serialized.go b/syft/pkg/cataloger/php/parse_pecl_serialized.go index 7f48f209607..84c5c4c3bbd 100644 --- a/syft/pkg/cataloger/php/parse_pecl_serialized.go +++ b/syft/pkg/cataloger/php/parse_pecl_serialized.go @@ -60,10 +60,10 @@ func readStruct(metadata any, fields ...string) string { if len(fields) > 0 { value, ok := metadata.(map[any]any) if !ok { - log.Tracef("unable to read '%s' from: %v", fields[0], metadata) + log.Tracef("unable to read '%s' from: %v", fields[0], metadata) //nolint:gosec return "" } - return readStruct(value[fields[0]], fields[1:]...) + return readStruct(value[fields[0]], fields[1:]...) //nolint:gosec } value, ok := metadata.(string) if !ok { diff --git a/syft/pkg/cataloger/redhat/parse_rpm_archive.go b/syft/pkg/cataloger/redhat/parse_rpm_archive.go index 8c4b395a76a..e7d4b228795 100644 --- a/syft/pkg/cataloger/redhat/parse_rpm_archive.go +++ b/syft/pkg/cataloger/redhat/parse_rpm_archive.go @@ -88,12 +88,12 @@ func mapFiles(files []rpmutils.FileInfo, digestAlgorithm string) []pkg.RpmFileRe } out = append(out, pkg.RpmFileRecord{ Path: f.Name(), - Mode: pkg.RpmFileMode(f.Mode()), + Mode: pkg.RpmFileMode(f.Mode()), //nolint:gosec Size: int(f.Size()), Digest: digest, UserName: f.UserName(), GroupName: f.GroupName(), - Flags: rpmdb.FileFlags(f.Flags()).String(), + Flags: rpmdb.FileFlags(f.Flags()).String(), //nolint:gosec }) } return out diff --git a/syft/pkg/cataloger/redhat/parse_rpm_db.go b/syft/pkg/cataloger/redhat/parse_rpm_db.go index d2954213703..23c5dd487a6 100644 --- a/syft/pkg/cataloger/redhat/parse_rpm_db.go +++ b/syft/pkg/cataloger/redhat/parse_rpm_db.go @@ -17,7 +17,8 @@ import ( ) // parseRpmDb parses an "Packages" RPM DB and returns the Packages listed within it. -// nolint:funlen +// +//nolint:funlen func parseRpmDB(_ context.Context, resolver file.Resolver, env *generic.Environment, reader file.LocationReadCloser) ([]pkg.Package, []artifact.Relationship, error) { f, err := os.CreateTemp("", "rpmdb") if err != nil { diff --git a/syft/pkg/cataloger/rust/package.go b/syft/pkg/cataloger/rust/package.go index 93d1eeaeee3..be67d96a936 100644 --- a/syft/pkg/cataloger/rust/package.go +++ b/syft/pkg/cataloger/rust/package.go @@ -29,7 +29,6 @@ func newPackagesFromAudit(location file.Location, versionInfo rustaudit.VersionI var pkgs []pkg.Package for _, dep := range versionInfo.Packages { - dep := dep p := newPackageFromAudit(&dep, location.WithAnnotation(pkg.EvidenceAnnotationKey, pkg.PrimaryEvidenceAnnotation)) if pkg.IsValid(&p) && dep.Kind == rustaudit.Runtime { pkgs = append(pkgs, p) From b6b5c8e3084327f118abdd4c7d3b41e8fe9efec7 Mon Sep 17 00:00:00 2001 From: Alex Goodman Date: Mon, 26 Aug 2024 08:44:39 -0400 Subject: [PATCH 086/122] fix ELF package correlations (#3151) --- .../binary/binary_dependencies.go | 5 ++-- .../binary/binary_dependencies_test.go | 30 ++++++++++++++++--- 2 files changed, 28 insertions(+), 7 deletions(-) diff --git a/internal/relationship/binary/binary_dependencies.go b/internal/relationship/binary/binary_dependencies.go index b23b42b9a42..210f88114c3 100644 --- a/internal/relationship/binary/binary_dependencies.go +++ b/internal/relationship/binary/binary_dependencies.go @@ -36,8 +36,7 @@ func generateRelationships(resolver file.Resolver, accessor sbomsync.Accessor, i newRelationships.Add(r) } } - - for _, parentPkg := range s.Artifacts.Packages.Sorted(pkg.BinaryPkg) { + for _, parentPkg := range allElfPackages(s) { for _, evidentLocation := range parentPkg.Locations.ToSlice() { if evidentLocation.Annotations[pkg.EvidenceAnnotationKey] != pkg.PrimaryEvidenceAnnotation { continue @@ -101,7 +100,7 @@ func onlyPrimaryEvidenceLocations(p pkg.Package) []file.Location { func allElfPackages(s *sbom.SBOM) []pkg.Package { var elfPkgs []pkg.Package - for _, p := range s.Artifacts.Packages.Sorted(pkg.BinaryPkg) { + for _, p := range s.Artifacts.Packages.Sorted() { if !isElfPackage(p) { continue } diff --git a/internal/relationship/binary/binary_dependencies_test.go b/internal/relationship/binary/binary_dependencies_test.go index 33c6436c351..ea524fa1f7c 100644 --- a/internal/relationship/binary/binary_dependencies_test.go +++ b/internal/relationship/binary/binary_dependencies_test.go @@ -50,6 +50,22 @@ func TestPackagesToRemove(t *testing.T) { } glibCBinaryELFPackage.SetID() + glibCBinaryELFPackageAsRPM := pkg.Package{ + Name: "glibc", + Locations: file.NewLocationSet( + file.NewLocation(glibcCoordinate.RealPath).WithAnnotation(pkg.EvidenceAnnotationKey, pkg.PrimaryEvidenceAnnotation), + ), + Type: pkg.RpmPkg, // note: the elf package claims it is a RPM, not binary + Metadata: pkg.ELFBinaryPackageNoteJSONPayload{ + Type: "rpm", + Vendor: "syft", + System: "syftsys", + SourceRepo: "https://github.com/someone/somewhere.git", + Commit: "5534c38d0ffef9a3f83154f0b7a7fb6ab0ab6dbb", + }, + } + glibCBinaryELFPackageAsRPM.SetID() + glibCBinaryClassifierPackage := pkg.Package{ Name: "glibc", Locations: file.NewLocationSet( @@ -83,9 +99,15 @@ func TestPackagesToRemove(t *testing.T) { want: []artifact.ID{glibCBinaryELFPackage.ID()}, }, { - name: "remove no packages when there is a single binary package", + name: "keep packages that are overlapping rpm --> binary when the binary self identifies as an RPM", resolver: file.NewMockResolverForPaths(glibcCoordinate.RealPath), - accessor: newAccessor([]pkg.Package{glibCBinaryELFPackage}, map[file.Coordinates]file.Executable{}, nil), + accessor: newAccessor([]pkg.Package{glibCPackage, glibCBinaryELFPackageAsRPM}, map[file.Coordinates]file.Executable{}, nil), + want: []artifact.ID{}, + }, + { + name: "remove no packages when there is a single binary package (or self identifying RPM)", + resolver: file.NewMockResolverForPaths(glibcCoordinate.RealPath), + accessor: newAccessor([]pkg.Package{glibCBinaryELFPackage, glibCBinaryELFPackageAsRPM}, map[file.Coordinates]file.Executable{}, nil), want: []artifact.ID{}, }, { @@ -173,9 +195,9 @@ func TestNewDependencyRelationships(t *testing.T) { file.NewLocation(parallelLibCoordinate.RealPath).WithAnnotation(pkg.EvidenceAnnotationKey, pkg.SupportingEvidenceAnnotation), ), Language: "", - Type: pkg.BinaryPkg, + Type: pkg.RpmPkg, Metadata: pkg.ELFBinaryPackageNoteJSONPayload{ - Type: "testfixture", + Type: "rpm", Vendor: "syft", System: "syftsys", SourceRepo: "https://github.com/someone/somewhere.git", From 6549ec9831ac3fd5ca23b615c54cab5201ead180 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 26 Aug 2024 10:07:18 -0400 Subject: [PATCH 087/122] chore(deps): bump github/codeql-action from 3.26.4 to 3.26.5 (#3162) Bumps [github/codeql-action](https://github.com/github/codeql-action) from 3.26.4 to 3.26.5. - [Release notes](https://github.com/github/codeql-action/releases) - [Changelog](https://github.com/github/codeql-action/blob/main/CHANGELOG.md) - [Commits](https://github.com/github/codeql-action/compare/f0f3afee809481da311ca3a6ff1ff51d81dbeb24...2c779ab0d087cd7fe7b826087247c2c81f27bfa6) --- updated-dependencies: - dependency-name: github/codeql-action dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- .github/workflows/codeql-analysis.yml | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/.github/workflows/codeql-analysis.yml b/.github/workflows/codeql-analysis.yml index 29d639451e8..768415473fd 100644 --- a/.github/workflows/codeql-analysis.yml +++ b/.github/workflows/codeql-analysis.yml @@ -45,7 +45,7 @@ jobs: # Initializes the CodeQL tools for scanning. - name: Initialize CodeQL - uses: github/codeql-action/init@f0f3afee809481da311ca3a6ff1ff51d81dbeb24 #v3.26.4 + uses: github/codeql-action/init@2c779ab0d087cd7fe7b826087247c2c81f27bfa6 #v3.26.5 with: languages: ${{ matrix.language }} # If you wish to specify custom queries, you can do so here or in a config file. @@ -56,7 +56,7 @@ jobs: # Autobuild attempts to build any compiled languages (C/C++, C#, or Java). # If this step fails, then you should remove it and run the build manually (see below) - name: Autobuild - uses: github/codeql-action/autobuild@f0f3afee809481da311ca3a6ff1ff51d81dbeb24 #v3.26.4 + uses: github/codeql-action/autobuild@2c779ab0d087cd7fe7b826087247c2c81f27bfa6 #v3.26.5 # ℹī¸ Command-line programs to run using the OS shell. # 📚 https://git.io/JvXDl @@ -70,4 +70,4 @@ jobs: # make release - name: Perform CodeQL Analysis - uses: github/codeql-action/analyze@f0f3afee809481da311ca3a6ff1ff51d81dbeb24 #v3.26.4 + uses: github/codeql-action/analyze@2c779ab0d087cd7fe7b826087247c2c81f27bfa6 #v3.26.5 From 0cd618571633ebb5887ae3cd8ada045bcaae7722 Mon Sep 17 00:00:00 2001 From: "anchore-actions-token-generator[bot]" <102182147+anchore-actions-token-generator[bot]@users.noreply.github.com> Date: Mon, 26 Aug 2024 10:07:44 -0400 Subject: [PATCH 088/122] chore(deps): update CPE dictionary index (#3161) Signed-off-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com> Co-authored-by: wagoodman <590471+wagoodman@users.noreply.github.com> --- .../internal/cpegenerate/dictionary/data/cpe-index.json | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/syft/pkg/cataloger/internal/cpegenerate/dictionary/data/cpe-index.json b/syft/pkg/cataloger/internal/cpegenerate/dictionary/data/cpe-index.json index 8fd77ee19f4..20dee5938ce 100644 --- a/syft/pkg/cataloger/internal/cpegenerate/dictionary/data/cpe-index.json +++ b/syft/pkg/cataloger/internal/cpegenerate/dictionary/data/cpe-index.json @@ -6075,6 +6075,9 @@ "ftpd": [ "cpe:2.3:a:ftpd_project:ftpd:*:*:*:*:*:ruby:*:*" ], + "fugit": [ + "cpe:2.3:a:floraison:fugit:*:*:*:*:*:ruby:*:*" + ], "geminabox": [ "cpe:2.3:a:geminabox_project:geminabox:*:*:*:*:*:ruby:*:*" ], @@ -7970,7 +7973,10 @@ "cpe:2.3:a:bcorp_shortcodes_project:bcorp_shortcodes:*:*:*:*:*:wordpress:*:*" ], "bdthemes-element-pack-lite": [ - "cpe:2.3:a:bdthemes:element_pack_elementor_addons:*:*:*:*:*:wordpress:*:*" + "cpe:2.3:a:bdthemes:element_pack:*:*:*:*:lite:wordpress:*:*" + ], + "bdthemes-element-pack-lite#tags": [ + "cpe:2.3:a:bdthemes:element_pack:*:*:*:*:lite:wordpress:*:*" ], "bdvs-password-reset": [ "cpe:2.3:a:bedevious:password_reset_with_code_for_wordpress_rest_api:*:*:*:*:*:wordpress:*:*" From cf9bb13f2bfeb737ca89be67e1b44fdab4adb2d1 Mon Sep 17 00:00:00 2001 From: "anchore-actions-token-generator[bot]" <102182147+anchore-actions-token-generator[bot]@users.noreply.github.com> Date: Mon, 26 Aug 2024 10:07:59 -0400 Subject: [PATCH 089/122] chore(deps): update tools to latest versions (#3160) Signed-off-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com> Co-authored-by: spiffcs <32073428+spiffcs@users.noreply.github.com> --- .binny.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.binny.yaml b/.binny.yaml index 2277f197d5c..a9a37439333 100644 --- a/.binny.yaml +++ b/.binny.yaml @@ -34,7 +34,7 @@ tools: # used for showing the changelog at release - name: glow version: - want: v1.5.1 + want: v2.0.0 method: github-release with: repo: charmbracelet/glow From 99be365f625fc49f2c4f9b7a4dbbb56af5d71b6e Mon Sep 17 00:00:00 2001 From: Weston Steimel Date: Tue, 27 Aug 2024 14:03:19 +0100 Subject: [PATCH 090/122] fix: use official CPE for curl binary cataloger (#3164) The official CPE for curl is `cpe:2.3:a:haxx:curl:*:*:*:*:*:*:*:*` Signed-off-by: Weston Steimel --- syft/pkg/cataloger/binary/classifiers.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/syft/pkg/cataloger/binary/classifiers.go b/syft/pkg/cataloger/binary/classifiers.go index 563a39cfafe..b9df7aa46dd 100644 --- a/syft/pkg/cataloger/binary/classifiers.go +++ b/syft/pkg/cataloger/binary/classifiers.go @@ -537,7 +537,7 @@ func DefaultClassifiers() []Classifier { ), Package: "curl", PURL: mustPURL("pkg:generic/curl@version"), - CPEs: singleCPE("cpe:2.3:a:curl:curl:*:*:*:*:*:*:*:*"), + CPEs: singleCPE("cpe:2.3:a:haxx:curl:*:*:*:*:*:*:*:*"), }, } } From 4ee6c179f8002158cbddb64fee484a9a8f606ddc Mon Sep 17 00:00:00 2001 From: Alex Goodman Date: Tue, 27 Aug 2024 09:23:43 -0400 Subject: [PATCH 091/122] set cataloger names within package cataloger task (#3165) Signed-off-by: Alex Goodman --- internal/task/package_task_factory.go | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/internal/task/package_task_factory.go b/internal/task/package_task_factory.go index 4fdb1121e2b..d220a2bea74 100644 --- a/internal/task/package_task_factory.go +++ b/internal/task/package_task_factory.go @@ -81,7 +81,7 @@ func (f PackageTaskFactories) Tasks(cfg CatalogingFactoryConfig) ([]Task, error) } // NewPackageTask creates a Task function for a generic pkg.Cataloger, honoring the common configuration options. -func NewPackageTask(cfg CatalogingFactoryConfig, c pkg.Cataloger, tags ...string) Task { +func NewPackageTask(cfg CatalogingFactoryConfig, c pkg.Cataloger, tags ...string) Task { //nolint: funlen fn := func(ctx context.Context, resolver file.Resolver, sbom sbomsync.Builder) error { catalogerName := c.Name() log.WithFields("name", catalogerName).Trace("starting package cataloger") @@ -100,12 +100,15 @@ func NewPackageTask(cfg CatalogingFactoryConfig, c pkg.Cataloger, tags ...string pkgs, relationships, err := c.Catalog(ctx, resolver) if err != nil { - return fmt.Errorf("unable to catalog packages with %q: %w", c.Name(), err) + return fmt.Errorf("unable to catalog packages with %q: %w", catalogerName, err) } - log.WithFields("cataloger", c.Name()).Debugf("discovered %d packages", len(pkgs)) + log.WithFields("cataloger", catalogerName).Debugf("discovered %d packages", len(pkgs)) for i, p := range pkgs { + if p.FoundBy == "" { + p.FoundBy = catalogerName + } if cfg.DataGenerationConfig.GenerateCPEs { // generate CPEs (note: this is excluded from package ID, so is safe to mutate) // we might have binary classified CPE already with the package so we want to append here @@ -143,7 +146,7 @@ func NewPackageTask(cfg CatalogingFactoryConfig, c pkg.Cataloger, tags ...string t.Add(int64(len(pkgs))) t.SetCompleted() - log.WithFields("name", c.Name()).Trace("package cataloger completed") + log.WithFields("name", catalogerName).Trace("package cataloger completed") return nil } From e9a8c27be123d03561a54f2755822c0bf872c35d Mon Sep 17 00:00:00 2001 From: Alex Goodman Date: Tue, 27 Aug 2024 10:26:35 -0400 Subject: [PATCH 092/122] respond to authoratative CPEs from catalogers (#3166) Signed-off-by: Alex Goodman --- internal/task/package_task_factory.go | 19 ++++++-- internal/task/package_task_factory_test.go | 55 ++++++++++++++++++++++ syft/pkg/cataloger/binary/classifier.go | 8 +++- syft/pkg/cataloger/binary/classifiers.go | 2 +- 4 files changed, 77 insertions(+), 7 deletions(-) create mode 100644 internal/task/package_task_factory_test.go diff --git a/internal/task/package_task_factory.go b/internal/task/package_task_factory.go index d220a2bea74..8a31c0483a7 100644 --- a/internal/task/package_task_factory.go +++ b/internal/task/package_task_factory.go @@ -15,10 +15,11 @@ import ( "github.com/anchore/syft/syft/artifact" "github.com/anchore/syft/syft/cataloging" "github.com/anchore/syft/syft/cataloging/pkgcataloging" + "github.com/anchore/syft/syft/cpe" "github.com/anchore/syft/syft/event/monitor" "github.com/anchore/syft/syft/file" "github.com/anchore/syft/syft/pkg" - "github.com/anchore/syft/syft/pkg/cataloger/common/cpe" + cpeutils "github.com/anchore/syft/syft/pkg/cataloger/common/cpe" ) type packageTaskFactory func(cfg CatalogingFactoryConfig) Task @@ -109,15 +110,16 @@ func NewPackageTask(cfg CatalogingFactoryConfig, c pkg.Cataloger, tags ...string if p.FoundBy == "" { p.FoundBy = catalogerName } - if cfg.DataGenerationConfig.GenerateCPEs { + + if cfg.DataGenerationConfig.GenerateCPEs && !hasAuthoritativeCPE(p.CPEs) { // generate CPEs (note: this is excluded from package ID, so is safe to mutate) // we might have binary classified CPE already with the package so we want to append here - dictionaryCPEs, ok := cpe.DictionaryFind(p) + dictionaryCPEs, ok := cpeutils.DictionaryFind(p) if ok { log.Tracef("used CPE dictionary to find CPEs for %s package %q: %s", p.Type, p.Name, dictionaryCPEs) p.CPEs = append(p.CPEs, dictionaryCPEs...) } else { - p.CPEs = append(p.CPEs, cpe.Generate(p)...) + p.CPEs = append(p.CPEs, cpeutils.Generate(p)...) } } @@ -155,6 +157,15 @@ func NewPackageTask(cfg CatalogingFactoryConfig, c pkg.Cataloger, tags ...string return NewTask(c.Name(), fn, tags...) } +func hasAuthoritativeCPE(cpes []cpe.CPE) bool { + for _, c := range cpes { + if c.Source != cpe.GeneratedSource { + return true + } + } + return false +} + func prettyName(s string) string { if s == "" { return "" diff --git a/internal/task/package_task_factory_test.go b/internal/task/package_task_factory_test.go new file mode 100644 index 00000000000..2876afb56c8 --- /dev/null +++ b/internal/task/package_task_factory_test.go @@ -0,0 +1,55 @@ +package task + +import ( + "testing" + + "github.com/stretchr/testify/assert" + + "github.com/anchore/syft/syft/cpe" +) + +func Test_hasAuthoritativeCPE(t *testing.T) { + tests := []struct { + name string + cpes []cpe.CPE + want bool + }{ + { + name: "no cpes", + cpes: []cpe.CPE{}, + want: false, + }, + { + name: "no authoritative cpes", + cpes: []cpe.CPE{ + { + Source: cpe.GeneratedSource, + }, + }, + want: false, + }, + { + name: "has declared (authoritative) cpe", + cpes: []cpe.CPE{ + { + Source: cpe.DeclaredSource, + }, + }, + want: true, + }, + { + name: "has lookup (authoritative) cpe", + cpes: []cpe.CPE{ + { + Source: cpe.NVDDictionaryLookupSource, + }, + }, + want: true, + }, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + assert.Equal(t, tt.want, hasAuthoritativeCPE(tt.cpes)) + }) + } +} diff --git a/syft/pkg/cataloger/binary/classifier.go b/syft/pkg/cataloger/binary/classifier.go index 998242b6646..490df82b330 100644 --- a/syft/pkg/cataloger/binary/classifier.go +++ b/syft/pkg/cataloger/binary/classifier.go @@ -274,9 +274,13 @@ func getContents(context matcherContext) ([]byte, error) { // singleCPE returns a []cpe.CPE with Source: Generated based on the cpe string or panics if the // cpe string cannot be parsed into valid CPE Attributes -func singleCPE(cpeString string) []cpe.CPE { +func singleCPE(cpeString string, source ...cpe.Source) []cpe.CPE { + src := cpe.GeneratedSource + if len(source) > 0 { + src = source[0] + } return []cpe.CPE{ - cpe.Must(cpeString, cpe.GeneratedSource), + cpe.Must(cpeString, src), } } diff --git a/syft/pkg/cataloger/binary/classifiers.go b/syft/pkg/cataloger/binary/classifiers.go index b9df7aa46dd..b8ecc991fa5 100644 --- a/syft/pkg/cataloger/binary/classifiers.go +++ b/syft/pkg/cataloger/binary/classifiers.go @@ -537,7 +537,7 @@ func DefaultClassifiers() []Classifier { ), Package: "curl", PURL: mustPURL("pkg:generic/curl@version"), - CPEs: singleCPE("cpe:2.3:a:haxx:curl:*:*:*:*:*:*:*:*"), + CPEs: singleCPE("cpe:2.3:a:haxx:curl:*:*:*:*:*:*:*:*", cpe.NVDDictionaryLookupSource), }, } } From 5ab43bafecb2fddd698c5c3c9aef315b47515d5f Mon Sep 17 00:00:00 2001 From: Weston Steimel Date: Tue, 27 Aug 2024 17:36:34 +0100 Subject: [PATCH 093/122] fix: improve known CPEs and set NVD as source for all current binary classifiers (#3167) Signed-off-by: Weston Steimel --- syft/pkg/cataloger/binary/classifiers.go | 103 ++++++++++++----------- 1 file changed, 54 insertions(+), 49 deletions(-) diff --git a/syft/pkg/cataloger/binary/classifiers.go b/syft/pkg/cataloger/binary/classifiers.go index b8ecc991fa5..24c514c7e45 100644 --- a/syft/pkg/cataloger/binary/classifiers.go +++ b/syft/pkg/cataloger/binary/classifiers.go @@ -23,8 +23,8 @@ func DefaultClassifiers() []Classifier { Package: "python", PURL: mustPURL("pkg:generic/python@version"), CPEs: []cpe.CPE{ - cpe.Must("cpe:2.3:a:python_software_foundation:python:*:*:*:*:*:*:*:*", cpe.GeneratedSource), - cpe.Must("cpe:2.3:a:python:python:*:*:*:*:*:*:*:*", cpe.GeneratedSource), + cpe.Must("cpe:2.3:a:python_software_foundation:python:*:*:*:*:*:*:*:*", cpe.NVDDictionaryLookupSource), + cpe.Must("cpe:2.3:a:python:python:*:*:*:*:*:*:*:*", cpe.NVDDictionaryLookupSource), }, }, { @@ -34,8 +34,8 @@ func DefaultClassifiers() []Classifier { Package: "python", PURL: mustPURL("pkg:generic/python@version"), CPEs: []cpe.CPE{ - cpe.Must("cpe:2.3:a:python_software_foundation:python:*:*:*:*:*:*:*:*", cpe.GeneratedSource), - cpe.Must("cpe:2.3:a:python:python:*:*:*:*:*:*:*:*", cpe.GeneratedSource), + cpe.Must("cpe:2.3:a:python_software_foundation:python:*:*:*:*:*:*:*:*", cpe.NVDDictionaryLookupSource), + cpe.Must("cpe:2.3:a:python:python:*:*:*:*:*:*:*:*", cpe.NVDDictionaryLookupSource), }, }, { @@ -53,7 +53,7 @@ func DefaultClassifiers() []Classifier { `(?m)go(?P[0-9]+\.[0-9]+(\.[0-9]+|beta[0-9]+|alpha[0-9]+|rc[0-9]+)?)\x00`), Package: "go", PURL: mustPURL("pkg:generic/go@version"), - CPEs: singleCPE("cpe:2.3:a:golang:go:*:*:*:*:*:*:*:*"), + CPEs: singleCPE("cpe:2.3:a:golang:go:*:*:*:*:*:*:*:*", cpe.NVDDictionaryLookupSource), }, { Class: "julia-binary", @@ -62,7 +62,7 @@ func DefaultClassifiers() []Classifier { `(?m)__init__\x00(?P[0-9]+\.[0-9]+\.[0-9]+)\x00verify`), Package: "julia", PURL: mustPURL("pkg:generic/julia@version"), - CPEs: singleCPE("cpe:2.3:a:julialang:julia:*:*:*:*:*:*:*:*"), + CPEs: singleCPE("cpe:2.3:a:julialang:julia:*:*:*:*:*:*:*:*", cpe.NVDDictionaryLookupSource), }, { Class: "helm", @@ -71,7 +71,7 @@ func DefaultClassifiers() []Classifier { `(?m)\x00v(?P[0-9]+\.[0-9]+\.[0-9]+)\x00`), Package: "helm", PURL: mustPURL("pkg:golang/helm.sh/helm@version"), - CPEs: singleCPE("cpe:2.3:a:helm:helm:*:*:*:*:*:*:*"), + CPEs: singleCPE("cpe:2.3:a:helm:helm:*:*:*:*:*:*:*", cpe.NVDDictionaryLookupSource), }, { Class: "redis-binary", @@ -82,7 +82,10 @@ func DefaultClassifiers() []Classifier { ), Package: "redis", PURL: mustPURL("pkg:generic/redis@version"), - CPEs: singleCPE("cpe:2.3:a:redislabs:redis:*:*:*:*:*:*:*:*"), + CPEs: []cpe.CPE{ + cpe.Must("cpe:2.3:a:redislabs:redis:*:*:*:*:*:*:*:*", cpe.NVDDictionaryLookupSource), + cpe.Must("cpe:2.3:a:redis:redis:*:*:*:*:*:*:*:*", cpe.NVDDictionaryLookupSource), + }, }, { Class: "java-binary-openjdk", @@ -103,7 +106,7 @@ func DefaultClassifiers() []Classifier { Package: "java/jre", PURL: mustPURL("pkg:generic/java/jre@version"), // TODO the updates might need to be part of the CPE Attributes, like: 1.8.0:update152 - CPEs: singleCPE("cpe:2.3:a:oracle:openjdk:*:*:*:*:*:*:*:*"), + CPEs: singleCPE("cpe:2.3:a:oracle:openjdk:*:*:*:*:*:*:*:*", cpe.NVDDictionaryLookupSource), }, { Class: "java-binary-ibm", @@ -113,7 +116,7 @@ func DefaultClassifiers() []Classifier { `(?m)\x00java\x00(?P[0-9]+[.0-9]+)\x00{4}(?P[0-9]+[-._a-zA-Z0-9]+)\x00`), Package: "java/jre", PURL: mustPURL("pkg:generic/java/jre@version"), - CPEs: singleCPE("cpe:2.3:a:ibm:java:*:*:*:*:*:*:*:*"), + CPEs: singleCPE("cpe:2.3:a:ibm:java:*:*:*:*:*:*:*:*", cpe.NVDDictionaryLookupSource), }, { Class: "java-binary-oracle", @@ -127,7 +130,7 @@ func DefaultClassifiers() []Classifier { ), Package: "java/jre", PURL: mustPURL("pkg:generic/java/jre@version"), - CPEs: singleCPE("cpe:2.3:a:oracle:jre:*:*:*:*:*:*:*:*"), + CPEs: singleCPE("cpe:2.3:a:oracle:jre:*:*:*:*:*:*:*:*", cpe.NVDDictionaryLookupSource), }, { Class: "java-binary-graalvm", @@ -136,7 +139,7 @@ func DefaultClassifiers() []Classifier { `(?m)\x00(?P[0-9]+[.0-9]+[.0-9]+\+[0-9]+-jvmci-[0-9]+[.0-9]+-b[0-9]+)\x00`), Package: "java/graalvm", PURL: mustPURL("pkg:generic/java/graalvm@version"), - CPEs: singleCPE("cpe:2.3:a:oracle:graalvm:*:*:*:*:*:*:*:*"), + CPEs: singleCPE("cpe:2.3:a:oracle:graalvm:*:*:*:*:*:*:*:*", cpe.NVDDictionaryLookupSource), }, { Class: "java-binary-jdk", @@ -145,7 +148,7 @@ func DefaultClassifiers() []Classifier { `(?m)\x00(?P[0-9]+\.[0-9]+\.[0-9]+(\+[0-9]+)?([-._a-zA-Z0-9]+)?)\x00`), Package: "java/jdk", PURL: mustPURL("pkg:generic/java/jdk@version"), - CPEs: singleCPE("cpe:2.3:a:oracle:jdk:*:*:*:*:*:*:*:*"), + CPEs: singleCPE("cpe:2.3:a:oracle:jdk:*:*:*:*:*:*:*:*", cpe.NVDDictionaryLookupSource), }, { Class: "nodejs-binary", @@ -154,7 +157,7 @@ func DefaultClassifiers() []Classifier { `(?m)node\.js\/v(?P[0-9]+\.[0-9]+\.[0-9]+)`), Package: "node", PURL: mustPURL("pkg:generic/node@version"), - CPEs: singleCPE("cpe:2.3:a:nodejs:node.js:*:*:*:*:*:*:*:*"), + CPEs: singleCPE("cpe:2.3:a:nodejs:node.js:*:*:*:*:*:*:*:*", cpe.NVDDictionaryLookupSource), }, { Class: "go-binary-hint", @@ -163,6 +166,7 @@ func DefaultClassifiers() []Classifier { `(?m)go(?P[0-9]+\.[0-9]+(\.[0-9]+|beta[0-9]+|alpha[0-9]+|rc[0-9]+)?)`), Package: "go", PURL: mustPURL("pkg:generic/go@version"), + CPEs: singleCPE("cpe:2.3:a:golang:go:*:*:*:*:*:*:*:*", cpe.NVDDictionaryLookupSource), }, { Class: "busybox-binary", @@ -171,7 +175,7 @@ func DefaultClassifiers() []Classifier { `(?m)BusyBox\s+v(?P[0-9]+\.[0-9]+\.[0-9]+)`), Package: "busybox", PURL: mustPURL("pkg:generic/busybox@version"), - CPEs: singleCPE("cpe:2.3:a:busybox:busybox:*:*:*:*:*:*:*:*"), + CPEs: singleCPE("cpe:2.3:a:busybox:busybox:*:*:*:*:*:*:*:*", cpe.NVDDictionaryLookupSource), }, { Class: "util-linux-binary", @@ -180,7 +184,7 @@ func DefaultClassifiers() []Classifier { `\x00util-linux\s(?P[0-9]+\.[0-9]+\.[0-9]+)\x00`), Package: "util-linux", PURL: mustPURL("pkg:generic/util-linux@version"), - CPEs: singleCPE("cpe:2.3:a:kernel:util-linux:*:*:*:*:*:*:*:*"), + CPEs: singleCPE("cpe:2.3:a:kernel:util-linux:*:*:*:*:*:*:*:*", cpe.NVDDictionaryLookupSource), }, { Class: "haproxy-binary", @@ -191,7 +195,7 @@ func DefaultClassifiers() []Classifier { ), Package: "haproxy", PURL: mustPURL("pkg:generic/haproxy@version"), - CPEs: singleCPE("cpe:2.3:a:haproxy:haproxy:*:*:*:*:*:*:*:*"), + CPEs: singleCPE("cpe:2.3:a:haproxy:haproxy:*:*:*:*:*:*:*:*", cpe.NVDDictionaryLookupSource), }, { Class: "perl-binary", @@ -200,7 +204,7 @@ func DefaultClassifiers() []Classifier { `(?m)\/usr\/local\/lib\/perl\d\/(?P[0-9]+\.[0-9]+\.[0-9]+)`), Package: "perl", PURL: mustPURL("pkg:generic/perl@version"), - CPEs: singleCPE("cpe:2.3:a:perl:perl:*:*:*:*:*:*:*:*"), + CPEs: singleCPE("cpe:2.3:a:perl:perl:*:*:*:*:*:*:*:*", cpe.NVDDictionaryLookupSource), }, { Class: "php-cli-binary", @@ -210,7 +214,7 @@ func DefaultClassifiers() []Classifier { `(?m)X-Powered-By: PHP\/(?P[0-9]+\.[0-9]+\.[0-9]+(beta[0-9]+|alpha[0-9]+|RC[0-9]+)?)`), Package: "php-cli", PURL: mustPURL("pkg:generic/php-cli@version"), - CPEs: singleCPE("cpe:2.3:a:php:php:*:*:*:*:*:*:*:*"), + CPEs: singleCPE("cpe:2.3:a:php:php:*:*:*:*:*:*:*:*", cpe.NVDDictionaryLookupSource), }, { Class: "php-fpm-binary", @@ -219,7 +223,7 @@ func DefaultClassifiers() []Classifier { `(?m)X-Powered-By: PHP\/(?P[0-9]+\.[0-9]+\.[0-9]+(beta[0-9]+|alpha[0-9]+|RC[0-9]+)?)`), Package: "php-fpm", PURL: mustPURL("pkg:generic/php-fpm@version"), - CPEs: singleCPE("cpe:2.3:a:php:php:*:*:*:*:*:*:*:*"), + CPEs: singleCPE("cpe:2.3:a:php:php:*:*:*:*:*:*:*:*", cpe.NVDDictionaryLookupSource), }, { Class: "php-apache-binary", @@ -228,7 +232,7 @@ func DefaultClassifiers() []Classifier { `(?m)X-Powered-By: PHP\/(?P[0-9]+\.[0-9]+\.[0-9]+(beta[0-9]+|alpha[0-9]+|RC[0-9]+)?)`), Package: "libphp", PURL: mustPURL("pkg:generic/php@version"), - CPEs: singleCPE("cpe:2.3:a:php:php:*:*:*:*:*:*:*:*"), + CPEs: singleCPE("cpe:2.3:a:php:php:*:*:*:*:*:*:*:*", cpe.NVDDictionaryLookupSource), }, { Class: "php-composer-binary", @@ -237,7 +241,7 @@ func DefaultClassifiers() []Classifier { `(?m)'pretty_version'\s*=>\s*'(?P[0-9]+\.[0-9]+\.[0-9]+(beta[0-9]+|alpha[0-9]+|RC[0-9]+)?)'`), Package: "composer", PURL: mustPURL("pkg:generic/composer@version"), - CPEs: singleCPE("cpe:2.3:a:getcomposer:composer:*:*:*:*:*:*:*:*"), + CPEs: singleCPE("cpe:2.3:a:getcomposer:composer:*:*:*:*:*:*:*:*", cpe.NVDDictionaryLookupSource), }, { Class: "httpd-binary", @@ -246,7 +250,7 @@ func DefaultClassifiers() []Classifier { `(?m)Apache\/(?P[0-9]+\.[0-9]+\.[0-9]+)`), Package: "httpd", PURL: mustPURL("pkg:generic/httpd@version"), - CPEs: singleCPE("cpe:2.3:a:apache:http_server:*:*:*:*:*:*:*:*"), + CPEs: singleCPE("cpe:2.3:a:apache:http_server:*:*:*:*:*:*:*:*", cpe.NVDDictionaryLookupSource), }, { Class: "memcached-binary", @@ -255,7 +259,7 @@ func DefaultClassifiers() []Classifier { `(?m)memcached\s(?P[0-9]+\.[0-9]+\.[0-9]+)`), Package: "memcached", PURL: mustPURL("pkg:generic/memcached@version"), - CPEs: singleCPE("cpe:2.3:a:memcached:memcached:*:*:*:*:*:*:*:*"), + CPEs: singleCPE("cpe:2.3:a:memcached:memcached:*:*:*:*:*:*:*:*", cpe.NVDDictionaryLookupSource), }, { Class: "traefik-binary", @@ -267,7 +271,7 @@ func DefaultClassifiers() []Classifier { `(?m)(\x00|\x{FFFD})?v?(?P[0-9]+\.[0-9]+\.[0-9]+(-alpha[0-9]|-beta[0-9]|-rc[0-9])?)\x00`), Package: "traefik", PURL: mustPURL("pkg:generic/traefik@version"), - CPEs: singleCPE("cpe:2.3:a:traefik:traefik:*:*:*:*:*:*:*:*"), + CPEs: singleCPE("cpe:2.3:a:traefik:traefik:*:*:*:*:*:*:*:*", cpe.NVDDictionaryLookupSource), }, { Class: "arangodb-binary", @@ -276,7 +280,7 @@ func DefaultClassifiers() []Classifier { `(?m)\x00*(?P[0-9]+\.[0-9]+\.[0-9]+(-[0-9]+)?)\s\[linux\]`), Package: "arangodb", PURL: mustPURL("pkg:generic/arangodb@version"), - CPEs: singleCPE("cpe:2.3:a:arangodb:arangodb:*:*:*:*:*:*:*:*"), + CPEs: singleCPE("cpe:2.3:a:arangodb:arangodb:*:*:*:*:*:*:*:*", cpe.NVDDictionaryLookupSource), }, { Class: "postgresql-binary", @@ -289,7 +293,7 @@ func DefaultClassifiers() []Classifier { `(?m)(\x00|\?)PostgreSQL (?P[0-9]+(\.[0-9]+)?(\.[0-9]+)?(alpha[0-9]|beta[0-9]|rc[0-9])?)`), Package: "postgresql", PURL: mustPURL("pkg:generic/postgresql@version"), - CPEs: singleCPE("cpe:2.3:a:postgresql:postgresql:*:*:*:*:*:*:*:*"), + CPEs: singleCPE("cpe:2.3:a:postgresql:postgresql:*:*:*:*:*:*:*:*", cpe.NVDDictionaryLookupSource), }, { Class: "mysql-binary", @@ -302,7 +306,7 @@ func DefaultClassifiers() []Classifier { ), Package: "mysql", PURL: mustPURL("pkg:generic/mysql@version"), - CPEs: singleCPE("cpe:2.3:a:oracle:mysql:*:*:*:*:*:*:*:*"), + CPEs: singleCPE("cpe:2.3:a:oracle:mysql:*:*:*:*:*:*:*:*", cpe.NVDDictionaryLookupSource), }, { Class: "mysql-binary", @@ -312,8 +316,8 @@ func DefaultClassifiers() []Classifier { Package: "percona-server", PURL: mustPURL("pkg:generic/percona-server@version"), CPEs: []cpe.CPE{ - cpe.Must("cpe:2.3:a:oracle:mysql:*:*:*:*:*:*:*:*", cpe.GeneratedSource), - cpe.Must("cpe:2.3:a:percona:percona_server:*:*:*:*:*:*:*:*", cpe.GeneratedSource), + cpe.Must("cpe:2.3:a:oracle:mysql:*:*:*:*:*:*:*:*", cpe.NVDDictionaryLookupSource), + cpe.Must("cpe:2.3:a:percona:percona_server:*:*:*:*:*:*:*:*", cpe.NVDDictionaryLookupSource), }, }, { @@ -324,9 +328,9 @@ func DefaultClassifiers() []Classifier { Package: "percona-xtradb-cluster", PURL: mustPURL("pkg:generic/percona-xtradb-cluster@version"), CPEs: []cpe.CPE{ - cpe.Must("cpe:2.3:a:oracle:mysql:*:*:*:*:*:*:*:*", cpe.GeneratedSource), - cpe.Must("cpe:2.3:a:percona:percona_server:*:*:*:*:*:*:*:*", cpe.GeneratedSource), - cpe.Must("cpe:2.3:a:percona:xtradb_cluster:*:*:*:*:*:*:*:*", cpe.GeneratedSource), + cpe.Must("cpe:2.3:a:oracle:mysql:*:*:*:*:*:*:*:*", cpe.NVDDictionaryLookupSource), + cpe.Must("cpe:2.3:a:percona:percona_server:*:*:*:*:*:*:*:*", cpe.NVDDictionaryLookupSource), + cpe.Must("cpe:2.3:a:percona:xtradb_cluster:*:*:*:*:*:*:*:*", cpe.NVDDictionaryLookupSource), }, }, { @@ -336,7 +340,7 @@ func DefaultClassifiers() []Classifier { `(?m).*/percona-xtrabackup-(?P[0-9]+(\.[0-9]+)?(\.[0-9]+)?(alpha[0-9]|beta[0-9]|rc[0-9])?)`), Package: "percona-xtrabackup", PURL: mustPURL("pkg:generic/percona-xtrabackup@version"), - CPEs: singleCPE("cpe:2.3:a:percona:xtrabackup:*:*:*:*:*:*:*:*"), + CPEs: singleCPE("cpe:2.3:a:percona:xtrabackup:*:*:*:*:*:*:*:*", cpe.NVDDictionaryLookupSource), }, { Class: "mariadb-binary", @@ -346,6 +350,7 @@ func DefaultClassifiers() []Classifier { `(?m)(?P[0-9]+(\.[0-9]+)?(\.[0-9]+)?(alpha[0-9]|beta[0-9]|rc[0-9])?)-MariaDB`), Package: "mariadb", PURL: mustPURL("pkg:generic/mariadb@version"), + CPEs: singleCPE("cpe:2.3:a:mariadb:mariadb:*:*:*:*:*:*:*:*", cpe.NVDDictionaryLookupSource), }, { Class: "rust-standard-library-linux", @@ -355,7 +360,7 @@ func DefaultClassifiers() []Classifier { `(?m)(\x00)clang LLVM \(rustc version (?P[0-9]+(\.[0-9]+)?(\.[0-9]+)) \(\w+ \d{4}\-\d{2}\-\d{2}\)`), Package: "rust", PURL: mustPURL("pkg:generic/rust@version"), - CPEs: singleCPE("cpe:2.3:a:rust-lang:rust:*:*:*:*:*:*:*:*"), + CPEs: singleCPE("cpe:2.3:a:rust-lang:rust:*:*:*:*:*:*:*:*", cpe.NVDDictionaryLookupSource), }, { Class: "rust-standard-library-macos", @@ -365,7 +370,7 @@ func DefaultClassifiers() []Classifier { `(?m)c (?P[0-9]+(\.[0-9]+)?(\.[0-9]+)) \(\w+ \d{4}\-\d{2}\-\d{2}\)`), Package: "rust", PURL: mustPURL("pkg:generic/rust@version"), - CPEs: singleCPE("cpe:2.3:a:rust-lang:rust:*:*:*:*:*:*:*:*"), + CPEs: singleCPE("cpe:2.3:a:rust-lang:rust:*:*:*:*:*:*:*:*", cpe.NVDDictionaryLookupSource), }, { Class: "ruby-binary", @@ -379,7 +384,7 @@ func DefaultClassifiers() []Classifier { ), Package: "ruby", PURL: mustPURL("pkg:generic/ruby@version"), - CPEs: singleCPE("cpe:2.3:a:ruby-lang:ruby:*:*:*:*:*:*:*:*"), + CPEs: singleCPE("cpe:2.3:a:ruby-lang:ruby:*:*:*:*:*:*:*:*", cpe.NVDDictionaryLookupSource), }, { Class: "erlang-binary", @@ -396,7 +401,7 @@ func DefaultClassifiers() []Classifier { ), Package: "erlang", PURL: mustPURL("pkg:generic/erlang@version"), - CPEs: singleCPE("cpe:2.3:a:erlang:erlang\\/otp:*:*:*:*:*:*:*:*"), + CPEs: singleCPE("cpe:2.3:a:erlang:erlang\\/otp:*:*:*:*:*:*:*:*", cpe.NVDDictionaryLookupSource), }, { Class: "erlang-alpine-binary", @@ -413,7 +418,7 @@ func DefaultClassifiers() []Classifier { ), Package: "erlang", PURL: mustPURL("pkg:generic/erlang@version"), - CPEs: singleCPE("cpe:2.3:a:erlang:erlang\\/otp:*:*:*:*:*:*:*:*"), + CPEs: singleCPE("cpe:2.3:a:erlang:erlang\\/otp:*:*:*:*:*:*:*:*", cpe.NVDDictionaryLookupSource), }, { Class: "erlang-library", @@ -430,7 +435,7 @@ func DefaultClassifiers() []Classifier { ), Package: "erlang", PURL: mustPURL("pkg:generic/erlang@version"), - CPEs: singleCPE("cpe:2.3:a:erlang:erlang\\/otp:*:*:*:*:*:*:*:*"), + CPEs: singleCPE("cpe:2.3:a:erlang:erlang\\/otp:*:*:*:*:*:*:*:*", cpe.NVDDictionaryLookupSource), }, { Class: "swipl-binary", @@ -440,7 +445,7 @@ func DefaultClassifiers() []Classifier { ), Package: "swipl", PURL: mustPURL("pkg:generic/swipl@version"), - CPEs: singleCPE("cpe:2.3:a:erlang:erlang\\/otp:*:*:*:*:*:*:*:*"), + CPEs: singleCPE("cpe:2.3:a:erlang:erlang\\/otp:*:*:*:*:*:*:*:*", cpe.NVDDictionaryLookupSource), }, { Class: "consul-binary", @@ -451,7 +456,7 @@ func DefaultClassifiers() []Classifier { ), Package: "consul", PURL: mustPURL("pkg:golang/github.com/hashicorp/consul@version"), - CPEs: singleCPE("cpe:2.3:a:hashicorp:consul:*:*:*:*:*:*:*:*"), + CPEs: singleCPE("cpe:2.3:a:hashicorp:consul:*:*:*:*:*:*:*:*", cpe.NVDDictionaryLookupSource), }, { Class: "nginx-binary", @@ -464,8 +469,8 @@ func DefaultClassifiers() []Classifier { Package: "nginx", PURL: mustPURL("pkg:generic/nginx@version"), CPEs: []cpe.CPE{ - cpe.Must("cpe:2.3:a:f5:nginx:*:*:*:*:*:*:*:*", cpe.GeneratedSource), - cpe.Must("cpe:2.3:a:nginx:nginx:*:*:*:*:*:*:*:*", cpe.GeneratedSource), + cpe.Must("cpe:2.3:a:f5:nginx:*:*:*:*:*:*:*:*", cpe.NVDDictionaryLookupSource), + cpe.Must("cpe:2.3:a:nginx:nginx:*:*:*:*:*:*:*:*", cpe.NVDDictionaryLookupSource), }, }, { @@ -480,7 +485,7 @@ func DefaultClassifiers() []Classifier { ), Package: "bash", PURL: mustPURL("pkg:generic/bash@version"), - CPEs: singleCPE("cpe:2.3:a:gnu:bash:*:*:*:*:*:*:*:*"), + CPEs: singleCPE("cpe:2.3:a:gnu:bash:*:*:*:*:*:*:*:*", cpe.NVDDictionaryLookupSource), }, { Class: "openssl-binary", @@ -492,7 +497,7 @@ func DefaultClassifiers() []Classifier { ), Package: "openssl", PURL: mustPURL("pkg:generic/openssl@version"), - CPEs: singleCPE("cpe:2.3:a:openssl:openssl:*:*:*:*:*:*:*:*"), + CPEs: singleCPE("cpe:2.3:a:openssl:openssl:*:*:*:*:*:*:*:*", cpe.NVDDictionaryLookupSource), }, { Class: "gcc-binary", @@ -503,7 +508,7 @@ func DefaultClassifiers() []Classifier { ), Package: "gcc", PURL: mustPURL("pkg:generic/gcc@version"), - CPEs: singleCPE("cpe:2.3:a:gnu:gcc:*:*:*:*:*:*:*:*"), + CPEs: singleCPE("cpe:2.3:a:gnu:gcc:*:*:*:*:*:*:*:*", cpe.NVDDictionaryLookupSource), }, { Class: "fluent-bit-binary", @@ -516,7 +521,7 @@ func DefaultClassifiers() []Classifier { ), Package: "fluent-bit", PURL: mustPURL("pkg:github/fluent/fluent-bit@version"), - CPEs: singleCPE("cpe:2.3:a:treasuredata:fluent_bit:*:*:*:*:*:*:*:*"), + CPEs: singleCPE("cpe:2.3:a:treasuredata:fluent_bit:*:*:*:*:*:*:*:*", cpe.NVDDictionaryLookupSource), }, { Class: "wordpress-cli-binary", @@ -527,7 +532,7 @@ func DefaultClassifiers() []Classifier { ), Package: "wp-cli", PURL: mustPURL("pkg:generic/wp-cli@version"), - CPEs: singleCPE("cpe:2.3:a:wp-cli:wp-cli:*:*:*:*:*:*:*:*"), + CPEs: singleCPE("cpe:2.3:a:wp-cli:wp-cli:*:*:*:*:*:*:*:*", cpe.NVDDictionaryLookupSource), }, { Class: "curl-binary", From 04e3371cce248fb221bd79641754898c6db01030 Mon Sep 17 00:00:00 2001 From: GGMU <49076226+tomersein@users.noreply.github.com> Date: Wed, 28 Aug 2024 18:04:26 +0300 Subject: [PATCH 094/122] fix: add log time of task (#3105) Signed-off-by: tomersein --- internal/task/executor.go | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/internal/task/executor.go b/internal/task/executor.go index 5ba48b58aa0..2935f61b12c 100644 --- a/internal/task/executor.go +++ b/internal/task/executor.go @@ -5,7 +5,9 @@ import ( "fmt" "runtime/debug" "sync" + "time" + "github.com/anchore/syft/internal/log" "github.com/hashicorp/go-multierror" "github.com/anchore/syft/internal/sbomsync" @@ -68,5 +70,8 @@ func runTaskSafely(ctx context.Context, t Task, resolver file.Resolver, s sbomsy } }() - return t.Execute(ctx, resolver, s) + start := time.Now() + res := t.Execute(ctx, resolver, s) + log.WithFields("task", t.Name(), "elapsed", time.Since(start)).Info("task completed") + return res } From 2c25f81b6822eb5035d5bc8d081ec02d618c5694 Mon Sep 17 00:00:00 2001 From: Weston Steimel Date: Wed, 28 Aug 2024 16:46:35 +0100 Subject: [PATCH 095/122] fix: improve generated cpes for binaries with existing classifiers (#3169) The existing syft binary classifiers already specify any known CPEs for the defined binary; however, sometimes these end up getting suppressed (such as when there are ELF notes extracted) and the CPE generator ends up being used instead. This adds enough detail to at least ensure the correct ones get appended to the generation list for the currently covered classifiers. Signed-off-by: Weston Steimel --- .../cpegenerate/candidate_by_package_type.go | 131 ++++++++++++++++++ 1 file changed, 131 insertions(+) diff --git a/syft/pkg/cataloger/internal/cpegenerate/candidate_by_package_type.go b/syft/pkg/cataloger/internal/cpegenerate/candidate_by_package_type.go index 5fca14c5199..39b62342a95 100644 --- a/syft/pkg/cataloger/internal/cpegenerate/candidate_by_package_type.go +++ b/syft/pkg/cataloger/internal/cpegenerate/candidate_by_package_type.go @@ -21,6 +21,137 @@ type candidateRemovalComposite struct { // select package information is discovered var defaultCandidateAdditions = buildCandidateLookup( []candidateComposite{ + // Binary packages + { + pkg.BinaryPkg, + candidateKey{PkgName: "curl"}, + candidateAddition{AdditionalVendors: []string{"haxx"}}, + }, + { + pkg.BinaryPkg, + candidateKey{PkgName: "go"}, + candidateAddition{AdditionalVendors: []string{"golang"}}, + }, + // Not including the various java ones for now since the raised + // binary package classifier name is the same but there are different CPEs + // for different distributions of OpenJDK. Also, it is unlikely this name will collide + // with whatever might be raised by an ELF notes section, so these are unlikely to + // be of much use here anyways + { + pkg.BinaryPkg, + candidateKey{PkgName: "julia"}, + candidateAddition{AdditionalVendors: []string{"julialang"}}, + }, + { + pkg.BinaryPkg, + candidateKey{PkgName: "python"}, + candidateAddition{AdditionalVendors: []string{"python_software_foundation"}}, + }, + { + pkg.BinaryPkg, + candidateKey{PkgName: "redis"}, + candidateAddition{AdditionalVendors: []string{"redislabs"}}, + }, + { + pkg.BinaryPkg, + candidateKey{PkgName: "node"}, + candidateAddition{AdditionalProducts: []string{"node.js"}, AdditionalVendors: []string{"nodejs"}}, + }, + { + pkg.BinaryPkg, + candidateKey{PkgName: "util-linux"}, + candidateAddition{AdditionalVendors: []string{"kernel"}}, + }, + { + pkg.BinaryPkg, + candidateKey{PkgName: "composer"}, + candidateAddition{AdditionalVendors: []string{"getcomposer"}}, + }, + { + pkg.BinaryPkg, + candidateKey{PkgName: "httpd"}, + candidateAddition{AdditionalProducts: []string{"http_server"}, AdditionalVendors: []string{"apache"}}, + }, + { + pkg.BinaryPkg, + candidateKey{PkgName: "mysql"}, + candidateAddition{AdditionalVendors: []string{"oracle"}}, + }, + { + pkg.BinaryPkg, + candidateKey{PkgName: "php-cli"}, + candidateAddition{AdditionalProducts: []string{"php"}, AdditionalVendors: []string{"php"}}, + }, + { + pkg.BinaryPkg, + candidateKey{PkgName: "php-fpm"}, + candidateAddition{AdditionalProducts: []string{"php"}, AdditionalVendors: []string{"php"}}, + }, + { + pkg.BinaryPkg, + candidateKey{PkgName: "libphp"}, + candidateAddition{AdditionalProducts: []string{"php"}, AdditionalVendors: []string{"php"}}, + }, + { + pkg.BinaryPkg, + candidateKey{PkgName: "percona-server"}, + candidateAddition{AdditionalProducts: []string{"percona_server", "mysql"}, AdditionalVendors: []string{"oracle", "percona"}}, + }, + { + pkg.BinaryPkg, + candidateKey{PkgName: "percona-xtradb-cluster"}, + candidateAddition{AdditionalProducts: []string{"percona_server", "mysql", "xtradb_cluster"}, AdditionalVendors: []string{"oracle", "percona"}}, + }, + { + pkg.BinaryPkg, + candidateKey{PkgName: "percona-xtrabackup"}, + candidateAddition{AdditionalProducts: []string{"xtrabackup"}, AdditionalVendors: []string{"percona"}}, + }, + { + pkg.BinaryPkg, + candidateKey{PkgName: "rust"}, + candidateAddition{AdditionalVendors: []string{"rust-lang"}}, + }, + { + pkg.BinaryPkg, + candidateKey{PkgName: "ruby"}, + candidateAddition{AdditionalVendors: []string{"ruby-lang"}}, + }, + { + pkg.BinaryPkg, + candidateKey{PkgName: "erlang"}, + candidateAddition{AdditionalProducts: []string{"erlang/otp"}}, + }, + { + pkg.BinaryPkg, + candidateKey{PkgName: "swipl"}, + candidateAddition{AdditionalProducts: []string{"erlang/otp"}, AdditionalVendors: []string{"erlang"}}, + }, + { + pkg.BinaryPkg, + candidateKey{PkgName: "consule"}, + candidateAddition{AdditionalVendors: []string{"hashicorp"}}, + }, + { + pkg.BinaryPkg, + candidateKey{PkgName: "nginx"}, + candidateAddition{AdditionalVendors: []string{"f5"}}, + }, + { + pkg.BinaryPkg, + candidateKey{PkgName: "bash"}, + candidateAddition{AdditionalVendors: []string{"gnu"}}, + }, + { + pkg.BinaryPkg, + candidateKey{PkgName: "gcc"}, + candidateAddition{AdditionalVendors: []string{"gnu"}}, + }, + { + pkg.BinaryPkg, + candidateKey{PkgName: "fluent-bit"}, + candidateAddition{AdditionalProducts: []string{"fluent_bit"}, AdditionalVendors: []string{"treasuredata"}}, + }, // Java packages { pkg.JavaPkg, From 11d77b4a9489604c5148bba7a6ca84bd31786691 Mon Sep 17 00:00:00 2001 From: Keith Zantow Date: Wed, 28 Aug 2024 15:12:13 -0400 Subject: [PATCH 096/122] fix: cycles resolving relative path parent poms with parent-defined variables (#3170) Signed-off-by: Keith Zantow --- syft/pkg/cataloger/java/archive_parser.go | 4 +- syft/pkg/cataloger/java/maven_resolver.go | 99 ++++++++++++------- .../pkg/cataloger/java/maven_resolver_test.go | 80 +++++++++++---- syft/pkg/cataloger/java/parse_pom_xml.go | 6 +- .../test-fixtures/pom/local/child-2/pom.xml | 15 +++ .../test-fixtures/pom/local/child-3/pom.xml | 15 +++ .../test-fixtures/pom/local/parent-3/pom.xml | 14 +++ 7 files changed, 170 insertions(+), 63 deletions(-) create mode 100644 syft/pkg/cataloger/java/test-fixtures/pom/local/child-2/pom.xml create mode 100644 syft/pkg/cataloger/java/test-fixtures/pom/local/child-3/pom.xml create mode 100644 syft/pkg/cataloger/java/test-fixtures/pom/local/parent-3/pom.xml diff --git a/syft/pkg/cataloger/java/archive_parser.go b/syft/pkg/cataloger/java/archive_parser.go index d2e16898c34..740ad0071a4 100644 --- a/syft/pkg/cataloger/java/archive_parser.go +++ b/syft/pkg/cataloger/java/archive_parser.go @@ -283,7 +283,7 @@ func (j *archiveParser) findLicenseFromJavaMetadata(ctx context.Context, groupID if parsedPom != nil { pomLicenses, err = j.maven.resolveLicenses(ctx, parsedPom.project) if err != nil { - log.WithFields("error", err, "mavenID", j.maven.resolveMavenID(ctx, parsedPom.project)).Debug("error attempting to resolve pom licenses") + log.WithFields("error", err, "mavenID", j.maven.getMavenID(ctx, parsedPom.project)).Debug("error attempting to resolve pom licenses") } } @@ -352,7 +352,7 @@ func (j *archiveParser) discoverMainPackageFromPomInfo(ctx context.Context) (gro version = pomProperties.Version if parsedPom != nil && parsedPom.project != nil { - id := j.maven.resolveMavenID(ctx, parsedPom.project) + id := j.maven.getMavenID(ctx, parsedPom.project) if group == "" { group = id.GroupID } diff --git a/syft/pkg/cataloger/java/maven_resolver.go b/syft/pkg/cataloger/java/maven_resolver.go index e7e73b0be80..f9d375b8ea3 100644 --- a/syft/pkg/cataloger/java/maven_resolver.go +++ b/syft/pkg/cataloger/java/maven_resolver.go @@ -67,10 +67,17 @@ func newMavenResolver(fileResolver file.Resolver, cfg ArchiveCatalogerConfig) *m // as well as supporting the project expressions like ${project.parent.groupId}. // Properties which are not resolved result in empty string "" func (r *mavenResolver) getPropertyValue(ctx context.Context, propertyValue *string, resolutionContext ...*gopom.Project) string { + return r.resolvePropertyValue(ctx, propertyValue, nil, resolutionContext...) +} + +// resolvePropertyValue resolves property values by emulating maven property resolution logic, looking in the project's variables +// as well as supporting the project expressions like ${project.parent.groupId}. +// Properties which are not resolved result in empty string "" +func (r *mavenResolver) resolvePropertyValue(ctx context.Context, propertyValue *string, resolvingProperties []string, resolutionContext ...*gopom.Project) string { if propertyValue == nil { return "" } - resolved, err := r.resolveExpression(ctx, resolutionContext, *propertyValue, nil) + resolved, err := r.resolveExpression(ctx, resolutionContext, *propertyValue, resolvingProperties) if err != nil { log.WithFields("error", err, "propertyValue", *propertyValue).Debug("error resolving maven property") return "" @@ -79,32 +86,35 @@ func (r *mavenResolver) getPropertyValue(ctx context.Context, propertyValue *str } // resolveExpression resolves an expression, which may be a plain string or a string with ${ property.references } -func (r *mavenResolver) resolveExpression(ctx context.Context, resolutionContext []*gopom.Project, expression string, resolving []string) (string, error) { - var err error +func (r *mavenResolver) resolveExpression(ctx context.Context, resolutionContext []*gopom.Project, expression string, resolvingProperties []string) (string, error) { + log.Tracef("resolving expression: '%v' in context: %v", expression, resolutionContext) + + var errs error return expressionMatcher.ReplaceAllStringFunc(expression, func(match string) string { + log.Tracef("resolving property: '%v' in context: %v", expression, resolutionContext) propertyExpression := strings.TrimSpace(match[2 : len(match)-1]) // remove leading ${ and trailing } - resolved, e := r.resolveProperty(ctx, resolutionContext, propertyExpression, resolving) - if e != nil { - err = errors.Join(err, e) + resolved, err := r.resolveProperty(ctx, resolutionContext, propertyExpression, resolvingProperties) + if err != nil { + errs = errors.Join(errs, err) return "" } return resolved - }), err + }), errs } // resolveProperty resolves properties recursively from the root project -func (r *mavenResolver) resolveProperty(ctx context.Context, resolutionContext []*gopom.Project, propertyExpression string, resolving []string) (string, error) { +func (r *mavenResolver) resolveProperty(ctx context.Context, resolutionContext []*gopom.Project, propertyExpression string, resolvingProperties []string) (string, error) { // prevent cycles - if slices.Contains(resolving, propertyExpression) { + if slices.Contains(resolvingProperties, propertyExpression) { return "", fmt.Errorf("cycle detected resolving: %s", propertyExpression) } if len(resolutionContext) == 0 { return "", fmt.Errorf("no project variable resolution context provided for expression: '%s'", propertyExpression) } - resolving = append(resolving, propertyExpression) + resolvingProperties = append(resolvingProperties, propertyExpression) // only resolve project. properties in the context of the current project pom - value, err := r.resolveProjectProperty(ctx, resolutionContext, resolutionContext[len(resolutionContext)-1], propertyExpression, resolving) + value, err := r.resolveProjectProperty(ctx, resolutionContext, resolutionContext[len(resolutionContext)-1], propertyExpression, resolvingProperties) if err != nil { return value, err } @@ -120,10 +130,10 @@ func (r *mavenResolver) resolveProperty(ctx context.Context, resolutionContext [ } if current.Properties != nil && current.Properties.Entries != nil { if value, ok := current.Properties.Entries[propertyExpression]; ok { - return r.resolveExpression(ctx, resolutionContext, value, resolving) // property values can contain expressions + return r.resolveExpression(ctx, resolutionContext, value, resolvingProperties) // property values can contain expressions } } - current, err = r.resolveParent(ctx, current) + current, err = r.resolveParent(ctx, current, resolvingProperties...) if err != nil { return "", err } @@ -200,23 +210,33 @@ func (r *mavenResolver) resolveProjectProperty(ctx context.Context, resolutionCo return "", nil } +// getMavenID creates a new mavenID from a pom, resolving parent information as necessary +func (r *mavenResolver) getMavenID(ctx context.Context, resolutionContext ...*gopom.Project) mavenID { + return r.resolveMavenID(ctx, nil, resolutionContext...) +} + // resolveMavenID creates a new mavenID from a pom, resolving parent information as necessary -func (r *mavenResolver) resolveMavenID(ctx context.Context, pom *gopom.Project) mavenID { +func (r *mavenResolver) resolveMavenID(ctx context.Context, resolvingProperties []string, resolutionContext ...*gopom.Project) mavenID { + if len(resolutionContext) == 0 || resolutionContext[0] == nil { + return mavenID{} + } + pom := resolutionContext[len(resolutionContext)-1] // get topmost pom if pom == nil { return mavenID{} } - groupID := r.getPropertyValue(ctx, pom.GroupID, pom) - artifactID := r.getPropertyValue(ctx, pom.ArtifactID, pom) - version := r.getPropertyValue(ctx, pom.Version, pom) + + groupID := r.resolvePropertyValue(ctx, pom.GroupID, resolvingProperties, resolutionContext...) + artifactID := r.resolvePropertyValue(ctx, pom.ArtifactID, resolvingProperties, resolutionContext...) + version := r.resolvePropertyValue(ctx, pom.Version, resolvingProperties, resolutionContext...) if pom.Parent != nil { if groupID == "" { - groupID = r.getPropertyValue(ctx, pom.Parent.GroupID, pom) + groupID = r.resolvePropertyValue(ctx, pom.Parent.GroupID, resolvingProperties, resolutionContext...) } if artifactID == "" { - artifactID = r.getPropertyValue(ctx, pom.Parent.ArtifactID, pom) + artifactID = r.resolvePropertyValue(ctx, pom.Parent.ArtifactID, resolvingProperties, resolutionContext...) } if version == "" { - version = r.getPropertyValue(ctx, pom.Parent.Version, pom) + version = r.resolvePropertyValue(ctx, pom.Parent.Version, resolvingProperties, resolutionContext...) } } return mavenID{groupID, artifactID, version} @@ -240,7 +260,7 @@ func (r *mavenResolver) resolveDependencyID(ctx context.Context, pom *gopom.Proj depID := mavenID{groupID, artifactID, version} if err != nil { - log.WithFields("error", err, "mavenID", r.resolveMavenID(ctx, pom), "dependencyID", depID) + log.WithFields("error", err, "mavenID", r.getMavenID(ctx, pom), "dependencyID", depID) } return depID @@ -390,16 +410,16 @@ func (r *mavenResolver) cacheResolveReader(key string, resolve func() (io.ReadCl } // resolveParent attempts to resolve the parent for the given pom -func (r *mavenResolver) resolveParent(ctx context.Context, pom *gopom.Project) (*gopom.Project, error) { +func (r *mavenResolver) resolveParent(ctx context.Context, pom *gopom.Project, resolvingProperties ...string) (*gopom.Project, error) { if pom == nil || pom.Parent == nil { return nil, nil } parent := pom.Parent pomWithoutParent := *pom pomWithoutParent.Parent = nil - groupID := r.getPropertyValue(ctx, parent.GroupID, &pomWithoutParent) - artifactID := r.getPropertyValue(ctx, parent.ArtifactID, &pomWithoutParent) - version := r.getPropertyValue(ctx, parent.Version, &pomWithoutParent) + groupID := r.resolvePropertyValue(ctx, parent.GroupID, resolvingProperties, &pomWithoutParent) + artifactID := r.resolvePropertyValue(ctx, parent.ArtifactID, resolvingProperties, &pomWithoutParent) + version := r.resolvePropertyValue(ctx, parent.Version, resolvingProperties, &pomWithoutParent) // check cache before resolving parentID := mavenID{groupID, artifactID, version} @@ -408,7 +428,7 @@ func (r *mavenResolver) resolveParent(ctx context.Context, pom *gopom.Project) ( } // check if the pom exists in the fileResolver - parentPom := r.findParentPomByRelativePath(ctx, pom, parentID) + parentPom := r.findParentPomByRelativePath(ctx, pom, parentID, resolvingProperties) if parentPom != nil { return parentPom, nil } @@ -425,10 +445,10 @@ func (r *mavenResolver) findInheritedVersion(ctx context.Context, pom *gopom.Pro return "", fmt.Errorf("nil pom provided to findInheritedVersion") } if r.cfg.MaxParentRecursiveDepth > 0 && len(resolutionContext) > r.cfg.MaxParentRecursiveDepth { - return "", fmt.Errorf("maximum depth reached attempting to resolve version for: %s:%s at: %v", groupID, artifactID, r.resolveMavenID(ctx, pom)) + return "", fmt.Errorf("maximum depth reached attempting to resolve version for: %s:%s at: %v", groupID, artifactID, r.getMavenID(ctx, pom)) } if slices.Contains(resolutionContext, pom) { - return "", fmt.Errorf("cycle detected attempting to resolve version for: %s:%s at: %v", groupID, artifactID, r.resolveMavenID(ctx, pom)) + return "", fmt.Errorf("cycle detected attempting to resolve version for: %s:%s at: %v", groupID, artifactID, r.getMavenID(ctx, pom)) } resolutionContext = append(resolutionContext, pom) @@ -452,13 +472,13 @@ func (r *mavenResolver) findInheritedVersion(ctx context.Context, pom *gopom.Pro depPom, err := r.findPom(ctx, depGroupID, depArtifactID, depVersion) if err != nil || depPom == nil { - log.WithFields("error", err, "mavenID", r.resolveMavenID(ctx, pom), "dependencyID", mavenID{depGroupID, depArtifactID, depVersion}). + log.WithFields("error", err, "mavenID", r.getMavenID(ctx, pom), "dependencyID", mavenID{depGroupID, depArtifactID, depVersion}). Debug("unable to find imported pom looking for managed dependencies") continue } version, err = r.findInheritedVersion(ctx, depPom, groupID, artifactID, resolutionContext...) if err != nil { - log.WithFields("error", err, "mavenID", r.resolveMavenID(ctx, pom), "dependencyID", mavenID{depGroupID, depArtifactID, depVersion}). + log.WithFields("error", err, "mavenID", r.getMavenID(ctx, pom), "dependencyID", mavenID{depGroupID, depArtifactID, depVersion}). Debug("error during findInheritedVersion") } if version != "" { @@ -508,7 +528,7 @@ func (r *mavenResolver) findLicenses(ctx context.Context, groupID, artifactID, v // resolveLicenses searches the pom for license, traversing parent poms if needed func (r *mavenResolver) resolveLicenses(ctx context.Context, pom *gopom.Project, processing ...mavenID) ([]gopom.License, error) { - id := r.resolveMavenID(ctx, pom) + id := r.getMavenID(ctx, pom) if slices.Contains(processing, id) { return nil, fmt.Errorf("cycle detected resolving licenses for: %v", id) } @@ -545,7 +565,7 @@ func (r *mavenResolver) pomLicenses(ctx context.Context, pom *gopom.Project) []g return out } -func (r *mavenResolver) findParentPomByRelativePath(ctx context.Context, pom *gopom.Project, parentID mavenID) *gopom.Project { +func (r *mavenResolver) findParentPomByRelativePath(ctx context.Context, pom *gopom.Project, parentID mavenID, resolvingProperties []string) *gopom.Project { // don't resolve if no resolver if r.fileResolver == nil { return nil @@ -555,7 +575,7 @@ func (r *mavenResolver) findParentPomByRelativePath(ctx context.Context, pom *go if !hasPomLocation || pom == nil || pom.Parent == nil { return nil } - relativePath := r.getPropertyValue(ctx, pom.Parent.RelativePath, pom) + relativePath := r.resolvePropertyValue(ctx, pom.Parent.RelativePath, resolvingProperties, pom) if relativePath == "" { return nil } @@ -563,9 +583,12 @@ func (r *mavenResolver) findParentPomByRelativePath(ctx context.Context, pom *go p = path.Dir(p) p = path.Join(p, relativePath) p = path.Clean(p) + if !strings.HasSuffix(p, ".xml") { + p = path.Join(p, "pom.xml") + } parentLocations, err := r.fileResolver.FilesByPath(p) if err != nil || len(parentLocations) == 0 { - log.WithFields("error", err, "mavenID", r.resolveMavenID(ctx, pom), "parentID", parentID, "relativePath", relativePath). + log.WithFields("error", err, "mavenID", r.resolveMavenID(ctx, resolvingProperties, pom), "parentID", parentID, "relativePath", relativePath). Trace("parent pom not found by relative path") return nil } @@ -573,21 +596,21 @@ func (r *mavenResolver) findParentPomByRelativePath(ctx context.Context, pom *go parentContents, err := r.fileResolver.FileContentsByLocation(parentLocation) if err != nil || parentContents == nil { - log.WithFields("error", err, "mavenID", r.resolveMavenID(ctx, pom), "parentID", parentID, "parentLocation", parentLocation). + log.WithFields("error", err, "mavenID", r.resolveMavenID(ctx, resolvingProperties, pom), "parentID", parentID, "parentLocation", parentLocation). Debug("unable to get contents of parent pom by relative path") return nil } defer internal.CloseAndLogError(parentContents, parentLocation.RealPath) parentPom, err := decodePomXML(parentContents) if err != nil || parentPom == nil { - log.WithFields("error", err, "mavenID", r.resolveMavenID(ctx, pom), "parentID", parentID, "parentLocation", parentLocation). + log.WithFields("error", err, "mavenID", r.resolveMavenID(ctx, resolvingProperties, pom), "parentID", parentID, "parentLocation", parentLocation). Debug("unable to parse parent pom") return nil } // ensure parent matches - newParentID := r.resolveMavenID(ctx, parentPom) + newParentID := r.resolveMavenID(ctx, resolvingProperties, parentPom) if newParentID.ArtifactID != parentID.ArtifactID { - log.WithFields("newParentID", newParentID, "mavenID", r.resolveMavenID(ctx, pom), "parentID", parentID, "parentLocation", parentLocation). + log.WithFields("newParentID", newParentID, "mavenID", r.resolveMavenID(ctx, resolvingProperties, pom), "parentID", parentID, "parentLocation", parentLocation). Debug("parent IDs do not match resolving parent by relative path") return nil } diff --git a/syft/pkg/cataloger/java/maven_resolver_test.go b/syft/pkg/cataloger/java/maven_resolver_test.go index d778efb6991..bec9b669156 100644 --- a/syft/pkg/cataloger/java/maven_resolver_test.go +++ b/syft/pkg/cataloger/java/maven_resolver_test.go @@ -273,32 +273,72 @@ func Test_relativePathParent(t *testing.T) { resolver, err := fileresolver.NewFromDirectory("test-fixtures/pom/local", "") require.NoError(t, err) - r := newMavenResolver(resolver, DefaultArchiveCatalogerConfig()) - locs, err := resolver.FilesByPath("child-1/pom.xml") - require.NoError(t, err) - require.Len(t, locs, 1) + ctx := context.Background() - loc := locs[0] - contents, err := resolver.FileContentsByLocation(loc) - require.NoError(t, err) - defer internal.CloseAndLogError(contents, loc.RealPath) + tests := []struct { + name string + pom string + validate func(t *testing.T, r *mavenResolver, pom *gopom.Project) + }{ + { + name: "basic", + pom: "child-1/pom.xml", + validate: func(t *testing.T, r *mavenResolver, pom *gopom.Project) { + parent, err := r.resolveParent(ctx, pom) + require.NoError(t, err) + require.Contains(t, r.pomLocations, parent) - pom, err := decodePomXML(contents) - require.NoError(t, err) + parent, err = r.resolveParent(ctx, parent) + require.NoError(t, err) + require.Contains(t, r.pomLocations, parent) - r.pomLocations[pom] = loc + got := r.getPropertyValue(ctx, ptr("${commons-exec_subversion}"), pom) + require.Equal(t, "3", got) - ctx := context.Background() - parent, err := r.resolveParent(ctx, pom) - require.NoError(t, err) - require.Contains(t, r.pomLocations, parent) + }, + }, + { + name: "parent property", + pom: "child-2/pom.xml", + validate: func(t *testing.T, r *mavenResolver, pom *gopom.Project) { + id := r.getMavenID(ctx, pom) + // child.parent.version = ${revision} + // parent.revision = 3.3.3 + require.Equal(t, id.Version, "3.3.3") + }, + }, + { + name: "invalid parent", + pom: "child-3/pom.xml", + validate: func(t *testing.T, r *mavenResolver, pom *gopom.Project) { + require.NotNil(t, pom) + id := r.getMavenID(ctx, pom) + // version should not be resolved to anything + require.Equal(t, "", id.Version) + }, + }, + } - parent, err = r.resolveParent(ctx, parent) - require.NoError(t, err) - require.Contains(t, r.pomLocations, parent) + for _, test := range tests { + t.Run(test.name, func(t *testing.T) { + r := newMavenResolver(resolver, DefaultArchiveCatalogerConfig()) + locs, err := resolver.FilesByPath(test.pom) + require.NoError(t, err) + require.Len(t, locs, 1) + + loc := locs[0] + contents, err := resolver.FileContentsByLocation(loc) + require.NoError(t, err) + defer internal.CloseAndLogError(contents, loc.RealPath) + + pom, err := decodePomXML(contents) + require.NoError(t, err) - got := r.getPropertyValue(ctx, ptr("${commons-exec_subversion}"), pom) - require.Equal(t, "3", got) + r.pomLocations[pom] = loc + + test.validate(t, r, pom) + }) + } } // mockMavenRepo starts a remote maven repo serving all the pom files found in test-fixtures/pom/maven-repo diff --git a/syft/pkg/cataloger/java/parse_pom_xml.go b/syft/pkg/cataloger/java/parse_pom_xml.go index d9fe4b2c25a..370ebc2c84a 100644 --- a/syft/pkg/cataloger/java/parse_pom_xml.go +++ b/syft/pkg/cataloger/java/parse_pom_xml.go @@ -53,7 +53,7 @@ func (p pomXMLCataloger) Catalog(ctx context.Context, fileResolver file.Resolver // store information about this pom for future lookups r.pomLocations[pom] = pomLocation - r.resolved[r.resolveMavenID(ctx, pom)] = pom + r.resolved[r.getMavenID(ctx, pom)] = pom } var pkgs []pkg.Package @@ -75,7 +75,7 @@ func readPomFromLocation(fileResolver file.Resolver, pomLocation file.Location) func processPomXML(ctx context.Context, r *mavenResolver, pom *gopom.Project, loc file.Location) []pkg.Package { var pkgs []pkg.Package - pomID := r.resolveMavenID(ctx, pom) + pomID := r.getMavenID(ctx, pom) for _, dep := range pomDependencies(pom) { depID := r.resolveDependencyID(ctx, pom, dep) log.WithFields("pomLocation", loc, "mavenID", pomID, "dependencyID", depID).Trace("adding maven pom dependency") @@ -100,7 +100,7 @@ func processPomXML(ctx context.Context, r *mavenResolver, pom *gopom.Project, lo } func newPomProject(ctx context.Context, r *mavenResolver, path string, pom *gopom.Project) *pkg.JavaPomProject { - id := r.resolveMavenID(ctx, pom) + id := r.getMavenID(ctx, pom) name := r.getPropertyValue(ctx, pom.Name, pom) projectURL := r.getPropertyValue(ctx, pom.URL, pom) diff --git a/syft/pkg/cataloger/java/test-fixtures/pom/local/child-2/pom.xml b/syft/pkg/cataloger/java/test-fixtures/pom/local/child-2/pom.xml new file mode 100644 index 00000000000..057233ae338 --- /dev/null +++ b/syft/pkg/cataloger/java/test-fixtures/pom/local/child-2/pom.xml @@ -0,0 +1,15 @@ + + + 4.0.0 + + + my.org + parent-three + ${revision} + ../parent-3 + + + child-two + jar + diff --git a/syft/pkg/cataloger/java/test-fixtures/pom/local/child-3/pom.xml b/syft/pkg/cataloger/java/test-fixtures/pom/local/child-3/pom.xml new file mode 100644 index 00000000000..741ab4c070e --- /dev/null +++ b/syft/pkg/cataloger/java/test-fixtures/pom/local/child-3/pom.xml @@ -0,0 +1,15 @@ + + + 4.0.0 + + + my.org + parent-three + ${revision} + ../invalid + + + child-three + jar + diff --git a/syft/pkg/cataloger/java/test-fixtures/pom/local/parent-3/pom.xml b/syft/pkg/cataloger/java/test-fixtures/pom/local/parent-3/pom.xml new file mode 100644 index 00000000000..eac8785b6b9 --- /dev/null +++ b/syft/pkg/cataloger/java/test-fixtures/pom/local/parent-3/pom.xml @@ -0,0 +1,14 @@ + + + 4.0.0 + + my.org + parent-three + ${revision} + pom + + + 3.3.3 + + From 19d2735affb0dcb7274d9b9711c67d67a02473d0 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Thu, 29 Aug 2024 14:16:34 +0000 Subject: [PATCH 097/122] chore(deps): bump github/codeql-action from 3.26.5 to 3.26.6 (#3173) --- .github/workflows/codeql-analysis.yml | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/.github/workflows/codeql-analysis.yml b/.github/workflows/codeql-analysis.yml index 768415473fd..65d23b35209 100644 --- a/.github/workflows/codeql-analysis.yml +++ b/.github/workflows/codeql-analysis.yml @@ -45,7 +45,7 @@ jobs: # Initializes the CodeQL tools for scanning. - name: Initialize CodeQL - uses: github/codeql-action/init@2c779ab0d087cd7fe7b826087247c2c81f27bfa6 #v3.26.5 + uses: github/codeql-action/init@4dd16135b69a43b6c8efb853346f8437d92d3c93 #v3.26.6 with: languages: ${{ matrix.language }} # If you wish to specify custom queries, you can do so here or in a config file. @@ -56,7 +56,7 @@ jobs: # Autobuild attempts to build any compiled languages (C/C++, C#, or Java). # If this step fails, then you should remove it and run the build manually (see below) - name: Autobuild - uses: github/codeql-action/autobuild@2c779ab0d087cd7fe7b826087247c2c81f27bfa6 #v3.26.5 + uses: github/codeql-action/autobuild@4dd16135b69a43b6c8efb853346f8437d92d3c93 #v3.26.6 # ℹī¸ Command-line programs to run using the OS shell. # 📚 https://git.io/JvXDl @@ -70,4 +70,4 @@ jobs: # make release - name: Perform CodeQL Analysis - uses: github/codeql-action/analyze@2c779ab0d087cd7fe7b826087247c2c81f27bfa6 #v3.26.5 + uses: github/codeql-action/analyze@4dd16135b69a43b6c8efb853346f8437d92d3c93 #v3.26.6 From 3499d92c6d57cffebf8d665e2b8c2b7b625f8b7f Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Thu, 29 Aug 2024 14:16:43 +0000 Subject: [PATCH 098/122] chore(deps): bump github.com/charmbracelet/bubbletea (#3171) --- go.mod | 2 +- go.sum | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/go.mod b/go.mod index f6d03ab6c7f..552fbaf308f 100644 --- a/go.mod +++ b/go.mod @@ -24,7 +24,7 @@ require ( github.com/aquasecurity/go-pep440-version v0.0.0-20210121094942-22b2f8951d46 github.com/bmatcuk/doublestar/v4 v4.6.1 github.com/charmbracelet/bubbles v0.19.0 - github.com/charmbracelet/bubbletea v0.27.0 + github.com/charmbracelet/bubbletea v1.0.0 github.com/charmbracelet/lipgloss v0.13.0 github.com/dave/jennifer v1.7.0 github.com/deitch/magic v0.0.0-20230404182410-1ff89d7342da diff --git a/go.sum b/go.sum index a9c8256cfb1..2d16cd1a5bc 100644 --- a/go.sum +++ b/go.sum @@ -157,8 +157,8 @@ github.com/cespare/xxhash/v2 v2.1.1/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XL github.com/cespare/xxhash/v2 v2.1.2/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs= github.com/charmbracelet/bubbles v0.19.0 h1:gKZkKXPP6GlDk6EcfujDK19PCQqRjaJZQ7QRERx1UF0= github.com/charmbracelet/bubbles v0.19.0/go.mod h1:WILteEqZ+krG5c3ntGEMeG99nCupcuIk7V0/zOP0tOA= -github.com/charmbracelet/bubbletea v0.27.0 h1:Mznj+vvYuYagD9Pn2mY7fuelGvP0HAXtZYGgRBCbHvU= -github.com/charmbracelet/bubbletea v0.27.0/go.mod h1:5MdP9XH6MbQkgGhnlxUqCNmBXf9I74KRQ8HIidRxV1Y= +github.com/charmbracelet/bubbletea v1.0.0 h1:BlNvkVed3DADQlV+W79eioNUOrnMUY25EEVdFUoDoGA= +github.com/charmbracelet/bubbletea v1.0.0/go.mod h1:xc4gm5yv+7tbniEvQ0naiG9P3fzYhk16cTgDZQQW6YE= github.com/charmbracelet/harmonica v0.2.0 h1:8NxJWRWg/bzKqqEaaeFNipOu77YR5t8aSwG4pgaUBiQ= github.com/charmbracelet/harmonica v0.2.0/go.mod h1:KSri/1RMQOZLbw7AHqgcBycp8pgJnQMYYT8QZRqZ1Ao= github.com/charmbracelet/lipgloss v0.13.0 h1:4X3PPeoWEDCMvzDvGmTajSyYPcZM4+y8sCA/SsA3cjw= From 731fc776412df87010c8e745d4ef24a1857161ba Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Thu, 29 Aug 2024 14:16:50 +0000 Subject: [PATCH 099/122] chore(deps): bump github.com/docker/docker (#3168) --- go.mod | 2 +- go.sum | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/go.mod b/go.mod index 552fbaf308f..4075c9be91c 100644 --- a/go.mod +++ b/go.mod @@ -29,7 +29,7 @@ require ( github.com/dave/jennifer v1.7.0 github.com/deitch/magic v0.0.0-20230404182410-1ff89d7342da github.com/distribution/reference v0.6.0 - github.com/docker/docker v27.1.2+incompatible + github.com/docker/docker v27.2.0+incompatible github.com/dustin/go-humanize v1.0.1 github.com/elliotchance/phpserialize v1.4.0 github.com/facebookincubator/nvdtools v0.1.5 diff --git a/go.sum b/go.sum index 2d16cd1a5bc..c01d9b3c265 100644 --- a/go.sum +++ b/go.sum @@ -231,8 +231,8 @@ github.com/docker/cli v27.1.1+incompatible h1:goaZxOqs4QKxznZjjBWKONQci/MywhtRv2 github.com/docker/cli v27.1.1+incompatible/go.mod h1:JLrzqnKDaYBop7H2jaqPtU4hHvMKP+vjCwu2uszcLI8= github.com/docker/distribution v2.8.3+incompatible h1:AtKxIZ36LoNK51+Z6RpzLpddBirtxJnzDrHLEKxTAYk= github.com/docker/distribution v2.8.3+incompatible/go.mod h1:J2gT2udsDAN96Uj4KfcMRqY0/ypR+oyYUYmja8H+y+w= -github.com/docker/docker v27.1.2+incompatible h1:AhGzR1xaQIy53qCkxARaFluI00WPGtXn0AJuoQsVYTY= -github.com/docker/docker v27.1.2+incompatible/go.mod h1:eEKB0N0r5NX/I1kEveEz05bcu8tLC/8azJZsviup8Sk= +github.com/docker/docker v27.2.0+incompatible h1:Rk9nIVdfH3+Vz4cyI/uhbINhEZ/oLmc+CBXmH6fbNk4= +github.com/docker/docker v27.2.0+incompatible/go.mod h1:eEKB0N0r5NX/I1kEveEz05bcu8tLC/8azJZsviup8Sk= github.com/docker/docker-credential-helpers v0.7.0 h1:xtCHsjxogADNZcdv1pKUHXryefjlVRqWqIhk/uXJp0A= github.com/docker/docker-credential-helpers v0.7.0/go.mod h1:rETQfLdHNT3foU5kuNkFR1R1V12OJRRO5lzt2D1b5X0= github.com/docker/go-connections v0.4.0 h1:El9xVISelRB7BuFusrZozjnkIM5YnzCViNKohAFqRJQ= From f2caf4569532619b43d298f1d4b6b264bcf3208e Mon Sep 17 00:00:00 2001 From: Mikail <6186720+NyanKiyoshi@users.noreply.github.com> Date: Thu, 29 Aug 2024 17:05:43 +0200 Subject: [PATCH 100/122] fix: properly decode SPDX license expressions in CycloneDX format (#3175) Signed-off-by: Mikail Kocak --- syft/format/internal/cyclonedxutil/helpers/licenses.go | 9 +++------ .../internal/cyclonedxutil/helpers/licenses_test.go | 4 ++-- 2 files changed, 5 insertions(+), 8 deletions(-) diff --git a/syft/format/internal/cyclonedxutil/helpers/licenses.go b/syft/format/internal/cyclonedxutil/helpers/licenses.go index a092d3abdf3..24c5d6ffb79 100644 --- a/syft/format/internal/cyclonedxutil/helpers/licenses.go +++ b/syft/format/internal/cyclonedxutil/helpers/licenses.go @@ -54,17 +54,14 @@ func decodeLicenses(c *cyclonedx.Component) []pkg.License { } for _, l := range *c.Licenses { - if l.License == nil { - continue - } // these fields are mutually exclusive in the spec switch { - case l.License.ID != "": + case l.License != nil && l.License.ID != "": licenses = append(licenses, pkg.NewLicenseFromURLs(l.License.ID, l.License.URL)) - case l.License.Name != "": + case l.License != nil && l.License.Name != "": licenses = append(licenses, pkg.NewLicenseFromURLs(l.License.Name, l.License.URL)) case l.Expression != "": - licenses = append(licenses, pkg.NewLicenseFromURLs(l.Expression, l.License.URL)) + licenses = append(licenses, pkg.NewLicense(l.Expression)) default: } } diff --git a/syft/format/internal/cyclonedxutil/helpers/licenses_test.go b/syft/format/internal/cyclonedxutil/helpers/licenses_test.go index e2532f607d4..373a0937758 100644 --- a/syft/format/internal/cyclonedxutil/helpers/licenses_test.go +++ b/syft/format/internal/cyclonedxutil/helpers/licenses_test.go @@ -254,7 +254,8 @@ func TestDecodeLicenses(t *testing.T) { input: &cyclonedx.Component{ Licenses: &cyclonedx.Licenses{ { - License: &cyclonedx.License{}, + // CycloneDX specification doesn't allow to provide License if Expression is provided + License: nil, Expression: "MIT AND GPL-3.0-only WITH Classpath-exception-2.0", }, }, @@ -264,7 +265,6 @@ func TestDecodeLicenses(t *testing.T) { Value: "MIT AND GPL-3.0-only WITH Classpath-exception-2.0", SPDXExpression: "MIT AND GPL-3.0-only WITH Classpath-exception-2.0", Type: license.Declared, - URLs: []string{}, }, }, }, From e299a9512045728c91ce979c52d417266f2f2416 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 3 Sep 2024 12:22:07 -0400 Subject: [PATCH 101/122] chore(deps): bump peter-evans/create-pull-request from 6.1.0 to 7.0.0 (#3187) Bumps [peter-evans/create-pull-request](https://github.com/peter-evans/create-pull-request) from 6.1.0 to 7.0.0. - [Release notes](https://github.com/peter-evans/create-pull-request/releases) - [Commits](https://github.com/peter-evans/create-pull-request/compare/c5a7806660adbe173f04e3e038b0ccdcd758773c...4320041ed380b20e97d388d56a7fb4f9b8c20e79) --- updated-dependencies: - dependency-name: peter-evans/create-pull-request dependency-type: direct:production update-type: version-update:semver-major ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- .github/workflows/update-bootstrap-tools.yml | 2 +- .github/workflows/update-cpe-dictionary-index.yml | 2 +- .github/workflows/update-stereoscope-release.yml | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/.github/workflows/update-bootstrap-tools.yml b/.github/workflows/update-bootstrap-tools.yml index 9518a233f27..488a2cf5bc2 100644 --- a/.github/workflows/update-bootstrap-tools.yml +++ b/.github/workflows/update-bootstrap-tools.yml @@ -50,7 +50,7 @@ jobs: app_id: ${{ secrets.TOKEN_APP_ID }} private_key: ${{ secrets.TOKEN_APP_PRIVATE_KEY }} - - uses: peter-evans/create-pull-request@c5a7806660adbe173f04e3e038b0ccdcd758773c #v6.1.0 + - uses: peter-evans/create-pull-request@4320041ed380b20e97d388d56a7fb4f9b8c20e79 #v7.0.0 with: signoff: true delete-branch: true diff --git a/.github/workflows/update-cpe-dictionary-index.yml b/.github/workflows/update-cpe-dictionary-index.yml index 18d3e2d14fc..879298e0689 100644 --- a/.github/workflows/update-cpe-dictionary-index.yml +++ b/.github/workflows/update-cpe-dictionary-index.yml @@ -33,7 +33,7 @@ jobs: app_id: ${{ secrets.TOKEN_APP_ID }} private_key: ${{ secrets.TOKEN_APP_PRIVATE_KEY }} - - uses: peter-evans/create-pull-request@c5a7806660adbe173f04e3e038b0ccdcd758773c #v6.1.0 + - uses: peter-evans/create-pull-request@4320041ed380b20e97d388d56a7fb4f9b8c20e79 #v7.0.0 with: signoff: true delete-branch: true diff --git a/.github/workflows/update-stereoscope-release.yml b/.github/workflows/update-stereoscope-release.yml index 94ea0ee1b71..41142261116 100644 --- a/.github/workflows/update-stereoscope-release.yml +++ b/.github/workflows/update-stereoscope-release.yml @@ -44,7 +44,7 @@ jobs: app_id: ${{ secrets.TOKEN_APP_ID }} private_key: ${{ secrets.TOKEN_APP_PRIVATE_KEY }} - - uses: peter-evans/create-pull-request@c5a7806660adbe173f04e3e038b0ccdcd758773c #v6.1.0 + - uses: peter-evans/create-pull-request@4320041ed380b20e97d388d56a7fb4f9b8c20e79 #v7.0.0 with: signoff: true delete-branch: true From 8ade3916585d76b330dc06647fc110af5aa0c342 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 3 Sep 2024 12:22:16 -0400 Subject: [PATCH 102/122] chore(deps): bump actions/upload-artifact from 4.3.6 to 4.4.0 (#3184) Bumps [actions/upload-artifact](https://github.com/actions/upload-artifact) from 4.3.6 to 4.4.0. - [Release notes](https://github.com/actions/upload-artifact/releases) - [Commits](https://github.com/actions/upload-artifact/compare/834a144ee995460fba8ed112a2fc961b36a5ec5a...50769540e7f4bd5e21e526ee35c689e35e0d6874) --- updated-dependencies: - dependency-name: actions/upload-artifact dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- .github/workflows/benchmark-testing.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/benchmark-testing.yaml b/.github/workflows/benchmark-testing.yaml index 8284d8264eb..9fff8c76ac5 100644 --- a/.github/workflows/benchmark-testing.yaml +++ b/.github/workflows/benchmark-testing.yaml @@ -39,7 +39,7 @@ jobs: OUTPUT="${OUTPUT//$'\r'/'%0D'}" # URL encode all '\r' characters echo "result=$OUTPUT" >> $GITHUB_OUTPUT - - uses: actions/upload-artifact@834a144ee995460fba8ed112a2fc961b36a5ec5a # v4.3.6 + - uses: actions/upload-artifact@50769540e7f4bd5e21e526ee35c689e35e0d6874 # v4.4.0 with: name: benchmark-test-results path: test/results/**/* From 8c690d000d6e5d6b423541d6b427954f27619b2a Mon Sep 17 00:00:00 2001 From: "anchore-actions-token-generator[bot]" <102182147+anchore-actions-token-generator[bot]@users.noreply.github.com> Date: Tue, 3 Sep 2024 12:22:30 -0400 Subject: [PATCH 103/122] chore(deps): update CPE dictionary index (#3183) Signed-off-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com> Co-authored-by: wagoodman <590471+wagoodman@users.noreply.github.com> --- .../dictionary/data/cpe-index.json | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) diff --git a/syft/pkg/cataloger/internal/cpegenerate/dictionary/data/cpe-index.json b/syft/pkg/cataloger/internal/cpegenerate/dictionary/data/cpe-index.json index 20dee5938ce..abd3b6ca8e8 100644 --- a/syft/pkg/cataloger/internal/cpegenerate/dictionary/data/cpe-index.json +++ b/syft/pkg/cataloger/internal/cpegenerate/dictionary/data/cpe-index.json @@ -6705,6 +6705,9 @@ "multiqueue2": [ "cpe:2.3:a:multiqueue2_project:multiqueue2:*:*:*:*:*:rust:*:*" ], + "naga": [ + "cpe:2.3:a:gfx-rs:naga:*:*:*:*:*:rust:*:*" + ], "nalgebra": [ "cpe:2.3:a:dimforge:nalgebra:*:*:*:*:*:rust:*:*" ], @@ -8081,6 +8084,9 @@ "block-specific-plugin-updates": [ "cpe:2.3:a:dineshkarki:block_plugin_update:*:*:*:*:*:wordpress:*:*" ], + "blockart-blocks": [ + "cpe:2.3:a:wpblockart:blockart_blocks:*:*:*:*:*:wordpress:*:*" + ], "blockonomics-bitcoin-payments": [ "cpe:2.3:a:blockonomics:blockonomics:*:*:*:*:*:wordpress:*:*" ], @@ -8218,6 +8224,9 @@ "bp-social-connect": [ "cpe:2.3:a:vibethemes:bp_social_connect:*:*:*:*:*:wordpress:*:*" ], + "bradmax-player": [ + "cpe:2.3:a:bradmax:bradmax_player:*:*:*:*:*:wordpress:*:*" + ], "brave-popup-builder": [ "cpe:2.3:a:getbrave:brave:*:*:*:*:*:wordpress:*:*" ], @@ -12482,6 +12491,7 @@ "cpe:2.3:a:mediavine:create:*:*:*:*:*:wordpress:*:*" ], "meeting-scheduler-by-vcita": [ + "cpe:2.3:a:vcita:online_booking_\\\u0026_scheduling_calendar:*:*:*:*:*:wordpress:*:*", "cpe:2.3:a:vcita:online_booking_\\\u0026_scheduling_calendar_for_wordpress:*:*:*:*:*:wordpress:*:*", "cpe:2.3:a:vcita:online_booking_\\\u0026_scheduling_calendar_for_wordpress_by_vcita:*:*:*:*:*:wordpress:*:*" ], @@ -13468,6 +13478,9 @@ "photo-gallery": [ "cpe:2.3:a:10web:photo_gallery:*:*:*:*:*:wordpress:*:*" ], + "photo-video-gallery-master": [ + "cpe:2.3:a:webhuntinfotech:photo_video_gallery_master:*:*:*:*:*:wordpress:*:*" + ], "photoblocks-grid-gallery": [ "cpe:2.3:a:greentreelabs:gallery_photoblocks:*:*:*:*:*:wordpress:*:*", "cpe:2.3:a:wpchill:gallery_photoblocks:*:*:*:*:*:wordpress:*:*" @@ -14351,6 +14364,9 @@ "review-schema": [ "cpe:2.3:a:radiustheme:review_schema:*:*:*:*:*:wordpress:*:*" ], + "reviews-feed": [ + "cpe:2.3:a:smashballoon:reviews_feed:*:*:*:*:*:wordpress:*:*" + ], "reviews-plus": [ "cpe:2.3:a:implecode:reviews_plus:*:*:*:*:*:wordpress:*:*" ], @@ -16077,6 +16093,9 @@ "ultimate-blocks": [ "cpe:2.3:a:dotcamp:ultimate_blocks:*:*:*:*:*:wordpress:*:*" ], + "ultimate-bootstrap-elements-for-elementor": [ + "cpe:2.3:a:g5plus:ultimate_bootstrap_elements_for_elementor:*:*:*:*:*:wordpress:*:*" + ], "ultimate-carousel-for-elementor": [ "cpe:2.3:a:topdigitaltrends:ultimate_carousel_for_elementor:*:*:*:*:*:wordpress:*:*" ], From 7c96a10cbea82e94c843112c8394abac7672b0dc Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 3 Sep 2024 12:22:43 -0400 Subject: [PATCH 104/122] chore(deps): bump github.com/Masterminds/sprig/v3 from 3.2.3 to 3.3.0 (#3177) Bumps [github.com/Masterminds/sprig/v3](https://github.com/Masterminds/sprig) from 3.2.3 to 3.3.0. - [Release notes](https://github.com/Masterminds/sprig/releases) - [Changelog](https://github.com/Masterminds/sprig/blob/master/CHANGELOG.md) - [Commits](https://github.com/Masterminds/sprig/compare/v3.2.3...v3.3.0) --- updated-dependencies: - dependency-name: github.com/Masterminds/sprig/v3 dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- go.mod | 13 ++++++------- go.sum | 33 ++++++++++++--------------------- 2 files changed, 18 insertions(+), 28 deletions(-) diff --git a/go.mod b/go.mod index 4075c9be91c..8e6a7ea63dd 100644 --- a/go.mod +++ b/go.mod @@ -5,7 +5,7 @@ go 1.22.0 require ( github.com/CycloneDX/cyclonedx-go v0.9.0 github.com/Masterminds/semver v1.5.0 - github.com/Masterminds/sprig/v3 v3.2.3 + github.com/Masterminds/sprig/v3 v3.3.0 github.com/acarl005/stripansi v0.0.0-20180116102854-5a71ef0e047d github.com/acobaugh/osrelease v0.1.0 github.com/anchore/bubbly v0.0.0-20231115134915-def0aba654a9 @@ -94,12 +94,12 @@ require ( ) require ( - dario.cat/mergo v1.0.0 // indirect + dario.cat/mergo v1.0.1 // indirect github.com/AdaLogics/go-fuzz-headers v0.0.0-20230811130428-ced1acdcaa24 // indirect github.com/AdamKorcz/go-118-fuzz-build v0.0.0-20230306123547-8075edf89bb0 // indirect github.com/DataDog/zstd v1.5.5 // indirect github.com/Masterminds/goutils v1.1.1 // indirect - github.com/Masterminds/semver/v3 v3.2.0 // indirect + github.com/Masterminds/semver/v3 v3.3.0 // indirect github.com/Microsoft/go-winio v0.6.1 // indirect github.com/Microsoft/hcsshim v0.11.4 // indirect github.com/ProtonMail/go-crypto v1.0.0 // indirect @@ -153,9 +153,8 @@ require ( github.com/hashicorp/errwrap v1.1.0 // indirect github.com/hashicorp/golang-lru/v2 v2.0.7 // indirect github.com/hashicorp/hcl v1.0.0 // indirect - github.com/huandu/xstrings v1.3.3 // indirect + github.com/huandu/xstrings v1.5.0 // indirect github.com/iancoleman/orderedmap v0.0.0-20190318233801-ac98e3ecb4b0 // indirect - github.com/imdario/mergo v0.3.15 // indirect github.com/inconshreveable/mousetrap v1.1.0 // indirect github.com/jbenet/go-context v0.0.0-20150711004518-d14ea06fba99 // indirect github.com/kevinburke/ssh_config v1.2.0 // indirect @@ -200,11 +199,11 @@ require ( github.com/sagikazarmark/slog-shim v0.1.0 // indirect github.com/sahilm/fuzzy v0.1.1 // indirect github.com/secDre4mer/pkcs7 v0.0.0-20240322103146-665324a4461d // indirect - github.com/shopspring/decimal v1.2.0 // indirect + github.com/shopspring/decimal v1.4.0 // indirect github.com/sirupsen/logrus v1.9.3 // indirect github.com/skeema/knownhosts v1.2.2 // indirect github.com/sourcegraph/conc v0.3.0 // indirect - github.com/spf13/cast v1.6.0 // indirect + github.com/spf13/cast v1.7.0 // indirect github.com/spf13/pflag v1.0.5 // indirect github.com/spf13/viper v1.18.2 // indirect github.com/subosito/gotenv v1.6.0 // indirect diff --git a/go.sum b/go.sum index c01d9b3c265..0cc5381b240 100644 --- a/go.sum +++ b/go.sum @@ -45,8 +45,8 @@ cloud.google.com/go/storage v1.5.0/go.mod h1:tpKbwo567HUNpVclU5sGELwQWBDZ8gh0Zeo cloud.google.com/go/storage v1.6.0/go.mod h1:N7U0C8pVQ/+NIKOBQyamJIeKQKkZ+mxpohlUTyfDhBk= cloud.google.com/go/storage v1.8.0/go.mod h1:Wv1Oy7z6Yz3DshWRJFhqM/UCfaWIRTdp0RXyy7KQOVs= cloud.google.com/go/storage v1.10.0/go.mod h1:FLPqc6j+Ki4BU591ie1oL6qBQGu2Bl/tZ9ullr3+Kg0= -dario.cat/mergo v1.0.0 h1:AGCNq9Evsj31mOgNPcLyXc+4PNABt905YmuqPYYpBWk= -dario.cat/mergo v1.0.0/go.mod h1:uNxQE+84aUszobStD9th8a29P2fMDhsBdgRYvZOxGmk= +dario.cat/mergo v1.0.1 h1:Ra4+bf83h2ztPIQYNP99R6m+Y7KfnARDfID+a+vLl4s= +dario.cat/mergo v1.0.1/go.mod h1:uNxQE+84aUszobStD9th8a29P2fMDhsBdgRYvZOxGmk= dmitri.shuralyov.com/gpu/mtl v0.0.0-20190408044501-666a987793e9/go.mod h1:H6x//7gZCb22OMCxBHrMx7a5I7Hp++hsVxbQ4BYO7hU= github.com/AdaLogics/go-fuzz-headers v0.0.0-20230811130428-ced1acdcaa24 h1:bvDV9vkmnHYOMsOr4WLk+Vo07yKIzd94sVoIqshQ4bU= github.com/AdaLogics/go-fuzz-headers v0.0.0-20230811130428-ced1acdcaa24/go.mod h1:8o94RPi1/7XTJvwPpRSzSUedZrtlirdB3r9Z20bi2f8= @@ -69,10 +69,10 @@ github.com/Masterminds/goutils v1.1.1 h1:5nUrii3FMTL5diU80unEVvNevw1nH4+ZV4DSLVJ github.com/Masterminds/goutils v1.1.1/go.mod h1:8cTjp+g8YejhMuvIA5y2vz3BpJxksy863GQaJW2MFNU= github.com/Masterminds/semver v1.5.0 h1:H65muMkzWKEuNDnfl9d70GUjFniHKHRbFPGBuZ3QEww= github.com/Masterminds/semver v1.5.0/go.mod h1:MB6lktGJrhw8PrUyiEoblNEGEQ+RzHPF078ddwwvV3Y= -github.com/Masterminds/semver/v3 v3.2.0 h1:3MEsd0SM6jqZojhjLWWeBY+Kcjy9i6MQAeY7YgDP83g= -github.com/Masterminds/semver/v3 v3.2.0/go.mod h1:qvl/7zhW3nngYb5+80sSMF+FG2BjYrf8m9wsX0PNOMQ= -github.com/Masterminds/sprig/v3 v3.2.3 h1:eL2fZNezLomi0uOLqjQoN6BfsDD+fyLtgbJMAj9n6YA= -github.com/Masterminds/sprig/v3 v3.2.3/go.mod h1:rXcFaZ2zZbLRJv/xSysmlgIM1u11eBaRMhvYXJNkGuM= +github.com/Masterminds/semver/v3 v3.3.0 h1:B8LGeaivUe71a5qox1ICM/JLl0NqZSW5CHyL+hmvYS0= +github.com/Masterminds/semver/v3 v3.3.0/go.mod h1:4V+yj/TJE1HU9XfppCwVMZq3I84lprf4nC11bSS5beM= +github.com/Masterminds/sprig/v3 v3.3.0 h1:mQh0Yrg1XPo6vjYXgtf5OtijNAKJRNcTdOOGZe3tPhs= +github.com/Masterminds/sprig/v3 v3.3.0/go.mod h1:Zy1iXRYNqNLUolqCpL4uhk6SHUMAOSCzdgBfDb35Lz0= github.com/Microsoft/go-winio v0.5.2/go.mod h1:WpS1mjBmmwHBEWmogvA2mj8546UReBk4v8QkMxJ6pZY= github.com/Microsoft/go-winio v0.6.1 h1:9/kr64B9VUZrLm5YYwbGtUJnMgqWVOdUAXu6Migciow= github.com/Microsoft/go-winio v0.6.1/go.mod h1:LRdKpFKfdobln8UmuiYcKPot9D2v6svN5+sAH+4kjUM= @@ -411,7 +411,6 @@ github.com/google/pprof v0.0.0-20211214055906-6f57359322fd/go.mod h1:KgnwoLYCZ8I github.com/google/pprof v0.0.0-20240409012703-83162a5b38cd h1:gbpYu9NMq8jhDVbvlGkMFWCjLFlqqEZjEmObmhUy6Vo= github.com/google/pprof v0.0.0-20240409012703-83162a5b38cd/go.mod h1:kf6iHlnVGwgKolg33glAes7Yg/8iWP8ukqeldJSO7jw= github.com/google/renameio v0.1.0/go.mod h1:KWCgfxg9yswjAJkECMjeO8J8rahYeXnNhOm40UhjYkI= -github.com/google/uuid v1.1.1/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= github.com/google/uuid v1.1.2/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= github.com/google/uuid v1.6.0 h1:NIvaJDMOsjHA8n1jAhLSgzrAzy1Hgr+hNrb57e+94F0= github.com/google/uuid v1.6.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= @@ -463,8 +462,8 @@ github.com/hashicorp/memberlist v0.2.2/go.mod h1:MS2lj3INKhZjWNqd3N0m3J+Jxf3DAOn github.com/hashicorp/memberlist v0.3.0/go.mod h1:MS2lj3INKhZjWNqd3N0m3J+Jxf3DAOnAH9VT3Sh9MUE= github.com/hashicorp/serf v0.9.5/go.mod h1:UWDWwZeL5cuWDJdl0C6wrvrUwEqtQ4ZKBKKENpqIUyk= github.com/hashicorp/serf v0.9.6/go.mod h1:TXZNMjZQijwlDvp+r0b63xZ45H7JmCmgg4gpTwn9UV4= -github.com/huandu/xstrings v1.3.3 h1:/Gcsuc1x8JVbJ9/rlye4xZnVAbEkGauT8lbebqcQws4= -github.com/huandu/xstrings v1.3.3/go.mod h1:y5/lhBue+AyNmUVz9RLU9xbLR0o4KIIExikq4ovT0aE= +github.com/huandu/xstrings v1.5.0 h1:2ag3IFq9ZDANvthTwTiqSSZLjDc+BedvHPAp5tJy2TI= +github.com/huandu/xstrings v1.5.0/go.mod h1:y5/lhBue+AyNmUVz9RLU9xbLR0o4KIIExikq4ovT0aE= github.com/iancoleman/orderedmap v0.0.0-20190318233801-ac98e3ecb4b0 h1:i462o439ZjprVSFSZLZxcsoAe592sZB1rci2Z8j4wdk= github.com/iancoleman/orderedmap v0.0.0-20190318233801-ac98e3ecb4b0/go.mod h1:N0Wam8K1arqPXNWjMo21EXnBPOPp36vB07FNRdD2geA= github.com/iancoleman/strcase v0.2.0/go.mod h1:iwCmte+B7n89clKwxIoIXy/HfoL7AsD47ZCWhYzw7ho= @@ -473,9 +472,6 @@ github.com/iancoleman/strcase v0.3.0/go.mod h1:iwCmte+B7n89clKwxIoIXy/HfoL7AsD47 github.com/ianlancetaylor/demangle v0.0.0-20181102032728-5e5cf60278f6/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc= github.com/ianlancetaylor/demangle v0.0.0-20200824232613-28f6c0f3b639/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc= github.com/ianlancetaylor/demangle v0.0.0-20210905161508-09a460cdf81d/go.mod h1:aYm2/VgdVmcIU8iMfdMvDMsRAQjcfZSKFby6HOFvi/w= -github.com/imdario/mergo v0.3.11/go.mod h1:jmQim1M+e3UYxmgPu/WyfjB3N3VflVyUjjjwH0dnCYA= -github.com/imdario/mergo v0.3.15 h1:M8XP7IuFNsqUx6VPK2P9OSmsYsI/YFaGil0uD21V3dM= -github.com/imdario/mergo v0.3.15/go.mod h1:WBLT9ZmE3lPoWsEzCh9LPo3TiwVN+ZKEjmz+hD27ysY= github.com/inconshreveable/mousetrap v1.0.0/go.mod h1:PxqpIevigyE2G7u3NXJIT2ANytuPF1OarO4DADm73n8= github.com/inconshreveable/mousetrap v1.1.0 h1:wN+x4NVGpMsO7ErUn/mUI3vEoE6Jt13X2s0bqwp9tc8= github.com/inconshreveable/mousetrap v1.1.0/go.mod h1:vpF70FUmC8bwa3OWnCshd2FqLfsEA9PFc4w1p2J65bw= @@ -563,7 +559,6 @@ github.com/miekg/dns v1.0.14/go.mod h1:W1PPwlIAgtquWBMBEV9nkV9Cazfe8ScdGz/Lj7v3N github.com/miekg/dns v1.1.26/go.mod h1:bPDLeHnStXmXAq1m/Ch/hvfNHr14JKNPMBo3VZKjuso= github.com/miekg/dns v1.1.41/go.mod h1:p6aan82bvRIyn+zDIv9xYNUpwa73JcSh9BKwknJysuI= github.com/mitchellh/cli v1.1.0/go.mod h1:xcISNoH86gajksDmfB23e/pu+B+GeFRMYmoHXxx3xhI= -github.com/mitchellh/copystructure v1.0.0/go.mod h1:SNtv71yrdKgLRyLFxmLdkAbkKEFWgYaq1OVrnRcwhnw= github.com/mitchellh/copystructure v1.2.0 h1:vpKXTN4ewci03Vljg/q9QvCGUDttBOGBIa15WveJJGw= github.com/mitchellh/copystructure v1.2.0/go.mod h1:qLl+cE2AmVv+CoeAwDPye/v+N2HKCj9FbZEVFJRxO9s= github.com/mitchellh/go-homedir v1.1.0 h1:lukF9ziXFxDFPkA1vsr5zpc1XuPDn/wFntq5mG+4E0Y= @@ -576,7 +571,6 @@ github.com/mitchellh/mapstructure v1.1.2/go.mod h1:FVVH3fgwuzCH5S8UJGiWEs2h04kUh github.com/mitchellh/mapstructure v1.4.3/go.mod h1:bFUtVrKA4DC2yAKiSyO/QUcy7e+RRV2QTWOzhPopBRo= github.com/mitchellh/mapstructure v1.5.0 h1:jeMsZIYE/09sWLaz43PL7Gy6RuMjD2eJVyuac5Z2hdY= github.com/mitchellh/mapstructure v1.5.0/go.mod h1:bFUtVrKA4DC2yAKiSyO/QUcy7e+RRV2QTWOzhPopBRo= -github.com/mitchellh/reflectwalk v1.0.0/go.mod h1:mSTlrgnPZtwu0c4WaC2kGObEpuNDbx0jmZXqmk4esnw= github.com/mitchellh/reflectwalk v1.0.2 h1:G2LzWKi524PWgd3mLHV8Y5k7s6XUvT0Gef6zxSIeXaQ= github.com/mitchellh/reflectwalk v1.0.2/go.mod h1:mSTlrgnPZtwu0c4WaC2kGObEpuNDbx0jmZXqmk4esnw= github.com/moby/docker-image-spec v1.3.1 h1:jMKff3w6PgbfSa69GfNg+zN/XLhfXJGnEx3Nl2EsFP0= @@ -707,8 +701,8 @@ github.com/sergi/go-diff v1.1.0/go.mod h1:STckp+ISIX8hZLjrqAeVduY0gWCT9IjLuqbuNX github.com/sergi/go-diff v1.2.0/go.mod h1:STckp+ISIX8hZLjrqAeVduY0gWCT9IjLuqbuNXdaHfM= github.com/sergi/go-diff v1.3.2-0.20230802210424-5b0b94c5c0d3 h1:n661drycOFuPLCN3Uc8sB6B/s6Z4t2xvBgU1htSHuq8= github.com/sergi/go-diff v1.3.2-0.20230802210424-5b0b94c5c0d3/go.mod h1:A0bzQcvG0E7Rwjx0REVgAGH58e96+X0MeOfepqsbeW4= -github.com/shopspring/decimal v1.2.0 h1:abSATXmQEYyShuxI4/vyW3tV1MrKAJzCZ/0zLUXYbsQ= -github.com/shopspring/decimal v1.2.0/go.mod h1:DKyhrW/HYNuLGql+MJL6WCR6knT2jwCFRcu2hWCYk4o= +github.com/shopspring/decimal v1.4.0 h1:bxl37RwXBklmTi0C79JfXCEBD1cqqHt0bbgBAGFp81k= +github.com/shopspring/decimal v1.4.0/go.mod h1:gawqmDU56v4yIKSwfBSFip1HdCCXN8/+DMd9qYNcwME= github.com/shurcooL/sanitized_anchor_name v1.0.0/go.mod h1:1NzhyTcUVG4SuEtjjoZeVRXNmyL/1OwPU0+IJeTBvfc= github.com/sirupsen/logrus v1.2.0/go.mod h1:LxeOpSwHxABJmUn/MG1IvRgCAasNZTLOkJPxbbu5VWo= github.com/sirupsen/logrus v1.4.2/go.mod h1:tLMulIdttU9McNUspp0xgXVQah82FyeX6MwdIuYE2rE= @@ -729,10 +723,9 @@ github.com/spf13/afero v1.3.3/go.mod h1:5KUK8ByomD5Ti5Artl0RtHeI5pTF7MIDuXL3yY52 github.com/spf13/afero v1.6.0/go.mod h1:Ai8FlHk4v/PARR026UzYexafAt9roJ7LcLMAmO6Z93I= github.com/spf13/afero v1.11.0 h1:WJQKhtpdm3v2IzqG8VMqrr6Rf3UYpEF239Jy9wNepM8= github.com/spf13/afero v1.11.0/go.mod h1:GH9Y3pIexgf1MTIWtNGyogA5MwRIDXGUr+hbWNoBjkY= -github.com/spf13/cast v1.3.1/go.mod h1:Qx5cxh0v+4UWYiBimWS+eyWzqEqokIECu5etghLkUJE= github.com/spf13/cast v1.4.1/go.mod h1:Qx5cxh0v+4UWYiBimWS+eyWzqEqokIECu5etghLkUJE= -github.com/spf13/cast v1.6.0 h1:GEiTHELF+vaR5dhz3VqZfFSzZjYbgeKDpBxQVS4GYJ0= -github.com/spf13/cast v1.6.0/go.mod h1:ancEpBxwJDODSW/UG4rDrAqiKolqNNh2DX3mk86cAdo= +github.com/spf13/cast v1.7.0 h1:ntdiHjuueXFgm5nzDRdOS4yfT43P5Fnud6DH50rz/7w= +github.com/spf13/cast v1.7.0/go.mod h1:ancEpBxwJDODSW/UG4rDrAqiKolqNNh2DX3mk86cAdo= github.com/spf13/cobra v1.3.0/go.mod h1:BrRVncBjOJa/eUcVVm9CE+oC6as8k+VYr4NY7WCi9V4= github.com/spf13/cobra v1.8.1 h1:e5/vxKd/rZsfSJMUX1agtjeTDf+qv1/JdBF8gg5k9ZM= github.com/spf13/cobra v1.8.1/go.mod h1:wHxEcudfqmLYa8iTfL+OuZPbBZkmvliBWKIezN3kD9Y= @@ -871,7 +864,6 @@ golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPh golang.org/x/crypto v0.0.0-20210817164053-32db794688a5/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= golang.org/x/crypto v0.0.0-20220622213112-05595931fe9d/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4= -golang.org/x/crypto v0.3.0/go.mod h1:hebNnKkNXi2UzZN1eVRvBB7co0a+JxK6XbPiWVs/3J4= golang.org/x/crypto v0.3.1-0.20221117191849-2c476679df9a/go.mod h1:hebNnKkNXi2UzZN1eVRvBB7co0a+JxK6XbPiWVs/3J4= golang.org/x/crypto v0.7.0/go.mod h1:pYwdfH91IfpZVANVyUOhSIPZaFoJGxTFbZhFTx+dXZU= golang.org/x/crypto v0.26.0 h1:RrRspgV4mU+YwB4FYnuBoKsUapNIL5cohGAmSH3azsw= @@ -1340,7 +1332,6 @@ gopkg.in/yaml.v2 v2.2.3/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v2 v2.2.4/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v2 v2.2.5/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v2 v2.2.8/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= -gopkg.in/yaml.v2 v2.3.0/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ= gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= From a3438256856d372d94a8f13c651dded916e5c56d Mon Sep 17 00:00:00 2001 From: witchcraze <67056980+witchcraze@users.noreply.github.com> Date: Fri, 6 Sep 2024 03:52:19 +0900 Subject: [PATCH 105/122] fix: haproxy classifier for versions with -dev suffix (#3180) Signed-off-by: witchcraze --- .../cataloger/binary/classifier_cataloger_test.go | 12 +++++++++++- syft/pkg/cataloger/binary/classifiers.go | 4 ++-- .../snippets/haproxy/3.1-dev0/linux-amd64/haproxy | Bin 0 -> 351 bytes .../cataloger/binary/test-fixtures/config.yaml | 7 +++++++ 4 files changed, 20 insertions(+), 3 deletions(-) create mode 100644 syft/pkg/cataloger/binary/test-fixtures/classifiers/snippets/haproxy/3.1-dev0/linux-amd64/haproxy diff --git a/syft/pkg/cataloger/binary/classifier_cataloger_test.go b/syft/pkg/cataloger/binary/classifier_cataloger_test.go index 721ee9ee045..4e283a56a1e 100644 --- a/syft/pkg/cataloger/binary/classifier_cataloger_test.go +++ b/syft/pkg/cataloger/binary/classifier_cataloger_test.go @@ -359,7 +359,17 @@ func Test_Cataloger_PositiveCases(t *testing.T) { Metadata: metadata("haproxy-binary"), }, }, - + { + logicalFixture: "haproxy/3.1-dev0/linux-amd64", + expected: pkg.Package{ + Name: "haproxy", + Version: "3.1-dev0", + Type: "binary", + PURL: "pkg:generic/haproxy@3.1-dev0", + Locations: locations("haproxy"), + Metadata: metadata("haproxy-binary"), + }, + }, { logicalFixture: "helm/3.11.1/linux-amd64", expected: pkg.Package{ diff --git a/syft/pkg/cataloger/binary/classifiers.go b/syft/pkg/cataloger/binary/classifiers.go index 24c514c7e45..46afa87f5cb 100644 --- a/syft/pkg/cataloger/binary/classifiers.go +++ b/syft/pkg/cataloger/binary/classifiers.go @@ -190,8 +190,8 @@ func DefaultClassifiers() []Classifier { Class: "haproxy-binary", FileGlob: "**/haproxy", EvidenceMatcher: evidenceMatchers( - FileContentsVersionMatcher(`(?m)HA-Proxy version (?P[0-9]+\.[0-9]+\.[0-9]+)`), - FileContentsVersionMatcher(`(?m)(?P[0-9]+\.[0-9]+\.[0-9]+)-[0-9a-zA-Z]{7}.+HAProxy version`), + FileContentsVersionMatcher(`(?m)HA-Proxy version (?P[0-9]+\.[0-9]+(\.|-dev)[0-9]+)`), + FileContentsVersionMatcher(`(?m)(?P[0-9]+\.[0-9]+(\.|-dev)[0-9]+)-[0-9a-zA-Z]{7}.+HAProxy version`), ), Package: "haproxy", PURL: mustPURL("pkg:generic/haproxy@version"), diff --git a/syft/pkg/cataloger/binary/test-fixtures/classifiers/snippets/haproxy/3.1-dev0/linux-amd64/haproxy b/syft/pkg/cataloger/binary/test-fixtures/classifiers/snippets/haproxy/3.1-dev0/linux-amd64/haproxy new file mode 100644 index 0000000000000000000000000000000000000000..94a91b1ad84b87e6746984d2de620782f99345f9 GIT binary patch literal 351 zcmYLFF>b>!49u*lPY~cajYL_pk{mJu6iv*js$YUSERIq;50;z)4x zXKH!pr%V32v7FLOOUspZt~QnpG`=rg%OwalkNq^!^459Krbt@YfDxQ87_88goYXGX zg^CE|Qez@wsDnl!Aw^Q?h>R5x!AM}KAL!2vl~dLhKZ8od;G0Hj>71g7$|q$!MQ<>g z;whV;oDK%d=0=7HR?C{Ps;W5N7UKJve91iJVaT7nv>3R<0R+@1p-(GcLp{o4q^mee qLXiMA^*_HnzphW=SGvr79(TL>aQ~=(hrV~bKj^LAk)OBzQ^6mkZdh&r literal 0 HcmV?d00001 diff --git a/syft/pkg/cataloger/binary/test-fixtures/config.yaml b/syft/pkg/cataloger/binary/test-fixtures/config.yaml index 15273d33d2f..78d8ba4b8cf 100644 --- a/syft/pkg/cataloger/binary/test-fixtures/config.yaml +++ b/syft/pkg/cataloger/binary/test-fixtures/config.yaml @@ -106,6 +106,13 @@ from-images: paths: - /usr/local/sbin/haproxy + - version: 3.1-dev0 + images: + - ref: haproxy:3.1-dev0@sha256:eba1aac9aa6ea84869bd2ecae79792a934563fd731eddf724eb3b12ef6a9b93f + platform: linux/amd64 + paths: + - /usr/local/sbin/haproxy + - version: 2.4.54 images: - ref: httpd:2.4.54@sha256:c13feaef62bdb03e65e645f47d9780adea5a080c78eb9e4b3c32e861327262b4 From ff0bae67bdaf052b4ac318ba23932651f98709f1 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Thu, 5 Sep 2024 15:05:15 -0400 Subject: [PATCH 106/122] chore(deps): bump golang.org/x/mod from 0.20.0 to 0.21.0 (#3197) Bumps [golang.org/x/mod](https://github.com/golang/mod) from 0.20.0 to 0.21.0. - [Commits](https://github.com/golang/mod/compare/v0.20.0...v0.21.0) --- updated-dependencies: - dependency-name: golang.org/x/mod dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- go.mod | 2 +- go.sum | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/go.mod b/go.mod index 8e6a7ea63dd..7cb63cf530d 100644 --- a/go.mod +++ b/go.mod @@ -78,7 +78,7 @@ require ( github.com/xeipuuv/gojsonschema v1.2.0 github.com/zyedidia/generic v1.2.2-0.20230320175451-4410d2372cb1 go.uber.org/goleak v1.3.0 - golang.org/x/mod v0.20.0 + golang.org/x/mod v0.21.0 golang.org/x/net v0.28.0 gopkg.in/yaml.v3 v3.0.1 modernc.org/sqlite v1.32.0 diff --git a/go.sum b/go.sum index 0cc5381b240..d3dc4b7d916 100644 --- a/go.sum +++ b/go.sum @@ -908,8 +908,8 @@ golang.org/x/mod v0.4.2/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/mod v0.5.0/go.mod h1:5OXOZSfqPIIbmVBIIKWRFfZjPR0E5r58TLhUjH0a2Ro= golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4= golang.org/x/mod v0.8.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs= -golang.org/x/mod v0.20.0 h1:utOm6MM3R3dnawAiJgn0y+xvuYRsm1RKM/4giyfDgV0= -golang.org/x/mod v0.20.0/go.mod h1:hTbmBsO62+eylJbnUtE2MGJUyE7QWk4xUqPFrRgJ+7c= +golang.org/x/mod v0.21.0 h1:vvrHzRwRfVKSiLrG+d4FMl/Qi4ukBCE6kZlTUkDYRT0= +golang.org/x/mod v0.21.0/go.mod h1:6SkKJ3Xj0I0BrPOZoBy3bdMptDDU9oJrpohJ3eWZ1fY= golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20181023162649-9b4f9f5ad519/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= From deabd4115a091e6d411e31b910e45e2309562b09 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Thu, 5 Sep 2024 15:06:23 -0400 Subject: [PATCH 107/122] chore(deps): bump peter-evans/create-pull-request from 7.0.0 to 7.0.1 (#3196) Bumps [peter-evans/create-pull-request](https://github.com/peter-evans/create-pull-request) from 7.0.0 to 7.0.1. - [Release notes](https://github.com/peter-evans/create-pull-request/releases) - [Commits](https://github.com/peter-evans/create-pull-request/compare/4320041ed380b20e97d388d56a7fb4f9b8c20e79...8867c4aba1b742c39f8d0ba35429c2dfa4b6cb20) --- updated-dependencies: - dependency-name: peter-evans/create-pull-request dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- .github/workflows/update-bootstrap-tools.yml | 2 +- .github/workflows/update-cpe-dictionary-index.yml | 2 +- .github/workflows/update-stereoscope-release.yml | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/.github/workflows/update-bootstrap-tools.yml b/.github/workflows/update-bootstrap-tools.yml index 488a2cf5bc2..b07ad4580d7 100644 --- a/.github/workflows/update-bootstrap-tools.yml +++ b/.github/workflows/update-bootstrap-tools.yml @@ -50,7 +50,7 @@ jobs: app_id: ${{ secrets.TOKEN_APP_ID }} private_key: ${{ secrets.TOKEN_APP_PRIVATE_KEY }} - - uses: peter-evans/create-pull-request@4320041ed380b20e97d388d56a7fb4f9b8c20e79 #v7.0.0 + - uses: peter-evans/create-pull-request@8867c4aba1b742c39f8d0ba35429c2dfa4b6cb20 #v7.0.1 with: signoff: true delete-branch: true diff --git a/.github/workflows/update-cpe-dictionary-index.yml b/.github/workflows/update-cpe-dictionary-index.yml index 879298e0689..cec2d939974 100644 --- a/.github/workflows/update-cpe-dictionary-index.yml +++ b/.github/workflows/update-cpe-dictionary-index.yml @@ -33,7 +33,7 @@ jobs: app_id: ${{ secrets.TOKEN_APP_ID }} private_key: ${{ secrets.TOKEN_APP_PRIVATE_KEY }} - - uses: peter-evans/create-pull-request@4320041ed380b20e97d388d56a7fb4f9b8c20e79 #v7.0.0 + - uses: peter-evans/create-pull-request@8867c4aba1b742c39f8d0ba35429c2dfa4b6cb20 #v7.0.1 with: signoff: true delete-branch: true diff --git a/.github/workflows/update-stereoscope-release.yml b/.github/workflows/update-stereoscope-release.yml index 41142261116..1a3e226236b 100644 --- a/.github/workflows/update-stereoscope-release.yml +++ b/.github/workflows/update-stereoscope-release.yml @@ -44,7 +44,7 @@ jobs: app_id: ${{ secrets.TOKEN_APP_ID }} private_key: ${{ secrets.TOKEN_APP_PRIVATE_KEY }} - - uses: peter-evans/create-pull-request@4320041ed380b20e97d388d56a7fb4f9b8c20e79 #v7.0.0 + - uses: peter-evans/create-pull-request@8867c4aba1b742c39f8d0ba35429c2dfa4b6cb20 #v7.0.1 with: signoff: true delete-branch: true From 0a3f513f923932d990bb9567339d9a0e142b0d36 Mon Sep 17 00:00:00 2001 From: Alex Goodman Date: Mon, 9 Sep 2024 11:15:13 -0400 Subject: [PATCH 108/122] Slim down docker cache size (#3190) * slim down docker cache size Signed-off-by: Alex Goodman * remove old centos images Signed-off-by: Alex Goodman * troubleshoot test failure Signed-off-by: Alex Goodman * fix wget version ref Signed-off-by: Alex Goodman * refactor caching mechanisms Signed-off-by: Alex Goodman * add cache cleanup steps Signed-off-by: Alex Goodman * simplify deleting cache Signed-off-by: Alex Goodman * fix first clone issue Signed-off-by: Alex Goodman * add tool dep Signed-off-by: Alex Goodman --------- Signed-off-by: Alex Goodman --- .binny.yaml | 16 + .github/actions/bootstrap/action.yaml | 23 +- .github/scripts/ci-check.sh | 11 - .github/scripts/find_cache_paths.py | 135 +++++++++ .../scripts/fingerprint_docker_fixtures.py | 70 +++++ .github/scripts/labeler.py | 2 + .github/scripts/labeler_test.py | 2 + .github/workflows/release-version-file.yaml | 2 +- .../workflows/test-fixture-cache-publish.yaml | 39 +++ .github/workflows/update-bootstrap-tools.yml | 1 - .github/workflows/validations.yaml | 93 ++---- Makefile | 4 +- Taskfile.yaml | 280 ++++++++++++++---- cmd/syft/internal/test/integration/.gitignore | 1 + .../all_layers_squashed_comparison_test.go | 2 +- .../integration/encode_decode_cycle_test.go | 62 ++-- .../integration/go_compiler_detection_test.go | 4 +- .../test/integration/java_purl_test.go | 13 +- .../integration/package_deduplication_test.go | 76 +++-- .../test/integration/test-fixtures/Makefile | 25 +- .../image-golang-compiler/Dockerfile | 7 +- .../image-java-no-main-package/Dockerfile | 8 +- .../Dockerfile | 10 +- .../extract.py | 69 +++++ .../image-large-apk-data/Dockerfile | 7 +- .../image-mariner-distroless/Dockerfile | 9 +- .../image-owning-package/Dockerfile | 7 +- .../image-photon-all-layers/Dockerfile | 6 +- .../image-sqlite-rpmdb/Dockerfile | 7 +- .../image-suse-all-layers/Dockerfile | 11 +- .../image-test-java-purls/Dockerfile | 19 +- .../image-test-java-purls/extract.py | 69 +++++ .../image-vertical-package-dups/Dockerfile | 29 +- go.mod | 1 + go.sum | 2 + internal/task/executor.go | 2 +- .../executable/test-fixtures/Makefile | 15 + .../executable/test-fixtures/elf/Makefile | 25 +- .../test-fixtures/shared-info/Makefile | 28 +- .../test-fixtures/image-simple/Dockerfile | 4 - .../test-fixtures/image-simple/file-1.txt | 1 - .../test-fixtures/image-simple/file-2.txt | 1 - .../snapshot/TestTextImageEncoder.golden | 4 +- .../cataloger/binary/test-fixtures/.gitignore | 1 - .../cataloger/binary/test-fixtures/Makefile | 31 +- .../traefik/3.0.4/linux-riscv64/traefik | Bin 0 -> 352 bytes .../binary/test-fixtures/config.yaml | 1 + .../elf-test-fixtures/Dockerfile | 19 +- .../image-fedora-32bit/Dockerfile | 2 +- .../image-fedora-64bit/Dockerfile | 2 +- .../internal/config/binary_from_image.go | 8 +- .../internal/config/binary_from_image_test.go | 6 +- .../manager/internal/download_from_image.go | 48 ++- .../internal/download_from_image_test.go | 30 +- .../manager/internal/list_entries.go | 2 +- syft/pkg/cataloger/gentoo/cataloger_test.go | 2 +- .../pkg/app-containers/skopeo-1.5.1/CONTENTS | 0 .../pkg/app-containers/skopeo-1.5.1/LICENSE | 0 .../db/pkg/app-containers/skopeo-1.5.1/SIZE | 0 .../cataloger/golang/test-fixtures/Makefile | 15 + .../golang/test-fixtures/archs/Makefile | 32 +- .../golang/test-fixtures/archs/src/build.sh | 5 +- .../pkg/cataloger/java/test-fixtures/Makefile | 15 + .../java/test-fixtures/jar-metadata/Makefile | 50 +++- .../java/test-fixtures/java-builds/Makefile | 29 +- .../cataloger/kernel/test-fixtures/Makefile | 26 +- .../image-multi-site-package/Dockerfile | 19 +- .../cataloger/redhat/test-fixtures/Makefile | 39 ++- .../test-fixtures/image-minimal/Dockerfile | 6 +- test/cli/.gitignore | 1 + test/cli/cyclonedx_valid_test.go | 2 +- test/cli/scan_cmd_test.go | 50 +++- test/cli/test-fixtures/Makefile | 26 +- .../image-hidden-packages/Dockerfile | 8 +- test/install/Makefile | 13 +- 75 files changed, 1305 insertions(+), 385 deletions(-) delete mode 100755 .github/scripts/ci-check.sh create mode 100755 .github/scripts/find_cache_paths.py create mode 100755 .github/scripts/fingerprint_docker_fixtures.py mode change 100644 => 100755 .github/scripts/labeler.py mode change 100644 => 100755 .github/scripts/labeler_test.py create mode 100644 .github/workflows/test-fixture-cache-publish.yaml create mode 100644 cmd/syft/internal/test/integration/.gitignore create mode 100644 cmd/syft/internal/test/integration/test-fixtures/image-java-virtualpath-regression/extract.py create mode 100644 cmd/syft/internal/test/integration/test-fixtures/image-test-java-purls/extract.py create mode 100644 syft/file/cataloger/executable/test-fixtures/Makefile delete mode 100644 syft/format/text/test-fixtures/image-simple/Dockerfile delete mode 100644 syft/format/text/test-fixtures/image-simple/file-1.txt delete mode 100644 syft/format/text/test-fixtures/image-simple/file-2.txt create mode 100644 syft/pkg/cataloger/binary/test-fixtures/classifiers/snippets/traefik/3.0.4/linux-riscv64/traefik rename syft/pkg/cataloger/gentoo/test-fixtures/{image-portage => layout}/var/db/pkg/app-containers/skopeo-1.5.1/CONTENTS (100%) rename syft/pkg/cataloger/gentoo/test-fixtures/{image-portage => layout}/var/db/pkg/app-containers/skopeo-1.5.1/LICENSE (100%) rename syft/pkg/cataloger/gentoo/test-fixtures/{image-portage => layout}/var/db/pkg/app-containers/skopeo-1.5.1/SIZE (100%) create mode 100644 syft/pkg/cataloger/golang/test-fixtures/Makefile create mode 100644 syft/pkg/cataloger/java/test-fixtures/Makefile create mode 100644 test/cli/.gitignore diff --git a/.binny.yaml b/.binny.yaml index a9a37439333..cab909d2941 100644 --- a/.binny.yaml +++ b/.binny.yaml @@ -115,3 +115,19 @@ tools: method: github-release with: repo: cli/cli + + # used to upload test fixture cache + - name: oras + version: + want: v1.2.0 + method: github-release + with: + repo: oras-project/oras + + # used to upload test fixture cache + - name: yq + version: + want: v4.44.3 + method: github-release + with: + repo: mikefarah/yq \ No newline at end of file diff --git a/.github/actions/bootstrap/action.yaml b/.github/actions/bootstrap/action.yaml index bc771d3b508..6150113aee0 100644 --- a/.github/actions/bootstrap/action.yaml +++ b/.github/actions/bootstrap/action.yaml @@ -13,16 +13,15 @@ inputs: cache-key-prefix: description: "Prefix all cache keys with this value" required: true - default: "1ac8281053" - compute-fingerprints: - description: "Compute test fixture fingerprints" + default: "181053ac82" + download-test-fixture-cache: + description: "Download test fixture cache from OCI and github actions" required: true - default: "true" + default: "false" bootstrap-apt-packages: description: "Space delimited list of tools to install via apt" default: "libxml2-utils" - runs: using: "composite" steps: @@ -54,8 +53,14 @@ runs: run: | DEBIAN_FRONTEND=noninteractive sudo apt update && sudo -E apt install -y ${{ inputs.bootstrap-apt-packages }} - - name: Create all cache fingerprints - if: inputs.compute-fingerprints == 'true' - shell: bash - run: make fingerprints + - name: Restore ORAS cache from github actions + if: inputs.download-test-fixture-cache == 'true' + uses: actions/cache@704facf57e6136b1bc63b828d79edcd491f0ee84 # v3.3.2 + with: + path: ${{ github.workspace }}/.tmp/oras-cache + key: ${{ inputs.cache-key-prefix }}-oras-cache + - name: Download test fixture cache + if: inputs.download-test-fixture-cache == 'true' + shell: bash + run: make download-test-fixture-cache diff --git a/.github/scripts/ci-check.sh b/.github/scripts/ci-check.sh deleted file mode 100755 index 0ab83a318ae..00000000000 --- a/.github/scripts/ci-check.sh +++ /dev/null @@ -1,11 +0,0 @@ -#!/usr/bin/env bash - -red=$(tput setaf 1) -bold=$(tput bold) -normal=$(tput sgr0) - -# assert we are running in CI (or die!) -if [[ -z "$CI" ]]; then - echo "${bold}${red}This step should ONLY be run in CI. Exiting...${normal}" - exit 1 -fi diff --git a/.github/scripts/find_cache_paths.py b/.github/scripts/find_cache_paths.py new file mode 100755 index 00000000000..cc2e4081af1 --- /dev/null +++ b/.github/scripts/find_cache_paths.py @@ -0,0 +1,135 @@ +#!/usr/bin/env python3 +from __future__ import annotations + +import os +import glob +import sys +import json +import hashlib + + +IGNORED_PREFIXES = [] + + +def find_fingerprints_and_check_dirs(base_dir): + all_fingerprints = set(glob.glob(os.path.join(base_dir, '**', 'test*', '**', '*.fingerprint'), recursive=True)) + + all_fingerprints = {os.path.relpath(fp) for fp in all_fingerprints + if not any(fp.startswith(prefix) for prefix in IGNORED_PREFIXES)} + + if not all_fingerprints: + show("No .fingerprint files or cache directories found.") + exit(1) + + missing_content = [] + valid_paths = set() + fingerprint_contents = [] + + for fingerprint in all_fingerprints: + path = fingerprint.replace('.fingerprint', '') + + if not os.path.exists(path): + missing_content.append(path) + continue + + if not os.path.isdir(path): + valid_paths.add(path) + continue + + if os.listdir(path): + valid_paths.add(path) + else: + missing_content.append(path) + + with open(fingerprint, 'r') as f: + content = f.read().strip() + fingerprint_contents.append((fingerprint, content)) + + return sorted(valid_paths), missing_content, fingerprint_contents + + +def parse_fingerprint_contents(fingerprint_content): + input_map = {} + for line in fingerprint_content.splitlines(): + digest, path = line.split() + input_map[path] = digest + return input_map + + +def calculate_sha256(fingerprint_contents): + sorted_fingerprint_contents = sorted(fingerprint_contents, key=lambda x: x[0]) + + concatenated_contents = ''.join(content for _, content in sorted_fingerprint_contents) + + sha256_hash = hashlib.sha256(concatenated_contents.encode()).hexdigest() + + return sha256_hash + + +def calculate_file_sha256(file_path): + sha256_hash = hashlib.sha256() + with open(file_path, 'rb') as f: + for byte_block in iter(lambda: f.read(4096), b""): + sha256_hash.update(byte_block) + return sha256_hash.hexdigest() + + +def show(*s: str): + print(*s, file=sys.stderr) + + +def main(file_path: str | None): + base_dir = '.' + valid_paths, missing_content, fingerprint_contents = find_fingerprints_and_check_dirs(base_dir) + + if missing_content: + show("The following paths are missing or have no content, but have corresponding .fingerprint files:") + for path in sorted(missing_content): + show(f"- {path}") + show("Please ensure these paths exist and have content if they are directories.") + exit(1) + + sha256_hash = calculate_sha256(fingerprint_contents) + + paths_with_digests = [] + for path in sorted(valid_paths): + fingerprint_file = f"{path}.fingerprint" + try: + if os.path.exists(fingerprint_file): + file_digest = calculate_file_sha256(fingerprint_file) + + # Parse the fingerprint file to get the digest/path tuples + with open(fingerprint_file, 'r') as f: + fingerprint_content = f.read().strip() + input_map = parse_fingerprint_contents(fingerprint_content) + + paths_with_digests.append({ + "path": path, + "digest": file_digest, + "input": input_map + }) + + except Exception as e: + show(f"Error processing {fingerprint_file}: {e}") + raise e + + + output = { + "digest": sha256_hash, + "paths": paths_with_digests + } + + content = json.dumps(output, indent=2, sort_keys=True) + + if file_path: + with open(file_path, 'w') as f: + f.write(content) + + print(content) + + +if __name__ == "__main__": + file_path = None + if len(sys.argv) > 1: + file_path = sys.argv[1] + main(file_path) diff --git a/.github/scripts/fingerprint_docker_fixtures.py b/.github/scripts/fingerprint_docker_fixtures.py new file mode 100755 index 00000000000..4a74420e010 --- /dev/null +++ b/.github/scripts/fingerprint_docker_fixtures.py @@ -0,0 +1,70 @@ +#!/usr/bin/env python3 + +import os +import subprocess +import hashlib + +BOLD = '\033[1m' +YELLOW = '\033[0;33m' +RESET = '\033[0m' + + +def print_message(message): + print(f"{YELLOW}{message}{RESET}") + + +def sha256sum(filepath): + h = hashlib.sha256() + with open(filepath, 'rb') as f: + for chunk in iter(lambda: f.read(4096), b""): + h.update(chunk) + return h.hexdigest() + + +def is_git_tracked_or_untracked(directory): + """Returns a sorted list of files in the directory that are tracked or not ignored by Git.""" + result = subprocess.run( + ["git", "ls-files", "--cached", "--others", "--exclude-standard"], + cwd=directory, + stdout=subprocess.PIPE, + text=True + ) + return sorted(result.stdout.strip().splitlines()) + + +def find_test_fixture_dirs_with_images(base_dir): + """Find directories that contain 'test-fixtures' and at least one 'image-*' directory.""" + for root, dirs, files in os.walk(base_dir): + if 'test-fixtures' in root: + image_dirs = [d for d in dirs if d.startswith('image-')] + if image_dirs: + yield os.path.realpath(root) + + +def generate_fingerprints(): + print_message("creating fingerprint files for docker fixtures...") + + for test_fixture_dir in find_test_fixture_dirs_with_images('.'): + cache_fingerprint_path = os.path.join(test_fixture_dir, 'cache.fingerprint') + + with open(cache_fingerprint_path, 'w') as fingerprint_file: + for image_dir in find_image_dirs(test_fixture_dir): + for file in is_git_tracked_or_untracked(image_dir): + file_path = os.path.join(image_dir, file) + checksum = sha256sum(file_path) + path_from_fixture_dir = os.path.relpath(file_path, test_fixture_dir) + fingerprint_file.write(f"{checksum} {path_from_fixture_dir}\n") + + +def find_image_dirs(test_fixture_dir): + """Find all 'image-*' directories inside a given test-fixture directory.""" + result = [] + for root, dirs, files in os.walk(test_fixture_dir): + for dir_name in dirs: + if dir_name.startswith('image-'): + result.append(os.path.join(root, dir_name)) + return sorted(result) + + +if __name__ == "__main__": + generate_fingerprints() diff --git a/.github/scripts/labeler.py b/.github/scripts/labeler.py old mode 100644 new mode 100755 index b33dd6df028..2efd33206c8 --- a/.github/scripts/labeler.py +++ b/.github/scripts/labeler.py @@ -1,3 +1,5 @@ +#!/usr/bin/env python3 + from __future__ import annotations import sys diff --git a/.github/scripts/labeler_test.py b/.github/scripts/labeler_test.py old mode 100644 new mode 100755 index 36eebd18c9f..d792929f106 --- a/.github/scripts/labeler_test.py +++ b/.github/scripts/labeler_test.py @@ -1,3 +1,5 @@ +#!/usr/bin/env python3 + import unittest from unittest.mock import patch import subprocess diff --git a/.github/workflows/release-version-file.yaml b/.github/workflows/release-version-file.yaml index cd41a0c8e91..6635a053f12 100644 --- a/.github/workflows/release-version-file.yaml +++ b/.github/workflows/release-version-file.yaml @@ -1,4 +1,4 @@ -name: "Release" +name: "Release: version file" on: diff --git a/.github/workflows/test-fixture-cache-publish.yaml b/.github/workflows/test-fixture-cache-publish.yaml new file mode 100644 index 00000000000..3144a0b6bc5 --- /dev/null +++ b/.github/workflows/test-fixture-cache-publish.yaml @@ -0,0 +1,39 @@ +name: "Test fixture cache: publish" + +on: + workflow_dispatch: + schedule: + # run nightly at 4AM UTC + - cron: "0 4 * * *" + +permissions: + contents: read + +jobs: + + Publish: + name: "Publish test fixture image cache" + # we use this runner to get enough storage space for docker images and fixture cache + runs-on: ubuntu-22.04-4core-16gb + permissions: + packages: write + steps: + - uses: actions/checkout@692973e3d937129bcbf40652eb9f2f61becf3332 #v4.1.7 + + - name: Bootstrap environment + uses: ./.github/actions/bootstrap + with: + # we want to rebuild the cache with no previous state + download-test-fixture-cache: false + + - name: Run all tests + run: make test + env: + # we want to rebuild the cache with no previous state + DOWNLOAD_TEST_FIXTURE_CACHE: "false" + + - name: Login to GitHub Container Registry (ORAS) + run: echo "${{ secrets.GITHUB_TOKEN }}" | .tool/oras login ghcr.io -u ${{ github.actor }} --password-stdin + + - name: Publish test fixture cache + run: make upload-test-fixture-cache diff --git a/.github/workflows/update-bootstrap-tools.yml b/.github/workflows/update-bootstrap-tools.yml index b07ad4580d7..3cdedf52af4 100644 --- a/.github/workflows/update-bootstrap-tools.yml +++ b/.github/workflows/update-bootstrap-tools.yml @@ -19,7 +19,6 @@ jobs: uses: ./.github/actions/bootstrap with: bootstrap-apt-packages: "" - compute-fingerprints: "false" go-dependencies: false - name: "Update tool versions" diff --git a/.github/workflows/validations.yaml b/.github/workflows/validations.yaml index 669d8b8c5c4..0ebca5c8235 100644 --- a/.github/workflows/validations.yaml +++ b/.github/workflows/validations.yaml @@ -35,48 +35,8 @@ jobs: - name: Bootstrap environment uses: ./.github/actions/bootstrap - - - name: Restore file executable test-fixture cache - uses: actions/cache@0c45773b623bea8c8e75f6c82b208c3cf94ea4f9 #v4.0.2 - with: - path: syft/file/cataloger/executable/test-fixtures/elf/bin - key: ${{ runner.os }}-unit-file-executable-elf-cache-${{ hashFiles( 'syft/file/cataloger/executable/test-fixtures/elf/cache.fingerprint' ) }} - - - name: Restore file executable shared-info test-fixture cache - uses: actions/cache@0c45773b623bea8c8e75f6c82b208c3cf94ea4f9 #v4.0.2 - with: - path: syft/file/cataloger/executable/test-fixtures/shared-info/bin - key: ${{ runner.os }}-unit-file-executable-shared-info-cache-${{ hashFiles( 'syft/file/cataloger/executable/test-fixtures/shared-info/cache.fingerprint' ) }} - - - name: Restore Java test-fixture cache - uses: actions/cache@0c45773b623bea8c8e75f6c82b208c3cf94ea4f9 #v4.0.2 - with: - path: syft/pkg/cataloger/java/test-fixtures/java-builds/packages - key: ${{ runner.os }}-unit-java-cache-${{ hashFiles( 'syft/pkg/cataloger/java/test-fixtures/java-builds/cache.fingerprint' ) }} - - - name: Restore RPM test-fixture cache - uses: actions/cache@0c45773b623bea8c8e75f6c82b208c3cf94ea4f9 #v4.0.2 with: - path: syft/pkg/cataloger/redhat/test-fixtures/rpms - key: ${{ runner.os }}-unit-rpm-cache-${{ hashFiles( 'syft/pkg/cataloger/redhat/test-fixtures/rpms.fingerprint' ) }} - - - name: Restore go binary test-fixture cache - uses: actions/cache@0c45773b623bea8c8e75f6c82b208c3cf94ea4f9 #v4.0.2 - with: - path: syft/pkg/cataloger/golang/test-fixtures/archs/binaries - key: ${{ runner.os }}-unit-go-binaries-cache-${{ hashFiles( 'syft/pkg/cataloger/golang/test-fixtures/archs/binaries.fingerprint' ) }} - - - name: Restore binary cataloger test-fixture cache - uses: actions/cache@0c45773b623bea8c8e75f6c82b208c3cf94ea4f9 #v4.0.2 - with: - path: syft/pkg/cataloger/binary/test-fixtures/classifiers/bin - key: ${{ runner.os }}-unit-binary-cataloger-cache-${{ hashFiles( 'syft/pkg/cataloger/binary/test-fixtures/cache.fingerprint' ) }} - - - name: Restore Kernel test-fixture cache - uses: actions/cache@0c45773b623bea8c8e75f6c82b208c3cf94ea4f9 #v4.0.2 - with: - path: syft/pkg/cataloger/kernel/test-fixtures/cache - key: ${{ runner.os }}-unit-kernel-cache-${{ hashFiles( 'syft/pkg/cataloger/kernel/test-fixtures/cache.fingerprint' ) }} + download-test-fixture-cache: true - name: Run unit tests run: make unit @@ -91,16 +51,12 @@ jobs: - name: Bootstrap environment uses: ./.github/actions/bootstrap + with: + download-test-fixture-cache: true - name: Validate syft output against the CycloneDX schema run: make validate-cyclonedx-schema - - name: Restore integration test cache - uses: actions/cache@0c45773b623bea8c8e75f6c82b208c3cf94ea4f9 #v4.0.2 - with: - path: ${{ github.workspace }}/cmd/syft/internal/test/integration/test-fixtures/cache - key: ${{ runner.os }}-integration-test-cache-${{ hashFiles('/cmd/syft/internal/test/integration/test-fixtures/cache.fingerprint') }} - - name: Run integration tests run: make integration @@ -143,6 +99,8 @@ jobs: - name: Bootstrap environment uses: ./.github/actions/bootstrap + with: + download-test-fixture-cache: true - name: Download snapshot build id: snapshot-cache @@ -162,13 +120,6 @@ jobs: - name: Run comparison tests (Linux) run: make compare-linux - - name: Restore install.sh test image cache - id: install-test-image-cache - uses: actions/cache@0c45773b623bea8c8e75f6c82b208c3cf94ea4f9 #v4.0.2 - with: - path: ${{ github.workspace }}/test/install/cache - key: ${{ runner.os }}-install-test-image-cache-${{ hashFiles('test/install/cache.fingerprint') }} - - name: Load test image cache if: steps.install-test-image-cache.outputs.cache-hit == 'true' run: make install-test-cache-load @@ -196,8 +147,8 @@ jobs: uses: ./.github/actions/bootstrap with: bootstrap-apt-packages: "" - compute-fingerprints: "false" go-dependencies: false + download-test-fixture-cache: true - name: Download snapshot build id: snapshot-cache @@ -214,13 +165,6 @@ jobs: if: steps.snapshot-cache.outputs.cache-hit != 'true' run: echo "unable to download snapshots from previous job" && false - - name: Restore docker image cache for compare testing - id: mac-compare-testing-cache - uses: actions/cache@0c45773b623bea8c8e75f6c82b208c3cf94ea4f9 #v4.0.2 - with: - path: image.tar - key: ${{ runner.os }}-${{ hashFiles('test/compare/mac.sh') }} - - name: Run comparison tests (Mac) run: make compare-mac @@ -238,12 +182,8 @@ jobs: - name: Bootstrap environment uses: ./.github/actions/bootstrap - - - name: Restore CLI test-fixture cache - uses: actions/cache@0c45773b623bea8c8e75f6c82b208c3cf94ea4f9 #v4.0.2 with: - path: ${{ github.workspace }}/test/cli/test-fixtures/cache - key: ${{ runner.os }}-cli-test-cache-${{ hashFiles('test/cli/test-fixtures/cache.fingerprint') }} + download-test-fixture-cache: true - name: Download snapshot build id: snapshot-cache @@ -262,3 +202,22 @@ jobs: - name: Run CLI Tests (Linux) run: make cli + + + Cleanup-Cache: + name: "Cleanup snapshot cache" + if: always() + runs-on: ubuntu-20.04 + permissions: + actions: write + needs: + - Acceptance-Linux + - Acceptance-Mac + - Cli-Linux + steps: + - uses: actions/checkout@692973e3d937129bcbf40652eb9f2f61becf3332 #v4.1.7 + + - name: Delete snapshot cache + run: gh cache delete "snapshot-build-${{ github.run_id }}" + env: + GH_TOKEN: ${{ github.token }} diff --git a/Makefile b/Makefile index 9089ee6192c..2f1ae1f8e5b 100644 --- a/Makefile +++ b/Makefile @@ -25,8 +25,8 @@ ci-bootstrap-go: # this is a bootstrapping catch-all, where if the target doesn't exist, we'll ensure the tools are installed and then try again %: - make $(TASK) - $(TASK) $@ + @make --silent $(TASK) + @$(TASK) $@ ## Shim targets ################################# diff --git a/Taskfile.yaml b/Taskfile.yaml index c0a8bc33402..feb12f636ec 100644 --- a/Taskfile.yaml +++ b/Taskfile.yaml @@ -4,9 +4,19 @@ vars: OWNER: anchore PROJECT: syft + CACHE_IMAGE: ghcr.io/{{ .OWNER }}/{{ .PROJECT }}/test-fixture-cache:latest + # static file dirs TOOL_DIR: .tool TMP_DIR: .tmp + ORAS_CACHE: "{{ .TMP_DIR }}/oras-cache" + CACHE_PATHS_FILE: "{{ .TMP_DIR }}/cache_paths.json" + LAST_CACHE_PULL_FILE: "{{ .TMP_DIR }}/last_cache_paths.json" + + # TOOLS + ORAS: "{{ .TOOL_DIR }}/oras" + YQ: "{{ .TOOL_DIR }}/yq" + TASK: "{{ .TOOL_DIR }}/task" # used for changelog generation CHANGELOG: CHANGELOG.md @@ -33,6 +43,9 @@ vars: COMPARE_DIR: ./test/compare COMPARE_TEST_IMAGE: centos:8.2.2004 +env: + GNUMAKEFLAGS: '--no-print-directory' + tasks: ## High-level tasks ################################# @@ -65,6 +78,7 @@ tasks: - task: benchmark - task: test-utils - task: cli + - task: check-docker-cache ## Bootstrap tasks ################################# @@ -212,10 +226,6 @@ tasks: # that the cache being restored with the correct binary will be rebuilt since the timestamps # and local checksums will not line up. deps: [tools, snapshot] - sources: - - "{{ .SNAPSHOT_BIN }}" - - ./test/cli/** - - ./**/*.go cmds: - cmd: "echo 'testing binary: {{ .SNAPSHOT_BIN }}'" silent: true @@ -229,18 +239,14 @@ tasks: test-utils: desc: Run tests for pipeline utils - sources: - - .github/scripts/labeler*.py cmds: - - cmd: python .github/scripts/labeler_test.py + - cmd: .github/scripts/labeler_test.py ## Benchmark test targets ################################# benchmark: deps: [tmpdir] - sources: - - ./**/*.go generates: - "{{ .TMP_DIR }}/benchmark-main.txt" cmds: @@ -253,8 +259,6 @@ tasks: show-benchstat: deps: [benchmark, tmpdir] - sources: - - "{{ .TMP_DIR }}/benchstat.txt" cmds: - cmd: "cat {{ .TMP_DIR }}/benchstat.txt" silent: true @@ -263,56 +267,188 @@ tasks: ## Test-fixture-related targets ################################# fingerprints: - desc: Generate test fixture fingerprints + desc: Generate fingerprints for all non-docker test fixture + silent: true + # this will look for `test-fixtures/Makefile` and invoke the `fingerprint` target to calculate all cache input fingerprint files generates: - - cmd/syft/internal/test/integration/test-fixtures/cache.fingerprint - - syft/file/cataloger/executable/test-fixtures/elf/cache.fingerprint - - syft/file/cataloger/executable/test-fixtures/shared-info/cache.fingerprint - - syft/pkg/cataloger/binary/test-fixtures/cache.fingerprint - - syft/pkg/cataloger/java/test-fixtures/java-builds/cache.fingerprint - - syft/pkg/cataloger/golang/test-fixtures/archs/binaries.fingerprint - - syft/pkg/cataloger/redhat/test-fixtures/rpms.fingerprint - - syft/pkg/cataloger/kernel/test-fixtures/cache.fingerprint + - '**/test-fixtures/**/*.fingerprint' - test/install/cache.fingerprint - - test/cli/test-fixtures/cache.fingerprint - cmds: - # for EXECUTABLE unit test fixtures - - "cd syft/file/cataloger/executable/test-fixtures/elf && make cache.fingerprint" - - "cd syft/file/cataloger/executable/test-fixtures/shared-info && make cache.fingerprint" - # for IMAGE integration test fixtures - - "cd cmd/syft/internal/test/integration/test-fixtures && make cache.fingerprint" - # for BINARY unit test fixtures - - "cd syft/pkg/cataloger/binary/test-fixtures && make cache.fingerprint" - # for JAVA BUILD unit test fixtures - - "cd syft/pkg/cataloger/java/test-fixtures/java-builds && make cache.fingerprint" - # for GO BINARY unit test fixtures - - "cd syft/pkg/cataloger/golang/test-fixtures/archs && make binaries.fingerprint" - # for RPM unit test fixtures - - "cd syft/pkg/cataloger/redhat/test-fixtures && make rpms.fingerprint" - # for Kernel unit test fixtures - - "cd syft/pkg/cataloger/kernel/test-fixtures && make cache.fingerprint" - # for INSTALL test fixtures - - "cd test/install && make cache.fingerprint" - # for CLI test fixtures - - "cd test/cli/test-fixtures && make cache.fingerprint" - - fixtures: - desc: Generate test fixtures - cmds: - - "cd syft/file/cataloger/executable/test-fixtures/elf && make" - - "cd syft/file/cataloger/executable/test-fixtures/shared-info && make" - - "cd syft/pkg/cataloger/java/test-fixtures/java-builds && make" - - "cd syft/pkg/cataloger/redhat/test-fixtures && make" - - "cd syft/pkg/cataloger/binary/test-fixtures && make" + cmds: + - | + BOLD='\033[1m' + YELLOW='\033[0;33m' + RESET='\033[0m' + + echo -e "${YELLOW}creating fingerprint files for non-docker fixtures...${RESET}" + for dir in $(find . -type d -name 'test-fixtures'); do + if [ -f "$dir/Makefile" ]; then + # for debugging... + #echo -e "${YELLOW}â€ĸ calculating fingerprints in $dir... ${RESET}" + + (make -C "$dir" fingerprint) + fi + done + + # for debugging... + # echo -e "generated all fixture fingerprints" + + - .github/scripts/fingerprint_docker_fixtures.py + - | + # if DOWNLOAD_TEST_FIXTURE_CACHE is set to 'false', then we don't need to calculate the fingerprint for the cache + if [ "$DOWNLOAD_TEST_FIXTURE_CACHE" = "false" ]; then + exit 0 + fi + .github/scripts/find_cache_paths.py {{ .CACHE_PATHS_FILE }} > /dev/null + + + refresh-fixtures: + desc: Clear and fetch all test fixture cache + aliases: + - fixtures + silent: true + deps: + - tools + cmds: + - | + BOLD='\033[1m' + PURPLE='\033[0;35m' + RESET='\033[0m' + + # if DOWNLOAD_TEST_FIXTURE_CACHE is set to 'false', then skip the cache download and always build + if [ "$DOWNLOAD_TEST_FIXTURE_CACHE" = "false" ]; then + echo -e "${BOLD}${PURPLE}skipping cache download, rebuilding cache...${RESET}" + {{ .TASK }} build-fixtures + exit 0 + fi + + LATEST_FINGERPRINT=$(docker manifest inspect {{ .CACHE_IMAGE }} | {{ .YQ }} -r '.annotations.fingerprint') + + echo "latest cache: $LATEST_FINGERPRINT" + + if [ -f {{ .LAST_CACHE_PULL_FILE }} ]; then + LAST_PULL_FINGERPRINT=$(cat {{ .LAST_CACHE_PULL_FILE }} | {{ .YQ }} -r '.digest') + else + echo -e "${BOLD}${PURPLE}empty cache, downloading cache...${RESET}" + {{ .TASK }} download-test-fixture-cache + exit 0 + fi + + {{ .TASK }} fingerprints + + WANT_FINGERPRINT=$(cat {{ .CACHE_PATHS_FILE }} | {{ .YQ }} -r '.digest') + + echo "desired cache: $WANT_FINGERPRINT" + echo "last pulled cache: $LAST_PULL_FINGERPRINT" + + # if we already have the latest cache, skip the refresh + if [ "$LAST_PULL_FINGERPRINT" = "$WANT_FINGERPRINT" ]; then + echo -e "${BOLD}${PURPLE}already have the latest cache (skipping cache download)${RESET}" + exit 0 + fi + + # at this point we only refresh the cache if we want the same cache that is currently available. + # we don't by default refresh the cache if the cache if it is simply different from what we have, + # because we may be working on a code change that doesn't require a cache refresh (but could trigger one, + # which would be annoying to deal with in a development workflow). + + if [ "$LATEST_FINGERPRINT" = "$WANT_FINGERPRINT" ]; then + echo -e "${BOLD}${PURPLE}found newer cache! downloading cache...${RESET}" + {{ .TASK }} download-test-fixture-cache + else + echo -e "${BOLD}${PURPLE}found different cache, but isn't clear if it's newer (skipping cache download and manually building)${RESET}" + + {{ .YQ }} eval '.paths[] | "\(.digest) \(.path)"' {{ .LAST_CACHE_PULL_FILE }} > .tmp/last_cache_lines + {{ .YQ }} eval '.paths[] | "\(.digest) \(.path)"' {{ .CACHE_PATHS_FILE }} > .tmp/cache_lines + diff .tmp/last_cache_lines .tmp/cache_lines || true + + echo -e "${BOLD}${PURPLE}diff with more context...${RESET}" + + diff -U10000 {{ .LAST_CACHE_PULL_FILE }} {{ .CACHE_PATHS_FILE }} || true + + echo -e "${BOLD}${PURPLE}detected changes to input material, manually building fixtures...${RESET}" + + {{ .TASK }} build-fixtures + fi + + build-fixtures: + desc: Generate all non-docker test fixtures + silent: true + # this will look for `test-fixtures/Makefile` and invoke the `fixtures` target to generate any and all test fixtures + cmds: + - | + BOLD='\033[1m' + YELLOW='\033[0;33m' + RESET='\033[0m' + + # Use a for loop with command substitution to avoid subshell issues + for dir in $(find . -type d -name 'test-fixtures'); do + if [ -f "$dir/Makefile" ]; then + echo -e "${YELLOW}${BOLD}generating fixtures in $dir${RESET}" + (make -C "$dir" fixtures) + fi + done + echo -e "${BOLD}generated all fixtures${RESET}" + + download-test-fixture-cache: + desc: Download test fixture cache from ghcr.io + deps: [tools, clean-cache] + vars: + CACHE_DIGEST: + sh: docker manifest inspect {{ .CACHE_IMAGE }} | {{ .YQ }} -r '.annotations.fingerprint' + cmds: + - silent: true + cmd: | + # if oras cache is > 4 GB, delete it + if [ -d {{ .ORAS_CACHE }} ]; then + total_size=$(du -c {{ .ORAS_CACHE }} | grep total | awk '{print $1}') + if [ "$total_size" -gt 4194304 ]; then + echo 'deleting oras cache' + rm -rf {{ .ORAS_CACHE }} + fi + fi + - "ORAS_CACHE={{ .ORAS_CACHE }} {{ .ORAS }} pull {{ .CACHE_IMAGE }}" + - "cp {{ .CACHE_PATHS_FILE }} {{ .LAST_CACHE_PULL_FILE }}" + + upload-test-fixture-cache: + desc: Upload the test fixture cache to ghcr.io + deps: [tools, fingerprints] + silent: true + cmd: | + set -eu + oras_command="{{ .ORAS }} push {{ .CACHE_IMAGE }}" + + paths=$(cat {{ .CACHE_PATHS_FILE }} | {{ .YQ }} -r '.paths[].path') + for path in $paths; do + oras_command+=" $path" + done + oras_command+=" {{ .CACHE_PATHS_FILE }}" + + oras_command+=" --annotation org.opencontainers.image.source=https://github.com/{{ .OWNER }}/{{ .PROJECT }}" + oras_command+=" --annotation fingerprint=$(cat {{ .CACHE_PATHS_FILE }} | {{ .YQ }} -r '.digest')" + + echo "Executing: $oras_command" + eval $oras_command show-test-image-cache: silent: true cmds: - - "echo '\nDocker daemon cache:'" + - "echo 'Docker daemon cache:'" - "docker images --format '{{`{{.ID}}`}} {{`{{.Repository}}`}}:{{`{{.Tag}}`}}' | grep stereoscope-fixture- | sort" - "echo '\nTar cache:'" - - 'find . -type f -wholename "**/test-fixtures/snapshot/*" | sort' + - 'find . -type f -wholename "**/test-fixtures/cache/stereoscope-fixture-*.tar" | sort' + check-docker-cache: + desc: Ensure docker caches aren't using too much disk space + silent: true + cmd: | + total_size=$(find . | grep cache | grep tar | xargs du -c | grep total | awk '{print $1}') + find . | grep cache | grep tar | xargs du + echo "total $total_size KB" + + if [ "$total_size" -gt 1048576 ]; then + echo 'docker cache is larger than 1GB' + exit 1 + fi ## install.sh testing targets ################################# @@ -457,7 +593,16 @@ tasks: ci-check: # desc: "[CI only] Are you in CI?" cmds: - - cmd: .github/scripts/ci-check.sh + - cmd: | + red=$(tput setaf 1) + bold=$(tput bold) + normal=$(tput sgr0) + + # assert we are running in CI (or die!) + if [[ -z "$CI" ]]; then + echo "${bold}${red}This step should ONLY be run in CI. Exiting...${normal}" + exit 1 + fi silent: true ci-release: @@ -489,8 +634,31 @@ tasks: - "rm -rf {{ .SNAPSHOT_DIR }}" - "rm -rf {{ .TMP_DIR }}/goreleaser.yaml" + clean-docker-cache: + desc: Remove all docker cache tars and images from the daemon + cmds: + - find . -type d -wholename "**/test-fixtures/cache" | xargs rm -rf + - docker images --format '{{`{{.ID}}`}} {{`{{.Repository}}`}}' | grep stereoscope-fixture- | awk '{print $1}' | uniq | xargs -r docker rmi --force + + clean-oras-cache: + desc: Remove all cache for oras commands + cmd: rm -rf {{ .ORAS_CACHE }} + clean-cache: - desc: Remove all docker cache and local image tar cache + desc: Remove all image docker tar cache, images from the docker daemon, and ephemeral test fixtures cmds: - - 'find . -type f -wholename "**/test-fixtures/cache/stereoscope-fixture-*.tar" -delete' - - "docker images --format '{{`{{.ID}}`}} {{`{{.Repository}}`}}' | grep stereoscope-fixture- | awk '{print $$1}' | uniq | xargs -r docker rmi --force" + - task: clean-docker-cache + - | + BOLD='\033[1m' + YELLOW='\033[0;33m' + RESET='\033[0m' + + # Use a for loop with command substitution to avoid subshell issues + for dir in $(find . -type d -name 'test-fixtures'); do + if [ -f "$dir/Makefile" ]; then + echo -e "${YELLOW}${BOLD}deleting ephemeral test fixtures in $dir${RESET}" + (make -C "$dir" clean) + fi + done + echo -e "${BOLD}Deleted all ephemeral test fixtures${RESET}" + - rm -f {{ .LAST_CACHE_PULL_FILE }} {{ .CACHE_PATHS_FILE }} diff --git a/cmd/syft/internal/test/integration/.gitignore b/cmd/syft/internal/test/integration/.gitignore new file mode 100644 index 00000000000..872aa273a4e --- /dev/null +++ b/cmd/syft/internal/test/integration/.gitignore @@ -0,0 +1 @@ +results \ No newline at end of file diff --git a/cmd/syft/internal/test/integration/all_layers_squashed_comparison_test.go b/cmd/syft/internal/test/integration/all_layers_squashed_comparison_test.go index 4dedd9ef44e..41f8e35023d 100644 --- a/cmd/syft/internal/test/integration/all_layers_squashed_comparison_test.go +++ b/cmd/syft/internal/test/integration/all_layers_squashed_comparison_test.go @@ -7,7 +7,7 @@ import ( ) func Test_AllLayersIncludesSquashed(t *testing.T) { - // This is a verification test for issue #894 (https://github.com/anchore/syft/issues/894) + // This is a verification test for issue grype/#894 (https://github.com/anchore/grype/issues/894) allLayers, _ := catalogFixtureImage(t, "image-suse-all-layers", source.AllLayersScope) squashed, _ := catalogFixtureImage(t, "image-suse-all-layers", source.SquashedScope) diff --git a/cmd/syft/internal/test/integration/encode_decode_cycle_test.go b/cmd/syft/internal/test/integration/encode_decode_cycle_test.go index 56bd7b77260..dd3a99a8552 100644 --- a/cmd/syft/internal/test/integration/encode_decode_cycle_test.go +++ b/cmd/syft/internal/test/integration/encode_decode_cycle_test.go @@ -2,7 +2,9 @@ package integration import ( "bytes" - "regexp" + "os" + "path/filepath" + "strings" "testing" "github.com/google/go-cmp/cmp" @@ -12,8 +14,6 @@ import ( "github.com/anchore/syft/cmd/syft/internal/options" "github.com/anchore/syft/syft/format" - "github.com/anchore/syft/syft/format/cyclonedxjson" - "github.com/anchore/syft/syft/format/cyclonedxxml" "github.com/anchore/syft/syft/format/syftjson" "github.com/anchore/syft/syft/source" ) @@ -43,26 +43,27 @@ func TestEncodeDecodeEncodeCycleComparison(t *testing.T) { }, json: true, }, - { - name: cyclonedxjson.ID.String(), - redactor: func(in []byte) []byte { - // unstable values - in = regexp.MustCompile(`"(timestamp|serialNumber|bom-ref|ref)":\s*"(\n|[^"])+"`).ReplaceAll(in, []byte(`"$1": "redacted"`)) - in = regexp.MustCompile(`"(dependsOn)":\s*\[(?:\s|[^]])+]`).ReplaceAll(in, []byte(`"$1": []`)) - return in - }, - json: true, - }, - { - name: cyclonedxxml.ID.String(), - redactor: func(in []byte) []byte { - // unstable values - in = regexp.MustCompile(`(serialNumber|bom-ref|ref)="[^"]+"`).ReplaceAll(in, []byte{}) - in = regexp.MustCompile(`[^<]+`).ReplaceAll(in, []byte{}) - - return in - }, - }, + // TODO: ignoring the `ref` field though does create stable results to compare, but the SBOM is fundamentally gutted and not worth comparing (find a better redaction or compare method) + //{ + // name: cyclonedxjson.ID.String(), + // redactor: func(in []byte) []byte { + // // unstable values + // in = regexp.MustCompile(`"(timestamp|serialNumber|bom-ref|ref)":\s*"(\n|[^"])+"`).ReplaceAll(in, []byte(`"$1": "redacted"`)) + // in = regexp.MustCompile(`"(dependsOn)":\s*\[(?:\s|[^]])+]`).ReplaceAll(in, []byte(`"$1": []`)) + // return in + // }, + // json: true, + //}, + //{ + // name: cyclonedxxml.ID.String(), + // redactor: func(in []byte) []byte { + // // unstable values + // in = regexp.MustCompile(`(serialNumber|bom-ref|ref)="[^"]+"`).ReplaceAll(in, []byte{}) + // in = regexp.MustCompile(`[^<]+`).ReplaceAll(in, []byte{}) + // + // return in + // }, + //}, } opts := options.DefaultOutput() @@ -112,6 +113,21 @@ func TestEncodeDecodeEncodeCycleComparison(t *testing.T) { diffs := dmp.DiffMain(string(by1), string(by2), true) t.Errorf("diff: %s", dmp.DiffPrettyText(diffs)) } + + // write raw IMAGE@NAME-start and IMAGE@NAME-finish to files within the results dir + // ... this is helpful for debugging + require.NoError(t, os.MkdirAll("results", 0700)) + + suffix := "sbom" + switch { + case strings.Contains(test.name, "json"): + suffix = "json" + case strings.Contains(test.name, "xml"): + suffix = "xml" + } + + require.NoError(t, os.WriteFile(filepath.Join("results", image+"@"+test.name+"-start."+suffix), by1, 0600)) + require.NoError(t, os.WriteFile(filepath.Join("results", image+"@"+test.name+"-finish."+suffix), by2, 0600)) } }) } diff --git a/cmd/syft/internal/test/integration/go_compiler_detection_test.go b/cmd/syft/internal/test/integration/go_compiler_detection_test.go index 8c440a0309e..e6a0d588872 100644 --- a/cmd/syft/internal/test/integration/go_compiler_detection_test.go +++ b/cmd/syft/internal/test/integration/go_compiler_detection_test.go @@ -35,8 +35,8 @@ func TestGolangCompilerDetection(t *testing.T) { for _, pkg := range packages { foundCompilerVersions[pkg.Version] = struct{}{} foundPURL[pkg.PURL] = struct{}{} - for _, cpe := range pkg.CPEs { - foundCPE[cpe] = struct{}{} + for _, c := range pkg.CPEs { + foundCPE[c] = struct{}{} } } diff --git a/cmd/syft/internal/test/integration/java_purl_test.go b/cmd/syft/internal/test/integration/java_purl_test.go index 5dab545d686..5de8875ca84 100644 --- a/cmd/syft/internal/test/integration/java_purl_test.go +++ b/cmd/syft/internal/test/integration/java_purl_test.go @@ -1,10 +1,9 @@ package integration import ( - "fmt" "testing" - "github.com/stretchr/testify/assert" + "github.com/google/go-cmp/cmp" "github.com/anchore/syft/syft/pkg" "github.com/anchore/syft/syft/source" @@ -26,13 +25,9 @@ func TestJavaPURLs(t *testing.T) { found[metadata.VirtualPath] = p.PURL } } - for key, expectedPURL := range expectedPURLs { - purl := found[key] - assert.Equal(t, expectedPURL, purl, fmt.Sprintf("found wrong or missing PURL for %s want %s, got %s", key, expectedPURL, purl)) - } - for key, foundPURL := range found { - expectedPURL := expectedPURLs[key] - assert.Equal(t, expectedPURL, foundPURL, fmt.Sprintf("found extra purl for %s want %s, got %s", key, expectedPURL, foundPURL)) + + if d := cmp.Diff(expectedPURLs, found); d != "" { + t.Errorf("unexpected purl values:\n%s", d) } } diff --git a/cmd/syft/internal/test/integration/package_deduplication_test.go b/cmd/syft/internal/test/integration/package_deduplication_test.go index 12fa9dcf207..ab8e580f8ad 100644 --- a/cmd/syft/internal/test/integration/package_deduplication_test.go +++ b/cmd/syft/internal/test/integration/package_deduplication_test.go @@ -1,5 +1,3 @@ -//go:build !arm64 - package integration import ( @@ -7,7 +5,6 @@ import ( "testing" "github.com/stretchr/testify/assert" - "github.com/stretchr/testify/require" "github.com/anchore/syft/syft/pkg" "github.com/anchore/syft/syft/source" @@ -22,41 +19,39 @@ func TestPackageDeduplication(t *testing.T) { }{ { scope: source.AllLayersScope, - packageCount: 172, // without deduplication this would be 618 + packageCount: 178, // without deduplication this would be ~600 instanceCount: map[string]int{ - "basesystem": 1, - "wget": 1, - "curl": 2, // upgraded in the image - "vsftpd": 1, - "httpd": 1, // rpm, - we exclude binary + "basesystem": 1, + "wget": 1, + "curl-minimal": 2, // upgraded in the image + "vsftpd": 1, + "httpd": 1, // rpm, - we exclude binary }, locationCount: map[string]int{ - "basesystem-10.0-7.el7.centos": 4, - "curl-7.29.0-59.el7": 1, // from base image - "curl-7.29.0-59.el7_9.1": 3, // upgrade - "wget-1.14-18.el7_6.1": 3, - "vsftpd-3.0.2-29.el7_9": 2, - "httpd-2.4.6-97.el7.centos.5": 1, - // "httpd-2.4.6": 1, // binary + "basesystem-11-13.el9": 5, // in all layers + "curl-minimal-7.76.1-26.el9_3.2.0.1": 2, // base + wget layer + "curl-minimal-7.76.1-29.el9_4.1": 3, // curl upgrade layer + all above layers + "wget-1.21.1-8.el9_4": 4, // wget + all above layers + "vsftpd-3.0.5-5.el9": 2, // vsftpd + all above layers + "httpd-2.4.57-11.el9_4.1": 1, // last layer }, }, { scope: source.SquashedScope, - packageCount: 170, + packageCount: 172, instanceCount: map[string]int{ - "basesystem": 1, - "wget": 1, - "curl": 1, // upgraded, but the most recent - "vsftpd": 1, - "httpd": 1, // rpm, binary is now excluded by overlap + "basesystem": 1, + "wget": 1, + "curl-minimal": 1, // upgraded, but the most recent + "vsftpd": 1, + "httpd": 1, // rpm, binary is now excluded by overlap }, locationCount: map[string]int{ - "basesystem-10.0-7.el7.centos": 1, - "curl-7.29.0-59.el7_9.1": 1, // upgrade - "wget-1.14-18.el7_6.1": 1, - "vsftpd-3.0.2-29.el7_9": 1, - "httpd-2.4.6-97.el7.centos.5": 1, - // "httpd-2.4.6": 1, // binary (excluded) + "basesystem-11-13.el9": 1, + "curl-minimal-7.76.1-29.el9_4.1": 1, // upgrade + "wget-1.21.1-8.el9_4": 1, + "vsftpd-3.0.5-5.el9": 1, + "httpd-2.4.57-11.el9_4.1": 1, }, }, } @@ -75,20 +70,21 @@ func TestPackageDeduplication(t *testing.T) { pkgs := sbom.Artifacts.Packages.PackagesByName(name) // with multiple packages with the same name, something is wrong (or this is the wrong fixture) - require.Len(t, pkgs, expectedInstanceCount) - - for _, p := range pkgs { - nameVersion := fmt.Sprintf("%s-%s", name, p.Version) - expectedLocationCount, ok := tt.locationCount[nameVersion] - if !ok { - t.Fatalf("missing name-version: %s", nameVersion) - } + if assert.Len(t, pkgs, expectedInstanceCount, "unexpected package count for %s", name) { + for _, p := range pkgs { + nameVersion := fmt.Sprintf("%s-%s", name, p.Version) + expectedLocationCount, ok := tt.locationCount[nameVersion] + if !ok { + t.Errorf("missing name-version: %s", nameVersion) + continue + } - // we should see merged locations (assumption, there was 1 location for each package) - assert.Len(t, p.Locations.ToSlice(), expectedLocationCount) + // we should see merged locations (assumption, there was 1 location for each package) + assert.Len(t, p.Locations.ToSlice(), expectedLocationCount, "unexpected location count for %s", nameVersion) - // all paths should match - assert.Len(t, p.Locations.CoordinateSet().Paths(), 1) + // all paths should match + assert.Len(t, p.Locations.CoordinateSet().Paths(), 1, "unexpected location count for %s", nameVersion) + } } } diff --git a/cmd/syft/internal/test/integration/test-fixtures/Makefile b/cmd/syft/internal/test/integration/test-fixtures/Makefile index 2a75aa43616..7cce0b0d8b4 100644 --- a/cmd/syft/internal/test/integration/test-fixtures/Makefile +++ b/cmd/syft/internal/test/integration/test-fixtures/Makefile @@ -1,6 +1,21 @@ -# change these if you want CI to not use previous stored cache -INTEGRATION_CACHE_BUSTER := "894d8ca" +FINGERPRINT_FILE := cache.fingerprint -.PHONY: cache.fingerprint -cache.fingerprint: - find image-* -type f -exec md5sum {} + | awk '{print $1}' | sort | tee /dev/stderr | md5sum | tee cache.fingerprint && echo "$(INTEGRATION_CACHE_BUSTER)" >> cache.fingerprint +.DEFAULT_GOAL := fixtures + +# requirement 1: 'fixtures' goal to generate any and all test fixtures +fixtures: + @echo "nothing to do" + +# requirement 2: 'fingerprint' goal to determine if the fixture input that indicates any existing cache should be busted +fingerprint: $(FINGERPRINT_FILE) + +# requirement 3: we always need to recalculate the fingerprint based on source regardless of any existing fingerprint +.PHONY: $(FINGERPRINT_FILE) +$(FINGERPRINT_FILE): + @find image-* -type f -exec sha256sum {} \; | sort -k2 > $(FINGERPRINT_FILE) + @#cat $(FINGERPRINT_FILE) | sha256sum | awk '{print $$1}' + +# requirement 4: 'clean' goal to remove all generated test fixtures +.PHONY: clean +clean: + rm -f $(FINGERPRINT_FILE) diff --git a/cmd/syft/internal/test/integration/test-fixtures/image-golang-compiler/Dockerfile b/cmd/syft/internal/test/integration/test-fixtures/image-golang-compiler/Dockerfile index 2d8e6bbdce5..e73f169b279 100644 --- a/cmd/syft/internal/test/integration/test-fixtures/image-golang-compiler/Dockerfile +++ b/cmd/syft/internal/test/integration/test-fixtures/image-golang-compiler/Dockerfile @@ -1 +1,6 @@ -FROM golang:1.18.10-alpine \ No newline at end of file +FROM --platform=linux/amd64 golang:1.18.10-alpine + +FROM scratch + +# we don't need the entire golang toolchain, just a single binary with the stdlib baked in +COPY --from=0 /usr/local/go/bin/gofmt bin/gofmt diff --git a/cmd/syft/internal/test/integration/test-fixtures/image-java-no-main-package/Dockerfile b/cmd/syft/internal/test/integration/test-fixtures/image-java-no-main-package/Dockerfile index dce8deba3e2..3271f14cfd8 100644 --- a/cmd/syft/internal/test/integration/test-fixtures/image-java-no-main-package/Dockerfile +++ b/cmd/syft/internal/test/integration/test-fixtures/image-java-no-main-package/Dockerfile @@ -1,4 +1,4 @@ -FROM jenkins/jenkins:2.346.3-slim-jdk17@sha256:028fbbd9112c60ed086f5197fcba71992317864d27644e5949cf9c52ff4b65f0 +FROM jenkins/jenkins:2.346.3-slim-jdk17@sha256:028fbbd9112c60ed086f5197fcba71992317864d27644e5949cf9c52ff4b65f0 AS base USER root @@ -12,7 +12,7 @@ RUN apt-get update 2>&1 > /dev/null && apt-get install -y less zip 2>&1 > /dev/n RUN unzip ../jenkins.war 2>&1 > /dev/null -RUN rm -f ./META-INF/MANIFEST.MF +RUN rm -rf ./META-INF/MANIFEST.MF ./WEB-INF ./jsbundles ./scripts ./css WORKDIR /usr/share/jenkins @@ -21,3 +21,7 @@ RUN rm -rf jenkins.war RUN cd ./tmp && zip -r ../jenkins.war . && cd .. RUN rm -rf ./tmp + +FROM scratch + +COPY --from=base /usr/share/jenkins/jenkins.war /jenkins.war diff --git a/cmd/syft/internal/test/integration/test-fixtures/image-java-virtualpath-regression/Dockerfile b/cmd/syft/internal/test/integration/test-fixtures/image-java-virtualpath-regression/Dockerfile index 63fc6c92aad..b7990d9d104 100644 --- a/cmd/syft/internal/test/integration/test-fixtures/image-java-virtualpath-regression/Dockerfile +++ b/cmd/syft/internal/test/integration/test-fixtures/image-java-virtualpath-regression/Dockerfile @@ -1,7 +1,15 @@ -FROM alpine:3.18.3@sha256:7144f7bab3d4c2648d7e59409f15ec52a18006a128c733fcff20d3a4a54ba44a +FROM alpine:3.18.3@sha256:7144f7bab3d4c2648d7e59409f15ec52a18006a128c733fcff20d3a4a54ba44a AS base RUN wget https://repo1.maven.org/maven2/org/jvnet/hudson/main/hudson-war/2.2.1/hudson-war-2.2.1.war RUN mv hudson-war-2.2.1.war hudson.war +# let's make this image a little smaller as to not take up so much disk space +# we'll only keep the jar metadata files (pom data + manifest) and throw away the rest +RUN apk add --no-cache python3 py3-pip +COPY extract.py /extract.py +RUN python extract.py +FROM scratch + +COPY --from=base /slim / diff --git a/cmd/syft/internal/test/integration/test-fixtures/image-java-virtualpath-regression/extract.py b/cmd/syft/internal/test/integration/test-fixtures/image-java-virtualpath-regression/extract.py new file mode 100644 index 00000000000..e0f005b4ce9 --- /dev/null +++ b/cmd/syft/internal/test/integration/test-fixtures/image-java-virtualpath-regression/extract.py @@ -0,0 +1,69 @@ +import os +import zipfile +import io + +ARCHIVE_EXTENSIONS = ('.jar', '.war', '.ear', '.hpi', '.war', '.sar', '.nar', '.par') +METADATA_FILES = ('pom.xml', 'pom.properties', 'MANIFEST.MF') + + +def slim_archive(archive, output_dir, base_path="", archive_name=""): + """ + extracts metadata files from the archive and creates a slim JAR file + containing only these files. handles nested JARs by preserving them. + """ + slim_buffer = io.BytesIO() + with zipfile.ZipFile(archive, 'r') as zip_file: + with zipfile.ZipFile(slim_buffer, 'w', zipfile.ZIP_DEFLATED) as slim_zip: + for file_name in zip_file.namelist(): + # check for metadata files or nested JARs + if file_name.endswith(METADATA_FILES): + # add metadata files directly to the slimmed archive + file_data = zip_file.read(file_name) + slim_zip.writestr(file_name, file_data) + elif file_name.endswith(ARCHIVE_EXTENSIONS): + # if it's a nested archive, recursively slim it + nested_archive = io.BytesIO(zip_file.read(file_name)) + nested_slim_buffer = io.BytesIO() + slim_archive( + nested_archive, + nested_slim_buffer, + base_path=os.path.join(base_path, os.path.dirname(file_name)), + archive_name=os.path.basename(file_name) + ) + # add the slimmed nested archive back to the parent archive + nested_slim_buffer.seek(0) + slim_zip.writestr(file_name, nested_slim_buffer.read()) + + # write out the slimmed JAR to the output directory if output_dir is a directory + if isinstance(output_dir, str): + output_path = os.path.join(output_dir, base_path, archive_name) + os.makedirs(os.path.dirname(output_path), exist_ok=True) + with open(output_path, 'wb') as f: + slim_buffer.seek(0) + f.write(slim_buffer.read()) + else: + # if output_dir is a BytesIO buffer (for nested archives), just write to it + output_dir.seek(0) + output_dir.write(slim_buffer.getvalue()) + + +def walk_directory_and_slim_jars(base_dir, output_dir): + """ + recursively walks through a directory tree looking for .jar, .war, .ear, + .hpi files and slims them down by keeping only metadata files. + """ + for dirpath, _, filenames in os.walk(base_dir): + for filename in filenames: + if filename.endswith(ARCHIVE_EXTENSIONS): + archive_path = os.path.join(dirpath, filename) + print(f"Processing {archive_path}") + slim_archive(archive_path, output_dir, os.path.relpath(dirpath, base_dir), filename) + + +# a helper script for slimming down JAR files by keeping only metadata files but still keeping the jar packaging, +# including nested JARs! Useful for testing purposes. +if __name__ == "__main__": + BASE_DIR = "." + OUTPUT_DIR = "./slim" + os.makedirs(OUTPUT_DIR, exist_ok=True) + walk_directory_and_slim_jars(BASE_DIR, OUTPUT_DIR) diff --git a/cmd/syft/internal/test/integration/test-fixtures/image-large-apk-data/Dockerfile b/cmd/syft/internal/test/integration/test-fixtures/image-large-apk-data/Dockerfile index 8187870a863..a8eaca2364d 100644 --- a/cmd/syft/internal/test/integration/test-fixtures/image-large-apk-data/Dockerfile +++ b/cmd/syft/internal/test/integration/test-fixtures/image-large-apk-data/Dockerfile @@ -1,4 +1,4 @@ -FROM alpine@sha256:d9a7354e3845ea8466bb00b22224d9116b183e594527fb5b6c3d30bc01a20378 +FROM alpine@sha256:d9a7354e3845ea8466bb00b22224d9116b183e594527fb5b6c3d30bc01a20378 AS base # we keep these unpinned so that if alpine # changes our integration tests can adapt @@ -6,3 +6,8 @@ RUN apk add --no-cache \ tzdata \ vim \ alpine-sdk + +# we don't need the installed bins for this test, only the APK installed metadata +FROM scratch + +COPY --from=base /lib/apk/db/installed /lib/apk/db/installed diff --git a/cmd/syft/internal/test/integration/test-fixtures/image-mariner-distroless/Dockerfile b/cmd/syft/internal/test/integration/test-fixtures/image-mariner-distroless/Dockerfile index 6a6e08f61cc..12e7a416d7f 100644 --- a/cmd/syft/internal/test/integration/test-fixtures/image-mariner-distroless/Dockerfile +++ b/cmd/syft/internal/test/integration/test-fixtures/image-mariner-distroless/Dockerfile @@ -1 +1,8 @@ -FROM mcr.microsoft.com/cbl-mariner/distroless/base:2.0.202205275@sha256:f550c5428df17b145851ad75983aca6d613ad4b51ca7983b2a83e67d0ac91a5d +FROM mcr.microsoft.com/cbl-mariner/distroless/base:2.0.202205275@sha256:f550c5428df17b145851ad75983aca6d613ad4b51ca7983b2a83e67d0ac91a5d AS base + +# let's shoot for smaller test fixtures +FROM scratch + +COPY --from=base /var/lib/rpmmanifest/container-manifest-2 /var/lib/rpmmanifest/container-manifest-2 +COPY --from=base /usr/bin/gencat /usr/bin/gencat +COPY --from=base /usr/bin/openssl /usr/bin/openssl diff --git a/cmd/syft/internal/test/integration/test-fixtures/image-owning-package/Dockerfile b/cmd/syft/internal/test/integration/test-fixtures/image-owning-package/Dockerfile index 192998626e9..931547acdc5 100644 --- a/cmd/syft/internal/test/integration/test-fixtures/image-owning-package/Dockerfile +++ b/cmd/syft/internal/test/integration/test-fixtures/image-owning-package/Dockerfile @@ -1,3 +1,8 @@ -FROM ubuntu:20.04@sha256:33a5cc25d22c45900796a1aca487ad7a7cb09f09ea00b779e3b2026b4fc2faba +FROM ubuntu:20.04@sha256:33a5cc25d22c45900796a1aca487ad7a7cb09f09ea00b779e3b2026b4fc2faba AS base # this covers rpm-python RUN apt-get update && apt-get install -y python-pil=6.2.1-3 + +# let's save some space... +FROM scratch + +COPY --from=base /var/lib/dpkg/status /var/lib/dpkg/status diff --git a/cmd/syft/internal/test/integration/test-fixtures/image-photon-all-layers/Dockerfile b/cmd/syft/internal/test/integration/test-fixtures/image-photon-all-layers/Dockerfile index 17bb3691b4c..4910647366c 100644 --- a/cmd/syft/internal/test/integration/test-fixtures/image-photon-all-layers/Dockerfile +++ b/cmd/syft/internal/test/integration/test-fixtures/image-photon-all-layers/Dockerfile @@ -1 +1,5 @@ -FROM photon:5.0-20230729@sha256:4cf2a1ce0a3f4625f13a0becb6b9bccfdb014c565be6e9a2ec4c4aad1ff8a5d9 +FROM photon:5.0-20230729@sha256:4cf2a1ce0a3f4625f13a0becb6b9bccfdb014c565be6e9a2ec4c4aad1ff8a5d9 AS base + +FROM scratch + +COPY --from=base /usr/lib/sysimage/rpm /usr/lib/sysimage/rpm diff --git a/cmd/syft/internal/test/integration/test-fixtures/image-sqlite-rpmdb/Dockerfile b/cmd/syft/internal/test/integration/test-fixtures/image-sqlite-rpmdb/Dockerfile index 938b431d518..1bda58960be 100644 --- a/cmd/syft/internal/test/integration/test-fixtures/image-sqlite-rpmdb/Dockerfile +++ b/cmd/syft/internal/test/integration/test-fixtures/image-sqlite-rpmdb/Dockerfile @@ -1 +1,6 @@ -FROM fedora:35@sha256:36af84ba69e21c9ef86a0424a090674c433b2b80c2462e57503886f1d823abe8 +FROM fedora:35@sha256:36af84ba69e21c9ef86a0424a090674c433b2b80c2462e57503886f1d823abe8 AS base + +# lets save some space +FROM scratch + +COPY --from=base /var/lib/rpm /var/lib/rpm diff --git a/cmd/syft/internal/test/integration/test-fixtures/image-suse-all-layers/Dockerfile b/cmd/syft/internal/test/integration/test-fixtures/image-suse-all-layers/Dockerfile index 339983d8800..0c4f1165606 100644 --- a/cmd/syft/internal/test/integration/test-fixtures/image-suse-all-layers/Dockerfile +++ b/cmd/syft/internal/test/integration/test-fixtures/image-suse-all-layers/Dockerfile @@ -1,2 +1,11 @@ -FROM registry.suse.com/suse/sle15:15.3.17.20.20@sha256:fd657ecbab5ca564d6933e887f6ae8542a9398e6a4b399f352ce10c3a24afc64 +FROM registry.suse.com/suse/sle15:15.3.17.20.20@sha256:fd657ecbab5ca564d6933e887f6ae8542a9398e6a4b399f352ce10c3a24afc64 AS base RUN zypper in -y wget + +# let's save some space... we really just need an image that has an RPM DB that is linked across layers +FROM --platform=linux/amd64 busybox:1.36.1 + +# setup a link /var/lib/rpm -> ../../usr/lib/sysimage/rpm +RUN mkdir -p /var/lib && ln -s ../../usr/lib/sysimage/rpm /var/lib/rpm + +# copy the RPM DB from the SUSE image +COPY --from=base /usr/lib/sysimage/rpm/Packages.db /usr/lib/sysimage/rpm/Packages.db diff --git a/cmd/syft/internal/test/integration/test-fixtures/image-test-java-purls/Dockerfile b/cmd/syft/internal/test/integration/test-fixtures/image-test-java-purls/Dockerfile index 16f074b362f..4e4cb13885b 100644 --- a/cmd/syft/internal/test/integration/test-fixtures/image-test-java-purls/Dockerfile +++ b/cmd/syft/internal/test/integration/test-fixtures/image-test-java-purls/Dockerfile @@ -1,3 +1,18 @@ -FROM docker.io/anchore/test_images:java-88948cc@sha256:dea0e6c24636937f53bdc997d9960c2a18966d1e38bcd8ebd0c395d4e169b806 +FROM docker.io/anchore/test_images:java-88948cc@sha256:dea0e6c24636937f53bdc997d9960c2a18966d1e38bcd8ebd0c395d4e169b806 AS base -RUN rm /packages/gradle-7.1.1-bin.zip \ No newline at end of file +# not covered in testing... +RUN rm /packages/gradle-7.1.1-bin.zip + +RUN apk add --no-cache python3 py3-pip + +COPY extract.py /extract.py + +WORKDIR / + +# let's make this image a little smaller as to not take up so much disk space +# we'll only keep the jar metadata files (pom data + manifest) and throw away the rest +RUN python extract.py + +FROM scratch + +COPY --from=base /slim/packages /packages diff --git a/cmd/syft/internal/test/integration/test-fixtures/image-test-java-purls/extract.py b/cmd/syft/internal/test/integration/test-fixtures/image-test-java-purls/extract.py new file mode 100644 index 00000000000..e0f005b4ce9 --- /dev/null +++ b/cmd/syft/internal/test/integration/test-fixtures/image-test-java-purls/extract.py @@ -0,0 +1,69 @@ +import os +import zipfile +import io + +ARCHIVE_EXTENSIONS = ('.jar', '.war', '.ear', '.hpi', '.war', '.sar', '.nar', '.par') +METADATA_FILES = ('pom.xml', 'pom.properties', 'MANIFEST.MF') + + +def slim_archive(archive, output_dir, base_path="", archive_name=""): + """ + extracts metadata files from the archive and creates a slim JAR file + containing only these files. handles nested JARs by preserving them. + """ + slim_buffer = io.BytesIO() + with zipfile.ZipFile(archive, 'r') as zip_file: + with zipfile.ZipFile(slim_buffer, 'w', zipfile.ZIP_DEFLATED) as slim_zip: + for file_name in zip_file.namelist(): + # check for metadata files or nested JARs + if file_name.endswith(METADATA_FILES): + # add metadata files directly to the slimmed archive + file_data = zip_file.read(file_name) + slim_zip.writestr(file_name, file_data) + elif file_name.endswith(ARCHIVE_EXTENSIONS): + # if it's a nested archive, recursively slim it + nested_archive = io.BytesIO(zip_file.read(file_name)) + nested_slim_buffer = io.BytesIO() + slim_archive( + nested_archive, + nested_slim_buffer, + base_path=os.path.join(base_path, os.path.dirname(file_name)), + archive_name=os.path.basename(file_name) + ) + # add the slimmed nested archive back to the parent archive + nested_slim_buffer.seek(0) + slim_zip.writestr(file_name, nested_slim_buffer.read()) + + # write out the slimmed JAR to the output directory if output_dir is a directory + if isinstance(output_dir, str): + output_path = os.path.join(output_dir, base_path, archive_name) + os.makedirs(os.path.dirname(output_path), exist_ok=True) + with open(output_path, 'wb') as f: + slim_buffer.seek(0) + f.write(slim_buffer.read()) + else: + # if output_dir is a BytesIO buffer (for nested archives), just write to it + output_dir.seek(0) + output_dir.write(slim_buffer.getvalue()) + + +def walk_directory_and_slim_jars(base_dir, output_dir): + """ + recursively walks through a directory tree looking for .jar, .war, .ear, + .hpi files and slims them down by keeping only metadata files. + """ + for dirpath, _, filenames in os.walk(base_dir): + for filename in filenames: + if filename.endswith(ARCHIVE_EXTENSIONS): + archive_path = os.path.join(dirpath, filename) + print(f"Processing {archive_path}") + slim_archive(archive_path, output_dir, os.path.relpath(dirpath, base_dir), filename) + + +# a helper script for slimming down JAR files by keeping only metadata files but still keeping the jar packaging, +# including nested JARs! Useful for testing purposes. +if __name__ == "__main__": + BASE_DIR = "." + OUTPUT_DIR = "./slim" + os.makedirs(OUTPUT_DIR, exist_ok=True) + walk_directory_and_slim_jars(BASE_DIR, OUTPUT_DIR) diff --git a/cmd/syft/internal/test/integration/test-fixtures/image-vertical-package-dups/Dockerfile b/cmd/syft/internal/test/integration/test-fixtures/image-vertical-package-dups/Dockerfile index cd0e69b5de8..28f95ba5949 100644 --- a/cmd/syft/internal/test/integration/test-fixtures/image-vertical-package-dups/Dockerfile +++ b/cmd/syft/internal/test/integration/test-fixtures/image-vertical-package-dups/Dockerfile @@ -1,6 +1,27 @@ -FROM centos:7.9.2009@sha256:be65f488b7764ad3638f236b7b515b3678369a5124c47b8d32916d6487418ea4 +FROM --platform=linux/amd64 rockylinux:9.3.20231119@sha256:d644d203142cd5b54ad2a83a203e1dee68af2229f8fe32f52a30c6e1d3c3a9e0 AS base + # modifying the RPM DB multiple times will result in duplicate packages when using all-layers (if there was no de-dup logic) # curl is tricky, it already exists in the image and is being upgraded -RUN yum install -y wget-1.14-18.el7_6.1 curl-7.29.0-59.el7_9.1 -RUN yum install -y vsftpd-3.0.2-29.el7_9 -RUN yum install -y httpd-2.4.6-97.el7.centos.5 + +# but... we want to make the test image as small as possible, so we are making the changes in stages and then +# copying the RPM DB from each stage to a final stage in separate layers. This will result in a much smaller image. + +FROM base AS stage1 +RUN dnf install -y wget + +FROM stage1 AS stage2 +RUN dnf update -y curl-minimal + +FROM stage2 AS stage3 +RUN dnf install -y vsftpd + +FROM stage3 AS stage4 +RUN dnf install -y httpd + +FROM scratch + +COPY --from=base /var/lib/rpm /var/lib/rpm +COPY --from=stage1 /var/lib/rpm /var/lib/rpm +COPY --from=stage2 /var/lib/rpm /var/lib/rpm +COPY --from=stage3 /var/lib/rpm /var/lib/rpm +COPY --from=stage4 /var/lib/rpm /var/lib/rpm diff --git a/go.mod b/go.mod index 7cb63cf530d..f6fc5241121 100644 --- a/go.mod +++ b/go.mod @@ -88,6 +88,7 @@ require google.golang.org/genproto v0.0.0-20231106174013-bbf56f31fb17 // indirec require ( github.com/BurntSushi/toml v1.4.0 + github.com/OneOfOne/xxhash v1.2.8 github.com/adrg/xdg v0.5.0 github.com/magiconair/properties v1.8.7 golang.org/x/exp v0.0.0-20231108232855-2478ac86f678 diff --git a/go.sum b/go.sum index d3dc4b7d916..61e20d6dd3f 100644 --- a/go.sum +++ b/go.sum @@ -79,6 +79,8 @@ github.com/Microsoft/go-winio v0.6.1/go.mod h1:LRdKpFKfdobln8UmuiYcKPot9D2v6svN5 github.com/Microsoft/hcsshim v0.11.4 h1:68vKo2VN8DE9AdN4tnkWnmdhqdbpUFM8OF3Airm7fz8= github.com/Microsoft/hcsshim v0.11.4/go.mod h1:smjE4dvqPX9Zldna+t5FG3rnoHhaB7QYxPRqGcpAD9w= 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.0.0 h1:LRuvITjQWX+WIfr930YHG2HNfjR1uOfyf5vE0kC2U78= github.com/ProtonMail/go-crypto v1.0.0/go.mod h1:EjAoLdwvbIOoOQr3ihjnSoLZRtE8azugULFRteWMNc0= github.com/acarl005/stripansi v0.0.0-20180116102854-5a71ef0e047d h1:licZJFw2RwpHMqeKTCYkitsPqHNxTmd4SNR5r94FGM8= diff --git a/internal/task/executor.go b/internal/task/executor.go index 2935f61b12c..899796424be 100644 --- a/internal/task/executor.go +++ b/internal/task/executor.go @@ -7,9 +7,9 @@ import ( "sync" "time" - "github.com/anchore/syft/internal/log" "github.com/hashicorp/go-multierror" + "github.com/anchore/syft/internal/log" "github.com/anchore/syft/internal/sbomsync" "github.com/anchore/syft/syft/event/monitor" "github.com/anchore/syft/syft/file" diff --git a/syft/file/cataloger/executable/test-fixtures/Makefile b/syft/file/cataloger/executable/test-fixtures/Makefile new file mode 100644 index 00000000000..da3e730e131 --- /dev/null +++ b/syft/file/cataloger/executable/test-fixtures/Makefile @@ -0,0 +1,15 @@ +.DEFAULT_GOAL := default + +default: + @for dir in $(shell find . -mindepth 1 -maxdepth 1 -type d); do \ + if [ -f "$$dir/Makefile" ]; then \ + $(MAKE) -C $$dir; \ + fi; \ + done + +%: + @for dir in $(shell find . -mindepth 1 -maxdepth 1 -type d); do \ + if [ -f "$$dir/Makefile" ]; then \ + $(MAKE) -C $$dir $@; \ + fi; \ + done diff --git a/syft/file/cataloger/executable/test-fixtures/elf/Makefile b/syft/file/cataloger/executable/test-fixtures/elf/Makefile index 1cff6183e1e..5130c8faccb 100644 --- a/syft/file/cataloger/executable/test-fixtures/elf/Makefile +++ b/syft/file/cataloger/executable/test-fixtures/elf/Makefile @@ -1,8 +1,19 @@ BIN=./bin TOOL_IMAGE=localhost/syft-bin-build-tools:latest VERIFY_FILE=actual_verify +FINGERPRINT_FILE=$(BIN).fingerprint -all: build verify +ifndef BIN + $(error BIN is not set) +endif + +.DEFAULT_GOAL := fixtures + +# requirement 1: 'fixtures' goal to generate any and all test fixtures +fixtures: build verify + +# requirement 2: 'fingerprint' goal to determine if the fixture input that indicates any existing cache should be busted +fingerprint: $(FINGERPRINT_FILE) tools-check: @sha256sum -c Dockerfile.sha256 || (echo "Tools Dockerfile has changed" && exit 1) @@ -25,10 +36,14 @@ verify: tools debug: docker run -i --rm -v $(shell pwd):/mount -w /mount/project $(TOOL_IMAGE) bash -cache.fingerprint: - @find project Dockerfile Makefile -type f -exec md5sum {} + | awk '{print $1}' | sort | tee cache.fingerprint +# requirement 3: we always need to recalculate the fingerprint based on source regardless of any existing fingerprint +.PHONY: $(FINGERPRINT_FILE) +$(FINGERPRINT_FILE): + @find project Dockerfile Makefile -type f -exec sha256sum {} \; | sort -k2 > $(FINGERPRINT_FILE) + @#cat $(FINGERPRINT_FILE) | sha256sum | awk '{print $$1}' +# requirement 4: 'clean' goal to remove all generated test fixtures clean: - rm -f $(BIN)/* + rm -rf $(BIN) Dockerfile.sha256 $(VERIFY_FILE) $(FINGERPRINT_FILE) -.PHONY: build verify debug build-image build-bins clean dockerfile-check cache.fingerprint +.PHONY: tools tools-check build verify debug clean \ No newline at end of file diff --git a/syft/file/cataloger/executable/test-fixtures/shared-info/Makefile b/syft/file/cataloger/executable/test-fixtures/shared-info/Makefile index a3d5959c358..8321e0ae09e 100644 --- a/syft/file/cataloger/executable/test-fixtures/shared-info/Makefile +++ b/syft/file/cataloger/executable/test-fixtures/shared-info/Makefile @@ -1,8 +1,20 @@ BIN=./bin TOOL_IMAGE=localhost/syft-shared-info-build-tools:latest VERIFY_FILE=actual_verify +FINGERPRINT_FILE=$(BIN).fingerprint + +ifndef BIN + $(error BIN is not set) +endif + +.DEFAULT_GOAL := fixtures + +# requirement 1: 'fixtures' goal to generate any and all test fixtures +fixtures: build + +# requirement 2: 'fingerprint' goal to determine if the fixture input that indicates any existing cache should be busted +fingerprint: $(FINGERPRINT_FILE) -all: build tools-check: @sha256sum -c Dockerfile.sha256 || (echo "Tools Dockerfile has changed" && exit 1) @@ -10,16 +22,20 @@ tools: @(docker inspect $(TOOL_IMAGE) > /dev/null && make tools-check) || (docker build -t $(TOOL_IMAGE) . && sha256sum Dockerfile > Dockerfile.sha256) build: tools - mkdir -p $(BIN) + @mkdir -p $(BIN) docker run --platform linux/amd64 -i -v $(shell pwd):/mount -w /mount/project $(TOOL_IMAGE) make debug: docker run --platform linux/amd64 -i --rm -v $(shell pwd):/mount -w /mount/project $(TOOL_IMAGE) bash -cache.fingerprint: - @find project Dockerfile Makefile -type f -exec md5sum {} + | awk '{print $1}' | sort | tee cache.fingerprint +# requirement 3: we always need to recalculate the fingerprint based on source regardless of any existing fingerprint +.PHONY: $(FINGERPRINT_FILE) +$(FINGERPRINT_FILE): + @find project Dockerfile Makefile -type f -exec sha256sum {} \; | sort -k2 > $(FINGERPRINT_FILE) + @#cat $(FINGERPRINT_FILE) | sha256sum | awk '{print $$1}' +# requirement 4: 'clean' goal to remove all generated test fixtures clean: - rm -f $(BIN)/* + rm -rf $(BIN) Dockerfile.sha256 $(VERIFY_FILE) $(FINGERPRINT_FILE) -.PHONY: build verify debug build-image build-bins clean dockerfile-check cache.fingerprint +.PHONY: tools tools-check build debug clean diff --git a/syft/format/text/test-fixtures/image-simple/Dockerfile b/syft/format/text/test-fixtures/image-simple/Dockerfile deleted file mode 100644 index 79cfa759e35..00000000000 --- a/syft/format/text/test-fixtures/image-simple/Dockerfile +++ /dev/null @@ -1,4 +0,0 @@ -# Note: changes to this file will result in updating several test values. Consider making a new image fixture instead of editing this one. -FROM scratch -ADD file-1.txt /somefile-1.txt -ADD file-2.txt /somefile-2.txt diff --git a/syft/format/text/test-fixtures/image-simple/file-1.txt b/syft/format/text/test-fixtures/image-simple/file-1.txt deleted file mode 100644 index 985d3408e98..00000000000 --- a/syft/format/text/test-fixtures/image-simple/file-1.txt +++ /dev/null @@ -1 +0,0 @@ -this file has contents \ No newline at end of file diff --git a/syft/format/text/test-fixtures/image-simple/file-2.txt b/syft/format/text/test-fixtures/image-simple/file-2.txt deleted file mode 100644 index 396d08bbc72..00000000000 --- a/syft/format/text/test-fixtures/image-simple/file-2.txt +++ /dev/null @@ -1 +0,0 @@ -file-2 contents! \ No newline at end of file diff --git a/syft/format/text/test-fixtures/snapshot/TestTextImageEncoder.golden b/syft/format/text/test-fixtures/snapshot/TestTextImageEncoder.golden index 4ab3a446e0c..0c49cecc049 100644 --- a/syft/format/text/test-fixtures/snapshot/TestTextImageEncoder.golden +++ b/syft/format/text/test-fixtures/snapshot/TestTextImageEncoder.golden @@ -1,11 +1,11 @@ [Image] Layer: 0 - Digest: sha256:fb6beecb75b39f4bb813dbf177e501edd5ddb3e69bb45cedeb78c676ee1b7a59 + Digest: sha256:100d5a55f9032faead28b7427fa3e650e4f0158f86ea89d06e1489df00cb8c6f Size: 22 MediaType: application/vnd.docker.image.rootfs.diff.tar.gzip Layer: 1 - Digest: sha256:319b588ce64253a87b533c8ed01cf0025e0eac98e7b516e12532957e1244fdec + Digest: sha256:000fb9200890d3a19138478b20023023c0dce1c54352007c2863716780f049eb Size: 16 MediaType: application/vnd.docker.image.rootfs.diff.tar.gzip diff --git a/syft/pkg/cataloger/binary/test-fixtures/.gitignore b/syft/pkg/cataloger/binary/test-fixtures/.gitignore index e1d59c126c8..4d4d11ec993 100644 --- a/syft/pkg/cataloger/binary/test-fixtures/.gitignore +++ b/syft/pkg/cataloger/binary/test-fixtures/.gitignore @@ -1,6 +1,5 @@ classifiers/dynamic classifiers/bin -cache.fingerprint # allow for lb patterns (rust, pytho, php and more) !lib*.so diff --git a/syft/pkg/cataloger/binary/test-fixtures/Makefile b/syft/pkg/cataloger/binary/test-fixtures/Makefile index 3e8efed9468..fa37d43c16b 100644 --- a/syft/pkg/cataloger/binary/test-fixtures/Makefile +++ b/syft/pkg/cataloger/binary/test-fixtures/Makefile @@ -1,8 +1,14 @@ -.PHONY: default list download download-all cache.fingerprint +BIN=classifiers/bin +FINGERPRINT_FILE=$(BIN).fingerprint -.DEFAULT_GOAL := default -default: download +.DEFAULT_GOAL := fixtures + +# requirement 1: 'fixtures' goal to generate any and all test fixtures +fixtures: download + +# requirement 2: 'fingerprint' goal to determine if the fixture input that indicates any existing cache should be busted +fingerprint: clean-fingerprint $(FINGERPRINT_FILE) list: ## list all managed binaries and snippets go run ./manager list @@ -16,14 +22,23 @@ download-all: ## download all managed binaries add-snippet: ## add a new snippet from an existing binary go run ./manager add-snippet -cache.fingerprint: ## prints the sha256sum of the any input to the download command (to determine if there is a cache miss) - @cat ./config.yaml | sha256sum | awk '{print $$1}' | tee cache.fingerprint +# requirement 3: we always need to recalculate the fingerprint based on source regardless of any existing fingerprint +.PHONY: $(FINGERPRINT_FILE) +$(FINGERPRINT_FILE): ## prints the sha256sum of the any input to the download command (to determine if there is a cache miss) + @sha256sum ./config.yaml > $(FINGERPRINT_FILE) + +# requirement 4: 'clean' goal to remove all generated test fixtures +clean: ## clean up all downloaded binaries + rm -rf $(BIN) + +clean-fingerprint: ## clean up all legacy fingerprint files + @find $(BIN) -name '*.fingerprint' -delete -clean: ## clean up all downloaded binaries - rm -rf ./classifiers/bin ## Halp! ################################# .PHONY: help help: - @grep -E '^[a-zA-Z_-]+:.*?## .*$$' $(MAKEFILE_LIST) | sort | awk 'BEGIN {FS = ":.*?## "}; {printf "$(BOLD)$(CYAN)%-25s$(RESET)%s\n", $$1, $$2}' \ No newline at end of file + @grep -E '^[a-zA-Z_-]+:.*?## .*$$' $(MAKEFILE_LIST) | sort | awk 'BEGIN {FS = ":.*?## "}; {printf "$(BOLD)$(CYAN)%-25s$(RESET)%s\n", $$1, $$2}' + +.PHONY: default list download download-all clean clean-fingerprint add-snippet fingerprint \ No newline at end of file diff --git a/syft/pkg/cataloger/binary/test-fixtures/classifiers/snippets/traefik/3.0.4/linux-riscv64/traefik b/syft/pkg/cataloger/binary/test-fixtures/classifiers/snippets/traefik/3.0.4/linux-riscv64/traefik new file mode 100644 index 0000000000000000000000000000000000000000..f361c692988ec8d3246272fd8a69b029bd6509c4 GIT binary patch literal 352 zcmY+8txf|$5P%zSYY-3=Vv{qdvVXU;Q$t8_NS6+l64t;$jEY4)Am?MXhB85 z5Yd}}62X>9IY)^sWKCd{%Sj_BnJ{__mL#FZU`lDUVyq|%9_~Bh!<)Qod2Z{vz2kk0 zjYh}MzpGKt;`HF<@o2vfJr-lLE)DDq-rE+=e|FdD;_dsNR~sH)m+v1J@O1X|x#48k JI~>e={{f-rVJ-jw literal 0 HcmV?d00001 diff --git a/syft/pkg/cataloger/binary/test-fixtures/config.yaml b/syft/pkg/cataloger/binary/test-fixtures/config.yaml index 78d8ba4b8cf..ac433555c22 100644 --- a/syft/pkg/cataloger/binary/test-fixtures/config.yaml +++ b/syft/pkg/cataloger/binary/test-fixtures/config.yaml @@ -85,6 +85,7 @@ from-images: paths: - /usr/local/go/bin/go + # TODO: this is no longer available from dockerhub! (the snippet is vital) - version: 1.5.14 images: - ref: haproxy:1.5.14@sha256:3d57e3921cc84e860f764e863ce729dd0765e3d28d444775127bc42d68f98e10 diff --git a/syft/pkg/cataloger/binary/test-fixtures/elf-test-fixtures/Dockerfile b/syft/pkg/cataloger/binary/test-fixtures/elf-test-fixtures/Dockerfile index a5efa56eb3f..42a74837c5a 100644 --- a/syft/pkg/cataloger/binary/test-fixtures/elf-test-fixtures/Dockerfile +++ b/syft/pkg/cataloger/binary/test-fixtures/elf-test-fixtures/Dockerfile @@ -1,14 +1,31 @@ -FROM rockylinux:8 +FROM rockylinux:8 AS base + RUN dnf update -y; \ dnf install make automake gcc gcc-c++ kernel-devel -y; \ dnf clean all RUN mkdir -p /usr/local/bin/elftests/elfbinwithnestedlib RUN mkdir -p /usr/local/bin/elftests/elfbinwithsisterlib + COPY ./elfbinwithnestedlib /usr/local/bin/elftests/elfbinwithnestedlib COPY ./elfbinwithsisterlib /usr/local/bin/elftests/elfbinwithsisterlib + ENV LD_LIBRARY_PATH=/usr/local/bin/elftests/elfbinwithnestedlib/bin/lib + WORKDIR /usr/local/bin/elftests/elfbinwithnestedlib/ RUN make + WORKDIR /usr/local/bin/elftests/elfbinwithsisterlib RUN make +# let's make the test image smaller, since we only require the built binaries and supporting libraries +FROM busybox:1.36.1-musl + +COPY --from=base /usr/local/bin/elftests /usr/local/bin/elftests +COPY --from=base /var/lib/rpm /var/lib/rpm +COPY --from=base '/usr/lib64/libstdc++.so.6.0.25' '/usr/lib64/libstdc++.so.6.0.25' +COPY --from=base '/usr/lib64/libstdc++.so.6' '/usr/lib64/libstdc++.so.6' +COPY --from=base '/usr/lib64/libc.so.6' '/usr/lib64/libc.so.6' +COPY --from=base '/usr/lib64/libc.so' '/usr/lib64/libc.so' + +# prove we can operate over symlinks (/lib64 -> usr/lib64) +RUN ln -s /usr/lib64 /lib64 diff --git a/syft/pkg/cataloger/binary/test-fixtures/image-fedora-32bit/Dockerfile b/syft/pkg/cataloger/binary/test-fixtures/image-fedora-32bit/Dockerfile index e89c76124bb..0df726644a7 100644 --- a/syft/pkg/cataloger/binary/test-fixtures/image-fedora-32bit/Dockerfile +++ b/syft/pkg/cataloger/binary/test-fixtures/image-fedora-32bit/Dockerfile @@ -1,4 +1,4 @@ -FROM --platform=linux/arm arm32v7/fedora:36 as build +FROM --platform=linux/arm arm32v7/fedora:36 AS build FROM scratch COPY --from=build /bin/sha256sum /sha256sum diff --git a/syft/pkg/cataloger/binary/test-fixtures/image-fedora-64bit/Dockerfile b/syft/pkg/cataloger/binary/test-fixtures/image-fedora-64bit/Dockerfile index 0d65e734110..bd9694091d8 100644 --- a/syft/pkg/cataloger/binary/test-fixtures/image-fedora-64bit/Dockerfile +++ b/syft/pkg/cataloger/binary/test-fixtures/image-fedora-64bit/Dockerfile @@ -1,4 +1,4 @@ -FROM --platform=linux/amd64 fedora:41@sha256:c05bf79137835bf5c521c58f8252d6031780ae865a0379ab57f412e0ac6b42aa as build +FROM --platform=linux/amd64 fedora:41@sha256:c05bf79137835bf5c521c58f8252d6031780ae865a0379ab57f412e0ac6b42aa AS build FROM scratch diff --git a/syft/pkg/cataloger/binary/test-fixtures/manager/internal/config/binary_from_image.go b/syft/pkg/cataloger/binary/test-fixtures/manager/internal/config/binary_from_image.go index f26ac3ae40a..dc558250186 100644 --- a/syft/pkg/cataloger/binary/test-fixtures/manager/internal/config/binary_from_image.go +++ b/syft/pkg/cataloger/binary/test-fixtures/manager/internal/config/binary_from_image.go @@ -1,11 +1,11 @@ package config import ( - "crypto/sha256" "fmt" "path/filepath" "strings" + "github.com/OneOfOne/xxhash" "gopkg.in/yaml.v3" ) @@ -68,13 +68,13 @@ func PlatformAsValue(platform string) string { return strings.ReplaceAll(platform, "/", "-") } -func (c BinaryFromImage) Fingerprint() string { +func (c BinaryFromImage) Digest() string { by, err := yaml.Marshal(c) if err != nil { panic(err) } - hasher := sha256.New() - hasher.Write(by) + hasher := xxhash.New64() + _, _ = hasher.Write(by) return fmt.Sprintf("%x", hasher.Sum(nil)) } diff --git a/syft/pkg/cataloger/binary/test-fixtures/manager/internal/config/binary_from_image_test.go b/syft/pkg/cataloger/binary/test-fixtures/manager/internal/config/binary_from_image_test.go index 8d76d5a2b29..55bb3ee40c2 100644 --- a/syft/pkg/cataloger/binary/test-fixtures/manager/internal/config/binary_from_image_test.go +++ b/syft/pkg/cataloger/binary/test-fixtures/manager/internal/config/binary_from_image_test.go @@ -158,7 +158,7 @@ func TestPlatformAsValue(t *testing.T) { } } -func TestFingerprint(t *testing.T) { +func TestDigest(t *testing.T) { tests := []struct { name string binary BinaryFromImage @@ -179,13 +179,13 @@ func TestFingerprint(t *testing.T) { "path/to/test", }, }, - expected: "54ed081c07e4eba031afed4c04315cf96047822196473971be98d0769a0e3645", + expected: "fc25c48e3d2f01e3", }, } for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { - assert.Equal(t, tt.expected, tt.binary.Fingerprint()) + assert.Equal(t, tt.expected, tt.binary.Digest()) }) } } diff --git a/syft/pkg/cataloger/binary/test-fixtures/manager/internal/download_from_image.go b/syft/pkg/cataloger/binary/test-fixtures/manager/internal/download_from_image.go index 32b9c83d6dd..1d5a667eabf 100644 --- a/syft/pkg/cataloger/binary/test-fixtures/manager/internal/download_from_image.go +++ b/syft/pkg/cataloger/binary/test-fixtures/manager/internal/download_from_image.go @@ -2,6 +2,7 @@ package internal import ( "encoding/json" + "errors" "fmt" "os" "os/exec" @@ -14,6 +15,8 @@ import ( "github.com/anchore/syft/syft/pkg/cataloger/binary/test-fixtures/manager/internal/ui" ) +const digestFileSuffix = ".xxh64" + func DownloadFromImage(dest string, config config.BinaryFromImage) error { t := ui.Title{Name: config.Name(), Version: config.Version} t.Start() @@ -39,22 +42,22 @@ func DownloadFromImage(dest string, config config.BinaryFromImage) error { } func isDownloadStale(config config.BinaryFromImage, binaryPaths []string) bool { - currentFingerprint := config.Fingerprint() + currentDigest := config.Digest() for _, path := range binaryPaths { - fingerprintPath := path + ".fingerprint" - if _, err := os.Stat(fingerprintPath); err != nil { + digestPath := path + digestFileSuffix + if _, err := os.Stat(digestPath); err != nil { // missing a fingerprint file means the download is stale return true } - writtenFingerprint, err := os.ReadFile(fingerprintPath) + writtenDigest, err := os.ReadFile(digestPath) if err != nil { // missing a fingerprint file means the download is stale return true } - if string(writtenFingerprint) != currentFingerprint { + if string(writtenDigest) != currentDigest { // the fingerprint file does not match the current fingerprint, so the download is stale return true } @@ -103,6 +106,12 @@ func pullDockerImage(imageReference, platform string) error { cmd := exec.Command("docker", "pull", "--platform", platform, imageReference) err := cmd.Run() if err != nil { + // attach stderr to output message + var exitErr *exec.ExitError + if errors.As(err, &exitErr) && len(exitErr.Stderr) > 0 { + err = fmt.Errorf("pull failed: %w:\n%s", err, exitErr.Stderr) + } + a.Done(err) return err } @@ -152,6 +161,12 @@ func copyBinariesFromDockerImage(config config.BinaryFromImage, destination stri cmd := exec.Command("docker", "create", "--name", containerName, image.Reference) if err = cmd.Run(); err != nil { + // attach stderr to output message + var exitErr *exec.ExitError + if errors.As(err, &exitErr) && len(exitErr.Stderr) > 0 { + err = fmt.Errorf("%w:\n%s", err, exitErr.Stderr) + } + return err } @@ -162,7 +177,7 @@ func copyBinariesFromDockerImage(config config.BinaryFromImage, destination stri for i, destinationPath := range config.AllStorePathsForImage(image, destination) { path := config.PathsInImage[i] - if err := copyBinaryFromContainer(containerName, path, destinationPath, config.Fingerprint()); err != nil { + if err := copyBinaryFromContainer(containerName, path, destinationPath, config.Digest()); err != nil { return err } } @@ -170,7 +185,7 @@ func copyBinariesFromDockerImage(config config.BinaryFromImage, destination stri return nil } -func copyBinaryFromContainer(containerName, containerPath, destinationPath, fingerprint string) (err error) { +func copyBinaryFromContainer(containerName, containerPath, destinationPath, digest string) (err error) { a := ui.Action{Msg: fmt.Sprintf("extract %s", containerPath)} a.Start() @@ -185,13 +200,24 @@ func copyBinaryFromContainer(containerName, containerPath, destinationPath, fing cmd := exec.Command("docker", "cp", fmt.Sprintf("%s:%s", containerName, containerPath), destinationPath) //nolint:gosec // reason for gosec exception: this is for processing test fixtures only, not used in production if err := cmd.Run(); err != nil { + // attach stderr to output message + var exitErr *exec.ExitError + if errors.As(err, &exitErr) && len(exitErr.Stderr) > 0 { + err = fmt.Errorf("%w:\n%s", err, exitErr.Stderr) + } + return err } - // capture fingerprint file - fingerprintPath := destinationPath + ".fingerprint" - if err := os.WriteFile(fingerprintPath, []byte(fingerprint), 0600); err != nil { - return fmt.Errorf("unable to write fingerprint file: %w", err) + // ensure permissions are 600 for destination + if err := os.Chmod(destinationPath, 0600); err != nil { + return fmt.Errorf("unable to set permissions on file %q: %w", destinationPath, err) + } + + // capture digest file + digestPath := destinationPath + digestFileSuffix + if err := os.WriteFile(digestPath, []byte(digest), 0600); err != nil { + return fmt.Errorf("unable to write digest file: %w", err) } return nil diff --git a/syft/pkg/cataloger/binary/test-fixtures/manager/internal/download_from_image_test.go b/syft/pkg/cataloger/binary/test-fixtures/manager/internal/download_from_image_test.go index ca62ea5476a..fc097a7dbf6 100644 --- a/syft/pkg/cataloger/binary/test-fixtures/manager/internal/download_from_image_test.go +++ b/syft/pkg/cataloger/binary/test-fixtures/manager/internal/download_from_image_test.go @@ -14,35 +14,35 @@ import ( func TestIsDownloadStale(t *testing.T) { cases := []struct { - name string - fingerprint string - expected bool + name string + digest string + expected bool }{ { - name: "no fingerprint", - fingerprint: "", - expected: true, + name: "no digest", + digest: "", + expected: true, }, { - name: "fingerprint matches", - // this is the fingerprint for config in the loop body - fingerprint: "5177d458eaca031ea16fa707841043df2e31b89be6bae7ea41290aa32f0251a6", - expected: false, + name: "digest matches", + // this is the digest for config in the loop body + digest: "c9c8007f9c55c2f1", + expected: false, }, { - name: "fingerprint does not match", - fingerprint: "fingerprint", - expected: true, + name: "digest does not match", + digest: "bogus", + expected: true, }, } for _, tt := range cases { t.Run(tt.name, func(t *testing.T) { binaryPath := filepath.Join(t.TempDir(), "binary") - fh, err := os.Create(binaryPath + ".fingerprint") + fh, err := os.Create(binaryPath + digestFileSuffix) require.NoError(t, err) - fh.Write([]byte(tt.fingerprint)) + fh.Write([]byte(tt.digest)) require.NoError(t, fh.Close()) cfg := config.BinaryFromImage{ diff --git a/syft/pkg/cataloger/binary/test-fixtures/manager/internal/list_entries.go b/syft/pkg/cataloger/binary/test-fixtures/manager/internal/list_entries.go index 7d6c2063045..9ecf254401e 100644 --- a/syft/pkg/cataloger/binary/test-fixtures/manager/internal/list_entries.go +++ b/syft/pkg/cataloger/binary/test-fixtures/manager/internal/list_entries.go @@ -170,7 +170,7 @@ func getLogicalKey(managedBinaryPath string) (*LogicalEntryKey, error) { func allFilePaths(root string) ([]string, error) { var paths []string err := filepath.Walk(root, func(path string, info os.FileInfo, _ error) error { - if info != nil && !info.IsDir() && !strings.HasSuffix(path, ".fingerprint") { + if info != nil && !info.IsDir() && !strings.HasSuffix(path, digestFileSuffix) { paths = append(paths, path) } return nil diff --git a/syft/pkg/cataloger/gentoo/cataloger_test.go b/syft/pkg/cataloger/gentoo/cataloger_test.go index f2deeb199b4..6fb80e78078 100644 --- a/syft/pkg/cataloger/gentoo/cataloger_test.go +++ b/syft/pkg/cataloger/gentoo/cataloger_test.go @@ -64,7 +64,7 @@ func TestPortageCataloger(t *testing.T) { var expectedRelationships []artifact.Relationship pkgtest.NewCatalogTester(). - FromDirectory(t, "test-fixtures/image-portage"). + FromDirectory(t, "test-fixtures/layout"). Expects(expectedPkgs, expectedRelationships). TestCataloger(t, NewPortageCataloger()) diff --git a/syft/pkg/cataloger/gentoo/test-fixtures/image-portage/var/db/pkg/app-containers/skopeo-1.5.1/CONTENTS b/syft/pkg/cataloger/gentoo/test-fixtures/layout/var/db/pkg/app-containers/skopeo-1.5.1/CONTENTS similarity index 100% rename from syft/pkg/cataloger/gentoo/test-fixtures/image-portage/var/db/pkg/app-containers/skopeo-1.5.1/CONTENTS rename to syft/pkg/cataloger/gentoo/test-fixtures/layout/var/db/pkg/app-containers/skopeo-1.5.1/CONTENTS diff --git a/syft/pkg/cataloger/gentoo/test-fixtures/image-portage/var/db/pkg/app-containers/skopeo-1.5.1/LICENSE b/syft/pkg/cataloger/gentoo/test-fixtures/layout/var/db/pkg/app-containers/skopeo-1.5.1/LICENSE similarity index 100% rename from syft/pkg/cataloger/gentoo/test-fixtures/image-portage/var/db/pkg/app-containers/skopeo-1.5.1/LICENSE rename to syft/pkg/cataloger/gentoo/test-fixtures/layout/var/db/pkg/app-containers/skopeo-1.5.1/LICENSE diff --git a/syft/pkg/cataloger/gentoo/test-fixtures/image-portage/var/db/pkg/app-containers/skopeo-1.5.1/SIZE b/syft/pkg/cataloger/gentoo/test-fixtures/layout/var/db/pkg/app-containers/skopeo-1.5.1/SIZE similarity index 100% rename from syft/pkg/cataloger/gentoo/test-fixtures/image-portage/var/db/pkg/app-containers/skopeo-1.5.1/SIZE rename to syft/pkg/cataloger/gentoo/test-fixtures/layout/var/db/pkg/app-containers/skopeo-1.5.1/SIZE diff --git a/syft/pkg/cataloger/golang/test-fixtures/Makefile b/syft/pkg/cataloger/golang/test-fixtures/Makefile new file mode 100644 index 00000000000..da3e730e131 --- /dev/null +++ b/syft/pkg/cataloger/golang/test-fixtures/Makefile @@ -0,0 +1,15 @@ +.DEFAULT_GOAL := default + +default: + @for dir in $(shell find . -mindepth 1 -maxdepth 1 -type d); do \ + if [ -f "$$dir/Makefile" ]; then \ + $(MAKE) -C $$dir; \ + fi; \ + done + +%: + @for dir in $(shell find . -mindepth 1 -maxdepth 1 -type d); do \ + if [ -f "$$dir/Makefile" ]; then \ + $(MAKE) -C $$dir $@; \ + fi; \ + done diff --git a/syft/pkg/cataloger/golang/test-fixtures/archs/Makefile b/syft/pkg/cataloger/golang/test-fixtures/archs/Makefile index 60eee7ff96a..872f2be9176 100644 --- a/syft/pkg/cataloger/golang/test-fixtures/archs/Makefile +++ b/syft/pkg/cataloger/golang/test-fixtures/archs/Makefile @@ -1,29 +1,39 @@ DESTINATION=binaries +FINGERPRINT_FILE=$(DESTINATION).fingerprint -all: $(DESTINATION)/hello-mach-o-arm64 $(DESTINATION)/hello-linux-arm $(DESTINATION)/hello-linux-ppc64le $(DESTINATION)/hello-win-amd64 +ifndef DESTINATION + $(error DESTINATION is not set) +endif + +.DEFAULT_GOAL := fixtures + +# requirement 1: 'fixtures' goal to generate any and all test fixtures +fixtures: $(DESTINATION) + +# requirement 2: 'fingerprint' goal to determine if the fixture input that indicates any existing cache should be busted +fingerprint: $(DESTINATION).fingerprint + +$(DESTINATION): $(DESTINATION)/hello-mach-o-arm64 $(DESTINATION)/hello-linux-arm $(DESTINATION)/hello-linux-ppc64le $(DESTINATION)/hello-win-amd64 $(DESTINATION)/hello-mach-o-arm64: - mkdir -p $(DESTINATION) GOARCH=arm64 GOOS=darwin ./src/build.sh $(DESTINATION)/hello-mach-o-arm64 $(DESTINATION)/hello-linux-arm: - mkdir -p $(DESTINATION) GOARCH=arm GOOS=linux ./src/build.sh $(DESTINATION)/hello-linux-arm $(DESTINATION)/hello-linux-ppc64le: - mkdir -p $(DESTINATION) GOARCH=ppc64le GOOS=linux ./src/build.sh $(DESTINATION)/hello-linux-ppc64le $(DESTINATION)/hello-win-amd64: - mkdir -p $(DESTINATION) GOARCH=amd64 GOOS=windows ./src/build.sh $(DESTINATION)/hello-win-amd64 -# we need a way to determine if CI should bust the test cache based on the source material -$(DESTINATION).fingerprint: clean - mkdir -p $(DESTINATION) - find src -type f -exec sha256sum {} \; | sort | tee /dev/stderr | tee $(DESTINATION).fingerprint - sha256sum $(DESTINATION).fingerprint +# requirement 3: we always need to recalculate the fingerprint based on source regardless of any existing fingerprint +.PHONY: $(FINGERPRINT_FILE) +$(FINGERPRINT_FILE): + @find src -type f -exec sha256sum {} \; | sort -k2 > $(FINGERPRINT_FILE) + @#cat $(FINGERPRINT_FILE) | sha256sum | awk '{print $$1}' +# requirement 4: 'clean' goal to remove all generated test fixtures .PHONY: clean clean: - rm -f $(DESTINATION)/* + rm -rf $(DESTINATION) diff --git a/syft/pkg/cataloger/golang/test-fixtures/archs/src/build.sh b/syft/pkg/cataloger/golang/test-fixtures/archs/src/build.sh index 8a3919470b3..a740b7dba02 100755 --- a/syft/pkg/cataloger/golang/test-fixtures/archs/src/build.sh +++ b/syft/pkg/cataloger/golang/test-fixtures/archs/src/build.sh @@ -1,10 +1,13 @@ #!/usr/bin/env bash -set -uxe +set -ue # note: this can be easily done in a 1-liner, however circle CI does NOT allow volume mounts from the host in docker executors (since they are on remote hosts, where the host files are inaccessible) # note: gocache override is so we can run docker build not as root in a container without permission issues BINARY=$1 + +mkdir -p "$(dirname "$BINARY")" + CTRID=$(docker create -e GOOS="${GOOS}" -e GOARCH="${GOARCH}" -u "$(id -u):$(id -g)" -e GOCACHE=/tmp -w /src golang:1.17 go build -o main main.go) function cleanup() { diff --git a/syft/pkg/cataloger/java/test-fixtures/Makefile b/syft/pkg/cataloger/java/test-fixtures/Makefile new file mode 100644 index 00000000000..da3e730e131 --- /dev/null +++ b/syft/pkg/cataloger/java/test-fixtures/Makefile @@ -0,0 +1,15 @@ +.DEFAULT_GOAL := default + +default: + @for dir in $(shell find . -mindepth 1 -maxdepth 1 -type d); do \ + if [ -f "$$dir/Makefile" ]; then \ + $(MAKE) -C $$dir; \ + fi; \ + done + +%: + @for dir in $(shell find . -mindepth 1 -maxdepth 1 -type d); do \ + if [ -f "$$dir/Makefile" ]; then \ + $(MAKE) -C $$dir $@; \ + fi; \ + done diff --git a/syft/pkg/cataloger/java/test-fixtures/jar-metadata/Makefile b/syft/pkg/cataloger/java/test-fixtures/jar-metadata/Makefile index 98083904234..cf0d21a8672 100644 --- a/syft/pkg/cataloger/java/test-fixtures/jar-metadata/Makefile +++ b/syft/pkg/cataloger/java/test-fixtures/jar-metadata/Makefile @@ -1,5 +1,10 @@ CACHE_DIR = cache CACHE_PATH = $(shell pwd)/cache +FINGERPRINT_FILE=$(CACHE_DIR).fingerprint + +ifndef CACHE_DIR + $(error CACHE_DIR is not set) +endif JACKSON_CORE = jackson-core-2.15.2 SBT_JACKSON_CORE = com.fasterxml.jackson.core.jackson-core-2.15.2 @@ -8,28 +13,53 @@ API_ALL_SOURCES = api-all-2.0.0-sources SPRING_INSTRUMENTATION = spring-instrumentation-4.3.0-1.0 MULTIPLE_MATCHING = multiple-matching-2.11.5 -$(CACHE_DIR): - mkdir -p $(CACHE_DIR) -$(CACHE_DIR)/$(JACKSON_CORE).jar: $(CACHE_DIR) +.DEFAULT_GOAL := fixtures + +# requirement 1: 'fixtures' goal to generate any and all test fixtures +fixtures: $(CACHE_DIR) + +# requirement 2: 'fingerprint' goal to determine if the fixture input that indicates any existing cache should be busted +fingerprint: $(FINGERPRINT_FILE) + +$(CACHE_DIR): $(CACHE_DIR)/$(JACKSON_CORE).jar $(CACHE_DIR)/$(SBT_JACKSON_CORE).jar $(CACHE_DIR)/$(OPENSAML_CORE).jar $(CACHE_DIR)/$(API_ALL_SOURCES).jar $(CACHE_DIR)/$(SPRING_INSTRUMENTATION).jar $(CACHE_DIR)/$(MULTIPLE_MATCHING).jar + +$(CACHE_DIR)/$(JACKSON_CORE).jar: + mkdir -p $(CACHE_DIR) cd $(JACKSON_CORE) && zip -r $(CACHE_PATH)/$(JACKSON_CORE).jar . -$(CACHE_DIR)/$(SBT_JACKSON_CORE).jar: $(CACHE_DIR) +$(CACHE_DIR)/$(SBT_JACKSON_CORE).jar: + mkdir -p $(CACHE_DIR) cd $(SBT_JACKSON_CORE) && zip -r $(CACHE_PATH)/$(SBT_JACKSON_CORE).jar . -$(CACHE_DIR)/$(OPENSAML_CORE).jar: $(CACHE_DIR) +$(CACHE_DIR)/$(OPENSAML_CORE).jar: + mkdir -p $(CACHE_DIR) cd $(OPENSAML_CORE) && zip -r $(CACHE_PATH)/$(OPENSAML_CORE).jar . -$(CACHE_DIR)/$(API_ALL_SOURCES).jar: $(CACHE_DIR) +$(CACHE_DIR)/$(API_ALL_SOURCES).jar: + mkdir -p $(CACHE_DIR) cd $(API_ALL_SOURCES) && zip -r $(CACHE_PATH)/$(API_ALL_SOURCES).jar . -$(CACHE_DIR)/$(SPRING_INSTRUMENTATION).jar: $(CACHE_DIR) +$(CACHE_DIR)/$(SPRING_INSTRUMENTATION).jar: + mkdir -p $(CACHE_DIR) cd $(SPRING_INSTRUMENTATION) && zip -r $(CACHE_PATH)/$(SPRING_INSTRUMENTATION).jar . -$(CACHE_DIR)/$(MULTIPLE_MATCHING).jar: $(CACHE_DIR) +$(CACHE_DIR)/$(MULTIPLE_MATCHING).jar: + mkdir -p $(CACHE_DIR) cd $(MULTIPLE_MATCHING) && zip -r $(CACHE_PATH)/$(MULTIPLE_MATCHING).jar . # Jenkins plugins typically do not have the version included in the archive name, # so it is important to not include it in the generated test fixture -$(CACHE_DIR)/gradle.hpi: $(CACHE_DIR) - cd jenkins-plugins/gradle/2.11 && zip -r $(CACHE_PATH)/gradle.hpi . \ No newline at end of file +$(CACHE_DIR)/gradle.hpi: + mkdir -p $(CACHE_DIR) + cd jenkins-plugins/gradle/2.11 && zip -r $(CACHE_PATH)/gradle.hpi . + +# requirement 3: we always need to recalculate the fingerprint based on source regardless of any existing fingerprint +.PHONY: $(FINGERPRINT_FILE) +$(FINGERPRINT_FILE): + @find . ! -path '*/cache*' -type f -exec sha256sum {} \; | sort -k2 > $(FINGERPRINT_FILE) + @#cat $(FINGERPRINT_FILE) | sha256sum | awk '{print $$1}' + +# requirement 4: 'clean' goal to remove all generated test fixtures +clean: + rm -rf $(CACHE_DIR)/* $(FINGERPRINT_FILE) diff --git a/syft/pkg/cataloger/java/test-fixtures/java-builds/Makefile b/syft/pkg/cataloger/java/test-fixtures/java-builds/Makefile index 1970b42f805..b3aae020a24 100644 --- a/syft/pkg/cataloger/java/test-fixtures/java-builds/Makefile +++ b/syft/pkg/cataloger/java/test-fixtures/java-builds/Makefile @@ -1,17 +1,18 @@ PKGSDIR=packages +FINGERPRINT_FILE=$(PKGSDIR).fingerprint ifndef PKGSDIR $(error PKGSDIR is not set) endif -all: jars archives native-image -clean: clean-examples - rm -f $(PKGSDIR)/* +.DEFAULT_GOAL := fixtures -clean-examples: clean-gradle clean-maven clean-jenkins clean-nestedjar +# requirement 1: 'fixtures' goal to generate any and all test fixtures +fixtures: jars archives native-image -.PHONY: maven gradle clean clean-gradle clean-maven clean-jenkins clean-examples clean-nestedjar jars archives +# requirement 2: 'fingerprint' goal to determine if the fixture input that indicates any existing cache should be busted +fingerprint: $(FINGERPRINT_FILE) jars: $(PKGSDIR)/example-java-app-maven-0.1.0.jar $(PKGSDIR)/example-java-app-gradle-0.1.0.jar $(PKGSDIR)/example-jenkins-plugin.hpi $(PKGSDIR)/spring-boot-0.0.1-SNAPSHOT.jar @@ -71,8 +72,16 @@ $(PKGSDIR)/example-java-app: $(PKGSDIR)/example-java-app-maven-0.1.0.jar $(PKGSDIR)/gcc-amd64-darwin-exec-debug: ./build-example-macho-binary.sh $(PKGSDIR) -# we need a way to determine if CI should bust the test cache based on the source material -.PHONY: cache.fingerprint -cache.fingerprint: - find example* build* gradle* Makefile -type f -exec sha256sum {} \; | sort | tee /dev/stderr | tee cache.fingerprint - sha256sum cache.fingerprint +# requirement 3: we always need to recalculate the fingerprint based on source regardless of any existing fingerprint +.PHONY: $(FINGERPRINT_FILE) +$(FINGERPRINT_FILE): + @find example-* build-* Makefile -type f -exec sha256sum {} \; | sort -k2 > $(FINGERPRINT_FILE) + @#cat $(FINGERPRINT_FILE) | sha256sum | awk '{print $$1}' + +# requirement 4: 'clean' goal to remove all generated test fixtures +clean: clean-examples + rm -rf $(PKGSDIR) $(FINGERPRINT_FILE) + +clean-examples: clean-gradle clean-maven clean-jenkins clean-nestedjar + +.PHONY: maven gradle clean clean-gradle clean-maven clean-jenkins clean-examples clean-nestedjar jars archives diff --git a/syft/pkg/cataloger/kernel/test-fixtures/Makefile b/syft/pkg/cataloger/kernel/test-fixtures/Makefile index 4a2849919c3..a2c19cf9f4e 100644 --- a/syft/pkg/cataloger/kernel/test-fixtures/Makefile +++ b/syft/pkg/cataloger/kernel/test-fixtures/Makefile @@ -1,7 +1,21 @@ -all: +FINGERPRINT_FILE=cache.fingerprint -# we need a way to determine if CI should bust the test cache based on the source material -.PHONY: cache.fingerprint -cache.fingerprint: - find Makefile **/Dockerfile -type f -exec sha256sum {} \; | sort | tee /dev/stderr | tee cache.fingerprint - sha256sum cache.fingerprint + +.DEFAULT_GOAL := fixtures + +# requirement 1: 'fixtures' goal to generate any and all test fixtures +fixtures: + @echo "nothing to do" + +# requirement 2: 'fingerprint' goal to determine if the fixture input that indicates any existing cache should be busted +fingerprint: $(FINGERPRINT_FILE) + +# requirement 3: we always need to recalculate the fingerprint based on source regardless of any existing fingerprint +.PHONY: $(FINGERPRINT_FILE) +$(FINGERPRINT_FILE): + @find Makefile **/Dockerfile -type f -exec sha256sum {} \; | sort -k2 > $(FINGERPRINT_FILE) + @#cat $(FINGERPRINT_FILE) | sha256sum | awk '{print $$1}' + +# requirement 4: 'clean' goal to remove all generated test fixtures +clean: + rm -f $(FINGERPRINT_FILE) diff --git a/syft/pkg/cataloger/python/test-fixtures/image-multi-site-package/Dockerfile b/syft/pkg/cataloger/python/test-fixtures/image-multi-site-package/Dockerfile index 3895cebbd96..7a8b39c984f 100644 --- a/syft/pkg/cataloger/python/test-fixtures/image-multi-site-package/Dockerfile +++ b/syft/pkg/cataloger/python/test-fixtures/image-multi-site-package/Dockerfile @@ -1,9 +1,8 @@ # digest is for linux/amd64 -FROM ubuntu:20.04@sha256:cc9cc8169c9517ae035cf293b15f06922cb8c6c864d625a72b7b18667f264b70 +FROM ubuntu:20.04@sha256:cc9cc8169c9517ae035cf293b15f06922cb8c6c864d625a72b7b18667f264b70 AS base # install Python 3.8 and Python 3.9 -ENV DEBIAN_FRONTEND=noninteractive -RUN apt-get update && apt-get install -y python3.8 python3.9 python3-pip python3-venv python3.9-venv python3.8-venv +RUN apt-get update && DEBIAN_FRONTEND=noninteractive apt-get install -y python3.8 python3.9 python3-pip python3-venv python3.9-venv python3.8-venv # install pip and virtualenv for both Python versions RUN python3.8 -m pip install --upgrade pip virtualenv @@ -35,3 +34,17 @@ RUN /app/project2/venv/bin/pip install click==8.0.3 pyyaml==6.0 RUN /app/project2/venv/bin/pip install inquirer==3.2.4 runs==1.2.2 xmod==1.8.1 six==1.16.0 wcwidth==0.2.13 blessed==1.20.0 editor==1.6.6 readchar==4.1.0 WORKDIR /app + +# let's not waste disk space... we only need the above state we've setup, not all of the os-level packages +RUN rm -rf /app/project1/venv/share +RUN rm -rf /app/project2/venv/share +RUN find /app/project1/venv/lib/python3.9/site-packages/* -type d ! -name '*.dist-info' -exec rm -rf {} + +RUN find /app/project2/venv/lib/python3.8/site-packages/* -type d ! -name '*.dist-info' -exec rm -rf {} + +RUN find /usr/local/lib/python3.8/dist-packages/* -type d ! -name '*.dist-info' -exec rm -rf {} + +RUN find /usr/local/lib/python3.9/dist-packages/* -type d ! -name '*.dist-info' -exec rm -rf {} + + +FROM scratch + +COPY --from=base /app/ /app/ +COPY --from=base /usr/local/lib/python3.8/ /usr/local/lib/python3.8/ +COPY --from=base /usr/local/lib/python3.9/ /usr/local/lib/python3.9/ diff --git a/syft/pkg/cataloger/redhat/test-fixtures/Makefile b/syft/pkg/cataloger/redhat/test-fixtures/Makefile index e280d5e60e7..2495210ab2d 100644 --- a/syft/pkg/cataloger/redhat/test-fixtures/Makefile +++ b/syft/pkg/cataloger/redhat/test-fixtures/Makefile @@ -1,21 +1,38 @@ RPMSDIR=rpms +FINGERPRINT_FILE=$(RPMSDIR).fingerprint ifndef RPMSDIR $(error RPMSDIR is not set) endif -all: rpms -clean: - rm -rf $(RPMSDIR) +.DEFAULT_GOAL := fixtures + +# requirement 1: 'fixtures' goal to generate any and all test fixtures +fixtures: rpms + +# requirement 2: 'fingerprint' goal to determine if the fixture input that indicates any existing cache should be busted +fingerprint: $(FINGERPRINT_FILE) rpms: mkdir -p $(RPMSDIR) - cd $(RPMSDIR) && curl https://dl.fedoraproject.org/pub/epel/7/x86_64/Packages/a/abc-1.01-9.hg20160905.el7.x86_64.rpm -O - cd $(RPMSDIR) && curl https://dl.fedoraproject.org/pub/epel/7/x86_64/Packages/z/zork-1.0.3-1.el7.x86_64.rpm -O - -# we need a way to determine if CI should bust the test cache based on the source material -.PHONY: $(RPMSDIR).fingerprint -$(RPMSDIR).fingerprint: - find Makefile -type f -exec sha256sum {} \; | sort | tee /dev/stderr | tee $(RPMSDIR).fingerprint - sha256sum $(RPMSDIR).fingerprint + @# see note from https://dl.fedoraproject.org/pub/epel/7/README + @# ATTENTION + @# ====================================== + @# The contents of this directory have been moved to our archives available at: + @# + @# http://archives.fedoraproject.org/pub/archive/epel/ + + cd $(RPMSDIR) && curl -LO https://archives.fedoraproject.org/pub/archive/epel/7/x86_64/Packages/a/abc-1.01-9.hg20160905.el7.x86_64.rpm + cd $(RPMSDIR) && curl -LO https://archives.fedoraproject.org/pub/archive/epel/7/x86_64/Packages/z/zork-1.0.3-1.el7.x86_64.rpm + +# requirement 3: we always need to recalculate the fingerprint based on source regardless of any existing fingerprint +.PHONY: $(FINGERPRINT_FILE) +$(FINGERPRINT_FILE): + @find Makefile -type f -exec sha256sum {} \; | sort -k2 > $(FINGERPRINT_FILE) + @#cat $(FINGERPRINT_FILE) | sha256sum | awk '{print $$1}' + +# requirement 4: 'clean' goal to remove all generated test fixtures +.PHONY: clean +clean: + rm -rf $(RPMSDIR) $(FINGERPRINT_FILE) diff --git a/syft/pkg/cataloger/redhat/test-fixtures/image-minimal/Dockerfile b/syft/pkg/cataloger/redhat/test-fixtures/image-minimal/Dockerfile index cda80c34964..6e01032f301 100644 --- a/syft/pkg/cataloger/redhat/test-fixtures/image-minimal/Dockerfile +++ b/syft/pkg/cataloger/redhat/test-fixtures/image-minimal/Dockerfile @@ -2,4 +2,8 @@ FROM rockylinux:9.3.20231119@sha256:45cc42828cc5ceeffa3a9b4f6363fb582fac3ab91f77bf403daa067f8f049f96 ADD remove.sh /remove.sh -RUN /remove.sh \ No newline at end of file +RUN /remove.sh + +# let's only keep what we need for testing (not the intermediate layers) +FROM scratch +COPY --from=0 / / diff --git a/test/cli/.gitignore b/test/cli/.gitignore new file mode 100644 index 00000000000..872aa273a4e --- /dev/null +++ b/test/cli/.gitignore @@ -0,0 +1 @@ +results \ No newline at end of file diff --git a/test/cli/cyclonedx_valid_test.go b/test/cli/cyclonedx_valid_test.go index 49755f0bc5e..4f2ce11ed98 100644 --- a/test/cli/cyclonedx_valid_test.go +++ b/test/cli/cyclonedx_valid_test.go @@ -33,7 +33,7 @@ func TestValidCycloneDX(t *testing.T) { { name: "validate cyclonedx output", subcommand: "scan", - args: []string{"-o", "cyclonedx-json"}, + args: []string{"-o", "cyclonedx-json", "-o", "cyclonedx-json=results/sbom.cdx.json"}, fixture: imageFixture, assertions: []traitAssertion{ assertSuccessfulReturnCode, diff --git a/test/cli/scan_cmd_test.go b/test/cli/scan_cmd_test.go index 555f0856b61..ed84933ffad 100644 --- a/test/cli/scan_cmd_test.go +++ b/test/cli/scan_cmd_test.go @@ -143,8 +143,22 @@ func TestPackagesCmdFlags(t *testing.T) { name: "squashed-scope-flag-hidden-packages", args: []string{"scan", "-o", "json", "-s", "squashed", hiddenPackagesImage}, assertions: []traitAssertion{ - assertPackageCount(162), - assertNotInOutput("vsftpd"), // hidden package + assertPackageCount(14), + // package 1: alpine-baselayout-data@3.6.5-r0 (apk) + // package 2: alpine-baselayout@3.6.5-r0 (apk) + // package 3: alpine-keys@2.4-r1 (apk) + // package 4: apk-tools@2.14.4-r0 (apk) + // package 5: busybox-binsh@1.36.1-r29 (apk) + // package 6: busybox@1.36.1-r29 (apk) + // package 7: ca-certificates-bundle@20240705-r0 (apk) + // package 8: libcrypto3@3.3.1-r3 (apk) + // package 9: libssl3@3.3.1-r3 (apk) + // package 10: musl-utils@1.2.5-r0 (apk) + // package 11: musl@1.2.5-r0 (apk) + // package 12: scanelf@1.3.7-r2 (apk) + // package 13: ssl_client@1.36.1-r29 (apk) + // package 14: zlib@1.3.1-r1 (apk) + assertNotInOutput(`"name":"curl"`), // hidden package assertSuccessfulReturnCode, }, }, @@ -152,9 +166,33 @@ func TestPackagesCmdFlags(t *testing.T) { name: "all-layers-scope-flag", args: []string{"scan", "-o", "json", "-s", "all-layers", hiddenPackagesImage}, assertions: []traitAssertion{ - assertPackageCount(163), // packages are now deduplicated for this case + assertPackageCount(24), + // package 1: alpine-baselayout-data@3.6.5-r0 (apk) + // package 2: alpine-baselayout@3.6.5-r0 (apk) + // package 3: alpine-keys@2.4-r1 (apk) + // package 4: apk-tools@2.14.4-r0 (apk) + // package 5: brotli-libs@1.1.0-r2 (apk) + // package 6: busybox-binsh@1.36.1-r29 (apk) + // package 7: busybox@1.36.1-r29 (apk) + // package 8: c-ares@1.28.1-r0 (apk) + // package 9: ca-certificates-bundle@20240705-r0 (apk) + // package 10: ca-certificates@20240705-r0 (apk) + // package 11: curl@8.9.1-r1 (apk) + // package 12: libcrypto3@3.3.1-r3 (apk) + // package 13: libcurl@8.9.1-r1 (apk) + // package 14: libidn2@2.3.7-r0 (apk) + // package 15: libpsl@0.21.5-r1 (apk) + // package 16: libssl3@3.3.1-r3 (apk) + // package 17: libunistring@1.2-r0 (apk) + // package 18: musl-utils@1.2.5-r0 (apk) + // package 19: musl@1.2.5-r0 (apk) + // package 20: nghttp2-libs@1.62.1-r0 (apk) + // package 21: scanelf@1.3.7-r2 (apk) + // package 22: ssl_client@1.36.1-r29 (apk) + // package 23: zlib@1.3.1-r1 (apk) + // package 24: zstd-libs@1.5.6-r0 (apk) assertInOutput("all-layers"), - assertInOutput("vsftpd"), // hidden package + assertInOutput(`"name":"curl"`), // hidden package assertSuccessfulReturnCode, }, }, @@ -165,9 +203,9 @@ func TestPackagesCmdFlags(t *testing.T) { "SYFT_SCOPE": "all-layers", }, assertions: []traitAssertion{ - assertPackageCount(163), // packages are now deduplicated for this case + assertPackageCount(24), // packages are now deduplicated for this case assertInOutput("all-layers"), - assertInOutput("vsftpd"), // hidden package + assertInOutput(`"name":"curl"`), // hidden package assertSuccessfulReturnCode, }, }, diff --git a/test/cli/test-fixtures/Makefile b/test/cli/test-fixtures/Makefile index 5042a5aad65..ff1de637eb7 100644 --- a/test/cli/test-fixtures/Makefile +++ b/test/cli/test-fixtures/Makefile @@ -1,6 +1,22 @@ -# change these if you want CI to not use previous stored cache -CLI_CACHE_BUSTER := "e5cdfd8" +FINGERPRINT_FILE=cache.fingerprint + +.DEFAULT_GOAL := fixtures + +# requirement 1: 'fixtures' goal to generate any and all test fixtures +fixtures: + @echo "nothing to do" + +# requirement 2: 'fingerprint' goal to determine if the fixture input that indicates any existing cache should be busted +fingerprint: $(FINGERPRINT_FILE) + +# requirement 3: we always need to recalculate the fingerprint based on source regardless of any existing fingerprint +.PHONY: $(FINGERPRINT_FILE) +$(FINGERPRINT_FILE): + @find image-* -type f -exec sha256sum {} \; | sort -k2 > $(FINGERPRINT_FILE) + @#cat $(FINGERPRINT_FILE) | sha256sum | awk '{print $$1}' + +# requirement 4: 'clean' goal to remove all generated test fixtures +.PHONY: clean +clean: + rm -f $(FINGERPRINT_FILE) -.PHONY: cache.fingerprint -cache.fingerprint: - find image-* -type f -exec md5sum {} + | awk '{print $1}' | sort | md5sum | tee cache.fingerprint && echo "$(CLI_CACHE_BUSTER)" >> cache.fingerprint diff --git a/test/cli/test-fixtures/image-hidden-packages/Dockerfile b/test/cli/test-fixtures/image-hidden-packages/Dockerfile index 1150209e8b2..07b7f32754e 100644 --- a/test/cli/test-fixtures/image-hidden-packages/Dockerfile +++ b/test/cli/test-fixtures/image-hidden-packages/Dockerfile @@ -1,4 +1,4 @@ -FROM centos:7.9.2009@sha256:dead07b4d8ed7e29e98de0f4504d87e8880d4347859d839686a31da35a3b532f -# all-layers scope should pickup on vsftpd -RUN yum install -y vsftpd -RUN yum remove -y vsftpd +FROM --platform=linux/amd64 alpine:3.20.2@sha256:eddacbc7e24bf8799a4ed3cdcfa50d4b88a323695ad80f317b6629883b2c2a78 + +RUN apk add --no-cache curl +RUN apk del curl diff --git a/test/install/Makefile b/test/install/Makefile index 2a632cd2825..9d26ebc6364 100644 --- a/test/install/Makefile +++ b/test/install/Makefile @@ -1,5 +1,7 @@ NAME=syft +FINGERPRINT_FILE := cache.fingerprint + # for local testing (not testing within containers) use the binny-managed version of cosign. # this also means that the user does not need to install cosign on their system to run tests. COSIGN_BINARY=../../.tool/cosign @@ -21,8 +23,6 @@ ACCEPTANCE_CMD=sh -c '../../install.sh -v -b /usr/local/bin && syft version && r PREVIOUS_RELEASE=v0.33.0 ACCEPTANCE_PREVIOUS_RELEASE_CMD=sh -c "../../install.sh -b /usr/local/bin $(PREVIOUS_RELEASE) && syft version" -# CI cache busting values; change these if you want CI to not use previous stored cache -INSTALL_TEST_CACHE_BUSTER=894d8ca define title @printf '\n≡≡≡[ $(1) ]≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡\n' @@ -130,7 +130,8 @@ busybox-1.36: ## For CI ######################################################## -.PHONY: cache.fingerprint -cache.fingerprint: - $(call title,Install test fixture fingerprint) - @find ./environments/* -type f -exec md5sum {} + | awk '{print $1}' | sort | tee /dev/stderr | md5sum | tee cache.fingerprint && echo "$(INSTALL_TEST_CACHE_BUSTER)" >> cache.fingerprint +# requirement 3: we always need to recalculate the fingerprint based on source regardless of any existing fingerprint +.PHONY: $(FINGERPRINT_FILE) +$(FINGERPRINT_FILE): + @find ./environments/* -type f -exec sha256sum {} \; | sort -k2 > $(FINGERPRINT_FILE) + @#cat $(FINGERPRINT_FILE) | sha256sum | awk '{print $$1}' From b153b1d5949dda172817289ca8b57c2474c6a5e0 Mon Sep 17 00:00:00 2001 From: Alex Goodman Date: Mon, 9 Sep 2024 11:27:59 -0400 Subject: [PATCH 109/122] less verbose java logging when non-fatal issues arise (#3208) Signed-off-by: Alex Goodman --- syft/pkg/cataloger/java/archive_filename.go | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/syft/pkg/cataloger/java/archive_filename.go b/syft/pkg/cataloger/java/archive_filename.go index cc377e43874..b753def1d3a 100644 --- a/syft/pkg/cataloger/java/archive_filename.go +++ b/syft/pkg/cataloger/java/archive_filename.go @@ -58,19 +58,19 @@ type archiveFilename struct { func getSubexp(matches []string, subexpName string, re *regexp.Regexp, raw string) string { if len(matches) < 1 { - log.Warnf("unexpectedly empty matches for archive '%s'", raw) + log.Tracef("unexpectedly empty matches for Java archive '%s'", raw) return "" } index := re.SubexpIndex(subexpName) if index < 1 { - log.Warnf("unexpected index of '%s' capture group for Java archive '%s'", subexpName, raw) + log.Tracef("unexpected index of '%s' capture group for Java archive '%s'", subexpName, raw) return "" } // Prevent out-of-range panic if len(matches) < index+1 { - log.Warnf("no match found for '%s' in '%s'", subexpName, matches[0]) + log.Tracef("no match found for '%s' in '%s' for Java archive", subexpName, matches[0]) return "" } From ba7bf6b85e416bfc2f3c73040f63390fee8f67d9 Mon Sep 17 00:00:00 2001 From: Alex Goodman Date: Mon, 9 Sep 2024 16:27:21 -0400 Subject: [PATCH 110/122] dont cleanup cache in forks (#3214) Signed-off-by: Alex Goodman --- .github/workflows/validations.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/validations.yaml b/.github/workflows/validations.yaml index 0ebca5c8235..0413e16371a 100644 --- a/.github/workflows/validations.yaml +++ b/.github/workflows/validations.yaml @@ -206,7 +206,7 @@ jobs: Cleanup-Cache: name: "Cleanup snapshot cache" - if: always() + if: github.event.pull_request.head.repo.full_name == github.repository runs-on: ubuntu-20.04 permissions: actions: write From f735a428ebc51aa6c9abfb4ced2e08952af7db56 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 9 Sep 2024 16:27:33 -0400 Subject: [PATCH 111/122] chore(deps): bump github.com/dave/jennifer from 1.7.0 to 1.7.1 (#3212) Bumps [github.com/dave/jennifer](https://github.com/dave/jennifer) from 1.7.0 to 1.7.1. - [Commits](https://github.com/dave/jennifer/compare/v1.7.0...v1.7.1) --- updated-dependencies: - dependency-name: github.com/dave/jennifer dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- go.mod | 2 +- go.sum | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/go.mod b/go.mod index f6fc5241121..8ebc9fd963d 100644 --- a/go.mod +++ b/go.mod @@ -26,7 +26,7 @@ require ( github.com/charmbracelet/bubbles v0.19.0 github.com/charmbracelet/bubbletea v1.0.0 github.com/charmbracelet/lipgloss v0.13.0 - github.com/dave/jennifer v1.7.0 + github.com/dave/jennifer v1.7.1 github.com/deitch/magic v0.0.0-20230404182410-1ff89d7342da github.com/distribution/reference v0.6.0 github.com/docker/docker v27.2.0+incompatible diff --git a/go.sum b/go.sum index 61e20d6dd3f..808dca0ec74 100644 --- a/go.sum +++ b/go.sum @@ -217,8 +217,8 @@ github.com/cpuguy83/go-md2man/v2 v2.0.4/go.mod h1:tgQtvFlXSQOSOSIRvRPT7W67SCa46t github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E= github.com/cyphar/filepath-securejoin v0.2.4 h1:Ugdm7cg7i6ZK6x3xDF1oEu1nfkyfH53EtKeQYTC3kyg= github.com/cyphar/filepath-securejoin v0.2.4/go.mod h1:aPGpWjXOXUn2NCNjFvBE6aRxGGx79pTxQpKOJNYHHl4= -github.com/dave/jennifer v1.7.0 h1:uRbSBH9UTS64yXbh4FrMHfgfY762RD+C7bUPKODpSJE= -github.com/dave/jennifer v1.7.0/go.mod h1:nXbxhEmQfOZhWml3D1cDK5M1FLnMSozpbFN/m3RmGZc= +github.com/dave/jennifer v1.7.1 h1:B4jJJDHelWcDhlRQxWeo0Npa/pYKBLrirAQoTN45txo= +github.com/dave/jennifer v1.7.1/go.mod h1:nXbxhEmQfOZhWml3D1cDK5M1FLnMSozpbFN/m3RmGZc= github.com/davecgh/go-spew v0.0.0-20161028175848-04cdfd42973b/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= From 2475f7f696cbfe654340e52e369f802ba2d0c9e9 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 9 Sep 2024 16:27:43 -0400 Subject: [PATCH 112/122] chore(deps): bump github.com/docker/docker (#3211) Bumps [github.com/docker/docker](https://github.com/docker/docker) from 27.2.0+incompatible to 27.2.1+incompatible. - [Release notes](https://github.com/docker/docker/releases) - [Commits](https://github.com/docker/docker/compare/v27.2.0...v27.2.1) --- updated-dependencies: - dependency-name: github.com/docker/docker dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- go.mod | 2 +- go.sum | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/go.mod b/go.mod index 8ebc9fd963d..ad588d080db 100644 --- a/go.mod +++ b/go.mod @@ -29,7 +29,7 @@ require ( github.com/dave/jennifer v1.7.1 github.com/deitch/magic v0.0.0-20230404182410-1ff89d7342da github.com/distribution/reference v0.6.0 - github.com/docker/docker v27.2.0+incompatible + github.com/docker/docker v27.2.1+incompatible github.com/dustin/go-humanize v1.0.1 github.com/elliotchance/phpserialize v1.4.0 github.com/facebookincubator/nvdtools v0.1.5 diff --git a/go.sum b/go.sum index 808dca0ec74..f48e183db60 100644 --- a/go.sum +++ b/go.sum @@ -233,8 +233,8 @@ github.com/docker/cli v27.1.1+incompatible h1:goaZxOqs4QKxznZjjBWKONQci/MywhtRv2 github.com/docker/cli v27.1.1+incompatible/go.mod h1:JLrzqnKDaYBop7H2jaqPtU4hHvMKP+vjCwu2uszcLI8= github.com/docker/distribution v2.8.3+incompatible h1:AtKxIZ36LoNK51+Z6RpzLpddBirtxJnzDrHLEKxTAYk= github.com/docker/distribution v2.8.3+incompatible/go.mod h1:J2gT2udsDAN96Uj4KfcMRqY0/ypR+oyYUYmja8H+y+w= -github.com/docker/docker v27.2.0+incompatible h1:Rk9nIVdfH3+Vz4cyI/uhbINhEZ/oLmc+CBXmH6fbNk4= -github.com/docker/docker v27.2.0+incompatible/go.mod h1:eEKB0N0r5NX/I1kEveEz05bcu8tLC/8azJZsviup8Sk= +github.com/docker/docker v27.2.1+incompatible h1:fQdiLfW7VLscyoeYEBz7/J8soYFDZV1u6VW6gJEjNMI= +github.com/docker/docker v27.2.1+incompatible/go.mod h1:eEKB0N0r5NX/I1kEveEz05bcu8tLC/8azJZsviup8Sk= github.com/docker/docker-credential-helpers v0.7.0 h1:xtCHsjxogADNZcdv1pKUHXryefjlVRqWqIhk/uXJp0A= github.com/docker/docker-credential-helpers v0.7.0/go.mod h1:rETQfLdHNT3foU5kuNkFR1R1V12OJRRO5lzt2D1b5X0= github.com/docker/go-connections v0.4.0 h1:El9xVISelRB7BuFusrZozjnkIM5YnzCViNKohAFqRJQ= From 16f89840fd6909dcd6d7f2a8d2f694864c633966 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 9 Sep 2024 16:27:52 -0400 Subject: [PATCH 113/122] chore(deps): bump modernc.org/sqlite from 1.32.0 to 1.33.0 (#3210) Bumps [modernc.org/sqlite](https://gitlab.com/cznic/sqlite) from 1.32.0 to 1.33.0. - [Commits](https://gitlab.com/cznic/sqlite/compare/v1.32.0...v1.33.0) --- updated-dependencies: - dependency-name: modernc.org/sqlite dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- go.mod | 2 +- go.sum | 14 ++------------ 2 files changed, 3 insertions(+), 13 deletions(-) diff --git a/go.mod b/go.mod index ad588d080db..3b3ec8e443d 100644 --- a/go.mod +++ b/go.mod @@ -81,7 +81,7 @@ require ( golang.org/x/mod v0.21.0 golang.org/x/net v0.28.0 gopkg.in/yaml.v3 v3.0.1 - modernc.org/sqlite v1.32.0 + modernc.org/sqlite v1.33.0 ) require google.golang.org/genproto v0.0.0-20231106174013-bbf56f31fb17 // indirect diff --git a/go.sum b/go.sum index f48e183db60..8581512a9e0 100644 --- a/go.sum +++ b/go.sum @@ -1348,14 +1348,8 @@ honnef.co/go/tools v0.0.0-20190523083050-ea95bdfd59fc/go.mod h1:rf3lG4BRIbNafJWh honnef.co/go/tools v0.0.1-2019.2.3/go.mod h1:a3bituU0lyd329TUQxRnasdCoJDkEUEAqEt0JzvZhAg= honnef.co/go/tools v0.0.1-2020.1.3/go.mod h1:X/FiERA/W4tHapMX5mGpAtMSVEeEUOyHaw9vFzvIQ3k= honnef.co/go/tools v0.0.1-2020.1.4/go.mod h1:X/FiERA/W4tHapMX5mGpAtMSVEeEUOyHaw9vFzvIQ3k= -modernc.org/cc/v4 v4.21.4 h1:3Be/Rdo1fpr8GrQ7IVw9OHtplU4gWbb+wNgeoBMmGLQ= -modernc.org/cc/v4 v4.21.4/go.mod h1:HM7VJTZbUCR3rV8EYBi9wxnJ0ZBRiGE5OeGXNA0IsLQ= -modernc.org/ccgo/v4 v4.19.2 h1:lwQZgvboKD0jBwdaeVCTouxhxAyN6iawF3STraAal8Y= -modernc.org/ccgo/v4 v4.19.2/go.mod h1:ysS3mxiMV38XGRTTcgo0DQTeTmAO4oCmJl1nX9VFI3s= modernc.org/fileutil v1.3.0 h1:gQ5SIzK3H9kdfai/5x41oQiKValumqNTDXMvKo62HvE= modernc.org/fileutil v1.3.0/go.mod h1:XatxS8fZi3pS8/hKG2GH/ArUogfxjpEKs3Ku3aK4JyQ= -modernc.org/gc/v2 v2.4.1 h1:9cNzOqPyMJBvrUipmynX0ZohMhcxPtMccYgGOJdOiBw= -modernc.org/gc/v2 v2.4.1/go.mod h1:wzN5dK1AzVGoH6XOzc3YZ+ey/jPgYHLuVckd62P0GYU= modernc.org/gc/v3 v3.0.0-20240107210532-573471604cb6 h1:5D53IMaUuA5InSeMu9eJtlQXS2NxAhyWQvkKEgXZhHI= modernc.org/gc/v3 v3.0.0-20240107210532-573471604cb6/go.mod h1:Qz0X07sNOR1jWYCrJMEnbW/X55x206Q7Vt4mz6/wHp4= modernc.org/libc v1.55.3 h1:AzcW1mhlPNrRtjS5sS+eW2ISCgSOLLNyFzRh/V3Qj/U= @@ -1364,12 +1358,8 @@ modernc.org/mathutil v1.6.0 h1:fRe9+AmYlaej+64JsEEhoWuAYBkOtQiMEU7n/XgfYi4= modernc.org/mathutil v1.6.0/go.mod h1:Ui5Q9q1TR2gFm0AQRqQUaBWFLAhQpCwNcuhBOSedWPo= modernc.org/memory v1.8.0 h1:IqGTL6eFMaDZZhEWwcREgeMXYwmW83LYW8cROZYkg+E= modernc.org/memory v1.8.0/go.mod h1:XPZ936zp5OMKGWPqbD3JShgd/ZoQ7899TUuQqxY+peU= -modernc.org/opt v0.1.3 h1:3XOZf2yznlhC+ibLltsDGzABUGVx8J6pnFMS3E4dcq4= -modernc.org/opt v0.1.3/go.mod h1:WdSiB5evDcignE70guQKxYUl14mgWtbClRi5wmkkTX0= -modernc.org/sortutil v1.2.0 h1:jQiD3PfS2REGJNzNCMMaLSp/wdMNieTbKX920Cqdgqc= -modernc.org/sortutil v1.2.0/go.mod h1:TKU2s7kJMf1AE84OoiGppNHJwvB753OYfNl2WRb++Ss= -modernc.org/sqlite v1.32.0 h1:6BM4uGza7bWypsw4fdLRsLxut6bHe4c58VeqjRgST8s= -modernc.org/sqlite v1.32.0/go.mod h1:UqoylwmTb9F+IqXERT8bW9zzOWN8qwAIcLdzeBZs4hA= +modernc.org/sqlite v1.33.0 h1:WWkA/T2G17okiLGgKAj4/RMIvgyMT19yQ038160IeYk= +modernc.org/sqlite v1.33.0/go.mod h1:9uQ9hF/pCZoYZK73D/ud5Z7cIRIILSZI8NdIemVMTX8= modernc.org/strutil v1.2.0 h1:agBi9dp1I+eOnxXeiZawM8F4LawKv4NzGWSaLfyeNZA= modernc.org/strutil v1.2.0/go.mod h1:/mdcBmfOibveCTBxUl5B5l6W+TTH1FXPLHZE6bTosX0= modernc.org/token v1.1.0 h1:Xl7Ap9dKaEs5kLoOQeQmPWevfnk/DM5qcLcYlA8ys6Y= From dafc6ad034340ee7027c37ca7996a47cd6ad519e Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 9 Sep 2024 16:28:01 -0400 Subject: [PATCH 114/122] chore(deps): bump github.com/charmbracelet/bubbles from 0.19.0 to 0.20.0 (#3209) Bumps [github.com/charmbracelet/bubbles](https://github.com/charmbracelet/bubbles) from 0.19.0 to 0.20.0. - [Release notes](https://github.com/charmbracelet/bubbles/releases) - [Changelog](https://github.com/charmbracelet/bubbles/blob/master/.goreleaser.yml) - [Commits](https://github.com/charmbracelet/bubbles/compare/v0.19.0...v0.20.0) --- updated-dependencies: - dependency-name: github.com/charmbracelet/bubbles dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- go.mod | 10 ++++------ go.sum | 20 ++++++++------------ 2 files changed, 12 insertions(+), 18 deletions(-) diff --git a/go.mod b/go.mod index 3b3ec8e443d..23cca47d1bb 100644 --- a/go.mod +++ b/go.mod @@ -23,8 +23,8 @@ require ( // go: warning: github.com/andybalholm/brotli@v1.0.1: retracted by module author: occasional panics and data corruption github.com/aquasecurity/go-pep440-version v0.0.0-20210121094942-22b2f8951d46 github.com/bmatcuk/doublestar/v4 v4.6.1 - github.com/charmbracelet/bubbles v0.19.0 - github.com/charmbracelet/bubbletea v1.0.0 + github.com/charmbracelet/bubbles v0.20.0 + github.com/charmbracelet/bubbletea v1.1.0 github.com/charmbracelet/lipgloss v0.13.0 github.com/dave/jennifer v1.7.1 github.com/deitch/magic v0.0.0-20230404182410-1ff89d7342da @@ -111,10 +111,8 @@ require ( github.com/aymanbagabas/go-osc52/v2 v2.0.1 // indirect github.com/becheran/wildmatch-go v1.0.0 // indirect github.com/charmbracelet/harmonica v0.2.0 // indirect - github.com/charmbracelet/x/ansi v0.1.4 // indirect - github.com/charmbracelet/x/input v0.1.0 // indirect - github.com/charmbracelet/x/term v0.1.1 // indirect - github.com/charmbracelet/x/windows v0.1.0 // indirect + github.com/charmbracelet/x/ansi v0.2.3 // indirect + github.com/charmbracelet/x/term v0.2.0 // indirect github.com/cloudflare/circl v1.3.8 // indirect github.com/containerd/cgroups v1.1.0 // indirect github.com/containerd/containerd v1.7.11 // indirect diff --git a/go.sum b/go.sum index 8581512a9e0..6eaf663a342 100644 --- a/go.sum +++ b/go.sum @@ -157,22 +157,18 @@ github.com/census-instrumentation/opencensus-proto v0.3.0/go.mod h1:f6KPmirojxKA github.com/cespare/xxhash v1.1.0/go.mod h1:XrSqR1VqqWfGrhpAt58auRo0WTKS1nRRg3ghfAqPWnc= github.com/cespare/xxhash/v2 v2.1.1/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs= github.com/cespare/xxhash/v2 v2.1.2/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs= -github.com/charmbracelet/bubbles v0.19.0 h1:gKZkKXPP6GlDk6EcfujDK19PCQqRjaJZQ7QRERx1UF0= -github.com/charmbracelet/bubbles v0.19.0/go.mod h1:WILteEqZ+krG5c3ntGEMeG99nCupcuIk7V0/zOP0tOA= -github.com/charmbracelet/bubbletea v1.0.0 h1:BlNvkVed3DADQlV+W79eioNUOrnMUY25EEVdFUoDoGA= -github.com/charmbracelet/bubbletea v1.0.0/go.mod h1:xc4gm5yv+7tbniEvQ0naiG9P3fzYhk16cTgDZQQW6YE= +github.com/charmbracelet/bubbles v0.20.0 h1:jSZu6qD8cRQ6k9OMfR1WlM+ruM8fkPWkHvQWD9LIutE= +github.com/charmbracelet/bubbles v0.20.0/go.mod h1:39slydyswPy+uVOHZ5x/GjwVAFkCsV8IIVy+4MhzwwU= +github.com/charmbracelet/bubbletea v1.1.0 h1:FjAl9eAL3HBCHenhz/ZPjkKdScmaS5SK69JAK2YJK9c= +github.com/charmbracelet/bubbletea v1.1.0/go.mod h1:9Ogk0HrdbHolIKHdjfFpyXJmiCzGwy+FesYkZr7hYU4= github.com/charmbracelet/harmonica v0.2.0 h1:8NxJWRWg/bzKqqEaaeFNipOu77YR5t8aSwG4pgaUBiQ= github.com/charmbracelet/harmonica v0.2.0/go.mod h1:KSri/1RMQOZLbw7AHqgcBycp8pgJnQMYYT8QZRqZ1Ao= github.com/charmbracelet/lipgloss v0.13.0 h1:4X3PPeoWEDCMvzDvGmTajSyYPcZM4+y8sCA/SsA3cjw= github.com/charmbracelet/lipgloss v0.13.0/go.mod h1:nw4zy0SBX/F/eAO1cWdcvy6qnkDUxr8Lw7dvFrAIbbY= -github.com/charmbracelet/x/ansi v0.1.4 h1:IEU3D6+dWwPSgZ6HBH+v6oUuZ/nVawMiWj5831KfiLM= -github.com/charmbracelet/x/ansi v0.1.4/go.mod h1:dk73KoMTT5AX5BsX0KrqhsTqAnhZZoCBjs7dGWp4Ktw= -github.com/charmbracelet/x/input v0.1.0 h1:TEsGSfZYQyOtp+STIjyBq6tpRaorH0qpwZUj8DavAhQ= -github.com/charmbracelet/x/input v0.1.0/go.mod h1:ZZwaBxPF7IG8gWWzPUVqHEtWhc1+HXJPNuerJGRGZ28= -github.com/charmbracelet/x/term v0.1.1 h1:3cosVAiPOig+EV4X9U+3LDgtwwAoEzJjNdwbXDjF6yI= -github.com/charmbracelet/x/term v0.1.1/go.mod h1:wB1fHt5ECsu3mXYusyzcngVWWlu1KKUmmLhfgr/Flxw= -github.com/charmbracelet/x/windows v0.1.0 h1:gTaxdvzDM5oMa/I2ZNF7wN78X/atWemG9Wph7Ika2k4= -github.com/charmbracelet/x/windows v0.1.0/go.mod h1:GLEO/l+lizvFDBPLIOk+49gdX49L9YWMB5t+DZd0jkQ= +github.com/charmbracelet/x/ansi v0.2.3 h1:VfFN0NUpcjBRd4DnKfRaIRo53KRgey/nhOoEqosGDEY= +github.com/charmbracelet/x/ansi v0.2.3/go.mod h1:dk73KoMTT5AX5BsX0KrqhsTqAnhZZoCBjs7dGWp4Ktw= +github.com/charmbracelet/x/term v0.2.0 h1:cNB9Ot9q8I711MyZ7myUR5HFWL/lc3OpU8jZ4hwm0x0= +github.com/charmbracelet/x/term v0.2.0/go.mod h1:GVxgxAbjUrmpvIINHIQnJJKpMlHiZ4cktEQCN6GWyF0= github.com/chzyer/logex v1.1.10/go.mod h1:+Ywpsq7O8HXn0nuIou7OrIPyXbp3wmkHB+jjWRnGsAI= github.com/chzyer/readline v0.0.0-20180603132655-2972be24d48e/go.mod h1:nSuG5e5PlCu98SY8svDHJxuZscDgtXS6KTTbou5AhLI= github.com/chzyer/test v0.0.0-20180213035817-a1ea475d72b1/go.mod h1:Q3SI9o4m/ZMnBNeIyt5eFwwo7qiLfzFZmjNmxjkiQlU= From 9c2799e379681eb94f904c020fe5734019032a85 Mon Sep 17 00:00:00 2001 From: Laurent Goderre Date: Tue, 10 Sep 2024 10:35:18 -0400 Subject: [PATCH 115/122] Add the Ocaml ecosystem (#3112) Signed-off-by: Laurent Goderre --- .../catalog_packages_cases_test.go | 8 + .../test/integration/catalog_packages_test.go | 2 + .../pkgs/opam/ocaml-base-compiler.4.14.0/opam | 93 + internal/constants.go | 2 +- internal/task/package_tasks.go | 2 + schema/json/schema-16.0.16.json | 2629 +++++++++++++++++ schema/json/schema-latest.json | 49 +- .../common/spdxhelpers/to_format_model.go | 8 + .../spdxhelpers/to_format_model_test.go | 25 + .../spdxutil/helpers/download_location.go | 2 + .../helpers/originator_supplier_test.go | 9 + .../internal/spdxutil/helpers/source_info.go | 2 + .../spdxutil/helpers/source_info_test.go | 8 + syft/internal/packagemetadata/generated.go | 1 + syft/internal/packagemetadata/names.go | 1 + syft/pkg/cataloger/ocaml/cataloger.go | 15 + syft/pkg/cataloger/ocaml/cataloger_test.go | 33 + syft/pkg/cataloger/ocaml/package.go | 37 + syft/pkg/cataloger/ocaml/package_test.go | 34 + syft/pkg/cataloger/ocaml/parse_opam.go | 150 + syft/pkg/cataloger/ocaml/parse_opam_test.go | 166 ++ .../ocaml/test-fixtures/alcotest.opam | 51 + .../glob-paths/opam/alcotest.opam | 1 + .../opam/ocaml-base-compiler.4.14.0/opam | 1 + .../ocaml-base-compiler.4.14.0/opam | 93 + syft/pkg/language.go | 4 + syft/pkg/language_test.go | 8 + syft/pkg/ocaml.go | 11 + syft/pkg/type.go | 8 +- syft/pkg/type_test.go | 4 + 30 files changed, 3454 insertions(+), 3 deletions(-) create mode 100644 cmd/syft/internal/test/integration/test-fixtures/image-pkg-coverage/pkgs/opam/ocaml-base-compiler.4.14.0/opam create mode 100644 schema/json/schema-16.0.16.json create mode 100644 syft/pkg/cataloger/ocaml/cataloger.go create mode 100644 syft/pkg/cataloger/ocaml/cataloger_test.go create mode 100644 syft/pkg/cataloger/ocaml/package.go create mode 100644 syft/pkg/cataloger/ocaml/package_test.go create mode 100644 syft/pkg/cataloger/ocaml/parse_opam.go create mode 100644 syft/pkg/cataloger/ocaml/parse_opam_test.go create mode 100644 syft/pkg/cataloger/ocaml/test-fixtures/alcotest.opam create mode 100644 syft/pkg/cataloger/ocaml/test-fixtures/glob-paths/opam/alcotest.opam create mode 100644 syft/pkg/cataloger/ocaml/test-fixtures/glob-paths/opam/ocaml-base-compiler.4.14.0/opam create mode 100644 syft/pkg/cataloger/ocaml/test-fixtures/ocaml-base-compiler.4.14.0/opam create mode 100644 syft/pkg/ocaml.go diff --git a/cmd/syft/internal/test/integration/catalog_packages_cases_test.go b/cmd/syft/internal/test/integration/catalog_packages_cases_test.go index 55822043ec0..a8ea39d09f5 100644 --- a/cmd/syft/internal/test/integration/catalog_packages_cases_test.go +++ b/cmd/syft/internal/test/integration/catalog_packages_cases_test.go @@ -410,6 +410,14 @@ var dirOnlyTestCases = []testCase{ "octo-org/this-repo/.github/workflows/workflow-1.yml": "172239021f7ba04fe7327647b213799853a9eb89", }, }, + { + name: "find opam package", + pkgType: pkg.OpamPkg, + pkgLanguage: pkg.OCaml, + pkgInfo: map[string]string{ + "ocaml-base-compiler": "4.14.0", + }, + }, } var commonTestCases = []testCase{ diff --git a/cmd/syft/internal/test/integration/catalog_packages_test.go b/cmd/syft/internal/test/integration/catalog_packages_test.go index e84d578391b..371ddb4e59b 100644 --- a/cmd/syft/internal/test/integration/catalog_packages_test.go +++ b/cmd/syft/internal/test/integration/catalog_packages_test.go @@ -52,6 +52,7 @@ func TestPkgCoverageImage(t *testing.T) { definedLanguages.Remove(pkg.Dart.String()) definedLanguages.Remove(pkg.Swift.String()) definedLanguages.Remove(pkg.Swipl.String()) + definedLanguages.Remove(pkg.OCaml.String()) definedLanguages.Remove(pkg.CPP.String()) definedLanguages.Remove(pkg.Haskell.String()) definedLanguages.Remove(pkg.Elixir.String()) @@ -78,6 +79,7 @@ func TestPkgCoverageImage(t *testing.T) { definedPkgs.Remove(string(pkg.LinuxKernelModulePkg)) definedPkgs.Remove(string(pkg.SwiftPkg)) definedPkgs.Remove(string(pkg.SwiplPackPkg)) + definedPkgs.Remove(string(pkg.OpamPkg)) definedPkgs.Remove(string(pkg.GithubActionPkg)) definedPkgs.Remove(string(pkg.GithubActionWorkflowPkg)) diff --git a/cmd/syft/internal/test/integration/test-fixtures/image-pkg-coverage/pkgs/opam/ocaml-base-compiler.4.14.0/opam b/cmd/syft/internal/test/integration/test-fixtures/image-pkg-coverage/pkgs/opam/ocaml-base-compiler.4.14.0/opam new file mode 100644 index 00000000000..15e874ec870 --- /dev/null +++ b/cmd/syft/internal/test/integration/test-fixtures/image-pkg-coverage/pkgs/opam/ocaml-base-compiler.4.14.0/opam @@ -0,0 +1,93 @@ +opam-version: "2.0" +synopsis: "Official release 4.14.0" +maintainer: [ + "David Allsopp " + "Florian Angeletti " +] +authors: "Xavier Leroy and many contributors" +license: "LGPL-2.1-or-later WITH OCaml-LGPL-linking-exception" +homepage: "https://ocaml.org" +bug-reports: "https://github.com/ocaml/opam-repository/issues" +depends: [ + "ocaml" {= "4.14.0" & post} + "base-unix" {post} + "base-bigarray" {post} + "base-threads" {post} + "host-arch-arm32" {arch = "arm32" & post} + "host-arch-arm64" {arch = "arm64" & post} + "host-arch-ppc64" {arch = "ppc64" & post} + "host-arch-riscv64" {arch = "riscv64" & post} + "host-arch-s390x" {arch = "s390x" & post} + "host-arch-x86_32" {os != "win32" & arch = "x86_32" & post} + "host-arch-x86_64" {os != "win32" & arch = "x86_64" & post} + "host-arch-unknown" + {os != "win32" & arch != "arm32" & arch != "arm64" & arch != "ppc64" & + arch != "riscv64" & + arch != "s390x" & + arch != "x86_32" & + arch != "x86_64" & + post} + (("arch-x86_64" {os = "win32" & arch = "x86_64"} & + (("system-mingw" & "mingw-w64-shims" {os-distribution = "cygwin" & post}) | + "system-msvc")) | + ("arch-x86_32" {os = "win32"} & + (("system-mingw" & "mingw-w64-shims" {os-distribution = "cygwin" & post}) | + "system-msvc")) | + "host-system-other" {os != "win32" & post}) + "ocaml-options-vanilla" {post} + "flexdll" {>= "0.36" & os = "win32"} +] +conflict-class: "ocaml-core-compiler" +flags: compiler +setenv: CAML_LD_LIBRARY_PATH = "%{lib}%/stublibs" +build: [ + [ + "./configure" + "--host=x86_64-pc-windows" + {system-msvc:installed & arch-x86_64:installed} + "--host=x86_64-w64-mingw32" + {os-distribution = "cygwin" & system-mingw:installed & + arch-x86_64:installed} + "--host=i686-pc-windows" {system-msvc:installed & arch-x86_32:installed} + "--host=i686-w64-mingw32" + {os-distribution = "cygwin" & system-mingw:installed & + arch-x86_32:installed} + "--prefix=%{prefix}%" + "--docdir=%{doc}%/ocaml" + "--with-flexdll=%{flexdll:share}%" {os = "win32" & flexdll:installed} + "-C" + "CC=cc" {os = "openbsd" | os = "macos"} + "ASPP=cc -c" {os = "openbsd" | os = "macos"} + ] + [make "-j%{jobs}%"] +] +install: [make "install"] +build-env: MSYS2_ARG_CONV_EXCL = "*" +post-messages: [ + """\ +A failure in the middle of the build may be caused by build parallelism + (enabled by default). + Please file a bug report at https://github.com/ocaml/opam-repository/issues""" + {failure & jobs > "1"} + """\ +You can try installing again including --jobs=1 + to force a sequential build instead.""" + {failure & jobs > "1" & opam-version >= "2.0.5"} +] +dev-repo: "git+https://github.com/ocaml/ocaml#4.14" +url { + src: "https://github.com/ocaml/ocaml/archive/4.14.0.tar.gz" + checksum: + "sha256=39f44260382f28d1054c5f9d8bf4753cb7ad64027da792f7938344544da155e8" +} +extra-source "ocaml-base-compiler.install" { + src: + "https://raw.githubusercontent.com/ocaml/opam-source-archives/main/patches/ocaml-base-compiler/ocaml-base-compiler.install" + checksum: [ + "sha256=79f2a1a5044a91350a0eb6ce12e261a72a2855c094c425cddf3860e58c486678" + "md5=3e969b841df1f51ca448e6e6295cb451" + ] +} +x-env-path-rewrite: [ + [CAML_LD_LIBRARY_PATH (";" {os = "win32"} ":" {os != "win32"}) "target"] +] diff --git a/internal/constants.go b/internal/constants.go index 6d1dd197439..93b0093ab6a 100644 --- a/internal/constants.go +++ b/internal/constants.go @@ -3,5 +3,5 @@ package internal const ( // JSONSchemaVersion is the current schema version output by the JSON encoder // This is roughly following the "SchemaVer" guidelines for versioning the JSON schema. Please see schema/json/README.md for details on how to increment. - JSONSchemaVersion = "16.0.15" + JSONSchemaVersion = "16.0.16" ) diff --git a/internal/task/package_tasks.go b/internal/task/package_tasks.go index 88ce35345b4..4d56dc88adc 100644 --- a/internal/task/package_tasks.go +++ b/internal/task/package_tasks.go @@ -21,6 +21,7 @@ import ( "github.com/anchore/syft/syft/pkg/cataloger/kernel" "github.com/anchore/syft/syft/pkg/cataloger/lua" "github.com/anchore/syft/syft/pkg/cataloger/nix" + "github.com/anchore/syft/syft/pkg/cataloger/ocaml" "github.com/anchore/syft/syft/pkg/cataloger/php" "github.com/anchore/syft/syft/pkg/cataloger/python" "github.com/anchore/syft/syft/pkg/cataloger/r" @@ -95,6 +96,7 @@ func DefaultPackageTaskFactories() PackageTaskFactories { newSimplePackageTaskFactory(swift.NewCocoapodsCataloger, pkgcataloging.DeclaredTag, pkgcataloging.DirectoryTag, pkgcataloging.LanguageTag, "swift", "cocoapods"), newSimplePackageTaskFactory(swift.NewSwiftPackageManagerCataloger, pkgcataloging.DeclaredTag, pkgcataloging.DirectoryTag, pkgcataloging.LanguageTag, "swift", "spm"), newSimplePackageTaskFactory(swipl.NewSwiplPackCataloger, pkgcataloging.DeclaredTag, pkgcataloging.DirectoryTag, pkgcataloging.LanguageTag, "swipl", "pack"), + newSimplePackageTaskFactory(ocaml.NewOpamPackageManagerCataloger, pkgcataloging.DeclaredTag, pkgcataloging.DirectoryTag, pkgcataloging.LanguageTag, "ocaml", "opam"), // language-specific package for both image and directory scans (but not necessarily declared) //////////////////////////////////////// newSimplePackageTaskFactory(dotnet.NewDotnetPortableExecutableCataloger, pkgcataloging.DirectoryTag, pkgcataloging.InstalledTag, pkgcataloging.ImageTag, pkgcataloging.LanguageTag, "dotnet", "c#", "binary"), diff --git a/schema/json/schema-16.0.16.json b/schema/json/schema-16.0.16.json new file mode 100644 index 00000000000..a8819785972 --- /dev/null +++ b/schema/json/schema-16.0.16.json @@ -0,0 +1,2629 @@ +{ + "$schema": "https://json-schema.org/draft/2020-12/schema", + "$id": "anchore.io/schema/syft/json/16.0.16/document", + "$ref": "#/$defs/Document", + "$defs": { + "AlpmDbEntry": { + "properties": { + "basepackage": { + "type": "string" + }, + "package": { + "type": "string" + }, + "version": { + "type": "string" + }, + "description": { + "type": "string" + }, + "architecture": { + "type": "string" + }, + "size": { + "type": "integer" + }, + "packager": { + "type": "string" + }, + "url": { + "type": "string" + }, + "validation": { + "type": "string" + }, + "reason": { + "type": "integer" + }, + "files": { + "items": { + "$ref": "#/$defs/AlpmFileRecord" + }, + "type": "array" + }, + "backup": { + "items": { + "$ref": "#/$defs/AlpmFileRecord" + }, + "type": "array" + }, + "provides": { + "items": { + "type": "string" + }, + "type": "array" + }, + "depends": { + "items": { + "type": "string" + }, + "type": "array" + } + }, + "type": "object", + "required": [ + "basepackage", + "package", + "version", + "description", + "architecture", + "size", + "packager", + "url", + "validation", + "reason", + "files", + "backup" + ] + }, + "AlpmFileRecord": { + "properties": { + "path": { + "type": "string" + }, + "type": { + "type": "string" + }, + "uid": { + "type": "string" + }, + "gid": { + "type": "string" + }, + "time": { + "type": "string", + "format": "date-time" + }, + "size": { + "type": "string" + }, + "link": { + "type": "string" + }, + "digest": { + "items": { + "$ref": "#/$defs/Digest" + }, + "type": "array" + } + }, + "type": "object" + }, + "ApkDbEntry": { + "properties": { + "package": { + "type": "string" + }, + "originPackage": { + "type": "string" + }, + "maintainer": { + "type": "string" + }, + "version": { + "type": "string" + }, + "architecture": { + "type": "string" + }, + "url": { + "type": "string" + }, + "description": { + "type": "string" + }, + "size": { + "type": "integer" + }, + "installedSize": { + "type": "integer" + }, + "pullDependencies": { + "items": { + "type": "string" + }, + "type": "array" + }, + "provides": { + "items": { + "type": "string" + }, + "type": "array" + }, + "pullChecksum": { + "type": "string" + }, + "gitCommitOfApkPort": { + "type": "string" + }, + "files": { + "items": { + "$ref": "#/$defs/ApkFileRecord" + }, + "type": "array" + } + }, + "type": "object", + "required": [ + "package", + "originPackage", + "maintainer", + "version", + "architecture", + "url", + "description", + "size", + "installedSize", + "pullDependencies", + "provides", + "pullChecksum", + "gitCommitOfApkPort", + "files" + ] + }, + "ApkFileRecord": { + "properties": { + "path": { + "type": "string" + }, + "ownerUid": { + "type": "string" + }, + "ownerGid": { + "type": "string" + }, + "permissions": { + "type": "string" + }, + "digest": { + "$ref": "#/$defs/Digest" + } + }, + "type": "object", + "required": [ + "path" + ] + }, + "BinarySignature": { + "properties": { + "matches": { + "items": { + "$ref": "#/$defs/ClassifierMatch" + }, + "type": "array" + } + }, + "type": "object", + "required": [ + "matches" + ] + }, + "CConanFileEntry": { + "properties": { + "ref": { + "type": "string" + } + }, + "type": "object", + "required": [ + "ref" + ] + }, + "CConanInfoEntry": { + "properties": { + "ref": { + "type": "string" + }, + "package_id": { + "type": "string" + } + }, + "type": "object", + "required": [ + "ref" + ] + }, + "CConanLockEntry": { + "properties": { + "ref": { + "type": "string" + }, + "package_id": { + "type": "string" + }, + "prev": { + "type": "string" + }, + "requires": { + "items": { + "type": "string" + }, + "type": "array" + }, + "build_requires": { + "items": { + "type": "string" + }, + "type": "array" + }, + "py_requires": { + "items": { + "type": "string" + }, + "type": "array" + }, + "options": { + "$ref": "#/$defs/KeyValues" + }, + "path": { + "type": "string" + }, + "context": { + "type": "string" + } + }, + "type": "object", + "required": [ + "ref" + ] + }, + "CConanLockV2Entry": { + "properties": { + "ref": { + "type": "string" + }, + "packageID": { + "type": "string" + }, + "username": { + "type": "string" + }, + "channel": { + "type": "string" + }, + "recipeRevision": { + "type": "string" + }, + "packageRevision": { + "type": "string" + }, + "timestamp": { + "type": "string" + } + }, + "type": "object", + "required": [ + "ref" + ] + }, + "CPE": { + "properties": { + "cpe": { + "type": "string" + }, + "source": { + "type": "string" + } + }, + "type": "object", + "required": [ + "cpe" + ] + }, + "ClassifierMatch": { + "properties": { + "classifier": { + "type": "string" + }, + "location": { + "$ref": "#/$defs/Location" + } + }, + "type": "object", + "required": [ + "classifier", + "location" + ] + }, + "CocoaPodfileLockEntry": { + "properties": { + "checksum": { + "type": "string" + } + }, + "type": "object", + "required": [ + "checksum" + ] + }, + "Coordinates": { + "properties": { + "path": { + "type": "string" + }, + "layerID": { + "type": "string" + } + }, + "type": "object", + "required": [ + "path" + ] + }, + "DartPubspecLockEntry": { + "properties": { + "name": { + "type": "string" + }, + "version": { + "type": "string" + }, + "hosted_url": { + "type": "string" + }, + "vcs_url": { + "type": "string" + } + }, + "type": "object", + "required": [ + "name", + "version" + ] + }, + "Descriptor": { + "properties": { + "name": { + "type": "string" + }, + "version": { + "type": "string" + }, + "configuration": true + }, + "type": "object", + "required": [ + "name", + "version" + ] + }, + "Digest": { + "properties": { + "algorithm": { + "type": "string" + }, + "value": { + "type": "string" + } + }, + "type": "object", + "required": [ + "algorithm", + "value" + ] + }, + "Document": { + "properties": { + "artifacts": { + "items": { + "$ref": "#/$defs/Package" + }, + "type": "array" + }, + "artifactRelationships": { + "items": { + "$ref": "#/$defs/Relationship" + }, + "type": "array" + }, + "files": { + "items": { + "$ref": "#/$defs/File" + }, + "type": "array" + }, + "source": { + "$ref": "#/$defs/Source" + }, + "distro": { + "$ref": "#/$defs/LinuxRelease" + }, + "descriptor": { + "$ref": "#/$defs/Descriptor" + }, + "schema": { + "$ref": "#/$defs/Schema" + } + }, + "type": "object", + "required": [ + "artifacts", + "artifactRelationships", + "source", + "distro", + "descriptor", + "schema" + ] + }, + "DotnetDepsEntry": { + "properties": { + "name": { + "type": "string" + }, + "version": { + "type": "string" + }, + "path": { + "type": "string" + }, + "sha512": { + "type": "string" + }, + "hashPath": { + "type": "string" + } + }, + "type": "object", + "required": [ + "name", + "version", + "path", + "sha512", + "hashPath" + ] + }, + "DotnetPortableExecutableEntry": { + "properties": { + "assemblyVersion": { + "type": "string" + }, + "legalCopyright": { + "type": "string" + }, + "comments": { + "type": "string" + }, + "internalName": { + "type": "string" + }, + "companyName": { + "type": "string" + }, + "productName": { + "type": "string" + }, + "productVersion": { + "type": "string" + } + }, + "type": "object", + "required": [ + "assemblyVersion", + "legalCopyright", + "companyName", + "productName", + "productVersion" + ] + }, + "DpkgDbEntry": { + "properties": { + "package": { + "type": "string" + }, + "source": { + "type": "string" + }, + "version": { + "type": "string" + }, + "sourceVersion": { + "type": "string" + }, + "architecture": { + "type": "string" + }, + "maintainer": { + "type": "string" + }, + "installedSize": { + "type": "integer" + }, + "provides": { + "items": { + "type": "string" + }, + "type": "array" + }, + "depends": { + "items": { + "type": "string" + }, + "type": "array" + }, + "preDepends": { + "items": { + "type": "string" + }, + "type": "array" + }, + "files": { + "items": { + "$ref": "#/$defs/DpkgFileRecord" + }, + "type": "array" + } + }, + "type": "object", + "required": [ + "package", + "source", + "version", + "sourceVersion", + "architecture", + "maintainer", + "installedSize", + "files" + ] + }, + "DpkgFileRecord": { + "properties": { + "path": { + "type": "string" + }, + "digest": { + "$ref": "#/$defs/Digest" + }, + "isConfigFile": { + "type": "boolean" + } + }, + "type": "object", + "required": [ + "path", + "isConfigFile" + ] + }, + "ELFSecurityFeatures": { + "properties": { + "symbolTableStripped": { + "type": "boolean" + }, + "stackCanary": { + "type": "boolean" + }, + "nx": { + "type": "boolean" + }, + "relRO": { + "type": "string" + }, + "pie": { + "type": "boolean" + }, + "dso": { + "type": "boolean" + }, + "safeStack": { + "type": "boolean" + }, + "cfi": { + "type": "boolean" + }, + "fortify": { + "type": "boolean" + } + }, + "type": "object", + "required": [ + "symbolTableStripped", + "nx", + "relRO", + "pie", + "dso" + ] + }, + "ElfBinaryPackageNoteJsonPayload": { + "properties": { + "type": { + "type": "string" + }, + "architecture": { + "type": "string" + }, + "osCPE": { + "type": "string" + }, + "os": { + "type": "string" + }, + "osVersion": { + "type": "string" + }, + "system": { + "type": "string" + }, + "vendor": { + "type": "string" + }, + "sourceRepo": { + "type": "string" + }, + "commit": { + "type": "string" + } + }, + "type": "object" + }, + "ElixirMixLockEntry": { + "properties": { + "name": { + "type": "string" + }, + "version": { + "type": "string" + }, + "pkgHash": { + "type": "string" + }, + "pkgHashExt": { + "type": "string" + } + }, + "type": "object", + "required": [ + "name", + "version", + "pkgHash", + "pkgHashExt" + ] + }, + "ErlangRebarLockEntry": { + "properties": { + "name": { + "type": "string" + }, + "version": { + "type": "string" + }, + "pkgHash": { + "type": "string" + }, + "pkgHashExt": { + "type": "string" + } + }, + "type": "object", + "required": [ + "name", + "version", + "pkgHash", + "pkgHashExt" + ] + }, + "Executable": { + "properties": { + "format": { + "type": "string" + }, + "hasExports": { + "type": "boolean" + }, + "hasEntrypoint": { + "type": "boolean" + }, + "importedLibraries": { + "items": { + "type": "string" + }, + "type": "array" + }, + "elfSecurityFeatures": { + "$ref": "#/$defs/ELFSecurityFeatures" + } + }, + "type": "object", + "required": [ + "format", + "hasExports", + "hasEntrypoint", + "importedLibraries" + ] + }, + "File": { + "properties": { + "id": { + "type": "string" + }, + "location": { + "$ref": "#/$defs/Coordinates" + }, + "metadata": { + "$ref": "#/$defs/FileMetadataEntry" + }, + "contents": { + "type": "string" + }, + "digests": { + "items": { + "$ref": "#/$defs/Digest" + }, + "type": "array" + }, + "licenses": { + "items": { + "$ref": "#/$defs/FileLicense" + }, + "type": "array" + }, + "executable": { + "$ref": "#/$defs/Executable" + } + }, + "type": "object", + "required": [ + "id", + "location" + ] + }, + "FileLicense": { + "properties": { + "value": { + "type": "string" + }, + "spdxExpression": { + "type": "string" + }, + "type": { + "type": "string" + }, + "evidence": { + "$ref": "#/$defs/FileLicenseEvidence" + } + }, + "type": "object", + "required": [ + "value", + "spdxExpression", + "type" + ] + }, + "FileLicenseEvidence": { + "properties": { + "confidence": { + "type": "integer" + }, + "offset": { + "type": "integer" + }, + "extent": { + "type": "integer" + } + }, + "type": "object", + "required": [ + "confidence", + "offset", + "extent" + ] + }, + "FileMetadataEntry": { + "properties": { + "mode": { + "type": "integer" + }, + "type": { + "type": "string" + }, + "linkDestination": { + "type": "string" + }, + "userID": { + "type": "integer" + }, + "groupID": { + "type": "integer" + }, + "mimeType": { + "type": "string" + }, + "size": { + "type": "integer" + } + }, + "type": "object", + "required": [ + "mode", + "type", + "userID", + "groupID", + "mimeType", + "size" + ] + }, + "GoModuleBuildinfoEntry": { + "properties": { + "goBuildSettings": { + "$ref": "#/$defs/KeyValues" + }, + "goCompiledVersion": { + "type": "string" + }, + "architecture": { + "type": "string" + }, + "h1Digest": { + "type": "string" + }, + "mainModule": { + "type": "string" + }, + "goCryptoSettings": { + "items": { + "type": "string" + }, + "type": "array" + }, + "goExperiments": { + "items": { + "type": "string" + }, + "type": "array" + } + }, + "type": "object", + "required": [ + "goCompiledVersion", + "architecture" + ] + }, + "GoModuleEntry": { + "properties": { + "h1Digest": { + "type": "string" + } + }, + "type": "object" + }, + "HaskellHackageStackEntry": { + "properties": { + "pkgHash": { + "type": "string" + } + }, + "type": "object" + }, + "HaskellHackageStackLockEntry": { + "properties": { + "pkgHash": { + "type": "string" + }, + "snapshotURL": { + "type": "string" + } + }, + "type": "object" + }, + "IDLikes": { + "items": { + "type": "string" + }, + "type": "array" + }, + "JavaArchive": { + "properties": { + "virtualPath": { + "type": "string" + }, + "manifest": { + "$ref": "#/$defs/JavaManifest" + }, + "pomProperties": { + "$ref": "#/$defs/JavaPomProperties" + }, + "pomProject": { + "$ref": "#/$defs/JavaPomProject" + }, + "digest": { + "items": { + "$ref": "#/$defs/Digest" + }, + "type": "array" + } + }, + "type": "object", + "required": [ + "virtualPath" + ] + }, + "JavaManifest": { + "properties": { + "main": { + "$ref": "#/$defs/KeyValues" + }, + "sections": { + "items": { + "$ref": "#/$defs/KeyValues" + }, + "type": "array" + } + }, + "type": "object" + }, + "JavaPomParent": { + "properties": { + "groupId": { + "type": "string" + }, + "artifactId": { + "type": "string" + }, + "version": { + "type": "string" + } + }, + "type": "object", + "required": [ + "groupId", + "artifactId", + "version" + ] + }, + "JavaPomProject": { + "properties": { + "path": { + "type": "string" + }, + "parent": { + "$ref": "#/$defs/JavaPomParent" + }, + "groupId": { + "type": "string" + }, + "artifactId": { + "type": "string" + }, + "version": { + "type": "string" + }, + "name": { + "type": "string" + }, + "description": { + "type": "string" + }, + "url": { + "type": "string" + } + }, + "type": "object", + "required": [ + "path", + "groupId", + "artifactId", + "version", + "name" + ] + }, + "JavaPomProperties": { + "properties": { + "path": { + "type": "string" + }, + "name": { + "type": "string" + }, + "groupId": { + "type": "string" + }, + "artifactId": { + "type": "string" + }, + "version": { + "type": "string" + }, + "scope": { + "type": "string" + }, + "extraFields": { + "patternProperties": { + ".*": { + "type": "string" + } + }, + "type": "object" + } + }, + "type": "object", + "required": [ + "path", + "name", + "groupId", + "artifactId", + "version" + ] + }, + "JavascriptNpmPackage": { + "properties": { + "name": { + "type": "string" + }, + "version": { + "type": "string" + }, + "author": { + "type": "string" + }, + "homepage": { + "type": "string" + }, + "description": { + "type": "string" + }, + "url": { + "type": "string" + }, + "private": { + "type": "boolean" + } + }, + "type": "object", + "required": [ + "name", + "version", + "author", + "homepage", + "description", + "url", + "private" + ] + }, + "JavascriptNpmPackageLockEntry": { + "properties": { + "resolved": { + "type": "string" + }, + "integrity": { + "type": "string" + } + }, + "type": "object", + "required": [ + "resolved", + "integrity" + ] + }, + "JavascriptYarnLockEntry": { + "properties": { + "resolved": { + "type": "string" + }, + "integrity": { + "type": "string" + } + }, + "type": "object", + "required": [ + "resolved", + "integrity" + ] + }, + "KeyValue": { + "properties": { + "key": { + "type": "string" + }, + "value": { + "type": "string" + } + }, + "type": "object", + "required": [ + "key", + "value" + ] + }, + "KeyValues": { + "items": { + "$ref": "#/$defs/KeyValue" + }, + "type": "array" + }, + "License": { + "properties": { + "value": { + "type": "string" + }, + "spdxExpression": { + "type": "string" + }, + "type": { + "type": "string" + }, + "urls": { + "items": { + "type": "string" + }, + "type": "array" + }, + "locations": { + "items": { + "$ref": "#/$defs/Location" + }, + "type": "array" + } + }, + "type": "object", + "required": [ + "value", + "spdxExpression", + "type", + "urls", + "locations" + ] + }, + "LinuxKernelArchive": { + "properties": { + "name": { + "type": "string" + }, + "architecture": { + "type": "string" + }, + "version": { + "type": "string" + }, + "extendedVersion": { + "type": "string" + }, + "buildTime": { + "type": "string" + }, + "author": { + "type": "string" + }, + "format": { + "type": "string" + }, + "rwRootFS": { + "type": "boolean" + }, + "swapDevice": { + "type": "integer" + }, + "rootDevice": { + "type": "integer" + }, + "videoMode": { + "type": "string" + } + }, + "type": "object", + "required": [ + "name", + "architecture", + "version" + ] + }, + "LinuxKernelModule": { + "properties": { + "name": { + "type": "string" + }, + "version": { + "type": "string" + }, + "sourceVersion": { + "type": "string" + }, + "path": { + "type": "string" + }, + "description": { + "type": "string" + }, + "author": { + "type": "string" + }, + "license": { + "type": "string" + }, + "kernelVersion": { + "type": "string" + }, + "versionMagic": { + "type": "string" + }, + "parameters": { + "patternProperties": { + ".*": { + "$ref": "#/$defs/LinuxKernelModuleParameter" + } + }, + "type": "object" + } + }, + "type": "object" + }, + "LinuxKernelModuleParameter": { + "properties": { + "type": { + "type": "string" + }, + "description": { + "type": "string" + } + }, + "type": "object" + }, + "LinuxRelease": { + "properties": { + "prettyName": { + "type": "string" + }, + "name": { + "type": "string" + }, + "id": { + "type": "string" + }, + "idLike": { + "$ref": "#/$defs/IDLikes" + }, + "version": { + "type": "string" + }, + "versionID": { + "type": "string" + }, + "versionCodename": { + "type": "string" + }, + "buildID": { + "type": "string" + }, + "imageID": { + "type": "string" + }, + "imageVersion": { + "type": "string" + }, + "variant": { + "type": "string" + }, + "variantID": { + "type": "string" + }, + "homeURL": { + "type": "string" + }, + "supportURL": { + "type": "string" + }, + "bugReportURL": { + "type": "string" + }, + "privacyPolicyURL": { + "type": "string" + }, + "cpeName": { + "type": "string" + }, + "supportEnd": { + "type": "string" + } + }, + "type": "object" + }, + "Location": { + "properties": { + "path": { + "type": "string" + }, + "layerID": { + "type": "string" + }, + "accessPath": { + "type": "string" + }, + "annotations": { + "patternProperties": { + ".*": { + "type": "string" + } + }, + "type": "object" + } + }, + "type": "object", + "required": [ + "path", + "accessPath" + ] + }, + "LuarocksPackage": { + "properties": { + "name": { + "type": "string" + }, + "version": { + "type": "string" + }, + "license": { + "type": "string" + }, + "homepage": { + "type": "string" + }, + "description": { + "type": "string" + }, + "url": { + "type": "string" + }, + "dependencies": { + "patternProperties": { + ".*": { + "type": "string" + } + }, + "type": "object" + } + }, + "type": "object", + "required": [ + "name", + "version", + "license", + "homepage", + "description", + "url", + "dependencies" + ] + }, + "MicrosoftKbPatch": { + "properties": { + "product_id": { + "type": "string" + }, + "kb": { + "type": "string" + } + }, + "type": "object", + "required": [ + "product_id", + "kb" + ] + }, + "NixStoreEntry": { + "properties": { + "outputHash": { + "type": "string" + }, + "output": { + "type": "string" + }, + "files": { + "items": { + "type": "string" + }, + "type": "array" + } + }, + "type": "object", + "required": [ + "outputHash", + "files" + ] + }, + "OpamPackage": { + "properties": { + "name": { + "type": "string" + }, + "version": { + "type": "string" + }, + "licenses": { + "items": { + "type": "string" + }, + "type": "array" + }, + "url": { + "type": "string" + }, + "checksum": { + "items": { + "type": "string" + }, + "type": "array" + }, + "homepage": { + "type": "string" + }, + "dependencies": { + "items": { + "type": "string" + }, + "type": "array" + } + }, + "type": "object", + "required": [ + "name", + "version", + "licenses", + "url", + "checksum", + "homepage", + "dependencies" + ] + }, + "Package": { + "properties": { + "id": { + "type": "string" + }, + "name": { + "type": "string" + }, + "version": { + "type": "string" + }, + "type": { + "type": "string" + }, + "foundBy": { + "type": "string" + }, + "locations": { + "items": { + "$ref": "#/$defs/Location" + }, + "type": "array" + }, + "licenses": { + "$ref": "#/$defs/licenses" + }, + "language": { + "type": "string" + }, + "cpes": { + "$ref": "#/$defs/cpes" + }, + "purl": { + "type": "string" + }, + "metadataType": { + "type": "string" + }, + "metadata": { + "anyOf": [ + { + "type": "null" + }, + { + "$ref": "#/$defs/AlpmDbEntry" + }, + { + "$ref": "#/$defs/ApkDbEntry" + }, + { + "$ref": "#/$defs/BinarySignature" + }, + { + "$ref": "#/$defs/CConanFileEntry" + }, + { + "$ref": "#/$defs/CConanInfoEntry" + }, + { + "$ref": "#/$defs/CConanLockEntry" + }, + { + "$ref": "#/$defs/CConanLockV2Entry" + }, + { + "$ref": "#/$defs/CocoaPodfileLockEntry" + }, + { + "$ref": "#/$defs/DartPubspecLockEntry" + }, + { + "$ref": "#/$defs/DotnetDepsEntry" + }, + { + "$ref": "#/$defs/DotnetPortableExecutableEntry" + }, + { + "$ref": "#/$defs/DpkgDbEntry" + }, + { + "$ref": "#/$defs/ElfBinaryPackageNoteJsonPayload" + }, + { + "$ref": "#/$defs/ElixirMixLockEntry" + }, + { + "$ref": "#/$defs/ErlangRebarLockEntry" + }, + { + "$ref": "#/$defs/GoModuleBuildinfoEntry" + }, + { + "$ref": "#/$defs/GoModuleEntry" + }, + { + "$ref": "#/$defs/HaskellHackageStackEntry" + }, + { + "$ref": "#/$defs/HaskellHackageStackLockEntry" + }, + { + "$ref": "#/$defs/JavaArchive" + }, + { + "$ref": "#/$defs/JavascriptNpmPackage" + }, + { + "$ref": "#/$defs/JavascriptNpmPackageLockEntry" + }, + { + "$ref": "#/$defs/JavascriptYarnLockEntry" + }, + { + "$ref": "#/$defs/LinuxKernelArchive" + }, + { + "$ref": "#/$defs/LinuxKernelModule" + }, + { + "$ref": "#/$defs/LuarocksPackage" + }, + { + "$ref": "#/$defs/MicrosoftKbPatch" + }, + { + "$ref": "#/$defs/NixStoreEntry" + }, + { + "$ref": "#/$defs/OpamPackage" + }, + { + "$ref": "#/$defs/PhpComposerInstalledEntry" + }, + { + "$ref": "#/$defs/PhpComposerLockEntry" + }, + { + "$ref": "#/$defs/PhpPeclEntry" + }, + { + "$ref": "#/$defs/PortageDbEntry" + }, + { + "$ref": "#/$defs/PythonPackage" + }, + { + "$ref": "#/$defs/PythonPipRequirementsEntry" + }, + { + "$ref": "#/$defs/PythonPipfileLockEntry" + }, + { + "$ref": "#/$defs/PythonPoetryLockEntry" + }, + { + "$ref": "#/$defs/RDescription" + }, + { + "$ref": "#/$defs/RpmArchive" + }, + { + "$ref": "#/$defs/RpmDbEntry" + }, + { + "$ref": "#/$defs/RubyGemspec" + }, + { + "$ref": "#/$defs/RustCargoAuditEntry" + }, + { + "$ref": "#/$defs/RustCargoLockEntry" + }, + { + "$ref": "#/$defs/SwiftPackageManagerLockEntry" + }, + { + "$ref": "#/$defs/SwiplpackPackage" + }, + { + "$ref": "#/$defs/WordpressPluginEntry" + } + ] + } + }, + "type": "object", + "required": [ + "id", + "name", + "version", + "type", + "foundBy", + "locations", + "licenses", + "language", + "cpes", + "purl" + ] + }, + "PhpComposerAuthors": { + "properties": { + "name": { + "type": "string" + }, + "email": { + "type": "string" + }, + "homepage": { + "type": "string" + } + }, + "type": "object", + "required": [ + "name" + ] + }, + "PhpComposerExternalReference": { + "properties": { + "type": { + "type": "string" + }, + "url": { + "type": "string" + }, + "reference": { + "type": "string" + }, + "shasum": { + "type": "string" + } + }, + "type": "object", + "required": [ + "type", + "url", + "reference" + ] + }, + "PhpComposerInstalledEntry": { + "properties": { + "name": { + "type": "string" + }, + "version": { + "type": "string" + }, + "source": { + "$ref": "#/$defs/PhpComposerExternalReference" + }, + "dist": { + "$ref": "#/$defs/PhpComposerExternalReference" + }, + "require": { + "patternProperties": { + ".*": { + "type": "string" + } + }, + "type": "object" + }, + "provide": { + "patternProperties": { + ".*": { + "type": "string" + } + }, + "type": "object" + }, + "require-dev": { + "patternProperties": { + ".*": { + "type": "string" + } + }, + "type": "object" + }, + "suggest": { + "patternProperties": { + ".*": { + "type": "string" + } + }, + "type": "object" + }, + "license": { + "items": { + "type": "string" + }, + "type": "array" + }, + "type": { + "type": "string" + }, + "notification-url": { + "type": "string" + }, + "bin": { + "items": { + "type": "string" + }, + "type": "array" + }, + "authors": { + "items": { + "$ref": "#/$defs/PhpComposerAuthors" + }, + "type": "array" + }, + "description": { + "type": "string" + }, + "homepage": { + "type": "string" + }, + "keywords": { + "items": { + "type": "string" + }, + "type": "array" + }, + "time": { + "type": "string" + } + }, + "type": "object", + "required": [ + "name", + "version", + "source", + "dist" + ] + }, + "PhpComposerLockEntry": { + "properties": { + "name": { + "type": "string" + }, + "version": { + "type": "string" + }, + "source": { + "$ref": "#/$defs/PhpComposerExternalReference" + }, + "dist": { + "$ref": "#/$defs/PhpComposerExternalReference" + }, + "require": { + "patternProperties": { + ".*": { + "type": "string" + } + }, + "type": "object" + }, + "provide": { + "patternProperties": { + ".*": { + "type": "string" + } + }, + "type": "object" + }, + "require-dev": { + "patternProperties": { + ".*": { + "type": "string" + } + }, + "type": "object" + }, + "suggest": { + "patternProperties": { + ".*": { + "type": "string" + } + }, + "type": "object" + }, + "license": { + "items": { + "type": "string" + }, + "type": "array" + }, + "type": { + "type": "string" + }, + "notification-url": { + "type": "string" + }, + "bin": { + "items": { + "type": "string" + }, + "type": "array" + }, + "authors": { + "items": { + "$ref": "#/$defs/PhpComposerAuthors" + }, + "type": "array" + }, + "description": { + "type": "string" + }, + "homepage": { + "type": "string" + }, + "keywords": { + "items": { + "type": "string" + }, + "type": "array" + }, + "time": { + "type": "string" + } + }, + "type": "object", + "required": [ + "name", + "version", + "source", + "dist" + ] + }, + "PhpPeclEntry": { + "properties": { + "name": { + "type": "string" + }, + "version": { + "type": "string" + }, + "license": { + "items": { + "type": "string" + }, + "type": "array" + } + }, + "type": "object", + "required": [ + "name", + "version" + ] + }, + "PortageDbEntry": { + "properties": { + "installedSize": { + "type": "integer" + }, + "files": { + "items": { + "$ref": "#/$defs/PortageFileRecord" + }, + "type": "array" + } + }, + "type": "object", + "required": [ + "installedSize", + "files" + ] + }, + "PortageFileRecord": { + "properties": { + "path": { + "type": "string" + }, + "digest": { + "$ref": "#/$defs/Digest" + } + }, + "type": "object", + "required": [ + "path" + ] + }, + "PythonDirectURLOriginInfo": { + "properties": { + "url": { + "type": "string" + }, + "commitId": { + "type": "string" + }, + "vcs": { + "type": "string" + } + }, + "type": "object", + "required": [ + "url" + ] + }, + "PythonFileDigest": { + "properties": { + "algorithm": { + "type": "string" + }, + "value": { + "type": "string" + } + }, + "type": "object", + "required": [ + "algorithm", + "value" + ] + }, + "PythonFileRecord": { + "properties": { + "path": { + "type": "string" + }, + "digest": { + "$ref": "#/$defs/PythonFileDigest" + }, + "size": { + "type": "string" + } + }, + "type": "object", + "required": [ + "path" + ] + }, + "PythonPackage": { + "properties": { + "name": { + "type": "string" + }, + "version": { + "type": "string" + }, + "author": { + "type": "string" + }, + "authorEmail": { + "type": "string" + }, + "platform": { + "type": "string" + }, + "files": { + "items": { + "$ref": "#/$defs/PythonFileRecord" + }, + "type": "array" + }, + "sitePackagesRootPath": { + "type": "string" + }, + "topLevelPackages": { + "items": { + "type": "string" + }, + "type": "array" + }, + "directUrlOrigin": { + "$ref": "#/$defs/PythonDirectURLOriginInfo" + }, + "requiresPython": { + "type": "string" + }, + "requiresDist": { + "items": { + "type": "string" + }, + "type": "array" + }, + "providesExtra": { + "items": { + "type": "string" + }, + "type": "array" + } + }, + "type": "object", + "required": [ + "name", + "version", + "author", + "authorEmail", + "platform", + "sitePackagesRootPath" + ] + }, + "PythonPipRequirementsEntry": { + "properties": { + "name": { + "type": "string" + }, + "extras": { + "items": { + "type": "string" + }, + "type": "array" + }, + "versionConstraint": { + "type": "string" + }, + "url": { + "type": "string" + }, + "markers": { + "type": "string" + } + }, + "type": "object", + "required": [ + "name", + "versionConstraint" + ] + }, + "PythonPipfileLockEntry": { + "properties": { + "hashes": { + "items": { + "type": "string" + }, + "type": "array" + }, + "index": { + "type": "string" + } + }, + "type": "object", + "required": [ + "hashes", + "index" + ] + }, + "PythonPoetryLockDependencyEntry": { + "properties": { + "name": { + "type": "string" + }, + "version": { + "type": "string" + }, + "optional": { + "type": "boolean" + }, + "markers": { + "type": "string" + }, + "extras": { + "items": { + "type": "string" + }, + "type": "array" + } + }, + "type": "object", + "required": [ + "name", + "version", + "optional" + ] + }, + "PythonPoetryLockEntry": { + "properties": { + "index": { + "type": "string" + }, + "dependencies": { + "items": { + "$ref": "#/$defs/PythonPoetryLockDependencyEntry" + }, + "type": "array" + }, + "extras": { + "items": { + "$ref": "#/$defs/PythonPoetryLockExtraEntry" + }, + "type": "array" + } + }, + "type": "object", + "required": [ + "index", + "dependencies" + ] + }, + "PythonPoetryLockExtraEntry": { + "properties": { + "name": { + "type": "string" + }, + "dependencies": { + "items": { + "type": "string" + }, + "type": "array" + } + }, + "type": "object", + "required": [ + "name", + "dependencies" + ] + }, + "RDescription": { + "properties": { + "title": { + "type": "string" + }, + "description": { + "type": "string" + }, + "author": { + "type": "string" + }, + "maintainer": { + "type": "string" + }, + "url": { + "items": { + "type": "string" + }, + "type": "array" + }, + "repository": { + "type": "string" + }, + "built": { + "type": "string" + }, + "needsCompilation": { + "type": "boolean" + }, + "imports": { + "items": { + "type": "string" + }, + "type": "array" + }, + "depends": { + "items": { + "type": "string" + }, + "type": "array" + }, + "suggests": { + "items": { + "type": "string" + }, + "type": "array" + } + }, + "type": "object" + }, + "Relationship": { + "properties": { + "parent": { + "type": "string" + }, + "child": { + "type": "string" + }, + "type": { + "type": "string" + }, + "metadata": true + }, + "type": "object", + "required": [ + "parent", + "child", + "type" + ] + }, + "RpmArchive": { + "properties": { + "name": { + "type": "string" + }, + "version": { + "type": "string" + }, + "epoch": { + "oneOf": [ + { + "type": "integer" + }, + { + "type": "null" + } + ] + }, + "architecture": { + "type": "string" + }, + "release": { + "type": "string" + }, + "sourceRpm": { + "type": "string" + }, + "size": { + "type": "integer" + }, + "vendor": { + "type": "string" + }, + "modularityLabel": { + "type": "string" + }, + "provides": { + "items": { + "type": "string" + }, + "type": "array" + }, + "requires": { + "items": { + "type": "string" + }, + "type": "array" + }, + "files": { + "items": { + "$ref": "#/$defs/RpmFileRecord" + }, + "type": "array" + } + }, + "type": "object", + "required": [ + "name", + "version", + "epoch", + "architecture", + "release", + "sourceRpm", + "size", + "vendor", + "files" + ] + }, + "RpmDbEntry": { + "properties": { + "name": { + "type": "string" + }, + "version": { + "type": "string" + }, + "epoch": { + "oneOf": [ + { + "type": "integer" + }, + { + "type": "null" + } + ] + }, + "architecture": { + "type": "string" + }, + "release": { + "type": "string" + }, + "sourceRpm": { + "type": "string" + }, + "size": { + "type": "integer" + }, + "vendor": { + "type": "string" + }, + "modularityLabel": { + "type": "string" + }, + "provides": { + "items": { + "type": "string" + }, + "type": "array" + }, + "requires": { + "items": { + "type": "string" + }, + "type": "array" + }, + "files": { + "items": { + "$ref": "#/$defs/RpmFileRecord" + }, + "type": "array" + } + }, + "type": "object", + "required": [ + "name", + "version", + "epoch", + "architecture", + "release", + "sourceRpm", + "size", + "vendor", + "files" + ] + }, + "RpmFileRecord": { + "properties": { + "path": { + "type": "string" + }, + "mode": { + "type": "integer" + }, + "size": { + "type": "integer" + }, + "digest": { + "$ref": "#/$defs/Digest" + }, + "userName": { + "type": "string" + }, + "groupName": { + "type": "string" + }, + "flags": { + "type": "string" + } + }, + "type": "object", + "required": [ + "path", + "mode", + "size", + "digest", + "userName", + "groupName", + "flags" + ] + }, + "RubyGemspec": { + "properties": { + "name": { + "type": "string" + }, + "version": { + "type": "string" + }, + "files": { + "items": { + "type": "string" + }, + "type": "array" + }, + "authors": { + "items": { + "type": "string" + }, + "type": "array" + }, + "homepage": { + "type": "string" + } + }, + "type": "object", + "required": [ + "name", + "version" + ] + }, + "RustCargoAuditEntry": { + "properties": { + "name": { + "type": "string" + }, + "version": { + "type": "string" + }, + "source": { + "type": "string" + } + }, + "type": "object", + "required": [ + "name", + "version", + "source" + ] + }, + "RustCargoLockEntry": { + "properties": { + "name": { + "type": "string" + }, + "version": { + "type": "string" + }, + "source": { + "type": "string" + }, + "checksum": { + "type": "string" + }, + "dependencies": { + "items": { + "type": "string" + }, + "type": "array" + } + }, + "type": "object", + "required": [ + "name", + "version", + "source", + "checksum", + "dependencies" + ] + }, + "Schema": { + "properties": { + "version": { + "type": "string" + }, + "url": { + "type": "string" + } + }, + "type": "object", + "required": [ + "version", + "url" + ] + }, + "Source": { + "properties": { + "id": { + "type": "string" + }, + "name": { + "type": "string" + }, + "version": { + "type": "string" + }, + "type": { + "type": "string" + }, + "metadata": true + }, + "type": "object", + "required": [ + "id", + "name", + "version", + "type", + "metadata" + ] + }, + "SwiftPackageManagerLockEntry": { + "properties": { + "revision": { + "type": "string" + } + }, + "type": "object", + "required": [ + "revision" + ] + }, + "SwiplpackPackage": { + "properties": { + "name": { + "type": "string" + }, + "version": { + "type": "string" + }, + "author": { + "type": "string" + }, + "authorEmail": { + "type": "string" + }, + "packager": { + "type": "string" + }, + "packagerEmail": { + "type": "string" + }, + "homepage": { + "type": "string" + }, + "dependencies": { + "items": { + "type": "string" + }, + "type": "array" + } + }, + "type": "object", + "required": [ + "name", + "version", + "author", + "authorEmail", + "packager", + "packagerEmail", + "homepage", + "dependencies" + ] + }, + "WordpressPluginEntry": { + "properties": { + "pluginInstallDirectory": { + "type": "string" + }, + "author": { + "type": "string" + }, + "authorUri": { + "type": "string" + } + }, + "type": "object", + "required": [ + "pluginInstallDirectory" + ] + }, + "cpes": { + "items": { + "$ref": "#/$defs/CPE" + }, + "type": "array" + }, + "licenses": { + "items": { + "$ref": "#/$defs/License" + }, + "type": "array" + } + } +} diff --git a/schema/json/schema-latest.json b/schema/json/schema-latest.json index 1bab78aa6ba..a8819785972 100644 --- a/schema/json/schema-latest.json +++ b/schema/json/schema-latest.json @@ -1,6 +1,6 @@ { "$schema": "https://json-schema.org/draft/2020-12/schema", - "$id": "anchore.io/schema/syft/json/16.0.15/document", + "$id": "anchore.io/schema/syft/json/16.0.16/document", "$ref": "#/$defs/Document", "$defs": { "AlpmDbEntry": { @@ -1436,6 +1436,50 @@ "files" ] }, + "OpamPackage": { + "properties": { + "name": { + "type": "string" + }, + "version": { + "type": "string" + }, + "licenses": { + "items": { + "type": "string" + }, + "type": "array" + }, + "url": { + "type": "string" + }, + "checksum": { + "items": { + "type": "string" + }, + "type": "array" + }, + "homepage": { + "type": "string" + }, + "dependencies": { + "items": { + "type": "string" + }, + "type": "array" + } + }, + "type": "object", + "required": [ + "name", + "version", + "licenses", + "url", + "checksum", + "homepage", + "dependencies" + ] + }, "Package": { "properties": { "id": { @@ -1563,6 +1607,9 @@ { "$ref": "#/$defs/NixStoreEntry" }, + { + "$ref": "#/$defs/OpamPackage" + }, { "$ref": "#/$defs/PhpComposerInstalledEntry" }, diff --git a/syft/format/common/spdxhelpers/to_format_model.go b/syft/format/common/spdxhelpers/to_format_model.go index 3fd136e84df..3f93883cf1b 100644 --- a/syft/format/common/spdxhelpers/to_format_model.go +++ b/syft/format/common/spdxhelpers/to_format_model.go @@ -505,6 +505,14 @@ func toPackageChecksums(p pkg.Package) ([]spdx.Checksum, bool) { Algorithm: spdx.ChecksumAlgorithm(algo), Value: hexStr, }) + case pkg.OpamPackage: + for _, checksum := range meta.Checksums { + parts := strings.Split(checksum, "=") + checksums = append(checksums, spdx.Checksum{ + Algorithm: spdx.ChecksumAlgorithm(strings.ToUpper(parts[0])), + Value: parts[1], + }) + } } return checksums, filesAnalyzed } diff --git a/syft/format/common/spdxhelpers/to_format_model_test.go b/syft/format/common/spdxhelpers/to_format_model_test.go index e986069bb3a..934fc95dd3d 100644 --- a/syft/format/common/spdxhelpers/to_format_model_test.go +++ b/syft/format/common/spdxhelpers/to_format_model_test.go @@ -335,6 +335,31 @@ func Test_toPackageChecksums(t *testing.T) { }, filesAnalyzed: false, }, + { + name: "Opam Package", + pkg: pkg.Package{ + Name: "test", + Version: "1.0.0", + Language: pkg.Go, + Metadata: pkg.OpamPackage{ + Checksums: []string{ + "sha256=f5f1c0b4ad2e0dfa6f79eaaaa3586411925c16f61702208ddd4bad2fc17dc47c", + "sha512=05a359dc8400d4ca200ff255dbd030acd33d2c4acb5020838f772c02cdb5f243f3dbafbc43a8cd51e6b5923a140f84c9e7ea25b2c0fa277bb68b996190d36e3b", + }, + }, + }, + expected: []spdx.Checksum{ + { + Algorithm: "SHA256", + Value: "f5f1c0b4ad2e0dfa6f79eaaaa3586411925c16f61702208ddd4bad2fc17dc47c", + }, + { + Algorithm: "SHA512", + Value: "05a359dc8400d4ca200ff255dbd030acd33d2c4acb5020838f772c02cdb5f243f3dbafbc43a8cd51e6b5923a140f84c9e7ea25b2c0fa277bb68b996190d36e3b", + }, + }, + filesAnalyzed: false, + }, { name: "Package with no metadata type", pkg: pkg.Package{ diff --git a/syft/format/internal/spdxutil/helpers/download_location.go b/syft/format/internal/spdxutil/helpers/download_location.go index 3ed1c9ed662..b2bae8f968b 100644 --- a/syft/format/internal/spdxutil/helpers/download_location.go +++ b/syft/format/internal/spdxutil/helpers/download_location.go @@ -26,6 +26,8 @@ func DownloadLocation(p pkg.Package) string { return NoneIfEmpty(metadata.Dist.URL) case pkg.PhpComposerInstalledEntry: return NoneIfEmpty(metadata.Dist.URL) + case pkg.OpamPackage: + return NoneIfEmpty(metadata.URL) } } return NOASSERTION diff --git a/syft/format/internal/spdxutil/helpers/originator_supplier_test.go b/syft/format/internal/spdxutil/helpers/originator_supplier_test.go index 51965925d1c..67abf1dc502 100644 --- a/syft/format/internal/spdxutil/helpers/originator_supplier_test.go +++ b/syft/format/internal/spdxutil/helpers/originator_supplier_test.go @@ -41,6 +41,7 @@ func Test_OriginatorSupplier(t *testing.T) { pkg.RustCargoLockEntry{}, pkg.SwiftPackageManagerResolvedEntry{}, pkg.SwiplPackEntry{}, + pkg.OpamPackage{}, pkg.YarnLockEntry{}, ) tests := []struct { @@ -350,6 +351,14 @@ func Test_OriginatorSupplier(t *testing.T) { originator: "Person: auth (auth@auth.gov)", supplier: "Person: me (me@auth.com)", }, + { + name: "from ocaml opam", + input: pkg.Package{ + Metadata: pkg.OpamPackage{}, + }, + originator: "", + supplier: "", + }, } for _, test := range tests { t.Run(test.name, func(t *testing.T) { diff --git a/syft/format/internal/spdxutil/helpers/source_info.go b/syft/format/internal/spdxutil/helpers/source_info.go index 77057711264..bf8b2721870 100644 --- a/syft/format/internal/spdxutil/helpers/source_info.go +++ b/syft/format/internal/spdxutil/helpers/source_info.go @@ -64,6 +64,8 @@ func SourceInfo(p pkg.Package) string { answer = "acquired package info from resolved Swift package manifest" case pkg.SwiplPackPkg: answer = "acquired package info from SWI Prolo pack package file" + case pkg.OpamPkg: + answer = "acquired package info from OCaml opam package file" case pkg.GithubActionPkg, pkg.GithubActionWorkflowPkg: answer = "acquired package info from GitHub Actions workflow file or composite action file" case pkg.WordpressPluginPkg: diff --git a/syft/format/internal/spdxutil/helpers/source_info_test.go b/syft/format/internal/spdxutil/helpers/source_info_test.go index df76ac7ebf4..d7da0eab133 100644 --- a/syft/format/internal/spdxutil/helpers/source_info_test.go +++ b/syft/format/internal/spdxutil/helpers/source_info_test.go @@ -271,6 +271,14 @@ func Test_SourceInfo(t *testing.T) { "acquired package info from SWI Prolo pack package file", }, }, + { + input: pkg.Package{ + Type: pkg.OpamPkg, + }, + expected: []string{ + "acquired package info from OCaml opam package file", + }, + }, { input: pkg.Package{ Type: pkg.GithubActionPkg, diff --git a/syft/internal/packagemetadata/generated.go b/syft/internal/packagemetadata/generated.go index db843261cd6..24b96175301 100644 --- a/syft/internal/packagemetadata/generated.go +++ b/syft/internal/packagemetadata/generated.go @@ -34,6 +34,7 @@ func AllTypes() []any { pkg.NixStoreEntry{}, pkg.NpmPackage{}, pkg.NpmPackageLockEntry{}, + pkg.OpamPackage{}, pkg.PhpComposerInstalledEntry{}, pkg.PhpComposerLockEntry{}, pkg.PhpPeclEntry{}, diff --git a/syft/internal/packagemetadata/names.go b/syft/internal/packagemetadata/names.go index 52deebce022..8f8390c2974 100644 --- a/syft/internal/packagemetadata/names.go +++ b/syft/internal/packagemetadata/names.go @@ -103,6 +103,7 @@ var jsonTypes = makeJSONTypes( jsonNamesWithoutLookup(pkg.RpmArchive{}, "rpm-archive", "RpmMetadata"), // the legacy value is split into two types, where the other is preferred jsonNames(pkg.SwiftPackageManagerResolvedEntry{}, "swift-package-manager-lock-entry", "SwiftPackageManagerMetadata"), jsonNames(pkg.SwiplPackEntry{}, "swiplpack-package"), + jsonNames(pkg.OpamPackage{}, "opam-package"), jsonNames(pkg.RustCargoLockEntry{}, "rust-cargo-lock-entry", "RustCargoPackageMetadata"), jsonNamesWithoutLookup(pkg.RustBinaryAuditEntry{}, "rust-cargo-audit-entry", "RustCargoPackageMetadata"), // the legacy value is split into two types, where the other is preferred jsonNames(pkg.WordpressPluginEntry{}, "wordpress-plugin-entry", "WordpressMetadata"), diff --git a/syft/pkg/cataloger/ocaml/cataloger.go b/syft/pkg/cataloger/ocaml/cataloger.go new file mode 100644 index 00000000000..c41ef477b0c --- /dev/null +++ b/syft/pkg/cataloger/ocaml/cataloger.go @@ -0,0 +1,15 @@ +/* +Package ocaml provides a concrete Cataloger implementation for packages relating to the OCaml language ecosystem. +*/ +package ocaml + +import ( + "github.com/anchore/syft/syft/pkg" + "github.com/anchore/syft/syft/pkg/cataloger/generic" +) + +// NewOpamPackageManagerCataloger returns a new cataloger object for OCaml opam. +func NewOpamPackageManagerCataloger() pkg.Cataloger { + return generic.NewCataloger("opam-cataloger"). + WithParserByGlobs(parseOpamPackage, "*opam") +} diff --git a/syft/pkg/cataloger/ocaml/cataloger_test.go b/syft/pkg/cataloger/ocaml/cataloger_test.go new file mode 100644 index 00000000000..b17f13c7821 --- /dev/null +++ b/syft/pkg/cataloger/ocaml/cataloger_test.go @@ -0,0 +1,33 @@ +package ocaml + +import ( + "testing" + + "github.com/anchore/syft/syft/pkg/cataloger/internal/pkgtest" +) + +func Test_PackageCataloger_Globs(t *testing.T) { + tests := []struct { + name string + fixture string + expected []string + }{ + { + name: "obtain package files", + fixture: "test-fixtures/glob-paths", + expected: []string{ + "opam/alcotest.opam", + "opam/ocaml-base-compiler.4.14.0/opam", + }, + }, + } + + for _, test := range tests { + t.Run(test.name, func(t *testing.T) { + pkgtest.NewCatalogTester(). + FromDirectory(t, test.fixture). + ExpectsResolverContentQueries(test.expected). + TestCataloger(t, NewOpamPackageManagerCataloger()) + }) + } +} diff --git a/syft/pkg/cataloger/ocaml/package.go b/syft/pkg/cataloger/ocaml/package.go new file mode 100644 index 00000000000..5144add4107 --- /dev/null +++ b/syft/pkg/cataloger/ocaml/package.go @@ -0,0 +1,37 @@ +package ocaml + +import ( + "github.com/anchore/packageurl-go" + "github.com/anchore/syft/syft/file" + "github.com/anchore/syft/syft/pkg" +) + +func newOpamPackage(m pkg.OpamPackage, fileLocation file.Location) pkg.Package { + p := pkg.Package{ + Name: m.Name, + Version: m.Version, + Licenses: pkg.NewLicenseSet(pkg.NewLicensesFromLocation(fileLocation, m.Licenses...)...), + PURL: opamPackageURL(m.Name, m.Version), + Locations: file.NewLocationSet(fileLocation), + Type: pkg.OpamPkg, + Language: pkg.OCaml, + Metadata: m, + } + + p.SetID() + + return p +} + +func opamPackageURL(name, version string) string { + var qualifiers packageurl.Qualifiers + + return packageurl.NewPackageURL( + "opam", + "", + name, + version, + qualifiers, + "", + ).ToString() +} diff --git a/syft/pkg/cataloger/ocaml/package_test.go b/syft/pkg/cataloger/ocaml/package_test.go new file mode 100644 index 00000000000..551c045246b --- /dev/null +++ b/syft/pkg/cataloger/ocaml/package_test.go @@ -0,0 +1,34 @@ +package ocaml + +import ( + "testing" + + "github.com/stretchr/testify/assert" +) + +func Test_packageURL(t *testing.T) { + + type args struct { + name string + version string + } + tests := []struct { + name string + args args + want string + }{ + { + name: "go case", + args: args{ + name: "ocaml-base-compiler", + version: "5.2.0", + }, + want: "pkg:opam/ocaml-base-compiler@5.2.0", + }, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + assert.Equal(t, tt.want, opamPackageURL(tt.args.name, tt.args.version)) + }) + } +} diff --git a/syft/pkg/cataloger/ocaml/parse_opam.go b/syft/pkg/cataloger/ocaml/parse_opam.go new file mode 100644 index 00000000000..6e56db757f9 --- /dev/null +++ b/syft/pkg/cataloger/ocaml/parse_opam.go @@ -0,0 +1,150 @@ +package ocaml + +import ( + "context" + "encoding/json" + "io" + "path" + "regexp" + "strings" + + "github.com/anchore/syft/internal/log" + "github.com/anchore/syft/syft/artifact" + "github.com/anchore/syft/syft/file" + "github.com/anchore/syft/syft/pkg" + "github.com/anchore/syft/syft/pkg/cataloger/generic" +) + +//nolint:funlen +func parseOpamPackage(_ context.Context, _ file.Resolver, _ *generic.Environment, reader file.LocationReadCloser) ([]pkg.Package, []artifact.Relationship, error) { + var pkgs []pkg.Package + + opamVersionRe := regexp.MustCompile(`(?m)opam-version:\s*"[0-9]+\.[0-9]+"`) + versionRe := regexp.MustCompile(`(?m)^version:\s*"(?P[^"]*)"`) + licenseRe := regexp.MustCompile(`(?m)^license:\s*(?P(?:"[^"]*")|(?:\[[^\]]*\]))`) + homepageRe := regexp.MustCompile(`(?m)homepage:\s*"(?P[^"]+)"`) + urlRe := regexp.MustCompile(`(?m)url\s*{(?P[^}]+)}`) + + data, err := io.ReadAll(reader) + if err != nil { + log.WithFields("error", err).Trace("unable to read opam package") + return nil, nil, nil + } + + if opamVersionRe.FindSubmatch(data) == nil { + log.WithFields("warning", err).Trace("opam version not found") + return nil, nil, nil + } + + // If name is inferred from file name/path + var name, version string + var licenses []string + loc := reader.Location.LocationData.AccessPath + dir, file := path.Split(loc) + + if file == "opam" { + // folder name is the package name and version + s := strings.SplitN(path.Base(dir), ".", 2) + name = s[0] + + if len(s) > 1 { + version = s[1] + } + } else { + // filename is the package name and version is in the content + name = strings.Replace(file, ".opam", "", 1) + + m := versionRe.FindSubmatch(data) + + if m != nil { + version = string(m[1]) + } + } + + entry := pkg.OpamPackage{ + Name: name, + Version: version, + } + + licenseMatch := licenseRe.FindSubmatch(data) + if licenseMatch != nil { + licenses = parseLicenses(string(licenseMatch[1])) + + entry.Licenses = licenses + } + + urlMatch := urlRe.FindSubmatch(data) + if urlMatch != nil { + url, checksums := parseURL(urlMatch[1]) + + if url != "" { + entry.URL = url + } + + if checksums != nil { + entry.Checksums = checksums + } + } + + homepageMatch := homepageRe.FindSubmatch(data) + if homepageMatch != nil { + entry.Homepage = string(homepageMatch[1]) + } + + pkgs = append( + pkgs, + newOpamPackage( + entry, + reader.Location.WithAnnotation(pkg.EvidenceAnnotationKey, pkg.PrimaryEvidenceAnnotation), + ), + ) + + return pkgs, nil, nil +} + +func parseLicenses(licensesStr string) []string { + licenses := []string{} + + if licensesStr[:1] == `"` { + content := licensesStr[1 : len(licensesStr)-1] + licenses = append(licenses, content) + } else { + var d []string + err := json.Unmarshal([]byte(licensesStr), &d) + + if err == nil { + licenses = append(licenses, d...) + } + } + + return licenses +} + +func parseURL(data []byte) (string, []string) { + urlRe := regexp.MustCompile(`(?m)src:\s*"(?P.*)"`) + checksumsRe := regexp.MustCompile(`(?m)checksum:\s*("[^"]*"|\[\s*((?:"[^"]*"\s*)+)\])`) + + urlMatch := urlRe.FindSubmatch(data) + if urlMatch == nil { + return "", nil + } + + url := urlMatch[1] + + var checksum []string + checksumMatch := checksumsRe.FindSubmatch(data) + if checksumMatch != nil { + var fields []string + if checksumMatch[2] != nil { + fields = strings.Fields(string(checksumMatch[2])) + } else { + fields = strings.Fields(string(checksumMatch[1])) + } + + for _, f := range fields { + checksum = append(checksum, strings.ReplaceAll(f, `"`, "")) + } + } + + return string(url), checksum +} diff --git a/syft/pkg/cataloger/ocaml/parse_opam_test.go b/syft/pkg/cataloger/ocaml/parse_opam_test.go new file mode 100644 index 00000000000..f25563be4d8 --- /dev/null +++ b/syft/pkg/cataloger/ocaml/parse_opam_test.go @@ -0,0 +1,166 @@ +package ocaml + +import ( + "testing" + + "github.com/anchore/syft/syft/artifact" + "github.com/anchore/syft/syft/file" + "github.com/anchore/syft/syft/pkg" + "github.com/anchore/syft/syft/pkg/cataloger/internal/pkgtest" + "github.com/stretchr/testify/assert" +) + +func TestParseOpamPackage(t *testing.T) { + fixture1 := "test-fixtures/ocaml-base-compiler.4.14.0/opam" + location1 := file.NewLocation(fixture1) + + fixture2 := "test-fixtures/alcotest.opam" + location2 := file.NewLocation(fixture2) + + tests := []struct { + fixture string + want []pkg.Package + }{ + { + fixture: fixture1, + want: []pkg.Package{ + { + Name: "ocaml-base-compiler", + Version: "4.14.0", + PURL: "pkg:opam/ocaml-base-compiler@4.14.0", + Locations: file.NewLocationSet(location1), + Licenses: pkg.NewLicenseSet( + pkg.NewLicensesFromLocation( + location1, + "LGPL-2.1-or-later WITH OCaml-LGPL-linking-exception", + )..., + ), + Language: pkg.OCaml, + Type: pkg.OpamPkg, + Metadata: pkg.OpamPackage{ + Name: "ocaml-base-compiler", + Version: "4.14.0", + Licenses: []string{"LGPL-2.1-or-later WITH OCaml-LGPL-linking-exception"}, + URL: "https://github.com/ocaml/ocaml/archive/4.14.0.tar.gz", + Checksums: []string{ + "sha256=39f44260382f28d1054c5f9d8bf4753cb7ad64027da792f7938344544da155e8", + }, + Homepage: "https://ocaml.org", + }, + }, + }, + }, + { + fixture: fixture2, + want: []pkg.Package{ + { + Name: "alcotest", + Version: "1.5.0", + PURL: "pkg:opam/alcotest@1.5.0", + Locations: file.NewLocationSet(location2), + Licenses: pkg.NewLicenseSet( + pkg.NewLicensesFromLocation( + location2, + "ISC", + )..., + ), + Language: pkg.OCaml, + Type: pkg.OpamPkg, + Metadata: pkg.OpamPackage{ + Name: "alcotest", + Version: "1.5.0", + Licenses: []string{"ISC"}, + Homepage: "https://github.com/mirage/alcotest", + }, + }, + }, + }, + } + for _, tt := range tests { + t.Run(tt.fixture, func(t *testing.T) { + // TODO: no relationships are under test yet + var expectedRelationships []artifact.Relationship + + pkgtest.TestFileParser(t, tt.fixture, parseOpamPackage, tt.want, expectedRelationships) + }) + } +} + +func TestParseLicense(t *testing.T) { + tests := []struct { + name string + input string + want []string + }{ + { + name: "single license", + input: `"MIT"`, + want: []string{ + "MIT", + }, + }, + { + name: "multiple license", + input: `[ + "MIT", "IST" + ]`, + want: []string{ + "MIT", + "IST", + }, + }, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + assert.Equal(t, tt.want, parseLicenses(tt.input)) + }) + } +} + +func TestParseUrl(t *testing.T) { + tests := []struct { + name string + input string + wantUrl string + wantChecksums []string + }{ + { + name: "single checksums", + input: ` +src: + "https://github.com/mirage/mirage-clock/releases/download/v4.2.0/mirage-clock-4.2.0.tbz" + checksum: + "sha256=fa17d15d5be23c79ba741f5f7cb88ed7112de16a4410cea81c71b98086889847" + `, + wantUrl: "https://github.com/mirage/mirage-clock/releases/download/v4.2.0/mirage-clock-4.2.0.tbz", + wantChecksums: []string{ + "sha256=fa17d15d5be23c79ba741f5f7cb88ed7112de16a4410cea81c71b98086889847", + }, + }, + { + name: "multiple checksums", + input: ` +src: + "https://github.com/mirage/mirage-clock/releases/download/v4.2.0/mirage-clock-4.2.0.tbz" + checksum: [ + "sha256=fa17d15d5be23c79ba741f5f7cb88ed7112de16a4410cea81c71b98086889847" + "sha512=05a359dc8400d4ca200ff255dbd030acd33d2c4acb5020838f772c02cdb5f243f3dbafbc43a8cd51e6b5923a140f84c9e7ea25b2c0fa277bb68b996190d36e3b" + "sha1024=05a359dc8400d4ca200ff255dbd030acd33d2c4acb5020838f772c02cdb5f243f3dbafbc43a8cd51e6b5923a140f84c9e7ea25b2c0fa277bb68b996190d36e3b" + ] + `, + wantUrl: "https://github.com/mirage/mirage-clock/releases/download/v4.2.0/mirage-clock-4.2.0.tbz", + wantChecksums: []string{ + "sha256=fa17d15d5be23c79ba741f5f7cb88ed7112de16a4410cea81c71b98086889847", + "sha512=05a359dc8400d4ca200ff255dbd030acd33d2c4acb5020838f772c02cdb5f243f3dbafbc43a8cd51e6b5923a140f84c9e7ea25b2c0fa277bb68b996190d36e3b", + "sha1024=05a359dc8400d4ca200ff255dbd030acd33d2c4acb5020838f772c02cdb5f243f3dbafbc43a8cd51e6b5923a140f84c9e7ea25b2c0fa277bb68b996190d36e3b", + }, + }, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + url, checksums := parseURL([]byte(tt.input)) + assert.Equal(t, tt.wantUrl, url) + assert.Equal(t, tt.wantChecksums, checksums) + }) + } +} diff --git a/syft/pkg/cataloger/ocaml/test-fixtures/alcotest.opam b/syft/pkg/cataloger/ocaml/test-fixtures/alcotest.opam new file mode 100644 index 00000000000..f1ef6f7a3d9 --- /dev/null +++ b/syft/pkg/cataloger/ocaml/test-fixtures/alcotest.opam @@ -0,0 +1,51 @@ +version: "1.5.0" +# This file is generated by dune, edit dune-project instead +opam-version: "2.0" +synopsis: "Alcotest is a lightweight and colourful test framework" +description: """ +Alcotest exposes simple interface to perform unit tests. It exposes +a simple TESTABLE module type, a check function to assert test +predicates and a run function to perform a list of unit -> unit +test callbacks. + +Alcotest provides a quiet and colorful output where only faulty runs +are fully displayed at the end of the run (with the full logs ready to +inspect), with a simple (yet expressive) query language to select the +tests to run. +""" +maintainer: ["thomas@gazagnaire.org"] +authors: ["Thomas Gazagnaire"] +license: "ISC" +homepage: "https://github.com/mirage/alcotest" +doc: "https://mirage.github.io/alcotest" +bug-reports: "https://github.com/mirage/alcotest/issues" +depends: [ + "dune" {>= "2.8"} + "ocaml" {>= "4.03.0"} + "fmt" {>= "0.8.7"} + "astring" + "cmdliner" {>= "1.0.0"} + "re" + "stdlib-shims" + "uutf" + "ocaml-syntax-shims" + "odoc" {with-doc} +] +conflicts: [ + "result" {< "1.5"} +] +build: [ + ["dune" "subst"] {dev} + [ + "dune" + "build" + "-p" + name + "-j" + jobs + "@install" + "@runtest" {with-test} + "@doc" {with-doc} + ] +] +dev-repo: "git+https://github.com/mirage/alcotest.git" \ No newline at end of file diff --git a/syft/pkg/cataloger/ocaml/test-fixtures/glob-paths/opam/alcotest.opam b/syft/pkg/cataloger/ocaml/test-fixtures/glob-paths/opam/alcotest.opam new file mode 100644 index 00000000000..882b6040c5d --- /dev/null +++ b/syft/pkg/cataloger/ocaml/test-fixtures/glob-paths/opam/alcotest.opam @@ -0,0 +1 @@ +bogus \ No newline at end of file diff --git a/syft/pkg/cataloger/ocaml/test-fixtures/glob-paths/opam/ocaml-base-compiler.4.14.0/opam b/syft/pkg/cataloger/ocaml/test-fixtures/glob-paths/opam/ocaml-base-compiler.4.14.0/opam new file mode 100644 index 00000000000..882b6040c5d --- /dev/null +++ b/syft/pkg/cataloger/ocaml/test-fixtures/glob-paths/opam/ocaml-base-compiler.4.14.0/opam @@ -0,0 +1 @@ +bogus \ No newline at end of file diff --git a/syft/pkg/cataloger/ocaml/test-fixtures/ocaml-base-compiler.4.14.0/opam b/syft/pkg/cataloger/ocaml/test-fixtures/ocaml-base-compiler.4.14.0/opam new file mode 100644 index 00000000000..15e874ec870 --- /dev/null +++ b/syft/pkg/cataloger/ocaml/test-fixtures/ocaml-base-compiler.4.14.0/opam @@ -0,0 +1,93 @@ +opam-version: "2.0" +synopsis: "Official release 4.14.0" +maintainer: [ + "David Allsopp " + "Florian Angeletti " +] +authors: "Xavier Leroy and many contributors" +license: "LGPL-2.1-or-later WITH OCaml-LGPL-linking-exception" +homepage: "https://ocaml.org" +bug-reports: "https://github.com/ocaml/opam-repository/issues" +depends: [ + "ocaml" {= "4.14.0" & post} + "base-unix" {post} + "base-bigarray" {post} + "base-threads" {post} + "host-arch-arm32" {arch = "arm32" & post} + "host-arch-arm64" {arch = "arm64" & post} + "host-arch-ppc64" {arch = "ppc64" & post} + "host-arch-riscv64" {arch = "riscv64" & post} + "host-arch-s390x" {arch = "s390x" & post} + "host-arch-x86_32" {os != "win32" & arch = "x86_32" & post} + "host-arch-x86_64" {os != "win32" & arch = "x86_64" & post} + "host-arch-unknown" + {os != "win32" & arch != "arm32" & arch != "arm64" & arch != "ppc64" & + arch != "riscv64" & + arch != "s390x" & + arch != "x86_32" & + arch != "x86_64" & + post} + (("arch-x86_64" {os = "win32" & arch = "x86_64"} & + (("system-mingw" & "mingw-w64-shims" {os-distribution = "cygwin" & post}) | + "system-msvc")) | + ("arch-x86_32" {os = "win32"} & + (("system-mingw" & "mingw-w64-shims" {os-distribution = "cygwin" & post}) | + "system-msvc")) | + "host-system-other" {os != "win32" & post}) + "ocaml-options-vanilla" {post} + "flexdll" {>= "0.36" & os = "win32"} +] +conflict-class: "ocaml-core-compiler" +flags: compiler +setenv: CAML_LD_LIBRARY_PATH = "%{lib}%/stublibs" +build: [ + [ + "./configure" + "--host=x86_64-pc-windows" + {system-msvc:installed & arch-x86_64:installed} + "--host=x86_64-w64-mingw32" + {os-distribution = "cygwin" & system-mingw:installed & + arch-x86_64:installed} + "--host=i686-pc-windows" {system-msvc:installed & arch-x86_32:installed} + "--host=i686-w64-mingw32" + {os-distribution = "cygwin" & system-mingw:installed & + arch-x86_32:installed} + "--prefix=%{prefix}%" + "--docdir=%{doc}%/ocaml" + "--with-flexdll=%{flexdll:share}%" {os = "win32" & flexdll:installed} + "-C" + "CC=cc" {os = "openbsd" | os = "macos"} + "ASPP=cc -c" {os = "openbsd" | os = "macos"} + ] + [make "-j%{jobs}%"] +] +install: [make "install"] +build-env: MSYS2_ARG_CONV_EXCL = "*" +post-messages: [ + """\ +A failure in the middle of the build may be caused by build parallelism + (enabled by default). + Please file a bug report at https://github.com/ocaml/opam-repository/issues""" + {failure & jobs > "1"} + """\ +You can try installing again including --jobs=1 + to force a sequential build instead.""" + {failure & jobs > "1" & opam-version >= "2.0.5"} +] +dev-repo: "git+https://github.com/ocaml/ocaml#4.14" +url { + src: "https://github.com/ocaml/ocaml/archive/4.14.0.tar.gz" + checksum: + "sha256=39f44260382f28d1054c5f9d8bf4753cb7ad64027da792f7938344544da155e8" +} +extra-source "ocaml-base-compiler.install" { + src: + "https://raw.githubusercontent.com/ocaml/opam-source-archives/main/patches/ocaml-base-compiler/ocaml-base-compiler.install" + checksum: [ + "sha256=79f2a1a5044a91350a0eb6ce12e261a72a2855c094c425cddf3860e58c486678" + "md5=3e969b841df1f51ca448e6e6295cb451" + ] +} +x-env-path-rewrite: [ + [CAML_LD_LIBRARY_PATH (";" {os = "win32"} ":" {os != "win32"}) "target"] +] diff --git a/syft/pkg/language.go b/syft/pkg/language.go index 24e2de35f42..d9289b2dad7 100644 --- a/syft/pkg/language.go +++ b/syft/pkg/language.go @@ -22,6 +22,7 @@ const ( Java Language = "java" JavaScript Language = "javascript" Lua Language = "lua" + OCaml Language = "ocaml" PHP Language = "php" Python Language = "python" R Language = "R" @@ -43,6 +44,7 @@ var AllLanguages = []Language{ Java, JavaScript, Lua, + OCaml, PHP, Python, R, @@ -92,6 +94,8 @@ func LanguageByName(name string) Language { return Swift case "swipl", string(SwiplPackPkg): return Swipl + case "ocaml", string(OpamPkg): + return OCaml case packageurl.TypeConan, string(CPP): return CPP case packageurl.TypeHackage, string(Haskell): diff --git a/syft/pkg/language_test.go b/syft/pkg/language_test.go index 5519a332bbd..d5ce5af266d 100644 --- a/syft/pkg/language_test.go +++ b/syft/pkg/language_test.go @@ -86,6 +86,10 @@ func TestLanguageFromPURL(t *testing.T) { purl: "pkg:luarocks/kong@3.7.0", want: Lua, }, + { + purl: "pkg:opam/ocaml-base-compiler@ 5.2.0", + want: OCaml, + }, } var languages = strset.New() @@ -227,6 +231,10 @@ func TestLanguageByName(t *testing.T) { name: "swiplpack", language: Swipl, }, + { + name: "opam", + language: OCaml, + }, { name: "pod", language: Swift, diff --git a/syft/pkg/ocaml.go b/syft/pkg/ocaml.go new file mode 100644 index 00000000000..350d0433994 --- /dev/null +++ b/syft/pkg/ocaml.go @@ -0,0 +1,11 @@ +package pkg + +type OpamPackage struct { + Name string `toml:"name" json:"name"` + Version string `toml:"version" json:"version"` + Licenses []string `mapstructure:"licenses" json:"licenses"` + URL string `mapstructure:"url" json:"url"` + Checksums []string `mapstructure:"checksums" json:"checksum"` + Homepage string `json:"homepage"` + Dependencies []string `toml:"dependencies" json:"dependencies"` +} diff --git a/syft/pkg/type.go b/syft/pkg/type.go index cdb06382863..7cebaa8e1da 100644 --- a/syft/pkg/type.go +++ b/syft/pkg/type.go @@ -43,6 +43,7 @@ const ( RustPkg Type = "rust-crate" SwiftPkg Type = "swift" SwiplPackPkg Type = "swiplpack" + OpamPkg Type = "opam" WordpressPluginPkg Type = "wordpress-plugin" ) @@ -80,12 +81,13 @@ var AllPkgs = []Type{ RustPkg, SwiftPkg, SwiplPackPkg, + OpamPkg, WordpressPluginPkg, } // PackageURLType returns the PURL package type for the current package. // -//nolint:funlen +//nolint:funlen, gocyclo func (t Type) PackageURLType() string { switch t { case AlpmPkg: @@ -145,6 +147,8 @@ func (t Type) PackageURLType() string { return packageurl.TypeSwift case SwiplPackPkg: return "swiplpack" + case OpamPkg: + return "opam" case WordpressPluginPkg: return "wordpress-plugin" default: @@ -223,6 +227,8 @@ func TypeByName(name string) Type { return SwiftPkg case "swiplpack": return SwiplPackPkg + case "opam": + return OpamPkg case "wordpress-plugin": return WordpressPluginPkg default: diff --git a/syft/pkg/type_test.go b/syft/pkg/type_test.go index b79ad772dd1..6607abd0634 100644 --- a/syft/pkg/type_test.go +++ b/syft/pkg/type_test.go @@ -115,6 +115,10 @@ func TestTypeFromPURL(t *testing.T) { purl: "pkg:swiplpack/condition@0.1.1", expected: SwiplPackPkg, }, + { + purl: "pkg:opam/ocaml-base-compiler@5.2.0", + expected: OpamPkg, + }, } var pkgTypes []string From 98bd4e99b65f6a02c50c25d8e4cff8433cf381a0 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 10 Sep 2024 10:35:43 -0400 Subject: [PATCH 116/122] chore(deps): bump golang.org/x/net from 0.28.0 to 0.29.0 (#3203) Bumps [golang.org/x/net](https://github.com/golang/net) from 0.28.0 to 0.29.0. - [Commits](https://github.com/golang/net/compare/v0.28.0...v0.29.0) --- updated-dependencies: - dependency-name: golang.org/x/net dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- go.mod | 10 +++++----- go.sum | 20 ++++++++++---------- 2 files changed, 15 insertions(+), 15 deletions(-) diff --git a/go.mod b/go.mod index 23cca47d1bb..30a9bb0e17b 100644 --- a/go.mod +++ b/go.mod @@ -79,7 +79,7 @@ require ( github.com/zyedidia/generic v1.2.2-0.20230320175451-4410d2372cb1 go.uber.org/goleak v1.3.0 golang.org/x/mod v0.21.0 - golang.org/x/net v0.28.0 + golang.org/x/net v0.29.0 gopkg.in/yaml.v3 v3.0.1 modernc.org/sqlite v1.33.0 ) @@ -227,11 +227,11 @@ require ( go.opentelemetry.io/otel/trace v1.19.0 // indirect go.uber.org/atomic v1.9.0 // indirect go.uber.org/multierr v1.9.0 // indirect - golang.org/x/crypto v0.26.0 // indirect + golang.org/x/crypto v0.27.0 // indirect golang.org/x/sync v0.8.0 // indirect - golang.org/x/sys v0.24.0 // indirect - golang.org/x/term v0.23.0 // indirect - golang.org/x/text v0.17.0 // indirect + golang.org/x/sys v0.25.0 // indirect + golang.org/x/term v0.24.0 // indirect + golang.org/x/text v0.18.0 // indirect golang.org/x/tools v0.21.1-0.20240508182429-e35e4ccd0d2d // indirect golang.org/x/xerrors v0.0.0-20220907171357-04be3eba64a2 // indirect google.golang.org/genproto/googleapis/rpc v0.0.0-20231120223509-83a465c0220f // indirect diff --git a/go.sum b/go.sum index 6eaf663a342..3d6c2b9f119 100644 --- a/go.sum +++ b/go.sum @@ -864,8 +864,8 @@ golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5y golang.org/x/crypto v0.0.0-20220622213112-05595931fe9d/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4= golang.org/x/crypto v0.3.1-0.20221117191849-2c476679df9a/go.mod h1:hebNnKkNXi2UzZN1eVRvBB7co0a+JxK6XbPiWVs/3J4= golang.org/x/crypto v0.7.0/go.mod h1:pYwdfH91IfpZVANVyUOhSIPZaFoJGxTFbZhFTx+dXZU= -golang.org/x/crypto v0.26.0 h1:RrRspgV4mU+YwB4FYnuBoKsUapNIL5cohGAmSH3azsw= -golang.org/x/crypto v0.26.0/go.mod h1:GY7jblb9wI+FOo5y8/S2oY4zWP07AkOJ4+jxCqdqn54= +golang.org/x/crypto v0.27.0 h1:GXm2NjJrPaiv/h1tb2UH8QfgC/hOf/+z0p6PT8o1w7A= +golang.org/x/crypto v0.27.0/go.mod h1:1Xngt8kV6Dvbssa53Ziq6Eqn0HqbZi5Z6R0ZpwQzt70= 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= @@ -954,8 +954,8 @@ golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug golang.org/x/net v0.2.0/go.mod h1:KqCZLdyyvdV855qA2rE3GC2aiw5xGR5TEjj8smXukLY= golang.org/x/net v0.6.0/go.mod h1:2Tu9+aMcznHK/AK1HMvgo6xiTLG5rD5rZLDS+rp2Bjs= golang.org/x/net v0.8.0/go.mod h1:QVkue5JL9kW//ek3r6jTKnTFis1tRmNAW2P1shuFdJc= -golang.org/x/net v0.28.0 h1:a9JDOJc5GMUJ0+UDqmLT86WiEy7iWyIhz8gz8E4e5hE= -golang.org/x/net v0.28.0/go.mod h1:yqtgsTWOOnlGLG9GFRrK3++bGOUEkNBoHZc8MEDWPNg= +golang.org/x/net v0.29.0 h1:5ORfpBpCs4HzDYoodCDBbwHzdR5UrLBZ3sOnUJmFoHo= +golang.org/x/net v0.29.0/go.mod h1:gLkgy8jTGERgjzMic6DS9+SP0ajcu6Xu3Orq/SpETg0= 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= @@ -1067,15 +1067,15 @@ golang.org/x/sys v0.2.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.3.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.5.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.24.0 h1:Twjiwq9dn6R1fQcyiK+wQyHWfaz/BJB+YIpzU/Cv3Xg= -golang.org/x/sys v0.24.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= +golang.org/x/sys v0.25.0 h1:r+8e+loiHxRqhXVl6ML1nO3l1+oFoWbnlu2Ehimmi34= +golang.org/x/sys v0.25.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= golang.org/x/term v0.2.0/go.mod h1:TVmDHMZPmdnySmBfhjOoOdhjzdE1h4u1VwSiw2l1Nuc= golang.org/x/term v0.5.0/go.mod h1:jMB1sMXY+tzblOD4FWmEbocvup2/aLOaQEp7JmGp78k= golang.org/x/term v0.6.0/go.mod h1:m6U89DPEgQRMq3DNkDClhWw02AUbt2daBVO4cn4Hv9U= -golang.org/x/term v0.23.0 h1:F6D4vR+EHoL9/sWAWgAR1H2DcHr4PareCbAaCo1RpuU= -golang.org/x/term v0.23.0/go.mod h1:DgV24QBUrK6jhZXl+20l6UWznPlwAHm1Q1mGHtydmSk= +golang.org/x/term v0.24.0 h1:Mh5cbb+Zk2hqqXNO7S1iTjEphVL+jb8ZWaqh/g+JWkM= +golang.org/x/term v0.24.0/go.mod h1:lOBK/LVxemqiMij05LGJ0tzNr8xlmwBRJ81PX6wVLH8= 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= @@ -1088,8 +1088,8 @@ golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ= golang.org/x/text v0.4.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8= golang.org/x/text v0.7.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8= golang.org/x/text v0.8.0/go.mod h1:e1OnstbJyHTd6l/uOt8jFFHp6TRDWZR/bV3emEE/zU8= -golang.org/x/text v0.17.0 h1:XtiM5bkSOt+ewxlOE/aE/AKEHibwj/6gvWMl9Rsh0Qc= -golang.org/x/text v0.17.0/go.mod h1:BuEKDfySbSR4drPmRPG/7iBdf8hvFMuRexcpahXilzY= +golang.org/x/text v0.18.0 h1:XvMDiNzPAl0jr17s6W9lcaIhGUfUORdGCNsuLmPG224= +golang.org/x/text v0.18.0/go.mod h1:BuEKDfySbSR4drPmRPG/7iBdf8hvFMuRexcpahXilzY= 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= From fce14fd5378c543fbf6f2dc5fbe11bf4ee5d83a1 Mon Sep 17 00:00:00 2001 From: "anchore-actions-token-generator[bot]" <102182147+anchore-actions-token-generator[bot]@users.noreply.github.com> Date: Tue, 10 Sep 2024 10:36:50 -0400 Subject: [PATCH 117/122] chore(deps): update CPE dictionary index (#3206) Signed-off-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com> Co-authored-by: wagoodman <590471+wagoodman@users.noreply.github.com> --- .../dictionary/data/cpe-index.json | 39 +++++++++++++++++-- 1 file changed, 36 insertions(+), 3 deletions(-) diff --git a/syft/pkg/cataloger/internal/cpegenerate/dictionary/data/cpe-index.json b/syft/pkg/cataloger/internal/cpegenerate/dictionary/data/cpe-index.json index abd3b6ca8e8..3227665cdca 100644 --- a/syft/pkg/cataloger/internal/cpegenerate/dictionary/data/cpe-index.json +++ b/syft/pkg/cataloger/internal/cpegenerate/dictionary/data/cpe-index.json @@ -2528,6 +2528,9 @@ "chart.js": [ "cpe:2.3:a:chartjs:chart.js:*:*:*:*:*:node.js:*:*" ], + "chartist": [ + "cpe:2.3:a:chartist:chartist:*:*:*:*:*:node.js:*:*" + ], "chatbyvista": [ "cpe:2.3:a:chatbyvista_project:chatbyvista:*:*:*:*:*:node.js:*:*" ], @@ -5567,8 +5570,8 @@ "cpe:2.3:a:pyconuk:conference-scheduler-cli:*:*:*:*:*:*:*:*" ], "cryptography": [ - "cpe:2.3:a:cryptography_project:cryptography:*:*:*:*:*:python:*:*", - "cpe:2.3:a:python-cryptography_project:python-cryptography:*:*:*:*:*:*:*:*" + "cpe:2.3:a:cryptography.io:cryptography:*:*:*:*:*:*:*:*", + "cpe:2.3:a:cryptography.io:cryptography:*:*:*:*:*:python:*:*" ], "cvxopt": [ "cpe:2.3:a:cvxopt_project:cvxopt:*:*:*:*:*:python:*:*" @@ -7659,6 +7662,9 @@ "apollo13-framework-extensions": [ "cpe:2.3:a:apollo13themes:apollo13_framework_extensions:*:*:*:*:*:wordpress:*:*" ], + "app-builder": [ + "cpe:2.3:a:appcheap:app_builder:*:*:*:*:*:wordpress:*:*" + ], "apply-online": [ "cpe:2.3:a:spiderteams:applyonline_-_application_form_builder_and_manager:*:*:*:*:*:wordpress:*:*" ], @@ -7881,6 +7887,9 @@ "ays-popup-box": [ "cpe:2.3:a:ays-pro:popup_box:*:*:*:*:*:wordpress:*:*" ], + "azurecurve-toggle-showhide": [ + "cpe:2.3:a:azurecurve:toggle_show\\/hide:*:*:*:*:*:wordpress:*:*" + ], "b2bking-wholesale-for-woocommerce": [ "cpe:2.3:a:webwizards:b2bking:*:*:*:*:*:wordpress:*:*" ], @@ -8064,6 +8073,7 @@ "cpe:2.3:a:bitapps:bit_assist:*:*:*:*:*:wordpress:*:*" ], "bit-form": [ + "cpe:2.3:a:bitapps:bit_form:*:*:*:*:free:wordpress:*:*", "cpe:2.3:a:bitapps:contact_form_builder:*:*:*:*:*:wordpress:*:*" ], "bitcoin-faucet": [ @@ -8078,6 +8088,9 @@ "blackhole-bad-bots": [ "cpe:2.3:a:plugin-planet:blackhole_for_bad_bots:*:*:*:*:*:wordpress:*:*" ], + "block-for-font-awesome": [ + "cpe:2.3:a:getbutterfly:block_for_font_awesome:*:*:*:*:*:wordpress:*:*" + ], "block-options": [ "cpe:2.3:a:extendify:editorskit:*:*:*:*:*:wordpress:*:*" ], @@ -10085,6 +10098,9 @@ "embed-comment-images": [ "cpe:2.3:a:embed_images_in_comments_project:embed_images_in_comments:*:*:*:*:*:wordpress:*:*" ], + "embed-power-bi": [ + "cpe:2.3:a:atlaspolicy:power_bi_embedded:*:*:*:*:*:wordpress:*:*" + ], "embed-swagger": [ "cpe:2.3:a:embed_swagger_project:embed_swagger:*:*:*:*:*:wordpress:*:*" ], @@ -10783,6 +10799,9 @@ "furikake": [ "cpe:2.3:a:furikake_project:furikake:*:*:*:*:*:wordpress:*:*" ], + "fusion-slider": [ + "cpe:2.3:a:webhuntinfotech:universal_slider:*:*:*:*:*:wordpress:*:*" + ], "futurio-extra": [ "cpe:2.3:a:futuriowp:futurio_extra:*:*:*:*:*:wordpress:*:*" ], @@ -12215,6 +12234,9 @@ "login-lockdown": [ "cpe:2.3:a:webfactoryltd:wp_login_lockdown:*:*:*:*:*:wordpress:*:*" ], + "login-logo-editor-by-oizuled": [ + "cpe:2.3:a:amplifyplugins:login_logo_editor:*:*:*:*:*:wordpress:*:*" + ], "login-logout-menu": [ "cpe:2.3:a:wpbrigade:login_logout_menu:*:*:*:*:*:wordpress:*:*" ], @@ -15716,6 +15738,9 @@ "template-events-calendar": [ "cpe:2.3:a:coolplugins:events_shortcodes_for_the_events_calendar:*:*:*:*:*:wordpress:*:*" ], + "template-kit-export": [ + "cpe:2.3:a:envato:template_kit_-_export:*:*:*:*:*:wordpress:*:*" + ], "templately": [ "cpe:2.3:a:templately:templately:*:*:*:*:*:wordpress:*:*" ], @@ -17680,6 +17705,9 @@ "wp-knowledgebase": [ "cpe:2.3:a:wpknowledgebase:wordpress_knowledge_base_\\\u0026_documentation_plugin:*:*:*:*:*:wordpress:*:*" ], + "wp-last-modified-info": [ + "cpe:2.3:a:sayandatta:wp_last_modified_info:*:*:*:*:*:wordpress:*:*" + ], "wp-latest-posts": [ "cpe:2.3:a:joomunited:wp_latest_posts:*:*:*:*:*:wordpress:*:*" ], @@ -18636,6 +18664,9 @@ "yith-woocommerce-product-add-ons": [ "cpe:2.3:a:yithemes:yith_woocommerce_product_add-ons:*:*:*:*:free:wordpress:*:*" ], + "yith-woocommerce-tab-manager": [ + "cpe:2.3:a:yithemes:yith_woocommerce_tab_manager:*:*:*:*:*:wordpress:*:*" + ], "ymc-smart-filter": [ "cpe:2.3:a:ymc-22:filter_\\\u0026_grids:*:*:*:*:*:wordpress:*:*" ], @@ -18714,7 +18745,9 @@ "cpe:2.3:a:zendrop:zendrop:*:*:*:*:*:wordpress:*:*" ], "zephyr-project-manager": [ - "cpe:2.3:a:zephyr_project_manager_project:zephyr_project_manager:*:*:*:*:*:wordpress:*:*" + "cpe:2.3:a:zephyr-one:zephyr_project_manager:*:*:*:*:*:wordpress:*:*", + "cpe:2.3:a:zephyr_project_manager_project:zephyr_project_manager:*:*:*:*:*:wordpress:*:*", + "cpe:2.3:a:zephyrproject:zephyr_project_manager:*:*:*:*:*:wordpress:*:*" ], "zero-bs-crm": [ "cpe:2.3:a:automattic:jetpack_crm:*:*:*:*:*:wordpress:*:*" From dbc4238f63c027efc09ce5fe51e069c1145f6846 Mon Sep 17 00:00:00 2001 From: Laurent Goderre Date: Tue, 10 Sep 2024 10:58:20 -0400 Subject: [PATCH 118/122] Add haskell binaries cataloger (#3078) Signed-off-by: Laurent Goderre --- .../binary/classifier_cataloger_test.go | 22 +++++++++++++ syft/pkg/cataloger/binary/classifiers.go | 30 ++++++++++++++++++ .../haskell-cabal/3.10.3.0/linux-amd64/cabal | Bin 0 -> 350 bytes .../haskell-ghc/9.6.5/linux-amd64/ghc-9.6.5 | Bin 0 -> 353 bytes .../binary/test-fixtures/config.yaml | 16 ++++++++++ 5 files changed, 68 insertions(+) create mode 100644 syft/pkg/cataloger/binary/test-fixtures/classifiers/snippets/haskell-cabal/3.10.3.0/linux-amd64/cabal create mode 100644 syft/pkg/cataloger/binary/test-fixtures/classifiers/snippets/haskell-ghc/9.6.5/linux-amd64/ghc-9.6.5 diff --git a/syft/pkg/cataloger/binary/classifier_cataloger_test.go b/syft/pkg/cataloger/binary/classifier_cataloger_test.go index 4e283a56a1e..c1bfbb322f0 100644 --- a/syft/pkg/cataloger/binary/classifier_cataloger_test.go +++ b/syft/pkg/cataloger/binary/classifier_cataloger_test.go @@ -961,6 +961,28 @@ func Test_Cataloger_PositiveCases(t *testing.T) { Metadata: metadata("swipl-binary"), }, }, + { + logicalFixture: "haskell-ghc/9.6.5/linux-amd64", + expected: pkg.Package{ + Name: "haskell/ghc", + Version: "9.6.5", + Type: "binary", + PURL: "pkg:generic/haskell/ghc@9.6.5", + Locations: locations("ghc-9.6.5"), + Metadata: metadata("haskell-ghc-binary"), + }, + }, + { + logicalFixture: "haskell-cabal/3.10.3.0/linux-amd64", + expected: pkg.Package{ + Name: "haskell/cabal", + Version: "3.10.3.0", + Type: "binary", + PURL: "pkg:generic/haskell/cabal@3.10.3.0", + Locations: locations("cabal"), + Metadata: metadata("haskell-cabal-binary"), + }, + }, { logicalFixture: "nginx/1.25.1/linux-amd64", expected: pkg.Package{ diff --git a/syft/pkg/cataloger/binary/classifiers.go b/syft/pkg/cataloger/binary/classifiers.go index 46afa87f5cb..5290b4d984e 100644 --- a/syft/pkg/cataloger/binary/classifiers.go +++ b/syft/pkg/cataloger/binary/classifiers.go @@ -447,6 +447,36 @@ func DefaultClassifiers() []Classifier { PURL: mustPURL("pkg:generic/swipl@version"), CPEs: singleCPE("cpe:2.3:a:erlang:erlang\\/otp:*:*:*:*:*:*:*:*", cpe.NVDDictionaryLookupSource), }, + { + Class: "haskell-ghc-binary", + FileGlob: "**/ghc*", + EvidenceMatcher: FileContentsVersionMatcher( + `(?m)\x00GHC (?P[0-9]+\.[0-9]+\.[0-9]+)\x00`, + ), + Package: "haskell/ghc", + PURL: mustPURL("pkg:generic/haskell/ghc@version"), + CPEs: singleCPE("cpe:2.3:a:haskell:ghc:*:*:*:*:*:*:*:*"), + }, + { + Class: "haskell-cabal-binary", + FileGlob: "**/cabal", + EvidenceMatcher: FileContentsVersionMatcher( + `(?m)\x00Cabal-(?P[0-9]+\.[0-9]+\.[0-9]+(\.[0-9]+)?)-`, + ), + Package: "haskell/cabal", + PURL: mustPURL("pkg:generic/haskell/cabal@version"), + CPEs: singleCPE("cpe:2.3:a:haskell:cabal:*:*:*:*:*:*:*:*"), + }, + { + Class: "haskell-stack-binary", + FileGlob: "**/stack", + EvidenceMatcher: FileContentsVersionMatcher( + `(?m)Version\s*(?P[0-9]+\.[0-9]+\.[0-9]+),\s*Git`, + ), + Package: "haskell/stack", + PURL: mustPURL("pkg:generic/haskell/stack@version"), + CPEs: singleCPE("cpe:2.3:a:haskell:stack:*:*:*:*:*:*:*:*"), + }, { Class: "consul-binary", FileGlob: "**/consul", diff --git a/syft/pkg/cataloger/binary/test-fixtures/classifiers/snippets/haskell-cabal/3.10.3.0/linux-amd64/cabal b/syft/pkg/cataloger/binary/test-fixtures/classifiers/snippets/haskell-cabal/3.10.3.0/linux-amd64/cabal new file mode 100644 index 0000000000000000000000000000000000000000..efc08c38af003803204a2647b785bfd5834dc757 GIT binary patch literal 350 zcmb7?5Loj5kGC4gE(U=`cTxNTf%$<9`e1IP0%Y6~0pd$s|j0U~eo?vyuRC8!`XDTU6G zf;FJmt97fz3?T+XCd@J=K~h+EugL}}HBJHuY|7HkND9pq zYVVYuHgFIbTb6~V&w>2sO+GrOUTgp0vtp$;aUG?e;@W0@EN#EL|K5BtLP=qSyp(p- Vm~ne3=XfjWef+_Qr$+rh;1>r0X=DHZ literal 0 HcmV?d00001 diff --git a/syft/pkg/cataloger/binary/test-fixtures/classifiers/snippets/haskell-ghc/9.6.5/linux-amd64/ghc-9.6.5 b/syft/pkg/cataloger/binary/test-fixtures/classifiers/snippets/haskell-ghc/9.6.5/linux-amd64/ghc-9.6.5 new file mode 100644 index 0000000000000000000000000000000000000000..551b9978c44ce488763aaccc19ff43a019c84c31 GIT binary patch literal 353 zcmXv~v2Mg53}t4h)IUIX%T;O+U?7mSLvQcc35dBwmm{YpQq@oFUzMb-2g}dT@5y!v zH|*GDNR8)~8#?E_;My_S8sn9u6PC+5RICJD%6Pxy`Zfe*Y{$SEXwhMmR_Tm7^&r70 z516FSPGOK9werfx)&)$ihoGgky=avcBGNog_;03_N-0~++GdSL%ie`xbWSaT>#G}} z2*UXc#z2B3LRCZr5usuiC_NsJEPk!X{?=sc%WTR)!5q8Sgvd=d9L_$dOtMNxvsigu@cw_?zrNzsejw`hv$7@#gE&jsl4Wr H+l~JL51U@J literal 0 HcmV?d00001 diff --git a/syft/pkg/cataloger/binary/test-fixtures/config.yaml b/syft/pkg/cataloger/binary/test-fixtures/config.yaml index ac433555c22..58408325be8 100644 --- a/syft/pkg/cataloger/binary/test-fixtures/config.yaml +++ b/syft/pkg/cataloger/binary/test-fixtures/config.yaml @@ -78,6 +78,22 @@ from-images: paths: - /usr/lib/swipl/bin/x86_64-linux/swipl + - name: haskell-ghc + version: 9.6.5 + images: + - ref: haskell:9.6.5-slim-buster@sha256:04a7293eb792b82335dffa7f08532657517ed9b4f01d52c1b499ad22deb3c6b1 + platform: linux/amd64 + paths: + - /opt/ghc/9.6.5/lib/ghc-9.6.5/bin/ghc-9.6.5 + + - name: haskell-cabal + version: 3.10.3.0 + images: + - ref: haskell:9.6.5-slim-buster@sha256:04a7293eb792b82335dffa7f08532657517ed9b4f01d52c1b499ad22deb3c6b1 + platform: linux/amd64 + paths: + - /usr/local/bin/cabal + - version: 1.21.3 images: - ref: golang:1.21.3@sha256:3ce8313c3513515040870c55e0c041a2b94f3576a58cfd3948633604214aa811 From c33a51d3d839ba619ea2217ee00a56be23f9fb9f Mon Sep 17 00:00:00 2001 From: Keith Zantow Date: Tue, 10 Sep 2024 15:19:05 -0400 Subject: [PATCH 119/122] chore: restore ci-check.sh script (#3218) Signed-off-by: Keith Zantow --- .github/scripts/ci-check.sh | 11 +++++++++++ Taskfile.yaml | 11 +---------- 2 files changed, 12 insertions(+), 10 deletions(-) create mode 100644 .github/scripts/ci-check.sh diff --git a/.github/scripts/ci-check.sh b/.github/scripts/ci-check.sh new file mode 100644 index 00000000000..0ab83a318ae --- /dev/null +++ b/.github/scripts/ci-check.sh @@ -0,0 +1,11 @@ +#!/usr/bin/env bash + +red=$(tput setaf 1) +bold=$(tput bold) +normal=$(tput sgr0) + +# assert we are running in CI (or die!) +if [[ -z "$CI" ]]; then + echo "${bold}${red}This step should ONLY be run in CI. Exiting...${normal}" + exit 1 +fi diff --git a/Taskfile.yaml b/Taskfile.yaml index feb12f636ec..5e7f2c000ee 100644 --- a/Taskfile.yaml +++ b/Taskfile.yaml @@ -593,16 +593,7 @@ tasks: ci-check: # desc: "[CI only] Are you in CI?" cmds: - - cmd: | - red=$(tput setaf 1) - bold=$(tput bold) - normal=$(tput sgr0) - - # assert we are running in CI (or die!) - if [[ -z "$CI" ]]; then - echo "${bold}${red}This step should ONLY be run in CI. Exiting...${normal}" - exit 1 - fi + - cmd: .github/scripts/ci-check.sh silent: true ci-release: From 61a9fde01c9d5409898c4ae0a94bb7078428538c Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 10 Sep 2024 21:20:43 +0000 Subject: [PATCH 120/122] chore(deps): bump github.com/opencontainers/runc from 1.1.12 to 1.1.14 (#3219) Bumps [github.com/opencontainers/runc](https://github.com/opencontainers/runc) from 1.1.12 to 1.1.14. - [Release notes](https://github.com/opencontainers/runc/releases) - [Changelog](https://github.com/opencontainers/runc/blob/main/CHANGELOG.md) - [Commits](https://github.com/opencontainers/runc/compare/v1.1.12...v1.1.14) --- updated-dependencies: - dependency-name: github.com/opencontainers/runc dependency-type: indirect ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- go.mod | 2 +- go.sum | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/go.mod b/go.mod index 30a9bb0e17b..29c60e19d8e 100644 --- a/go.mod +++ b/go.mod @@ -181,7 +181,7 @@ require ( github.com/ncruces/go-strftime v0.1.9 // indirect github.com/nwaples/rardecode v1.1.0 // indirect github.com/opencontainers/image-spec v1.1.0 // indirect - github.com/opencontainers/runc v1.1.12 // indirect + github.com/opencontainers/runc v1.1.14 // indirect github.com/opencontainers/runtime-spec v1.1.0-rc.1 // indirect github.com/opencontainers/selinux v1.11.0 // indirect github.com/pborman/indent v1.2.1 // indirect diff --git a/go.sum b/go.sum index 3d6c2b9f119..9e2e0333b85 100644 --- a/go.sum +++ b/go.sum @@ -609,8 +609,8 @@ github.com/opencontainers/go-digest v1.0.0 h1:apOUWs51W5PlhuyGyz9FCeeBIOUDA/6nW8 github.com/opencontainers/go-digest v1.0.0/go.mod h1:0JzlMkj0TRzQZfJkVvzbP0HBR3IKzErnv2BNG4W4MAM= github.com/opencontainers/image-spec v1.1.0 h1:8SG7/vwALn54lVB/0yZ/MMwhFrPYtpEHQb2IpWsCzug= github.com/opencontainers/image-spec v1.1.0/go.mod h1:W4s4sFTMaBeK1BQLXbG4AdM2szdn85PY75RI83NrTrM= -github.com/opencontainers/runc v1.1.12 h1:BOIssBaW1La0/qbNZHXOOa71dZfZEQOzW7dqQf3phss= -github.com/opencontainers/runc v1.1.12/go.mod h1:S+lQwSfncpBha7XTy/5lBwWgm5+y5Ma/O44Ekby9FK8= +github.com/opencontainers/runc v1.1.14 h1:rgSuzbmgz5DUJjeSnw337TxDbRuqjs6iqQck/2weR6w= +github.com/opencontainers/runc v1.1.14/go.mod h1:E4C2z+7BxR7GHXp0hAY53mek+x49X1LjPNeMTfRGvOA= github.com/opencontainers/runtime-spec v1.1.0-rc.1 h1:wHa9jroFfKGQqFHj0I1fMRKLl0pfj+ynAqBxo3v6u9w= github.com/opencontainers/runtime-spec v1.1.0-rc.1/go.mod h1:jwyrGlmzljRJv/Fgzds9SsS/C5hL+LL3ko9hs6T5lQ0= github.com/opencontainers/selinux v1.11.0 h1:+5Zbo97w3Lbmb3PeqQtpmTkMwsW5nRI3YaLpt7tQ7oU= From fcd5ec951de6b3fc1f1aa2a36968356d2eb22170 Mon Sep 17 00:00:00 2001 From: Ryuichi Okumura Date: Wed, 11 Sep 2024 23:02:37 +0900 Subject: [PATCH 121/122] chore: make ci-check.sh an executable file (#3220) Signed-off-by: Ryuichi Okumura --- .github/scripts/ci-check.sh | 0 1 file changed, 0 insertions(+), 0 deletions(-) mode change 100644 => 100755 .github/scripts/ci-check.sh diff --git a/.github/scripts/ci-check.sh b/.github/scripts/ci-check.sh old mode 100644 new mode 100755 From 1b863268df8945a7bfcf7f27272c1b1fa8e34371 Mon Sep 17 00:00:00 2001 From: Keith Zantow Date: Thu, 12 Sep 2024 10:45:18 -0400 Subject: [PATCH 122/122] feat: --enrich flag for data enrichment feature enablement (#3182) Signed-off-by: Keith Zantow --- cmd/syft/internal/options/catalog.go | 99 ++++++++++++++++++----- cmd/syft/internal/options/catalog_test.go | 66 +++++++++++++++ cmd/syft/internal/options/golang.go | 8 +- cmd/syft/internal/options/java.go | 8 +- cmd/syft/internal/options/javascript.go | 2 +- go.mod | 24 +++--- go.sum | 52 ++++++------ internal/task/package_tasks.go | 31 +++++-- 8 files changed, 217 insertions(+), 73 deletions(-) diff --git a/cmd/syft/internal/options/catalog.go b/cmd/syft/internal/options/catalog.go index 99359abec51..8d18518605e 100644 --- a/cmd/syft/internal/options/catalog.go +++ b/cmd/syft/internal/options/catalog.go @@ -11,6 +11,7 @@ import ( "github.com/anchore/fangs" intFile "github.com/anchore/syft/internal/file" "github.com/anchore/syft/internal/log" + "github.com/anchore/syft/internal/task" "github.com/anchore/syft/syft" "github.com/anchore/syft/syft/cataloging" "github.com/anchore/syft/syft/cataloging/filecataloging" @@ -36,6 +37,7 @@ type Catalog struct { Scope string `yaml:"scope" json:"scope" mapstructure:"scope"` Parallelism int `yaml:"parallelism" json:"parallelism" mapstructure:"parallelism"` // the number of catalog workers to run in parallel Relationships relationshipsConfig `yaml:"relationships" json:"relationships" mapstructure:"relationships"` + Enrich []string `yaml:"enrich" json:"enrich" mapstructure:"enrich"` // ecosystem-specific cataloger configuration Golang golangConfig `yaml:"golang" json:"golang" mapstructure:"golang"` @@ -55,7 +57,7 @@ type Catalog struct { var _ interface { clio.FlagAdder clio.PostLoader - fangs.FieldDescriber + clio.FieldDescriber } = (*Catalog)(nil) func DefaultCatalog() Catalog { @@ -130,9 +132,9 @@ func (cfg Catalog) ToPackagesConfig() pkgcataloging.Config { return pkgcataloging.Config{ Binary: binary.DefaultClassifierCatalogerConfig(), Golang: golang.DefaultCatalogerConfig(). - WithSearchLocalModCacheLicenses(cfg.Golang.SearchLocalModCacheLicenses). + WithSearchLocalModCacheLicenses(*multiLevelOption(false, enrichmentEnabled(cfg.Enrich, task.Go, task.Golang), cfg.Golang.SearchLocalModCacheLicenses)). WithLocalModCacheDir(cfg.Golang.LocalModCacheDir). - WithSearchRemoteLicenses(cfg.Golang.SearchRemoteLicenses). + WithSearchRemoteLicenses(*multiLevelOption(false, enrichmentEnabled(cfg.Enrich, task.Go, task.Golang), cfg.Golang.SearchRemoteLicenses)). WithProxy(cfg.Golang.Proxy). WithNoProxy(cfg.Golang.NoProxy). WithMainModuleVersion( @@ -142,7 +144,7 @@ func (cfg Catalog) ToPackagesConfig() pkgcataloging.Config { WithFromLDFlags(cfg.Golang.MainModuleVersion.FromLDFlags), ), JavaScript: javascript.DefaultCatalogerConfig(). - WithSearchRemoteLicenses(cfg.JavaScript.SearchRemoteLicenses). + WithSearchRemoteLicenses(*multiLevelOption(false, enrichmentEnabled(cfg.Enrich, task.JavaScript, task.Node, task.NPM), cfg.JavaScript.SearchRemoteLicenses)). WithNpmBaseURL(cfg.JavaScript.NpmBaseURL), LinuxKernel: kernel.LinuxKernelCatalogerConfig{ CatalogModules: cfg.LinuxKernel.CatalogModules, @@ -151,9 +153,9 @@ func (cfg Catalog) ToPackagesConfig() pkgcataloging.Config { GuessUnpinnedRequirements: cfg.Python.GuessUnpinnedRequirements, }, JavaArchive: java.DefaultArchiveCatalogerConfig(). - WithUseMavenLocalRepository(cfg.Java.UseMavenLocalRepository). + WithUseMavenLocalRepository(*multiLevelOption(false, enrichmentEnabled(cfg.Enrich, task.Java, task.Maven), cfg.Java.UseMavenLocalRepository)). WithMavenLocalRepositoryDir(cfg.Java.MavenLocalRepositoryDir). - WithUseNetwork(cfg.Java.UseNetwork). + WithUseNetwork(*multiLevelOption(false, enrichmentEnabled(cfg.Enrich, task.Java, task.Maven), cfg.Java.UseNetwork)). WithMavenBaseURL(cfg.Java.MavenURL). WithArchiveTraversal(archiveSearch, cfg.Java.MaxParentRecursiveDepth), } @@ -193,6 +195,9 @@ func (cfg *Catalog) AddFlags(flags clio.FlagSet) { flags.StringArrayVarP(&cfg.SelectCatalogers, "select-catalogers", "", "add, remove, and filter the catalogers to be used") + flags.StringArrayVarP(&cfg.Enrich, "enrich", "", + fmt.Sprintf("enable package data enrichment from local and online sources (options: %s)", strings.Join(publicisedEnrichmentOptions, ", "))) + flags.StringVarP(&cfg.Source.Name, "source-name", "", "set the name of the target being analyzed") @@ -205,6 +210,10 @@ func (cfg *Catalog) AddFlags(flags clio.FlagSet) { func (cfg *Catalog) DescribeFields(descriptions fangs.FieldDescriptionSet) { descriptions.Add(&cfg.Parallelism, "number of cataloger workers to run in parallel") + + descriptions.Add(&cfg.Enrich, fmt.Sprintf(`Enable data enrichment operations, which can utilize services such as Maven Central and NPM. +By default all enrichment is disabled, use: all to enable everything. +Available options are: %s`, strings.Join(publicisedEnrichmentOptions, ", "))) } func (cfg *Catalog) PostLoad() error { @@ -215,23 +224,12 @@ func (cfg *Catalog) PostLoad() error { return fmt.Errorf("cannot use both 'catalogers' and 'select-catalogers'/'default-catalogers' flags") } - flatten := func(l []string) []string { - var out []string - for _, v := range l { - for _, s := range strings.Split(v, ",") { - out = append(out, strings.TrimSpace(s)) - } - } - sort.Strings(out) - - return out - } - cfg.From = flatten(cfg.From) cfg.Catalogers = flatten(cfg.Catalogers) cfg.DefaultCatalogers = flatten(cfg.DefaultCatalogers) cfg.SelectCatalogers = flatten(cfg.SelectCatalogers) + cfg.Enrich = flatten(cfg.Enrich) // for backwards compatibility cfg.DefaultCatalogers = append(cfg.DefaultCatalogers, cfg.Catalogers...) @@ -243,3 +241,68 @@ func (cfg *Catalog) PostLoad() error { return nil } + +func flatten(commaSeparatedEntries []string) []string { + var out []string + for _, v := range commaSeparatedEntries { + for _, s := range strings.Split(v, ",") { + out = append(out, strings.TrimSpace(s)) + } + } + sort.Strings(out) + return out +} + +var publicisedEnrichmentOptions = []string{ + "all", + task.Golang, + task.Java, + task.JavaScript, +} + +func enrichmentEnabled(enrichDirectives []string, features ...string) *bool { + if len(enrichDirectives) == 0 { + return nil + } + + enabled := func(features ...string) *bool { + for _, directive := range enrichDirectives { + enable := true + directive = strings.TrimPrefix(directive, "+") // +java and java are equivalent + if strings.HasPrefix(directive, "-") { + directive = directive[1:] + enable = false + } + for _, feature := range features { + if directive == feature { + return &enable + } + } + } + return nil + } + + enableAll := enabled("all") + disableAll := enabled("none") + + if disableAll != nil && *disableAll { + if enableAll != nil { + log.Warn("you have specified to both enable and disable all enrichment functionality, defaulting to disabled") + } + enableAll = ptr(false) + } + + // check for explicit enable/disable of feature names + for _, feat := range features { + enableFeature := enabled(feat) + if enableFeature != nil { + return enableFeature + } + } + + return enableAll +} + +func ptr[T any](val T) *T { + return &val +} diff --git a/cmd/syft/internal/options/catalog_test.go b/cmd/syft/internal/options/catalog_test.go index f9a54249ae3..cf02630bf64 100644 --- a/cmd/syft/internal/options/catalog_test.go +++ b/cmd/syft/internal/options/catalog_test.go @@ -70,3 +70,69 @@ func TestCatalog_PostLoad(t *testing.T) { }) } } + +func Test_enrichmentEnabled(t *testing.T) { + tests := []struct { + directives string + test string + expected *bool + }{ + { + directives: "", + test: "java", + expected: nil, + }, + { + directives: "none", + test: "java", + expected: ptr(false), + }, + { + directives: "none,+java", + test: "java", + expected: ptr(true), + }, + { + directives: "all,none", + test: "java", + expected: ptr(false), + }, + { + directives: "all", + test: "java", + expected: ptr(true), + }, + { + directives: "golang,js", + test: "java", + expected: nil, + }, + { + directives: "golang,-js,java", + test: "java", + expected: ptr(true), + }, + { + directives: "golang,js,-java", + test: "java", + expected: ptr(false), + }, + { + directives: "all", + test: "java", + expected: ptr(true), + }, + { + directives: "all,-java", + test: "java", + expected: ptr(false), + }, + } + + for _, test := range tests { + t.Run(test.directives, func(t *testing.T) { + got := enrichmentEnabled(flatten([]string{test.directives}), test.test) + assert.Equal(t, test.expected, got) + }) + } +} diff --git a/cmd/syft/internal/options/golang.go b/cmd/syft/internal/options/golang.go index 63ac1bcc7c8..59fe421fe56 100644 --- a/cmd/syft/internal/options/golang.go +++ b/cmd/syft/internal/options/golang.go @@ -8,9 +8,9 @@ import ( ) type golangConfig struct { - SearchLocalModCacheLicenses bool `json:"search-local-mod-cache-licenses" yaml:"search-local-mod-cache-licenses" mapstructure:"search-local-mod-cache-licenses"` + SearchLocalModCacheLicenses *bool `json:"search-local-mod-cache-licenses" yaml:"search-local-mod-cache-licenses" mapstructure:"search-local-mod-cache-licenses"` LocalModCacheDir string `json:"local-mod-cache-dir" yaml:"local-mod-cache-dir" mapstructure:"local-mod-cache-dir"` - SearchRemoteLicenses bool `json:"search-remote-licenses" yaml:"search-remote-licenses" mapstructure:"search-remote-licenses"` + SearchRemoteLicenses *bool `json:"search-remote-licenses" yaml:"search-remote-licenses" mapstructure:"search-remote-licenses"` Proxy string `json:"proxy" yaml:"proxy" mapstructure:"proxy"` NoProxy string `json:"no-proxy" yaml:"no-proxy" mapstructure:"no-proxy"` MainModuleVersion golangMainModuleVersionConfig `json:"main-module-version" yaml:"main-module-version" mapstructure:"main-module-version"` @@ -47,9 +47,9 @@ type golangMainModuleVersionConfig struct { func defaultGolangConfig() golangConfig { def := golang.DefaultCatalogerConfig() return golangConfig{ - SearchLocalModCacheLicenses: def.SearchLocalModCacheLicenses, + SearchLocalModCacheLicenses: nil, // this defaults to false, which is the API default LocalModCacheDir: def.LocalModCacheDir, - SearchRemoteLicenses: def.SearchRemoteLicenses, + SearchRemoteLicenses: nil, // this defaults to false, which is the API default Proxy: strings.Join(def.Proxies, ","), NoProxy: strings.Join(def.NoProxy, ","), MainModuleVersion: golangMainModuleVersionConfig{ diff --git a/cmd/syft/internal/options/java.go b/cmd/syft/internal/options/java.go index 8894c760b75..6244de44fab 100644 --- a/cmd/syft/internal/options/java.go +++ b/cmd/syft/internal/options/java.go @@ -6,8 +6,8 @@ import ( ) type javaConfig struct { - UseNetwork bool `yaml:"use-network" json:"use-network" mapstructure:"use-network"` - UseMavenLocalRepository bool `yaml:"use-maven-local-repository" json:"use-maven-local-repository" mapstructure:"use-maven-local-repository"` + UseNetwork *bool `yaml:"use-network" json:"use-network" mapstructure:"use-network"` + UseMavenLocalRepository *bool `yaml:"use-maven-local-repository" json:"use-maven-local-repository" mapstructure:"use-maven-local-repository"` MavenLocalRepositoryDir string `yaml:"maven-local-repository-dir" json:"maven-local-repository-dir" mapstructure:"maven-local-repository-dir"` MavenURL string `yaml:"maven-url" json:"maven-url" mapstructure:"maven-url"` MaxParentRecursiveDepth int `yaml:"max-parent-recursive-depth" json:"max-parent-recursive-depth" mapstructure:"max-parent-recursive-depth"` @@ -17,9 +17,9 @@ func defaultJavaConfig() javaConfig { def := java.DefaultArchiveCatalogerConfig() return javaConfig{ - UseNetwork: def.UseNetwork, + UseNetwork: nil, // this defaults to false, which is the API default MaxParentRecursiveDepth: def.MaxParentRecursiveDepth, - UseMavenLocalRepository: def.UseMavenLocalRepository, + UseMavenLocalRepository: nil, // this defaults to false, which is the API default MavenLocalRepositoryDir: def.MavenLocalRepositoryDir, MavenURL: def.MavenBaseURL, } diff --git a/cmd/syft/internal/options/javascript.go b/cmd/syft/internal/options/javascript.go index 5f88c0f33f4..e618037ccaa 100644 --- a/cmd/syft/internal/options/javascript.go +++ b/cmd/syft/internal/options/javascript.go @@ -3,7 +3,7 @@ package options import "github.com/anchore/clio" type javaScriptConfig struct { - SearchRemoteLicenses bool `json:"search-remote-licenses" yaml:"search-remote-licenses" mapstructure:"search-remote-licenses"` + SearchRemoteLicenses *bool `json:"search-remote-licenses" yaml:"search-remote-licenses" mapstructure:"search-remote-licenses"` NpmBaseURL string `json:"npm-base-url" yaml:"npm-base-url" mapstructure:"npm-base-url"` } diff --git a/go.mod b/go.mod index 29c60e19d8e..38b4a830029 100644 --- a/go.mod +++ b/go.mod @@ -10,7 +10,7 @@ require ( github.com/acobaugh/osrelease v0.1.0 github.com/anchore/bubbly v0.0.0-20231115134915-def0aba654a9 github.com/anchore/clio v0.0.0-20240522144804-d81e109008aa - github.com/anchore/fangs v0.0.0-20240508143433-f016b099950f + github.com/anchore/fangs v0.0.0-20240903175602-e716ef12c23d github.com/anchore/go-collections v0.0.0-20240216171411-9321230ce537 github.com/anchore/go-logger v0.0.0-20230725134548-c21dafa1ec5a github.com/anchore/go-macholibre v0.0.0-20220308212642-53e6d0aaf6fb @@ -84,7 +84,7 @@ require ( modernc.org/sqlite v1.33.0 ) -require google.golang.org/genproto v0.0.0-20231106174013-bbf56f31fb17 // indirect +require google.golang.org/genproto v0.0.0-20240213162025-012b6fc9bca9 // indirect require ( github.com/BurntSushi/toml v1.4.0 @@ -135,13 +135,13 @@ require ( github.com/emirpasic/gods v1.18.1 // indirect github.com/erikgeiser/coninput v0.0.0-20211004153227-1c3628e74d0f // indirect github.com/felixge/fgprof v0.9.3 // indirect - github.com/felixge/httpsnoop v1.0.3 // indirect + github.com/felixge/httpsnoop v1.0.4 // indirect github.com/fsnotify/fsnotify v1.7.0 // indirect github.com/gabriel-vasile/mimetype v1.4.4 // indirect github.com/gkampitakis/ciinfo v0.3.0 // indirect github.com/gkampitakis/go-diff v1.3.2 // indirect github.com/go-git/gcfg v1.5.1-0.20230307220236-3a3c6141e376 // indirect - github.com/go-logr/logr v1.2.4 // indirect + github.com/go-logr/logr v1.4.1 // indirect github.com/go-logr/stdr v1.2.2 // indirect github.com/go-restruct/restruct v1.2.0-alpha // indirect github.com/gogo/protobuf v1.3.2 // indirect @@ -185,7 +185,7 @@ require ( github.com/opencontainers/runtime-spec v1.1.0-rc.1 // indirect github.com/opencontainers/selinux v1.11.0 // indirect github.com/pborman/indent v1.2.1 // indirect - github.com/pelletier/go-toml/v2 v2.1.0 // indirect + github.com/pelletier/go-toml/v2 v2.2.2 // indirect github.com/pierrec/lz4/v4 v4.1.19 // indirect github.com/pjbgf/sha1cd v0.3.0 // indirect github.com/pkg/errors v0.9.1 // indirect @@ -204,7 +204,7 @@ require ( github.com/sourcegraph/conc v0.3.0 // indirect github.com/spf13/cast v1.7.0 // indirect github.com/spf13/pflag v1.0.5 // indirect - github.com/spf13/viper v1.18.2 // indirect + github.com/spf13/viper v1.19.0 // indirect github.com/subosito/gotenv v1.6.0 // indirect github.com/sylabs/sif/v2 v2.17.1 // indirect github.com/sylabs/squashfs v1.0.0 // indirect @@ -221,10 +221,10 @@ require ( github.com/xi2/xz v0.0.0-20171230120015-48954b6210f8 // indirect github.com/xo/terminfo v0.0.0-20220910002029-abceb7e1c41e // indirect go.opencensus.io v0.24.0 // indirect - go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.45.0 // indirect - go.opentelemetry.io/otel v1.19.0 // indirect - go.opentelemetry.io/otel/metric v1.19.0 // indirect - go.opentelemetry.io/otel/trace v1.19.0 // indirect + go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.49.0 // indirect + go.opentelemetry.io/otel v1.24.0 // indirect + go.opentelemetry.io/otel/metric v1.24.0 // indirect + go.opentelemetry.io/otel/trace v1.24.0 // indirect go.uber.org/atomic v1.9.0 // indirect go.uber.org/multierr v1.9.0 // indirect golang.org/x/crypto v0.27.0 // indirect @@ -234,8 +234,8 @@ require ( golang.org/x/text v0.18.0 // indirect golang.org/x/tools v0.21.1-0.20240508182429-e35e4ccd0d2d // indirect golang.org/x/xerrors v0.0.0-20220907171357-04be3eba64a2 // indirect - google.golang.org/genproto/googleapis/rpc v0.0.0-20231120223509-83a465c0220f // indirect - google.golang.org/grpc v1.59.0 // indirect + google.golang.org/genproto/googleapis/rpc v0.0.0-20240314234333-6e1732d8331c // indirect + google.golang.org/grpc v1.62.1 // indirect google.golang.org/protobuf v1.33.0 // indirect gopkg.in/ini.v1 v1.67.0 // indirect gopkg.in/warnings.v0 v0.1.2 // indirect diff --git a/go.sum b/go.sum index 9e2e0333b85..d4b999ae8c2 100644 --- a/go.sum +++ b/go.sum @@ -99,8 +99,8 @@ github.com/anchore/bubbly v0.0.0-20231115134915-def0aba654a9 h1:p0ZIe0htYOX284Y4 github.com/anchore/bubbly v0.0.0-20231115134915-def0aba654a9/go.mod h1:3ZsFB9tzW3vl4gEiUeuSOMDnwroWxIxJelOOHUp8dSw= github.com/anchore/clio v0.0.0-20240522144804-d81e109008aa h1:pwlAn4O9SBUnlgfa69YcqIynbUyobLVFYu8HxSoCffA= github.com/anchore/clio v0.0.0-20240522144804-d81e109008aa/go.mod h1:nD3H5uIvjxlfmakOBgtyFQbk5Zjp3l538kxfpHPslzI= -github.com/anchore/fangs v0.0.0-20240508143433-f016b099950f h1:NOhzafCyNYFi88qxkBFjMzQo4dRa1vDhBzx+0Uovx8Q= -github.com/anchore/fangs v0.0.0-20240508143433-f016b099950f/go.mod h1:sVpRS2yNCw6tLVpvA1QSDVWTJVpCuAm8JNZgn4Sjz/k= +github.com/anchore/fangs v0.0.0-20240903175602-e716ef12c23d h1:ZD4wdCBgJJzJybjTUIEiiupLF7B9H3WLuBTjspBO2Mc= +github.com/anchore/fangs v0.0.0-20240903175602-e716ef12c23d/go.mod h1:Xh4ObY3fmoMzOEVXwDtS1uK44JC7+nRD0n29/1KYFYg= github.com/anchore/go-collections v0.0.0-20240216171411-9321230ce537 h1:GjNGuwK5jWjJMyVppBjYS54eOiiSNv4Ba869k4wh72Q= github.com/anchore/go-collections v0.0.0-20240216171411-9321230ce537/go.mod h1:1aiktV46ATCkuVg0O573ZrH56BUawTECPETbZyBcqT8= github.com/anchore/go-logger v0.0.0-20230725134548-c21dafa1ec5a h1:nJ2G8zWKASyVClGVgG7sfM5mwoZlZ2zYpIzN2OhjWkw= @@ -275,8 +275,8 @@ github.com/fatih/set v0.2.1 h1:nn2CaJyknWE/6txyUDGwysr3G5QC6xWB/PtVjPBbeaA= github.com/fatih/set v0.2.1/go.mod h1:+RKtMCH+favT2+3YecHGxcc0b4KyVWA1QWWJUs4E0CI= github.com/felixge/fgprof v0.9.3 h1:VvyZxILNuCiUCSXtPtYmmtGvb65nqXh2QFWc0Wpf2/g= github.com/felixge/fgprof v0.9.3/go.mod h1:RdbpDgzqYVh/T9fPELJyV7EYJuHB55UTEULNun8eiPw= -github.com/felixge/httpsnoop v1.0.3 h1:s/nj+GCswXYzN5v2DpNMuMQYe+0DDwt5WVCU6CWBdXk= -github.com/felixge/httpsnoop v1.0.3/go.mod h1:m8KPJKqk1gH5J9DgRY2ASl2lWCfGKXixSwevea8zH2U= +github.com/felixge/httpsnoop v1.0.4 h1:NFTV2Zj1bL4mc9sqWACXbQFVBBg2W3GPvqp8/ESS2Wg= +github.com/felixge/httpsnoop v1.0.4/go.mod h1:m8KPJKqk1gH5J9DgRY2ASl2lWCfGKXixSwevea8zH2U= github.com/frankban/quicktest v1.14.6 h1:7Xjx+VpznH+oBnejlPUj8oUpdxnVs4f8XU8WnHkI4W8= github.com/frankban/quicktest v1.14.6/go.mod h1:4ptaffx2x8+WTWXmUCuVU6aPUX1/Mz7zb5vbUoiM6w0= github.com/fsnotify/fsnotify v1.5.1/go.mod h1:T3375wBYaZdLLcVNkcVbzGHY7f1l/uK5T5Ai1i3InKU= @@ -313,8 +313,8 @@ github.com/go-kit/kit v0.9.0/go.mod h1:xBxKIO96dXMWWy0MnWVtmwkA9/13aqxPnvrjFYMA2 github.com/go-logfmt/logfmt v0.3.0/go.mod h1:Qt1PoO58o5twSAckw1HlFXLmHsOX5/0LbT9GBnD5lWE= github.com/go-logfmt/logfmt v0.4.0/go.mod h1:3RMwSq7FuexP4Kalkev3ejPJsZTpXXBr9+V4qmtdjCk= github.com/go-logr/logr v1.2.2/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A= -github.com/go-logr/logr v1.2.4 h1:g01GSCwiDw2xSZfjJ2/T9M+S6pFdcNtFYsp+Y43HYDQ= -github.com/go-logr/logr v1.2.4/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A= +github.com/go-logr/logr v1.4.1 h1:pKouT5E8xu9zeFC39JXRDukb6JFQPXM5p5I91188VAQ= +github.com/go-logr/logr v1.4.1/go.mod h1:9T104GzyrTigFIr8wt5mBrctHMim0Nb2HLGrmQ40KvY= github.com/go-logr/stdr v1.2.2 h1:hSWxHoqTgW2S2qGc0LTAI563KZ5YKYRhT3MFKZMbjag= github.com/go-logr/stdr v1.2.2/go.mod h1:mMo/vtBO5dYbehREoey6XUKy/eSumjCCveDpRre4VKE= github.com/go-restruct/restruct v1.2.0-alpha h1:2Lp474S/9660+SJjpVxoKuWX09JsXHSrdV7Nv3/gkvc= @@ -622,8 +622,8 @@ github.com/pborman/indent v1.2.1/go.mod h1:FitS+t35kIYtB5xWTZAPhnmrxcciEEOdbyrrp github.com/pelletier/go-toml v1.9.4/go.mod h1:u1nR/EPcESfeI/szUZKdtJ0xRNbUoANCkoOuaOx1Y+c= github.com/pelletier/go-toml v1.9.5 h1:4yBQzkHv+7BHq2PQUZF3Mx0IYxG7LsP222s7Agd3ve8= github.com/pelletier/go-toml v1.9.5/go.mod h1:u1nR/EPcESfeI/szUZKdtJ0xRNbUoANCkoOuaOx1Y+c= -github.com/pelletier/go-toml/v2 v2.1.0 h1:FnwAJ4oYMvbT/34k9zzHuZNrhlz48GB3/s6at6/MHO4= -github.com/pelletier/go-toml/v2 v2.1.0/go.mod h1:tJU2Z3ZkXwnxa4DPO899bsyIoywizdUvyaeZurnPPDc= +github.com/pelletier/go-toml/v2 v2.2.2 h1:aYUidT7k73Pcl9nb2gScu7NSrKCSHIDE89b3+6Wq+LM= +github.com/pelletier/go-toml/v2 v2.2.2/go.mod h1:1t835xjRzz80PqgE6HHgN2JOsmgYu/h4qDAS4n929Rs= github.com/pierrec/lz4/v4 v4.1.2/go.mod h1:gZWDp/Ze/IJXGXf23ltt2EXimqmTUXEy0GFuRQyBid4= github.com/pierrec/lz4/v4 v4.1.19 h1:tYLzDnjDXh9qIxSTKHwXwOYmm9d887Y7Y1ZkyXYHAN4= github.com/pierrec/lz4/v4 v4.1.19/go.mod h1:gZWDp/Ze/IJXGXf23ltt2EXimqmTUXEy0GFuRQyBid4= @@ -731,8 +731,8 @@ github.com/spf13/jwalterweatherman v1.1.0/go.mod h1:aNWZUN0dPAAO/Ljvb5BEdw96iTZ0 github.com/spf13/pflag v1.0.5 h1:iy+VFUOCP1a+8yFto/drg2CJ5u0yRoB7fZw3DKv/JXA= github.com/spf13/pflag v1.0.5/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg= github.com/spf13/viper v1.10.0/go.mod h1:SoyBPwAtKDzypXNDFKN5kzH7ppppbGZtls1UpIy5AsM= -github.com/spf13/viper v1.18.2 h1:LUXCnvUvSM6FXAsj6nnfc8Q2tp1dIgUfY9Kc8GsSOiQ= -github.com/spf13/viper v1.18.2/go.mod h1:EKmWIqdnk5lOcmR72yw6hS+8OPYcwD0jteitLMVB+yk= +github.com/spf13/viper v1.19.0 h1:RWq5SEjt8o25SROyN3z2OrDB9l7RPd3lwTWU8EcEdcI= +github.com/spf13/viper v1.19.0/go.mod h1:GQUN9bilAbhU/jgc1bKs99f/suXKeUMct8Adx5+Ntkg= github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= github.com/stretchr/objx v0.1.1/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= github.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw= @@ -824,20 +824,20 @@ go.opencensus.io v0.22.5/go.mod h1:5pWMHQbX5EPX2/62yrJeAkowc+lfs/XD7Uxpq3pI6kk= go.opencensus.io v0.23.0/go.mod h1:XItmlyltB5F7CS4xOC1DcqMoFqwtC6OG2xF7mCv7P7E= go.opencensus.io v0.24.0 h1:y73uSU6J157QMP2kn2r30vwW1A2W2WFwSCGnAVxeaD0= go.opencensus.io v0.24.0/go.mod h1:vNK8G9p7aAivkbmorf4v+7Hgx+Zs0yY+0fOtgBfjQKo= -go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.45.0 h1:x8Z78aZx8cOF0+Kkazoc7lwUNMGy0LrzEMxTm4BbTxg= -go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.45.0/go.mod h1:62CPTSry9QZtOaSsE3tOzhx6LzDhHnXJ6xHeMNNiM6Q= -go.opentelemetry.io/otel v1.19.0 h1:MuS/TNf4/j4IXsZuJegVzI1cwut7Qc00344rgH7p8bs= -go.opentelemetry.io/otel v1.19.0/go.mod h1:i0QyjOq3UPoTzff0PJB2N66fb4S0+rSbSB15/oyH9fY= +go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.49.0 h1:jq9TW8u3so/bN+JPT166wjOI6/vQPF6Xe7nMNIltagk= +go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.49.0/go.mod h1:p8pYQP+m5XfbZm9fxtSKAbM6oIllS7s2AfxrChvc7iw= +go.opentelemetry.io/otel v1.24.0 h1:0LAOdjNmQeSTzGBzduGe/rU4tZhMwL5rWgtp9Ku5Jfo= +go.opentelemetry.io/otel v1.24.0/go.mod h1:W7b9Ozg4nkF5tWI5zsXkaKKDjdVjpD4oAt9Qi/MArHo= go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.19.0 h1:Mne5On7VWdx7omSrSSZvM4Kw7cS7NQkOOmLcgscI51U= go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.19.0/go.mod h1:IPtUMKL4O3tH5y+iXVyAXqpAwMuzC1IrxVS81rummfE= go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp v1.19.0 h1:IeMeyr1aBvBiPVYihXIaeIZba6b8E1bYp7lbdxK8CQg= go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp v1.19.0/go.mod h1:oVdCUtjq9MK9BlS7TtucsQwUcXcymNiEDjgDD2jMtZU= -go.opentelemetry.io/otel/metric v1.19.0 h1:aTzpGtV0ar9wlV4Sna9sdJyII5jTVJEvKETPiOKwvpE= -go.opentelemetry.io/otel/metric v1.19.0/go.mod h1:L5rUsV9kM1IxCj1MmSdS+JQAcVm319EUrDVLrt7jqt8= +go.opentelemetry.io/otel/metric v1.24.0 h1:6EhoGWWK28x1fbpA4tYTOWBkPefTDQnb8WSGXlc88kI= +go.opentelemetry.io/otel/metric v1.24.0/go.mod h1:VYhLe1rFfxuTXLgj4CBiyz+9WYBA8pNGJgDcSFRKBco= go.opentelemetry.io/otel/sdk v1.19.0 h1:6USY6zH+L8uMH8L3t1enZPR3WFEmSTADlqldyHtJi3o= go.opentelemetry.io/otel/sdk v1.19.0/go.mod h1:NedEbbS4w3C6zElbLdPJKOpJQOrGUJ+GfzpjUvI0v1A= -go.opentelemetry.io/otel/trace v1.19.0 h1:DFVQmlVbfVeOuBRrwdtaehRrWiL1JoVs9CPIQ1Dzxpg= -go.opentelemetry.io/otel/trace v1.19.0/go.mod h1:mfaSyvGyEJEI0nyV2I4qhNQnbBOUUmYZpYojqMnX2vo= +go.opentelemetry.io/otel/trace v1.24.0 h1:CsKnnL4dUAr/0llH9FKuc698G04IrpWV0MQA/Y1YELI= +go.opentelemetry.io/otel/trace v1.24.0/go.mod h1:HPc3Xr/cOApsBI154IU0OI0HJexz+aw5uPdbs3UCjNU= go.opentelemetry.io/proto/otlp v0.7.0/go.mod h1:PqfVotwruBrMGOCsRd/89rSnXhoiJIqeYNgFYFoEGnI= go.opentelemetry.io/proto/otlp v1.0.0 h1:T0TX0tmXU8a3CbNXzEKGeU5mIVOdf0oykP+u2lIVU/I= go.opentelemetry.io/proto/otlp v1.0.0/go.mod h1:Sy6pihPLfYHkr3NkUbEhGHFhINUSI/v80hjKIs5JXpM= @@ -1261,12 +1261,12 @@ google.golang.org/genproto v0.0.0-20211129164237-f09f9a12af12/go.mod h1:5CzLGKJ6 google.golang.org/genproto v0.0.0-20211203200212-54befc351ae9/go.mod h1:5CzLGKJ67TSI2B9POpiiyGha0AjJvZIUgRMt1dSmuhc= google.golang.org/genproto v0.0.0-20211206160659-862468c7d6e0/go.mod h1:5CzLGKJ67TSI2B9POpiiyGha0AjJvZIUgRMt1dSmuhc= google.golang.org/genproto v0.0.0-20211208223120-3a66f561d7aa/go.mod h1:5CzLGKJ67TSI2B9POpiiyGha0AjJvZIUgRMt1dSmuhc= -google.golang.org/genproto v0.0.0-20231106174013-bbf56f31fb17 h1:wpZ8pe2x1Q3f2KyT5f8oP/fa9rHAKgFPr/HZdNuS+PQ= -google.golang.org/genproto v0.0.0-20231106174013-bbf56f31fb17/go.mod h1:J7XzRzVy1+IPwWHZUzoD0IccYZIrXILAQpc+Qy9CMhY= -google.golang.org/genproto/googleapis/api v0.0.0-20231106174013-bbf56f31fb17 h1:JpwMPBpFN3uKhdaekDpiNlImDdkUAyiJ6ez/uxGaUSo= -google.golang.org/genproto/googleapis/api v0.0.0-20231106174013-bbf56f31fb17/go.mod h1:0xJLfVdJqpAPl8tDg1ujOCGzx6LFLttXT5NhllGOXY4= -google.golang.org/genproto/googleapis/rpc v0.0.0-20231120223509-83a465c0220f h1:ultW7fxlIvee4HYrtnaRPon9HpEgFk5zYpmfMgtKB5I= -google.golang.org/genproto/googleapis/rpc v0.0.0-20231120223509-83a465c0220f/go.mod h1:L9KNLi232K1/xB6f7AlSX692koaRnKaWSR0stBki0Yc= +google.golang.org/genproto v0.0.0-20240213162025-012b6fc9bca9 h1:9+tzLLstTlPTRyJTh+ah5wIMsBW5c4tQwGTN3thOW9Y= +google.golang.org/genproto v0.0.0-20240213162025-012b6fc9bca9/go.mod h1:mqHbVIp48Muh7Ywss/AD6I5kNVKZMmAa/QEW58Gxp2s= +google.golang.org/genproto/googleapis/api v0.0.0-20240311132316-a219d84964c2 h1:rIo7ocm2roD9DcFIX67Ym8icoGCKSARAiPljFhh5suQ= +google.golang.org/genproto/googleapis/api v0.0.0-20240311132316-a219d84964c2/go.mod h1:O1cOfN1Cy6QEYr7VxtjOyP5AdAuR0aJ/MYZaaof623Y= +google.golang.org/genproto/googleapis/rpc v0.0.0-20240314234333-6e1732d8331c h1:lfpJ/2rWPa/kJgxyyXM8PrNnfCzcmxJ265mADgwmvLI= +google.golang.org/genproto/googleapis/rpc v0.0.0-20240314234333-6e1732d8331c/go.mod h1:WtryC6hu0hhx87FDGxWCDptyssuo68sk10vYjF+T9fY= google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c= google.golang.org/grpc v1.20.1/go.mod h1:10oTOabMzJvdu6/UiuZezV6QK5dSlG84ov/aaiqXj38= google.golang.org/grpc v1.21.1/go.mod h1:oYelfM1adQP15Ek0mdvEgi9Df8B9CZIaU1084ijfRaM= @@ -1294,8 +1294,8 @@ google.golang.org/grpc v1.39.1/go.mod h1:PImNr+rS9TWYb2O4/emRugxiyHZ5JyHW5F+RPnD google.golang.org/grpc v1.40.0/go.mod h1:ogyxbiOoUXAkP+4+xa6PZSE9DZgIHtSpzjDTB9KAK34= google.golang.org/grpc v1.40.1/go.mod h1:ogyxbiOoUXAkP+4+xa6PZSE9DZgIHtSpzjDTB9KAK34= google.golang.org/grpc v1.42.0/go.mod h1:k+4IHHFw41K8+bbowsex27ge2rCb65oeWqe4jJ590SU= -google.golang.org/grpc v1.59.0 h1:Z5Iec2pjwb+LEOqzpB2MR12/eKFhDPhuqW91O+4bwUk= -google.golang.org/grpc v1.59.0/go.mod h1:aUPDwccQo6OTjy7Hct4AfBPD1GptF4fyUjIkQ9YtF98= +google.golang.org/grpc v1.62.1 h1:B4n+nfKzOICUXMgyrNd19h/I9oH0L1pizfk1d4zSgTk= +google.golang.org/grpc v1.62.1/go.mod h1:IWTG0VlJLCh1SkC58F7np9ka9mx/WNkjl4PGJaiq+QE= google.golang.org/grpc/cmd/protoc-gen-go-grpc v1.1.0/go.mod h1:6Kw0yEErY5E/yWrBtf03jp27GLLJujG4z/JK95pnjjw= google.golang.org/protobuf v0.0.0-20200109180630-ec00e32a8dfd/go.mod h1:DFci5gLYBciE7Vtevhsrf46CRTquxDuWsQurQQe4oz8= google.golang.org/protobuf v0.0.0-20200221191635-4d8936d0db64/go.mod h1:kwYJMbMJ01Woi6D6+Kah6886xMZcty6N08ah7+eCXa0= diff --git a/internal/task/package_tasks.go b/internal/task/package_tasks.go index 4d56dc88adc..c38299f4dd6 100644 --- a/internal/task/package_tasks.go +++ b/internal/task/package_tasks.go @@ -34,6 +34,21 @@ import ( "github.com/anchore/syft/syft/pkg/cataloger/wordpress" ) +const ( + // Java ecosystem labels + Java = "java" + Maven = "maven" + + // Go ecosystem labels + Go = "go" + Golang = "golang" + + // JavaScript ecosystem labels + JavaScript = "javascript" + Node = "node" + NPM = "npm" +) + //nolint:funlen func DefaultPackageTaskFactories() PackageTaskFactories { return []packageTaskFactory{ @@ -49,7 +64,7 @@ func DefaultPackageTaskFactories() PackageTaskFactories { // language-specific package installed catalogers /////////////////////////////////////////////////////////////////////////// newSimplePackageTaskFactory(cpp.NewConanInfoCataloger, pkgcataloging.InstalledTag, pkgcataloging.ImageTag, pkgcataloging.LanguageTag, "cpp", "conan"), - newSimplePackageTaskFactory(javascript.NewPackageCataloger, pkgcataloging.InstalledTag, pkgcataloging.ImageTag, pkgcataloging.LanguageTag, "javascript", "node"), + newSimplePackageTaskFactory(javascript.NewPackageCataloger, pkgcataloging.InstalledTag, pkgcataloging.ImageTag, pkgcataloging.LanguageTag, JavaScript, Node), newSimplePackageTaskFactory(php.NewComposerInstalledCataloger, pkgcataloging.InstalledTag, pkgcataloging.ImageTag, pkgcataloging.LanguageTag, "php", "composer"), newSimplePackageTaskFactory(r.NewPackageCataloger, pkgcataloging.InstalledTag, pkgcataloging.ImageTag, pkgcataloging.LanguageTag, "r"), newSimplePackageTaskFactory(ruby.NewInstalledGemSpecCataloger, pkgcataloging.InstalledTag, pkgcataloging.ImageTag, pkgcataloging.LanguageTag, "ruby", "gem", "gemspec"), @@ -67,20 +82,20 @@ func DefaultPackageTaskFactories() PackageTaskFactories { func(cfg CatalogingFactoryConfig) pkg.Cataloger { return golang.NewGoModuleFileCataloger(cfg.PackagesConfig.Golang) }, - pkgcataloging.DeclaredTag, pkgcataloging.DirectoryTag, pkgcataloging.LanguageTag, "go", "golang", "gomod", + pkgcataloging.DeclaredTag, pkgcataloging.DirectoryTag, pkgcataloging.LanguageTag, Go, Golang, "gomod", ), - newSimplePackageTaskFactory(java.NewGradleLockfileCataloger, pkgcataloging.DeclaredTag, pkgcataloging.DirectoryTag, pkgcataloging.LanguageTag, "java", "gradle"), + newSimplePackageTaskFactory(java.NewGradleLockfileCataloger, pkgcataloging.DeclaredTag, pkgcataloging.DirectoryTag, pkgcataloging.LanguageTag, Java, "gradle"), newPackageTaskFactory( func(cfg CatalogingFactoryConfig) pkg.Cataloger { return java.NewPomCataloger(cfg.PackagesConfig.JavaArchive) }, - pkgcataloging.DeclaredTag, pkgcataloging.DirectoryTag, pkgcataloging.LanguageTag, "java", "maven", + pkgcataloging.DeclaredTag, pkgcataloging.DirectoryTag, pkgcataloging.LanguageTag, Java, Maven, ), newPackageTaskFactory( func(cfg CatalogingFactoryConfig) pkg.Cataloger { return javascript.NewLockCataloger(cfg.PackagesConfig.JavaScript) }, - pkgcataloging.DeclaredTag, pkgcataloging.DirectoryTag, pkgcataloging.LanguageTag, "javascript", "node", "npm", + pkgcataloging.DeclaredTag, pkgcataloging.DirectoryTag, pkgcataloging.LanguageTag, JavaScript, Node, NPM, ), newSimplePackageTaskFactory(php.NewComposerLockCataloger, pkgcataloging.DeclaredTag, pkgcataloging.DirectoryTag, pkgcataloging.LanguageTag, "php", "composer"), newSimplePackageTaskFactory(php.NewPeclCataloger, pkgcataloging.DeclaredTag, pkgcataloging.DirectoryTag, pkgcataloging.LanguageTag, pkgcataloging.ImageTag, "php", "pecl"), @@ -105,15 +120,15 @@ func DefaultPackageTaskFactories() PackageTaskFactories { func(cfg CatalogingFactoryConfig) pkg.Cataloger { return golang.NewGoModuleBinaryCataloger(cfg.PackagesConfig.Golang) }, - pkgcataloging.DirectoryTag, pkgcataloging.InstalledTag, pkgcataloging.ImageTag, pkgcataloging.LanguageTag, "go", "golang", "gomod", "binary", + pkgcataloging.DirectoryTag, pkgcataloging.InstalledTag, pkgcataloging.ImageTag, pkgcataloging.LanguageTag, Go, Golang, "gomod", "binary", ), newPackageTaskFactory( func(cfg CatalogingFactoryConfig) pkg.Cataloger { return java.NewArchiveCataloger(cfg.PackagesConfig.JavaArchive) }, - pkgcataloging.DirectoryTag, pkgcataloging.InstalledTag, pkgcataloging.ImageTag, pkgcataloging.LanguageTag, "java", "maven", + pkgcataloging.DirectoryTag, pkgcataloging.InstalledTag, pkgcataloging.ImageTag, pkgcataloging.LanguageTag, Java, Maven, ), - newSimplePackageTaskFactory(java.NewNativeImageCataloger, pkgcataloging.DirectoryTag, pkgcataloging.InstalledTag, pkgcataloging.ImageTag, pkgcataloging.LanguageTag, "java"), + newSimplePackageTaskFactory(java.NewNativeImageCataloger, pkgcataloging.DirectoryTag, pkgcataloging.InstalledTag, pkgcataloging.ImageTag, pkgcataloging.LanguageTag, Java), newSimplePackageTaskFactory(nix.NewStoreCataloger, pkgcataloging.DirectoryTag, pkgcataloging.InstalledTag, pkgcataloging.ImageTag, pkgcataloging.LanguageTag, "nix"), newSimplePackageTaskFactory(lua.NewPackageCataloger, pkgcataloging.DirectoryTag, pkgcataloging.InstalledTag, pkgcataloging.ImageTag, pkgcataloging.LanguageTag, "lua"),