Compare commits

..
Author SHA1 Message Date
Brian EbarbandAlex Goodman 4194a2cd34 feat: add relationships to ELF package discovery (#2715)
This PR adds DependencyOf relationships when ELF packages have been discovered by the binary cataloger. The discovered file.Executable type has a []ImportedLibraries that's read from the file when discovered by syft. By mapping these imported libraries back to the package collection, syft is able to create relationships showing which packages are dependencies of other packages by just reading metadata from the ELF executable.

---------

Signed-off-by: Alex Goodman <wagoodman@users.noreply.github.com>
Signed-off-by: Brian Ebarb <ebarb.brian@sers.noreply.github.com>
Co-authored-by: Alex Goodman <wagoodman@users.noreply.github.com>
2024-05-09 13:53:59 -04:00
Jörg Thalheim 74b01a1c38 README.md: link to official wiki (#2858)
This commit updates the the link from the former, unofficial nixos wiki page to the new https://wiki.nixos.org
ref: NixOS/foundation#113

Signed-off-by: Jörg Thalheim <joerg@thalheim.io>
2024-05-09 13:49:37 -04:00
William Murphy b2ca5fbf89 fix Windows file paths in local go mod cache (#2654)
Previously, the file resolver was created from incorrect calls
(path.Join instead of filepath.Join) which resulted Go license searches
always missing on Windows. Use filepath.* functions when initializing
the Go config, and when the unindexed file resolver is being created.

Signed-off-by: Will Murphy <will.murphy@anchore.com>
2024-05-09 13:08:58 -04:00
dependabot[bot] 1892f24002 chore(deps): bump github.com/docker/docker (#2859)
Bumps [github.com/docker/docker](https://github.com/docker/docker) from 26.1.1+incompatible to 26.1.2+incompatible.
- [Release notes](https://github.com/docker/docker/releases)
- [Commits](https://github.com/docker/docker/compare/v26.1.1...v26.1.2)

---
updated-dependencies:
- dependency-name: github.com/docker/docker
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2024-05-09 12:02:36 -04:00
dependabot[bot] 88aaab2841 chore(deps): bump github.com/charmbracelet/bubbletea (#2860)
Bumps [github.com/charmbracelet/bubbletea](https://github.com/charmbracelet/bubbletea) from 0.26.1 to 0.26.2.
- [Release notes](https://github.com/charmbracelet/bubbletea/releases)
- [Commits](https://github.com/charmbracelet/bubbletea/compare/v0.26.1...v0.26.2)

---
updated-dependencies:
- dependency-name: github.com/charmbracelet/bubbletea
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2024-05-09 12:02:28 -04:00
dependabot[bot] 5044f48cd6 chore(deps): bump github/codeql-action from 3.25.3 to 3.25.4 (#2855)
Bumps [github/codeql-action](https://github.com/github/codeql-action) from 3.25.3 to 3.25.4.
- [Release notes](https://github.com/github/codeql-action/releases)
- [Changelog](https://github.com/github/codeql-action/blob/main/CHANGELOG.md)
- [Commits](https://github.com/github/codeql-action/compare/d39d31e687223d841ef683f52467bd88e9b21c14...ccf74c947955fd1cf117aef6a0e4e66191ef6f61)

---
updated-dependencies:
- dependency-name: github/codeql-action
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2024-05-08 10:33:38 -04:00
dependabot[bot] 6c2e8c8c4b chore(deps): bump github.com/sassoftware/go-rpmutils from 0.3.0 to 0.4.0 (#2856)
Bumps [github.com/sassoftware/go-rpmutils](https://github.com/sassoftware/go-rpmutils) from 0.3.0 to 0.4.0.
- [Release notes](https://github.com/sassoftware/go-rpmutils/releases)
- [Commits](https://github.com/sassoftware/go-rpmutils/compare/v0.3.0...v0.4.0)

---
updated-dependencies:
- dependency-name: github.com/sassoftware/go-rpmutils
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2024-05-08 10:33:11 -04:00
Alex Goodman ada8f009d2 Add relationships for ALPM packages (arch linux) (#2851)
* add alpm relationships

Signed-off-by: Alex Goodman <wagoodman@users.noreply.github.com>

* tweak reader linter rule to check for reader impl

Signed-off-by: Alex Goodman <wagoodman@users.noreply.github.com>

* update JSON schema with alpm dependency information

Signed-off-by: Alex Goodman <wagoodman@users.noreply.github.com>

---------

Signed-off-by: Alex Goodman <wagoodman@users.noreply.github.com>
2024-05-07 13:29:46 -04:00
Laurent Goderre e7b6284039 Add binary classifier for ArangoDB (#2830)
Signed-off-by: Laurent Goderre <laurent.goderre@docker.com>
2024-05-07 12:06:32 -04:00
dependabot[bot] 78625164c6 chore(deps): bump golang.org/x/net from 0.24.0 to 0.25.0 (#2849)
Bumps [golang.org/x/net](https://github.com/golang/net) from 0.24.0 to 0.25.0.
- [Commits](https://github.com/golang/net/compare/v0.24.0...v0.25.0)

---
updated-dependencies:
- dependency-name: golang.org/x/net
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2024-05-07 12:05:43 -04:00
dependabot[bot] c0635a77a9 chore(deps): bump actions/checkout from 4.1.4 to 4.1.5 (#2850)
Bumps [actions/checkout](https://github.com/actions/checkout) from 4.1.4 to 4.1.5.
- [Release notes](https://github.com/actions/checkout/releases)
- [Changelog](https://github.com/actions/checkout/blob/main/CHANGELOG.md)
- [Commits](https://github.com/actions/checkout/compare/0ad4b8fadaa221de15dcec353f45205ec38ea70b...44c2b7a8a4ea60a981eaca3cf939b5f4305c123b)

---
updated-dependencies:
- dependency-name: actions/checkout
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2024-05-07 12:05:33 -04:00
William Murphy 3713d97b7b chore: use ruleguard to test for missing defer statements (#2837)
* chore: ruleguard to enforce defer use

Signed-off-by: Will Murphy <will.murphy@anchore.com>

* fix go.mod location

Signed-off-by: Will Murphy <will.murphy@anchore.com>

* chore: defer close in linux release identifier

Signed-off-by: Will Murphy <will.murphy@anchore.com>

* chore: better lint suggestion

Signed-off-by: Will Murphy <will.murphy@anchore.com>

* chore: refactor binary classifier to defer close

Signed-off-by: Will Murphy <will.murphy@anchore.com>

* chore: defer close readers in gentoo cataloger

Signed-off-by: Will Murphy <will.murphy@anchore.com>

* chore: make go license parsing defer close readers

Signed-off-by: Will Murphy <will.murphy@anchore.com>

* chore: defer closing readers in alpine apm parser

Signed-off-by: Will Murphy <will.murphy@anchore.com>

* chore: defer close readers in graalvm parser

Signed-off-by: Will Murphy <will.murphy@anchore.com>

* chore: defer close readers in debian package parser

Signed-off-by: Will Murphy <will.murphy@anchore.com>

* chore: defer close readers in alpm parser

Signed-off-by: Will Murphy <will.murphy@anchore.com>

* chore: defer close readers in executable file cataloger

Signed-off-by: Will Murphy <will.murphy@anchore.com>

* chore: defer close readers in javascript license parser

Signed-off-by: Will Murphy <will.murphy@anchore.com>

* chore: defer close readers in go mod parser

Signed-off-by: Will Murphy <will.murphy@anchore.com>

---------

Signed-off-by: Will Murphy <will.murphy@anchore.com>
2024-05-07 05:42:29 -04:00
Alex Goodman 430c55a5b0 remove homebrew update workflow (#2846)
Signed-off-by: Alex Goodman <wagoodman@users.noreply.github.com>
2024-05-06 15:38:12 -04:00
Alex Goodman 49e93646eb Restore version file update on release (#2844)
* restore version file update on release

Signed-off-by: Alex Goodman <wagoodman@users.noreply.github.com>

* allow for shallower fetch depth

Signed-off-by: Alex Goodman <wagoodman@users.noreply.github.com>

---------

Signed-off-by: Alex Goodman <wagoodman@users.noreply.github.com>
2024-05-06 15:14:43 -04:00
Laurent Goderre 5ca26ed3ca fix: Add missing CPE for traefik, memcached, and postgres binaries (#2845)
Signed-off-by: Laurent Goderre <laurent.goderre@docker.com>
2024-05-06 15:06:30 -04:00
Laurent Goderre e353214ef8 Add detection for newer version of ErLang/OTP (#2829)
Signed-off-by: Laurent Goderre <laurent.goderre@docker.com>
2024-05-06 11:47:54 -04:00
Alex Goodman a56eff90d6 fix ui race for package count (#2839)
Signed-off-by: Alex Goodman <wagoodman@users.noreply.github.com>
2024-05-06 11:45:52 -04:00
anchore-actions-token-generator[bot]andwagoodman 00ff3ffda9 chore(deps): update CPE dictionary index (#2841)
Signed-off-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
Co-authored-by: wagoodman <590471+wagoodman@users.noreply.github.com>
2024-05-06 11:44:19 -04:00
dependabot[bot] 9de533996e chore(deps): bump github.com/jedib0t/go-pretty/v6 from 6.5.8 to 6.5.9 (#2842)
Bumps [github.com/jedib0t/go-pretty/v6](https://github.com/jedib0t/go-pretty) from 6.5.8 to 6.5.9.
- [Release notes](https://github.com/jedib0t/go-pretty/releases)
- [Commits](https://github.com/jedib0t/go-pretty/compare/v6.5.8...v6.5.9)

---
updated-dependencies:
- dependency-name: github.com/jedib0t/go-pretty/v6
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2024-05-06 11:44:05 -04:00
dependabot[bot] 7aae7470e2 chore(deps): bump modernc.org/sqlite from 1.29.8 to 1.29.9 (#2843)
Bumps [modernc.org/sqlite](https://gitlab.com/cznic/sqlite) from 1.29.8 to 1.29.9.
- [Commits](https://gitlab.com/cznic/sqlite/compare/v1.29.8...v1.29.9)

---
updated-dependencies:
- dependency-name: modernc.org/sqlite
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2024-05-06 11:43:55 -04:00
dependabot[bot] d6604adaaf chore(deps): bump github.com/charmbracelet/bubbletea (#2838)
Bumps [github.com/charmbracelet/bubbletea](https://github.com/charmbracelet/bubbletea) from 0.26.0 to 0.26.1.
- [Release notes](https://github.com/charmbracelet/bubbletea/releases)
- [Commits](https://github.com/charmbracelet/bubbletea/compare/v0.26.0...v0.26.1)

---
updated-dependencies:
- dependency-name: github.com/charmbracelet/bubbletea
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2024-05-03 09:50:20 -04:00
Alex Goodman 34ca9a8412 add security policy (#2835)
Signed-off-by: Alex Goodman <wagoodman@users.noreply.github.com>
2024-05-02 14:45:17 +00:00
dependabot[bot] f51b39ca04 chore(deps): bump actions/setup-go from 5.0.0 to 5.0.1 (#2834)
Bumps [actions/setup-go](https://github.com/actions/setup-go) from 5.0.0 to 5.0.1.
- [Release notes](https://github.com/actions/setup-go/releases)
- [Commits](https://github.com/actions/setup-go/compare/0c52d547c9bc32b1aa3301fd7a9cb496313a4491...cdcb36043654635271a94b9a6d1392de5bb323a7)

---
updated-dependencies:
- dependency-name: actions/setup-go
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2024-05-02 10:12:10 -04:00
anchore-actions-token-generator[bot]andkzantow 9bbb42620a chore(deps): update stereoscope to 2e9894674185d121917b283f773c2b5830f8b360 (#2831)
Signed-off-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
Co-authored-by: kzantow <3009477+kzantow@users.noreply.github.com>
2024-05-02 09:38:23 -04:00
dependabot[bot] 0b4de3d0c7 chore(deps): bump github.com/charmbracelet/bubbletea (#2833)
Bumps [github.com/charmbracelet/bubbletea](https://github.com/charmbracelet/bubbletea) from 0.25.0 to 0.26.0.
- [Release notes](https://github.com/charmbracelet/bubbletea/releases)
- [Commits](https://github.com/charmbracelet/bubbletea/compare/v0.25.0...v0.26.0)

---
updated-dependencies:
- dependency-name: github.com/charmbracelet/bubbletea
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2024-05-02 09:36:49 -04:00
camcuiandChristopher Phillips 80d196a8c9 chore: fix function name in comment (#2771)
Signed-off-by: camcui <cuishua@sina.cn>
Co-authored-by: Christopher Phillips <christopher.phillips@anchore.com>
2024-05-01 18:04:02 +00:00
William Murphy ed40833b30 chore: enable go-critic deferInLoop lint (#2825)
The goal here is to be more careful about leaking file handles and other
resources.

Signed-off-by: Will Murphy <will.murphy@anchore.com>
2024-05-01 12:59:35 -04:00
William Murphy 93a7d2ee27 fix: better clean up of file handles (#2823)
* always close ELF cataloger file handles

The elf-binary-package-cataloger does its own file IO to account for the
possibility of a logical ELF package being broken across multiple
physical files. However, this casued it to skip the normal invocation
pattern in the generic cataloger code that prevented file leaks. Ensure
this cataloger always closes its file handles.

Signed-off-by: Will Murphy <will.murphy@anchore.com>

* defer closing of generic cataloger file handles

Otherwise, a panicking cataloger could leak file handles.

Signed-off-by: Will Murphy <will.murphy@anchore.com>

* add unit test for file closed on panic parser

Signed-off-by: Will Murphy <will.murphy@anchore.com>

* make invoke parser a static function

Signed-off-by: Will Murphy <will.murphy@anchore.com>

* push error logging down into invoke parser

Signed-off-by: Will Murphy <will.murphy@anchore.com>

---------

Signed-off-by: Will Murphy <will.murphy@anchore.com>
2024-05-01 12:58:17 -04:00
dependabot[bot] 93a99e36c2 chore(deps): bump github.com/docker/docker (#2827)
Bumps [github.com/docker/docker](https://github.com/docker/docker) from 26.1.0+incompatible to 26.1.1+incompatible.
- [Release notes](https://github.com/docker/docker/releases)
- [Commits](https://github.com/docker/docker/compare/v26.1.0...v26.1.1)

---
updated-dependencies:
- dependency-name: github.com/docker/docker
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2024-05-01 11:03:31 -04:00
Keith Zantow b0c88ddea9 fix(spdx): include required fields (#2168)
* fix(spdx): include required fields

Signed-off-by: Keith Zantow <kzantow@gmail.com>

* chore: missed update due to refactoring

Signed-off-by: Keith Zantow <kzantow@gmail.com>

* chore: update tools-golang

Signed-off-by: Keith Zantow <kzantow@gmail.com>

* chore: add test with packageVerificationCode included and excluded

Signed-off-by: Keith Zantow <kzantow@gmail.com>

---------

Signed-off-by: Keith Zantow <kzantow@gmail.com>
2024-04-30 13:28:42 -04:00
Keith Zantow 047e31a969 fix: add correct vendor for dnsmasq CPE (#2659)
Signed-off-by: Keith Zantow <kzantow@gmail.com>
2024-04-30 13:24:01 -04:00
guangwuandChristopher Phillips 25b55e1704 fix: close temp rpmdb file (#2792)
* fix: close temp rpmdb file and db

Signed-off-by: guoguangwu <guoguangwug@gmail.com>

* chore: fix linter

Signed-off-by: Christopher Phillips <christopher.phillips@anchore.com>

---------

Signed-off-by: guoguangwu <guoguangwug@gmail.com>
Signed-off-by: Christopher Phillips <christopher.phillips@anchore.com>
Co-authored-by: Christopher Phillips <christopher.phillips@anchore.com>
2024-04-30 12:47:17 -04:00
dependabot[bot]andChristopher Phillips 02dc2dfa9b chore(deps): bump github/codeql-action from 3.25.2 to 3.25.3 (#2817)
Bumps [github/codeql-action](https://github.com/github/codeql-action) from 3.25.2 to 3.25.3.
- [Release notes](https://github.com/github/codeql-action/releases)
- [Changelog](https://github.com/github/codeql-action/blob/main/CHANGELOG.md)
- [Commits](https://github.com/github/codeql-action/compare/8f596b4ae3cb3c588a5c46780b86dd53fef16c52...d39d31e687223d841ef683f52467bd88e9b21c14)

---
updated-dependencies:
- dependency-name: github/codeql-action
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Co-authored-by: Christopher Phillips <christopher.phillips@anchore.com>
2024-04-30 16:27:14 +00:00
Alex Goodman 5b03788300 Fill in SPDX originator for all supported package types (#2822)
* add failing test + beef up doc comments

Signed-off-by: Alex Goodman <wagoodman@users.noreply.github.com>

* cover more metadata types in spdx originator processing

Signed-off-by: Alex Goodman <wagoodman@users.noreply.github.com>

---------

Signed-off-by: Alex Goodman <wagoodman@users.noreply.github.com>
2024-04-29 16:33:00 -04:00
dependabot[bot] 9901ea8fe9 chore(deps): bump anchore/sbom-action from 0.15.10 to 0.15.11 (#2821)
Bumps [anchore/sbom-action](https://github.com/anchore/sbom-action) from 0.15.10 to 0.15.11.
- [Release notes](https://github.com/anchore/sbom-action/releases)
- [Commits](https://github.com/anchore/sbom-action/compare/ab5d7b5f48981941c4c5d6bf33aeb98fe3bae38c...7ccf588e3cf3cc2611714c2eeae48550fbc17552)

---
updated-dependencies:
- dependency-name: anchore/sbom-action
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2024-04-29 12:40:43 -04:00
Alex Goodman 87cd6c8c48 update spdx license list to 3.23 (#2818)
Signed-off-by: Alex Goodman <wagoodman@users.noreply.github.com>
2024-04-26 14:50:55 +00:00
William Murphy d3310a1830 fix: re-use embedded union reader if possible (#2814)
* fix: re-use embedded union reader if possible

Previously, because file.LocationReadCloser embeds a ReadCloser that
might be a UnionReader, but doesn't implement the interface itself, the
type assertion would fall and Syft would fall back to io.ReadAll to
enable seeking on the underlying reader, resulting in a potentially
large extra allocation.

Instead, check whether the passed ReadCloser is a
file.LocationReadCloser, and if so, try to use the embedded ReadCloser
as a UnionReader.

Signed-off-by: Will Murphy <will.murphy@anchore.com>

* lint fix

Signed-off-by: Will Murphy <will.murphy@anchore.com>

* Assert that underlying reader is returned

Signed-off-by: Will Murphy <will.murphy@anchore.com>

---------

Signed-off-by: Will Murphy <will.murphy@anchore.com>
2024-04-26 10:21:38 -04:00
Weston Steimel 8640f978ba feat: index known CPEs for go modules (#2816)
Signed-off-by: Weston Steimel <commits@weston.slmail.me>
2024-04-26 09:55:05 -04:00
dependabot[bot] 13b06dad45 chore(deps): bump peter-evans/create-pull-request from 6.0.4 to 6.0.5 (#2812) 2024-04-25 10:32:10 -04:00
Weston Steimel 9604e3dc9c feat: support multiple known CPEs in index (#2813)
It is possible that a given package has multiple known "official" CPEs
active in the dictionary at once, so the index should support a slice of
CPE strings per package

Signed-off-by: Weston Steimel <commits@weston.slmail.me>
2024-04-25 15:22:26 +01:00
anchore-actions-token-generator[bot]andkzantow f2fc10aa86 chore(deps): update stereoscope to 8b297badafd5d81fa1187b26ae34dd2a7ce7e425 (#2807)
Signed-off-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
Co-authored-by: kzantow <3009477+kzantow@users.noreply.github.com>
2024-04-24 15:19:13 -04:00
dependabot[bot] 21b22555d2 chore(deps): bump actions/checkout from 4.1.3 to 4.1.4 (#2809)
Bumps [actions/checkout](https://github.com/actions/checkout) from 4.1.3 to 4.1.4.
- [Release notes](https://github.com/actions/checkout/releases)
- [Changelog](https://github.com/actions/checkout/blob/main/CHANGELOG.md)
- [Commits](https://github.com/actions/checkout/compare/1d96c772d19495a3b5c517cd2bc0cb401ea0529f...0ad4b8fadaa221de15dcec353f45205ec38ea70b)

---
updated-dependencies:
- dependency-name: actions/checkout
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2024-04-24 15:19:03 -04:00
dependabot[bot] 5326efcef1 chore(deps): bump github.com/gkampitakis/go-snaps from 0.5.3 to 0.5.4 (#2810)
Bumps [github.com/gkampitakis/go-snaps](https://github.com/gkampitakis/go-snaps) from 0.5.3 to 0.5.4.
- [Release notes](https://github.com/gkampitakis/go-snaps/releases)
- [Commits](https://github.com/gkampitakis/go-snaps/compare/v0.5.3...v0.5.4)

---
updated-dependencies:
- dependency-name: github.com/gkampitakis/go-snaps
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2024-04-24 12:04:09 -04:00
Gijs Calis b90e7f9437 Fix removing labels in 'Detect schema changes' job (#2772)
* Fix error messages for add & remove label

Signed-off-by: Gijs Calis <51088038+GijsCalis@users.noreply.github.com>

* Check if label exists on PR before removing

Signed-off-by: Gijs Calis <51088038+GijsCalis@users.noreply.github.com>

---------

Signed-off-by: Gijs Calis <51088038+GijsCalis@users.noreply.github.com>
2024-04-23 14:42:57 -04:00
dependabot[bot] fbdd4ee015 chore(deps): bump github.com/docker/docker (#2805)
Bumps [github.com/docker/docker](https://github.com/docker/docker) from 26.0.2+incompatible to 26.1.0+incompatible.
- [Release notes](https://github.com/docker/docker/releases)
- [Commits](https://github.com/docker/docker/compare/v26.0.2...v26.1.0)

---
updated-dependencies:
- dependency-name: github.com/docker/docker
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2024-04-23 14:32:34 -04:00
William Murphy f154bf570d Display which provider caused which error in output (#2757)
* Display which provider caused which error in output

Otherwise, the output is very difficult to parse.

Signed-off-by: Will Murphy <will.murphy@anchore.com>

* lint fix

Signed-off-by: Will Murphy <will.murphy@anchore.com>

* bump stereoscope to v0.0.2

Signed-off-by: Will Murphy <will.murphy@anchore.com>

---------

Signed-off-by: Will Murphy <will.murphy@anchore.com>
2024-04-23 14:27:39 -04:00
Weston Steimel 99b58db497 fix: prefer non-deprecated CPEs and include jenkins plugins from plugins.jenkins.io (#2806)
Improves the logic for adding known CPEs for Jenkins plugins by
including `plugins.jenkins.io` and prefers non-deprecated CPEs

Signed-off-by: Weston Steimel <commits@weston.slmail.me>
2024-04-23 11:11:47 -04:00
Weston Steimel 8d960e62c6 feat: index known CPEs for PHP Composer packagist.org packages (#2804)
Indexes known CPEs from `packagist.org`

Signed-off-by: Weston Steimel <commits@weston.slmail.me>
2024-04-23 10:42:59 -04:00
dependabot[bot] 27a8a1be03 chore(deps): bump github/codeql-action from 3.25.1 to 3.25.2 (#2802)
Bumps [github/codeql-action](https://github.com/github/codeql-action) from 3.25.1 to 3.25.2.
- [Release notes](https://github.com/github/codeql-action/releases)
- [Changelog](https://github.com/github/codeql-action/blob/main/CHANGELOG.md)
- [Commits](https://github.com/github/codeql-action/compare/c7f9125735019aa87cfc361530512d50ea439c71...8f596b4ae3cb3c588a5c46780b86dd53fef16c52)

---
updated-dependencies:
- dependency-name: github/codeql-action
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2024-04-23 09:54:36 -04:00
dependabot[bot] 4ccbd17255 chore(deps): bump actions/upload-artifact from 4.3.2 to 4.3.3 (#2803)
Bumps [actions/upload-artifact](https://github.com/actions/upload-artifact) from 4.3.2 to 4.3.3.
- [Release notes](https://github.com/actions/upload-artifact/releases)
- [Commits](https://github.com/actions/upload-artifact/compare/1746f4ab65b179e0ea60a494b83293b640dd5bba...65462800fd760344b1a7b4382951275a0abb4808)

---
updated-dependencies:
- dependency-name: actions/upload-artifact
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2024-04-23 09:54:28 -04:00
Weston Steimel 891e61a2ef fix: improvements to known CPE index construction (#2801)
* fix: stop pre-filtering potential known CPE URLs

Previously when building the known CPE index, there was logic to
de-duplicate processing based on the normalized CPE name; however, this
means a significant number of known CPE's don't get indexed because the
first instance of that name didn't have a supported collection url but a
later one did.  This isn't code that executes at runtime in syft so
de-duplicating the processing for performance isn't really necessary
here and it doesn't add much to the total runtime anyways

Signed-off-by: Weston Steimel <commits@weston.slmail.me>

* fix: CPE index builder should extract and consider all reference urls

Previously the struct definition for CpeItem caused only the last URL
reference in the list to be kept and processed for inclusion in the
index

Signed-off-by: Weston Steimel <commits@weston.slmail.me>

---------

Signed-off-by: Weston Steimel <commits@weston.slmail.me>
2024-04-23 09:28:18 -04:00
Keith Zantow f7d3d552ce fix: exclude known instrumentation jars from being erroneously identified (#2796)
Signed-off-by: Keith Zantow <kzantow@gmail.com>
2024-04-22 15:03:17 -04:00
Weston Steimel 12ea9912b4 feat: index known cpes for PHP extensions (#2777)
Indexes known CPEs from `pecl.php.net` and `pear.php.net`

Signed-off-by: Weston Steimel <commits@weston.slmail.me>
2024-04-22 13:43:19 -04:00
dependabot[bot] cf6f92f2c8 chore(deps): bump actions/checkout from 4.1.2 to 4.1.3 (#2799)
Bumps [actions/checkout](https://github.com/actions/checkout) from 4.1.2 to 4.1.3.
- [Release notes](https://github.com/actions/checkout/releases)
- [Changelog](https://github.com/actions/checkout/blob/main/CHANGELOG.md)
- [Commits](https://github.com/actions/checkout/compare/9bb56186c3b09b4f86b1c65136769dd318469633...1d96c772d19495a3b5c517cd2bc0cb401ea0529f)

---
updated-dependencies:
- dependency-name: actions/checkout
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2024-04-22 13:29:13 -04:00
William Murphy 6440f26b5a fix: return empty string if dereferncing pom var fails (#2797)
Previously, Syft would attempt to dereference pom variables, but if it
detected a cycle or failed to get back to a non-variable value, it would
return the last variable. Instead, return an empty string. Otherwise,
certain jars will have versions like "${project.version}" in the SBOM,
which is not helpful.

Signed-off-by: Will Murphy <will.murphy@anchore.com>
2024-04-19 19:38:36 +00:00
dependabot[bot] f2633800ce chore(deps): bump github.com/docker/docker (#2793)
Bumps [github.com/docker/docker](https://github.com/docker/docker) from 26.0.1+incompatible to 26.0.2+incompatible.
- [Release notes](https://github.com/docker/docker/releases)
- [Commits](https://github.com/docker/docker/compare/v26.0.1...v26.0.2)

---
updated-dependencies:
- dependency-name: github.com/docker/docker
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2024-04-19 15:06:57 -04:00
dependabot[bot] 4f227bf447 chore(deps): bump modernc.org/sqlite from 1.29.7 to 1.29.8 (#2794)
Bumps [modernc.org/sqlite](https://gitlab.com/cznic/sqlite) from 1.29.7 to 1.29.8.
- [Commits](https://gitlab.com/cznic/sqlite/compare/v1.29.7...v1.29.8)

---
updated-dependencies:
- dependency-name: modernc.org/sqlite
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2024-04-19 15:06:44 -04:00
dependabot[bot] d70eb3d04b chore(deps): bump actions/upload-artifact from 4.3.1 to 4.3.2 (#2795)
Bumps [actions/upload-artifact](https://github.com/actions/upload-artifact) from 4.3.1 to 4.3.2.
- [Release notes](https://github.com/actions/upload-artifact/releases)
- [Commits](https://github.com/actions/upload-artifact/compare/5d5d22a31266ced268874388b861e4b58bb5c2f3...1746f4ab65b179e0ea60a494b83293b640dd5bba)

---
updated-dependencies:
- dependency-name: actions/upload-artifact
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2024-04-19 15:06:32 -04:00
guangwu fe4819bc08 chore: cleanup redundant code (#2791)
Signed-off-by: guoguangwu <guoguangwug@gmail.com>
2024-04-19 12:12:48 -04:00
anchore-actions-token-generator[bot]andspiffcs b26b38d6c5 chore(deps): update tools to latest versions (#2789)
Signed-off-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
Co-authored-by: spiffcs <32073428+spiffcs@users.noreply.github.com>
2024-04-18 12:40:08 -04:00
dependabot[bot] 31969136e3 chore(deps): bump github.com/spdx/tools-golang from 0.5.3 to 0.5.4 (#2790)
Bumps [github.com/spdx/tools-golang](https://github.com/spdx/tools-golang) from 0.5.3 to 0.5.4.
- [Release notes](https://github.com/spdx/tools-golang/releases)
- [Changelog](https://github.com/spdx/tools-golang/blob/main/RELEASE-NOTES.md)
- [Commits](https://github.com/spdx/tools-golang/compare/v0.5.3...v0.5.4)

---
updated-dependencies:
- dependency-name: github.com/spdx/tools-golang
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2024-04-18 12:39:42 -04:00
dependabot[bot] f6845474bd chore(deps): bump github/codeql-action from 3.25.0 to 3.25.1 (#2786)
Bumps [github/codeql-action](https://github.com/github/codeql-action) from 3.25.0 to 3.25.1.
- [Release notes](https://github.com/github/codeql-action/releases)
- [Changelog](https://github.com/github/codeql-action/blob/main/CHANGELOG.md)
- [Commits](https://github.com/github/codeql-action/compare/df5a14dc28094dc936e103b37d749c6628682b60...c7f9125735019aa87cfc361530512d50ea439c71)

---
updated-dependencies:
- dependency-name: github/codeql-action
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2024-04-17 10:46:34 -04:00
dependabot[bot] e1cadead1d chore(deps): bump peter-evans/create-pull-request from 6.0.3 to 6.0.4 (#2787)
Bumps [peter-evans/create-pull-request](https://github.com/peter-evans/create-pull-request) from 6.0.3 to 6.0.4.
- [Release notes](https://github.com/peter-evans/create-pull-request/releases)
- [Commits](https://github.com/peter-evans/create-pull-request/compare/c55203cfde3e5c11a452d352b4393e68b85b4533...9153d834b60caba6d51c9b9510b087acf9f33f83)

---
updated-dependencies:
- dependency-name: peter-evans/create-pull-request
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2024-04-17 10:46:24 -04:00
William Murphy 3e71f46fc8 Fix: repeatedly dereference pom variables (#2781)
* Fix: repeatedly dereference pom variables

Previously, if there was more than one layer of variable indirection in
the pom property (propert A says it has the same value as property B,
property B says it has the same value as property C), then Syft would
only dereference one layer. Add a loop to dereference variables until
either dereferencing fails, or until the variable is completely
dereferenced back to a literal.

Signed-off-by: Will Murphy <will.murphy@anchore.com>

* switch to recursive implementation

Signed-off-by: Will Murphy <will.murphy@anchore.com>

* add test cases for degenerate poms

Signed-off-by: Will Murphy <will.murphy@anchore.com>

* switch to recursive implementation

Signed-off-by: Will Murphy <will.murphy@anchore.com>

* remove redundant pieces of test cases

Signed-off-by: Will Murphy <will.murphy@anchore.com>

---------

Signed-off-by: Will Murphy <will.murphy@anchore.com>
2024-04-16 15:44:02 -04:00
dependabot[bot] 3b01e13f92 chore(deps): bump modernc.org/sqlite from 1.29.6 to 1.29.7 (#2783)
Bumps [modernc.org/sqlite](https://gitlab.com/cznic/sqlite) from 1.29.6 to 1.29.7.
- [Commits](https://gitlab.com/cznic/sqlite/compare/v1.29.6...v1.29.7)

---
updated-dependencies:
- dependency-name: modernc.org/sqlite
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2024-04-16 11:05:35 -04:00
anchore-actions-token-generator[bot]andwestonsteimel 25c2e60358 chore(deps): update CPE dictionary index (#2780)
Signed-off-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
Co-authored-by: westonsteimel <1593939+westonsteimel@users.noreply.github.com>
2024-04-15 11:15:38 -04:00
dependabot[bot] dc7fa21980 chore(deps): bump github/codeql-action from 3.24.10 to 3.25.0 (#2779)
Bumps [github/codeql-action](https://github.com/github/codeql-action) from 3.24.10 to 3.25.0.
- [Release notes](https://github.com/github/codeql-action/releases)
- [Changelog](https://github.com/github/codeql-action/blob/main/CHANGELOG.md)
- [Commits](https://github.com/github/codeql-action/compare/4355270be187e1b672a7a1c7c7bae5afdc1ab94a...df5a14dc28094dc936e103b37d749c6628682b60)

---
updated-dependencies:
- dependency-name: github/codeql-action
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2024-04-15 10:00:54 -04:00
Weston Steimel 587690b875 chore: fix broken cpe index generation task (#2778)
Signed-off-by: Weston Steimel <commits@weston.slmail.me>
2024-04-15 09:39:57 -04:00
dependabot[bot] 21eaa5c82b chore(deps): bump github.com/docker/docker (#2773)
Bumps [github.com/docker/docker](https://github.com/docker/docker) from 26.0.0+incompatible to 26.0.1+incompatible.
- [Release notes](https://github.com/docker/docker/releases)
- [Commits](https://github.com/docker/docker/compare/v26.0.0...v26.0.1)

---
updated-dependencies:
- dependency-name: github.com/docker/docker
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2024-04-12 15:33:27 -04:00
dependabot[bot] 081ec04b3f chore(deps): bump peter-evans/create-pull-request from 6.0.2 to 6.0.3 (#2774)
Bumps [peter-evans/create-pull-request](https://github.com/peter-evans/create-pull-request) from 6.0.2 to 6.0.3.
- [Release notes](https://github.com/peter-evans/create-pull-request/releases)
- [Commits](https://github.com/peter-evans/create-pull-request/compare/70a41aba780001da0a30141984ae2a0c95d8704e...c55203cfde3e5c11a452d352b4393e68b85b4533)

---
updated-dependencies:
- dependency-name: peter-evans/create-pull-request
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2024-04-12 15:31:36 -04:00
Keith ZantowandWill Murphy dde5d349b1 fix: more robust go main version extraction (#2767)
Signed-off-by: Keith Zantow <kzantow@gmail.com>
Signed-off-by: Will Murphy <will.murphy@anchore.com>
Co-authored-by: Will Murphy <will.murphy@anchore.com>
2024-04-11 11:58:51 -04:00
anchore-actions-token-generator[bot]andspiffcs a5d77b9263 chore(deps): update tools to latest versions (#2768)
Signed-off-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
Co-authored-by: spiffcs <32073428+spiffcs@users.noreply.github.com>
2024-04-11 11:53:55 -04:00
Laurent GoderreandKeith Zantow c9aab4863b fix: binary character in java version (#2766)
Signed-off-by: Laurent Goderre <laurent.goderre@docker.com>
Signed-off-by: Keith Zantow <kzantow@gmail.com>
Co-authored-by: Keith Zantow <kzantow@gmail.com>
2024-04-11 10:32:24 -04:00
anchore-actions-token-generator[bot]andspiffcs af1a065d2a chore(deps): update tools to latest versions (#2760)
Signed-off-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
Co-authored-by: spiffcs <32073428+spiffcs@users.noreply.github.com>
2024-04-09 12:03:12 -04:00
dependabot[bot] 88cef1e05c chore(deps): bump modernc.org/sqlite from 1.29.5 to 1.29.6 (#2761)
Bumps [modernc.org/sqlite](https://gitlab.com/cznic/sqlite) from 1.29.5 to 1.29.6.
- [Commits](https://gitlab.com/cznic/sqlite/compare/v1.29.5...v1.29.6)

---
updated-dependencies:
- dependency-name: modernc.org/sqlite
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2024-04-09 12:02:56 -04:00
dependabot[bot] 870d97ca5a chore(deps): bump github.com/jedib0t/go-pretty/v6 from 6.5.6 to 6.5.8 (#2754)
Bumps [github.com/jedib0t/go-pretty/v6](https://github.com/jedib0t/go-pretty) from 6.5.6 to 6.5.8.
- [Release notes](https://github.com/jedib0t/go-pretty/releases)
- [Commits](https://github.com/jedib0t/go-pretty/compare/v6.5.6...v6.5.8)

---
updated-dependencies:
- dependency-name: github.com/jedib0t/go-pretty/v6
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2024-04-08 12:19:45 -04:00
dependabot[bot] e681bc4780 chore(deps): bump github.com/gkampitakis/go-snaps from 0.5.2 to 0.5.3 (#2755)
Bumps [github.com/gkampitakis/go-snaps](https://github.com/gkampitakis/go-snaps) from 0.5.2 to 0.5.3.
- [Release notes](https://github.com/gkampitakis/go-snaps/releases)
- [Commits](https://github.com/gkampitakis/go-snaps/compare/v0.5.2...v0.5.3)

---
updated-dependencies:
- dependency-name: github.com/gkampitakis/go-snaps
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2024-04-08 12:19:32 -04:00
dependabot[bot] c31696f131 chore(deps): bump github/codeql-action from 3.24.9 to 3.24.10 (#2756)
Bumps [github/codeql-action](https://github.com/github/codeql-action) from 3.24.9 to 3.24.10.
- [Release notes](https://github.com/github/codeql-action/releases)
- [Changelog](https://github.com/github/codeql-action/blob/main/CHANGELOG.md)
- [Commits](https://github.com/github/codeql-action/compare/1b1aada464948af03b950897e5eb522f92603cc2...4355270be187e1b672a7a1c7c7bae5afdc1ab94a)

---
updated-dependencies:
- dependency-name: github/codeql-action
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2024-04-08 12:19:20 -04:00
dependabot[bot] 67781e98a2 chore(deps): bump golang.org/x/mod from 0.16.0 to 0.17.0 (#2751)
Bumps [golang.org/x/mod](https://github.com/golang/mod) from 0.16.0 to 0.17.0.
- [Commits](https://github.com/golang/mod/compare/v0.16.0...v0.17.0)

---
updated-dependencies:
- dependency-name: golang.org/x/mod
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2024-04-05 19:22:00 +00:00
Laurent Goderre 619ace65c3 Differentiate between JRE and JDK (#2748)
Signed-off-by: Laurent Goderre <laurent.goderre@docker.com>
2024-04-05 15:10:58 -04:00
dependabot[bot] 3e4e3bb1d4 chore(deps): bump golang.org/x/net from 0.23.0 to 0.24.0 (#2752)
Bumps [golang.org/x/net](https://github.com/golang/net) from 0.23.0 to 0.24.0.
- [Commits](https://github.com/golang/net/compare/v0.23.0...v0.24.0)

---
updated-dependencies:
- dependency-name: golang.org/x/net
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2024-04-05 15:10:15 -04:00
anchore-actions-token-generator[bot]andspiffcs 1e31356c49 chore(deps): update tools to latest versions (#2744)
Signed-off-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
Co-authored-by: spiffcs <32073428+spiffcs@users.noreply.github.com>
2024-04-04 10:34:19 -04:00
dependabot[bot] 0fa925e5af chore(deps): bump golang.org/x/net from 0.22.0 to 0.23.0 (#2747)
Bumps [golang.org/x/net](https://github.com/golang/net) from 0.22.0 to 0.23.0.
- [Commits](https://github.com/golang/net/compare/v0.22.0...v0.23.0)

---
updated-dependencies:
- dependency-name: golang.org/x/net
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2024-04-04 10:34:03 -04:00
Christopher Angelo Phillips e100776f22 chore: update anchore/packageurl-go to use latest commits (#2746)
chore: update packageurl-go dependency to use latest commits
chore: go mod tidy
unit: update + -> %2B
---------
Signed-off-by: Christopher Phillips <christopher.phillips@anchore.com>
2024-04-04 10:33:51 -04:00
Laurent Goderre e0233625cb feat: cataloger for PHP Pecl and PEAR packages (#2604)
Signed-off-by: Laurent Goderre <laurent.goderre@docker.com>
2024-04-02 11:55:56 -04:00
dependabot[bot] e0f5b5a787 chore(deps): bump github.com/go-git/go-git/v5 from 5.11.0 to 5.12.0 (#2743)
Bumps [github.com/go-git/go-git/v5](https://github.com/go-git/go-git) from 5.11.0 to 5.12.0.
- [Release notes](https://github.com/go-git/go-git/releases)
- [Commits](https://github.com/go-git/go-git/compare/v5.11.0...v5.12.0)

---
updated-dependencies:
- dependency-name: github.com/go-git/go-git/v5
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2024-04-01 14:14:07 -04:00
anchore-actions-token-generator[bot]andspiffcs 9c42c83229 chore(deps): update tools to latest versions (#2741)
Signed-off-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
Co-authored-by: spiffcs <32073428+spiffcs@users.noreply.github.com>
2024-03-30 17:51:21 -04:00
Keith Zantow 01340b2a5c fix: conan poco project cpe (#2740)
Signed-off-by: Keith Zantow <kzantow@gmail.com>
2024-03-28 16:56:24 -04:00
dependabot[bot] 16edb40c72 chore(deps): bump github.com/distribution/reference from 0.5.0 to 0.6.0 (#2738)
Bumps [github.com/distribution/reference](https://github.com/distribution/reference) from 0.5.0 to 0.6.0.
- [Release notes](https://github.com/distribution/reference/releases)
- [Commits](https://github.com/distribution/reference/compare/v0.5.0...v0.6.0)

---
updated-dependencies:
- dependency-name: github.com/distribution/reference
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2024-03-28 12:22:00 -04:00
dependabot[bot] 5a865d0d90 chore(deps): bump anchore/sbom-action from 0.15.9 to 0.15.10 (#2737) 2024-03-27 17:52:22 +00:00
Keith Zantow 410867ca0c fix: panic scanning binaries without symtab (#2739)
Signed-off-by: Keith Zantow <kzantow@gmail.com>
2024-03-27 13:51:45 -04:00
guangwu 469b4c13bb chore: remove useless code (#2716)
Signed-off-by: guoguangwu <guoguangwug@gmail.com>
2024-03-26 12:21:03 -04:00
dependabot[bot] 57e9cc52a4 chore(deps): bump google.golang.org/protobuf from 1.31.0 to 1.33.0 (#2731)
Bumps google.golang.org/protobuf from 1.31.0 to 1.33.0.

---
updated-dependencies:
- dependency-name: google.golang.org/protobuf
  dependency-type: indirect
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2024-03-26 11:52:50 -04:00
dependabot[bot] 55fff0f4a1 chore(deps): bump github/codeql-action from 3.24.8 to 3.24.9 (#2732)
Bumps [github/codeql-action](https://github.com/github/codeql-action) from 3.24.8 to 3.24.9.
- [Release notes](https://github.com/github/codeql-action/releases)
- [Changelog](https://github.com/github/codeql-action/blob/main/CHANGELOG.md)
- [Commits](https://github.com/github/codeql-action/compare/05963f47d870e2cb19a537396c1f668a348c7d8f...1b1aada464948af03b950897e5eb522f92603cc2)

---
updated-dependencies:
- dependency-name: github/codeql-action
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2024-03-26 11:50:31 -04:00
anchore-actions-token-generator[bot]andspiffcs 2a7b4f3761 chore(deps): update tools to latest versions (#2733)
Signed-off-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
Co-authored-by: spiffcs <32073428+spiffcs@users.noreply.github.com>
2024-03-26 11:50:21 -04:00
dependabot[bot] fe3704d4a9 chore(deps): bump github.com/jedib0t/go-pretty/v6 from 6.5.5 to 6.5.6 (#2734)
Bumps [github.com/jedib0t/go-pretty/v6](https://github.com/jedib0t/go-pretty) from 6.5.5 to 6.5.6.
- [Release notes](https://github.com/jedib0t/go-pretty/releases)
- [Commits](https://github.com/jedib0t/go-pretty/compare/v6.5.5...v6.5.6)

---
updated-dependencies:
- dependency-name: github.com/jedib0t/go-pretty/v6
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2024-03-26 11:50:07 -04:00
Hung Nguyen 059cfd6730 update release token from readonly to write token (#2735)
Signed-off-by: Hung Nguyen <hung.tran.nguyen.585@gmail.com>
2024-03-26 09:06:55 -04:00
Colm O hEigeartaigh f4e18961b9 Adding the ability to retrieve remote licenses from package.lock (#2708)
Signed-off-by: Colm O hEigeartaigh <coheigea@apache.org>
2024-03-21 13:20:04 -04:00
Alex Goodman 0d5ebed74a dont include labels for dependabot ecosystems (#2720)
Signed-off-by: Alex Goodman <wagoodman@users.noreply.github.com>
2024-03-21 12:16:01 -04:00
dependabot[bot] 8f7305ef78 chore(deps): bump fountainhead/action-wait-for-check from 1.1.0 to 1.2.0 (#2717)
Bumps [fountainhead/action-wait-for-check](https://github.com/fountainhead/action-wait-for-check) from 1.1.0 to 1.2.0.
- [Release notes](https://github.com/fountainhead/action-wait-for-check/releases)
- [Commits](https://github.com/fountainhead/action-wait-for-check/compare/297be350cf8393728ea4d4b39435c7d7ae167c93...5a908a24814494009c4bb27c242ea38c93c593be)

---
updated-dependencies:
- dependency-name: fountainhead/action-wait-for-check
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2024-03-21 12:15:30 -04:00
anchore-actions-token-generator[bot]andspiffcs c199b80b88 chore(deps): update tools to latest versions (#2726)
Signed-off-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
Co-authored-by: spiffcs <32073428+spiffcs@users.noreply.github.com>
2024-03-21 12:15:06 -04:00
dependabot[bot] df547020ef chore(deps): bump github/codeql-action from 3.24.7 to 3.24.8 (#2725)
Bumps [github/codeql-action](https://github.com/github/codeql-action) from 3.24.7 to 3.24.8.
- [Release notes](https://github.com/github/codeql-action/releases)
- [Changelog](https://github.com/github/codeql-action/blob/main/CHANGELOG.md)
- [Commits](https://github.com/github/codeql-action/compare/3ab4101902695724f9365a384f86c1074d94e18c...05963f47d870e2cb19a537396c1f668a348c7d8f)

---
updated-dependencies:
- dependency-name: github/codeql-action
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2024-03-21 12:14:51 -04:00
dependabot[bot] 37094c9751 chore(deps): bump actions/cache from 4.0.1 to 4.0.2 (#2728)
Bumps [actions/cache](https://github.com/actions/cache) from 4.0.1 to 4.0.2.
- [Release notes](https://github.com/actions/cache/releases)
- [Changelog](https://github.com/actions/cache/blob/main/RELEASES.md)
- [Commits](https://github.com/actions/cache/compare/ab5e6d0c87105b4c9c2047343972218f562e4319...0c45773b623bea8c8e75f6c82b208c3cf94ea4f9)

---
updated-dependencies:
- dependency-name: actions/cache
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2024-03-21 12:14:43 -04:00
dependabot[bot] c83556e7b6 chore(deps): bump github.com/docker/docker (#2730)
Bumps [github.com/docker/docker](https://github.com/docker/docker) from 25.0.4+incompatible to 26.0.0+incompatible.
- [Release notes](https://github.com/docker/docker/releases)
- [Commits](https://github.com/docker/docker/compare/v25.0.4...v26.0.0)

---
updated-dependencies:
- dependency-name: github.com/docker/docker
  dependency-type: direct:production
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2024-03-21 12:14:32 -04:00
Hung Nguyen 3ac1cd7a9f updating credentials to scoped permissions (#2722)
* updating credentials to scoped permissions

Signed-off-by: Hung Nguyen <hung.tran.nguyen.585@gmail.com>

---------

Signed-off-by: Hung Nguyen <hung.tran.nguyen.585@gmail.com>
2024-03-20 17:35:07 -04:00
dependabot[bot] 96d2b4a368 chore(deps): bump github.com/jedib0t/go-pretty/v6 from 6.5.4 to 6.5.5 (#2718)
Bumps [github.com/jedib0t/go-pretty/v6](https://github.com/jedib0t/go-pretty) from 6.5.4 to 6.5.5.
- [Release notes](https://github.com/jedib0t/go-pretty/releases)
- [Commits](https://github.com/jedib0t/go-pretty/compare/v6.5.4...v6.5.5)

---
updated-dependencies:
- dependency-name: github.com/jedib0t/go-pretty/v6
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2024-03-15 10:33:11 -04:00
dependabot[bot] 807de976c4 chore(deps): bump github.com/google/go-containerregistry (#2719)
Bumps [github.com/google/go-containerregistry](https://github.com/google/go-containerregistry) from 0.19.0 to 0.19.1.
- [Release notes](https://github.com/google/go-containerregistry/releases)
- [Changelog](https://github.com/google/go-containerregistry/blob/main/.goreleaser.yml)
- [Commits](https://github.com/google/go-containerregistry/compare/v0.19.0...v0.19.1)

---
updated-dependencies:
- dependency-name: github.com/google/go-containerregistry
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2024-03-15 10:32:51 -04:00
Laurent GoderreandAlex Goodman cf17bd69b2 Add detection for Oracle GraalVM (#2705)
Signed-off-by: Laurent Goderre <laurent.goderre@docker.com>
Signed-off-by: Alex Goodman <wagoodman@users.noreply.github.com>
Co-authored-by: Alex Goodman <wagoodman@users.noreply.github.com>
2024-03-14 15:40:07 +00:00
dependabot[bot] 1c8d29d577 chore(deps): bump docker/login-action from 3.0.0 to 3.1.0 (#2714)
Bumps [docker/login-action](https://github.com/docker/login-action) from 3.0.0 to 3.1.0.
- [Release notes](https://github.com/docker/login-action/releases)
- [Commits](https://github.com/docker/login-action/compare/343f7c4344506bcbf9b4de18042ae17996df046d...e92390c5fb421da1463c202d546fed0ec5c39f20)

---
updated-dependencies:
- dependency-name: docker/login-action
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2024-03-14 11:16:16 -04:00
6a2517b5d2 Add ELF binary package cataloger (#2396)
* feat Adds Elf package catalogger

Signed-off-by: Brian Ebarb <ebarb.brian@gmail.com>

* Add test fixtures for elf package

Signed-off-by: Colleen Divers <colleen.divers@gmail.com>

* bump JSON schema to v16.0.6 + expand test fixtures

Signed-off-by: Alex Goodman <wagoodman@users.noreply.github.com>

* less verbose logging

Signed-off-by: Alex Goodman <wagoodman@users.noreply.github.com>

* remove dead test code

Signed-off-by: Alex Goodman <wagoodman@users.noreply.github.com>

* remove unreleated swift change

Signed-off-by: Alex Goodman <wagoodman@users.noreply.github.com>

---------

Signed-off-by: Brian Ebarb <ebarb.brian@gmail.com>
Signed-off-by: Colleen Divers <colleen.divers@gmail.com>
Signed-off-by: Alex Goodman <wagoodman@users.noreply.github.com>
Co-authored-by: Colleen Divers <colleen.divers@gmail.com>
Co-authored-by: Alex Goodman <wagoodman@users.noreply.github.com>
2024-03-14 11:16:03 -04:00
dependabot[bot] 7ab6fc3fe4 chore(deps): bump modernc.org/sqlite from 1.29.3 to 1.29.5 (#2710)
Bumps [modernc.org/sqlite](https://gitlab.com/cznic/sqlite) from 1.29.3 to 1.29.5.
- [Commits](https://gitlab.com/cznic/sqlite/compare/v1.29.3...v1.29.5)

---
updated-dependencies:
- dependency-name: modernc.org/sqlite
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2024-03-14 09:58:56 -04:00
dependabot[bot] 2051a62ded chore(deps): bump github/codeql-action from 3.24.6 to 3.24.7 (#2711)
Bumps [github/codeql-action](https://github.com/github/codeql-action) from 3.24.6 to 3.24.7.
- [Release notes](https://github.com/github/codeql-action/releases)
- [Changelog](https://github.com/github/codeql-action/blob/main/CHANGELOG.md)
- [Commits](https://github.com/github/codeql-action/compare/8a470fddafa5cbb6266ee11b37ef4d8aae19c571...3ab4101902695724f9365a384f86c1074d94e18c)

---
updated-dependencies:
- dependency-name: github/codeql-action
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2024-03-14 09:58:42 -04:00
159 changed files with 19774 additions and 4813 deletions
+6 -6
View File
@@ -2,7 +2,7 @@ tools:
# we want to use a pinned version of binny to manage the toolchain (so binny manages itself!)
- name: binny
version:
want: v0.6.3
want: v0.7.0
method: github-release
with:
repo: anchore/binny
@@ -26,7 +26,7 @@ tools:
# used for linting
- name: golangci-lint
version:
want: v1.56.2
want: v1.57.2
method: github-release
with:
repo: golangci/golangci-lint
@@ -42,7 +42,7 @@ tools:
# used for signing the checksums file at release
- name: cosign
version:
want: v2.2.3
want: v2.2.4
method: github-release
with:
repo: sigstore/cosign
@@ -58,7 +58,7 @@ tools:
# used to release all artifacts
- name: goreleaser
version:
want: v1.24.0
want: v1.25.1
method: github-release
with:
repo: goreleaser/goreleaser
@@ -103,7 +103,7 @@ tools:
# used for running all local and CI tasks
- name: task
version:
want: v3.35.1
want: v3.36.0
method: github-release
with:
repo: go-task/task
@@ -111,7 +111,7 @@ tools:
# used for triggering a release
- name: gh
version:
want: v2.45.0
want: v2.48.0
method: github-release
with:
repo: cli/cli
+1 -1
View File
@@ -27,7 +27,7 @@ runs:
using: "composite"
steps:
# note: go mod and build is automatically cached on default with v4+
- uses: actions/setup-go@93397bea11091df50f3d7e59dc26a7711a8bcfbe #v4.1.0
- uses: actions/setup-go@cdcb36043654635271a94b9a6d1392de5bb323a7 #v5.0.1
if: inputs.go-version != ''
with:
go-version: ${{ inputs.go-version }}
+8 -1
View File
@@ -1,12 +1,19 @@
version: 2
updates:
- package-ecosystem: gomod
directory: "/"
schedule:
interval: "daily"
open-pull-requests-limit: 10
labels:
- "dependencies"
- package-ecosystem: "github-actions"
directory: "/"
schedule:
interval: "daily"
open-pull-requests-limit: 10
open-pull-requests-limit: 10
labels:
- "dependencies"
+19 -4
View File
@@ -56,6 +56,8 @@ def main(changed_files: str | None = None, merge_base_schema_files: str | None =
pr_json_schema_files = filter_to_schema_files(pr_changed_files)
pr_labels = get_pr_labels(pr_number)
# print("schema files in pr: ", summarize_schema_files(pr_json_schema_files))
# print("og schema files: ", summarize_schema_files(og_json_schema_files))
@@ -76,7 +78,8 @@ def main(changed_files: str | None = None, merge_base_schema_files: str | None =
add_label(pr_number, JSON_SCHEMA_LABEL)
else:
remove_label(pr_number, JSON_SCHEMA_LABEL)
if JSON_SCHEMA_LABEL in pr_labels:
remove_label(pr_number, JSON_SCHEMA_LABEL)
# new schema files should be scrutinized, comparing the latest and added versions to see if it's a breaking
# change (major version bump). Warn about it on the PR via adding a breaking-change label...
@@ -84,7 +87,8 @@ def main(changed_files: str | None = None, merge_base_schema_files: str | None =
print("\nBreaking change detected...")
add_label(pr_number, BREAKING_CHANGE_LABEL)
else:
remove_label(pr_number, BREAKING_CHANGE_LABEL)
if BREAKING_CHANGE_LABEL in pr_labels:
remove_label(pr_number, BREAKING_CHANGE_LABEL)
# modifying an existing schema could be a breaking change, we should warn about it on the PR via a comment...
# removing schema files should never be allowed, we should warn about it on the PR via a comment...
@@ -119,7 +123,7 @@ def add_label(pr_number: str, label: str):
# run "gh pr edit --add-label <label>"
result = run(f"gh pr edit {pr_number} --add-label {label}", shell=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
if result.returncode != 0:
print(f"Unable to add {label!r} label to PR with")
print(f"Unable to add '{label!r}' label to PR, error:")
print(str(result.stderr))
sys.exit(1)
@@ -128,7 +132,7 @@ def remove_label(pr_number: str, label: str):
# run "gh pr edit --remove-label <label>"
result = run(f"gh pr edit {pr_number} --remove-label {label}", shell=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
if result.returncode != 0:
print(f"Unable to label PR with {label!r}")
print(f"Unable to remove '{label!r}' label from PR, error:")
print(str(result.stderr))
sys.exit(1)
@@ -165,6 +169,17 @@ def get_pr_changed_files(pr_number: str) -> list[str]:
return list_of_files
def get_pr_labels(pr_number: str) -> list[str]:
result = run(f"gh pr view {pr_number} --json labels --jq '.labels[].name'", shell=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE, text=True)
if result.returncode != 0:
print("Unable to get list of labels on PR")
print(str(result.stderr))
sys.exit(1)
list_of_labels = result.stdout.splitlines()
return list_of_labels
def filter_to_schema_files(list_of_files: list[str]) -> list[str]:
# get files matching "schema/json/schema-*.json"
files = []
+3 -4
View File
@@ -2,8 +2,8 @@
set -ue
BIN="syft"
DISTDIR=$1
VERSION=$2
VERSION_FILE="VERSION"
VERSION=$1
# the source of truth as to whether we want to notify users of an update is if the release just created is NOT
# flagged as a pre-release on github
@@ -12,10 +12,9 @@ if [[ "$(curl -SsL https://api.github.com/repos/anchore/${BIN}/releases/tags/${V
exit 0
fi
echo "creating and publishing version file"
echo "creating and publishing version file (${VERSION})"
# create a version file for version-update checks
VERSION_FILE="${DISTDIR}/VERSION"
echo "${VERSION}" | tee "${VERSION_FILE}"
# upload the version file that supports the application version update check
+3 -3
View File
@@ -17,13 +17,13 @@ jobs:
# the job by event.
steps:
- name: Checkout code
uses: actions/checkout@9bb56186c3b09b4f86b1c65136769dd318469633 # v4.1.2
uses: actions/checkout@44c2b7a8a4ea60a981eaca3cf939b5f4305c123b # v4.1.5
- name: Bootstrap environment
uses: ./.github/actions/bootstrap
- name: Restore base benchmark result
uses: actions/cache@ab5e6d0c87105b4c9c2047343972218f562e4319 #v4.0.1
uses: actions/cache@0c45773b623bea8c8e75f6c82b208c3cf94ea4f9 #v4.0.2
with:
path: test/results/benchmark-main.txt
# use base sha for PR or new commit hash for main push in benchmark result key
@@ -39,7 +39,7 @@ jobs:
OUTPUT="${OUTPUT//$'\r'/'%0D'}" # URL encode all '\r' characters
echo "result=$OUTPUT" >> $GITHUB_OUTPUT
- uses: actions/upload-artifact@5d5d22a31266ced268874388b861e4b58bb5c2f3 # v4.3.1
- uses: actions/upload-artifact@65462800fd760344b1a7b4382951275a0abb4808 # v4.3.3
with:
name: benchmark-test-results
path: test/results/**/*
+5 -5
View File
@@ -36,16 +36,16 @@ jobs:
steps:
- name: Checkout repository
uses: actions/checkout@9bb56186c3b09b4f86b1c65136769dd318469633 #v4.1.2
uses: actions/checkout@44c2b7a8a4ea60a981eaca3cf939b5f4305c123b #v4.1.5
- name: Install Go
uses: actions/setup-go@0c52d547c9bc32b1aa3301fd7a9cb496313a4491 #v5.0.0
uses: actions/setup-go@cdcb36043654635271a94b9a6d1392de5bb323a7 #v5.0.1
with:
go-version-file: go.mod
# Initializes the CodeQL tools for scanning.
- name: Initialize CodeQL
uses: github/codeql-action/init@8a470fddafa5cbb6266ee11b37ef4d8aae19c571 #v3.24.6
uses: github/codeql-action/init@ccf74c947955fd1cf117aef6a0e4e66191ef6f61 #v3.25.4
with:
languages: ${{ matrix.language }}
# If you wish to specify custom queries, you can do so here or in a config file.
@@ -56,7 +56,7 @@ jobs:
# Autobuild attempts to build any compiled languages (C/C++, C#, or Java).
# If this step fails, then you should remove it and run the build manually (see below)
- name: Autobuild
uses: github/codeql-action/autobuild@8a470fddafa5cbb6266ee11b37ef4d8aae19c571 #v3.24.6
uses: github/codeql-action/autobuild@ccf74c947955fd1cf117aef6a0e4e66191ef6f61 #v3.25.4
# ℹ️ Command-line programs to run using the OS shell.
# 📚 https://git.io/JvXDl
@@ -70,4 +70,4 @@ jobs:
# make release
- name: Perform CodeQL Analysis
uses: github/codeql-action/analyze@8a470fddafa5cbb6266ee11b37ef4d8aae19c571 #v3.24.6
uses: github/codeql-action/analyze@ccf74c947955fd1cf117aef6a0e4e66191ef6f61 #v3.25.4
+1 -1
View File
@@ -30,7 +30,7 @@ jobs:
runs-on: ubuntu-22.04
steps:
- uses: actions/checkout@9bb56186c3b09b4f86b1c65136769dd318469633 #v4.1.2
- uses: actions/checkout@44c2b7a8a4ea60a981eaca3cf939b5f4305c123b #v4.1.5
- run: python .github/scripts/labeler.py
env:
-48
View File
@@ -1,48 +0,0 @@
name: "Release Homebrew"
on:
workflow_dispatch:
release:
types:
- released
jobs:
homebrew:
runs-on: ubuntu-20.04
steps:
- uses: actions/checkout@9bb56186c3b09b4f86b1c65136769dd318469633 #v4.1.2
with:
# we need to be able to get the commit for a tag
fetch-depth: 0
- name: Get release info
id: release_info
run: |
echo -n "tag_name=$(gh release view --json tagName --jq '.tagName')" | tee -a $GITHUB_OUTPUT
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
- name: Get commit info
id: git_info
run: |
git checkout ${{ steps.release_info.outputs.tag_name }}
echo -n "commit=$(git rev-parse HEAD)" | tee -a $GITHUB_OUTPUT
- name: Update Homebrew formula
uses: dawidd6/action-homebrew-bump-formula@baf2b60c51fc1f8453c884b0c61052668a71bd1d # v3.11.0
with:
token: ${{ secrets.HOMEBREW_TOKEN }}
org: anchore
formula: syft
tag: ${{ steps.release_info.outputs.tag_name }}
revision: ${{ steps.git_info.outputs.commit }}
- uses: 8398a7/action-slack@28ba43ae48961b90635b50953d216767a6bea486 #v3.16.2
if: ${{ failure() }}
with:
status: ${{ job.status }}
fields: repo,workflow,action,eventName
text: "Post-release homebrew publish workflow has failed: https://github.com/anchore/syft/actions/workflows/release-homebrew.yaml"
env:
SLACK_WEBHOOK_URL: ${{ secrets.SLACK_TOOLBOX_WEBHOOK_URL }}
@@ -0,0 +1,31 @@
name: "Release"
on:
workflow_dispatch:
inputs:
version:
description: release version to update the version file with (prefixed with v)
required: true
workflow_call:
inputs:
version:
type: string
description: release version to update the version file with (prefixed with v)
required: true
jobs:
release:
runs-on: ubuntu-20.04
steps:
- uses: actions/checkout@44c2b7a8a4ea60a981eaca3cf939b5f4305c123b #v4.1.5
- name: Update version file
run: make ci-release-version-file
env:
RELEASE_VERSION: ${{ github.event.inputs.version }}
# for updating the VERSION file in S3...
AWS_ACCESS_KEY_ID: ${{ secrets.TOOLBOX_AWS_ACCESS_KEY_ID }}
AWS_SECRET_ACCESS_KEY: ${{ secrets.TOOLBOX_AWS_SECRET_ACCESS_KEY }}
+21 -17
View File
@@ -15,7 +15,7 @@ jobs:
environment: release
runs-on: ubuntu-20.04
steps:
- uses: actions/checkout@9bb56186c3b09b4f86b1c65136769dd318469633 #v4.1.2
- uses: actions/checkout@44c2b7a8a4ea60a981eaca3cf939b5f4305c123b #v4.1.5
- name: Check if tag already exists
# note: this will fail if the tag already exists
@@ -24,7 +24,7 @@ jobs:
git tag ${{ github.event.inputs.version }}
- name: Check static analysis results
uses: fountainhead/action-wait-for-check@297be350cf8393728ea4d4b39435c7d7ae167c93 # v1.1.0
uses: fountainhead/action-wait-for-check@5a908a24814494009c4bb27c242ea38c93c593be # v1.2.0
id: static-analysis
with:
token: ${{ secrets.GITHUB_TOKEN }}
@@ -33,7 +33,7 @@ jobs:
ref: ${{ github.event.pull_request.head.sha || github.sha }}
- name: Check unit test results
uses: fountainhead/action-wait-for-check@297be350cf8393728ea4d4b39435c7d7ae167c93 # v1.1.0
uses: fountainhead/action-wait-for-check@5a908a24814494009c4bb27c242ea38c93c593be # v1.2.0
id: unit
with:
token: ${{ secrets.GITHUB_TOKEN }}
@@ -42,7 +42,7 @@ jobs:
ref: ${{ github.event.pull_request.head.sha || github.sha }}
- name: Check integration test results
uses: fountainhead/action-wait-for-check@297be350cf8393728ea4d4b39435c7d7ae167c93 # v1.1.0
uses: fountainhead/action-wait-for-check@5a908a24814494009c4bb27c242ea38c93c593be # v1.2.0
id: integration
with:
token: ${{ secrets.GITHUB_TOKEN }}
@@ -51,7 +51,7 @@ jobs:
ref: ${{ github.event.pull_request.head.sha || github.sha }}
- name: Check acceptance test results (linux)
uses: fountainhead/action-wait-for-check@297be350cf8393728ea4d4b39435c7d7ae167c93 # v1.1.0
uses: fountainhead/action-wait-for-check@5a908a24814494009c4bb27c242ea38c93c593be # v1.2.0
id: acceptance-linux
with:
token: ${{ secrets.GITHUB_TOKEN }}
@@ -60,7 +60,7 @@ jobs:
ref: ${{ github.event.pull_request.head.sha || github.sha }}
- name: Check acceptance test results (mac)
uses: fountainhead/action-wait-for-check@297be350cf8393728ea4d4b39435c7d7ae167c93 # v1.1.0
uses: fountainhead/action-wait-for-check@5a908a24814494009c4bb27c242ea38c93c593be # v1.2.0
id: acceptance-mac
with:
token: ${{ secrets.GITHUB_TOKEN }}
@@ -69,7 +69,7 @@ jobs:
ref: ${{ github.event.pull_request.head.sha || github.sha }}
- name: Check cli test results (linux)
uses: fountainhead/action-wait-for-check@297be350cf8393728ea4d4b39435c7d7ae167c93 # v1.1.0
uses: fountainhead/action-wait-for-check@5a908a24814494009c4bb27c242ea38c93c593be # v1.2.0
id: cli-linux
with:
token: ${{ secrets.GITHUB_TOKEN }}
@@ -97,7 +97,7 @@ jobs:
# required for goreleaser signs section with cosign
id-token: write
steps:
- uses: actions/checkout@9bb56186c3b09b4f86b1c65136769dd318469633 #v4.1.2
- uses: actions/checkout@44c2b7a8a4ea60a981eaca3cf939b5f4305c123b #v4.1.5
with:
fetch-depth: 0
@@ -105,13 +105,13 @@ jobs:
uses: ./.github/actions/bootstrap
- name: Login to Docker Hub
uses: docker/login-action@343f7c4344506bcbf9b4de18042ae17996df046d #v3.0.0
uses: docker/login-action@e92390c5fb421da1463c202d546fed0ec5c39f20 #v3.1.0
with:
username: ${{ secrets.TOOLBOX_DOCKER_USER }}
password: ${{ secrets.TOOLBOX_DOCKER_PASS }}
username: ${{ secrets.ANCHOREOSSWRITE_DH_USERNAME }}
password: ${{ secrets.ANCHOREOSSWRITE_DH_PAT }}
- name: Login to GitHub Container Registry
uses: docker/login-action@343f7c4344506bcbf9b4de18042ae17996df046d #v3.0.0
uses: docker/login-action@e92390c5fb421da1463c202d546fed0ec5c39f20 #v3.1.0
with:
registry: ghcr.io
username: ${{ github.actor }}
@@ -138,12 +138,9 @@ jobs:
# for creating the release (requires write access to packages and content)
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
# for updating brew formula in anchore/homebrew-syft
GITHUB_BREW_TOKEN: ${{ secrets.ANCHORE_GIT_READ_TOKEN }}
# for updating the VERSION file in S3...
AWS_ACCESS_KEY_ID: ${{ secrets.TOOLBOX_AWS_ACCESS_KEY_ID }}
AWS_SECRET_ACCESS_KEY: ${{ secrets.TOOLBOX_AWS_SECRET_ACCESS_KEY }}
GITHUB_BREW_TOKEN: ${{ secrets.ANCHOREOPS_GITHUB_OSS_WRITE_TOKEN }}
- uses: anchore/sbom-action@9fece9e20048ca9590af301449208b2b8861333b #v0.15.9
- uses: anchore/sbom-action@7ccf588e3cf3cc2611714c2eeae48550fbc17552 #v0.15.11
continue-on-error: true
with:
artifact-name: sbom.spdx.json
@@ -157,3 +154,10 @@ jobs:
env:
SLACK_WEBHOOK_URL: ${{ secrets.SLACK_TOOLBOX_WEBHOOK_URL }}
if: ${{ success() }}
release-version-file:
needs: [release]
uses: ./.github/workflows/release-version-file.yaml
with:
version: ${{ github.event.inputs.version }}
secrets: inherit
+2 -2
View File
@@ -13,7 +13,7 @@ jobs:
runs-on: ubuntu-latest
if: github.repository == 'anchore/syft' # only run for main repo
steps:
- uses: actions/checkout@9bb56186c3b09b4f86b1c65136769dd318469633 #v4.1.2
- uses: actions/checkout@44c2b7a8a4ea60a981eaca3cf939b5f4305c123b #v4.1.5
- name: Bootstrap environment
uses: ./.github/actions/bootstrap
@@ -50,7 +50,7 @@ jobs:
app_id: ${{ secrets.TOKEN_APP_ID }}
private_key: ${{ secrets.TOKEN_APP_PRIVATE_KEY }}
- uses: peter-evans/create-pull-request@70a41aba780001da0a30141984ae2a0c95d8704e #v6.0.2
- uses: peter-evans/create-pull-request@6d6857d36972b65feb161a90e484f2984215f83e #v6.0.5
with:
signoff: true
delete-branch: true
@@ -16,7 +16,7 @@ jobs:
runs-on: ubuntu-latest
if: github.repository == 'anchore/syft' # only run for main repo
steps:
- uses: actions/checkout@9bb56186c3b09b4f86b1c65136769dd318469633 #v4.1.2
- uses: actions/checkout@44c2b7a8a4ea60a981eaca3cf939b5f4305c123b #v4.1.5
- name: Bootstrap environment
uses: ./.github/actions/bootstrap
@@ -33,7 +33,7 @@ jobs:
app_id: ${{ secrets.TOKEN_APP_ID }}
private_key: ${{ secrets.TOKEN_APP_PRIVATE_KEY }}
- uses: peter-evans/create-pull-request@70a41aba780001da0a30141984ae2a0c95d8704e #v6.0.2
- uses: peter-evans/create-pull-request@6d6857d36972b65feb161a90e484f2984215f83e #v6.0.5
with:
signoff: true
delete-branch: true
@@ -17,9 +17,9 @@ jobs:
runs-on: ubuntu-latest
if: github.repository == 'anchore/syft' # only run for main repo
steps:
- uses: actions/checkout@9bb56186c3b09b4f86b1c65136769dd318469633 #v4.1.2
- uses: actions/checkout@44c2b7a8a4ea60a981eaca3cf939b5f4305c123b #v4.1.5
- uses: actions/setup-go@0c52d547c9bc32b1aa3301fd7a9cb496313a4491 #v5.0.0
- uses: actions/setup-go@cdcb36043654635271a94b9a6d1392de5bb323a7 #v5.0.1
with:
go-version: ${{ env.GO_VERSION }}
stable: ${{ env.GO_STABLE_VERSION }}
@@ -44,7 +44,7 @@ jobs:
app_id: ${{ secrets.TOKEN_APP_ID }}
private_key: ${{ secrets.TOKEN_APP_PRIVATE_KEY }}
- uses: peter-evans/create-pull-request@70a41aba780001da0a30141984ae2a0c95d8704e #v6.0.2
- uses: peter-evans/create-pull-request@6d6857d36972b65feb161a90e484f2984215f83e #v6.0.5
with:
signoff: true
delete-branch: true
+22 -22
View File
@@ -17,7 +17,7 @@ jobs:
name: "Static analysis"
runs-on: ubuntu-20.04
steps:
- uses: actions/checkout@9bb56186c3b09b4f86b1c65136769dd318469633 #v4.1.2
- uses: actions/checkout@44c2b7a8a4ea60a981eaca3cf939b5f4305c123b #v4.1.5
- name: Bootstrap environment
uses: ./.github/actions/bootstrap
@@ -31,49 +31,49 @@ jobs:
name: "Unit tests"
runs-on: ubuntu-20.04
steps:
- uses: actions/checkout@9bb56186c3b09b4f86b1c65136769dd318469633 #v4.1.2
- uses: actions/checkout@44c2b7a8a4ea60a981eaca3cf939b5f4305c123b #v4.1.5
- name: Bootstrap environment
uses: ./.github/actions/bootstrap
- name: Restore file executable test-fixture cache
uses: actions/cache@ab5e6d0c87105b4c9c2047343972218f562e4319 #v4.0.1
uses: actions/cache@0c45773b623bea8c8e75f6c82b208c3cf94ea4f9 #v4.0.2
with:
path: syft/file/cataloger/executable/test-fixtures/elf/bin
key: ${{ runner.os }}-unit-file-executable-elf-cache-${{ hashFiles( 'syft/file/cataloger/executable/test-fixtures/elf/cache.fingerprint' ) }}
- name: Restore file executable shared-info test-fixture cache
uses: actions/cache@ab5e6d0c87105b4c9c2047343972218f562e4319 #v4.0.1
uses: actions/cache@0c45773b623bea8c8e75f6c82b208c3cf94ea4f9 #v4.0.2
with:
path: syft/file/cataloger/executable/test-fixtures/shared-info/bin
key: ${{ runner.os }}-unit-file-executable-shared-info-cache-${{ hashFiles( 'syft/file/cataloger/executable/test-fixtures/shared-info/cache.fingerprint' ) }}
- name: Restore Java test-fixture cache
uses: actions/cache@ab5e6d0c87105b4c9c2047343972218f562e4319 #v4.0.1
uses: actions/cache@0c45773b623bea8c8e75f6c82b208c3cf94ea4f9 #v4.0.2
with:
path: syft/pkg/cataloger/java/test-fixtures/java-builds/packages
key: ${{ runner.os }}-unit-java-cache-${{ hashFiles( 'syft/pkg/cataloger/java/test-fixtures/java-builds/cache.fingerprint' ) }}
- name: Restore RPM test-fixture cache
uses: actions/cache@ab5e6d0c87105b4c9c2047343972218f562e4319 #v4.0.1
uses: actions/cache@0c45773b623bea8c8e75f6c82b208c3cf94ea4f9 #v4.0.2
with:
path: syft/pkg/cataloger/redhat/test-fixtures/rpms
key: ${{ runner.os }}-unit-rpm-cache-${{ hashFiles( 'syft/pkg/cataloger/redhat/test-fixtures/rpms.fingerprint' ) }}
- name: Restore go binary test-fixture cache
uses: actions/cache@ab5e6d0c87105b4c9c2047343972218f562e4319 #v4.0.1
uses: actions/cache@0c45773b623bea8c8e75f6c82b208c3cf94ea4f9 #v4.0.2
with:
path: syft/pkg/cataloger/golang/test-fixtures/archs/binaries
key: ${{ runner.os }}-unit-go-binaries-cache-${{ hashFiles( 'syft/pkg/cataloger/golang/test-fixtures/archs/binaries.fingerprint' ) }}
- name: Restore binary cataloger test-fixture cache
uses: actions/cache@ab5e6d0c87105b4c9c2047343972218f562e4319 #v4.0.1
uses: actions/cache@0c45773b623bea8c8e75f6c82b208c3cf94ea4f9 #v4.0.2
with:
path: syft/pkg/cataloger/binary/test-fixtures/classifiers/bin
key: ${{ runner.os }}-unit-binary-cataloger-cache-${{ hashFiles( 'syft/pkg/cataloger/binary/test-fixtures/cache.fingerprint' ) }}
- name: Restore Kernel test-fixture cache
uses: actions/cache@ab5e6d0c87105b4c9c2047343972218f562e4319 #v4.0.1
uses: actions/cache@0c45773b623bea8c8e75f6c82b208c3cf94ea4f9 #v4.0.2
with:
path: syft/pkg/cataloger/kernel/test-fixtures/cache
key: ${{ runner.os }}-unit-kernel-cache-${{ hashFiles( 'syft/pkg/cataloger/kernel/test-fixtures/cache.fingerprint' ) }}
@@ -87,7 +87,7 @@ jobs:
name: "Integration tests"
runs-on: ubuntu-20.04
steps:
- uses: actions/checkout@9bb56186c3b09b4f86b1c65136769dd318469633 #v4.1.2
- uses: actions/checkout@44c2b7a8a4ea60a981eaca3cf939b5f4305c123b #v4.1.5
- name: Bootstrap environment
uses: ./.github/actions/bootstrap
@@ -96,7 +96,7 @@ jobs:
run: make validate-cyclonedx-schema
- name: Restore integration test cache
uses: actions/cache@ab5e6d0c87105b4c9c2047343972218f562e4319 #v4.0.1
uses: actions/cache@0c45773b623bea8c8e75f6c82b208c3cf94ea4f9 #v4.0.2
with:
path: ${{ github.workspace }}/cmd/syft/internal/test/integration/test-fixtures/cache
key: ${{ runner.os }}-integration-test-cache-${{ hashFiles('/cmd/syft/internal/test/integration/test-fixtures/cache.fingerprint') }}
@@ -109,7 +109,7 @@ jobs:
name: "Build snapshot artifacts"
runs-on: ubuntu-20.04
steps:
- uses: actions/checkout@9bb56186c3b09b4f86b1c65136769dd318469633 #v4.1.2
- uses: actions/checkout@44c2b7a8a4ea60a981eaca3cf939b5f4305c123b #v4.1.5
- name: Bootstrap environment
uses: ./.github/actions/bootstrap
@@ -122,7 +122,7 @@ jobs:
# why not use actions/upload-artifact? It is very slow (3 minutes to upload ~600MB of data, vs 10 seconds with this approach).
# see https://github.com/actions/upload-artifact/issues/199 for more info
- name: Upload snapshot artifacts
uses: actions/cache/save@ab5e6d0c87105b4c9c2047343972218f562e4319 #v4.0.1
uses: actions/cache/save@0c45773b623bea8c8e75f6c82b208c3cf94ea4f9 #v4.0.2
with:
# we need to preserve the snapshot data itself as well as the task data that confirms if the
# snapshot build is stale or not. Otherwise the downstream jobs will attempt to rebuild the snapshot
@@ -139,14 +139,14 @@ jobs:
needs: [Build-Snapshot-Artifacts]
runs-on: ubuntu-20.04
steps:
- uses: actions/checkout@9bb56186c3b09b4f86b1c65136769dd318469633 #v4.1.2
- uses: actions/checkout@44c2b7a8a4ea60a981eaca3cf939b5f4305c123b #v4.1.5
- name: Bootstrap environment
uses: ./.github/actions/bootstrap
- name: Download snapshot build
id: snapshot-cache
uses: actions/cache/restore@ab5e6d0c87105b4c9c2047343972218f562e4319 #v4.0.1
uses: actions/cache/restore@0c45773b623bea8c8e75f6c82b208c3cf94ea4f9 #v4.0.2
with:
path: |
snapshot
@@ -164,7 +164,7 @@ jobs:
- name: Restore install.sh test image cache
id: install-test-image-cache
uses: actions/cache@ab5e6d0c87105b4c9c2047343972218f562e4319 #v4.0.1
uses: actions/cache@0c45773b623bea8c8e75f6c82b208c3cf94ea4f9 #v4.0.2
with:
path: ${{ github.workspace }}/test/install/cache
key: ${{ runner.os }}-install-test-image-cache-${{ hashFiles('test/install/cache.fingerprint') }}
@@ -187,7 +187,7 @@ jobs:
needs: [Build-Snapshot-Artifacts]
runs-on: macos-latest
steps:
- uses: actions/checkout@9bb56186c3b09b4f86b1c65136769dd318469633 #v4.1.2
- uses: actions/checkout@44c2b7a8a4ea60a981eaca3cf939b5f4305c123b #v4.1.5
- name: Bootstrap environment
uses: ./.github/actions/bootstrap
@@ -199,7 +199,7 @@ jobs:
- name: Download snapshot build
id: snapshot-cache
uses: actions/cache/restore@ab5e6d0c87105b4c9c2047343972218f562e4319 #v4.0.1
uses: actions/cache/restore@0c45773b623bea8c8e75f6c82b208c3cf94ea4f9 #v4.0.2
with:
path: |
snapshot
@@ -214,7 +214,7 @@ jobs:
- name: Restore docker image cache for compare testing
id: mac-compare-testing-cache
uses: actions/cache@ab5e6d0c87105b4c9c2047343972218f562e4319 #v4.0.1
uses: actions/cache@0c45773b623bea8c8e75f6c82b208c3cf94ea4f9 #v4.0.2
with:
path: image.tar
key: ${{ runner.os }}-${{ hashFiles('test/compare/mac.sh') }}
@@ -232,20 +232,20 @@ jobs:
needs: [Build-Snapshot-Artifacts]
runs-on: ubuntu-20.04
steps:
- uses: actions/checkout@9bb56186c3b09b4f86b1c65136769dd318469633 #v4.1.2
- uses: actions/checkout@44c2b7a8a4ea60a981eaca3cf939b5f4305c123b #v4.1.5
- name: Bootstrap environment
uses: ./.github/actions/bootstrap
- name: Restore CLI test-fixture cache
uses: actions/cache@ab5e6d0c87105b4c9c2047343972218f562e4319 #v4.0.1
uses: actions/cache@0c45773b623bea8c8e75f6c82b208c3cf94ea4f9 #v4.0.2
with:
path: ${{ github.workspace }}/test/cli/test-fixtures/cache
key: ${{ runner.os }}-cli-test-cache-${{ hashFiles('test/cli/test-fixtures/cache.fingerprint') }}
- name: Download snapshot build
id: snapshot-cache
uses: actions/cache/restore@ab5e6d0c87105b4c9c2047343972218f562e4319 #v4.0.1
uses: actions/cache/restore@0c45773b623bea8c8e75f6c82b208c3cf94ea4f9 #v4.0.2
with:
path: |
snapshot
+8
View File
@@ -49,10 +49,18 @@ linters-settings:
# If lower than 0, disable the check.
# Default: 40
statements: 50
gocritic:
enabled-checks:
- deferInLoop
- ruleguard
settings:
ruleguard:
rules: "test/rules/rules.go"
output:
uniq-by-line: false
run:
timeout: 10m
tests: false
# do not enable...
# - deadcode # The owner seems to have abandoned the linter. Replaced by "unused".
+1 -1
View File
@@ -92,7 +92,7 @@ brew install syft
### Nix
**Note**: Nix packaging of Syft is [community maintained](https://github.com/NixOS/nixpkgs/blob/master/pkgs/tools/admin/syft/default.nix). Syft is available in the [stable channel](https://nixos.wiki/wiki/Nix_channels#The_official_channels) since NixOS `22.05`.
**Note**: Nix packaging of Syft is [community maintained](https://github.com/NixOS/nixpkgs/blob/master/pkgs/tools/admin/syft/default.nix). Syft is available in the [stable channel](https://wiki.nixos.org/wiki/Nix_channels#The_official_channels) since NixOS `22.05`.
```bash
nix-env -i syft
+32
View File
@@ -0,0 +1,32 @@
# Security Policy
## Supported Versions
<!-- Use this section to tell people about which versions of your project are
currently being supported with security updates.
| Version | Supported |
| ------- | ------------------ |
| 5.1.x | :white_check_mark: |
| 5.0.x | :x: |
| 4.0.x | :white_check_mark: |
| < 4.0 | :x: |
-->
Security updates are applied only to the most recent release, try to always be up to date.
## Reporting a Vulnerability
<!-- Use this section to tell people how to report a vulnerability.
Tell them where to go, how often they can expect to get an update on a
reported vulnerability, what to expect if the vulnerability is accepted or
declined, etc. -->
To report a security issue, please email
[security@anchore.com](mailto:security@anchore.com)
with a description of the issue, the steps you took to create the issue,
affected versions, and, if known, mitigations for the issue.
All support will be made on the best effort base, so please indicate the "urgency level" of the vulnerability as Critical, High, Medium or Low.
+11 -1
View File
@@ -390,7 +390,7 @@ tasks:
generate-cpe-dictionary-index:
desc: Generate the CPE index based off of the latest available CPE dictionary
dir: "syft/pkg/cataloger/common/cpe/dictionary"
dir: "syft/pkg/cataloger/internal/cpegenerate/dictionary"
cmds:
- "go generate"
@@ -470,6 +470,16 @@ tasks:
silent: true
- "{{ .RELEASE_CMD }}"
ci-release-version-file:
# desc: "[CI only] Update the version file"
deps: [tools]
cmds:
- task: ci-check
- ".github/scripts/update-version-file.sh {{ .RELEASE_VERSION }}"
requires:
vars:
- RELEASE_VERSION
## Cleanup targets #################################
-7
View File
@@ -249,13 +249,6 @@ func getSource(ctx context.Context, opts *options.Catalog, userInput string, sou
return nil, fmt.Errorf("could not determine source: %w", err)
}
if err != nil {
if userInput == "power-user" {
bus.Notify("Note: the 'power-user' command has been removed.")
}
return nil, fmt.Errorf("failed to construct source from user input %q: %w", userInput, err)
}
return src, nil
}
@@ -460,4 +460,12 @@ var commonTestCases = []testCase{
"Akismet Anti-spam: Spam Protection": "5.3",
},
},
{
name: "find php pecl package",
pkgType: pkg.PhpPeclPkg,
pkgLanguage: pkg.PHP,
pkgInfo: map[string]string{
"memcached": "3.2.0",
},
},
}
@@ -0,0 +1,65 @@
package integration
import (
"github.com/anchore/syft/syft/artifact"
"github.com/anchore/syft/syft/source"
"github.com/stretchr/testify/require"
"testing"
)
func TestBinaryElfRelationships(t *testing.T) {
// node --> ["dependency of" nodes]
expectedGraph := map[string][]string{
"glibc": {
"libhello_world.so",
"syfttestfixture",
},
"libstdc++": {
"syfttestfixture",
},
"libhello_world.so": {
"syfttestfixture",
},
}
// run the test...
sbom, _ := catalogFixtureImage(t, "elf-test-fixtures", source.SquashedScope)
// get a mapping of package names to their IDs
nameToId := map[string]artifact.ID{}
recordPkgId := func(name string) {
pkgs := sbom.Artifacts.Packages.PackagesByName(name)
require.NotEmpty(t, pkgs, "expected package %q to be present in the SBOM", name)
for _, p := range pkgs {
nameToId[p.Name] = p.ID()
}
}
for name, depNames := range expectedGraph {
recordPkgId(name)
for _, depName := range depNames {
recordPkgId(depName)
}
}
for name, expectedDepNames := range expectedGraph {
pkgId := nameToId[name]
p := sbom.Artifacts.Packages.Package(pkgId)
require.NotNil(t, p, "expected package %q to be present in the SBOM", name)
rels := sbom.RelationshipsForPackage(*p, artifact.DependencyOfRelationship)
require.NotEmpty(t, rels, "expected package %q to have relationships", name)
toIds := map[artifact.ID]struct{}{}
for _, rel := range rels {
toIds[rel.To.ID()] = struct{}{}
}
for _, depName := range expectedDepNames {
depId := nameToId[depName]
_, exists := toIds[depId]
require.True(t, exists, "expected package %q to have a relationship to %q", name, depName)
}
}
}
@@ -0,0 +1 @@
../../../../../../syft/pkg/cataloger/binary/test-fixtures/elf-test-fixtures
@@ -0,0 +1 @@
a:5:{s:4:"name";s:9:"memcached";s:4:"date";s:10:"2022-01-11";s:4:"time";s:8:"15:23:47";s:7:"version";a:2:{s:7:"release";s:5:"3.2.0";s:3:"api";s:5:"3.2.0";}s:7:"license";a:2:{s:7:"attribs";a:1:{s:3:"uri";s:26:"http://www.php.net/license";}s:8:"_content";s:11:"PHP License";}}
@@ -32,7 +32,6 @@ func catalogFixtureImageWithConfig(t *testing.T, fixtureImageName string, cfg *s
cfg.CatalogerSelection = cfg.CatalogerSelection.WithDefaults(pkgcataloging.ImageTag)
// get the fixture image tar file
imagetest.GetFixtureImage(t, "docker-archive", fixtureImageName)
tarPath := imagetest.GetFixtureImageTarPath(t, fixtureImageName)
// get the source to build an SBOM against
+40 -35
View File
@@ -16,36 +16,37 @@ require (
github.com/anchore/go-macholibre v0.0.0-20220308212642-53e6d0aaf6fb
github.com/anchore/go-testutils v0.0.0-20200925183923-d5f45b0d3c04
github.com/anchore/go-version v1.2.2-0.20200701162849-18adb9c92b9b
github.com/anchore/packageurl-go v0.1.1-0.20240202171727-877e1747d426
github.com/anchore/stereoscope v0.0.2-0.20240229175558-fe426d1b1c84
github.com/anchore/packageurl-go v0.1.1-0.20240312213626-055233e539b4
github.com/anchore/stereoscope v0.0.3-0.20240501181043-2e9894674185
github.com/anmitsu/go-shlex v0.0.0-20200514113438-38f4b401e2be
// we are hinting brotli to latest due to warning when installing archiver v3:
// go: warning: github.com/andybalholm/brotli@v1.0.1: retracted by module author: occasional panics and data corruption
github.com/aquasecurity/go-pep440-version v0.0.0-20210121094942-22b2f8951d46
github.com/bmatcuk/doublestar/v4 v4.6.1
github.com/charmbracelet/bubbles v0.18.0
github.com/charmbracelet/bubbletea v0.25.0
github.com/charmbracelet/bubbletea v0.26.2
github.com/charmbracelet/lipgloss v0.10.0
github.com/dave/jennifer v1.7.0
github.com/deitch/magic v0.0.0-20230404182410-1ff89d7342da
github.com/distribution/reference v0.5.0
github.com/docker/docker v25.0.4+incompatible
github.com/distribution/reference v0.6.0
github.com/docker/docker v26.1.2+incompatible
github.com/dustin/go-humanize v1.0.1
github.com/elliotchance/phpserialize v1.4.0
github.com/facebookincubator/nvdtools v0.1.5
github.com/github/go-spdx/v2 v2.2.0
github.com/gkampitakis/go-snaps v0.5.2
github.com/gkampitakis/go-snaps v0.5.4
github.com/go-git/go-billy/v5 v5.5.0
github.com/go-git/go-git/v5 v5.11.0
github.com/go-git/go-git/v5 v5.12.0
github.com/go-test/deep v1.1.0
github.com/google/go-cmp v0.6.0
github.com/google/go-containerregistry v0.19.0
github.com/google/go-containerregistry v0.19.1
github.com/google/licensecheck v0.3.1
github.com/google/uuid v1.6.0
github.com/gookit/color v1.5.4
github.com/hashicorp/go-multierror v1.1.1
github.com/iancoleman/strcase v0.3.0
github.com/invopop/jsonschema v0.7.0
github.com/jedib0t/go-pretty/v6 v6.5.4
github.com/jedib0t/go-pretty/v6 v6.5.9
github.com/jinzhu/copier v0.4.0
github.com/kastenhq/goversion v0.0.0-20230811215019-93b2f8823953
github.com/knqyf263/go-rpmdb v0.1.0
@@ -58,14 +59,15 @@ require (
github.com/olekukonko/tablewriter v0.0.5
github.com/opencontainers/go-digest v1.0.0
github.com/pelletier/go-toml v1.9.5
github.com/quasilyte/go-ruleguard/dsl v0.3.22
github.com/saferwall/pe v1.5.2
github.com/saintfish/chardet v0.0.0-20230101081208-5e3ef4b5456d
github.com/sanity-io/litter v1.5.5
github.com/sassoftware/go-rpmutils v0.3.0
github.com/sassoftware/go-rpmutils v0.4.0
// pinned to pull in 386 arch fix: https://github.com/scylladb/go-set/commit/cc7b2070d91ebf40d233207b633e28f5bd8f03a5
github.com/scylladb/go-set v1.0.3-0.20200225121959-cc7b2070d91e
github.com/sergi/go-diff v1.3.1
github.com/spdx/tools-golang v0.5.3
github.com/sergi/go-diff v1.3.2-0.20230802210424-5b0b94c5c0d3
github.com/spdx/tools-golang v0.5.4
github.com/spf13/afero v1.11.0
github.com/spf13/cobra v1.8.0
github.com/stretchr/testify v1.9.0
@@ -76,12 +78,16 @@ require (
github.com/xeipuuv/gojsonschema v1.2.0
github.com/zyedidia/generic v1.2.2-0.20230320175451-4410d2372cb1
go.uber.org/goleak v1.3.0
golang.org/x/mod v0.16.0
golang.org/x/net v0.22.0
golang.org/x/mod v0.17.0
golang.org/x/net v0.25.0
gopkg.in/yaml.v3 v3.0.1
modernc.org/sqlite v1.29.3
modernc.org/sqlite v1.29.9
)
require google.golang.org/genproto v0.0.0-20231106174013-bbf56f31fb17 // indirect
require github.com/magiconair/properties v1.8.7
require (
dario.cat/mergo v1.0.0 // indirect
github.com/AdaLogics/go-fuzz-headers v0.0.0-20230811130428-ced1acdcaa24 // indirect
@@ -91,7 +97,7 @@ require (
github.com/Masterminds/semver/v3 v3.2.0 // indirect
github.com/Microsoft/go-winio v0.6.1 // indirect
github.com/Microsoft/hcsshim v0.11.4 // indirect
github.com/ProtonMail/go-crypto v0.0.0-20230828082145-3c4c8a2d2371 // indirect
github.com/ProtonMail/go-crypto v1.0.0 // indirect
github.com/adrg/xdg v0.4.0 // indirect
github.com/anchore/go-struct-converter v0.0.0-20221118182256-c68fdcfa2092 // indirect
github.com/andybalholm/brotli v1.0.4 // indirect
@@ -100,9 +106,8 @@ require (
github.com/aymanbagabas/go-osc52/v2 v2.0.1 // indirect
github.com/becheran/wildmatch-go v1.0.0 // indirect
github.com/charmbracelet/harmonica v0.2.0 // indirect
github.com/cloudflare/circl v1.3.7 // indirect
github.com/cloudflare/circl v1.3.8 // indirect
github.com/containerd/cgroups v1.1.0 // indirect
github.com/containerd/console v1.0.4-0.20230313162750-1ae8d489ac81 // indirect
github.com/containerd/containerd v1.7.11 // indirect
github.com/containerd/continuity v0.4.2 // indirect
github.com/containerd/fifo v1.1.0 // indirect
@@ -121,6 +126,7 @@ require (
github.com/dsnet/compress v0.0.2-0.20210315054119-f66993602bf5 // indirect
github.com/edsrzf/mmap-go v1.1.0 // indirect
github.com/emirpasic/gods v1.18.1 // indirect
github.com/erikgeiser/coninput v0.0.0-20211004153227-1c3628e74d0f // indirect
github.com/felixge/fgprof v0.9.3 // indirect
github.com/felixge/httpsnoop v1.0.3 // indirect
github.com/fsnotify/fsnotify v1.6.0 // indirect
@@ -135,7 +141,7 @@ require (
github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da // indirect
github.com/golang/protobuf v1.5.3 // indirect
github.com/golang/snappy v0.0.4 // indirect
github.com/google/pprof v0.0.0-20221118152302-e6195bd50e26 // indirect
github.com/google/pprof v0.0.0-20240409012703-83162a5b38cd // indirect
github.com/hashicorp/errwrap v1.1.0 // indirect
github.com/hashicorp/golang-lru/v2 v2.0.7 // indirect
github.com/hashicorp/hcl v1.0.0 // indirect
@@ -145,25 +151,25 @@ require (
github.com/inconshreveable/mousetrap v1.1.0 // indirect
github.com/jbenet/go-context v0.0.0-20150711004518-d14ea06fba99 // indirect
github.com/kevinburke/ssh_config v1.2.0 // indirect
github.com/klauspost/compress v1.17.4 // indirect
github.com/klauspost/compress v1.17.8 // indirect
github.com/klauspost/pgzip v1.2.5 // indirect
github.com/kr/pretty v0.3.1 // indirect
github.com/kr/text v0.2.0 // indirect
github.com/logrusorgru/aurora v0.0.0-20200102142835-e9ef32dff381 // indirect
github.com/lucasb-eyer/go-colorful v1.2.0 // indirect
github.com/magiconair/properties v1.8.7 // indirect
github.com/maruel/natural v1.1.1 // indirect
github.com/mattn/go-colorable v0.1.13 // indirect
github.com/mattn/go-isatty v0.0.18 // indirect
github.com/mattn/go-isatty v0.0.20 // indirect
github.com/mattn/go-localereader v0.0.2-0.20220822084749-2491eb6c1c75 // indirect
github.com/mattn/go-runewidth v0.0.15 // indirect
github.com/mgutz/ansi v0.0.0-20200706080929-d51e80ef957d // indirect
github.com/mitchellh/copystructure v1.2.0 // indirect
github.com/mitchellh/reflectwalk v1.0.2 // indirect
github.com/moby/docker-image-spec v1.3.1 // indirect
github.com/moby/locker v1.0.1 // indirect
github.com/moby/sys/sequential v0.5.0 // indirect
github.com/moby/sys/signal v0.7.0 // indirect
github.com/muesli/ansi v0.0.0-20211031195517-c9f0611b6c70 // indirect
github.com/muesli/ansi v0.0.0-20230316100256-276c6243b2f6 // indirect
github.com/muesli/cancelreader v0.2.2 // indirect
github.com/muesli/reflow v0.3.0 // indirect
github.com/muesli/termenv v0.15.2 // indirect
@@ -188,7 +194,7 @@ require (
github.com/sahilm/fuzzy v0.1.1-0.20230530133925-c48e322e2a8f // indirect
github.com/shopspring/decimal v1.2.0 // indirect
github.com/sirupsen/logrus v1.9.3 // indirect
github.com/skeema/knownhosts v1.2.1 // indirect
github.com/skeema/knownhosts v1.2.2 // indirect
github.com/sourcegraph/conc v0.3.0 // indirect
github.com/spf13/cast v1.5.1 // indirect
github.com/spf13/pflag v1.0.5 // indirect
@@ -201,7 +207,7 @@ require (
github.com/tidwall/match v1.1.1 // indirect
github.com/tidwall/pretty v1.2.1 // indirect
github.com/tidwall/sjson v1.2.5 // indirect
github.com/ulikunitz/xz v0.5.11 // indirect
github.com/ulikunitz/xz v0.5.12 // indirect
github.com/vbatts/tar-split v0.11.3 // indirect
github.com/xanzy/ssh-agent v0.3.3 // indirect
github.com/xeipuuv/gojsonpointer v0.0.0-20190905194746-02993c407bfb // indirect
@@ -216,24 +222,23 @@ require (
go.opentelemetry.io/otel/trace v1.19.0 // indirect
go.uber.org/atomic v1.9.0 // indirect
go.uber.org/multierr v1.9.0 // indirect
golang.org/x/crypto v0.21.0 // indirect
golang.org/x/crypto v0.23.0 // indirect
golang.org/x/exp v0.0.0-20231108232855-2478ac86f678 // indirect
golang.org/x/sync v0.6.0 // indirect
golang.org/x/sys v0.18.0 // indirect
golang.org/x/term v0.18.0 // indirect
golang.org/x/text v0.14.0 // indirect
golang.org/x/tools v0.17.0 // indirect
golang.org/x/sync v0.7.0 // indirect
golang.org/x/sys v0.20.0 // indirect
golang.org/x/term v0.20.0 // indirect
golang.org/x/text v0.15.0 // indirect
golang.org/x/tools v0.19.0 // indirect
golang.org/x/xerrors v0.0.0-20220907171357-04be3eba64a2 // indirect
google.golang.org/genproto v0.0.0-20231106174013-bbf56f31fb17 // indirect
google.golang.org/genproto/googleapis/rpc v0.0.0-20231120223509-83a465c0220f // indirect
google.golang.org/grpc v1.59.0 // indirect
google.golang.org/protobuf v1.31.0 // indirect
google.golang.org/protobuf v1.33.0 // indirect
gopkg.in/ini.v1 v1.67.0 // indirect
gopkg.in/warnings.v0 v0.1.2 // indirect
modernc.org/gc/v3 v3.0.0-20240107210532-573471604cb6 // indirect
modernc.org/libc v1.41.0 // indirect
modernc.org/libc v1.49.3 // indirect
modernc.org/mathutil v1.6.0 // indirect
modernc.org/memory v1.7.2 // indirect
modernc.org/memory v1.8.0 // indirect
modernc.org/strutil v1.2.0 // indirect
modernc.org/token v1.1.0 // indirect
)
+86 -71
View File
@@ -77,8 +77,8 @@ github.com/Microsoft/go-winio v0.6.1/go.mod h1:LRdKpFKfdobln8UmuiYcKPot9D2v6svN5
github.com/Microsoft/hcsshim v0.11.4 h1:68vKo2VN8DE9AdN4tnkWnmdhqdbpUFM8OF3Airm7fz8=
github.com/Microsoft/hcsshim v0.11.4/go.mod h1:smjE4dvqPX9Zldna+t5FG3rnoHhaB7QYxPRqGcpAD9w=
github.com/OneOfOne/xxhash v1.2.2/go.mod h1:HSdplMjZKSmBqAxg5vPj2TmRDmfkzw+cTzAElWljhcU=
github.com/ProtonMail/go-crypto v0.0.0-20230828082145-3c4c8a2d2371 h1:kkhsdkhsCvIsutKu5zLMgWtgh9YxGCNAw8Ad8hjwfYg=
github.com/ProtonMail/go-crypto v0.0.0-20230828082145-3c4c8a2d2371/go.mod h1:EjAoLdwvbIOoOQr3ihjnSoLZRtE8azugULFRteWMNc0=
github.com/ProtonMail/go-crypto v1.0.0 h1:LRuvITjQWX+WIfr930YHG2HNfjR1uOfyf5vE0kC2U78=
github.com/ProtonMail/go-crypto v1.0.0/go.mod h1:EjAoLdwvbIOoOQr3ihjnSoLZRtE8azugULFRteWMNc0=
github.com/acarl005/stripansi v0.0.0-20180116102854-5a71ef0e047d h1:licZJFw2RwpHMqeKTCYkitsPqHNxTmd4SNR5r94FGM8=
github.com/acarl005/stripansi v0.0.0-20180116102854-5a71ef0e047d/go.mod h1:asat636LX7Bqt5lYEZ27JNDcqxfjdBQuJ/MM4CN/Lzo=
github.com/acobaugh/osrelease v0.1.0 h1:Yb59HQDGGNhCj4suHaFQQfBps5wyoKLSSX/J/+UifRE=
@@ -109,10 +109,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/go-version v1.2.2-0.20200701162849-18adb9c92b9b h1:e1bmaoJfZVsCYMrIZBpFxwV26CbsuoEh5muXD5I1Ods=
github.com/anchore/go-version v1.2.2-0.20200701162849-18adb9c92b9b/go.mod h1:Bkc+JYWjMCF8OyZ340IMSIi2Ebf3uwByOk6ho4wne1E=
github.com/anchore/packageurl-go v0.1.1-0.20240202171727-877e1747d426 h1:agoiZchSf1Nnnos1azwIg5hk5Ao9TzZNBD9++AChGEg=
github.com/anchore/packageurl-go v0.1.1-0.20240202171727-877e1747d426/go.mod h1:Blo6OgJNiYF41ufcgHKkbCKF2MDOMlrqhXv/ij6ocR4=
github.com/anchore/stereoscope v0.0.2-0.20240229175558-fe426d1b1c84 h1:/E74wU51M87fX5UWHubLZiENXbuAci+xtbSb+JFsIYg=
github.com/anchore/stereoscope v0.0.2-0.20240229175558-fe426d1b1c84/go.mod h1:evQiJMQG56Z7/L5uhA8kfhhjF6ESJUZzUH9ms6bQ2Co=
github.com/anchore/packageurl-go v0.1.1-0.20240312213626-055233e539b4 h1:SjemQ90fgflz39HG+VMkNfrpUVJpcFW6ZFA3TDXqzBM=
github.com/anchore/packageurl-go v0.1.1-0.20240312213626-055233e539b4/go.mod h1:Blo6OgJNiYF41ufcgHKkbCKF2MDOMlrqhXv/ij6ocR4=
github.com/anchore/stereoscope v0.0.3-0.20240501181043-2e9894674185 h1:SuViDJ27nZ+joGdKbAkxAlm7tYMt9NTxTZZ05po4hls=
github.com/anchore/stereoscope v0.0.3-0.20240501181043-2e9894674185/go.mod h1:ckIamHiRMp8iBwWoTtE5Xkt9VQ5QC+6+O4VzwqyZr5Q=
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=
@@ -155,8 +155,8 @@ github.com/cespare/xxhash/v2 v2.1.1/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XL
github.com/cespare/xxhash/v2 v2.1.2/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs=
github.com/charmbracelet/bubbles v0.18.0 h1:PYv1A036luoBGroX6VWjQIE9Syf2Wby2oOl/39KLfy0=
github.com/charmbracelet/bubbles v0.18.0/go.mod h1:08qhZhtIwzgrtBjAcJnij1t1H0ZRjwHyGsy6AL11PSw=
github.com/charmbracelet/bubbletea v0.25.0 h1:bAfwk7jRz7FKFl9RzlIULPkStffg5k6pNt5dywy4TcM=
github.com/charmbracelet/bubbletea v0.25.0/go.mod h1:EN3QDR1T5ZdWmdfDzYcqOCAps45+QIJbLOBxmVNWNNg=
github.com/charmbracelet/bubbletea v0.26.2 h1:Eeb+n75Om9gQ+I6YpbCXQRKHt5Pn4vMwusQpwLiEgJQ=
github.com/charmbracelet/bubbletea v0.26.2/go.mod h1:6I0nZ3YHUrQj7YHIHlM8RySX4ZIthTliMY+W8X8b+Gs=
github.com/charmbracelet/harmonica v0.2.0 h1:8NxJWRWg/bzKqqEaaeFNipOu77YR5t8aSwG4pgaUBiQ=
github.com/charmbracelet/harmonica v0.2.0/go.mod h1:KSri/1RMQOZLbw7AHqgcBycp8pgJnQMYYT8QZRqZ1Ao=
github.com/charmbracelet/lipgloss v0.10.0 h1:KWeXFSexGcfahHX+54URiZGkBFazf70JNMtwg/AFW3s=
@@ -168,8 +168,8 @@ github.com/circonus-labs/circonus-gometrics v2.3.1+incompatible/go.mod h1:nmEj6D
github.com/circonus-labs/circonusllhist v0.1.3/go.mod h1:kMXHVDlOchFAehlya5ePtbp5jckzBHf4XRpQvBOLI+I=
github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw=
github.com/cloudflare/circl v1.3.3/go.mod h1:5XYMA4rFBvNIrhs50XuiBJ15vF2pZn4nnUKZrLbUZFA=
github.com/cloudflare/circl v1.3.7 h1:qlCDlTPz2n9fu58M0Nh1J/JzcFpfgkFHHX3O35r5vcU=
github.com/cloudflare/circl v1.3.7/go.mod h1:sRTcRWXGLrKw6yIGJ+l7amYJFfAXbZG0kBSc8r4zxgA=
github.com/cloudflare/circl v1.3.8 h1:j+V8jJt09PoeMFIu2uh5JUyEaIHTXVOHslFoLNAKqwI=
github.com/cloudflare/circl v1.3.8/go.mod h1:PDRU+oXvdD7KCtgKxW95M5Z8BpSCJXQORiZFnBQS5QU=
github.com/cncf/udpa/go v0.0.0-20191209042840-269d4d468f6f/go.mod h1:M8M6+tZqaGXZJjfX53e64911xZQV5JYwmTeXPW+k8Sc=
github.com/cncf/udpa/go v0.0.0-20200629203442-efcf912fb354/go.mod h1:WmhPx2Nbnhtbo57+VJT5O0JRkEi1Wbu0z5j0R8u5Hbk=
github.com/cncf/udpa/go v0.0.0-20201120205902-5459f2c99403/go.mod h1:WmhPx2Nbnhtbo57+VJT5O0JRkEi1Wbu0z5j0R8u5Hbk=
@@ -182,8 +182,6 @@ github.com/cncf/xds/go v0.0.0-20211011173535-cb28da3451f1/go.mod h1:eXthEFrGJvWH
github.com/cncf/xds/go v0.0.0-20211130200136-a8f946100490/go.mod h1:eXthEFrGJvWHgFFCl3hGmgk+/aYT6PnTQLykKQRLhEs=
github.com/containerd/cgroups v1.1.0 h1:v8rEWFl6EoqHB+swVNjVoCJE8o3jX7e8nqBGPLaDFBM=
github.com/containerd/cgroups v1.1.0/go.mod h1:6ppBcbh/NOOUU+dMKrykgaBnK9lCIBxHqJDGwsa1mIw=
github.com/containerd/console v1.0.4-0.20230313162750-1ae8d489ac81 h1:q2hJAaP1k2wIvVRd/hEHD7lacgqrCPS+k8g1MndzfWY=
github.com/containerd/console v1.0.4-0.20230313162750-1ae8d489ac81/go.mod h1:YynlIjWYF8myEu6sdkwKIvGQq+cOckRm6So2avqoYAk=
github.com/containerd/containerd v1.7.11 h1:lfGKw3eU35sjV0aG2eYZTiwFEY1pCzxdzicHP3SZILw=
github.com/containerd/containerd v1.7.11/go.mod h1:5UluHxHTX2rdvYuZ5OJTC5m/KJNs0Zs9wVoJm9zf5ZE=
github.com/containerd/continuity v0.4.2 h1:v3y/4Yz5jwnvqPKJJ+7Wf93fyWoCB3F5EclWG023MDM=
@@ -217,14 +215,14 @@ github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc/go.mod h1:J7Y8Yc
github.com/deitch/magic v0.0.0-20230404182410-1ff89d7342da h1:ZOjWpVsFZ06eIhnh4mkaceTiVoktdU67+M7KDHJ268M=
github.com/deitch/magic v0.0.0-20230404182410-1ff89d7342da/go.mod h1:B3tI9iGHi4imdLi4Asdha1Sc6feLMTfPLXh9IUYmysk=
github.com/dgrijalva/jwt-go/v4 v4.0.0-preview1/go.mod h1:+hnT3ywWDTAFrW5aE+u2Sa/wT555ZqwoCS+pk3p6ry4=
github.com/distribution/reference v0.5.0 h1:/FUIFXtfc/x2gpa5/VGfiGLuOIdYa1t65IKK2OFGvA0=
github.com/distribution/reference v0.5.0/go.mod h1:BbU0aIcezP1/5jX/8MP0YiH4SdvB5Y4f/wlDRiLyi3E=
github.com/distribution/reference v0.6.0 h1:0IXCQ5g4/QMHHkarYzh5l+u8T3t73zM5QvfrDyIgxBk=
github.com/distribution/reference v0.6.0/go.mod h1:BbU0aIcezP1/5jX/8MP0YiH4SdvB5Y4f/wlDRiLyi3E=
github.com/docker/cli v24.0.0+incompatible h1:0+1VshNwBQzQAx9lOl+OYCTCEAD8fKs/qeXMx3O0wqM=
github.com/docker/cli v24.0.0+incompatible/go.mod h1:JLrzqnKDaYBop7H2jaqPtU4hHvMKP+vjCwu2uszcLI8=
github.com/docker/distribution v2.8.3+incompatible h1:AtKxIZ36LoNK51+Z6RpzLpddBirtxJnzDrHLEKxTAYk=
github.com/docker/distribution v2.8.3+incompatible/go.mod h1:J2gT2udsDAN96Uj4KfcMRqY0/ypR+oyYUYmja8H+y+w=
github.com/docker/docker v25.0.4+incompatible h1:XITZTrq+52tZyZxUOtFIahUf3aH367FLxJzt9vZeAF8=
github.com/docker/docker v25.0.4+incompatible/go.mod h1:eEKB0N0r5NX/I1kEveEz05bcu8tLC/8azJZsviup8Sk=
github.com/docker/docker v26.1.2+incompatible h1:UVX5ZOrrfTGZZYEP+ZDq3Xn9PdHNXaSYMFPDumMqG2k=
github.com/docker/docker v26.1.2+incompatible/go.mod h1:eEKB0N0r5NX/I1kEveEz05bcu8tLC/8azJZsviup8Sk=
github.com/docker/docker-credential-helpers v0.7.0 h1:xtCHsjxogADNZcdv1pKUHXryefjlVRqWqIhk/uXJp0A=
github.com/docker/docker-credential-helpers v0.7.0/go.mod h1:rETQfLdHNT3foU5kuNkFR1R1V12OJRRO5lzt2D1b5X0=
github.com/docker/go-connections v0.4.0 h1:El9xVISelRB7BuFusrZozjnkIM5YnzCViNKohAFqRJQ=
@@ -242,6 +240,8 @@ github.com/edsrzf/mmap-go v1.1.0 h1:6EUwBLQ/Mcr1EYLE4Tn1VdW1A4ckqCQWZBw8Hr0kjpQ=
github.com/edsrzf/mmap-go v1.1.0/go.mod h1:19H/e8pUPLicwkyNgOykDXkJ9F0MHE+Z52B8EIth78Q=
github.com/elazarl/goproxy v0.0.0-20230808193330-2592e75ae04a h1:mATvB/9r/3gvcejNsXKSkQ6lcIaNec2nyfOdlTBR2lU=
github.com/elazarl/goproxy v0.0.0-20230808193330-2592e75ae04a/go.mod h1:Ro8st/ElPeALwNFlcTpWmkr6IoMFfkjXAvTHpevnDsM=
github.com/elliotchance/phpserialize v1.4.0 h1:cAp/9+KSnEbUC8oYCE32n2n84BeW8HOY3HMDI8hG2OY=
github.com/elliotchance/phpserialize v1.4.0/go.mod h1:gt7XX9+ETUcLXbtTKEuyrqW3lcLUAeS/AnGZ2e49TZs=
github.com/emirpasic/gods v1.18.1 h1:FXtiHYKDGKCW2KzwZKx0iC0PQmdlorYgdFG9jPXJ1Bc=
github.com/emirpasic/gods v1.18.1/go.mod h1:8tpGGwCnJ5H4r6BWwaV6OrWmMoPhUl5jm/FMNAnJvWQ=
github.com/envoyproxy/go-control-plane v0.9.0/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4=
@@ -255,6 +255,8 @@ github.com/envoyproxy/go-control-plane v0.9.10-0.20210907150352-cf90f659a021/go.
github.com/envoyproxy/go-control-plane v0.10.1/go.mod h1:AY7fTTXNdv/aJ2O5jwpxAPOWUZ7hQAEvzN5Pf27BkQQ=
github.com/envoyproxy/protoc-gen-validate v0.1.0/go.mod h1:iSmxcyjqTsJpI2R4NaDN7+kN2VEUnK/pcBlmesArF7c=
github.com/envoyproxy/protoc-gen-validate v0.6.2/go.mod h1:2t7qjJNvHPx8IjnBOzl9E9/baC+qXE/TeeyBRzgJDws=
github.com/erikgeiser/coninput v0.0.0-20211004153227-1c3628e74d0f h1:Y/CXytFA4m6baUTXGLOoWe4PQhGxaX0KpnayAqC48p4=
github.com/erikgeiser/coninput v0.0.0-20211004153227-1c3628e74d0f/go.mod h1:vw97MGsxSvLiUE2X8qFplwetxpGLQrlU1Q9AUEIzCaM=
github.com/facebookincubator/flog v0.0.0-20190930132826-d2511d0ce33c/go.mod h1:QGzNH9ujQ2ZUr/CjDGZGWeDAVStrWNjHeEcjJL96Nuk=
github.com/facebookincubator/nvdtools v0.1.5 h1:jbmDT1nd6+k+rlvKhnkgMokrCAzHoASWE5LtHbX2qFQ=
github.com/facebookincubator/nvdtools v0.1.5/go.mod h1:Kh55SAWnjckS96TBSrXI99KrEKH4iB0OJby3N8GRJO4=
@@ -281,20 +283,20 @@ github.com/gkampitakis/ciinfo v0.3.0 h1:gWZlOC2+RYYttL0hBqcoQhM7h1qNkVqvRCV1fOvp
github.com/gkampitakis/ciinfo v0.3.0/go.mod h1:1NIwaOcFChN4fa/B0hEBdAb6npDlFL8Bwx4dfRLRqAo=
github.com/gkampitakis/go-diff v1.3.2 h1:Qyn0J9XJSDTgnsgHRdz9Zp24RaJeKMUHg2+PDZZdC4M=
github.com/gkampitakis/go-diff v1.3.2/go.mod h1:LLgOrpqleQe26cte8s36HTWcTmMEur6OPYerdAAS9tk=
github.com/gkampitakis/go-snaps v0.5.2 h1:ay/6f7WHwRkOgpBec9DjMLRBAApziJommZ21NkOOCwY=
github.com/gkampitakis/go-snaps v0.5.2/go.mod h1:ZABkO14uCuVxBHAXAfKG+bqNz+aa1bGPAg8jkI0Nk8Y=
github.com/gkampitakis/go-snaps v0.5.4 h1:GX+dkKmVsRenz7SoTbdIEL4KQARZctkMiZ8ZKprRwT8=
github.com/gkampitakis/go-snaps v0.5.4/go.mod h1:ZABkO14uCuVxBHAXAfKG+bqNz+aa1bGPAg8jkI0Nk8Y=
github.com/glebarez/go-sqlite v1.20.3 h1:89BkqGOXR9oRmG58ZrzgoY/Fhy5x0M+/WV48U5zVrZ4=
github.com/glebarez/go-sqlite v1.20.3/go.mod h1:u3N6D/wftiAzIOJtZl6BmedqxmmkDfH3q+ihjqxC9u0=
github.com/gliderlabs/ssh v0.3.5 h1:OcaySEmAQJgyYcArR+gGGTHCyE7nvhEMTlYY+Dp8CpY=
github.com/gliderlabs/ssh v0.3.5/go.mod h1:8XB4KraRrX39qHhT6yxPsHedjA08I/uBVwj4xC+/+z4=
github.com/gliderlabs/ssh v0.3.7 h1:iV3Bqi942d9huXnzEF2Mt+CY9gLu8DNM4Obd+8bODRE=
github.com/gliderlabs/ssh v0.3.7/go.mod h1:zpHEXBstFnQYtGnB8k8kQLol82umzn/2/snG7alWVD8=
github.com/go-git/gcfg v1.5.1-0.20230307220236-3a3c6141e376 h1:+zs/tPmkDkHx3U66DAb0lQFJrpS6731Oaa12ikc+DiI=
github.com/go-git/gcfg v1.5.1-0.20230307220236-3a3c6141e376/go.mod h1:an3vInlBmSxCcxctByoQdvwPiA7DTK7jaaFDBTtu0ic=
github.com/go-git/go-billy/v5 v5.5.0 h1:yEY4yhzCDuMGSv83oGxiBotRzhwhNr8VZyphhiu+mTU=
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.11.0 h1:XIZc1p+8YzypNr34itUfSvYJcv+eYdTnTvOZ2vD3cA4=
github.com/go-git/go-git/v5 v5.11.0/go.mod h1:6GFcX2P3NM7FPBfpePbpLd21XxsgdAt+lKqXmCUiUCY=
github.com/go-git/go-git/v5 v5.12.0 h1:7Md+ndsjrzZxbddRDZjF14qK+NN56sy6wkqaVrjZtys=
github.com/go-git/go-git/v5 v5.12.0/go.mod h1:FTM9VKtnI2m65hNI/TenDDDnUf2Q9FHnXYjuz9i5OEY=
github.com/go-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=
@@ -372,8 +374,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.19.0 h1:uIsMRBV7m/HDkDxE/nXMnv1q+lOOSPlQ/ywc5JbB8Ic=
github.com/google/go-containerregistry v0.19.0/go.mod h1:u0qB2l7mvtWVR5kNcbFIhFY1hLbf8eeGapA+vbFDCtQ=
github.com/google/go-containerregistry v0.19.1 h1:yMQ62Al6/V0Z7CqIrrS1iYoA5/oQCm88DeNujc7C1KY=
github.com/google/go-containerregistry v0.19.1/go.mod h1:YCMFNQeeXeLF+dnhhWkqDItx/JSkH01j1Kis4PsjzFI=
github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg=
github.com/google/licensecheck v0.3.1 h1:QoxgoDkaeC4nFrtGN1jV7IPmDCHFNIVh54e5hSt6sPs=
github.com/google/licensecheck v0.3.1/go.mod h1:ORkR35t/JjW+emNKtfJDII0zlciG9JgbT7SmsohlHmY=
@@ -396,8 +398,8 @@ github.com/google/pprof v0.0.0-20210601050228-01bbb1931b22/go.mod h1:kpwsk12EmLe
github.com/google/pprof v0.0.0-20210609004039-a478d1d731e9/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE=
github.com/google/pprof v0.0.0-20210720184732-4bb14d4b1be1/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE=
github.com/google/pprof v0.0.0-20211214055906-6f57359322fd/go.mod h1:KgnwoLYCZ8IQu3XUZ8Nc/bM9CCZFOyjUNOSygVozoDg=
github.com/google/pprof v0.0.0-20221118152302-e6195bd50e26 h1:Xim43kblpZXfIBQsbuBVKCudVG457BR2GZFIz3uw3hQ=
github.com/google/pprof v0.0.0-20221118152302-e6195bd50e26/go.mod h1:dDKJzRmX4S37WGHujM7tX//fmj1uioxKzKxz3lo4HJo=
github.com/google/pprof v0.0.0-20240409012703-83162a5b38cd h1:gbpYu9NMq8jhDVbvlGkMFWCjLFlqqEZjEmObmhUy6Vo=
github.com/google/pprof v0.0.0-20240409012703-83162a5b38cd/go.mod h1:kf6iHlnVGwgKolg33glAes7Yg/8iWP8ukqeldJSO7jw=
github.com/google/renameio v0.1.0/go.mod h1:KWCgfxg9yswjAJkECMjeO8J8rahYeXnNhOm40UhjYkI=
github.com/google/uuid v1.1.1/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
github.com/google/uuid v1.1.2/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
@@ -471,8 +473,8 @@ github.com/invopop/jsonschema v0.7.0 h1:2vgQcBz1n256N+FpX3Jq7Y17AjYt46Ig3zIWyy77
github.com/invopop/jsonschema v0.7.0/go.mod h1:O9uiLokuu0+MGFlyiaqtWxwqJm41/+8Nj0lD7A36YH0=
github.com/jbenet/go-context v0.0.0-20150711004518-d14ea06fba99 h1:BQSFePA1RWJOlocH6Fxy8MmwDt+yVQYULKfN0RoTN8A=
github.com/jbenet/go-context v0.0.0-20150711004518-d14ea06fba99/go.mod h1:1lJo3i6rXxKeerYnT8Nvf0QmHCRC1n8sfWVwXF2Frvo=
github.com/jedib0t/go-pretty/v6 v6.5.4 h1:gOGo0613MoqUcf0xCj+h/V3sHDaZasfv152G6/5l91s=
github.com/jedib0t/go-pretty/v6 v6.5.4/go.mod h1:5LQIxa52oJ/DlDSLv0HEkWOFMDGoWkJb9ss5KqPpJBg=
github.com/jedib0t/go-pretty/v6 v6.5.9 h1:ACteMBRrrmm1gMsXe9PSTOClQ63IXDUt03H5U+UV8OU=
github.com/jedib0t/go-pretty/v6 v6.5.9/go.mod h1:zbn98qrYlh95FIhwwsbIip0LYpwSG8SUOScs+v9/t0E=
github.com/jinzhu/copier v0.4.0 h1:w3ciUoD19shMCRargcpm0cm91ytaBhDvuRpz1ODO/U8=
github.com/jinzhu/copier v0.4.0/go.mod h1:DfbEm0FYsaqBcKcFuvmOZb218JkPGtvSHsKg8S8hyyg=
github.com/json-iterator/go v1.1.6/go.mod h1:+SdeFBvtyEkXs7REEP0seUULqWtbJapLOCVDaaPEHmU=
@@ -490,8 +492,8 @@ github.com/kisielk/errcheck v1.5.0/go.mod h1:pFxgyoBC7bSaBwPgfKdkLd5X25qrDl4LWUI
github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck=
github.com/klauspost/compress v1.4.1/go.mod h1:RyIbtBH6LamlWaDj8nUwkbUhJ87Yi3uG0guNDohfE1A=
github.com/klauspost/compress v1.11.4/go.mod h1:aoV0uJVorq1K+umq18yTdKaF57EivdYsUV+/s2qKfXs=
github.com/klauspost/compress v1.17.4 h1:Ej5ixsIri7BrIjBkRZLTo6ghwrEtHFk7ijlczPW4fZ4=
github.com/klauspost/compress v1.17.4/go.mod h1:/dCuZOvVtNoHsyb+cuJD3itjs3NbnF6KH9zAO4BDxPM=
github.com/klauspost/compress v1.17.8 h1:YcnTYrq7MikUT7k0Yb5eceMmALQPYBW/Xltxn0NAMnU=
github.com/klauspost/compress v1.17.8/go.mod h1:Di0epgTjJY877eYKx5yC51cX2A2Vl2ibi7bDH9ttBbw=
github.com/klauspost/cpuid v1.2.0/go.mod h1:Pj4uuM528wm8OyEC2QMXAi2YiTZ96dNQPGgoMS4s3ek=
github.com/klauspost/pgzip v1.2.5 h1:qnWYvvKqedOF2ulHpMG72XQol4ILEJ8k2wwRl/Km8oE=
github.com/klauspost/pgzip v1.2.5/go.mod h1:Ch1tH69qFZu15pkjo5kYi6mth2Zzwzt50oCQKQE9RUs=
@@ -534,16 +536,14 @@ github.com/mattn/go-isatty v0.0.11/go.mod h1:PhnuNfih5lzO57/f3n+odYbM4JtupLOxQOA
github.com/mattn/go-isatty v0.0.12/go.mod h1:cbi8OIDigv2wuxKPP5vlRcQ1OAZbq2CE4Kysco4FUpU=
github.com/mattn/go-isatty v0.0.14/go.mod h1:7GGIvUiUoEMVVmxf/4nioHXj79iQHKdU27kJ6hsGG94=
github.com/mattn/go-isatty v0.0.16/go.mod h1:kYGgaQfpe5nmfYZH+SKPsOc2e4SrIfOl2e/yFXSvRLM=
github.com/mattn/go-isatty v0.0.18 h1:DOKFKCQ7FNG2L1rbrmstDN4QVRdS89Nkh85u68Uwp98=
github.com/mattn/go-isatty v0.0.18/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y=
github.com/mattn/go-isatty v0.0.20 h1:xfD0iDuEKnDkl03q4limB+vH+GxLEtL/jb4xVJSWWEY=
github.com/mattn/go-isatty v0.0.20/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y=
github.com/mattn/go-localereader v0.0.2-0.20220822084749-2491eb6c1c75 h1:P8UmIzZMYDR+NGImiFvErt6VWfIRPuGM+vyjiEdkmIw=
github.com/mattn/go-localereader v0.0.2-0.20220822084749-2491eb6c1c75/go.mod h1:8fBrzywKY7BI3czFoHkuzRoWE9C+EiG4R1k4Cjx5p88=
github.com/mattn/go-runewidth v0.0.9/go.mod h1:H031xJmbD/WCDINGzjvQ9THkh0rPKHF+m2gUSrubnMI=
github.com/mattn/go-runewidth v0.0.12/go.mod h1:RAqKPSqVFrSLVXbA8x7dzmKdmGzieGRCM46jaSJTDAk=
github.com/mattn/go-runewidth v0.0.15 h1:UNAjwbU9l54TA3KzvqLGxwWjHmMgBUVhBiTjelZgg3U=
github.com/mattn/go-runewidth v0.0.15/go.mod h1:Jdepj2loyihRzMpdS35Xk/zdY8IAYHsh153qUoGf23w=
github.com/mattn/go-sqlite3 v1.14.22 h1:2gZY6PC6kBnID23Tichd1K+Z0oS6nE/XwU+Vz/5o4kU=
github.com/mattn/go-sqlite3 v1.14.22/go.mod h1:Uh1q+B4BYcTPb+yiD3kU8Ct7aC0hY9fxUwlHK0RXw+Y=
github.com/matttproud/golang_protobuf_extensions v1.0.1/go.mod h1:D8He9yQNgCq6Z5Ld7szi9bcBfOoFv/3dc6xSMkL2PC0=
github.com/mgutz/ansi v0.0.0-20200706080929-d51e80ef957d h1:5PJl274Y63IEHC+7izoQE9x6ikvDFZS2mDVS3drnohI=
github.com/mgutz/ansi v0.0.0-20200706080929-d51e80ef957d/go.mod h1:01TrycV0kFyexm33Z7vhZRXopbI8J3TDReVlkTgMUxE=
@@ -569,6 +569,8 @@ github.com/mitchellh/mapstructure v1.5.0/go.mod h1:bFUtVrKA4DC2yAKiSyO/QUcy7e+RR
github.com/mitchellh/reflectwalk v1.0.0/go.mod h1:mSTlrgnPZtwu0c4WaC2kGObEpuNDbx0jmZXqmk4esnw=
github.com/mitchellh/reflectwalk v1.0.2 h1:G2LzWKi524PWgd3mLHV8Y5k7s6XUvT0Gef6zxSIeXaQ=
github.com/mitchellh/reflectwalk v1.0.2/go.mod h1:mSTlrgnPZtwu0c4WaC2kGObEpuNDbx0jmZXqmk4esnw=
github.com/moby/docker-image-spec v1.3.1 h1:jMKff3w6PgbfSa69GfNg+zN/XLhfXJGnEx3Nl2EsFP0=
github.com/moby/docker-image-spec v1.3.1/go.mod h1:eKmb5VW8vQEh/BAr2yvVNvuiJuY6UIocYsFu/DxxRpo=
github.com/moby/locker v1.0.1 h1:fOXqR41zeveg4fFODix+1Ch4mj/gT0NE1XJbp/epuBg=
github.com/moby/locker v1.0.1/go.mod h1:S7SDdo5zpBK84bzzVlKr2V0hz+7x9hWbYC/kq7oQppc=
github.com/moby/sys/mountinfo v0.7.1 h1:/tTvQaSJRr2FshkhXiIpux6fQ2Zvc4j7tAhMTStAG2g=
@@ -586,8 +588,8 @@ github.com/modern-go/reflect2 v1.0.1/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3Rllmb
github.com/modern-go/reflect2 v1.0.2/go.mod h1:yWuevngMOJpCy52FWWMvUC8ws7m/LJsjYzDa0/r8luk=
github.com/morikuni/aec v1.0.0 h1:nP9CBfwrvYnBRgY6qfDQkygYDmYwOilePFkwzv4dU8A=
github.com/morikuni/aec v1.0.0/go.mod h1:BbKIizmSmc5MMPqRYbxO4ZU0S0+P200+tUnFx7PXmsc=
github.com/muesli/ansi v0.0.0-20211031195517-c9f0611b6c70 h1:kMlmsLSbjkikxQJ1IPwaM+7LJ9ltFu/fi8CRzvSnQmA=
github.com/muesli/ansi v0.0.0-20211031195517-c9f0611b6c70/go.mod h1:fQuZ0gauxyBcmsdE3ZT4NasjaRdxmbCS0jRHsrWu3Ho=
github.com/muesli/ansi v0.0.0-20230316100256-276c6243b2f6 h1:ZK8zHtRHOkbHy6Mmr5D264iyp3TiX5OmNcI5cIARiQI=
github.com/muesli/ansi v0.0.0-20230316100256-276c6243b2f6/go.mod h1:CJlz5H+gyd6CUWT45Oy4q24RdLyn7Md9Vj2/ldJBSIo=
github.com/muesli/cancelreader v0.2.2 h1:3I4Kt4BQjOR54NavqnDogx/MIoWBFa0StPA8ELUXHmA=
github.com/muesli/cancelreader v0.2.2/go.mod h1:3XuTXfFS2VjM+HTLZY9Ak0l6eUKfijIfMUZ4EgX0QYo=
github.com/muesli/reflow v0.3.0 h1:IFsN6K9NfGtjeggFP+68I4chLZV2yIKsXJFNZ+eWh6s=
@@ -656,6 +658,8 @@ github.com/prometheus/procfs v0.0.8/go.mod h1:7Qr8sr6344vo1JqZ6HhLceV9o3AJ1Ff+Gx
github.com/prometheus/procfs v0.6.0/go.mod h1:cz+aTbrPOrUb4q7XlbU9ygM+/jj0fzG6c1xBZuNvfVA=
github.com/prometheus/procfs v0.8.0 h1:ODq8ZFEaYeCaZOJlZZdJA2AbQR98dSHSM1KW/You5mo=
github.com/prometheus/procfs v0.8.0/go.mod h1:z7EfXMXOkbkqb9IINtpCn86r/to3BnA0uaxHdg830/4=
github.com/quasilyte/go-ruleguard/dsl v0.3.22 h1:wd8zkOhSNr+I+8Qeciml08ivDt1pSXe60+5DqOpCjPE=
github.com/quasilyte/go-ruleguard/dsl v0.3.22/go.mod h1:KeCP03KrjuSO0H1kTuZQCWlQPulDV6YMIXmpQss17rU=
github.com/remyoudompheng/bigfft v0.0.0-20230129092748-24d4a6f8daec h1:W09IVJc94icq4NjY3clb7Lk8O1qJ8BdBEF8z0ibU0rE=
github.com/remyoudompheng/bigfft v0.0.0-20230129092748-24d4a6f8daec/go.mod h1:qqbHyh8v60DhA7CoWK5oRCqLrMHRGoxYCSS9EjAz6Eo=
github.com/rivo/uniseg v0.1.0/go.mod h1:J6wj4VEh+S6ZtnVlnTBMWIodfgj8LQOQFoIToxlJtxc=
@@ -683,8 +687,8 @@ github.com/saintfish/chardet v0.0.0-20230101081208-5e3ef4b5456d h1:hrujxIzL1woJ7
github.com/saintfish/chardet v0.0.0-20230101081208-5e3ef4b5456d/go.mod h1:uugorj2VCxiV1x+LzaIdVa9b4S4qGAcH6cbhh4qVxOU=
github.com/sanity-io/litter v1.5.5 h1:iE+sBxPBzoK6uaEP5Lt3fHNgpKcHXc/A2HGETy0uJQo=
github.com/sanity-io/litter v1.5.5/go.mod h1:9gzJgR2i4ZpjZHsKvUXIRQVk7P+yM3e+jAF7bU2UI5U=
github.com/sassoftware/go-rpmutils v0.3.0 h1:tE4TZ8KcOXay5iIP64P291s6Qxd9MQCYhI7DU+f3gFA=
github.com/sassoftware/go-rpmutils v0.3.0/go.mod h1:hM9wdxFsjUFR/tJ6SMsLrJuChcucCa0DsCzE9RMfwMo=
github.com/sassoftware/go-rpmutils v0.4.0 h1:ojND82NYBxgwrV+mX1CWsd5QJvvEZTKddtCdFLPWhpg=
github.com/sassoftware/go-rpmutils v0.4.0/go.mod h1:3goNWi7PGAT3/dlql2lv3+MSN5jNYPjT5mVcQcIsYzI=
github.com/scylladb/go-set v1.0.3-0.20200225121959-cc7b2070d91e h1:7q6NSFZDeGfvvtIRwBrU/aegEYJYmvev0cHAwo17zZQ=
github.com/scylladb/go-set v1.0.3-0.20200225121959-cc7b2070d91e/go.mod h1:DkpGd78rljTxKAnTDPFqXSGxvETQnJyuSOQwsHycqfs=
github.com/sean-/seed v0.0.0-20170313163322-e2103e2c3529/go.mod h1:DxrIzT+xaE7yg65j358z/aeFdxmN0P9QXhEzd20vsDc=
@@ -692,8 +696,8 @@ github.com/sebdah/goldie/v2 v2.5.3 h1:9ES/mNN+HNUbNWpVAlrzuZ7jE+Nrczbj8uFRjM7624
github.com/sebdah/goldie/v2 v2.5.3/go.mod h1:oZ9fp0+se1eapSRjfYbsV/0Hqhbuu3bJVvKI/NNtssI=
github.com/sergi/go-diff v1.1.0/go.mod h1:STckp+ISIX8hZLjrqAeVduY0gWCT9IjLuqbuNXdaHfM=
github.com/sergi/go-diff v1.2.0/go.mod h1:STckp+ISIX8hZLjrqAeVduY0gWCT9IjLuqbuNXdaHfM=
github.com/sergi/go-diff v1.3.1 h1:xkr+Oxo4BOQKmkn/B9eMK0g5Kg/983T9DqqPHwYqD+8=
github.com/sergi/go-diff v1.3.1/go.mod h1:aMJSSKb2lpPvRNec0+w3fl7LP9IOFzdc9Pa4NFbPK1I=
github.com/sergi/go-diff v1.3.2-0.20230802210424-5b0b94c5c0d3 h1:n661drycOFuPLCN3Uc8sB6B/s6Z4t2xvBgU1htSHuq8=
github.com/sergi/go-diff v1.3.2-0.20230802210424-5b0b94c5c0d3/go.mod h1:A0bzQcvG0E7Rwjx0REVgAGH58e96+X0MeOfepqsbeW4=
github.com/shopspring/decimal v1.2.0 h1:abSATXmQEYyShuxI4/vyW3tV1MrKAJzCZ/0zLUXYbsQ=
github.com/shopspring/decimal v1.2.0/go.mod h1:DKyhrW/HYNuLGql+MJL6WCR6knT2jwCFRcu2hWCYk4o=
github.com/shurcooL/sanitized_anchor_name v1.0.0/go.mod h1:1NzhyTcUVG4SuEtjjoZeVRXNmyL/1OwPU0+IJeTBvfc=
@@ -704,14 +708,14 @@ github.com/sirupsen/logrus v1.8.1/go.mod h1:yWOB1SBYBC5VeMP7gHvWumXLIWorT60ONWic
github.com/sirupsen/logrus v1.9.0/go.mod h1:naHLuLoDiP4jHNo9R0sCBMtWGeIprob74mVsIT4qYEQ=
github.com/sirupsen/logrus v1.9.3 h1:dueUQJ1C2q9oE3F7wvmSGAaVtTmUizReu6fjN8uqzbQ=
github.com/sirupsen/logrus v1.9.3/go.mod h1:naHLuLoDiP4jHNo9R0sCBMtWGeIprob74mVsIT4qYEQ=
github.com/skeema/knownhosts v1.2.1 h1:SHWdIUa82uGZz+F+47k8SY4QhhI291cXCpopT1lK2AQ=
github.com/skeema/knownhosts v1.2.1/go.mod h1:xYbVRSPxqBZFrdmDyMmsOs+uX1UZC3nTN3ThzgDxUwo=
github.com/skeema/knownhosts v1.2.2 h1:Iug2P4fLmDw9f41PB6thxUkNUkJzB5i+1/exaj40L3A=
github.com/skeema/knownhosts v1.2.2/go.mod h1:xYbVRSPxqBZFrdmDyMmsOs+uX1UZC3nTN3ThzgDxUwo=
github.com/sourcegraph/conc v0.3.0 h1:OQTbbt6P72L20UqAkXXuLOj79LfEanQ+YQFNpLA9ySo=
github.com/sourcegraph/conc v0.3.0/go.mod h1:Sdozi7LEKbFPqYX2/J+iBAM6HpqSLTASQIKqDmF7Mt0=
github.com/spaolacci/murmur3 v0.0.0-20180118202830-f09979ecbc72/go.mod h1:JwIasOWyU6f++ZhiEuf87xNszmSA2myDM2Kzu9HwQUA=
github.com/spdx/gordf v0.0.0-20201111095634-7098f93598fb/go.mod h1:uKWaldnbMnjsSAXRurWqqrdyZen1R7kxl8TkmWk2OyM=
github.com/spdx/tools-golang v0.5.3 h1:ialnHeEYUC4+hkm5vJm4qz2x+oEJbS0mAMFrNXdQraY=
github.com/spdx/tools-golang v0.5.3/go.mod h1:/ETOahiAo96Ob0/RAIBmFZw6XN0yTnyr/uFZm2NTMhI=
github.com/spdx/tools-golang v0.5.4 h1:fRW4iz16P1ZCUtWStFqS6YiMgnK7WgfTFU/lrsYlvqY=
github.com/spdx/tools-golang v0.5.4/go.mod h1:MVIsXx8ZZzaRWNQpUDhC4Dud34edUYJYecciXgrw5vE=
github.com/spf13/afero v1.3.3/go.mod h1:5KUK8ByomD5Ti5Artl0RtHeI5pTF7MIDuXL3yY520V4=
github.com/spf13/afero v1.6.0/go.mod h1:Ai8FlHk4v/PARR026UzYexafAt9roJ7LcLMAmO6Z93I=
github.com/spf13/afero v1.11.0 h1:WJQKhtpdm3v2IzqG8VMqrr6Rf3UYpEF239Jy9wNepM8=
@@ -773,8 +777,8 @@ github.com/tidwall/sjson v1.2.5/go.mod h1:Fvgq9kS/6ociJEDnK0Fk1cpYF4FIW6ZF7LAe+6
github.com/tv42/httpunix v0.0.0-20150427012821-b75d8614f926/go.mod h1:9ESjWnEqriFuLhtthL60Sar/7RFoluCcXsuvEwTV5KM=
github.com/ulikunitz/xz v0.5.8/go.mod h1:nbz6k7qbPmH4IRqmfOplQw/tblSgqTqBwxkY0oWt/14=
github.com/ulikunitz/xz v0.5.9/go.mod h1:nbz6k7qbPmH4IRqmfOplQw/tblSgqTqBwxkY0oWt/14=
github.com/ulikunitz/xz v0.5.11 h1:kpFauv27b6ynzBNT/Xy+1k+fK4WswhN/6PN5WhFAGw8=
github.com/ulikunitz/xz v0.5.11/go.mod h1:nbz6k7qbPmH4IRqmfOplQw/tblSgqTqBwxkY0oWt/14=
github.com/ulikunitz/xz v0.5.12 h1:37Nm15o69RwBkXM0J6A5OlE67RZTfzUxTj8fB3dfcsc=
github.com/ulikunitz/xz v0.5.12/go.mod h1:nbz6k7qbPmH4IRqmfOplQw/tblSgqTqBwxkY0oWt/14=
github.com/urfave/cli v1.22.12/go.mod h1:sSBEIC79qR6OvcmsD4U3KABeOTxDqQtdDnaFuUN30b8=
github.com/urfave/cli/v2 v2.3.0/go.mod h1:LJmUH05zAU44vOAcrfzZQKsZbVcdbOG8rtL3/XcUArI=
github.com/vbatts/go-mtree v0.5.3 h1:S/jYlfG8rZ+a0bhZd+RANXejy7M4Js8fq9U+XoWTd5w=
@@ -863,8 +867,8 @@ golang.org/x/crypto v0.0.0-20220622213112-05595931fe9d/go.mod h1:IxCIyHEi3zRg3s0
golang.org/x/crypto v0.3.0/go.mod h1:hebNnKkNXi2UzZN1eVRvBB7co0a+JxK6XbPiWVs/3J4=
golang.org/x/crypto v0.3.1-0.20221117191849-2c476679df9a/go.mod h1:hebNnKkNXi2UzZN1eVRvBB7co0a+JxK6XbPiWVs/3J4=
golang.org/x/crypto v0.7.0/go.mod h1:pYwdfH91IfpZVANVyUOhSIPZaFoJGxTFbZhFTx+dXZU=
golang.org/x/crypto v0.21.0 h1:X31++rzVUdKhX5sWmSOFZxx8UW/ldWx55cbf08iNAMA=
golang.org/x/crypto v0.21.0/go.mod h1:0BP7YvVV9gBbVKyeTG0Gyn+gZm94bibOW5BjDEYAOMs=
golang.org/x/crypto v0.23.0 h1:dIJU/v2J8Mdglj/8rJ6UUOM3Zc9zLZxVZwwxMooUSAI=
golang.org/x/crypto v0.23.0/go.mod h1:CKFgDieR+mRhux2Lsu27y0fO304Db0wZe70UKqHu0v8=
golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
golang.org/x/exp v0.0.0-20190306152737-a1d7652674e8/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
golang.org/x/exp v0.0.0-20190510132918-efd6b22b2522/go.mod h1:ZjyILWgesfNpC6sMxTJOJm9Kp84zZh5NQWvqDGG3Qr8=
@@ -905,8 +909,8 @@ golang.org/x/mod v0.4.2/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
golang.org/x/mod v0.5.0/go.mod h1:5OXOZSfqPIIbmVBIIKWRFfZjPR0E5r58TLhUjH0a2Ro=
golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4=
golang.org/x/mod v0.8.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs=
golang.org/x/mod v0.16.0 h1:QX4fJ0Rr5cPQCF7O9lh9Se4pmwfwskqZfq5moyldzic=
golang.org/x/mod v0.16.0/go.mod h1:hTbmBsO62+eylJbnUtE2MGJUyE7QWk4xUqPFrRgJ+7c=
golang.org/x/mod v0.17.0 h1:zY54UmvipHiNd+pm+m0x9KhZ9hl1/7QNMyxXbc6ICqA=
golang.org/x/mod v0.17.0/go.mod h1:hTbmBsO62+eylJbnUtE2MGJUyE7QWk4xUqPFrRgJ+7c=
golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
golang.org/x/net v0.0.0-20181023162649-9b4f9f5ad519/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
@@ -954,8 +958,8 @@ golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug
golang.org/x/net v0.2.0/go.mod h1:KqCZLdyyvdV855qA2rE3GC2aiw5xGR5TEjj8smXukLY=
golang.org/x/net v0.6.0/go.mod h1:2Tu9+aMcznHK/AK1HMvgo6xiTLG5rD5rZLDS+rp2Bjs=
golang.org/x/net v0.8.0/go.mod h1:QVkue5JL9kW//ek3r6jTKnTFis1tRmNAW2P1shuFdJc=
golang.org/x/net v0.22.0 h1:9sGLhx7iRIHEiX0oAJ3MRZMUCElJgy7Br1nO+AMN3Tc=
golang.org/x/net v0.22.0/go.mod h1:JKghWKKOSdJwpW2GEx0Ja7fmaKnMsbu+MWVZTokSYmg=
golang.org/x/net v0.25.0 h1:d/OCCoBEUq33pjydKrGQhw7IlUPI2Oylr+8qLx49kac=
golang.org/x/net v0.25.0/go.mod h1:JkAGAh7GEvH74S6FOH42FLoXpXbE/aqXSrIQjXgsiwM=
golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U=
golang.org/x/oauth2 v0.0.0-20190226205417-e64efc72b421/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
golang.org/x/oauth2 v0.0.0-20190604053449-0f29369cfe45/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
@@ -986,8 +990,8 @@ golang.org/x/sync v0.0.0-20201207232520-09787c993a3a/go.mod h1:RxMgew5VJxzue5/jJ
golang.org/x/sync v0.0.0-20210220032951-036812b2e83c/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.1.0/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.6.0 h1:5BMeUDZ7vkXGfEr1x9B4bRcTH4lpkTkpdh0T/J+qjbQ=
golang.org/x/sync v0.6.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk=
golang.org/x/sync v0.7.0 h1:YsImfSBoP9QPYL0xyKJPq0gcaJdG3rInoqxTWbfQu9M=
golang.org/x/sync v0.7.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk=
golang.org/x/sys v0.0.0-20180823144017-11551d06cbcc/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20180905080454-ebe1bf3edb33/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
@@ -1047,6 +1051,7 @@ golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBc
golang.org/x/sys v0.0.0-20210616094352-59db8d763f22/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20210630005230-0f9fa26af87c/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20210806184541-e5e7981a1069/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20210809222454-d867a43fc93e/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20210816183151-1e6c022a8912/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20210823070655-63515b42dcdf/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20210908233432-aa78b53d3365/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
@@ -1067,15 +1072,15 @@ golang.org/x/sys v0.2.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.3.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.5.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.18.0 h1:DBdB3niSjOA/O0blCZBqDefyWNYveAYMNF1Wum0DYQ4=
golang.org/x/sys v0.18.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
golang.org/x/sys v0.20.0 h1:Od9JTbYCk261bKm4M/mw7AklTlFYIa0bIp9BgSm1S8Y=
golang.org/x/sys v0.20.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8=
golang.org/x/term v0.2.0/go.mod h1:TVmDHMZPmdnySmBfhjOoOdhjzdE1h4u1VwSiw2l1Nuc=
golang.org/x/term v0.5.0/go.mod h1:jMB1sMXY+tzblOD4FWmEbocvup2/aLOaQEp7JmGp78k=
golang.org/x/term v0.6.0/go.mod h1:m6U89DPEgQRMq3DNkDClhWw02AUbt2daBVO4cn4Hv9U=
golang.org/x/term v0.18.0 h1:FcHjZXDMxI8mM3nwhX9HlKop4C0YQvCVCdwYl2wOtE8=
golang.org/x/term v0.18.0/go.mod h1:ILwASektA3OnRv7amZ1xhE/KTR+u50pbXfZ03+6Nx58=
golang.org/x/term v0.20.0 h1:VnkxpohqXaOBYJtBmEppKUG6mXpi+4O6purfc2+sMhw=
golang.org/x/term v0.20.0/go.mod h1:8UkIAJTvZgivsXaD6/pH6U9ecQzZ45awqEOzuCvwpFY=
golang.org/x/text v0.0.0-20170915032832-14c0d48ead0c/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
golang.org/x/text v0.3.1-0.20180807135948-17ff2d5776d2/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
@@ -1088,8 +1093,8 @@ golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ=
golang.org/x/text v0.4.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8=
golang.org/x/text v0.7.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8=
golang.org/x/text v0.8.0/go.mod h1:e1OnstbJyHTd6l/uOt8jFFHp6TRDWZR/bV3emEE/zU8=
golang.org/x/text v0.14.0 h1:ScX5w1eTa3QqT8oi6+ziP7dTV1S2+ALU0bI+0zXKWiQ=
golang.org/x/text v0.14.0/go.mod h1:18ZOQIKpY8NJVqYksKHtTdi31H5itFRjB5/qKTNYzSU=
golang.org/x/text v0.15.0 h1:h1V/4gjBv8v9cjcR6+AR5+/cIYK5N/WAgiv4xlsEtAk=
golang.org/x/text v0.15.0/go.mod h1:18ZOQIKpY8NJVqYksKHtTdi31H5itFRjB5/qKTNYzSU=
golang.org/x/time v0.0.0-20181108054448-85acf8d2951c/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
golang.org/x/time v0.0.0-20190308202827-9d24e82272b4/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
golang.org/x/time v0.0.0-20191024005414-555d28b269f0/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
@@ -1151,8 +1156,8 @@ golang.org/x/tools v0.1.4/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk=
golang.org/x/tools v0.1.5/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk=
golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc=
golang.org/x/tools v0.6.0/go.mod h1:Xwgl3UAJ/d3gWutnCtw505GrjyAbvKui8lOU390QaIU=
golang.org/x/tools v0.17.0 h1:FvmRgNOcs3kOa+T20R1uhfP9F6HgG2mfxDv1vrx1Htc=
golang.org/x/tools v0.17.0/go.mod h1:xsh6VxdV005rRVaS6SSAf9oiAqljS7UZUacMZ8Bnsps=
golang.org/x/tools v0.19.0 h1:tfGCXNR1OsFG+sVdLAitlpjAvD/I6dHDKnYrpEZUHkw=
golang.org/x/tools v0.19.0/go.mod h1:qoJWxmGSIBmAeriMx19ogtrEPrGtDbPK634QFIcLAhc=
golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
@@ -1310,8 +1315,8 @@ google.golang.org/protobuf v1.25.0/go.mod h1:9JNX74DMeImyA3h4bdi1ymwjUzf21/xIlba
google.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp09yW+WbY/TyQbw=
google.golang.org/protobuf v1.26.0/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc=
google.golang.org/protobuf v1.27.1/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc=
google.golang.org/protobuf v1.31.0 h1:g0LDEJHgrBl9N9r17Ru3sqWhkIx2NB67okBHPwC7hs8=
google.golang.org/protobuf v1.31.0/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I=
google.golang.org/protobuf v1.33.0 h1:uNO2rsAINq/JlFpSdYEKIZ0uKD/R9cpdv0T+yoGwGmI=
google.golang.org/protobuf v1.33.0/go.mod h1:c6P6GXX6sHbq/GpV6MGZEdwhWPcYBgnhAHhKbcUYpos=
gopkg.in/alecthomas/kingpin.v2 v2.2.6/go.mod h1:FMv+mEhP44yOT+4EoQTLFTRgOQ1FBLkstjWtayDeSgw=
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
@@ -1345,18 +1350,28 @@ honnef.co/go/tools v0.0.0-20190523083050-ea95bdfd59fc/go.mod h1:rf3lG4BRIbNafJWh
honnef.co/go/tools v0.0.1-2019.2.3/go.mod h1:a3bituU0lyd329TUQxRnasdCoJDkEUEAqEt0JzvZhAg=
honnef.co/go/tools v0.0.1-2020.1.3/go.mod h1:X/FiERA/W4tHapMX5mGpAtMSVEeEUOyHaw9vFzvIQ3k=
honnef.co/go/tools v0.0.1-2020.1.4/go.mod h1:X/FiERA/W4tHapMX5mGpAtMSVEeEUOyHaw9vFzvIQ3k=
modernc.org/cc/v4 v4.20.0 h1:45Or8mQfbUqJOG9WaxvlFYOAQO0lQ5RvqBcFCXngjxk=
modernc.org/cc/v4 v4.20.0/go.mod h1:HM7VJTZbUCR3rV8EYBi9wxnJ0ZBRiGE5OeGXNA0IsLQ=
modernc.org/ccgo/v4 v4.16.0 h1:ofwORa6vx2FMm0916/CkZjpFPSR70VwTjUCe2Eg5BnA=
modernc.org/ccgo/v4 v4.16.0/go.mod h1:dkNyWIjFrVIZ68DTo36vHK+6/ShBn4ysU61So6PIqCI=
modernc.org/fileutil v1.3.0 h1:gQ5SIzK3H9kdfai/5x41oQiKValumqNTDXMvKo62HvE=
modernc.org/fileutil v1.3.0/go.mod h1:XatxS8fZi3pS8/hKG2GH/ArUogfxjpEKs3Ku3aK4JyQ=
modernc.org/gc/v2 v2.4.1 h1:9cNzOqPyMJBvrUipmynX0ZohMhcxPtMccYgGOJdOiBw=
modernc.org/gc/v2 v2.4.1/go.mod h1:wzN5dK1AzVGoH6XOzc3YZ+ey/jPgYHLuVckd62P0GYU=
modernc.org/gc/v3 v3.0.0-20240107210532-573471604cb6 h1:5D53IMaUuA5InSeMu9eJtlQXS2NxAhyWQvkKEgXZhHI=
modernc.org/gc/v3 v3.0.0-20240107210532-573471604cb6/go.mod h1:Qz0X07sNOR1jWYCrJMEnbW/X55x206Q7Vt4mz6/wHp4=
modernc.org/libc v1.41.0 h1:g9YAc6BkKlgORsUWj+JwqoB1wU3o4DE3bM3yvA3k+Gk=
modernc.org/libc v1.41.0/go.mod h1:w0eszPsiXoOnoMJgrXjglgLuDy/bt5RR4y3QzUUeodY=
modernc.org/libc v1.49.3 h1:j2MRCRdwJI2ls/sGbeSk0t2bypOG/uvPZUsGQFDulqg=
modernc.org/libc v1.49.3/go.mod h1:yMZuGkn7pXbKfoT/M35gFJOAEdSKdxL0q64sF7KqCDo=
modernc.org/mathutil v1.6.0 h1:fRe9+AmYlaej+64JsEEhoWuAYBkOtQiMEU7n/XgfYi4=
modernc.org/mathutil v1.6.0/go.mod h1:Ui5Q9q1TR2gFm0AQRqQUaBWFLAhQpCwNcuhBOSedWPo=
modernc.org/memory v1.7.2 h1:Klh90S215mmH8c9gO98QxQFsY+W451E8AnzjoE2ee1E=
modernc.org/memory v1.7.2/go.mod h1:NO4NVCQy0N7ln+T9ngWqOQfi7ley4vpwvARR+Hjw95E=
modernc.org/sqlite v1.29.3 h1:6L71d3zXVB8oubdVSuwiurNyYRetQ3It8l1FSwylwQ0=
modernc.org/sqlite v1.29.3/go.mod h1:MjUIBKZ+tU/lqjNLbVAAMjsQPdWdA/ciwdhsT9kBwk8=
modernc.org/memory v1.8.0 h1:IqGTL6eFMaDZZhEWwcREgeMXYwmW83LYW8cROZYkg+E=
modernc.org/memory v1.8.0/go.mod h1:XPZ936zp5OMKGWPqbD3JShgd/ZoQ7899TUuQqxY+peU=
modernc.org/opt v0.1.3 h1:3XOZf2yznlhC+ibLltsDGzABUGVx8J6pnFMS3E4dcq4=
modernc.org/opt v0.1.3/go.mod h1:WdSiB5evDcignE70guQKxYUl14mgWtbClRi5wmkkTX0=
modernc.org/sortutil v1.2.0 h1:jQiD3PfS2REGJNzNCMMaLSp/wdMNieTbKX920Cqdgqc=
modernc.org/sortutil v1.2.0/go.mod h1:TKU2s7kJMf1AE84OoiGppNHJwvB753OYfNl2WRb++Ss=
modernc.org/sqlite v1.29.9 h1:9RhNMklxJs+1596GNuAX+O/6040bvOwacTxuFcRuQow=
modernc.org/sqlite v1.29.9/go.mod h1:ItX2a1OVGgNsFh6Dv60JQvGfJfTPHPVpV6DF59akYOA=
modernc.org/strutil v1.2.0 h1:agBi9dp1I+eOnxXeiZawM8F4LawKv4NzGWSaLfyeNZA=
modernc.org/strutil v1.2.0/go.mod h1:/mdcBmfOibveCTBxUl5B5l6W+TTH1FXPLHZE6bTosX0=
modernc.org/token v1.1.0 h1:Xl7Ap9dKaEs5kLoOQeQmPWevfnk/DM5qcLcYlA8ys6Y=
@@ -1364,4 +1379,4 @@ modernc.org/token v1.1.0/go.mod h1:UGzOrNV1mAFSEB63lOFHIpNRUVMvYTc6yu1SMY/XTDM=
rsc.io/binaryregexp v0.2.0/go.mod h1:qTv7/COck+e2FymRvadv62gMdZztPaShugOCi3I+8D8=
rsc.io/quote/v3 v3.1.0/go.mod h1:yEA65RcK8LyAZtP9Kv3t0HmxON59tX3rD+tICJqUlj0=
rsc.io/sampler v1.3.0/go.mod h1:T1hPZKmBbMNahiBKFy5HrXp6adAjACjK9JXDnKaTXpA=
sigs.k8s.io/yaml v1.3.0/go.mod h1:GeOyir5tyXNByN85N/dRIT9es5UQNerPYEKK56eTBm8=
sigs.k8s.io/yaml v1.4.0/go.mod h1:Ejl7/uTz7PSA4eKMyQCUTnhZYNmLIl+5c2lQPGR2BPY=
+1 -1
View File
@@ -3,5 +3,5 @@ package internal
const (
// JSONSchemaVersion is the current schema version output by the JSON encoder
// This is roughly following the "SchemaVer" guidelines for versioning the JSON schema. Please see schema/json/README.md for details on how to increment.
JSONSchemaVersion = "16.0.6"
JSONSchemaVersion = "16.0.8"
)
@@ -3,6 +3,8 @@ package binary
import (
"path"
"github.com/anchore/syft/internal/log"
"github.com/anchore/syft/internal/sbomsync"
"github.com/anchore/syft/syft/artifact"
"github.com/anchore/syft/syft/file"
@@ -12,21 +14,24 @@ import (
func NewDependencyRelationships(resolver file.Resolver, accessor sbomsync.Accessor) []artifact.Relationship {
// TODO: consider library format (e.g. ELF, Mach-O, PE) for the meantime assume all binaries are homogeneous format
// start with building new file-to-file relationships for executables-to-executables
// you need to make certain that they are unique, store in a map[id]map[id]relationship to avoid dupes.
// before creating the new file-to-file relationship, check to see if there are packages that represent each
// file. If there are, create a package-to-package, file-to-package, or package-to-file relationship as appropriate.
// start with building new package-to-package relationships for executables-to-executables
// each relationship must be unique, store in a map[id]map[id]relationship to avoid duplicates
// 1 & 2... build an index of all shared libraries and their owning packages to search against
index := newShareLibIndex(resolver, accessor)
// 3. craft package-to-package or package-to-file relationships that represent binary shared library dependencies
// note: prefer package-to-package relationships over package-to-file relationships
// 3. craft package-to-package relationships for each binary that represent shared library dependencies
//note: we only care about package-to-package relationships
var relIndex *relationshipIndex
accessor.ReadFromSBOM(func(s *sbom.SBOM) {
relIndex = newRelationshipIndex(s.Relationships...)
})
relIndex := newRelationshipIndex()
return generateRelationships(resolver, accessor, index, relIndex)
}
func generateRelationships(resolver file.Resolver, accessor sbomsync.Accessor, index *sharedLibraryIndex, relIndex *relationshipIndex) []artifact.Relationship {
// read all existing dependencyOf relationships
accessor.ReadFromSBOM(func(s *sbom.SBOM) {
// read all existing dependencyOf relationships
for _, r := range s.Relationships {
if r.Type != artifact.DependencyOfRelationship {
continue
@@ -35,7 +40,7 @@ func NewDependencyRelationships(resolver file.Resolver, accessor sbomsync.Access
}
})
// find all new relationships to add...
// find all package-to-package relationships for shared library dependencies
accessor.ReadFromSBOM(func(s *sbom.SBOM) {
for _, parentPkg := range s.Artifacts.Packages.Sorted(pkg.BinaryPkg) {
for _, evidentLocation := range parentPkg.Locations.ToSlice() {
@@ -49,49 +54,118 @@ func NewDependencyRelationships(resolver file.Resolver, accessor sbomsync.Access
continue
}
for _, libReference := range exec.ImportedLibraries {
// TODO: is this always a basename? technically no, it could be a path...
libBasename := path.Base(libReference)
pkgsThatOwnLib := index.owningLibraryPackage(libBasename)
if pkgsThatOwnLib == nil {
// create package-to-file relationship...
// if there is more than one library for this given library name, then we will include
// all of them as dependencies since we don't know the LD_LIBRARY_PATH order
// TODO: add configuration for LD_LIBRARY_PATH order?
for _, libCoord := range index.owningLibraryLocations(libBasename).ToSlice() {
relIndex.add(
artifact.Relationship{
From: libCoord,
To: parentPkg,
Type: artifact.DependencyOfRelationship,
},
)
}
// don't create a package-to-package relationship for this library... since we can't
continue
}
// create a package-to-package relationship between the binary package and the library package
// if there is more than one library for this given library name, then we will include
// all of them as dependencies since we don't know the LD_LIBRARY_PATH order
for _, pkgThatOwnsLib := range pkgsThatOwnLib.Sorted() {
relIndex.add(
artifact.Relationship{
From: pkgThatOwnsLib,
To: parentPkg,
Type: artifact.DependencyOfRelationship,
},
)
}
}
populateRelationships(exec, parentPkg, resolver, relIndex, index)
}
}
})
// so far this handles the first order dependencies from the binary package. Odds are that the OS package manager
// will have already created a package-to-package relationship for the lib packages to other lib packages.
return relIndex.newRelationships()
}
// PackagesToRemove returns a list of binary packages (resolved by the ELF cataloger) that should be removed from the SBOM
// These packages are removed because they are already represented by a higher order packages in the SBOM.
func PackagesToRemove(resolver file.Resolver, accessor sbomsync.Accessor) []artifact.ID {
pkgsToDelete := make([]artifact.ID, 0)
accessor.ReadFromSBOM(func(s *sbom.SBOM) {
// OTHER > ELF > Binary
pkgsToDelete = append(pkgsToDelete, getBinaryPackagesToDelete(resolver, s)...)
pkgsToDelete = append(pkgsToDelete, compareElfBinaryPackages(resolver, s)...)
})
return pkgsToDelete
}
func compareElfBinaryPackages(resolver file.Resolver, s *sbom.SBOM) []artifact.ID {
pkgsToDelete := make([]artifact.ID, 0)
for _, p := range s.Artifacts.Packages.Sorted(pkg.BinaryPkg) {
for _, loc := range p.Locations.ToSlice() {
if loc.Annotations[pkg.EvidenceAnnotationKey] != pkg.PrimaryEvidenceAnnotation {
continue
}
locations, err := resolver.FilesByPath(loc.RealPath)
if err != nil {
log.WithFields("error", err).Trace("unable to find path for owned file")
continue
}
for _, ownedL := range locations {
for _, pathPkg := range s.Artifacts.Packages.PackagesByPath(ownedL.RealPath) {
// we only care about comparing binary packages to each other (not other types)
if pathPkg.Type != pkg.BinaryPkg {
continue
}
if _, ok := pathPkg.Metadata.(pkg.ELFBinaryPackageNoteJSONPayload); !ok {
pkgsToDelete = append(pkgsToDelete, pathPkg.ID())
}
}
}
}
}
return pkgsToDelete
}
func getBinaryPackagesToDelete(resolver file.Resolver, s *sbom.SBOM) []artifact.ID {
pkgsToDelete := make([]artifact.ID, 0)
for p := range s.Artifacts.Packages.Enumerate() {
if p.Type == pkg.BinaryPkg {
continue
}
fileOwner, ok := p.Metadata.(pkg.FileOwner)
if !ok {
continue
}
ownedFiles := fileOwner.OwnedFiles()
locations, err := resolver.FilesByPath(ownedFiles...)
if err != nil {
log.WithFields("error", err).Trace("unable to find path for owned file")
continue
}
for _, loc := range locations {
for _, pathPkg := range s.Artifacts.Packages.PackagesByPath(loc.RealPath) {
if pathPkg.Type == pkg.BinaryPkg {
pkgsToDelete = append(pkgsToDelete, pathPkg.ID())
}
}
}
}
return pkgsToDelete
}
func populateRelationships(exec file.Executable, parentPkg pkg.Package, resolver file.Resolver, relIndex *relationshipIndex, index *sharedLibraryIndex) {
for _, libReference := range exec.ImportedLibraries {
// for each library reference, check s.Artifacts.Packages.Sorted(pkg.BinaryPkg) for a binary package that represents that library
// if found, create a relationship between the parent package and the library package
// if not found do nothing.
// note: we only care about package-to-package relationships
// find the basename of the library
libBasename := path.Base(libReference)
libLocations, err := resolver.FilesByGlob("**/" + libBasename)
if err != nil {
log.WithFields("lib", libReference, "error", err).Trace("unable to resolve library basename")
continue
}
for _, loc := range libLocations {
// are you in our index?
realBaseName := path.Base(loc.RealPath)
pkgCollection := index.owningLibraryPackage(realBaseName)
if pkgCollection.PackageCount() < 1 {
relIndex.add(
artifact.Relationship{
From: loc.Coordinates,
To: parentPkg,
Type: artifact.DependencyOfRelationship,
},
)
}
for _, p := range pkgCollection.Sorted() {
relIndex.add(
artifact.Relationship{
From: p,
To: parentPkg,
Type: artifact.DependencyOfRelationship,
},
)
}
}
}
}
@@ -0,0 +1,337 @@
package binary
import (
"path"
"testing"
"github.com/google/go-cmp/cmp"
"github.com/google/go-cmp/cmp/cmpopts"
"github.com/anchore/syft/internal/sbomsync"
"github.com/anchore/syft/syft/artifact"
"github.com/anchore/syft/syft/file"
"github.com/anchore/syft/syft/pkg"
"github.com/anchore/syft/syft/sbom"
)
func TestPackagesToRemove(t *testing.T) {
glibcCoordinate := file.NewCoordinates("/usr/lib64/libc.so.6", "")
glibCPackage := pkg.Package{
Name: "glibc",
Version: "2.28-236.el8_9.12",
Locations: file.NewLocationSet(
file.NewLocation(glibcCoordinate.RealPath),
),
Type: pkg.RpmPkg,
Metadata: pkg.RpmDBEntry{
Files: []pkg.RpmFileRecord{
{
Path: glibcCoordinate.RealPath,
},
},
},
}
glibCPackage.SetID()
glibCBinaryELFPackage := pkg.Package{
Name: "glibc",
Version: "",
Locations: file.NewLocationSet(
file.NewLocation(glibcCoordinate.RealPath).WithAnnotation(pkg.EvidenceAnnotationKey, pkg.PrimaryEvidenceAnnotation),
),
Language: "",
Type: pkg.BinaryPkg,
Metadata: pkg.ELFBinaryPackageNoteJSONPayload{
Type: "testfixture",
Vendor: "syft",
System: "syftsys",
SourceRepo: "https://github.com/someone/somewhere.git",
Commit: "5534c38d0ffef9a3f83154f0b7a7fb6ab0ab6dbb",
},
}
glibCBinaryELFPackage.SetID()
glibCBinaryClassifierPackage := pkg.Package{
Name: "glibc",
Version: "",
Locations: file.NewLocationSet(
file.NewLocation(glibcCoordinate.RealPath).WithAnnotation(pkg.EvidenceAnnotationKey, pkg.SupportingEvidenceAnnotation),
),
Language: "",
Type: pkg.BinaryPkg,
Metadata: pkg.BinarySignature{},
}
glibCBinaryClassifierPackage.SetID()
tests := []struct {
name string
resolver file.Resolver
accessor sbomsync.Accessor
want []artifact.ID
}{
{
name: "remove packages that are overlapping rpm --> binary",
resolver: file.NewMockResolverForPaths(glibcCoordinate.RealPath),
accessor: newAccesor([]pkg.Package{glibCPackage, glibCBinaryELFPackage}, map[file.Coordinates]file.Executable{}, nil),
want: []artifact.ID{glibCBinaryELFPackage.ID()},
},
{
name: "remove no packages when there is a single binary package",
resolver: file.NewMockResolverForPaths(glibcCoordinate.RealPath),
accessor: newAccesor([]pkg.Package{glibCBinaryELFPackage}, map[file.Coordinates]file.Executable{}, nil),
want: []artifact.ID{},
},
{
name: "remove packages when there is a single binary package and a classifier package",
resolver: file.NewMockResolverForPaths(glibcCoordinate.RealPath),
accessor: newAccesor([]pkg.Package{glibCBinaryELFPackage, glibCBinaryClassifierPackage}, map[file.Coordinates]file.Executable{}, nil),
want: []artifact.ID{glibCBinaryClassifierPackage.ID()},
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
pkgsToDelete := PackagesToRemove(tt.resolver, tt.accessor)
if diff := cmp.Diff(tt.want, pkgsToDelete); diff != "" {
t.Errorf("unexpected packages to delete (-want, +got): %s", diff)
}
})
}
}
func TestNewDependencyRelationships(t *testing.T) {
// coordinates for the files under test
glibcCoordinate := file.NewCoordinates("/usr/lib64/libc.so.6", "")
secondGlibcCoordinate := file.NewCoordinates("/usr/local/lib64/libc.so.6", "")
nestedLibCoordinate := file.NewCoordinates("/usr/local/bin/elftests/elfbinwithnestedlib/bin/elfbinwithnestedlib", "")
parrallelLibCoordinate := file.NewCoordinates("/usr/local/bin/elftests/elfbinwithsisterlib/bin/elfwithparallellibbin1", "")
// rpm package that was discovered in linked section of the ELF binary package
glibCPackage := pkg.Package{
Name: "glibc",
Version: "2.28-236.el8_9.12",
Locations: file.NewLocationSet(
file.NewLocation(glibcCoordinate.RealPath),
file.NewLocation("some/other/path"),
),
Type: pkg.RpmPkg,
Metadata: pkg.RpmDBEntry{
Files: []pkg.RpmFileRecord{
{
Path: glibcCoordinate.RealPath,
},
{
Path: "some/other/path",
},
},
},
}
glibCPackage.SetID()
// second rpm package that could be discovered in linked section of the ELF binary package (same base path as above)
glibCustomPackage := pkg.Package{
Name: "glibc",
Version: "2.28-236.el8_9.12",
Locations: file.NewLocationSet(file.NewLocation(secondGlibcCoordinate.RealPath)),
Type: pkg.RpmPkg,
Metadata: pkg.RpmDBEntry{
Files: []pkg.RpmFileRecord{
{
Path: secondGlibcCoordinate.RealPath,
},
},
},
}
glibCustomPackage.SetID()
// binary package that is an executable that can link against above rpm packages
syftTestFixturePackage := pkg.Package{
Name: "syfttestfixture",
Version: "0.01",
PURL: "pkg:generic/syftsys/syfttestfixture@0.01",
FoundBy: "",
Locations: file.NewLocationSet(
file.NewLocation(nestedLibCoordinate.RealPath).WithAnnotation(pkg.EvidenceAnnotationKey, pkg.PrimaryEvidenceAnnotation),
file.NewLocation(parrallelLibCoordinate.RealPath).WithAnnotation(pkg.EvidenceAnnotationKey, pkg.SupportingEvidenceAnnotation),
),
Language: "",
Type: pkg.BinaryPkg,
Metadata: pkg.ELFBinaryPackageNoteJSONPayload{
Type: "testfixture",
Vendor: "syft",
System: "syftsys",
SourceRepo: "https://github.com/someone/somewhere.git",
Commit: "5534c38d0ffef9a3f83154f0b7a7fb6ab0ab6dbb",
},
}
syftTestFixturePackage.SetID()
// dummy executable representation of glibc
glibcExecutable := file.Executable{
Format: "elf",
HasExports: true,
HasEntrypoint: true,
ImportedLibraries: []string{},
}
// executable representation of the syftTestFixturePackage
syftTestFixtureExecutable := file.Executable{
Format: "elf",
HasExports: true,
HasEntrypoint: true,
ImportedLibraries: []string{
path.Base(glibcCoordinate.RealPath),
},
}
// second executable representation that has no parent package
syftTestFixtureExecutable2 := file.Executable{
Format: "elf",
HasExports: true,
HasEntrypoint: true,
ImportedLibraries: []string{
// this should not be a relationship because it is not a coordinate
"foo.so.6",
},
}
tests := []struct {
name string
resolver file.Resolver
coordinateIndex map[file.Coordinates]file.Executable
packages []pkg.Package
prexistingRelationships []artifact.Relationship
want []artifact.Relationship
}{
{
name: "blank sbom and accessor returns empty relationships",
resolver: nil,
coordinateIndex: map[file.Coordinates]file.Executable{},
packages: []pkg.Package{},
want: make([]artifact.Relationship, 0),
},
{
name: "given a package that imports glibc, expect a relationship between the two packages when the package is an executable",
resolver: file.NewMockResolverForPaths(
glibcCoordinate.RealPath,
nestedLibCoordinate.RealPath,
parrallelLibCoordinate.RealPath,
),
// path -> executable (above mock resolver needs to be able to resolve to paths in this map)
coordinateIndex: map[file.Coordinates]file.Executable{
glibcCoordinate: glibcExecutable,
nestedLibCoordinate: syftTestFixtureExecutable,
parrallelLibCoordinate: syftTestFixtureExecutable2,
},
packages: []pkg.Package{glibCPackage, syftTestFixturePackage},
want: []artifact.Relationship{
{
From: glibCPackage,
To: syftTestFixturePackage,
Type: artifact.DependencyOfRelationship,
},
},
},
{
name: "given an executable maps to one base path represented by two RPM we make two relationships",
resolver: file.NewMockResolverForPaths(
glibcCoordinate.RealPath,
secondGlibcCoordinate.RealPath,
nestedLibCoordinate.RealPath,
parrallelLibCoordinate.RealPath,
),
coordinateIndex: map[file.Coordinates]file.Executable{
glibcCoordinate: glibcExecutable,
secondGlibcCoordinate: glibcExecutable,
nestedLibCoordinate: syftTestFixtureExecutable,
parrallelLibCoordinate: syftTestFixtureExecutable2,
},
packages: []pkg.Package{glibCPackage, glibCustomPackage, syftTestFixturePackage},
want: []artifact.Relationship{
{
From: glibCPackage,
To: syftTestFixturePackage,
Type: artifact.DependencyOfRelationship,
},
{
From: glibCustomPackage,
To: syftTestFixturePackage,
Type: artifact.DependencyOfRelationship,
},
},
},
{
name: "given some dependency relationships already exist, expect no duplicate relationships to be created",
resolver: file.NewMockResolverForPaths(
glibcCoordinate.RealPath,
nestedLibCoordinate.RealPath,
parrallelLibCoordinate.RealPath,
),
coordinateIndex: map[file.Coordinates]file.Executable{
glibcCoordinate: glibcExecutable,
nestedLibCoordinate: syftTestFixtureExecutable,
parrallelLibCoordinate: syftTestFixtureExecutable2,
},
packages: []pkg.Package{glibCPackage, glibCustomPackage, syftTestFixturePackage},
prexistingRelationships: []artifact.Relationship{
{
From: glibCPackage,
To: syftTestFixturePackage,
Type: artifact.DependencyOfRelationship,
},
},
want: []artifact.Relationship{},
},
{
name: "given a package that imports a library that is not tracked by the resolver, expect no relationships to be created",
resolver: file.NewMockResolverForPaths(),
coordinateIndex: map[file.Coordinates]file.Executable{
glibcCoordinate: glibcExecutable,
nestedLibCoordinate: syftTestFixtureExecutable,
parrallelLibCoordinate: syftTestFixtureExecutable2,
},
packages: []pkg.Package{glibCPackage, syftTestFixturePackage},
want: []artifact.Relationship{},
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
accessor := newAccesor(tt.packages, tt.coordinateIndex, tt.prexistingRelationships)
// given a resolver that knows about the paths of the packages and executables,
// and given an SBOM accessor that knows about the packages and executables,
// we should be able to create a set of relationships between the packages and executables
relationships := NewDependencyRelationships(tt.resolver, accessor)
if diff := relationshipComparer(tt.want, relationships); diff != "" {
t.Errorf("unexpected relationships (-want, +got): %s", diff)
}
})
}
}
func relationshipComparer(x, y []artifact.Relationship) string {
return cmp.Diff(x, y, cmpopts.IgnoreUnexported(
pkg.Package{},
artifact.Relationship{},
file.LocationSet{},
pkg.LicenseSet{},
))
}
func newAccesor(pkgs []pkg.Package, coordinateIndex map[file.Coordinates]file.Executable, prexistingRelationships []artifact.Relationship) sbomsync.Accessor {
sb := sbom.SBOM{
Artifacts: sbom.Artifacts{
Packages: pkg.NewCollection(),
},
}
builder := sbomsync.NewBuilder(&sb)
builder.AddPackages(pkgs...)
accessor := builder.(sbomsync.Accessor)
accessor.WriteToSBOM(func(s *sbom.SBOM) {
s.Artifacts.Executables = coordinateIndex
if prexistingRelationships != nil {
s.Relationships = prexistingRelationships
}
})
return accessor
}
@@ -41,12 +41,13 @@ func (i *relationshipIndex) track(r artifact.Relationship) bool {
}
i.typesByFromTo[fromID][toID].Add(string(r.Type))
return exists
return !exists
}
// add a new relationship to the index, returning true if the relationship is new to the index, false otherwise (thus is a duplicate).
// nolint:unparam
func (i *relationshipIndex) add(r artifact.Relationship) bool {
if !i.track(r) {
if i.track(r) {
i.additional = append(i.additional, r)
return true
}
@@ -0,0 +1,128 @@
package binary
import (
"reflect"
"testing"
"github.com/scylladb/go-set/strset"
"github.com/anchore/syft/syft/artifact"
)
func Test_newRelationshipIndex(t *testing.T) {
from := fakeIdentifiable{id: "from"}
to := fakeIdentifiable{id: "to"}
tests := []struct {
name string
given []artifact.Relationship
want *relationshipIndex
}{
{
name: "newRelationshipIndex returns an empty index with no existing relationships",
want: &relationshipIndex{
typesByFromTo: make(map[artifact.ID]map[artifact.ID]*strset.Set),
additional: make([]artifact.Relationship, 0),
},
},
{
name: "newRelationshipIndex returns an index which tracks existing relationships",
given: []artifact.Relationship{
{
From: from,
To: to,
Type: artifact.EvidentByRelationship,
},
},
want: &relationshipIndex{
typesByFromTo: map[artifact.ID]map[artifact.ID]*strset.Set{
"from": {
"to": strset.New("evident-by"),
},
},
additional: make([]artifact.Relationship, 0),
},
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
if got := newRelationshipIndex(tt.given...); !reflect.DeepEqual(got, tt.want) {
t.Errorf("newRelationshipIndex() = %v, want %v", got, tt.want)
}
})
}
}
func Test_relationshipIndex_track(t *testing.T) {
from := fakeIdentifiable{id: "from"}
to := fakeIdentifiable{id: "to"}
relationship := artifact.Relationship{From: from, To: to, Type: artifact.EvidentByRelationship}
tests := []struct {
name string
existing []artifact.Relationship
given artifact.Relationship
want bool
}{
{
name: "track returns true for a new relationship",
existing: []artifact.Relationship{},
given: relationship,
want: true,
},
{
name: "track returns false for an existing relationship",
existing: []artifact.Relationship{relationship},
given: relationship,
want: false,
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
i := newRelationshipIndex(tt.existing...)
if got := i.track(tt.given); got != tt.want {
t.Errorf("track() = %v, want %v", got, tt.want)
}
})
}
}
func Test_relationshipIndex_add(t *testing.T) {
from := fakeIdentifiable{id: "from"}
to := fakeIdentifiable{id: "to"}
relationship := artifact.Relationship{From: from, To: to, Type: artifact.EvidentByRelationship}
tests := []struct {
name string
existing []artifact.Relationship
given artifact.Relationship
want bool
}{
{
name: "add returns true for a new relationship",
existing: []artifact.Relationship{},
given: relationship,
want: true,
},
{
name: "add returns false for an existing relationship",
existing: []artifact.Relationship{relationship},
given: relationship,
want: false,
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
i := newRelationshipIndex(tt.existing...)
if got := i.add(tt.given); got != tt.want {
t.Errorf("add() = %v, want %v", got, tt.want)
}
})
}
}
type fakeIdentifiable struct {
id string
}
func (f fakeIdentifiable) ID() artifact.ID {
return artifact.ID(f.id)
}
@@ -36,25 +36,19 @@ func (i *sharedLibraryIndex) build(resolver file.Resolver, accessor sbomsync.Acc
i.packagesByLibraryPath = packagesWithLibraryOwnership(resolver, accessor, i.allLibLocations)
}
func (i *sharedLibraryIndex) owningLibraryLocations(libraryBasename string) file.CoordinateSet {
if set, ok := i.libLocationsByBasename[libraryBasename]; ok {
return set
}
return file.NewCoordinateSet()
}
func (i *sharedLibraryIndex) owningLibraryPackage(libraryBasename string) *pkg.Collection {
// find all packages that own a library by it's basename
// find all packages that own a library by its basename
collection := pkg.NewCollection()
if set, ok := i.libLocationsByBasename[libraryBasename]; ok {
for _, coord := range set.ToSlice() {
if pkgSet, ok := i.packagesByLibraryPath[coord]; ok {
return pkgSet
toAdd := pkgSet.Sorted()
collection.Add(toAdd...)
}
}
}
return nil
return collection
}
func locationsThatProvideLibraries(accessor sbomsync.Accessor) (map[string]file.CoordinateSet, file.CoordinateSet) {
@@ -63,6 +57,7 @@ func locationsThatProvideLibraries(accessor sbomsync.Accessor) (map[string]file.
allLibLocations := file.NewCoordinateSet()
accessor.ReadFromSBOM(func(s *sbom.SBOM) {
// PROBLEM: this does not consider all symlinks to real paths that are libraries
for coord, f := range s.Artifacts.Executables {
if !f.HasExports {
continue
@@ -84,34 +79,53 @@ func packagesWithLibraryOwnership(resolver file.Resolver, accessor sbomsync.Acce
accessor.ReadFromSBOM(func(s *sbom.SBOM) {
for _, p := range s.Artifacts.Packages.Sorted() {
fileOwner, ok := p.Metadata.(pkg.FileOwner)
if !ok {
continue
}
for _, pth := range fileOwner.OwnedFiles() {
ownedLocation, err := resolver.FilesByPath(pth)
if err != nil {
log.WithFields("error", err, "path", pth).Trace("unable to find path for owned file")
var ownedFilePaths []string
if p.Type == pkg.BinaryPkg {
for _, loc := range p.Locations.ToSlice() {
ownedFilePaths = append(ownedFilePaths, loc.Path())
}
} else {
fileOwner, ok := p.Metadata.(pkg.FileOwner)
if !ok {
continue
}
for _, loc := range ownedLocation {
// if the location is a library, add the package to the set of packages that own the library
if !allLibLocations.Contains(loc.Coordinates) {
continue
}
if _, ok := packagesByLibraryPath[loc.Coordinates]; !ok {
packagesByLibraryPath[loc.Coordinates] = pkg.NewCollection()
}
// we have a library path, add the package to the set of packages that own the library
packagesByLibraryPath[loc.Coordinates].Add(p)
}
ownedFilePaths = fileOwner.OwnedFiles()
}
packagesByLibraryPath = populatePackagesByLibraryPath(resolver, allLibLocations, packagesByLibraryPath, p, ownedFilePaths)
}
})
return packagesByLibraryPath
}
func populatePackagesByLibraryPath(
resolver file.Resolver,
allLibLocations file.CoordinateSet,
packagesByLibraryPath map[file.Coordinates]*pkg.Collection,
p pkg.Package,
ownedFilePaths []string,
) map[file.Coordinates]*pkg.Collection {
for _, pth := range ownedFilePaths {
ownedLocation, err := resolver.FilesByPath(pth)
if err != nil {
log.WithFields("error", err, "path", pth).Trace("unable to find path for owned file")
continue
}
for _, loc := range ownedLocation {
// if the location is a library, add the package to the set of packages that own the library
if !allLibLocations.Contains(loc.Coordinates) {
continue
}
if _, ok := packagesByLibraryPath[loc.Coordinates]; !ok {
packagesByLibraryPath[loc.Coordinates] = pkg.NewCollection()
}
// we have a library path, add the package to the set of packages that own the library
packagesByLibraryPath[loc.Coordinates].Add(p)
}
}
return packagesByLibraryPath
}
@@ -0,0 +1,105 @@
package binary
import (
"path"
"testing"
"github.com/anchore/syft/syft/artifact"
"github.com/anchore/syft/syft/file"
"github.com/anchore/syft/syft/pkg"
)
func Test_newShareLibIndex(t *testing.T) {
tests := []struct {
name string
resolver file.Resolver
coordinateIndex map[file.Coordinates]file.Executable
packages []pkg.Package
prexistingRelationships []artifact.Relationship
}{
{
name: "constructor",
resolver: file.NewMockResolverForPaths(),
coordinateIndex: map[file.Coordinates]file.Executable{},
packages: []pkg.Package{},
prexistingRelationships: []artifact.Relationship{},
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
accessor := newAccesor(tt.packages, tt.coordinateIndex, tt.prexistingRelationships)
sharedLibraryIndex := newShareLibIndex(tt.resolver, accessor)
if sharedLibraryIndex == nil {
t.Errorf("newShareLibIndex() = %v, want non-nil", sharedLibraryIndex)
}
})
}
}
func Test_sharedLibraryIndex_build(t *testing.T) {
glibcCoordinate := file.NewCoordinates("/usr/lib64/libc.so.6", "")
secondGlibcCoordinate := file.NewCoordinates("/usr/local/lib64/libc.so.6", "")
glibcExecutable := file.Executable{
Format: "elf",
HasExports: true,
HasEntrypoint: true,
ImportedLibraries: []string{
path.Base(glibcCoordinate.RealPath),
path.Base(secondGlibcCoordinate.RealPath),
},
}
glibCPackage := pkg.Package{
Name: "glibc",
Version: "2.28-236.el8_9.12",
Locations: file.NewLocationSet(
file.NewLocation(glibcCoordinate.RealPath),
file.NewLocation("some/other/path"),
),
Type: pkg.RpmPkg,
Metadata: pkg.RpmDBEntry{
Files: []pkg.RpmFileRecord{
{
Path: glibcCoordinate.RealPath,
},
{
Path: "some/other/path",
},
},
},
}
tests := []struct {
name string
resolver file.Resolver
coordinateIndex map[file.Coordinates]file.Executable
packages []pkg.Package
prexistingRelationships []artifact.Relationship
}{
{
name: "build with locations and packages",
resolver: file.NewMockResolverForPaths([]string{
glibcCoordinate.RealPath,
secondGlibcCoordinate.RealPath,
}...),
coordinateIndex: map[file.Coordinates]file.Executable{
glibcCoordinate: glibcExecutable,
secondGlibcCoordinate: glibcExecutable,
},
packages: []pkg.Package{
glibCPackage,
},
prexistingRelationships: []artifact.Relationship{},
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
accessor := newAccesor(tt.packages, tt.coordinateIndex, tt.prexistingRelationships)
sharedLibraryIndex := newShareLibIndex(tt.resolver, accessor)
sharedLibraryIndex.build(tt.resolver, accessor)
pkgs := sharedLibraryIndex.owningLibraryPackage(path.Base(glibcCoordinate.RealPath))
if pkgs.PackageCount() < 1 {
t.Errorf("owningLibraryPackage() = %v, want non-empty", pkgs)
}
})
}
}
@@ -0,0 +1 @@
../../../../syft/pkg/cataloger/binary/test-fixtures/elf-test-fixtures
+5 -3
View File
@@ -12,8 +12,9 @@ import (
func Finalize(resolver file.Resolver, builder sbomsync.Builder, cfg cataloging.RelationshipsConfig, src artifact.Identifiable) {
accessor := builder.(sbomsync.Accessor)
// remove ELF packages that are already represented by a non-ELF package
// TODO (also, how should we update the TUI to reflect that we removed packages?)
// remove ELF packages and Binary packages that are already
// represented by a source package (e.g. a package that is evident by some package manager)
builder.DeletePackages(binary.PackagesToRemove(resolver, accessor)...)
// add relationships showing packages that are evident by a file which is owned by another package (package-to-package)
if cfg.PackageFileOwnershipOverlap {
@@ -31,7 +32,7 @@ func Finalize(resolver file.Resolver, builder sbomsync.Builder, cfg cataloging.R
accessor.WriteToSBOM(func(s *sbom.SBOM) {
s.Relationships = append(s.Relationships, newBinaryRelationships...)
})
builder.AddRelationships(newBinaryRelationships...)
// add source "contains package" relationship (source-to-package)
var sourceRelationships []artifact.Relationship
accessor.ReadFromSBOM(func(s *sbom.SBOM) {
@@ -44,5 +45,6 @@ func Finalize(resolver file.Resolver, builder sbomsync.Builder, cfg cataloging.R
accessor.ReadFromSBOM(func(s *sbom.SBOM) {
evidentByRelationships = evidentBy(s.Artifacts.Packages)
})
builder.AddRelationships(evidentByRelationships...)
}
+47 -5
View File
@@ -20,6 +20,8 @@ type Builder interface {
AddPackages(...pkg.Package)
DeletePackages(...artifact.ID)
// edges
AddRelationships(...artifact.Relationship)
@@ -36,14 +38,22 @@ type Accessor interface {
}
type sbomBuilder struct {
sbom *sbom.SBOM
lock *sync.RWMutex
sbom *sbom.SBOM
lock *sync.RWMutex
onWrite []func(*sbom.SBOM)
}
func NewBuilder(s *sbom.SBOM) Builder {
func NewBuilder(s *sbom.SBOM, onWrite ...func(*sbom.SBOM)) Builder {
return &sbomBuilder{
sbom: s,
lock: &sync.RWMutex{},
sbom: s,
lock: &sync.RWMutex{},
onWrite: onWrite,
}
}
func (b sbomBuilder) onWriteEvent() {
for _, fn := range b.onWrite {
fn(b.sbom)
}
}
@@ -52,6 +62,7 @@ func (b sbomBuilder) WriteToSBOM(fn func(*sbom.SBOM)) {
defer b.lock.Unlock()
fn(b.sbom)
b.onWriteEvent()
}
func (b sbomBuilder) ReadFromSBOM(fn func(*sbom.SBOM)) {
@@ -66,6 +77,35 @@ func (b sbomBuilder) AddPackages(p ...pkg.Package) {
defer b.lock.Unlock()
b.sbom.Artifacts.Packages.Add(p...)
b.onWriteEvent()
}
func (b sbomBuilder) DeletePackages(ids ...artifact.ID) {
b.lock.Lock()
defer b.lock.Unlock()
deleted := make(map[artifact.ID]struct{})
for _, id := range ids {
b.sbom.Artifacts.Packages.Delete(id)
deleted[id] = struct{}{}
}
// remove any relationships that reference the deleted packages
var relationships []artifact.Relationship
for _, rel := range b.sbom.Relationships {
if _, ok := deleted[rel.From.ID()]; ok {
continue
}
if _, ok := deleted[rel.To.ID()]; ok {
continue
}
// only keep relationships that don't reference the deleted packages
relationships = append(relationships, rel)
}
b.sbom.Relationships = relationships
b.onWriteEvent()
}
func (b sbomBuilder) AddRelationships(relationship ...artifact.Relationship) {
@@ -73,6 +113,7 @@ func (b sbomBuilder) AddRelationships(relationship ...artifact.Relationship) {
defer b.lock.Unlock()
b.sbom.Relationships = append(b.sbom.Relationships, relationship...)
b.onWriteEvent()
}
func (b sbomBuilder) SetLinuxDistribution(release linux.Release) {
@@ -80,4 +121,5 @@ func (b sbomBuilder) SetLinuxDistribution(release linux.Release) {
defer b.lock.Unlock()
b.sbom.Artifacts.LinuxDistribution = &release
b.onWriteEvent()
}
+98
View File
@@ -0,0 +1,98 @@
package sbomsync
import (
"testing"
"github.com/magiconair/properties/assert"
"github.com/anchore/syft/syft/artifact"
"github.com/anchore/syft/syft/pkg"
"github.com/anchore/syft/syft/sbom"
)
func TestNewBuilder(t *testing.T) {
tests := []struct {
name string
sbom sbom.SBOM
}{
{
"TestNewBuilder with empty sbom",
sbom.SBOM{
Artifacts: sbom.Artifacts{
Packages: pkg.NewCollection(),
},
},
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
builder := NewBuilder(&tt.sbom)
builder.AddPackages(pkg.Package{})
accessor := builder.(Accessor)
accessor.ReadFromSBOM(func(s *sbom.SBOM) {
packageCount := s.Artifacts.Packages.PackageCount()
assert.Equal(t, packageCount, 1, "expected 1 package in sbom")
})
})
}
}
func Test_sbomBuilder_DeletePackages(t *testing.T) {
testPackage := pkg.Package{
Name: "test",
Version: "1.0.0",
Type: pkg.DebPkg,
}
testPackage.SetID()
keepMe := pkg.Package{
Name: "keepMe",
Version: "1.0.0",
Type: pkg.DebPkg,
}
prexistingRelationships := []artifact.Relationship{
{
From: testPackage,
To: testPackage,
Type: artifact.DependencyOfRelationship,
},
}
tests := []struct {
name string
sbom sbom.SBOM
}{
{
"Test_sbomBuilder_DeletePackages deletes a given package",
sbom.SBOM{
Artifacts: sbom.Artifacts{
Packages: pkg.NewCollection(),
},
},
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
builder := NewBuilder(&tt.sbom)
builder.AddPackages(testPackage, keepMe)
accessor := builder.(Accessor)
accessor.WriteToSBOM(func(s *sbom.SBOM) {
s.Relationships = prexistingRelationships
})
builder.DeletePackages(testPackage.ID())
newAccess := builder.(Accessor)
newAccess.ReadFromSBOM(func(s *sbom.SBOM) {
packageCount := s.Artifacts.Packages.PackageCount()
// deleted target package
assert.Equal(t, packageCount, 1, "expected 1 packages in sbom")
relationshipCount := len(s.Relationships)
// deleted relationships that reference the deleted package
assert.Equal(t, relationshipCount, 0, "expected 0 relationships in sbom")
})
})
}
}
+3 -3
View File
@@ -111,10 +111,10 @@ func NewPackageTask(cfg CatalogingFactoryConfig, c pkg.Cataloger, tags ...string
if cfg.DataGenerationConfig.GenerateCPEs {
// generate CPEs (note: this is excluded from package ID, so is safe to mutate)
// we might have binary classified CPE already with the package so we want to append here
dictionaryCPE, ok := cpe.DictionaryFind(p)
dictionaryCPEs, ok := cpe.DictionaryFind(p)
if ok {
log.Tracef("used CPE dictionary to find CPE for %s package %q: %s", p.Type, p.Name, dictionaryCPE.Attributes.BindToFmtString())
p.CPEs = append(p.CPEs, dictionaryCPE)
log.Tracef("used CPE dictionary to find CPEs for %s package %q: %s", p.Type, p.Name, dictionaryCPEs)
p.CPEs = append(p.CPEs, dictionaryCPEs...)
} else {
p.CPEs = append(p.CPEs, cpe.Generate(p)...)
}
+1
View File
@@ -80,6 +80,7 @@ func DefaultPackageTaskFactories() PackageTaskFactories {
pkgcataloging.DeclaredTag, pkgcataloging.DirectoryTag, pkgcataloging.LanguageTag, "javascript", "node", "npm",
),
newSimplePackageTaskFactory(php.NewComposerLockCataloger, pkgcataloging.DeclaredTag, pkgcataloging.DirectoryTag, pkgcataloging.LanguageTag, "php", "composer"),
newSimplePackageTaskFactory(php.NewPeclCataloger, pkgcataloging.DeclaredTag, pkgcataloging.DirectoryTag, pkgcataloging.LanguageTag, pkgcataloging.ImageTag, "php", "pecl"),
newPackageTaskFactory(
func(cfg CatalogingFactoryConfig) pkg.Cataloger {
return python.NewPackageCataloger(cfg.PackagesConfig.Python)
+3262 -2367
View File
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
+37 -1
View File
@@ -1,6 +1,6 @@
{
"$schema": "https://json-schema.org/draft/2020-12/schema",
"$id": "anchore.io/schema/syft/json/16.0.6/document",
"$id": "anchore.io/schema/syft/json/16.0.8/document",
"$ref": "#/$defs/Document",
"$defs": {
"AlpmDbEntry": {
@@ -46,6 +46,18 @@
"$ref": "#/$defs/AlpmFileRecord"
},
"type": "array"
},
"provides": {
"items": {
"type": "string"
},
"type": "array"
},
"depends": {
"items": {
"type": "string"
},
"type": "array"
}
},
"type": "object",
@@ -1496,6 +1508,9 @@
{
"$ref": "#/$defs/PhpComposerLockEntry"
},
{
"$ref": "#/$defs/PhpPeclEntry"
},
{
"$ref": "#/$defs/PortageDbEntry"
},
@@ -1779,6 +1794,27 @@
"dist"
]
},
"PhpPeclEntry": {
"properties": {
"name": {
"type": "string"
},
"version": {
"type": "string"
},
"license": {
"items": {
"type": "string"
},
"type": "array"
}
},
"type": "object",
"required": [
"name",
"version"
]
},
"PortageDbEntry": {
"properties": {
"installedSize": {
+11 -24
View File
@@ -4,11 +4,9 @@ import (
"context"
"fmt"
"sort"
"time"
"github.com/dustin/go-humanize"
"github.com/scylladb/go-set/strset"
"github.com/wagoodman/go-progress"
"github.com/anchore/syft/internal/bus"
"github.com/anchore/syft/internal/sbomsync"
@@ -63,9 +61,9 @@ func CreateSBOM(ctx context.Context, src source.Source, cfg *CreateSBOMConfig) (
}
catalogingProgress := monitorCatalogingTask(src.ID(), taskGroups)
packageCatalogingProgress := monitorPackageCatalogingTask(s.Artifacts.Packages)
packageCatalogingProgress := monitorPackageCatalogingTask()
builder := sbomsync.NewBuilder(&s)
builder := sbomsync.NewBuilder(&s, monitorPackageCount(packageCatalogingProgress))
for i := range taskGroups {
err := task.NewTaskExecutor(taskGroups[i], cfg.Parallelism).Execute(ctx, resolver, builder, catalogingProgress)
if err != nil {
@@ -80,7 +78,14 @@ func CreateSBOM(ctx context.Context, src source.Source, cfg *CreateSBOMConfig) (
return &s, nil
}
func monitorPackageCatalogingTask(pkgs *pkg.Collection) *monitor.CatalogerTaskProgress {
func monitorPackageCount(prog *monitor.CatalogerTaskProgress) func(s *sbom.SBOM) {
return func(s *sbom.SBOM) {
count := humanize.Comma(int64(s.Artifacts.Packages.PackageCount()))
prog.AtomicStage.Set(fmt.Sprintf("%s packages", count))
}
}
func monitorPackageCatalogingTask() *monitor.CatalogerTaskProgress {
info := monitor.GenericTask{
Title: monitor.Title{
Default: "Packages",
@@ -90,25 +95,7 @@ func monitorPackageCatalogingTask(pkgs *pkg.Collection) *monitor.CatalogerTaskPr
ParentID: monitor.TopLevelCatalogingTaskID,
}
prog := bus.StartCatalogerTask(info, -1, "")
go func() {
ticker := time.NewTicker(200 * time.Millisecond)
defer ticker.Stop()
for {
<-ticker.C
count := humanize.Comma(int64(pkgs.PackageCount()))
prog.AtomicStage.Set(fmt.Sprintf("%s packages", count))
if progress.IsCompleted(prog) {
break
}
}
}()
return prog
return bus.StartCatalogerTask(info, -1, "")
}
func monitorCatalogingTask(srcID artifact.ID, tasks [][]task.Task) *monitor.CatalogerTaskProgress {
+25 -17
View File
@@ -11,6 +11,7 @@ import (
"github.com/bmatcuk/doublestar/v4"
"github.com/dustin/go-humanize"
"github.com/anchore/syft/internal"
"github.com/anchore/syft/internal/bus"
"github.com/anchore/syft/internal/log"
"github.com/anchore/syft/internal/mimetype"
@@ -60,24 +61,8 @@ func (i *Cataloger) Catalog(resolver file.Resolver) (map[file.Coordinates]file.E
for _, loc := range locs {
prog.AtomicStage.Set(loc.Path())
reader, err := resolver.FileContentsByLocation(loc)
if err != nil {
// TODO: known-unknowns
log.WithFields("error", err).Warnf("unable to get file contents for %q", loc.RealPath)
continue
}
exec := processExecutableLocation(loc, resolver)
uReader, err := unionreader.GetUnionReader(reader)
if err != nil {
// TODO: known-unknowns
log.WithFields("error", err).Warnf("unable to get union reader for %q", loc.RealPath)
continue
}
exec, err := processExecutable(loc, uReader)
if err != nil {
log.WithFields("error", err).Warnf("unable to process executable %q", loc.RealPath)
}
if exec != nil {
prog.Increment()
results[loc.Coordinates] = *exec
@@ -92,6 +77,29 @@ func (i *Cataloger) Catalog(resolver file.Resolver) (map[file.Coordinates]file.E
return results, nil
}
func processExecutableLocation(loc file.Location, resolver file.Resolver) *file.Executable {
reader, err := resolver.FileContentsByLocation(loc)
if err != nil {
// TODO: known-unknowns
log.WithFields("error", err).Warnf("unable to get file contents for %q", loc.RealPath)
return nil
}
defer internal.CloseAndLogError(reader, loc.RealPath)
uReader, err := unionreader.GetUnionReader(reader)
if err != nil {
// TODO: known-unknowns
log.WithFields("error", err).Warnf("unable to get union reader for %q", loc.RealPath)
return nil
}
exec, err := processExecutable(loc, uReader)
if err != nil {
log.WithFields("error", err).Warnf("unable to process executable %q", loc.RealPath)
}
return exec
}
func catalogingProgress(locations int64) *monitor.CatalogerTaskProgress {
info := monitor.GenericTask{
Title: monitor.Title{
+3
View File
@@ -57,6 +57,9 @@ func machoHasEntrypoint(f *macho.File) bool {
}
func machoHasExports(f *macho.File) bool {
if f == nil || f.Symtab == nil {
return false
}
for _, sym := range f.Symtab.Syms {
// look for symbols that are:
// - not private and are external
@@ -69,6 +69,11 @@ func Test_machoHasExports(t *testing.T) {
fixture: "bin/hello_mac",
want: false,
},
{
name: "gcc-amd64-darwin-exec-debug",
fixture: "bin/gcc-amd64-darwin-exec-debug",
want: false,
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
@@ -1,10 +1,13 @@
# invoke all make files in subdirectories
.PHONY: all hello libhello
all: hello libhello
all: hello libhello ../bin/gcc-amd64-darwin-exec-debug
hello:
$(MAKE) -C hello
libhello:
$(MAKE) -C libhello
../bin/gcc-amd64-darwin-exec-debug:
curl -L -o ../bin/gcc-amd64-darwin-exec-debug https://github.com/golang/tools/raw/9ed98faabadd2cb94de86d5290b1c6942b7c4877/cmd/splitdwarf/internal/macho/testdata/gcc-amd64-darwin-exec-debug
+7
View File
@@ -13,6 +13,13 @@ type Coordinates struct {
FileSystemID string `json:"layerID,omitempty" cyclonedx:"layerID"` // An ID representing the filesystem. For container images, this is a layer digest. For directories or a root filesystem, this is blank.
}
func NewCoordinates(realPath, fsID string) Coordinates {
return Coordinates{
RealPath: realPath,
FileSystemID: fsID,
}
}
func (c Coordinates) ID() artifact.ID {
f, err := artifact.IDByHash(c)
if err != nil {
@@ -245,6 +245,8 @@ func toRootPackage(s source.Description) *spdx.Package {
Supplier: helpers.NOASSERTION,
},
PackageDownloadLocation: helpers.NOASSERTION,
PackageLicenseConcluded: helpers.NOASSERTION,
PackageLicenseDeclared: helpers.NOASSERTION,
}
if purl != nil {
@@ -517,9 +519,7 @@ func toPackageOriginator(p pkg.Package) *spdx.Originator {
}
func toPackageSupplier(p pkg.Package) *spdx.Supplier {
// this uses the Originator function for now until
// a better distinction can be made for supplier
kind, supplier := helpers.Originator(p)
kind, supplier := helpers.Supplier(p)
if kind == "" || supplier == "" {
return &spdx.Supplier{
Supplier: helpers.NOASSERTION,
@@ -624,6 +624,9 @@ func toFiles(s sbom.SBOM) (results []*spdx.File) {
Checksums: toFileChecksums(digests),
FileName: coordinates.RealPath,
FileTypes: toFileTypes(metadata),
LicenseInfoInFiles: []string{ // required in SPDX 2.2
helpers.NOASSERTION,
},
})
}
@@ -0,0 +1,210 @@
package helpers
import (
"fmt"
"regexp"
"strings"
"github.com/anchore/syft/internal"
"github.com/anchore/syft/syft/pkg"
)
const (
orgType = "Organization"
personType = "Person"
)
// Originator needs to conform to the SPDX spec here:
// https://spdx.github.io/spdx-spec/v2.2.2/package-information/#76-package-originator-field
//
// Definition:
//
// If the package identified in the SPDX document originated from a different person or
// organization than identified as Package Supplier (see 7.5 above), this field identifies from
// where or whom the package originally came. In some cases, a package may be created and
// originally distributed by a different third party than the Package Supplier of the package.
// For example, the SPDX document identifies the package as glibc and the Package Supplier as
// Red Hat, but the Free Software Foundation is the Package Originator.
//
// Use NOASSERTION if:
//
// - the SPDX document creator has attempted to but cannot reach a reasonable objective determination;
// - the SPDX document creator has made no attempt to determine this field; or
// - the SPDX document creator has intentionally provided no information (no meaning should be implied by doing so).
//
// Available options are: <omit>, NOASSERTION, Person: <person>, Organization: <org>
// return values are: <type>, <value>
func Originator(p pkg.Package) (typ string, author string) { // nolint: funlen
if !hasMetadata(p) {
return typ, author
}
switch metadata := p.Metadata.(type) {
case pkg.ApkDBEntry:
author = metadata.Maintainer
case pkg.DotnetPortableExecutableEntry:
typ = orgType
author = metadata.CompanyName
case pkg.DpkgDBEntry:
author = metadata.Maintainer
case pkg.JavaArchive:
if metadata.Manifest != nil {
author = metadata.Manifest.Main.MustGet("Specification-Vendor")
if author == "" {
author = metadata.Manifest.Main.MustGet("Implementation-Vendor")
}
}
case pkg.LinuxKernelModule:
author = metadata.Author
case pkg.PhpComposerLockEntry:
if len(metadata.Authors) > 0 {
entry := metadata.Authors[0]
author = formatPersonOrOrg(entry.Name, entry.Email)
}
case pkg.PhpComposerInstalledEntry:
if len(metadata.Authors) > 0 {
entry := metadata.Authors[0]
author = formatPersonOrOrg(entry.Name, entry.Email)
}
case pkg.RDescription:
// this is most likely to have a name and email
author = metadata.Maintainer
if author == "" {
author = metadata.Author
}
case pkg.NpmPackage:
author = metadata.Author
case pkg.PythonPackage:
author = formatPersonOrOrg(metadata.Author, metadata.AuthorEmail)
case pkg.RubyGemspec:
if len(metadata.Authors) > 0 {
author = metadata.Authors[0]
}
case pkg.RpmDBEntry:
typ = orgType
author = metadata.Vendor
case pkg.RpmArchive:
typ = orgType
author = metadata.Vendor
case pkg.WordpressPluginEntry:
// it seems that the vast majority of the time the author is an org, not a person
typ = orgType
author = metadata.Author
}
if typ == "" && author != "" {
typ = personType
}
return typ, parseAndFormatPersonOrOrg(author)
}
// Supplier needs to conform to the SPDX spec here:
// https://spdx.github.io/spdx-spec/v2.2.2/package-information/#75-package-supplier-field
//
// Definition:
//
// Identify the actual distribution source for the package/directory identified in the SPDX document. This might
// or might not be different from the originating distribution source for the package. The name of the Package Supplier
// shall be an organization or recognized author and not a web site. For example, SourceForge is a host website, not a
// supplier, the supplier for https://sourceforge.net/projects/bridge/ is “The Linux Foundation.”
//
// Use NOASSERTION if:
//
// - the SPDX document creator has attempted to but cannot reach a reasonable objective determination;
// - the SPDX document creator has made no attempt to determine this field; or
// - the SPDX document creator has intentionally provided no information (no meaning should be implied by doing so).
//
// Available options are: <omit>, NOASSERTION, Person: <person>, Organization: <org>
// return values are: <type>, <value>
func Supplier(p pkg.Package) (typ string, author string) {
if !hasMetadata(p) {
return
}
if metadata, ok := p.Metadata.(pkg.AlpmDBEntry); ok {
// most indications here are that this is the person that is simply packaging the upstream software. Most
// of the time this is not the original author of the upstream software (which would be the originator).
// Though it is possible for users to be both the packager and the author, this code cannot distinct this
// case and sticks to the semantically correct interpretation of the "packager" (which says nothing about the
// authorship of the upstream software).
author = metadata.Packager
}
if author == "" {
// TODO: this uses the Originator function for now until a better distinction can be made for supplier
return Originator(p)
}
if typ == "" && author != "" {
typ = personType
}
return typ, parseAndFormatPersonOrOrg(author)
}
var nameEmailURLPattern = regexp.MustCompile(`^(?P<name>[^<>()]*)( <(?P<email>[^@]+@\w+\.\w+)>)?( \((?P<url>.*)\))?$`)
func parseAndFormatPersonOrOrg(s string) string {
name, email, _ := parseNameEmailURL(s)
return formatPersonOrOrg(name, email)
}
func parseNameEmailURL(s string) (name, email, url string) {
fields := internal.MatchNamedCaptureGroups(nameEmailURLPattern, s)
name = strings.TrimSpace(fields["name"])
email = strings.TrimSpace(fields["email"])
url = strings.TrimSpace(fields["url"])
if email == "" {
if approximatesAsEmail(url) {
email = url
url = ""
} else if approximatesAsEmail(name) {
email = name
name = ""
}
}
return name, email, url
}
func approximatesAsEmail(s string) bool {
atIndex := strings.Index(s, "@")
if atIndex == -1 {
return false
}
dotIndex := strings.Index(s[atIndex:], ".")
return dotIndex != -1
}
func formatPersonOrOrg(name, email string) string {
name = strings.TrimSpace(name)
email = strings.TrimSpace(email)
blankName := name == ""
blankEmail := email == ""
if !blankEmail && !blankName {
return fmt.Sprintf("%s (%s)", name, email)
}
if !blankName && blankEmail {
return name
}
if blankName && !blankEmail {
return email
}
return ""
}
@@ -0,0 +1,482 @@
package helpers
import (
"testing"
"github.com/stretchr/testify/assert"
"github.com/anchore/syft/syft/internal/packagemetadata"
"github.com/anchore/syft/syft/pkg"
)
func Test_OriginatorSupplier(t *testing.T) {
completionTester := packagemetadata.NewCompletionTester(t,
pkg.BinarySignature{},
pkg.CocoaPodfileLockEntry{},
pkg.ConanV1LockEntry{},
pkg.ConanV2LockEntry{}, // the field Username might be the username of either the package originator or the supplier (unclear currently)
pkg.ConanfileEntry{},
pkg.ConaninfoEntry{},
pkg.DartPubspecLockEntry{},
pkg.DotnetDepsEntry{},
pkg.ELFBinaryPackageNoteJSONPayload{},
pkg.ElixirMixLockEntry{},
pkg.ErlangRebarLockEntry{},
pkg.GolangBinaryBuildinfoEntry{},
pkg.GolangModuleEntry{},
pkg.HackageStackYamlLockEntry{},
pkg.HackageStackYamlEntry{},
pkg.LinuxKernel{},
pkg.MicrosoftKbPatch{},
pkg.NixStoreEntry{},
pkg.NpmPackageLockEntry{},
pkg.PhpComposerInstalledEntry{},
pkg.PhpPeclEntry{},
pkg.PortageEntry{},
pkg.PythonPipfileLockEntry{},
pkg.PythonRequirementsEntry{},
pkg.PythonPoetryLockEntry{},
pkg.RustBinaryAuditEntry{},
pkg.RustCargoLockEntry{},
pkg.SwiftPackageManagerResolvedEntry{},
pkg.YarnLockEntry{},
)
tests := []struct {
name string
input pkg.Package
originator string
supplier string
}{
{
// note: since this is an optional field, no value is preferred over NONE or NOASSERTION
name: "no metadata",
input: pkg.Package{},
originator: "",
supplier: "",
},
{
// note: since this is an optional field, no value is preferred over NONE or NOASSERTION
name: "empty author on existing metadata",
input: pkg.Package{
Metadata: pkg.NpmPackage{
Author: "",
},
},
originator: "",
supplier: "",
},
{
name: "from apk",
input: pkg.Package{
Metadata: pkg.ApkDBEntry{
Maintainer: "auth",
},
},
originator: "Person: auth",
supplier: "Person: auth",
},
{
name: "from alpm",
input: pkg.Package{
Metadata: pkg.AlpmDBEntry{
Packager: "someone",
},
},
originator: "",
supplier: "Person: someone",
},
{
name: "from dotnet -- PE binary",
input: pkg.Package{
Metadata: pkg.DotnetPortableExecutableEntry{
CompanyName: "Microsoft Corporation",
},
},
originator: "Organization: Microsoft Corporation",
supplier: "Organization: Microsoft Corporation",
},
{
name: "from dpkg",
input: pkg.Package{
Metadata: pkg.DpkgDBEntry{
Maintainer: "auth",
},
},
originator: "Person: auth",
supplier: "Person: auth",
},
{
name: "from gem",
input: pkg.Package{
Metadata: pkg.RubyGemspec{
Authors: []string{
"auth1",
"auth2",
},
},
},
originator: "Person: auth1",
supplier: "Person: auth1",
},
{
name: "from java -- spec > impl cendor in main manifest section",
input: pkg.Package{
Metadata: pkg.JavaArchive{
Manifest: &pkg.JavaManifest{
Main: pkg.KeyValues{
{
Key: "Implementation-Vendor",
Value: "auth-impl",
},
{
Key: "Specification-Vendor",
Value: "auth-spec",
},
},
},
},
},
originator: "Person: auth-spec",
supplier: "Person: auth-spec",
},
{
name: "from java -- fallback to impl vendor in main manifest section",
input: pkg.Package{
Metadata: pkg.JavaArchive{
Manifest: &pkg.JavaManifest{
Main: pkg.KeyValues{
{
Key: "Implementation-Vendor",
Value: "auth-impl",
},
},
},
},
},
originator: "Person: auth-impl",
supplier: "Person: auth-impl",
},
{
name: "from java -- non-main manifest sections ignored",
input: pkg.Package{
Metadata: pkg.JavaArchive{
Manifest: &pkg.JavaManifest{
Sections: []pkg.KeyValues{
{
{
Key: "Implementation-Vendor",
Value: "auth-impl",
},
},
},
Main: pkg.KeyValues{},
},
},
},
// note: empty!
},
{
name: "from linux kernel module",
input: pkg.Package{
Metadata: pkg.LinuxKernelModule{
Author: "auth",
},
},
originator: "Person: auth",
supplier: "Person: auth",
},
{
name: "from npm",
input: pkg.Package{
Metadata: pkg.NpmPackage{
Author: "auth",
},
},
originator: "Person: auth",
supplier: "Person: auth",
},
{
name: "from npm -- name, email, and url",
input: pkg.Package{
Metadata: pkg.NpmPackage{
Author: "Isaac Z. Schlueter <i@izs.me> (http://blog.izs.me)",
},
},
originator: "Person: Isaac Z. Schlueter (i@izs.me)",
supplier: "Person: Isaac Z. Schlueter (i@izs.me)",
},
{
name: "from npm -- name, email",
input: pkg.Package{
Metadata: pkg.NpmPackage{
Author: "Isaac Z. Schlueter <i@izs.me>",
},
},
originator: "Person: Isaac Z. Schlueter (i@izs.me)",
supplier: "Person: Isaac Z. Schlueter (i@izs.me)",
},
{
name: "from php composer installed file",
input: pkg.Package{
Metadata: pkg.PhpComposerInstalledEntry{
Authors: []pkg.PhpComposerAuthors{
{
Name: "auth",
Email: "me@auth.com",
},
},
},
},
originator: "Person: auth (me@auth.com)",
supplier: "Person: auth (me@auth.com)",
},
{
name: "from php composer installed file",
input: pkg.Package{
Metadata: pkg.PhpComposerLockEntry{
Authors: []pkg.PhpComposerAuthors{
{
Name: "auth",
Email: "me@auth.com",
},
},
},
},
originator: "Person: auth (me@auth.com)",
supplier: "Person: auth (me@auth.com)",
},
{
name: "from python - just name",
input: pkg.Package{
Metadata: pkg.PythonPackage{
Author: "auth",
},
},
originator: "Person: auth",
supplier: "Person: auth",
},
{
name: "from python - just email",
input: pkg.Package{
Metadata: pkg.PythonPackage{
AuthorEmail: "auth@auth.gov",
},
},
originator: "Person: auth@auth.gov",
supplier: "Person: auth@auth.gov",
},
{
name: "from python - both name and email",
input: pkg.Package{
Metadata: pkg.PythonPackage{
Author: "auth",
AuthorEmail: "auth@auth.gov",
},
},
originator: "Person: auth (auth@auth.gov)",
supplier: "Person: auth (auth@auth.gov)",
},
{
name: "from r -- maintainer > author",
input: pkg.Package{
Metadata: pkg.RDescription{
Author: "author",
Maintainer: "maintainer",
},
},
originator: "Person: maintainer",
supplier: "Person: maintainer",
},
{
name: "from r -- fallback to author",
input: pkg.Package{
Metadata: pkg.RDescription{
Author: "author",
},
},
originator: "Person: author",
supplier: "Person: author",
},
{
name: "from rpm archive",
input: pkg.Package{
Metadata: pkg.RpmArchive{
Vendor: "auth",
},
},
originator: "Organization: auth",
supplier: "Organization: auth",
},
{
name: "from rpm DB",
input: pkg.Package{
Metadata: pkg.RpmDBEntry{
Vendor: "auth",
},
},
originator: "Organization: auth",
supplier: "Organization: auth",
},
{
name: "from wordpress plugin",
input: pkg.Package{
Metadata: pkg.WordpressPluginEntry{
Author: "auth",
},
},
originator: "Organization: auth",
supplier: "Organization: auth",
},
}
for _, test := range tests {
t.Run(test.name, func(t *testing.T) {
completionTester.Tested(t, test.input.Metadata)
typ, value := Originator(test.input)
if typ != "" {
value = typ + ": " + value
}
assert.Equal(t, test.originator, value)
typ, value = Supplier(test.input)
if typ != "" {
value = typ + ": " + value
}
assert.Equal(t, test.supplier, value)
})
}
}
func Test_parseNameEmailUrl(t *testing.T) {
tests := []struct {
name string
input string
wantName string
wantEmail string
wantUrl string
}{
{
name: "empty",
input: "",
},
{
name: "npm-like: name only",
input: "Isaac Z. Schlueter",
wantName: "Isaac Z. Schlueter",
},
{
name: "npm-like: name and email",
input: "Ray Nos <bogus2@gmail.com>",
wantName: "Ray Nos",
wantEmail: "bogus2@gmail.com",
},
{
name: "npm-like: name and url",
input: "Ray Nos (http://example.com)",
wantName: "Ray Nos",
wantUrl: "http://example.com",
},
{
name: "npm-like: name, email, and url",
input: "Isaac Z. Schlueter <i@izs.me> (http://blog.izs.me)",
wantName: "Isaac Z. Schlueter",
wantEmail: "i@izs.me",
wantUrl: "http://blog.izs.me",
},
{
name: "mixed input: email only",
input: "i@izs.me",
wantEmail: "i@izs.me",
},
{
name: "mixed input: email in url",
input: "my name (i@izs.me)",
wantName: "my name",
wantEmail: "i@izs.me",
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
gotName, gotEmail, gotUrl := parseNameEmailURL(tt.input)
assert.Equal(t, tt.wantName, gotName)
assert.Equal(t, tt.wantEmail, gotEmail)
assert.Equal(t, tt.wantUrl, gotUrl)
})
}
}
func Test_formatPersonOrOrg(t *testing.T) {
tests := []struct {
name string
input string
email string
want string
}{
{
name: "empty",
want: "",
},
{
name: "name only",
input: "Isaac Z. Schlueter",
want: "Isaac Z. Schlueter",
},
{
name: "email only",
email: "i@something.com",
want: "i@something.com",
},
{
name: "name and email",
input: "Isaac Z. Schlueter",
email: "i@something.com",
want: "Isaac Z. Schlueter (i@something.com)",
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
assert.Equal(t, tt.want, formatPersonOrOrg(tt.input, tt.email))
})
}
}
func Test_approximatesAsEmail(t *testing.T) {
tests := []struct {
name string
input string
want bool
}{
{
name: "empty",
input: "",
want: false,
},
{
name: "no at",
input: "something.com",
want: false,
},
{
name: "no dot",
input: "something@com",
want: false,
},
{
name: "dot before at",
input: "something.com@nothing",
want: false,
},
{
name: "valid",
input: "something@nothing.com",
want: true,
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
assert.Equal(t, tt.want, approximatesAsEmail(tt.input))
})
}
}
@@ -1,119 +0,0 @@
package helpers
import (
"testing"
"github.com/stretchr/testify/assert"
"github.com/anchore/syft/syft/pkg"
)
func Test_Originator(t *testing.T) {
tests := []struct {
name string
input pkg.Package
expected string
}{
{
// note: since this is an optional field, no value is preferred over NONE or NOASSERTION
name: "no metadata",
input: pkg.Package{},
expected: "",
},
{
name: "from gem",
input: pkg.Package{
Metadata: pkg.RubyGemspec{
Authors: []string{
"auth1",
"auth2",
},
},
},
expected: "Person: auth1",
},
{
name: "from npm",
input: pkg.Package{
Metadata: pkg.NpmPackage{
Author: "auth",
},
},
expected: "Person: auth",
},
{
name: "from apk",
input: pkg.Package{
Metadata: pkg.ApkDBEntry{
Maintainer: "auth",
},
},
expected: "Person: auth",
},
{
name: "from python - just name",
input: pkg.Package{
Metadata: pkg.PythonPackage{
Author: "auth",
},
},
expected: "Person: auth",
},
{
name: "from python - just email",
input: pkg.Package{
Metadata: pkg.PythonPackage{
AuthorEmail: "auth@auth.gov",
},
},
expected: "Person: auth@auth.gov",
},
{
name: "from python - both name and email",
input: pkg.Package{
Metadata: pkg.PythonPackage{
Author: "auth",
AuthorEmail: "auth@auth.gov",
},
},
expected: "Person: auth (auth@auth.gov)",
},
{
name: "from rpm",
input: pkg.Package{
Metadata: pkg.RpmDBEntry{
Vendor: "auth",
},
},
expected: "Organization: auth",
},
{
name: "from dpkg",
input: pkg.Package{
Metadata: pkg.DpkgDBEntry{
Maintainer: "auth",
},
},
expected: "Person: auth",
},
{
// note: since this is an optional field, no value is preferred over NONE or NOASSERTION
name: "empty",
input: pkg.Package{
Metadata: pkg.NpmPackage{
Author: "",
},
},
expected: "",
},
}
for _, test := range tests {
t.Run(test.name, func(t *testing.T) {
typ, value := Originator(test.input)
if typ != "" {
value = typ + ": " + value
}
assert.Equal(t, test.expected, value)
})
}
}
@@ -1,44 +0,0 @@
package helpers
import (
"fmt"
"github.com/anchore/syft/syft/pkg"
)
// Originator needs to conform to the SPDX spec here:
// https://spdx.github.io/spdx-spec/package-information/#76-package-originator-field
// Available options are: <omit>, NOASSERTION, Person: <person>, Organization: <org>
// return values are: <type>, <value>
func Originator(p pkg.Package) (string, string) {
typ := ""
author := ""
if hasMetadata(p) {
switch metadata := p.Metadata.(type) {
case pkg.ApkDBEntry:
author = metadata.Maintainer
case pkg.NpmPackage:
author = metadata.Author
case pkg.PythonPackage:
author = metadata.Author
if author == "" {
author = metadata.AuthorEmail
} else if metadata.AuthorEmail != "" {
author = fmt.Sprintf("%s (%s)", author, metadata.AuthorEmail)
}
case pkg.RubyGemspec:
if len(metadata.Authors) > 0 {
author = metadata.Authors[0]
}
case pkg.RpmDBEntry:
typ = "Organization"
author = metadata.Vendor
case pkg.DpkgDBEntry:
author = metadata.Maintainer
}
if typ == "" && author != "" {
typ = "Person"
}
}
return typ, author
}
@@ -36,6 +36,8 @@ func SourceInfo(p pkg.Package) string {
answer = "acquired package info from rust cargo manifest"
case pkg.PhpComposerPkg:
answer = "acquired package info from PHP composer manifest"
case pkg.PhpPeclPkg:
answer = "acquired package info from PHP Pecl manifest"
case pkg.CocoapodsPkg:
answer = "acquired package info from installed cocoapods manifest file"
case pkg.ConanPkg:
@@ -127,6 +127,14 @@ func Test_SourceInfo(t *testing.T) {
"from PHP composer manifest",
},
},
{
input: pkg.Package{
Type: pkg.PhpPeclPkg,
},
expected: []string{
"from PHP Pecl manifest",
},
},
{
input: pkg.Package{
Type: pkg.DartPubPkg,
+70
View File
@@ -9,6 +9,8 @@ import (
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
"github.com/anchore/syft/syft/artifact"
"github.com/anchore/syft/syft/file"
"github.com/anchore/syft/syft/format/internal/spdxutil"
"github.com/anchore/syft/syft/format/internal/testutil"
"github.com/anchore/syft/syft/pkg"
@@ -113,6 +115,74 @@ func TestSPDXJSONImageEncoder(t *testing.T) {
)
}
func TestSPDX22JSONRequredProperties(t *testing.T) {
cfg := DefaultEncoderConfig()
cfg.Pretty = true
cfg.Version = "2.2"
enc, err := NewFormatEncoderWithConfig(cfg)
require.NoError(t, err)
coords := file.Coordinates{
RealPath: "/some/file",
FileSystemID: "ac897d978b6c38749a1",
}
p1 := pkg.Package{
Name: "files-analyzed-true",
Version: "v1",
Locations: file.NewLocationSet(file.NewLocation(coords.RealPath)),
Licenses: pkg.LicenseSet{},
Language: pkg.Java,
Metadata: pkg.JavaArchive{
ArchiveDigests: []file.Digest{
{
Algorithm: "sha256",
Value: "a9b87321a9879c79d87987987a97c97b9789ce978dffea987",
},
},
Parent: nil,
},
}
p1.SetID()
p2 := pkg.Package{
Name: "files-analyzed-false",
Version: "v2",
}
p2.SetID()
testutil.AssertEncoderAgainstGoldenSnapshot(t,
testutil.EncoderSnapshotTestConfig{
Subject: sbom.SBOM{
Artifacts: sbom.Artifacts{
Packages: pkg.NewCollection(p1, p2),
FileDigests: map[file.Coordinates][]file.Digest{
coords: {
{
Algorithm: "sha1",
Value: "3b4ab96c371d913e2a88c269844b6c5fb5cbe761",
},
},
},
},
Relationships: []artifact.Relationship{
{
From: p1,
To: coords,
Type: artifact.ContainsRelationship,
},
},
},
Format: enc,
UpdateSnapshot: *updateSnapshot,
PersistRedactionsInSnapshot: true,
IsJSON: true,
Redactor: redactor(),
},
)
}
func TestSPDXRelationshipOrder(t *testing.T) {
testImage := "image-simple"
@@ -0,0 +1,100 @@
{
"spdxVersion": "SPDX-2.2",
"dataLicense": "CC0-1.0",
"SPDXID": "SPDXRef-DOCUMENT",
"name": "unknown",
"documentNamespace":"redacted",
"creationInfo": {
"licenseListVersion":"redacted",
"creators": [
"Organization: Anchore, Inc",
"Tool: -"
],
"created":"redacted"
},
"packages": [
{
"SPDXID": "SPDXRef-Package-files-analyzed-false-7d37ba9d2f7c574b",
"copyrightText": "NOASSERTION",
"downloadLocation": "NOASSERTION",
"filesAnalyzed": false,
"licenseConcluded": "NOASSERTION",
"licenseDeclared": "NOASSERTION",
"name": "files-analyzed-false",
"sourceInfo": "acquired package info from the following paths: ",
"supplier": "NOASSERTION",
"versionInfo": "v2"
},
{
"name": "files-analyzed-true",
"SPDXID": "SPDXRef-Package-files-analyzed-true-035066c2086b8bb4",
"versionInfo": "v1",
"supplier": "NOASSERTION",
"downloadLocation": "NOASSERTION",
"filesAnalyzed": true,
"packageVerificationCode": {
"packageVerificationCodeValue": "6fe0c471faaaa544e33cae0918eabcdc1c798d18"
},
"checksums": [
{
"algorithm": "SHA256",
"checksumValue": "a9b87321a9879c79d87987987a97c97b9789ce978dffea987"
}
],
"sourceInfo": "acquired package info from the following paths: /some/file",
"licenseConcluded": "NOASSERTION",
"licenseDeclared": "NOASSERTION",
"copyrightText": "NOASSERTION"
},
{
"SPDXID": "SPDXRef-DocumentRoot-Unknown-",
"copyrightText": "",
"downloadLocation": "NOASSERTION",
"filesAnalyzed": false,
"licenseConcluded": "NOASSERTION",
"licenseDeclared": "NOASSERTION",
"name": "",
"supplier": "NOASSERTION"
}
],
"files": [
{
"fileName": "/some/file",
"SPDXID": "SPDXRef-File-some-file-2c5bc344430decac",
"checksums": [
{
"algorithm": "SHA1",
"checksumValue": "3b4ab96c371d913e2a88c269844b6c5fb5cbe761"
}
],
"licenseConcluded": "NOASSERTION",
"licenseInfoInFiles": [
"NOASSERTION"
],
"copyrightText": "",
"comment": "layerID: ac897d978b6c38749a1"
}
],
"relationships": [
{
"spdxElementId": "SPDXRef-Package-files-analyzed-true-035066c2086b8bb4",
"relatedSpdxElement": "SPDXRef-File-some-file-2c5bc344430decac",
"relationshipType": "CONTAINS"
},
{
"spdxElementId": "SPDXRef-DocumentRoot-Unknown-",
"relatedSpdxElement": "SPDXRef-Package-files-analyzed-false-7d37ba9d2f7c574b",
"relationshipType": "CONTAINS"
},
{
"spdxElementId": "SPDXRef-DocumentRoot-Unknown-",
"relatedSpdxElement": "SPDXRef-Package-files-analyzed-true-035066c2086b8bb4",
"relationshipType": "CONTAINS"
},
{
"spdxElementId": "SPDXRef-DOCUMENT",
"relatedSpdxElement": "SPDXRef-DocumentRoot-Unknown-",
"relationshipType": "DESCRIBES"
}
]
}
@@ -67,6 +67,8 @@
"supplier": "NOASSERTION",
"downloadLocation": "NOASSERTION",
"filesAnalyzed": false,
"licenseConcluded": "NOASSERTION",
"licenseDeclared": "NOASSERTION",
"primaryPackagePurpose": "FILE"
}
],
@@ -74,6 +74,8 @@
"checksumValue": "2731251dc34951c0e50fcc643b4c5f74922dad1a5d98f302b504cf46cd5d9368"
}
],
"licenseConcluded": "NOASSERTION",
"licenseDeclared": "NOASSERTION",
"externalRefs": [
{
"referenceCategory": "PACKAGE-MANAGER",
@@ -74,6 +74,8 @@
"checksumValue": "2731251dc34951c0e50fcc643b4c5f74922dad1a5d98f302b504cf46cd5d9368"
}
],
"licenseConcluded": "NOASSERTION",
"licenseDeclared": "NOASSERTION",
"externalRefs": [
{
"referenceCategory": "PACKAGE-MANAGER",
@@ -98,6 +100,9 @@
}
],
"licenseConcluded": "NOASSERTION",
"licenseInfoInFiles": [
"NOASSERTION"
],
"copyrightText": ""
},
{
@@ -113,6 +118,9 @@
}
],
"licenseConcluded": "NOASSERTION",
"licenseInfoInFiles": [
"NOASSERTION"
],
"copyrightText": ""
},
{
@@ -128,6 +136,9 @@
}
],
"licenseConcluded": "NOASSERTION",
"licenseInfoInFiles": [
"NOASSERTION"
],
"copyrightText": ""
},
{
@@ -143,6 +154,9 @@
}
],
"licenseConcluded": "NOASSERTION",
"licenseInfoInFiles": [
"NOASSERTION"
],
"copyrightText": ""
},
{
@@ -158,6 +172,9 @@
}
],
"licenseConcluded": "NOASSERTION",
"licenseInfoInFiles": [
"NOASSERTION"
],
"copyrightText": ""
},
{
@@ -173,6 +190,9 @@
}
],
"licenseConcluded": "NOASSERTION",
"licenseInfoInFiles": [
"NOASSERTION"
],
"copyrightText": ""
}
],
@@ -16,6 +16,8 @@ PackageSupplier: NOASSERTION
PackageDownloadLocation: NOASSERTION
PrimaryPackagePurpose: FILE
FilesAnalyzed: false
PackageLicenseConcluded: NOASSERTION
PackageLicenseDeclared: NOASSERTION
##### Package: @at-sign
@@ -15,36 +15,42 @@ SPDXID: SPDXRef-File-a1-f6-9c2f7510199b17f6
FileType: OTHER
FileChecksum: SHA1: 0000000000000000000000000000000000000000
LicenseConcluded: NOASSERTION
LicenseInfoInFile: NOASSERTION
FileName: /d1/f3
SPDXID: SPDXRef-File-d1-f3-c6f5b29dca12661f
FileType: OTHER
FileChecksum: SHA1: 0000000000000000000000000000000000000000
LicenseConcluded: NOASSERTION
LicenseInfoInFile: NOASSERTION
FileName: /d2/f4
SPDXID: SPDXRef-File-d2-f4-c641caa71518099f
FileType: OTHER
FileChecksum: SHA1: 0000000000000000000000000000000000000000
LicenseConcluded: NOASSERTION
LicenseInfoInFile: NOASSERTION
FileName: /f1
SPDXID: SPDXRef-File-f1-5265a4dde3edbf7c
FileType: OTHER
FileChecksum: SHA1: 0000000000000000000000000000000000000000
LicenseConcluded: NOASSERTION
LicenseInfoInFile: NOASSERTION
FileName: /f2
SPDXID: SPDXRef-File-f2-f9e49132a4b96ccd
FileType: OTHER
FileChecksum: SHA1: 0000000000000000000000000000000000000000
LicenseConcluded: NOASSERTION
LicenseInfoInFile: NOASSERTION
FileName: /z1/f5
SPDXID: SPDXRef-File-z1-f5-839d99ee67d9d174
FileType: OTHER
FileChecksum: SHA1: 0000000000000000000000000000000000000000
LicenseConcluded: NOASSERTION
LicenseInfoInFile: NOASSERTION
##### Package: user-image-input
@@ -56,6 +62,8 @@ PackageDownloadLocation: NOASSERTION
PrimaryPackagePurpose: CONTAINER
FilesAnalyzed: false
PackageChecksum: SHA256: 2731251dc34951c0e50fcc643b4c5f74922dad1a5d98f302b504cf46cd5d9368
PackageLicenseConcluded: NOASSERTION
PackageLicenseDeclared: NOASSERTION
ExternalRef: PACKAGE-MANAGER purl pkg:oci/user-image-input@sha256:2731251dc34951c0e50fcc643b4c5f74922dad1a5d98f302b504cf46cd5d9368?arch=
##### Package: package-2
@@ -16,6 +16,8 @@ PackageSupplier: NOASSERTION
PackageDownloadLocation: NOASSERTION
PrimaryPackagePurpose: FILE
FilesAnalyzed: false
PackageLicenseConcluded: NOASSERTION
PackageLicenseDeclared: NOASSERTION
##### Package: package-2
@@ -18,6 +18,8 @@ PackageDownloadLocation: NOASSERTION
PrimaryPackagePurpose: CONTAINER
FilesAnalyzed: false
PackageChecksum: SHA256: 2731251dc34951c0e50fcc643b4c5f74922dad1a5d98f302b504cf46cd5d9368
PackageLicenseConcluded: NOASSERTION
PackageLicenseDeclared: NOASSERTION
ExternalRef: PACKAGE-MANAGER purl pkg:oci/user-image-input@sha256:2731251dc34951c0e50fcc643b4c5f74922dad1a5d98f302b504cf46cd5d9368?arch=
##### Package: package-2
+8 -40
View File
@@ -5,6 +5,7 @@ import (
"errors"
"fmt"
"os"
"strings"
"github.com/anchore/syft/syft/source"
)
@@ -21,21 +22,16 @@ func GetSource(ctx context.Context, userInput string, cfg *GetSourceConfig) (sou
}
var errs []error
var fileNotfound error
var fileNotFoundProviders []string
// call each source provider until we find a valid source
for _, p := range providers {
src, err := p.Provide(ctx)
if err != nil {
err = eachError(err, func(err error) error {
if errors.Is(err, os.ErrNotExist) {
fileNotfound = err
return nil
}
return err
})
if err != nil {
errs = append(errs, err)
if errors.Is(err, os.ErrNotExist) {
fileNotFoundProviders = append(fileNotFoundProviders, p.Name())
} else {
errs = append(errs, fmt.Errorf("%s: %w", p.Name(), err))
}
}
if src != nil {
@@ -52,8 +48,8 @@ func GetSource(ctx context.Context, userInput string, cfg *GetSourceConfig) (sou
}
}
if fileNotfound != nil {
errs = append([]error{fileNotfound}, errs...)
if len(fileNotFoundProviders) > 0 {
errs = append(errs, fmt.Errorf("additionally, the following providers failed with %w: %s", os.ErrNotExist, strings.Join(fileNotFoundProviders, ", ")))
}
return nil, sourceError(userInput, errs...)
}
@@ -71,31 +67,3 @@ func sourceError(userInput string, errs ...error) error {
}
return fmt.Errorf("errors occurred attempting to resolve '%s':%s", userInput, errorTexts)
}
func eachError(err error, fn func(error) error) error {
out := fn(err)
// unwrap singly wrapped errors
if e, ok := err.(interface {
Unwrap() error
}); ok {
wrapped := e.Unwrap()
got := eachError(wrapped, fn)
// return the outer error if received the same wrapped error
if errors.Is(got, wrapped) {
return err
}
return got
}
// unwrap errors from errors.Join
if errs, ok := err.(interface {
Unwrap() []error
}); ok {
for _, e := range errs.Unwrap() {
e = eachError(e, fn)
if e != nil {
out = errors.Join(out, e)
}
}
}
return out
}
@@ -8,6 +8,7 @@ import (
"io/fs"
"os"
"path"
"path/filepath"
"slices"
"sort"
"strings"
@@ -61,11 +62,11 @@ func NewFromUnindexedDirectoryFS(fs afero.Fs, dir string, base string) file.Writ
}
wd, err := os.Getwd()
if err == nil {
if !path.IsAbs(dir) {
dir = path.Clean(path.Join(wd, dir))
if !filepath.IsAbs(dir) {
dir = filepath.Clean(filepath.Join(wd, dir))
}
if base != "" && !path.IsAbs(base) {
base = path.Clean(path.Join(wd, base))
if base != "" && !filepath.IsAbs(base) {
base = filepath.Clean(filepath.Join(wd, base))
}
}
return UnindexedDirectory{
@@ -35,6 +35,7 @@ func AllTypes() []any {
pkg.NpmPackageLockEntry{},
pkg.PhpComposerInstalledEntry{},
pkg.PhpComposerLockEntry{},
pkg.PhpPeclEntry{},
pkg.PortageEntry{},
pkg.PythonPackage{},
pkg.PythonPipfileLockEntry{},
+1
View File
@@ -91,6 +91,7 @@ var jsonTypes = makeJSONTypes(
jsonNames(pkg.YarnLockEntry{}, "javascript-yarn-lock-entry", "YarnLockJsonMetadata"),
jsonNames(pkg.PhpComposerLockEntry{}, "php-composer-lock-entry", "PhpComposerJsonMetadata"),
jsonNamesWithoutLookup(pkg.PhpComposerInstalledEntry{}, "php-composer-installed-entry", "PhpComposerJsonMetadata"), // the legacy value is split into two types, where the other is preferred
jsonNames(pkg.PhpPeclEntry{}, "php-pecl-entry", "PhpPeclMetadata"),
jsonNames(pkg.PortageEntry{}, "portage-db-entry", "PortageMetadata"),
jsonNames(pkg.PythonPackage{}, "python-package", "PythonPackageMetadata"),
jsonNames(pkg.PythonPipfileLockEntry{}, "python-pipfile-lock-entry", "PythonPipfileLockMetadata"),
@@ -200,6 +200,11 @@ func TestReflectTypeFromJSONName_LegacyValues(t *testing.T) {
input: "PythonRequirementsMetadata",
expected: reflect.TypeOf(pkg.PythonRequirementsEntry{}),
},
{
name: "map pkg.PhpPeclEntry struct type",
input: "PhpPeclMetadata",
expected: reflect.TypeOf(pkg.PhpPeclEntry{}),
},
{
name: "map pkg.ErlangRebarLockEntry struct type",
input: "RebarLockMetadataType",
@@ -414,6 +419,12 @@ func Test_JSONName_JSONLegacyName(t *testing.T) {
expectedJSONName: "php-composer-installed-entry",
expectedLegacyName: "PhpComposerJsonMetadata", // note: maps to multiple entries (v11-12 breaking change)
},
{
name: "PhpPeclMetadata",
metadata: pkg.PhpPeclEntry{},
expectedJSONName: "php-pecl-entry",
expectedLegacyName: "PhpPeclMetadata",
},
{
name: "PortageMetadata",
metadata: pkg.PortageEntry{},
+12
View File
@@ -7,6 +7,7 @@ import (
macho "github.com/anchore/go-macholibre"
"github.com/anchore/syft/internal/log"
"github.com/anchore/syft/syft/file"
)
// UnionReader is a single interface with all reading functions needed by multi-arch binary catalogers
@@ -44,6 +45,17 @@ func GetUnionReader(readerCloser io.ReadCloser) (UnionReader, error) {
return reader, nil
}
// file.LocationReadCloser embeds a ReadCloser, which is likely
// to implement UnionReader. Check whether the embedded read closer
// implements UnionReader, and just return that if so.
r, ok := readerCloser.(file.LocationReadCloser)
if ok {
ur, ok := r.ReadCloser.(UnionReader)
if ok {
return ur, nil
}
}
b, err := io.ReadAll(readerCloser)
if err != nil {
return nil, fmt.Errorf("unable to read contents from binary: %w", err)
@@ -7,6 +7,8 @@ import (
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
"github.com/anchore/syft/syft/file"
)
func Test_getUnionReader_notUnionReader(t *testing.T) {
@@ -28,3 +30,34 @@ func Test_getUnionReader_notUnionReader(t *testing.T) {
assert.Equal(t, expectedContents, string(b))
}
type panickingUnionReader struct{}
func (p2 *panickingUnionReader) ReadAt(p []byte, off int64) (n int, err error) {
panic("don't call this in your unit test!")
}
func (p2 *panickingUnionReader) Seek(offset int64, whence int) (int64, error) {
panic("don't call this in your unit test!")
}
func (p2 *panickingUnionReader) Read(p []byte) (n int, err error) {
panic("don't call this in your unit test!")
}
func (p2 *panickingUnionReader) Close() error {
panic("don't call this in your unit test!")
}
var _ UnionReader = (*panickingUnionReader)(nil)
func Test_getUnionReader_fileLocationReadCloser(t *testing.T) {
// panickingUnionReader is a UnionReader
p := &panickingUnionReader{}
embedsUnionReader := file.NewLocationReadCloser(file.Location{}, p)
// embedded union reader is returned without "ReadAll" invocation
ur, err := GetUnionReader(embedsUnionReader)
require.NoError(t, err)
require.Equal(t, p, ur)
}
+25 -19
View File
@@ -9,6 +9,7 @@ import (
"github.com/acobaugh/osrelease"
"github.com/google/go-cmp/cmp"
"github.com/anchore/go-logger"
"github.com/anchore/syft/internal"
"github.com/anchore/syft/internal/log"
"github.com/anchore/syft/syft/file"
@@ -64,25 +65,7 @@ func IdentifyRelease(resolver file.Resolver) *Release {
}
for _, location := range locations {
contentReader, err := resolver.FileContentsByLocation(location)
if err != nil {
logger.WithFields("error", err, "path", location.RealPath).Trace("unable to get contents")
continue
}
content, err := io.ReadAll(contentReader)
internal.CloseAndLogError(contentReader, location.AccessPath)
if err != nil {
logger.WithFields("error", err, "path", location.RealPath).Trace("unable to read contents")
continue
}
release, err := entry.fn(string(content))
if err != nil {
logger.WithFields("error", err, "path", location.RealPath).Trace("unable to parse contents")
continue
}
release := tryParseReleaseInfo(resolver, location, logger, entry)
if release != nil {
return release
}
@@ -92,6 +75,29 @@ func IdentifyRelease(resolver file.Resolver) *Release {
return nil
}
func tryParseReleaseInfo(resolver file.Resolver, location file.Location, logger logger.Logger, entry parseEntry) *Release {
contentReader, err := resolver.FileContentsByLocation(location)
if err != nil {
logger.WithFields("error", err, "path", location.RealPath).Trace("unable to get contents")
return nil
}
defer internal.CloseAndLogError(contentReader, location.AccessPath)
content, err := io.ReadAll(contentReader)
if err != nil {
logger.WithFields("error", err, "path", location.RealPath).Trace("unable to read contents")
return nil
}
release, err := entry.fn(string(content))
if err != nil {
logger.WithFields("error", err, "path", location.RealPath).Trace("unable to parse contents")
return nil
}
return release
}
func parseOsRelease(contents string) (*Release, error) {
values, err := osrelease.ReadString(contents)
if err != nil {
+2
View File
@@ -27,6 +27,8 @@ type AlpmDBEntry struct {
Reason int `mapstructure:"reason" json:"reason"`
Files []AlpmFileRecord `mapstructure:"files" json:"files"`
Backup []AlpmFileRecord `mapstructure:"backup" json:"backup"`
Provides []string `mapstructure:"provides" json:"provides,omitempty"`
Depends []string `mapstructure:"depends" json:"depends,omitempty"`
}
type AlpmFileRecord struct {
+1 -1
View File
@@ -80,7 +80,7 @@ func Test_PackageURL(t *testing.T) {
ID: "alpine",
VersionID: "3.4.6",
},
expected: "pkg:apk/alpine/g++@v84?arch=am86&distro=alpine-3.4.6",
expected: "pkg:apk/alpine/g%2B%2B@v84?arch=am86&distro=alpine-3.4.6",
},
{
metadata: parsedData{
@@ -156,6 +156,7 @@ func findReleases(resolver file.Resolver, dbPath string) []linux.Release {
log.Tracef("unable to fetch contents for APK repositories file %q: %+v", reposLocation, err)
return nil
}
defer internal.CloseAndLogError(reposReader, location.RealPath)
return parseReleasesFromAPKRepository(file.LocationReadCloser{
Location: location,
+86 -2
View File
@@ -4,12 +4,96 @@ Package arch provides a concrete Cataloger implementations for packages relating
package arch
import (
"context"
"strings"
"github.com/anchore/syft/internal/log"
"github.com/anchore/syft/syft/artifact"
"github.com/anchore/syft/syft/file"
"github.com/anchore/syft/syft/pkg"
"github.com/anchore/syft/syft/pkg/cataloger/generic"
)
type cataloger struct {
*generic.Cataloger
}
// NewDBCataloger returns a new cataloger object initialized for arch linux pacman database flat-file stores.
func NewDBCataloger() pkg.Cataloger {
return generic.NewCataloger("alpm-db-cataloger").
WithParserByGlobs(parseAlpmDB, pkg.AlpmDBGlob)
return cataloger{
Cataloger: generic.NewCataloger("alpm-db-cataloger").
WithParserByGlobs(parseAlpmDB, pkg.AlpmDBGlob),
}
}
func (c cataloger) Catalog(ctx context.Context, resolver file.Resolver) ([]pkg.Package, []artifact.Relationship, error) {
pkgs, rels, err := c.Cataloger.Catalog(ctx, resolver)
if err != nil {
return nil, nil, err
}
rels = append(rels, associateRelationships(pkgs)...)
return pkgs, rels, nil
}
// associateRelationships will create relationships between packages based on the "Depends" and "Provides"
// fields for installed packages. If there is an installed package that has a dependency that is (somehow) not installed,
// then that relationship (between the installed and uninstalled package) will NOT be created.
func associateRelationships(pkgs []pkg.Package) (relationships []artifact.Relationship) {
// map["provides" + "package"] -> packages that provide that package
lookup := make(map[string][]pkg.Package)
// read providers and add lookup keys as needed
for _, p := range pkgs {
meta, ok := p.Metadata.(pkg.AlpmDBEntry)
if !ok {
log.Warnf("cataloger failed to extract alpm 'provides' metadata for package %+v", p.Name)
continue
}
// allow for lookup by package name
lookup[p.Name] = append(lookup[p.Name], p)
for _, provides := range meta.Provides {
// allow for lookup by exact specification
lookup[provides] = append(lookup[provides], p)
// allow for lookup by library name only
k := stripVersionSpecifier(provides)
lookup[k] = append(lookup[k], p)
}
}
// read "Depends" and match with provider keys
for _, p := range pkgs {
meta, ok := p.Metadata.(pkg.AlpmDBEntry)
if !ok {
log.Warnf("cataloger failed to extract alpm 'dependency' metadata for package %+v", p.Name)
continue
}
for _, dep := range meta.Depends {
for _, depPkg := range lookup[dep] {
relationships = append(relationships, artifact.Relationship{
From: depPkg,
To: p,
Type: artifact.DependencyOfRelationship,
})
}
}
}
return relationships
}
func stripVersionSpecifier(s string) string {
// examples:
// gcc-libs --> gcc-libs
// libtree-sitter.so=0-64 --> libtree-sitter.so
items := strings.Split(s, "=")
if len(items) == 0 {
return s
}
return strings.TrimSpace(items[0])
}
+278 -158
View File
@@ -12,169 +12,289 @@ import (
)
func TestAlpmCataloger(t *testing.T) {
dbLocation := file.NewLocation("var/lib/pacman/local/gmp-6.2.1-2/desc")
expectedPkgs := []pkg.Package{
{
Name: "gmp",
Version: "6.2.1-2",
Type: pkg.AlpmPkg,
FoundBy: "alpm-db-cataloger",
Licenses: pkg.NewLicenseSet(
pkg.NewLicenseFromLocations("LGPL3", dbLocation),
pkg.NewLicenseFromLocations("GPL", dbLocation),
),
Locations: file.NewLocationSet(dbLocation),
CPEs: nil,
PURL: "",
Metadata: pkg.AlpmDBEntry{
BasePackage: "gmp",
Package: "gmp",
Version: "6.2.1-2",
Description: "A free library for arbitrary precision arithmetic",
Architecture: "x86_64",
Size: 1044438,
Packager: "Antonio Rojas <arojas@archlinux.org>",
URL: "https://gmplib.org/",
Validation: "pgp",
Reason: 1,
Files: []pkg.AlpmFileRecord{
{
Path: "/usr",
Type: "dir",
Digests: []file.Digest{},
},
{
Path: "/usr/include",
Type: "dir",
Digests: []file.Digest{},
},
{
Path: "/usr/include/gmp.h",
Size: "84140",
Digests: []file.Digest{
{Algorithm: "md5", Value: "76595f70565c72550eb520809bf86856"},
{Algorithm: "sha256", Value: "91a614b9202453153fe3b7512d15e89659108b93ce8841c8e13789eb85da9e3a"},
},
},
{
Path: "/usr/include/gmpxx.h",
Size: "129113",
Digests: []file.Digest{
{Algorithm: "md5", Value: "ea3d21de4bcf7c696799c5c55dd3655b"},
{Algorithm: "sha256", Value: "0011ae411a0bc1030e07d968b32fdc1343f5ac2a17b7d28f493e7976dde2ac82"},
},
},
{
Path: "/usr/lib",
Type: "dir",
Digests: []file.Digest{},
},
{
Path: "/usr/lib/libgmp.so",
Type: "link",
Link: "libgmp.so.10.4.1",
Digests: []file.Digest{},
},
{
Path: "/usr/lib/libgmp.so.10",
Type: "link",
Link: "libgmp.so.10.4.1",
Digests: []file.Digest{},
},
{
Path: "/usr/lib/libgmp.so.10.4.1",
Size: "663224",
Digests: []file.Digest{
{Algorithm: "md5", Value: "d6d03eadacdd9048d5b2adf577e9d722"},
{Algorithm: "sha256", Value: "39898bd3d8d6785222432fa8b8aef7ce3b7e5bbfc66a52b7c0da09bed4adbe6a"},
},
},
{
Path: "/usr/lib/libgmpxx.so",
Type: "link",
Link: "libgmpxx.so.4.6.1",
Digests: []file.Digest{},
},
{
Path: "/usr/lib/libgmpxx.so.4",
Type: "link",
Link: "libgmpxx.so.4.6.1",
Digests: []file.Digest{},
},
{
Path: "/usr/lib/libgmpxx.so.4.6.1",
Size: "30680",
Digests: []file.Digest{
{Algorithm: "md5", Value: "dd5f0c4d635fa599fa7f4339c0e8814d"},
{Algorithm: "sha256", Value: "0ef67cbde4841f58d2e4b41f59425eb87c9eeaf4e649c060b326342c53bedbec"},
},
},
{
Path: "/usr/lib/pkgconfig",
Type: "dir",
Digests: []file.Digest{},
},
{
Path: "/usr/lib/pkgconfig/gmp.pc",
Size: "245",
Digests: []file.Digest{
{Algorithm: "md5", Value: "a91a9f1b66218cb77b9cd2cdf341756d"},
{Algorithm: "sha256", Value: "4e9de547a48c4e443781e9fa702a1ec5a23ee28b4bc520306cff2541a855be37"},
},
},
{
Path: "/usr/lib/pkgconfig/gmpxx.pc",
Size: "280",
Digests: []file.Digest{
{Algorithm: "md5", Value: "8c0f54e987934352177a6a30a811b001"},
{Algorithm: "sha256", Value: "fc5dbfbe75977057ba50953d94b9daecf696c9fdfe5b94692b832b44ecca871b"},
},
},
{
Path: "/usr/share",
Type: "dir",
Digests: []file.Digest{},
},
{
Path: "/usr/share/info",
Type: "dir",
Digests: []file.Digest{},
},
{
Path: "/usr/share/info/gmp.info-1.gz",
Size: "85892",
Digests: []file.Digest{
{Algorithm: "md5", Value: "63304d4d2f0247fb8a999fae66a81c19"},
{Algorithm: "sha256", Value: "86288c1531a2789db5da8b9838b5cde4db07bda230ae11eba23a1f33698bd14e"},
},
},
{
Path: "/usr/share/info/gmp.info-2.gz",
Size: "48484",
Digests: []file.Digest{
{Algorithm: "md5", Value: "4bb0dadec416d305232cac6eae712ff7"},
{Algorithm: "sha256", Value: "b7443c1b529588d98a074266087f79b595657ac7274191c34b10a9ceedfa950e"},
},
},
{
Path: "/usr/share/info/gmp.info.gz",
Size: "2380",
Digests: []file.Digest{
{Algorithm: "md5", Value: "cf6880fb0d862ee1da0d13c3831b5720"},
{Algorithm: "sha256", Value: "a13c8eecda3f3e5ad1e09773e47a9686f07d9d494eaddf326f3696bbef1548fd"},
},
},
},
Backup: []pkg.AlpmFileRecord{},
},
gmpDbLocation := file.NewLocation("var/lib/pacman/local/gmp-6.2.1-2/desc")
treeSitterDbLocation := file.NewLocation("var/lib/pacman/local/tree-sitter-0.22.6-1/desc")
emacsDbLocation := file.NewLocation("var/lib/pacman/local/emacs-29.3-3/desc")
fuzzyDbLocation := file.NewLocation("var/lib/pacman/local/fuzzy-1.2-3/desc")
madeupDbLocation := file.NewLocation("var/lib/pacman/local/madeup-20.30-4/desc")
treeSitterPkg := pkg.Package{
Name: "tree-sitter",
Version: "0.22.6-1",
Type: pkg.AlpmPkg,
FoundBy: "alpm-db-cataloger",
Licenses: pkg.NewLicenseSet(
pkg.NewLicenseFromLocations("MIT", treeSitterDbLocation),
),
Locations: file.NewLocationSet(treeSitterDbLocation),
Metadata: pkg.AlpmDBEntry{
BasePackage: "tree-sitter",
Package: "tree-sitter",
Version: "0.22.6-1",
Description: "Incremental parsing library",
Architecture: "x86_64",
Size: 223539,
Packager: "Daniel M. Capella <polyzen@archlinux.org>",
URL: "https://github.com/tree-sitter/tree-sitter",
Validation: "pgp",
Reason: 1,
Files: []pkg.AlpmFileRecord{},
Backup: []pkg.AlpmFileRecord{},
Provides: []string{"libtree-sitter.so=0-64"},
},
}
// TODO: relationships are not under test yet
var expectedRelationships []artifact.Relationship
emacsPkg := pkg.Package{
Name: "emacs",
Version: "29.3-3",
Type: pkg.AlpmPkg,
FoundBy: "alpm-db-cataloger",
Licenses: pkg.NewLicenseSet(
pkg.NewLicenseFromLocations("GPL3", emacsDbLocation),
),
Locations: file.NewLocationSet(emacsDbLocation),
Metadata: pkg.AlpmDBEntry{
BasePackage: "emacs",
Package: "emacs",
Version: "29.3-3",
Description: "The extensible, customizable, self-documenting real-time display editor",
Architecture: "x86_64",
Size: 126427862,
Packager: "Frederik Schwan <freswa@archlinux.org>",
URL: "https://www.gnu.org/software/emacs/emacs.html",
Validation: "pgp",
Files: []pkg.AlpmFileRecord{},
Backup: []pkg.AlpmFileRecord{},
Depends: []string{"libtree-sitter.so=0-64"},
},
}
fuzzyPkg := pkg.Package{
Name: "fuzzy",
Version: "1.2-3",
Type: pkg.AlpmPkg,
FoundBy: "alpm-db-cataloger",
Locations: file.NewLocationSet(
fuzzyDbLocation,
file.NewLocation("var/lib/pacman/local/fuzzy-1.2-3/files"),
),
Metadata: pkg.AlpmDBEntry{
Package: "fuzzy",
Version: "1.2-3",
Files: []pkg.AlpmFileRecord{},
Backup: []pkg.AlpmFileRecord{
{
Path: "/etc/fuzzy.conf",
Digests: []file.Digest{
{Algorithm: "md5", Value: "79fce043df7dfc676ae5ecb903762d8b"},
},
},
},
Depends: []string{"tree-sitter"},
},
}
madeupPkg := pkg.Package{
Name: "madeup",
Version: "20.30-4",
Type: pkg.AlpmPkg,
FoundBy: "alpm-db-cataloger",
Locations: file.NewLocationSet(madeupDbLocation),
Metadata: pkg.AlpmDBEntry{
Package: "madeup",
Version: "20.30-4",
Files: []pkg.AlpmFileRecord{},
Backup: []pkg.AlpmFileRecord{},
Depends: []string{"libtree-sitter.so"},
},
}
gmpPkg := pkg.Package{
Name: "gmp",
Version: "6.2.1-2",
Type: pkg.AlpmPkg,
FoundBy: "alpm-db-cataloger",
Licenses: pkg.NewLicenseSet(
pkg.NewLicenseFromLocations("LGPL3", gmpDbLocation),
pkg.NewLicenseFromLocations("GPL", gmpDbLocation),
),
Locations: file.NewLocationSet(
gmpDbLocation,
file.NewLocation("var/lib/pacman/local/gmp-6.2.1-2/files"),
file.NewLocation("var/lib/pacman/local/gmp-6.2.1-2/mtree"),
),
Metadata: pkg.AlpmDBEntry{
BasePackage: "gmp",
Package: "gmp",
Version: "6.2.1-2",
Description: "A free library for arbitrary precision arithmetic",
Architecture: "x86_64",
Size: 1044438,
Packager: "Antonio Rojas <arojas@archlinux.org>",
URL: "https://gmplib.org/",
Validation: "pgp",
Reason: 1,
Depends: []string{"gcc-libs", "sh", "libtree-sitter.so=1-64"},
Files: []pkg.AlpmFileRecord{
{
Path: "/usr",
Type: "dir",
Digests: []file.Digest{},
},
{
Path: "/usr/include",
Type: "dir",
Digests: []file.Digest{},
},
{
Path: "/usr/include/gmp.h",
Size: "84140",
Digests: []file.Digest{
{Algorithm: "md5", Value: "76595f70565c72550eb520809bf86856"},
{Algorithm: "sha256", Value: "91a614b9202453153fe3b7512d15e89659108b93ce8841c8e13789eb85da9e3a"},
},
},
{
Path: "/usr/include/gmpxx.h",
Size: "129113",
Digests: []file.Digest{
{Algorithm: "md5", Value: "ea3d21de4bcf7c696799c5c55dd3655b"},
{Algorithm: "sha256", Value: "0011ae411a0bc1030e07d968b32fdc1343f5ac2a17b7d28f493e7976dde2ac82"},
},
},
{
Path: "/usr/lib",
Type: "dir",
Digests: []file.Digest{},
},
{
Path: "/usr/lib/libgmp.so",
Type: "link",
Link: "libgmp.so.10.4.1",
Digests: []file.Digest{},
},
{
Path: "/usr/lib/libgmp.so.10",
Type: "link",
Link: "libgmp.so.10.4.1",
Digests: []file.Digest{},
},
{
Path: "/usr/lib/libgmp.so.10.4.1",
Size: "663224",
Digests: []file.Digest{
{Algorithm: "md5", Value: "d6d03eadacdd9048d5b2adf577e9d722"},
{Algorithm: "sha256", Value: "39898bd3d8d6785222432fa8b8aef7ce3b7e5bbfc66a52b7c0da09bed4adbe6a"},
},
},
{
Path: "/usr/lib/libgmpxx.so",
Type: "link",
Link: "libgmpxx.so.4.6.1",
Digests: []file.Digest{},
},
{
Path: "/usr/lib/libgmpxx.so.4",
Type: "link",
Link: "libgmpxx.so.4.6.1",
Digests: []file.Digest{},
},
{
Path: "/usr/lib/libgmpxx.so.4.6.1",
Size: "30680",
Digests: []file.Digest{
{Algorithm: "md5", Value: "dd5f0c4d635fa599fa7f4339c0e8814d"},
{Algorithm: "sha256", Value: "0ef67cbde4841f58d2e4b41f59425eb87c9eeaf4e649c060b326342c53bedbec"},
},
},
{
Path: "/usr/lib/pkgconfig",
Type: "dir",
Digests: []file.Digest{},
},
{
Path: "/usr/lib/pkgconfig/gmp.pc",
Size: "245",
Digests: []file.Digest{
{Algorithm: "md5", Value: "a91a9f1b66218cb77b9cd2cdf341756d"},
{Algorithm: "sha256", Value: "4e9de547a48c4e443781e9fa702a1ec5a23ee28b4bc520306cff2541a855be37"},
},
},
{
Path: "/usr/lib/pkgconfig/gmpxx.pc",
Size: "280",
Digests: []file.Digest{
{Algorithm: "md5", Value: "8c0f54e987934352177a6a30a811b001"},
{Algorithm: "sha256", Value: "fc5dbfbe75977057ba50953d94b9daecf696c9fdfe5b94692b832b44ecca871b"},
},
},
{
Path: "/usr/share",
Type: "dir",
Digests: []file.Digest{},
},
{
Path: "/usr/share/info",
Type: "dir",
Digests: []file.Digest{},
},
{
Path: "/usr/share/info/gmp.info-1.gz",
Size: "85892",
Digests: []file.Digest{
{Algorithm: "md5", Value: "63304d4d2f0247fb8a999fae66a81c19"},
{Algorithm: "sha256", Value: "86288c1531a2789db5da8b9838b5cde4db07bda230ae11eba23a1f33698bd14e"},
},
},
{
Path: "/usr/share/info/gmp.info-2.gz",
Size: "48484",
Digests: []file.Digest{
{Algorithm: "md5", Value: "4bb0dadec416d305232cac6eae712ff7"},
{Algorithm: "sha256", Value: "b7443c1b529588d98a074266087f79b595657ac7274191c34b10a9ceedfa950e"},
},
},
{
Path: "/usr/share/info/gmp.info.gz",
Size: "2380",
Digests: []file.Digest{
{Algorithm: "md5", Value: "cf6880fb0d862ee1da0d13c3831b5720"},
{Algorithm: "sha256", Value: "a13c8eecda3f3e5ad1e09773e47a9686f07d9d494eaddf326f3696bbef1548fd"},
},
},
},
Backup: []pkg.AlpmFileRecord{},
},
}
expectedPkgs := []pkg.Package{
treeSitterPkg,
emacsPkg,
fuzzyPkg,
madeupPkg,
gmpPkg,
}
expectedRelationships := []artifact.Relationship{
{ // exact spec lookup
From: treeSitterPkg,
To: emacsPkg,
Type: artifact.DependencyOfRelationship,
},
{ // package name lookup
From: treeSitterPkg,
To: fuzzyPkg,
Type: artifact.DependencyOfRelationship,
},
{ // library name lookup
From: treeSitterPkg,
To: madeupPkg,
Type: artifact.DependencyOfRelationship,
},
}
pkgtest.NewCatalogTester().
FromDirectory(t, "test-fixtures/gmp-fixture").
FromDirectory(t, "test-fixtures/installed").
WithCompareOptions(cmpopts.IgnoreFields(pkg.AlpmFileRecord{}, "Time")).
Expects(expectedPkgs, expectedRelationships).
TestCataloger(t, NewDBCataloger())
+5 -2
View File
@@ -9,13 +9,16 @@ import (
"github.com/anchore/syft/syft/pkg"
)
func newPackage(m *parsedData, release *linux.Release, dbLocation file.Location) pkg.Package {
func newPackage(m *parsedData, release *linux.Release, dbLocation file.Location, otherLocations ...file.Location) pkg.Package {
licenseCandidates := strings.Split(m.Licenses, "\n")
locs := file.NewLocationSet(dbLocation)
locs.Add(otherLocations...)
p := pkg.Package{
Name: m.Package,
Version: m.Version,
Locations: file.NewLocationSet(dbLocation),
Locations: locs,
Licenses: pkg.NewLicenseSet(pkg.NewLicensesFromLocation(dbLocation.WithoutAnnotations(), licenseCandidates...)...),
Type: pkg.AlpmPkg,
PURL: packageURL(m, release),
+103 -32
View File
@@ -6,6 +6,7 @@ import (
"context"
"fmt"
"io"
"path"
"path/filepath"
"strconv"
"strings"
@@ -14,6 +15,8 @@ import (
"github.com/mitchellh/mapstructure"
"github.com/vbatts/go-mtree"
"github.com/anchore/syft/internal"
"github.com/anchore/syft/internal/log"
"github.com/anchore/syft/syft/artifact"
"github.com/anchore/syft/syft/file"
"github.com/anchore/syft/syft/pkg"
@@ -43,33 +46,26 @@ func parseAlpmDB(_ context.Context, resolver file.Resolver, env *generic.Environ
return nil, nil, err
}
base := filepath.Dir(reader.RealPath)
r, err := getFileReader(filepath.Join(base, "mtree"), resolver)
if err != nil {
return nil, nil, err
if data == nil {
return nil, nil, nil
}
pkgFiles, err := parseMtree(r)
if err != nil {
return nil, nil, err
}
base := path.Dir(reader.RealPath)
// replace the files found the pacman database with the files from the mtree These contain more metadata and
// thus more useful.
// TODO: probably want to use MTREE and PKGINFO here
data.Files = pkgFiles
files, fileLoc := fetchPkgFiles(base, resolver)
backups, backupLoc := fetchBackupFiles(base, resolver)
// We only really do this to get any backup database entries from the files database
files := filepath.Join(base, "files")
_, err = getFileReader(files, resolver)
if err != nil {
return nil, nil, err
var locs []file.Location
if fileLoc != nil {
locs = append(locs, fileLoc.WithAnnotation(pkg.EvidenceAnnotationKey, pkg.SupportingEvidenceAnnotation))
data.Files = files
}
filesMetadata, err := parseAlpmDBEntry(reader)
if err != nil {
return nil, nil, err
} else if filesMetadata != nil {
data.Backup = filesMetadata.Backup
if backupLoc != nil {
locs = append(locs, backupLoc.WithAnnotation(pkg.EvidenceAnnotationKey, pkg.SupportingEvidenceAnnotation))
data.Backup = backups
}
if data.Package == "" {
@@ -81,10 +77,67 @@ func parseAlpmDB(_ context.Context, resolver file.Resolver, env *generic.Environ
data,
env.LinuxRelease,
reader.Location.WithAnnotation(pkg.EvidenceAnnotationKey, pkg.PrimaryEvidenceAnnotation),
locs...,
),
}, nil, nil
}
func fetchPkgFiles(base string, resolver file.Resolver) ([]pkg.AlpmFileRecord, *file.Location) {
// TODO: probably want to use MTREE and PKGINFO here
target := path.Join(base, "mtree")
loc, err := getLocation(target, resolver)
if err != nil {
log.WithFields("error", err, "path", target).Trace("failed to find mtree file")
return []pkg.AlpmFileRecord{}, nil
}
if loc == nil {
return []pkg.AlpmFileRecord{}, nil
}
reader, err := resolver.FileContentsByLocation(*loc)
if err != nil {
return []pkg.AlpmFileRecord{}, nil
}
defer internal.CloseAndLogError(reader, loc.RealPath)
pkgFiles, err := parseMtree(reader)
if err != nil {
log.WithFields("error", err, "path", target).Trace("failed to parse mtree file")
return []pkg.AlpmFileRecord{}, nil
}
return pkgFiles, loc
}
func fetchBackupFiles(base string, resolver file.Resolver) ([]pkg.AlpmFileRecord, *file.Location) {
// We only really do this to get any backup database entries from the files database
target := filepath.Join(base, "files")
loc, err := getLocation(target, resolver)
if err != nil {
log.WithFields("error", err, "path", target).Trace("failed to find alpm files")
return []pkg.AlpmFileRecord{}, nil
}
if loc == nil {
return []pkg.AlpmFileRecord{}, nil
}
reader, err := resolver.FileContentsByLocation(*loc)
if err != nil {
return []pkg.AlpmFileRecord{}, nil
}
defer internal.CloseAndLogError(reader, loc.RealPath)
filesMetadata, err := parseAlpmDBEntry(reader)
if err != nil {
return []pkg.AlpmFileRecord{}, nil
}
if filesMetadata != nil {
return filesMetadata.Backup, loc
}
return []pkg.AlpmFileRecord{}, loc
}
func parseAlpmDBEntry(reader io.Reader) (*parsedData, error) {
scanner := newScanner(reader)
metadata, err := parseDatabase(scanner)
@@ -118,7 +171,7 @@ func newScanner(reader io.Reader) *bufio.Scanner {
return scanner
}
func getFileReader(path string, resolver file.Resolver) (io.Reader, error) {
func getLocation(path string, resolver file.Resolver) (*file.Location, error) {
locs, err := resolver.FilesByPath(path)
if err != nil {
return nil, err
@@ -127,12 +180,11 @@ func getFileReader(path string, resolver file.Resolver) (io.Reader, error) {
if len(locs) == 0 {
return nil, fmt.Errorf("could not find file: %s", path)
}
// TODO: Should we maybe check if we found the file
dbContentReader, err := resolver.FileContentsByLocation(locs[0])
if err != nil {
return nil, err
if len(locs) > 1 {
log.WithFields("path", path).Trace("multiple files found for path, using first path")
}
return dbContentReader, nil
return &locs[0], nil
}
func parseDatabase(b *bufio.Scanner) (*parsedData, error) {
@@ -155,9 +207,9 @@ func parseDatabase(b *bufio.Scanner) (*parsedData, error) {
case "files":
var files []map[string]string
for _, f := range strings.Split(value, "\n") {
path := fmt.Sprintf("/%s", f)
if ok := ignoredFiles[path]; !ok {
files = append(files, map[string]string{"path": path})
p := fmt.Sprintf("/%s", f)
if ok := ignoredFiles[p]; !ok {
files = append(files, map[string]string{"path": p})
}
}
pkgFields[key] = files
@@ -165,10 +217,10 @@ func parseDatabase(b *bufio.Scanner) (*parsedData, error) {
var backup []map[string]interface{}
for _, f := range strings.Split(value, "\n") {
fields := strings.SplitN(f, "\t", 2)
path := fmt.Sprintf("/%s", fields[0])
if ok := ignoredFiles[path]; !ok {
p := fmt.Sprintf("/%s", fields[0])
if ok := ignoredFiles[p]; !ok {
backup = append(backup, map[string]interface{}{
"path": path,
"path": p,
"digests": []file.Digest{{
Algorithm: "md5",
Value: fields[1],
@@ -176,6 +228,8 @@ func parseDatabase(b *bufio.Scanner) (*parsedData, error) {
}
}
pkgFields[key] = backup
case "depends", "provides":
pkgFields[key] = processLibrarySpecs(value)
case "reason":
fallthrough
case "size":
@@ -191,6 +245,19 @@ func parseDatabase(b *bufio.Scanner) (*parsedData, error) {
return parsePkgFiles(pkgFields)
}
func processLibrarySpecs(value string) []string {
lines := strings.Split(value, "\n")
librarySpecs := make([]string, 0)
for _, line := range lines {
line = strings.TrimSpace(line)
if line == "" {
continue
}
librarySpecs = append(librarySpecs, line)
}
return librarySpecs
}
func parsePkgFiles(pkgFields map[string]interface{}) (*parsedData, error) {
var entry parsedData
if err := mapstructure.Decode(pkgFields, &entry); err != nil {
@@ -201,6 +268,10 @@ func parsePkgFiles(pkgFields map[string]interface{}) (*parsedData, error) {
entry.Backup = make([]pkg.AlpmFileRecord, 0)
}
if entry.Files == nil {
entry.Files = make([]pkg.AlpmFileRecord, 0)
}
if entry.Package == "" && len(entry.Files) == 0 && len(entry.Backup) == 0 {
return nil, nil
}
+110 -67
View File
@@ -17,74 +17,120 @@ func TestDatabaseParser(t *testing.T) {
tests := []struct {
name string
fixture string
expected pkg.AlpmDBEntry
expected *parsedData
}{
{
name: "test alpm database parsing",
name: "simple desc parsing",
fixture: "test-fixtures/files",
expected: pkg.AlpmDBEntry{
Backup: []pkg.AlpmFileRecord{
{
Path: "/etc/pacman.conf",
Digests: []file.Digest{{
Algorithm: "md5",
Value: "de541390e52468165b96511c4665bff4",
}},
expected: &parsedData{
AlpmDBEntry: pkg.AlpmDBEntry{
Backup: []pkg.AlpmFileRecord{
{
Path: "/etc/pacman.conf",
Digests: []file.Digest{{
Algorithm: "md5",
Value: "de541390e52468165b96511c4665bff4",
}},
},
{
Path: "/etc/makepkg.conf",
Digests: []file.Digest{{
Algorithm: "md5",
Value: "79fce043df7dfc676ae5ecb903762d8b",
}},
},
},
{
Path: "/etc/makepkg.conf",
Digests: []file.Digest{{
Algorithm: "md5",
Value: "79fce043df7dfc676ae5ecb903762d8b",
}},
Files: []pkg.AlpmFileRecord{
{
Path: "/etc/",
},
{
Path: "/etc/makepkg.conf",
},
{
Path: "/etc/pacman.conf",
},
{
Path: "/usr/",
},
{
Path: "/usr/bin/",
},
{
Path: "/usr/bin/makepkg",
},
{
Path: "/usr/bin/makepkg-template",
},
{
Path: "/usr/bin/pacman",
},
{
Path: "/usr/bin/pacman-conf",
},
{
Path: "/var/",
},
{
Path: "/var/cache/",
},
{
Path: "/var/cache/pacman/",
},
{
Path: "/var/cache/pacman/pkg/",
},
{
Path: "/var/lib/",
},
{
Path: "/var/lib/pacman/",
},
},
},
Files: []pkg.AlpmFileRecord{
{
Path: "/etc/",
},
{
Path: "/etc/makepkg.conf",
},
{
Path: "/etc/pacman.conf",
},
{
Path: "/usr/",
},
{
Path: "/usr/bin/",
},
{
Path: "/usr/bin/makepkg",
},
{
Path: "/usr/bin/makepkg-template",
},
{
Path: "/usr/bin/pacman",
},
{
Path: "/usr/bin/pacman-conf",
},
{
Path: "/var/",
},
{
Path: "/var/cache/",
},
{
Path: "/var/cache/pacman/",
},
{
Path: "/var/cache/pacman/pkg/",
},
{
Path: "/var/lib/",
},
{
Path: "/var/lib/pacman/",
},
},
},
{
name: "with dependencies",
fixture: "test-fixtures/installed/var/lib/pacman/local/gmp-6.2.1-2/desc",
expected: &parsedData{
Licenses: "LGPL3\nGPL",
AlpmDBEntry: pkg.AlpmDBEntry{
BasePackage: "gmp",
Package: "gmp",
Version: "6.2.1-2",
Description: "A free library for arbitrary precision arithmetic",
Architecture: "x86_64",
Size: 1044438,
Packager: "Antonio Rojas <arojas@archlinux.org>",
URL: "https://gmplib.org/",
Validation: "pgp",
Reason: 1,
Files: []pkg.AlpmFileRecord{},
Backup: []pkg.AlpmFileRecord{},
Depends: []string{"gcc-libs", "sh", "libtree-sitter.so=1-64"},
},
},
},
{
name: "with provides",
fixture: "test-fixtures/installed/var/lib/pacman/local/tree-sitter-0.22.6-1/desc",
expected: &parsedData{
Licenses: "MIT",
AlpmDBEntry: pkg.AlpmDBEntry{
BasePackage: "tree-sitter",
Package: "tree-sitter",
Version: "0.22.6-1",
Description: "Incremental parsing library",
Architecture: "x86_64",
Size: 223539,
Packager: "Daniel M. Capella <polyzen@archlinux.org>",
URL: "https://github.com/tree-sitter/tree-sitter",
Validation: "pgp",
Reason: 1,
Files: []pkg.AlpmFileRecord{},
Backup: []pkg.AlpmFileRecord{},
Provides: []string{"libtree-sitter.so=0-64"},
},
},
},
@@ -101,13 +147,10 @@ func TestDatabaseParser(t *testing.T) {
entry, err := parseAlpmDBEntry(reader)
require.NoError(t, err)
if diff := cmp.Diff(entry.Files, test.expected.Files); diff != "" {
t.Errorf("Files mismatch (-want +got):\n%s", diff)
if diff := cmp.Diff(test.expected, entry); diff != "" {
t.Errorf("parsed data mismatch (-want +got):\n%s", diff)
}
if diff := cmp.Diff(entry.Backup, test.expected.Backup); diff != "" {
t.Errorf("Backup mismatch (-want +got):\n%s", diff)
}
})
}
}
@@ -0,0 +1,38 @@
%NAME%
emacs
%VERSION%
29.3-3
%BASE%
emacs
%DESC%
The extensible, customizable, self-documenting real-time display editor
%URL%
https://www.gnu.org/software/emacs/emacs.html
%ARCH%
x86_64
%BUILDDATE%
1714249917
%INSTALLDATE%
1715026363
%PACKAGER%
Frederik Schwan <freswa@archlinux.org>
%SIZE%
126427862
%LICENSE%
GPL3
%VALIDATION%
pgp
%DEPENDS%
libtree-sitter.so=0-64
@@ -0,0 +1,8 @@
%NAME%
fuzzy
%VERSION%
1.2-3
%DEPENDS%
tree-sitter
@@ -0,0 +1,6 @@
%FILES%
etc/
etc/fuzzy.conf
%BACKUP%
etc/fuzzy.conf 79fce043df7dfc676ae5ecb903762d8b
@@ -0,0 +1,8 @@
%NAME%
madeup
%VERSION%
20.30-4
%DEPENDS%
libtree-sitter.so
@@ -0,0 +1,41 @@
%NAME%
tree-sitter
%VERSION%
0.22.6-1
%BASE%
tree-sitter
%DESC%
Incremental parsing library
%URL%
https://github.com/tree-sitter/tree-sitter
%ARCH%
x86_64
%BUILDDATE%
1714945746
%INSTALLDATE%
1715026360
%PACKAGER%
Daniel M. Capella <polyzen@archlinux.org>
%SIZE%
223539
%REASON%
1
%LICENSE%
MIT
%VALIDATION%
pgp
%PROVIDES%
libtree-sitter.so=0-64
+23 -7
View File
@@ -17,7 +17,6 @@ import (
"github.com/anchore/syft/internal/log"
"github.com/anchore/syft/syft/cpe"
"github.com/anchore/syft/syft/file"
"github.com/anchore/syft/syft/internal/unionreader"
"github.com/anchore/syft/syft/pkg"
)
@@ -153,6 +152,27 @@ func FileContentsVersionMatcher(pattern string) EvidenceMatcher {
}
}
// matchExcluding tests the provided regular expressions against the file, and if matched, DOES NOT return
// anything that the matcher would otherwise return
func matchExcluding(matcher EvidenceMatcher, contentPatternsToExclude ...string) EvidenceMatcher {
var nonMatchPatterns []*regexp.Regexp
for _, p := range contentPatternsToExclude {
nonMatchPatterns = append(nonMatchPatterns, regexp.MustCompile(p))
}
return func(resolver file.Resolver, classifier Classifier, location file.Location) ([]pkg.Package, error) {
contents, err := getContents(resolver, location)
if err != nil {
return nil, fmt.Errorf("unable to get read contents for file: %w", err)
}
for _, nonMatch := range nonMatchPatterns {
if nonMatch.Match(contents) {
return nil, nil
}
}
return matcher(resolver, classifier, location)
}
}
//nolint:gocognit
func sharedLibraryLookup(sharedLibraryPattern string, sharedLibraryMatcher EvidenceMatcher) EvidenceMatcher {
pat := regexp.MustCompile(sharedLibraryPattern)
@@ -210,14 +230,10 @@ func getContents(resolver file.Resolver, location file.Location) ([]byte, error)
if err != nil {
return nil, err
}
unionReader, err := unionreader.GetUnionReader(reader)
if err != nil {
return nil, fmt.Errorf("unable to get union reader for file: %w", err)
}
defer internal.CloseAndLogError(reader, location.AccessPath)
// TODO: there may be room for improvement here, as this may use an excessive amount of memory. Alternate approach is to leverage a RuneReader.
contents, err := io.ReadAll(unionReader)
contents, err := io.ReadAll(reader)
if err != nil {
return nil, fmt.Errorf("unable to get contents for file: %w", err)
}
@@ -37,6 +37,17 @@ func Test_Cataloger_PositiveCases(t *testing.T) {
logicalFixture string
expected pkg.Package
}{
{
logicalFixture: "arangodb/3.11.8/linux-amd64",
expected: pkg.Package{
Name: "arangodb",
Version: "3.11.8",
Type: "binary",
PURL: "pkg:generic/arangodb@3.11.8",
Locations: locations("arangosh"),
Metadata: metadata("arangodb-binary"),
},
},
{
logicalFixture: "postgres/15beta4/linux-amd64",
expected: pkg.Package{
@@ -608,10 +619,10 @@ func Test_Cataloger_PositiveCases(t *testing.T) {
{
logicalFixture: "java-jre-openjdk/1.8.0_352-b08/linux-amd64",
expected: pkg.Package{
Name: "java",
Name: "java/jre",
Version: "1.8.0_352-b08",
Type: "binary",
PURL: "pkg:generic/java@1.8.0_352-b08",
PURL: "pkg:generic/java/jre@1.8.0_352-b08",
Locations: locations("java"),
Metadata: metadata("java-binary-openjdk", "java"),
},
@@ -619,23 +630,56 @@ func Test_Cataloger_PositiveCases(t *testing.T) {
{
logicalFixture: "java-jre-openjdk/11.0.17/linux-amd64",
expected: pkg.Package{
Name: "java",
Name: "java/jre",
Version: "11.0.17+8-LTS",
Type: "binary",
PURL: "pkg:generic/java@11.0.17+8-LTS",
PURL: "pkg:generic/java/jre@11.0.17%2B8-LTS",
Locations: locations("java"),
Metadata: metadata("java-binary-openjdk", "java"),
},
},
{
logicalFixture: "java-jre-openjdk-eclipse/11.0.22/linux-amd64",
expected: pkg.Package{
Name: "java/jre",
Version: "11.0.22+7",
Type: "binary",
PURL: "pkg:generic/java/jre@11.0.22%2B7",
Locations: locations("java"),
Metadata: metadata("java-binary-openjdk", "java"),
},
},
{
logicalFixture: "java-jre-openjdk-arm64-eclipse/11.0.22/linux-arm64",
expected: pkg.Package{
Name: "java/jre",
Version: "11.0.22+7",
Type: "binary",
PURL: "pkg:generic/java/jre@11.0.22%2B7",
Locations: locations("java"),
Metadata: metadata("java-binary-openjdk", "java"),
},
},
{
logicalFixture: "java-graal-openjdk/17.0.3+7-jvmci-22.1-b06/linux-amd64",
expected: pkg.Package{
Name: "java/graalvm",
Version: "17.0.3+7-jvmci-22.1-b06",
Type: "binary",
PURL: "pkg:generic/java/graalvm@17.0.3%2B7-jvmci-22.1-b06",
Locations: locations("java"),
Metadata: metadata("java-binary-graalvm", "java"),
},
},
{
// TODO: find original binary...
// note: cannot find the original binary, using a custom snippet based on the original snippet in the repo
logicalFixture: "java-jre-oracle/19.0.1/linux-amd64",
expected: pkg.Package{
Name: "java",
Name: "java/jre",
Version: "19.0.1+10-21",
Type: "binary",
PURL: "pkg:generic/java@19.0.1+10-21",
PURL: "pkg:generic/java/jre@19.0.1%2B10-21",
Locations: locations("java"),
Metadata: metadata("java-binary-oracle", "java"),
},
@@ -645,10 +689,10 @@ func Test_Cataloger_PositiveCases(t *testing.T) {
// note: cannot find the original binary, using a custom snippet based on the original snippet in the repo
logicalFixture: "java-jre-oracle/19.0.1/darwin",
expected: pkg.Package{
Name: "java",
Name: "java/jre",
Version: "19.0.1+10-21",
Type: "binary",
PURL: "pkg:generic/java@19.0.1+10-21",
PURL: "pkg:generic/java/jre@19.0.1%2B10-21",
Locations: locations("java"),
Metadata: metadata("java-binary-oracle", "java"),
},
@@ -656,14 +700,25 @@ func Test_Cataloger_PositiveCases(t *testing.T) {
{
logicalFixture: "java-jre-ibm/1.8.0_391/linux-amd64",
expected: pkg.Package{
Name: "java",
Name: "java/jre",
Version: "1.8.0-foreman_2023_10_12_13_27-b00",
Type: "binary",
PURL: "pkg:generic/java@1.8.0-foreman_2023_10_12_13_27-b00",
PURL: "pkg:generic/java/jre@1.8.0-foreman_2023_10_12_13_27-b00",
Locations: locations("java"),
Metadata: metadata("java-binary-ibm", "java"),
},
},
{
logicalFixture: "java-jdk-openjdk/21.0.2+13-LTS/linux-amd64",
expected: pkg.Package{
Name: "java/jdk",
Version: "21.0.2+13-LTS",
Type: "binary",
PURL: "pkg:generic/java/jdk@21.0.2%2B13-LTS",
Locations: locations("jdb"),
Metadata: metadata("java-binary-jdk", "java"),
},
},
{
logicalFixture: "rust-libstd/1.50.0/linux-amd64",
expected: pkg.Package{
@@ -799,7 +854,7 @@ func Test_Cataloger_PositiveCases(t *testing.T) {
},
},
{
logicalFixture: "erlexec/25.3.2.6/linux-amd64",
logicalFixture: "erlang/25.3.2.6/linux-amd64",
expected: pkg.Package{
Name: "erlang",
Version: "25.3.2.6",
@@ -810,7 +865,7 @@ func Test_Cataloger_PositiveCases(t *testing.T) {
},
},
{
logicalFixture: "erlexec/26.2.0.0/linux-amd64",
logicalFixture: "erlang/26.2.0.0/linux-amd64",
expected: pkg.Package{
Name: "erlang",
Version: "26.2",
@@ -820,6 +875,17 @@ func Test_Cataloger_PositiveCases(t *testing.T) {
Metadata: metadata("erlang-binary"),
},
},
{
logicalFixture: "erlang/26.2.4/linux-amd64",
expected: pkg.Package{
Name: "erlang",
Version: "26.2.4",
Type: "binary",
PURL: "pkg:generic/erlang@26.2.4",
Locations: locations("liberts_internal.a"),
Metadata: metadata("erlang-library"),
},
},
{
logicalFixture: "nginx/1.25.1/linux-amd64",
expected: pkg.Package{
+75 -15
View File
@@ -87,12 +87,21 @@ func DefaultClassifiers() []Classifier {
{
Class: "java-binary-openjdk",
FileGlob: "**/java",
EvidenceMatcher: FileContentsVersionMatcher(
// [NUL]openjdk[NUL]java[NUL]0.0[NUL]11.0.17+8-LTS[NUL]
// [NUL]openjdk[NUL]java[NUL]1.8[NUL]1.8.0_352-b08[NUL]
`(?m)\x00openjdk\x00java\x00(?P<release>[0-9]+[.0-9]*)\x00(?P<version>[0-9]+[^\x00]+)\x00`),
Package: "java",
PURL: mustPURL("pkg:generic/java@version"),
EvidenceMatcher: matchExcluding(
evidenceMatchers(
FileContentsVersionMatcher(
// [NUL]openjdk[NUL]java[NUL]0.0[NUL]11.0.17+8-LTS[NUL]
// [NUL]openjdk[NUL]java[NUL]1.8[NUL]1.8.0_352-b08[NUL]
`(?m)\x00openjdk\x00java\x00(?P<release>[0-9]+[.0-9]*)\x00(?P<version>[0-9]+[^\x00]+)\x00`),
FileContentsVersionMatcher(
// arm64 versions: [NUL]0.0[NUL][NUL][NUL][NUL][NUL]11.0.22+7[NUL][NUL][NUL][NUL][NUL][NUL][NUL]openjdk[NUL]java[NUL]
`(?m)\x00(?P<release>[0-9]+[.0-9]*)\x00+(?P<version>[0-9]+[^\x00]+)\x00+openjdk\x00java`),
),
// don't match graalvm
"-jvmci-",
),
Package: "java/jre",
PURL: mustPURL("pkg:generic/java/jre@version"),
// TODO the updates might need to be part of the CPE Attributes, like: 1.8.0:update152
CPEs: singleCPE("cpe:2.3:a:oracle:openjdk:*:*:*:*:*:*:*:*"),
},
@@ -102,20 +111,42 @@ func DefaultClassifiers() []Classifier {
EvidenceMatcher: FileContentsVersionMatcher(
// [NUL]java[NUL]1.8[NUL][NUL][NUL][NUL]1.8.0-foreman_2022_09_22_15_30-b00[NUL]
`(?m)\x00java\x00(?P<release>[0-9]+[.0-9]+)\x00{4}(?P<version>[0-9]+[-._a-zA-Z0-9]+)\x00`),
Package: "java",
PURL: mustPURL("pkg:generic/java@version"),
Package: "java/jre",
PURL: mustPURL("pkg:generic/java/jre@version"),
CPEs: singleCPE("cpe:2.3:a:ibm:java:*:*:*:*:*:*:*:*"),
},
{
Class: "java-binary-oracle",
FileGlob: "**/java",
EvidenceMatcher: FileContentsVersionMatcher(
// [NUL]19.0.1+10-21[NUL]
`(?m)\x00(?P<version>[0-9]+[.0-9]+[+][-0-9]+)\x00`),
Package: "java",
PURL: mustPURL("pkg:generic/java@version"),
EvidenceMatcher: matchExcluding(
FileContentsVersionMatcher(
// [NUL]19.0.1+10-21[NUL]
`(?m)\x00(?P<version>[0-9]+[.0-9]+[+][-0-9]+)\x00`),
// don't match openjdk
`\x00openjdk\x00`,
),
Package: "java/jre",
PURL: mustPURL("pkg:generic/java/jre@version"),
CPEs: singleCPE("cpe:2.3:a:oracle:jre:*:*:*:*:*:*:*:*"),
},
{
Class: "java-binary-graalvm",
FileGlob: "**/java",
EvidenceMatcher: FileContentsVersionMatcher(
`(?m)\x00(?P<version>[0-9]+[.0-9]+[.0-9]+\+[0-9]+-jvmci-[0-9]+[.0-9]+-b[0-9]+)\x00`),
Package: "java/graalvm",
PURL: mustPURL("pkg:generic/java/graalvm@version"),
CPEs: singleCPE("cpe:2.3:a:oracle:graalvm:*:*:*:*:*:*:*:*"),
},
{
Class: "java-binary-jdk",
FileGlob: "**/jdb",
EvidenceMatcher: FileContentsVersionMatcher(
`(?m)\x00(?P<version>[0-9]+\.[0-9]+\.[0-9]+(\+[0-9]+)?([-._a-zA-Z0-9]+)?)\x00`),
Package: "java/jdk",
PURL: mustPURL("pkg:generic/java/jdk@version"),
CPEs: singleCPE("cpe:2.3:a:oracle:jdk:*:*:*:*:*:*:*:*"),
},
{
Class: "nodejs-binary",
FileGlob: "**/node",
@@ -215,6 +246,7 @@ func DefaultClassifiers() []Classifier {
`(?m)memcached\s(?P<version>[0-9]+\.[0-9]+\.[0-9]+)`),
Package: "memcached",
PURL: mustPURL("pkg:generic/memcached@version"),
CPEs: singleCPE("cpe:2.3:a:memcached:memcached:*:*:*:*:*:*:*:*"),
},
{
Class: "traefik-binary",
@@ -225,6 +257,16 @@ func DefaultClassifiers() []Classifier {
`(?m)(\x00|\x{FFFD})v?(?P<version>[0-9]+\.[0-9]+\.[0-9]+(-alpha[0-9]|-beta[0-9]|-rc[0-9])?)\x00`),
Package: "traefik",
PURL: mustPURL("pkg:generic/traefik@version"),
CPEs: singleCPE("cpe:2.3:a:traefik:traefik:*:*:*:*:*:*:*:*"),
},
{
Class: "arangodb-binary",
FileGlob: "**/arangosh",
EvidenceMatcher: FileContentsVersionMatcher(
`(?m)ArangoDB\s\x00*(?P<version>[0-9]+\.[0-9]+\.[0-9]+)\s\[linux\]`),
Package: "arangodb",
PURL: mustPURL("pkg:generic/arangodb@version"),
CPEs: singleCPE("cpe:2.3:a:arangodb:arangodb:*:*:*:*:*:*:*:*"),
},
{
Class: "postgresql-binary",
@@ -237,6 +279,7 @@ func DefaultClassifiers() []Classifier {
`(?m)(\x00|\?)PostgreSQL (?P<version>[0-9]+(\.[0-9]+)?(\.[0-9]+)?(alpha[0-9]|beta[0-9]|rc[0-9])?)`),
Package: "postgresql",
PURL: mustPURL("pkg:generic/postgresql@version"),
CPEs: singleCPE("cpe:2.3:a:postgresql:postgresql:*:*:*:*:*:*:*:*"),
},
{
Class: "mysql-binary",
@@ -330,11 +373,28 @@ func DefaultClassifiers() []Classifier {
EvidenceMatcher: evidenceMatchers(
FileContentsVersionMatcher(
// <artificial>[NUL]/usr/src/otp_src_25.3.2.6/erts/
`(?m)/src/otp_src_(?P<version>[0-9]+\.[0-9]+(\.[0-9]+\.[0-9]+)?)/erts/`,
`(?m)/src/otp_src_(?P<version>[0-9]+\.[0-9]+(\.[0-9]+){0,2}(-rc[0-9])?)/erts/`,
),
FileContentsVersionMatcher(
// <artificial>[NUL]/usr/local/src/otp-25.3.2.7/erts/
`(?m)/usr/local/src/otp-(?P<version>[0-9]+\.[0-9]+(\.[0-9]+\.[0-9]+)?)/erts/`,
`(?m)/usr/local/src/otp-(?P<version>[0-9]+\.[0-9]+(\.[0-9]+){0,2}(-rc[0-9])?)/erts/`,
),
),
Package: "erlang",
PURL: mustPURL("pkg:generic/erlang@version"),
CPEs: singleCPE("cpe:2.3:a:erlang:erlang\\/otp:*:*:*:*:*:*:*:*"),
},
{
Class: "erlang-library",
FileGlob: "**/liberts_internal.a",
EvidenceMatcher: evidenceMatchers(
FileContentsVersionMatcher(
// <artificial>[NUL]/usr/src/otp_src_25.3.2.6/erts/
`(?m)/src/otp_src_(?P<version>[0-9]+\.[0-9]+(\.[0-9]+){0,2}(-rc[0-9])?)/erts/`,
),
FileContentsVersionMatcher(
// <artificial>[NUL]/usr/local/src/otp-25.3.2.7/erts/
`(?m)/usr/local/src/otp-(?P<version>[0-9]+\.[0-9]+(\.[0-9]+){0,2}(-rc[0-9])?)/erts/`,
),
),
Package: "erlang",
@@ -6,6 +6,7 @@ import (
"encoding/json"
"fmt"
"github.com/anchore/syft/internal"
"github.com/anchore/syft/internal/log"
"github.com/anchore/syft/internal/mimetype"
"github.com/anchore/syft/syft/artifact"
@@ -57,31 +58,13 @@ func (c *elfPackageCataloger) Catalog(_ context.Context, resolver file.Resolver)
// first find all ELF binaries that have notes
var notesByLocation = make(map[elfPackageKey][]elfBinaryPackageNotes)
for _, location := range locations {
reader, err := resolver.FileContentsByLocation(location)
notes, key, err := parseElfPackageNotes(resolver, location, c)
if err != nil {
return nil, nil, fmt.Errorf("unable to get binary contents %q: %w", location.Path(), err)
return nil, nil, err
}
notes, err := c.parseElfNotes(file.LocationReadCloser{
Location: location,
ReadCloser: reader,
})
if err != nil {
log.WithFields("file", location.Path(), "error", err).Trace("unable to parse ELF notes")
continue
}
if notes == nil {
continue
}
notes.Location = location
key := elfPackageKey{
Name: notes.Name,
Version: notes.Version,
PURL: notes.PURL,
CPE: notes.CPE,
}
notesByLocation[key] = append(notesByLocation[key], *notes)
}
@@ -105,6 +88,37 @@ func (c *elfPackageCataloger) Catalog(_ context.Context, resolver file.Resolver)
return pkgs, nil, nil
}
func parseElfPackageNotes(resolver file.Resolver, location file.Location, c *elfPackageCataloger) (*elfBinaryPackageNotes, elfPackageKey, error) {
reader, err := resolver.FileContentsByLocation(location)
if err != nil {
return nil, elfPackageKey{}, fmt.Errorf("unable to get binary contents %q: %w", location.Path(), err)
}
defer internal.CloseAndLogError(reader, location.AccessPath)
notes, err := c.parseElfNotes(file.LocationReadCloser{
Location: location,
ReadCloser: reader,
})
if err != nil {
log.WithFields("file", location.Path(), "error", err).Trace("unable to parse ELF notes")
return nil, elfPackageKey{}, nil
}
if notes == nil {
return nil, elfPackageKey{}, nil
}
notes.Location = location
key := elfPackageKey{
Name: notes.Name,
Version: notes.Version,
PURL: notes.PURL,
CPE: notes.CPE,
}
return notes, key, nil
}
func (c *elfPackageCataloger) parseElfNotes(reader file.LocationReadCloser) (*elfBinaryPackageNotes, error) {
metadata, err := getELFNotes(reader)
if err != nil {

Some files were not shown because too many files have changed in this diff Show More