From f53cb477c940124234fcef289b32d6b3262ceb20 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Fri, 22 Dec 2023 02:20:35 +0000 Subject: [PATCH] build(deps): bump github.com/anchore/syft from 0.98.0 to 0.99.0 Bumps [github.com/anchore/syft](https://github.com/anchore/syft) from 0.98.0 to 0.99.0. - [Release notes](https://github.com/anchore/syft/releases) - [Changelog](https://github.com/anchore/syft/blob/main/.goreleaser.yaml) - [Commits](https://github.com/anchore/syft/compare/v0.98.0...v0.99.0) --- updated-dependencies: - dependency-name: github.com/anchore/syft dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] --- go.mod | 18 +- go.sum | 36 +- .../CycloneDX/cyclonedx-go/.golangci.yml | 1 + .../CycloneDX/cyclonedx-go/Dockerfile.gitpod | 2 +- .../CycloneDX/cyclonedx-go/convert.go | 178 ++- .../CycloneDX/cyclonedx-go/cyclonedx.go | 465 ++++++- .../CycloneDX/cyclonedx-go/cyclonedx_json.go | 133 ++ .../CycloneDX/cyclonedx-go/cyclonedx_xml.go | 214 ++- .../github.com/anchore/fangs/.golangci.yaml | 1 - vendor/github.com/anchore/fangs/Makefile | 2 +- vendor/github.com/anchore/fangs/README.md | 1 + .../anchore/fangs/field_describer.go | 4 +- vendor/github.com/anchore/fangs/flags.go | 6 +- vendor/github.com/anchore/fangs/load.go | 35 +- vendor/github.com/anchore/fangs/summarize.go | 22 +- .../pkg/image/registry_credentials.go | 3 +- .../anchore/syft/internal/bus/helpers.go | 17 + .../anchore/syft/syft/cataloging/config.go | 7 + .../anchore/syft/syft/event/event.go | 9 - .../syft/syft/event/monitor/cataloger_task.go | 55 - .../event/monitor/cataloger_task_progress.go | 10 + .../syft/syft/event/monitor/generic_task.go | 17 +- .../format/common/cyclonedxhelpers/decoder.go | 19 +- .../format/common/cyclonedxhelpers/format.go | 13 +- .../cataloger/binary/default_classifiers.go | 29 + .../syft/syft/pkg/cataloger/catalog.go | 59 +- .../syft/syft/pkg/cataloger/cataloger.go | 8 +- .../common/cpe/dictionary/data/cpe-index.json | 10 + .../syft/pkg/cataloger/common/cpe/java.go | 2 +- .../cataloger/common/cpe/java_groupid_map.go | 1181 +++++++++++++---- .../anchore/syft/syft/pkg/cataloger/config.go | 3 + .../parse_dotnet_portable_executable.go | 151 ++- .../syft/pkg/cataloger/golang/licenses.go | 32 +- .../pkg/cataloger/haskell/parse_stack_lock.go | 14 +- .../syft/pkg/cataloger/java/archive_parser.go | 144 +- .../syft/syft/pkg/cataloger/java/cataloger.go | 6 +- .../syft/syft/pkg/cataloger/java/config.go | 5 +- .../pkg/cataloger/java/maven_repo_utils.go | 133 ++ .../pkg/cataloger/java/parse_java_manifest.go | 26 +- .../syft/pkg/cataloger/java/parse_pom_xml.go | 27 +- .../pkg/cataloger/javascript/cataloger.go | 5 +- .../syft/pkg/cataloger/javascript/config.go | 27 + .../syft/pkg/cataloger/javascript/package.go | 77 +- .../cataloger/javascript/parse_yarn_lock.go | 21 +- .../syft/syft/pkg/cataloger/python/package.go | 35 +- .../pkg/cataloger/python/parse_wheel_egg.go | 2 +- .../python/parse_wheel_egg_metadata.go | 6 +- .../anchore/syft/syft/pkg/collection.go | 51 +- .../anchore/syft/syft/source/file_source.go | 2 +- .../go-git/go-git/v5/config/branch.go | 2 +- .../go-git/go-git/v5/config/config.go | 3 +- .../go-git/go-git/v5/plumbing/object/patch.go | 4 +- .../go-git/go-git/v5/plumbing/reference.go | 89 ++ vendor/github.com/go-git/go-git/v5/remote.go | 23 +- .../github.com/go-git/go-git/v5/repository.go | 9 +- .../v5/storage/filesystem/dotgit/dotgit.go | 64 +- .../go-git/v5/storage/filesystem/storage.go | 5 + .../github.com/go-git/go-git/v5/worktree.go | 124 +- .../pkg/authn/keychain.go | 2 +- .../go-containerregistry/pkg/v1/layout/gc.go | 137 ++ .../pkg/v1/remote/write.go | 5 + vendor/github.com/google/uuid/CHANGELOG.md | 7 + vendor/github.com/google/uuid/time.go | 21 +- vendor/github.com/google/uuid/uuid.go | 53 + vendor/github.com/google/uuid/version6.go | 56 + vendor/github.com/google/uuid/version7.go | 75 ++ vendor/github.com/saferwall/pe/dotnet.go | 4 +- vendor/modernc.org/sqlite/AUTHORS | 1 + vendor/modernc.org/sqlite/CONTRIBUTORS | 1 + vendor/modernc.org/sqlite/Makefile | 2 +- vendor/modernc.org/sqlite/doc.go | 7 + vendor/modernc.org/sqlite/sqlite.go | 37 +- vendor/modules.txt | 18 +- 73 files changed, 3373 insertions(+), 700 deletions(-) delete mode 100644 vendor/github.com/anchore/syft/syft/event/monitor/cataloger_task.go create mode 100644 vendor/github.com/anchore/syft/syft/event/monitor/cataloger_task_progress.go create mode 100644 vendor/github.com/anchore/syft/syft/pkg/cataloger/java/maven_repo_utils.go create mode 100644 vendor/github.com/anchore/syft/syft/pkg/cataloger/javascript/config.go create mode 100644 vendor/github.com/google/go-containerregistry/pkg/v1/layout/gc.go create mode 100644 vendor/github.com/google/uuid/version6.go create mode 100644 vendor/github.com/google/uuid/version7.go diff --git a/go.mod b/go.mod index 3a88967e..e5f4d748 100644 --- a/go.mod +++ b/go.mod @@ -4,19 +4,19 @@ go 1.21.0 require ( github.com/anchore/go-logger v0.0.0-20230725134548-c21dafa1ec5a - github.com/anchore/stereoscope v0.0.0-20231117203853-3610f4ef3e83 - github.com/anchore/syft v0.98.0 + github.com/anchore/stereoscope v0.0.0-20231215220732-4b999b76ca89 + github.com/anchore/syft v0.99.0 github.com/in-toto/in-toto-golang v0.9.0 github.com/pkg/errors v0.9.1 github.com/sirupsen/logrus v1.9.3 - modernc.org/sqlite v1.27.0 + modernc.org/sqlite v1.28.0 ) require ( dario.cat/mergo v1.0.0 // 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/CycloneDX/cyclonedx-go v0.7.2 // indirect + github.com/CycloneDX/cyclonedx-go v0.8.0 // indirect github.com/DataDog/zstd v1.4.5 // indirect github.com/Masterminds/semver v1.5.0 // indirect github.com/Microsoft/go-winio v0.6.1 // indirect @@ -25,7 +25,7 @@ require ( github.com/acobaugh/osrelease v0.1.0 // indirect github.com/adrg/xdg v0.4.0 // indirect github.com/anchore/clio v0.0.0-20231016125544-c98a83e1c7fc // indirect - github.com/anchore/fangs v0.0.0-20231103141714-84c94dc43a2e // indirect + github.com/anchore/fangs v0.0.0-20231201140849-5075d28d6d8b // indirect github.com/anchore/go-macholibre v0.0.0-20220308212642-53e6d0aaf6fb // indirect github.com/anchore/go-struct-converter v0.0.0-20221118182256-c68fdcfa2092 // indirect github.com/anchore/packageurl-go v0.1.1-0.20230104203445-02e0a6721501 // indirect @@ -64,7 +64,7 @@ require ( github.com/github/go-spdx/v2 v2.2.0 // indirect github.com/go-git/gcfg v1.5.1-0.20230307220236-3a3c6141e376 // indirect github.com/go-git/go-billy/v5 v5.5.0 // indirect - github.com/go-git/go-git/v5 v5.10.1 // indirect + github.com/go-git/go-git/v5 v5.11.0 // indirect github.com/go-logr/logr v1.2.3 // indirect github.com/go-logr/stdr v1.2.2 // indirect github.com/go-restruct/restruct v1.2.0-alpha // indirect @@ -73,10 +73,10 @@ require ( github.com/golang/protobuf v1.5.3 // indirect github.com/golang/snappy v0.0.4 // indirect github.com/google/go-cmp v0.6.0 // indirect - github.com/google/go-containerregistry v0.16.1 // indirect + github.com/google/go-containerregistry v0.17.0 // indirect github.com/google/licensecheck v0.3.1 // indirect github.com/google/pprof v0.0.0-20221118152302-e6195bd50e26 // indirect - github.com/google/uuid v1.4.0 // indirect + github.com/google/uuid v1.5.0 // indirect github.com/gookit/color v1.5.4 // indirect github.com/hashicorp/errwrap v1.1.0 // indirect github.com/hashicorp/go-multierror v1.1.1 // indirect @@ -117,7 +117,7 @@ require ( github.com/pjbgf/sha1cd v0.3.0 // indirect github.com/pkg/profile v1.7.0 // indirect github.com/remyoudompheng/bigfft v0.0.0-20230129092748-24d4a6f8daec // indirect - github.com/saferwall/pe v1.4.7 // indirect + github.com/saferwall/pe v1.4.8 // indirect github.com/sagikazarmark/locafero v0.3.0 // indirect github.com/sagikazarmark/slog-shim v0.1.0 // indirect github.com/saintfish/chardet v0.0.0-20230101081208-5e3ef4b5456d // indirect diff --git a/go.sum b/go.sum index f2f422c8..299c5d78 100644 --- a/go.sum +++ b/go.sum @@ -58,8 +58,8 @@ github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03 github.com/BurntSushi/toml v0.4.1/go.mod h1:CxXYINrC8qIiEnFrOxCa7Jy5BFHlXnUU2pbicEuybxQ= github.com/BurntSushi/toml v1.2.1/go.mod h1:CxXYINrC8qIiEnFrOxCa7Jy5BFHlXnUU2pbicEuybxQ= github.com/BurntSushi/xgb v0.0.0-20160522181843-27f122750802/go.mod h1:IVnqGOEym/WlBOVXweHU+Q+/VP0lqqI8lqeDx9IjBqo= -github.com/CycloneDX/cyclonedx-go v0.7.2 h1:kKQ0t1dPOlugSIYVOMiMtFqeXI2wp/f5DBIdfux8gnQ= -github.com/CycloneDX/cyclonedx-go v0.7.2/go.mod h1:K2bA+324+Og0X84fA8HhN2X066K7Bxz4rpMQ4ZhjtSk= +github.com/CycloneDX/cyclonedx-go v0.8.0 h1:FyWVj6x6hoJrui5uRQdYZcSievw3Z32Z88uYzG/0D6M= +github.com/CycloneDX/cyclonedx-go v0.8.0/go.mod h1:K2bA+324+Og0X84fA8HhN2X066K7Bxz4rpMQ4ZhjtSk= github.com/DataDog/datadog-go v3.2.0+incompatible/go.mod h1:LButxg5PwREeZtORoXG3tL4fMGNddJ+vMq1mwgfaqoQ= github.com/DataDog/zstd v1.4.5 h1:EndNeuB0l9syBZhut0wns3gV1hL8zX8LIu6ZiVHWLIQ= github.com/DataDog/zstd v1.4.5/go.mod h1:1jcaCB/ufaK+sKp1NBhlGmpz41jOoPQ35bpF36t7BBo= @@ -83,8 +83,8 @@ github.com/alecthomas/units v0.0.0-20151022065526-2efee857e7cf/go.mod h1:ybxpYRF github.com/alecthomas/units v0.0.0-20190717042225-c3de453c63f4/go.mod h1:ybxpYRFXyAe+OPACYpWeL0wqObRcbAqCMya13uyzqw0= github.com/anchore/clio v0.0.0-20231016125544-c98a83e1c7fc h1:A1KFO+zZZmbNlz1+WKsCF0RKVx6XRoxsAG3lrqH9hUQ= github.com/anchore/clio v0.0.0-20231016125544-c98a83e1c7fc/go.mod h1:QeWvNzxsrUNxcs6haQo3OtISfXUXW0qAuiG4EQiz0GU= -github.com/anchore/fangs v0.0.0-20231103141714-84c94dc43a2e h1:O8ZubApaSl7dRzKNvyfGq9cLIPLQ5v3Iz0Y3huHKCgg= -github.com/anchore/fangs v0.0.0-20231103141714-84c94dc43a2e/go.mod h1:yPsN3NUGhU5dcBtYBa1dMNzGu1yT5ZAfSjKq9DY4aV8= +github.com/anchore/fangs v0.0.0-20231201140849-5075d28d6d8b h1:L/djgY7ZbZ/38+wUtdkk398W3PIBJLkt1N8nU/7e47A= +github.com/anchore/fangs v0.0.0-20231201140849-5075d28d6d8b/go.mod h1:TLcE0RE5+8oIx2/NPWem/dq1DeaMoC+fPEH7hoSzPLo= github.com/anchore/go-logger v0.0.0-20230725134548-c21dafa1ec5a h1:nJ2G8zWKASyVClGVgG7sfM5mwoZlZ2zYpIzN2OhjWkw= github.com/anchore/go-logger v0.0.0-20230725134548-c21dafa1ec5a/go.mod h1:ubLFmlsv8/DFUQrZwY5syT5/8Er3ugSr4rDFwHsE3hg= github.com/anchore/go-macholibre v0.0.0-20220308212642-53e6d0aaf6fb h1:iDMnx6LIjtjZ46C0akqveX83WFzhpTD3eqOthawb5vU= @@ -95,10 +95,10 @@ github.com/anchore/go-testutils v0.0.0-20200925183923-d5f45b0d3c04 h1:VzprUTpc0v github.com/anchore/go-testutils v0.0.0-20200925183923-d5f45b0d3c04/go.mod h1:6dK64g27Qi1qGQZ67gFmBFvEHScy0/C8qhQhNe5B5pQ= github.com/anchore/packageurl-go v0.1.1-0.20230104203445-02e0a6721501 h1:AV7qjwMcM4r8wFhJq3jLRztew3ywIyPTRapl2T1s9o8= github.com/anchore/packageurl-go v0.1.1-0.20230104203445-02e0a6721501/go.mod h1:Blo6OgJNiYF41ufcgHKkbCKF2MDOMlrqhXv/ij6ocR4= -github.com/anchore/stereoscope v0.0.0-20231117203853-3610f4ef3e83 h1:mxGIOmj+asEm8LUkPTG3/v0hi27WIlDVjiEVsUB9eqY= -github.com/anchore/stereoscope v0.0.0-20231117203853-3610f4ef3e83/go.mod h1:GKAnytSVV1hoqB5r5Gd9M5Ph3Rzqq0zPdEJesewjC2w= -github.com/anchore/syft v0.98.0 h1:mPDah48zZCFeSiGweqPd2C2++rOUh3/cAZylEy1VPwU= -github.com/anchore/syft v0.98.0/go.mod h1:FMj8zZFF3mP4IAuTxb6n14CZ6ouWXpI9RZqXpnkLK+Y= +github.com/anchore/stereoscope v0.0.0-20231215220732-4b999b76ca89 h1:dymFMCwnENqLr74KQppq8zHKwOPL0M1ToYAU+KVfTew= +github.com/anchore/stereoscope v0.0.0-20231215220732-4b999b76ca89/go.mod h1:GKAnytSVV1hoqB5r5Gd9M5Ph3Rzqq0zPdEJesewjC2w= +github.com/anchore/syft v0.99.0 h1:oqycIA7XfHCB09meroN7eY2RWTGUZIdtWsMQL2HlPvw= +github.com/anchore/syft v0.99.0/go.mod h1:tGZGyDxB2z/yu+x266+b67fMenGKCrUvSNVKED1euuo= 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= @@ -258,8 +258,8 @@ github.com/go-git/go-billy/v5 v5.5.0 h1:yEY4yhzCDuMGSv83oGxiBotRzhwhNr8VZyphhiu+ github.com/go-git/go-billy/v5 v5.5.0/go.mod h1:hmexnoNsr2SJU1Ju67OaNz5ASJY3+sHgFRpCtpDCKow= github.com/go-git/go-git-fixtures/v4 v4.3.2-0.20231010084843-55a94097c399 h1:eMje31YglSBqCdIqdhKBW8lokaMrL3uTkpGYlE2OOT4= github.com/go-git/go-git-fixtures/v4 v4.3.2-0.20231010084843-55a94097c399/go.mod h1:1OCfN199q1Jm3HZlxleg+Dw/mwps2Wbk9frAWm+4FII= -github.com/go-git/go-git/v5 v5.10.1 h1:tu8/D8i+TWxgKpzQ3Vc43e+kkhXqtsZCKI/egajKnxk= -github.com/go-git/go-git/v5 v5.10.1/go.mod h1:uEuHjxkHap8kAl//V5F/nNWwqIYtP/402ddd05mp0wg= +github.com/go-git/go-git/v5 v5.11.0 h1:XIZc1p+8YzypNr34itUfSvYJcv+eYdTnTvOZ2vD3cA4= +github.com/go-git/go-git/v5 v5.11.0/go.mod h1:6GFcX2P3NM7FPBfpePbpLd21XxsgdAt+lKqXmCUiUCY= github.com/go-gl/glfw v0.0.0-20190409004039-e6da0acd62b1/go.mod h1:vR7hzQXu2zJy9AVAgeJqvqgH9Q5CA+iKCZ2gyEVpxRU= github.com/go-gl/glfw/v3.3/glfw v0.0.0-20191125211704-12ad95a8df72/go.mod h1:tQ2UAYgL5IevRw8kRxooKSPJfGvJ9fJQFa0TUsXzTg8= github.com/go-gl/glfw/v3.3/glfw v0.0.0-20200222043503-6f7a984d4dc4/go.mod h1:tQ2UAYgL5IevRw8kRxooKSPJfGvJ9fJQFa0TUsXzTg8= @@ -338,8 +338,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.16.1 h1:rUEt426sR6nyrL3gt+18ibRcvYpKYdpsa5ZW7MA08dQ= -github.com/google/go-containerregistry v0.16.1/go.mod h1:u0qB2l7mvtWVR5kNcbFIhFY1hLbf8eeGapA+vbFDCtQ= +github.com/google/go-containerregistry v0.17.0 h1:5p+zYs/R4VGHkhyvgWurWrpJ2hW4Vv9fQI+GzdcwXLk= +github.com/google/go-containerregistry v0.17.0/go.mod h1:u0qB2l7mvtWVR5kNcbFIhFY1hLbf8eeGapA+vbFDCtQ= 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= @@ -366,8 +366,8 @@ github.com/google/pprof v0.0.0-20221118152302-e6195bd50e26 h1:Xim43kblpZXfIBQsbu github.com/google/pprof v0.0.0-20221118152302-e6195bd50e26/go.mod h1:dDKJzRmX4S37WGHujM7tX//fmj1uioxKzKxz3lo4HJo= github.com/google/renameio v0.1.0/go.mod h1:KWCgfxg9yswjAJkECMjeO8J8rahYeXnNhOm40UhjYkI= github.com/google/uuid v1.1.2/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= -github.com/google/uuid v1.4.0 h1:MtMxsa51/r9yyhkyLsVeVt0B+BGQZzpQiTQ4eHZ8bc4= -github.com/google/uuid v1.4.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= +github.com/google/uuid v1.5.0 h1:1p67kYwdtXjb0gL0BPiP1Av9wiZPo5A8z2cWkTZ+eyU= +github.com/google/uuid v1.5.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= github.com/googleapis/gax-go/v2 v2.0.4/go.mod h1:0Wqv26UfaUD9n4G6kQubkQ+KchISgw+vpHVxEJEs9eg= github.com/googleapis/gax-go/v2 v2.0.5/go.mod h1:DWXyrwAJ9X0FpwwEdw+IPEYBICEFu5mhpdKc/us6bOk= github.com/googleapis/gax-go/v2 v2.1.0/go.mod h1:Q3nei7sK6ybPYH7twZdmQpAd1MKb7pfu6SK+H1/DsU0= @@ -594,8 +594,8 @@ github.com/rogpeppe/go-internal v1.11.0/go.mod h1:ddIwULY96R17DhadqLgMfk9H9tvdUz github.com/russross/blackfriday/v2 v2.0.1/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM= github.com/russross/blackfriday/v2 v2.1.0/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM= github.com/ryanuber/columnize v0.0.0-20160712163229-9b3edd62028f/go.mod h1:sm1tb6uqfes/u+d4ooFouqFdy9/2g9QGwK3SQygK0Ts= -github.com/saferwall/pe v1.4.7 h1:A+G3DxX49paJ5OsxBfHKskhyDtmTjShlDmBd81IsHlQ= -github.com/saferwall/pe v1.4.7/go.mod h1:SNzv3cdgk8SBI0UwHfyTcdjawfdnN+nbydnEL7GZ25s= +github.com/saferwall/pe v1.4.8 h1:ey/L8FGBMrJ1Xh+Rltj1MAFPZ4LOQYGJqNa5B1Na6B0= +github.com/saferwall/pe v1.4.8/go.mod h1:SNzv3cdgk8SBI0UwHfyTcdjawfdnN+nbydnEL7GZ25s= github.com/sagikazarmark/crypt v0.3.0/go.mod h1:uD/D+6UF4SrIR1uGEv7bBNkNqLGqUr43MRiaGWX1Nig= github.com/sagikazarmark/locafero v0.3.0 h1:zT7VEGWC2DTflmccN/5T1etyKvxSxpHsjb9cJvm4SvQ= github.com/sagikazarmark/locafero v0.3.0/go.mod h1:w+v7UsPNFwzF1cHuOajOOzoq4U7v/ig1mpRjqV+Bu1U= @@ -1268,8 +1268,8 @@ modernc.org/memory v1.7.2 h1:Klh90S215mmH8c9gO98QxQFsY+W451E8AnzjoE2ee1E= modernc.org/memory v1.7.2/go.mod h1:NO4NVCQy0N7ln+T9ngWqOQfi7ley4vpwvARR+Hjw95E= modernc.org/opt v0.1.3 h1:3XOZf2yznlhC+ibLltsDGzABUGVx8J6pnFMS3E4dcq4= modernc.org/opt v0.1.3/go.mod h1:WdSiB5evDcignE70guQKxYUl14mgWtbClRi5wmkkTX0= -modernc.org/sqlite v1.27.0 h1:MpKAHoyYB7xqcwnUwkuD+npwEa0fojF0B5QRbN+auJ8= -modernc.org/sqlite v1.27.0/go.mod h1:Qxpazz0zH8Z1xCFyi5GSL3FzbtZ3fvbjmywNogldEW0= +modernc.org/sqlite v1.28.0 h1:Zx+LyDDmXczNnEQdvPuEfcFVA2ZPyaD7UCZDjef3BHQ= +modernc.org/sqlite v1.28.0/go.mod h1:Qxpazz0zH8Z1xCFyi5GSL3FzbtZ3fvbjmywNogldEW0= modernc.org/strutil v1.1.3 h1:fNMm+oJklMGYfU9Ylcywl0CO5O6nTfaowNsh2wpPjzY= modernc.org/strutil v1.1.3/go.mod h1:MEHNA7PdEnEwLvspRMtWTNnp2nnyvMfkimT1NKNAGbw= modernc.org/tcl v1.15.2 h1:C4ybAYCGJw968e+Me18oW55kD/FexcHbqH2xak1ROSY= diff --git a/vendor/github.com/CycloneDX/cyclonedx-go/.golangci.yml b/vendor/github.com/CycloneDX/cyclonedx-go/.golangci.yml index a9ac9d33..d1d92a82 100644 --- a/vendor/github.com/CycloneDX/cyclonedx-go/.golangci.yml +++ b/vendor/github.com/CycloneDX/cyclonedx-go/.golangci.yml @@ -1,6 +1,7 @@ linters: enable: - asciicheck + - errorlint - gofmt - gosec - wastedassign diff --git a/vendor/github.com/CycloneDX/cyclonedx-go/Dockerfile.gitpod b/vendor/github.com/CycloneDX/cyclonedx-go/Dockerfile.gitpod index ffd79189..5b984c3e 100644 --- a/vendor/github.com/CycloneDX/cyclonedx-go/Dockerfile.gitpod +++ b/vendor/github.com/CycloneDX/cyclonedx-go/Dockerfile.gitpod @@ -15,4 +15,4 @@ # SPDX-License-Identifier: Apache-2.0 # Copyright (c) OWASP Foundation. All Rights Reserved. -FROM gitpod/workspace-go:latest@sha256:f37c673d89ea7569a1b960679a44321ee221ccf7a82dcdd450179a2d79284c65 +FROM gitpod/workspace-go:latest@sha256:94ae638d8389303df9a6dde51a0daa5e475ca5db79ea9ee459309fe1d36ea701 diff --git a/vendor/github.com/CycloneDX/cyclonedx-go/convert.go b/vendor/github.com/CycloneDX/cyclonedx-go/convert.go index 4e8b20cb..6acec2fd 100644 --- a/vendor/github.com/CycloneDX/cyclonedx-go/convert.go +++ b/vendor/github.com/CycloneDX/cyclonedx-go/convert.go @@ -50,6 +50,7 @@ func (b *BOM) convert(specVersion SpecVersion) { } if specVersion < SpecVersion1_5 { b.Annotations = nil + b.Formulation = nil } if b.Metadata != nil { @@ -61,13 +62,13 @@ func (b *BOM) convert(specVersion SpecVersion) { b.Metadata.Lifecycles = nil } + if specVersion < SpecVersion1_5 { + b.Metadata.Lifecycles = nil + } + recurseComponent(b.Metadata.Component, componentConverter(specVersion)) convertLicenses(b.Metadata.Licenses, specVersion) - if b.Metadata.Tools != nil { - for i := range *b.Metadata.Tools { - convertTool(&(*b.Metadata.Tools)[i], specVersion) - } - } + convertTools(b.Metadata.Tools, specVersion) } if b.Components != nil { @@ -82,6 +83,18 @@ func (b *BOM) convert(specVersion SpecVersion) { } } + if b.Vulnerabilities != nil { + convertVulnerabilities(b.Vulnerabilities, specVersion) + } + + if b.Compositions != nil { + convertCompositions(b.Compositions, specVersion) + } + + if b.ExternalReferences != nil { + convertExternalReferences(b.ExternalReferences, specVersion) + } + b.SpecVersion = specVersion b.XMLNS = xmlNamespaces[specVersion] b.JSONSchema = jsonSchemas[specVersion] @@ -121,6 +134,17 @@ func componentConverter(specVersion SpecVersion) func(*Component) { } } + if specVersion < SpecVersion1_5 { + c.ModelCard = nil + c.Data = nil + + if c.Evidence != nil { + c.Evidence.Identity = nil + c.Evidence.Occurrences = nil + c.Evidence.Callstack = nil + } + } + if !specVersion.supportsComponentType(c.Type) { c.Type = ComponentTypeApplication } @@ -133,6 +157,19 @@ func componentConverter(specVersion SpecVersion) func(*Component) { } } +func convertCompositions(comps *[]Composition, specVersion SpecVersion) { + if comps == nil { + return + } + + for i := range *comps { + comp := &(*comps)[i] + if !specVersion.supportsCompositionAggregate(comp.Aggregate) { + comp.Aggregate = CompositionAggregateUnknown + } + } +} + // convertExternalReferences modifies an ExternalReference slice such that it adheres to a given SpecVersion. func convertExternalReferences(extRefs *[]ExternalReference, specVersion SpecVersion) { if extRefs == nil { @@ -218,6 +255,33 @@ func convertLicenses(licenses *Licenses, specVersion SpecVersion) { } } +func convertVulnerabilities(vulns *[]Vulnerability, specVersion SpecVersion) { + if vulns == nil { + return + } + + for i := range *vulns { + vuln := &(*vulns)[i] + + convertTools(vuln.Tools, specVersion) + + if specVersion < SpecVersion1_5 { + vuln.ProofOfConcept = nil + vuln.Rejected = "" + vuln.Workaround = "" + } + + if vuln.Ratings != nil { + for j := range *vuln.Ratings { + rating := &(*vuln.Ratings)[j] + if !specVersion.supportsScoringMethod(rating.Method) { + rating.Method = ScoringMethodOther + } + } + } + } +} + // serviceConverter modifies a Service such that it adheres to a given SpecVersion. func serviceConverter(specVersion SpecVersion) func(*Service) { return func(s *Service) { @@ -233,6 +297,50 @@ func serviceConverter(specVersion SpecVersion) func(*Service) { } } +// convertTools modifies a ToolsChoice such that it adheres to a given SpecVersion. +func convertTools(tools *ToolsChoice, specVersion SpecVersion) { + if tools == nil { + return + } + + if specVersion < SpecVersion1_5 { + convertedTools := make([]Tool, 0) + if tools.Components != nil { + for i := range *tools.Components { + tool := convertComponentToTool((*tools.Components)[i], specVersion) + if tool != nil { + convertedTools = append(convertedTools, *tool) + } + } + tools.Components = nil + } + + if tools.Services != nil { + for i := range *tools.Services { + tool := convertServiceToTool((*tools.Services)[i], specVersion) + if tool != nil { + convertedTools = append(convertedTools, *tool) + } + } + tools.Services = nil + } + + if len(convertedTools) > 0 { + if tools.Tools == nil { + tools.Tools = &convertedTools + } else { + *tools.Tools = append(*tools.Tools, convertedTools...) + } + } + } + + if tools.Tools != nil { + for i := range *tools.Tools { + convertTool(&(*tools.Tools)[i], specVersion) + } + } +} + // convertTool modifies a Tool such that it adheres to a given SpecVersion. func convertTool(tool *Tool, specVersion SpecVersion) { if tool == nil { @@ -247,6 +355,40 @@ func convertTool(tool *Tool, specVersion SpecVersion) { convertHashes(tool.Hashes, specVersion) } +// convertComponentToTool converts a Component to a Tool for use in ToolsChoice.Tools. +func convertComponentToTool(component Component, _ SpecVersion) *Tool { + tool := Tool{ + Vendor: component.Author, + Name: component.Name, + Version: component.Version, + Hashes: component.Hashes, + ExternalReferences: component.ExternalReferences, + } + + if component.Supplier != nil { + // There is no perfect 1:1 mapping for the Vendor field, but Supplier comes closest. + // https://github.com/CycloneDX/cyclonedx-go/issues/115#issuecomment-1688710539 + tool.Vendor = component.Supplier.Name + } + + return &tool +} + +// convertServiceToTool converts a Service to a Tool for use in ToolsChoice.Tools. +func convertServiceToTool(service Service, _ SpecVersion) *Tool { + tool := Tool{ + Name: service.Name, + Version: service.Version, + ExternalReferences: service.ExternalReferences, + } + + if service.Provider != nil { + tool.Vendor = service.Provider.Name + } + + return &tool +} + func recurseComponent(component *Component, f func(c *Component)) { if component == nil { return @@ -307,6 +449,16 @@ func (sv SpecVersion) supportsComponentType(cType ComponentType) bool { return false } +func (sv SpecVersion) supportsCompositionAggregate(ca CompositionAggregate) bool { + switch ca { + case CompositionAggregateIncompleteFirstPartyOpenSourceOnly, CompositionAggregateIncompleteFirstPartyProprietaryOnly, + CompositionAggregateIncompleteThirdPartyOpenSourceOnly, CompositionAggregateIncompleteThirdPartyProprietaryOnly: + return sv >= SpecVersion1_5 + } + + return sv >= SpecVersion1_3 +} + func (sv SpecVersion) supportsExternalReferenceType(ert ExternalReferenceType) bool { switch ert { case ERTypeAdversaryModel, @@ -314,10 +466,15 @@ func (sv SpecVersion) supportsExternalReferenceType(ert ExternalReferenceType) b ERTypeCertificationReport, ERTypeCodifiedInfrastructure, ERTypeComponentAnalysisReport, + ERTypeConfiguration, ERTypeDistributionIntake, ERTypeDynamicAnalysisReport, + ERTypeEvidence, ERTypeExploitabilityStatement, + ERTypeFormulation, + ERTypeLog, ERTypeMaturityReport, + ERTypeModelCard, ERTypePentestReport, ERTypeQualityMetrics, ERTypeRiskAssessment, @@ -352,3 +509,14 @@ func (sv SpecVersion) supportsScope(scope Scope) bool { return false } + +func (sv SpecVersion) supportsScoringMethod(method ScoringMethod) bool { + switch method { + case ScoringMethodCVSSv2, ScoringMethodCVSSv3, ScoringMethodCVSSv31, ScoringMethodOWASP, ScoringMethodOther: + return sv >= SpecVersion1_4 + case ScoringMethodCVSSv4, ScoringMethodSSVC: + return sv >= SpecVersion1_5 + } + + return false +} diff --git a/vendor/github.com/CycloneDX/cyclonedx-go/cyclonedx.go b/vendor/github.com/CycloneDX/cyclonedx-go/cyclonedx.go index 55574e9c..e51e6879 100644 --- a/vendor/github.com/CycloneDX/cyclonedx-go/cyclonedx.go +++ b/vendor/github.com/CycloneDX/cyclonedx-go/cyclonedx.go @@ -90,6 +90,7 @@ type BOM struct { Properties *[]Property `json:"properties,omitempty" xml:"properties>property,omitempty"` Vulnerabilities *[]Vulnerability `json:"vulnerabilities,omitempty" xml:"vulnerabilities>vulnerability,omitempty"` Annotations *[]Annotation `json:"annotations,omitempty" xml:"annotations>annotation,omitempty"` + Formulation *[]Formula `json:"formulation,omitempty" xml:"formulation>formula,omitempty"` } func NewBOM() *BOM { @@ -116,6 +117,20 @@ func Bool(value bool) *bool { type BOMReference string +type Callstack struct { + Frames *[]CallstackFrame `json:"frames,omitempty" xml:"frames>frame,omitempty"` +} + +type CallstackFrame struct { + Package string `json:"package,omitempty" xml:"package,omitempty"` + Module string `json:"module,omitempty" xml:"module,omitempty"` + Function string `json:"function,omitempty" xml:"function,omitempty"` + Parameters *[]string `json:"parameters,omitempty" xml:"parameters>parameter,omitempty"` + Line *int `json:"line,omitempty" xml:"line,omitempty"` + Column *int `json:"column,omitempty" xml:"column,omitempty"` + FullFilename string `json:"fullFilename,omitempty" xml:"fullFilename,omitempty"` +} + type ComponentType string const ( @@ -166,23 +181,80 @@ type Component struct { Components *[]Component `json:"components,omitempty" xml:"components>component,omitempty"` Evidence *Evidence `json:"evidence,omitempty" xml:"evidence,omitempty"` ReleaseNotes *ReleaseNotes `json:"releaseNotes,omitempty" xml:"releaseNotes,omitempty"` + ModelCard *MLModelCard `json:"modelCard,omitempty" xml:"modelCard,omitempty"` + Data *ComponentData `json:"data,omitempty" xml:"data,omitempty"` +} + +type ComponentData struct { + BOMRef string `json:"bom-ref,omitempty" xml:"bom-ref,attr,omitempty"` + Type ComponentDataType `json:"type,omitempty" xml:"type,omitempty"` + Name string `json:"name,omitempty" xml:"name,omitempty"` + Contents *ComponentDataContents `json:"contents,omitempty" xml:"contents,omitempty"` + Classification string `json:"classification,omitempty" xml:"classification,omitempty"` + SensitiveData *[]string `json:"sensitiveData,omitempty" xml:"sensitiveData,omitempty"` + Graphics *ComponentDataGraphics `json:"graphics,omitempty" xml:"graphics,omitempty"` + Description string `json:"description,omitempty" xml:"description,omitempty"` + Governance *ComponentDataGovernance `json:"governance,omitempty" xml:"governance,omitempty"` +} + +type ComponentDataContents struct { + Attachment *AttachedText `json:"attachment,omitempty" xml:"attachment,omitempty"` + URL string `json:"url,omitempty" xml:"url,omitempty"` + Properties *[]Property `json:"properties,omitempty" xml:"properties,omitempty"` +} + +type ComponentDataGovernance struct { + Custodians *[]ComponentDataGovernanceResponsibleParty `json:"custodians,omitempty" xml:"custodians>custodian,omitempty"` + Stewards *[]ComponentDataGovernanceResponsibleParty `json:"stewards,omitempty" xml:"stewards>steward,omitempty"` + Owners *[]ComponentDataGovernanceResponsibleParty `json:"owners,omitempty" xml:"owners>owner,omitempty"` +} + +type ComponentDataGovernanceResponsibleParty struct { + Organization *OrganizationalEntity `json:"organization,omitempty" xml:"organization,omitempty"` + Contact *OrganizationalContact `json:"contact,omitempty" xml:"contact,omitempty"` +} + +type ComponentDataGraphic struct { + Name string `json:"name,omitempty" xml:"name,omitempty"` + Image *AttachedText `json:"image,omitempty" xml:"image,omitempty"` } +type ComponentDataGraphics struct { + Description string `json:"description,omitempty" xml:"description,omitempty"` + Collection *[]ComponentDataGraphic `json:"collection,omitempty" xml:"collection>graphic,omitempty"` +} + +type ComponentDataType string + +const ( + ComponentDataTypeConfiguration ComponentDataType = "configuration" + ComponentDataTypeDataset ComponentDataType = "dataset" + ComponentDataTypeDefinition ComponentDataType = "definition" + ComponentDataTypeOther ComponentDataType = "other" + ComponentDataTypeSourceCode ComponentDataType = "source-code" +) + type Composition struct { - Aggregate CompositionAggregate `json:"aggregate" xml:"aggregate"` - Assemblies *[]BOMReference `json:"assemblies,omitempty" xml:"assemblies>assembly,omitempty"` - Dependencies *[]BOMReference `json:"dependencies,omitempty" xml:"dependencies>dependency,omitempty"` + BOMRef string `json:"bom-ref,omitempty" xml:"bom-ref,attr,omitempty"` + Aggregate CompositionAggregate `json:"aggregate" xml:"aggregate"` + Assemblies *[]BOMReference `json:"assemblies,omitempty" xml:"assemblies>assembly,omitempty"` + Dependencies *[]BOMReference `json:"dependencies,omitempty" xml:"dependencies>dependency,omitempty"` + Vulnerabilities *[]BOMReference `json:"vulnerabilities,omitempty" xml:"vulnerabilities>vulnerability,omitempty"` } type CompositionAggregate string const ( - CompositionAggregateComplete CompositionAggregate = "complete" - CompositionAggregateIncomplete CompositionAggregate = "incomplete" - CompositionAggregateIncompleteFirstPartyOnly CompositionAggregate = "incomplete_first_party_only" - CompositionAggregateIncompleteThirdPartyOnly CompositionAggregate = "incomplete_third_party_only" - CompositionAggregateUnknown CompositionAggregate = "unknown" - CompositionAggregateNotSpecified CompositionAggregate = "not_specified" + CompositionAggregateComplete CompositionAggregate = "complete" + CompositionAggregateIncomplete CompositionAggregate = "incomplete" + CompositionAggregateIncompleteFirstPartyOnly CompositionAggregate = "incomplete_first_party_only" + CompositionAggregateIncompleteFirstPartyOpenSourceOnly CompositionAggregate = "incomplete_first_party_opensource_only" + CompositionAggregateIncompleteFirstPartyProprietaryOnly CompositionAggregate = "incomplete_first_party_proprietary_only" + CompositionAggregateIncompleteThirdPartyOnly CompositionAggregate = "incomplete_third_party_only" + CompositionAggregateIncompleteThirdPartyOpenSourceOnly CompositionAggregate = "incomplete_third_party_opensource_only" + CompositionAggregateIncompleteThirdPartyProprietaryOnly CompositionAggregate = "incomplete_third_party_proprietary_only" + CompositionAggregateNotSpecified CompositionAggregate = "not_specified" + CompositionAggregateUnknown CompositionAggregate = "unknown" ) type Copyright struct { @@ -218,9 +290,74 @@ type Diff struct { URL string `json:"url,omitempty" xml:"url,omitempty"` } +type EnvironmentVariables []EnvironmentVariableChoice + +type EnvironmentVariableChoice struct { + Property *Property `json:"-" xml:"-"` + Value string `json:"-" xml:"-"` +} + +type Event struct { + UID string `json:"uid,omitempty" xml:"uid,omitempty"` + Description string `json:"description,omitempty" xml:"description,omitempty"` + TimeReceived string `json:"timeReceived,omitempty" xml:"timeReceived,omitempty"` + Data *AttachedText `json:"data,omitempty" xml:"data,omitempty"` + Source *ResourceReferenceChoice `json:"source,omitempty" xml:"source,omitempty"` + Target *ResourceReferenceChoice `json:"target,omitempty" xml:"target,omitempty"` + Properties *[]Property `json:"properties,omitempty" xml:"properties>property,omitempty"` +} + type Evidence struct { - Licenses *Licenses `json:"licenses,omitempty" xml:"licenses,omitempty"` - Copyright *[]Copyright `json:"copyright,omitempty" xml:"copyright>text,omitempty"` + Identity *EvidenceIdentity `json:"identity,omitempty" xml:"identity,omitempty"` + Occurrences *[]EvidenceOccurrence `json:"occurrences,omitempty" xml:"occurrences>occurrence,omitempty"` + Callstack *Callstack `json:"callstack,omitempty" xml:"callstack,omitempty"` + Licenses *Licenses `json:"licenses,omitempty" xml:"licenses,omitempty"` + Copyright *[]Copyright `json:"copyright,omitempty" xml:"copyright>text,omitempty"` +} + +type EvidenceIdentity struct { + Field EvidenceIdentityFieldType `json:"field,omitempty" xml:"field,omitempty"` + Confidence *float32 `json:"confidence,omitempty" xml:"confidence,omitempty"` + Methods *[]EvidenceIdentityMethod `json:"methods,omitempty" xml:"methods>method,omitempty"` + Tools *[]BOMReference `json:"tools,omitempty" xml:"tools>tool,omitempty"` +} + +type EvidenceIdentityFieldType string + +const ( + EvidenceIdentityFieldTypeCPE EvidenceIdentityFieldType = "cpe" + EvidenceIdentityFieldTypeGroup EvidenceIdentityFieldType = "group" + EvidenceIdentityFieldTypeHash EvidenceIdentityFieldType = "hash" + EvidenceIdentityFieldTypeName EvidenceIdentityFieldType = "name" + EvidenceIdentityFieldTypePURL EvidenceIdentityFieldType = "purl" + EvidenceIdentityFieldTypeSWID EvidenceIdentityFieldType = "swid" + EvidenceIdentityFieldTypeVersion EvidenceIdentityFieldType = "version" +) + +type EvidenceIdentityMethod struct { + Technique EvidenceIdentityTechnique `json:"technique,omitempty" xml:"technique,omitempty"` + Confidence *float32 `json:"confidence,omitempty" xml:"confidence,omitempty"` + Value string `json:"value,omitempty" xml:"value,omitempty"` +} + +type EvidenceIdentityTechnique string + +const ( + EvidenceIdentityTechniqueASTFingerprint EvidenceIdentityTechnique = "ast-fingerprint" + EvidenceIdentityTechniqueAttestation EvidenceIdentityTechnique = "attestation" + EvidenceIdentityTechniqueBinaryAnalysis EvidenceIdentityTechnique = "binary-analysis" + EvidenceIdentityTechniqueDynamicAnalysis EvidenceIdentityTechnique = "dynamic-analysis" + EvidenceIdentityTechniqueFilename EvidenceIdentityTechnique = "filename" + EvidenceIdentityTechniqueHashComparison EvidenceIdentityTechnique = "hash-comparison" + EvidenceIdentityTechniqueInstrumentation EvidenceIdentityTechnique = "instrumentation" + EvidenceIdentityTechniqueManifestAnalysis EvidenceIdentityTechnique = "manifest-analysis" + EvidenceIdentityTechniqueOther EvidenceIdentityTechnique = "other" + EvidenceIdentityTechniqueSourceCodeAnalysis EvidenceIdentityTechnique = "source-code-analysis" +) + +type EvidenceOccurrence struct { + BOMRef string `json:"bom-ref,omitempty" xml:"bom-ref,attr,omitempty"` + Location string `json:"location,omitempty" xml:"location,omitempty"` } type ExternalReference struct { @@ -241,17 +378,22 @@ const ( ERTypeBuildSystem ExternalReferenceType = "build-system" ERTypeCertificationReport ExternalReferenceType = "certification-report" ERTypeChat ExternalReferenceType = "chat" + ERTypeConfiguration ExternalReferenceType = "configuration" ERTypeCodifiedInfrastructure ExternalReferenceType = "codified-infrastructure" ERTypeComponentAnalysisReport ExternalReferenceType = "component-analysis-report" ERTypeDistribution ExternalReferenceType = "distribution" ERTypeDistributionIntake ExternalReferenceType = "distribution-intake" ERTypeDocumentation ExternalReferenceType = "documentation" ERTypeDynamicAnalysisReport ExternalReferenceType = "dynamic-analysis-report" + ERTypeEvidence ExternalReferenceType = "evidence" ERTypeExploitabilityStatement ExternalReferenceType = "exploitability-statement" + ERTypeFormulation ExternalReferenceType = "formulation" ERTypeIssueTracker ExternalReferenceType = "issue-tracker" ERTypeLicense ExternalReferenceType = "license" + ERTypeLog ExternalReferenceType = "log" ERTypeMailingList ExternalReferenceType = "mailing-list" ERTypeMaturityReport ExternalReferenceType = "maturity-report" + ERTypeModelCard ExternalReferenceType = "model-card" ERTypeOther ExternalReferenceType = "other" ERTypePentestReport ExternalReferenceType = "pentest-report" ERTypeQualityMetrics ExternalReferenceType = "quality-metrics" @@ -268,6 +410,14 @@ const ( ERTypeWebsite ExternalReferenceType = "website" ) +type Formula struct { + BOMRef string `json:"bom-ref,omitempty" xml:"bom-ref,attr,omitempty"` + Components *[]Component `json:"components,omitempty" xml:"components>component,omitempty"` + Services *[]Service `json:"services,omitempty" xml:"services>service,omitempty"` + Workflows *[]Workflow `json:"workflows,omitempty" xml:"workflows>workflow,omitempty"` + Properties *[]Property `json:"properties,omitempty" xml:"properties>property,omitempty"` +} + type Hash struct { Algorithm HashAlgorithm `json:"alg" xml:"alg,attr"` Value string `json:"content" xml:",chardata"` @@ -436,7 +586,7 @@ func (mt MediaType) WithVersion(specVersion SpecVersion) (string, error) { type Metadata struct { Timestamp string `json:"timestamp,omitempty" xml:"timestamp,omitempty"` Lifecycles *[]Lifecycle `json:"lifecycles,omitempty" xml:"lifecycles>lifecycle,omitempty"` - Tools *[]Tool `json:"tools,omitempty" xml:"tools>tool,omitempty"` + Tools *ToolsChoice `json:"tools,omitempty" xml:"tools,omitempty"` Authors *[]OrganizationalContact `json:"authors,omitempty" xml:"authors>author,omitempty"` Component *Component `json:"component,omitempty" xml:"component,omitempty"` Manufacture *OrganizationalEntity `json:"manufacture,omitempty" xml:"manufacture,omitempty"` @@ -445,6 +595,84 @@ type Metadata struct { Properties *[]Property `json:"properties,omitempty" xml:"properties>property,omitempty"` } +type MLDatasetChoice struct { + Ref string `json:"-" xml:"-"` + ComponentData *ComponentData `json:"-" xml:"-"` +} + +type MLInputOutputParameters struct { + Format string `json:"format,omitempty" xml:"format,omitempty"` +} + +type MLModelCard struct { + BOMRef string `json:"bom-ref,omitempty" xml:"bom-ref,attr,omitempty"` + ModelParameters *MLModelParameters `json:"modelParameters,omitempty" xml:"modelParameters,omitempty"` + QuantitativeAnalysis *MLQuantitativeAnalysis `json:"quantitativeAnalysis,omitempty" xml:"quantitativeAnalysis,omitempty"` + Considerations *MLModelCardConsiderations `json:"considerations,omitempty" xml:"considerations,omitempty"` +} + +type MLModelCardConsiderations struct { + Users *[]string `json:"users,omitempty" xml:"users>user,omitempty"` + UseCases *[]string `json:"useCases,omitempty" xml:"useCases>useCase,omitempty"` + TechnicalLimitations *[]string `json:"technicalLimitations,omitempty" xml:"technicalLimitations>technicalLimitation,omitempty"` + PerformanceTradeoffs *[]string `json:"performanceTradeoffs,omitempty" xml:"performanceTradeoffs>performanceTradeoff,omitempty"` + EthicalConsiderations *[]MLModelCardEthicalConsideration `json:"ethicalConsiderations,omitempty" xml:"ethicalConsiderations>ethicalConsideration,omitempty"` + FairnessAssessments *[]MLModelCardFairnessAssessment `json:"fairnessAssessments,omitempty" xml:"fairnessAssessments>fairnessAssessment,omitempty"` +} + +type MLModelCardEthicalConsideration struct { + Name string `json:"name,omitempty" xml:"name,omitempty"` + MitigationStrategy string `json:"mitigationStrategy,omitempty" xml:"mitigationStrategy,omitempty"` +} + +type MLModelCardFairnessAssessment struct { + GroupAtRisk string `json:"groupAtRisk,omitempty" xml:"groupAtRisk,omitempty"` + Benefits string `json:"benefits,omitempty" xml:"benefits,omitempty"` + Harms string `json:"harms,omitempty" xml:"harms,omitempty"` + MitigationStrategy string `json:"mitigationStrategy,omitempty" xml:"mitigationStrategy,omitempty"` +} + +type MLModelParameters struct { + Approach *MLModelParametersApproach `json:"approach,omitempty" xml:"approach,omitempty"` + Task string `json:"task,omitempty" xml:"task,omitempty"` + ArchitectureFamily string `json:"architectureFamily,omitempty" xml:"architectureFamily,omitempty"` + ModelArchitecture string `json:"modelArchitecture,omitempty" xml:"modelArchitecture,omitempty"` + Datasets *[]MLDatasetChoice `json:"datasets,omitempty" xml:"datasets>dataset,omitempty"` + Inputs *[]MLInputOutputParameters `json:"inputs,omitempty" xml:"inputs>input,omitempty"` + Outputs *[]MLInputOutputParameters `json:"outputs,omitempty" xml:"outputs>output,omitempty"` +} + +type MLModelParametersApproach struct { + Type MLModelParametersApproachType `json:"type,omitempty" xml:"type,omitempty"` +} + +type MLModelParametersApproachType string + +const ( + MLModelParametersApproachTypeSupervised MLModelParametersApproachType = "supervised" + MLModelParametersApproachTypeUnsupervised MLModelParametersApproachType = "unsupervised" + MLModelParametersApproachTypeReinforcementLearning MLModelParametersApproachType = "reinforcement-learning" + MLModelParametersApproachTypeSemiSupervised MLModelParametersApproachType = "semi-supervised" + MLModelParametersApproachTypeSelfSupervised MLModelParametersApproachType = "self-supervised" +) + +type MLQuantitativeAnalysis struct { + PerformanceMetrics *[]MLPerformanceMetric `json:"performanceMetrics,omitempty" xml:"performanceMetrics>performanceMetric,omitempty"` + Graphics *ComponentDataGraphics `json:"graphics,omitempty" xml:"graphics,omitempty"` +} + +type MLPerformanceMetric struct { + Type string `json:"type,omitempty" xml:"type,omitempty"` + Value string `json:"value,omitempty" xml:"value,omitempty"` + Slice string `json:"slice,omitempty" xml:"slice,omitempty"` + ConfidenceInterval *MLPerformanceMetricConfidenceInterval `json:"confidenceInterval,omitempty" xml:"confidenceInterval,omitempty"` +} + +type MLPerformanceMetricConfidenceInterval struct { + LowerBound string `json:"lowerBound,omitempty" xml:"lowerBound,omitempty"` + UpperBound string `json:"upperBound,omitempty" xml:"upperBound,omitempty"` +} + type Note struct { Locale string `json:"locale,omitempty" xml:"locale,omitempty"` Text AttachedText `json:"text" xml:"text"` @@ -467,6 +695,12 @@ type OrganizationalEntityOrContact struct { Individual *OrganizationalContact `json:"individual,omitempty" xml:"individual,omitempty"` } +type Parameter struct { + Name string `json:"name,omitempty" xml:"name,omitempty"` + Value string `json:"value,omitempty" xml:"value,omitempty"` + DataType string `json:"dataType,omitempty" xml:"dataType,omitempty"` +} + type Patch struct { Diff *Diff `json:"diff,omitempty" xml:"diff,omitempty"` Resolves *[]Issue `json:"resolves,omitempty" xml:"resolves>issue,omitempty"` @@ -491,6 +725,12 @@ type Pedigree struct { Notes string `json:"notes,omitempty" xml:"notes,omitempty"` } +type ProofOfConcept struct { + ReproductionSteps string `json:"reproductionSteps,omitempty" xml:"reproductionSteps,omitempty"` + Environment string `json:"environment,omitempty" xml:"environment,omitempty"` + SupportingMaterial *[]AttachedText `json:"supportingMaterial,omitempty" xml:"supportingMaterial>attachment,omitempty"` +} + type Property struct { Name string `json:"name" xml:"name,attr"` Value string `json:"value" xml:",chardata"` @@ -510,6 +750,11 @@ type ReleaseNotes struct { Properties *[]Property `json:"properties,omitempty" xml:"properties>property,omitempty"` } +type ResourceReferenceChoice struct { + Ref string `json:"ref,omitempty" xml:"ref,omitempty"` + ExternalReference *ExternalReference `json:"externalReference,omitempty" xml:"externalReference,omitempty"` +} + type Scope string const ( @@ -525,7 +770,9 @@ const ( ScoringMethodCVSSv2 ScoringMethod = "CVSSv2" ScoringMethodCVSSv3 ScoringMethod = "CVSSv3" ScoringMethodCVSSv31 ScoringMethod = "CVSSv31" + ScoringMethodCVSSv4 ScoringMethod = "CVSSv4" ScoringMethodOWASP ScoringMethod = "OWASP" + ScoringMethodSSVC ScoringMethod = "SSVC" ) type Service struct { @@ -586,6 +833,141 @@ type SWID struct { Patch *bool `json:"patch,omitempty" xml:"patch,attr,omitempty"` } +type Task struct { + BOMRef string `json:"bom-ref,omitempty" xml:"bom-ref,attr,omitempty"` + UID string `json:"uid,omitempty" xml:"uid,omitempty"` + Name string `json:"name,omitempty" xml:"name,omitempty"` + Description string `json:"description,omitempty" xml:"description,omitempty"` + Properties *[]Property `json:"properties,omitempty" xml:"properties>property,omitempty"` + ResourceReferences *[]ResourceReferenceChoice `json:"resourceReferences,omitempty" xml:"resourceReferences>resourceReference,omitempty"` + TaskTypes *[]TaskType `json:"taskTypes,omitempty" xml:"taskTypes>taskType,omitempty"` + Trigger *TaskTrigger `json:"trigger,omitempty" xml:"trigger,omitempty"` + Steps *[]TaskStep `json:"steps,omitempty" xml:"steps>step,omitempty"` + Inputs *[]TaskInput `json:"inputs,omitempty" xml:"inputs>input,omitempty"` + Outputs *[]TaskOutput `json:"outputs,omitempty" xml:"outputs>output,omitempty"` + TimeStart string `json:"timeStart,omitempty" xml:"timeStart,omitempty"` + TimeEnd string `json:"timeEnd,omitempty" xml:"timeEnd,omitempty"` + Workspaces *[]TaskWorkspace `json:"workspaces,omitempty" xml:"workspaces>workspace,omitempty"` + RuntimeTopology *[]Dependency `json:"runtimeTopology,omitempty" xml:"runtimeTopology>dependency,omitempty"` +} + +type TaskCommand struct { + Executed string `json:"executed,omitempty" xml:"executed,omitempty"` + Properties *[]Property `json:"properties,omitempty" xml:"properties>property,omitempty"` +} + +type TaskInput struct { + Resource *ResourceReferenceChoice `json:"resource,omitempty" xml:"resource,omitempty"` + Parameters *[]Parameter `json:"parameters,omitempty" xml:"parameters>parameter,omitempty"` + EnvironmentVars *EnvironmentVariables `json:"environmentVars,omitempty" xml:"environmentVars,omitempty"` + Data *AttachedText `json:"data,omitempty" xml:"data,omitempty"` + Source *ResourceReferenceChoice `json:"source,omitempty" xml:"source,omitempty"` + Target *ResourceReferenceChoice `json:"target,omitempty" xml:"target,omitempty"` + Properties *[]Property `json:"properties,omitempty" xml:"properties>property,omitempty"` +} + +type TaskOutput struct { + Resource *ResourceReferenceChoice `json:"resource,omitempty" xml:"resource,omitempty"` + Parameters *[]Parameter `json:"parameters,omitempty" xml:"parameters>parameter,omitempty"` + EnvironmentVars *EnvironmentVariables `json:"environmentVars,omitempty" xml:"environmentVars,omitempty"` + Data *AttachedText `json:"data,omitempty" xml:"data,omitempty"` + Type TaskOutputType `json:"type,omitempty" xml:"type,omitempty"` + Source *ResourceReferenceChoice `json:"source,omitempty" xml:"source,omitempty"` + Target *ResourceReferenceChoice `json:"target,omitempty" xml:"target,omitempty"` + Properties *[]Property `json:"properties,omitempty" xml:"properties>property,omitempty"` +} + +type TaskOutputType string + +const ( + TaskOutputTypeArtifact TaskOutputType = "artifact" + TaskOutputTypeAttestation TaskOutputType = "attestation" + TaskOutputTypeEvidence TaskOutputType = "evidence" + TaskOutputTypeLog TaskOutputType = "log" + TaskOutputTypeMetrics TaskOutputType = "metrics" + TaskOutputTypeOther TaskOutputType = "other" +) + +type TaskStep struct { + Name string `json:"name,omitempty" xml:"name,omitempty"` + Description string `json:"description,omitempty" xml:"description,omitempty"` + Commands *[]TaskCommand `json:"commands,omitempty" xml:"commands>command,omitempty"` + Properties *[]Property `json:"properties,omitempty" xml:"properties>property,omitempty"` +} + +type TaskTrigger struct { + BOMRef string `json:"bom-ref,omitempty" xml:"bom-ref,attr,omitempty"` + UID string `json:"uid,omitempty" xml:"uid,omitempty"` + Name string `json:"name,omitempty" xml:"name,omitempty"` + Description string `json:"description,omitempty" xml:"description,omitempty"` + ResourceReferences *[]ResourceReferenceChoice `json:"resourceReferences,omitempty" xml:"resourceReferences>resourceReference,omitempty"` + Type TaskTriggerType `json:"type,omitempty" xml:"type,omitempty"` + Event *Event `json:"event,omitempty" xml:"event,omitempty"` + Conditions *[]TaskTriggerCondition `json:"conditions,omitempty" xml:"conditions>condition,omitempty"` + TimeActivated string `json:"timeActivated,omitempty" xml:"timeActivated,omitempty"` + Inputs *[]TaskInput `json:"inputs,omitempty" xml:"inputs>input,omitempty"` + Outputs *[]TaskOutput `json:"outputs,omitempty" xml:"outputs>output,omitempty"` + Properties *[]Property `json:"properties,omitempty" xml:"properties>property,omitempty"` +} + +type TaskTriggerCondition struct { + Description string `json:"description,omitempty" xml:"description,omitempty"` + Expression string `json:"expression,omitempty" xml:"expression,omitempty"` + Properties *[]Property `json:"properties,omitempty" xml:"properties>property,omitempty"` +} + +type TaskTriggerType string + +const ( + TaskTriggerTypeAPI TaskTriggerType = "api" + TaskTriggerTypeManual TaskTriggerType = "manual" + TaskTriggerTypeScheduled TaskTriggerType = "scheduled" + TaskTriggerTypeWebhook TaskTriggerType = "webhook" +) + +type TaskType string + +const ( + TaskTypeBuild TaskType = "build" + TaskTypeClean TaskType = "clean" + TaskTypeClone TaskType = "clone" + TaskTypeCopy TaskType = "copy" + TaskTypeDeliver TaskType = "deliver" + TaskTypeDeploy TaskType = "deploy" + TaskTypeLint TaskType = "lint" + TaskTypeMerge TaskType = "merge" + TaskTypeOther TaskType = "other" + TaskTypeRelease TaskType = "release" + TaskTypeScan TaskType = "scan" + TaskTypeTest TaskType = "test" +) + +type TaskWorkspace struct { + BOMRef string `json:"bom-ref,omitempty" xml:"bom-ref,attr,omitempty"` + UID string `json:"uid,omitempty" xml:"uid,omitempty"` + Name string `json:"name,omitempty" xml:"name,omitempty"` + Aliases *[]string `json:"aliases,omitempty" xml:"aliases>alias,omitempty"` + Description string `json:"description,omitempty" xml:"description,omitempty"` + ResourceReferences *[]ResourceReferenceChoice `json:"resourceReferences,omitempty" xml:"resourceReferences>resourceReference,omitempty"` + AccessMode TaskWorkspaceAccessMode `json:"accessMode,omitempty" xml:"accessMode,omitempty"` + MountPath string `json:"mountPath,omitempty" xml:"mountPath,omitempty"` + ManagedDataType string `json:"managedDataType,omitempty" xml:"managedDataType,omitempty"` + VolumeRequest string `json:"volumeRequest,omitempty" xml:"volumeRequest,omitempty"` + Volume *Volume `json:"volume,omitempty" xml:"volume,omitempty"` + Properties *[]Property `json:"properties,omitempty" xml:"properties>property,omitempty"` +} + +type TaskWorkspaceAccessMode string + +const ( + TaskWorkspaceAccessModeReadOnly TaskWorkspaceAccessMode = "read-only" + TaskWorkspaceAccessModeReadWrite TaskWorkspaceAccessMode = "read-write" + TaskWorkspaceAccessModeReadWriteOnce TaskWorkspaceAccessMode = "read-write-once" + TaskWorkspaceAccessModeWriteOnce TaskWorkspaceAccessMode = "write-once" + TaskWorkspaceAccessModeWriteOnly TaskWorkspaceAccessMode = "write-only" +) + +// Deprecated: Use Component or Service instead. type Tool struct { Vendor string `json:"vendor,omitempty" xml:"vendor,omitempty"` Name string `json:"name" xml:"name"` @@ -594,6 +976,38 @@ type Tool struct { ExternalReferences *[]ExternalReference `json:"externalReferences,omitempty" xml:"externalReferences>reference,omitempty"` } +// ToolsChoice represents a union of either Tools (deprecated as of CycloneDX v1.5), and Components or Services. +// +// Encoding or decoding a ToolsChoice with both options present will raise an error. +// When encoding to a SpecVersion lower than SpecVersion1_5, and Components or Services are set, +// they will be automatically converted to legacy Tools. +// +// It is strongly recommended to use Components and Services. However, when consuming BOMs, +// applications should still expect legacy Tools to be present, and handle them accordingly. +type ToolsChoice struct { + Tools *[]Tool `json:"-" xml:"-"` // Deprecated: Use Components and Services instead. + Components *[]Component `json:"-" xml:"-"` + Services *[]Service `json:"-" xml:"-"` +} + +type Volume struct { + UID string `json:"uid,omitempty" xml:"uid,omitempty"` + Name string `json:"name,omitempty" xml:"name,omitempty"` + Mode VolumeMode `json:"mode,omitempty" xml:"mode,omitempty"` + Path string `json:"path,omitempty" xml:"path,omitempty"` + SizeAllocated string `json:"sizeAllocated,omitempty" xml:"sizeAllocated,omitempty"` + Persistent *bool `json:"persistent,omitempty" xml:"persistent,omitempty"` + Remote *bool `json:"remote,omitempty" xml:"remote,omitempty"` + Properties *[]Property `json:"properties,omitempty" xml:"properties>property,omitempty"` +} + +type VolumeMode string + +const ( + VolumeModeBlock VolumeMode = "block" + VolumeModeFilesystem VolumeMode = "file-system" +) + type Vulnerability struct { BOMRef string `json:"bom-ref,omitempty" xml:"bom-ref,attr,omitempty"` ID string `json:"id" xml:"id"` @@ -604,12 +1018,15 @@ type Vulnerability struct { Description string `json:"description,omitempty" xml:"description,omitempty"` Detail string `json:"detail,omitempty" xml:"detail,omitempty"` Recommendation string `json:"recommendation,omitempty" xml:"recommendation,omitempty"` + Workaround string `json:"workaround,omitempty" xml:"workaround,omitempty"` + ProofOfConcept *ProofOfConcept `json:"proofOfConcept,omitempty" xml:"proofOfConcept,omitempty"` Advisories *[]Advisory `json:"advisories,omitempty" xml:"advisories>advisory,omitempty"` Created string `json:"created,omitempty" xml:"created,omitempty"` Published string `json:"published,omitempty" xml:"published,omitempty"` Updated string `json:"updated,omitempty" xml:"updated,omitempty"` + Rejected string `json:"rejected,omitempty" xml:"rejected,omitempty"` Credits *Credits `json:"credits,omitempty" xml:"credits,omitempty"` - Tools *[]Tool `json:"tools,omitempty" xml:"tools>tool,omitempty"` + Tools *ToolsChoice `json:"tools,omitempty" xml:"tools,omitempty"` Analysis *VulnerabilityAnalysis `json:"analysis,omitempty" xml:"analysis,omitempty"` Affects *[]Affects `json:"affects,omitempty" xml:"affects>target,omitempty"` Properties *[]Property `json:"properties,omitempty" xml:"properties>property,omitempty"` @@ -620,6 +1037,8 @@ type VulnerabilityAnalysis struct { Justification ImpactAnalysisJustification `json:"justification,omitempty" xml:"justification,omitempty"` Response *[]ImpactAnalysisResponse `json:"response,omitempty" xml:"responses>response,omitempty"` Detail string `json:"detail,omitempty" xml:"detail,omitempty"` + FirstIssued string `json:"firstIssued,omitempty" xml:"firstIssued,omitempty"` + LastUpdated string `json:"lastUpdated,omitempty" xml:"lastUpdated,omitempty"` } type VulnerabilityRating struct { @@ -643,3 +1062,23 @@ const ( VulnerabilityStatusAffected VulnerabilityStatus = "affected" VulnerabilityStatusNotAffected VulnerabilityStatus = "unaffected" ) + +type Workflow struct { + BOMRef string `json:"bom-ref,omitempty" xml:"bom-ref,attr,omitempty"` + UID string `json:"uid,omitempty" xml:"uid,omitempty"` + Name string `json:"name,omitempty" xml:"name,omitempty"` + Description string `json:"description,omitempty" xml:"description,omitempty"` + ResourceReferences *[]ResourceReferenceChoice `json:"resourceReferences,omitempty" xml:"resourceReferences>resourceReference,omitempty"` + Tasks *[]Task `json:"tasks,omitempty" xml:"tasks>task,omitempty"` + TaskDependencies *[]Dependency `json:"taskDependencies,omitempty" xml:"taskDependencies>dependency"` + TaskTypes *[]TaskType `json:"taskTypes,omitempty" xml:"taskTypes>taskType,omitempty"` + Trigger *TaskTrigger `json:"trigger,omitempty" xml:"trigger,omitempty"` + Steps *[]TaskStep `json:"steps,omitempty" xml:"steps>step,omitempty"` + Inputs *[]TaskInput `json:"inputs,omitempty" xml:"inputs>input,omitempty"` + Outputs *[]TaskOutput `json:"outputs,omitempty" xml:"outputs>output,omitempty"` + TimeStart string `json:"timeStart,omitempty" xml:"timeStart,omitempty"` + TimeEnd string `json:"timeEnd,omitempty" xml:"timeEnd,omitempty"` + Workspaces *[]TaskWorkspace `json:"workspaces,omitempty" xml:"workspaces>workspace,omitempty"` + RuntimeTopology *[]Dependency `json:"runtimeTopology,omitempty" xml:"runtimeTopology>dependency,omitempty"` + Properties *[]Property `json:"properties,omitempty" xml:"properties>property,omitempty"` +} diff --git a/vendor/github.com/CycloneDX/cyclonedx-go/cyclonedx_json.go b/vendor/github.com/CycloneDX/cyclonedx-go/cyclonedx_json.go index f5cc251f..15305108 100644 --- a/vendor/github.com/CycloneDX/cyclonedx-go/cyclonedx_json.go +++ b/vendor/github.com/CycloneDX/cyclonedx-go/cyclonedx_json.go @@ -19,8 +19,87 @@ package cyclonedx import ( "encoding/json" + "errors" + "fmt" ) +func (ev EnvironmentVariableChoice) MarshalJSON() ([]byte, error) { + if ev.Property != nil && *ev.Property != (Property{}) { + return json.Marshal(ev.Property) + } else if ev.Value != "" { + return json.Marshal(ev.Value) + } + + return []byte("{}"), nil +} + +func (ev *EnvironmentVariableChoice) UnmarshalJSON(bytes []byte) error { + var property Property + err := json.Unmarshal(bytes, &property) + if err != nil { + var ute *json.UnmarshalTypeError + if !errors.As(err, &ute) || ute.Value != "string" { + return err + } + } + + if property != (Property{}) { + ev.Property = &property + return nil + } + + var value string + err = json.Unmarshal(bytes, &value) + if err != nil { + var ute *json.UnmarshalTypeError + if !errors.As(err, &ute) || ute.Value != "object" { + return err + } + } + + ev.Value = value + return nil +} + +type mlDatasetChoiceRefJSON struct { + Ref string `json:"ref" xml:"-"` +} + +func (dc MLDatasetChoice) MarshalJSON() ([]byte, error) { + if dc.Ref != "" { + return json.Marshal(mlDatasetChoiceRefJSON{Ref: dc.Ref}) + } else if dc.ComponentData != nil { + return json.Marshal(dc.ComponentData) + } + + return []byte("{}"), nil +} + +func (dc *MLDatasetChoice) UnmarshalJSON(bytes []byte) error { + var refObj mlDatasetChoiceRefJSON + err := json.Unmarshal(bytes, &refObj) + if err != nil { + return err + } + + if refObj.Ref != "" { + dc.Ref = refObj.Ref + return nil + } + + var componentData ComponentData + err = json.Unmarshal(bytes, &componentData) + if err != nil { + return err + } + + if componentData != (ComponentData{}) { + dc.ComponentData = &componentData + } + + return nil +} + func (sv SpecVersion) MarshalJSON() ([]byte, error) { return json.Marshal(sv.String()) } @@ -52,6 +131,60 @@ func (sv *SpecVersion) UnmarshalJSON(bytes []byte) error { return nil } +type toolsChoiceJSON struct { + Components *[]Component `json:"components,omitempty" xml:"-"` + Services *[]Service `json:"services,omitempty" xml:"-"` +} + +func (tc ToolsChoice) MarshalJSON() ([]byte, error) { + if tc.Tools != nil && (tc.Components != nil || tc.Services != nil) { + return nil, fmt.Errorf("either a list of tools, or an object holding components and services can be used, but not both") + } + + if tc.Tools != nil { + return json.Marshal(tc.Tools) + } + + choiceJSON := toolsChoiceJSON{ + Components: tc.Components, + Services: tc.Services, + } + if choiceJSON.Components != nil || choiceJSON.Services != nil { + return json.Marshal(choiceJSON) + } + + return []byte(nil), nil +} + +func (tc *ToolsChoice) UnmarshalJSON(bytes []byte) error { + var choiceJSON toolsChoiceJSON + err := json.Unmarshal(bytes, &choiceJSON) + if err != nil { + var typeErr *json.UnmarshalTypeError + if !errors.As(err, &typeErr) || typeErr.Value != "array" { + return err + } + + var legacyTools []Tool + err = json.Unmarshal(bytes, &legacyTools) + if err != nil { + return err + } + + *tc = ToolsChoice{Tools: &legacyTools} + return nil + } + + if choiceJSON.Components != nil || choiceJSON.Services != nil { + *tc = ToolsChoice{ + Components: choiceJSON.Components, + Services: choiceJSON.Services, + } + } + + return nil +} + var jsonSchemas = map[SpecVersion]string{ SpecVersion1_0: "", SpecVersion1_1: "", diff --git a/vendor/github.com/CycloneDX/cyclonedx-go/cyclonedx_xml.go b/vendor/github.com/CycloneDX/cyclonedx-go/cyclonedx_xml.go index 4e038f21..32eb80c8 100644 --- a/vendor/github.com/CycloneDX/cyclonedx-go/cyclonedx_xml.go +++ b/vendor/github.com/CycloneDX/cyclonedx-go/cyclonedx_xml.go @@ -52,7 +52,7 @@ func (c *Copyright) UnmarshalXML(d *xml.Decoder, start xml.StartElement) error { if err := d.DecodeElement(&text, &start); err != nil { return err } - (*c).Text = text + c.Text = text return nil } @@ -97,6 +97,75 @@ func (d *Dependency) UnmarshalXML(dec *xml.Decoder, start xml.StartElement) erro return nil } +func (ev EnvironmentVariables) MarshalXML(e *xml.Encoder, start xml.StartElement) error { + if len(ev) == 0 { + return nil + } + + err := e.EncodeToken(start) + if err != nil { + return err + } + + for _, choice := range ev { + if choice.Property != nil && choice.Value != "" { + return fmt.Errorf("either property or value must be set, but not both") + } + + if choice.Property != nil { + err = e.EncodeElement(choice.Property, xml.StartElement{Name: xml.Name{Local: "environmentVar"}}) + if err != nil { + return err + } + } else if choice.Value != "" { + err = e.EncodeElement(choice.Value, xml.StartElement{Name: xml.Name{Local: "value"}}) + if err != nil { + return err + } + } + } + + return e.EncodeToken(start.End()) +} + +func (ev *EnvironmentVariables) UnmarshalXML(d *xml.Decoder, _ xml.StartElement) error { + envVars := make([]EnvironmentVariableChoice, 0) + + for { + token, err := d.Token() + if err != nil { + if errors.Is(err, io.EOF) { + break + } + return err + } + + switch tokenType := token.(type) { + case xml.StartElement: + if tokenType.Name.Local == "value" { + var value string + err = d.DecodeElement(&value, &tokenType) + if err != nil { + return err + } + envVars = append(envVars, EnvironmentVariableChoice{Value: value}) + } else if tokenType.Name.Local == "environmentVar" { + var property Property + err = d.DecodeElement(&property, &tokenType) + if err != nil { + return err + } + envVars = append(envVars, EnvironmentVariableChoice{Property: &property}) + } else { + return fmt.Errorf("unknown element: %s", tokenType.Name.Local) + } + } + } + + *ev = envVars + return nil +} + func (l Licenses) MarshalXML(e *xml.Encoder, start xml.StartElement) error { if len(l) == 0 { return nil @@ -161,6 +230,44 @@ func (l *Licenses) UnmarshalXML(d *xml.Decoder, _ xml.StartElement) error { return nil } +type mlDatasetChoiceRefXML struct { + Ref string `json:"-" xml:"ref"` +} + +type mlDatasetChoiceXML struct { + Ref string `json:"-" xml:"ref"` + ComponentData +} + +func (dc MLDatasetChoice) MarshalXML(e *xml.Encoder, start xml.StartElement) error { + if dc.Ref != "" { + return e.EncodeElement(mlDatasetChoiceRefXML{Ref: dc.Ref}, start) + } else if dc.ComponentData != nil { + return e.EncodeElement(dc.ComponentData, start) + } + + return nil +} + +func (dc *MLDatasetChoice) UnmarshalXML(d *xml.Decoder, start xml.StartElement) error { + var choice mlDatasetChoiceXML + err := d.DecodeElement(&choice, &start) + if err != nil { + return err + } + + if choice.Ref != "" { + dc.Ref = choice.Ref + return nil + } + + if choice.ComponentData != (ComponentData{}) { + dc.ComponentData = &choice.ComponentData + } + + return nil +} + func (sv SpecVersion) MarshalXML(e *xml.Encoder, start xml.StartElement) error { return e.EncodeElement(sv.String(), start) } @@ -192,6 +299,111 @@ func (sv *SpecVersion) UnmarshalXML(d *xml.Decoder, start xml.StartElement) erro return nil } +// toolsChoiceMarshalXML is a helper struct for marshalling ToolsChoice. +type toolsChoiceMarshalXML struct { + LegacyTools *[]Tool `json:"-" xml:"tool,omitempty"` + Components *[]Component `json:"-" xml:"components>component,omitempty"` + Services *[]Service `json:"-" xml:"services>service,omitempty"` +} + +// toolsChoiceUnmarshalXML is a helper struct for unmarshalling tools represented +// as components and / or services. It is intended to be used with the streaming XML API. +// +// <-- cursor should be here when unmarshalling this! +// +// foo +// +// +type toolsChoiceUnmarshalXML struct { + Components *[]Component `json:"-" xml:"component,omitempty"` + Services *[]Service `json:"-" xml:"service,omitempty"` +} + +func (tc ToolsChoice) MarshalXML(e *xml.Encoder, start xml.StartElement) error { + if tc.Tools != nil && (tc.Components != nil || tc.Services != nil) { + return fmt.Errorf("either a list of tools, or an object holding components and services can be used, but not both") + } + + if tc.Tools != nil { + return e.EncodeElement(toolsChoiceMarshalXML{LegacyTools: tc.Tools}, start) + } + + tools := toolsChoiceMarshalXML{ + Components: tc.Components, + Services: tc.Services, + } + if tools.Components != nil || tools.Services != nil { + return e.EncodeElement(tools, start) + } + + return nil +} + +func (tc *ToolsChoice) UnmarshalXML(d *xml.Decoder, _ xml.StartElement) error { + var components []Component + var services []Service + legacyTools := make([]Tool, 0) + + for { + token, err := d.Token() + if err != nil { + if errors.Is(err, io.EOF) { + break + } + return err + } + + switch tokenType := token.(type) { + case xml.StartElement: + if tokenType.Name.Local == "tool" { + var tool Tool + if err = d.DecodeElement(&tool, &tokenType); err != nil { + return err + } + legacyTools = append(legacyTools, tool) + } else if tokenType.Name.Local == "components" { + var foo toolsChoiceUnmarshalXML + if err = d.DecodeElement(&foo, &tokenType); err != nil { + return err + } + if foo.Components != nil { + components = *foo.Components + } + } else if tokenType.Name.Local == "services" { + var foo toolsChoiceUnmarshalXML + if err = d.DecodeElement(&foo, &tokenType); err != nil { + return err + } + if foo.Services != nil { + services = *foo.Services + } + } else { + return fmt.Errorf("unknown element: %s", tokenType.Name.Local) + } + } + } + + choice := ToolsChoice{} + if len(legacyTools) > 0 && (len(components) > 0 || len(services) > 0) { + return fmt.Errorf("either a list of tools, or an object holding components and services can be used, but not both") + } + if len(components) > 0 { + choice.Components = &components + } + if len(services) > 0 { + choice.Services = &services + } + if len(legacyTools) > 0 { + choice.Tools = &legacyTools + } + + if choice.Tools != nil || choice.Components != nil || choice.Services != nil { + *tc = choice + } + + return nil +} + var xmlNamespaces = map[SpecVersion]string{ SpecVersion1_0: "http://cyclonedx.org/schema/bom/1.0", SpecVersion1_1: "http://cyclonedx.org/schema/bom/1.1", diff --git a/vendor/github.com/anchore/fangs/.golangci.yaml b/vendor/github.com/anchore/fangs/.golangci.yaml index 343f5e85..e91be90d 100644 --- a/vendor/github.com/anchore/fangs/.golangci.yaml +++ b/vendor/github.com/anchore/fangs/.golangci.yaml @@ -12,7 +12,6 @@ linters: enable: - asciicheck - bodyclose - - depguard - dogsled - dupl - errcheck diff --git a/vendor/github.com/anchore/fangs/Makefile b/vendor/github.com/anchore/fangs/Makefile index ea4a04a3..eac3c81a 100644 --- a/vendor/github.com/anchore/fangs/Makefile +++ b/vendor/github.com/anchore/fangs/Makefile @@ -5,7 +5,7 @@ LINT_CMD := $(TEMP_DIR)/golangci-lint run --tests=false GOIMPORTS_CMD := $(TEMP_DIR)/gosimports -local github.com/anchore # Tool versions ################################# -GOLANGCILINT_VERSION := v1.52.1 +GOLANGCILINT_VERSION := v1.55.1 GOSIMPORTS_VERSION := v0.3.8 BOUNCER_VERSION := v0.4.0 diff --git a/vendor/github.com/anchore/fangs/README.md b/vendor/github.com/anchore/fangs/README.md index 1847cddf..41c23cc4 100644 --- a/vendor/github.com/anchore/fangs/README.md +++ b/vendor/github.com/anchore/fangs/README.md @@ -18,6 +18,7 @@ In order to use this library, a consumer will need to: * Define configuration structs * By default, use `mapstructure` struct tags (can be changed in the `Config`) * For embedded structs to be inline, these must use the nonstandard `,squash` option + * For embedded structs, the embedded type must exported if it is embedded via a pointer * Define Cobra commands * Add flags to Cobra using the `*Var*` flag variants * Call `config.Load` during command invocation diff --git a/vendor/github.com/anchore/fangs/field_describer.go b/vendor/github.com/anchore/fangs/field_describer.go index 3aa6a9d7..ca7ae445 100644 --- a/vendor/github.com/anchore/fangs/field_describer.go +++ b/vendor/github.com/anchore/fangs/field_describer.go @@ -69,7 +69,7 @@ func (d *directDescriber) GetDescription(v reflect.Value, _ reflect.StructField) func addFieldDescriptions(d FieldDescriptionSet, v reflect.Value) { t := v.Type() - for isPtr(t) { + for isPtr(t) && v.CanInterface() { o := v.Interface() if p, ok := o.(FieldDescriber); ok && !isPromotedMethod(o, "DescribeFields") { p.DescribeFields(d) @@ -84,7 +84,7 @@ func addFieldDescriptions(d FieldDescriptionSet, v reflect.Value) { for i := 0; i < v.NumField(); i++ { f := t.Field(i) - if !f.IsExported() { + if !includeField(f) { continue } v := v.Field(i) diff --git a/vendor/github.com/anchore/fangs/flags.go b/vendor/github.com/anchore/fangs/flags.go index 0a60efc8..ec06a89d 100644 --- a/vendor/github.com/anchore/fangs/flags.go +++ b/vendor/github.com/anchore/fangs/flags.go @@ -35,7 +35,7 @@ func addFlags(log logger.Logger, flags FlagSet, o any) { if isStruct(t) { for i := 0; i < t.NumField(); i++ { f := t.Field(i) - if !f.IsExported() { + if !includeField(f) { continue } v := v.Field(i) @@ -45,7 +45,9 @@ func addFlags(log logger.Logger, flags FlagSet, o any) { kind := v.Type().Elem().Kind() if v.IsNil() && kind == reflect.Struct { newV := reflect.New(v.Type().Elem()) - v.Set(newV) + if v.CanSet() { + v.Set(newV) + } } } else { v = v.Addr() diff --git a/vendor/github.com/anchore/fangs/load.go b/vendor/github.com/anchore/fangs/load.go index 204a9867..98d7f5bb 100644 --- a/vendor/github.com/anchore/fangs/load.go +++ b/vendor/github.com/anchore/fangs/load.go @@ -89,6 +89,8 @@ func loadConfig(cfg Config, flags flagRefs, configurations ...any) error { // configureViper loads the default configuration values into the viper instance, // before the config values are read and parsed. the value _must_ be a pointer but // may be a pointer to a pointer +// +//nolint:gocognit func configureViper(cfg Config, vpr *viper.Viper, v reflect.Value, flags flagRefs, path []string) { t := v.Type() if !isPtr(t) { @@ -128,7 +130,7 @@ func configureViper(cfg Config, vpr *viper.Viper, v reflect.Value, flags flagRef // for each field in the configuration struct, see if the field implements the defaultValueLoader interface and invoke it if it does for i := 0; i < t.NumField(); i++ { f := t.Field(i) - if !f.IsExported() { + if !includeField(f) { continue } @@ -152,6 +154,12 @@ func configureViper(cfg Config, vpr *viper.Viper, v reflect.Value, flags flagRef path = append(path, f.Name) } + if !v.IsValid() { + // v is an unitialized embedded struct pointer to an unexported type. + // This is considered private, and we won't be able to set any values on it. + // Skipping this to avoid a panic. + continue + } v := v.Field(i) t := f.Type @@ -159,7 +167,11 @@ func configureViper(cfg Config, vpr *viper.Viper, v reflect.Value, flags flagRef t = t.Elem() if isStruct(t) { newV := reflect.New(t) - v.Set(newV) + // v.CanSet can be false if we're trying to set a field on a struct + // embedded via pointer when the embedded struct is unexported + if v.CanSet() { + v.Set(newV) + } } } @@ -196,13 +208,14 @@ func postLoad(v reflect.Value) error { return nil } - obj := v.Interface() - if p, ok := obj.(PostLoader); ok && !isPromotedMethod(obj, "PostLoad") { - if err := p.PostLoad(); err != nil { - return err + if v.CanInterface() { + obj := v.Interface() + if p, ok := obj.(PostLoader); ok && !isPromotedMethod(obj, "PostLoad") { + if err := p.PostLoad(); err != nil { + return err + } } } - t = t.Elem() v = v.Elem() } @@ -225,7 +238,7 @@ func postLoadStruct(v reflect.Value) error { for i := 0; i < v.NumField(); i++ { f := t.Field(i) - if !f.IsExported() { + if !includeField(f) { continue } @@ -383,3 +396,9 @@ func isNotFoundErr(err error) bool { var notFound *viper.ConfigFileNotFoundError return err != nil && errors.As(err, ¬Found) } + +// includeField determines whether to include or skip a field when processing the application's nested configuration load. +// fields that are processed include: public/exported fields, embedded structs (not pointer private/unexported embedding) +func includeField(f reflect.StructField) bool { + return (f.Anonymous && !isPtr(f.Type)) || f.IsExported() +} diff --git a/vendor/github.com/anchore/fangs/summarize.go b/vendor/github.com/anchore/fangs/summarize.go index 1883a867..b7e93f5f 100644 --- a/vendor/github.com/anchore/fangs/summarize.go +++ b/vendor/github.com/anchore/fangs/summarize.go @@ -50,7 +50,7 @@ func summarize(cfg Config, descriptions DescriptionProvider, s *section, value r for i := 0; i < t.NumField(); i++ { f := t.Field(i) - if !f.IsExported() { + if !includeField(f) { continue } @@ -104,6 +104,7 @@ func summarize(cfg Config, descriptions DescriptionProvider, s *section, value r } // printVal prints a value in YAML format +// nolint:gocognit func printVal(cfg Config, value reflect.Value, indent string) string { buf := bytes.Buffer{} @@ -134,7 +135,7 @@ func printVal(cfg Config, value reflect.Value, indent string) string { case isStruct(t): for i := 0; i < t.NumField(); i++ { f := t.Field(i) - if !f.IsExported() { + if !includeField(f) { continue } @@ -168,6 +169,9 @@ func printVal(cfg Config, value reflect.Value, indent string) string { } case v.CanInterface(): + if v.Kind() == reflect.Ptr && v.IsNil() { + return "" + } v := v.Interface() switch v.(type) { case string: @@ -188,7 +192,15 @@ func base(v reflect.Value) (reflect.Value, reflect.Type) { for isPtr(t) { t = t.Elem() if v.IsNil() { - v = reflect.New(t) + newV := reflect.New(t) + // If the field we're looking at is nil, and is a pointer to a struct, + // change it to point to an empty instance of the struct, so that we can + // continue recursing on the config structure. However, if it's a nil pointer + // to a primitive type, leave it as nil so that we can tell later in the summary + // that it wasn't set. + if newV.Kind() == reflect.Struct { + v = newV + } } else { v = v.Elem() } @@ -292,8 +304,10 @@ func stringifySection(cfg Config, out *bytes.Buffer, s *section, indent string) out.WriteString(":") if s.value.IsValid() { - out.WriteString(" ") val := printVal(cfg, s.value, indent+" ") + if val != "" { + out.WriteString(" ") + } out.WriteString(val) } diff --git a/vendor/github.com/anchore/stereoscope/pkg/image/registry_credentials.go b/vendor/github.com/anchore/stereoscope/pkg/image/registry_credentials.go index d16a6e41..f7b92a3c 100644 --- a/vendor/github.com/anchore/stereoscope/pkg/image/registry_credentials.go +++ b/vendor/github.com/anchore/stereoscope/pkg/image/registry_credentials.go @@ -60,7 +60,8 @@ func (c RegistryCredentials) canBeUsedWithRegistry(registry string) bool { // it might be that the user has configured docker.io specifically in the credentials. // try again with the new host. The same can occur when asking for docker.io directly, containerd // will transform this to index.docker.io. - if strset.New("registry-1.docker.io", "index.docker.io", "docker.io").Has(registry) { + dockerAliases := strset.New("registry-1.docker.io", "index.docker.io", "docker.io") + if dockerAliases.Has(c.Authority) && dockerAliases.Has(registry) { // these are all the same in terms of auth return true } diff --git a/vendor/github.com/anchore/syft/internal/bus/helpers.go b/vendor/github.com/anchore/syft/internal/bus/helpers.go index b2c883eb..363d9754 100644 --- a/vendor/github.com/anchore/syft/internal/bus/helpers.go +++ b/vendor/github.com/anchore/syft/internal/bus/helpers.go @@ -2,10 +2,12 @@ package bus import ( "github.com/wagoodman/go-partybus" + "github.com/wagoodman/go-progress" "github.com/anchore/clio" "github.com/anchore/syft/internal/redact" "github.com/anchore/syft/syft/event" + "github.com/anchore/syft/syft/event/monitor" ) func Exit() { @@ -33,3 +35,18 @@ func Notify(message string) { Value: message, }) } + +func StartCatalogerTask(info monitor.GenericTask, size int64, initialStage string) *monitor.CatalogerTaskProgress { + t := &monitor.CatalogerTaskProgress{ + AtomicStage: progress.NewAtomicStage(initialStage), + Manual: progress.NewManual(size), + } + + Publish(partybus.Event{ + Type: event.CatalogerTaskStarted, + Source: info, + Value: progress.StagedProgressable(t), + }) + + return t +} diff --git a/vendor/github.com/anchore/syft/syft/cataloging/config.go b/vendor/github.com/anchore/syft/syft/cataloging/config.go index ba9b7e4a..d8e4f397 100644 --- a/vendor/github.com/anchore/syft/syft/cataloging/config.go +++ b/vendor/github.com/anchore/syft/syft/cataloging/config.go @@ -4,3 +4,10 @@ type ArchiveSearchConfig struct { IncludeIndexedArchives bool `yaml:"include-indexed-archives" json:"include-indexed-archives" mapstructure:"include-indexed-archives"` IncludeUnindexedArchives bool `yaml:"include-unindexed-archives" json:"include-unindexed-archives" mapstructure:"include-unindexed-archives"` } + +func DefaultArchiveSearchConfig() ArchiveSearchConfig { + return ArchiveSearchConfig{ + IncludeIndexedArchives: true, + IncludeUnindexedArchives: false, + } +} diff --git a/vendor/github.com/anchore/syft/syft/event/event.go b/vendor/github.com/anchore/syft/syft/event/event.go index b18ff9de..6c760af6 100644 --- a/vendor/github.com/anchore/syft/syft/event/event.go +++ b/vendor/github.com/anchore/syft/syft/event/event.go @@ -14,15 +14,6 @@ const ( // Events from the syft library - // PackageCatalogerStarted is a partybus event that occurs when the package cataloging has begun - PackageCatalogerStarted partybus.EventType = typePrefix + "-package-cataloger-started-event" - - // FileMetadataCatalogerStarted is a partybus event that occurs when the file metadata cataloging has begun - FileMetadataCatalogerStarted partybus.EventType = typePrefix + "-file-metadata-cataloger-started-event" - - // FileDigestsCatalogerStarted is a partybus event that occurs when the file digests cataloging has begun - FileDigestsCatalogerStarted partybus.EventType = typePrefix + "-file-digests-cataloger-started-event" - // FileIndexingStarted is a partybus event that occurs when the directory resolver begins indexing a filesystem FileIndexingStarted partybus.EventType = typePrefix + "-file-indexing-started-event" diff --git a/vendor/github.com/anchore/syft/syft/event/monitor/cataloger_task.go b/vendor/github.com/anchore/syft/syft/event/monitor/cataloger_task.go deleted file mode 100644 index 4a06132e..00000000 --- a/vendor/github.com/anchore/syft/syft/event/monitor/cataloger_task.go +++ /dev/null @@ -1,55 +0,0 @@ -package monitor - -import ( - "github.com/wagoodman/go-partybus" - "github.com/wagoodman/go-progress" - - "github.com/anchore/syft/internal/bus" - "github.com/anchore/syft/syft/event" -) - -// TODO: this should be refactored to support read-only/write-only access using idioms of the progress lib - -type CatalogerTask struct { - prog *progress.Manual - // Title - Title string - // TitleOnCompletion a string to use as title when completed - TitleOnCompletion string - // SubStatus indicates this progress should be rendered as a sub-item - SubStatus bool - // RemoveOnCompletion indicates this progress line will be removed when completed - RemoveOnCompletion bool - // value is the value to display -- not public as SetValue needs to be called to initialize this progress - value string -} - -func (e *CatalogerTask) init() { - e.prog = progress.NewManual(-1) - - bus.Publish(partybus.Event{ - Type: event.CatalogerTaskStarted, - Source: e, - }) -} - -func (e *CatalogerTask) SetCompleted() { - if e.prog != nil { - e.prog.SetCompleted() - } -} - -func (e *CatalogerTask) SetValue(value string) { - if e.prog == nil { - e.init() - } - e.value = value -} - -func (e *CatalogerTask) GetValue() string { - return e.value -} - -func (e *CatalogerTask) GetMonitor() *progress.Manual { - return e.prog -} diff --git a/vendor/github.com/anchore/syft/syft/event/monitor/cataloger_task_progress.go b/vendor/github.com/anchore/syft/syft/event/monitor/cataloger_task_progress.go new file mode 100644 index 00000000..6f459c8e --- /dev/null +++ b/vendor/github.com/anchore/syft/syft/event/monitor/cataloger_task_progress.go @@ -0,0 +1,10 @@ +package monitor + +import ( + "github.com/wagoodman/go-progress" +) + +type CatalogerTaskProgress struct { + *progress.AtomicStage + *progress.Manual +} diff --git a/vendor/github.com/anchore/syft/syft/event/monitor/generic_task.go b/vendor/github.com/anchore/syft/syft/event/monitor/generic_task.go index cf5a6ea6..b4ed48d2 100644 --- a/vendor/github.com/anchore/syft/syft/event/monitor/generic_task.go +++ b/vendor/github.com/anchore/syft/syft/event/monitor/generic_task.go @@ -18,6 +18,19 @@ type Title struct { } type GenericTask struct { - Title Title - Context string + + // required fields + + Title Title + + // optional format fields + + HideOnSuccess bool + HideStageOnSuccess bool + + // optional fields + + ID string + ParentID string + Context string } diff --git a/vendor/github.com/anchore/syft/syft/format/common/cyclonedxhelpers/decoder.go b/vendor/github.com/anchore/syft/syft/format/common/cyclonedxhelpers/decoder.go index 37de22a9..6af03df1 100644 --- a/vendor/github.com/anchore/syft/syft/format/common/cyclonedxhelpers/decoder.go +++ b/vendor/github.com/anchore/syft/syft/format/common/cyclonedxhelpers/decoder.go @@ -249,9 +249,22 @@ func extractDescriptor(meta *cyclonedx.Metadata) (desc sbom.Descriptor) { return } - for _, t := range *meta.Tools { - desc.Name = t.Name - desc.Version = t.Version + // handle 1.5 component element + if meta.Tools.Components != nil { + for _, t := range *meta.Tools.Components { + desc.Name = t.Name + desc.Version = t.Version + return + } + } + + // handle pre-1.5 tool element + if meta.Tools.Tools != nil { + for _, t := range *meta.Tools.Tools { + desc.Name = t.Name + desc.Version = t.Version + return + } } return diff --git a/vendor/github.com/anchore/syft/syft/format/common/cyclonedxhelpers/format.go b/vendor/github.com/anchore/syft/syft/format/common/cyclonedxhelpers/format.go index b5d96487..548a65c2 100644 --- a/vendor/github.com/anchore/syft/syft/format/common/cyclonedxhelpers/format.go +++ b/vendor/github.com/anchore/syft/syft/format/common/cyclonedxhelpers/format.go @@ -114,11 +114,14 @@ func formatCPE(cpeString string) string { func toBomDescriptor(name, version string, srcMetadata source.Description) *cyclonedx.Metadata { return &cyclonedx.Metadata{ Timestamp: time.Now().Format(time.RFC3339), - Tools: &[]cyclonedx.Tool{ - { - Vendor: "anchore", - Name: name, - Version: version, + Tools: &cyclonedx.ToolsChoice{ + Components: &[]cyclonedx.Component{ + { + Type: cyclonedx.ComponentTypeApplication, + Author: "anchore", + Name: name, + Version: version, + }, }, }, Properties: toBomProperties(srcMetadata), diff --git a/vendor/github.com/anchore/syft/syft/pkg/cataloger/binary/default_classifiers.go b/vendor/github.com/anchore/syft/syft/pkg/cataloger/binary/default_classifiers.go index 88e16454..e3ecd58b 100644 --- a/vendor/github.com/anchore/syft/syft/pkg/cataloger/binary/default_classifiers.go +++ b/vendor/github.com/anchore/syft/syft/pkg/cataloger/binary/default_classifiers.go @@ -46,6 +46,15 @@ var defaultClassifiers = []classifier{ PURL: mustPURL("pkg:generic/go@version"), CPEs: singleCPE("cpe:2.3:a:golang:go:*:*:*:*:*:*:*:*"), }, + { + Class: "julia-binary", + FileGlob: "**/libjulia-internal.so", + EvidenceMatcher: fileContentsVersionMatcher( + `(?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:*:*:*:*:*:*:*:*"), + }, { Class: "helm", FileGlob: "**/helm", @@ -172,6 +181,15 @@ var defaultClassifiers = []classifier{ PURL: mustPURL("pkg:generic/php@version"), CPEs: singleCPE("cpe:2.3:a:php:php:*:*:*:*:*:*:*:*"), }, + { + Class: "php-composer-binary", + FileGlob: "**/composer*", + EvidenceMatcher: fileContentsVersionMatcher( + `(?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:*:*:*:*:*:*:*:*"), + }, { Class: "httpd-binary", FileGlob: "**/httpd", @@ -265,6 +283,17 @@ var defaultClassifiers = []classifier{ PURL: mustPURL("pkg:generic/ruby@version"), CPEs: singleCPE("cpe:2.3:a:ruby-lang:ruby:*:*:*:*:*:*:*:*"), }, + { + Class: "erlang-binary", + FileGlob: "**/erlexec", + EvidenceMatcher: fileContentsVersionMatcher( + // [NUL]/usr/local/src/otp-25.3.2.7/erts/ + `(?m)\\x00/usr/local/src/otp-(?P[0-9]+\.[0-9]+\.[0-9]+\.[0-9]+?)/erts/`, + ), + Package: "erlang", + PURL: mustPURL("pkg:generic/erlang@version"), + CPEs: singleCPE("cpe:2.3:a:erlang:erlang\\/otp:*:*:*:*:*:*:*:*"), + }, { Class: "consul-binary", FileGlob: "**/consul", diff --git a/vendor/github.com/anchore/syft/syft/pkg/cataloger/catalog.go b/vendor/github.com/anchore/syft/syft/pkg/cataloger/catalog.go index 840ea72b..e8784034 100644 --- a/vendor/github.com/anchore/syft/syft/pkg/cataloger/catalog.go +++ b/vendor/github.com/anchore/syft/syft/pkg/cataloger/catalog.go @@ -6,14 +6,14 @@ import ( "runtime/debug" "sync" + "github.com/dustin/go-humanize" "github.com/hashicorp/go-multierror" - "github.com/wagoodman/go-partybus" "github.com/wagoodman/go-progress" "github.com/anchore/syft/internal/bus" "github.com/anchore/syft/internal/log" "github.com/anchore/syft/syft/artifact" - "github.com/anchore/syft/syft/event" + "github.com/anchore/syft/syft/event/monitor" "github.com/anchore/syft/syft/file" "github.com/anchore/syft/syft/linux" "github.com/anchore/syft/syft/pkg" @@ -35,21 +35,6 @@ type catalogResult struct { Error error } -// newMonitor creates a new Monitor object and publishes the object on the bus as a PackageCatalogerStarted event. -func newMonitor() (*progress.Manual, *progress.Manual) { - filesProcessed := progress.Manual{} - packagesDiscovered := progress.Manual{} - - bus.Publish(partybus.Event{ - Type: event.PackageCatalogerStarted, - Value: Monitor{ - FilesProcessed: progress.Monitorable(&filesProcessed), - PackagesDiscovered: progress.Monitorable(&packagesDiscovered), - }, - }) - return &filesProcessed, &packagesDiscovered -} - func runCataloger(cataloger pkg.Cataloger, resolver file.Resolver) (catalogerResult *catalogResult, err error) { // handle individual cataloger panics defer func() { @@ -101,6 +86,7 @@ func runCataloger(cataloger pkg.Cataloger, resolver file.Resolver) (catalogerRes } catalogerResult.Packages = append(catalogerResult.Packages, p) } + catalogerResult.Relationships = append(catalogerResult.Relationships, relationships...) log.WithFields("cataloger", cataloger.Name()).Trace("cataloging complete") return catalogerResult, err @@ -116,9 +102,7 @@ func Catalog(resolver file.Resolver, _ *linux.Release, parallelism int, cataloge catalog := pkg.NewCollection() var allRelationships []artifact.Relationship - filesProcessed, packagesDiscovered := newMonitor() - defer filesProcessed.SetCompleted() - defer packagesDiscovered.SetCompleted() + prog := monitorPackageCatalogingTask() // perform analysis, accumulating errors for each failed analysis var errs error @@ -131,10 +115,11 @@ func Catalog(resolver file.Resolver, _ *linux.Release, parallelism int, cataloge jobs := make(chan pkg.Cataloger, nCatalogers) results := make(chan *catalogResult, nCatalogers) - discoveredPackages := make(chan int64, nCatalogers) waitGroup := sync.WaitGroup{} + var totalPackagesDiscovered int64 + for i := 0; i < parallelism; i++ { waitGroup.Add(1) @@ -148,20 +133,16 @@ func Catalog(resolver file.Resolver, _ *linux.Release, parallelism int, cataloge // ensure we set the error to be aggregated result.Error = err - discoveredPackages <- result.Discovered + prog.Add(result.Discovered) + totalPackagesDiscovered += result.Discovered + count := humanize.Comma(totalPackagesDiscovered) + prog.AtomicStage.Set(fmt.Sprintf("%s packages", count)) results <- result } }() } - // dynamically show updated discovered package status - go func() { - for discovered := range discoveredPackages { - packagesDiscovered.Add(discovered) - } - }() - // Enqueue the jobs for _, cataloger := range catalogers { jobs <- cataloger @@ -171,7 +152,6 @@ func Catalog(resolver file.Resolver, _ *linux.Release, parallelism int, cataloge // Wait for the jobs to finish waitGroup.Wait() close(results) - close(discoveredPackages) // collect the results for result := range results { @@ -186,6 +166,12 @@ func Catalog(resolver file.Resolver, _ *linux.Release, parallelism int, cataloge allRelationships = append(allRelationships, pkg.NewRelationships(catalog)...) + if errs != nil { + prog.SetError(errs) + } else { + prog.SetCompleted() + } + return catalog, allRelationships, errs } @@ -228,3 +214,16 @@ func packageFileOwnershipRelationships(p pkg.Package, resolver file.PathResolver } return relationships, nil } + +func monitorPackageCatalogingTask() *monitor.CatalogerTaskProgress { + info := monitor.GenericTask{ + Title: monitor.Title{ + Default: "Catalog packages", + WhileRunning: "Cataloging packages", + OnSuccess: "Cataloged packages", + }, + HideOnSuccess: false, + } + + return bus.StartCatalogerTask(info, -1, "") +} diff --git a/vendor/github.com/anchore/syft/syft/pkg/cataloger/cataloger.go b/vendor/github.com/anchore/syft/syft/pkg/cataloger/cataloger.go index a66a0569..ca3d4086 100644 --- a/vendor/github.com/anchore/syft/syft/pkg/cataloger/cataloger.go +++ b/vendor/github.com/anchore/syft/syft/pkg/cataloger/cataloger.go @@ -83,9 +83,9 @@ func DirectoryCatalogers(cfg Config) []pkg.Cataloger { haskell.NewHackageCataloger(), java.NewArchiveCataloger(cfg.JavaConfig()), java.NewGradleLockfileCataloger(), - java.NewPomCataloger(), + java.NewPomCataloger(cfg.JavaConfig()), java.NewNativeImageCataloger(), - javascript.NewLockCataloger(), + javascript.NewLockCataloger(cfg.Javascript), nix.NewStoreCataloger(), php.NewComposerLockCataloger(), gentoo.NewPortageCataloger(), @@ -122,9 +122,9 @@ func AllCatalogers(cfg Config) []pkg.Cataloger { haskell.NewHackageCataloger(), java.NewArchiveCataloger(cfg.JavaConfig()), java.NewGradleLockfileCataloger(), - java.NewPomCataloger(), + java.NewPomCataloger(cfg.JavaConfig()), java.NewNativeImageCataloger(), - javascript.NewLockCataloger(), + javascript.NewLockCataloger(cfg.Javascript), javascript.NewPackageCataloger(), kernel.NewLinuxKernelCataloger(cfg.LinuxKernel), nix.NewStoreCataloger(), diff --git a/vendor/github.com/anchore/syft/syft/pkg/cataloger/common/cpe/dictionary/data/cpe-index.json b/vendor/github.com/anchore/syft/syft/pkg/cataloger/common/cpe/dictionary/data/cpe-index.json index e9eee86f..bec345ac 100644 --- a/vendor/github.com/anchore/syft/syft/pkg/cataloger/common/cpe/dictionary/data/cpe-index.json +++ b/vendor/github.com/anchore/syft/syft/pkg/cataloger/common/cpe/dictionary/data/cpe-index.json @@ -115,6 +115,7 @@ "google-kubernetes-engine": "cpe:2.3:a:jenkins:google_kubernetes_engine:*:*:*:*:*:jenkins:*:*", "google-oauth": "cpe:2.3:a:jenkins:google_oauth_credentials:*:*:*:*:*:jenkins:*:*", "google-play-android-publisher": "cpe:2.3:a:jenkins:google-play-android-publisher:*:*:*:*:*:jenkins:*:*", + "gradle": "cpe:2.3:a:jenkins:gradle:*:*:*:*:*:jenkins:*:*", "groovy": "cpe:2.3:a:jenkins:groovy:*:*:*:*:*:jenkins:*:*", "harvest": "cpe:2.3:a:jenkins:harvest_scm:*:*:*:*:*:jenkins:*:*", "hipchat": "cpe:2.3:a:atlassian:hipchat:*:*:*:*:*:jenkins:*:*", @@ -288,6 +289,7 @@ "@awsui/components-react": "cpe:2.3:a:amazon:awsui\\/components-react:*:*:*:*:*:node.js:*:*", "@azure/ms-rest-nodeauth": "cpe:2.3:a:microsoft:ms-rest-nodeauth:*:*:*:*:*:node.js:*:*", "@backstage/plugin-auth-backend": "cpe:2.3:a:linuxfoundation:auth_backend:*:*:*:*:*:node.js:*:*", + "@evershop/evershop": "cpe:2.3:a:evershop:evershop:*:*:*:*:*:node.js:*:*", "@fastly/js-compute": "cpe:2.3:a:fastly:js-compute:*:*:*:*:*:node.js:*:*", "@firebase/util": "cpe:2.3:a:google:firebase\\/util:*:*:*:*:*:node.js:*:*", "@github/paste-markdown": "cpe:2.3:a:paste-markdown_project:paste-markdown:*:*:*:*:*:node.js:*:*", @@ -295,9 +297,11 @@ "@nuxt/devalue": "cpe:2.3:a:nuxtjs:\\@nuxt\\/devalue:*:*:*:*:*:node.js:*:*", "@progfay/scrapbox-parser": "cpe:2.3:a:scrapbox-parser_project:scrapbox-parser:*:*:*:*:*:node.js:*:*", "@rkesters/gnuplot": "cpe:2.3:a:gnuplot_project:gnuplot:*:*:*:*:*:node.js:*:*", + "@sap/xssec": "cpe:2.3:a:sap:\\@sap\\/xssec:*:*:*:*:*:node.js:*:*", "@solana/pay": "cpe:2.3:a:solanalabs:pay:*:*:*:*:*:*:*:*", "@strikeentco/set": "cpe:2.3:a:set_project:set:*:*:*:*:*:node.js:*:*", "@thi.ng/egf": "cpe:2.3:a:\\@thi.ng\\/egf_project:\\@thi.ng\\/egf:*:*:*:*:*:node.js:*:*", + "@vue/devtools": "cpe:2.3:a:vuejs:devtools:*:*:*:*:*:node.js:*:*", "@zxcvbn-ts/core": "cpe:2.3:a:zxcvbn-ts_project:zxcvbn-ts:*:*:*:*:*:node.js:*:*", "Proto": "cpe:2.3:a:proto_project:proto:*:*:*:*:*:node.js:*:*", "Templ8": "cpe:2.3:a:templ8_project:templ8:*:*:*:*:*:node.js:*:*", @@ -389,6 +393,7 @@ "conf-cfg-ini": "cpe:2.3:a:conf-cfg-ini_project:conf-cfg-ini:*:*:*:*:*:node.js:*:*", "confinit": "cpe:2.3:a:confinit_project:confinit:*:*:*:*:*:node.js:*:*", "confucious": "cpe:2.3:a:realseriousgames:confucious:*:*:*:*:*:node.js:*:*", + "connect-multiparty": "cpe:2.3:a:connect-multiparty_project:connect-multiparty:*:*:*:*:*:*:*:*", "connect-pg-simple": "cpe:2.3:a:connect-pg-simple_project:connect-pg-simple:*:*:*:*:*:node.js:*:*", "connection-tester": "cpe:2.3:a:connection-tester_project:connection-tester:*:*:*:*:*:node.js:*:*", "console-io": "cpe:2.3:a:console-io_project:console-io:*:*:*:*:*:node.js:*:*", @@ -1084,11 +1089,15 @@ "reqmgr2": "cpe:2.3:a:reqmgr2_project:reqmgr2:*:*:*:*:*:python:*:*", "reqmon": "cpe:2.3:a:reqmon_project:reqmon:*:*:*:*:*:python:*:*", "requests-xml": "cpe:2.3:a:requests-xml_project:requests-xml:*:*:*:*:*:python:*:*", + "rondolu-yt-concate": "cpe:2.3:a:rondolu-yt-concate_project:rondolu-yt-concate:*:*:*:*:*:pypi:*:*", "rope": "cpe:2.3:a:rope_project:rope:*:*:*:*:*:python:*:*", "rply": "cpe:2.3:a:rply_project:rply:*:*:*:*:*:*:*:*", "rsa": "cpe:2.3:a:python:rsa:*:*:*:*:*:python:*:*", "ruamel.yaml": "cpe:2.3:a:ruamel.yaml_project:ruamel.yaml:*:*:*:*:*:*:*:*", + "sap-xssec": "cpe:2.3:a:sap:sap-xssec:*:*:*:*:*:python:*:*", + "scoptrial": "cpe:2.3:a:scoptrial_project:scoptrial:*:*:*:*:*:pypi:*:*", "simiki": "cpe:2.3:a:simiki_project:simiki:*:*:*:*:*:*:*:*", + "sixfab-power-python-api": "cpe:2.3:a:sixfab-tool_project:sixfab-tool:*:*:*:*:*:pypi:*:*", "slashify": "cpe:2.3:a:google:slashify:*:*:*:*:*:node.js:*:*", "sopel-plugins.channelmgnt": "cpe:2.3:a:mirahezebots:channelmgnt:*:*:*:*:*:sopel:*:*", "spacy": "cpe:2.3:a:explosion:spacy:*:*:*:*:*:python:*:*", @@ -1219,6 +1228,7 @@ "bzip2": "cpe:2.3:a:bzip2_project:bzip2:*:*:*:*:*:rust:*:*", "cache": "cpe:2.3:a:cache_project:cache:*:*:*:*:*:rust:*:*", "cached": "cpe:2.3:a:cached_project:cached:*:*:*:*:*:rust:*:*", + "candid": "cpe:2.3:a:dfinity:candid:*:*:*:*:*:rust:*:*", "cbox": "cpe:2.3:a:cbox_project:cbox:*:*:*:*:*:rust:*:*", "ckb": "cpe:2.3:a:nervos:ckb:*:*:*:*:*:rust:*:*", "conduit-hyper": "cpe:2.3:a:conduit-hyper_project:conduit-hyper:*:*:*:*:*:rust:*:*", diff --git a/vendor/github.com/anchore/syft/syft/pkg/cataloger/common/cpe/java.go b/vendor/github.com/anchore/syft/syft/pkg/cataloger/common/cpe/java.go index 7920e38b..feb3960a 100644 --- a/vendor/github.com/anchore/syft/syft/pkg/cataloger/common/cpe/java.go +++ b/vendor/github.com/anchore/syft/syft/pkg/cataloger/common/cpe/java.go @@ -294,7 +294,7 @@ func GetManifestFieldGroupIDs(manifest *pkg.JavaManifest, fields []string) (grou } func cleanGroupID(groupID string) string { - return strings.TrimSpace(removeOSCIDirectives(groupID)) + return strings.TrimSpace(strings.Split(removeOSCIDirectives(groupID), "#")[0]) } func removeOSCIDirectives(groupID string) string { diff --git a/vendor/github.com/anchore/syft/syft/pkg/cataloger/common/cpe/java_groupid_map.go b/vendor/github.com/anchore/syft/syft/pkg/cataloger/common/cpe/java_groupid_map.go index 2b4c55ac..09c57f23 100644 --- a/vendor/github.com/anchore/syft/syft/pkg/cataloger/common/cpe/java_groupid_map.go +++ b/vendor/github.com/anchore/syft/syft/pkg/cataloger/common/cpe/java_groupid_map.go @@ -1,269 +1,488 @@ package cpe var DefaultArtifactIDToGroupID = map[string]string{ - "ant": "org.apache.ant", - "ant-antlr": "org.apache.ant", - "ant-antunit": "org.apache.ant", - "ant-apache-bcel": "org.apache.ant", - "ant-apache-bsf": "org.apache.ant", - "ant-apache-log4j": "org.apache.ant", - "ant-apache-oro": "org.apache.ant", - "ant-apache-regexp": "org.apache.ant", - "ant-apache-resolver": "org.apache.ant", - "ant-apache-xalan2": "org.apache.ant", - "ant-commons-logging": "org.apache.ant", - "ant-commons-net": "org.apache.ant", - "ant-compress": "org.apache.ant", - "ant-dotnet": "org.apache.ant", - "ant-imageio": "org.apache.ant", - "ant-jai": "org.apache.ant", - "ant-jakartamail": "org.apache.ant", - "ant-javamail": "org.apache.ant", - "ant-jdepend": "org.apache.ant", - "ant-jmf": "org.apache.ant", - "ant-jsch": "org.apache.ant", - "ant-junit": "org.apache.ant", - "ant-junit4": "org.apache.ant", - "ant-junitlauncher": "org.apache.ant", - "ant-launcher": "org.apache.ant", - "ant-netrexx": "org.apache.ant", - "ant-nodeps": "org.apache.ant", - "ant-parent": "org.apache.ant", - "ant-starteam": "org.apache.ant", - "ant-stylebook": "org.apache.ant", - "ant-swing": "org.apache.ant", - "ant-testutil": "org.apache.ant", - "ant-trax": "org.apache.ant", - "ant-weblogic": "org.apache.ant", - "ant-xz": "org.apache.ant", - "commons-codec": "commons-codec", - "commons-logging": "commons-logging", // see e.g. https://mvnrepository.com/artifact/commons-logging/commons-logging/1.1.1 - "okhttp": "com.squareup.okhttp3", - "okio": "com.squareup.okio", - "spring-velocity-support": "org.apache.velocity", - "velocity": "org.apache.velocity", - "velocity-engine-core": "org.apache.velocity", - "velocity-engine-parent": "org.apache.velocity", - "velocity-engine-scripting": "org.apache.velocity", - "velocity-tools": "org.apache.velocity", - "bc-fips": "org.bouncycastle", - "bc-fips-debug": "org.bouncycastle", - "bcjmail-debug-jdk15to18": "org.bouncycastle", - "bcjmail-debug-jdk18on": "org.bouncycastle", - "bcjmail-jdk15on": "org.bouncycastle", - "bcjmail-jdk15to18": "org.bouncycastle", - "bcjmail-jdk18on": "org.bouncycastle", - "bcjmail-lts8on": "org.bouncycastle", - "bcmail-debug-jdk15to18": "org.bouncycastle", - "bcmail-debug-jdk18on": "org.bouncycastle", - "bcmail-fips": "org.bouncycastle", - "bcmail-jdk14": "org.bouncycastle", - "bcmail-jdk15": "org.bouncycastle", - "bcmail-jdk15+": "org.bouncycastle", - "bcmail-jdk15on": "org.bouncycastle", - "bcmail-jdk15to18": "org.bouncycastle", - "bcmail-jdk16": "org.bouncycastle", - "bcmail-jdk18on": "org.bouncycastle", - "bcmail-lts8on": "org.bouncycastle", - "bcpg-debug-jdk15to18": "org.bouncycastle", - "bcpg-debug-jdk18on": "org.bouncycastle", - "bcpg-fips": "org.bouncycastle", - "bcpg-jdk12": "org.bouncycastle", - "bcpg-jdk14": "org.bouncycastle", - "bcpg-jdk15": "org.bouncycastle", - "bcpg-jdk15+": "org.bouncycastle", - "bcpg-jdk15on": "org.bouncycastle", - "bcpg-jdk15to18": "org.bouncycastle", - "bcpg-jdk16": "org.bouncycastle", - "bcpg-jdk18on": "org.bouncycastle", - "bcpg-lts8on": "org.bouncycastle", - "bcpkix-debug-jdk15to18": "org.bouncycastle", - "bcpkix-debug-jdk18on": "org.bouncycastle", - "bcpkix-fips": "org.bouncycastle", - "bcpkix-jdk14": "org.bouncycastle", - "bcpkix-jdk15on": "org.bouncycastle", - "bcpkix-jdk15to18": "org.bouncycastle", - "bcpkix-jdk18on": "org.bouncycastle", - "bcpkix-lts8on": "org.bouncycastle", - "bcpqc-addon-fips": "org.bouncycastle", - "bcprov-debug-jdk14": "org.bouncycastle", - "bcprov-debug-jdk15on": "org.bouncycastle", - "bcprov-debug-jdk15to18": "org.bouncycastle", - "bcprov-debug-jdk18on": "org.bouncycastle", - "bcprov-ext-debug-jdk14": "org.bouncycastle", - "bcprov-ext-debug-jdk15on": "org.bouncycastle", - "bcprov-ext-debug-jdk15to18": "org.bouncycastle", - "bcprov-ext-debug-jdk18on": "org.bouncycastle", - "bcprov-ext-jdk14": "org.bouncycastle", - "bcprov-ext-jdk15": "org.bouncycastle", - "bcprov-ext-jdk15on": "org.bouncycastle", - "bcprov-ext-jdk15to18": "org.bouncycastle", - "bcprov-ext-jdk16": "org.bouncycastle", - "bcprov-ext-jdk18on": "org.bouncycastle", - "bcprov-jdk12": "org.bouncycastle", - "bcprov-jdk14": "org.bouncycastle", - "bcprov-jdk15": "org.bouncycastle", - "bcprov-jdk15+": "org.bouncycastle", - "bcprov-jdk15on": "org.bouncycastle", - "bcprov-jdk15to18": "org.bouncycastle", - "bcprov-jdk16": "org.bouncycastle", - "bcprov-jdk18on": "org.bouncycastle", - "bcprov-lts8on": "org.bouncycastle", - "bctls-debug-jdk15to18": "org.bouncycastle", - "bctls-debug-jdk18on": "org.bouncycastle", - "bctls-fips": "org.bouncycastle", - "bctls-jdk14": "org.bouncycastle", - "bctls-jdk15on": "org.bouncycastle", - "bctls-jdk15to18": "org.bouncycastle", - "bctls-jdk18on": "org.bouncycastle", - "bctls-lts8on": "org.bouncycastle", - "bctsp-jdk14": "org.bouncycastle", - "bctsp-jdk15": "org.bouncycastle", - "bctsp-jdk15+": "org.bouncycastle", - "bctsp-jdk15on": "org.bouncycastle", - "bctsp-jdk16": "org.bouncycastle", - "bcutil-debug-jdk15to18": "org.bouncycastle", - "bcutil-debug-jdk18on": "org.bouncycastle", - "bcutil-jdk14": "org.bouncycastle", - "bcutil-jdk15on": "org.bouncycastle", - "bcutil-jdk15to18": "org.bouncycastle", - "bcutil-jdk18on": "org.bouncycastle", - "bcutil-lts8on": "org.bouncycastle", - "spring": "org.springframework", - "spring-agent": "org.springframework", - "spring-aop": "org.springframework", - "spring-asm": "org.springframework", - "spring-aspects": "org.springframework", - "spring-beandoc": "org.springframework", - "spring-beans": "org.springframework", - "spring-context": "org.springframework", - "spring-context-indexer": "org.springframework", - "spring-context-support": "org.springframework", - "spring-core": "org.springframework", - "spring-core-test": "org.springframework", - "spring-dao": "org.springframework", - "spring-expression": "org.springframework", - "spring-framework-bom": "org.springframework", - "spring-full": "org.springframework", - "spring-hibernate": "org.springframework", - "spring-hibernate2": "org.springframework", - "spring-hibernate3": "org.springframework", - "spring-ibatis": "org.springframework", - "spring-instrument": "org.springframework", - "spring-instrument-tomcat": "org.springframework", - "spring-jca": "org.springframework", - "spring-jcl": "org.springframework", - "spring-jdbc": "org.springframework", - "spring-jdo": "org.springframework", - "spring-jms": "org.springframework", - "spring-jmx": "org.springframework", - "spring-jpa": "org.springframework", - "spring-ldap": "org.springframework", - "spring-messaging": "org.springframework", - "spring-mock": "org.springframework", - "spring-ojb": "org.springframework", - "spring-orm": "org.springframework", - "spring-oxm": "org.springframework", - "spring-parent": "org.springframework", - "spring-portlet": "org.springframework", - "spring-r2dbc": "org.springframework", - "spring-remoting": "org.springframework", - "spring-struts": "org.springframework", - "spring-support": "org.springframework", - "spring-test": "org.springframework", - "spring-tomcat-weaver": "org.springframework", - "spring-toplink": "org.springframework", - "spring-tuple": "org.springframework", - "spring-tuple-parent": "org.springframework", - "spring-tx": "org.springframework", - "spring-web": "org.springframework", - "spring-webflux": "org.springframework", - "spring-webmvc": "org.springframework", - "spring-webmvc-portlet": "org.springframework", - "spring-webmvc-struts": "org.springframework", - "spring-websocket": "org.springframework", - "spring-amqp": "org.springframework.amqp", - "spring-amqp-bom": "org.springframework.amqp", - "spring-amqp-dist": "org.springframework.amqp", - "spring-amqp-parent": "org.springframework.amqp", - "spring-erlang": "org.springframework.amqp", - "spring-rabbit": "org.springframework.amqp", - "spring-rabbit-junit": "org.springframework.amqp", - "spring-rabbit-stream": "org.springframework.amqp", - "spring-rabbit-test": "org.springframework.amqp", - "spring-analytics": "org.springframework.analytics", - "spring-batch": "org.springframework.batch", - "spring-batch-admin-manager": "org.springframework.batch", - "spring-batch-admin-parent": "org.springframework.batch", - "spring-batch-admin-resources": "org.springframework.batch", - "spring-batch-archetypes": "org.springframework.batch", - "spring-batch-bom": "org.springframework.batch", - "spring-batch-core": "org.springframework.batch", - "spring-batch-docs": "org.springframework.batch", - "spring-batch-infrastructure": "org.springframework.batch", - "spring-batch-infrastructure-tests": "org.springframework.batch", - "spring-batch-integration": "org.springframework.batch", - "spring-batch-parent": "org.springframework.batch", - "spring-batch-samples": "org.springframework.batch", - "spring-batch-test": "org.springframework.batch", - "spring-batch-tuple": "org.springframework.batch", - "spring-boot": "org.springframework.boot", - "spring-boot-actuator": "org.springframework.boot", - "spring-boot-actuator-autoconfigure": "org.springframework.boot", - "spring-boot-actuator-docs": "org.springframework.boot", - "spring-boot-antlib": "org.springframework.boot", - "spring-boot-archetypes": "org.springframework.boot", - "spring-boot-autoconfigure": "org.springframework.boot", - "spring-boot-autoconfigure-processor": "org.springframework.boot", - "spring-boot-build": "org.springframework.boot", - "spring-boot-buildpack-platform": "org.springframework.boot", - "spring-boot-cli": "org.springframework.boot", - "spring-boot-configuration-metadata": "org.springframework.boot", - "spring-boot-configuration-processor": "org.springframework.boot", - "spring-boot-dependencies": "org.springframework.boot", - "spring-boot-dependency-tools": "org.springframework.boot", - "spring-boot-deployment-test-glassfish": "org.springframework.boot", - "spring-boot-deployment-test-tomcat": "org.springframework.boot", - "spring-boot-deployment-test-tomee": "org.springframework.boot", - "spring-boot-deployment-test-wildfly": "org.springframework.boot", - "spring-boot-deployment-test-wlp": "org.springframework.boot", - "spring-boot-deployment-tests": "org.springframework.boot", - "spring-boot-devtools": "org.springframework.boot", - "spring-boot-devtools-tests": "org.springframework.boot", - "spring-boot-docker-compose": "org.springframework.boot", - "spring-boot-docs": "org.springframework.boot", - "spring-boot-full-build": "org.springframework.boot", - "spring-boot-gradle-plugin": "org.springframework.boot", - "spring-boot-gradle-tests": "org.springframework.boot", - "spring-boot-jarmode-layertools": "org.springframework.boot", - "spring-boot-launch-script-tests": "org.springframework.boot", - "spring-boot-legacy": "org.springframework.boot", - "spring-boot-loader": "org.springframework.boot", - "spring-boot-loader-tools": "org.springframework.boot", - "spring-boot-maven-plugin": "org.springframework.boot", - "spring-boot-parent": "org.springframework.boot", - "spring-boot-project": "org.springframework.boot", - "spring-boot-properties-migrator": "org.springframework.boot", - "spring-boot-sample-actuator-archetype": "org.springframework.boot", - "spring-boot-sample-actuator-log4j-archetype": "org.springframework.boot", - "spring-boot-sample-actuator-noweb-archetype": "org.springframework.boot", - "spring-boot-sample-actuator-ui-archetype": "org.springframework.boot", - "spring-boot-sample-amqp-archetype": "org.springframework.boot", - "spring-boot-sample-aop-archetype": "org.springframework.boot", - "spring-boot-sample-batch-archetype": "org.springframework.boot", - "spring-boot-sample-data-jpa-archetype": "org.springframework.boot", - "spring-boot-sample-data-mongodb-archetype": "org.springframework.boot", - "spring-boot-sample-data-redis-archetype": "org.springframework.boot", - "spring-boot-sample-data-rest-archetype": "org.springframework.boot", - "spring-boot-sample-integration-archetype": "org.springframework.boot", - "spring-boot-sample-jetty-archetype": "org.springframework.boot", - "spring-boot-sample-profile-archetype": "org.springframework.boot", - "spring-boot-sample-secure-archetype": "org.springframework.boot", - "spring-boot-sample-servlet-archetype": "org.springframework.boot", - "spring-boot-sample-simple-archetype": "org.springframework.boot", - "spring-boot-sample-tomcat-archetype": "org.springframework.boot", - "spring-boot-sample-traditional-archetype": "org.springframework.boot", - "spring-boot-sample-web-jsp-archetype": "org.springframework.boot", + "ant": "org.apache.ant", + "ant-antlr": "org.apache.ant", + "ant-antunit": "org.apache.ant", + "ant-apache-bcel": "org.apache.ant", + "ant-apache-bsf": "org.apache.ant", + "ant-apache-log4j": "org.apache.ant", + "ant-apache-oro": "org.apache.ant", + "ant-apache-regexp": "org.apache.ant", + "ant-apache-resolver": "org.apache.ant", + "ant-apache-xalan2": "org.apache.ant", + "ant-commons-logging": "org.apache.ant", + "ant-commons-net": "org.apache.ant", + "ant-compress": "org.apache.ant", + "ant-dotnet": "org.apache.ant", + "ant-imageio": "org.apache.ant", + "ant-jai": "org.apache.ant", + "ant-jakartamail": "org.apache.ant", + "ant-javamail": "org.apache.ant", + "ant-jdepend": "org.apache.ant", + "ant-jmf": "org.apache.ant", + "ant-jsch": "org.apache.ant", + "ant-junit": "org.apache.ant", + "ant-junit4": "org.apache.ant", + "ant-junitlauncher": "org.apache.ant", + "ant-launcher": "org.apache.ant", + "ant-netrexx": "org.apache.ant", + "ant-nodeps": "org.apache.ant", + "ant-parent": "org.apache.ant", + "ant-starteam": "org.apache.ant", + "ant-stylebook": "org.apache.ant", + "ant-swing": "org.apache.ant", + "ant-testutil": "org.apache.ant", + "ant-trax": "org.apache.ant", + "ant-weblogic": "org.apache.ant", + "ant-xz": "org.apache.ant", + "commons-codec": "commons-codec", + "commons-logging": "commons-logging", // see e.g. https://mvnrepository.com/artifact/commons-logging/commons-logging/1.1.1 + "okhttp": "com.squareup.okhttp3", + "okio": "com.squareup.okio", + "cassandra-all": "org.apache.cassandra", + "cassandra-clientutil": "org.apache.cassandra", + "cassandra-javautils": "org.apache.cassandra", + "cassandra-parent": "org.apache.cassandra", + "cassandra-thrift": "org.apache.cassandra", + "apache-geode": "org.apache.geode", + "geode-all-bom": "org.apache.geode", + "geode-apis-compatible-with-redis": "org.apache.geode", + "geode-client-bom": "org.apache.geode", + "geode-client-protocol": "org.apache.geode", + "geode-common": "org.apache.geode", + "geode-concurrency-test": "org.apache.geode", + "geode-connectors": "org.apache.geode", + "geode-core": "org.apache.geode", + "geode-cq": "org.apache.geode", + "geode-deployment-legacy": "org.apache.geode", + "geode-dunit": "org.apache.geode", + "geode-experimental-driver": "org.apache.geode", + "geode-gfsh": "org.apache.geode", + "geode-http-service": "org.apache.geode", + "geode-jmh": "org.apache.geode", + "geode-joptsimple": "org.apache.geode", + "geode-json": "org.apache.geode", + "geode-junit": "org.apache.geode", + "geode-log4j": "org.apache.geode", + "geode-logging": "org.apache.geode", + "geode-lucene": "org.apache.geode", + "geode-management": "org.apache.geode", + "geode-membership": "org.apache.geode", + "geode-memcached": "org.apache.geode", + "geode-modules": "org.apache.geode", + "geode-modules-hibernate": "org.apache.geode", + "geode-modules-session": "org.apache.geode", + "geode-modules-session-internal": "org.apache.geode", + "geode-modules-tomcat7": "org.apache.geode", + "geode-modules-tomcat8": "org.apache.geode", + "geode-modules-tomcat9": "org.apache.geode", + "geode-old-client-support": "org.apache.geode", + "geode-protobuf": "org.apache.geode", + "geode-protobuf-messages": "org.apache.geode", + "geode-pulse": "org.apache.geode", + "geode-rebalancer": "org.apache.geode", + "geode-redis": "org.apache.geode", + "geode-serialization": "org.apache.geode", + "geode-server-all": "org.apache.geode", + "geode-tcp-server": "org.apache.geode", + "geode-unsafe": "org.apache.geode", + "geode-wan": "org.apache.geode", + "geode-web": "org.apache.geode", + "geode-web-api": "org.apache.geode", + "geode-web-management": "org.apache.geode", + "spring-velocity-support": "org.apache.velocity", + "velocity": "org.apache.velocity", + "velocity-engine-core": "org.apache.velocity", + "velocity-engine-parent": "org.apache.velocity", + "velocity-engine-scripting": "org.apache.velocity", + "velocity-tools": "org.apache.velocity", + "tapestry-TimeTracker": "org.apache.tapestry", + "tapestry-Vlib": "org.apache.tapestry", + "tapestry-VlibBeans": "org.apache.tapestry", + "tapestry-Workbench": "org.apache.tapestry", + "tapestry-annotations": "org.apache.tapestry", + "tapestry-archetype": "org.apache.tapestry", + "tapestry-beanvalidator": "org.apache.tapestry", + "tapestry-clojure": "org.apache.tapestry", + "tapestry-component-report": "org.apache.tapestry", + "tapestry-contrib": "org.apache.tapestry", + "tapestry-core": "org.apache.tapestry", + "tapestry-examples": "org.apache.tapestry", + "tapestry-framework": "org.apache.tapestry", + "tapestry-func": "org.apache.tapestry", + "tapestry-hibernate": "org.apache.tapestry", + "tapestry-hibernate-core": "org.apache.tapestry", + "tapestry-http": "org.apache.tapestry", + "tapestry-internal-test": "org.apache.tapestry", + "tapestry-ioc": "org.apache.tapestry", + "tapestry-ioc-jcache": "org.apache.tapestry", + "tapestry-ioc-junit": "org.apache.tapestry", + "tapestry-ioc-test": "org.apache.tapestry", + "tapestry-javadoc": "org.apache.tapestry", + "tapestry-jmx": "org.apache.tapestry", + "tapestry-jpa": "org.apache.tapestry", + "tapestry-json": "org.apache.tapestry", + "tapestry-kaptcha": "org.apache.tapestry", + "tapestry-mongodb": "org.apache.tapestry", + "tapestry-openapi-viewer": "org.apache.tapestry", + "tapestry-portlet": "org.apache.tapestry", + "tapestry-project": "org.apache.tapestry", + "tapestry-rest-jackson": "org.apache.tapestry", + "tapestry-runner": "org.apache.tapestry", + "tapestry-simple": "org.apache.tapestry", + "tapestry-site": "org.apache.tapestry", + "tapestry-spock": "org.apache.tapestry", + "tapestry-spring": "org.apache.tapestry", + "tapestry-test": "org.apache.tapestry", + "tapestry-test-constants": "org.apache.tapestry", + "tapestry-test-data": "org.apache.tapestry", + "tapestry-upload": "org.apache.tapestry", + "tapestry-version-migrator": "org.apache.tapestry", + "tapestry-webflow": "org.apache.tapestry", + "tapestry-webresources": "org.apache.tapestry", + "tapestry-yuicompressor": "org.apache.tapestry", + "tapestry5-annotations": "org.apache.tapestry", + "tomcat": "org.apache.tomcat", + "tomcat-annotations-api": "org.apache.tomcat", + "tomcat-api": "org.apache.tomcat", + "tomcat-catalina": "org.apache.tomcat", + "tomcat-catalina-ant": "org.apache.tomcat", + "tomcat-catalina-ha": "org.apache.tomcat", + "tomcat-catalina-jmx-remote": "org.apache.tomcat", + "tomcat-catalina-ws": "org.apache.tomcat", + "tomcat-coyote": "org.apache.tomcat", + "tomcat-dbcp": "org.apache.tomcat", + "tomcat-el-api": "org.apache.tomcat", + "tomcat-i18n-cs": "org.apache.tomcat", + "tomcat-i18n-de": "org.apache.tomcat", + "tomcat-i18n-es": "org.apache.tomcat", + "tomcat-i18n-fr": "org.apache.tomcat", + "tomcat-i18n-ja": "org.apache.tomcat", + "tomcat-i18n-ko": "org.apache.tomcat", + "tomcat-i18n-pt-BR": "org.apache.tomcat", + "tomcat-i18n-ru": "org.apache.tomcat", + "tomcat-i18n-zh-CN": "org.apache.tomcat", + "tomcat-jasper": "org.apache.tomcat", + "tomcat-jasper-el": "org.apache.tomcat", + "tomcat-jaspic-api": "org.apache.tomcat", + "tomcat-jdbc": "org.apache.tomcat", + "tomcat-jni": "org.apache.tomcat", + "tomcat-jsp-api": "org.apache.tomcat", + "tomcat-juli": "org.apache.tomcat", + "tomcat-servlet-api": "org.apache.tomcat", + "tomcat-spdy": "org.apache.tomcat", + "tomcat-ssi": "org.apache.tomcat", + "tomcat-storeconfig": "org.apache.tomcat", + "tomcat-tribes": "org.apache.tomcat", + "tomcat-util": "org.apache.tomcat", + "tomcat-util-scan": "org.apache.tomcat", + "tomcat-websocket": "org.apache.tomcat", + "tomcat-websocket-api": "org.apache.tomcat", + "tomcat-websocket-client-api": "org.apache.tomcat", + "tomcat7-websocket": "org.apache.tomcat", + "tomcat-embed-core": "org.apache.tomcat.embed", + "tomcat-embed-el": "org.apache.tomcat.embed", + "tomcat-embed-jasper": "org.apache.tomcat.embed", + "tomcat-embed-logging-juli": "org.apache.tomcat.embed", + "tomcat-embed-logging-log4j": "org.apache.tomcat.embed", + "tomcat-embed-websocket": "org.apache.tomcat.embed", + "bc-fips": "org.bouncycastle", + "bc-fips-debug": "org.bouncycastle", + "bcjmail-debug-jdk15to18": "org.bouncycastle", + "bcjmail-debug-jdk18on": "org.bouncycastle", + "bcjmail-jdk15on": "org.bouncycastle", + "bcjmail-jdk15to18": "org.bouncycastle", + "bcjmail-jdk18on": "org.bouncycastle", + "bcjmail-lts8on": "org.bouncycastle", + "bcmail-debug-jdk15to18": "org.bouncycastle", + "bcmail-debug-jdk18on": "org.bouncycastle", + "bcmail-fips": "org.bouncycastle", + "bcmail-jdk14": "org.bouncycastle", + "bcmail-jdk15": "org.bouncycastle", + "bcmail-jdk15+": "org.bouncycastle", + "bcmail-jdk15on": "org.bouncycastle", + "bcmail-jdk15to18": "org.bouncycastle", + "bcmail-jdk16": "org.bouncycastle", + "bcmail-jdk18on": "org.bouncycastle", + "bcmail-lts8on": "org.bouncycastle", + "bcpg-debug-jdk15to18": "org.bouncycastle", + "bcpg-debug-jdk18on": "org.bouncycastle", + "bcpg-fips": "org.bouncycastle", + "bcpg-jdk12": "org.bouncycastle", + "bcpg-jdk14": "org.bouncycastle", + "bcpg-jdk15": "org.bouncycastle", + "bcpg-jdk15+": "org.bouncycastle", + "bcpg-jdk15on": "org.bouncycastle", + "bcpg-jdk15to18": "org.bouncycastle", + "bcpg-jdk16": "org.bouncycastle", + "bcpg-jdk18on": "org.bouncycastle", + "bcpg-lts8on": "org.bouncycastle", + "bcpkix-debug-jdk15to18": "org.bouncycastle", + "bcpkix-debug-jdk18on": "org.bouncycastle", + "bcpkix-fips": "org.bouncycastle", + "bcpkix-jdk14": "org.bouncycastle", + "bcpkix-jdk15on": "org.bouncycastle", + "bcpkix-jdk15to18": "org.bouncycastle", + "bcpkix-jdk18on": "org.bouncycastle", + "bcpkix-lts8on": "org.bouncycastle", + "bcpqc-addon-fips": "org.bouncycastle", + "bcprov-debug-jdk14": "org.bouncycastle", + "bcprov-debug-jdk15on": "org.bouncycastle", + "bcprov-debug-jdk15to18": "org.bouncycastle", + "bcprov-debug-jdk18on": "org.bouncycastle", + "bcprov-ext-debug-jdk14": "org.bouncycastle", + "bcprov-ext-debug-jdk15on": "org.bouncycastle", + "bcprov-ext-debug-jdk15to18": "org.bouncycastle", + "bcprov-ext-debug-jdk18on": "org.bouncycastle", + "bcprov-ext-jdk14": "org.bouncycastle", + "bcprov-ext-jdk15": "org.bouncycastle", + "bcprov-ext-jdk15on": "org.bouncycastle", + "bcprov-ext-jdk15to18": "org.bouncycastle", + "bcprov-ext-jdk16": "org.bouncycastle", + "bcprov-ext-jdk18on": "org.bouncycastle", + "bcprov-jdk12": "org.bouncycastle", + "bcprov-jdk14": "org.bouncycastle", + "bcprov-jdk15": "org.bouncycastle", + "bcprov-jdk15+": "org.bouncycastle", + "bcprov-jdk15on": "org.bouncycastle", + "bcprov-jdk15to18": "org.bouncycastle", + "bcprov-jdk16": "org.bouncycastle", + "bcprov-jdk18on": "org.bouncycastle", + "bcprov-lts8on": "org.bouncycastle", + "bctls-debug-jdk15to18": "org.bouncycastle", + "bctls-debug-jdk18on": "org.bouncycastle", + "bctls-fips": "org.bouncycastle", + "bctls-jdk14": "org.bouncycastle", + "bctls-jdk15on": "org.bouncycastle", + "bctls-jdk15to18": "org.bouncycastle", + "bctls-jdk18on": "org.bouncycastle", + "bctls-lts8on": "org.bouncycastle", + "bctsp-jdk14": "org.bouncycastle", + "bctsp-jdk15": "org.bouncycastle", + "bctsp-jdk15+": "org.bouncycastle", + "bctsp-jdk15on": "org.bouncycastle", + "bctsp-jdk16": "org.bouncycastle", + "bcutil-debug-jdk15to18": "org.bouncycastle", + "bcutil-debug-jdk18on": "org.bouncycastle", + "bcutil-jdk14": "org.bouncycastle", + "bcutil-jdk15on": "org.bouncycastle", + "bcutil-jdk15to18": "org.bouncycastle", + "bcutil-jdk18on": "org.bouncycastle", + "bcutil-lts8on": "org.bouncycastle", + "elasticsearch": "org.elasticsearch", + "elasticsearch-analysis-icu": "org.elasticsearch", + "elasticsearch-analysis-ik": "org.elasticsearch", + "elasticsearch-analysis-kuromoji": "org.elasticsearch", + "elasticsearch-analysis-mmseg": "org.elasticsearch", + "elasticsearch-analysis-phonetic": "org.elasticsearch", + "elasticsearch-analysis-pinyin": "org.elasticsearch", + "elasticsearch-analysis-smartcn": "org.elasticsearch", + "elasticsearch-analysis-stconvert": "org.elasticsearch", + "elasticsearch-analysis-stempel": "org.elasticsearch", + "elasticsearch-attachments": "org.elasticsearch", + "elasticsearch-benchmarks": "org.elasticsearch", + "elasticsearch-cli": "org.elasticsearch", + "elasticsearch-client-groovy": "org.elasticsearch", + "elasticsearch-cloud": "org.elasticsearch", + "elasticsearch-cloud-aws": "org.elasticsearch", + "elasticsearch-cloud-azure": "org.elasticsearch", + "elasticsearch-cloud-gce": "org.elasticsearch", + "elasticsearch-core": "org.elasticsearch", + "elasticsearch-discovery-jgroups": "org.elasticsearch", + "elasticsearch-geo": "org.elasticsearch", + "elasticsearch-grok": "org.elasticsearch", + "elasticsearch-groovy": "org.elasticsearch", + "elasticsearch-h3": "org.elasticsearch", + "elasticsearch-hadoop": "org.elasticsearch", + "elasticsearch-hadoop-cascading": "org.elasticsearch", + "elasticsearch-hadoop-hive": "org.elasticsearch", + "elasticsearch-hadoop-mr": "org.elasticsearch", + "elasticsearch-hadoop-pig": "org.elasticsearch", + "elasticsearch-lang-groovy": "org.elasticsearch", + "elasticsearch-lang-javascript": "org.elasticsearch", + "elasticsearch-lang-mvel": "org.elasticsearch", + "elasticsearch-lang-python": "org.elasticsearch", + "elasticsearch-logging": "org.elasticsearch", + "elasticsearch-lz4": "org.elasticsearch", + "elasticsearch-mapper-attachments": "org.elasticsearch", + "elasticsearch-nio": "org.elasticsearch", + "elasticsearch-parent": "org.elasticsearch", + "elasticsearch-plugin-analysis-api": "org.elasticsearch", + "elasticsearch-plugin-api": "org.elasticsearch", + "elasticsearch-plugin-classloader": "org.elasticsearch", + "elasticsearch-plugin-scanner": "org.elasticsearch", + "elasticsearch-preallocate": "org.elasticsearch", + "elasticsearch-repository-hdfs": "org.elasticsearch", + "elasticsearch-river-couchdb": "org.elasticsearch", + "elasticsearch-river-rabbitmq": "org.elasticsearch", + "elasticsearch-river-twitter": "org.elasticsearch", + "elasticsearch-river-wikipedia": "org.elasticsearch", + "elasticsearch-secure-sm": "org.elasticsearch", + "elasticsearch-spark-1.2": "org.elasticsearch", + "elasticsearch-spark-1.2_2.10": "org.elasticsearch", + "elasticsearch-spark-1.2_2.11": "org.elasticsearch", + "elasticsearch-spark-13_2.10": "org.elasticsearch", + "elasticsearch-spark-13_2.11": "org.elasticsearch", + "elasticsearch-spark-20_2.10": "org.elasticsearch", + "elasticsearch-spark-20_2.11": "org.elasticsearch", + "elasticsearch-spark-20_2.12": "org.elasticsearch", + "elasticsearch-spark-30_2.12": "org.elasticsearch", + "elasticsearch-spark-30_2.13": "org.elasticsearch", + "elasticsearch-spark_2.10": "org.elasticsearch", + "elasticsearch-spark_2.11": "org.elasticsearch", + "elasticsearch-ssl-config": "org.elasticsearch", + "elasticsearch-storm": "org.elasticsearch", + "elasticsearch-tdigest": "org.elasticsearch", + "elasticsearch-transport-memcached": "org.elasticsearch", + "elasticsearch-transport-thrift": "org.elasticsearch", + "elasticsearch-transport-wares": "org.elasticsearch", + "elasticsearch-x-content": "org.elasticsearch", + "elasticsearch-yarn": "org.elasticsearch", + "elasticsearch-rest-client": "org.elasticsearch.client", + "elasticsearch-rest-client-sniffer": "org.elasticsearch.client", + "elasticsearch-rest-high-level-client": "org.elasticsearch.client", + "apoc": "org.neo4j.procedure", + "apoc-common": "org.neo4j.procedure", + "apoc-core": "org.neo4j.procedure", + "apoc-extended": "org.neo4j.procedure", + "apoc-processor": "org.neo4j.procedure", + "apoc-test-utils": "org.neo4j.procedure", + "spring": "org.springframework", + "spring-agent": "org.springframework", + "spring-aop": "org.springframework", + "spring-asm": "org.springframework", + "spring-aspects": "org.springframework", + "spring-beandoc": "org.springframework", + "spring-beans": "org.springframework", + "spring-context": "org.springframework", + "spring-context-indexer": "org.springframework", + "spring-context-support": "org.springframework", + "spring-core": "org.springframework", + "spring-core-test": "org.springframework", + "spring-dao": "org.springframework", + "spring-expression": "org.springframework", + "spring-framework-bom": "org.springframework", + "spring-full": "org.springframework", + "spring-hibernate": "org.springframework", + "spring-hibernate2": "org.springframework", + "spring-hibernate3": "org.springframework", + "spring-ibatis": "org.springframework", + "spring-instrument": "org.springframework", + "spring-instrument-tomcat": "org.springframework", + "spring-jca": "org.springframework", + "spring-jcl": "org.springframework", + "spring-jdbc": "org.springframework", + "spring-jdo": "org.springframework", + "spring-jms": "org.springframework", + "spring-jmx": "org.springframework", + "spring-jpa": "org.springframework", + "spring-ldap": "org.springframework", + "spring-messaging": "org.springframework", + "spring-mock": "org.springframework", + "spring-ojb": "org.springframework", + "spring-orm": "org.springframework", + "spring-oxm": "org.springframework", + "spring-parent": "org.springframework", + "spring-portlet": "org.springframework", + "spring-r2dbc": "org.springframework", + "spring-remoting": "org.springframework", + "spring-struts": "org.springframework", + "spring-support": "org.springframework", + "spring-test": "org.springframework", + "spring-tomcat-weaver": "org.springframework", + "spring-toplink": "org.springframework", + "spring-tuple": "org.springframework", + "spring-tuple-parent": "org.springframework", + "spring-tx": "org.springframework", + "spring-web": "org.springframework", + "spring-webflux": "org.springframework", + "spring-webmvc": "org.springframework", + "spring-webmvc-portlet": "org.springframework", + "spring-webmvc-struts": "org.springframework", + "spring-websocket": "org.springframework", + "spring-amqp": "org.springframework.amqp", + "spring-amqp-bom": "org.springframework.amqp", + "spring-amqp-dist": "org.springframework.amqp", + "spring-amqp-parent": "org.springframework.amqp", + "spring-erlang": "org.springframework.amqp", + "spring-rabbit": "org.springframework.amqp", + "spring-rabbit-junit": "org.springframework.amqp", + "spring-rabbit-stream": "org.springframework.amqp", + "spring-rabbit-test": "org.springframework.amqp", + "spring-analytics": "org.springframework.analytics", + "spring-batch": "org.springframework.batch", + "spring-batch-admin-manager": "org.springframework.batch", + "spring-batch-admin-parent": "org.springframework.batch", + "spring-batch-admin-resources": "org.springframework.batch", + "spring-batch-archetypes": "org.springframework.batch", + "spring-batch-bom": "org.springframework.batch", + "spring-batch-core": "org.springframework.batch", + "spring-batch-docs": "org.springframework.batch", + "spring-batch-infrastructure": "org.springframework.batch", + "spring-batch-infrastructure-tests": "org.springframework.batch", + "spring-batch-integration": "org.springframework.batch", + "spring-batch-parent": "org.springframework.batch", + "spring-batch-samples": "org.springframework.batch", + "spring-batch-test": "org.springframework.batch", + "spring-batch-tuple": "org.springframework.batch", + "spring-boot": "org.springframework.boot", + "spring-boot-actuator": "org.springframework.boot", + "spring-boot-actuator-autoconfigure": "org.springframework.boot", + "spring-boot-actuator-docs": "org.springframework.boot", + "spring-boot-antlib": "org.springframework.boot", + "spring-boot-archetypes": "org.springframework.boot", + "spring-boot-autoconfigure": "org.springframework.boot", + "spring-boot-autoconfigure-processor": "org.springframework.boot", + "spring-boot-build": "org.springframework.boot", + "spring-boot-buildpack-platform": "org.springframework.boot", + "spring-boot-cli": "org.springframework.boot", + "spring-boot-configuration-metadata": "org.springframework.boot", + "spring-boot-configuration-processor": "org.springframework.boot", + "spring-boot-dependencies": "org.springframework.boot", + "spring-boot-dependency-tools": "org.springframework.boot", + "spring-boot-deployment-test-glassfish": "org.springframework.boot", + "spring-boot-deployment-test-tomcat": "org.springframework.boot", + "spring-boot-deployment-test-tomee": "org.springframework.boot", + "spring-boot-deployment-test-wildfly": "org.springframework.boot", + "spring-boot-deployment-test-wlp": "org.springframework.boot", + "spring-boot-deployment-tests": "org.springframework.boot", + "spring-boot-devtools": "org.springframework.boot", + "spring-boot-devtools-tests": "org.springframework.boot", + "spring-boot-docker-compose": "org.springframework.boot", + "spring-boot-docs": "org.springframework.boot", + "spring-boot-full-build": "org.springframework.boot", + "spring-boot-gradle-plugin": "org.springframework.boot", + "spring-boot-gradle-tests": "org.springframework.boot", + "spring-boot-jarmode-layertools": "org.springframework.boot", + "spring-boot-launch-script-tests": "org.springframework.boot", + "spring-boot-legacy": "org.springframework.boot", + "spring-boot-loader": "org.springframework.boot", + "spring-boot-loader-tools": "org.springframework.boot", + "spring-boot-maven-plugin": "org.springframework.boot", + "spring-boot-parent": "org.springframework.boot", + "spring-boot-project": "org.springframework.boot", + "spring-boot-properties-migrator": "org.springframework.boot", + "spring-boot-sample-actuator-archetype": "org.springframework.boot", + "spring-boot-sample-actuator-log4j-archetype": "org.springframework.boot", + "spring-boot-sample-actuator-noweb-archetype": "org.springframework.boot", + "spring-boot-sample-actuator-ui-archetype": "org.springframework.boot", + "spring-boot-sample-amqp-archetype": "org.springframework.boot", + "spring-boot-sample-aop-archetype": "org.springframework.boot", + "spring-boot-sample-batch-archetype": "org.springframework.boot", + "spring-boot-sample-data-jpa-archetype": "org.springframework.boot", + "spring-boot-sample-data-mongodb-archetype": "org.springframework.boot", + "spring-boot-sample-data-redis-archetype": "org.springframework.boot", + "spring-boot-sample-data-rest-archetype": "org.springframework.boot", + "spring-boot-sample-integration-archetype": "org.springframework.boot", + "spring-boot-sample-jetty-archetype": "org.springframework.boot", + "spring-boot-sample-profile-archetype": "org.springframework.boot", + "spring-boot-sample-secure-archetype": "org.springframework.boot", + "spring-boot-sample-servlet-archetype": "org.springframework.boot", + "spring-boot-sample-simple-archetype": "org.springframework.boot", + "spring-boot-sample-tomcat-archetype": "org.springframework.boot", + "spring-boot-sample-traditional-archetype": "org.springframework.boot", + "spring-boot-sample-web-jsp-archetype": "org.springframework.boot", "spring-boot-sample-web-method-security-archetype": "org.springframework.boot", "spring-boot-sample-web-secure-archetype": "org.springframework.boot", "spring-boot-sample-web-static-archetype": "org.springframework.boot", @@ -1200,4 +1419,440 @@ var DefaultArtifactIDToGroupID = map[string]string{ "spring-ws": "org.springframework.ws", "spring-xml": "org.springframework.ws", "xalan": "xalan", // see https://mvnrepository.com/artifact/xalan/xalan/2.7.2 + "org.eclipse.ant.core": "org.eclipse.platform", + "org.eclipse.ant.launching": "org.eclipse.platform", + "org.eclipse.ant.optional.junit": "org.eclipse.platform", + "org.eclipse.ant.ui": "org.eclipse.platform", + "org.eclipse.compare": "org.eclipse.platform", + "org.eclipse.compare.core": "org.eclipse.platform", + "org.eclipse.compare.examples": "org.eclipse.platform", + "org.eclipse.compare.examples.xml": "org.eclipse.platform", + "org.eclipse.compare.win32": "org.eclipse.platform", + "org.eclipse.core.commands": "org.eclipse.platform", + "org.eclipse.core.contenttype": "org.eclipse.platform", + "org.eclipse.core.databinding": "org.eclipse.platform", + "org.eclipse.core.databinding.beans": "org.eclipse.platform", + "org.eclipse.core.databinding.observable": "org.eclipse.platform", + "org.eclipse.core.databinding.property": "org.eclipse.platform", + "org.eclipse.core.expressions": "org.eclipse.platform", + "org.eclipse.core.externaltools": "org.eclipse.platform", + "org.eclipse.core.filebuffers": "org.eclipse.platform", + "org.eclipse.core.filesystem": "org.eclipse.platform", + "org.eclipse.core.filesystem.aix.ppc": "org.eclipse.platform", + "org.eclipse.core.filesystem.aix.ppc64": "org.eclipse.platform", + "org.eclipse.core.filesystem.hpux.ia64": "org.eclipse.platform", + "org.eclipse.core.filesystem.linux.aarch64": "org.eclipse.platform", + "org.eclipse.core.filesystem.linux.ppc": "org.eclipse.platform", + "org.eclipse.core.filesystem.linux.ppc64": "org.eclipse.platform", + "org.eclipse.core.filesystem.linux.ppc64le": "org.eclipse.platform", + "org.eclipse.core.filesystem.linux.x86": "org.eclipse.platform", + "org.eclipse.core.filesystem.linux.x86_64": "org.eclipse.platform", + "org.eclipse.core.filesystem.macosx": "org.eclipse.platform", + "org.eclipse.core.filesystem.win32.x86": "org.eclipse.platform", + "org.eclipse.core.filesystem.win32.x86_64": "org.eclipse.platform", + "org.eclipse.core.jobs": "org.eclipse.platform", + "org.eclipse.core.net": "org.eclipse.platform", + "org.eclipse.core.net.linux": "org.eclipse.platform", + "org.eclipse.core.net.linux.x86": "org.eclipse.platform", + "org.eclipse.core.net.linux.x86_64": "org.eclipse.platform", + "org.eclipse.core.net.win32": "org.eclipse.platform", + "org.eclipse.core.net.win32.x86": "org.eclipse.platform", + "org.eclipse.core.net.win32.x86_64": "org.eclipse.platform", + "org.eclipse.core.resources": "org.eclipse.platform", + "org.eclipse.core.resources.win32.x86": "org.eclipse.platform", + "org.eclipse.core.resources.win32.x86_64": "org.eclipse.platform", + "org.eclipse.core.runtime": "org.eclipse.platform", + "org.eclipse.core.variables": "org.eclipse.platform", + "org.eclipse.cvs": "org.eclipse.platform", + "org.eclipse.debug.core": "org.eclipse.platform", + "org.eclipse.debug.examples.core": "org.eclipse.platform", + "org.eclipse.debug.examples.ui": "org.eclipse.platform", + "org.eclipse.debug.ui": "org.eclipse.platform", + "org.eclipse.debug.ui.launchview": "org.eclipse.platform", + "org.eclipse.e4.core.commands": "org.eclipse.platform", + "org.eclipse.e4.core.contexts": "org.eclipse.platform", + "org.eclipse.e4.core.di": "org.eclipse.platform", + "org.eclipse.e4.core.di.annotations": "org.eclipse.platform", + "org.eclipse.e4.core.di.extensions": "org.eclipse.platform", + "org.eclipse.e4.core.di.extensions.supplier": "org.eclipse.platform", + "org.eclipse.e4.core.services": "org.eclipse.platform", + "org.eclipse.e4.emf.xpath": "org.eclipse.platform", + "org.eclipse.e4.tools": "org.eclipse.platform", + "org.eclipse.e4.tools.compat": "org.eclipse.platform", + "org.eclipse.e4.tools.compatibility.migration": "org.eclipse.platform", + "org.eclipse.e4.tools.emf.editor3x": "org.eclipse.platform", + "org.eclipse.e4.tools.emf.ui": "org.eclipse.platform", + "org.eclipse.e4.tools.jdt.templates": "org.eclipse.platform", + "org.eclipse.e4.tools.persistence": "org.eclipse.platform", + "org.eclipse.e4.tools.services": "org.eclipse.platform", + "org.eclipse.e4.ui.bindings": "org.eclipse.platform", + "org.eclipse.e4.ui.css.core": "org.eclipse.platform", + "org.eclipse.e4.ui.css.swt": "org.eclipse.platform", + "org.eclipse.e4.ui.css.swt.theme": "org.eclipse.platform", + "org.eclipse.e4.ui.di": "org.eclipse.platform", + "org.eclipse.e4.ui.dialogs": "org.eclipse.platform", + "org.eclipse.e4.ui.ide": "org.eclipse.platform", + "org.eclipse.e4.ui.model.workbench": "org.eclipse.platform", + "org.eclipse.e4.ui.progress": "org.eclipse.platform", + "org.eclipse.e4.ui.services": "org.eclipse.platform", + "org.eclipse.e4.ui.swt.gtk": "org.eclipse.platform", + "org.eclipse.e4.ui.swt.win32": "org.eclipse.platform", + "org.eclipse.e4.ui.widgets": "org.eclipse.platform", + "org.eclipse.e4.ui.workbench": "org.eclipse.platform", + "org.eclipse.e4.ui.workbench.addons.swt": "org.eclipse.platform", + "org.eclipse.e4.ui.workbench.renderers.swt": "org.eclipse.platform", + "org.eclipse.e4.ui.workbench.renderers.swt.cocoa": "org.eclipse.platform", + "org.eclipse.e4.ui.workbench.swt": "org.eclipse.platform", + "org.eclipse.e4.ui.workbench3": "org.eclipse.platform", + "org.eclipse.equinox.app": "org.eclipse.platform", + "org.eclipse.equinox.bidi": "org.eclipse.platform", + "org.eclipse.equinox.cm": "org.eclipse.platform", + "org.eclipse.equinox.common": "org.eclipse.platform", + "org.eclipse.equinox.concurrent": "org.eclipse.platform", + "org.eclipse.equinox.console": "org.eclipse.platform", + "org.eclipse.equinox.console.jaas.fragment": "org.eclipse.platform", + "org.eclipse.equinox.console.ssh": "org.eclipse.platform", + "org.eclipse.equinox.coordinator": "org.eclipse.platform", + "org.eclipse.equinox.device": "org.eclipse.platform", + "org.eclipse.equinox.ds": "org.eclipse.platform", + "org.eclipse.equinox.event": "org.eclipse.platform", + "org.eclipse.equinox.frameworkadmin": "org.eclipse.platform", + "org.eclipse.equinox.frameworkadmin.equinox": "org.eclipse.platform", + "org.eclipse.equinox.http.jetty": "org.eclipse.platform", + "org.eclipse.equinox.http.registry": "org.eclipse.platform", + "org.eclipse.equinox.http.servlet": "org.eclipse.platform", + "org.eclipse.equinox.http.servletbridge": "org.eclipse.platform", + "org.eclipse.equinox.io": "org.eclipse.platform", + "org.eclipse.equinox.ip": "org.eclipse.platform", + "org.eclipse.equinox.jsp.jasper": "org.eclipse.platform", + "org.eclipse.equinox.jsp.jasper.registry": "org.eclipse.platform", + "org.eclipse.equinox.launcher": "org.eclipse.platform", + "org.eclipse.equinox.launcher.cocoa.macosx": "org.eclipse.platform", + "org.eclipse.equinox.launcher.cocoa.macosx.aarch64": "org.eclipse.platform", + "org.eclipse.equinox.launcher.cocoa.macosx.x86_64": "org.eclipse.platform", + "org.eclipse.equinox.launcher.gtk.aix.ppc": "org.eclipse.platform", + "org.eclipse.equinox.launcher.gtk.aix.ppc64": "org.eclipse.platform", + "org.eclipse.equinox.launcher.gtk.hpux.ia64": "org.eclipse.platform", + "org.eclipse.equinox.launcher.gtk.linux.aarch64": "org.eclipse.platform", + "org.eclipse.equinox.launcher.gtk.linux.ppc": "org.eclipse.platform", + "org.eclipse.equinox.launcher.gtk.linux.ppc64": "org.eclipse.platform", + "org.eclipse.equinox.launcher.gtk.linux.ppc64le": "org.eclipse.platform", + "org.eclipse.equinox.launcher.gtk.linux.s390": "org.eclipse.platform", + "org.eclipse.equinox.launcher.gtk.linux.s390x": "org.eclipse.platform", + "org.eclipse.equinox.launcher.gtk.linux.x86": "org.eclipse.platform", + "org.eclipse.equinox.launcher.gtk.linux.x86_64": "org.eclipse.platform", + "org.eclipse.equinox.launcher.gtk.solaris.sparcv9": "org.eclipse.platform", + "org.eclipse.equinox.launcher.gtk.solaris.x86_64": "org.eclipse.platform", + "org.eclipse.equinox.launcher.win32.win32.x86": "org.eclipse.platform", + "org.eclipse.equinox.launcher.win32.win32.x86_64": "org.eclipse.platform", + "org.eclipse.equinox.log.stream": "org.eclipse.platform", + "org.eclipse.equinox.metatype": "org.eclipse.platform", + "org.eclipse.equinox.p2.artifact.repository": "org.eclipse.platform", + "org.eclipse.equinox.p2.console": "org.eclipse.platform", + "org.eclipse.equinox.p2.core": "org.eclipse.platform", + "org.eclipse.equinox.p2.director": "org.eclipse.platform", + "org.eclipse.equinox.p2.director.app": "org.eclipse.platform", + "org.eclipse.equinox.p2.directorywatcher": "org.eclipse.platform", + "org.eclipse.equinox.p2.discovery": "org.eclipse.platform", + "org.eclipse.equinox.p2.discovery.compatibility": "org.eclipse.platform", + "org.eclipse.equinox.p2.engine": "org.eclipse.platform", + "org.eclipse.equinox.p2.extensionlocation": "org.eclipse.platform", + "org.eclipse.equinox.p2.garbagecollector": "org.eclipse.platform", + "org.eclipse.equinox.p2.installer": "org.eclipse.platform", + "org.eclipse.equinox.p2.jarprocessor": "org.eclipse.platform", + "org.eclipse.equinox.p2.metadata": "org.eclipse.platform", + "org.eclipse.equinox.p2.metadata.repository": "org.eclipse.platform", + "org.eclipse.equinox.p2.operations": "org.eclipse.platform", + "org.eclipse.equinox.p2.publisher": "org.eclipse.platform", + "org.eclipse.equinox.p2.publisher.eclipse": "org.eclipse.platform", + "org.eclipse.equinox.p2.reconciler.dropins": "org.eclipse.platform", + "org.eclipse.equinox.p2.repository": "org.eclipse.platform", + "org.eclipse.equinox.p2.repository.tools": "org.eclipse.platform", + "org.eclipse.equinox.p2.touchpoint.eclipse": "org.eclipse.platform", + "org.eclipse.equinox.p2.touchpoint.natives": "org.eclipse.platform", + "org.eclipse.equinox.p2.transport.ecf": "org.eclipse.platform", + "org.eclipse.equinox.p2.ui": "org.eclipse.platform", + "org.eclipse.equinox.p2.ui.admin": "org.eclipse.platform", + "org.eclipse.equinox.p2.ui.admin.rcp": "org.eclipse.platform", + "org.eclipse.equinox.p2.ui.discovery": "org.eclipse.platform", + "org.eclipse.equinox.p2.ui.importexport": "org.eclipse.platform", + "org.eclipse.equinox.p2.ui.sdk": "org.eclipse.platform", + "org.eclipse.equinox.p2.ui.sdk.scheduler": "org.eclipse.platform", + "org.eclipse.equinox.p2.updatechecker": "org.eclipse.platform", + "org.eclipse.equinox.p2.updatesite": "org.eclipse.platform", + "org.eclipse.equinox.preferences": "org.eclipse.platform", + "org.eclipse.equinox.region": "org.eclipse.platform", + "org.eclipse.equinox.registry": "org.eclipse.platform", + "org.eclipse.equinox.security": "org.eclipse.platform", + "org.eclipse.equinox.security.linux": "org.eclipse.platform", + "org.eclipse.equinox.security.linux.x86_64": "org.eclipse.platform", + "org.eclipse.equinox.security.macosx": "org.eclipse.platform", + "org.eclipse.equinox.security.ui": "org.eclipse.platform", + "org.eclipse.equinox.security.win32.x86": "org.eclipse.platform", + "org.eclipse.equinox.security.win32.x86_64": "org.eclipse.platform", + "org.eclipse.equinox.servletbridge": "org.eclipse.platform", + "org.eclipse.equinox.simpleconfigurator": "org.eclipse.platform", + "org.eclipse.equinox.simpleconfigurator.manipulator": "org.eclipse.platform", + "org.eclipse.equinox.supplement": "org.eclipse.platform", + "org.eclipse.equinox.transforms.hook": "org.eclipse.platform", + "org.eclipse.equinox.transforms.xslt": "org.eclipse.platform", + "org.eclipse.equinox.useradmin": "org.eclipse.platform", + "org.eclipse.equinox.util": "org.eclipse.platform", + "org.eclipse.equinox.weaving.caching": "org.eclipse.platform", + "org.eclipse.equinox.weaving.caching.j9": "org.eclipse.platform", + "org.eclipse.equinox.weaving.hook": "org.eclipse.platform", + "org.eclipse.equinox.wireadmin": "org.eclipse.platform", + "org.eclipse.help": "org.eclipse.platform", + "org.eclipse.help.base": "org.eclipse.platform", + "org.eclipse.help.ui": "org.eclipse.platform", + "org.eclipse.help.webapp": "org.eclipse.platform", + "org.eclipse.jface": "org.eclipse.platform", + "org.eclipse.jface.databinding": "org.eclipse.platform", + "org.eclipse.jface.examples.databinding": "org.eclipse.platform", + "org.eclipse.jface.notifications": "org.eclipse.platform", + "org.eclipse.jface.text": "org.eclipse.platform", + "org.eclipse.jsch.core": "org.eclipse.platform", + "org.eclipse.jsch.ui": "org.eclipse.platform", + "org.eclipse.ltk.core.refactoring": "org.eclipse.platform", + "org.eclipse.ltk.ui.refactoring": "org.eclipse.platform", + "org.eclipse.osgi": "org.eclipse.platform", + "org.eclipse.osgi.compatibility.plugins": "org.eclipse.platform", + "org.eclipse.osgi.compatibility.state": "org.eclipse.platform", + "org.eclipse.osgi.services": "org.eclipse.platform", + "org.eclipse.osgi.util": "org.eclipse.platform", + "org.eclipse.platform": "org.eclipse.platform", + "org.eclipse.platform.doc.isv": "org.eclipse.platform", + "org.eclipse.platform.doc.user": "org.eclipse.platform", + "org.eclipse.rcp": "org.eclipse.platform", + "org.eclipse.releng.tools": "org.eclipse.platform", + "org.eclipse.sdk": "org.eclipse.platform", + "org.eclipse.sdk.examples": "org.eclipse.platform", + "org.eclipse.search": "org.eclipse.platform", + "org.eclipse.swt": "org.eclipse.platform", + "org.eclipse.swt.browser.chromium.cocoa.macosx.x86_64": "org.eclipse.platform", + "org.eclipse.swt.browser.chromium.gtk.linux.x86_64": "org.eclipse.platform", + "org.eclipse.swt.browser.chromium.win32.win32.x86_64": "org.eclipse.platform", + "org.eclipse.swt.cocoa.macosx.aarch64": "org.eclipse.platform", + "org.eclipse.swt.cocoa.macosx.x86_64": "org.eclipse.platform", + "org.eclipse.swt.examples": "org.eclipse.platform", + "org.eclipse.swt.examples.browser.demos": "org.eclipse.platform", + "org.eclipse.swt.examples.launcher": "org.eclipse.platform", + "org.eclipse.swt.examples.ole.win32": "org.eclipse.platform", + "org.eclipse.swt.examples.views": "org.eclipse.platform", + "org.eclipse.swt.gtk.aix.ppc": "org.eclipse.platform", + "org.eclipse.swt.gtk.aix.ppc64": "org.eclipse.platform", + "org.eclipse.swt.gtk.hpux.ia64": "org.eclipse.platform", + "org.eclipse.swt.gtk.linux.aarch64": "org.eclipse.platform", + "org.eclipse.swt.gtk.linux.ppc": "org.eclipse.platform", + "org.eclipse.swt.gtk.linux.ppc64": "org.eclipse.platform", + "org.eclipse.swt.gtk.linux.ppc64le": "org.eclipse.platform", + "org.eclipse.swt.gtk.linux.s390": "org.eclipse.platform", + "org.eclipse.swt.gtk.linux.s390x": "org.eclipse.platform", + "org.eclipse.swt.gtk.linux.x86": "org.eclipse.platform", + "org.eclipse.swt.gtk.linux.x86_64": "org.eclipse.platform", + "org.eclipse.swt.gtk.solaris.sparcv9": "org.eclipse.platform", + "org.eclipse.swt.gtk.solaris.x86_64": "org.eclipse.platform", + "org.eclipse.swt.tools": "org.eclipse.platform", + "org.eclipse.swt.tools.base": "org.eclipse.platform", + "org.eclipse.swt.tools.spies": "org.eclipse.platform", + "org.eclipse.swt.win32.win32.x86": "org.eclipse.platform", + "org.eclipse.swt.win32.win32.x86_64": "org.eclipse.platform", + "org.eclipse.team.core": "org.eclipse.platform", + "org.eclipse.team.cvs.core": "org.eclipse.platform", + "org.eclipse.team.cvs.ssh2": "org.eclipse.platform", + "org.eclipse.team.cvs.ui": "org.eclipse.platform", + "org.eclipse.team.examples.filesystem": "org.eclipse.platform", + "org.eclipse.team.genericeditor.diff.extension": "org.eclipse.platform", + "org.eclipse.team.ui": "org.eclipse.platform", + "org.eclipse.text": "org.eclipse.platform", + "org.eclipse.text.quicksearch": "org.eclipse.platform", + "org.eclipse.tips.core": "org.eclipse.platform", + "org.eclipse.tips.ide": "org.eclipse.platform", + "org.eclipse.tips.json": "org.eclipse.platform", + "org.eclipse.tips.ui": "org.eclipse.platform", + "org.eclipse.tools.layout.spy": "org.eclipse.platform", + "org.eclipse.ui": "org.eclipse.platform", + "org.eclipse.ui.browser": "org.eclipse.platform", + "org.eclipse.ui.cheatsheets": "org.eclipse.platform", + "org.eclipse.ui.cocoa": "org.eclipse.platform", + "org.eclipse.ui.console": "org.eclipse.platform", + "org.eclipse.ui.editors": "org.eclipse.platform", + "org.eclipse.ui.examples.contributions": "org.eclipse.platform", + "org.eclipse.ui.examples.fieldassist": "org.eclipse.platform", + "org.eclipse.ui.examples.filesystem": "org.eclipse.platform", + "org.eclipse.ui.examples.javaeditor": "org.eclipse.platform", + "org.eclipse.ui.examples.multipageeditor": "org.eclipse.platform", + "org.eclipse.ui.examples.propertysheet": "org.eclipse.platform", + "org.eclipse.ui.examples.readmetool": "org.eclipse.platform", + "org.eclipse.ui.examples.undo": "org.eclipse.platform", + "org.eclipse.ui.examples.uriSchemeHandler": "org.eclipse.platform", + "org.eclipse.ui.examples.views.properties.tabbed.article": "org.eclipse.platform", + "org.eclipse.ui.externaltools": "org.eclipse.platform", + "org.eclipse.ui.forms": "org.eclipse.platform", + "org.eclipse.ui.genericeditor": "org.eclipse.platform", + "org.eclipse.ui.genericeditor.examples": "org.eclipse.platform", + "org.eclipse.ui.ide": "org.eclipse.platform", + "org.eclipse.ui.ide.application": "org.eclipse.platform", + "org.eclipse.ui.intro": "org.eclipse.platform", + "org.eclipse.ui.intro.quicklinks": "org.eclipse.platform", + "org.eclipse.ui.intro.universal": "org.eclipse.platform", + "org.eclipse.ui.monitoring": "org.eclipse.platform", + "org.eclipse.ui.navigator": "org.eclipse.platform", + "org.eclipse.ui.navigator.resources": "org.eclipse.platform", + "org.eclipse.ui.net": "org.eclipse.platform", + "org.eclipse.ui.themes": "org.eclipse.platform", + "org.eclipse.ui.trace": "org.eclipse.platform", + "org.eclipse.ui.views": "org.eclipse.platform", + "org.eclipse.ui.views.log": "org.eclipse.platform", + "org.eclipse.ui.views.properties.tabbed": "org.eclipse.platform", + "org.eclipse.ui.win32": "org.eclipse.platform", + "org.eclipse.ui.workbench": "org.eclipse.platform", + "org.eclipse.ui.workbench.texteditor": "org.eclipse.platform", + "org.eclipse.update.configurator": "org.eclipse.platform", + "org.eclipse.update.core": "org.eclipse.platform", + "org.eclipse.urischeme": "org.eclipse.platform", + "reactor-netty": "io.projectreactor.netty", + "reactor-netty-core": "io.projectreactor.netty", + "reactor-netty-http": "io.projectreactor.netty", + "reactor-netty-http-brave": "io.projectreactor.netty", + "reactor-netty-incubator-quic": "io.projectreactor.netty.incubator", + "ratpack-base": "io.ratpack", + "ratpack-codahale-metrics": "io.ratpack", + "ratpack-config": "io.ratpack", + "ratpack-consul": "io.ratpack", + "ratpack-core": "io.ratpack", + "ratpack-dropwizard-metrics": "io.ratpack", + "ratpack-exec": "io.ratpack", + "ratpack-func": "io.ratpack", + "ratpack-gradle": "io.ratpack", + "ratpack-groovy": "io.ratpack", + "ratpack-groovy-test": "io.ratpack", + "ratpack-gson": "io.ratpack", + "ratpack-guice": "io.ratpack", + "ratpack-h2": "io.ratpack", + "ratpack-handlebars": "io.ratpack", + "ratpack-hikari": "io.ratpack", + "ratpack-hystrix": "io.ratpack", + "ratpack-jackson": "io.ratpack", + "ratpack-jackson-guice": "io.ratpack", + "ratpack-jdbc-tx": "io.ratpack", + "ratpack-manual": "io.ratpack", + "ratpack-newrelic": "io.ratpack", + "ratpack-pac4j": "io.ratpack", + "ratpack-reactor": "io.ratpack", + "ratpack-remote": "io.ratpack", + "ratpack-remote-test": "io.ratpack", + "ratpack-retrofit2": "io.ratpack", + "ratpack-rocker": "io.ratpack", + "ratpack-rx": "io.ratpack", + "ratpack-rx2": "io.ratpack", + "ratpack-session": "io.ratpack", + "ratpack-session-redis": "io.ratpack", + "ratpack-session-serialization-kryo": "io.ratpack", + "ratpack-spring-boot": "io.ratpack", + "ratpack-spring-boot-starter": "io.ratpack", + "ratpack-test": "io.ratpack", + "ratpack-thymeleaf": "io.ratpack", + "ratpack-thymeleaf3": "io.ratpack", + "graphiql-spring-boot-autoconfigure": "com.graphql-java", + "graphiql-spring-boot-starter": "com.graphql-java", + "graphql-java": "com.graphql-java", + "graphql-java-annotations": "com.graphql-java", + "graphql-java-extended-scalars": "com.graphql-java", + "graphql-java-extended-validation": "com.graphql-java", + "graphql-java-servlet": "com.graphql-java", + "graphql-java-spring-boot-starter-webflux": "com.graphql-java", + "graphql-java-spring-boot-starter-webmvc": "com.graphql-java", + "graphql-java-spring-webflux": "com.graphql-java", + "graphql-java-spring-webmvc": "com.graphql-java", + "graphql-java-tools": "com.graphql-java", + "graphql-rxjava": "com.graphql-java", + "graphql-spring-boot-autoconfigure": "com.graphql-java", + "graphql-spring-boot-starter": "com.graphql-java", + "graphql-spring-boot-starter-test": "com.graphql-java", + "graphql-spring-boot-test": "com.graphql-java", + "graphql-spring-boot-test-autoconfigure": "com.graphql-java", + "java-dataloader": "com.graphql-java", + "voyager-spring-boot-autoconfigure": "com.graphql-java", + "voyager-spring-boot-starter": "com.graphql-java", + "minio": "io.minio", + "minio-admin": "io.minio", + "minio-java": "io.minio", + "commons-jelly": "commons-jelly", + "commons-jelly-avalon": "commons-jelly", + "commons-jelly-tags-ant": "commons-jelly", + "commons-jelly-tags-antlr": "commons-jelly", + "commons-jelly-tags-avalon": "commons-jelly", + "commons-jelly-tags-bean": "commons-jelly", + "commons-jelly-tags-beanshell": "commons-jelly", + "commons-jelly-tags-betwixt": "commons-jelly", + "commons-jelly-tags-bsf": "commons-jelly", + "commons-jelly-tags-define": "commons-jelly", + "commons-jelly-tags-dynabean": "commons-jelly", + "commons-jelly-tags-email": "commons-jelly", + "commons-jelly-tags-fmt": "commons-jelly", + "commons-jelly-tags-html": "commons-jelly", + "commons-jelly-tags-http": "commons-jelly", + "commons-jelly-tags-interaction": "commons-jelly", + "commons-jelly-tags-jaxme": "commons-jelly", + "commons-jelly-tags-jetty": "commons-jelly", + "commons-jelly-tags-jface": "commons-jelly", + "commons-jelly-tags-jms": "commons-jelly", + "commons-jelly-tags-jmx": "commons-jelly", + "commons-jelly-tags-jsl": "commons-jelly", + "commons-jelly-tags-junit": "commons-jelly", + "commons-jelly-tags-log": "commons-jelly", + "commons-jelly-tags-ojb": "commons-jelly", + "commons-jelly-tags-quartz": "commons-jelly", + "commons-jelly-tags-regexp": "commons-jelly", + "commons-jelly-tags-soap": "commons-jelly", + "commons-jelly-tags-sql": "commons-jelly", + "commons-jelly-tags-swing": "commons-jelly", + "commons-jelly-tags-swt": "commons-jelly", + "commons-jelly-tags-threads": "commons-jelly", + "commons-jelly-tags-util": "commons-jelly", + "commons-jelly-tags-validate": "commons-jelly", + "commons-jelly-tags-velocity": "commons-jelly", + "commons-jelly-tags-xml": "commons-jelly", + "commons-jelly-tags-xmlunit": "commons-jelly", + "groovy": "org.codehaus.groovy", + "groovy-all": "org.codehaus.groovy", + "groovy-all-jdk14": "org.codehaus.groovy", + "groovy-all-minimal": "org.codehaus.groovy", + "groovy-all-tests": "org.codehaus.groovy", + "groovy-ant": "org.codehaus.groovy", + "groovy-astbuilder": "org.codehaus.groovy", + "groovy-backports-compat23": "org.codehaus.groovy", + "groovy-binary": "org.codehaus.groovy", + "groovy-bom": "org.codehaus.groovy", + "groovy-bsf": "org.codehaus.groovy", + "groovy-cli-commons": "org.codehaus.groovy", + "groovy-cli-picocli": "org.codehaus.groovy", + "groovy-console": "org.codehaus.groovy", + "groovy-datetime": "org.codehaus.groovy", + "groovy-dateutil": "org.codehaus.groovy", + "groovy-docgenerator": "org.codehaus.groovy", + "groovy-eclipse-batch": "org.codehaus.groovy", + "groovy-eclipse-compiler": "org.codehaus.groovy", + "groovy-groovydoc": "org.codehaus.groovy", + "groovy-groovysh": "org.codehaus.groovy", + "groovy-jaxb": "org.codehaus.groovy", + "groovy-jdk14": "org.codehaus.groovy", + "groovy-jmx": "org.codehaus.groovy", + "groovy-json": "org.codehaus.groovy", + "groovy-json-direct": "org.codehaus.groovy", + "groovy-jsr223": "org.codehaus.groovy", + "groovy-macro": "org.codehaus.groovy", + "groovy-nio": "org.codehaus.groovy", + "groovy-servlet": "org.codehaus.groovy", + "groovy-sql": "org.codehaus.groovy", + "groovy-swing": "org.codehaus.groovy", + "groovy-templates": "org.codehaus.groovy", + "groovy-test": "org.codehaus.groovy", + "groovy-test-junit5": "org.codehaus.groovy", + "groovy-testng": "org.codehaus.groovy", + "groovy-tests-vm8": "org.codehaus.groovy", + "groovy-xml": "org.codehaus.groovy", + "groovy-xmlrpc": "org.codehaus.groovy", + "groovy-yaml": "org.codehaus.groovy", } diff --git a/vendor/github.com/anchore/syft/syft/pkg/cataloger/config.go b/vendor/github.com/anchore/syft/syft/pkg/cataloger/config.go index e91718b3..7a352e0a 100644 --- a/vendor/github.com/anchore/syft/syft/pkg/cataloger/config.go +++ b/vendor/github.com/anchore/syft/syft/pkg/cataloger/config.go @@ -4,6 +4,7 @@ import ( "github.com/anchore/syft/syft/cataloging" "github.com/anchore/syft/syft/pkg/cataloger/golang" "github.com/anchore/syft/syft/pkg/cataloger/java" + "github.com/anchore/syft/syft/pkg/cataloger/javascript" "github.com/anchore/syft/syft/pkg/cataloger/kernel" "github.com/anchore/syft/syft/pkg/cataloger/python" ) @@ -15,6 +16,7 @@ type Config struct { LinuxKernel kernel.LinuxKernelCatalogerConfig Python python.CatalogerConfig Java java.ArchiveCatalogerConfig + Javascript javascript.CatalogerConfig Catalogers []string Parallelism int ExcludeBinaryOverlapByOwnership bool @@ -27,6 +29,7 @@ func DefaultConfig() Config { LinuxKernel: kernel.DefaultLinuxCatalogerConfig(), Python: python.DefaultCatalogerConfig(), Java: java.DefaultArchiveCatalogerConfig(), + Javascript: javascript.DefaultCatalogerConfig(), ExcludeBinaryOverlapByOwnership: true, } } diff --git a/vendor/github.com/anchore/syft/syft/pkg/cataloger/dotnet/parse_dotnet_portable_executable.go b/vendor/github.com/anchore/syft/syft/pkg/cataloger/dotnet/parse_dotnet_portable_executable.go index 3dc6a968..d3a782d5 100644 --- a/vendor/github.com/anchore/syft/syft/pkg/cataloger/dotnet/parse_dotnet_portable_executable.go +++ b/vendor/github.com/anchore/syft/syft/pkg/cataloger/dotnet/parse_dotnet_portable_executable.go @@ -58,23 +58,14 @@ func parseDotnetPortableExecutable(_ file.Resolver, _ *generic.Environment, f fi func buildDotNetPackage(versionResources map[string]string, f file.LocationReadCloser) (dnpkg pkg.Package, err error) { name := findName(versionResources) if name == "" { - return dnpkg, fmt.Errorf("unable to find FileDescription, or ProductName in PE file: %s", f.RealPath) + return dnpkg, fmt.Errorf("unable to find PE name in file: %s", f.RealPath) } version := findVersion(versionResources) - if strings.TrimSpace(version) == "" { - return dnpkg, fmt.Errorf("unable to find FileVersion in PE file: %s", f.RealPath) + if version == "" { + return dnpkg, fmt.Errorf("unable to find PE version in file: %s", f.RealPath) } - purl := packageurl.NewPackageURL( - packageurl.TypeNuget, // See explanation in syft/pkg/cataloger/dotnet/package.go as to why this was chosen. - "", - name, - version, - nil, - "", - ).ToString() - metadata := pkg.DotnetPortableExecutableEntry{ AssemblyVersion: versionResources["Assembly Version"], LegalCopyright: versionResources["LegalCopyright"], @@ -91,7 +82,7 @@ func buildDotNetPackage(versionResources map[string]string, f file.LocationReadC Locations: file.NewLocationSet(f.Location.WithAnnotation(pkg.EvidenceAnnotationKey, pkg.PrimaryEvidenceAnnotation)), Type: pkg.DotnetPkg, Language: pkg.Dotnet, - PURL: purl, + PURL: portableExecutablePackageURL(name, version), Metadata: metadata, } @@ -100,30 +91,128 @@ func buildDotNetPackage(versionResources map[string]string, f file.LocationReadC return dnpkg, nil } -func findVersion(versionResources map[string]string) string { - for _, key := range []string{"FileVersion"} { - if version, ok := versionResources[key]; ok { - if strings.TrimSpace(version) == "" { - continue - } - fields := strings.Fields(version) - if len(fields) > 0 { - return fields[0] - } +func portableExecutablePackageURL(name, version string) string { + return packageurl.NewPackageURL( + packageurl.TypeNuget, // See explanation in syft/pkg/cataloger/dotnet/package.go as to why this was chosen. + "", + name, + version, + nil, + "", + ).ToString() +} + +func extractVersion(version string) string { + version = strings.TrimSpace(version) + + out := "" + + // some example versions are: "1, 0, 0, 0", "Release 73" or "4.7.4076.0 built by: NET472REL1LAST_B" + // so try to split it and take the first parts that look numeric + for i, f := range strings.Fields(version) { + // if the output already has a number but the current segment does not have a number, + // return what we found for the version + if containsNumber(out) && !containsNumber(f) { + return out + } + + if i == 0 { + out = f + } else { + out += " " + f } } - return "" + + return out } +func findVersion(versionResources map[string]string) string { + productVersion := extractVersion(versionResources["ProductVersion"]) + fileVersion := extractVersion(versionResources["FileVersion"]) + + if productVersion == "" { + return fileVersion + } + + productVersionDetail := punctuationCount(productVersion) + fileVersionDetail := punctuationCount(fileVersion) + + if containsNumber(productVersion) && productVersionDetail >= fileVersionDetail { + return productVersion + } + + if containsNumber(fileVersion) && fileVersionDetail > 0 { + return fileVersion + } + + if containsNumber(productVersion) { + return productVersion + } + + if containsNumber(fileVersion) { + return fileVersion + } + + return productVersion +} + +func containsNumber(s string) bool { + return numberRegex.MatchString(s) +} + +func punctuationCount(s string) int { + return len(versionPunctuationRegex.FindAllString(s, -1)) +} + +var ( + // spaceRegex includes nbsp (#160) considered to be a space character + spaceRegex = regexp.MustCompile(`[\s\xa0]+`) + numberRegex = regexp.MustCompile(`\d`) + versionPunctuationRegex = regexp.MustCompile(`[.,]+`) +) + func findName(versionResources map[string]string) string { - for _, key := range []string{"FileDescription", "ProductName"} { - if name, ok := versionResources[key]; ok { - if strings.TrimSpace(name) == "" { - continue - } - trimmed := strings.TrimSpace(name) - return regexp.MustCompile(`[^a-zA-Z0-9.]+`).ReplaceAllString(trimmed, "") + // PE files found in the wild _not_ authored by Microsoft seem to use ProductName as a clear + // identifier of the software + nameFields := []string{"ProductName", "FileDescription", "InternalName", "OriginalFilename"} + + if isMicrosoft(versionResources) { + // Microsoft seems to be consistent using the FileDescription, with a few that are blank and have + // fallbacks to ProductName last, as this is often something very broad like "Microsoft Windows" + nameFields = []string{"FileDescription", "InternalName", "OriginalFilename", "ProductName"} + } + + for _, field := range nameFields { + value := spaceNormalize(versionResources[field]) + if value == "" { + continue } + return value } + return "" } + +// normalizes a string to a trimmed version with all contigous whitespace collapsed to a single space character +func spaceNormalize(value string) string { + value = strings.TrimSpace(value) + if value == "" { + return "" + } + // ensure valid utf8 text + value = strings.ToValidUTF8(value, "") + // consolidate all space characters + value = spaceRegex.ReplaceAllString(value, " ") + // remove other non-space, non-printable characters + value = regexp.MustCompile(`[\x00-\x1f]`).ReplaceAllString(value, "") + // consolidate all space characters again in case other non-printables were in-between + value = spaceRegex.ReplaceAllString(value, " ") + // finally, remove any remaining surrounding whitespace + value = strings.TrimSpace(value) + return value +} + +func isMicrosoft(versionResources map[string]string) bool { + return strings.Contains(strings.ToLower(versionResources["CompanyName"]), "microsoft") || + strings.Contains(strings.ToLower(versionResources["ProductName"]), "microsoft") +} diff --git a/vendor/github.com/anchore/syft/syft/pkg/cataloger/golang/licenses.go b/vendor/github.com/anchore/syft/syft/pkg/cataloger/golang/licenses.go index 3787f427..c21937bb 100644 --- a/vendor/github.com/anchore/syft/syft/pkg/cataloger/golang/licenses.go +++ b/vendor/github.com/anchore/syft/syft/pkg/cataloger/golang/licenses.go @@ -20,6 +20,7 @@ import ( "github.com/go-git/go-git/v5/storage/memory" "github.com/scylladb/go-set/strset" + "github.com/anchore/syft/internal/bus" "github.com/anchore/syft/internal/licenses" "github.com/anchore/syft/internal/log" "github.com/anchore/syft/syft/event/monitor" @@ -31,7 +32,6 @@ import ( type goLicenses struct { opts CatalogerConfig localModCacheResolver file.WritableResolver - progress *monitor.CatalogerTask lowerLicenseFileNames *strset.Set } @@ -39,11 +39,6 @@ func newGoLicenses(opts CatalogerConfig) goLicenses { return goLicenses{ opts: opts, localModCacheResolver: modCacheResolver(opts.LocalModCacheDir), - progress: &monitor.CatalogerTask{ - SubStatus: true, - RemoveOnCompletion: true, - Title: "Downloading go mod", - }, lowerLicenseFileNames: strset.New(lowercaseLicenseFiles()...), } } @@ -123,7 +118,16 @@ func (c *goLicenses) getLicensesFromRemote(moduleName, moduleVersion string) ([] proxies := remotesForModule(c.opts.Proxies, c.opts.NoProxy, moduleName) - fsys, err := getModule(c.progress, proxies, moduleName, moduleVersion) + prog := bus.StartCatalogerTask(monitor.GenericTask{ + Title: monitor.Title{ + Default: "Download go mod", + WhileRunning: "Downloading go mod", + OnSuccess: "Downloaded go mod", + }, + HideOnSuccess: true, + }, -1, "") + + fsys, err := getModule(prog, proxies, moduleName, moduleVersion) if err != nil { return nil, err } @@ -206,7 +210,7 @@ func processCaps(s string) string { }) } -func getModule(progress *monitor.CatalogerTask, proxies []string, moduleName, moduleVersion string) (fsys fs.FS, err error) { +func getModule(progress *monitor.CatalogerTaskProgress, proxies []string, moduleName, moduleVersion string) (fsys fs.FS, err error) { for _, proxy := range proxies { u, _ := url.Parse(proxy) if proxy == "direct" { @@ -218,7 +222,7 @@ func getModule(progress *monitor.CatalogerTask, proxies []string, moduleName, mo fsys, err = getModuleProxy(progress, proxy, moduleName, moduleVersion) case "file": p := filepath.Join(u.Path, moduleName, "@v", moduleVersion) - progress.SetValue(fmt.Sprintf("file: %s", p)) + progress.AtomicStage.Set(fmt.Sprintf("file: %s", p)) fsys = os.DirFS(p) } if fsys != nil { @@ -228,9 +232,9 @@ func getModule(progress *monitor.CatalogerTask, proxies []string, moduleName, mo return } -func getModuleProxy(progress *monitor.CatalogerTask, proxy string, moduleName string, moduleVersion string) (out fs.FS, _ error) { +func getModuleProxy(progress *monitor.CatalogerTaskProgress, proxy string, moduleName string, moduleVersion string) (out fs.FS, _ error) { u := fmt.Sprintf("%s/%s/@v/%s.zip", proxy, moduleName, moduleVersion) - progress.SetValue(u) + progress.AtomicStage.Set(u) // get the module zip resp, err := http.Get(u) //nolint:gosec @@ -241,7 +245,7 @@ func getModuleProxy(progress *monitor.CatalogerTask, proxy string, moduleName st if resp.StatusCode != http.StatusOK { u = fmt.Sprintf("%s/%s/@v/%s.zip", proxy, strings.ToLower(moduleName), moduleVersion) - progress.SetValue(u) + progress.AtomicStage.Set(u) // try lowercasing it; some packages have mixed casing that really messes up the proxy resp, err = http.Get(u) //nolint:gosec @@ -284,14 +288,14 @@ func findVersionPath(f fs.FS, dir string) string { return "" } -func getModuleRepository(progress *monitor.CatalogerTask, moduleName string, moduleVersion string) (fs.FS, error) { +func getModuleRepository(progress *monitor.CatalogerTaskProgress, moduleName string, moduleVersion string) (fs.FS, error) { repoName := moduleName parts := strings.Split(moduleName, "/") if len(parts) > 2 { repoName = fmt.Sprintf("%s/%s/%s", parts[0], parts[1], parts[2]) } - progress.SetValue(fmt.Sprintf("git: %s", repoName)) + progress.AtomicStage.Set(fmt.Sprintf("git: %s", repoName)) f := memfs.New() buf := &bytes.Buffer{} diff --git a/vendor/github.com/anchore/syft/syft/pkg/cataloger/haskell/parse_stack_lock.go b/vendor/github.com/anchore/syft/syft/pkg/cataloger/haskell/parse_stack_lock.go index 40dc6aa6..62ee5bc1 100644 --- a/vendor/github.com/anchore/syft/syft/pkg/cataloger/haskell/parse_stack_lock.go +++ b/vendor/github.com/anchore/syft/syft/pkg/cataloger/haskell/parse_stack_lock.go @@ -63,6 +63,9 @@ func parseStackLock(_ file.Resolver, _ *generic.Environment, reader file.Locatio } for _, pack := range lockFile.Packages { + if pack.Completed.Hackage == "" { + continue + } pkgName, pkgVersion, pkgHash := parseStackPackageEncoding(pack.Completed.Hackage) pkgs = append( pkgs, @@ -80,13 +83,20 @@ func parseStackLock(_ file.Resolver, _ *generic.Environment, reader file.Locatio return pkgs, nil, nil } + func parseStackPackageEncoding(pkgEncoding string) (name, version, hash string) { lastDashIdx := strings.LastIndex(pkgEncoding, "-") + if lastDashIdx == -1 { + name = pkgEncoding + return + } name = pkgEncoding[:lastDashIdx] remainingEncoding := pkgEncoding[lastDashIdx+1:] encodingSplits := strings.Split(remainingEncoding, "@") version = encodingSplits[0] - startHash, endHash := strings.Index(encodingSplits[1], ":")+1, strings.Index(encodingSplits[1], ",") - hash = encodingSplits[1][startHash:endHash] + if len(encodingSplits) > 1 { + startHash, endHash := strings.Index(encodingSplits[1], ":")+1, strings.Index(encodingSplits[1], ",") + hash = encodingSplits[1][startHash:endHash] + } return } diff --git a/vendor/github.com/anchore/syft/syft/pkg/cataloger/java/archive_parser.go b/vendor/github.com/anchore/syft/syft/pkg/cataloger/java/archive_parser.go index dac3e676..c423be76 100644 --- a/vendor/github.com/anchore/syft/syft/pkg/cataloger/java/archive_parser.go +++ b/vendor/github.com/anchore/syft/syft/pkg/cataloger/java/archive_parser.go @@ -3,15 +3,9 @@ package java import ( "crypto" "fmt" - "io" - "net/http" - "net/url" "os" "path" "strings" - "time" - - "github.com/vifraa/gopom" intFile "github.com/anchore/syft/internal/file" "github.com/anchore/syft/internal/licenses" @@ -263,19 +257,13 @@ func findLicenseFromJavaMetadata(name string, manifest *pkg.JavaManifest, versio if gID := groupIDFromJavaMetadata(name, pkg.JavaArchive{Manifest: manifest}); gID != "" { groupID = gID } - pomLicenses, err := recursivelyFindLicensesFromParentPom(groupID, name, version, j.cfg) - if err != nil { - log.Tracef("unable to get parent pom from Maven central: %v", err) - } + pomLicenses := recursivelyFindLicensesFromParentPom(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, err = recursivelyFindLicensesFromParentPom(groupID, name, version, j.cfg) - if err != nil { - log.Tracef("unable to get parent pom from Maven central: %v", err) - } + pomLicenses = recursivelyFindLicensesFromParentPom(groupID, name, version, j.cfg) } if len(pomLicenses) > 0 { @@ -320,8 +308,18 @@ func (j *archiveParser) guessMainPackageNameAndVersionFromPomInfo() (name, versi if version == "" && pomProjectObject != nil { version = pomProjectObject.Version } - if pomProjectObject != nil && j.cfg.UseNetwork { - findPomLicenses(pomProjectObject, j.cfg) + if j.cfg.UseNetwork { + if pomProjectObject == nil { + // If we have no pom.xml, check maven central using pom.properties + parentLicenses := recursivelyFindLicensesFromParentPom(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(pomProjectObject, j.cfg) + } } if pomProjectObject != nil { @@ -341,16 +339,12 @@ func artifactIDMatchesFilename(artifactID, fileName string) bool { func findPomLicenses(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, err := recursivelyFindLicensesFromParentPom( + parentLicenses := recursivelyFindLicensesFromParentPom( pomProjectObject.Parent.GroupID, pomProjectObject.Parent.ArtifactID, pomProjectObject.Parent.Version, cfg) - 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 - } + if len(parentLicenses) > 0 { for _, licenseName := range parentLicenses { pomProjectObject.Licenses = append(pomProjectObject.Licenses, pkg.NewLicenseFromFields(licenseName, "", nil)) @@ -359,96 +353,6 @@ func findPomLicenses(pomProjectObject *parsedPomProject, cfg ArchiveCatalogerCon } } -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 -} - -func recursivelyFindLicensesFromParentPom(groupID, artifactID, version string, cfg ArchiveCatalogerConfig) ([]string, error) { - 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(groupID, artifactID, version, cfg.MavenBaseURL) - if err != nil { - return nil, err - } - 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, nil -} - -func getPomFromMavenRepo(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, - } - - 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 -} - // 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 @@ -693,10 +597,22 @@ func newPackageFromMavenData(pomProperties pkg.JavaPomProperties, parsedPomProje var pkgPomProject *pkg.JavaPomProject licenses := make([]pkg.License, 0) - if parsedPomProject != nil { - if cfg.UseNetwork { + + if cfg.UseNetwork { + if parsedPomProject == nil { + // If we have no pom.xml, check maven central using pom.properties + parentLicenses := recursivelyFindLicensesFromParentPom(pomProperties.GroupID, pomProperties.ArtifactID, pomProperties.Version, cfg) + if len(parentLicenses) > 0 { + for _, licenseName := range parentLicenses { + licenses = append(licenses, pkg.NewLicenseFromFields(licenseName, "", nil)) + } + } + } else { findPomLicenses(parsedPomProject, cfg) } + } + + if parsedPomProject != nil { pkgPomProject = parsedPomProject.JavaPomProject licenses = append(licenses, parsedPomProject.Licenses...) } diff --git a/vendor/github.com/anchore/syft/syft/pkg/cataloger/java/cataloger.go b/vendor/github.com/anchore/syft/syft/pkg/cataloger/java/cataloger.go index 6764109b..fa8560ec 100644 --- a/vendor/github.com/anchore/syft/syft/pkg/cataloger/java/cataloger.go +++ b/vendor/github.com/anchore/syft/syft/pkg/cataloger/java/cataloger.go @@ -31,9 +31,11 @@ func NewArchiveCataloger(cfg ArchiveCatalogerConfig) *generic.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() pkg.Cataloger { +func NewPomCataloger(cfg ArchiveCatalogerConfig) pkg.Cataloger { + gap := newGenericArchiveParserAdapter(cfg) + return generic.NewCataloger("java-pom-cataloger"). - WithParserByGlobs(parserPomXML, "**/pom.xml") + WithParserByGlobs(gap.parserPomXML, "**/pom.xml") } // NewGradleLockfileCataloger returns a cataloger capable of parsing dependencies from a gradle.lockfile file. diff --git a/vendor/github.com/anchore/syft/syft/pkg/cataloger/java/config.go b/vendor/github.com/anchore/syft/syft/pkg/cataloger/java/config.go index 132f6024..14c31d33 100644 --- a/vendor/github.com/anchore/syft/syft/pkg/cataloger/java/config.go +++ b/vendor/github.com/anchore/syft/syft/pkg/cataloger/java/config.go @@ -13,10 +13,7 @@ type ArchiveCatalogerConfig struct { func DefaultArchiveCatalogerConfig() ArchiveCatalogerConfig { return ArchiveCatalogerConfig{ - ArchiveSearchConfig: cataloging.ArchiveSearchConfig{ - IncludeIndexedArchives: true, - IncludeUnindexedArchives: false, - }, + ArchiveSearchConfig: cataloging.DefaultArchiveSearchConfig(), UseNetwork: false, MavenBaseURL: mavenBaseURL, MaxParentRecursiveDepth: 5, diff --git a/vendor/github.com/anchore/syft/syft/pkg/cataloger/java/maven_repo_utils.go b/vendor/github.com/anchore/syft/syft/pkg/cataloger/java/maven_repo_utils.go new file mode 100644 index 00000000..126037c2 --- /dev/null +++ b/vendor/github.com/anchore/syft/syft/pkg/cataloger/java/maven_repo_utils.go @@ -0,0 +1,133 @@ +package java + +import ( + "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(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(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(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(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(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, + } + + 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/vendor/github.com/anchore/syft/syft/pkg/cataloger/java/parse_java_manifest.go b/vendor/github.com/anchore/syft/syft/pkg/cataloger/java/parse_java_manifest.go index 14a3a363..50088111 100644 --- a/vendor/github.com/anchore/syft/syft/pkg/cataloger/java/parse_java_manifest.go +++ b/vendor/github.com/anchore/syft/syft/pkg/cataloger/java/parse_java_manifest.go @@ -153,6 +153,22 @@ func extractNameFromApacheMavenBundlePlugin(manifest *pkg.JavaManifest) string { return "" } +func extractNameFromArchiveFilename(a archiveFilename) string { + if strings.Contains(a.name, ".") { + // special case: this *might* be a group id + artifact id. By convention artifact ids do not have "." in them; + // however, there are some specific exceptions like with the artifacts under + // https://repo1.maven.org/maven2/org/eclipse/platform/ + if strings.HasPrefix(a.name, "org.eclipse.") { + return a.name + } + + fields := strings.Split(a.name, ".") + return fields[len(fields)-1] + } + + return a.name +} + func selectName(manifest *pkg.JavaManifest, filenameObj archiveFilename) string { name := extractNameFromApacheMavenBundlePlugin(manifest) if name != "" { @@ -160,13 +176,9 @@ func selectName(manifest *pkg.JavaManifest, filenameObj archiveFilename) string } // the filename tends to be the next-best reference for the package name - if filenameObj.name != "" { - if strings.Contains(filenameObj.name, ".") { - // special case: this *might* be a group id + artifact id. By convention artifact ids do not have "." in them. - fields := strings.Split(filenameObj.name, ".") - return fields[len(fields)-1] - } - return filenameObj.name + name = extractNameFromArchiveFilename(filenameObj) + if name != "" { + return name } // remaining fields in the manifest is a bit of a free-for-all depending on the build tooling used and package maintainer preferences diff --git a/vendor/github.com/anchore/syft/syft/pkg/cataloger/java/parse_pom_xml.go b/vendor/github.com/anchore/syft/syft/pkg/cataloger/java/parse_pom_xml.go index 75376521..b3c6f2b6 100644 --- a/vendor/github.com/anchore/syft/syft/pkg/cataloger/java/parse_pom_xml.go +++ b/vendor/github.com/anchore/syft/syft/pkg/cataloger/java/parse_pom_xml.go @@ -24,7 +24,7 @@ const pomXMLGlob = "*pom.xml" var propertyMatcher = regexp.MustCompile("[$][{][^}]+[}]") -func parserPomXML(_ file.Resolver, _ *generic.Environment, reader file.LocationReadCloser) ([]pkg.Package, []artifact.Relationship, error) { +func (gap genericArchiveParserAdapter) parserPomXML(_ file.Resolver, _ *generic.Environment, reader file.LocationReadCloser) ([]pkg.Package, []artifact.Relationship, error) { pom, err := decodePomXML(reader) if err != nil { return nil, nil, err @@ -36,6 +36,7 @@ func parserPomXML(_ file.Resolver, _ *generic.Environment, reader file.LocationR p := newPackageFromPom( pom, dep, + gap.cfg, reader.Location.WithAnnotation(pkg.EvidenceAnnotationKey, pkg.PrimaryEvidenceAnnotation), ) if p.Name == "" { @@ -97,7 +98,7 @@ func newPomProject(path string, p gopom.Project, location file.Location) *parsed } } -func newPackageFromPom(pom gopom.Project, dep gopom.Dependency, locations ...file.Location) pkg.Package { +func newPackageFromPom(pom gopom.Project, dep gopom.Dependency, cfg ArchiveCatalogerConfig, locations ...file.Location) pkg.Package { m := pkg.JavaArchive{ PomProperties: &pkg.JavaPomProperties{ GroupID: resolveProperty(pom, dep.GroupID, "groupId"), @@ -109,10 +110,32 @@ func newPackageFromPom(pom gopom.Project, dep gopom.Dependency, locations ...fil name := safeString(dep.ArtifactID) version := resolveProperty(pom, dep.Version, "version") + 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(*dep.GroupID, *dep.ArtifactID, *pom.Parent.GroupID, *pom.Parent.ArtifactID, *pom.Parent.Version, cfg) + } + if version != "" { + parentLicenses := recursivelyFindLicensesFromParentPom( + m.PomProperties.GroupID, + m.PomProperties.ArtifactID, + version, + cfg) + + if len(parentLicenses) > 0 { + for _, licenseName := range parentLicenses { + licenses = append(licenses, pkg.NewLicenseFromFields(licenseName, "", nil)) + } + } + } + } + p := pkg.Package{ Name: name, Version: version, Locations: file.NewLocationSet(locations...), + Licenses: pkg.NewLicenseSet(licenses...), PURL: packageURL(name, 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? diff --git a/vendor/github.com/anchore/syft/syft/pkg/cataloger/javascript/cataloger.go b/vendor/github.com/anchore/syft/syft/pkg/cataloger/javascript/cataloger.go index 8d6c0de1..256c759d 100644 --- a/vendor/github.com/anchore/syft/syft/pkg/cataloger/javascript/cataloger.go +++ b/vendor/github.com/anchore/syft/syft/pkg/cataloger/javascript/cataloger.go @@ -15,9 +15,10 @@ func NewPackageCataloger() pkg.Cataloger { } // NewLockCataloger returns a new cataloger object for NPM (and NPM-adjacent, such as yarn) lock files. -func NewLockCataloger() pkg.Cataloger { +func NewLockCataloger(cfg CatalogerConfig) pkg.Cataloger { + yarnLockAdapter := newGenericYarnLockAdapter(cfg) return generic.NewCataloger("javascript-lock-cataloger"). WithParserByGlobs(parsePackageLock, "**/package-lock.json"). - WithParserByGlobs(parseYarnLock, "**/yarn.lock"). + WithParserByGlobs(yarnLockAdapter.parseYarnLock, "**/yarn.lock"). WithParserByGlobs(parsePnpmLock, "**/pnpm-lock.yaml") } diff --git a/vendor/github.com/anchore/syft/syft/pkg/cataloger/javascript/config.go b/vendor/github.com/anchore/syft/syft/pkg/cataloger/javascript/config.go new file mode 100644 index 00000000..f73e1899 --- /dev/null +++ b/vendor/github.com/anchore/syft/syft/pkg/cataloger/javascript/config.go @@ -0,0 +1,27 @@ +package javascript + +const npmBaseURL = "https://registry.npmjs.org" + +type CatalogerConfig struct { + 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"` +} + +func DefaultCatalogerConfig() CatalogerConfig { + return CatalogerConfig{ + SearchRemoteLicenses: false, + NPMBaseURL: npmBaseURL, + } +} + +func (j CatalogerConfig) WithSearchRemoteLicenses(input bool) CatalogerConfig { + j.SearchRemoteLicenses = input + return j +} + +func (j CatalogerConfig) WithNpmBaseURL(input string) CatalogerConfig { + if input != "" { + j.NPMBaseURL = input + } + return j +} diff --git a/vendor/github.com/anchore/syft/syft/pkg/cataloger/javascript/package.go b/vendor/github.com/anchore/syft/syft/pkg/cataloger/javascript/package.go index 9a1331ac..990f5b01 100644 --- a/vendor/github.com/anchore/syft/syft/pkg/cataloger/javascript/package.go +++ b/vendor/github.com/anchore/syft/syft/pkg/cataloger/javascript/package.go @@ -2,9 +2,13 @@ package javascript import ( "encoding/json" + "fmt" "io" + "net/http" + "net/url" "path" "strings" + "time" "github.com/anchore/packageurl-go" "github.com/anchore/syft/internal/log" @@ -106,13 +110,27 @@ func newPnpmPackage(resolver file.Resolver, location file.Location, name, versio ) } -func newYarnLockPackage(resolver file.Resolver, location file.Location, name, version string) pkg.Package { +func newYarnLockPackage(cfg CatalogerConfig, resolver file.Resolver, location file.Location, name, version string) pkg.Package { + var licenseSet pkg.LicenseSet + + if cfg.SearchRemoteLicenses { + license, err := getLicenseFromNpmRegistry(cfg.NPMBaseURL, name, version) + if err == nil && license != "" { + licenses := pkg.NewLicensesFromValues(license) + licenseSet = pkg.NewLicenseSet(licenses...) + } + if err != nil { + log.Warnf("unable to extract licenses from javascript yarn.lock for package %s:%s: %+v", name, version, err) + } + } + return finalizeLockPkg( resolver, location, pkg.Package{ Name: name, Version: version, + Licenses: licenseSet, Locations: file.NewLocationSet(location.WithAnnotation(pkg.EvidenceAnnotationKey, pkg.PrimaryEvidenceAnnotation)), PURL: packageURL(name, version), Language: pkg.JavaScript, @@ -121,6 +139,63 @@ func newYarnLockPackage(resolver file.Resolver, location file.Location, name, ve ) } +func formatNpmRegistryURL(baseURL, packageName, version string) (requestURL string, err error) { + urlPath := []string{packageName, version} + requestURL, err = url.JoinPath(baseURL, urlPath...) + if err != nil { + return requestURL, fmt.Errorf("unable to format npm request for pkg:version %s%s; %w", packageName, version, err) + } + return requestURL, nil +} + +func getLicenseFromNpmRegistry(basURL, packageName, version string) (string, error) { + // "https://registry.npmjs.org/%s/%s", packageName, version + requestURL, err := formatNpmRegistryURL(basURL, 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) + + npmRequest, err := http.NewRequest(http.MethodGet, requestURL, nil) + if err != nil { + return "", fmt.Errorf("unable to format remote request: %w", err) + } + + httpClient := &http.Client{ + Timeout: time.Second * 10, + } + + resp, err := httpClient.Do(npmRequest) + if err != nil { + return "", fmt.Errorf("unable to get package from npm registry: %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 "", fmt.Errorf("unable to parse package from npm registry: %w", err) + } + + dec := json.NewDecoder(strings.NewReader(string(bytes))) + + // Read "license" from the response + var license struct { + License string `json:"license"` + } + + if err := dec.Decode(&license); err != nil { + return "", fmt.Errorf("unable to parse license from npm registry: %w", err) + } + + log.Tracef("Retrieved License: %s", license.License) + + return license.License, nil +} + func finalizeLockPkg(resolver file.Resolver, location file.Location, p pkg.Package) pkg.Package { licenseCandidate := addLicenses(p.Name, resolver, location) p.Licenses.Add(pkg.NewLicensesFromLocation(location, licenseCandidate...)...) diff --git a/vendor/github.com/anchore/syft/syft/pkg/cataloger/javascript/parse_yarn_lock.go b/vendor/github.com/anchore/syft/syft/pkg/cataloger/javascript/parse_yarn_lock.go index d42490ed..fdbc51b2 100644 --- a/vendor/github.com/anchore/syft/syft/pkg/cataloger/javascript/parse_yarn_lock.go +++ b/vendor/github.com/anchore/syft/syft/pkg/cataloger/javascript/parse_yarn_lock.go @@ -13,9 +13,6 @@ import ( "github.com/anchore/syft/syft/pkg/cataloger/generic" ) -// integrity check -var _ generic.Parser = parseYarnLock - var ( // packageNameExp matches the name of the dependency in yarn.lock // including scope/namespace prefix if found. @@ -43,7 +40,17 @@ const ( noVersion = "" ) -func parseYarnLock(resolver file.Resolver, _ *generic.Environment, reader file.LocationReadCloser) ([]pkg.Package, []artifact.Relationship, error) { +type genericYarnLockAdapter struct { + cfg CatalogerConfig +} + +func newGenericYarnLockAdapter(cfg CatalogerConfig) genericYarnLockAdapter { + return genericYarnLockAdapter{ + cfg: cfg, + } +} + +func (a genericYarnLockAdapter) parseYarnLock(resolver file.Resolver, _ *generic.Environment, reader file.LocationReadCloser) ([]pkg.Package, []artifact.Relationship, error) { // in the case we find yarn.lock files in the node_modules directories, skip those // as the whole purpose of the lock file is for the specific dependencies of the project if pathContainsNodeModulesDirectory(reader.Path()) { @@ -62,7 +69,7 @@ func parseYarnLock(resolver file.Resolver, _ *generic.Environment, reader file.L if packageName := findPackageName(line); packageName != noPackage { // When we find a new package, check if we have unsaved identifiers if currentPackage != noPackage && currentVersion != noVersion && !parsedPackages.Has(currentPackage+"@"+currentVersion) { - pkgs = append(pkgs, newYarnLockPackage(resolver, reader.Location, currentPackage, currentVersion)) + pkgs = append(pkgs, newYarnLockPackage(a.cfg, resolver, reader.Location, currentPackage, currentVersion)) parsedPackages.Add(currentPackage + "@" + currentVersion) } @@ -70,7 +77,7 @@ func parseYarnLock(resolver file.Resolver, _ *generic.Environment, reader file.L } else if version := findPackageVersion(line); version != noVersion { currentVersion = version } else if packageName, version := findPackageAndVersion(line); packageName != noPackage && version != noVersion && !parsedPackages.Has(packageName+"@"+version) { - pkgs = append(pkgs, newYarnLockPackage(resolver, reader.Location, packageName, version)) + pkgs = append(pkgs, newYarnLockPackage(a.cfg, resolver, reader.Location, packageName, version)) parsedPackages.Add(packageName + "@" + version) // Cleanup to indicate no unsaved identifiers @@ -81,7 +88,7 @@ func parseYarnLock(resolver file.Resolver, _ *generic.Environment, reader file.L // check if we have valid unsaved data after end-of-file has reached if currentPackage != noPackage && currentVersion != noVersion && !parsedPackages.Has(currentPackage+"@"+currentVersion) { - pkgs = append(pkgs, newYarnLockPackage(resolver, reader.Location, currentPackage, currentVersion)) + pkgs = append(pkgs, newYarnLockPackage(a.cfg, resolver, reader.Location, currentPackage, currentVersion)) parsedPackages.Add(currentPackage + "@" + currentVersion) } diff --git a/vendor/github.com/anchore/syft/syft/pkg/cataloger/python/package.go b/vendor/github.com/anchore/syft/syft/pkg/cataloger/python/package.go index 59fd9f6b..7e6f39a2 100644 --- a/vendor/github.com/anchore/syft/syft/pkg/cataloger/python/package.go +++ b/vendor/github.com/anchore/syft/syft/pkg/cataloger/python/package.go @@ -4,6 +4,8 @@ import ( "fmt" "github.com/anchore/packageurl-go" + "github.com/anchore/syft/internal/licenses" + "github.com/anchore/syft/internal/log" "github.com/anchore/syft/syft/file" "github.com/anchore/syft/syft/pkg" ) @@ -55,13 +57,42 @@ func newPackageForRequirementsWithMetadata(name, version string, metadata pkg.Py return p } -func newPackageForPackage(m parsedData, sources ...file.Location) pkg.Package { +func newPackageForPackage(resolver file.Resolver, m parsedData, sources ...file.Location) pkg.Package { + var licenseSet pkg.LicenseSet + + switch { + case m.LicenseExpression != "": + licenseSet = pkg.NewLicenseSet(pkg.NewLicensesFromLocation(m.LicenseLocation, m.LicenseExpression)...) + case m.Licenses != "": + licenseSet = pkg.NewLicenseSet(pkg.NewLicensesFromLocation(m.LicenseLocation, m.Licenses)...) + case m.LicenseLocation.Path() != "": + // If we have a license file then resolve and parse it + found, err := resolver.FilesByPath(m.LicenseLocation.Path()) + if err != nil { + log.WithFields("error", err).Tracef("unable to resolve python license path %s", m.LicenseLocation.Path()) + } + if len(found) > 0 { + metadataContents, err := resolver.FileContentsByLocation(found[0]) + if err == nil { + parsed, err := licenses.Parse(metadataContents, m.LicenseLocation) + if err != nil { + log.WithFields("error", err).Tracef("unable to parse a license from the file in %s", m.LicenseLocation.Path()) + } + if len(parsed) > 0 { + licenseSet = pkg.NewLicenseSet(parsed...) + } + } else { + log.WithFields("error", err).Tracef("unable to read file contents at %s", m.LicenseLocation.Path()) + } + } + } + p := pkg.Package{ Name: m.Name, Version: m.Version, PURL: packageURL(m.Name, m.Version, &m.PythonPackage), Locations: file.NewLocationSet(sources...), - Licenses: pkg.NewLicenseSet(pkg.NewLicensesFromLocation(m.LicenseLocation, m.Licenses)...), + Licenses: licenseSet, Language: pkg.Python, Type: pkg.PythonPkg, Metadata: m.PythonPackage, diff --git a/vendor/github.com/anchore/syft/syft/pkg/cataloger/python/parse_wheel_egg.go b/vendor/github.com/anchore/syft/syft/pkg/cataloger/python/parse_wheel_egg.go index e98fe9de..a50f9d55 100644 --- a/vendor/github.com/anchore/syft/syft/pkg/cataloger/python/parse_wheel_egg.go +++ b/vendor/github.com/anchore/syft/syft/pkg/cataloger/python/parse_wheel_egg.go @@ -32,7 +32,7 @@ func parseWheelOrEgg(resolver file.Resolver, _ *generic.Environment, reader file return nil, nil, nil } - pkgs := []pkg.Package{newPackageForPackage(*pd, sources...)} + pkgs := []pkg.Package{newPackageForPackage(resolver, *pd, sources...)} return pkgs, nil, nil } diff --git a/vendor/github.com/anchore/syft/syft/pkg/cataloger/python/parse_wheel_egg_metadata.go b/vendor/github.com/anchore/syft/syft/pkg/cataloger/python/parse_wheel_egg_metadata.go index a5211999..4522dd45 100644 --- a/vendor/github.com/anchore/syft/syft/pkg/cataloger/python/parse_wheel_egg_metadata.go +++ b/vendor/github.com/anchore/syft/syft/pkg/cataloger/python/parse_wheel_egg_metadata.go @@ -17,6 +17,8 @@ import ( type parsedData struct { Licenses string `mapstructure:"License"` + LicenseFile string `mapstructure:"LicenseFile"` + LicenseExpression string `mapstructure:"LicenseExpression"` LicenseLocation file.Location pkg.PythonPackage `mapstructure:",squash"` } @@ -80,8 +82,10 @@ func parseWheelOrEggMetadata(path string, reader io.Reader) (parsedData, error) // add additional metadata not stored in the egg/wheel metadata file pd.SitePackagesRootPath = determineSitePackagesRootPath(path) - if pd.Licenses != "" { + if pd.Licenses != "" || pd.LicenseExpression != "" { pd.LicenseLocation = file.NewLocation(path) + } else if pd.LicenseFile != "" { + pd.LicenseLocation = file.NewLocation(filepath.Join(filepath.Dir(path), pd.LicenseFile)) } return pd, nil diff --git a/vendor/github.com/anchore/syft/syft/pkg/collection.go b/vendor/github.com/anchore/syft/syft/pkg/collection.go index 10a3ed64..7ed028b2 100644 --- a/vendor/github.com/anchore/syft/syft/pkg/collection.go +++ b/vendor/github.com/anchore/syft/syft/pkg/collection.go @@ -21,7 +21,7 @@ type Collection struct { // NewCollection returns a new empty Collection func NewCollection(pkgs ...Package) *Collection { - catalog := Collection{ + c := Collection{ byID: make(map[artifact.ID]Package), idsByName: make(map[string]orderedIDSet), idsByType: make(map[Type]orderedIDSet), @@ -29,10 +29,10 @@ func NewCollection(pkgs ...Package) *Collection { } for _, p := range pkgs { - catalog.Add(p) + c.Add(p) } - return &catalog + return &c } // PackageCount returns the total number of packages that have been added. @@ -97,32 +97,37 @@ func (c *Collection) packages(ids []artifact.ID) (result []Package) { return result } -// Add n packages to the catalog. +// Add n packages to the collection. func (c *Collection) Add(pkgs ...Package) { + for _, p := range pkgs { + c.add(p) + } +} + +// Add a package to the Collection. +func (c *Collection) add(p Package) { c.lock.Lock() defer c.lock.Unlock() - for _, p := range pkgs { - id := p.ID() - if id == "" { - log.Warnf("found package with empty ID while adding to the catalog: %+v", p) - p.SetID() - id = p.ID() - } + id := p.ID() + if id == "" { + log.Warnf("found package with empty ID while adding to the collection: %+v", p) + p.SetID() + id = p.ID() + } - if existing, exists := c.byID[id]; exists { - // there is already a package with this fingerprint merge the existing record with the new one - if err := existing.merge(p); err != nil { - log.Warnf("failed to merge packages: %+v", err) - } else { - c.byID[id] = existing - c.addPathsToIndex(p) - } - return + if existing, exists := c.byID[id]; exists { + // there is already a package with this fingerprint merge the existing record with the new one + if err := existing.merge(p); err != nil { + log.Warnf("failed to merge packages: %+v", err) + } else { + c.byID[id] = existing + c.addPathsToIndex(p) } - - c.addToIndex(p) + return } + + c.addToIndex(p) } func (c *Collection) addToIndex(p Package) { @@ -242,7 +247,7 @@ func (c *Collection) Enumerate(types ...Type) <-chan Package { defer close(channel) if c == nil { - // we should allow enumerating from a catalog that was never created (which will result in no packages enumerated) + // we should allow enumerating from a collection that was never created (which will result in no packages enumerated) return } diff --git a/vendor/github.com/anchore/syft/syft/source/file_source.go b/vendor/github.com/anchore/syft/syft/source/file_source.go index fcccd592..c3a89668 100644 --- a/vendor/github.com/anchore/syft/syft/source/file_source.go +++ b/vendor/github.com/anchore/syft/syft/source/file_source.go @@ -189,7 +189,7 @@ func (s FileSource) FileResolver(_ Scope) (file.Resolver, error) { return fs.SkipDir } - if path.Base(p) != path.Base(s.config.Path) { + if filepath.Base(p) != filepath.Base(s.config.Path) { // we're in the root directory, but this is not the file we want to scan... // we should selectively skip this file (not the directory we're in). return fileresolver.ErrSkipPath diff --git a/vendor/github.com/go-git/go-git/v5/config/branch.go b/vendor/github.com/go-git/go-git/v5/config/branch.go index 652270a2..db2cb499 100644 --- a/vendor/github.com/go-git/go-git/v5/config/branch.go +++ b/vendor/github.com/go-git/go-git/v5/config/branch.go @@ -54,7 +54,7 @@ func (b *Branch) Validate() error { return errBranchInvalidRebase } - return nil + return plumbing.NewBranchReferenceName(b.Name).Validate() } func (b *Branch) marshal() *format.Subsection { diff --git a/vendor/github.com/go-git/go-git/v5/config/config.go b/vendor/github.com/go-git/go-git/v5/config/config.go index da425a78..6d41c15d 100644 --- a/vendor/github.com/go-git/go-git/v5/config/config.go +++ b/vendor/github.com/go-git/go-git/v5/config/config.go @@ -13,6 +13,7 @@ import ( "github.com/go-git/go-billy/v5/osfs" "github.com/go-git/go-git/v5/internal/url" + "github.com/go-git/go-git/v5/plumbing" format "github.com/go-git/go-git/v5/plumbing/format/config" ) @@ -614,7 +615,7 @@ func (c *RemoteConfig) Validate() error { c.Fetch = []RefSpec{RefSpec(fmt.Sprintf(DefaultFetchRefSpec, c.Name))} } - return nil + return plumbing.NewRemoteHEADReferenceName(c.Name).Validate() } func (c *RemoteConfig) unmarshal(s *format.Subsection) error { diff --git a/vendor/github.com/go-git/go-git/v5/plumbing/object/patch.go b/vendor/github.com/go-git/go-git/v5/plumbing/object/patch.go index 06bc35bb..dd8fef44 100644 --- a/vendor/github.com/go-git/go-git/v5/plumbing/object/patch.go +++ b/vendor/github.com/go-git/go-git/v5/plumbing/object/patch.go @@ -317,8 +317,8 @@ func getFileStatsFromFilePatches(filePatches []fdiff.FilePatch) FileStats { // File is deleted. cs.Name = from.Path() } else if from.Path() != to.Path() { - // File is renamed. Not supported. - // cs.Name = fmt.Sprintf("%s => %s", from.Path(), to.Path()) + // File is renamed. + cs.Name = fmt.Sprintf("%s => %s", from.Path(), to.Path()) } else { cs.Name = from.Path() } diff --git a/vendor/github.com/go-git/go-git/v5/plumbing/reference.go b/vendor/github.com/go-git/go-git/v5/plumbing/reference.go index 5a67f69e..ddba9302 100644 --- a/vendor/github.com/go-git/go-git/v5/plumbing/reference.go +++ b/vendor/github.com/go-git/go-git/v5/plumbing/reference.go @@ -3,6 +3,7 @@ package plumbing import ( "errors" "fmt" + "regexp" "strings" ) @@ -29,6 +30,9 @@ var RefRevParseRules = []string{ var ( ErrReferenceNotFound = errors.New("reference not found") + + // ErrInvalidReferenceName is returned when a reference name is invalid. + ErrInvalidReferenceName = errors.New("invalid reference name") ) // ReferenceType reference type's @@ -124,6 +128,91 @@ func (r ReferenceName) Short() string { return res } +var ( + ctrlSeqs = regexp.MustCompile(`[\000-\037\177]`) +) + +// Validate validates a reference name. +// This follows the git-check-ref-format rules. +// See https://git-scm.com/docs/git-check-ref-format +// +// It is important to note that this function does not check if the reference +// exists in the repository. +// It only checks if the reference name is valid. +// This functions does not support the --refspec-pattern, --normalize, and +// --allow-onelevel options. +// +// Git imposes the following rules on how references are named: +// +// 1. They can include slash / for hierarchical (directory) grouping, but no +// slash-separated component can begin with a dot . or end with the +// sequence .lock. +// 2. They must contain at least one /. This enforces the presence of a +// category like heads/, tags/ etc. but the actual names are not +// restricted. If the --allow-onelevel option is used, this rule is +// waived. +// 3. They cannot have two consecutive dots .. anywhere. +// 4. They cannot have ASCII control characters (i.e. bytes whose values are +// lower than \040, or \177 DEL), space, tilde ~, caret ^, or colon : +// anywhere. +// 5. They cannot have question-mark ?, asterisk *, or open bracket [ +// anywhere. See the --refspec-pattern option below for an exception to this +// rule. +// 6. They cannot begin or end with a slash / or contain multiple consecutive +// slashes (see the --normalize option below for an exception to this rule). +// 7. They cannot end with a dot .. +// 8. They cannot contain a sequence @{. +// 9. They cannot be the single character @. +// 10. They cannot contain a \. +func (r ReferenceName) Validate() error { + s := string(r) + if len(s) == 0 { + return ErrInvalidReferenceName + } + + // HEAD is a special case + if r == HEAD { + return nil + } + + // rule 7 + if strings.HasSuffix(s, ".") { + return ErrInvalidReferenceName + } + + // rule 2 + parts := strings.Split(s, "/") + if len(parts) < 2 { + return ErrInvalidReferenceName + } + + isBranch := r.IsBranch() + isTag := r.IsTag() + for _, part := range parts { + // rule 6 + if len(part) == 0 { + return ErrInvalidReferenceName + } + + if strings.HasPrefix(part, ".") || // rule 1 + strings.Contains(part, "..") || // rule 3 + ctrlSeqs.MatchString(part) || // rule 4 + strings.ContainsAny(part, "~^:?*[ \t\n") || // rule 4 & 5 + strings.Contains(part, "@{") || // rule 8 + part == "@" || // rule 9 + strings.Contains(part, "\\") || // rule 10 + strings.HasSuffix(part, ".lock") { // rule 1 + return ErrInvalidReferenceName + } + + if (isBranch || isTag) && strings.HasPrefix(part, "-") { // branches & tags can't start with - + return ErrInvalidReferenceName + } + } + + return nil +} + const ( HEAD ReferenceName = "HEAD" Master ReferenceName = "refs/heads/master" diff --git a/vendor/github.com/go-git/go-git/v5/remote.go b/vendor/github.com/go-git/go-git/v5/remote.go index 8ca9b102..0cb70bc0 100644 --- a/vendor/github.com/go-git/go-git/v5/remote.go +++ b/vendor/github.com/go-git/go-git/v5/remote.go @@ -1070,7 +1070,7 @@ func checkFastForwardUpdate(s storer.EncodedObjectStorer, remoteRefs storer.Refe return fmt.Errorf("non-fast-forward update: %s", cmd.Name.String()) } - ff, err := isFastForward(s, cmd.Old, cmd.New) + ff, err := isFastForward(s, cmd.Old, cmd.New, nil) if err != nil { return err } @@ -1082,14 +1082,28 @@ func checkFastForwardUpdate(s storer.EncodedObjectStorer, remoteRefs storer.Refe return nil } -func isFastForward(s storer.EncodedObjectStorer, old, new plumbing.Hash) (bool, error) { +func isFastForward(s storer.EncodedObjectStorer, old, new plumbing.Hash, earliestShallow *plumbing.Hash) (bool, error) { c, err := object.GetCommit(s, new) if err != nil { return false, err } + parentsToIgnore := []plumbing.Hash{} + if earliestShallow != nil { + earliestCommit, err := object.GetCommit(s, *earliestShallow) + if err != nil { + return false, err + } + + parentsToIgnore = earliestCommit.ParentHashes + } + found := false - iter := object.NewCommitPreorderIter(c, nil, nil) + // stop iterating at the earlist shallow commit, ignoring its parents + // note: when pull depth is smaller than the number of new changes on the remote, this fails due to missing parents. + // as far as i can tell, without the commits in-between the shallow pull and the earliest shallow, there's no + // real way of telling whether it will be a fast-forward merge. + iter := object.NewCommitPreorderIter(c, nil, parentsToIgnore) err = iter.ForEach(func(c *object.Commit) error { if c.Hash != old { return nil @@ -1205,7 +1219,7 @@ func (r *Remote) updateLocalReferenceStorage( // If the ref exists locally as a non-tag and force is not // specified, only update if the new ref is an ancestor of the old if old != nil && !old.Name().IsTag() && !force && !spec.IsForceUpdate() { - ff, err := isFastForward(r.s, old.Hash(), new.Hash()) + ff, err := isFastForward(r.s, old.Hash(), new.Hash(), nil) if err != nil { return updated, err } @@ -1390,7 +1404,6 @@ func pushHashes( useRefDeltas bool, allDelete bool, ) (*packp.ReportStatus, error) { - rd, wr := io.Pipe() config, err := s.Config() diff --git a/vendor/github.com/go-git/go-git/v5/repository.go b/vendor/github.com/go-git/go-git/v5/repository.go index 48988383..1524a691 100644 --- a/vendor/github.com/go-git/go-git/v5/repository.go +++ b/vendor/github.com/go-git/go-git/v5/repository.go @@ -98,6 +98,10 @@ func InitWithOptions(s storage.Storer, worktree billy.Filesystem, options InitOp options.DefaultBranch = plumbing.Master } + if err := options.DefaultBranch.Validate(); err != nil { + return nil, err + } + r := newRepository(s, worktree) _, err := r.Reference(plumbing.HEAD, false) switch err { @@ -724,7 +728,10 @@ func (r *Repository) DeleteBranch(name string) error { // CreateTag creates a tag. If opts is included, the tag is an annotated tag, // otherwise a lightweight tag is created. func (r *Repository) CreateTag(name string, hash plumbing.Hash, opts *CreateTagOptions) (*plumbing.Reference, error) { - rname := plumbing.ReferenceName(path.Join("refs", "tags", name)) + rname := plumbing.NewTagReferenceName(name) + if err := rname.Validate(); err != nil { + return nil, err + } _, err := r.Storer.Reference(rname) switch err { diff --git a/vendor/github.com/go-git/go-git/v5/storage/filesystem/dotgit/dotgit.go b/vendor/github.com/go-git/go-git/v5/storage/filesystem/dotgit/dotgit.go index 3080e4ac..31c46948 100644 --- a/vendor/github.com/go-git/go-git/v5/storage/filesystem/dotgit/dotgit.go +++ b/vendor/github.com/go-git/go-git/v5/storage/filesystem/dotgit/dotgit.go @@ -10,18 +10,19 @@ import ( "os" "path" "path/filepath" + "reflect" "runtime" "sort" "strings" "time" - "github.com/go-git/go-billy/v5/osfs" "github.com/go-git/go-git/v5/plumbing" "github.com/go-git/go-git/v5/plumbing/hash" "github.com/go-git/go-git/v5/storage" "github.com/go-git/go-git/v5/utils/ioutil" "github.com/go-git/go-billy/v5" + "github.com/go-git/go-billy/v5/helper/chroot" ) const ( @@ -81,6 +82,10 @@ type Options struct { // KeepDescriptors makes the file descriptors to be reused but they will // need to be manually closed calling Close(). KeepDescriptors bool + // AlternatesFS provides the billy filesystem to be used for Git Alternates. + // If none is provided, it falls back to using the underlying instance used for + // DotGit. + AlternatesFS billy.Filesystem } // The DotGit type represents a local git repository on disk. This @@ -1146,28 +1151,55 @@ func (d *DotGit) Alternates() ([]*DotGit, error) { } defer f.Close() + fs := d.options.AlternatesFS + if fs == nil { + fs = d.fs + } + var alternates []*DotGit + seen := make(map[string]struct{}) // Read alternate paths line-by-line and create DotGit objects. scanner := bufio.NewScanner(f) for scanner.Scan() { path := scanner.Text() - if !filepath.IsAbs(path) { - // For relative paths, we can perform an internal conversion to - // slash so that they work cross-platform. - slashPath := filepath.ToSlash(path) - // If the path is not absolute, it must be relative to object - // database (.git/objects/info). - // https://www.kernel.org/pub/software/scm/git/docs/gitrepository-layout.html - // Hence, derive a path relative to DotGit's root. - // "../../../reponame/.git/" -> "../../reponame/.git" - // Remove the first ../ - relpath := filepath.Join(strings.Split(slashPath, "/")[1:]...) - normalPath := filepath.FromSlash(relpath) - path = filepath.Join(d.fs.Root(), normalPath) + + // Avoid creating multiple dotgits for the same alternative path. + if _, ok := seen[path]; ok { + continue + } + + seen[path] = struct{}{} + + if filepath.IsAbs(path) { + // Handling absolute paths should be straight-forward. However, the default osfs (Chroot) + // tries to concatenate an abs path with the root path in some operations (e.g. Stat), + // which leads to unexpected errors. Therefore, make the path relative to the current FS instead. + if reflect.TypeOf(fs) == reflect.TypeOf(&chroot.ChrootHelper{}) { + path, err = filepath.Rel(fs.Root(), path) + if err != nil { + return nil, fmt.Errorf("cannot make path %q relative: %w", path, err) + } + } + } else { + // By Git conventions, relative paths should be based on the object database (.git/objects/info) + // location as per: https://www.kernel.org/pub/software/scm/git/docs/gitrepository-layout.html + // However, due to the nature of go-git and its filesystem handling via Billy, paths cannot + // cross its "chroot boundaries". Therefore, ignore any "../" and treat the path from the + // fs root. If this is not correct based on the dotgit fs, set a different one via AlternatesFS. + abs := filepath.Join(string(filepath.Separator), filepath.ToSlash(path)) + path = filepath.FromSlash(abs) + } + + // Aligns with upstream behavior: exit if target path is not a valid directory. + if fi, err := fs.Stat(path); err != nil || !fi.IsDir() { + return nil, fmt.Errorf("invalid object directory %q: %w", path, err) + } + afs, err := fs.Chroot(filepath.Dir(path)) + if err != nil { + return nil, fmt.Errorf("cannot chroot %q: %w", path, err) } - fs := osfs.New(filepath.Dir(path)) - alternates = append(alternates, New(fs)) + alternates = append(alternates, New(afs)) } if err = scanner.Err(); err != nil { diff --git a/vendor/github.com/go-git/go-git/v5/storage/filesystem/storage.go b/vendor/github.com/go-git/go-git/v5/storage/filesystem/storage.go index 2069d3a6..951ea00c 100644 --- a/vendor/github.com/go-git/go-git/v5/storage/filesystem/storage.go +++ b/vendor/github.com/go-git/go-git/v5/storage/filesystem/storage.go @@ -37,6 +37,10 @@ type Options struct { // LargeObjectThreshold maximum object size (in bytes) that will be read in to memory. // If left unset or set to 0 there is no limit LargeObjectThreshold int64 + // AlternatesFS provides the billy filesystem to be used for Git Alternates. + // If none is provided, it falls back to using the underlying instance used for + // DotGit. + AlternatesFS billy.Filesystem } // NewStorage returns a new Storage backed by a given `fs.Filesystem` and cache. @@ -49,6 +53,7 @@ func NewStorage(fs billy.Filesystem, cache cache.Object) *Storage { func NewStorageWithOptions(fs billy.Filesystem, cache cache.Object, ops Options) *Storage { dirOps := dotgit.Options{ ExclusiveAccess: ops.ExclusiveAccess, + AlternatesFS: ops.AlternatesFS, } dir := dotgit.NewWithOptions(fs, dirOps) diff --git a/vendor/github.com/go-git/go-git/v5/worktree.go b/vendor/github.com/go-git/go-git/v5/worktree.go index f8b854dd..ad525c1a 100644 --- a/vendor/github.com/go-git/go-git/v5/worktree.go +++ b/vendor/github.com/go-git/go-git/v5/worktree.go @@ -7,6 +7,7 @@ import ( "io" "os" "path/filepath" + "runtime" "strings" "github.com/go-git/go-billy/v5" @@ -95,7 +96,15 @@ func (w *Worktree) PullContext(ctx context.Context, o *PullOptions) error { head, err := w.r.Head() if err == nil { - headAheadOfRef, err := isFastForward(w.r.Storer, ref.Hash(), head.Hash()) + // if we don't have a shallows list, just ignore it + shallowList, _ := w.r.Storer.Shallow() + + var earliestShallow *plumbing.Hash + if len(shallowList) > 0 { + earliestShallow = &shallowList[0] + } + + headAheadOfRef, err := isFastForward(w.r.Storer, ref.Hash(), head.Hash(), earliestShallow) if err != nil { return err } @@ -104,7 +113,7 @@ func (w *Worktree) PullContext(ctx context.Context, o *PullOptions) error { return NoErrAlreadyUpToDate } - ff, err := isFastForward(w.r.Storer, head.Hash(), ref.Hash()) + ff, err := isFastForward(w.r.Storer, head.Hash(), ref.Hash(), earliestShallow) if err != nil { return err } @@ -188,7 +197,12 @@ func (w *Worktree) Checkout(opts *CheckoutOptions) error { return w.Reset(ro) } + func (w *Worktree) createBranch(opts *CheckoutOptions) error { + if err := opts.Branch.Validate(); err != nil { + return err + } + _, err := w.r.Storer.Reference(opts.Branch) if err == nil { return fmt.Errorf("a branch named %q already exists", opts.Branch) @@ -381,6 +395,9 @@ func (w *Worktree) resetWorktree(t *object.Tree) error { b := newIndexBuilder(idx) for _, ch := range changes { + if err := w.validChange(ch); err != nil { + return err + } if err := w.checkoutChange(ch, t, b); err != nil { return err } @@ -390,6 +407,104 @@ func (w *Worktree) resetWorktree(t *object.Tree) error { return w.r.Storer.SetIndex(idx) } +// worktreeDeny is a list of paths that are not allowed +// to be used when resetting the worktree. +var worktreeDeny = map[string]struct{}{ + // .git + GitDirName: {}, + + // For other historical reasons, file names that do not conform to the 8.3 + // format (up to eight characters for the basename, three for the file + // extension, certain characters not allowed such as `+`, etc) are associated + // with a so-called "short name", at least on the `C:` drive by default. + // Which means that `git~1/` is a valid way to refer to `.git/`. + "git~1": {}, +} + +// validPath checks whether paths are valid. +// The rules around invalid paths could differ from upstream based on how +// filesystems are managed within go-git, but they are largely the same. +// +// For upstream rules: +// https://github.com/git/git/blob/564d0252ca632e0264ed670534a51d18a689ef5d/read-cache.c#L946 +// https://github.com/git/git/blob/564d0252ca632e0264ed670534a51d18a689ef5d/path.c#L1383 +func validPath(paths ...string) error { + for _, p := range paths { + parts := strings.FieldsFunc(p, func(r rune) bool { return (r == '\\' || r == '/') }) + if _, denied := worktreeDeny[strings.ToLower(parts[0])]; denied { + return fmt.Errorf("invalid path prefix: %q", p) + } + + if runtime.GOOS == "windows" { + // Volume names are not supported, in both formats: \\ and :. + if vol := filepath.VolumeName(p); vol != "" { + return fmt.Errorf("invalid path: %q", p) + } + + if !windowsValidPath(parts[0]) { + return fmt.Errorf("invalid path: %q", p) + } + } + + for _, part := range parts { + if part == ".." { + return fmt.Errorf("invalid path %q: cannot use '..'", p) + } + } + } + return nil +} + +// windowsPathReplacer defines the chars that need to be replaced +// as part of windowsValidPath. +var windowsPathReplacer *strings.Replacer + +func init() { + windowsPathReplacer = strings.NewReplacer(" ", "", ".", "") +} + +func windowsValidPath(part string) bool { + if len(part) > 3 && strings.EqualFold(part[:4], GitDirName) { + // For historical reasons, file names that end in spaces or periods are + // automatically trimmed. Therefore, `.git . . ./` is a valid way to refer + // to `.git/`. + if windowsPathReplacer.Replace(part[4:]) == "" { + return false + } + + // For yet other historical reasons, NTFS supports so-called "Alternate Data + // Streams", i.e. metadata associated with a given file, referred to via + // `::`. There exists a default stream + // type for directories, allowing `.git/` to be accessed via + // `.git::$INDEX_ALLOCATION/`. + // + // For performance reasons, _all_ Alternate Data Streams of `.git/` are + // forbidden, not just `::$INDEX_ALLOCATION`. + if len(part) > 4 && part[4:5] == ":" { + return false + } + } + return true +} + +func (w *Worktree) validChange(ch merkletrie.Change) error { + action, err := ch.Action() + if err != nil { + return nil + } + + switch action { + case merkletrie.Delete: + return validPath(ch.From.String()) + case merkletrie.Insert: + return validPath(ch.To.String()) + case merkletrie.Modify: + return validPath(ch.From.String(), ch.To.String()) + } + + return nil +} + func (w *Worktree) checkoutChange(ch merkletrie.Change, t *object.Tree, idx *indexBuilder) error { a, err := ch.Action() if err != nil { @@ -562,6 +677,11 @@ func (w *Worktree) checkoutFile(f *object.File) (err error) { } func (w *Worktree) checkoutFileSymlink(f *object.File) (err error) { + // https://github.com/git/git/commit/10ecfa76491e4923988337b2e2243b05376b40de + if strings.EqualFold(f.Name, gitmodulesFile) { + return ErrGitModulesSymlink + } + from, err := f.Reader() if err != nil { return diff --git a/vendor/github.com/google/go-containerregistry/pkg/authn/keychain.go b/vendor/github.com/google/go-containerregistry/pkg/authn/keychain.go index 4e32500c..99e0b81c 100644 --- a/vendor/github.com/google/go-containerregistry/pkg/authn/keychain.go +++ b/vendor/github.com/google/go-containerregistry/pkg/authn/keychain.go @@ -53,7 +53,7 @@ type defaultKeychain struct { var ( // DefaultKeychain implements Keychain by interpreting the docker config file. - DefaultKeychain = RefreshingKeychain(&defaultKeychain{}, 5*time.Minute) + DefaultKeychain = &defaultKeychain{} ) const ( diff --git a/vendor/github.com/google/go-containerregistry/pkg/v1/layout/gc.go b/vendor/github.com/google/go-containerregistry/pkg/v1/layout/gc.go new file mode 100644 index 00000000..5fdb2c05 --- /dev/null +++ b/vendor/github.com/google/go-containerregistry/pkg/v1/layout/gc.go @@ -0,0 +1,137 @@ +// Copyright 2018 Google LLC All Rights Reserved. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +// This is an EXPERIMENTAL package, and may change in arbitrary ways without notice. +package layout + +import ( + "fmt" + "io/fs" + "path/filepath" + "strings" + + v1 "github.com/google/go-containerregistry/pkg/v1" +) + +// GarbageCollect removes unreferenced blobs from the oci-layout +// +// This is an experimental api, and not subject to any stability guarantees +// We may abandon it at any time, without prior notice. +// Deprecated: Use it at your own risk! +func (l Path) GarbageCollect() ([]v1.Hash, error) { + idx, err := l.ImageIndex() + if err != nil { + return nil, err + } + blobsToKeep := map[string]bool{} + if err := l.garbageCollectImageIndex(idx, blobsToKeep); err != nil { + return nil, err + } + blobsDir := l.path("blobs") + removedBlobs := []v1.Hash{} + + err = filepath.WalkDir(blobsDir, func(path string, d fs.DirEntry, err error) error { + if err != nil { + return err + } + + if d.IsDir() { + return nil + } + + rel, err := filepath.Rel(blobsDir, path) + if err != nil { + return err + } + hashString := strings.Replace(rel, "/", ":", 1) + if present := blobsToKeep[hashString]; !present { + h, err := v1.NewHash(hashString) + if err != nil { + return err + } + removedBlobs = append(removedBlobs, h) + } + return nil + }) + + if err != nil { + return nil, err + } + + return removedBlobs, nil +} + +func (l Path) garbageCollectImageIndex(index v1.ImageIndex, blobsToKeep map[string]bool) error { + idxm, err := index.IndexManifest() + if err != nil { + return err + } + + h, err := index.Digest() + if err != nil { + return err + } + + blobsToKeep[h.String()] = true + + for _, descriptor := range idxm.Manifests { + if descriptor.MediaType.IsImage() { + img, err := index.Image(descriptor.Digest) + if err != nil { + return err + } + if err := l.garbageCollectImage(img, blobsToKeep); err != nil { + return err + } + } else if descriptor.MediaType.IsIndex() { + idx, err := index.ImageIndex(descriptor.Digest) + if err != nil { + return err + } + if err := l.garbageCollectImageIndex(idx, blobsToKeep); err != nil { + return err + } + } else { + return fmt.Errorf("gc: unknown media type: %s", descriptor.MediaType) + } + } + return nil +} + +func (l Path) garbageCollectImage(image v1.Image, blobsToKeep map[string]bool) error { + h, err := image.Digest() + if err != nil { + return err + } + blobsToKeep[h.String()] = true + + h, err = image.ConfigName() + if err != nil { + return err + } + blobsToKeep[h.String()] = true + + ls, err := image.Layers() + if err != nil { + return err + } + for _, l := range ls { + h, err := l.Digest() + if err != nil { + return err + } + blobsToKeep[h.String()] = true + } + return nil +} diff --git a/vendor/github.com/google/go-containerregistry/pkg/v1/remote/write.go b/vendor/github.com/google/go-containerregistry/pkg/v1/remote/write.go index 6bfce75e..04a3989a 100644 --- a/vendor/github.com/google/go-containerregistry/pkg/v1/remote/write.go +++ b/vendor/github.com/google/go-containerregistry/pkg/v1/remote/write.go @@ -280,6 +280,11 @@ func (w *writer) streamBlob(ctx context.Context, layer v1.Layer, streamLocation if _, ok := layer.(*stream.Layer); !ok { // We can't retry streaming layers. req.GetBody = getBody + + // If we know the size, set it. + if size, err := layer.Size(); err == nil { + req.ContentLength = size + } } req.Header.Set("Content-Type", "application/octet-stream") diff --git a/vendor/github.com/google/uuid/CHANGELOG.md b/vendor/github.com/google/uuid/CHANGELOG.md index 7ed347d3..c9fb829d 100644 --- a/vendor/github.com/google/uuid/CHANGELOG.md +++ b/vendor/github.com/google/uuid/CHANGELOG.md @@ -1,5 +1,12 @@ # Changelog +## [1.5.0](https://github.com/google/uuid/compare/v1.4.0...v1.5.0) (2023-12-12) + + +### Features + +* Validate UUID without creating new UUID ([#141](https://github.com/google/uuid/issues/141)) ([9ee7366](https://github.com/google/uuid/commit/9ee7366e66c9ad96bab89139418a713dc584ae29)) + ## [1.4.0](https://github.com/google/uuid/compare/v1.3.1...v1.4.0) (2023-10-26) diff --git a/vendor/github.com/google/uuid/time.go b/vendor/github.com/google/uuid/time.go index e6ef06cd..c3511292 100644 --- a/vendor/github.com/google/uuid/time.go +++ b/vendor/github.com/google/uuid/time.go @@ -108,12 +108,23 @@ func setClockSequence(seq int) { } // Time returns the time in 100s of nanoseconds since 15 Oct 1582 encoded in -// uuid. The time is only defined for version 1 and 2 UUIDs. +// uuid. The time is only defined for version 1, 2, 6 and 7 UUIDs. func (uuid UUID) Time() Time { - time := int64(binary.BigEndian.Uint32(uuid[0:4])) - time |= int64(binary.BigEndian.Uint16(uuid[4:6])) << 32 - time |= int64(binary.BigEndian.Uint16(uuid[6:8])&0xfff) << 48 - return Time(time) + var t Time + switch uuid.Version() { + case 6: + time := binary.BigEndian.Uint64(uuid[:8]) // Ignore uuid[6] version b0110 + t = Time(time) + case 7: + time := binary.BigEndian.Uint64(uuid[:8]) + t = Time((time>>16)*10000 + g1582ns100) + default: // forward compatible + time := int64(binary.BigEndian.Uint32(uuid[0:4])) + time |= int64(binary.BigEndian.Uint16(uuid[4:6])) << 32 + time |= int64(binary.BigEndian.Uint16(uuid[6:8])&0xfff) << 48 + t = Time(time) + } + return t } // ClockSequence returns the clock sequence encoded in uuid. diff --git a/vendor/github.com/google/uuid/uuid.go b/vendor/github.com/google/uuid/uuid.go index dc75f7d9..5232b486 100644 --- a/vendor/github.com/google/uuid/uuid.go +++ b/vendor/github.com/google/uuid/uuid.go @@ -186,6 +186,59 @@ func Must(uuid UUID, err error) UUID { return uuid } +// Validate returns an error if s is not a properly formatted UUID in one of the following formats: +// xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx +// urn:uuid:xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx +// xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx +// {xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx} +// It returns an error if the format is invalid, otherwise nil. +func Validate(s string) error { + switch len(s) { + // Standard UUID format + case 36: + + // UUID with "urn:uuid:" prefix + case 36 + 9: + if !strings.EqualFold(s[:9], "urn:uuid:") { + return fmt.Errorf("invalid urn prefix: %q", s[:9]) + } + s = s[9:] + + // UUID enclosed in braces + case 36 + 2: + if s[0] != '{' || s[len(s)-1] != '}' { + return fmt.Errorf("invalid bracketed UUID format") + } + s = s[1 : len(s)-1] + + // UUID without hyphens + case 32: + for i := 0; i < len(s); i += 2 { + _, ok := xtob(s[i], s[i+1]) + if !ok { + return errors.New("invalid UUID format") + } + } + + default: + return invalidLengthError{len(s)} + } + + // Check for standard UUID format + if len(s) == 36 { + if s[8] != '-' || s[13] != '-' || s[18] != '-' || s[23] != '-' { + return errors.New("invalid UUID format") + } + for _, x := range []int{0, 2, 4, 6, 9, 11, 14, 16, 19, 21, 24, 26, 28, 30, 32, 34} { + if _, ok := xtob(s[x], s[x+1]); !ok { + return errors.New("invalid UUID format") + } + } + } + + return nil +} + // String returns the string form of uuid, xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx // , or "" if uuid is invalid. func (uuid UUID) String() string { diff --git a/vendor/github.com/google/uuid/version6.go b/vendor/github.com/google/uuid/version6.go new file mode 100644 index 00000000..339a959a --- /dev/null +++ b/vendor/github.com/google/uuid/version6.go @@ -0,0 +1,56 @@ +// Copyright 2023 Google Inc. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package uuid + +import "encoding/binary" + +// UUID version 6 is a field-compatible version of UUIDv1, reordered for improved DB locality. +// It is expected that UUIDv6 will primarily be used in contexts where there are existing v1 UUIDs. +// Systems that do not involve legacy UUIDv1 SHOULD consider using UUIDv7 instead. +// +// see https://datatracker.ietf.org/doc/html/draft-peabody-dispatch-new-uuid-format-03#uuidv6 +// +// NewV6 returns a Version 6 UUID based on the current NodeID and clock +// sequence, and the current time. If the NodeID has not been set by SetNodeID +// or SetNodeInterface then it will be set automatically. If the NodeID cannot +// be set NewV6 set NodeID is random bits automatically . If clock sequence has not been set by +// SetClockSequence then it will be set automatically. If GetTime fails to +// return the current NewV6 returns Nil and an error. +func NewV6() (UUID, error) { + var uuid UUID + now, seq, err := GetTime() + if err != nil { + return uuid, err + } + + /* + 0 1 2 3 + 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + | time_high | + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + | time_mid | time_low_and_version | + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + |clk_seq_hi_res | clk_seq_low | node (0-1) | + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + | node (2-5) | + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + */ + + binary.BigEndian.PutUint64(uuid[0:], uint64(now)) + binary.BigEndian.PutUint16(uuid[8:], seq) + + uuid[6] = 0x60 | (uuid[6] & 0x0F) + uuid[8] = 0x80 | (uuid[8] & 0x3F) + + nodeMu.Lock() + if nodeID == zeroID { + setNodeInterface("") + } + copy(uuid[10:], nodeID[:]) + nodeMu.Unlock() + + return uuid, nil +} diff --git a/vendor/github.com/google/uuid/version7.go b/vendor/github.com/google/uuid/version7.go new file mode 100644 index 00000000..ba9dd5eb --- /dev/null +++ b/vendor/github.com/google/uuid/version7.go @@ -0,0 +1,75 @@ +// Copyright 2023 Google Inc. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package uuid + +import ( + "io" +) + +// UUID version 7 features a time-ordered value field derived from the widely +// implemented and well known Unix Epoch timestamp source, +// the number of milliseconds seconds since midnight 1 Jan 1970 UTC, leap seconds excluded. +// As well as improved entropy characteristics over versions 1 or 6. +// +// see https://datatracker.ietf.org/doc/html/draft-peabody-dispatch-new-uuid-format-03#name-uuid-version-7 +// +// Implementations SHOULD utilize UUID version 7 over UUID version 1 and 6 if possible. +// +// NewV7 returns a Version 7 UUID based on the current time(Unix Epoch). +// Uses the randomness pool if it was enabled with EnableRandPool. +// On error, NewV7 returns Nil and an error +func NewV7() (UUID, error) { + uuid, err := NewRandom() + if err != nil { + return uuid, err + } + makeV7(uuid[:]) + return uuid, nil +} + +// NewV7FromReader returns a Version 7 UUID based on the current time(Unix Epoch). +// it use NewRandomFromReader fill random bits. +// On error, NewV7FromReader returns Nil and an error. +func NewV7FromReader(r io.Reader) (UUID, error) { + uuid, err := NewRandomFromReader(r) + if err != nil { + return uuid, err + } + + makeV7(uuid[:]) + return uuid, nil +} + +// makeV7 fill 48 bits time (uuid[0] - uuid[5]), set version b0111 (uuid[6]) +// uuid[8] already has the right version number (Variant is 10) +// see function NewV7 and NewV7FromReader +func makeV7(uuid []byte) { + /* + 0 1 2 3 + 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + | unix_ts_ms | + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + | unix_ts_ms | ver | rand_a | + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + |var| rand_b | + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + | rand_b | + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + */ + _ = uuid[15] // bounds check + + t := timeNow().UnixMilli() + + uuid[0] = byte(t >> 40) + uuid[1] = byte(t >> 32) + uuid[2] = byte(t >> 24) + uuid[3] = byte(t >> 16) + uuid[4] = byte(t >> 8) + uuid[5] = byte(t) + + uuid[6] = 0x70 | (uuid[6] & 0x0F) + // uuid[8] has already has right version +} diff --git a/vendor/github.com/saferwall/pe/dotnet.go b/vendor/github.com/saferwall/pe/dotnet.go index 7defaccd..2f90a1e7 100644 --- a/vendor/github.com/saferwall/pe/dotnet.go +++ b/vendor/github.com/saferwall/pe/dotnet.go @@ -6,7 +6,6 @@ package pe import ( "encoding/binary" - "fmt" ) // References @@ -727,7 +726,8 @@ func (pe *File) parseCLRHeaderDirectory(rva, size uint32) error { table.Content, n, err = pe.parseMetadataGenericParamConstraintTable(offset) default: - fmt.Printf("unhandled metadata table %d %s offset 0x%x cols %d\n", tableIndex, MetadataTableIndexToString(tableIndex), offset, table.CountCols) + pe.logger.Warnf("unhandled metadata table %d %s offset 0x%x cols %d", + tableIndex, MetadataTableIndexToString(tableIndex), offset, table.CountCols) } offset += n diff --git a/vendor/modernc.org/sqlite/AUTHORS b/vendor/modernc.org/sqlite/AUTHORS index e724f81c..580af028 100644 --- a/vendor/modernc.org/sqlite/AUTHORS +++ b/vendor/modernc.org/sqlite/AUTHORS @@ -8,6 +8,7 @@ # # Please keep the list sorted. +Angus Dippenaar Artyom Pervukhin Dan Kortschak Dan Peterson diff --git a/vendor/modernc.org/sqlite/CONTRIBUTORS b/vendor/modernc.org/sqlite/CONTRIBUTORS index ba51f056..108a09db 100644 --- a/vendor/modernc.org/sqlite/CONTRIBUTORS +++ b/vendor/modernc.org/sqlite/CONTRIBUTORS @@ -8,6 +8,7 @@ Alexander Menzhinsky Alexey Palazhchenko +Angus Dippenaar Artyom Pervukhin Dan Kortschak Dan Peterson diff --git a/vendor/modernc.org/sqlite/Makefile b/vendor/modernc.org/sqlite/Makefile index 0ce355fb..2e3ad1de 100644 --- a/vendor/modernc.org/sqlite/Makefile +++ b/vendor/modernc.org/sqlite/Makefile @@ -201,7 +201,7 @@ cpu: clean edit: @touch log - @if [ -f "Session.vim" ]; then gvim -S & else gvim -p Makefile *.go & fi + @if [ -f "Session.vim" ]; then gvim -S & else gvim -p Makefile all_test.go sqlite.go & fi editor: gofmt -l -s -w *.go diff --git a/vendor/modernc.org/sqlite/doc.go b/vendor/modernc.org/sqlite/doc.go index 923a8db7..620bc262 100644 --- a/vendor/modernc.org/sqlite/doc.go +++ b/vendor/modernc.org/sqlite/doc.go @@ -94,6 +94,13 @@ // // # Changelog // +// 2023-12-14 v1.28.0: +// +// (*Driver).RegisterConnectionHook: added +// ConnectionHookFn: added +// ExecQuerierContext: added +// RegisterConnectionHook: added +// // 2023-08-03 v1.25.0: enable SQLITE_ENABLE_DBSTAT_VTAB. // // 2023-07-11 v1.24.0: diff --git a/vendor/modernc.org/sqlite/sqlite.go b/vendor/modernc.org/sqlite/sqlite.go index ec5b2c0f..9763713f 100644 --- a/vendor/modernc.org/sqlite/sqlite.go +++ b/vendor/modernc.org/sqlite/sqlite.go @@ -1844,17 +1844,32 @@ func (b *Backup) Finish() error { } } +type ExecQuerierContext interface { + driver.ExecerContext + driver.QueryerContext +} + +// ConnectionHookFn function type for a connection hook on the Driver. Connection +// hooks are called after the connection has been set up. +type ConnectionHookFn func( + conn ExecQuerierContext, + dsn string, +) error + // Driver implements database/sql/driver.Driver. type Driver struct { // user defined functions that are added to every new connection on Open udfs map[string]*userDefinedFunction // collations that are added to every new connection on Open collations map[string]*collation + // connection hooks are called after a connection is opened + connectionHooks []ConnectionHookFn } var d = &Driver{ - udfs: make(map[string]*userDefinedFunction, 0), - collations: make(map[string]*collation, 0), + udfs: make(map[string]*userDefinedFunction, 0), + collations: make(map[string]*collation, 0), + connectionHooks: make([]ConnectionHookFn, 0), } func newDriver() *Driver { return d } @@ -1909,6 +1924,12 @@ func (d *Driver) Open(name string) (conn driver.Conn, err error) { return nil, err } } + for _, connHookFn := range d.connectionHooks { + if err = connHookFn(c, name); err != nil { + c.Close() + return nil, fmt.Errorf("connection hook: %w", err) + } + } return c, nil } @@ -2063,6 +2084,18 @@ func registerFunction( return nil } +// RegisterConnectionHook registers a function to be called after each connection +// is opened. This is called after all the connection has been set up. +func (d *Driver) RegisterConnectionHook(fn ConnectionHookFn) { + d.connectionHooks = append(d.connectionHooks, fn) +} + +// RegisterConnectionHook registers a function to be called after each connection +// is opened. This is called after all the connection has been set up. +func RegisterConnectionHook(fn ConnectionHookFn) { + d.RegisterConnectionHook(fn) +} + func origin(skip int) string { pc, fn, fl, _ := runtime.Caller(skip) f := runtime.FuncForPC(pc) diff --git a/vendor/modules.txt b/vendor/modules.txt index 76ff5246..c30a76d8 100644 --- a/vendor/modules.txt +++ b/vendor/modules.txt @@ -7,7 +7,7 @@ github.com/AdaLogics/go-fuzz-headers # github.com/AdamKorcz/go-118-fuzz-build v0.0.0-20230306123547-8075edf89bb0 ## explicit; go 1.18 github.com/AdamKorcz/go-118-fuzz-build/testing -# github.com/CycloneDX/cyclonedx-go v0.7.2 +# github.com/CycloneDX/cyclonedx-go v0.8.0 ## explicit; go 1.18 github.com/CycloneDX/cyclonedx-go # github.com/DataDog/zstd v1.4.5 @@ -85,7 +85,7 @@ github.com/adrg/xdg/internal/pathutil # github.com/anchore/clio v0.0.0-20231016125544-c98a83e1c7fc ## explicit; go 1.18 github.com/anchore/clio -# github.com/anchore/fangs v0.0.0-20231103141714-84c94dc43a2e +# github.com/anchore/fangs v0.0.0-20231201140849-5075d28d6d8b ## explicit; go 1.19 github.com/anchore/fangs # github.com/anchore/go-logger v0.0.0-20230725134548-c21dafa1ec5a @@ -103,7 +103,7 @@ github.com/anchore/go-struct-converter # github.com/anchore/packageurl-go v0.1.1-0.20230104203445-02e0a6721501 ## explicit; go 1.17 github.com/anchore/packageurl-go -# github.com/anchore/stereoscope v0.0.0-20231117203853-3610f4ef3e83 +# github.com/anchore/stereoscope v0.0.0-20231215220732-4b999b76ca89 ## explicit; go 1.19 github.com/anchore/stereoscope github.com/anchore/stereoscope/internal/bus @@ -122,7 +122,7 @@ github.com/anchore/stereoscope/pkg/image/oci github.com/anchore/stereoscope/pkg/image/sif github.com/anchore/stereoscope/pkg/tree github.com/anchore/stereoscope/pkg/tree/node -# github.com/anchore/syft v0.98.0 +# github.com/anchore/syft v0.99.0 ## explicit; go 1.21.0 github.com/anchore/syft/internal github.com/anchore/syft/internal/bus @@ -440,7 +440,7 @@ github.com/go-git/go-billy/v5/helper/polyfill github.com/go-git/go-billy/v5/memfs github.com/go-git/go-billy/v5/osfs github.com/go-git/go-billy/v5/util -# github.com/go-git/go-git/v5 v5.10.1 +# github.com/go-git/go-git/v5 v5.11.0 ## explicit; go 1.19 github.com/go-git/go-git/v5 github.com/go-git/go-git/v5/config @@ -525,7 +525,7 @@ github.com/google/go-cmp/cmp/internal/diff github.com/google/go-cmp/cmp/internal/flags github.com/google/go-cmp/cmp/internal/function github.com/google/go-cmp/cmp/internal/value -# github.com/google/go-containerregistry v0.16.1 +# github.com/google/go-containerregistry v0.17.0 ## explicit; go 1.18 github.com/google/go-containerregistry/internal/and github.com/google/go-containerregistry/internal/compression @@ -558,7 +558,7 @@ github.com/google/licensecheck/internal/match # github.com/google/pprof v0.0.0-20221118152302-e6195bd50e26 ## explicit; go 1.18 github.com/google/pprof/profile -# github.com/google/uuid v1.4.0 +# github.com/google/uuid v1.5.0 ## explicit github.com/google/uuid # github.com/gookit/color v1.5.4 @@ -729,7 +729,7 @@ github.com/pkg/profile # github.com/remyoudompheng/bigfft v0.0.0-20230129092748-24d4a6f8daec ## explicit; go 1.12 github.com/remyoudompheng/bigfft -# github.com/saferwall/pe v1.4.7 +# github.com/saferwall/pe v1.4.8 ## explicit; go 1.15 github.com/saferwall/pe github.com/saferwall/pe/log @@ -1164,7 +1164,7 @@ modernc.org/memory # modernc.org/opt v0.1.3 ## explicit; go 1.13 modernc.org/opt -# modernc.org/sqlite v1.27.0 +# modernc.org/sqlite v1.28.0 ## explicit; go 1.19 modernc.org/sqlite modernc.org/sqlite/lib