Showing preview only (5,058K chars total). Download the full file or copy to clipboard to get everything.
Repository: anchore/grype
Branch: main
Commit: dee8de483dfb
Files: 1026
Total size: 4.6 MB
Directory structure:
gitextract_p7zkpam3/
├── .binny.yaml
├── .bouncer.yaml
├── .chronicle.yaml
├── .github/
│ ├── ISSUE_TEMPLATE/
│ │ ├── bug_report.md
│ │ ├── config.yml
│ │ ├── feature_request.md
│ │ └── match_issue.md
│ ├── actions/
│ │ └── bootstrap/
│ │ └── action.yaml
│ ├── dependabot.yaml
│ ├── scripts/
│ │ ├── check-syft-version-is-release.sh
│ │ ├── ci-check.sh
│ │ ├── coverage.py
│ │ ├── db-schema-drift-check.sh
│ │ ├── go-mod-tidy-check.sh
│ │ ├── json-schema-drift-check.sh
│ │ └── trigger-release.sh
│ ├── workflows/
│ │ ├── codeql-analysis.yml
│ │ ├── dependabot-automation.yaml
│ │ ├── oss-project-board-add.yaml
│ │ ├── release.yaml
│ │ ├── remove-awaiting-response-label.yaml
│ │ ├── scorecards.yml
│ │ ├── update-anchore-dependencies.yml
│ │ ├── update-bootstrap-tools.yml
│ │ ├── update-generated-code.yml
│ │ ├── update-quality-gate-db.yml
│ │ ├── validate-github-actions.yaml
│ │ └── validations.yaml
│ └── zizmor.yml
├── .gitignore
├── .gitmodules
├── .golangci.yaml
├── .goreleaser.yaml
├── CODE_OF_CONDUCT.md
├── CONTRIBUTING.md
├── Dockerfile
├── Dockerfile.debug
├── Dockerfile.nonroot
├── LICENSE
├── Makefile
├── README.md
├── RELEASE.md
├── SECURITY.md
├── Taskfile.yaml
├── artifacthub-repo.yml
├── cmd/
│ └── grype/
│ ├── cli/
│ │ ├── cli.go
│ │ ├── cli_test.go
│ │ ├── commands/
│ │ │ ├── completion.go
│ │ │ ├── db.go
│ │ │ ├── db_check.go
│ │ │ ├── db_check_test.go
│ │ │ ├── db_delete.go
│ │ │ ├── db_import.go
│ │ │ ├── db_list.go
│ │ │ ├── db_list_test.go
│ │ │ ├── db_providers.go
│ │ │ ├── db_providers_test.go
│ │ │ ├── db_search.go
│ │ │ ├── db_search_test.go
│ │ │ ├── db_search_vuln.go
│ │ │ ├── db_search_vuln_test.go
│ │ │ ├── db_status.go
│ │ │ ├── db_status_test.go
│ │ │ ├── db_update.go
│ │ │ ├── explain.go
│ │ │ ├── internal/
│ │ │ │ ├── dbsearch/
│ │ │ │ │ ├── affected_packages.go
│ │ │ │ │ ├── affected_packages_test.go
│ │ │ │ │ ├── common.go
│ │ │ │ │ ├── matches.go
│ │ │ │ │ ├── matches_test.go
│ │ │ │ │ ├── versions.go
│ │ │ │ │ ├── vulnerabilities.go
│ │ │ │ │ ├── vulnerabilities_test.go
│ │ │ │ │ └── vulnerability_decorations.go
│ │ │ │ └── jsonschema/
│ │ │ │ └── main.go
│ │ │ ├── root.go
│ │ │ ├── root_test.go
│ │ │ ├── testdata/
│ │ │ │ └── provider-metadata.json
│ │ │ ├── update.go
│ │ │ ├── update_test.go
│ │ │ ├── util.go
│ │ │ └── util_test.go
│ │ ├── options/
│ │ │ ├── alerts.go
│ │ │ ├── alerts_test.go
│ │ │ ├── database.go
│ │ │ ├── database_command.go
│ │ │ ├── database_search_bounds.go
│ │ │ ├── database_search_format.go
│ │ │ ├── database_search_os.go
│ │ │ ├── database_search_os_test.go
│ │ │ ├── database_search_packages.go
│ │ │ ├── database_search_packages_test.go
│ │ │ ├── database_search_vulnerabilities.go
│ │ │ ├── database_search_vulnerabilities_test.go
│ │ │ ├── datasources.go
│ │ │ ├── experimental.go
│ │ │ ├── fix_channels.go
│ │ │ ├── grype.go
│ │ │ ├── grype_test.go
│ │ │ ├── match.go
│ │ │ ├── match_test.go
│ │ │ ├── registry.go
│ │ │ ├── registry_test.go
│ │ │ ├── search.go
│ │ │ ├── secret.go
│ │ │ └── sort_by.go
│ │ └── ui/
│ │ ├── __snapshots__/
│ │ │ ├── handle_database_diff_started_test.snap
│ │ │ ├── handle_update_vulnerability_database_test.snap
│ │ │ └── handle_vulnerability_scanning_started_test.snap
│ │ ├── handle_database_diff_started.go
│ │ ├── handle_database_diff_started_test.go
│ │ ├── handle_update_vulnerability_database.go
│ │ ├── handle_update_vulnerability_database_test.go
│ │ ├── handle_vulnerability_scanning_started.go
│ │ ├── handle_vulnerability_scanning_started_test.go
│ │ ├── handler.go
│ │ ├── new_task_progress.go
│ │ └── util_test.go
│ ├── internal/
│ │ ├── constants.go
│ │ └── ui/
│ │ ├── __snapshots__/
│ │ │ └── post_ui_event_writer_test.snap
│ │ ├── no_ui.go
│ │ ├── post_ui_event_writer.go
│ │ ├── post_ui_event_writer_test.go
│ │ └── ui.go
│ └── main.go
├── go.mod
├── go.sum
├── grype/
│ ├── cpe/
│ │ ├── cpe.go
│ │ └── cpe_test.go
│ ├── db/
│ │ ├── build.go
│ │ ├── data/
│ │ │ ├── entry.go
│ │ │ ├── processor.go
│ │ │ ├── severity.go
│ │ │ ├── severity_test.go
│ │ │ ├── transformers.go
│ │ │ └── writer.go
│ │ ├── default_schema_version.go
│ │ ├── generate.go
│ │ ├── internal/
│ │ │ ├── codename/
│ │ │ │ ├── codename.go
│ │ │ │ ├── codename_test.go
│ │ │ │ ├── codenames_generated.go
│ │ │ │ └── generate/
│ │ │ │ └── main.go
│ │ │ ├── gormadapter/
│ │ │ │ ├── logger.go
│ │ │ │ ├── open.go
│ │ │ │ └── open_test.go
│ │ │ ├── provider/
│ │ │ │ └── unmarshal/
│ │ │ │ ├── annotated_openvex_vulnerability.go
│ │ │ │ ├── eol.go
│ │ │ │ ├── epss.go
│ │ │ │ ├── errors.go
│ │ │ │ ├── github_advisory.go
│ │ │ │ ├── items_envelope.go
│ │ │ │ ├── known_exploited_vulnerability.go
│ │ │ │ ├── match_exclusion.go
│ │ │ │ ├── msrc_vulnerability.go
│ │ │ │ ├── nvd/
│ │ │ │ │ ├── cve.go
│ │ │ │ │ ├── cve_test.go
│ │ │ │ │ ├── cvss20/
│ │ │ │ │ │ └── cvss20.go
│ │ │ │ │ ├── cvss30/
│ │ │ │ │ │ └── cvss30.go
│ │ │ │ │ ├── cvss31/
│ │ │ │ │ │ └── cvss31.go
│ │ │ │ │ └── cvss40/
│ │ │ │ │ └── cvss40.go
│ │ │ │ ├── nvd_vulnerability.go
│ │ │ │ ├── openvex_vulnerability.go
│ │ │ │ ├── os_vulnerability.go
│ │ │ │ ├── os_vulnerability_test.go
│ │ │ │ ├── osv_vulnerability.go
│ │ │ │ └── single_or_multi.go
│ │ │ ├── sqlite/
│ │ │ │ ├── nullable_types.go
│ │ │ │ └── nullable_types_test.go
│ │ │ ├── tarutil/
│ │ │ │ ├── file_entry.go
│ │ │ │ ├── file_entry_test.go
│ │ │ │ ├── populate.go
│ │ │ │ ├── populate_test.go
│ │ │ │ ├── reader_entry.go
│ │ │ │ ├── reader_entry_test.go
│ │ │ │ ├── tar.go
│ │ │ │ ├── writer.go
│ │ │ │ └── writer_test.go
│ │ │ ├── testutil/
│ │ │ │ └── utils.go
│ │ │ └── versionutil/
│ │ │ ├── clean_fixed_in_version.go
│ │ │ ├── constraint.go
│ │ │ └── constraint_test.go
│ │ ├── package.go
│ │ ├── package_legacy.go
│ │ ├── processors/
│ │ │ ├── annotated_openvex_processor.go
│ │ │ ├── eol_processor.go
│ │ │ ├── eol_processor_test.go
│ │ │ ├── epss_processor.go
│ │ │ ├── epss_processor_test.go
│ │ │ ├── github_processor.go
│ │ │ ├── github_processor_test.go
│ │ │ ├── kev_processor.go
│ │ │ ├── kev_processor_test.go
│ │ │ ├── match_exclusion_processor.go
│ │ │ ├── match_exclusion_processor_test.go
│ │ │ ├── msrc_processor.go
│ │ │ ├── msrc_processor_test.go
│ │ │ ├── nvd_processor.go
│ │ │ ├── nvd_processor_test.go
│ │ │ ├── openvex_processor.go
│ │ │ ├── openvex_processor_test.go
│ │ │ ├── os_processor.go
│ │ │ ├── os_processor_test.go
│ │ │ ├── osv_processor.go
│ │ │ ├── osv_processor_test.go
│ │ │ ├── testdata/
│ │ │ │ ├── eol-with-empty.json
│ │ │ │ ├── eol.json
│ │ │ │ ├── epss.json
│ │ │ │ ├── exclusions.json
│ │ │ │ ├── github.json
│ │ │ │ ├── kev.json
│ │ │ │ ├── msrc.json
│ │ │ │ ├── nvd.json
│ │ │ │ ├── openvex.json
│ │ │ │ ├── oracle.json
│ │ │ │ ├── os.json
│ │ │ │ └── osv.json
│ │ │ ├── version.go
│ │ │ └── version_test.go
│ │ ├── provider/
│ │ │ ├── entry/
│ │ │ │ ├── file.go
│ │ │ │ ├── opener.go
│ │ │ │ └── sqlite.go
│ │ │ ├── file.go
│ │ │ ├── model.go
│ │ │ ├── model_test.go
│ │ │ ├── provider.go
│ │ │ ├── state.go
│ │ │ ├── state_test.go
│ │ │ └── workspace.go
│ │ ├── v5/
│ │ │ ├── advisory.go
│ │ │ ├── build/
│ │ │ │ ├── processors.go
│ │ │ │ ├── transformers/
│ │ │ │ │ ├── entry.go
│ │ │ │ │ ├── github/
│ │ │ │ │ │ ├── testdata/
│ │ │ │ │ │ │ ├── github-github-npm-0.json
│ │ │ │ │ │ │ ├── github-github-python-0.json
│ │ │ │ │ │ │ ├── github-github-python-1.json
│ │ │ │ │ │ │ ├── github-withdrawn.json
│ │ │ │ │ │ │ └── multiple-fixed-in-names.json
│ │ │ │ │ │ ├── transform.go
│ │ │ │ │ │ └── transform_test.go
│ │ │ │ │ ├── matchexclusions/
│ │ │ │ │ │ └── transform.go
│ │ │ │ │ ├── msrc/
│ │ │ │ │ │ ├── testdata/
│ │ │ │ │ │ │ └── microsoft-msrc-0.json
│ │ │ │ │ │ ├── transform.go
│ │ │ │ │ │ └── transform_test.go
│ │ │ │ │ ├── nvd/
│ │ │ │ │ │ ├── testdata/
│ │ │ │ │ │ │ ├── CVE-2023-45283-platform-cpe-first.json
│ │ │ │ │ │ │ ├── CVE-2023-45283-platform-cpe-last.json
│ │ │ │ │ │ │ ├── compound-pkg.json
│ │ │ │ │ │ │ ├── cve-2020-10729.json
│ │ │ │ │ │ │ ├── cve-2022-0543.json
│ │ │ │ │ │ │ ├── invalid_cpe.json
│ │ │ │ │ │ │ ├── multiple-platforms-with-application-cpe.json
│ │ │ │ │ │ │ ├── platform-cpe.json
│ │ │ │ │ │ │ ├── single-package-multi-distro.json
│ │ │ │ │ │ │ ├── unmarshal-test.json
│ │ │ │ │ │ │ └── version-range.json
│ │ │ │ │ │ ├── transform.go
│ │ │ │ │ │ ├── transform_test.go
│ │ │ │ │ │ ├── unique_pkg.go
│ │ │ │ │ │ ├── unique_pkg_test.go
│ │ │ │ │ │ └── unique_pkg_tracker.go
│ │ │ │ │ ├── os/
│ │ │ │ │ │ ├── testdata/
│ │ │ │ │ │ │ ├── alpine-3.9.json
│ │ │ │ │ │ │ ├── amazon-multiple-kernel-advisories.json
│ │ │ │ │ │ │ ├── amzn.json
│ │ │ │ │ │ │ ├── azure-linux-3.json
│ │ │ │ │ │ │ ├── debian-8-multiple-entries-for-same-package.json
│ │ │ │ │ │ │ ├── debian-8.json
│ │ │ │ │ │ │ ├── mariner-20.json
│ │ │ │ │ │ │ ├── mariner-range.json
│ │ │ │ │ │ │ ├── ol-8-modules.json
│ │ │ │ │ │ │ ├── ol-8.json
│ │ │ │ │ │ │ ├── photon-4.0.json
│ │ │ │ │ │ │ ├── rhel-8-eus.json
│ │ │ │ │ │ │ ├── rhel-8-modules.json
│ │ │ │ │ │ │ ├── rhel-8.json
│ │ │ │ │ │ │ └── unmarshal-test.json
│ │ │ │ │ │ ├── transform.go
│ │ │ │ │ │ └── transform_test.go
│ │ │ │ │ └── vulnerability_metadata.go
│ │ │ │ ├── writer.go
│ │ │ │ └── writer_test.go
│ │ │ ├── cvss.go
│ │ │ ├── diff.go
│ │ │ ├── differ/
│ │ │ │ ├── differ.go
│ │ │ │ ├── differ_test.go
│ │ │ │ └── testdata/
│ │ │ │ ├── dbs/
│ │ │ │ │ ├── base/
│ │ │ │ │ │ └── 5/
│ │ │ │ │ │ └── metadata.json
│ │ │ │ │ └── target/
│ │ │ │ │ └── 5/
│ │ │ │ │ └── metadata.json
│ │ │ │ └── snapshot/
│ │ │ │ ├── TestPresent_Json.golden
│ │ │ │ └── TestPresent_Table.golden
│ │ │ ├── distribution/
│ │ │ │ ├── curator.go
│ │ │ │ ├── curator_test.go
│ │ │ │ ├── listing.go
│ │ │ │ ├── listing_entry.go
│ │ │ │ ├── listing_test.go
│ │ │ │ ├── metadata.go
│ │ │ │ ├── metadata_test.go
│ │ │ │ ├── status.go
│ │ │ │ └── testdata/
│ │ │ │ ├── curator-validate/
│ │ │ │ │ ├── bad-checksum/
│ │ │ │ │ │ └── metadata.json
│ │ │ │ │ └── good-checksum/
│ │ │ │ │ └── metadata.json
│ │ │ │ ├── listing-sorted.json
│ │ │ │ ├── listing-unsorted.json
│ │ │ │ ├── listing.json
│ │ │ │ ├── metadata-edt-timezone/
│ │ │ │ │ └── metadata.json
│ │ │ │ ├── metadata-gocase/
│ │ │ │ │ └── metadata.json
│ │ │ │ └── tls/
│ │ │ │ ├── .gitignore
│ │ │ │ ├── Makefile
│ │ │ │ ├── README.md
│ │ │ │ ├── generate-x509-cert-pair.sh
│ │ │ │ ├── listing.py
│ │ │ │ └── serve.py
│ │ │ ├── fix.go
│ │ │ ├── id.go
│ │ │ ├── match_exclusion_provider.go
│ │ │ ├── namespace/
│ │ │ │ ├── cpe/
│ │ │ │ │ ├── namespace.go
│ │ │ │ │ └── namespace_test.go
│ │ │ │ ├── distro/
│ │ │ │ │ ├── namespace.go
│ │ │ │ │ └── namespace_test.go
│ │ │ │ ├── from_string.go
│ │ │ │ ├── from_string_test.go
│ │ │ │ ├── language/
│ │ │ │ │ ├── namespace.go
│ │ │ │ │ └── namespace_test.go
│ │ │ │ └── namespace.go
│ │ │ ├── pkg/
│ │ │ │ ├── qualifier/
│ │ │ │ │ ├── from_json.go
│ │ │ │ │ ├── platformcpe/
│ │ │ │ │ │ └── qualifier.go
│ │ │ │ │ ├── qualifier.go
│ │ │ │ │ └── rpmmodularity/
│ │ │ │ │ └── qualifier.go
│ │ │ │ └── resolver/
│ │ │ │ ├── java/
│ │ │ │ │ ├── resolver.go
│ │ │ │ │ └── resolver_test.go
│ │ │ │ ├── python/
│ │ │ │ │ ├── resolver.go
│ │ │ │ │ └── resolver_test.go
│ │ │ │ ├── resolver.go
│ │ │ │ ├── resolver_test.go
│ │ │ │ └── stock/
│ │ │ │ ├── resolver.go
│ │ │ │ └── resolver_test.go
│ │ │ ├── provider_store.go
│ │ │ ├── schema_version.go
│ │ │ ├── store/
│ │ │ │ ├── diff.go
│ │ │ │ ├── diff_test.go
│ │ │ │ ├── model/
│ │ │ │ │ ├── id.go
│ │ │ │ │ ├── vulnerability.go
│ │ │ │ │ ├── vulnerability_match_exclusion.go
│ │ │ │ │ ├── vulnerability_match_exclusion_test.go
│ │ │ │ │ ├── vulnerability_metadata.go
│ │ │ │ │ └── vulnerability_test.go
│ │ │ │ ├── store.go
│ │ │ │ └── store_test.go
│ │ │ ├── store.go
│ │ │ ├── vulnerability.go
│ │ │ ├── vulnerability_match_exclusion.go
│ │ │ ├── vulnerability_match_exclusion_store.go
│ │ │ ├── vulnerability_metadata.go
│ │ │ ├── vulnerability_metadata_store.go
│ │ │ └── vulnerability_store.go
│ │ └── v6/
│ │ ├── affected_cpe_store.go
│ │ ├── affected_cpe_store_test.go
│ │ ├── affected_package_store.go
│ │ ├── affected_package_store_test.go
│ │ ├── blob_store.go
│ │ ├── blob_store_test.go
│ │ ├── blobs.go
│ │ ├── blobs_test.go
│ │ ├── build/
│ │ │ ├── archive.go
│ │ │ ├── processors.go
│ │ │ ├── transformers/
│ │ │ │ ├── entry.go
│ │ │ │ ├── eol/
│ │ │ │ │ ├── transform.go
│ │ │ │ │ └── transform_test.go
│ │ │ │ ├── epss/
│ │ │ │ │ ├── testdata/
│ │ │ │ │ │ └── go-case.json
│ │ │ │ │ ├── transform.go
│ │ │ │ │ └── transform_test.go
│ │ │ │ ├── github/
│ │ │ │ │ ├── testdata/
│ │ │ │ │ │ ├── GHSA-2wgc-48g2-cj5w.json
│ │ │ │ │ │ ├── GHSA-3x74-v64j-qc3f.json
│ │ │ │ │ │ ├── GHSA-92cp-5422-2mw7.json
│ │ │ │ │ │ ├── GHSA-qc55-vm3j-74gp.json
│ │ │ │ │ │ ├── github-github-npm-0.json
│ │ │ │ │ │ ├── github-github-python-0.json
│ │ │ │ │ │ ├── github-withdrawn.json
│ │ │ │ │ │ └── multiple-fixed-in-names.json
│ │ │ │ │ ├── transform.go
│ │ │ │ │ └── transform_test.go
│ │ │ │ ├── internal/
│ │ │ │ │ ├── sort.go
│ │ │ │ │ ├── time.go
│ │ │ │ │ └── time_test.go
│ │ │ │ ├── kev/
│ │ │ │ │ ├── testdata/
│ │ │ │ │ │ └── go-case.json
│ │ │ │ │ ├── transform.go
│ │ │ │ │ └── transform_test.go
│ │ │ │ ├── msrc/
│ │ │ │ │ ├── testdata/
│ │ │ │ │ │ └── microsoft-msrc-0.json
│ │ │ │ │ ├── transform.go
│ │ │ │ │ └── transform_test.go
│ │ │ │ ├── nvd/
│ │ │ │ │ ├── affected_range.go
│ │ │ │ │ ├── affected_range_test.go
│ │ │ │ │ ├── node.go
│ │ │ │ │ ├── node_test.go
│ │ │ │ │ ├── testdata/
│ │ │ │ │ │ ├── CVE-2004-0377.json
│ │ │ │ │ │ ├── CVE-2008-3442.json
│ │ │ │ │ │ ├── CVE-2023-45283-platform-cpe-first.json
│ │ │ │ │ │ ├── CVE-2023-45283-platform-cpe-last.json
│ │ │ │ │ │ ├── compound-pkg.json
│ │ │ │ │ │ ├── cve-2020-10729.json
│ │ │ │ │ │ ├── cve-2021-1566.json
│ │ │ │ │ │ ├── cve-2022-0543.json
│ │ │ │ │ │ ├── cve-2024-26663-standalone-os.json
│ │ │ │ │ │ ├── fix-version.json
│ │ │ │ │ │ ├── fix-wrong-version.json
│ │ │ │ │ │ ├── invalid_cpe.json
│ │ │ │ │ │ ├── jvm-packages.json
│ │ │ │ │ │ ├── multiple-platforms-with-application-cpe.json
│ │ │ │ │ │ ├── platform-cpe.json
│ │ │ │ │ │ ├── single-package-multi-distro.json
│ │ │ │ │ │ └── version-range.json
│ │ │ │ │ ├── transform.go
│ │ │ │ │ └── transform_test.go
│ │ │ │ ├── openvex/
│ │ │ │ │ ├── transform.go
│ │ │ │ │ └── transform_test.go
│ │ │ │ ├── os/
│ │ │ │ │ ├── testdata/
│ │ │ │ │ │ ├── alpine-3.9.json
│ │ │ │ │ │ ├── amazon-multiple-kernel-advisories.json
│ │ │ │ │ │ ├── amzn.json
│ │ │ │ │ │ ├── azure-linux-3.json
│ │ │ │ │ │ ├── debian-8-multiple-entries-for-same-package.json
│ │ │ │ │ │ ├── debian-8.json
│ │ │ │ │ │ ├── fedora-39.json
│ │ │ │ │ │ ├── mariner-20.json
│ │ │ │ │ │ ├── mariner-range.json
│ │ │ │ │ │ ├── ol-8-modules.json
│ │ │ │ │ │ ├── ol-8.json
│ │ │ │ │ │ ├── rhel-8-modules.json
│ │ │ │ │ │ └── rhel-8.json
│ │ │ │ │ ├── transform.go
│ │ │ │ │ └── transform_test.go
│ │ │ │ ├── osv/
│ │ │ │ │ ├── testdata/
│ │ │ │ │ │ ├── ALSA-2025-7467.json
│ │ │ │ │ │ ├── BIT-apache-2020-11984.json
│ │ │ │ │ │ └── BIT-node-2020-8201.json
│ │ │ │ │ ├── transform.go
│ │ │ │ │ └── transform_test.go
│ │ │ │ └── references.go
│ │ │ ├── writer.go
│ │ │ └── writer_test.go
│ │ ├── cache.go
│ │ ├── cache_test.go
│ │ ├── cpe_store.go
│ │ ├── data.go
│ │ ├── db.go
│ │ ├── db_metadata_store.go
│ │ ├── db_metadata_store_test.go
│ │ ├── description.go
│ │ ├── description_test.go
│ │ ├── distribution/
│ │ │ ├── client.go
│ │ │ ├── client_test.go
│ │ │ ├── latest.go
│ │ │ ├── latest_test.go
│ │ │ └── status.go
│ │ ├── enumerations.go
│ │ ├── enumerations_test.go
│ │ ├── fillers.go
│ │ ├── import_metadata.go
│ │ ├── import_metadata_test.go
│ │ ├── installation/
│ │ │ ├── curator.go
│ │ │ └── curator_test.go
│ │ ├── log_dropped.go
│ │ ├── models.go
│ │ ├── models_test.go
│ │ ├── name/
│ │ │ ├── java.go
│ │ │ ├── java_test.go
│ │ │ ├── python.go
│ │ │ ├── python_test.go
│ │ │ └── resolver.go
│ │ ├── operating_system_store.go
│ │ ├── operating_system_store_test.go
│ │ ├── package_store.go
│ │ ├── provider_store.go
│ │ ├── provider_store_test.go
│ │ ├── refs.go
│ │ ├── schema/
│ │ │ └── main.go
│ │ ├── search_query.go
│ │ ├── search_query_test.go
│ │ ├── severity.go
│ │ ├── severity_test.go
│ │ ├── store.go
│ │ ├── store_test.go
│ │ ├── unaffected_cpe_store.go
│ │ ├── unaffected_cpe_store_test.go
│ │ ├── unaffected_package_store.go
│ │ ├── unaffected_package_store_test.go
│ │ ├── vulnerability.go
│ │ ├── vulnerability_decorator_store.go
│ │ ├── vulnerability_decorator_store_test.go
│ │ ├── vulnerability_provider.go
│ │ ├── vulnerability_provider_mocks_test.go
│ │ ├── vulnerability_provider_test.go
│ │ ├── vulnerability_store.go
│ │ ├── vulnerability_store_test.go
│ │ └── vulnerability_test.go
│ ├── deprecated.go
│ ├── distro/
│ │ ├── distro.go
│ │ ├── distro_test.go
│ │ ├── fix_channel.go
│ │ ├── fix_channel_test.go
│ │ ├── testdata/
│ │ │ ├── bad-id
│ │ │ ├── bad-redhat-release
│ │ │ ├── bad-system-release-cpe
│ │ │ ├── centos-8
│ │ │ ├── debian-8
│ │ │ ├── os/
│ │ │ │ ├── almalinux/
│ │ │ │ │ └── etc/
│ │ │ │ │ └── os-release
│ │ │ │ ├── alpine/
│ │ │ │ │ └── etc/
│ │ │ │ │ └── os-release
│ │ │ │ ├── alpine-edge/
│ │ │ │ │ └── etc/
│ │ │ │ │ └── os-release
│ │ │ │ ├── amazon/
│ │ │ │ │ └── etc/
│ │ │ │ │ └── os-release
│ │ │ │ ├── arch/
│ │ │ │ │ └── etc/
│ │ │ │ │ └── os-release
│ │ │ │ ├── azurelinux/
│ │ │ │ │ └── etc/
│ │ │ │ │ └── os-release
│ │ │ │ ├── busybox/
│ │ │ │ │ └── bin/
│ │ │ │ │ └── busybox
│ │ │ │ ├── centos/
│ │ │ │ │ └── usr/
│ │ │ │ │ └── lib/
│ │ │ │ │ └── os-release
│ │ │ │ ├── centos5/
│ │ │ │ │ └── etc/
│ │ │ │ │ └── redhat-release
│ │ │ │ ├── centos6/
│ │ │ │ │ └── etc/
│ │ │ │ │ └── system-release-cpe
│ │ │ │ ├── chainguard/
│ │ │ │ │ └── etc/
│ │ │ │ │ └── os-release
│ │ │ │ ├── custom/
│ │ │ │ │ └── etc/
│ │ │ │ │ └── os-release
│ │ │ │ ├── debian/
│ │ │ │ │ └── usr/
│ │ │ │ │ └── lib/
│ │ │ │ │ └── os-release
│ │ │ │ ├── debian-sid/
│ │ │ │ │ └── usr/
│ │ │ │ │ └── lib/
│ │ │ │ │ └── os-release
│ │ │ │ ├── echo/
│ │ │ │ │ └── etc/
│ │ │ │ │ └── os-release
│ │ │ │ ├── empty/
│ │ │ │ │ └── etc/
│ │ │ │ │ └── os-release
│ │ │ │ ├── fedora/
│ │ │ │ │ └── usr/
│ │ │ │ │ └── lib/
│ │ │ │ │ └── os-release
│ │ │ │ ├── gentoo/
│ │ │ │ │ └── etc/
│ │ │ │ │ └── os-release
│ │ │ │ ├── mariner/
│ │ │ │ │ └── etc/
│ │ │ │ │ └── os-release
│ │ │ │ ├── minimos/
│ │ │ │ │ └── etc/
│ │ │ │ │ └── os-release
│ │ │ │ ├── opensuse-leap/
│ │ │ │ │ └── etc/
│ │ │ │ │ └── os-release
│ │ │ │ ├── oraclelinux/
│ │ │ │ │ └── etc/
│ │ │ │ │ └── os-release
│ │ │ │ ├── photon/
│ │ │ │ │ └── etc/
│ │ │ │ │ └── os-release
│ │ │ │ ├── postmarketos/
│ │ │ │ │ └── etc/
│ │ │ │ │ └── os-release
│ │ │ │ ├── postmarketos-edge/
│ │ │ │ │ └── etc/
│ │ │ │ │ └── os-release
│ │ │ │ ├── raspbian/
│ │ │ │ │ └── etc/
│ │ │ │ │ └── os-release
│ │ │ │ ├── redhat/
│ │ │ │ │ └── usr/
│ │ │ │ │ └── lib/
│ │ │ │ │ └── os-release
│ │ │ │ ├── rockylinux/
│ │ │ │ │ └── etc/
│ │ │ │ │ └── os-release
│ │ │ │ ├── scientific/
│ │ │ │ │ └── etc/
│ │ │ │ │ └── os-release
│ │ │ │ ├── scientific6/
│ │ │ │ │ └── etc/
│ │ │ │ │ └── redhat-release
│ │ │ │ ├── secureos/
│ │ │ │ │ └── etc/
│ │ │ │ │ └── os-release
│ │ │ │ ├── sles/
│ │ │ │ │ └── etc/
│ │ │ │ │ └── os-release
│ │ │ │ ├── ubuntu/
│ │ │ │ │ └── etc/
│ │ │ │ │ └── os-release
│ │ │ │ └── wolfi/
│ │ │ │ └── etc/
│ │ │ │ └── os-release
│ │ │ ├── partial-fields/
│ │ │ │ ├── missing-id/
│ │ │ │ │ └── usr/
│ │ │ │ │ └── lib/
│ │ │ │ │ └── os-release
│ │ │ │ ├── missing-version/
│ │ │ │ │ └── usr/
│ │ │ │ │ └── lib/
│ │ │ │ │ └── os-release
│ │ │ │ └── unknown-id/
│ │ │ │ └── usr/
│ │ │ │ └── lib/
│ │ │ │ └── os-release
│ │ │ ├── rhel-8
│ │ │ ├── ubuntu-20.04
│ │ │ └── unprintable
│ │ ├── type.go
│ │ └── type_test.go
│ ├── event/
│ │ ├── event.go
│ │ ├── monitor/
│ │ │ ├── db_diff.go
│ │ │ └── matching.go
│ │ └── parsers/
│ │ └── parsers.go
│ ├── grypeerr/
│ │ ├── errors.go
│ │ └── expected_error.go
│ ├── internal/
│ │ ├── generate.go
│ │ └── packagemetadata/
│ │ ├── discover_type_names.go
│ │ ├── generate/
│ │ │ └── main.go
│ │ ├── generated.go
│ │ ├── names.go
│ │ └── names_test.go
│ ├── lib.go
│ ├── load_vulnerability_db.go
│ ├── load_vulnerability_db_bench_test.go
│ ├── match/
│ │ ├── details.go
│ │ ├── details_test.go
│ │ ├── explicit_ignores.go
│ │ ├── explicit_ignores_test.go
│ │ ├── fingerprint.go
│ │ ├── ignore.go
│ │ ├── ignore_test.go
│ │ ├── match.go
│ │ ├── match_test.go
│ │ ├── matcher.go
│ │ ├── matcher_type.go
│ │ ├── matches.go
│ │ ├── matches_test.go
│ │ ├── provider.go
│ │ ├── results.go
│ │ ├── sort.go
│ │ └── type.go
│ ├── matcher/
│ │ ├── apk/
│ │ │ ├── matcher.go
│ │ │ └── matcher_test.go
│ │ ├── bitnami/
│ │ │ └── matcher.go
│ │ ├── dotnet/
│ │ │ └── matcher.go
│ │ ├── dpkg/
│ │ │ ├── matcher.go
│ │ │ ├── matcher_mocks_test.go
│ │ │ └── matcher_test.go
│ │ ├── golang/
│ │ │ ├── matcher.go
│ │ │ └── matcher_test.go
│ │ ├── hex/
│ │ │ └── matcher.go
│ │ ├── internal/
│ │ │ ├── common.go
│ │ │ ├── cpe.go
│ │ │ ├── cpe_test.go
│ │ │ ├── distro.go
│ │ │ ├── distro_test.go
│ │ │ ├── eol.go
│ │ │ ├── eol_test.go
│ │ │ ├── language.go
│ │ │ ├── language_test.go
│ │ │ ├── only_non_withdrawn_vulnerabilities.go
│ │ │ ├── only_qualified_packages.go
│ │ │ ├── only_vulnerable_targets.go
│ │ │ ├── only_vulnerable_targets_test.go
│ │ │ ├── only_vulnerable_versions.go
│ │ │ ├── result/
│ │ │ │ ├── match_details_set.go
│ │ │ │ ├── provider.go
│ │ │ │ ├── results.go
│ │ │ │ └── results_test.go
│ │ │ └── utils_test.go
│ │ ├── java/
│ │ │ ├── matcher.go
│ │ │ ├── matcher_integration_test.go
│ │ │ ├── matcher_mocks_test.go
│ │ │ ├── matcher_test.go
│ │ │ ├── maven_search.go
│ │ │ └── maven_test.go
│ │ ├── javascript/
│ │ │ └── matcher.go
│ │ ├── matchers.go
│ │ ├── mock/
│ │ │ └── matcher.go
│ │ ├── msrc/
│ │ │ └── matcher.go
│ │ ├── pacman/
│ │ │ ├── matcher.go
│ │ │ └── matcher_test.go
│ │ ├── portage/
│ │ │ ├── matcher.go
│ │ │ ├── matcher_mocks_test.go
│ │ │ └── matcher_test.go
│ │ ├── python/
│ │ │ └── matcher.go
│ │ ├── rpm/
│ │ │ ├── almalinux.go
│ │ │ ├── almalinux_package_utils.go
│ │ │ ├── almalinux_package_utils_test.go
│ │ │ ├── almalinux_test.go
│ │ │ ├── matcher.go
│ │ │ ├── matcher_mocks_test.go
│ │ │ ├── matcher_test.go
│ │ │ ├── rhel_eus.go
│ │ │ └── rhel_eus_test.go
│ │ ├── ruby/
│ │ │ └── matcher.go
│ │ ├── rust/
│ │ │ └── matcher.go
│ │ └── stock/
│ │ ├── matcher.go
│ │ └── matcher_test.go
│ ├── pkg/
│ │ ├── apk_metadata.go
│ │ ├── context.go
│ │ ├── context_test.go
│ │ ├── cpe_provider.go
│ │ ├── cpe_provider_test.go
│ │ ├── file_owner.go
│ │ ├── golang_metadata.go
│ │ ├── java_metadata.go
│ │ ├── java_metadata_test.go
│ │ ├── package.go
│ │ ├── package_test.go
│ │ ├── provider.go
│ │ ├── provider_config.go
│ │ ├── provider_test.go
│ │ ├── purl_provider.go
│ │ ├── purl_provider_test.go
│ │ ├── qualifier/
│ │ │ ├── platformcpe/
│ │ │ │ ├── qualifier.go
│ │ │ │ └── qualifier_test.go
│ │ │ ├── qualifier.go
│ │ │ └── rpmmodularity/
│ │ │ ├── qualifier.go
│ │ │ └── qualifier_test.go
│ │ ├── rpm_metadata.go
│ │ ├── syft_provider.go
│ │ ├── syft_sbom_provider.go
│ │ ├── syft_sbom_provider_test.go
│ │ ├── testdata/
│ │ │ ├── alpine-tampered.att.json
│ │ │ ├── alpine-tampered.cdx.att.json
│ │ │ ├── alpine.att.json
│ │ │ ├── alpine.cdx.att.json
│ │ │ ├── another_cosign.pub
│ │ │ ├── bad-sbom.json
│ │ │ ├── cosign.pub
│ │ │ ├── cosign_broken.pub
│ │ │ ├── image-simple/
│ │ │ │ ├── Dockerfile
│ │ │ │ ├── package.json
│ │ │ │ └── target/
│ │ │ │ └── nested/
│ │ │ │ └── package.json
│ │ │ ├── invalid.json
│ │ │ ├── purl/
│ │ │ │ ├── different-os.txt
│ │ │ │ ├── empty.json
│ │ │ │ ├── homogeneous-os.txt
│ │ │ │ ├── invalid-cpe.txt
│ │ │ │ ├── invalid-purl.txt
│ │ │ │ ├── valid-purl.txt
│ │ │ │ ├── valid-rhel-9+eus.txt
│ │ │ │ └── valid-rhel-9.txt
│ │ │ ├── sbom-with-intoto-string.json
│ │ │ ├── syft-java-bad-cpes.json
│ │ │ ├── syft-multiple-ecosystems.json
│ │ │ └── syft-spring.json
│ │ ├── upstream_package.go
│ │ ├── upstream_package_test.go
│ │ ├── version_format.go
│ │ └── version_format_test.go
│ ├── presenter/
│ │ ├── cyclonedx/
│ │ │ ├── presenter.go
│ │ │ ├── presenter_test.go
│ │ │ ├── testdata/
│ │ │ │ └── snapshot/
│ │ │ │ ├── TestCycloneDxPresenterDir.golden
│ │ │ │ └── TestCycloneDxPresenterImage.golden
│ │ │ ├── vulnerability.go
│ │ │ └── vulnerability_test.go
│ │ ├── explain/
│ │ │ ├── __snapshots__/
│ │ │ │ └── explain_snapshot_test.snap
│ │ │ ├── explain.go
│ │ │ ├── explain_cve.tmpl
│ │ │ ├── explain_snapshot_test.go
│ │ │ └── testdata/
│ │ │ ├── chainguard-ruby-test.json
│ │ │ ├── ghsa-test.json
│ │ │ └── keycloak-test.json
│ │ ├── internal/
│ │ │ └── test_helpers.go
│ │ ├── json/
│ │ │ ├── presenter.go
│ │ │ ├── presenter_test.go
│ │ │ └── testdata/
│ │ │ ├── image-simple/
│ │ │ │ ├── Dockerfile
│ │ │ │ ├── file-1.txt
│ │ │ │ ├── file-2.txt
│ │ │ │ └── target/
│ │ │ │ └── really/
│ │ │ │ └── nested/
│ │ │ │ └── file-3.txt
│ │ │ └── snapshot/
│ │ │ ├── TestEmptyJsonPresenter.golden
│ │ │ ├── TestJsonDirsPresenter.golden
│ │ │ ├── TestJsonImgsPresenter.golden
│ │ │ ├── anchore-fixture-image-simple.golden
│ │ │ └── stereoscope-fixture-image-simple.golden
│ │ ├── models/
│ │ │ ├── alert.go
│ │ │ ├── alert_test.go
│ │ │ ├── cvss.go
│ │ │ ├── descriptor.go
│ │ │ ├── distribution.go
│ │ │ ├── document.go
│ │ │ ├── document_test.go
│ │ │ ├── ignore.go
│ │ │ ├── ignore_test.go
│ │ │ ├── match.go
│ │ │ ├── metadata_mock.go
│ │ │ ├── package.go
│ │ │ ├── presenter_bundle.go
│ │ │ ├── sort.go
│ │ │ ├── sort_test.go
│ │ │ ├── source.go
│ │ │ ├── source_test.go
│ │ │ ├── vulnerability.go
│ │ │ ├── vulnerability_metadata.go
│ │ │ └── vulnerability_test.go
│ │ ├── presenter.go
│ │ ├── sarif/
│ │ │ ├── presenter.go
│ │ │ ├── presenter_test.go
│ │ │ └── testdata/
│ │ │ ├── image-simple/
│ │ │ │ ├── Dockerfile
│ │ │ │ ├── file-1.txt
│ │ │ │ ├── file-2.txt
│ │ │ │ └── target/
│ │ │ │ └── really/
│ │ │ │ └── nested/
│ │ │ │ └── file-3.txt
│ │ │ └── snapshot/
│ │ │ ├── TestSarifPresenter_directory.golden
│ │ │ └── TestSarifPresenter_image.golden
│ │ ├── table/
│ │ │ ├── __snapshots__/
│ │ │ │ └── presenter_test.snap
│ │ │ ├── presenter.go
│ │ │ ├── presenter_test.go
│ │ │ └── testdata/
│ │ │ └── snapshot/
│ │ │ └── TestTablePresenter_Color.golden
│ │ └── template/
│ │ ├── presenter.go
│ │ ├── presenter_test.go
│ │ └── testdata/
│ │ ├── snapshot/
│ │ │ └── TestPresenter_Present.golden
│ │ ├── test.template
│ │ ├── test.template.sprig.date
│ │ └── test.valid.template
│ ├── search/
│ │ ├── cpe.go
│ │ ├── cpe_test.go
│ │ ├── criteria.go
│ │ ├── criteria_test.go
│ │ ├── distro.go
│ │ ├── distro_test.go
│ │ ├── ecosystem.go
│ │ ├── ecosystem_test.go
│ │ ├── func.go
│ │ ├── func_test.go
│ │ ├── id.go
│ │ ├── id_test.go
│ │ ├── package_name.go
│ │ ├── package_name_test.go
│ │ ├── unaffected.go
│ │ ├── version_constraint.go
│ │ └── version_constraint_test.go
│ ├── version/
│ │ ├── apk_version.go
│ │ ├── apk_version_test.go
│ │ ├── bitnami_version.go
│ │ ├── bitnami_version_test.go
│ │ ├── combined_constraint.go
│ │ ├── combined_constraint_test.go
│ │ ├── comparator.go
│ │ ├── constraint.go
│ │ ├── deb_version.go
│ │ ├── deb_version_test.go
│ │ ├── deprecated.go
│ │ ├── error.go
│ │ ├── format.go
│ │ ├── format_test.go
│ │ ├── fuzzy_constraint.go
│ │ ├── fuzzy_constraint_test.go
│ │ ├── fuzzy_version.go
│ │ ├── fuzzy_version_test.go
│ │ ├── gem_version.go
│ │ ├── gem_version_test.go
│ │ ├── generic_constraint.go
│ │ ├── generic_constraint_test.go
│ │ ├── golang_version.go
│ │ ├── golang_version_test.go
│ │ ├── helper_test.go
│ │ ├── jvm_version.go
│ │ ├── jvm_version_test.go
│ │ ├── kb_constraint.go
│ │ ├── kb_constraint_test.go
│ │ ├── kb_version.go
│ │ ├── kb_version_test.go
│ │ ├── maven_version.go
│ │ ├── maven_version_test.go
│ │ ├── operator.go
│ │ ├── pacman_version.go
│ │ ├── pacman_version_test.go
│ │ ├── pep440_version.go
│ │ ├── pep440_version_test.go
│ │ ├── portage_version.go
│ │ ├── portage_version_test.go
│ │ ├── range.go
│ │ ├── range_expression.go
│ │ ├── range_expression_test.go
│ │ ├── range_test.go
│ │ ├── rpm_version.go
│ │ ├── rpm_version_test.go
│ │ ├── semantic_version.go
│ │ ├── semantic_version_test.go
│ │ ├── set.go
│ │ ├── set_test.go
│ │ ├── version.go
│ │ └── version_test.go
│ ├── vex/
│ │ ├── csaf/
│ │ │ ├── csaf.go
│ │ │ ├── csaf_test.go
│ │ │ ├── implementation.go
│ │ │ ├── implementation_test.go
│ │ │ └── status.go
│ │ ├── openvex/
│ │ │ ├── implementation.go
│ │ │ └── implementation_test.go
│ │ ├── processor.go
│ │ ├── processor_test.go
│ │ ├── status/
│ │ │ └── status.go
│ │ └── testdata/
│ │ └── vex-docs/
│ │ ├── csaf-demo1.json
│ │ ├── csaf-demo2.json
│ │ ├── openvex-debian.json
│ │ ├── openvex-demo1.json
│ │ ├── openvex-demo2.json
│ │ ├── openvex-image-no-subcomponents.json
│ │ └── openvex-package-product.json
│ ├── vulnerability/
│ │ ├── advisory.go
│ │ ├── fix.go
│ │ ├── metadata.go
│ │ ├── metadata_test.go
│ │ ├── mock/
│ │ │ └── vulnerability_provider.go
│ │ ├── provider.go
│ │ ├── severity.go
│ │ └── vulnerability.go
│ ├── vulnerability_matcher.go
│ └── vulnerability_matcher_test.go
├── install.sh
├── internal/
│ ├── bus/
│ │ ├── bus.go
│ │ └── helpers.go
│ ├── cvss/
│ │ ├── metrics.go
│ │ └── metrics_test.go
│ ├── dbtest/
│ │ ├── default_vulnerabilities.go
│ │ ├── server.go
│ │ └── server_test.go
│ ├── file/
│ │ ├── copy.go
│ │ ├── exists.go
│ │ ├── getter.go
│ │ ├── getter_test.go
│ │ ├── hasher.go
│ │ ├── hasher_test.go
│ │ ├── tar_xz_decompressor.go
│ │ ├── tar_xz_decompressor_test.go
│ │ ├── xz_decompressor.go
│ │ └── xz_decompressor_test.go
│ ├── format/
│ │ ├── format.go
│ │ ├── format_test.go
│ │ ├── presenter.go
│ │ ├── writer.go
│ │ └── writer_test.go
│ ├── input.go
│ ├── log/
│ │ ├── errors.go
│ │ └── log.go
│ ├── redact/
│ │ └── redact.go
│ ├── regex_helpers.go
│ ├── regex_helpers_test.go
│ ├── schemaver/
│ │ ├── schema_ver.go
│ │ └── schema_ver_test.go
│ ├── stringutil/
│ │ ├── color.go
│ │ ├── parse.go
│ │ ├── string_helpers.go
│ │ ├── string_helpers_test.go
│ │ ├── stringset.go
│ │ └── tprint.go
│ └── testutils/
│ └── golden_file.go
├── llms.txt
├── schema/
│ └── grype/
│ ├── db/
│ │ ├── README.md
│ │ ├── blob/
│ │ │ └── json/
│ │ │ ├── schema-6.1.1.json
│ │ │ ├── schema-6.1.2.json
│ │ │ ├── schema-6.1.3.json
│ │ │ ├── schema-6.1.4.json
│ │ │ └── schema-latest.json
│ │ └── sql/
│ │ ├── schema-6.1.1.sql
│ │ ├── schema-6.1.2.sql
│ │ ├── schema-6.1.3.sql
│ │ ├── schema-6.1.4.sql
│ │ └── schema-latest.sql
│ ├── db-search/
│ │ └── json/
│ │ ├── README.md
│ │ ├── schema-1.0.0.json
│ │ ├── schema-1.0.1.json
│ │ ├── schema-1.0.2.json
│ │ ├── schema-1.0.3.json
│ │ ├── schema-1.1.0.json
│ │ ├── schema-1.1.1.json
│ │ ├── schema-1.1.2.json
│ │ ├── schema-1.1.3.json
│ │ └── schema-latest.json
│ └── db-search-vuln/
│ └── json/
│ ├── README.md
│ ├── schema-1.0.0.json
│ ├── schema-1.0.1.json
│ ├── schema-1.0.3.json
│ ├── schema-1.0.4.json
│ ├── schema-1.0.5.json
│ └── schema-latest.json
├── templates/
│ ├── README.md
│ ├── csv.tmpl
│ ├── html.tmpl
│ ├── junit.tmpl
│ ├── markdown.tmpl
│ └── table.tmpl
└── test/
├── cli/
│ ├── cmd_test.go
│ ├── config_test.go
│ ├── db_providers_test.go
│ ├── db_validations_test.go
│ ├── registry_auth_test.go
│ ├── sbom_input_test.go
│ ├── subprocess_test.go
│ ├── testdata/
│ │ ├── Makefile
│ │ ├── another_cosign.pub
│ │ ├── configs/
│ │ │ ├── dir1/
│ │ │ │ └── .grype.yaml
│ │ │ ├── dir2/
│ │ │ │ └── .grype.yaml
│ │ │ └── dir3/
│ │ │ └── .grype.yaml
│ │ ├── cosign.pub
│ │ ├── cosign_broken.pub
│ │ ├── empty.json
│ │ ├── image-bare/
│ │ │ ├── Dockerfile
│ │ │ └── file-1.txt
│ │ ├── image-java-subprocess/
│ │ │ ├── Dockerfile
│ │ │ └── app.java
│ │ ├── image-node-subprocess/
│ │ │ ├── Dockerfile
│ │ │ └── app.js
│ │ ├── sbom-grype-source.json
│ │ ├── sbom-ubuntu-20.04--pruned.json
│ │ └── test-ignore-reason/
│ │ ├── config-with-ignore.yaml
│ │ ├── sbom.json
│ │ └── template-with-ignore-reasons
│ ├── trait_assertions_test.go
│ ├── utils_test.go
│ └── version_cmd_test.go
├── grype-test-config.yaml
├── ignore-att-signature.yaml
├── install/
│ ├── .dockerignore
│ ├── .gitignore
│ ├── 0_checksums_test.sh
│ ├── 1_download_snapshot_asset_test.sh
│ ├── 2_download_release_asset_test.sh
│ ├── 3_install_asset_test.sh
│ ├── 4_prep_signature_verification_test.sh
│ ├── Makefile
│ ├── environments/
│ │ ├── Dockerfile-alpine-3.6
│ │ ├── Dockerfile-busybox-1.36
│ │ └── Dockerfile-ubuntu-20.04
│ ├── github_test.sh
│ ├── test_harness.sh
│ └── testdata/
│ ├── assets/
│ │ ├── invalid/
│ │ │ ├── .gitignore
│ │ │ └── checksums.txt
│ │ └── valid/
│ │ ├── .gitignore
│ │ └── checksums.txt
│ ├── github-api-grype-v0.32.0-release.json
│ ├── grype_0.32.0-SNAPSHOT-d461f63_checksums.txt
│ └── grype_0.32.0_checksums.txt
├── integration/
│ ├── compare_sbom_input_vs_lib_test.go
│ ├── db_mock_test.go
│ ├── match_by_image_test.go
│ ├── match_by_sbom_document_test.go
│ ├── testdata/
│ │ ├── .gitignore
│ │ ├── Makefile
│ │ ├── image-alpine-match-coverage/
│ │ │ ├── Dockerfile
│ │ │ ├── etc/
│ │ │ │ └── os-release
│ │ │ └── lib/
│ │ │ └── apk/
│ │ │ └── db/
│ │ │ └── installed
│ │ ├── image-arch-match-coverage/
│ │ │ └── Dockerfile
│ │ ├── image-centos-match-coverage/
│ │ │ ├── Dockerfile
│ │ │ ├── etc/
│ │ │ │ └── os-release
│ │ │ └── var/
│ │ │ └── lib/
│ │ │ └── rpm/
│ │ │ ├── Packages
│ │ │ └── generate-fixture.sh
│ │ ├── image-debian-match-coverage/
│ │ │ ├── Dockerfile
│ │ │ ├── dotnet/
│ │ │ │ └── TestLibrary.deps.json
│ │ │ ├── golang/
│ │ │ │ ├── go.mod
│ │ │ │ ├── go.sum
│ │ │ │ └── main.go
│ │ │ ├── haskell/
│ │ │ │ ├── cabal.project.freeze
│ │ │ │ └── stack.yaml
│ │ │ ├── java/
│ │ │ │ └── generate-fixtures.md
│ │ │ ├── javascript/
│ │ │ │ └── pkg-json/
│ │ │ │ └── package.json
│ │ │ ├── python/
│ │ │ │ └── dist-info/
│ │ │ │ ├── METADATA
│ │ │ │ └── top_level.txt
│ │ │ ├── ruby/
│ │ │ │ └── specifications/
│ │ │ │ └── bundler.gemspec
│ │ │ ├── usr/
│ │ │ │ └── lib/
│ │ │ │ └── os-release
│ │ │ └── var/
│ │ │ └── lib/
│ │ │ └── dpkg/
│ │ │ └── status
│ │ ├── image-jvm-match-coverage/
│ │ │ ├── Dockerfile
│ │ │ └── opt/
│ │ │ └── java/
│ │ │ └── openjdk/
│ │ │ └── release
│ │ ├── image-portage-match-coverage/
│ │ │ ├── Dockerfile
│ │ │ ├── etc/
│ │ │ │ └── os-release
│ │ │ └── var/
│ │ │ └── db/
│ │ │ ├── pkg/
│ │ │ │ └── app-containers/
│ │ │ │ └── skopeo-1.5.1/
│ │ │ │ ├── CONTENTS
│ │ │ │ ├── LICENSE
│ │ │ │ └── SIZE
│ │ │ └── repos/
│ │ │ └── gentoo/
│ │ │ └── skel.ebuild
│ │ ├── image-rust-auditable-match-coverage/
│ │ │ └── Dockerfile
│ │ ├── image-sles-match-coverage/
│ │ │ ├── Dockerfile
│ │ │ ├── etc/
│ │ │ │ └── os-release
│ │ │ └── var/
│ │ │ └── lib/
│ │ │ └── rpm/
│ │ │ ├── Packages
│ │ │ └── generate-fixture.sh
│ │ ├── sbom/
│ │ │ ├── syft-sbom-with-kb-packages.json
│ │ │ └── syft-sbom-with-unknown-packages.json
│ │ ├── skopeo-policy.json
│ │ ├── snapshot/
│ │ │ └── TestDatabaseDiff.golden
│ │ └── vex/
│ │ ├── csaf/
│ │ │ ├── affected.csaf.json
│ │ │ └── under_investigation.csaf.json
│ │ └── openvex/
│ │ ├── affected.openvex.json
│ │ └── under_investigation.openvex.json
│ └── utils_test.go
├── quality/
│ ├── .gitignore
│ ├── .grype.yaml
│ ├── .python-version
│ ├── .yardstick.yaml
│ ├── Makefile
│ ├── README.md
│ ├── requirements.txt
│ └── test-db
└── validate-grype-db-schema.py
================================================
FILE CONTENTS
================================================
================================================
FILE: .binny.yaml
================================================
tools:
# we want to use a pinned version of binny to manage the toolchain (so binny manages itself!)
- name: binny
version:
want: v0.12.0
method: github-release
with:
repo: anchore/binny
# used to produce SBOMs during release
- name: syft
version:
want: latest
method: github-release
with:
repo: anchore/syft
# used to sign mac binaries at release
- name: quill
version:
want: v0.7.1
method: github-release
with:
repo: anchore/quill
# used for linting
- name: golangci-lint
version:
want: v2.11.3
method: github-release
with:
repo: golangci/golangci-lint
# used for showing the changelog at release
- name: glow
version:
want: v2.1.1
method: github-release
with:
repo: charmbracelet/glow
# used for signing the checksums file at release
- name: cosign
version:
want: v3.0.5
method: github-release
with:
repo: sigstore/cosign
# used to release all artifacts
- name: goreleaser
version:
want: v2.14.3
method: github-release
with:
repo: goreleaser/goreleaser
# used for organizing imports during static analysis
- name: gosimports
version:
want: v0.3.8
method: github-release
with:
repo: rinchsan/gosimports
# used at release to generate the changelog
- name: chronicle
version:
want: v0.8.0
method: github-release
with:
repo: anchore/chronicle
# used during static analysis for license compliance
- name: bouncer
version:
want: v0.4.0
method: github-release
with:
repo: wagoodman/go-bouncer
# used for running all local and CI tasks
- name: task
version:
want: v3.49.1
method: github-release
with:
repo: go-task/task
# used for triggering a release
- name: gh
version:
want: v2.88.1
method: github-release
with:
repo: cli/cli
# used for integration tests
- name: skopeo
version:
want: v1.22.0
method: go-install
with:
module: github.com/containers/skopeo
entrypoint: cmd/skopeo
args:
- "-tags"
- containers_image_openpgp
env:
- CGO_ENABLED=0
- GO_DYN_FLAGS=""
================================================
FILE: .bouncer.yaml
================================================
permit:
- BSD.*
- CC0.*
- MIT.*
- Apache.*
- MPL.*
- ISC
- WTFPL
ignore-packages:
# packageurl-go is released under the MIT license located in the root of the repo at /mit.LICENSE
- github.com/anchore/packageurl-go
# github.com/gocsaf/csaf is released under the Apache License, version 2.0 (Apache-2.0)
# https://github.com/gocsaf/csaf/blob/main/LICENSE-Apache-2.0.txt
- github.com/gocsaf/csaf/v3/csaf
- github.com/gocsaf/csaf/v3/internal/misc
- github.com/gocsaf/csaf/v3/util
# tools-golang is released under the Apache License, version 2.0 (Apache-2.0)
# https://github.com/spdx/tools-golang/blob/main/LICENSE.code
- github.com/spdx/tools-golang
# crypto/internal/boring is released under the openSSL license as a part of the Golang Standard Libary
- crypto/internal/boring
# from: https://github.com/xi2/xz/blob/master/LICENSE
# All these files have been put into the public domain.
# You can do whatever you want with these files.
- github.com/xi2/xz
# from: https://github.com/owenrumney/go-sarif/blob/main/LICENSE
# This is released into the public domain using the "Unlicense license"
- github.com/owenrumney/go-sarif
# github.com/sorairolake/lzip-go is released under the Apache License, version 2.0 (Apache-2.0)
# https://github.com/sorairolake/lzip-go/blob/develop/LICENSE-APACHE
- github.com/sorairolake/lzip-go
# from: https://gitlab.com/cznic/sqlite/-/blob/v1.66.3/LICENSE
# This is a BSD-3-Clause license
- modernc.org/libc
- modernc.org/libc/errno
- modernc.org/libc/fcntl
- modernc.org/libc/fts
- modernc.org/libc/grp
- modernc.org/libc/langinfo
- modernc.org/libc/limits
- modernc.org/libc/netdb
- modernc.org/libc/netinet/in
- modernc.org/libc/poll
- modernc.org/libc/pthread
- modernc.org/libc/pwd
- modernc.org/libc/signal
- modernc.org/libc/stdio
- modernc.org/libc/stdlib
- modernc.org/libc/sys/socket
- modernc.org/libc/sys/stat
- modernc.org/libc/sys/types
- modernc.org/libc/termios
- modernc.org/libc/time
- modernc.org/libc/unistd
- modernc.org/libc/utime
- modernc.org/libc/uuid/uuid
- modernc.org/libc/wctype
- modernc.org/mathutil
- modernc.org/memory
================================================
FILE: .chronicle.yaml
================================================
enforce-v0: true # don't make breaking-change label bump major version before 1.0.
title: ""
================================================
FILE: .github/ISSUE_TEMPLATE/bug_report.md
================================================
---
name: Bug report
about: Create a report to help us improve
title: ''
labels: bug
assignees: ''
---
**What happened**:
**What you expected to happen**:
**How to reproduce it (as minimally and precisely as possible)**:
<!--
If possible, please include a link to an artifact grype can scan, instructions to make
one, or upload it on this issue. Some suggestions:
1. Link to Dockerhub, GitHub, GitLab, maven central, quay.io, etc to a public
artifact we can try scanning
2. A Dockerfile that we can build and scan
3. A simple script that creates a directory exhibiting the issue, for example a
list of `npm install` commands
Please also include the grype command and any configuration used.
-->
**Anything else we need to know?**:
**Environment**:
- Output of `grype version`:
- OS (e.g: `cat /etc/os-release` or similar):
================================================
FILE: .github/ISSUE_TEMPLATE/config.yml
================================================
contact_links:
- name: Join our Discourse community 💬
# link to our community Discourse site
url: https://anchore.com/discourse
about: 'Come chat with us! Ask for help, join our software development efforts, or just give us feedback!'
================================================
FILE: .github/ISSUE_TEMPLATE/feature_request.md
================================================
---
name: Feature request
about: Suggest an idea for this project
title: ''
labels: enhancement
assignees: ''
---
**What would you like to be added**:
**Why is this needed**:
**Additional context**:
<!-- Add any other context or screenshots about the feature request here. -->
================================================
FILE: .github/ISSUE_TEMPLATE/match_issue.md
================================================
---
name: Vulnerability Match Issue
about: Report an issue with vulnerability matching
title: ''
labels: [ bug, false-positive ]
assignees: ''
---
**Vulnerability ID**:
<!-- CVE, GHSA, etc. -->
**Package URL or steps to reproduce**:
<!--
Running `grype <PackageURL>` should show the matching issue. If it does, please provide
the full Package URL, e.g.: pkg:apk/alpine/alpine-baselayout@3.7.0-r0?arch=x86_64&distro=alpine-3.22.2
make sure to include all parameters, including the distro, where applicable.
If the issue can't be reproduced with a Package URL, please link to a public artifact
grype can scan or provide other instructions to reproduce.
Some suggestions:
1. Link to Dockerhub, GitHub, GitLab, maven central, quay.io, etc to a public
artifact we can try scanning
2. A Dockerfile that we can build and scan
3. A simple script that creates a directory exhibiting the issue, for example a
list of `npm install` commands
Please also include the grype command and any configuration used.
-->
**Anything else we need to know?**:
<!-- Add additional information here:
Some suggestions:
1. Links to the GHSA or CVE page(s)
2. Explanation why a vulnerability is or isn't applicable
-->
**Environment**:
- Output of `grype version`:
- OS (e.g: `cat /etc/os-release` or similar):
================================================
FILE: .github/actions/bootstrap/action.yaml
================================================
name: "Bootstrap"
description: "Bootstrap all tools and dependencies"
inputs:
go-version:
description: "Go version to install"
required: true
default: "1.25.x"
python-version:
description: "Python version to install"
required: true
default: "3.11"
go-dependencies:
description: "Download go dependencies"
required: true
default: "true"
cache-key-prefix:
description: "Prefix all cache keys with this value"
required: true
default: "1ac8281053"
compute-fingerprints:
description: "Compute test fixture fingerprints"
required: true
default: "true"
tools:
description: "whether to install tools"
default: "true"
bootstrap-apt-packages:
description: "Space delimited list of tools to install via apt"
default: "libxml2-utils"
runs:
using: "composite"
steps:
# note: go mod and build is automatically cached on default with v4+
- uses: actions/setup-go@4b73464bb391d4059bd26b0524d20df3927bd417 # v6.3.0
if: inputs.go-version != ''
with:
go-version: ${{ inputs.go-version }}
check-latest: true
- uses: actions/setup-python@a309ff8b426b58ec0e2a45f0f869d46889d02405 # v6.2.0
with:
python-version: ${{ inputs.python-version }}
- name: Restore tool cache
id: tool-cache
uses: actions/cache@cdf6c1fa76f9f475f3d7449005a359c84ca0f306 # v5.0.3
if: inputs.tools == 'true'
with:
path: ${{ github.workspace }}/.tool
key: ${{ inputs.cache-key-prefix }}-${{ runner.os }}-tool-${{ hashFiles('.binny.yaml') }}
- name: Install project tools
if: inputs.tools == 'true'
shell: bash
run: |
make tools
.tool/binny list
.tool/binny check
- name: Install go dependencies
if: inputs.go-dependencies == 'true'
shell: bash
run: make ci-bootstrap-go
- name: Install apt packages
if: inputs.bootstrap-apt-packages != ''
shell: bash
run: |
read -ra PACKAGES <<< "$BOOTSTRAP_APT_PACKAGES"
DEBIAN_FRONTEND=noninteractive sudo apt update && sudo -E apt install -y "${PACKAGES[@]}"
env:
BOOTSTRAP_APT_PACKAGES: ${{ inputs.bootstrap-apt-packages }}
- name: Create all cache fingerprints
if: inputs.compute-fingerprints == 'true'
shell: bash
run: make fingerprints
================================================
FILE: .github/dependabot.yaml
================================================
version: 2
updates:
- package-ecosystem: "github-actions"
directory: "/"
schedule:
interval: daily
cooldown:
default-days: 7
- package-ecosystem: "github-actions"
directory: "/.github/actions/bootstrap"
schedule:
interval: "daily"
open-pull-requests-limit: 10
labels:
- "dependencies"
cooldown:
default-days: 7
- package-ecosystem: "gomod"
directory: "/"
schedule:
interval: daily
cooldown:
default-days: 7
================================================
FILE: .github/scripts/check-syft-version-is-release.sh
================================================
#!/usr/bin/env bash
set -e
version=$(grep -E "github.com/anchore/syft" go.mod | awk '{print $NF}')
# ensure that the version is a release version (not a commit hash)
# a release in this case means that the go tooling resolved the version to a tag
# this does not guarantee that the tag has a github release associated with it
if [[ ! $version =~ ^v[0-9]+\.[0-9]+\.[0-9]?$ ]]; then
echo "syft version in go.mod is not a release version: $version"
echo "please update the version in go.mod to a release version and try again"
exit 1
else
echo "syft version in go.mod is a release version: $version"
fi
================================================
FILE: .github/scripts/ci-check.sh
================================================
#!/usr/bin/env bash
red=$(tput setaf 1)
bold=$(tput bold)
normal=$(tput sgr0)
# assert we are running in CI (or die!)
if [[ -z "$CI" ]]; then
echo "${bold}${red}This step should ONLY be run in CI. Exiting...${normal}"
exit 1
fi
================================================
FILE: .github/scripts/coverage.py
================================================
#!/usr/bin/env python3
import subprocess
import sys
import shlex
class bcolors:
HEADER = '\033[95m'
OKBLUE = '\033[94m'
OKCYAN = '\033[96m'
OKGREEN = '\033[92m'
WARNING = '\033[93m'
FAIL = '\033[91m'
ENDC = '\033[0m'
BOLD = '\033[1m'
UNDERLINE = '\033[4m'
if len(sys.argv) < 3:
print("Usage: coverage.py [threshold] [go-coverage-report]")
sys.exit(1)
threshold = float(sys.argv[1])
report = sys.argv[2]
args = shlex.split(f"go tool cover -func {report}")
p = subprocess.run(args, capture_output=True, text=True)
percent_coverage = float(p.stdout.splitlines()[-1].split()[-1].replace("%", ""))
print(f"{bcolors.BOLD}Coverage: {percent_coverage}%{bcolors.ENDC}")
if percent_coverage < threshold:
print(f"{bcolors.BOLD}{bcolors.FAIL}Coverage below threshold of {threshold}%{bcolors.ENDC}")
sys.exit(1)
================================================
FILE: .github/scripts/db-schema-drift-check.sh
================================================
#!/usr/bin/env bash
set -u
if [ "$(git status --porcelain | wc -l)" -ne "0" ]; then
echo " 🔴 there are uncommitted changes, please commit them before running this check"
exit 1
fi
if ! make generate-db-schema; then
echo "Generating database blob schemas failed"
exit 1
fi
if [ "$(git status --porcelain | wc -l)" -ne "0" ]; then
echo " 🔴 database blob schemas have uncommitted changes"
echo " Run 'task generate-db-schema' and commit the changes"
echo ""
git status --porcelain
echo ""
git diff schema/grype/db/
exit 1
fi
echo "✅ Database blob schemas are up to date"
================================================
FILE: .github/scripts/go-mod-tidy-check.sh
================================================
#!/usr/bin/env bash
set -eu
ORIGINAL_STATE_DIR=$(mktemp -d "TEMP-original-state-XXXXXXXXX")
TIDY_STATE_DIR=$(mktemp -d "TEMP-tidy-state-XXXXXXXXX")
trap "cp -p ${ORIGINAL_STATE_DIR}/* ./ && git update-index -q --refresh && rm -fR ${ORIGINAL_STATE_DIR} ${TIDY_STATE_DIR}" EXIT
# capturing original state of files...
cp go.mod go.sum "${ORIGINAL_STATE_DIR}"
# capturing state of go.mod and go.sum after running go mod tidy...
go mod tidy
cp go.mod go.sum "${TIDY_STATE_DIR}"
set +e
# detect difference between the git HEAD state and the go mod tidy state
DIFF_MOD=$(diff -u "${ORIGINAL_STATE_DIR}/go.mod" "${TIDY_STATE_DIR}/go.mod")
DIFF_SUM=$(diff -u "${ORIGINAL_STATE_DIR}/go.sum" "${TIDY_STATE_DIR}/go.sum")
if [[ -n "${DIFF_MOD}" || -n "${DIFF_SUM}" ]]; then
echo "go.mod diff:"
echo "${DIFF_MOD}"
echo "go.sum diff:"
echo "${DIFF_SUM}"
echo ""
printf "FAILED! go.mod and/or go.sum are NOT tidy; please run 'go mod tidy'.\n\n"
exit 1
fi
================================================
FILE: .github/scripts/json-schema-drift-check.sh
================================================
#!/usr/bin/env bash
set -u
if [ "$(git status --porcelain | wc -l)" -ne "0" ]; then
echo " 🔴 there are uncommitted changes, please commit them before running this check"
exit 1
fi
if ! make generate-json-schema; then
echo "Generating json schema failed"
exit 1
fi
if [ "$(git status --porcelain | wc -l)" -ne "0" ]; then
echo " 🔴 there are uncommitted changes, please commit them before running this check"
exit 1
fi
================================================
FILE: .github/scripts/trigger-release.sh
================================================
#!/usr/bin/env bash
set -eu
bold=$(tput bold)
normal=$(tput sgr0)
GH_CLI=.tool/gh
if ! [ -x "$(command -v $GH_CLI)" ]; then
echo "The GitHub CLI could not be found. run: make bootstrap"
exit 1
fi
# we want to stop the release as early as possible if the version is not a release version
./.github/scripts/check-syft-version-is-release.sh
$GH_CLI auth status
# set the default repo in cases where multiple remotes are defined
$GH_CLI repo set-default anchore/grype
export GITHUB_TOKEN="${GITHUB_TOKEN-"$($GH_CLI auth token)"}"
# we need all of the git state to determine the next version. Since tagging is done by
# the release pipeline it is possible to not have all of the tags from previous releases.
git fetch --tags
# populates the CHANGELOG.md and VERSION files
echo "${bold}Generating changelog...${normal}"
make changelog 2> /dev/null
NEXT_VERSION=$(cat VERSION)
if [[ "$NEXT_VERSION" == "" || "${NEXT_VERSION}" == "(Unreleased)" ]]; then
echo "Could not determine the next version to release. Exiting..."
exit 1
fi
while true; do
read -p "${bold}Do you want to trigger a release for version '${NEXT_VERSION}'?${normal} [y/n] " yn
case $yn in
[Yy]* ) echo; break;;
[Nn]* ) echo; echo "Cancelling release..."; exit;;
* ) echo "Please answer yes or no.";;
esac
done
echo "${bold}Kicking off release for ${NEXT_VERSION}${normal}..."
echo
$GH_CLI workflow run release.yaml -f version=${NEXT_VERSION}
echo
echo "${bold}Waiting for release to start...${normal}"
sleep 10
set +e
echo "${bold}Head to the release workflow to monitor the release:${normal} $($GH_CLI run list --workflow=release.yaml --limit=1 --json url --jq '.[].url')"
id=$($GH_CLI run list --workflow=release.yaml --limit=1 --json databaseId --jq '.[].databaseId')
$GH_CLI run watch $id --exit-status || (echo ; echo "${bold}Logs of failed step:${normal}" && GH_PAGER="" $GH_CLI run view $id --log-failed)
================================================
FILE: .github/workflows/codeql-analysis.yml
================================================
name: CodeQL Security Scan
on:
workflow_dispatch:
push:
paths:
- '**'
- '!**.md'
- '!LICENSE'
- '!test/**'
branches: [ main ]
schedule:
- cron: '0 14 * * 4'
jobs:
CodeQL:
uses: anchore/workflows/.github/workflows/codeql-go.yaml@main
with:
entrypoint: "./cmd/${{ github.event.repository.name }}"
permissions:
security-events: write
contents: read
================================================
FILE: .github/workflows/dependabot-automation.yaml
================================================
name: Dependabot Automation
on:
pull_request:
permissions:
pull-requests: write
jobs:
run:
uses: anchore/workflows/.github/workflows/dependabot-automation.yaml@main
================================================
FILE: .github/workflows/oss-project-board-add.yaml
================================================
name: Add to OSS board
permissions:
contents: read
on:
issues:
types:
- opened
- reopened
- transferred
- labeled
jobs:
run:
uses: "anchore/workflows/.github/workflows/oss-project-board-add.yaml@main"
secrets:
token: ${{ secrets.OSS_PROJECT_GH_TOKEN }}
================================================
FILE: .github/workflows/release.yaml
================================================
name: "Release"
on:
workflow_dispatch:
inputs:
version:
description: tag the latest commit on main with the given version (prefixed with v)
required: true
skip_quality_gate:
description: skip quality gate and proceed directly to releasing (for emergency releases)
type: boolean
default: false
permissions:
contents: read
jobs:
quality-gate:
if: ${{ !inputs.skip_quality_gate }}
environment: release
runs-on: ubuntu-24.04
steps:
- uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd #v6.0.2
with:
persist-credentials: false
- name: Check if running on main
if: github.ref != 'refs/heads/main'
# we are using the following flag when running `cosign blob-verify` for checksum signature verification:
# --certificate-identity-regexp "https://github.com/anchore/.github/workflows/release.yaml@refs/heads/main"
# if we are not on the main branch, the signature will not be verifiable since the suffix requires the main branch
# at the time of when the OIDC token was issued on the Github Actions runner.
run: echo "This can only be run on the main branch otherwise releases produced will not be verifiable with cosign" && exit 1
- uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd #v6.0.2
with:
persist-credentials: false
- name: Check if pinned syft is a release version
run: .github/scripts/check-syft-version-is-release.sh
- name: Check if tag already exists
# note: this will fail if the tag already exists
run: |
[[ "$VERSION" == v* ]] || (echo "version '$VERSION' does not have a 'v' prefix" && exit 1)
git tag "$VERSION"
env:
VERSION: ${{ github.event.inputs.version }}
- name: Check static analysis results
uses: fountainhead/action-wait-for-check@5a908a24814494009c4bb27c242ea38c93c593be # v1.2.0
id: static-analysis
with:
token: ${{ secrets.GITHUB_TOKEN }}
# This check name is defined as the github action job name (in .github/workflows/testing.yaml)
checkName: "Static analysis"
ref: ${{ github.event.pull_request.head.sha || github.sha }}
- name: Check unit test results
uses: fountainhead/action-wait-for-check@5a908a24814494009c4bb27c242ea38c93c593be # v1.2.0
id: unit
with:
token: ${{ secrets.GITHUB_TOKEN }}
# This check name is defined as the github action job name (in .github/workflows/testing.yaml)
checkName: "Unit tests"
ref: ${{ github.event.pull_request.head.sha || github.sha }}
- name: Check integration test results
uses: fountainhead/action-wait-for-check@5a908a24814494009c4bb27c242ea38c93c593be # v1.2.0
id: integration
with:
token: ${{ secrets.GITHUB_TOKEN }}
# This check name is defined as the github action job name (in .github/workflows/testing.yaml)
checkName: "Integration tests"
timeoutSeconds: 1200 # 20 minutes, it sometimes takes that long
ref: ${{ github.event.pull_request.head.sha || github.sha }}
- name: Check integration test results
uses: fountainhead/action-wait-for-check@5a908a24814494009c4bb27c242ea38c93c593be # v1.2.0
id: quality_tests
with:
token: ${{ secrets.GITHUB_TOKEN }}
# This check name is defined as the github action job name (in .github/workflows/testing.yaml)
checkName: "Quality tests"
timeoutSeconds: 1200 # 20 minutes, it sometimes takes that long
ref: ${{ github.event.pull_request.head.sha || github.sha }}
- name: Check acceptance test results (linux)
uses: fountainhead/action-wait-for-check@5a908a24814494009c4bb27c242ea38c93c593be # v1.2.0
id: acceptance-linux
with:
token: ${{ secrets.GITHUB_TOKEN }}
# This check name is defined as the github action job name (in .github/workflows/testing.yaml)
checkName: "Acceptance tests (Linux)"
ref: ${{ github.event.pull_request.head.sha || github.sha }}
- name: Check acceptance test results (mac)
uses: fountainhead/action-wait-for-check@5a908a24814494009c4bb27c242ea38c93c593be # v1.2.0
id: acceptance-mac
with:
token: ${{ secrets.GITHUB_TOKEN }}
# This check name is defined as the github action job name (in .github/workflows/testing.yaml)
checkName: "Acceptance tests (Mac)"
ref: ${{ github.event.pull_request.head.sha || github.sha }}
- name: Check cli test results (linux)
uses: fountainhead/action-wait-for-check@5a908a24814494009c4bb27c242ea38c93c593be # v1.2.0
id: cli-linux
with:
token: ${{ secrets.GITHUB_TOKEN }}
# This check name is defined as the github action job name (in .github/workflows/testing.yaml)
checkName: "CLI tests (Linux)"
ref: ${{ github.event.pull_request.head.sha || github.sha }}
- name: Quality gate
if: steps.static-analysis.outputs.conclusion != 'success' || steps.unit.outputs.conclusion != 'success' || steps.integration.outputs.conclusion != 'success' || steps.quality_tests.outputs.conclusion != 'success' || steps.cli-linux.outputs.conclusion != 'success' || steps.acceptance-linux.outputs.conclusion != 'success' || steps.acceptance-mac.outputs.conclusion != 'success'
env:
STATIC_ANALYSIS_STATUS: ${{ steps.static-analysis.conclusion }}
UNIT_TEST_STATUS: ${{ steps.unit.outputs.conclusion }}
INTEGRATION_TEST_STATUS: ${{ steps.integration.outputs.conclusion }}
QUALITY_TEST_STATUS: ${{ steps.quality_tests.outputs.conclusion }}
ACCEPTANCE_LINUX_STATUS: ${{ steps.acceptance-linux.outputs.conclusion }}
ACCEPTANCE_MAC_STATUS: ${{ steps.acceptance-mac.outputs.conclusion }}
CLI_LINUX_STATUS: ${{ steps.cli-linux.outputs.conclusion }}
run: |
echo "Static Analysis Status: $STATIC_ANALYSIS_STATUS"
echo "Unit Test Status: $UNIT_TEST_STATUS"
echo "Integration Test Status: $INTEGRATION_TEST_STATUS"
echo "Quality Test Status: $QUALITY_TEST_STATUS"
echo "Acceptance Test (Linux) Status: $ACCEPTANCE_LINUX_STATUS"
echo "Acceptance Test (Mac) Status: $ACCEPTANCE_MAC_STATUS"
echo "CLI Test (Linux) Status: $CLI_LINUX_STATUS"
false
# only release core assets within the "release" job. Any other assets not already under the purview of the
# goreleaser configuration should be added as separate jobs to allow for debugging separately from the release workflow
# as well as not accidentally be re-run as a step multiple times (as could be done within the release workflow) as
# not all actions are guaranteed to be idempotent.
release:
needs: [quality-gate]
if: ${{ always() && (needs.quality-gate.result == 'success' || inputs.skip_quality_gate) }}
runs-on: ubuntu-24.04
permissions:
contents: write
packages: write
id-token: write
steps:
- uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd #v6.0.2
with:
fetch-depth: 0
persist-credentials: true
- name: Bootstrap environment
uses: ./.github/actions/bootstrap
with:
# use the same cache we used for building snapshots
build-cache-key-prefix: "snapshot"
- name: Login to Docker Hub
uses: docker/login-action@b45d80f862d83dbcd57f89517bcf500b2ab88fb2 #v4.0.0
with:
username: ${{ secrets.ANCHOREOSSWRITE_DH_USERNAME }}
password: ${{ secrets.ANCHOREOSSWRITE_DH_PAT }}
- name: Login to GitHub Container Registry
uses: docker/login-action@b45d80f862d83dbcd57f89517bcf500b2ab88fb2 #v4.0.0
with:
registry: ghcr.io
username: ${{ github.actor }}
password: ${{ secrets.GITHUB_TOKEN }}
- name: Tag release
run: |
git config user.name "anchoreci"
git config user.email "anchoreci@users.noreply.github.com"
git tag -a "$VERSION" -m "Release $VERSION"
git push origin --tags
env:
VERSION: ${{ github.event.inputs.version }}
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
- name: Build & publish release artifacts
run: make ci-release
env:
# for mac signing and notarization...
QUILL_SIGN_P12: ${{ secrets.ANCHORE_APPLE_DEVELOPER_ID_CERT_CHAIN }}
QUILL_SIGN_PASSWORD: ${{ secrets.ANCHORE_APPLE_DEVELOPER_ID_CERT_PASS }}
QUILL_NOTARY_ISSUER: ${{ secrets.APPLE_NOTARY_ISSUER }}
QUILL_NOTARY_KEY_ID: ${{ secrets.APPLE_NOTARY_KEY_ID }}
QUILL_NOTARY_KEY: ${{ secrets.APPLE_NOTARY_KEY }}
# 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.ANCHOREOPS_GITHUB_OSS_WRITE_TOKEN }}
- uses: anchore/sbom-action@57aae528053a48a3f6235f2d9461b05fbcb7366d # v0.23.1
continue-on-error: true
with:
artifact-name: sbom.spdx.json
- name: Notify Slack of new release
uses: slackapi/slack-github-action@91efab103c0de0a537f72a35f6b8cda0ee76bf0a #v2.1.1
continue-on-error: true
with:
webhook: ${{ secrets.SLACK_TOOLBOX_WEBHOOK_URL }}
webhook-type: incoming-webhook
payload: |
text: "A new Grype release has been published: https://github.com/anchore/grype/releases/tag/${{ github.event.inputs.version }}"
blocks:
- type: section
text:
type: mrkdwn
text: |
*A new Grype release has been published* :rocket:
• Release: <https://github.com/anchore/grype/releases/tag/${{ github.event.inputs.version }}|${{ github.event.inputs.version }}>
• Repo: `${{ github.repository }}`
• Workflow: `${{ github.workflow }}`
• Event: `${{ github.event_name }}`
if: ${{ success() }}
release-install-script:
needs: [release]
if: ${{ needs.release.result == 'success' }}
uses: "anchore/workflows/.github/workflows/release-install-script.yaml@main"
with:
tag: ${{ github.event.inputs.version }}
secrets:
# needed for r2...
R2_INSTALL_ACCESS_KEY_ID: ${{ secrets.OSS_R2_INSTALL_ACCESS_KEY_ID }}
R2_INSTALL_SECRET_ACCESS_KEY: ${{ secrets.OSS_R2_INSTALL_SECRET_ACCESS_KEY }}
R2_ENDPOINT: ${{ secrets.TOOLBOX_CLOUDFLARE_R2_ENDPOINT }}
# needed for s3...
S3_INSTALL_AWS_ACCESS_KEY_ID: ${{ secrets.TOOLBOX_AWS_ACCESS_KEY_ID }}
S3_INSTALL_AWS_SECRET_ACCESS_KEY: ${{ secrets.TOOLBOX_AWS_SECRET_ACCESS_KEY }}
================================================
FILE: .github/workflows/remove-awaiting-response-label.yaml
================================================
name: "Manage Awaiting Response Label"
on:
issue_comment:
types: [created]
jobs:
run:
permissions:
issues: write
pull-requests: write
uses: "anchore/workflows/.github/workflows/remove-awaiting-response-label.yaml@main"
secrets:
token: ${{ secrets.OSS_PROJECT_GH_TOKEN }}
================================================
FILE: .github/workflows/scorecards.yml
================================================
name: Scorecards supply-chain security
on:
# Only the default branch is supported.
branch_protection_rule:
push:
branches: [ "main" ]
# Declare default permissions as read only.
permissions: read-all
jobs:
analysis:
name: Scorecards analysis
runs-on: ubuntu-latest
permissions:
# Needed to upload the results to code-scanning dashboard.
security-events: write
# Used to receive a badge.
id-token: write
steps:
- name: "Checkout code"
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
with:
persist-credentials: false
- name: "Run analysis"
uses: ossf/scorecard-action@4eaacf0543bb3f2c246792bd56e8cdeffafb205a # v2.4.3
with:
results_file: results.sarif
results_format: sarif
# Publish the results for public repositories to enable scorecard badges. For more details, see
# https://github.com/ossf/scorecard-action#publishing-results.
# For private repositories, `publish_results` will automatically be set to `false`, regardless
# of the value entered here.
publish_results: true
# Upload the results to GitHub's code scanning dashboard.
- name: "Upload to code-scanning"
uses: github/codeql-action/upload-sarif@0d579ffd059c29b07949a3cce3983f0780820c98 # v4.32.6
with:
sarif_file: results.sarif
================================================
FILE: .github/workflows/update-anchore-dependencies.yml
================================================
name: PR to update Anchore dependencies
on:
workflow_dispatch:
inputs:
repos:
description: "List of dependencies to update"
required: true
type: string
permissions:
contents: read
jobs:
update:
runs-on: ubuntu-latest
if: github.repository_owner == 'anchore' # only run for main repo (not forks)
steps:
- uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd #v6.0.2
with:
persist-credentials: false
- name: Bootstrap environment
uses: ./.github/actions/bootstrap
with:
tools: false
bootstrap-apt-packages: ""
- name: Update dependencies
id: update
uses: anchore/workflows/.github/actions/update-go-dependencies@main
with:
repos: ${{ github.event.inputs.repos }}
- uses: tibdex/github-app-token@3beb63f4bd073e61482598c45c71c1019b59b73a #v2.1.0
id: generate-token
with:
app_id: ${{ secrets.TOKEN_APP_ID }}
private_key: ${{ secrets.TOKEN_APP_PRIVATE_KEY }}
- uses: peter-evans/create-pull-request@98357b18bf14b5342f975ff684046ec3b2a07725 #v8.0.0
with:
signoff: true
delete-branch: true
draft: ${{ steps.update.outputs.draft }}
# do not change this branch, as other workflows depend on it
branch: auto/integration
labels: dependencies,pre-release
commit-message: "chore(deps): update anchore dependencies"
title: "chore(deps): update anchore dependencies"
body: ${{ steps.update.outputs.summary }}
token: ${{ steps.generate-token.outputs.token }}
================================================
FILE: .github/workflows/update-bootstrap-tools.yml
================================================
name: PR for latest versions of tools
on:
schedule:
- cron: "0 8 * * *" # 3 AM EST
workflow_dispatch:
permissions:
contents: read
jobs:
update-bootstrap-tools:
runs-on: ubuntu-latest
if: github.repository == 'anchore/grype' # only run for main repo
steps:
- uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd #v6.0.2
with:
persist-credentials: false
- name: Bootstrap environment
uses: ./.github/actions/bootstrap
with:
bootstrap-apt-packages: ""
compute-fingerprints: "false"
go-dependencies: false
- name: "Update tool versions"
id: latest-versions
run: |
make update-tools
make list-tools
export NO_COLOR=1
delimiter="$(openssl rand -hex 8)"
{
echo "status<<${delimiter}"
make list-tool-updates
echo "${delimiter}"
} >> $GITHUB_OUTPUT
{
echo "### Tool version status"
echo "\`\`\`"
make list-tool-updates
echo "\`\`\`"
} >> $GITHUB_STEP_SUMMARY
- uses: tibdex/github-app-token@3beb63f4bd073e61482598c45c71c1019b59b73a #v2.1.0
id: generate-token
with:
app_id: ${{ secrets.TOKEN_APP_ID }}
private_key: ${{ secrets.TOKEN_APP_PRIVATE_KEY }}
- uses: peter-evans/create-pull-request@98357b18bf14b5342f975ff684046ec3b2a07725 #v8.0.0
with:
signoff: true
delete-branch: true
branch: auto/latest-tools
labels: dependencies
commit-message: 'chore(deps): update tools to latest versions'
title: 'chore(deps): update tools to latest versions'
body: |
```
${{ steps.latest-versions.outputs.status }}
```
This is an auto-generated pull request to update all of the tools to the latest versions.
token: ${{ steps.generate-token.outputs.token }}
================================================
FILE: .github/workflows/update-generated-code.yml
================================================
name: PR to update OS codename generated code
on:
schedule:
- cron: "0 1 * * 1" # every Monday at 1 AM UTC
workflow_dispatch:
permissions:
contents: read
env:
SLACK_NOTIFICATIONS: true
jobs:
run-code-gen:
name: "Run code generation"
runs-on: ubuntu-latest
if: github.repository == 'anchore/grype' # only run for main repo
steps:
- uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd #v6.0.2
with:
persist-credentials: false
- name: Bootstrap environment
uses: ./.github/actions/bootstrap
with:
bootstrap-apt-packages: ""
compute-fingerprints: "false"
go-dependencies: true
- name: "Generate codename data"
run: |
make generate-codename-data
- uses: tibdex/github-app-token@3beb63f4bd073e61482598c45c71c1019b59b73a #v2.1.0
id: generate-token
with:
app_id: ${{ secrets.TOKEN_APP_ID }}
private_key: ${{ secrets.TOKEN_APP_PRIVATE_KEY }}
- uses: peter-evans/create-pull-request@c0f553fe549906ede9cf27b5156039d195d2ece0 #v8.1.0
with:
signoff: true
delete-branch: true
branch: auto/latest-codename-data
labels: dependencies
commit-message: "chore(deps): update OS codename generated code"
title: "chore(deps): update OS codename generated code"
body: |
Update OS codename data from endoflife.date
token: ${{ steps.generate-token.outputs.token }}
- name: Notify Slack on failure
uses: slackapi/slack-github-action@91efab103c0de0a537f72a35f6b8cda0ee76bf0a #v2.1.1
if: ${{ failure() && env.SLACK_NOTIFICATIONS == 'true' }}
with:
webhook: ${{ secrets.SLACK_TOOLBOX_WEBHOOK_URL }}
webhook-type: incoming-webhook
payload: |
text: "Grype OS codename code generation failed"
blocks:
- type: section
text:
type: mrkdwn
text: |
*Grype OS codename code generation failed*
• Workflow: `${{ github.workflow }}`
• Event: `${{ github.event_name }}`
• Job Status: `${{ job.status }}`
• <${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }}|View Run>
================================================
FILE: .github/workflows/update-quality-gate-db.yml
================================================
name: PR for upgrading quality gate test DB
on:
schedule:
- cron: "0 16 1 * *" # first day of each month @ 11 AM EST
workflow_dispatch:
permissions:
contents: read
jobs:
update-test-db-url:
runs-on: ubuntu-latest
if: github.repository == 'anchore/grype' # only run for main repo
steps:
- uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd #v6.0.2
with:
persist-credentials: false
- name: "Update quality DB"
run: |
make update-quality-gate-db
- uses: tibdex/github-app-token@3beb63f4bd073e61482598c45c71c1019b59b73a #v2.1.0
id: generate-token
with:
app_id: ${{ secrets.TOKEN_APP_ID }}
private_key: ${{ secrets.TOKEN_APP_PRIVATE_KEY }}
- uses: peter-evans/create-pull-request@98357b18bf14b5342f975ff684046ec3b2a07725 #v8.0.0
with:
signoff: true
delete-branch: true
branch: auto/update-quality-test-db
labels: test, changelog-ignore
commit-message: 'test: update quality gate db to latest version'
title: 'test: update quality gate db to latest version'
body: |
This is an auto-generated pull request to update the quality gate db to latest version
token: ${{ steps.generate-token.outputs.token }}
================================================
FILE: .github/workflows/validate-github-actions.yaml
================================================
name: "Validate GitHub Actions"
on:
pull_request:
paths:
- '.github/workflows/**'
- '.github/actions/**'
push:
branches:
- main
paths:
- '.github/workflows/**'
- '.github/actions/**'
permissions:
contents: read
jobs:
zizmor:
name: "Lint"
runs-on: ubuntu-latest
permissions:
contents: read
security-events: write # for uploading SARIF results
steps:
- uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
with:
persist-credentials: false
- name: "Run zizmor"
uses: zizmorcore/zizmor-action@0dce2577a4760a2749d8cfb7a84b7d5585ebcb7d # v0.5.0
with:
config: .github/zizmor.yml
# Disable SARIF upload so the step is a simple pass/fail gate
advanced-security: false
inputs: .github
================================================
FILE: .github/workflows/validations.yaml
================================================
name: "Validations"
on:
workflow_dispatch:
pull_request:
push:
branches:
- main
permissions:
contents: read
jobs:
Static-Analysis:
# Note: changing this job name requires making the same update in the .github/workflows/release.yaml pipeline
name: "Static analysis"
runs-on: ubuntu-24.04
steps:
- uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
with:
persist-credentials: false
- name: Bootstrap environment
uses: ./.github/actions/bootstrap
- name: Run static analysis
run: make static-analysis
Unit-Test:
# Note: changing this job name requires making the same update in the .github/workflows/release.yaml pipeline
name: "Unit tests"
runs-on: ubuntu-24.04
steps:
- uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
with:
persist-credentials: false
- name: Bootstrap environment
uses: ./.github/actions/bootstrap
- name: Run unit tests
run: make unit
Quality-Test:
# Note: changing this job name requires making the same update in the .github/workflows/release.yaml pipeline
name: "Quality tests"
runs-on: ubuntu-22.04-4core-16gb
steps:
- uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
with:
submodules: true
persist-credentials: false
- name: Bootstrap environment
uses: ./.github/actions/bootstrap
- name: Run quality tests
run: make quality
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
- name: Archive the provider state
if: ${{ failure() }}
run: tar -czvf qg-capture-state.tar.gz -C test/quality --exclude tools --exclude labels .yardstick.yaml .yardstick
- name: Upload the provider state archive
if: ${{ failure() }}
uses: actions/upload-artifact@bbbca2ddaa5d8feaa63e36b76fdaad77386f024f # v7.0.0
with:
name: qg-capture-state
path: qg-capture-state.tar.gz
- name: Show instructions to debug
if: ${{ failure() }}
run: |
ARCHIVE_BASENAME=qg-capture-state
ARCHIVE_NAME=$ARCHIVE_BASENAME.zip
cat << EOF >> $GITHUB_STEP_SUMMARY
## Troubleshooting failed run
Download the artifact from this workflow run: \`$ARCHIVE_NAME\`
Then run the following commands to debug:
\`\`\`bash
# copy the archive to the tests/quality directory
cd test/quality
unzip $ARCHIVE_NAME && tar -xzf $ARCHIVE_BASENAME.tar.gz
\`\`\`
Now you can debug the with yardstick:
\`\`\`bash
poetry shell
yardstick result list
yardstick label explore
\`\`\`
EOF
Integration-Test:
# Note: changing this job name requires making the same update in the .github/workflows/release.yaml pipeline
name: "Integration tests"
runs-on: ubuntu-24.04
steps:
- uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
with:
persist-credentials: false
- name: Bootstrap environment
uses: ./.github/actions/bootstrap
- name: Restore integration test cache
uses: actions/cache@cdf6c1fa76f9f475f3d7449005a359c84ca0f306 #v5.0.3
with:
path: ${{ github.workspace }}/test/integration/testdata/cache
key: ${{ runner.os }}-integration-test-cache-${{ hashFiles('test/integration/testdata/cache.fingerprint') }}
- name: Run integration tests
run: make integration
Build-Snapshot-Artifacts:
name: "Build snapshot artifacts"
runs-on: ubuntu-24.04
steps:
- uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
with:
persist-credentials: false
- name: Bootstrap environment
uses: ./.github/actions/bootstrap
with:
# why have another build cache key? We don't want unit/integration/etc test build caches to replace
# the snapshot build cache, which includes builds for all OSs and architectures. As long as this key is
# unique from the build-cache-key-prefix in other CI jobs, we should be fine.
#
# note: ideally this value should match what is used in release (just to help with build times).
build-cache-key-prefix: "snapshot"
bootstrap-apt-packages: ""
- name: Build snapshot artifacts
run: make snapshot
# 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@cdf6c1fa76f9f475f3d7449005a359c84ca0f306 #v5.0.3
with:
path: snapshot
key: snapshot-build-${{ github.run_id }}
Upload-Snapshot-Artifacts:
name: "Upload snapshot artifacts"
needs: [Build-Snapshot-Artifacts]
runs-on: ubuntu-24.04
steps:
- uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd #v6.0.2
with:
persist-credentials: false
- name: Download snapshot build
uses: actions/cache/restore@cdf6c1fa76f9f475f3d7449005a359c84ca0f306 #v5.0.3
with:
path: snapshot
key: snapshot-build-${{ github.run_id }}
- run: npm install @actions/artifact@2.2.2
- uses: actions/github-script@ed597411d8f924073f98dfc5c65a23a2325f34cd #v8.0.0
with:
script: |
const { readdirSync } = require('fs')
const { DefaultArtifactClient } = require('@actions/artifact')
const artifact = new DefaultArtifactClient()
const ls = d => readdirSync(d, { withFileTypes: true })
const baseDir = "./snapshot"
const dirs = ls(baseDir).filter(f => f.isDirectory()).map(f => f.name)
const uploads = []
for (const dir of dirs) {
// uploadArtifact returns Promise<{id, size}>
uploads.push(artifact.uploadArtifact(
// name of the archive:
`${dir}`,
// array of all files to include:
ls(`${baseDir}/${dir}`).map(f => `${baseDir}/${dir}/${f.name}`),
// base directory to trim from entries:
`${baseDir}/${dir}`,
{ retentionDays: 30 }
))
}
// wait for all uploads to finish
Promise.all(uploads)
Acceptance-Linux:
# Note: changing this job name requires making the same update in the .github/workflows/release.yaml pipeline
name: "Acceptance tests (Linux)"
needs: [Build-Snapshot-Artifacts]
runs-on: ubuntu-24.04
steps:
- uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd #v6.0.2
with:
persist-credentials: false
- name: Download snapshot build
uses: actions/cache/restore@cdf6c1fa76f9f475f3d7449005a359c84ca0f306 #v5.0.3
with:
path: snapshot
key: snapshot-build-${{ github.run_id }}
- name: Restore install.sh test image cache
id: install-test-image-cache
uses: actions/cache@cdf6c1fa76f9f475f3d7449005a359c84ca0f306 #v5.0.3
with:
path: ${{ github.workspace }}/test/install/cache
key: ${{ runner.os }}-install-test-image-cache-${{ hashFiles('test/install/cache.fingerprint') }}
- name: Load test image cache
if: steps.install-test-image-cache.outputs.cache-hit == 'true'
run: make install-test-cache-load
- name: Run install.sh tests (Linux)
run: make install-test
- name: (cache-miss) Create test image cache
if: steps.install-test-image-cache.outputs.cache-hit != 'true'
run: make install-test-cache-save
Acceptance-Mac:
# Note: changing this job name requires making the same update in the .github/workflows/release.yaml pipeline
name: "Acceptance tests (Mac)"
needs: [Build-Snapshot-Artifacts]
runs-on: macos-latest
steps:
- name: Install Cosign
uses: sigstore/cosign-installer@ba7bc0a3fef59531c69a25acd34668d6d3fe6f22 #v4.1.0
- uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd #v6.0.2
with:
persist-credentials: false
- name: Download snapshot build
uses: actions/cache/restore@cdf6c1fa76f9f475f3d7449005a359c84ca0f306 #v5.0.3
with:
path: snapshot
key: snapshot-build-${{ github.run_id }}
- name: Restore docker image cache for compare testing
id: mac-compare-testing-cache
uses: actions/cache@cdf6c1fa76f9f475f3d7449005a359c84ca0f306 #v5.0.3
with:
path: image.tar
key: ${{ runner.os }}-${{ hashFiles('test/compare/mac.sh') }}
- name: Run install.sh tests (Mac)
run: make install-test-ci-mac
Cli-Linux:
# Note: changing this job name requires making the same update in the .github/workflows/release.yaml pipeline
name: "CLI tests (Linux)"
needs: [Build-Snapshot-Artifacts]
runs-on: ubuntu-24.04
steps:
- uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd #v6.0.2
with:
persist-credentials: false
- name: Bootstrap environment
uses: ./.github/actions/bootstrap
- name: Restore CLI test-fixture cache
uses: actions/cache@cdf6c1fa76f9f475f3d7449005a359c84ca0f306 #v5.0.3
with:
path: ${{ github.workspace }}/test/cli/testdata/cache
key: ${{ runner.os }}-cli-test-cache-${{ hashFiles('test/cli/testdata/cache.fingerprint') }}
- name: Download snapshot build
uses: actions/cache/restore@cdf6c1fa76f9f475f3d7449005a359c84ca0f306 #v5.0.3
with:
path: snapshot
key: snapshot-build-${{ github.run_id }}
- name: Run CLI Tests (Linux)
run: make cli
env:
GRYPE_SNAPSHOT_PREBUILT: "true"
GRYPE_BINARY_LOCATION: ${{ github.workspace }}/snapshot/linux-build_linux_amd64_v1/grype
Cleanup-Cache:
name: "Cleanup snapshot cache"
if: github.event.pull_request.head.repo.full_name == github.repository
runs-on: ubuntu-24.04
permissions:
actions: write
needs:
- Acceptance-Linux
- Acceptance-Mac
- Cli-Linux
- Upload-Snapshot-Artifacts
steps:
- uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd #v6.0.2
with:
persist-credentials: false
- name: Delete snapshot cache
run: gh cache delete "snapshot-build-${{ github.run_id }}" || echo "Cache deletion failed or cache not found - continuing"
env:
GH_TOKEN: ${{ github.token }}
================================================
FILE: .github/zizmor.yml
================================================
rules:
unpinned-uses:
config:
policies:
# anchore/workflows is an internal repository; using @main is acceptable
anchore/*: any
================================================
FILE: .gitignore
================================================
# AI
.claude
CLAUDE.MD
# local development tailoring
go.work
go.work.sum
.tool-versions
.jj/
mise.toml
specs/
*.xxh64
# AI and LLM related files
CLAUDE.md
.claude
# app configuration
/.grype.yaml
# tool and bin directories
.tmp/
bin/
/bin
/.bin
/build
/dist
/snapshot
/.tool
/.task
# changelog generation
/CHANGELOG.md
/VERSION
# IDE configuration
.vscode/
.idea/
.server/
.history/
# test related
*.fingerprint
/test/results
coverage.txt
*.log
.server
# grype-db related
/metadata.json
/listing.json
*.db
*.db-journal
!**/testdata/**/*.db
!**/testdata/**/bin/
!**/testdata/**/*.jar
# probable archives
.images
*.tar
*.jar
*.war
*.ear
*.jpi
*.hpi
*.zip
*.iml
# Binaries for programs and plugins
*.exe
*.exe~
*.dll
*.so
*.dylib
# Test binary, build with `go test -c`
*.test
# OS files
.DS_Store
*.profile
# Binaries for programs and plugins
*.exe
*.exe~
*.dll
*.so
*.dylib
/grype/grype
main
# Test binary, build with `go test -c`
*.test
# Output of the go coverage tool, specifically when used with LiteIDE
*.out
================================================
FILE: .gitmodules
================================================
[submodule "test/quality/vulnerability-match-labels"]
path = test/quality/vulnerability-match-labels
url = https://github.com/anchore/vulnerability-match-labels.git
branch = main
================================================
FILE: .golangci.yaml
================================================
version: "2"
linters:
# inverted configuration with `enable-all` and `disable` is not scalable during updates of golangci-lint
default: none
enable:
- asciicheck
- bodyclose
- copyloopvar
- dogsled
- dupl
- errcheck
- funlen
- gocognit
- goconst
- gocritic
- gocyclo
- goprintffuncname
- gosec
- govet
- ineffassign
- misspell
- nakedret
- revive
- staticcheck
- unconvert
- unparam
- unused
- whitespace
settings:
funlen:
lines: 70
statements: 50
exclusions:
generated: lax
presets:
- comments
- common-false-positives
- legacy
- std-error-handling
rules:
# we have multiple packages in grype that might overlap with the stblib; their names reflect their purpose
- linters:
- revive
text: "var-naming: avoid package names that conflict"
paths:
- third_party$
- builtin$
- examples$
# do not enable...
# - deadcode # The owner seems to have abandoned the linter. Replaced by "unused".
# - depguard # we need to setup a configuration for this
# - goprintffuncname # does not catch all cases and there are exceptions
# - nakedret # does not catch all cases and should not fail a build
# - gochecknoglobals
# - gochecknoinits # this is too aggressive
# - rowserrcheck disabled per generics https://github.com/golangci/golangci-lint/issues/2649
# - godot
# - godox
# - goerr113
# - goimports # we're using gosimports now instead to account for extra whitespaces (see https://github.com/golang/go/issues/20818)
# - golint # deprecated
# - gomnd # this is too aggressive
# - interfacer # this is a good idea, but is no longer supported and is prone to false positives
# - lll # without a way to specify per-line exception cases, this is not usable
# - maligned # this is an excellent linter, but tricky to optimize and we are not sensitive to memory layout optimizations
# - nestif
# - nolintlint # as of go1.19 this conflicts with the behavior of gofmt, which is a deal-breaker (lint-fix will still fail when running lint)
# - prealloc # following this rule isn't consistently a good idea, as it sometimes forces unnecessary allocations that result in less idiomatic code
# - rowserrcheck # not in a repo with sql, so this is not useful
# - scopelint # deprecated
# - structcheck # The owner seems to have abandoned the linter. Replaced by "unused".
# - testpackage
# - varcheck # The owner seems to have abandoned the linter. Replaced by "unused".
# - wsl # this doens't have an auto-fixer yet and is pretty noisy (https://github.com/bombsimon/wsl/issues/90)
issues:
max-same-issues: 25
uniq-by-line: false
# TODO: enable this when we have coverage on docstring comments
# # The list of ids of default excludes to include or disable.
# include:
# - EXC0002 # disable excluding of issues about comments from golint
formatters:
enable:
- gofmt
- goimports
exclusions:
generated: lax
paths:
- third_party$
- builtin$
- examples$
================================================
FILE: .goreleaser.yaml
================================================
version: 2
release:
prerelease: auto
draft: false
env:
# required to support multi architecture docker builds
- DOCKER_CLI_EXPERIMENTAL=enabled
- CGO_ENABLED=0
builds:
- id: linux-build
dir: ./cmd/grype
binary: grype
goos:
- linux
goarch:
- amd64
- arm64
- ppc64le
- s390x
# set the modified timestamp on the output binary to the git timestamp to ensure a reproducible build
mod_timestamp: &build-timestamp '{{ .CommitTimestamp }}'
ldflags: &build-ldflags |
-w
-s
-extldflags '-static'
-X main.version={{.Version}}
-X main.gitCommit={{.Commit}}
-X main.buildDate={{.Date}}
-X main.gitDescription={{.Summary}}
- id: darwin-build
dir: ./cmd/grype
binary: grype
goos:
- darwin
goarch:
- amd64
- arm64
mod_timestamp: *build-timestamp
ldflags: *build-ldflags
hooks:
post:
- cmd: .tool/quill sign-and-notarize "{{ .Path }}" --dry-run={{ .IsSnapshot }} --ad-hoc={{ .IsSnapshot }} -vv
env:
- QUILL_LOG_FILE=/tmp/quill-{{ .Target }}.log
- id: windows-build
dir: ./cmd/grype
binary: grype
goos:
- windows
goarch:
- amd64
mod_timestamp: *build-timestamp
ldflags: *build-ldflags
archives:
- id: linux-archives
ids:
- linux-build
- id: darwin-archives
ids:
- darwin-build
- id: windows-archives
formats: [zip]
ids:
- windows-build
nfpms:
- license: "Apache 2.0"
maintainer: "Anchore, Inc"
homepage: &website "https://github.com/anchore/grype"
description: &description "A vulnerability scanner for container images and filesystems"
formats:
- rpm
- deb
homebrew_casks:
- repository:
owner: anchore
name: homebrew-grype
token: "{{.Env.GITHUB_BREW_TOKEN}}"
ids:
- darwin-archives
- linux-archives
homepage: *website
description: *description
license: "Apache License 2.0"
conflicts:
# claim that the previous grype formula (in the root of homebrew-grype) conflicts with the new cask
# see https://goreleaser.com/deprecations/#brews for more information
- formula: grype
dockers:
# production images...
- image_templates:
- anchore/grype:{{.Tag}}-amd64
- ghcr.io/anchore/grype:{{.Tag}}-amd64
goarch: amd64
dockerfile: Dockerfile
use: buildx
build_flag_templates:
- "--platform=linux/amd64"
- "--provenance=false"
- "--build-arg=BUILD_DATE={{.Date}}"
- "--build-arg=BUILD_VERSION={{.Version}}"
- "--build-arg=VCS_REF={{.FullCommit}}"
- "--build-arg=VCS_URL={{.GitURL}}"
- image_templates:
- anchore/grype:{{.Tag}}-arm64v8
- ghcr.io/anchore/grype:{{.Tag}}-arm64v8
goarch: arm64
dockerfile: Dockerfile
use: buildx
build_flag_templates:
- "--platform=linux/arm64/v8"
- "--provenance=false"
- "--build-arg=BUILD_DATE={{.Date}}"
- "--build-arg=BUILD_VERSION={{.Version}}"
- "--build-arg=VCS_REF={{.FullCommit}}"
- "--build-arg=VCS_URL={{.GitURL}}"
- image_templates:
- anchore/grype:{{.Tag}}-ppc64le
- ghcr.io/anchore/grype:{{.Tag}}-ppc64le
goarch: ppc64le
dockerfile: Dockerfile
use: buildx
build_flag_templates:
- "--platform=linux/ppc64le"
- "--provenance=false"
- "--build-arg=BUILD_DATE={{.Date}}"
- "--build-arg=BUILD_VERSION={{.Version}}"
- "--build-arg=VCS_REF={{.FullCommit}}"
- "--build-arg=VCS_URL={{.GitURL}}"
- image_templates:
- anchore/grype:{{.Tag}}-s390x
- ghcr.io/anchore/grype:{{.Tag}}-s390x
goarch: s390x
dockerfile: Dockerfile
use: buildx
build_flag_templates:
- "--platform=linux/s390x"
- "--provenance=false"
- "--build-arg=BUILD_DATE={{.Date}}"
- "--build-arg=BUILD_VERSION={{.Version}}"
- "--build-arg=VCS_REF={{.FullCommit}}"
- "--build-arg=VCS_URL={{.GitURL}}"
# nonroot images...
- image_templates:
- anchore/grype:{{.Tag}}-nonroot-amd64
- ghcr.io/anchore/grype:{{.Tag}}-nonroot-amd64
goarch: amd64
dockerfile: Dockerfile.nonroot
use: buildx
build_flag_templates:
- "--platform=linux/amd64"
- "--provenance=false"
- "--build-arg=BUILD_DATE={{.Date}}"
- "--build-arg=BUILD_VERSION={{.Version}}"
- "--build-arg=VCS_REF={{.FullCommit}}"
- "--build-arg=VCS_URL={{.GitURL}}"
- image_templates:
- anchore/grype:{{.Tag}}-nonroot-arm64v8
- ghcr.io/anchore/grype:{{.Tag}}-nonroot-arm64v8
goarch: arm64
dockerfile: Dockerfile.nonroot
use: buildx
build_flag_templates:
- "--platform=linux/arm64/v8"
- "--provenance=false"
- "--build-arg=BUILD_DATE={{.Date}}"
- "--build-arg=BUILD_VERSION={{.Version}}"
- "--build-arg=VCS_REF={{.FullCommit}}"
- "--build-arg=VCS_URL={{.GitURL}}"
- image_templates:
- anchore/grype:{{.Tag}}-nonroot-ppc64le
- ghcr.io/anchore/grype:{{.Tag}}-nonroot-ppc64le
goarch: ppc64le
dockerfile: Dockerfile.nonroot
use: buildx
build_flag_templates:
- "--platform=linux/ppc64le"
- "--provenance=false"
- "--build-arg=BUILD_DATE={{.Date}}"
- "--build-arg=BUILD_VERSION={{.Version}}"
- "--build-arg=VCS_REF={{.FullCommit}}"
- "--build-arg=VCS_URL={{.GitURL}}"
- image_templates:
- anchore/grype:{{.Tag}}-nonroot-s390x
- ghcr.io/anchore/grype:{{.Tag}}-nonroot-s390x
goarch: s390x
dockerfile: Dockerfile.nonroot
use: buildx
build_flag_templates:
- "--platform=linux/s390x"
- "--provenance=false"
- "--build-arg=BUILD_DATE={{.Date}}"
- "--build-arg=BUILD_VERSION={{.Version}}"
- "--build-arg=VCS_REF={{.FullCommit}}"
- "--build-arg=VCS_URL={{.GitURL}}"
# debug images...
- image_templates:
- anchore/grype:{{.Tag}}-debug-amd64
- ghcr.io/anchore/grype:{{.Tag}}-debug-amd64
goarch: amd64
dockerfile: Dockerfile.debug
use: buildx
build_flag_templates:
- "--platform=linux/amd64"
- "--provenance=false"
- "--build-arg=BUILD_DATE={{.Date}}"
- "--build-arg=BUILD_VERSION={{.Version}}"
- "--build-arg=VCS_REF={{.FullCommit}}"
- "--build-arg=VCS_URL={{.GitURL}}"
- image_templates:
- anchore/grype:{{.Tag}}-debug-arm64v8
- ghcr.io/anchore/grype:{{.Tag}}-debug-arm64v8
goarch: arm64
dockerfile: Dockerfile.debug
use: buildx
build_flag_templates:
- "--platform=linux/arm64/v8"
- "--provenance=false"
- "--build-arg=BUILD_DATE={{.Date}}"
- "--build-arg=BUILD_VERSION={{.Version}}"
- "--build-arg=VCS_REF={{.FullCommit}}"
- "--build-arg=VCS_URL={{.GitURL}}"
- image_templates:
- anchore/grype:{{.Tag}}-debug-ppc64le
- ghcr.io/anchore/grype:{{.Tag}}-debug-ppc64le
goarch: ppc64le
dockerfile: Dockerfile.debug
use: buildx
build_flag_templates:
- "--platform=linux/ppc64le"
- "--provenance=false"
- "--build-arg=BUILD_DATE={{.Date}}"
- "--build-arg=BUILD_VERSION={{.Version}}"
- "--build-arg=VCS_REF={{.FullCommit}}"
- "--build-arg=VCS_URL={{.GitURL}}"
- image_templates:
- anchore/grype:{{.Tag}}-debug-s390x
- ghcr.io/anchore/grype:{{.Tag}}-debug-s390x
goarch: s390x
dockerfile: Dockerfile.debug
use: buildx
build_flag_templates:
- "--platform=linux/s390x"
- "--provenance=false"
- "--build-arg=BUILD_DATE={{.Date}}"
- "--build-arg=BUILD_VERSION={{.Version}}"
- "--build-arg=VCS_REF={{.FullCommit}}"
- "--build-arg=VCS_URL={{.GitURL}}"
docker_manifests:
- name_template: anchore/grype:latest
image_templates:
- anchore/grype:{{.Tag}}-amd64
- anchore/grype:{{.Tag}}-arm64v8
- anchore/grype:{{.Tag}}-ppc64le
- anchore/grype:{{.Tag}}-s390x
- name_template: ghcr.io/anchore/grype:latest
image_templates:
- ghcr.io/anchore/grype:{{.Tag}}-amd64
- ghcr.io/anchore/grype:{{.Tag}}-arm64v8
- ghcr.io/anchore/grype:{{.Tag}}-ppc64le
- ghcr.io/anchore/grype:{{.Tag}}-s390x
- name_template: anchore/grype:{{.Tag}}
image_templates:
- anchore/grype:{{.Tag}}-amd64
- anchore/grype:{{.Tag}}-arm64v8
- anchore/grype:{{.Tag}}-ppc64le
- anchore/grype:{{.Tag}}-s390x
- name_template: ghcr.io/anchore/grype:{{.Tag}}
image_templates:
- ghcr.io/anchore/grype:{{.Tag}}-amd64
- ghcr.io/anchore/grype:{{.Tag}}-arm64v8
- ghcr.io/anchore/grype:{{.Tag}}-ppc64le
- ghcr.io/anchore/grype:{{.Tag}}-s390x
# nonroot images...
- name_template: anchore/grype:nonroot
image_templates:
- anchore/grype:{{.Tag}}-nonroot-amd64
- anchore/grype:{{.Tag}}-nonroot-arm64v8
- anchore/grype:{{.Tag}}-nonroot-ppc64le
- anchore/grype:{{.Tag}}-nonroot-s390x
- name_template: ghcr.io/anchore/grype:nonroot
image_templates:
- ghcr.io/anchore/grype:{{.Tag}}-nonroot-amd64
- ghcr.io/anchore/grype:{{.Tag}}-nonroot-arm64v8
- ghcr.io/anchore/grype:{{.Tag}}-nonroot-ppc64le
- ghcr.io/anchore/grype:{{.Tag}}-nonroot-s390x
- name_template: anchore/grype:{{.Tag}}-nonroot
image_templates:
- anchore/grype:{{.Tag}}-nonroot-amd64
- anchore/grype:{{.Tag}}-nonroot-arm64v8
- anchore/grype:{{.Tag}}-nonroot-ppc64le
- anchore/grype:{{.Tag}}-nonroot-s390x
- name_template: ghcr.io/anchore/grype:{{.Tag}}-nonroot
image_templates:
- ghcr.io/anchore/grype:{{.Tag}}-nonroot-amd64
- ghcr.io/anchore/grype:{{.Tag}}-nonroot-arm64v8
- ghcr.io/anchore/grype:{{.Tag}}-nonroot-ppc64le
- ghcr.io/anchore/grype:{{.Tag}}-nonroot-s390x
# debug images...
- name_template: anchore/grype:debug
image_templates:
- anchore/grype:{{.Tag}}-debug-amd64
- anchore/grype:{{.Tag}}-debug-arm64v8
- anchore/grype:{{.Tag}}-debug-ppc64le
- anchore/grype:{{.Tag}}-debug-s390x
- name_template: ghcr.io/anchore/grype:debug
image_templates:
- ghcr.io/anchore/grype:{{.Tag}}-debug-amd64
- ghcr.io/anchore/grype:{{.Tag}}-debug-arm64v8
- ghcr.io/anchore/grype:{{.Tag}}-debug-ppc64le
- ghcr.io/anchore/grype:{{.Tag}}-debug-s390x
- name_template: anchore/grype:{{.Tag}}-debug
image_templates:
- anchore/grype:{{.Tag}}-debug-amd64
- anchore/grype:{{.Tag}}-debug-arm64v8
- anchore/grype:{{.Tag}}-debug-ppc64le
- anchore/grype:{{.Tag}}-debug-s390x
- name_template: ghcr.io/anchore/grype:{{.Tag}}-debug
image_templates:
- ghcr.io/anchore/grype:{{.Tag}}-debug-amd64
- ghcr.io/anchore/grype:{{.Tag}}-debug-arm64v8
- ghcr.io/anchore/grype:{{.Tag}}-debug-ppc64le
- ghcr.io/anchore/grype:{{.Tag}}-debug-s390x
signs:
- cmd: .tool/cosign
signature: "${artifact}.sig"
certificate: "${artifact}.pem"
args:
- "sign-blob"
- "--use-signing-config=false"
- "--oidc-issuer=https://token.actions.githubusercontent.com"
- "--output-certificate=${certificate}"
- "--output-signature=${signature}"
- "${artifact}"
- "--yes"
artifacts: checksum
================================================
FILE: CODE_OF_CONDUCT.md
================================================
# Code of Conduct
All contributors for any Anchore project must follow the [Contributor Covenant Code of Conduct](https://oss.anchore.com/docs/contributing/code-of-conduct/).
**TLDR:** Be kind, be respectful, and assume good intentions. We're all here to build great software together.
================================================
FILE: CONTRIBUTING.md
================================================
# Contributing
Thank you for your interest in contributing to Grype!
Please see the [contribution guide](https://oss.anchore.com/docs/contributing/grype/) for development requirements and helpful tips to get started developing in the repo. For a deeper dive, please see the [architecture docs for grype](https://oss.anchore.com/docs/architecture/grype/) and the sister project [grype-db](https://oss.anchore.com/docs/architecture/grype-db/).
**Have a question or need help?** Check out our [issues and discussions guide](https://oss.anchore.com/docs/contributing/issues-and-discussions/) to find the right place to start a conversation.
**Ready to submit code?** Our [pull request guide](https://oss.anchore.com/docs/contributing/pull-requests/) covers everything from title conventions to the review process. Don't forget that ***all commits require a [sign-off](https://oss.anchore.com/docs/contributing/sign-off/)***.
**Found a security issue?** Please do **not** open a public issue. Instead, see our [security policy](https://oss.anchore.com/docs/contributing/security/) for how to report vulnerabilities responsibly.
**Want to help improve the docs?** Check out the [anchore/oss-docs](https://github.com/anchore/oss-docs) repository.
================================================
FILE: Dockerfile
================================================
FROM gcr.io/distroless/static-debian12:latest AS build
FROM scratch
# needed for version check HTTPS request
COPY --from=build /etc/ssl/certs/ca-certificates.crt /etc/ssl/certs/ca-certificates.crt
# create the /tmp dir, which is needed for image content cache
WORKDIR /tmp
COPY grype /
ARG BUILD_DATE
ARG BUILD_VERSION
ARG VCS_REF
ARG VCS_URL
LABEL org.opencontainers.image.created=$BUILD_DATE
LABEL org.opencontainers.image.title="grype"
LABEL org.opencontainers.image.description="A vulnerability scanner for container images and filesystems"
LABEL org.opencontainers.image.source=$VCS_URL
LABEL org.opencontainers.image.revision=$VCS_REF
LABEL org.opencontainers.image.vendor="Anchore, Inc."
LABEL org.opencontainers.image.version=$BUILD_VERSION
LABEL org.opencontainers.image.licenses="Apache-2.0"
LABEL io.artifacthub.package.readme-url="https://raw.githubusercontent.com/anchore/grype/main/README.md"
LABEL io.artifacthub.package.logo-url="https://user-images.githubusercontent.com/5199289/136855393-d0a9eef9-ccf1-4e2b-9d7c-7aad16a567e5.png"
LABEL io.artifacthub.package.license="Apache-2.0"
ENTRYPOINT ["/grype"]
================================================
FILE: Dockerfile.debug
================================================
FROM gcr.io/distroless/static-debian12:debug-nonroot
# create the /tmp dir, which is needed for image content cache
WORKDIR /tmp
COPY grype /
ARG BUILD_DATE
ARG BUILD_VERSION
ARG VCS_REF
ARG VCS_URL
LABEL org.opencontainers.image.created=$BUILD_DATE
LABEL org.opencontainers.image.title="grype"
LABEL org.opencontainers.image.description="A vulnerability scanner for container images and filesystems"
LABEL org.opencontainers.image.source=$VCS_URL
LABEL org.opencontainers.image.revision=$VCS_REF
LABEL org.opencontainers.image.vendor="Anchore, Inc."
LABEL org.opencontainers.image.version=$BUILD_VERSION
LABEL org.opencontainers.image.licenses="Apache-2.0"
LABEL io.artifacthub.package.readme-url="https://raw.githubusercontent.com/anchore/grype/main/README.md"
LABEL io.artifacthub.package.logo-url="https://user-images.githubusercontent.com/5199289/136855393-d0a9eef9-ccf1-4e2b-9d7c-7aad16a567e5.png"
LABEL io.artifacthub.package.license="Apache-2.0"
ENTRYPOINT ["/grype"]
================================================
FILE: Dockerfile.nonroot
================================================
FROM gcr.io/distroless/static-debian12:nonroot
# create the /tmp dir, which is needed for image content cache
WORKDIR /tmp
COPY grype /
ARG BUILD_DATE
ARG BUILD_VERSION
ARG VCS_REF
ARG VCS_URL
LABEL org.opencontainers.image.created=$BUILD_DATE
LABEL org.opencontainers.image.title="grype"
LABEL org.opencontainers.image.description="A vulnerability scanner for container images and filesystems"
LABEL org.opencontainers.image.source=$VCS_URL
LABEL org.opencontainers.image.revision=$VCS_REF
LABEL org.opencontainers.image.vendor="Anchore, Inc."
LABEL org.opencontainers.image.version=$BUILD_VERSION
LABEL org.opencontainers.image.licenses="Apache-2.0"
LABEL io.artifacthub.package.readme-url="https://raw.githubusercontent.com/anchore/grype/main/README.md"
LABEL io.artifacthub.package.logo-url="https://user-images.githubusercontent.com/5199289/136855393-d0a9eef9-ccf1-4e2b-9d7c-7aad16a567e5.png"
LABEL io.artifacthub.package.license="Apache-2.0"
ENTRYPOINT ["/grype"]
================================================
FILE: LICENSE
================================================
Apache License
Version 2.0, January 2004
http://www.apache.org/licenses/
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
1. Definitions.
"License" shall mean the terms and conditions for use, reproduction,
and distribution as defined by Sections 1 through 9 of this document.
"Licensor" shall mean the copyright owner or entity authorized by
the copyright owner that is granting the License.
"Legal Entity" shall mean the union of the acting entity and all
other entities that control, are controlled by, or are under common
control with that entity. For the purposes of this definition,
"control" means (i) the power, direct or indirect, to cause the
direction or management of such entity, whether by contract or
otherwise, or (ii) ownership of fifty percent (50%) or more of the
outstanding shares, or (iii) beneficial ownership of such entity.
"You" (or "Your") shall mean an individual or Legal Entity
exercising permissions granted by this License.
"Source" form shall mean the preferred form for making modifications,
including but not limited to software source code, documentation
source, and configuration files.
"Object" form shall mean any form resulting from mechanical
transformation or translation of a Source form, including but
not limited to compiled object code, generated documentation,
and conversions to other media types.
"Work" shall mean the work of authorship, whether in Source or
Object form, made available under the License, as indicated by a
copyright notice that is included in or attached to the work
(an example is provided in the Appendix below).
"Derivative Works" shall mean any work, whether in Source or Object
form, that is based on (or derived from) the Work and for which the
editorial revisions, annotations, elaborations, or other modifications
represent, as a whole, an original work of authorship. For the purposes
of this License, Derivative Works shall not include works that remain
separable from, or merely link (or bind by name) to the interfaces of,
the Work and Derivative Works thereof.
"Contribution" shall mean any work of authorship, including
the original version of the Work and any modifications or additions
to that Work or Derivative Works thereof, that is intentionally
submitted to Licensor for inclusion in the Work by the copyright owner
or by an individual or Legal Entity authorized to submit on behalf of
the copyright owner. For the purposes of this definition, "submitted"
means any form of electronic, verbal, or written communication sent
to the Licensor or its representatives, including but not limited to
communication on electronic mailing lists, source code control systems,
and issue tracking systems that are managed by, or on behalf of, the
Licensor for the purpose of discussing and improving the Work, but
excluding communication that is conspicuously marked or otherwise
designated in writing by the copyright owner as "Not a Contribution."
"Contributor" shall mean Licensor and any individual or Legal Entity
on behalf of whom a Contribution has been received by Licensor and
subsequently incorporated within the Work.
2. Grant of Copyright License. Subject to the terms and conditions of
this License, each Contributor hereby grants to You a perpetual,
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
copyright license to reproduce, prepare Derivative Works of,
publicly display, publicly perform, sublicense, and distribute the
Work and such Derivative Works in Source or Object form.
3. Grant of Patent License. Subject to the terms and conditions of
this License, each Contributor hereby grants to You a perpetual,
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
(except as stated in this section) patent license to make, have made,
use, offer to sell, sell, import, and otherwise transfer the Work,
where such license applies only to those patent claims licensable
by such Contributor that are necessarily infringed by their
Contribution(s) alone or by combination of their Contribution(s)
with the Work to which such Contribution(s) was submitted. If You
institute patent litigation against any entity (including a
cross-claim or counterclaim in a lawsuit) alleging that the Work
or a Contribution incorporated within the Work constitutes direct
or contributory patent infringement, then any patent licenses
granted to You under this License for that Work shall terminate
as of the date such litigation is filed.
4. Redistribution. You may reproduce and distribute copies of the
Work or Derivative Works thereof in any medium, with or without
modifications, and in Source or Object form, provided that You
meet the following conditions:
(a) You must give any other recipients of the Work or
Derivative Works a copy of this License; and
(b) You must cause any modified files to carry prominent notices
stating that You changed the files; and
(c) You must retain, in the Source form of any Derivative Works
that You distribute, all copyright, patent, trademark, and
attribution notices from the Source form of the Work,
excluding those notices that do not pertain to any part of
the Derivative Works; and
(d) If the Work includes a "NOTICE" text file as part of its
distribution, then any Derivative Works that You distribute must
include a readable copy of the attribution notices contained
within such NOTICE file, excluding those notices that do not
pertain to any part of the Derivative Works, in at least one
of the following places: within a NOTICE text file distributed
as part of the Derivative Works; within the Source form or
documentation, if provided along with the Derivative Works; or,
within a display generated by the Derivative Works, if and
wherever such third-party notices normally appear. The contents
of the NOTICE file are for informational purposes only and
do not modify the License. You may add Your own attribution
notices within Derivative Works that You distribute, alongside
or as an addendum to the NOTICE text from the Work, provided
that such additional attribution notices cannot be construed
as modifying the License.
You may add Your own copyright statement to Your modifications and
may provide additional or different license terms and conditions
for use, reproduction, or distribution of Your modifications, or
for any such Derivative Works as a whole, provided Your use,
reproduction, and distribution of the Work otherwise complies with
the conditions stated in this License.
5. Submission of Contributions. Unless You explicitly state otherwise,
any Contribution intentionally submitted for inclusion in the Work
by You to the Licensor shall be under the terms and conditions of
this License, without any additional terms or conditions.
Notwithstanding the above, nothing herein shall supersede or modify
the terms of any separate license agreement you may have executed
with Licensor regarding such Contributions.
6. Trademarks. This License does not grant permission to use the trade
names, trademarks, service marks, or product names of the Licensor,
except as required for reasonable and customary use in describing the
origin of the Work and reproducing the content of the NOTICE file.
7. Disclaimer of Warranty. Unless required by applicable law or
agreed to in writing, Licensor provides the Work (and each
Contributor provides its Contributions) on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
implied, including, without limitation, any warranties or conditions
of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
PARTICULAR PURPOSE. You are solely responsible for determining the
appropriateness of using or redistributing the Work and assume any
risks associated with Your exercise of permissions under this License.
8. Limitation of Liability. In no event and under no legal theory,
whether in tort (including negligence), contract, or otherwise,
unless required by applicable law (such as deliberate and grossly
negligent acts) or agreed to in writing, shall any Contributor be
liable to You for damages, including any direct, indirect, special,
incidental, or consequential damages of any character arising as a
result of this License or out of the use or inability to use the
Work (including but not limited to damages for loss of goodwill,
work stoppage, computer failure or malfunction, or any and all
other commercial damages or losses), even if such Contributor
has been advised of the possibility of such damages.
9. Accepting Warranty or Additional Liability. While redistributing
the Work or Derivative Works thereof, You may choose to offer,
and charge a fee for, acceptance of support, warranty, indemnity,
or other liability obligations and/or rights consistent with this
License. However, in accepting such obligations, You may act only
on Your own behalf and on Your sole responsibility, not on behalf
of any other Contributor, and only if You agree to indemnify,
defend, and hold each Contributor harmless for any liability
incurred by, or claims asserted against, such Contributor by reason
of your accepting any such warranty or additional liability.
END OF TERMS AND CONDITIONS
APPENDIX: How to apply the Apache License to your work.
To apply the Apache License to your work, attach the following
boilerplate notice, with the fields enclosed by brackets "[]"
replaced with your own identifying information. (Don't include
the brackets!) The text should be enclosed in the appropriate
comment syntax for the file format. We also recommend that a
file or class name and description of purpose be included on the
same "printed page" as the copyright notice for easier
identification within third-party archives.
Copyright [yyyy] [name of copyright owner]
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
================================================
FILE: Makefile
================================================
TOOL_DIR = .tool
BINNY = $(TOOL_DIR)/binny
TASK = $(TOOL_DIR)/task
.DEFAULT_GOAL := make-default
## Bootstrapping targets #################################
# note: we need to assume that binny and task have not already been installed
$(BINNY):
@mkdir -p $(TOOL_DIR)
@curl -sSfL https://get.anchore.io/binny | sh -s -- -b $(TOOL_DIR)
# note: we need to assume that binny and task have not already been installed
.PHONY: task
$(TASK) task: $(BINNY)
@$(BINNY) install task -q
.PHONY: ci-bootstrap-go
ci-bootstrap-go:
go mod download
# this is a bootstrapping catch-all, where if the target doesn't exist, we'll ensure the tools are installed and then try again
%:
make $(TASK)
$(TASK) $@
## Shim targets #################################
.PHONY: make-default
make-default: $(TASK)
@# run the default task in the taskfile
@$(TASK)
# for those of us that can't seem to kick the habit of typing `make ...` lets wrap the superior `task` tool
TASKS := $(shell bash -c "test -f $(TASK) && NO_COLOR=1 $(TASK) -l | grep '^\* ' | cut -d' ' -f2 | tr -d ':' | tr '\n' ' '" ) $(shell bash -c "test -f $(TASK) && NO_COLOR=1 $(TASK) -l | grep 'aliases:' | cut -d ':' -f 3 | tr '\n' ' ' | tr -d ','")
.PHONY: $(TASKS)
$(TASKS): $(TASK)
@$(TASK) $@
help: $(TASK)
@$(TASK) -l
================================================
FILE: README.md
================================================
<p align="center">
<img alt="Grype logo" src="https://user-images.githubusercontent.com/5199289/136855393-d0a9eef9-ccf1-4e2b-9d7c-7aad16a567e5.png" width="234">
</p>
# Grype
**A vulnerability scanner for container images and filesystems.**
<p align="center">
<a href="https://github.com/anchore/grype/actions?query=workflow%3A%22Static+Analysis+%2B+Unit+%2B+Integration%22"><img src="https://github.com/anchore/grype/workflows/Static%20Analysis%20+%20Unit%20+%20Integration/badge.svg" alt="Static Analysis + Unit + Integration"></a>
<a href="https://github.com/anchore/grype/actions/workflows/validations.yaml"><img src="https://github.com/anchore/grype/workflows/Validations/badge.svg" alt="Validations"></a>
<a href="https://goreportcard.com/report/github.com/anchore/grype"><img src="https://goreportcard.com/badge/github.com/anchore/grype" alt="Go Report Card"></a>
<a href="https://github.com/anchore/grype/releases/latest"><img src="https://img.shields.io/github/release/anchore/grype.svg" alt="GitHub release"></a>
<a href="https://github.com/anchore/grype"><img src="https://img.shields.io/github/go-mod/go-version/anchore/grype.svg" alt="GitHub go.mod Go version"></a>
<a href="https://github.com/anchore/grype/blob/main/LICENSE"><img src="https://img.shields.io/badge/License-Apache%202.0-blue.svg" alt="License: Apache-2.0"></a>
<a href="https://anchore.com/discourse"><img src="https://img.shields.io/badge/Discourse-Join-blue?logo=discourse" alt="Join our Discourse"></a>
<a rel="me" href="https://fosstodon.org/@grype"><img src="https://img.shields.io/badge/Mastodon-Follow-blue?logoColor=white&logo=mastodon" alt="Follow on Mastodon"></a>
</p>

## Features
- Scan **container images**, **filesystems**, and **SBOMs** for known vulnerabilities (see the docs for a full list of [supported scan targets](https://oss.anchore.com/docs/guides/vulnerability/scan-targets/))
- Supports major OS package ecosystems (Alpine, Debian, Ubuntu, RHEL, Oracle Linux, Amazon Linux, and [more](https://oss.anchore.com/docs/capabilities/all-os/))
- Supports language-specific packages (Ruby, Java, JavaScript, Python, .NET, Go, PHP, Rust, and [more](https://oss.anchore.com/docs/capabilities/all-packages/))
- Supports Docker, OCI, and [Singularity](https://github.com/sylabs/singularity) image formats
- Threat & risk prioritization with **EPSS**, **KEV**, and **risk scoring** (see [interpreting the results docs](https://oss.anchore.com/docs/guides/vulnerability/interpreting-results/))
- [OpenVEX](https://github.com/openvex) support for filtering and augmenting scan results
> [!TIP]
> New to Grype? Check out the [Getting Started guide](https://oss.anchore.com/docs/guides/vulnerability/getting-started/) for a walkthrough!
## Installation
The quickest way to get up and going:
```bash
curl -sSfL https://get.anchore.io/grype | sudo sh -s -- -b /usr/local/bin
```
> [!TIP]
> See [Installation docs](https://oss.anchore.com/docs/installation/grype/) for more ways to get Grype, including Homebrew, Docker, Chocolatey, MacPorts, and more!
## The basics
Scan a container image or directory for vulnerabilities:
```bash
# container image
grype alpine:latest
# directory
grype ./my-project
```
Scan an SBOM for even faster vulnerability detection:
```bash
# scan a Syft SBOM
grype sbom:./sbom.json
# pipe an SBOM into Grype
cat ./sbom.json | grype
```
> [!TIP]
> Check out the [Getting Started guide](https://oss.anchore.com/docs/guides/vulnerability/getting-started/) to explore all of the capabilities and features.
>
> Want to know all of the ins-and-outs of Grype? Check out the [CLI docs](https://oss.anchore.com/docs/reference/grype/cli/) and [configuration docs](https://oss.anchore.com/docs/reference/grype/configuration/).
## Contributing
We encourage users to help make these tools better by [submitting issues](https://github.com/anchore/grype/issues) when you find a bug or want a new feature.
Check out our [contributing overview](https://oss.anchore.com/docs/contributing/) and [developer-specific documentation](https://oss.anchore.com/docs/contributing/grype/) if you are interested in providing code contributions.
<p xmlns:cc="http://creativecommons.org/ns#" xmlns:dct="http://purl.org/dc/terms/">
Grype development is sponsored by <a href="https://anchore.com/">Anchore</a>, and is released under the <a href="https://github.com/anchore/grype?tab=Apache-2.0-1-ov-file">Apache-2.0 License</a>.
The <a property="dct:title" rel="cc:attributionURL" href="https://anchore.com/wp-content/uploads/2024/11/grype-logo.svg">Grype logo</a> by <a rel="cc:attributionURL dct:creator" property="cc:attributionName" href="https://anchore.com/">Anchore</a> is licensed under <a href="https://creativecommons.org/licenses/by/4.0/" target="_blank" rel="license noopener noreferrer" style="display:inline-block;">CC BY 4.0<img style="height:22px!important;margin-left:3px;vertical-align:text-bottom;" src="https://mirrors.creativecommons.org/presskit/icons/cc.svg" alt=""><img style="height:22px!important;margin-left:3px;vertical-align:text-bottom;" src="https://mirrors.creativecommons.org/presskit/icons/by.svg" alt=""></a>
</p>
For commercial support options with Syft or Grype, please [contact Anchore](https://get.anchore.com/contact/).
## Come talk to us!
The Grype Team holds regular community meetings online. All are welcome to join to bring topics for discussion.
- Check the [calendar](https://calendar.google.com/calendar/u/0/r?cid=Y182OTM4dGt0MjRtajI0NnNzOThiaGtnM29qNEBncm91cC5jYWxlbmRhci5nb29nbGUuY29t) for the next meeting date.
- Add items to the [agenda](https://docs.google.com/document/d/1ZtSAa6fj2a6KRWviTn3WoJm09edvrNUp4Iz_dOjjyY8/edit?usp=sharing) (join [this group](https://groups.google.com/g/anchore-oss-community) for write access to the [agenda](https://docs.google.com/document/d/1ZtSAa6fj2a6KRWviTn3WoJm09edvrNUp4Iz_dOjjyY8/edit?usp=sharing))
- See you there!
================================================
FILE: RELEASE.md
================================================
# Release
A release of grype comprises:
- a new semver git tag from the current tip of the main branch
- a new [github release](https://github.com/anchore/grype/releases) with a changelog and archived binary assets
- docker images published to `ghcr.io` and `dockerhub`, including multi architecture images + manifest
- [`anchore/homebrew-grype`](https://github.com/anchore/homebrew-grype) tap updated to point to assets in the latest github release
Ideally releasing should be done often with small increments when possible. Unless a
breaking change is blocking the release, or no fixes/features have been merged, a good
target release cadence is between every 1 or 2 weeks.
## Creating a release
This release process itself should be as automated as possible, and has only a few steps:
1. **Trigger a new release with `make release`**. At this point you'll see a preview
changelog in the terminal. If you're happy with the changelog, press `y` to continue, otherwise
you can abort and adjust the labels on the PRs and issues to be included in the release and
re-run the release trigger command.
1. A release admin must approve the release on the GitHub Actions [release pipeline](https://github.com/anchore/grype/actions/workflows/release.yaml) run page.
Once approved, the release pipeline will generate all assets and publish a GitHub Release.
## Retracting a release
If a release is found to be problematic, it can be retracted with the following steps:
- Deleting the GitHub Release
- Untag the docker images in the `ghcr.io` and `docker.io` registries
- Revert the brew formula in [`anchore/homebrew-grype`](https://github.com/anchore/homebrew-grype) to point to the previous release
- Add a new `retract` entry in the go.mod for the versioned release
**Note**: do not delete release tags from the git repository since there may already be references to the release
in the go proxy, which will cause confusion when trying to reuse the tag later (the H1 hash will not match and there
will be a warning when users try to pull the new release).
================================================
FILE: SECURITY.md
================================================
# Security Policy
## Supported Versions
Security updates are applied only to the most recent release, try to always be up to date.
## Reporting a Vulnerability
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 a best effort basis, so please indicate the "urgency level" of the vulnerability as Critical, High, Medium or Low.
For more details, see our [security policy documentation](https://oss.anchore.com/docs/contributing/security/).
================================================
FILE: Taskfile.yaml
================================================
version: "3"
vars:
OWNER: anchore
PROJECT: grype
# static file dirs
TOOL_DIR: .tool
TMP_DIR: .tmp
# used for changelog generation
CHANGELOG: CHANGELOG.md
NEXT_VERSION: VERSION
# used for snapshot builds
OS:
sh: uname -s | tr '[:upper:]' '[:lower:]'
ARCH:
sh: |
[ "$(uname -m)" = "x86_64" ] && echo "amd64_v1" || echo $(uname -m)
PROJECT_ROOT:
sh: echo $PWD
# note: the snapshot dir must be a relative path starting with ./
SNAPSHOT_DIR: ./snapshot
SNAPSHOT_BIN: "{{ .PROJECT_ROOT }}/{{ .SNAPSHOT_DIR }}/{{ .OS }}-build_{{ .OS }}_{{ .ARCH }}/{{ .PROJECT }}"
SNAPSHOT_CMD: "{{ .TOOL_DIR }}/goreleaser release --config {{ .TMP_DIR }}/goreleaser.yaml --clean --snapshot --skip=publish --skip=sign"
BUILD_CMD: "{{ .TOOL_DIR }}/goreleaser build --config {{ .TMP_DIR }}/goreleaser.yaml --clean --snapshot --single-target"
RELEASE_CMD: "{{ .TOOL_DIR }}/goreleaser release --clean --release-notes {{ .CHANGELOG }}"
VERSION:
sh: git describe --dirty --always --tags
# used for install and acceptance testing
COMPARE_DIR: ./test/compare
COMPARE_TEST_IMAGE: centos:8.2.2004
env:
SYFT_CHECK_FOR_APP_UPDATE: false
GRYPE_CHECK_FOR_APP_UPDATE: false
tasks:
## High-level tasks #################################
# note: the default task should not run levels of test, only build the project.
default:
desc: Build the project
cmds:
- task: build
validate:
desc: Run all validation tasks
aliases:
- pr-validations
- validations
cmds:
- task: static-analysis
- task: test
- task: install-test
static-analysis:
desc: Run all static analysis tasks
cmds:
- task: check-go-mod-tidy
- task: check-licenses
- task: lint
- task: check-json-schema-drift
- task: check-db-schema-drift
# TODO: while developing v6, we need to disable this check (since v5 and v6 are imported in the same codebase)
# - task: validate-grype-db-schema
test:
desc: Run all levels of test
cmds:
- task: unit
- task: integration
- task: cli
## Bootstrap tasks #################################
binny:
internal: true
# desc: Get the binny tool
generates:
- "{{ .TOOL_DIR }}/binny"
status:
- "test -f {{ .TOOL_DIR }}/binny"
cmd: "curl -sSfL https://get.anchore.io/binny | sh -s -- -b .tool"
silent: true
tools:
desc: Install all tools needed for CI and local development
deps: [binny]
aliases:
- bootstrap
generates:
- ".binny.yaml"
- "{{ .TOOL_DIR }}/*"
status:
- "{{ .TOOL_DIR }}/binny check -v"
cmd: "{{ .TOOL_DIR }}/binny install -v"
silent: true
update-tools:
desc: Update pinned versions of all tools to their latest available versions
deps: [binny]
generates:
- ".binny.yaml"
- "{{ .TOOL_DIR }}/*"
cmd: "{{ .TOOL_DIR }}/binny update -v"
silent: true
update-quality-gate-db:
desc: Update pinned version of quality gate database
cmds:
- cmd: "go run cmd/grype/main.go db list -o json | jq -r '\"https://grype.anchore.io/databases/v6/\" + .[0].path' > test/quality/test-db"
silent: true
list-tools:
desc: List all tools needed for CI and local development
deps: [binny]
cmd: "{{ .TOOL_DIR }}/binny list"
silent: true
list-tool-updates:
desc: List all tools that are not up to date relative to the binny config
deps: [binny]
cmd: "{{ .TOOL_DIR }}/binny list --updates"
silent: true
tmpdir:
silent: true
generates:
- "{{ .TMP_DIR }}"
cmd: "mkdir -p {{ .TMP_DIR }}"
## Static analysis tasks #################################
format:
desc: Auto-format all source code
deps: [tools]
cmds:
- gofmt -w -s .
- "{{ .TOOL_DIR }}/gosimports -local github.com/anchore -w ."
- go mod tidy
lint-fix:
desc: Auto-format all source code + run golangci lint fixers
deps: [tools]
cmds:
- task: format
- "{{ .TOOL_DIR }}/golangci-lint run --tests=false --fix"
lint:
desc: Run gofmt + golangci lint checks
vars:
BAD_FMT_FILES:
sh: gofmt -l -s .
BAD_FILE_NAMES:
sh: "find . | grep -e ':' | grep -v -e 'test/quality/.yardstick' -e 'test/quality/vulnerability-match-labels' || true"
deps: [tools]
cmds:
# ensure there are no go fmt differences
- cmd: 'test -z "{{ .BAD_FMT_FILES }}" || (echo "files with gofmt issues: [{{ .BAD_FMT_FILES }}]"; exit 1)'
silent: true
# ensure there are no files with ":" in it (a known back case in the go ecosystem)
- cmd: 'test -z "{{ .BAD_FILE_NAMES }}" || (echo "files with bad names: [{{ .BAD_FILE_NAMES }}]"; exit 1)'
silent: true
# run linting
- "{{ .TOOL_DIR }}/golangci-lint run --tests=false"
check-licenses:
# desc: Ensure transitive dependencies are compliant with the current license policy
deps: [tools]
cmd: "{{ .TOOL_DIR }}/bouncer check ./..."
check-go-mod-tidy:
# desc: Ensure go.mod and go.sum are up to date
cmds:
- cmd: .github/scripts/go-mod-tidy-check.sh && echo "go.mod and go.sum are tidy!"
silent: true
check-json-schema-drift:
desc: Ensure there is no drift between the JSON schema and the code
cmds:
- .github/scripts/json-schema-drift-check.sh
check-db-schema-drift:
desc: Ensure there is no drift between the database blob schemas and the code
cmds:
- .github/scripts/db-schema-drift-check.sh
validate-grype-db-schema:
desc: Ensure the codebase is only referencing a single grype-db schema version (multiple is not allowed)
cmds:
- python test/validate-grype-db-schema.py
## Testing tasks #################################
unit:
desc: Run unit tests
deps:
- tmpdir
vars:
TEST_PKGS:
sh: "go list ./... | grep -v {{ .OWNER }}/{{ .PROJECT }}/test | grep -v {{ .OWNER }}/{{ .PROJECT }}/internal/test | tr '\n' ' '"
# unit test coverage threshold (in % coverage)
COVERAGE_THRESHOLD: 47
cmds:
- "go test -coverprofile {{ .TMP_DIR }}/unit-coverage-details.txt {{ .TEST_PKGS }}"
- cmd: ".github/scripts/coverage.py {{ .COVERAGE_THRESHOLD }} {{ .TMP_DIR }}/unit-coverage-details.txt"
silent: true
integration:
desc: Run integration tests
cmds:
- "go test -v ./test/integration"
# update database outside race detector, since doing so with
# race detector on is very slow
- "go run cmd/{{ .PROJECT }}/main.go db update"
# exercise most of the CLI with the data race detector enabled
- "go run -race cmd/{{ .PROJECT }}/main.go alpine:latest"
_ensure-snapshot:
# Ensure the snapshot binary is available, building only if needed.
# In CI, set GRYPE_SNAPSHOT_PREBUILT=true to skip the rebuild when the binary was restored from cache.
# Locally, this falls through to the snapshot task which uses checksum-based staleness detection
# so that code changes always produce a fresh binary.
internal: true
status:
- test -n "$GRYPE_SNAPSHOT_PREBUILT" -a -f "{{ .SNAPSHOT_BIN }}"
cmds:
- task: snapshot
cli:
desc: Run CLI tests
deps: [tools, _ensure-snapshot]
sources:
- "{{ .SNAPSHOT_BIN }}"
- ./test/cli/**
- ./**/*.go
cmds:
- cmd: "echo 'testing binary: {{ .SNAPSHOT_BIN }}'"
silent: true
- cmd: "test -f {{ .SNAPSHOT_BIN }} || (find {{ .SNAPSHOT_DIR }} && echo '\nno snapshot found' && false)"
silent: true
- "go test -count=1 -timeout=15m -v ./test/cli"
quality:
desc: Run quality tests
cmds:
- "cd test/quality && make"
## Test-fixture-related targets #################################
fingerprints:
desc: Generate test fixture fingerprints
generates:
- test/integration/testdata/cache.fingerprint
- test/install/cache.fingerprint
- test/cli/testdata/cache.fingerprint
cmds:
# for IMAGE integration test fixtures
- "cd test/integration/testdata && make cache.fingerprint"
# for INSTALL integration test fixtures
- "cd test/install && make cache.fingerprint"
# for CLI test fixtures
- "cd test/cli/testdata && make cache.fingerprint"
show-test-image-cache:
silent: true
cmds:
- "echo '\nDocker daemon cache:'"
- "docker images --format '{{`{{.ID}}`}} {{`{{.Repository}}`}}:{{`{{.Tag}}`}}' | grep stereoscope-fixture- | sort"
- "echo '\nTar cache:'"
- 'find . -type f -wholename "**/testdata/snapshot/*" | sort'
## install.sh testing targets #################################
install-test:
cmds:
- "cd test/install && make"
install-test-cache-save:
cmds:
- "cd test/install && make save"
install-test-cache-load:
cmds:
- "cd test/install && make load"
install-test-ci-mac:
cmds:
- "cd test/install && make ci-test-mac"
generate-compare-file:
cmd: "go run ./cmd/{{ .PROJECT }} {{ .COMPARE_TEST_IMAGE }} -o json > {{ .COMPARE_DIR }}/testdata/acceptance-{{ .COMPARE_TEST_IMAGE }}.json"
compare-mac:
deps: [tmpdir]
cmd: |
{{ .COMPARE_DIR }}/mac.sh \
{{ .SNAPSHOT_DIR }} \
{{ .COMPARE_DIR }} \
{{ .COMPARE_TEST_IMAGE }} \
{{ .TMP_DIR }}
compare-linux:
cmds:
- task: compare-test-deb-package-install
- task: compare-test-rpm-package-install
compare-test-deb-package-install:
deps: [tmpdir]
cmd: |
{{ .COMPARE_DIR }}/deb.sh \
{{ .SNAPSHOT_DIR }} \
{{ .COMPARE_DIR }} \
{{ .COMPARE_TEST_IMAGE }} \
{{ .TMP_DIR }}
compare-test-rpm-package-install:
deps: [tmpdir]
cmd: |
{{ .COMPARE_DIR }}/rpm.sh \
{{ .SNAPSHOT_DIR }} \
{{ .COMPARE_DIR }} \
{{ .COMPARE_TEST_IMAGE }} \
{{ .TMP_DIR }}
## Code and data generation targets #################################
generate:
desc: Run code and data generation tasks
cmds:
- task: generate-json-schema
- task: generate-db-schema
- task: generate-codename-data
generate-json-schema:
desc: Generate a new JSON schema
cmds:
# re-generate package metadata
- "cd grype/internal && go generate"
# generate the JSON schema for the CLI output
- "cd cmd/grype/cli/commands/internal/jsonschema && go run ."
generate-db-schema:
desc: Generate database blob JSON schemas
cmds:
# generate the JSON schema for database blob types
- "cd grype/db/v6/schema && go run ."
generate-codename-data:
desc: Generate OS codename lookup data
cmds:
- "go generate ./grype/db"
- task: format
## Build-related targets #################################
build:
desc: Build the project
deps: [tools, tmpdir]
generates:
- "{{ .PROJECT }}"
cmds:
- silent: true
cmd: |
echo "dist: {{ .SNAPSHOT_DIR }}" > {{ .TMP_DIR }}/goreleaser.yaml
cat .goreleaser.yaml >> {{ .TMP_DIR }}/goreleaser.yaml
- "{{ .BUILD_CMD }}"
snapshot:
desc: Create a snapshot release
aliases:
- build
deps: [tools, tmpdir]
sources:
- cmd/**/*.go
- "{{ .PROJECT }}/**/*.go"
- internal/**/*.go
method: checksum
generates:
- "{{ .SNAPSHOT_BIN }}"
cmds:
- silent: true
cmd: |
echo "dist: {{ .SNAPSHOT_DIR }}" > {{ .TMP_DIR }}/goreleaser.yaml
cat .goreleaser.yaml >> {{ .TMP_DIR }}/goreleaser.yaml
- "{{ .SNAPSHOT_CMD }}"
changelog:
desc: Generate a changelog
deps: [tools]
generates:
- "{{ .CHANGELOG }}"
- "{{ .NEXT_VERSION }}"
cmds:
- "{{ .TOOL_DIR }}/chronicle -vv -n --version-file {{ .NEXT_VERSION }} > {{ .CHANGELOG }}"
- "{{ .TOOL_DIR }}/glow -w 0 {{ .CHANGELOG }}"
## Release targets #################################
release:
desc: Create a release
interactive: true
deps: [tools]
cmds:
- cmd: .github/scripts/trigger-release.sh
silent: true
## CI-only targets #################################
ci-check:
# desc: "[CI only] Are you in CI?"
cmds:
- cmd: .github/scripts/ci-check.sh
silent: true
ci-release:
# desc: "[CI only] Create a release"
deps: [tools]
cmds:
- task: ci-check
- "{{ .TOOL_DIR }}/chronicle -vvv > CHANGELOG.md"
- cmd: "cat CHANGELOG.md"
silent: true
- "{{ .RELEASE_CMD }}"
ci-validate-test-config:
# desc: "[CI only] Ensure the update URL is not overridden (not pointing to staging)"
silent: true
cmd: |
bash -c '\
grep -q "update-url" test/grype-test-config.yaml; \
if [ $? -eq 0 ]; then \
echo "Found \"update-url\" in CLI testing config. Cannot release if previous CLI testing did not use production (default) values"; \
else
echo "Test configuration valid"
fi'
## Cleanup targets #################################
clean-snapshot:
desc: Remove any snapshot builds
cmds:
- "rm -rf {{ .SNAPSHOT_DIR }}"
- "rm -rf {{ .TMP_DIR }}/goreleaser.yaml"
clean-cache:
desc: Remove all docker cache and local image tar cache
cmds:
- 'find . -type f -wholename "**/testdata/cache/stereoscope-fixture-*.tar" -delete'
- "docker images --format '{{`{{.ID}}`}} {{`{{.Repository}}`}}' | grep stereoscope-fixture- | awk '{print $$1}' | uniq | xargs -r docker rmi --force"
================================================
FILE: artifacthub-repo.yml
================================================
# See documentation here: https://github.com/artifacthub/hub/blob/v1.6.0/docs/metadata/artifacthub-repo.yml
repositoryID: 8ff93ef9-2a75-40b6-945e-514e936fe9bb
owners:
- name: wagoodman
email: wagoodman@gmail.com
================================================
FILE: cmd/grype/cli/cli.go
================================================
package cli
import (
"errors"
"os"
"runtime/debug"
"strings"
"github.com/charmbracelet/lipgloss"
"github.com/muesli/termenv"
"github.com/spf13/cobra"
"github.com/anchore/clio"
"github.com/anchore/grype/cmd/grype/cli/commands"
grypeHandler "github.com/anchore/grype/cmd/grype/cli/ui"
"github.com/anchore/grype/cmd/grype/internal/ui"
v6 "github.com/anchore/grype/grype/db/v6"
"github.com/anchore/grype/grype/grypeerr"
"github.com/anchore/grype/internal/bus"
"github.com/anchore/grype/internal/log"
"github.com/anchore/grype/internal/redact"
"github.com/anchore/stereoscope"
syftHandler "github.com/anchore/syft/cmd/syft/cli/ui"
"github.com/anchore/syft/syft"
)
func Application(id clio.Identification) clio.Application {
app, _ := create(id)
return app
}
func Command(id clio.Identification) *cobra.Command {
_, cmd := create(id)
return cmd
}
func SetupConfig(id clio.Identification) *clio.SetupConfig {
return clio.NewSetupConfig(id).
WithGlobalConfigFlag(). // add persistent -c <path> for reading an application config from
WithGlobalLoggingFlags(). // add persistent -v and -q flags tied to the logging config
WithConfigInRootHelp(). // --help on the root command renders the full application config in the help text
WithUIConstructor(
// select a UI based on the logging configuration and state of stdin (if stdin is a tty)
func(cfg clio.Config) (*clio.UICollection, error) {
// remove CI var from consideration when determining if we should use the UI
lipgloss.SetDefaultRenderer(lipgloss.NewRenderer(os.Stdout, termenv.WithEnvironment(environWithoutCI{})))
// setup the UIs
noUI := ui.None(cfg.Log.Quiet)
if !cfg.Log.AllowUI(os.Stdin) || cfg.Log.Quiet {
return clio.NewUICollection(noUI), nil
}
return clio.NewUICollection(
ui.New(cfg.Log.Quiet,
grypeHandler.New(grypeHandler.DefaultHandlerConfig()),
syftHandler.New(syftHandler.DefaultHandlerConfig()),
),
noUI,
), nil
},
).
WithInitializers(
func(state *clio.State) error {
// clio is setting up and providing the bus, redact store, and logger to the application. Once loaded,
// we can hoist them into the internal packages for global use.
stereoscope.SetBus(state.Bus)
syft.SetBus(state.Bus)
bus.Set(state.Bus)
redact.Set(state.RedactStore)
log.Set(state.Logger)
syft.SetLogger(state.Logger.Nested("from", "syft"))
stereoscope.SetLogger(state.Logger.Nested("from", "stereoscope"))
return nil
},
).
WithPostRuns(func(_ *clio.State, _ error) {
stereoscope.Cleanup() //nolint:staticcheck
}).
WithMapExitCode(func(err error) int {
// return exit code 2 to indicate when a vulnerability severity is discovered
// that is equal or above the given --fail-on severity value.
if errors.Is(err, grypeerr.ErrAboveSeverityThreshold) {
return 2
}
// return exit code 100 to indicate a DB upgrade is available (cmd: db check).
if errors.Is(err, grypeerr.ErrDBUpgradeAvailable) {
return 100
}
return 1
})
}
func create(id clio.Identification) (clio.Application, *cobra.Command) {
clioCfg := SetupConfig(id)
app := clio.New(*clioCfg)
rootCmd := commands.Root(app)
// add sub-commands
rootCmd.AddCommand(
commands.DB(app),
commands.Completion(app),
commands.Explain(app),
clio.VersionCommand(id, syftVersion, dbVersion),
clio.ConfigCommand(app, nil),
)
return app, rootCmd
}
func syftVersion() (string, any) {
buildInfo, ok := debug.ReadBuildInfo()
if !ok {
log.Debug("unable to find the buildinfo section of the binary (syft version is unknown)")
return "", ""
}
for _, d := range buildInfo.Deps {
if d.Path == "github.com/anchore/syft" {
return "Syft Version", d.Version
}
}
log.Debug("unable to find 'github.com/anchore/syft' from the buildinfo section of the binary")
return "", ""
}
func dbVersion() (string, any) {
return "Supported DB Schema", v6.ModelVersion
}
type environWithoutCI struct {
}
func (e environWithoutCI) Environ() []string {
var out []string
for _, s := range os.Environ() {
if strings.HasPrefix(s, "CI=") {
continue
}
out = append(out, s)
}
return out
}
func (e environWithoutCI) Getenv(s string) string {
if s == "CI" {
return ""
}
return os.Getenv(s)
}
================================================
FILE: cmd/grype/cli/cli_test.go
================================================
package cli
import (
"testing"
"github.com/stretchr/testify/require"
"github.com/anchore/clio"
)
func Test_Command(t *testing.T) {
root := Command(clio.Identification{
Name: "test-name",
Version: "test-version",
})
require.Equal(t, root.Name(), "test-name")
require.NotEmpty(t, root.Commands())
}
================================================
FILE: cmd/grype/cli/commands/completion.go
================================================
package commands
import (
"context"
"os"
"strings"
"github.com/docker/docker/api/types/filters"
"github.com/docker/docker/api/types/image"
"github.com/docker/docker/client"
"github.com/spf13/cobra"
"github.com/anchore/clio"
)
// Completion returns a command to provide completion to various terminal shells
func Completion(app clio.Application) *cobra.Command {
return &cobra.Command{
Use: "completion [bash|zsh|fish]",
Short: "Generate a shell completion for Grype (listing local docker images)",
Long: `To load completions (docker image list):
Bash:
$ source <(grype completion bash)
# To load completions for each session, execute once:
Linux:
$ grype completion bash > /etc/bash_completion.d/grype
MacOS:
$ grype completion bash > /usr/local/etc/bash_completion.d/grype
Zsh:
# If shell completion is not already enabled in your environment you will need
# to enable it. You can execute the following once:
$ echo "autoload -U compinit; compinit" >> ~/.zshrc
# To load completions for each session, execute once:
$ grype completion zsh > "${fpath[1]}/_grype"
# You will need to start a new shell for this setup to take effect.
Fish:
$ grype completion fish | source
# To load completions for each session, execute once:
$ grype completion fish > ~/.config/fish/completions/grype.fish
`,
DisableFlagsInUseLine: true,
ValidArgs: []string{"bash", "fish", "zsh"},
PreRunE: disableUI(app),
Args: cobra.MatchAll(cobra.ExactArgs(1), cobra.OnlyValidArgs),
RunE: func(cmd *cobra.Command, args []string) error {
var err error
switch args[0] {
case "zsh":
err = cmd.Root().GenZshCompletion(os.Stdout)
case "bash":
err = cmd.Root().GenBashCompletion(os.Stdout)
case "fish":
err = cmd.Root().GenFishCompletion(os.Stdout, true)
}
return err
},
}
}
func listLocalDockerImages(prefix string) ([]string, error) {
var repoTags = make([]string, 0)
ctx := context.Background()
cli, err := client.NewClientWithOpts(client.FromEnv, client.WithAPIVersionNegotiation())
if err != nil {
return repoTags, err
}
// Only want to return tagged images
imageListArgs := filters.NewArgs()
imageListArgs.Add("dangling", "false")
images, err := cli.ImageList(ctx, image.ListOptions{All: false, Filters: imageListArgs})
if err != nil {
return repoTags, err
}
for _, image := range images {
// image may have multiple tags
for _, tag := range image.RepoTags {
if strings.HasPrefix(tag, prefix) {
repoTags = append(repoTags, tag)
}
}
}
return repoTags, nil
}
func dockerImageValidArgsFunction(_ *cobra.Command, _ []string, toComplete string) ([]string, cobra.ShellCompDirective) {
// Since we use ValidArgsFunction, Cobra will call this AFTER having parsed all flags and arguments provided
dockerImageRepoTags, err := listLocalDockerImages(toComplete)
if err != nil {
// Indicates that an error occurred and completions should be ignored
return []string{"completion failed"}, cobra.ShellCompDirectiveError
}
if len(dockerImageRepoTags) == 0 {
return []string{"no docker images found"}, cobra.ShellCompDirectiveError
}
// ShellCompDirectiveDefault indicates that the shell will perform its default behavior after completions have
// been provided (without implying other possible directives)
return dockerImageRepoTags, cobra.ShellCompDirectiveDefault
}
================================================
FILE: cmd/grype/cli/commands/db.go
================================================
package commands
import (
"github.com/spf13/cobra"
"github.com/anchore/clio"
)
const (
jsonOutputFormat = "json"
tableOutputFormat = "table"
textOutputFormat = "text"
)
func DB(app clio.Application) *cobra.Command {
db := &cobra.Command{
Use: "db",
Short: "vulnerability database operations",
}
db.AddCommand(
DBCheck(app),
DBDelete(app),
DBImport(app),
DBList(app),
DBStatus(app),
DBUpdate(app),
DBSearch(app),
DBProviders(app),
)
return db
}
================================================
FILE: cmd/grype/cli/commands/db_check.go
================================================
package commands
import (
"encoding/json"
"fmt"
"io"
"os"
"github.com/spf13/cobra"
"github.com/anchore/clio"
"github.com/anchore/grype/cmd/grype/cli/options"
db "github.com/anchore/grype/grype/db/v6"
"github.com/anchore/grype/grype/db/v6/distribution"
"github.com/anchore/grype/grype/grypeerr"
"github.com/anchore/grype/internal/log"
)
type dbCheckOptions struct {
Output string `yaml:"output" json:"output" mapstructure:"output"`
options.DatabaseCommand `yaml:",inline" mapstructure:",squash"`
}
var _ clio.FlagAdder = (*dbCheckOptions)(nil)
func (d *dbCheckOptions) AddFlags(flags clio.FlagSet) {
flags.StringVarP(&d.Output, "output", "o", "format to display results (available=[text, json])")
}
func DBCheck(app clio.Application) *cobra.Command {
opts := &dbCheckOptions{
Output: textOutputFormat,
DatabaseCommand: *options.DefaultDatabaseCommand(app.ID()),
}
cmd := &cobra.Command{
Use: "check",
Short: "Check to see if there is a database update available",
PreRunE: func(cmd *cobra.Command, args []string) error {
// DB commands should not opt into the low-pass check filter
opts.DB.MaxUpdateCheckFrequency = 0
return disableUI(app)(cmd, args)
},
Args: cobra.ExactArgs(0),
RunE: func(_ *cobra.Command, _ []string) error {
return runDBCheck(*opts)
},
}
// prevent from being shown in the grype config
type configWrapper struct {
Hidden *dbCheckOptions `json:"-" yaml:"-" mapstructure:"-"`
*options.DatabaseCommand `yaml:",inline" mapstructure:",squash"`
}
return app.SetupCommand(cmd, &configWrapper{Hidden: opts, DatabaseCommand: &opts.DatabaseCommand})
}
func runDBCheck(opts dbCheckOptions) error {
client, err := distribution.NewClient(opts.ToClientConfig())
if err != nil {
return fmt.Errorf("unable to create distribution client: %w", err)
}
cfg := opts.ToCuratorConfig()
current, err := db.ReadDescription(cfg.DBFilePath())
if err != nil {
log.WithFields("error", err).Debug("unable to read current database metadata")
current = nil
}
archive, err := client.IsUpdateAvailable(current)
if err != nil {
return fmt.Errorf("unable to check for vulnerability database update: %w", err)
}
updateAvailable := archive != nil
if err := presentNewDBCheck(opts.Output, os.Stdout, updateAvailable, current, archive); err != nil {
return err
}
if updateAvailable {
return grypeerr.ErrDBUpgradeAvailable
}
return nil
}
type dbCheckJSON struct {
CurrentDB *db.Description `json:"currentDB"`
CandidateDB *distribution.Archive `json:"candidateDB"`
UpdateAvailable bool `json:"updateAvailable"`
}
func presentNewDBCheck(format string, writer io.Writer, updateAvailable bool, current *db.Description, candidate *distribution.Archive) error {
switch format {
case textOutputFormat:
if current != nil {
fmt.Fprintf(writer, "Installed DB version %s was built on %s\n", current.SchemaVersion, current.Built.String())
} else {
fmt.Fprintln(writer, "No installed DB version found")
}
if !updateAvailable {
fmt.Fprintln(writer, "No update available")
return nil
}
fmt.Fprintf(writer, "Updated DB version %s was built on %s\n", candidate.SchemaVersion, candidate.Built.String())
fmt.Fprintln(writer, "You can run 'grype db update' to update to the latest db")
case jsonOutputFormat:
data := dbCheckJSON{
CurrentDB: current,
CandidateDB: candidate,
UpdateAvailable: updateAvailable,
}
enc := json.NewEncoder(writer)
enc.SetEscapeHTML(false)
enc.SetIndent("", " ")
if err := enc.Encode(&data); err != nil {
return fmt.Errorf("failed to db listing information: %+v", err)
}
default:
return fmt.Errorf("unsupported output format: %s", format)
}
return nil
}
================================================
FILE: cmd/grype/cli/commands/db_check_test.go
================================================
package commands
import (
"bytes"
"strings"
"testing"
"time"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
db "github.com/anchore/grype/grype/db/v6"
"github.com/anchore/grype/grype/db/v6/distribution"
"github.com/anchore/grype/internal/schemaver"
)
func TestPresentNewDBCheck(t *testing.T) {
currentDB := &db.Description{
SchemaVersion: schemaver.New(6, 0, 0),
Built: db.Time{Time: time.Date(2023, 11, 25, 12, 0, 0, 0, time.UTC)},
}
candidateDB := &distribution.Archive{
Description: db.Description{
SchemaVersion: schemaver.New(6, 0, 1),
Built: db.Time{Time: time.Date(2023, 11, 26, 12, 0, 0, 0, time.UTC)},
},
Path: "vulnerability-db_6.0.1_2023-11-26T12:00:00Z_6238463.tar.gz",
Checksum: "sha256:1234561234567890345674561234567890345678",
}
tests := []struct {
name string
format string
updateAvailable bool
current *db.Description
candidate *distribution.Archive
expectedText string
expectErr require.ErrorAssertionFunc
}{
{
name: "text format with update available",
format: textOutputFormat,
updateAvailable: true,
current: currentDB,
candidate: candidateDB,
expectedText: `
Installed DB version v6.0.0 was built on 2023-11-25T12:00:00Z
Updated DB version v6.0.1 was built on 2023-11-26T12:00:00Z
You can run 'grype db update' to update to the latest db
`,
},
{
name: "text format without update available",
format: textOutputFormat,
updateAvailable: false,
current: currentDB,
candidate: nil,
expectedText: `
Installed DB version v6.0.0 was built on 2023-11-25T12:00:00Z
No update available
`,
},
{
name: "json format with update available",
format: jsonOutputFormat,
updateAvailable: true,
current: currentDB,
candidate: candidateDB,
expectedText: `
{
"currentDB": {
"schemaVersion": "v6.0.0",
"built": "2023-11-25T12:00:00Z"
},
"candidateDB": {
"schemaVersion": "v6.0.1",
"built": "2023-11-26T12:00:00Z",
"path": "vulnerability-db_6.0.1_2023-11-26T12:00:00Z_6238463.tar.gz",
"checksum": "sha256:1234561234567890345674561234567890345678"
},
"updateAvailable": true
}
`,
},
{
name: "json format without update available",
format: jsonOutputFormat,
updateAvailable: false,
current: currentDB,
candidate: nil,
expectedText: `
{
"currentDB": {
"schemaVersion": "v6.0.0",
"built": "2023-11-25T12:00:00Z"
},
"candidateDB": null,
"updateAvailable": false
}
`,
},
{
name: "unsupported format",
format: "xml",
expectErr: requireErrorContains("unsupported output format: xml"),
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
if tt.expectErr == nil {
tt.expectErr = require.NoError
}
buf := &bytes.Buffer{}
err := presentNewDBCheck(tt.format, buf, tt.updateAvailable, tt.current, tt.candidate)
tt.expectErr(t, err)
if err != nil {
return
}
assert.Equal(t, strings.TrimSpace(tt.expectedText), strings.TrimSpace(buf.String()))
})
}
}
func requireErrorContains(expected string) require.ErrorAssertionFunc {
return func(t require.TestingT, err error, msgAndArgs ...interface{}) {
require.Error(t, err)
assert.Contains(t, err.Error(), expected)
}
}
================================================
FILE: cmd/grype/cli/commands/db_delete.go
================================================
package commands
import (
"fmt"
"github.com/spf13/cobra"
"github.com/anchore/clio"
"github.com/anchore/grype/cmd/grype/cli/options"
"github.com/anchore/grype/grype/db/v6/distribution"
"github.com/anchore/grype/grype/db/v6/installation"
)
func DBDelete(app clio.Application) *cobra.Command {
opts := options.DefaultDatabaseCommand(app.ID())
cmd := &cobra.Command{
Use: "delete",
Short: "Delete the vulnerability database",
Args: cobra.ExactArgs(0),
PreRunE: disableUI(app),
RunE: func(_ *cobra.Command, _ []string) error {
return runDBDelete(*opts)
},
}
// prevent from being shown in the grype config
type configWrapper struct {
*options.DatabaseCommand `yaml:",inline" mapstructure:",squash"`
}
return app.SetupCommand(cmd, &configWrapper{opts})
}
func runDBDelete(opts options.DatabaseCommand) error {
client, err := distribution.NewClient(opts.ToClientConfig())
if err != nil {
return fmt.Errorf("unable to create distribution client: %w", err)
}
c, err := installation.NewCurator(opts.ToCuratorConfig(), client)
if err != nil {
return fmt.Errorf("unable to create curator: %w", err)
}
if err := c.Delete(); err != nil {
return fmt.Errorf("unable to delete vulnerability database: %+v", err)
}
return stderrPrintLnf("Vulnerability database deleted")
}
================================================
FILE: cmd/grype/cli/commands/db_import.go
================================================
package commands
import (
"fmt"
"github.com/spf13/cobra"
"github.com/anchore/clio"
"github.com/anchore/grype/cmd/grype/cli/options"
"github.com/anchore/grype/grype/db/v6/distribution"
"github.com/anchore/grype/grype/db/v6/installation"
"github.com/anchore/grype/internal/log"
)
func DBImport(app clio.Application) *cobra.Command {
opts := options.DefaultDatabaseCommand(app.ID())
cmd := &cobra.Command{
Use: "import FILE | URL",
Short: "Import a vulnerability database or archive from a local file or URL",
Long: fmt.Sprintf("import a vulnerability database archive from a local FILE or URL.\nDB archives can be obtained from %q (or running `db list`). If the URL has a `checksum` query parameter with a fully qualified digest (e.g. 'sha256:abc728...') then the archive/DB will be verified against this value.", opts.DB.UpdateURL),
Args: cobra.ExactArgs(1),
RunE: func(_ *cobra.Command, args []string) error {
return runDBImport(*opts, args[0])
},
}
// prevent from being shown in the grype config
type configWrapper struct {
*options.DatabaseCommand `yaml:",inline" mapstructure:",squash"`
}
return app.SetupCommand(cmd, &configWrapper{opts})
}
func runDBImport(opts options.DatabaseCommand, reference string) error {
// TODO: tui update? better logging?
client, err := distribution.NewClient(opts.ToClientConfig())
if err != nil {
return fmt.Errorf("unable to create distribution client: %w", err)
}
c, err := installation.NewCurator(opts.ToCuratorConfig(), client)
if err != nil {
return fmt.Errorf("unable to create curator: %w", err)
}
log.WithFields("reference", reference).Infof("importing vulnerability database archive")
if err := c.Import(reference); err != nil {
return fmt.Errorf("unable to import vulnerability database: %w", err)
}
s := c.Status()
log.WithFields("built", s.Built.String(), "status", renderStoreValidation(s)).Info("vulnerability database imported")
return nil
}
================================================
FILE: cmd/grype/cli/commands/db_list.go
================================================
package commands
import (
"encoding/json"
"fmt"
"io"
"net/url"
"os"
"github.com/spf13/cobra"
"github.com/anchore/clio"
"github.com/anchore/grype/cmd/grype/cli/options"
"github.com/anchore/grype/grype/db/v6/distribution"
)
type dbListOptions struct {
Output string `yaml:"output" json:"output" mapstructure:"output"`
options.DatabaseCommand `yaml:",inline" mapstructure:",squash"`
}
var _ clio.FlagAdder = (*dbListOptions)(nil)
func (d *dbListOptions) AddFlags(flags clio.FlagSet) {
flags.StringVarP(&d.Output, "output", "o", "format to display results (available=[text, raw, json])")
}
func DBList(app clio.Application) *cobra.Command {
opts := &dbListOptions{
Output: textOutputFormat,
DatabaseCommand: *options.DefaultDatabaseCommand(app.ID()),
}
cmd := &cobra.Command{
Use: "list",
Short: "List all DBs available according to the listing URL",
PreRunE: disableUI(app),
Args: cobra.ExactArgs(0),
RunE: func(_ *cobra.Command, _ []string) error {
return runDBList(*opts)
},
}
// prevent from being shown in the grype config
type configWrapper struct {
Hidden *dbListOptions `json:"-" yaml:"-" mapstructure:"-"`
*options.DatabaseCommand `yaml:",inline" mapstructure:",squash"`
}
return app.SetupCommand(cmd, &configWrapper{Hidden: opts, DatabaseCommand: &opts.DatabaseCommand})
}
func runDBList(opts dbListOptions) error {
c, err := distribution.NewClient(opts.ToClientConfig())
if err != nil {
return fmt.Errorf("unable to create distribution client: %w", err)
}
latest, err := c.Latest()
if err != nil {
return fmt.Errorf("unable to get database listing: %w", err)
}
u, err := c.ResolveArchiveURL(latest.Archive)
if err != nil {
return fmt.Errorf("unable to resolve database URL: %w", err)
}
return presentDBList(opts.Output, u, opts.DB.UpdateURL, os.Stdout, latest)
}
func presentDBList(format string, archiveURL, listingURL string, writer io.Writer, latest *distribution.LatestDocument) error {
if latest == nil {
return fmt.Errorf("no database listing found")
}
// remove query params
archiveURLObj, err := url.Parse(archiveURL)
if err != nil {
return fmt.Errorf("unable to parse db URL %q: %w", archiveURL, err)
}
archiveURLObj.RawQuery = ""
if listingURL == distribution.DefaultConfig().LatestURL {
// append on the schema
listingURL = fmt.Sprintf("%s/v%v/%s", listingURL, latest.SchemaVersion.Model, distribution.LatestFileName)
}
switch format {
case textOutputFormat:
fmt.Fprintf(writer, "Status: %s\n", latest.Status)
fmt.Fprintf(writer, "Schema: %s\n", latest.SchemaVersion.String())
fmt.Fprintf(writer, "Built: %s\n", latest.Built.String())
fmt.Fprintf(writer, "Listing: %s\n", listingURL)
fmt.Fprintf(writer, "DB URL: %s\n", archiveURLObj.String())
fmt.Fprintf(writer, "Checksum: %s\n", latest.Checksum)
case jsonOutputFormat, "raw":
enc := json.NewEncoder(writer)
enc.SetEscapeHTML(false)
enc.SetIndent("", " ")
// why make an array? We are reserving the right to list additional entries in the future without the
// need to change from an object to an array at that point in time. This will be useful if we implement
// the history.json functionality for grabbing historical database listings.
if err := enc.Encode([]any{latest}); err != nil {
return fmt.Errorf("failed to db listing information: %+v", err)
}
default:
return fmt.Errorf("unsupported output format: %s", format)
}
return nil
}
================================================
FILE: cmd/grype/cli/commands/db_list_test.go
================================================
package commands
import (
"bytes"
"encoding/json"
"net/http"
"net/http/httptest"
"strings"
"testing"
"time"
"github.com/stretchr/testify/require"
"github.com/anchore/clio"
"github.com/anchore/grype/cmd/grype/cli/options"
db "github.com/anchore/grype/grype/db/v6"
"github.com/anchore/grype/grype/db/v6/distribution"
"github.com/anchore/grype/internal/schemaver"
)
func Test_ListingUserAgent(t *testing.T) {
t.Run("new", func(t *testing.T) {
listingFile := "/latest.json"
got := ""
// setup mock
handler := http.NewServeMux()
handler.HandleFunc(listingFile, func(w http.ResponseWriter, r *http.Request) {
got = r.Header.Get("User-Agent")
w.WriteHeader(http.StatusOK)
_ = json.NewEncoder(w).Encode(&distribution.LatestDocument{
Status: "active",
Archive: distribution.Archive{
Description: db.Description{
SchemaVersion: schemaver.New(6, 0, 0),
Built: db.Time{Time: time.Now()},
},
Path: "vulnerability-db_v6.0.0.tar.gz",
Checksum: "sha256:dummychecksum",
},
})
})
mockSrv := httptest.NewServer(handler)
defer mockSrv.Close()
dbOptions := *options.DefaultDatabaseCommand(clio.Identification{
Name: "new-app",
Version: "v4.0.0",
})
dbOptions.DB.RequireUpdateCheck = true
dbOptions.DB.UpdateURL = mockSrv.URL + listingFile
err := runDBList(dbListOptions{
Output: textOutputFormat,
DatabaseCommand: dbOptions,
})
require.NoError(t, err)
if got != "new-app v4.0.0" {
t.Errorf("expected User-Agent header to match, got: %v", got)
}
})
}
func TestPresentDBList(t *testing.T) {
latestDoc := &distribution.LatestDocument{
Status: "active",
Archive: distribution.Archive{
Description: db.Description{
SchemaVersion: schemaver.New(6, 0, 0),
Built: db.Time{Time: time.Date(2024, 11, 27, 14, 43, 17, 0, time.UTC)},
},
Path: "vulnerability-db_v6.0.0_2024-11-25T01:31:56Z_1732718597.tar.zst",
Checksum: "sha256:16bcb6551c748056f752f299fcdb4fa50fe61589d086be3889e670261ff21ca4",
},
}
tests := []struct {
name string
format string
baseURL string
archiveURL string
latest *distribution.LatestDocument
expectedText string
expectedErr require.ErrorAssertionFunc
}{
{
name: "valid text format",
format: textOutputFormat,
latest: latestDoc,
baseURL: "http://localhost:8000/latest.json",
archiveURL: "http://localhost:8000/vulnerability-db_v6.0.0_2024-11-25T01:31:56Z_1732718597.tar.zst",
expectedText: `Status: active
Schema: v6.0.0
Built: 2024-11-27T14:43:17Z
Listing: http://localhost:8000/latest.json
DB URL: http://localhost:8000/vulnerability-db_v6.0.0_2024-11-25T01:31:56Z_1732718597.tar.zst
Checksum: sha256:16bcb6551c748056f752f299fcdb4fa50fe61589d086be3889e670261ff21ca4
`,
expectedErr: require.NoError,
},
{
name: "complete default values",
format: textOutputFormat,
latest: latestDoc,
baseURL: "https://grype.anchore.io/databases",
archiveURL: "https://grype.anchore.io/databases/v6/vulnerability-db_v6.0.0_2024-11-25T01:31:56Z_1732718597.tar.zst",
expectedText: `Status: active
Schema: v6.0.0
Built: 2024-11-27T14:43:17Z
Listing: https://grype.anchore.io/databases/v6/latest.json
DB URL: https://grype.anchore.io/databases/v6/vulnerability-db_v6.0.0_2024-11-25T01:31:56Z_1732718597.tar.zst
Checksum: sha256:16bcb6551c748056f752f299fcdb4fa50fe61589d086be3889e670261ff21ca4
`,
expectedErr: require.NoError,
},
{
name: "valid JSON format",
format: jsonOutputFormat,
latest: latestDoc,
expectedText: `[
{
"status": "active",
"schemaVersion": "v6.0.0",
"built": "2024-11-27T14:43:17Z",
"path": "vulnerability-db_v6.0.0_2024-11-25T01:31:56Z_1732718597.tar.zst",
"checksum": "sha256:16bcb6551c748056f752f299fcdb4fa50fe61589d086be3889e670261ff21ca4"
}
]
`,
expectedErr: require.NoError,
},
{
name: "nil latest document",
format: textOutputFormat,
latest: nil,
expectedErr: requireErrorContains("no database listing found"),
},
{
name: "unsupported format",
format: "unsupported",
latest: latestDoc,
expectedErr: requireErrorContains("unsupported output format"),
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
writer := &bytes.Buffer{}
err := presentDBList(tt.format, tt.archiveURL, tt.baseURL, writer, tt.latest)
if tt.expectedErr == nil {
tt.expectedErr = require.NoError
}
tt.expectedErr(t, err)
if err != nil {
return
}
require.Equal(t, strings.TrimSpace(tt.expectedText), strings.TrimSpace(writer.String()))
})
}
}
================================================
FILE: cmd/grype/cli/commands/db_providers.go
================================================
package commands
import (
"encoding/json"
"fmt"
"io"
"strings"
"time"
"github.com/spf13/cobra"
"github.com/anchore/clio"
"github.com/anchore/grype/cmd/grype/cli/options"
v6 "github.com/anchore/grype/grype/db/v6"
"github.com/anchore/grype/grype/db/v6/distribution"
"github.com/anchore/grype/grype/db/v6/installation"
"github.com/anchore/grype/internal/bus"
)
type dbProvidersOptions struct {
Output string `yaml:"output" json:"output"`
options.DatabaseCommand `yaml:",inline" mapstructure:",squash"`
}
var _ clio.FlagAdder = (*dbProvidersOptions)(nil)
func (d *dbProvidersOptions) AddFlags(flags clio.FlagSet) {
flags.StringVarP(&d.Output, "output", "o", "format to display results (available=[table, json])")
}
func DBProviders(app clio.Application) *cobra.Command {
opts := &dbProvidersOptions{
Output: tableOutputFormat,
DatabaseCommand: *options.DefaultDatabaseCommand(app.ID()),
}
cmd := &cobra.Command{
Use: "providers",
Short: "List vulnerability providers that are in the database",
Args: cobra.ExactArgs(0),
RunE: func(_ *cobra.Command, _ []string) error {
return runDBProviders(opts)
},
}
// prevent from being shown in the grype config
type configWrapper struct {
Hidden *dbProvidersOptions `json:"-" yaml:"-" mapstructure:"-"`
*options.DatabaseCommand `yaml:",inline" mapstructure:",squash"`
}
return app.SetupCommand(cmd, &configWrapper{Hidden: opts, DatabaseCommand: &opts.DatabaseCommand})
}
func runDBProviders(opts *dbProvidersOptions) error {
client, err := distribution.NewClient(opts.ToClientConfig())
if err != nil {
return fmt.Errorf("unable to create distribution client: %w", err)
}
c, err := installation.NewCurator(opts.ToCuratorConfig(), client)
if err != nil {
return fmt.Errorf("unable to create curator: %w", err)
}
reader, err := c.Reader()
if err != nil {
return fmt.Errorf("unable to get providers: %w", err)
}
providerModels, err := reader.AllProviders()
if err != nil {
return fmt.Errorf("unable to get providers: %w", err)
}
sb := &strings.Builder{}
switch opts.Output {
case tableOutputFormat, textOutputFormat:
err = displayDBProvidersTable(toProviders(providerModels), sb)
if err != nil {
return err
}
case jsonOutputFormat:
err = displayDBProvidersJSON(toProviders(providerModels), sb)
if err != nil {
return err
}
default:
return fmt.Errorf("unsupported output format: %s", opts.Output)
}
bus.Report(sb.String())
return nil
}
type provider struct {
Name string `json:"name"`
Version string `json:"version"`
Processor string `json:"processor"`
DateCaptured *time.Time `json:"dateCaptured"`
InputDigest string `json:"inputDigest"`
}
func toProviders(providers []v6.Provider) []provider {
var res []provider
for _, p := range providers {
res = append(res, provider{
Name: p.ID,
Version: p.Version,
Processor: p.Processor,
DateCaptured: p.DateCaptured,
InputDigest: p.InputDigest,
})
}
return res
}
func displayDBProvidersTable(providers []provider, output io.Writer) error {
rows := [][]string{}
for _, p := range providers {
rows = append(rows, []string{p.Name, p.Version, p.Processor, p.DateCaptured.String(), p.InputDigest})
}
table := newTable(output, []string{"Name", "Version", "Processor", "Date Captured", "Input Digest"})
if err := table.Bulk(rows); err != nil {
return fmt.Errorf("failed to add table rows: %w", err)
}
return table.Render()
}
func displayDBProvidersJSON(providers []provider, output io.Writer) error {
encoder := json.NewEncoder(output)
encoder.SetEscapeHTML(false)
encoder.SetIndent("", " ")
err := encoder.Encode(providers)
if err != nil {
return fmt.Errorf("cannot display json: %w", err)
}
return nil
}
================================================
FILE: cmd/grype/cli/commands/db_providers_test.go
================================================
package commands
import (
"bytes"
"testing"
"time"
"github.com/stretchr/testify/require"
)
func TestDisplayDBProvidersTable(t *testing.T) {
providers := []provider{
{
Name: "provider1",
Version: "1.0.0",
Processor: "vunnel@3.2",
DateCaptured: timeRef(time.Date(2024, 11, 25, 14, 30, 0, 0, time.UTC)),
InputDigest: "xxh64:1234567834567",
},
{
Name: "provider2",
Version: "2.0.0",
Processor: "vunnel@3.2",
DateCaptured: timeRef(time.Date(2024, 11, 26, 10, 15, 0, 0, time.UTC)),
InputDigest: "xxh64:9876543212345",
},
}
expectedOutput := `NAME VERSION PROCESSOR DATE CAPTURED INPUT DIGEST
provider1 1.0.0 vunnel@3.2 2024-11-25 14:30:00 +0000 UTC xxh64:1234567834567
provider2 2.0.0 vunnel@3.2 2024-11-26 10:15:00 +0000 UTC xxh64:9876543212345
`
var output bytes.Buffer
require.NoError(t, displayDBProvidersTable(providers, &output))
require.Equal(t, expectedOutput, output.String())
}
func TestDisplayDBProvidersJSON(t *testing.T) {
providers := []provider{
{
Name: "provider1",
Version: "1.0.0",
Processor: "vunnel@3.2",
DateCaptured: timeRef(time.Date(2024, 11, 25, 14, 30, 0, 0, time.UTC)),
InputDigest: "xxh64:1234567834567",
},
{
Name: "provider2",
Version: "2.0.0",
Processor: "vunnel@3.2",
DateCaptured: timeRef(time.Date(2024, 11, 26, 10, 15, 0, 0, time.UTC)),
InputDigest: "xxh64:9876543212345",
},
}
expectedJSON := `[
{
"name": "provider1",
"version": "1.0.0",
"processor": "vunnel@3.2",
"dateCaptured": "2024-11-25T14:30:00Z",
"inputDigest": "xxh64:1234567834567"
},
{
"name": "provider2",
"version": "2.0.0",
"processor": "vunnel@3.2",
"dateCaptured": "2024-11-26T10:15:00Z",
"inputDigest": "xxh64:9876543212345"
}
]
`
var output bytes.Buffer
err := displayDBProvidersJSON(providers, &output)
require.NoError(t, err)
require.JSONEq(t, expectedJSON, output.String())
}
func timeRef(t time.Time) *time.Time {
return &t
}
================================================
FILE: cmd/grype/cli/commands/db_search.go
================================================
package commands
import (
"encoding/json"
"errors"
"fmt"
"io"
"regexp"
"sort"
"strings"
"github.com/spf13/cobra"
"github.com/anchore/clio"
"github.com/anchore/grype/cmd/grype/cli/commands/internal/dbsearch"
"github.com/anchore/grype/cmd/grype/cli/options"
v6 "github.com/anchore/grype/grype/db/v6"
"github.com/anchore/grype/grype/db/v6/distribution"
"github.com/anchore/grype/grype/db/v6/installation"
"github.com/anchore/grype/internal/bus"
"github.com/anchore/grype/internal/log"
)
type dbSearchMatchOptions struct {
Format options.DBSearchFormat `yaml:",inline" mapstructure:",squash"`
Vulnerability options.DBSearchVulnerabilities `yaml:",inline" mapstructure:",squash"`
Package options.DBSearchPackages `yaml:",inline" mapstructure:",squash"`
OS options.DBSearchOSs `yaml:",inline" mapstructure:",squash"`
Bounds options.DBSearchBounds `yaml:",inline" mapstructure:",squash"`
options.DatabaseCommand `yaml:",inline" mapstructure:",squash"`
}
var alasPattern = regexp.MustCompile(`^alas[\w]*-\d+-\d+$`)
func (o *dbSearchMatchOptions) applyArgs(args []string) error {
for _, arg := range args {
lowerArg := strings.ToLower(arg)
switch {
case hasAnyPrefix(lowerArg, "cpe:", "purl:"):
// this is explicitly a package...
log.WithFields("value", arg).Trace("assuming arg is a package specifier")
o.Package.Packages = append(o.Package.Packages, arg)
case hasAnyPrefix(lowerArg, "cve-", "ghsa-", "elsa-", "rhsa-") || alasPattern.MatchString(lowerArg):
// this is a vulnerability...
log.WithFields("value", arg).Trace("assuming arg is a vulnerability ID")
o.Vulnerability.VulnerabilityIDs = append(o.Vulnerability.VulnerabilityIDs, arg)
default:
// assume this is a package name
log.WithFields("value", arg).Trace("assuming arg is a package name")
o.Package.Packages = append(o.Package.Packages, arg)
}
}
if err := o.Vulnerability.PostLoad(); err != nil {
return err
}
if err := o.Package.PostLoad(); err != nil {
return err
}
return nil
}
func hasAnyPrefix(s string, prefixes ...string) bool {
for _, prefix := range prefixes {
if strings.HasPrefix(s, prefix) {
return true
}
}
return false
}
func DBSearch(app clio.Application) *cobra.Command {
opts := &dbSearchMatchOptions{
Format: options.DefaultDBSearchFormat(),
Vulnerability: options.DBSearchVulnerabilities{
UseVulnIDFlag: true,
},
Bounds: options.DefaultDBSearchBounds(),
DatabaseCommand: *options.DefaultDatabaseCommand(app.ID()),
}
cmd := &cobra.Command{
Use: "search",
Short: "Search the DB for vulnerabilities or affected packages",
Example: `
Search for affected packages by vulnerability ID:
$ grype db search --vuln ELSA-2023-12205
Search for affected packages by package name:
$ grype db search --pkg log4j
Search for affected packages by package name, filtering down to a specific vulnerability:
$ grype db search --pkg log4j --vuln CVE-2021-44228
Search for affected packages by PURL (note: version is not considered):
$ grype db search --pkg 'pkg:rpm/redhat/openssl' # or: '--ecosystem rpm --pkg openssl
Search for affected packages by CPE (note: version/update is not considered):
$ grype db search --pkg 'cpe:2.3:a:jetty:jetty_http_server:*:*:*:*:*:*:*:*'
$ grype db search --pkg 'cpe:/a:jetty:jetty_http_server'`,
PreRunE: disableUI(app),
RunE: func(cmd *cobra.Command, args []string) (err error) {
if len(args) > 0 {
// try to stay backwards compatible with v5 search command (which takes args)
if err := opts.applyArgs(args); err != nil {
return err
}
}
err = runDBSearchMatches(*opts)
if err != nil {
if errors.Is(err, dbsearch.ErrNoSearchCriteria) {
_ = cmd.Usage()
}
return err
}
return nil
},
}
cmd.AddCommand(
DBSearchVulnerabilities(app),
)
// prevent from being shown in the grype config
type configWrapper struct {
Hidden *dbSearchMatchOptions `json:"-" yaml:"-" mapstructure:"-"`
*options.DatabaseCommand `yaml:",inline" mapstructure:",squash"`
}
return app.SetupCommand(cmd, &configWrapper{Hidden: opts, DatabaseCommand: &opts.DatabaseCommand})
}
func runDBSearchMatches(opts dbSearchMatchOptions) error {
client, err := distribution.NewClient(opts.ToClientConfig())
if err != nil {
return fmt.Errorf("unable to create distribution client: %w", err)
}
curator, err := installation.NewCurator(opts.ToCuratorConfig(), client)
if err != nil {
return fmt.Errorf("unable to create curator: %w", err)
}
reader, err := curator.Reader()
if err != nil {
return fmt.Errorf("unable to get providers: %w", err)
}
if err := validateProvidersFilter(reader, opts.Vulnerability.Providers); err != nil {
return err
}
rows, queryErr := dbsearch.FindMatches(reader, dbsearch.AffectedPackagesOptions{
Vulnerability: opts.Vulnerability.Specs,
Package: opts.Package.PkgSpecs,
CPE: opts.Package.CPESpecs,
OS: opts.OS.Specs,
AllowBroadCPEMatching: opts.Package.AllowBroadCPEMatching,
RecordLimit: opts.Bounds.RecordLimit,
FixedStates: opts.Vulnerability.FixedState,
})
if queryErr != nil {
if !errors.Is(queryErr, v6.ErrLimitReached) {
return queryErr
}
}
sb := &strings.Builder{}
err = presentDBSearchMatches(opts.Format.Output, rows, sb)
rep := sb.String()
if rep != "" {
bus.Report(rep)
}
if err != nil {
return fmt.Errorf("unable to present search results: %w", err)
}
return queryErr
}
func presentDBSearchMatches(outputFormat string, structuredRows dbsearch.Matches, output io.Writer) error {
switch outputFormat {
case tableOutputFormat:
if len(structuredRows) == 0 {
bus.Notify("No results found")
return nil
}
rows := renderDBSearchPackagesTableRows(structuredRows.Flatten())
table := newTable(output, []string{"Vulnerability", "Package", "Ecosystem", "Namespace", "Version Constraint"})
if err := table.Bulk(rows); err != nil {
return fmt.Errorf("failed to add table rows: %+v", err)
}
return table.Render()
case jsonOutputFormat:
if structuredRows == nil {
// always allocate the top level collection
structuredRows = dbsearch.Matches{}
}
enc := json.NewEncoder(output)
enc.SetEscapeHTML(false)
enc.SetIndent("", " ")
if err := enc.Encode(structuredRows); err != nil {
return fmt.Errorf("failed to encode diff information: %+v", err)
}
default:
return fmt.Errorf("unsupported output format: %s", outputFormat)
}
return nil
}
func renderDBSearchPackagesTableRows(structuredRows []dbsearch.AffectedPackage) [][]string {
var rows [][]string
for _, rr := range structuredRows {
var pkgOrCPE, ecosystem string
if rr.Package != nil {
pkgOrCPE = rr.Package.Name
ecosystem = rr.Package.Ecosystem
} else if rr.CPE != nil {
pkgOrCPE = rr.CPE.String()
ecosystem = rr.CPE.TargetSoftware
}
var ranges []string
for _, ra := range rr.Detail.Ranges {
ranges = append(ranges, ra.Version.Constraint)
}
rangeStr := strings.Join(ranges, " || ")
rows = append(rows, []string{rr.Vulnerability.ID, pkgOrCPE, ecosystem, mimicV5Namespace(rr), rangeStr})
}
// sort rows by each column
sort.Slice(rows, func(i, j int) bool {
for k := range rows[i] {
if rows[i][k] != rows[j][k] {
return rows[i][k] < rows[j][k]
}
}
return false
})
return rows
}
func mimicV5Namespace(row dbsearch.AffectedPackage) string {
namespace := v6.MimicV5Namespace(&row.Vulnerability.Model, row.Model)
if row.Model != nil && row.Model.OperatingSystem != nil && row.Model.OperatingSystem.Channel != "" {
return namespace + ":" + row.Model.OperatingSystem.Channel
}
return namespace
}
================================================
FILE: cmd/grype/cli/commands/db_search_test.go
================================================
package commands
import (
"testing"
"github.com/google/go-cmp/cmp"
"github.com/google/go-cmp/cmp/cmpopts"
"github.com/stretchr/testify/require"
"github.com/anchore/grype/cmd/grype/cli/commands/internal/dbsearch"
"github.com/anchore/grype/cmd/grype/cli/options"
v6 "github.com/anchore/grype/grype/db/v6"
)
func TestDBSearchMatchOptionsApplyArgs(t *testing.T) {
testCases := []struct {
name string
args []string
expectedPackages []string
expectedVulnIDs []string
expectedErrMessage string
}{
{
name: "empty arguments",
args: []string{},
expectedPackages: []string{},
expectedVulnIDs: []string{},
},
{
name: "valid cpe",
args: []string{"cpe:2.3:a:vendor:product:1.0:*:*:*:*:*:*:*"},
expectedPackages: []string{
"cpe:2.3:a:vendor:product:1.0:*:*:*:*:*:*:*",
},
expectedVulnIDs: []string{},
},
{
name: "valid purl",
args: []string{"pkg:npm/package-name@1.0.0"},
expectedPackages: []string{
"pkg:npm/package-name@1.0.0",
},
expectedVulnIDs: []string{},
},
{
name: "valid vulnerability IDs",
args: []string{"CVE-2023-0001", "GHSA-1234", "ALAS-2023-1234"},
expectedPackages: []string{},
expectedVulnIDs: []string{
"CVE-2023-0001",
"GHSA-1234",
"ALAS-2023-1234",
},
},
{
name: "mixed package and vulns",
args: []string{"cpe:2.3:a:vendor:product:1.0:*:*:*:*:*:*:*", "CVE-2023-0001"},
expectedPackages: []string{
"cpe:2.3:a:vendor:product:1.0:*:*:*:*:*:*:*",
},
expectedVulnIDs: []string{
"CVE-2023-0001",
},
},
{
name: "plain package name",
args: []string{"package-name"},
expectedPackages: []string{
"package-name",
},
expectedVulnIDs: []string{},
},
{
name: "invalid PostLoad error for Package",
args: []string{"pkg:npm/package-name@1.0.0", "cpe:invalid"},
expectedPackages: []string{
"pkg:npm/package-name@1.0.0",
},
expectedErrMessage: "invalid CPE",
},
}
for _, tc := range testCases {
t.Run(tc.name, func(t *testing.T) {
opts := &dbSearchMatchOptions{
Vulnerability: options.DBSearchVulnerabilities{},
Package: options.DBSearchPackages{},
}
err := opts.applyArgs(tc.args)
if tc.expectedErrMessage != "" {
require.Error(t, err)
require.Contains(t, err.Error(), tc.expectedErrMessage)
return
}
require.NoError(t, err)
if d := cmp.Diff(tc.expectedPackages, opts.Package.Packages, cmpopts.EquateEmpty()); d != "" {
t.Errorf("unexpected package specifiers: %s", d)
}
if d := cmp.Diff(tc.expectedVulnIDs, opts.Vulnerability.VulnerabilityIDs, cmpopts.EquateEmpty()); d != "" {
t.Errorf("unexpected vulnerability specifiers: %s", d)
}
})
}
}
func TestMimicV5Namespace(t *testing.T) {
tests := []struct {
name string
osName string
osChannel string
expected string
}{
{
name: "distro namespace without channel",
osName: "redhat",
osChannel: "",
expected: "redhat:distro:redhat:8",
},
{
name: "distro namespace with channel",
osName: "redhat",
osChannel: "eus",
expected: "redhat:distro:redhat:8:eus",
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
row := dbsearch.AffectedPackage{
Vulnerability: dbsearch.VulnerabilityInfo{
Model: v6.VulnerabilityHandle{
Provider: &v6.Provider{ID: "rhel"},
},
},
AffectedPackageInfo: dbsearch.AffectedPackageInfo{
Model: &v6.AffectedPackageHandle{
OperatingSystem: &v6.OperatingSystem{
Name: tt.osName,
MajorVersion: "8",
MinorVersion: "6",
Channel: tt.osChannel,
},
Package: &v6.Package{
Name: "test-package",
Ecosystem: "rpm",
},
},
},
}
result := mimicV5Namespace(row)
require.Equal(t, tt.expected, result)
})
}
}
================================================
FILE: cmd/grype/cli/commands/db_search_vuln.go
================================================
package commands
import (
"encoding/json"
"fmt"
"io"
"sort"
"strings"
"time"
"github.com/hashicorp/go-multierror"
"github.com/scylladb/go-set/strset"
"github.com/spf13/cobra"
"github.com/anchore/clio"
"github.com/anchore/grype/cmd/grype/cli/commands/internal/dbsearch"
"github.com/anchore/grype/cmd/grype/cli/options"
v6 "github.com/anchore/grype/grype/db/v6"
"github.com/anchore/grype/grype/db/v6/distribution"
"github.com/anchore/grype/grype/db/v6/installation"
"github.com/anchore/grype/internal/bus"
)
type dbSearchVulnerabilityOptions struct {
Format options.DBSearchFormat `yaml:",inline" mapstructure:",squash"`
Vulnerability options.DBSearchVulnerabilities `yaml:",inline" mapstructure:",squash"`
Bounds options.DBSearchBounds `yaml:",inline" mapstructure:",squash"`
options.DatabaseCommand `yaml:",inline" mapstructure:",squash"`
}
func DBSearchVulnerabilities(app clio.Application) *cobra.Command {
opts := &dbSearchVulnerabilityOptions{
Format: options.DefaultDBSearchFormat(),
Vulnerability: options.DBSearchVulnerabilities{
UseVulnIDFlag: false, // we input this through the args
},
Bounds: options.DefaultDBSearchBounds(),
DatabaseCommand: *options.DefaultDatabaseCommand(app.ID()),
}
cmd := &cobra.Command{
Use: "vuln ID...",
Aliases: []string{"vulnerability", "vulnerabilities", "vulns"},
Short: "Search for vulnerabilities within the DB (supports DB schema v6+ only)",
Args: func(_ *cobra.Command, args []string) error {
if len(args) == 0 {
return fmt.Errorf("must specify at least one vulnerability ID")
}
opts.Vulnerability.VulnerabilityIDs = args
return nil
},
RunE: func(_ *cobra.Command, _ []string) (err error) {
return runDBSearchVulnerabilities(*opts)
},
}
// prevent from being shown in the grype config
type configWrapper struct {
Hidden *dbSearchVulnerabilityOptions `json:"-" yaml:"-" mapstructure:"-"`
*options.DatabaseCommand `yaml:",inline" mapstructure:",squash"`
}
return app.SetupCommand(cmd, &configWrapper{Hidden: opts, DatabaseCommand: &opts.DatabaseCommand})
}
func runDBSearchVulnerabilities(opts dbSearchVulnerabilityOptions) error {
client, err := distribution.NewClient(opts.ToClientConfig())
if err != nil {
return fmt.Errorf("unable to create distribution client: %w", err)
}
c, err := installation.NewCurator(opts.ToCuratorConfig(), client)
if err != nil {
return fmt.Errorf("unable to create curator: %w", err)
}
reader, err := c.Reader()
if err != nil {
return fmt.Errorf("unable to get providers: %w", err)
}
if err := validateProvidersFilter(reader, opts.Vulnerability.Providers); err != nil {
return err
}
rows, err := dbsearch.FindVulnerabilities(reader, dbsearch.VulnerabilitiesOptions{
Vulnerability: opts.Vulnerability.Specs,
RecordLimit: opts.Bounds.RecordLimit,
})
if err != nil {
return err
}
sb := &strings.Builder{}
err = presentDBSearchVulnerabilities(opts.Format.Output, rows, sb)
rep := sb.String()
if rep != "" {
bus.Report(rep)
}
return err
}
func validateProvidersFilter(reader v6.Reader, providers []string) error {
if len(providers) == 0 {
return nil
}
availableProviders, err := reader.AllProviders()
if err != nil {
return fmt.Errorf("unable to get providers: %w", err)
}
activeProviders := strset.New()
for _, p := range availableProviders {
activeProviders.Add(p.ID)
}
provSet := strset.New(providers...)
diff := strset.Difference(provSet, activeProviders)
diffList := diff.List()
sort.Strings(diffList)
var errs error
for _, p := range diffList {
errs = multierror.Append(errs, fmt.Errorf("provider not found: %q", p))
}
return errs
}
func presentDBSearchVulnerabilities(outputFormat string, structuredRows []dbsearch.Vulnerability, output io.Writer) error {
switch outputFormat {
case tableOutputFormat:
if len(structuredRows) == 0 {
bus.Notify("No results found")
return nil
}
rows := renderDBSearchVulnerabilitiesTableRows(structuredRows)
table := newTable(output, []string{"ID", "Provider", "Published", "Severity", "Reference"})
if err := table.Bulk(rows); err != nil {
return fmt.Errorf("failed to add table rows: %+v", err)
}
return table.Render()
case jsonOutputFormat:
if structuredRows == nil {
// always allocate the top level collection
structuredRows = []dbsearch.Vulnerability{}
}
enc := json.NewEncoder(output)
enc.SetEscapeHTML(false)
enc.SetIndent("", " ")
if err := enc.Encode(structuredRows); err != nil {
return fmt.Errorf("failed to encode diff information: %+v", err)
}
default:
return fmt.Errorf("unsupported output format: %s", outputFormat)
}
return nil
}
func renderDBSearchVulnerabilitiesTableRows(structuredRows []dbsearch.Vulnerability) [][]string {
type row struct {
Vuln string
ProviderWithoutVersions string
PublishedDate string
Severity string
Reference string
}
versionsByRow := make(map[row][]string)
for _, rr := range structuredRows {
r := row{
Vuln: rr.ID,
ProviderWithoutVersions: rr.Provider,
PublishedDate: getDate(rr.PublishedDate),
Severity: rr.Severity,
Reference: getPrimaryReference(rr.References),
}
versionsByRow[r] = append(versionsByRow[r], getOSVersions(rr.OperatingSystems)...)
}
var rows [][]string
for r, versions := range versionsByRow {
prov := r.ProviderWithoutVersions
if len(versions) > 0 {
sort.Strings(versions)
prov = fmt.Sprintf("%s (%s)", r.ProviderWithoutVersions, strings.Join(versions, ", "))
}
rows = append(rows, []string{r.Vuln, prov, r.PublishedDate, r.Severity, r.Reference})
}
// sort rows by each column
sort.Slice(rows, func(i, j int) bool {
for k := range rows[i] {
if rows[i][k] != rows[j][k] {
return rows[i][k] < rows[j][k]
}
}
return false
})
return rows
}
func getOSVersions(oss []dbsearch.OperatingSystem) []string {
var versions []string
for _, os := range oss {
versions = append(versions, os.Version)
}
return versions
}
func getPrimaryReference(refs []v6.Reference) string {
if len(refs) > 0 {
return refs[0].URL
}
return ""
}
func getDate(t *time.Time) string {
if t != nil && !t.IsZero() {
return t.Format("2006-01-02")
}
return ""
}
================================================
FILE: cmd/grype/cli/commands/db_search_vuln_test.go
================================================
package commands
import (
"testing"
"time"
"github.com/stretchr/testify/require"
"github.com/anchore/grype/cmd/grype/cli/commands/internal/dbsearch"
v6 "github.com/anchore/grype/grype/db/v6"
)
func TestGetOSVersions(t *testing.T) {
tests := []struct {
name string
input []dbsearch.OperatingSystem
expected []string
}{
{
name: "empty list",
input: []dbsearch.OperatingSystem{},
expected: nil,
},
{
name: "single os",
input: []dbsearch.OperatingSystem{
{
Name: "debian",
Version: "11",
},
},
expected: []string{"11"},
},
{
name: "multiple os",
input: []dbsearch.OperatingSystem{
{
Name: "ubuntu",
Version: "16.04",
},
{
Name: "ubuntu",
Version: "22.04",
},
{
Name: "ubuntu",
Version: "24.04",
},
},
expected: []string{"16.04", "22.04", "24.04"},
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
actual := getOSVersions(tt.input)
require.Equal(t, tt.expected, actual)
})
}
}
func TestGetPrimaryReference(t *testing.T) {
tests := []struct {
name string
input []v6.Reference
expected string
}{
{
name: "empty list",
input: []v6.Reference{},
expected: "",
},
{
name: "single reference",
input: []v6.Reference{
{
URL: "https://example.com/vuln/123",
Tags: []string{"primary"},
},
},
expected: "https://example.com/vuln/123",
},
{
name: "multiple references",
input: []v6.Reference{
{
URL: "https://example.com/vuln/123",
Tags: []string{"primary"},
},
{
URL: "https://example.com/advisory/123",
Tags: []string{"secondary"},
},
},
expected: "https://example.com/vuln/123",
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
actual := getPrimaryReference(tt.input)
require.Equal(t, tt.expected, actual)
})
}
}
func TestGetDate(t *testing.T) {
tests := []struct {
name string
input *time.Time
expected string
}{
{
name: "nil time",
input: nil,
expected: "",
},
{
name: "zero time",
input: &time.Time{},
expected: "",
},
{
name: "valid time",
input: timePtr(time.Date(2023, 5, 15, 0, 0, 0, 0, time.UTC)),
expected: "2023-05-15",
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
actual := getDate(tt.input)
require.Equal(t, tt.expected, actual)
})
}
}
func timePtr(t time.Time) *time.Time {
return &t
}
================================================
FILE: cmd/grype/cli/commands/db_status.go
================================================
package commands
import (
"encoding/json"
"fmt"
"io"
"os"
"time"
"github.com/spf13/cobra"
"github.com/anchore/clio"
"github.com/anchore/grype/cmd/grype/cli/options"
"github.com/anchore/grype/grype/db/v6/distribution"
"github.com/anchore/grype/grype/db/v6/installation"
"github.com/anchore/grype/grype/vulnerability"
)
type dbStatusOptions struct {
Output string `yaml:"output" json:"output" mapstructure:"output"`
options.DatabaseCommand `yaml:",inline" mapstructure:",squash"`
}
var _ clio.FlagAdder = (*dbStatusOptions)(nil)
func (d *dbStatusOptions) AddFlags(flags clio.FlagSet) {
flags.StringVarP(&d.Output, "output", "o", "format to display results (available=[text, json])")
}
func DBStatus(app clio.Application) *cobra.Command {
opts := &dbStatusOptions{
Output: textOutputFormat,
DatabaseCommand: *options.DefaultDatabaseCommand(app.ID()),
}
cmd := &cobra.Command{
Use: "status",
Short: "Display database status and metadata",
Args: cobra.ExactArgs(0),
PreRunE: disableUI(app),
RunE: func(_ *cobra.Command, _ []string) error {
return runDBStatus(*opts)
},
}
// prevent from being shown in the grype config
type configWrapper struct {
Hidden *dbStatusOptions `json:"-" yaml:"-" mapstructure:"-"`
*options.DatabaseCommand `yaml:",inline" mapstructure:",squash"`
}
return app.SetupCommand(cmd, &configWrapper{Hidden: opts, DatabaseCommand: &opts.DatabaseCommand})
}
func runDBStatus(opts dbStatusOptions) error {
client, err := distribution.NewClient(opts.ToClientConfig())
if err != nil {
return fmt.Errorf("unable to create distribution client: %w", err)
}
c, err := installation.NewCurator(opts.ToCuratorConfig(), client)
if err != nil {
return fmt.Errorf("unable to create distribution client: %w", err)
}
status := c.Status()
if err := presentDBStatus(opts.Output, os.Stdout, status); err != nil {
return fmt.Errorf("failed to present db status information: %+v", err)
}
return status.Error
}
func presentDBStatus(format string, writer io.Writer, status vulnerability.ProviderStatus) error {
switch format {
case textOutputFormat:
fmt.Fprintln(writer, "Path: ", status.Path)
fmt.Fprintln(writer, "Schema: ", status.SchemaVersion)
fmt.Fprintln(writer, "Built: ", status.Built.Format(time.RFC3339))
if status.From != "" {
fmt.Fprintln(writer, "From: ", status.From)
}
fmt.Fprintln(writer, "Status: ", renderStoreValidation(status))
case jsonOutputFormat:
enc := json.NewEncoder(writer)
enc.SetEscapeHTML(false)
enc.SetIndent("", " ")
if err := enc.Encode(&status); err != nil {
return fmt.Errorf("failed to db status information: %+v", err)
}
default:
return fmt.Errorf("unsupported output format: %s", format)
}
return nil
}
func renderStoreValidation(status vulnerability.ProviderStatus) string {
if status.Error != nil {
return "invalid"
}
return "valid"
}
================================================
FILE: cmd/grype/cli/commands/db_status_test.go
================================================
package commands
import (
"bytes"
"errors"
"strings"
"testing"
"time"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
"github.com/anchore/grype/grype/vulnerability"
)
func TestPresentDBStatus(t *testing.T) {
validStatus := vulnerability.ProviderStatus{
Path: "/Users/test/Library/Caches/grype/db/6/vulnerability.db",
From: "https://grype.anchore.io/databases/v6/vulnerability-db_v6.0.2_2025-03-14T01:31:06Z_1741925227.tar.zst?checksum=sha256%3Ad4654e3b212f1d8a1aaab979599691099af541568d687c4a7c4e7c1da079b9b8",
SchemaVersion: "6.0.0",
Built: time.Date(2024, 11, 27, 14, 43, 17, 0, time.UTC),
Error: nil,
}
invalidStatus := vulnerability.ProviderStatus{
Path: "/Users/test/Library/Caches/grype/db/6/vulnerability.db",
From: "https://grype.anchore.io/databases/v6/vulnerability-db_v6.0.2_2025-03-14T01:31:06Z_1741925227.tar.zst?checksum=sha256%3Ad4654e3b212f1d8a1aaab979599691099af541568d687c4a7c4e7c1da079b9b8",
SchemaVersion: "6.0.0",
Built: time.Date(2024, 11, 27, 14, 43, 17, 0, time.UTC),
Error: errors.New("checksum mismatch"),
}
tests := []struct {
name string
format string
status vulnerability.ProviderStatus
expectedText string
expectedErr require.ErrorAssertionFunc
}{
{
name: "valid status, text format",
format: textOutputFormat,
status: validStatus,
expectedText: `Path: /Users/test/Library/Caches/grype/db/6/vulnerability.db
Schema: 6.0.0
Built: 2024-11-27T14:43:17Z
From: https://grype.anchore.io/databases/v6/vulnerability-db_v6.0.2_2025-03-14T01:31:06Z_1741925227.tar.zst?checksum=sha256%3Ad4654e3b212f1d8a1aaab979599691099af541568d687c4a7c4e7c1da079b9b8
Status: valid
`,
expectedErr: require.NoError,
},
{
name: "invalid status, text format",
format: textOutputFormat,
status: invalidStatus,
expectedText: `Path: /Users/test/Library/Caches/grype/db/6/vulnerability.db
Schema: 6.0.0
Built: 2024-11-27T14:43:17Z
From: https://grype.anchore.io/databases/v6/vulnerability-db_v6.0.2_2025-03-14T01:31:06Z_1741925227.tar.zst?checksum=sha256%3Ad4654e3b212f1d8a1aaab979599691099af541568d687c4a7c4e7c1da079b9b8
Status: invalid
`,
expectedErr: require.NoError,
},
{
name: "valid status, JSON format",
format: jsonOutputFormat,
status: validStatus,
expectedText: `{
"schemaVersion": "6.0.0",
"from": "https://grype.anchore.io/databases/v6/vulnerability-db_v6.0.2_2025-03-14T01:31:06Z_1741925227.tar.zst?checksum=sha256%3Ad4654e3b212f1d8a1aaab979599691099af541568d687c4a7c4e7c1da079b9b8",
"built": "2024-11-27T14:43:17Z",
"path": "/Users/test/Library/Caches/grype/db/6/vulnerability.db",
"valid": true
}
`,
expectedErr: require.NoError,
},
{
name: "invalid status, JSON format",
format: jsonOutputFormat,
status: invalidStatus,
expectedText: `{
"schemaVersion": "6.0.0",
"from": "https://grype.anchore.io/databases/v6/vulnerability-db_v6.0.2_2025-03-14T01:31:06Z_1741925227.tar.zst?checksum=sha256%3Ad4654e3b212f1d8a1aaab979599691099af541568d687c4a7c4e7c1da079b9b8",
"built": "2024-11-27T14:43:17Z",
"path": "/Users/test/Library/Caches/grype/db/6/vulnerability.db",
"valid": false,
"error": "checksum mismatch"
}
`,
expectedErr: require.NoError,
},
{
name: "unsupported format",
format: "unsupported",
status: validStatus,
expectedErr: requireErrorContains("unsupported output format"),
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
if tt.expectedErr == nil {
tt.expectedErr = require.NoError
}
writer := &bytes.Buffer{}
err := presentDBStatus(tt.format, writer, tt.status)
tt.expectedErr(t, err)
if err != nil {
return
}
assert.Equal(t, strings.TrimSpace(tt.expectedText), strings.TrimSpace(writer.String()))
})
}
}
================================================
FILE: cmd/grype/cli/commands/db_update.go
================================================
package commands
import (
"fmt"
"github.com/spf13/cobra"
"github.com/anchore/clio"
"github.com/anchore/grype/cmd/grype/cli/options"
"github.com/anchore/grype/grype/db/v6/distribution"
"github.com/anchore/grype/grype/db/v6/installation"
"github.com/anchore/grype/internal/bus"
"github.com/anchore/grype/internal/log"
)
func DBUpdate(app clio.Application) *cobra.Command {
opts := options.DefaultDatabaseCommand(app.ID())
cmd := &cobra.Command{
Use: "update",
Short: "Download and install the latest vulnerability database",
Args: cobra.ExactArgs(0),
PreRunE: func(_ *cobra.Command, _ []string) error {
// DB commands should not opt into the low-pass check filter
opts.DB.MaxUpdateCheckFrequency = 0
return nil
},
RunE: func(_ *cobra.Command, _ []string) error {
return runDBUpdate(*opts)
},
}
// prevent from being shown in the grype config
type configWrapper struct {
*options.DatabaseCommand `yaml:",inline" mapstructure:",squash"`
}
return app.SetupCommand(cmd, &configWrapper{opts})
}
func runDBUpdate(opts options.DatabaseCommand) error {
cfg := opts.ToClientConfig()
// we need to have this set to true to force the update call to try to update
// regardless of what the user provided in order for update checks to fail
if !cfg.RequireUpdateCheck {
log.Warn("overriding db update check")
cfg.RequireUpdateCheck = true
}
client, err := distribution.NewClient(cfg)
if err != nil {
return fmt.Errorf("unable to create distribution client: %w", err)
}
c, err := installation.NewCurator(opts.ToCuratorConfig(), client)
if err != nil {
return fmt.Errorf("unable to create curator: %w", err)
}
updated, err := c.Update()
if err != nil {
return fmt.Errorf("unable to update vulnerability database: %w", err)
}
result := "No vulnerability database update available\n"
if updated {
result = "Vulnerability database updated to latest version!\n"
}
log.Debugf("completed db update check with result: %s", result)
bus.Report(result)
return nil
}
================================================
FILE: cmd/grype/cli/commands/explain.go
================================================
package commands
import (
"encoding/json"
"fmt"
"os"
"github.com/spf13/cobra"
"github.com/anchore/clio"
"github.com/anchore/grype/grype/presenter/explain"
"github.com/anchore/grype/grype/presenter/models"
"github.com/anchore/grype/internal"
"github.com/anchore/grype/internal/log"
)
type explainOptions struct {
CVEIDs []string `yaml:"cve-ids" json:"cve-ids" mapstructure:"cve-ids"`
}
var _ clio.FlagAdder = (*explainOptions)(nil)
func (d *explainOptions) AddFlags(flags clio.FlagSet) {
flags.StringArrayVarP(&d.CVEIDs, "id", "", "CVE IDs to explain")
}
func Explain(app clio.Application) *cobra.Command {
opts := &explainOptions{}
cmd := &cobra.Command{
Use: "explain --id [VULNERABILITY ID]",
Short: "Ask grype to explain a set of findings",
PreRunE: disableUI(app),
RunE: func(_ *cobra.Command, _ []string) error {
log.Warn("grype explain is a prototype feature and is subject to change")
isStdinPipeOrRedirect, err := internal.IsStdinPipeOrRedirect()
if err != nil {
log.Warnf("unable to determine if there is piped input: %+v", err)
isStdinPipeOrRedirect = false
}
if isStdinPipeOrRedirect {
// TODO: eventually detect different types of input; for now assume grype json
var parseResult models.Document
decoder := json.NewDecoder(os.Stdin)
err := decoder.Decode(&parseResult)
if err != nil {
return fmt.Errorf("unable to parse piped input: %+v", err)
}
explainer := explain.NewVulnerabilityExplainer(os.Stdout, &parseResult)
return explainer.ExplainByID(opts.CVEIDs)
}
// perform a scan, then explain requested CVEs
// TODO: implement
return fmt.Errorf("requires grype json on stdin, please run 'grype -o json ... | grype explain ...'")
},
}
// prevent from being shown in the grype config
type configWrapper struct {
Opts *explainOptions `json:"-" yaml:"-" mapstructure:"-"`
}
return app.SetupCommand(cmd, &configWrapper{opts})
}
================================================
FILE: cmd/grype/cli/commands/internal/dbsearch/affected_packages.go
================================================
package dbsearch
import (
"errors"
"fmt"
v6 "github.com/anchore/grype/grype/db/v6"
"github.com/anchore/grype/internal/log"
"github.com/anchore/syft/syft/cpe"
)
var ErrNoSearchCriteria = errors.New("must provide at least one of vulnerability or package to search for")
// AffectedPackage represents a package affected by a vulnerability
type AffectedPackage struct {
// Vulnerability is the core advisory record for a single known vulnerability from a specific provider.
Vulnerability VulnerabilityInfo `json:"vulnerability"`
// AffectedPackageInfo is the detailed information about the affected package
AffectedPackageInfo `json:",inline"`
}
type AffectedPackageInfo struct {
// TODO: remove this when namespace is no longer used
Model *v6.AffectedPackageHandle `json:"-"` // tracking package handle info is necessary for namespace lookup (note CPE handles are not tracked)
// OS identifies the operating system release that the affected package is released for
OS *OperatingSystem `json:"os,omitempty"`
// Package identifies the name of the package in a specific ecosystem affected by the vulnerability
Package *Package `json:"package,omitempty"`
// CPE is a Common Platform Enumeration that is affected by the vulnerability
CPE *CPE `json:"cpe,omitempty"`
// Namespace is a holdover value from the v5 DB schema that combines provider and search methods into a single value
//
// Deprecated: this field will be removed in a later version of the search schema
Namespace string `json:"namespace"`
// Detail is the detailed information about the affected package
Detail v6.PackageBlob `json:"detail"`
}
// Package represents a package name within a known ecosystem, such as "python" or "golang".
type Package struct {
// Name is the name of the package within the ecosystem
Name string `json:"name"`
// Ecosystem is the tooling and language ecosystem that the package is released within
Ecosystem string `json:"ecosystem"`
}
// CPE is a Common Platform Enumeration that identifies a package
type CPE v6.Cpe
func (c *CPE) MarshalJSON() ([]byte, error) {
return []byte(fmt.Sprintf("%q", c.String())), nil
}
func (c *CPE) String() string {
if c == nil {
return ""
}
return v6.Cpe(*c).String()
}
type AffectedPackagesOptions struct {
Vulnerability v6.VulnerabilitySpecifiers
Package v6.PackageSpecifiers
CPE v6.PackageSpecifiers
OS v6.OSSpecifiers
AllowBroadCPEMatching bool
RecordLimit int
FixedStates []string
}
type affectedPackageWithDecorations struct {
v6.AffectedPackageHandle
vulnerabilityDecorations
}
func (a *affectedPackageWithDecorations) getCVEs() []string {
if a == nil {
return nil
}
return getCVEs(a.Vulnerability)
}
type affectedCPEWithDecorations struct {
v6.AffectedCPEHandle
vulnerabilityDecorations
}
func (a *affectedCPEWithDecorations) getCVEs() []string {
if a == nil {
return nil
}
return getCVEs(a.Vulnerability)
}
func newAffectedPackageRows(affectedPkgs []affectedPackageWithDecorations, affectedCPEs []affectedCPEWithDecorations) (rows []AffectedPackage) {
for i := range affectedPkgs {
pkg := affectedPkgs[i]
var detail v6.PackageBlob
if pkg.BlobValue != nil {
detail = *pkg.BlobValue
}
if pkg.Vulnerability == nil {
log.Errorf("affected package record missing vulnerability: %+v", pkg)
continue
}
rows = append(rows, AffectedPackage{
Vulnerability: newVulnerabilityInfo(*pkg.Vulnerability, pkg.vulnerabilityDecorations),
AffectedPackageInfo: AffectedPackageInfo{
Model: &pkg.AffectedPackageHandle,
OS: toOS(pkg.OperatingSystem),
Package: toPackage(pkg.Package),
Namespace: v6.MimicV5Namespace(pkg.Vulnerability, &pkg.AffectedPackageHandle),
Detail: detail,
},
})
}
for _, ac := range affectedCPEs {
var detail v6.PackageBlob
if ac.BlobValue != nil {
detail = *ac.BlobValue
}
if ac.Vulnerability == nil {
log.Errorf("affected CPE record missing vulnerability: %+v", ac)
continue
}
var c *CPE
if ac.CPE != nil {
cv := CPE(*ac.CPE)
c = &cv
}
rows = append(rows, AffectedPackage{
// tracking model information is not possible with CPE handles
Vulnerability: newVulnerabilityInfo(*ac.Vulnerability, ac.vulnerabilityDecorations),
AffectedPackageInfo: AffectedPackageInfo{
CPE: c,
Namespace: v6.MimicV5Namespace(ac.Vulnerability, nil), // no affected package will default to NVD
Detail: detail,
},
})
}
return rows
}
func toPackage(pkg *v6.Package) *Package {
if pkg == nil {
return nil
}
return &Package{
Name: pkg.Name,
Ecosystem: pkg.Ecosystem,
}
}
func toOS(os *v6.OperatingSystem) *OperatingSystem {
if os == nil {
return nil
}
return &OperatingSystem{
Name: os.Name,
Version: os.Version(),
}
}
func FindAffectedPackages(reader interface {
v6.AffectedPackageStoreReader
v6.AffectedCPEStoreReader
v6.VulnerabilityDecoratorStoreReader
}, criteria AffectedPackagesOptions,
) ([]AffectedPackage, error) {
allAffectedPkgs, allAffectedCPEs, err := findAffectedPackages(reader, criteria)
if err != nil {
return nil, err
}
if len(criteria.FixedStates) > 0 {
allAffectedPkgs = filterByFixedStateForPackages(allAffectedPkgs, criteria.FixedStates)
allAffectedCPEs = filterByFixedStateForCPEs(allAffectedCPEs, criteria.FixedStates)
}
return newAffectedPackageRows(allAffectedPkgs, allAffectedCPEs), nil
}
func findAffectedPackages(reader interface { //nolint:funlen,gocognit
v6.AffectedPackageStoreReader
v6.AffectedCPEStoreReader
v6.VulnerabilityDecoratorStoreReader
}, config AffectedPackagesOptions,
) ([]affectedPackageWithDecorations, []affectedCPEWithDecorations, error) {
var allAffectedPkgs []affectedPackageWithDecorations
var allAffectedCPEs []affectedCPEWithDecorations
pkgSpecs := config.Package
cpeSpecs := config.CPE
osSpecs := config.OS
vulnSpecs := config.Vulnerability
if config.RecordLimit == 0 {
log.Warn("no record limit set! For queries with large result sets this may result in performance issues")
}
if len(vulnSpecs) == 0 && len(pkgSpecs) == 0 && len(cpeSpecs) == 0 {
return nil, nil, ErrNoSearchCriteria
}
// don't allow for searching by any package AND any CPE AND any vulnerability AND any OS. Since these searches
// are oriented by primarily package, we only want to have ANY package/CPE when there is a vulnerability or OS specified.
if len(vulnSpecs) > 0 || !osSpecs.IsAny() {
if len(pkgSpecs) == 0 {
pkgSpecs = []*v6.PackageSpecifier{v6.AnyPackageSpecified}
}
if len(cpeSpecs) == 0 {
cpeSpecs = []*v6.PackageSpecifier{v6.AnyPackageSpecified}
}
}
// we have multiple return points that return actual values, using a defer to decorate any given results
// ensures that all paths are handled the same way.
defer func() {
for i := range allAffectedPkgs {
decorateVulnerabilities(reader, &allAffectedPkgs[i])
}
for i := range allAffectedCPEs {
decorateVulnerabilities(reader, &allAffectedCPEs[i])
}
}()
for i := range pkgSpecs {
pkgSpec := pkgSpecs[i]
log.WithFields("vuln", vulnSpecs, "pkg", pkgSpec, "os", osSpecs).Debug("searching for affected packages")
affectedPkgs, err := reader.GetAffectedPackages(pkgSpec, &v6.GetPackageOptions{
PreloadOS: true,
PreloadPackage: true,
PreloadPackageCPEs: false,
PreloadVulnerability: true,
PreloadBlob: true,
OSs: osSpecs,
Vulnerabilities: vulnSpecs,
AllowBroadCPEMatching: config.AllowBroadCPEMatching,
Limit: config.RecordLimit,
})
for i := range affectedPkgs {
allAffectedPkgs = append(allAffectedPkgs, affectedPackageWithDecorations{
AffectedPackageHandle: affectedPkgs[i],
})
}
if err != nil {
if errors.Is(err, v6.ErrLimitReached) {
return allAffectedPkgs, allAffectedCPEs, err
}
return nil, nil, fmt.Errorf("unable to get affected packages for %s: %w", vulnSpecs, err)
}
}
if osSpecs.IsAny() {
for i := range cpeSpecs {
cpeSpec := cpeSpecs[i]
var searchCPE *cpe.Attributes
if cpeSpec != nil {
searchCPE = cpeSpec.CPE
}
log.WithFields("vuln", vulnSpecs, "cpe", cpeSpec).Debug("searching for affected packages")
affectedCPEs, err := reader.GetAffectedCPEs(searchCPE, &v6.GetCPEOptions{
PreloadCPE: true,
PreloadVulnerability: true,
PreloadBlob: true,
Vulnerabilities: vulnSpecs,
AllowBroadCPEMatching: config.AllowBroadCPEMatching,
Limit: config.RecordLimit,
})
for i := range affectedCPEs {
allAffectedCPEs = append(allAffectedCPEs, affectedCPEWithDecorations{
AffectedCPEHandle: affectedCPEs[i],
})
}
if err != nil {
if errors.Is(err, v6.ErrLimitReached) {
return allAffectedPkgs, allAffectedCPEs, err
}
return nil, nil, fmt.Errorf("unable to get affected cpes for %s: %w", vulnSpecs, err)
}
}
}
return allAffectedPkgs, allAffectedCPEs, nil
}
================================================
FILE: cmd/grype/cli/commands/internal/dbsearch/affected_packages_test.go
================================================
package dbsearch
import (
"bytes"
"encoding/json"
"testing"
"time"
"github.com/google/go-cmp/cmp"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/mock"
"github.com/stretchr/testify/require"
v6 "github.com/anchore/grype/grype/db/v6"
"github.com/anchore/syft/syft/cpe"
)
func TestAffectedPackageTableRowMarshalJSON(t *testing.T) {
row := AffectedPackage{
Vulnerability: VulnerabilityInfo{
VulnerabilityBlob: v6.VulnerabilityBlob{
ID: "CVE-1234-5678",
Description: "Test vulnerability",
},
Provider: "provider1",
Status: "active",
PublishedDate: ptr(time.Date(2023, 1, 1, 0, 0, 0, 0, time.UTC)),
ModifiedDate: ptr(time.Date(2023, 2, 1, 0, 0, 0, 0, time.UTC)),
KnownExploited: []KnownExploited{
{
CVE: "CVE-1234-5678",
VendorProject: "LinuxFoundation",
Product: "Linux",
DateAdded: "2025-02-02",
RequiredAction: "Yes",
DueDate: "2025-02-02",
KnownRansomwareCampaignUse: "Known",
Notes: "note!",
URLs: []string{"https://example.com"},
CWEs: []string{"CWE-1234"},
},
},
EPSS: []EPSS{
{
CVE: "CVE-1234-5678",
EPSS: 0.893,
Percentile: 0.99,
Date: "2025-02-24",
},
},
},
AffectedPackageInfo: AffectedPackageInfo{
Package: &Package{Name: "pkg1", Ecosystem: "ecosystem1"},
CPE: &CPE{Part: "a", Vendor: "vendor1", Product: "product1"},
Namespace: "namespace1",
Detail: v6.PackageBlob{
CVEs: []string{"CVE-1234-5678"},
Qualifiers: &v6.PackageQualifiers{
RpmModularity: ptr("modularity"),
PlatformCPEs: []string{"platform-cpe-1"},
},
Ranges: []v6.Range{
{
Version: v6.Version{
Type: "semver",
Constraint: ">=1.0.0, <2.0.0",
},
Fix: &v6.Fix{
Version: "1.2.0",
State: "fixed",
},
},
},
},
},
}
buf := bytes.Buffer{}
enc := json.NewEncoder(&buf)
enc.SetIndent("", " ")
enc.SetEscapeHTML(false)
err := enc.Encode(row)
require.NoError(t, err)
expectedJSON := `{
"vulnerability": {
"id": "CVE-1234-5678",
"description": "Test vulnerability",
"provider": "provider1",
"status": "active",
"published_date": "2023-01-01T00:00:00Z",
"modified_date": "2023-02-01T00:00:00Z",
"known_exploited": [
{
"cve": "CVE-1234-5678",
"vendor_project": "LinuxFoundation",
"product": "Linux",
"date_added": "2025-02-02",
"required_action": "Yes",
"due_date": "2025-02-02",
"known_ransomware_campaign_use": "Known",
"notes": "note!",
"urls": [
"https://example.com"
],
"cwes": [
"CWE-1234"
]
}
],
"epss": [
{
"cve": "CVE-1234-5678",
"epss": 0.893,
"percentile": 0.99,
"date": "2025-02-24"
}
]
},
"package": {
"name": "pkg1",
"ecosystem": "ecosystem1"
},
"cpe": "cpe:2.3:a:vendor1:product1:*:*:*:*:*:*:*:*",
"namespace": "namespace1",
"detail": {
"cves": [
"CVE-1234-5678"
],
"qualifiers": {
"rpm_modularity": "modularity",
"platform_cpes": [
"platform-cpe-1"
]
},
"ranges": [
{
"version": {
"type": "semver",
"constraint": ">=1.0.0, <2.0.0"
},
"fix": {
"version": "1.2.0",
"state": "fixed"
}
}
]
}
}
`
if diff := cmp.Diff(expectedJSON, buf.String()); diff != "" {
t.Errorf("unexpected JSON (-want +got):\n%s", diff)
}
}
func TestNewAffectedPackageRows(t *testing.T) {
affectedPkgs := []affectedPackageWithDecorations{
{
AffectedPackageHandle: v6.AffectedPackageHandle{
Package: &v6.Package{Name: "pkg1", Ecosystem: "ecosystem1"},
OperatingSystem: &v6.OperatingSystem{
Name: "Linux",
MajorVersion: "5",
MinorVersion: "10",
},
Vulnerability: &v6.VulnerabilityHandle{
Name: "CVE-1234-5678",
Provider: &v6.Provider{ID: "provider1"},
Status: "active",
PublishedDate: ptr(time.Date(2023, 1, 1, 0, 0, 0, 0, time.UTC)),
ModifiedDate: ptr(time.Date(2023, 2, 1, 0, 0, 0, 0, time.UTC)),
BlobValue: &v6.VulnerabilityBlob{
Description: "Test vulnerability",
Severities: []v6.Severity{
{
Scheme: "CVSS_V3",
Value: CVSSSeverity{
Vector: "CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:H/A:H",
Version: "3.1",
Metrics: CvssMetrics{
BaseScore: 9.8,
},
},
Source: "nvd@nist.gov",
Rank: 1,
},
},
},
},
BlobValue: &v6.PackageBlob{
CVEs: []string{"CVE-1234-5678"},
Qualifiers: &v6.PackageQualifiers{
RpmModularity: ptr("modularity"),
PlatformCPEs: []string{"platform-cpe-1"},
},
Ranges: []v6.Range{
{
Version: v6.Version{
Type: "semver",
Constraint: ">=1.0.0, <2.0.0",
},
Fix: &v6.Fix{
Version: "1.2.0",
State: "fixed",
},
},
},
},
},
vulnerabilityDecorations: vulnerabilityDecorations{
KnownExploited: []KnownExploited{
{
CVE: "CVE-1234-5678",
VendorProject: "LinuxFoundation",
Product: "Linux",
DateAdded: "2025-02-02",
RequiredAction: "Yes",
DueDate: "2025-02-02",
KnownRansomwareCampaignUse: "Known",
Notes: "note!",
URLs: []string{"https://example.com"},
CWEs: []string{"CWE-1234"},
},
},
EPSS: []EPSS{
{
CVE: "CVE-1234-5678",
EPSS: 0.893,
Percentile: 0.99,
Date: "2025-02-24",
},
},
},
},
}
affectedCPEs := []affectedCPEWithDecorations{
{
AffectedCPEHandle: v6.AffectedCPEHandle{
CPE: &v6.Cpe{Part: "a", Vendor: "vendor1", Product: "product1"},
Vulnerability: &v6.VulnerabilityHandle{
Name: "CVE-9876-5432",
Provider: &v6.Provider{ID: "provider2"},
BlobValue: &v6.VulnerabilityBlob{Description: "CPE vulnerability description"},
},
BlobValue: &v6.PackageBlob{
CVEs: []string{"CVE-9876-5432"},
Ranges: []v6.Range{
{
Version: v6.Version{
Type: "rpm",
Constraint: ">=2.0.0, <3.0.0",
},
Fix: &v6.Fix{
Version: "2.5.0",
State: "fixed",
},
},
},
},
},
vulnerabilityDecorations: vulnerabilityDecorations{
KnownExploited: []KnownExploited{
{
CVE: "CVE-9876-5432",
VendorProject: "vendor1",
Product: "product1",
DateAdded: "2025-02-03",
RequiredAction: "Yes",
DueDate: "2025-02-03",
KnownRansomwareCampaignUse: "Known",
Notes: "note!",
URLs: []string{"https://example.com"},
CWEs: []string{"CWE-5678"},
},
},
EPSS: []EPSS{
{
CVE: "CVE-9876-5432",
EPSS: 0.938,
Percentile: 0.9222,
Date: "2025-02-25",
},
},
},
},
}
rows := newAffectedPackageRows(affectedPkgs, affectedCPEs)
expected := []AffectedPackage{
{
Vulnerability: VulnerabilityInfo{
VulnerabilityBlob: v6.VulnerabilityBlob{
Description: "Test vulnerability",
Severities: []v6.Severity{
{
Scheme: "CVSS_V3",
Value: CVSSSeverity{
Vector: "CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:H/A:H",
Version: "3.1",
Metrics: CvssMetrics{
BaseScore: 9.8,
},
},
Source: "nvd@nist.gov",
Rank: 1,
},
},
},
Severity: "critical",
Provider: "provider1",
Status: "active",
PublishedDate: ptr(time.Date(2023, 1, 1, 0, 0, 0, 0, time.UTC)),
ModifiedDate: ptr(time.Date(2023, 2, 1, 0, 0, 0, 0, time.UTC)),
KnownExploited: []KnownExploited{
{
CVE: "CVE-1234-5678",
VendorProject: "LinuxFoundation",
Product: "Linux",
DateAdded: "2025-02-02",
RequiredAction: "Yes",
DueDate: "2025-02-02",
KnownRansomwareCampaignUse: "Known",
Notes: "note!",
URLs: []string{"https://example.com"},
CWEs: []string{"CWE-1234"},
},
},
EPSS: []EPSS{
{
CVE: "CVE-1234-5678",
EPSS: 0.893,
Percentile: 0.99,
Date: "2025-02-24",
},
},
},
AffectedPackageInfo: AffectedPackageInfo{
OS: &OperatingSystem{Name: "Linux", Version: "5.10"},
Package: &Package{Name: "pkg1", Ecosystem: "ecosystem1"},
Namespace: "provider1:distro:Linux:5.10",
Detail: v6.PackageBlob{
CVEs: []string{"CVE-1234-5678"},
Qualifiers: &v6.PackageQualifiers{
RpmModularity: ptr("modularity"),
PlatformCPEs: []string{"platform-cpe-1"},
},
Ranges: []v6.Range{
{
Version: v6.Version{
Type: "semver",
Constraint: ">=1.0.0, <2.0.0",
},
Fix: &v6.Fix{
Version: "1.2.0",
State: "fixed",
},
},
},
},
},
},
{
Vulnerability: VulnerabilityInfo{
VulnerabilityBlob: v6.VulnerabilityBlob{Description: "CPE vulnerability description"},
Severity: "unknown",
Provider: "provider2",
KnownExploited: []KnownExploited{
{
CVE: "CVE-9876-5432",
VendorProject: "vendor1",
Product: "product1",
DateAdded: "2025-02-03",
RequiredAction: "Yes",
DueDate: "2025-02-03",
KnownRansomwareCampaignUse: "Known",
Notes: "note!",
URLs: []string{"https://example.com"},
CWEs: []string{"CWE-5678"},
},
},
EPSS: []EPSS{
{
CVE: "CVE-9876-5432",
EPSS: 0.938,
Percentile: 0.9222,
Date: "2025-02-25",
},
},
},
AffectedPackageInfo: AffectedPackageInfo{
CPE: &CPE{Part: "a", Vendor: "vendor1", Product: "product1"},
Namespace: "provider2:cpe",
Detail: v6.PackageBlob{
CVEs: []string{"CVE-9876-5432"},
Ranges: []v6.Range{
{
Version: v6.Version{
Type: "rpm",
Constraint: ">=2.0.0, <3.0.0",
},
Fix: &v6.Fix{
Version: "2.5.0",
State: "fixed",
},
},
},
},
},
},
}
if diff := cmp.Diff(expected, rows, cmpOpts()...); diff != "" {
t.Errorf("unexpected rows (-want +got):\n%s", diff)
}
}
func TestAffectedPackages(t *testing.T) {
mockReader := new(affectedMockReader)
mockReader.On("GetAffectedPackages", mock.Anything, mock.Anything).Return([]v6.AffectedPackageHandle{
{
Package: &v6.Package{Name: "pkg1", Ecosystem: "ecosystem1"},
OperatingSystem: &v6.OperatingSystem{
Name: "Linux",
MajorVersion: "5",
MinorVersion: "10",
},
Vulnerability: &v6.VulnerabilityHandle{
Name: "CVE-1234-5678",
Provider: &v6.Provider{ID: "provider1"},
Status: "active",
PublishedDate: ptr(time.Date(2023, 1, 1, 0, 0, 0, 0, time.UTC)),
ModifiedDate: ptr(time.Date(2023, 2, 1, 0, 0, 0, 0, time.UTC)),
BlobValue: &v6.VulnerabilityBlob{Description: "Test vulnerability"},
},
BlobValue: &v6.PackageBlob{
CVEs: []string{"CVE-1234-5678"},
Ranges: []v6.Range{
{
Version: v6.Version{
Type: "semver",
Constraint: ">=1.0.0, <2.0.0",
},
Fix: &v6.Fix{
Version: "1.2.0",
State: "fixed",
},
},
},
},
},
}, nil)
mockReader.On("GetAffectedCPEs", mock.Anything, mock.Anything).Return([]v6.AffectedCPEHandle{
{
CPE: &v6.Cpe{Part: "a", Vendor: "vendor1", Product: "product1"},
Vulnerability: &v6.VulnerabilityHandle{
Name: "CVE-9876-5432",
Provider: &v6.Provider{ID: "provider2"},
BlobValue: &v6.VulnerabilityBlob
gitextract_p7zkpam3/
├── .binny.yaml
├── .bouncer.yaml
├── .chronicle.yaml
├── .github/
│ ├── ISSUE_TEMPLATE/
│ │ ├── bug_report.md
│ │ ├── config.yml
│ │ ├── feature_request.md
│ │ └── match_issue.md
│ ├── actions/
│ │ └── bootstrap/
│ │ └── action.yaml
│ ├── dependabot.yaml
│ ├── scripts/
│ │ ├── check-syft-version-is-release.sh
│ │ ├── ci-check.sh
│ │ ├── coverage.py
│ │ ├── db-schema-drift-check.sh
│ │ ├── go-mod-tidy-check.sh
│ │ ├── json-schema-drift-check.sh
│ │ └── trigger-release.sh
│ ├── workflows/
│ │ ├── codeql-analysis.yml
│ │ ├── dependabot-automation.yaml
│ │ ├── oss-project-board-add.yaml
│ │ ├── release.yaml
│ │ ├── remove-awaiting-response-label.yaml
│ │ ├── scorecards.yml
│ │ ├── update-anchore-dependencies.yml
│ │ ├── update-bootstrap-tools.yml
│ │ ├── update-generated-code.yml
│ │ ├── update-quality-gate-db.yml
│ │ ├── validate-github-actions.yaml
│ │ └── validations.yaml
│ └── zizmor.yml
├── .gitignore
├── .gitmodules
├── .golangci.yaml
├── .goreleaser.yaml
├── CODE_OF_CONDUCT.md
├── CONTRIBUTING.md
├── Dockerfile
├── Dockerfile.debug
├── Dockerfile.nonroot
├── LICENSE
├── Makefile
├── README.md
├── RELEASE.md
├── SECURITY.md
├── Taskfile.yaml
├── artifacthub-repo.yml
├── cmd/
│ └── grype/
│ ├── cli/
│ │ ├── cli.go
│ │ ├── cli_test.go
│ │ ├── commands/
│ │ │ ├── completion.go
│ │ │ ├── db.go
│ │ │ ├── db_check.go
│ │ │ ├── db_check_test.go
│ │ │ ├── db_delete.go
│ │ │ ├── db_import.go
│ │ │ ├── db_list.go
│ │ │ ├── db_list_test.go
│ │ │ ├── db_providers.go
│ │ │ ├── db_providers_test.go
│ │ │ ├── db_search.go
│ │ │ ├── db_search_test.go
│ │ │ ├── db_search_vuln.go
│ │ │ ├── db_search_vuln_test.go
│ │ │ ├── db_status.go
│ │ │ ├── db_status_test.go
│ │ │ ├── db_update.go
│ │ │ ├── explain.go
│ │ │ ├── internal/
│ │ │ │ ├── dbsearch/
│ │ │ │ │ ├── affected_packages.go
│ │ │ │ │ ├── affected_packages_test.go
│ │ │ │ │ ├── common.go
│ │ │ │ │ ├── matches.go
│ │ │ │ │ ├── matches_test.go
│ │ │ │ │ ├── versions.go
│ │ │ │ │ ├── vulnerabilities.go
│ │ │ │ │ ├── vulnerabilities_test.go
│ │ │ │ │ └── vulnerability_decorations.go
│ │ │ │ └── jsonschema/
│ │ │ │ └── main.go
│ │ │ ├── root.go
│ │ │ ├── root_test.go
│ │ │ ├── testdata/
│ │ │ │ └── provider-metadata.json
│ │ │ ├── update.go
│ │ │ ├── update_test.go
│ │ │ ├── util.go
│ │ │ └── util_test.go
│ │ ├── options/
│ │ │ ├── alerts.go
│ │ │ ├── alerts_test.go
│ │ │ ├── database.go
│ │ │ ├── database_command.go
│ │ │ ├── database_search_bounds.go
│ │ │ ├── database_search_format.go
│ │ │ ├── database_search_os.go
│ │ │ ├── database_search_os_test.go
│ │ │ ├── database_search_packages.go
│ │ │ ├── database_search_packages_test.go
│ │ │ ├── database_search_vulnerabilities.go
│ │ │ ├── database_search_vulnerabilities_test.go
│ │ │ ├── datasources.go
│ │ │ ├── experimental.go
│ │ │ ├── fix_channels.go
│ │ │ ├── grype.go
│ │ │ ├── grype_test.go
│ │ │ ├── match.go
│ │ │ ├── match_test.go
│ │ │ ├── registry.go
│ │ │ ├── registry_test.go
│ │ │ ├── search.go
│ │ │ ├── secret.go
│ │ │ └── sort_by.go
│ │ └── ui/
│ │ ├── __snapshots__/
│ │ │ ├── handle_database_diff_started_test.snap
│ │ │ ├── handle_update_vulnerability_database_test.snap
│ │ │ └── handle_vulnerability_scanning_started_test.snap
│ │ ├── handle_database_diff_started.go
│ │ ├── handle_database_diff_started_test.go
│ │ ├── handle_update_vulnerability_database.go
│ │ ├── handle_update_vulnerability_database_test.go
│ │ ├── handle_vulnerability_scanning_started.go
│ │ ├── handle_vulnerability_scanning_started_test.go
│ │ ├── handler.go
│ │ ├── new_task_progress.go
│ │ └── util_test.go
│ ├── internal/
│ │ ├── constants.go
│ │ └── ui/
│ │ ├── __snapshots__/
│ │ │ └── post_ui_event_writer_test.snap
│ │ ├── no_ui.go
│ │ ├── post_ui_event_writer.go
│ │ ├── post_ui_event_writer_test.go
│ │ └── ui.go
│ └── main.go
├── go.mod
├── go.sum
├── grype/
│ ├── cpe/
│ │ ├── cpe.go
│ │ └── cpe_test.go
│ ├── db/
│ │ ├── build.go
│ │ ├── data/
│ │ │ ├── entry.go
│ │ │ ├── processor.go
│ │ │ ├── severity.go
│ │ │ ├── severity_test.go
│ │ │ ├── transformers.go
│ │ │ └── writer.go
│ │ ├── default_schema_version.go
│ │ ├── generate.go
│ │ ├── internal/
│ │ │ ├── codename/
│ │ │ │ ├── codename.go
│ │ │ │ ├── codename_test.go
│ │ │ │ ├── codenames_generated.go
│ │ │ │ └── generate/
│ │ │ │ └── main.go
│ │ │ ├── gormadapter/
│ │ │ │ ├── logger.go
│ │ │ │ ├── open.go
│ │ │ │ └── open_test.go
│ │ │ ├── provider/
│ │ │ │ └── unmarshal/
│ │ │ │ ├── annotated_openvex_vulnerability.go
│ │ │ │ ├── eol.go
│ │ │ │ ├── epss.go
│ │ │ │ ├── errors.go
│ │ │ │ ├── github_advisory.go
│ │ │ │ ├── items_envelope.go
│ │ │ │ ├── known_exploited_vulnerability.go
│ │ │ │ ├── match_exclusion.go
│ │ │ │ ├── msrc_vulnerability.go
│ │ │ │ ├── nvd/
│ │ │ │ │ ├── cve.go
│ │ │ │ │ ├── cve_test.go
│ │ │ │ │ ├── cvss20/
│ │ │ │ │ │ └── cvss20.go
│ │ │ │ │ ├── cvss30/
│ │ │ │ │ │ └── cvss30.go
│ │ │ │ │ ├── cvss31/
│ │ │ │ │ │ └── cvss31.go
│ │ │ │ │ └── cvss40/
│ │ │ │ │ └── cvss40.go
│ │ │ │ ├── nvd_vulnerability.go
│ │ │ │ ├── openvex_vulnerability.go
│ │ │ │ ├── os_vulnerability.go
│ │ │ │ ├── os_vulnerability_test.go
│ │ │ │ ├── osv_vulnerability.go
│ │ │ │ └── single_or_multi.go
│ │ │ ├── sqlite/
│ │ │ │ ├── nullable_types.go
│ │ │ │ └── nullable_types_test.go
│ │ │ ├── tarutil/
│ │ │ │ ├── file_entry.go
│ │ │ │ ├── file_entry_test.go
│ │ │ │ ├── populate.go
│ │ │ │ ├── populate_test.go
│ │ │ │ ├── reader_entry.go
│ │ │ │ ├── reader_entry_test.go
│ │ │ │ ├── tar.go
│ │ │ │ ├── writer.go
│ │ │ │ └── writer_test.go
│ │ │ ├── testutil/
│ │ │ │ └── utils.go
│ │ │ └── versionutil/
│ │ │ ├── clean_fixed_in_version.go
│ │ │ ├── constraint.go
│ │ │ └── constraint_test.go
│ │ ├── package.go
│ │ ├── package_legacy.go
│ │ ├── processors/
│ │ │ ├── annotated_openvex_processor.go
│ │ │ ├── eol_processor.go
│ │ │ ├── eol_processor_test.go
│ │ │ ├── epss_processor.go
│ │ │ ├── epss_processor_test.go
│ │ │ ├── github_processor.go
│ │ │ ├── github_processor_test.go
│ │ │ ├── kev_processor.go
│ │ │ ├── kev_processor_test.go
│ │ │ ├── match_exclusion_processor.go
│ │ │ ├── match_exclusion_processor_test.go
│ │ │ ├── msrc_processor.go
│ │ │ ├── msrc_processor_test.go
│ │ │ ├── nvd_processor.go
│ │ │ ├── nvd_processor_test.go
│ │ │ ├── openvex_processor.go
│ │ │ ├── openvex_processor_test.go
│ │ │ ├── os_processor.go
│ │ │ ├── os_processor_test.go
│ │ │ ├── osv_processor.go
│ │ │ ├── osv_processor_test.go
│ │ │ ├── testdata/
│ │ │ │ ├── eol-with-empty.json
│ │ │ │ ├── eol.json
│ │ │ │ ├── epss.json
│ │ │ │ ├── exclusions.json
│ │ │ │ ├── github.json
│ │ │ │ ├── kev.json
│ │ │ │ ├── msrc.json
│ │ │ │ ├── nvd.json
│ │ │ │ ├── openvex.json
│ │ │ │ ├── oracle.json
│ │ │ │ ├── os.json
│ │ │ │ └── osv.json
│ │ │ ├── version.go
│ │ │ └── version_test.go
│ │ ├── provider/
│ │ │ ├── entry/
│ │ │ │ ├── file.go
│ │ │ │ ├── opener.go
│ │ │ │ └── sqlite.go
│ │ │ ├── file.go
│ │ │ ├── model.go
│ │ │ ├── model_test.go
│ │ │ ├── provider.go
│ │ │ ├── state.go
│ │ │ ├── state_test.go
│ │ │ └── workspace.go
│ │ ├── v5/
│ │ │ ├── advisory.go
│ │ │ ├── build/
│ │ │ │ ├── processors.go
│ │ │ │ ├── transformers/
│ │ │ │ │ ├── entry.go
│ │ │ │ │ ├── github/
│ │ │ │ │ │ ├── testdata/
│ │ │ │ │ │ │ ├── github-github-npm-0.json
│ │ │ │ │ │ │ ├── github-github-python-0.json
│ │ │ │ │ │ │ ├── github-github-python-1.json
│ │ │ │ │ │ │ ├── github-withdrawn.json
│ │ │ │ │ │ │ └── multiple-fixed-in-names.json
│ │ │ │ │ │ ├── transform.go
│ │ │ │ │ │ └── transform_test.go
│ │ │ │ │ ├── matchexclusions/
│ │ │ │ │ │ └── transform.go
│ │ │ │ │ ├── msrc/
│ │ │ │ │ │ ├── testdata/
│ │ │ │ │ │ │ └── microsoft-msrc-0.json
│ │ │ │ │ │ ├── transform.go
│ │ │ │ │ │ └── transform_test.go
│ │ │ │ │ ├── nvd/
│ │ │ │ │ │ ├── testdata/
│ │ │ │ │ │ │ ├── CVE-2023-45283-platform-cpe-first.json
│ │ │ │ │ │ │ ├── CVE-2023-45283-platform-cpe-last.json
│ │ │ │ │ │ │ ├── compound-pkg.json
│ │ │ │ │ │ │ ├── cve-2020-10729.json
│ │ │ │ │ │ │ ├── cve-2022-0543.json
│ │ │ │ │ │ │ ├── invalid_cpe.json
│ │ │ │ │ │ │ ├── multiple-platforms-with-application-cpe.json
│ │ │ │ │ │ │ ├── platform-cpe.json
│ │ │ │ │ │ │ ├── single-package-multi-distro.json
│ │ │ │ │ │ │ ├── unmarshal-test.json
│ │ │ │ │ │ │ └── version-range.json
│ │ │ │ │ │ ├── transform.go
│ │ │ │ │ │ ├── transform_test.go
│ │ │ │ │ │ ├── unique_pkg.go
│ │ │ │ │ │ ├── unique_pkg_test.go
│ │ │ │ │ │ └── unique_pkg_tracker.go
│ │ │ │ │ ├── os/
│ │ │ │ │ │ ├── testdata/
│ │ │ │ │ │ │ ├── alpine-3.9.json
│ │ │ │ │ │ │ ├── amazon-multiple-kernel-advisories.json
│ │ │ │ │ │ │ ├── amzn.json
│ │ │ │ │ │ │ ├── azure-linux-3.json
│ │ │ │ │ │ │ ├── debian-8-multiple-entries-for-same-package.json
│ │ │ │ │ │ │ ├── debian-8.json
│ │ │ │ │ │ │ ├── mariner-20.json
│ │ │ │ │ │ │ ├── mariner-range.json
│ │ │ │ │ │ │ ├── ol-8-modules.json
│ │ │ │ │ │ │ ├── ol-8.json
│ │ │ │ │ │ │ ├── photon-4.0.json
│ │ │ │ │ │ │ ├── rhel-8-eus.json
│ │ │ │ │ │ │ ├── rhel-8-modules.json
│ │ │ │ │ │ │ ├── rhel-8.json
│ │ │ │ │ │ │ └── unmarshal-test.json
│ │ │ │ │ │ ├── transform.go
│ │ │ │ │ │ └── transform_test.go
│ │ │ │ │ └── vulnerability_metadata.go
│ │ │ │ ├── writer.go
│ │ │ │ └── writer_test.go
│ │ │ ├── cvss.go
│ │ │ ├── diff.go
│ │ │ ├── differ/
│ │ │ │ ├── differ.go
│ │ │ │ ├── differ_test.go
│ │ │ │ └── testdata/
│ │ │ │ ├── dbs/
│ │ │ │ │ ├── base/
│ │ │ │ │ │ └── 5/
│ │ │ │ │ │ └── metadata.json
│ │ │ │ │ └── target/
│ │ │ │ │ └── 5/
│ │ │ │ │ └── metadata.json
│ │ │ │ └── snapshot/
│ │ │ │ ├── TestPresent_Json.golden
│ │ │ │ └── TestPresent_Table.golden
│ │ │ ├── distribution/
│ │ │ │ ├── curator.go
│ │ │ │ ├── curator_test.go
│ │ │ │ ├── listing.go
│ │ │ │ ├── listing_entry.go
│ │ │ │ ├── listing_test.go
│ │ │ │ ├── metadata.go
│ │ │ │ ├── metadata_test.go
│ │ │ │ ├── status.go
│ │ │ │ └── testdata/
│ │ │ │ ├── curator-validate/
│ │ │ │ │ ├── bad-checksum/
│ │ │ │ │ │ └── metadata.json
│ │ │ │ │ └── good-checksum/
│ │ │ │ │ └── metadata.json
│ │ │ │ ├── listing-sorted.json
│ │ │ │ ├── listing-unsorted.json
│ │ │ │ ├── listing.json
│ │ │ │ ├── metadata-edt-timezone/
│ │ │ │ │ └── metadata.json
│ │ │ │ ├── metadata-gocase/
│ │ │ │ │ └── metadata.json
│ │ │ │ └── tls/
│ │ │ │ ├── .gitignore
│ │ │ │ ├── Makefile
│ │ │ │ ├── README.md
│ │ │ │ ├── generate-x509-cert-pair.sh
│ │ │ │ ├── listing.py
│ │ │ │ └── serve.py
│ │ │ ├── fix.go
│ │ │ ├── id.go
│ │ │ ├── match_exclusion_provider.go
│ │ │ ├── namespace/
│ │ │ │ ├── cpe/
│ │ │ │ │ ├── namespace.go
│ │ │ │ │ └── namespace_test.go
│ │ │ │ ├── distro/
│ │ │ │ │ ├── namespace.go
│ │ │ │ │ └── namespace_test.go
│ │ │ │ ├── from_string.go
│ │ │ │ ├── from_string_test.go
│ │ │ │ ├── language/
│ │ │ │ │ ├── namespace.go
│ │ │ │ │ └── namespace_test.go
│ │ │ │ └── namespace.go
│ │ │ ├── pkg/
│ │ │ │ ├── qualifier/
│ │ │ │ │ ├── from_json.go
│ │ │ │ │ ├── platformcpe/
│ │ │ │ │ │ └── qualifier.go
│ │ │ │ │ ├── qualifier.go
│ │ │ │ │ └── rpmmodularity/
│ │ │ │ │ └── qualifier.go
│ │ │ │ └── resolver/
│ │ │ │ ├── java/
│ │ │ │ │ ├── resolver.go
│ │ │ │ │ └── resolver_test.go
│ │ │ │ ├── python/
│ │ │ │ │ ├── resolver.go
│ │ │ │ │ └── resolver_test.go
│ │ │ │ ├── resolver.go
│ │ │ │ ├── resolver_test.go
│ │ │ │ └── stock/
│ │ │ │ ├── resolver.go
│ │ │ │ └── resolver_test.go
│ │ │ ├── provider_store.go
│ │ │ ├── schema_version.go
│ │ │ ├── store/
│ │ │ │ ├── diff.go
│ │ │ │ ├── diff_test.go
│ │ │ │ ├── model/
│ │ │ │ │ ├── id.go
│ │ │ │ │ ├── vulnerability.go
│ │ │ │ │ ├── vulnerability_match_exclusion.go
│ │ │ │ │ ├── vulnerability_match_exclusion_test.go
│ │ │ │ │ ├── vulnerability_metadata.go
│ │ │ │ │ └── vulnerability_test.go
│ │ │ │ ├── store.go
│ │ │ │ └── store_test.go
│ │ │ ├── store.go
│ │ │ ├── vulnerability.go
│ │ │ ├── vulnerability_match_exclusion.go
│ │ │ ├── vulnerability_match_exclusion_store.go
│ │ │ ├── vulnerability_metadata.go
│ │ │ ├── vulnerability_metadata_store.go
│ │ │ └── vulnerability_store.go
│ │ └── v6/
│ │ ├── affected_cpe_store.go
│ │ ├── affected_cpe_store_test.go
│ │ ├── affected_package_store.go
│ │ ├── affected_package_store_test.go
│ │ ├── blob_store.go
│ │ ├── blob_store_test.go
│ │ ├── blobs.go
│ │ ├── blobs_test.go
│ │ ├── build/
│ │ │ ├── archive.go
│ │ │ ├── processors.go
│ │ │ ├── transformers/
│ │ │ │ ├── entry.go
│ │ │ │ ├── eol/
│ │ │ │ │ ├── transform.go
│ │ │ │ │ └── transform_test.go
│ │ │ │ ├── epss/
│ │ │ │ │ ├── testdata/
│ │ │ │ │ │ └── go-case.json
│ │ │ │ │ ├── transform.go
│ │ │ │ │ └── transform_test.go
│ │ │ │ ├── github/
│ │ │ │ │ ├── testdata/
│ │ │ │ │ │ ├── GHSA-2wgc-48g2-cj5w.json
│ │ │ │ │ │ ├── GHSA-3x74-v64j-qc3f.json
│ │ │ │ │ │ ├── GHSA-92cp-5422-2mw7.json
│ │ │ │ │ │ ├── GHSA-qc55-vm3j-74gp.json
│ │ │ │ │ │ ├── github-github-npm-0.json
│ │ │ │ │ │ ├── github-github-python-0.json
│ │ │ │ │ │ ├── github-withdrawn.json
│ │ │ │ │ │ └── multiple-fixed-in-names.json
│ │ │ │ │ ├── transform.go
│ │ │ │ │ └── transform_test.go
│ │ │ │ ├── internal/
│ │ │ │ │ ├── sort.go
│ │ │ │ │ ├── time.go
│ │ │ │ │ └── time_test.go
│ │ │ │ ├── kev/
│ │ │ │ │ ├── testdata/
│ │ │ │ │ │ └── go-case.json
│ │ │ │ │ ├── transform.go
│ │ │ │ │ └── transform_test.go
│ │ │ │ ├── msrc/
│ │ │ │ │ ├── testdata/
│ │ │ │ │ │ └── microsoft-msrc-0.json
│ │ │ │ │ ├── transform.go
│ │ │ │ │ └── transform_test.go
│ │ │ │ ├── nvd/
│ │ │ │ │ ├── affected_range.go
│ │ │ │ │ ├── affected_range_test.go
│ │ │ │ │ ├── node.go
│ │ │ │ │ ├── node_test.go
│ │ │ │ │ ├── testdata/
│ │ │ │ │ │ ├── CVE-2004-0377.json
│ │ │ │ │ │ ├── CVE-2008-3442.json
│ │ │ │ │ │ ├── CVE-2023-45283-platform-cpe-first.json
│ │ │ │ │ │ ├── CVE-2023-45283-platform-cpe-last.json
│ │ │ │ │ │ ├── compound-pkg.json
│ │ │ │ │ │ ├── cve-2020-10729.json
│ │ │ │ │ │ ├── cve-2021-1566.json
│ │ │ │ │ │ ├── cve-2022-0543.json
│ │ │ │ │ │ ├── cve-2024-26663-standalone-os.json
│ │ │ │ │ │ ├── fix-version.json
│ │ │ │ │ │ ├── fix-wrong-version.json
│ │ │ │ │ │ ├── invalid_cpe.json
│ │ │ │ │ │ ├── jvm-packages.json
│ │ │ │ │ │ ├── multiple-platforms-with-application-cpe.json
│ │ │ │ │ │ ├── platform-cpe.json
│ │ │ │ │ │ ├── single-package-multi-distro.json
│ │ │ │ │ │ └── version-range.json
│ │ │ │ │ ├── transform.go
│ │ │ │ │ └── transform_test.go
│ │ │ │ ├── openvex/
│ │ │ │ │ ├── transform.go
│ │ │ │ │ └── transform_test.go
│ │ │ │ ├── os/
│ │ │ │ │ ├── testdata/
│ │ │ │ │ │ ├── alpine-3.9.json
│ │ │ │ │ │ ├── amazon-multiple-kernel-advisories.json
│ │ │ │ │ │ ├── amzn.json
│ │ │ │ │ │ ├── azure-linux-3.json
│ │ │ │ │ │ ├── debian-8-multiple-entries-for-same-package.json
│ │ │ │ │ │ ├── debian-8.json
│ │ │ │ │ │ ├── fedora-39.json
│ │ │ │ │ │ ├── mariner-20.json
│ │ │ │ │ │ ├── mariner-range.json
│ │ │ │ │ │ ├── ol-8-modules.json
│ │ │ │ │ │ ├── ol-8.json
│ │ │ │ │ │ ├── rhel-8-modules.json
│ │ │ │ │ │ └── rhel-8.json
│ │ │ │ │ ├── transform.go
│ │ │ │ │ └── transform_test.go
│ │ │ │ ├── osv/
│ │ │ │ │ ├── testdata/
│ │ │ │ │ │ ├── ALSA-2025-7467.json
│ │ │ │ │ │ ├── BIT-apache-2020-11984.json
│ │ │ │ │ │ └── BIT-node-2020-8201.json
│ │ │ │ │ ├── transform.go
│ │ │ │ │ └── transform_test.go
│ │ │ │ └── references.go
│ │ │ ├── writer.go
│ │ │ └── writer_test.go
│ │ ├── cache.go
│ │ ├── cache_test.go
│ │ ├── cpe_store.go
│ │ ├── data.go
│ │ ├── db.go
│ │ ├── db_metadata_store.go
│ │ ├── db_metadata_store_test.go
│ │ ├── description.go
│ │ ├── description_test.go
│ │ ├── distribution/
│ │ │ ├── client.go
│ │ │ ├── client_test.go
│ │ │ ├── latest.go
│ │ │ ├── latest_test.go
│ │ │ └── status.go
│ │ ├── enumerations.go
│ │ ├── enumerations_test.go
│ │ ├── fillers.go
│ │ ├── import_metadata.go
│ │ ├── import_metadata_test.go
│ │ ├── installation/
│ │ │ ├── curator.go
│ │ │ └── curator_test.go
│ │ ├── log_dropped.go
│ │ ├── models.go
│ │ ├── models_test.go
│ │ ├── name/
│ │ │ ├── java.go
│ │ │ ├── java_test.go
│ │ │ ├── python.go
│ │ │ ├── python_test.go
│ │ │ └── resolver.go
│ │ ├── operating_system_store.go
│ │ ├── operating_system_store_test.go
│ │ ├── package_store.go
│ │ ├── provider_store.go
│ │ ├── provider_store_test.go
│ │ ├── refs.go
│ │ ├── schema/
│ │ │ └── main.go
│ │ ├── search_query.go
│ │ ├── search_query_test.go
│ │ ├── severity.go
│ │ ├── severity_test.go
│ │ ├── store.go
│ │ ├── store_test.go
│ │ ├── unaffected_cpe_store.go
│ │ ├── unaffected_cpe_store_test.go
│ │ ├── unaffected_package_store.go
│ │ ├── unaffected_package_store_test.go
│ │ ├── vulnerability.go
│ │ ├── vulnerability_decorator_store.go
│ │ ├── vulnerability_decorator_store_test.go
│ │ ├── vulnerability_provider.go
│ │ ├── vulnerability_provider_mocks_test.go
│ │ ├── vulnerability_provider_test.go
│ │ ├── vulnerability_store.go
│ │ ├── vulnerability_store_test.go
│ │ └── vulnerability_test.go
│ ├── deprecated.go
│ ├── distro/
│ │ ├── distro.go
│ │ ├── distro_test.go
│ │ ├── fix_channel.go
│ │ ├── fix_channel_test.go
│ │ ├── testdata/
│ │ │ ├── bad-id
│ │ │ ├── bad-redhat-release
│ │ │ ├── bad-system-release-cpe
│ │ │ ├── centos-8
│ │ │ ├── debian-8
│ │ │ ├── os/
│ │ │ │ ├── almalinux/
│ │ │ │ │ └── etc/
│ │ │ │ │ └── os-release
│ │ │ │ ├── alpine/
│ │ │ │ │ └── etc/
│ │ │ │ │ └── os-release
│ │ │ │ ├── alpine-edge/
│ │ │ │ │ └── etc/
│ │ │ │ │ └── os-release
│ │ │ │ ├── amazon/
│ │ │ │ │ └── etc/
│ │ │ │ │ └── os-release
│ │ │ │ ├── arch/
│ │ │ │ │ └── etc/
│ │ │ │ │ └── os-release
│ │ │ │ ├── azurelinux/
│ │ │ │ │ └── etc/
│ │ │ │ │ └── os-release
│ │ │ │ ├── busybox/
│ │ │ │ │ └── bin/
│ │ │ │ │ └── busybox
│ │ │ │ ├── centos/
│ │ │ │ │ └── usr/
│ │ │ │ │ └── lib/
│ │ │ │ │ └── os-release
│ │ │ │ ├── centos5/
│ │ │ │ │ └── etc/
│ │ │ │ │ └── redhat-release
│ │ │ │ ├── centos6/
│ │ │ │ │ └── etc/
│ │ │ │ │ └── system-release-cpe
│ │ │ │ ├── chainguard/
│ │ │ │ │ └── etc/
│ │ │ │ │ └── os-release
│ │ │ │ ├── custom/
│ │ │ │ │ └── etc/
│ │ │ │ │ └── os-release
│ │ │ │ ├── debian/
│ │ │ │ │ └── usr/
│ │ │ │ │ └── lib/
│ │ │ │ │ └── os-release
│ │ │ │ ├── debian-sid/
│ │ │ │ │ └── usr/
│ │ │ │ │ └── lib/
│ │ │ │ │ └── os-release
│ │ │ │ ├── echo/
│ │ │ │ │ └── etc/
│ │ │ │ │ └── os-release
│ │ │ │ ├── empty/
│ │ │ │ │ └── etc/
│ │ │ │ │ └── os-release
│ │ │ │ ├── fedora/
│ │ │ │ │ └── usr/
│ │ │ │ │ └── lib/
│ │ │ │ │ └── os-release
│ │ │ │ ├── gentoo/
│ │ │ │ │ └── etc/
│ │ │ │ │ └── os-release
│ │ │ │ ├── mariner/
│ │ │ │ │ └── etc/
│ │ │ │ │ └── os-release
│ │ │ │ ├── minimos/
│ │ │ │ │ └── etc/
│ │ │ │ │ └── os-release
│ │ │ │ ├── opensuse-leap/
│ │ │ │ │ └── etc/
│ │ │ │ │ └── os-release
│ │ │ │ ├── oraclelinux/
│ │ │ │ │ └── etc/
│ │ │ │ │ └── os-release
│ │ │ │ ├── photon/
│ │ │ │ │ └── etc/
│ │ │ │ │ └── os-release
│ │ │ │ ├── postmarketos/
│ │ │ │ │ └── etc/
│ │ │ │ │ └── os-release
│ │ │ │ ├── postmarketos-edge/
│ │ │ │ │ └── etc/
│ │ │ │ │ └── os-release
│ │ │ │ ├── raspbian/
│ │ │ │ │ └── etc/
│ │ │ │ │ └── os-release
│ │ │ │ ├── redhat/
│ │ │ │ │ └── usr/
│ │ │ │ │ └── lib/
│ │ │ │ │ └── os-release
│ │ │ │ ├── rockylinux/
│ │ │ │ │ └── etc/
│ │ │ │ │ └── os-release
│ │ │ │ ├── scientific/
│ │ │ │ │ └── etc/
│ │ │ │ │ └── os-release
│ │ │ │ ├── scientific6/
│ │ │ │ │ └── etc/
│ │ │ │ │ └── redhat-release
│ │ │ │ ├── secureos/
│ │ │ │ │ └── etc/
│ │ │ │ │ └── os-release
│ │ │ │ ├── sles/
│ │ │ │ │ └── etc/
│ │ │ │ │ └── os-release
│ │ │ │ ├── ubuntu/
│ │ │ │ │ └── etc/
│ │ │ │ │ └── os-release
│ │ │ │ └── wolfi/
│ │ │ │ └── etc/
│ │ │ │ └── os-release
│ │ │ ├── partial-fields/
│ │ │ │ ├── missing-id/
│ │ │ │ │ └── usr/
│ │ │ │ │ └── lib/
│ │ │ │ │ └── os-release
│ │ │ │ ├── missing-version/
│ │ │ │ │ └── usr/
│ │ │ │ │ └── lib/
│ │ │ │ │ └── os-release
│ │ │ │ └── unknown-id/
│ │ │ │ └── usr/
│ │ │ │ └── lib/
│ │ │ │ └── os-release
│ │ │ ├── rhel-8
│ │ │ ├── ubuntu-20.04
│ │ │ └── unprintable
│ │ ├── type.go
│ │ └── type_test.go
│ ├── event/
│ │ ├── event.go
│ │ ├── monitor/
│ │ │ ├── db_diff.go
│ │ │ └── matching.go
│ │ └── parsers/
│ │ └── parsers.go
│ ├── grypeerr/
│ │ ├── errors.go
│ │ └── expected_error.go
│ ├── internal/
│ │ ├── generate.go
│ │ └── packagemetadata/
│ │ ├── discover_type_names.go
│ │ ├── generate/
│ │ │ └── main.go
│ │ ├── generated.go
│ │ ├── names.go
│ │ └── names_test.go
│ ├── lib.go
│ ├── load_vulnerability_db.go
│ ├── load_vulnerability_db_bench_test.go
│ ├── match/
│ │ ├── details.go
│ │ ├── details_test.go
│ │ ├── explicit_ignores.go
│ │ ├── explicit_ignores_test.go
│ │ ├── fingerprint.go
│ │ ├── ignore.go
│ │ ├── ignore_test.go
│ │ ├── match.go
│ │ ├── match_test.go
│ │ ├── matcher.go
│ │ ├── matcher_type.go
│ │ ├── matches.go
│ │ ├── matches_test.go
│ │ ├── provider.go
│ │ ├── results.go
│ │ ├── sort.go
│ │ └── type.go
│ ├── matcher/
│ │ ├── apk/
│ │ │ ├── matcher.go
│ │ │ └── matcher_test.go
│ │ ├── bitnami/
│ │ │ └── matcher.go
│ │ ├── dotnet/
│ │ │ └── matcher.go
│ │ ├── dpkg/
│ │ │ ├── matcher.go
│ │ │ ├── matcher_mocks_test.go
│ │ │ └── matcher_test.go
│ │ ├── golang/
│ │ │ ├── matcher.go
│ │ │ └── matcher_test.go
│ │ ├── hex/
│ │ │ └── matcher.go
│ │ ├── internal/
│ │ │ ├── common.go
│ │ │ ├── cpe.go
│ │ │ ├── cpe_test.go
│ │ │ ├── distro.go
│ │ │ ├── distro_test.go
│ │ │ ├── eol.go
│ │ │ ├── eol_test.go
│ │ │ ├── language.go
│ │ │ ├── language_test.go
│ │ │ ├── only_non_withdrawn_vulnerabilities.go
│ │ │ ├── only_qualified_packages.go
│ │ │ ├── only_vulnerable_targets.go
│ │ │ ├── only_vulnerable_targets_test.go
│ │ │ ├── only_vulnerable_versions.go
│ │ │ ├── result/
│ │ │ │ ├── match_details_set.go
│ │ │ │ ├── provider.go
│ │ │ │ ├── results.go
│ │ │ │ └── results_test.go
│ │ │ └── utils_test.go
│ │ ├── java/
│ │ │ ├── matcher.go
│ │ │ ├── matcher_integration_test.go
│ │ │ ├── matcher_mocks_test.go
│ │ │ ├── matcher_test.go
│ │ │ ├── maven_search.go
│ │ │ └── maven_test.go
│ │ ├── javascript/
│ │ │ └── matcher.go
│ │ ├── matchers.go
│ │ ├── mock/
│ │ │ └── matcher.go
│ │ ├── msrc/
│ │ │ └── matcher.go
│ │ ├── pacman/
│ │ │ ├── matcher.go
│ │ │ └── matcher_test.go
│ │ ├── portage/
│ │ │ ├── matcher.go
│ │ │ ├── matcher_mocks_test.go
│ │ │ └── matcher_test.go
│ │ ├── python/
│ │ │ └── matcher.go
│ │ ├── rpm/
│ │ │ ├── almalinux.go
│ │ │ ├── almalinux_package_utils.go
│ │ │ ├── almalinux_package_utils_test.go
│ │ │ ├── almalinux_test.go
│ │ │ ├── matcher.go
│ │ │ ├── matcher_mocks_test.go
│ │ │ ├── matcher_test.go
│ │ │ ├── rhel_eus.go
│ │ │ └── rhel_eus_test.go
│ │ ├── ruby/
│ │ │ └── matcher.go
│ │ ├── rust/
│ │ │ └── matcher.go
│ │ └── stock/
│ │ ├── matcher.go
│ │ └── matcher_test.go
│ ├── pkg/
│ │ ├── apk_metadata.go
│ │ ├── context.go
│ │ ├── context_test.go
│ │ ├── cpe_provider.go
│ │ ├── cpe_provider_test.go
│ │ ├── file_owner.go
│ │ ├── golang_metadata.go
│ │ ├── java_metadata.go
│ │ ├── java_metadata_test.go
│ │ ├── package.go
│ │ ├── package_test.go
│ │ ├── provider.go
│ │ ├── provider_config.go
│ │ ├── provider_test.go
│ │ ├── purl_provider.go
│ │ ├── purl_provider_test.go
│ │ ├── qualifier/
│ │ │ ├── platformcpe/
│ │ │ │ ├── qualifier.go
│ │ │ │ └── qualifier_test.go
│ │ │ ├── qualifier.go
│ │ │ └── rpmmodularity/
│ │ │ ├── qualifier.go
│ │ │ └── qualifier_test.go
│ │ ├── rpm_metadata.go
│ │ ├── syft_provider.go
│ │ ├── syft_sbom_provider.go
│ │ ├── syft_sbom_provider_test.go
│ │ ├── testdata/
│ │ │ ├── alpine-tampered.att.json
│ │ │ ├── alpine-tampered.cdx.att.json
│ │ │ ├── alpine.att.json
│ │ │ ├── alpine.cdx.att.json
│ │ │ ├── another_cosign.pub
│ │ │ ├── bad-sbom.json
│ │ │ ├── cosign.pub
│ │ │ ├── cosign_broken.pub
│ │ │ ├── image-simple/
│ │ │ │ ├── Dockerfile
│ │ │ │ ├── package.json
│ │ │ │ └── target/
│ │ │ │ └── nested/
│ │ │ │ └── package.json
│ │ │ ├── invalid.json
│ │ │ ├── purl/
│ │ │ │ ├── different-os.txt
│ │ │ │ ├── empty.json
│ │ │ │ ├── homogeneous-os.txt
│ │ │ │ ├── invalid-cpe.txt
│ │ │ │ ├── invalid-purl.txt
│ │ │ │ ├── valid-purl.txt
│ │ │ │ ├── valid-rhel-9+eus.txt
│ │ │ │ └── valid-rhel-9.txt
│ │ │ ├── sbom-with-intoto-string.json
│ │ │ ├── syft-java-bad-cpes.json
│ │ │ ├── syft-multiple-ecosystems.json
│ │ │ └── syft-spring.json
│ │ ├── upstream_package.go
│ │ ├── upstream_package_test.go
│ │ ├── version_format.go
│ │ └── version_format_test.go
│ ├── presenter/
│ │ ├── cyclonedx/
│ │ │ ├── presenter.go
│ │ │ ├── presenter_test.go
│ │ │ ├── testdata/
│ │ │ │ └── snapshot/
│ │ │ │ ├── TestCycloneDxPresenterDir.golden
│ │ │ │ └── TestCycloneDxPresenterImage.golden
│ │ │ ├── vulnerability.go
│ │ │ └── vulnerability_test.go
│ │ ├── explain/
│ │ │ ├── __snapshots__/
│ │ │ │ └── explain_snapshot_test.snap
│ │ │ ├── explain.go
│ │ │ ├── explain_cve.tmpl
│ │ │ ├── explain_snapshot_test.go
│ │ │ └── testdata/
│ │ │ ├── chainguard-ruby-test.json
│ │ │ ├── ghsa-test.json
│ │ │ └── keycloak-test.json
│ │ ├── internal/
│ │ │ └── test_helpers.go
│ │ ├── json/
│ │ │ ├── presenter.go
│ │ │ ├── presenter_test.go
│ │ │ └── testdata/
│ │ │ ├── image-simple/
│ │ │ │ ├── Dockerfile
│ │ │ │ ├── file-1.txt
│ │ │ │ ├── file-2.txt
│ │ │ │ └── target/
│ │ │ │ └── really/
│ │ │ │ └── nested/
│ │ │ │ └── file-3.txt
│ │ │ └── snapshot/
│ │ │ ├── TestEmptyJsonPresenter.golden
│ │ │ ├── TestJsonDirsPresenter.golden
│ │ │ ├── TestJsonImgsPresenter.golden
│ │ │ ├── anchore-fixture-image-simple.golden
│ │ │ └── stereoscope-fixture-image-simple.golden
│ │ ├── models/
│ │ │ ├── alert.go
│ │ │ ├── alert_test.go
│ │ │ ├── cvss.go
│ │ │ ├── descriptor.go
│ │ │ ├── distribution.go
│ │ │ ├── document.go
│ │ │ ├── document_test.go
│ │ │ ├── ignore.go
│ │ │ ├── ignore_test.go
│ │ │ ├── match.go
│ │ │ ├── metadata_mock.go
│ │ │ ├── package.go
│ │ │ ├── presenter_bundle.go
│ │ │ ├── sort.go
│ │ │ ├── sort_test.go
│ │ │ ├── source.go
│ │ │ ├── source_test.go
│ │ │ ├── vulnerability.go
│ │ │ ├── vulnerability_metadata.go
│ │ │ └── vulnerability_test.go
│ │ ├── presenter.go
│ │ ├── sarif/
│ │ │ ├── presenter.go
│ │ │ ├── presenter_test.go
│ │ │ └── testdata/
│ │ │ ├── image-simple/
│ │ │ │ ├── Dockerfile
│ │ │ │ ├── file-1.txt
│ │ │ │ ├── file-2.txt
│ │ │ │ └── target/
│ │ │ │ └── really/
│ │ │ │ └── nested/
│ │ │ │ └── file-3.txt
│ │ │ └── snapshot/
│ │ │ ├── TestSarifPresenter_directory.golden
│ │ │ └── TestSarifPresenter_image.golden
│ │ ├── table/
│ │ │ ├── __snapshots__/
│ │ │ │ └── presenter_test.snap
│ │ │ ├── presenter.go
│ │ │ ├── presenter_test.go
│ │ │ └── testdata/
│ │ │ └── snapshot/
│ │ │ └── TestTablePresenter_Color.golden
│ │ └── template/
│ │ ├── presenter.go
│ │ ├── presenter_test.go
│ │ └── testdata/
│ │ ├── snapshot/
│ │ │ └── TestPresenter_Present.golden
│ │ ├── test.template
│ │ ├── test.template.sprig.date
│ │ └── test.valid.template
│ ├── search/
│ │ ├── cpe.go
│ │ ├── cpe_test.go
│ │ ├── criteria.go
│ │ ├── criteria_test.go
│ │ ├── distro.go
│ │ ├── distro_test.go
│ │ ├── ecosystem.go
│ │ ├── ecosystem_test.go
│ │ ├── func.go
│ │ ├── func_test.go
│ │ ├── id.go
│ │ ├── id_test.go
│ │ ├── package_name.go
│ │ ├── package_name_test.go
│ │ ├── unaffected.go
│ │ ├── version_constraint.go
│ │ └── version_constraint_test.go
│ ├── version/
│ │ ├── apk_version.go
│ │ ├── apk_version_test.go
│ │ ├── bitnami_version.go
│ │ ├── bitnami_version_test.go
│ │ ├── combined_constraint.go
│ │ ├── combined_constraint_test.go
│ │ ├── comparator.go
│ │ ├── constraint.go
│ │ ├── deb_version.go
│ │ ├── deb_version_test.go
│ │ ├── deprecated.go
│ │ ├── error.go
│ │ ├── format.go
│ │ ├── format_test.go
│ │ ├── fuzzy_constraint.go
│ │ ├── fuzzy_constraint_test.go
│ │ ├── fuzzy_version.go
│ │ ├── fuzzy_version_test.go
│ │ ├── gem_version.go
│ │ ├── gem_version_test.go
│ │ ├── generic_constraint.go
│ │ ├── generic_constraint_test.go
│ │ ├── golang_version.go
│ │ ├── golang_version_test.go
│ │ ├── helper_test.go
│ │ ├── jvm_version.go
│ │ ├── jvm_version_test.go
│ │ ├── kb_constraint.go
│ │ ├── kb_constraint_test.go
│ │ ├── kb_version.go
│ │ ├── kb_version_test.go
│ │ ├── maven_version.go
│ │ ├── maven_version_test.go
│ │ ├── operator.go
│ │ ├── pacman_version.go
│ │ ├── pacman_version_test.go
│ │ ├── pep440_version.go
│ │ ├── pep440_version_test.go
│ │ ├── portage_version.go
│ │ ├── portage_version_test.go
│ │ ├── range.go
│ │ ├── range_expression.go
│ │ ├── range_expression_test.go
│ │ ├── range_test.go
│ │ ├── rpm_version.go
│ │ ├── rpm_version_test.go
│ │ ├── semantic_version.go
│ │ ├── semantic_version_test.go
│ │ ├── set.go
│ │ ├── set_test.go
│ │ ├── version.go
│ │ └── version_test.go
│ ├── vex/
│ │ ├── csaf/
│ │ │ ├── csaf.go
│ │ │ ├── csaf_test.go
│ │ │ ├── implementation.go
│ │ │ ├── implementation_test.go
│ │ │ └── status.go
│ │ ├── openvex/
│ │ │ ├── implementation.go
│ │ │ └── implementation_test.go
│ │ ├── processor.go
│ │ ├── processor_test.go
│ │ ├── status/
│ │ │ └── status.go
│ │ └── testdata/
│ │ └── vex-docs/
│ │ ├── csaf-demo1.json
│ │ ├── csaf-demo2.json
│ │ ├── openvex-debian.json
│ │ ├── openvex-demo1.json
│ │ ├── openvex-demo2.json
│ │ ├── openvex-image-no-subcomponents.json
│ │ └── openvex-package-product.json
│ ├── vulnerability/
│ │ ├── advisory.go
│ │ ├── fix.go
│ │ ├── metadata.go
│ │ ├── metadata_test.go
│ │ ├── mock/
│ │ │ └── vulnerability_provider.go
│ │ ├── provider.go
│ │ ├── severity.go
│ │ └── vulnerability.go
│ ├── vulnerability_matcher.go
│ └── vulnerability_matcher_test.go
├── install.sh
├── internal/
│ ├── bus/
│ │ ├── bus.go
│ │ └── helpers.go
│ ├── cvss/
│ │ ├── metrics.go
│ │ └── metrics_test.go
│ ├── dbtest/
│ │ ├── default_vulnerabilities.go
│ │ ├── server.go
│ │ └── server_test.go
│ ├── file/
│ │ ├── copy.go
│ │ ├── exists.go
│ │ ├── getter.go
│ │ ├── getter_test.go
│ │ ├── hasher.go
│ │ ├── hasher_test.go
│ │ ├── tar_xz_decompressor.go
│ │ ├── tar_xz_decompressor_test.go
│ │ ├── xz_decompressor.go
│ │ └── xz_decompressor_test.go
│ ├── format/
│ │ ├── format.go
│ │ ├── format_test.go
│ │ ├── presenter.go
│ │ ├── writer.go
│ │ └── writer_test.go
│ ├── input.go
│ ├── log/
│ │ ├── errors.go
│ │ └── log.go
│ ├── redact/
│ │ └── redact.go
│ ├── regex_helpers.go
│ ├── regex_helpers_test.go
│ ├── schemaver/
│ │ ├── schema_ver.go
│ │ └── schema_ver_test.go
│ ├── stringutil/
│ │ ├── color.go
│ │ ├── parse.go
│ │ ├── string_helpers.go
│ │ ├── string_helpers_test.go
│ │ ├── stringset.go
│ │ └── tprint.go
│ └── testutils/
│ └── golden_file.go
├── llms.txt
├── schema/
│ └── grype/
│ ├── db/
│ │ ├── README.md
│ │ ├── blob/
│ │ │ └── json/
│ │ │ ├── schema-6.1.1.json
│ │ │ ├── schema-6.1.2.json
│ │ │ ├── schema-6.1.3.json
│ │ │ ├── schema-6.1.4.json
│ │ │ └── schema-latest.json
│ │ └── sql/
│ │ ├── schema-6.1.1.sql
│ │ ├── schema-6.1.2.sql
│ │ ├── schema-6.1.3.sql
│ │ ├── schema-6.1.4.sql
│ │ └── schema-latest.sql
│ ├── db-search/
│ │ └── json/
│ │ ├── README.md
│ │ ├── schema-1.0.0.json
│ │ ├── schema-1.0.1.json
│ │ ├── schema-1.0.2.json
│ │ ├── schema-1.0.3.json
│ │ ├── schema-1.1.0.json
│ │ ├── schema-1.1.1.json
│ │ ├── schema-1.1.2.json
│ │ ├── schema-1.1.3.json
│ │ └── schema-latest.json
│ └── db-search-vuln/
│ └── json/
│ ├── README.md
│ ├── schema-1.0.0.json
│ ├── schema-1.0.1.json
│ ├── schema-1.0.3.json
│ ├── schema-1.0.4.json
│ ├── schema-1.0.5.json
│ └── schema-latest.json
├── templates/
│ ├── README.md
│ ├── csv.tmpl
│ ├── html.tmpl
│ ├── junit.tmpl
│ ├── markdown.tmpl
│ └── table.tmpl
└── test/
├── cli/
│ ├── cmd_test.go
│ ├── config_test.go
│ ├── db_providers_test.go
│ ├── db_validations_test.go
│ ├── registry_auth_test.go
│ ├── sbom_input_test.go
│ ├── subprocess_test.go
│ ├── testdata/
│ │ ├── Makefile
│ │ ├── another_cosign.pub
│ │ ├── configs/
│ │ │ ├── dir1/
│ │ │ │ └── .grype.yaml
│ │ │ ├── dir2/
│ │ │ │ └── .grype.yaml
│ │ │ └── dir3/
│ │ │ └── .grype.yaml
│ │ ├── cosign.pub
│ │ ├── cosign_broken.pub
│ │ ├── empty.json
│ │ ├── image-bare/
│ │ │ ├── Dockerfile
│ │ │ └── file-1.txt
│ │ ├── image-java-subprocess/
│ │ │ ├── Dockerfile
│ │ │ └── app.java
│ │ ├── image-node-subprocess/
│ │ │ ├── Dockerfile
│ │ │ └── app.js
│ │ ├── sbom-grype-source.json
│ │ ├── sbom-ubuntu-20.04--pruned.json
│ │ └── test-ignore-reason/
│ │ ├── config-with-ignore.yaml
│ │ ├── sbom.json
│ │ └── template-with-ignore-reasons
│ ├── trait_assertions_test.go
│ ├── utils_test.go
│ └── version_cmd_test.go
├── grype-test-config.yaml
├── ignore-att-signature.yaml
├── install/
│ ├── .dockerignore
│ ├── .gitignore
│ ├── 0_checksums_test.sh
│ ├── 1_download_snapshot_asset_test.sh
│ ├── 2_download_release_asset_test.sh
│ ├── 3_install_asset_test.sh
│ ├── 4_prep_signature_verification_test.sh
│ ├── Makefile
│ ├── environments/
│ │ ├── Dockerfile-alpine-3.6
│ │ ├── Dockerfile-busybox-1.36
│ │ └── Dockerfile-ubuntu-20.04
│ ├── github_test.sh
│ ├── test_harness.sh
│ └── testdata/
│ ├── assets/
│ │ ├── invalid/
│ │ │ ├── .gitignore
│ │ │ └── checksums.txt
│ │ └── valid/
│ │ ├── .gitignore
│ │ └── checksums.txt
│ ├── github-api-grype-v0.32.0-release.json
│ ├── grype_0.32.0-SNAPSHOT-d461f63_checksums.txt
│ └── grype_0.32.0_checksums.txt
├── integration/
│ ├── compare_sbom_input_vs_lib_test.go
│ ├── db_mock_test.go
│ ├── match_by_image_test.go
│ ├── match_by_sbom_document_test.go
│ ├── testdata/
│ │ ├── .gitignore
│ │ ├── Makefile
│ │ ├── image-alpine-match-coverage/
│ │ │ ├── Dockerfile
│ │ │ ├── etc/
│ │ │ │ └── os-release
│ │ │ └── lib/
│ │ │ └── apk/
│ │ │ └── db/
│ │ │ └── installed
│ │ ├── image-arch-match-coverage/
│ │ │ └── Dockerfile
│ │ ├── image-centos-match-coverage/
│ │ │ ├── Dockerfile
│ │ │ ├── etc/
│ │ │ │ └── os-release
│ │ │ └── var/
│ │ │ └── lib/
│ │ │ └── rpm/
│ │ │ ├── Packages
│ │ │ └── generate-fixture.sh
│ │ ├── image-debian-match-coverage/
│ │ │ ├── Dockerfile
│ │ │ ├── dotnet/
│ │ │ │ └── TestLibrary.deps.json
│ │ │ ├── golang/
│ │ │ │ ├── go.mod
│ │ │ │ ├── go.sum
│ │ │ │ └── main.go
│ │ │ ├── haskell/
│ │ │ │ ├── cabal.project.freeze
│ │ │ │ └── stack.yaml
│ │ │ ├── java/
│ │ │ │ └── generate-fixtures.md
│ │ │ ├── javascript/
│ │ │ │ └── pkg-json/
│ │ │ │ └── package.json
│ │ │ ├── python/
│ │ │ │ └── dist-info/
│ │ │ │ ├── METADATA
│ │ │ │ └── top_level.txt
│ │ │ ├── ruby/
│ │ │ │ └── specifications/
│ │ │ │ └── bundler.gemspec
│ │ │ ├── usr/
│ │ │ │ └── lib/
│ │ │ │ └── os-release
│ │ │ └── var/
│ │ │ └── lib/
│ │ │ └── dpkg/
│ │ │ └── status
│ │ ├── image-jvm-match-coverage/
│ │ │ ├── Dockerfile
│ │ │ └── opt/
│ │ │ └── java/
│ │ │ └── openjdk/
│ │ │ └── release
│ │ ├── image-portage-match-coverage/
│ │ │ ├── Dockerfile
│ │ │ ├── etc/
│ │ │ │ └── os-release
│ │ │ └── var/
│ │ │ └── db/
│ │ │ ├── pkg/
│ │ │ │ └── app-containers/
│ │ │ │ └── skopeo-1.5.1/
│ │ │ │ ├── CONTENTS
│ │ │ │ ├── LICENSE
│ │ │ │ └── SIZE
│ │ │ └── repos/
│ │ │ └── gentoo/
│ │ │ └── skel.ebuild
│ │ ├── image-rust-auditable-match-coverage/
│ │ │ └── Dockerfile
│ │ ├── image-sles-match-coverage/
│ │ │ ├── Dockerfile
│ │ │ ├── etc/
│ │ │ │ └── os-release
│ │ │ └── var/
│ │ │ └── lib/
│ │ │ └── rpm/
│ │ │ ├── Packages
│ │ │ └── generate-fixture.sh
│ │ ├── sbom/
│ │ │ ├── syft-sbom-with-kb-packages.json
│ │ │ └── syft-sbom-with-unknown-packages.json
│ │ ├── skopeo-policy.json
│ │ ├── snapshot/
│ │ │ └── TestDatabaseDiff.golden
│ │ └── vex/
│ │ ├── csaf/
│ │ │ ├── affected.csaf.json
│ │ │ └── under_investigation.csaf.json
│ │ └── openvex/
│ │ ├── affected.openvex.json
│ │ └── under_investigation.openvex.json
│ └── utils_test.go
├── quality/
│ ├── .gitignore
│ ├── .grype.yaml
│ ├── .python-version
│ ├── .yardstick.yaml
│ ├── Makefile
│ ├── README.md
│ ├── requirements.txt
│ └── test-db
└── validate-grype-db-schema.py
Showing preview only (406K chars total). Download the full file or copy to clipboard to get everything.
SYMBOL INDEX (4164 symbols across 640 files)
FILE: .github/scripts/coverage.py
class bcolors (line 7) | class bcolors:
FILE: cmd/grype/cli/cli.go
function Application (line 27) | func Application(id clio.Identification) clio.Application {
function Command (line 32) | func Command(id clio.Identification) *cobra.Command {
function SetupConfig (line 37) | func SetupConfig(id clio.Identification) *clio.SetupConfig {
function create (line 97) | func create(id clio.Identification) (clio.Application, *cobra.Command) {
function syftVersion (line 116) | func syftVersion() (string, any) {
function dbVersion (line 133) | func dbVersion() (string, any) {
type environWithoutCI (line 137) | type environWithoutCI struct
method Environ (line 140) | func (e environWithoutCI) Environ() []string {
method Getenv (line 151) | func (e environWithoutCI) Getenv(s string) string {
FILE: cmd/grype/cli/cli_test.go
function Test_Command (line 11) | func Test_Command(t *testing.T) {
FILE: cmd/grype/cli/commands/completion.go
function Completion (line 17) | func Completion(app clio.Application) *cobra.Command {
function listLocalDockerImages (line 71) | func listLocalDockerImages(prefix string) ([]string, error) {
function dockerImageValidArgsFunction (line 98) | func dockerImageValidArgsFunction(_ *cobra.Command, _ []string, toComple...
FILE: cmd/grype/cli/commands/db.go
constant jsonOutputFormat (line 10) | jsonOutputFormat = "json"
constant tableOutputFormat (line 11) | tableOutputFormat = "table"
constant textOutputFormat (line 12) | textOutputFormat = "text"
function DB (line 15) | func DB(app clio.Application) *cobra.Command {
FILE: cmd/grype/cli/commands/db_check.go
type dbCheckOptions (line 19) | type dbCheckOptions struct
method AddFlags (line 26) | func (d *dbCheckOptions) AddFlags(flags clio.FlagSet) {
function DBCheck (line 30) | func DBCheck(app clio.Application) *cobra.Command {
function runDBCheck (line 59) | func runDBCheck(opts dbCheckOptions) error {
type dbCheckJSON (line 90) | type dbCheckJSON struct
function presentNewDBCheck (line 96) | func presentNewDBCheck(format string, writer io.Writer, updateAvailable ...
FILE: cmd/grype/cli/commands/db_check_test.go
function TestPresentNewDBCheck (line 17) | func TestPresentNewDBCheck(t *testing.T) {
function requireErrorContains (line 127) | func requireErrorContains(expected string) require.ErrorAssertionFunc {
FILE: cmd/grype/cli/commands/db_delete.go
function DBDelete (line 14) | func DBDelete(app clio.Application) *cobra.Command {
function runDBDelete (line 35) | func runDBDelete(opts options.DatabaseCommand) error {
FILE: cmd/grype/cli/commands/db_import.go
function DBImport (line 15) | func DBImport(app clio.Application) *cobra.Command {
function runDBImport (line 36) | func runDBImport(opts options.DatabaseCommand, reference string) error {
FILE: cmd/grype/cli/commands/db_list.go
type dbListOptions (line 17) | type dbListOptions struct
method AddFlags (line 24) | func (d *dbListOptions) AddFlags(flags clio.FlagSet) {
function DBList (line 28) | func DBList(app clio.Application) *cobra.Command {
function runDBList (line 53) | func runDBList(opts dbListOptions) error {
function presentDBList (line 72) | func presentDBList(format string, archiveURL, listingURL string, writer ...
FILE: cmd/grype/cli/commands/db_list_test.go
function Test_ListingUserAgent (line 21) | func Test_ListingUserAgent(t *testing.T) {
function TestPresentDBList (line 68) | func TestPresentDBList(t *testing.T) {
FILE: cmd/grype/cli/commands/db_providers.go
type dbProvidersOptions (line 20) | type dbProvidersOptions struct
method AddFlags (line 27) | func (d *dbProvidersOptions) AddFlags(flags clio.FlagSet) {
function DBProviders (line 31) | func DBProviders(app clio.Application) *cobra.Command {
function runDBProviders (line 55) | func runDBProviders(opts *dbProvidersOptions) error {
type provider (line 96) | type provider struct
function toProviders (line 104) | func toProviders(providers []v6.Provider) []provider {
function displayDBProvidersTable (line 118) | func displayDBProvidersTable(providers []provider, output io.Writer) err...
function displayDBProvidersJSON (line 132) | func displayDBProvidersJSON(providers []provider, output io.Writer) error {
FILE: cmd/grype/cli/commands/db_providers_test.go
function TestDisplayDBProvidersTable (line 11) | func TestDisplayDBProvidersTable(t *testing.T) {
function TestDisplayDBProvidersJSON (line 40) | func TestDisplayDBProvidersJSON(t *testing.T) {
function timeRef (line 83) | func timeRef(t time.Time) *time.Time {
FILE: cmd/grype/cli/commands/db_search.go
type dbSearchMatchOptions (line 24) | type dbSearchMatchOptions struct
method applyArgs (line 36) | func (o *dbSearchMatchOptions) applyArgs(args []string) error {
function hasAnyPrefix (line 66) | func hasAnyPrefix(s string, prefixes ...string) bool {
function DBSearch (line 75) | func DBSearch(app clio.Application) *cobra.Command {
function runDBSearchMatches (line 141) | func runDBSearchMatches(opts dbSearchMatchOptions) error {
function presentDBSearchMatches (line 189) | func presentDBSearchMatches(outputFormat string, structuredRows dbsearch...
function renderDBSearchPackagesTableRows (line 221) | func renderDBSearchPackagesTableRows(structuredRows []dbsearch.AffectedP...
function mimicV5Namespace (line 254) | func mimicV5Namespace(row dbsearch.AffectedPackage) string {
FILE: cmd/grype/cli/commands/db_search_test.go
function TestDBSearchMatchOptionsApplyArgs (line 15) | func TestDBSearchMatchOptionsApplyArgs(t *testing.T) {
function TestMimicV5Namespace (line 109) | func TestMimicV5Namespace(t *testing.T) {
FILE: cmd/grype/cli/commands/db_search_vuln.go
type dbSearchVulnerabilityOptions (line 24) | type dbSearchVulnerabilityOptions struct
function DBSearchVulnerabilities (line 32) | func DBSearchVulnerabilities(app clio.Application) *cobra.Command {
function runDBSearchVulnerabilities (line 67) | func runDBSearchVulnerabilities(opts dbSearchVulnerabilityOptions) error {
function validateProvidersFilter (line 105) | func validateProvidersFilter(reader v6.Reader, providers []string) error {
function presentDBSearchVulnerabilities (line 131) | func presentDBSearchVulnerabilities(outputFormat string, structuredRows ...
function renderDBSearchVulnerabilitiesTableRows (line 164) | func renderDBSearchVulnerabilitiesTableRows(structuredRows []dbsearch.Vu...
function getOSVersions (line 208) | func getOSVersions(oss []dbsearch.OperatingSystem) []string {
function getPrimaryReference (line 216) | func getPrimaryReference(refs []v6.Reference) string {
function getDate (line 224) | func getDate(t *time.Time) string {
FILE: cmd/grype/cli/commands/db_search_vuln_test.go
function TestGetOSVersions (line 13) | func TestGetOSVersions(t *testing.T) {
function TestGetPrimaryReference (line 62) | func TestGetPrimaryReference(t *testing.T) {
function TestGetDate (line 107) | func TestGetDate(t *testing.T) {
function timePtr (line 138) | func timePtr(t time.Time) *time.Time {
FILE: cmd/grype/cli/commands/db_status.go
type dbStatusOptions (line 19) | type dbStatusOptions struct
method AddFlags (line 26) | func (d *dbStatusOptions) AddFlags(flags clio.FlagSet) {
function DBStatus (line 30) | func DBStatus(app clio.Application) *cobra.Command {
function runDBStatus (line 55) | func runDBStatus(opts dbStatusOptions) error {
function presentDBStatus (line 74) | func presentDBStatus(format string, writer io.Writer, status vulnerabili...
function renderStoreValidation (line 98) | func renderStoreValidation(status vulnerability.ProviderStatus) string {
FILE: cmd/grype/cli/commands/db_status_test.go
function TestPresentDBStatus (line 16) | func TestPresentDBStatus(t *testing.T) {
FILE: cmd/grype/cli/commands/db_update.go
function DBUpdate (line 16) | func DBUpdate(app clio.Application) *cobra.Command {
function runDBUpdate (line 41) | func runDBUpdate(opts options.DatabaseCommand) error {
FILE: cmd/grype/cli/commands/explain.go
type explainOptions (line 17) | type explainOptions struct
method AddFlags (line 23) | func (d *explainOptions) AddFlags(flags clio.FlagSet) {
function Explain (line 27) | func Explain(app clio.Application) *cobra.Command {
FILE: cmd/grype/cli/commands/internal/dbsearch/affected_packages.go
type AffectedPackage (line 15) | type AffectedPackage struct
type AffectedPackageInfo (line 23) | type AffectedPackageInfo struct
type Package (line 46) | type Package struct
type CPE (line 55) | type CPE
method MarshalJSON (line 57) | func (c *CPE) MarshalJSON() ([]byte, error) {
method String (line 61) | func (c *CPE) String() string {
type AffectedPackagesOptions (line 69) | type AffectedPackagesOptions struct
type affectedPackageWithDecorations (line 79) | type affectedPackageWithDecorations struct
method getCVEs (line 84) | func (a *affectedPackageWithDecorations) getCVEs() []string {
type affectedCPEWithDecorations (line 91) | type affectedCPEWithDecorations struct
method getCVEs (line 96) | func (a *affectedCPEWithDecorations) getCVEs() []string {
function newAffectedPackageRows (line 103) | func newAffectedPackageRows(affectedPkgs []affectedPackageWithDecoration...
function toPackage (line 157) | func toPackage(pkg *v6.Package) *Package {
function toOS (line 167) | func toOS(os *v6.OperatingSystem) *OperatingSystem {
function FindAffectedPackages (line 178) | func FindAffectedPackages(reader interface {
function findAffectedPackages (line 197) | func findAffectedPackages(reader interface { //nolint:funlen,gocognit
FILE: cmd/grype/cli/commands/internal/dbsearch/affected_packages_test.go
function TestAffectedPackageTableRowMarshalJSON (line 18) | func TestAffectedPackageTableRowMarshalJSON(t *testing.T) {
function TestNewAffectedPackageRows (line 157) | func TestNewAffectedPackageRows(t *testing.T) {
function TestAffectedPackages (line 419) | func TestAffectedPackages(t *testing.T) {
function TestFindAffectedPackages (line 653) | func TestFindAffectedPackages(t *testing.T) {
type affectedMockReader (line 874) | type affectedMockReader struct
method GetAffectedPackages (line 878) | func (m *affectedMockReader) GetAffectedPackages(pkgSpec *v6.PackageSp...
method GetAffectedCPEs (line 883) | func (m *affectedMockReader) GetAffectedCPEs(cpeSpec *cpe.Attributes, ...
method GetKnownExploitedVulnerabilities (line 888) | func (m *affectedMockReader) GetKnownExploitedVulnerabilities(cve stri...
method GetEpss (line 893) | func (m *affectedMockReader) GetEpss(cve string) ([]v6.EpssHandle, err...
method GetCWEs (line 898) | func (m *affectedMockReader) GetCWEs(cve string) ([]v6.CWEHandle, erro...
function ptr (line 903) | func ptr[T any](t T) *T {
function TestGetFixStateFromPackageBlob (line 907) | func TestGetFixStateFromPackageBlob(t *testing.T) {
function TestFilterByFixedStateForPackages (line 1003) | func TestFilterByFixedStateForPackages(t *testing.T) {
function TestFilterByFixedStateForCPEs (line 1065) | func TestFilterByFixedStateForCPEs(t *testing.T) {
function makeAffectedPackageWithFixState (line 1119) | func makeAffectedPackageWithFixState(state v6.FixStatus) affectedPackage...
function makeAffectedCPEWithFixState (line 1136) | func makeAffectedCPEWithFixState(state v6.FixStatus) affectedCPEWithDeco...
FILE: cmd/grype/cli/commands/internal/dbsearch/common.go
constant fixStateFixed (line 6) | fixStateFixed = "fixed"
constant fixStateNotFixed (line 7) | fixStateNotFixed = "not-fixed"
constant fixStateWontFix (line 8) | fixStateWontFix = "wont-fix"
constant fixStateUnknown (line 9) | fixStateUnknown = "unknown"
function getFixStateFromPackageBlob (line 16) | func getFixStateFromPackageBlob(blob *v6.PackageBlob) string {
function filterByFixedStateForPackages (line 52) | func filterByFixedStateForPackages(packages []affectedPackageWithDecorat...
function filterByFixedStateForCPEs (line 77) | func filterByFixedStateForCPEs(cpes []affectedCPEWithDecorations, fixedS...
FILE: cmd/grype/cli/commands/internal/dbsearch/matches.go
type Matches (line 14) | type Matches
method Flatten (line 36) | func (m Matches) Flatten() []AffectedPackage {
type Match (line 17) | type Match struct
method Flatten (line 25) | func (m Match) Flatten() []AffectedPackage {
function newMatchesRows (line 44) | func newMatchesRows(affectedPkgs []affectedPackageWithDecorations, affec...
function FindMatches (line 120) | func FindMatches(reader interface {
FILE: cmd/grype/cli/commands/internal/dbsearch/matches_test.go
function TestGetFixStateFromBlob (line 11) | func TestGetFixStateFromBlob(t *testing.T) {
function TestFilterByFixedState (line 125) | func TestFilterByFixedState(t *testing.T) {
function TestFilterCPEsByFixedState (line 200) | func TestFilterCPEsByFixedState(t *testing.T) {
function makeTestPackages (line 265) | func makeTestPackages(count int) []affectedPackageWithDecorations {
function makePackageWithFixState (line 277) | func makePackageWithFixState(state v6.FixStatus) affectedPackageWithDeco...
function makeTestCPEs (line 294) | func makeTestCPEs(count int) []affectedCPEWithDecorations {
function makeCPEWithFixState (line 306) | func makeCPEWithFixState(state v6.FixStatus) affectedCPEWithDecorations {
FILE: cmd/grype/cli/commands/internal/dbsearch/versions.go
constant MatchesSchemaVersion (line 5) | MatchesSchemaVersion = "1.1.3"
constant VulnerabilitiesSchemaVersion (line 18) | VulnerabilitiesSchemaVersion = "1.0.5"
FILE: cmd/grype/cli/commands/internal/dbsearch/vulnerabilities.go
type Vulnerabilities (line 16) | type Vulnerabilities
type Vulnerability (line 19) | type Vulnerability struct
type VulnerabilityInfo (line 29) | type VulnerabilityInfo struct
type OperatingSystem (line 66) | type OperatingSystem struct
type KnownExploited (line 74) | type KnownExploited struct
type EPSS (line 87) | type EPSS struct
type CWE (line 94) | type CWE struct
type CVSSSeverity (line 101) | type CVSSSeverity struct
type CvssMetrics (line 112) | type CvssMetrics struct
type vulnerabilityAffectedPackageJoin (line 118) | type vulnerabilityAffectedPackageJoin struct
type VulnerabilitiesOptions (line 125) | type VulnerabilitiesOptions struct
function newVulnerabilityRows (line 130) | func newVulnerabilityRows(vaps ...vulnerabilityAffectedPackageJoin) (row...
function newVulnerabilityInfo (line 141) | func newVulnerabilityInfo(vuln v6.VulnerabilityHandle, vc vulnerabilityD...
function patchCVSSMetrics (line 161) | func patchCVSSMetrics(blob *v6.VulnerabilityBlob) {
function newOperatingSystems (line 184) | func newOperatingSystems(oss []v6.OperatingSystem) (os []OperatingSystem) {
function FindVulnerabilities (line 194) | func FindVulnerabilities(reader interface { //nolint:funlen
function getSeverity (line 286) | func getSeverity(sevs []v6.Severity) string {
FILE: cmd/grype/cli/commands/internal/dbsearch/vulnerabilities_test.go
function TestGetSeverity (line 17) | func TestGetSeverity(t *testing.T) {
function TestNewVulnerabilityRows (line 104) | func TestNewVulnerabilityRows(t *testing.T) {
function TestVulnerabilities (line 224) | func TestVulnerabilities(t *testing.T) {
function TestFindVulnerabilities_DecorationErrors (line 354) | func TestFindVulnerabilities_DecorationErrors(t *testing.T) {
type mockVulnReader (line 414) | type mockVulnReader struct
method GetVulnerabilities (line 418) | func (m *mockVulnReader) GetVulnerabilities(vuln *v6.VulnerabilitySpec...
method GetAffectedPackages (line 423) | func (m *mockVulnReader) GetAffectedPackages(pkg *v6.PackageSpecifier,...
method GetKnownExploitedVulnerabilities (line 428) | func (m *mockVulnReader) GetKnownExploitedVulnerabilities(cve string) ...
method GetEpss (line 433) | func (m *mockVulnReader) GetEpss(cve string) ([]v6.EpssHandle, error) {
method GetCWEs (line 438) | func (m *mockVulnReader) GetCWEs(cve string) ([]v6.CWEHandle, error) {
function cmpOpts (line 443) | func cmpOpts() []cmp.Option {
FILE: cmd/grype/cli/commands/internal/dbsearch/vulnerability_decorations.go
type canonicalVulnerability (line 14) | type canonicalVulnerability interface
type vulnerabilityDecorations (line 23) | type vulnerabilityDecorations struct
method decorate (line 89) | func (vd *vulnerabilityDecorations) decorate(kevs []KnownExploited, ep...
function decorateVulnerabilities (line 28) | func decorateVulnerabilities(reader v6.VulnerabilityDecoratorStoreReader...
method getCVEs (line 49) | func (afj *vulnerabilityAffectedPackageJoin) getCVEs() []string {
function getCVEs (line 56) | func getCVEs(v *v6.VulnerabilityHandle) []string {
function fetchKnownExploited (line 98) | func fetchKnownExploited(reader v6.VulnerabilityDecoratorStoreReader, cv...
function fetchEpss (line 125) | func fetchEpss(reader v6.VulnerabilityDecoratorStoreReader, cves []strin...
FILE: cmd/grype/cli/commands/internal/jsonschema/main.go
function main (line 21) | func main() {
function compose (line 31) | func compose(document any, component, version string, comments map[strin...
function write (line 35) | func write(schema []byte, component, version string) {
function encode (line 88) | func encode(schema *jsonschema.Schema) []byte {
function build (line 102) | func build(document any, component, version string, comments map[string]...
function parseCommentsFromPackages (line 148) | func parseCommentsFromPackages(pkgPatterns []string) map[string]map[stri...
function parseFileComments (line 173) | func parseFileComments(node *ast.File) map[string]map[string]string {
function cleanComment (line 227) | func cleanComment(comment string) string {
function getJSONTag (line 237) | func getJSONTag(field *ast.Field) string {
function schemaID (line 249) | func schemaID(component, version string) jsonschema.ID {
function repoRoot (line 253) | func repoRoot() string {
FILE: cmd/grype/cli/commands/root.go
function Root (line 49) | func Root(app clio.Application) *cobra.Command {
function runGrype (line 119) | func runGrype(ctx context.Context, app clio.Application, opts *options.G...
function warnWhenDistroHintNeeded (line 278) | func warnWhenDistroHintNeeded(pkgs []pkg.Package, context *pkg.Context) {
function warnDistroAlerts (line 296) | func warnDistroAlerts(data *models.DistroAlertData) {
function countPackagesByDistro (line 308) | func countPackagesByDistro(packages []pkg.Package) map[string]int {
function dbInfo (line 320) | func dbInfo(status *vulnerability.ProviderStatus, vp vulnerability.Provi...
function checkForAppUpdate (line 343) | func checkForAppUpdate(id clio.Identification, opts *options.Grype) {
function getMatcherConfig (line 367) | func getMatcherConfig(opts *options.Grype) matcher.Config {
function getMatchers (line 395) | func getMatchers(opts *options.Grype) []match.Matcher {
function getProviderConfig (line 399) | func getProviderConfig(opts *options.Grype) pkg.ProviderConfig {
function getFixChannels (line 429) | func getFixChannels(fixChannelOpts options.FixChannels) distro.FixChanne...
function applyDistroHint (line 455) | func applyDistroHint(hint string) *distro.Distro {
function validateDBLoad (line 464) | func validateDBLoad(loadErr error, status *vulnerability.ProviderStatus)...
function validateRootArgs (line 484) | func validateRootArgs(cmd *cobra.Command, args []string) error {
function applyVexRules (line 510) | func applyVexRules(opts *options.Grype) error {
FILE: cmd/grype/cli/commands/root_test.go
function Test_getProviderConfig (line 35) | func Test_getProviderConfig(t *testing.T) {
function Test_getMatcherConfig (line 88) | func Test_getMatcherConfig(t *testing.T) {
function Test_applyVexRules (line 208) | func Test_applyVexRules(t *testing.T) {
FILE: cmd/grype/cli/commands/update.go
function isProductionBuild (line 22) | func isProductionBuild(version string) bool {
function isUpdateAvailable (line 29) | func isUpdateAvailable(id clio.Identification) (bool, string, error) {
function fetchLatestApplicationVersion (line 51) | func fetchLatestApplicationVersion(id clio.Identification) (*hashiVersio...
FILE: cmd/grype/cli/commands/update_test.go
function TestIsUpdateAvailable (line 13) | func TestIsUpdateAvailable(t *testing.T) {
function TestFetchLatestApplicationVersion (line 131) | func TestFetchLatestApplicationVersion(t *testing.T) {
function Test_UserAgent (line 213) | func Test_UserAgent(t *testing.T) {
FILE: cmd/grype/cli/commands/util.go
function disableUI (line 21) | func disableUI(app clio.Application) func(*cobra.Command, []string) error {
function stderrPrintLnf (line 34) | func stderrPrintLnf(message string, args ...interface{}) error {
function parallel (line 45) | func parallel(funcs ...func() error) error {
function parallelMapped (line 59) | func parallelMapped(funcs ...func() error) map[int]error {
function appendErrors (line 79) | func appendErrors(errs error, err ...error) error {
function newTable (line 91) | func newTable(output io.Writer, columns []string) *tablewriter.Table {
FILE: cmd/grype/cli/commands/util_test.go
constant lotsaParallel (line 13) | lotsaParallel = 100
function Test_lotsaLotsaParallel (line 15) | func Test_lotsaLotsaParallel(t *testing.T) {
function Test_lotsaParallel (line 27) | func Test_lotsaParallel(t *testing.T) {
function Test_parallel (line 35) | func Test_parallel(t *testing.T) {
function Test_parallelMapped (line 95) | func Test_parallelMapped(t *testing.T) {
FILE: cmd/grype/cli/options/alerts.go
type Alerts (line 6) | type Alerts struct
method DescribeFields (line 19) | func (a *Alerts) DescribeFields(descriptions clio.FieldDescriptionSet) {
function defaultAlerts (line 13) | func defaultAlerts() Alerts {
FILE: cmd/grype/cli/options/alerts_test.go
function TestDefaultAlerts (line 9) | func TestDefaultAlerts(t *testing.T) {
FILE: cmd/grype/cli/options/database.go
type Database (line 12) | type Database struct
method DescribeFields (line 52) | func (cfg *Database) DescribeFields(descriptions clio.FieldDescription...
method PostLoad (line 70) | func (cfg *Database) PostLoad() error {
function DefaultDatabase (line 32) | func DefaultDatabase(id clio.Identification) Database {
FILE: cmd/grype/cli/options/database_command.go
type DatabaseCommand (line 9) | type DatabaseCommand struct
method ToCuratorConfig (line 26) | func (cfg DatabaseCommand) ToCuratorConfig() installation.Config {
method ToClientConfig (line 37) | func (cfg DatabaseCommand) ToClientConfig() distribution.Config {
function DefaultDatabaseCommand (line 15) | func DefaultDatabaseCommand(id clio.Identification) *DatabaseCommand {
FILE: cmd/grype/cli/options/database_search_bounds.go
type DBSearchBounds (line 9) | type DBSearchBounds struct
method AddFlags (line 19) | func (o *DBSearchBounds) AddFlags(flags clio.FlagSet) {
method PostLoad (line 23) | func (o *DBSearchBounds) PostLoad() error {
function DefaultDBSearchBounds (line 13) | func DefaultDBSearchBounds() DBSearchBounds {
FILE: cmd/grype/cli/options/database_search_format.go
type DBSearchFormat (line 12) | type DBSearchFormat struct
method AddFlags (line 24) | func (c *DBSearchFormat) AddFlags(flags clio.FlagSet) {
method PostLoad (line 29) | func (c *DBSearchFormat) PostLoad() error {
function DefaultDBSearchFormat (line 17) | func DefaultDBSearchFormat() DBSearchFormat {
FILE: cmd/grype/cli/options/database_search_os.go
type DBSearchOSs (line 13) | type DBSearchOSs struct
method AddFlags (line 18) | func (o *DBSearchOSs) AddFlags(flags clio.FlagSet) {
method PostLoad (line 23) | func (o *DBSearchOSs) PostLoad() error {
function parseOSString (line 42) | func parseOSString(osValue string) (*v6.OSSpecifier, error) {
FILE: cmd/grype/cli/options/database_search_os_test.go
function TestDBSearchOSsPostLoad (line 12) | func TestDBSearchOSsPostLoad(t *testing.T) {
FILE: cmd/grype/cli/options/database_search_packages.go
type DBSearchPackages (line 15) | type DBSearchPackages struct
method AddFlags (line 23) | func (o *DBSearchPackages) AddFlags(flags clio.FlagSet) {
method PostLoad (line 29) | func (o *DBSearchPackages) PostLoad() error {
FILE: cmd/grype/cli/options/database_search_packages_test.go
function TestDBSearchPackagesPostLoad (line 13) | func TestDBSearchPackagesPostLoad(t *testing.T) {
FILE: cmd/grype/cli/options/database_search_vulnerabilities.go
type DBSearchVulnerabilities (line 13) | type DBSearchVulnerabilities struct
method AddFlags (line 26) | func (c *DBSearchVulnerabilities) AddFlags(flags clio.FlagSet) {
method PostLoad (line 36) | func (c *DBSearchVulnerabilities) PostLoad() error {
FILE: cmd/grype/cli/options/database_search_vulnerabilities_test.go
function TestDBSearchVulnerabilitiesPostLoad (line 13) | func TestDBSearchVulnerabilitiesPostLoad(t *testing.T) {
function parseTime (line 145) | func parseTime(value string) *time.Time {
FILE: cmd/grype/cli/options/datasources.go
constant defaultMavenBaseURL (line 11) | defaultMavenBaseURL = "https://search.maven.org/solrsearch/select"
type externalSources (line 14) | type externalSources struct
method ToJavaMatcherConfig (line 39) | func (cfg externalSources) ToJavaMatcherConfig() java.ExternalSearchCo...
method DescribeFields (line 52) | func (cfg *externalSources) DescribeFields(descriptions clio.FieldDesc...
type maven (line 23) | type maven struct
function defaultExternalSources (line 29) | func defaultExternalSources() externalSources {
FILE: cmd/grype/cli/options/experimental.go
type Experimental (line 9) | type Experimental struct
FILE: cmd/grype/cli/options/fix_channels.go
type FixChannelEnabled (line 11) | type FixChannelEnabled
type FixChannels (line 13) | type FixChannels struct
method DescribeFields (line 57) | func (o *FixChannels) DescribeFields(descriptions clio.FieldDescriptio...
type FixChannel (line 20) | type FixChannel struct
method PostLoad (line 28) | func (o *FixChannel) PostLoad() error {
function DefaultFixChannels (line 41) | func DefaultFixChannels() FixChannels {
FILE: cmd/grype/cli/options/grype.go
type Grype (line 14) | type Grype struct
method AddFlags (line 81) | func (o *Grype) AddFlags(flags clio.FlagSet) {
method PostLoad (line 167) | func (o *Grype) PostLoad() error {
method DescribeFields (line 179) | func (o *Grype) DescribeFields(descriptions clio.FieldDescriptionSet) {
method FailOnSeverity (line 217) | func (o Grype) FailOnSeverity() *vulnerability.Severity {
type developer (line 48) | type developer struct
type databaseDeveloper (line 52) | type databaseDeveloper struct
function DefaultGrype (line 62) | func DefaultGrype(id clio.Identification) *Grype {
function flatten (line 223) | func flatten(commaSeparatedEntries []string) []string {
FILE: cmd/grype/cli/options/grype_test.go
function Test_flatten (line 9) | func Test_flatten(t *testing.T) {
FILE: cmd/grype/cli/options/match.go
type matchConfig (line 11) | type matchConfig struct
method PostLoad (line 136) | func (cfg *matchConfig) PostLoad() error {
method DescribeFields (line 164) | func (cfg *matchConfig) DescribeFields(descriptions clio.FieldDescript...
type matcherConfig (line 31) | type matcherConfig struct
type golangConfig (line 35) | type golangConfig struct
type dpkgConfig (line 42) | type dpkgConfig struct
method PostLoad (line 156) | func (cfg *dpkgConfig) PostLoad() error {
type rpmConfig (line 67) | type rpmConfig struct
method PostLoad (line 147) | func (cfg *rpmConfig) PostLoad() error {
function defaultGolangConfig (line 91) | func defaultGolangConfig() golangConfig {
function defaultRpmConfig (line 101) | func defaultRpmConfig() rpmConfig {
function defaultDpkgConfig (line 109) | func defaultDpkgConfig() dpkgConfig {
function defaultMatchConfig (line 117) | func defaultMatchConfig() matchConfig {
FILE: cmd/grype/cli/options/match_test.go
function TestRpmConfig_PostLoad (line 12) | func TestRpmConfig_PostLoad(t *testing.T) {
function TestDpkgConfig_PostLoad (line 68) | func TestDpkgConfig_PostLoad(t *testing.T) {
function TestMatchConfig_PostLoad (line 119) | func TestMatchConfig_PostLoad(t *testing.T) {
function TestDefaultRpmConfig (line 177) | func TestDefaultRpmConfig(t *testing.T) {
function TestDefaultDpkgConfig (line 187) | func TestDefaultDpkgConfig(t *testing.T) {
function TestDefaultMatchConfig (line 197) | func TestDefaultMatchConfig(t *testing.T) {
FILE: cmd/grype/cli/options/registry.go
type RegistryCredentials (line 10) | type RegistryCredentials struct
type registry (line 21) | type registry struct
method PostLoad (line 33) | func (cfg *registry) PostLoad() error {
method DescribeFields (line 59) | func (cfg *registry) DescribeFields(descriptions clio.FieldDescription...
method ToOptions (line 80) | func (cfg *registry) ToOptions() *image.RegistryOptions {
function hasNonEmptyCredentials (line 73) | func hasNonEmptyCredentials(username, password, token, tlsCert, tlsKey s...
FILE: cmd/grype/cli/options/registry_test.go
function TestHasNonEmptyCredentials (line 12) | func TestHasNonEmptyCredentials(t *testing.T) {
function Test_registry_ToOptions (line 72) | func Test_registry_ToOptions(t *testing.T) {
FILE: cmd/grype/cli/options/search.go
type search (line 11) | type search struct
method PostLoad (line 31) | func (cfg *search) PostLoad() error {
method DescribeFields (line 39) | func (cfg *search) DescribeFields(descriptions clio.FieldDescriptionSe...
method GetScope (line 47) | func (cfg search) GetScope() source.Scope {
function defaultSearch (line 22) | func defaultSearch(scope source.Scope) search {
FILE: cmd/grype/cli/options/secret.go
type secret (line 10) | type secret
method PostLoad (line 18) | func (r *secret) PostLoad() error {
method String (line 23) | func (r secret) String() string {
method MarshalText (line 31) | func (r secret) MarshalText() ([]byte, error) {
FILE: cmd/grype/cli/options/sort_by.go
type SortBy (line 19) | type SortBy struct
method AddFlags (line 35) | func (o *SortBy) AddFlags(flags clio.FlagSet) {
method PostLoad (line 42) | func (o *SortBy) PostLoad() error {
function defaultSortBy (line 24) | func defaultSortBy() SortBy {
FILE: cmd/grype/cli/ui/handle_database_diff_started.go
type dbDiffProgressStager (line 16) | type dbDiffProgressStager struct
method Stage (line 20) | func (p dbDiffProgressStager) Stage() string {
method Current (line 27) | func (p dbDiffProgressStager) Current() int64 {
method Error (line 31) | func (p dbDiffProgressStager) Error() error {
method Size (line 35) | func (p dbDiffProgressStager) Size() int64 {
method handleDatabaseDiffStarted (line 39) | func (m *Handler) handleDatabaseDiffStarted(e partybus.Event) ([]tea.Mod...
FILE: cmd/grype/cli/ui/handle_database_diff_started_test.go
function TestHandler_handleDatabaseDiffStarted (line 18) | func TestHandler_handleDatabaseDiffStarted(t *testing.T) {
FILE: cmd/grype/cli/ui/handle_update_vulnerability_database.go
type dbDownloadProgressStager (line 16) | type dbDownloadProgressStager struct
method Stage (line 20) | func (s dbDownloadProgressStager) Stage() string {
method handleUpdateVulnerabilityDatabase (line 38) | func (m *Handler) handleUpdateVulnerabilityDatabase(e partybus.Event) ([...
function safeConvertInt64ToUint64 (line 58) | func safeConvertInt64ToUint64(i int64) uint64 {
FILE: cmd/grype/cli/ui/handle_update_vulnerability_database_test.go
function TestHandler_handleUpdateVulnerabilityDatabase (line 17) | func TestHandler_handleUpdateVulnerabilityDatabase(t *testing.T) {
FILE: cmd/grype/cli/ui/handle_vulnerability_scanning_started.go
constant branch (line 22) | branch = "├──"
constant end (line 23) | end = "└──"
type vulnerabilityProgressTree (line 28) | type vulnerabilityProgressTree struct
method Init (line 112) | func (l vulnerabilityProgressTree) Init() tea.Cmd {
method Update (line 129) | func (l vulnerabilityProgressTree) Update(msg tea.Msg) (tea.Model, tea...
method View (line 155) | func (l vulnerabilityProgressTree) View() string {
method queueNextTick (line 193) | func (l vulnerabilityProgressTree) queueNextTick() tea.Cmd {
method handleTick (line 203) | func (l *vulnerabilityProgressTree) handleTick(msg vulnerabilityProgre...
function newVulnerabilityProgressTree (line 47) | func newVulnerabilityProgressTree(monitor *monitor.Matching, textStyle l...
type vulnerabilityProgressTreeTickMsg (line 60) | type vulnerabilityProgressTreeTickMsg struct
type vulnerabilityScanningAdapter (line 66) | type vulnerabilityScanningAdapter struct
method Current (line 70) | func (p vulnerabilityScanningAdapter) Current() int64 {
method Error (line 74) | func (p vulnerabilityScanningAdapter) Error() error {
method Size (line 78) | func (p vulnerabilityScanningAdapter) Size() int64 {
method Stage (line 82) | func (p vulnerabilityScanningAdapter) Stage() string {
method handleVulnerabilityScanningStarted (line 86) | func (m *Handler) handleVulnerabilityScanningStarted(e partybus.Event) (...
FILE: cmd/grype/cli/ui/handle_vulnerability_scanning_started_test.go
function TestHandler_handleVulnerabilityScanningStarted (line 20) | func TestHandler_handleVulnerabilityScanningStarted(t *testing.T) {
function getVulnerabilityMonitor (line 86) | func getVulnerabilityMonitor(completed bool) monitor.Matching {
FILE: cmd/grype/cli/ui/handler.go
type HandlerConfig (line 20) | type HandlerConfig struct
type Handler (line 25) | type Handler struct
method OnMessage (line 58) | func (m *Handler) OnMessage(msg tea.Msg) {
method Wait (line 64) | func (m *Handler) Wait() {
function DefaultHandlerConfig (line 33) | func DefaultHandlerConfig() HandlerConfig {
function New (line 39) | func New(cfg HandlerConfig) *Handler {
FILE: cmd/grype/cli/ui/new_task_progress.go
method newTaskProgress (line 5) | func (m Handler) newTaskProgress(title taskprogress.Title, opts ...taskp...
FILE: cmd/grype/cli/ui/util_test.go
function runModel (line 12) | func runModel(t testing.TB, m tea.Model, iterations int, message tea.Msg...
function flatten (line 42) | func flatten(p tea.Msg) (msgs []tea.Msg) {
function extractBatchMessages (line 54) | func extractBatchMessages(m tea.Msg) (ret []tea.Msg) {
FILE: cmd/grype/internal/constants.go
constant NotProvided (line 4) | NotProvided = "[not provided]"
FILE: cmd/grype/internal/ui/no_ui.go
type NoUI (line 14) | type NoUI struct
method Setup (line 26) | func (n *NoUI) Setup(subscription partybus.Unsubscribable) error {
method Handle (line 31) | func (n *NoUI) Handle(e partybus.Event) error {
method Teardown (line 40) | func (n NoUI) Teardown(_ bool) error {
function None (line 20) | func None(quiet bool) *NoUI {
FILE: cmd/grype/internal/ui/post_ui_event_writer.go
type postUIEventWriter (line 17) | type postUIEventWriter struct
method write (line 55) | func (w postUIEventWriter) write(quiet bool, events ...partybus.Event)...
type postUIHandle (line 21) | type postUIHandle struct
type eventWriter (line 28) | type eventWriter
function newPostUIEventWriter (line 30) | func newPostUIEventWriter(stdout, stderr io.Writer) *postUIEventWriter {
function writeReports (line 75) | func writeReports(writer io.Writer, events ...partybus.Event) error {
function writeNotifications (line 97) | func writeNotifications(writer io.Writer, events ...partybus.Event) error {
function writeAppUpdate (line 116) | func writeAppUpdate(writer io.Writer, events ...partybus.Event) error {
FILE: cmd/grype/internal/ui/post_ui_event_writer_test.go
function Test_postUIEventWriter_write (line 15) | func Test_postUIEventWriter_write(t *testing.T) {
FILE: cmd/grype/internal/ui/ui.go
type UI (line 27) | type UI struct
method Setup (line 47) | func (m *UI) Setup(subscription partybus.Unsubscribable) error {
method Handle (line 68) | func (m *UI) Handle(e partybus.Event) error {
method Teardown (line 75) | func (m *UI) Teardown(force bool) error {
method Init (line 115) | func (m UI) Init() tea.Cmd {
method RespondsTo (line 119) | func (m UI) RespondsTo() []partybus.EventType {
method Update (line 127) | func (m *UI) Update(msg tea.Msg) (tea.Model, tea.Cmd) {
method View (line 182) | func (m UI) View() string {
function New (line 38) | func New(quiet bool, handlers ...bubbly.EventHandler) *UI {
function runWithTimeout (line 186) | func runWithTimeout(timeout time.Duration, fn func() error) (err error) {
FILE: cmd/grype/main.go
constant applicationName (line 12) | applicationName = "grype"
function main (line 22) | func main() {
FILE: grype/cpe/cpe.go
function NewSlice (line 10) | func NewSlice(cpeStrs ...string) ([]cpe.CPE, error) {
function MatchWithoutVersion (line 24) | func MatchWithoutVersion(c cpe.CPE, candidates []cpe.CPE) []cpe.CPE {
FILE: grype/cpe/cpe_test.go
function TestMatchWithoutVersion (line 11) | func TestMatchWithoutVersion(t *testing.T) {
FILE: grype/db/build.go
constant DefaultBatchSize (line 25) | DefaultBatchSize = 2000
type BuildConfig (line 27) | type BuildConfig struct
function Build (line 39) | func Build(cfg BuildConfig) error {
type providerResults (line 86) | type providerResults struct
function getProcessors (line 92) | func getProcessors(cfg BuildConfig) ([]data.Processor, error) {
function getWriter (line 103) | func getWriter(cfg BuildConfig) (data.Writer, error) {
function build (line 120) | func build(results []providerResults, writer data.Writer, processors ......
function hydrate (line 204) | func hydrate(cfg BuildConfig) error {
function logDropped (line 222) | func logDropped(droppedElementsByProvider, droppedSchemaElements map[str...
type expMovingAverage (line 242) | type expMovingAverage struct
method Add (line 252) | func (e *expMovingAverage) Add(sample float64) {
method Average (line 261) | func (e *expMovingAverage) Average() float64 {
function newEMA (line 248) | func newEMA(alpha float64) *expMovingAverage {
function recordsPerSecond (line 265) | func recordsPerSecond(idx int, lastUpdate time.Time) float64 {
function percent (line 273) | func percent(idx, total int) float64 {
function eta (line 280) | func eta(idx, total int, rate float64) time.Duration {
FILE: grype/db/data/entry.go
type Entry (line 4) | type Entry struct
FILE: grype/db/data/processor.go
type Processor (line 11) | type Processor interface
FILE: grype/db/data/severity.go
type Severity (line 5) | type Severity
constant SeverityUnknown (line 8) | SeverityUnknown Severity = "Unknown"
constant SeverityNegligible (line 9) | SeverityNegligible Severity = "Negligible"
constant SeverityLow (line 10) | SeverityLow Severity = "Low"
constant SeverityMedium (line 11) | SeverityMedium Severity = "Medium"
constant SeverityHigh (line 12) | SeverityHigh Severity = "High"
constant SeverityCritical (line 13) | SeverityCritical Severity = "Critical"
function ParseSeverity (line 16) | func ParseSeverity(s string) Severity {
FILE: grype/db/data/severity_test.go
function TestParseSeverity (line 9) | func TestParseSeverity(t *testing.T) {
FILE: grype/db/data/transformers.go
type GitHubTransformer (line 14) | type GitHubTransformer
type MSRCTransformer (line 15) | type MSRCTransformer
type NVDTransformer (line 16) | type NVDTransformer
type OSTransformer (line 17) | type OSTransformer
type MatchExclusionTransformer (line 18) | type MatchExclusionTransformer
type GitHubTransformerV2 (line 22) | type GitHubTransformerV2
type MSRCTransformerV2 (line 23) | type MSRCTransformerV2
type NVDTransformerV2 (line 24) | type NVDTransformerV2
type OSTransformerV2 (line 25) | type OSTransformerV2
type MatchExclusionTransformerV2 (line 26) | type MatchExclusionTransformerV2
type KnownExploitedVulnerabilityTransformerV2 (line 28) | type KnownExploitedVulnerabilityTransformerV2
type EPSSTransformerV2 (line 29) | type EPSSTransformerV2
type OSVTransformerV2 (line 30) | type OSVTransformerV2
type OpenVEXTransformerV2 (line 31) | type OpenVEXTransformerV2
type AnnotatedOpenVEXTransformerV2 (line 32) | type AnnotatedOpenVEXTransformerV2
type EOLTransformerV2 (line 33) | type EOLTransformerV2
FILE: grype/db/data/writer.go
type Writer (line 6) | type Writer interface
FILE: grype/db/default_schema_version.go
constant DefaultSchemaVersion (line 5) | DefaultSchemaVersion = db.ModelVersion
FILE: grype/db/internal/codename/codename.go
function LookupOS (line 5) | func LookupOS(osName, majorVersion, minorVersion string) string {
FILE: grype/db/internal/codename/codename_test.go
function TestLookupOSCodename (line 9) | func TestLookupOSCodename(t *testing.T) {
FILE: grype/db/internal/codename/generate/main.go
constant outputPackage (line 15) | outputPackage = "grype/db/internal/codename"
constant outputPath (line 16) | outputPath = "internal/codename/codenames_generated.go"
type Version (line 19) | type Version struct
function main (line 24) | func main() {
function fetchAndParse (line 70) | func fetchAndParse(url string, handler func(string) string) map[string]m...
function lowercaseHandler (line 101) | func lowercaseHandler(codename string) string {
function ubuntuHandler (line 105) | func ubuntuHandler(codename string) string {
function parseVersion (line 110) | func parseVersion(version string) (string, string) {
FILE: grype/db/internal/gormadapter/logger.go
type logAdapter (line 16) | type logAdapter struct
method LogMode (line 23) | func (l *logAdapter) LogMode(level logger.LogLevel) logger.Interface {
method Info (line 29) | func (l logAdapter) Info(_ context.Context, fmt string, v ...interface...
method Warn (line 37) | func (l logAdapter) Warn(_ context.Context, fmt string, v ...interface...
method Error (line 43) | func (l logAdapter) Error(_ context.Context, fmt string, v ...interfac...
method Trace (line 50) | func (l logAdapter) Trace(_ context.Context, t time.Time, fn func() (s...
FILE: grype/db/internal/gormadapter/open.go
type config (line 38) | type config struct
method apply (line 101) | func (c *config) apply(path string, opts []Option) {
method connectionString (line 109) | func (c config) connectionString() string {
method prepareDB (line 153) | func (c config) prepareDB(dbObj *gorm.DB) (*gorm.DB, error) {
method applyStatements (line 207) | func (c config) applyStatements(db *gorm.DB, statements []string) error {
method pragmaNameValue (line 237) | func (c config) pragmaNameValue(sqlStmt string) (string, string, error) {
type Option (line 50) | type Option
function WithDebug (line 52) | func WithDebug(debug bool) Option {
function WithTruncate (line 58) | func WithTruncate(truncate bool, models []any, initialData []any) Option {
function WithStatements (line 70) | func WithStatements(statements ...string) Option {
function WithModels (line 76) | func WithModels(models []any) Option {
function WithWritable (line 82) | func WithWritable(write bool, models []any) Option {
function WithLargeMemoryFootprint (line 89) | func WithLargeMemoryFootprint(largeFootprint bool) Option {
function newConfig (line 95) | func newConfig(path string, opts []Option) config {
function Open (line 129) | func Open(path string, options ...Option) (*gorm.DB, error) {
function deleteDB (line 269) | func deleteDB(path string) error {
FILE: grype/db/internal/gormadapter/open_test.go
function TestConfigApply (line 11) | func TestConfigApply(t *testing.T) {
function TestConfigConnectionString (line 52) | func TestConfigConnectionString(t *testing.T) {
function TestPrepareWritableDB (line 93) | func TestPrepareWritableDB(t *testing.T) {
function TestPragmaNameValue (line 131) | func TestPragmaNameValue(t *testing.T) {
FILE: grype/db/internal/provider/unmarshal/annotated_openvex_vulnerability.go
type AnnotatedOpenVEXVulnerability (line 9) | type AnnotatedOpenVEXVulnerability struct
type AnnotatedOpenVEXFix (line 14) | type AnnotatedOpenVEXFix struct
type AnnotatedOpenVEXFixAvailability (line 19) | type AnnotatedOpenVEXFixAvailability struct
function AnnotatedOpenVEXVulnerabilityEntries (line 24) | func AnnotatedOpenVEXVulnerabilityEntries(reader io.Reader) ([]Annotated...
FILE: grype/db/internal/provider/unmarshal/eol.go
type EndOfLifeDateRelease (line 10) | type EndOfLifeDateRelease struct
method IsEmpty (line 82) | func (e EndOfLifeDateRelease) IsEmpty() bool {
method ProductName (line 87) | func (e EndOfLifeDateRelease) ProductName() string {
type EndOfLifeDateLatest (line 32) | type EndOfLifeDateLatest struct
type EndOfLifeDateIdentifier (line 39) | type EndOfLifeDateIdentifier struct
type EndOfLifeDateLabels (line 45) | type EndOfLifeDateLabels struct
type EndOfLifeDateLinks (line 53) | type EndOfLifeDateLinks struct
type EndOfLifeDateResult (line 60) | type EndOfLifeDateResult struct
type EndOfLifeDateProduct (line 74) | type EndOfLifeDateProduct struct
function EndOfLifeDateReleaseEntries (line 92) | func EndOfLifeDateReleaseEntries(reader io.Reader) ([]EndOfLifeDateRelea...
FILE: grype/db/internal/provider/unmarshal/epss.go
type EPSS (line 5) | type EPSS struct
method IsEmpty (line 12) | func (o EPSS) IsEmpty() bool {
function EPSSEntries (line 16) | func EPSSEntries(reader io.Reader) ([]EPSS, error) {
FILE: grype/db/internal/provider/unmarshal/errors.go
function handleJSONUnmarshalError (line 8) | func handleJSONUnmarshalError(err error) error {
FILE: grype/db/internal/provider/unmarshal/github_advisory.go
type GitHubAdvisory (line 7) | type GitHubAdvisory struct
method IsEmpty (line 44) | func (g GitHubAdvisory) IsEmpty() bool {
function GitHubAdvisoryEntries (line 48) | func GitHubAdvisoryEntries(reader io.Reader) ([]GitHubAdvisory, error) {
type GithubFixedIn (line 52) | type GithubFixedIn struct
FILE: grype/db/internal/provider/unmarshal/items_envelope.go
type ItemsEnvelope (line 9) | type ItemsEnvelope struct
function Envelope (line 15) | func Envelope(reader io.Reader) (*ItemsEnvelope, error) {
FILE: grype/db/internal/provider/unmarshal/known_exploited_vulnerability.go
type KnownExploitedVulnerability (line 5) | type KnownExploitedVulnerability struct
method IsEmpty (line 19) | func (g KnownExploitedVulnerability) IsEmpty() bool {
function KnownExploitedVulnerabilityEntries (line 23) | func KnownExploitedVulnerabilityEntries(reader io.Reader) ([]KnownExploi...
FILE: grype/db/internal/provider/unmarshal/match_exclusion.go
type MatchExclusion (line 7) | type MatchExclusion struct
method IsEmpty (line 25) | func (m MatchExclusion) IsEmpty() bool {
function MatchExclusions (line 29) | func MatchExclusions(reader io.Reader) ([]MatchExclusion, error) {
FILE: grype/db/internal/provider/unmarshal/msrc_vulnerability.go
type MSRCVulnerability (line 8) | type MSRCVulnerability struct
method IsEmpty (line 36) | func (o MSRCVulnerability) IsEmpty() bool {
function MSRCVulnerabilityEntries (line 40) | func MSRCVulnerabilityEntries(reader io.Reader) ([]MSRCVulnerability, er...
FILE: grype/db/internal/provider/unmarshal/nvd/cve.go
type Operator (line 19) | type Operator
constant And (line 22) | And Operator = "AND"
constant Or (line 23) | Or Operator = "OR"
constant englishLanguage (line 26) | englishLanguage = "en"
type Vulnerability (line 39) | type Vulnerability struct
method IsEmpty (line 334) | func (o Vulnerability) IsEmpty() bool {
type CveItem (line 43) | type CveItem struct
method Description (line 172) | func (o CveItem) Description() string {
method CVSS (line 263) | func (o CveItem) CVSS() []CvssSummary {
type Configuration (line 64) | type Configuration struct
type Node (line 70) | type Node struct
type FixInfo (line 76) | type FixInfo struct
type CpeMatch (line 82) | type CpeMatch struct
type LangString (line 93) | type LangString struct
type Metrics (line 99) | type Metrics struct
type CvssV2 (line 106) | type CvssV2 struct
type CvssV30 (line 120) | type CvssV30 struct
type CvssV31 (line 128) | type CvssV31 struct
type CvssV40 (line 136) | type CvssV40 struct
type CvssType (line 148) | type CvssType
constant Primary (line 151) | Primary CvssType = "Primary"
constant Secondary (line 152) | Secondary CvssType = "Secondary"
type Reference (line 155) | type Reference struct
type Weakness (line 166) | type Weakness struct
type CvssSummary (line 181) | type CvssSummary struct
method Severity (line 192) | func (o CvssSummary) Severity() string {
method version (line 199) | func (o CvssSummary) version() *semver.Version {
type CvssSummaries (line 207) | type CvssSummaries
method Len (line 209) | func (o CvssSummaries) Len() int {
method Less (line 213) | func (o CvssSummaries) Less(i, j int) bool {
method Swap (line 240) | func (o CvssSummaries) Swap(i, j int) {
method Severity (line 244) | func (o CvssSummaries) Severity() string {
method Sorted (line 254) | func (o CvssSummaries) Sorted() CvssSummaries {
FILE: grype/db/internal/provider/unmarshal/nvd/cve_test.go
function TestCvssSummariesSorted (line 10) | func TestCvssSummariesSorted(t *testing.T) {
function TestCvssSummaryVersion (line 176) | func TestCvssSummaryVersion(t *testing.T) {
FILE: grype/db/internal/provider/unmarshal/nvd/cvss20/cvss20.go
type Cvss20 (line 5) | type Cvss20 struct
FILE: grype/db/internal/provider/unmarshal/nvd/cvss30/cvss30.go
type Cvss30 (line 5) | type Cvss30 struct
type SeverityType (line 71) | type SeverityType
constant Critical (line 74) | Critical SeverityType = "CRITICAL"
constant SeverityTypeHIGH (line 75) | SeverityTypeHIGH SeverityType = "HIGH"
constant SeverityTypeLOW (line 76) | SeverityTypeLOW SeverityType = "LOW"
constant SeverityTypeMEDIUM (line 77) | SeverityTypeMEDIUM SeverityType = "MEDIUM"
constant SeverityTypeNONE (line 78) | SeverityTypeNONE SeverityType = "NONE"
FILE: grype/db/internal/provider/unmarshal/nvd/cvss31/cvss31.go
type Cvss31 (line 5) | type Cvss31 struct
type SeverityType (line 71) | type SeverityType
constant Critical (line 74) | Critical SeverityType = "CRITICAL"
constant SeverityTypeHIGH (line 75) | SeverityTypeHIGH SeverityType = "HIGH"
constant SeverityTypeLOW (line 76) | SeverityTypeLOW SeverityType = "LOW"
constant SeverityTypeMEDIUM (line 77) | SeverityTypeMEDIUM SeverityType = "MEDIUM"
constant SeverityTypeNONE (line 78) | SeverityTypeNONE SeverityType = "NONE"
FILE: grype/db/internal/provider/unmarshal/nvd/cvss40/cvss40.go
type Cvss40 (line 5) | type Cvss40 struct
type SeverityType (line 44) | type SeverityType
constant SeverityTypeCritical (line 47) | SeverityTypeCritical SeverityType = "CRITICAL"
constant SeverityTypeHIGH (line 48) | SeverityTypeHIGH SeverityType = "HIGH"
constant SeverityTypeLOW (line 49) | SeverityTypeLOW SeverityType = "LOW"
constant SeverityTypeMEDIUM (line 50) | SeverityTypeMEDIUM SeverityType = "MEDIUM"
constant SeverityTypeNONE (line 51) | SeverityTypeNONE SeverityType = "NONE"
FILE: grype/db/internal/provider/unmarshal/nvd_vulnerability.go
function NvdVulnerabilityEntries (line 13) | func NvdVulnerabilityEntries(reader io.Reader) ([]nvd.Vulnerability, err...
FILE: grype/db/internal/provider/unmarshal/openvex_vulnerability.go
function OpenVEXVulnerabilityEntries (line 11) | func OpenVEXVulnerabilityEntries(reader io.Reader) ([]OpenVEXVulnerabili...
FILE: grype/db/internal/provider/unmarshal/os_vulnerability.go
type OSFixedIn (line 13) | type OSFixedIn struct
type OSFixedIns (line 33) | type OSFixedIns
method FilterToHighestModularity (line 84) | func (fixes OSFixedIns) FilterToHighestModularity() OSFixedIns {
type OSVulnerability (line 35) | type OSVulnerability struct
method IsEmpty (line 72) | func (o OSVulnerability) IsEmpty() bool {
function OSVulnerabilityEntries (line 76) | func OSVulnerabilityEntries(reader io.Reader) ([]OSVulnerability, error) {
function moduleNameAndVersion (line 136) | func moduleNameAndVersion(module *string) (bool, string, *version.Versio...
function moduleVersionConstraint (line 159) | func moduleVersionConstraint(moduleVersion string) (*version.Version, *v...
FILE: grype/db/internal/provider/unmarshal/os_vulnerability_test.go
function Test_OSFixedIns_FilterToHighestModularity (line 9) | func Test_OSFixedIns_FilterToHighestModularity(t *testing.T) {
FILE: grype/db/internal/provider/unmarshal/osv_vulnerability.go
function OSVVulnerabilityEntries (line 11) | func OSVVulnerabilityEntries(reader io.Reader) ([]OSVVulnerability, erro...
FILE: grype/db/internal/provider/unmarshal/single_or_multi.go
function unmarshalSingleOrMulti (line 10) | func unmarshalSingleOrMulti[T interface{}](reader io.Reader) ([]T, error) {
FILE: grype/db/internal/sqlite/nullable_types.go
type NullString (line 8) | type NullString struct
method ToByteSlice (line 49) | func (v NullString) ToByteSlice() []byte {
method MarshalJSON (line 57) | func (v NullString) MarshalJSON() ([]byte, error) {
method UnmarshalJSON (line 65) | func (v *NullString) UnmarshalJSON(data []byte) error {
function NewNullString (line 12) | func NewNullString(s string, valid bool) NullString {
function ToNullString (line 21) | func ToNullString(v any) NullString {
FILE: grype/db/internal/sqlite/nullable_types_test.go
function TestToNullString (line 9) | func TestToNullString(t *testing.T) {
FILE: grype/db/internal/tarutil/file_entry.go
type FileEntry (line 11) | type FileEntry struct
method writeEntry (line 29) | func (t FileEntry) writeEntry(tw lowLevelWriter) error {
function NewEntryFromFilePath (line 15) | func NewEntryFromFilePath(path string) Entry {
function NewEntryFromFilePaths (line 21) | func NewEntryFromFilePaths(paths ...string) []Entry {
FILE: grype/db/internal/tarutil/file_entry_test.go
type mockTarWriter (line 17) | type mockTarWriter struct
method Flush (line 26) | func (m *mockTarWriter) Flush() error {
method Close (line 31) | func (m *mockTarWriter) Close() error {
method WriteHeader (line 36) | func (m *mockTarWriter) WriteHeader(header *tar.Header) error {
method Write (line 42) | func (m *mockTarWriter) Write(b []byte) (int, error) {
function TestFileEntry_writeEntry (line 46) | func TestFileEntry_writeEntry(t *testing.T) {
FILE: grype/db/internal/tarutil/populate.go
function PopulateWithPaths (line 4) | func PopulateWithPaths(tarPath string, filePaths ...string) error {
function PopulateWithPathsAndCompressors (line 9) | func PopulateWithPathsAndCompressors(tarPath string, compressorCommands ...
FILE: grype/db/internal/tarutil/populate_test.go
function TestPopulateWithPaths (line 17) | func TestPopulateWithPaths(t *testing.T) {
FILE: grype/db/internal/tarutil/reader_entry.go
type ReaderEntry (line 15) | type ReaderEntry struct
method writeEntry (line 29) | func (t ReaderEntry) writeEntry(tw lowLevelWriter) error {
function NewEntryFromBytes (line 21) | func NewEntryFromBytes(by []byte, filename string, fileInfo os.FileInfo)...
type autoDeleteFile (line 37) | type autoDeleteFile struct
method Close (line 41) | func (f *autoDeleteFile) Close() error {
function readerWithSize (line 54) | func readerWithSize(reader io.Reader) (int64, io.ReadCloser, error) {
function writeEntry (line 95) | func writeEntry(tw lowLevelWriter, filename string, fileInfo os.FileInfo...
FILE: grype/db/internal/tarutil/reader_entry_test.go
type mockFileInfo (line 23) | type mockFileInfo struct
method Name (line 32) | func (m mockFileInfo) Name() string {
method Size (line 36) | func (m mockFileInfo) Size() int64 {
method Mode (line 40) | func (m mockFileInfo) Mode() fs.FileMode {
method ModTime (line 44) | func (m mockFileInfo) ModTime() time.Time {
method IsDir (line 48) | func (m mockFileInfo) IsDir() bool {
method Sys (line 52) | func (m mockFileInfo) Sys() any {
function TestReaderEntry_writeEntry (line 56) | func TestReaderEntry_writeEntry(t *testing.T) {
function Test_readerWithSize (line 148) | func Test_readerWithSize(t *testing.T) {
function Test_autoDeleteFile (line 222) | func Test_autoDeleteFile(t *testing.T) {
FILE: grype/db/internal/tarutil/tar.go
type Writer (line 9) | type Writer interface
type lowLevelWriter (line 15) | type lowLevelWriter interface
type Entry (line 22) | type Entry interface
FILE: grype/db/internal/tarutil/writer.go
type writer (line 23) | type writer struct
method WriteEntry (line 150) | func (w *writer) WriteEntry(entry Entry) error {
method Close (line 154) | func (w *writer) Close() error {
function NewWriter (line 29) | func NewWriter(archivePath string) (Writer, error) {
function NewWriterWithCompressors (line 34) | func NewWriterWithCompressors(archivePath string, compressorCommands map...
function newCompressorWithCommands (line 48) | func newCompressorWithCommands(archivePath string, compressorCommands ma...
type shellCompressor (line 81) | type shellCompressor struct
method Write (line 136) | func (sc *shellCompressor) Write(p []byte) (int, error) {
method Close (line 140) | func (sc *shellCompressor) Close() error {
function newShellCompressor (line 86) | func newShellCompressor(c string, archive io.Writer) (*shellCompressor, ...
FILE: grype/db/internal/tarutil/writer_test.go
function TestNewWriter (line 17) | func TestNewWriter(t *testing.T) {
FILE: grype/db/internal/testutil/utils.go
function CloseFile (line 8) | func CloseFile(f *os.File) {
FILE: grype/db/internal/versionutil/clean_fixed_in_version.go
function CleanFixedInVersion (line 5) | func CleanFixedInVersion(version string) string {
FILE: grype/db/internal/versionutil/constraint.go
function EnforceSemVerConstraint (line 18) | func EnforceSemVerConstraint(constraint string) string {
function AndConstraints (line 26) | func AndConstraints(c ...string) string {
function OrConstraints (line 30) | func OrConstraints(c ...string) string {
function CleanConstraint (line 34) | func CleanConstraint(constraint string) string {
FILE: grype/db/internal/versionutil/constraint_test.go
function TestEnforceSemVerConstraint (line 5) | func TestEnforceSemVerConstraint(t *testing.T) {
FILE: grype/db/package.go
function Package (line 11) | func Package(dbDir, publishBaseURL, overrideArchiveExtension string, com...
FILE: grype/db/package_legacy.go
function packageLegacyDB (line 25) | func packageLegacyDB(dbDir, publishBaseURL, overrideArchiveExtension str...
function populateLegacyTar (line 113) | func populateLegacyTar(tarPath string, compressorCommands map[string]str...
function secondsSinceEpoch (line 152) | func secondsSinceEpoch() int64 {
FILE: grype/db/processors/annotated_openvex_processor.go
type annotatedOpenVEXProcessor (line 12) | type annotatedOpenVEXProcessor struct
method Process (line 22) | func (p annotatedOpenVEXProcessor) Process(reader io.Reader, state pro...
method IsSupported (line 42) | func (p annotatedOpenVEXProcessor) IsSupported(schemaURL string) bool {
function NewV2AnnotatedOpenVEXProcessor (line 16) | func NewV2AnnotatedOpenVEXProcessor(transformer data.AnnotatedOpenVEXTra...
FILE: grype/db/processors/eol_processor.go
type eolProcessor (line 13) | type eolProcessor struct
method Process (line 23) | func (p eolProcessor) Process(reader io.Reader, state provider.State) ...
method IsSupported (line 48) | func (p eolProcessor) IsSupported(schemaURL string) bool {
function NewV2EOLProcessor (line 17) | func NewV2EOLProcessor(transformer data.EOLTransformerV2) data.Processor {
FILE: grype/db/processors/eol_processor_test.go
function mockEOLProcessorTransform (line 15) | func mockEOLProcessorTransform(entry unmarshal.EndOfLifeDateRelease, sta...
function TestEOLProcessor_Process (line 24) | func TestEOLProcessor_Process(t *testing.T) {
function TestEOLProcessor_Process_EmptyEntry (line 51) | func TestEOLProcessor_Process_EmptyEntry(t *testing.T) {
function TestEOLProcessor_IsSupported (line 70) | func TestEOLProcessor_IsSupported(t *testing.T) {
FILE: grype/db/processors/epss_processor.go
type epssProcessor (line 13) | type epssProcessor struct
method Process (line 23) | func (p epssProcessor) Process(reader io.Reader, state provider.State)...
method IsSupported (line 48) | func (p epssProcessor) IsSupported(schemaURL string) bool {
function NewV2EPSSProcessor (line 17) | func NewV2EPSSProcessor(transformer data.EPSSTransformerV2) data.Process...
FILE: grype/db/processors/epss_processor_test.go
function mockEPSSProcessorTransform (line 15) | func mockEPSSProcessorTransform(entry unmarshal.EPSS, state provider.Sta...
function TestEPSSProcessor_Process (line 24) | func TestEPSSProcessor_Process(t *testing.T) {
function TestEPSSProcessor_IsSupported (line 38) | func TestEPSSProcessor_IsSupported(t *testing.T) {
FILE: grype/db/processors/github_processor.go
type githubProcessor (line 13) | type githubProcessor struct
method Process (line 29) | func (p githubProcessor) Process(reader io.Reader, state provider.Stat...
method IsSupported (line 66) | func (p githubProcessor) IsSupported(schemaURL string) bool {
function NewGitHubProcessor (line 17) | func NewGitHubProcessor(transformer data.GitHubTransformer) data.Process...
function NewV2GitHubProcessor (line 23) | func NewV2GitHubProcessor(transformer data.GitHubTransformerV2) data.Pro...
FILE: grype/db/processors/github_processor_test.go
function mockGithubProcessorTransform (line 16) | func mockGithubProcessorTransform(vulnerability unmarshal.GitHubAdvisory...
function TestGitHubProcessor_Process (line 25) | func TestGitHubProcessor_Process(t *testing.T) {
function TestGithubProcessor_IsSupported (line 39) | func TestGithubProcessor_IsSupported(t *testing.T) {
FILE: grype/db/processors/kev_processor.go
type kevProcessor (line 13) | type kevProcessor struct
method Process (line 23) | func (p kevProcessor) Process(reader io.Reader, state provider.State) ...
method IsSupported (line 48) | func (p kevProcessor) IsSupported(schemaURL string) bool {
function NewV2KEVProcessor (line 17) | func NewV2KEVProcessor(transformer data.KnownExploitedVulnerabilityTrans...
FILE: grype/db/processors/kev_processor_test.go
function mockKEVProcessorTransform (line 15) | func mockKEVProcessorTransform(vulnerability unmarshal.KnownExploitedVul...
function TestKEVProcessor_Process (line 24) | func TestKEVProcessor_Process(t *testing.T) {
function TestKEVProcessor_IsSupported (line 38) | func TestKEVProcessor_IsSupported(t *testing.T) {
FILE: grype/db/processors/match_exclusion_processor.go
type matchExclusionProcessor (line 13) | type matchExclusionProcessor struct
method Process (line 23) | func (p matchExclusionProcessor) Process(reader io.Reader, _ provider....
method IsSupported (line 48) | func (p matchExclusionProcessor) IsSupported(schemaURL string) bool {
function NewMatchExclusionProcessor (line 17) | func NewMatchExclusionProcessor(transformer data.MatchExclusionTransform...
FILE: grype/db/processors/match_exclusion_processor_test.go
function mockMatchExclusionProcessorTransform (line 16) | func mockMatchExclusionProcessorTransform(vulnerability unmarshal.MatchE...
function TestMatchExclusionProcessor_Process (line 25) | func TestMatchExclusionProcessor_Process(t *testing.T) {
function TestMatchExclusionProcessor_IsSupported (line 39) | func TestMatchExclusionProcessor_IsSupported(t *testing.T) {
FILE: grype/db/processors/msrc_processor.go
type msrcProcessor (line 14) | type msrcProcessor struct
method Process (line 31) | func (p msrcProcessor) Process(reader io.Reader, state provider.State)...
method IsSupported (line 68) | func (p msrcProcessor) IsSupported(schemaURL string) bool {
function NewMSRCProcessor (line 19) | func NewMSRCProcessor(transformer data.MSRCTransformer) data.Processor {
function NewV2MSRCProcessor (line 25) | func NewV2MSRCProcessor(transformer data.MSRCTransformerV2) data.Process...
FILE: grype/db/processors/msrc_processor_test.go
function mockMSRCProcessorTransform (line 16) | func mockMSRCProcessorTransform(vulnerability unmarshal.MSRCVulnerabilit...
function TestMSRCProcessor_Process (line 25) | func TestMSRCProcessor_Process(t *testing.T) {
function TestMsrcProcessor_IsSupported (line 39) | func TestMsrcProcessor_IsSupported(t *testing.T) {
FILE: grype/db/processors/nvd_processor.go
type nvdProcessor (line 12) | type nvdProcessor struct
method Process (line 28) | func (p nvdProcessor) Process(reader io.Reader, state provider.State) ...
method IsSupported (line 65) | func (p nvdProcessor) IsSupported(schemaURL string) bool {
function NewNVDProcessor (line 16) | func NewNVDProcessor(transformer data.NVDTransformer) data.Processor {
function NewV2NVDProcessor (line 22) | func NewV2NVDProcessor(transformer data.NVDTransformerV2) data.Processor {
FILE: grype/db/processors/nvd_processor_test.go
function mockNVDProcessorTransform (line 16) | func mockNVDProcessorTransform(vulnerability unmarshal.NVDVulnerability)...
function TestNVDProcessor_Process (line 25) | func TestNVDProcessor_Process(t *testing.T) {
function TestNvdProcessor_IsSupported (line 39) | func TestNvdProcessor_IsSupported(t *testing.T) {
FILE: grype/db/processors/openvex_processor.go
type openVEXProcessor (line 12) | type openVEXProcessor struct
method Process (line 22) | func (p openVEXProcessor) Process(reader io.Reader, state provider.Sta...
method IsSupported (line 42) | func (p openVEXProcessor) IsSupported(schemaURL string) bool {
function NewV2OpenVEXProcessor (line 16) | func NewV2OpenVEXProcessor(transformer data.OpenVEXTransformerV2) data.P...
FILE: grype/db/processors/openvex_processor_test.go
function mockOpenVEXProcessorTransform (line 16) | func mockOpenVEXProcessorTransform(vulnerability unmarshal.OpenVEXVulner...
function TestV2OpenVEXProcessor_Process (line 25) | func TestV2OpenVEXProcessor_Process(t *testing.T) {
function TestOpenVEXProcessor_IsSupported (line 39) | func TestOpenVEXProcessor_IsSupported(t *testing.T) {
FILE: grype/db/processors/os_processor.go
type osProcessor (line 13) | type osProcessor struct
method Process (line 29) | func (p osProcessor) Process(reader io.Reader, state provider.State) (...
method IsSupported (line 66) | func (p osProcessor) IsSupported(schemaURL string) bool {
function NewOSProcessor (line 17) | func NewOSProcessor(transformer data.OSTransformer) data.Processor {
function NewV2OSProcessor (line 23) | func NewV2OSProcessor(transformer data.OSTransformerV2) data.Processor {
FILE: grype/db/processors/os_processor_test.go
function mockOSProcessorTransform (line 16) | func mockOSProcessorTransform(vulnerability unmarshal.OSVulnerability) (...
function TestOSProcessor_Process (line 25) | func TestOSProcessor_Process(t *testing.T) {
function TestOsProcessor_IsSupported (line 39) | func TestOsProcessor_IsSupported(t *testing.T) {
FILE: grype/db/processors/osv_processor.go
type osvProcessor (line 12) | type osvProcessor struct
method Process (line 22) | func (p osvProcessor) Process(reader io.Reader, state provider.State) ...
method IsSupported (line 42) | func (p osvProcessor) IsSupported(schemaURL string) bool {
function NewV2OSVProcessor (line 16) | func NewV2OSVProcessor(transformer data.OSVTransformerV2) data.Processor {
FILE: grype/db/processors/osv_processor_test.go
function mockOSVProcessorTransform (line 16) | func mockOSVProcessorTransform(vulnerability unmarshal.OSVVulnerability,...
function TestV2OSVProcessor_Process (line 25) | func TestV2OSVProcessor_Process(t *testing.T) {
function TestOSVProcessor_IsSupported (line 39) | func TestOSVProcessor_IsSupported(t *testing.T) {
FILE: grype/db/processors/version.go
type version (line 12) | type version struct
function parseVersion (line 18) | func parseVersion(schemaURL string) (*version, error) {
function hasSchemaSegment (line 46) | func hasSchemaSegment(schemaURL string, segment string) bool {
FILE: grype/db/processors/version_test.go
function TestParseVersion (line 9) | func TestParseVersion(t *testing.T) {
FILE: grype/db/provider/entry/file.go
type fileOpener (line 8) | type fileOpener struct
method Open (line 23) | func (e fileOpener) Open() (io.ReadCloser, error) {
method String (line 27) | func (e fileOpener) String() string {
function fileOpeners (line 12) | func fileOpeners(resultPaths []string) <-chan Opener {
FILE: grype/db/provider/entry/opener.go
type Opener (line 8) | type Opener interface
function Openers (line 13) | func Openers(store string, resultPaths []string) (<-chan Opener, int64, ...
function Count (line 23) | func Count(store string, resultPaths []string) (int64, error) {
FILE: grype/db/provider/entry/sqlite.go
type results (line 25) | type results struct
type bytesOpener (line 30) | type bytesOpener struct
method Open (line 115) | func (e bytesOpener) Open() (io.ReadCloser, error) {
method String (line 119) | func (e bytesOpener) String() string {
type errorOpener (line 35) | type errorOpener struct
method Open (line 123) | func (e errorOpener) Open() (io.ReadCloser, error) {
method String (line 127) | func (e errorOpener) String() string {
function sqliteEntryCount (line 39) | func sqliteEntryCount(resultPaths []string) (int64, error) {
function sqliteOpeners (line 64) | func sqliteOpeners(resultPaths []string) (<-chan Opener, int64, error) {
function openDB (line 132) | func openDB(path string) (*gorm.DB, error) {
function connectionString (line 152) | func connectionString(path string) (string, error) {
type logAdapter (line 159) | type logAdapter struct
method LogMode (line 165) | func (l logAdapter) LogMode(logger.LogLevel) logger.Interface {
method Info (line 169) | func (l logAdapter) Info(_ context.Context, _ string, _ ...interface{}) {
method Warn (line 173) | func (l logAdapter) Warn(_ context.Context, fmt string, v ...interface...
method Error (line 177) | func (l logAdapter) Error(_ context.Context, fmt string, v ...interfac...
method Trace (line 181) | func (l logAdapter) Trace(_ context.Context, _ time.Time, _ func() (_ ...
function newLogger (line 161) | func newLogger() logger.Interface {
FILE: grype/db/provider/file.go
type File (line 13) | type File struct
type Files (line 19) | type Files
method Paths (line 46) | func (i Files) Paths() []string {
function NewFile (line 21) | func NewFile(path string) (*File, error) {
function NewFiles (line 34) | func NewFiles(paths ...string) (Files, error) {
function NewFilesFromDir (line 54) | func NewFilesFromDir(dir string) (Files, error) {
FILE: grype/db/provider/model.go
function Model (line 9) | func Model(state State) *db.Provider {
FILE: grype/db/provider/model_test.go
function TestProviderModel (line 12) | func TestProviderModel(t *testing.T) {
FILE: grype/db/provider/provider.go
type Kind (line 7) | type Kind
type Reader (line 9) | type Reader interface
type Writer (line 14) | type Writer interface
type Identifier (line 18) | type Identifier struct
type Providers (line 23) | type Providers
method Filter (line 25) | func (ps Providers) Filter(names ...string) Providers {
type Collection (line 37) | type Collection struct
FILE: grype/db/provider/state.go
type State (line 20) | type State struct
method ResultPath (line 98) | func (sd State) ResultPath(filename string) string {
method ResultPaths (line 102) | func (sd State) ResultPaths() []string {
method Verify (line 110) | func (sd State) Verify(workspaceRoots ...string) error {
type Schema (line 36) | type Schema struct
type States (line 41) | type States
method Names (line 134) | func (s States) Names() []string {
method EarliestTimestamp (line 142) | func (s States) EarliestTimestamp() (time.Time, error) {
function ReadState (line 43) | func ReadState(location string) (*State, error) {
FILE: grype/db/provider/state_test.go
function Test_earliestTimestamp (line 11) | func Test_earliestTimestamp(t *testing.T) {
function requireErrorContains (line 125) | func requireErrorContains(text string) require.ErrorAssertionFunc {
FILE: grype/db/provider/workspace.go
type Workspace (line 7) | type Workspace struct
method Path (line 26) | func (w Workspace) Path() string {
method StatePath (line 30) | func (w Workspace) StatePath() string {
method InputPath (line 34) | func (w Workspace) InputPath() string {
method ResultsPath (line 38) | func (w Workspace) ResultsPath() string {
method ReadState (line 42) | func (w Workspace) ReadState() (*State, error) {
function NewWorkspace (line 12) | func NewWorkspace(root, name string) Workspace {
function NewWorkspaceFromExisting (line 19) | func NewWorkspaceFromExisting(workspacePath string) Workspace {
FILE: grype/db/v5/advisory.go
type Advisory (line 4) | type Advisory struct
FILE: grype/db/v5/build/processors.go
type Config (line 15) | type Config struct
type Option (line 19) | type Option
function WithCPEParts (line 21) | func WithCPEParts(included []string) Option {
function WithInferNVDFixVersions (line 27) | func WithInferNVDFixVersions(infer bool) Option {
function NewConfig (line 33) | func NewConfig(options ...Option) Config {
function Processors (line 42) | func Processors(cfg Config) []data.Processor {
FILE: grype/db/v5/build/transformers/entry.go
function NewEntries (line 8) | func NewEntries(vs []db.Vulnerability, metadata db.VulnerabilityMetadata...
FILE: grype/db/v5/build/transformers/github/transform.go
function buildGrypeNamespace (line 19) | func buildGrypeNamespace(group string) (namespace.Namespace, error) {
function Transform (line 50) | func Transform(vulnerability unmarshal.GitHubAdvisory) ([]data.Entry, er...
function getFix (line 112) | func getFix(entry unmarshal.GitHubAdvisory, idx int) db.Fix {
function getRelatedVulnerabilities (line 132) | func getRelatedVulnerabilities(entry unmarshal.GitHubAdvisory) []db.Vuln...
function getCvss (line 143) | func getCvss(entry unmarshal.GitHubAdvisory) (cvss []db.Cvss) {
FILE: grype/db/v5/build/transformers/github/transform_test.go
function TestBuildGrypeNamespace (line 21) | func TestBuildGrypeNamespace(t *testing.T) {
function TestUnmarshalGitHubEntries (line 77) | func TestUnmarshalGitHubEntries(t *testing.T) {
function TestParseGitHubEntry (line 89) | func TestParseGitHubEntry(t *testing.T) {
function TestDefaultVersionFormatNpmGitHubEntry (line 188) | func TestDefaultVersionFormatNpmGitHubEntry(t *testing.T) {
function TestFilterWithdrawnEntries (line 257) | func TestFilterWithdrawnEntries(t *testing.T) {
FILE: grype/db/v5/build/transformers/matchexclusions/transform.go
function Transform (line 9) | func Transform(matchExclusion unmarshal.MatchExclusion) ([]data.Entry, e...
FILE: grype/db/v5/build/transformers/msrc/transform.go
function Transform (line 17) | func Transform(vulnerability unmarshal.MSRCVulnerability) ([]data.Entry,...
function getFix (line 67) | func getFix(entry unmarshal.MSRCVulnerability) db.Fix {
function fixedInKB (line 83) | func fixedInKB(vulnerability unmarshal.MSRCVulnerability) string {
FILE: grype/db/v5/build/transformers/msrc/transform_test.go
function TestUnmarshalMsrcVulnerabilities (line 15) | func TestUnmarshalMsrcVulnerabilities(t *testing.T) {
function TestParseMSRCEntry (line 26) | func TestParseMSRCEntry(t *testing.T) {
FILE: grype/db/v5/build/transformers/nvd/transform.go
type Config (line 23) | type Config struct
function defaultConfig (line 28) | func defaultConfig() Config {
function Transformer (line 35) | func Transformer(cfg Config) data.NVDTransformer {
function transform (line 44) | func transform(cfg Config, vulnerability unmarshal.NVDVulnerability) ([]...
function getVersionFormat (line 115) | func getVersionFormat(name string, cpes []string) version.Format {
function getFix (line 131) | func getFix(matches []nvd.CpeMatch, inferNVDFixVersions bool) db.Fix {
function getCvss (line 185) | func getCvss(cvss ...nvd.CvssSummary) []db.Cvss {
FILE: grype/db/v5/build/transformers/nvd/transform_test.go
function TestUnmarshalNVDVulnerabilitiesEntries (line 21) | func TestUnmarshalNVDVulnerabilitiesEntries(t *testing.T) {
function TestParseAllNVDVulnerabilityEntries (line 31) | func TestParseAllNVDVulnerabilityEntries(t *testing.T) {
function TestGetVersionFormat (line 753) | func TestGetVersionFormat(t *testing.T) {
function TestGetFix (line 812) | func TestGetFix(t *testing.T) {
FILE: grype/db/v5/build/transformers/nvd/unique_pkg.go
constant ANY (line 15) | ANY = "*"
constant NA (line 16) | NA = "-"
type pkgCandidate (line 19) | type pkgCandidate struct
method String (line 26) | func (p pkgCandidate) String() string {
function newPkgCandidate (line 34) | func newPkgCandidate(tCfg Config, match nvd.CpeMatch, platformCPE string...
function findUniquePkgs (line 59) | func findUniquePkgs(tCfg Config, cfgs ...nvd.Configuration) uniquePkgTra...
function platformPackageCandidates (line 67) | func platformPackageCandidates(tCfg Config, set uniquePkgTracker, c nvd....
function anyHardwareCPEPresent (line 127) | func anyHardwareCPEPresent(n nvd.Node) bool {
function allCPEsVulnerable (line 137) | func allCPEsVulnerable(node nvd.Node) bool {
function noCPEsVulnerable (line 146) | func noCPEsVulnerable(node nvd.Node) bool {
function _findUniquePkgs (line 155) | func _findUniquePkgs(tCfg Config, set uniquePkgTracker, c nvd.Configurat...
function buildConstraints (line 181) | func buildConstraints(matches []nvd.CpeMatch) string {
function buildConstraint (line 190) | func buildConstraint(match nvd.CpeMatch) string {
function removeDuplicateConstraints (line 223) | func removeDuplicateConstraints(constraints []string) []string {
FILE: grype/db/v5/build/transformers/nvd/unique_pkg_test.go
function newUniquePkgTrackerFromSlice (line 15) | func newUniquePkgTrackerFromSlice(candidates []pkgCandidate) uniquePkgTr...
function TestFindUniquePkgs (line 23) | func TestFindUniquePkgs(t *testing.T) {
function strRef (line 450) | func strRef(s string) *string {
function TestBuildConstraints (line 454) | func TestBuildConstraints(t *testing.T) {
function Test_UniquePackageTrackerHandlesOnlyPlatformDiff (line 553) | func Test_UniquePackageTrackerHandlesOnlyPlatformDiff(t *testing.T) {
function TestPlatformPackageCandidates (line 604) | func TestPlatformPackageCandidates(t *testing.T) {
function opRef (line 744) | func opRef(op nvd.Operator) *nvd.Operator {
function boolRef (line 748) | func boolRef(b bool) *bool {
function mustNewPackage (line 752) | func mustNewPackage(t *testing.T, match nvd.CpeMatch, platformCPE string...
FILE: grype/db/v5/build/transformers/nvd/unique_pkg_tracker.go
type uniquePkgTracker (line 9) | type uniquePkgTracker
method Diff (line 15) | func (s uniquePkgTracker) Diff(other uniquePkgTracker) (missing []pkgC...
method Matches (line 31) | func (s uniquePkgTracker) Matches(i pkgCandidate) []nvd.CpeMatch {
method Add (line 35) | func (s uniquePkgTracker) Add(i pkgCandidate, match nvd.CpeMatch) {
method Remove (line 42) | func (s uniquePkgTracker) Remove(i pkgCandidate) {
method Contains (line 46) | func (s uniquePkgTracker) Contains(i pkgCandidate) bool {
method All (line 51) | func (s uniquePkgTracker) All() []pkgCandidate {
function newUniquePkgTracker (line 11) | func newUniquePkgTracker() uniquePkgTracker {
FILE: grype/db/v5/build/transformers/os/transform.go
function buildGrypeNamespace (line 18) | func buildGrypeNamespace(group string) (namespace.Namespace, error) {
function buildPackageQualifiers (line 67) | func buildPackageQualifiers(fixedInEntry unmarshal.OSFixedIn) (qualifier...
function Transform (line 83) | func Transform(vulnerability unmarshal.OSVulnerability) ([]data.Entry, e...
function getLinks (line 133) | func getLinks(entry unmarshal.OSVulnerability) []string {
function getCvss (line 146) | func getCvss(entry unmarshal.OSVulnerability) (cvss []db.Cvss) {
function getAdvisories (line 165) | func getAdvisories(entry unmarshal.OSVulnerability, idx int) (advisories...
function getFix (line 177) | func getFix(entry unmarshal.OSVulnerability, idx int) db.Fix {
function getRelatedVulnerabilities (line 199) | func getRelatedVulnerabilities(entry unmarshal.OSVulnerability) (vulns [...
function deriveConstraintFromFix (line 218) | func deriveConstraintFromFix(fixVersion, vulnerabilityID string) string {
function enforceConstraint (line 239) | func enforceConstraint(fixedVersion, vulnerableRange, format, vulnerabil...
FILE: grype/db/v5/build/transformers/os/transform_test.go
function TestUnmarshalOSVulnerabilitiesEntries (line 19) | func TestUnmarshalOSVulnerabilitiesEntries(t *testing.T) {
function TestParseVulnerabilitiesEntry (line 31) | func TestParseVulnerabilitiesEntry(t *testing.T) {
function TestParseVulnerabilitiesAllEntries (line 798) | func TestParseVulnerabilitiesAllEntries(t *testing.T) {
FILE: grype/db/v5/build/transformers/vulnerability_metadata.go
type VendorBaseMetrics (line 5) | type VendorBaseMetrics struct
FILE: grype/db/v5/build/writer.go
constant nvdNamespace (line 27) | nvdNamespace = "nvd:cpe"
constant providerMetadataFileName (line 28) | providerMetadataFileName = "provider-metadata.json"
type writer (line 33) | type writer struct
method Write (line 81) | func (w *writer) Write(entries ...data.Entry) error {
method addToBatch (line 123) | func (w *writer) addToBatch(op func() error) error {
method Flush (line 136) | func (w *writer) Flush() error {
method flushUnlocked (line 143) | func (w *writer) flushUnlocked() error {
method metadataAndClose (line 168) | func (w *writer) metadataAndClose() (*distribution.Metadata, error) {
method ProviderMetadata (line 193) | func (w *writer) ProviderMetadata() *ProviderMetadata {
method Close (line 205) | func (w *writer) Close() error {
type ProviderMetadata (line 47) | type ProviderMetadata struct
method Write (line 264) | func (p ProviderMetadata) Write(path string) error {
type Provider (line 51) | type Provider struct
function NewWriter (line 56) | func NewWriter(directory string, dataAge time.Time, states provider.Stat...
function NewProviderMetadata (line 187) | func NewProviderMetadata() ProviderMetadata {
function normalizeSeverity (line 236) | func normalizeSeverity(metadata *db.VulnerabilityMetadata, reader db.Vul...
FILE: grype/db/v5/build/writer_test.go
type mockReader (line 15) | type mockReader struct
method GetVulnerabilityMetadata (line 35) | func (m mockReader) GetVulnerabilityMetadata(_, _ string) (*db.Vulnera...
method GetAllVulnerabilityMetadata (line 39) | func (m mockReader) GetAllVulnerabilityMetadata() (*[]db.Vulnerability...
function newMockReader (line 20) | func newMockReader(sev string) *mockReader {
function newDeadMockReader (line 29) | func newDeadMockReader() *mockReader {
function Test_normalizeSeverity (line 43) | func Test_normalizeSeverity(t *testing.T) {
FILE: grype/db/v5/cvss.go
function NewCvss (line 7) | func NewCvss(m []Cvss) []vulnerability.Cvss {
FILE: grype/db/v5/diff.go
constant DiffAdded (line 6) | DiffAdded DiffReason = "added"
constant DiffChanged (line 7) | DiffChanged DiffReason = "changed"
constant DiffRemoved (line 8) | DiffRemoved DiffReason = "removed"
type Diff (line 11) | type Diff struct
FILE: grype/db/v5/differ/differ.go
type Differ (line 23) | type Differ struct
method SetBaseDB (line 55) | func (d *Differ) SetBaseDB(base string) error {
method SetTargetDB (line 59) | func (d *Differ) SetTargetDB(target string) error {
method setOrDownload (line 63) | func (d *Differ) setOrDownload(curator *legacyDistribution.Curator, fi...
method DiffDatabases (line 127) | func (d *Differ) DiffDatabases() (*[]v5.Diff, error) {
method DeleteDatabases (line 145) | func (d *Differ) DeleteDatabases() error {
method Present (line 155) | func (d *Differ) Present(outputFormat string, diff *[]v5.Diff, output ...
function NewDiffer (line 28) | func NewDiffer(config legacyDistribution.Config) (*Differ, error) {
function download (line 103) | func download(curator *legacyDistribution.Curator, listing *legacyDistri...
function newTable (line 186) | func newTable(output io.Writer, columns []string) *tablewriter.Table {
FILE: grype/db/v5/differ/differ_test.go
function TestNewDiffer (line 19) | func TestNewDiffer(t *testing.T) {
function Test_DifferDirectory (line 31) | func Test_DifferDirectory(t *testing.T) {
function TestPresent_Json (line 50) | func TestPresent_Json(t *testing.T) {
function TestPresent_Table (line 76) | func TestPresent_Table(t *testing.T) {
function TestPresent_Invalid (line 102) | func TestPresent_Invalid(t *testing.T) {
FILE: grype/db/v5/distribution/curator.go
constant FileName (line 33) | FileName = v5.VulnerabilityStoreFileName
constant lastUpdateCheckFileName (line 34) | lastUpdateCheckFileName = "last_update_check"
type Config (line 37) | type Config struct
type Curator (line 51) | type Curator struct
method SupportedSchema (line 98) | func (c Curator) SupportedSchema() int {
method GetStore (line 102) | func (c *Curator) GetStore() (v5.StoreReader, error) {
method Status (line 112) | func (c *Curator) Status() Status {
method Delete (line 135) | func (c *Curator) Delete() error {
method Update (line 140) | func (c *Curator) Update() (bool, error) { // nolint: funlen
method isUpdateCheckAllowed (line 215) | func (c Curator) isUpdateCheckAllowed() bool {
method durationSinceUpdateCheck (line 235) | func (c Curator) durationSinceUpdateCheck() (*time.Duration, error) {
method setLastSuccessfulUpdateCheck (line 272) | func (c Curator) setLastSuccessfulUpdateCheck() {
method IsUpdateAvailable (line 290) | func (c *Curator) IsUpdateAvailable() (bool, *Metadata, *ListingEntry,...
method UpdateTo (line 320) | func (c *Curator) UpdateTo(listing *ListingEntry, downloadProgress, im...
method Validate (line 347) | func (c *Curator) Validate() error {
method ImportFrom (line 357) | func (c *Curator) ImportFrom(dbArchivePath string) error {
method download (line 382) | func (c *Curator) download(listing *ListingEntry, downloadProgress *pr...
method validateStaleness (line 408) | func (c *Curator) validateStaleness(m Metadata) error {
method validateIntegrity (line 425) | func (c *Curator) validateIntegrity(dbDirPath string) (Metadata, error) {
method activate (line 456) | func (c *Curator) activate(dbDirPath string) error {
method ListingFromURL (line 477) | func (c Curator) ListingFromURL() (Listing, error) {
function NewCurator (line 66) | func NewCurator(cfg Config) (Curator, error) {
function defaultHTTPClient (line 504) | func defaultHTTPClient(fs afero.Fs, caCertPath string) (*http.Client, er...
function unarchive (line 524) | func unarchive(source, destination string) error {
FILE: grype/db/v5/distribution/curator_test.go
type testGetter (line 39) | type testGetter struct
method GetFile (line 56) | func (g *testGetter) GetFile(dst, src string, _ ...*progress.Manual) e...
method GetToDir (line 65) | func (g *testGetter) GetToDir(dst, src string, _ ...*progress.Manual) ...
function newTestGetter (line 46) | func newTestGetter(fs afero.Fs, f, d map[string]string) *testGetter {
function newTestCurator (line 73) | func newTestCurator(tb testing.TB, fs afero.Fs, getter file.Getter, dbDi...
function Test_defaultHTTPClientHasCert (line 89) | func Test_defaultHTTPClientHasCert(t *testing.T) {
function Test_defaultHTTPClientTimeout (line 124) | func Test_defaultHTTPClientTimeout(t *testing.T) {
function generateCertFixture (line 130) | func generateCertFixture(t *testing.T) string {
function TestCuratorDownload (line 191) | func TestCuratorDownload(t *testing.T) {
function TestCuratorValidate (line 247) | func TestCuratorValidate(t *testing.T) {
function TestCuratorDBPathHasSchemaVersion (line 314) | func TestCuratorDBPathHasSchemaVersion(t *testing.T) {
function TestCurator_validateStaleness (line 323) | func TestCurator_validateStaleness(t *testing.T) {
function Test_requireUpdateCheck (line 385) | func Test_requireUpdateCheck(t *testing.T) {
function TestCuratorTimeoutBehavior (line 550) | func TestCuratorTimeoutBehavior(t *testing.T) {
function TestCurator_IsUpdateCheckAllowed (line 624) | func TestCurator_IsUpdateCheckAllowed(t *testing.T) {
function TestCurator_DurationSinceUpdateCheck (line 656) | func TestCurator_DurationSinceUpdateCheck(t *testing.T) {
function TestCurator_SetLastSuccessfulUpdateCheck (line 701) | func TestCurator_SetLastSuccessfulUpdateCheck(t *testing.T) {
type MockGetter (line 730) | type MockGetter struct
method GetFile (line 734) | func (m *MockGetter) GetFile(dst, src string, monitor ...*progress.Man...
method GetToDir (line 739) | func (m *MockGetter) GetToDir(dst, src string, monitor ...*progress.Ma...
function TestCurator_Update_setLastSuccessfulUpdateCheck_notCalled (line 744) | func TestCurator_Update_setLastSuccessfulUpdateCheck_notCalled(t *testin...
function Test_unarchive (line 771) | func Test_unarchive(t *testing.T) {
FILE: grype/db/v5/distribution/listing.go
constant ListingFileName (line 12) | ListingFileName = "listing.json"
type Listing (line 16) | type Listing struct
method BestUpdate (line 69) | func (l *Listing) BestUpdate(targetSchema int) *ListingEntry {
method Write (line 79) | func (l Listing) Write(toPath string) error {
function NewListing (line 21) | func NewListing(entries ...ListingEntry) Listing {
function NewListingFromFile (line 44) | func NewListingFromFile(fs afero.Fs, path string) (Listing, error) {
FILE: grype/db/v5/distribution/listing_entry.go
type ListingEntry (line 19) | type ListingEntry struct
method UnmarshalJSON (line 73) | func (l *ListingEntry) UnmarshalJSON(data []byte) error {
method MarshalJSON (line 86) | func (l *ListingEntry) MarshalJSON() ([]byte, error) {
method String (line 95) | func (l ListingEntry) String() string {
type ListingEntryJSON (line 27) | type ListingEntryJSON struct
method ToListingEntry (line 54) | func (l ListingEntryJSON) ToListingEntry() (ListingEntry, error) {
function NewListingEntryFromArchive (line 35) | func NewListingEntryFromArchive(fs afero.Fs, metadata Metadata, dbArchiv...
FILE: grype/db/v5/distribution/listing_test.go
function mustUrl (line 12) | func mustUrl(u *url.URL, err error) *url.URL {
function TestNewListingFromPath (line 19) | func TestNewListingFromPath(t *testing.T) {
function TestListingBestUpdate (line 108) | func TestListingBestUpdate(t *testing.T) {
FILE: grype/db/v5/distribution/metadata.go
constant MetadataFileName (line 16) | MetadataFileName = "metadata.json"
type Metadata (line 20) | type Metadata struct
method UnmarshalJSON (line 77) | func (m *Metadata) UnmarshalJSON(data []byte) error {
method IsSupersededBy (line 92) | func (m *Metadata) IsSupersededBy(entry *ListingEntry) bool {
method String (line 115) | func (m Metadata) String() string {
method Write (line 120) | func (m Metadata) Write(toPath string) error {
type MetadataJSON (line 27) | type MetadataJSON struct
method ToMetadata (line 34) | func (m MetadataJSON) ToMetadata() (Metadata, error) {
function metadataPath (line 49) | func metadataPath(dir string) string {
function NewMetadataFromDir (line 54) | func NewMetadataFromDir(fs afero.Fs, dir string) (*Metadata, error) {
FILE: grype/db/v5/distribution/metadata_test.go
function TestMetadataParse (line 11) | func TestMetadataParse(t *testing.T) {
function TestMetadataIsSupercededBy (line 59) | func TestMetadataIsSupercededBy(t *testing.T) {
FILE: grype/db/v5/distribution/status.go
type Status (line 5) | type Status struct
method Status (line 13) | func (s Status) Status() string {
FILE: grype/db/v5/distribution/testdata/tls/serve.py
class Handler (line 9) | class Handler(SimpleHTTPRequestHandler):
method __init__ (line 10) | def __init__(self, *args, **kwargs):
method do_GET (line 13) | def do_GET(self):
FILE: grype/db/v5/fix.go
type FixState (line 3) | type FixState
constant UnknownFixState (line 6) | UnknownFixState FixState = "unknown"
constant FixedState (line 7) | FixedState FixState = "fixed"
constant NotFixedState (line 8) | NotFixedState FixState = "not-fixed"
constant WontFixState (line 9) | WontFixState FixState = "wont-fix"
type Fix (line 13) | type Fix struct
FILE: grype/db/v5/id.go
type ID (line 8) | type ID struct
type IDReader (line 15) | type IDReader interface
type IDWriter (line 19) | type IDWriter interface
function NewID (line 23) | func NewID(age time.Time) ID {
FILE: grype/db/v5/match_exclusion_provider.go
type MatchExclusionProvider (line 11) | type MatchExclusionProvider struct
method IgnoreRules (line 47) | func (pr *MatchExclusionProvider) IgnoreRules(vulnerabilityID string) ...
function NewMatchExclusionProvider (line 15) | func NewMatchExclusionProvider(reader VulnerabilityMatchExclusionStoreRe...
function buildIgnoreRulesFromMatchExclusion (line 21) | func buildIgnoreRulesFromMatchExclusion(e VulnerabilityMatchExclusion) [...
FILE: grype/db/v5/namespace/cpe/namespace.go
constant ID (line 12) | ID = "cpe"
type Namespace (line 14) | type Namespace struct
method Provider (line 47) | func (n *Namespace) Provider() string {
method Resolver (line 51) | func (n *Namespace) Resolver() resolver.Resolver {
method String (line 55) | func (n Namespace) String() string {
function NewNamespace (line 19) | func NewNamespace(provider string) *Namespace {
function FromString (line 26) | func FromString(namespaceStr string) (*Namespace, error) {
function FromComponents (line 35) | func FromComponents(components []string) (*Namespace, error) {
FILE: grype/db/v5/namespace/cpe/namespace_test.go
function TestFromString (line 9) | func TestFromString(t *testing.T) {
FILE: grype/db/v5/namespace/distro/namespace.go
constant ID (line 13) | ID = "distro"
type Namespace (line 15) | type Namespace struct
method Provider (line 52) | func (n *Namespace) Provider() string {
method DistroType (line 56) | func (n *Namespace) DistroType() distro.Type {
method Version (line 60) | func (n *Namespace) Version() string {
method Resolver (line 64) | func (n *Namespace) Resolver() resolver.Resolver {
method String (line 68) | func (n Namespace) String() string {
function NewNamespace (line 22) | func NewNamespace(provider string, distroType distro.Type, version strin...
function FromString (line 31) | func FromString(namespaceStr string) (*Namespace, error) {
function FromComponents (line 40) | func FromComponents(components []string) (*Namespace, error) {
FILE: grype/db/v5/namespace/distro/namespace_test.go
function TestFromString (line 11) | func TestFromString(t *testing.T) {
FILE: grype/db/v5/namespace/from_string.go
function FromString (line 13) | func FromString(namespaceStr string) (Namespace, error) {
FILE: grype/db/v5/namespace/from_string_test.go
function TestFromString (line 15) | func TestFromString(t *testing.T) {
FILE: grype/db/v5/namespace/language/namespace.go
constant ID (line 12) | ID = "language"
type Namespace (line 14) | type Namespace struct
method Provider (line 59) | func (n *Namespace) Provider() string {
method Language (line 63) | func (n *Namespace) Language() syftPkg.Language {
method PackageType (line 67) | func (n *Namespace) PackageType() syftPkg.Type {
method Resolver (line 71) | func (n *Namespace) Resolver() resolver.Resolver {
method String (line 75) | func (n Namespace) String() string {
function NewNamespace (line 21) | func NewNamespace(provider string, language syftPkg.Language, packageTyp...
function FromString (line 32) | func FromString(namespaceStr string) (*Namespace, error) {
function FromComponents (line 41) | func FromComponents(components []string) (*Namespace, error) {
FILE: grype/db/v5/namespace/language/namespace_test.go
function TestFromString (line 11) | func TestFromString(t *testing.T) {
FILE: grype/db/v5/namespace/namespace.go
type Namespace (line 7) | type Namespace interface
FILE: grype/db/v5/pkg/qualifier/from_json.go
function FromJSON (line 13) | func FromJSON(data []byte) ([]Qualifier, error) {
FILE: grype/db/v5/pkg/qualifier/platformcpe/qualifier.go
type Qualifier (line 10) | type Qualifier struct
method Parse (line 15) | func (q Qualifier) Parse() qualifier.Qualifier {
method String (line 19) | func (q Qualifier) String() string {
FILE: grype/db/v5/pkg/qualifier/qualifier.go
type Qualifier (line 9) | type Qualifier interface
FILE: grype/db/v5/pkg/qualifier/rpmmodularity/qualifier.go
type Qualifier (line 10) | type Qualifier struct
method Parse (line 15) | func (q Qualifier) Parse() qualifier.Qualifier {
method String (line 19) | func (q Qualifier) String() string {
FILE: grype/db/v5/pkg/resolver/java/resolver.go
type Resolver (line 13) | type Resolver struct
method Normalize (line 16) | func (r *Resolver) Normalize(name string) string {
method Resolve (line 20) | func (r *Resolver) Resolve(p grypePkg.Package) []string {
FILE: grype/db/v5/pkg/resolver/java/resolver_test.go
function TestResolver_Normalize (line 12) | func TestResolver_Normalize(t *testing.T) {
function TestResolver_Resolve (line 49) | func TestResolver_Resolve(t *testing.T) {
FILE: grype/db/v5/pkg/resolver/python/resolver.go
type Resolver (line 10) | type Resolver struct
method Normalize (line 13) | func (r *Resolver) Normalize(name string) string {
method Resolve (line 22) | func (r *Resolver) Resolve(p grypePkg.Package) []string {
FILE: grype/db/v5/pkg/resolver/python/resolver_test.go
function TestResolver_Normalize (line 9) | func TestResolver_Normalize(t *testing.T) {
FILE: grype/db/v5/pkg/resolver/resolver.go
type Resolver (line 11) | type Resolver interface
function FromLanguage (line 16) | func FromLanguage(language syftPkg.Language) (Resolver, error) {
function PackageNames (line 31) | func PackageNames(p grypePkg.Package) []string {
FILE: grype/db/v5/pkg/resolver/resolver_test.go
function TestFromLanguage (line 14) | func TestFromLanguage(t *testing.T) {
FILE: grype/db/v5/pkg/resolver/stock/resolver.go
type Resolver (line 9) | type Resolver struct
method Normalize (line 12) | func (r *Resolver) Normalize(name string) string {
method Resolve (line 16) | func (r *Resolver) Resolve(p grypePkg.Package) []string {
FILE: grype/db/v5/pkg/resolver/stock/resolver_test.go
function TestResolver_Normalize (line 9) | func TestResolver_Normalize(t *testing.T) {
FILE: grype/db/v5/provider_store.go
type ProviderStore (line 8) | type ProviderStore struct
FILE: grype/db/v5/schema_version.go
constant SchemaVersion (line 3) | SchemaVersion = 5
FILE: grype/db/v5/store.go
type Store (line 5) | type Store interface
type StoreReader (line 10) | type StoreReader interface
type StoreWriter (line 19) | type StoreWriter interface
type DiffReader (line 27) | type DiffReader interface
FILE: grype/db/v5/store/diff.go
type storeKey (line 13) | type storeKey struct
type storeVulnerabilityList (line 21) | type storeVulnerabilityList struct
type storeVulnerability (line 25) | type storeVulnerability struct
type storeMetadata (line 29) | type storeMetadata struct
function trackDiff (line 35) | func trackDiff(total int64) (*progress.Manual, *progress.Manual, *progre...
function buildVulnerabilityPkgsMap (line 53) | func buildVulnerabilityPkgsMap(models *[]v5.Vulnerability) *map[storeKey...
function createDiff (line 69) | func createDiff(baseStore, targetStore *PkgMap, key storeKey, reason v5....
function getVulnerabilityParentKey (line 101) | func getVulnerabilityParentKey(vuln v5.Vulnerability) storeKey {
function getVulnerabilityKey (line 106) | func getVulnerabilityKey(vuln v5.Vulnerability) storeKey {
type VulnerabilitySet (line 110) | type VulnerabilitySet struct
method in (line 143) | func (v *VulnerabilitySet) in(item v5.Vulnerability) bool {
method match (line 148) | func (v *VulnerabilitySet) match(item v5.Vulnerability) bool {
method getUnmatched (line 164) | func (v *VulnerabilitySet) getUnmatched() ([]storeKey, []storeKey) {
function NewVulnerabilitySet (line 114) | func NewVulnerabilitySet(models *[]v5.Vulnerability) *VulnerabilitySet {
function diffVulnerabilities (line 185) | func diffVulnerabilities(baseModels, targetModels *[]v5.Vulnerability, b...
type MetadataSet (line 228) | type MetadataSet struct
method in (line 246) | func (v *MetadataSet) in(item v5.VulnerabilityMetadata) bool {
method match (line 251) | func (v *MetadataSet) match(item v5.VulnerabilityMetadata) bool {
method getUnmatched (line 259) | func (v *MetadataSet) getUnmatched() []storeKey {
function NewMetadataSet (line 232) | func NewMetadataSet(models *[]v5.VulnerabilityMetadata) *MetadataSet {
function diffVulnerabilityMetadata (line 269) | func diffVulnerabilityMetadata(baseModels, targetModels *[]v5.Vulnerabil...
function getMetadataKey (line 303) | func getMetadataKey(metadata v5.VulnerabilityMetadata) storeKey {
FILE: grype/db/v5/store/diff_test.go
function Test_GetAllVulnerabilities (line 13) | func Test_GetAllVulnerabilities(t *testing.T) {
function Test_GetAllVulnerabilityMetadata (line 30) | func Test_GetAllVulnerabilityMetadata(t *testing.T) {
function Test_Diff_Vulnerabilities (line 49) | func Test_Diff_Vulnerabilities(t *testing.T) {
function Test_Diff_Metadata (line 155) | func Test_Diff_Metadata(t *testing.T) {
FILE: grype/db/v5/store/model/id.go
constant IDTableName (line 11) | IDTableName = "id"
type IDModel (line 14) | type IDModel struct
method TableName (line 26) | func (IDModel) TableName() string {
method Inflate (line 30) | func (m *IDModel) Inflate() (v5.ID, error) {
function NewIDModel (line 19) | func NewIDModel(id v5.ID) IDModel {
FILE: grype/db/v5/store/model/vulnerability.go
constant VulnerabilityTableName (line 13) | VulnerabilityTableName = "vulnerability"
constant GetVulnerabilityIndexName (line 14) | GetVulnerabilityIndexName = "get_vulnerability_index"
type VulnerabilityModel (line 18) | type VulnerabilityModel struct
method TableName (line 51) | func (VulnerabilityModel) TableName() string {
method Inflate (line 56) | func (m *VulnerabilityModel) Inflate() (v5.Vulnerability, error) {
function NewVulnerabilityModel (line 34) | func NewVulnerabilityModel(vulnerability v5.Vulnerability) Vulnerability...
FILE: grype/db/v5/store/model/vulnerability_match_exclusion.go
constant VulnerabilityMatchExclusionTableName (line 13) | VulnerabilityMatchExclusionTableName = "vulnerability_match_exclusion"
constant GetVulnerabilityMatchExclusionIndexName (line 14) | GetVulnerabilityMatchExclusionIndexName = "get_vulnerability_match_exclu...
type VulnerabilityMatchExclusionModel (line 18) | type VulnerabilityMatchExclusionModel struct
method TableName (line 35) | func (VulnerabilityMatchExclusionModel) TableName() string {
method Inflate (line 40) | func (m *VulnerabilityMatchExclusionModel) Inflate() (*v5.Vulnerabilit...
function NewVulnerabilityMatchExclusionModel (line 26) | func NewVulnerabilityMatchExclusionModel(v v5.VulnerabilityMatchExclusio...
FILE: grype/db/v5/store/model/vulnerability_match_exclusion_test.go
function TestVulnerabilityMatchExclusionModel_Inflate (line 12) | func TestVulnerabilityMatchExclusionModel_Inflate(t *testing.T) {
FILE: grype/db/v5/store/model/vulnerability_metadata.go
constant VulnerabilityMetadataTableName (line 12) | VulnerabilityMetadataTableName = "vulnerability_metadata"
type VulnerabilityMetadataModel (line 16) | type VulnerabilityMetadataModel struct
method TableName (line 46) | func (VulnerabilityMetadataModel) TableName() string {
method Inflate (line 51) | func (m *VulnerabilityMetadataModel) Inflate() (v5.VulnerabilityMetada...
function NewVulnerabilityMetadataModel (line 28) | func NewVulnerabilityMetadataModel(metadata v5.VulnerabilityMetadata) Vu...
FILE: grype/db/v5/store/model/vulnerability_test.go
function TestVulnerabilityModel_Inflate (line 15) | func TestVulnerabilityModel_Inflate(t *testing.T) {
FILE: grype/db/v5/store/store.go
type store (line 19) | type store struct
method GetID (line 45) | func (s *store) GetID() (*v5.ID, error) {
method SetID (line 67) | func (s *store) SetID(id v5.ID) error {
method GetVulnerabilityNamespaces (line 84) | func (s *store) GetVulnerabilityNamespaces() ([]string, error) {
method GetVulnerability (line 91) | func (s *store) GetVulnerability(namespace, id string) ([]v5.Vulnerabi...
method SearchForVulnerabilities (line 115) | func (s *store) SearchForVulnerabilities(namespace, packageName string...
method AddVulnerability (line 133) | func (s *store) AddVulnerability(vulnerabilities ...v5.Vulnerability) ...
method GetVulnerabilityMetadata (line 150) | func (s *store) GetVulnerabilityMetadata(id, namespace string) (*v5.Vu...
method AddVulnerabilityMetadata (line 176) | func (s *store) AddVulnerabilityMetadata(metadata ...v5.VulnerabilityM...
method GetVulnerabilityMatchExclusion (line 243) | func (s *store) GetVulnerabilityMatchExclusion(id string) ([]v5.Vulner...
method AddVulnerabilityMatchExclusion (line 264) | func (s *store) AddVulnerabilityMatchExclusion(exclusions ...v5.Vulner...
method Close (line 281) | func (s *store) Close() error {
method GetAllVulnerabilities (line 313) | func (s *store) GetAllVulnerabilities() (*[]v5.Vulnerability, error) {
method GetAllVulnerabilityMetadata (line 330) | func (s *store) GetAllVulnerabilityMetadata() (*[]v5.VulnerabilityMeta...
method DiffStore (line 347) | func (s *store) DiffStore(targetStore v5.StoreReader) (*[]v5.Diff, err...
function models (line 23) | func models() []any {
function New (line 33) | func New(dbFilePath string, overwrite bool) (v5.Store, error) {
FILE: grype/db/v5/store/store_test.go
function assertIDReader (line 16) | func assertIDReader(t *testing.T, reader v5.IDReader, expected v5.ID) {
function TestStore_GetID_SetID (line 30) | func TestStore_GetID_SetID(t *testing.T) {
function assertVulnerabilityReader (line 51) | func assertVulnerabilityReader(t *testing.T, reader v5.VulnerabilityStor...
function TestStore_GetVulnerability_SetVulnerability (line 69) | func TestStore_GetVulnerability_SetVulnerability(t *testing.T) {
function assertVulnerabilityMetadataReader (line 212) | func assertVulnerabilityMetadataReader(t *testing.T, reader v5.Vulnerabi...
function sortMetadataCvss (line 249) | func sortMetadataCvss(cvss []v5.Cvss) {
type CustomMetadata (line 266) | type CustomMetadata struct
function TestStore_GetVulnerabilityMetadata_SetVulnerabilityMetadata (line 271) | func TestStore_GetVulnerabilityMetadata_SetVulnerabilityMetadata(t *test...
function TestStore_MergeVulnerabilityMetadata (line 355) | func TestStore_MergeVulnerabilityMetadata(t *testing.T) {
function TestCvssScoresInMetadata (line 790) | func TestCvssScoresInMetadata(t *testing.T) {
function assertVulnerabilityMatchExclusionReader (line 1038) | func assertVulnerabilityMatchExclusionReader(t *testing.T, reader v5.Vul...
function TestStore_GetVulnerabilityMatchExclusion_SetVulnerabilityMatchExclusion (line 1057) | func TestStore_GetVulnerabilityMatchExclusion_SetVulnerabilityMatchExclu...
function Test_DiffStore (line 1213) | func Test_DiffStore(t *testing.T) {
FILE: grype/db/v5/vulnerability.go
type Vulnerability (line 17) | type Vulnerability struct
method Equal (line 36) | func (v *Vulnerability) Equal(vv Vulnerability) bool {
type VulnerabilityReference (line 30) | type VulnerabilityReference struct
function sortRelatedVulns (line 91) | func sortRelatedVulns(vulns []VulnerabilityReference) []VulnerabilityRef...
function sortAdvisories (line 103) | func sortAdvisories(advisories []Advisory) []Advisory {
function sortPackageQualifiers (line 115) | func sortPackageQualifiers(qualifiers []qualifierV5.Qualifier) []qualifi...
function NewVulnerability (line 122) | func NewVulnerability(vuln Vulnerability) (*vulnerability.Vulnerability,...
FILE: grype/db/v5/vulnerability_match_exclusion.go
type VulnerabilityMatchExclusion (line 9) | type VulnerabilityMatchExclusion struct
type VulnerabilityMatchExclusionConstraint (line 16) | type VulnerabilityMatchExclusionConstraint struct
method Usable (line 22) | func (c VulnerabilityMatchExclusionConstraint) Usable() bool {
method UnmarshalJSON (line 26) | func (c *VulnerabilityMatchExclusionConstraint) UnmarshalJSON(data []b...
type VulnerabilityExclusionConstraint (line 53) | type VulnerabilityExclusionConstraint struct
method Usable (line 59) | func (v VulnerabilityExclusionConstraint) Usable() bool {
method UnmarshalJSON (line 63) | func (v *VulnerabilityExclusionConstraint) UnmarshalJSON(data []byte) ...
type PackageExclusionConstraint (line 90) | type PackageExclusionConstraint struct
method Usable (line 99) | func (p PackageExclusionConstraint) Usable() bool {
method UnmarshalJSON (line 103) | func (p *PackageExclusionConstraint) UnmarshalJSON(data []byte) error {
FILE: grype/db/v5/vulnerability_match_exclusion_store.go
type VulnerabilityMatchExclusionStore (line 3) | type VulnerabilityMatchExclusionStore interface
type VulnerabilityMatchExclusionStoreReader (line 8) | type VulnerabilityMatchExclusionStoreReader interface
type VulnerabilityMatchExclusionStoreWriter (line 12) | type VulnerabilityMatchExclusionStoreWriter interface
FILE: grype/db/v5/vulnerability_metadata.go
type VulnerabilityMetadata (line 10) | type VulnerabilityMetadata struct
method Equal (line 57) | func (v *VulnerabilityMetadata) Equal(vv VulnerabilityMetadata) bool {
type Cvss (line 22) | type Cvss struct
type CvssMetrics (line 35) | type CvssMetrics struct
function NewCvssMetrics (line 49) | func NewCvssMetrics(baseScore, exploitabilityScore, impactScore float64)...
function NewMetadata (line 84) | func NewMetadata(m *VulnerabilityMetadata) (*vulnerability.Metadata, err...
FILE: grype/db/v5/vulnerability_metadata_store.go
type VulnerabilityMetadataStore (line 3) | type VulnerabilityMetadataStore interface
type VulnerabilityMetadataStoreReader (line 8) | type VulnerabilityMetadataStoreReader interface
type VulnerabilityMetadataStoreWriter (line 13) | type VulnerabilityMetadataStoreWriter interface
FILE: grype/db/v5/vulnerability_store.go
constant VulnerabilityStoreFileName (line 3) | VulnerabilityStoreFileName = "vulnerability.db"
type VulnerabilityStore (line 5) | type VulnerabilityStore interface
type VulnerabilityStoreReader (line 10) | type VulnerabilityStoreReader interface
type VulnerabilityStoreWriter (line 20) | type VulnerabilityStoreWriter interface
FILE: grype/db/v6/affected_cpe_store.go
type AffectedCPEStoreWriter (line 9) | type AffectedCPEStoreWriter interface
type AffectedCPEStoreReader (line 13) | type AffectedCPEStoreReader interface
type affectedCPEStore (line 17) | type affectedCPEStore struct
method AddAffectedCPEs (line 31) | func (s *affectedCPEStore) AddAffectedCPEs(packages ...*AffectedCPEHan...
method GetAffectedCPEs (line 35) | func (s *affectedCPEStore) GetAffectedCPEs(cpe *cpe.Attributes, config...
function newAffectedCPEStore (line 23) | func newAffectedCPEStore(db *gorm.DB, bs *blobStore) *affectedCPEStore {
FILE: grype/db/v6/affected_cpe_store_test.go
function TestAffectedCPEStore_AddAffectedCPEs (line 13) | func TestAffectedCPEStore_AddAffectedCPEs(t *testing.T) {
function TestAffectedCPEStore_GetCPEs (line 58) | func TestAffectedCPEStore_GetCPEs(t *testing.T) {
function TestAffectedCPEStore_GetExact (line 89) | func TestAffectedCPEStore_GetExact(t *testing.T) {
function TestAffectedCPEStore_Get_CaseInsensitive (line 109) | func TestAffectedCPEStore_Get_CaseInsensitive(t *testing.T) {
function TestAffectedCPEStore_PreventDuplicateCPEs (line 138) | func TestAffectedCPEStore_PreventDuplicateCPEs(t *testing.T) {
function cpeFromProduct (line 213) | func cpeFromProduct(product string) *cpe.Attributes {
function toCPE (line 219) | func toCPE(c *Cpe) *cpe.Attributes {
function testAffectedCPEHandle (line 233) | func testAffectedCPEHandle() *AffectedCPEHandle {
FILE: grype/db/v6/affected_package_store.go
type AffectedPackageStoreWriter (line 5) | type AffectedPackageStoreWriter interface
type AffectedPackageStoreReader (line 9) | type AffectedPackageStoreReader interface
type affectedPackageStore (line 13) | type affectedPackageStore struct
method AddAffectedPackages (line 27) | func (s *affectedPackageStore) AddAffectedPackages(packages ...*Affect...
method GetAffectedPackages (line 31) | func (s *affectedPackageStore) GetAffectedPackages(pkg *PackageSpecifi...
function newAffectedPackageStore (line 19) | func newAffectedPackageStore(db *gorm.DB, bs *blobStore, oss *operatingS...
FILE: grype/db/v6/affected_package_store_test.go
type affectedPackageHandlePreloadConfig (line 16) | type affectedPackageHandlePreloadConfig struct
function defaultAffectedPackageHandlePreloadCases (line 25) | func defaultAffectedPackageHandlePreloadCases() []affectedPackageHandleP...
function TestAffectedPackageStore_AddAffectedPackages (line 137) | func TestAffectedPackageStore_AddAffectedPackages(t *testing.T) {
function TestAffectedPackageStore_GetAffectedPackages_ByCPE (line 431) | func TestAffectedPackageStore_GetAffectedPackages_ByCPE(t *testing.T) {
function TestAffectedPackageStore_GetAffectedPackages_CaseInsensitive (line 597) | func TestAffectedPackageStore_GetAffectedPackages_CaseInsensitive(t *tes...
function TestAffectedPackageStore_GetAffectedPackages_MultipleVulnerabilitySpecs (line 737) | func TestAffectedPackageStore_GetAffectedPackages_MultipleVulnerabilityS...
function TestAffectedPackageStore_GetAffectedPackages (line 793) | func TestAffectedPackageStore_GetAffectedPackages(t *testing.T) {
function TestAffectedPackageStore_ApplyPackageAlias (line 948) | func TestAffectedPackageStore_ApplyPackageAlias(t *testing.T) {
function testDistro1AffectedPackage2Handle (line 988) | func testDistro1AffectedPackage2Handle() *AffectedPackageHandle {
function testDistro2AffectedPackage2Handle (line 1017) | func testDistro2AffectedPackage2Handle() *AffectedPackageHandle {
function testNonDistroAffectedPackage2Handle (line 1045) | func testNonDistroAffectedPackage2Handle() *AffectedPackageHandle {
function expectErrIs (line 1067) | func expectErrIs(t *testing.T, expected error) require.ErrorAssertionFunc {
function pkgFromName (line 1075) | func pkgFromName(name string) *PackageSpecifier {
FILE: grype/db/v6/blob_store.go
type blobable (line 14) | type blobable interface
type blobStore (line 21) | type blobStore struct
method addBlobable (line 33) | func (s *blobStore) addBlobable(bs ...blobable) error {
method addBlobs (line 51) | func (s *blobStore) addBlobs(blobs ...*Blob) error {
method getBlobValues (line 72) | func (s *blobStore) getBlobValues(ids ...ID) ([]Blob, error) {
method attachBlobValue (line 83) | func (s *blobStore) attachBlobValue(bs ...blobable) error {
function newBlobStore (line 26) | func newBlobStore(db *gorm.DB) *blobStore {
function newBlob (line 123) | func newBlob(obj any) *Blob {
FILE: grype/db/v6/blob_store_test.go
function TestBlobWriter_AddBlobs (line 10) | func TestBlobWriter_AddBlobs(t *testing.T) {
function TestBlob_computeDigest (line 36) | func TestBlob_computeDigest(t *testing.T) {
FILE: grype/db/v6/blobs.go
type VulnerabilityBlob (line 11) | type VulnerabilityBlob struct
method String (line 31) | func (v VulnerabilityBlob) String() string {
type Reference (line 36) | type Reference struct
type Severity (line 48) | type Severity struct
method UnmarshalJSON (line 71) | func (s *Severity) UnmarshalJSON(data []byte) error {
type severityAlias (line 63) | type severityAlias
type severityUnmarshalProxy (line 65) | type severityUnmarshalProxy struct
type CVSSSeverity (line 96) | type CVSSSeverity struct
method String (line 104) | func (c CVSSSeverity) String() string {
type PackageBlob (line 113) | type PackageBlob struct
method String (line 124) | func (a PackageBlob) String() string {
type PackageQualifiers (line 143) | type PackageQualifiers struct
type Range (line 152) | type Range struct
method String (line 160) | func (a Range) String() string {
type Fix (line 165) | type Fix struct
method String (line 176) | func (f Fix) String() string {
type FixDetail (line 187) | type FixDetail struct
type FixAvailability (line 195) | type FixAvailability struct
method MarshalJSON (line 203) | func (f FixAvailability) MarshalJSON() ([]byte, error) {
method UnmarshalJSON (line 221) | func (f *FixAvailability) UnmarshalJSON(data []byte) error {
type Version (line 252) | type Version struct
type KnownExploitedVulnerabilityBlob (line 260) | type KnownExploitedVulnerabilityBlob struct
FILE: grype/db/v6/blobs_test.go
function TestFixAvailability_MarshalJSON (line 12) | func TestFixAvailability_MarshalJSON(t *testing.T) {
function TestFixAvailability_UnmarshalJSON_SimpleDateFormat (line 27) | func TestFixAvailability_UnmarshalJSON_SimpleDateFormat(t *testing.T) {
function TestFixAvailability_UnmarshalJSON_RFC3339Format (line 39) | func TestFixAvailability_UnmarshalJSON_RFC3339Format(t *testing.T) {
function TestFixAvailability_RoundTripMarshalUnmarshal (line 51) | func TestFixAvailability_RoundTripMarshalUnmarshal(t *testing.T) {
function TestPackageBlob_WithFixAvailability (line 72) | func TestPackageBlob_WithFixAvailability(t *testing.T) {
function TestFixAvailability_UnmarshalJSON_InvalidDateFormat (line 116) | func TestFixAvailability_UnmarshalJSON_InvalidDateFormat(t *testing.T) {
FILE: grype/db/v6/build/archive.go
function CreateArchive (line 19) | func CreateArchive(dbDir, overrideArchiveExtension string, compressorCom...
function toProviders (line 83) | func toProviders(states []v6.Provider) provider.States {
function resolveExtension (line 94) | func resolveExtension(overrideArchiveExtension string) (string, error) {
function populateTar (line 115) | func populateTar(dbDir, tarName string, compressorCommands map[string]st...
function writeLatestDocument (line 147) | func writeLatestDocument(tarPath string, metadata v6.DBMetadata) error {
FILE: grype/db/v6/build/processors.go
type Config (line 19) | type Config struct
type Option (line 23) | type Option
function WithCPEParts (line 25) | func WithCPEParts(included []string) Option {
function WithInferNVDFixVersions (line 31) | func WithInferNVDFixVersions(infer bool) Option {
function NewConfig (line 37) | func NewConfig(options ...Option) Config {
function Processors (line 46) | func Processors(cfg Config) []data.Processor {
FILE: grype/db/v6/build/transformers/entry.go
type RelatedEntries (line 11) | type RelatedEntries struct
method String (line 44) | func (re RelatedEntries) String() string {
function NewEntries (line 17) | func NewEntries(models ...any) []data.Entry {
FILE: grype/db/v6/build/transformers/eol/transform.go
function Transform (line 50) | func Transform(entry unmarshal.EndOfLifeDateRelease, state provider.Stat...
function translateProductName (line 69) | func translateProductName(product string) string {
function getOperatingSystemEOL (line 77) | func getOperatingSystemEOL(entry unmarshal.EndOfLifeDateRelease, distroN...
function parseVersion (line 110) | func parseVersion(cycle string) (major, minor string) {
function normalizeVersion (line 122) | func normalizeVersion(v string) string {
FILE: grype/db/v6/build/transformers/eol/transform_test.go
function TestParseVersion (line 9) | func TestParseVersion(t *testing.T) {
function TestNormalizeVersion (line 75) | func TestNormalizeVersion(t *testing.T) {
function TestTranslateProductName (line 126) | func TestTranslateProductName(t *testing.T) {
FILE: grype/db/v6/build/transformers/epss/transform.go
function Transform (line 15) | func Transform(entry unmarshal.EPSS, state provider.State) ([]data.Entry...
function getEPSS (line 23) | func getEPSS(entry unmarshal.EPSS, date time.Time) db.EpssHandle {
FILE: grype/db/v6/build/transformers/epss/transform_test.go
function TestTransform (line 19) | func TestTransform(t *testing.T) {
function epssSlice (line 84) | func epssSlice(a ...db.EpssHandle) []any {
function loadFixture (line 92) | func loadFixture(t *testing.T, fixturePath string) []unmarshal.EPSS {
FILE: grype/db/v6/build/transformers/github/transform.go
function Transform (line 20) | func Transform(vulnerability unmarshal.GitHubAdvisory, state provider.St...
function getVulnerability (line 32) | func getVulnerability(vuln unmarshal.GitHubAdvisory, state provider.Stat...
function getVulnStatus (line 55) | func getVulnStatus(vuln unmarshal.GitHubAdvisory) db.VulnerabilityStatus {
function getAffectedPackage (line 63) | func getAffectedPackage(vuln unmarshal.GitHubAdvisory) []db.AffectedPack...
function getRanges (line 92) | func getRanges(fixedInEntry unmarshal.GithubFixedIn) ([]db.Range, error) {
function validateAffectedVersion (line 110) | func validateAffectedVersion(v db.Version) error {
function getAffectedVersionFormat (line 130) | func getAffectedVersionFormat(fixedInEntry unmarshal.GithubFixedIn) stri...
function getFix (line 140) | func getFix(fixedInEntry unmarshal.GithubFixedIn) *db.Fix {
function getFixAvailability (line 163) | func getFixAvailability(fixedInEntry unmarshal.GithubFixedIn) *db.FixAva...
type groupIndex (line 180) | type groupIndex struct
function groupFixedIns (line 185) | func groupFixedIns(vuln unmarshal.GitHubAdvisory) map[groupIndex][]unmar...
function getPackageType (line 199) | func getPackageType(ecosystem string) pkg.Type {
function getPackage (line 243) | func getPackage(group groupIndex) *db.Package {
function getSeverities (line 251) | func getSeverities(vulnerability unmarshal.GitHubAdvisory) []db.Severity {
function getAliases (line 291) | func getAliases(vulnerability unmarshal.GitHubAdvisory) (aliases []strin...
function getReferences (line 296) | func getReferences(vulnerability unmarshal.GitHubAdvisory) []db.Reference {
FILE: grype/db/v6/build/transformers/github/transform_test.go
function TestTransform (line 19) | func TestTransform(t *testing.T) {
function TestGetVulnerability (line 72) | func TestGetVulnerability(t *testing.T) {
function TestGetAffectedPackage (line 403) | func TestGetAffectedPackage(t *testing.T) {
function TestGetPackageType (line 625) | func TestGetPackageType(t *testing.T) {
function TestGetRanges (line 670) | func TestGetRanges(t *testing.T) {
function TestGetFixAvailability (line 725) | func TestGetFixAvailability(t *testing.T) {
function TestGetFix (line 794) | func TestGetFix(t *testing.T) {
function loadFixture (line 888) | func loadFixture(t *testing.T, path string) []unmarshal.GitHubAdvisory {
FILE: grype/db/v6/build/transformers/internal/sort.go
type ByAffectedPackage (line 5) | type ByAffectedPackage
method Len (line 7) | func (a ByAffectedPackage) Len() int { return len(a) }
method Swap (line 8) | func (a ByAffectedPackage) Swap(i, j int) { a[i], a[j] = a[j], a[i] }
method Less (line 9) | func (a ByAffectedPackage) Less(i, j int) bool {
type ByUnaffectedPackage (line 13) | type ByUnaffectedPackage
method Len (line 15) | func (a ByUnaffectedPackage) Len() int { return len(a) }
method Swap (line 16) | func (a ByUnaffectedPackage) Swap(i, j int) { a[i], a[j] = a[j], a[i] }
method Less (line 17) | func (a ByUnaffectedPackage) Less(i, j int) bool {
function comparePackageHandles (line 22) | func comparePackageHandles(pkg1 *db.Package, ranges1 []db.Range, pkg2 *d...
FILE: grype/db/v6/build/transformers/internal/time.go
function ParseTime (line 12) | func ParseTime(s string) *time.Time {
FILE: grype/db/v6/build/transformers/internal/time_test.go
function TestParseTime (line 10) | func TestParseTime(t *testing.T) {
FILE: grype/db/v6/build/transformers/kev/transform.go
function Transform (line 17) | func Transform(kev unmarshal.KnownExploitedVulnerability, state provider...
function getKev (line 21) | func getKev(kev unmarshal.KnownExploitedVulnerability) db.KnownExploited...
function getURLs (line 42) | func getURLs(aux []string, notes string) ([]string, string) {
FILE: grype/db/v6/build/transformers/kev/transform_test.go
function TestTransform (line 18) | func TestTransform(t *testing.T) {
function kevSlice (line 97) | func kevSlice(a ...db.KnownExploitedVulnerabilityHandle) []any {
function loadFixture (line 105) | func loadFixture(t *testing.T, fixturePath string) []unmarshal.KnownExpl...
FILE: grype/db/v6/build/transformers/msrc/transform.go
function Transform (line 17) | func Transform(vulnerability unmarshal.MSRCVulnerability, state provider...
function getVulnerability (line 27) | func getVulnerability(vuln unmarshal.MSRCVulnerability, state provider.S...
function getAffectedPackage (line 42) | func getAffectedPackage(vuln unmarshal.MSRCVulnerability) db.AffectedPac...
function getPackage (line 51) | func getPackage(vuln unmarshal.MSRCVulnerability) *db.Package {
function getRanges (line 58) | func getRanges(vuln unmarshal.MSRCVulnerability) []db.Range {
function getFix (line 75) | func getFix(vuln unmarshal.MSRCVulnerability) *db.Fix {
function fixedInKB (line 92) | func fixedInKB(vulnerability unmarshal.MSRCVulnerability) (string, *db.F...
function getReferences (line 110) | func getReferences(vuln unmarshal.MSRCVulnerability) []db.Reference {
function getSeverities (line 120) | func getSeverities(vuln unmarshal.MSRCVulnerability) []db.Severity {
FILE: grype/db/v6/build/transformers/msrc/transform_test.go
function TestUnmarshalMsrcVulnerabilities (line 20) | func TestUnmarshalMsrcVulnerabilities(t *testing.T) {
function TestParseMSRCEntry (line 31) | func TestParseMSRCEntry(t *testing.T) {
function timePtr (line 199) | func timePtr(t time.Time) *time.Time {
FILE: grype/db/v6/build/transformers/nvd/affected_range.go
type affectedRangeSet (line 12) | type affectedRangeSet
method addRanges (line 40) | func (s affectedRangeSet) addRanges(rs ...affectedCPERange) {
method toSlice (line 46) | func (s affectedRangeSet) toSlice() []affectedCPERange {
type affectedCPERange (line 14) | type affectedCPERange struct
method String (line 75) | func (r affectedCPERange) String() string {
function newAffectedRanges (line 24) | func newAffectedRanges(rs ...affectedCPERange) affectedRangeSet {
function newAffectedRange (line 30) | func newAffectedRange(match nvd.CpeMatch) affectedCPERange {
function nonEmptyValue (line 104) | func nonEmptyValue(value *string) string {
FILE: grype/db/v6/build/transformers/nvd/affected_range_test.go
function Test_AffectedCPERange_String (line 11) | func Test_AffectedCPERange_String(t *testing.T) {
function Test_newAffectedRange (line 130) | func Test_newAffectedRange(t *testing.T) {
function stringPtr (line 181) | func stringPtr(s string) *string {
FILE: grype/db/v6/build/transformers/nvd/node.go
type affectedPackageCandidate (line 13) | type affectedPackageCandidate struct
function allCandidates (line 19) | func allCandidates(cve string, configs []nvd.Configuration, cfg Config) ...
function processConfiguration (line 34) | func processConfiguration(cve string, config nvd.Configuration, cfg Conf...
function processANDNodes (line 50) | func processANDNodes(cve string, nodes []nvd.Node, cfg Config, depth int...
function processORNodes (line 119) | func processORNodes(cve string, nodes []nvd.Node, cfg Config, depth int)...
function deduplicateCandidates (line 147) | func deduplicateCandidates(candidates []affectedPackageCandidate) []affe...
function deriveRangesFromCPE (line 195) | func deriveRangesFromCPE(attr cpe.Attributes) []affectedCPERange {
function extractVulnerableCPEs (line 214) | func extractVulnerableCPEs(node nvd.Node, cfg Config) ([]affectedPackage...
function extractPlatformCPEs (line 254) | func extractPlatformCPEs(node nvd.Node) ([]cpe.Attributes, error) {
function cpeKey (line 272) | func cpeKey(cpe cpe.Attributes) string {
FILE: grype/db/v6/build/transformers/nvd/node_test.go
function TestDeduplicateCandidates (line 12) | func TestDeduplicateCandidates(t *testing.T) {
function TestDeduplicateCandidates_SensitiveToAllCPEFields (line 409) | func TestDeduplicateCandidates_SensitiveToAllCPEFields(t *testing.T) {
FILE: grype/db/v6/build/transformers/nvd/transform.go
type Config (line 24) | type Config struct
function defaultConfig (line 29) | func defaultConfig() Config {
function getVersionFormat (line 36) | func getVersionFormat(cpeProduct string) string {
function Transformer (line 43) | func Transformer(cfg Config) data.NVDTransformerV2 {
function transform (line 52) | func transform(cfg Config, vulnerability unmarshal.NVDVulnerability, sta...
function getAssigner (line 82) | func getAssigner(vuln unmarshal.NVDVulnerability) []string {
function getVulnStatus (line 96) | func getVulnStatus(vuln unmarshal.NVDVulnerability) db.VulnerabilityStat...
function getAffected (line 153) | func getAffected(cfg Config, vulnerability unmarshal.NVDVulnerability) [...
function getCWEs (line 168) | func getCWEs(vulnerability unmarshal.NVDVulnerability) []db.CWEHandle {
function isValidCWE (line 186) | func isValidCWE(cwe string) bool {
function encodeCPEs (line 199) | func encodeCPEs(cpes []cpe.Attributes) []string {
function affectedApplicationPackage (line 207) | func affectedApplicationPackage(cfg Config, vulnerability unmarshal.NVDV...
function getRanges (line 229) | func getRanges(cfg Config, c cpe.Attributes, ras []affectedCPERange, vul...
function getRange (line 241) | func getRange(cfg Config, c cpe.Attributes, ra affectedCPERange, vulnID ...
function getFix (line 251) | func getFix(cfg Config, vulnCPE cpe.Attributes, ra affectedCPERange, vul...
function getCPEFromAttributes (line 305) | func getCPEFromAttributes(atts cpe.Attributes) *db.Cpe {
function getSeverities (line 319) | func getSeverities(vuln unmarshal.NVDVulnerability) []db.Severity {
function getReferences (line 341) | func getReferences(vuln unmarshal.NVDVulnerability) []db.Reference {
FILE: grype/db/v6/build/transformers/nvd/transform_test.go
function inputProviderState (line 28) | func inputProviderState(name string) provider.State {
function expectedProvider (line 38) | func expectedProvider(name string) *db.Provider {
function TestTransform (line 48) | func TestTransform(t *testing.T) {
function relatedEntries (line 1899) | func relatedEntries(items ...any) []any {
function loadFixture (line 1903) | func loadFixture(t *testing.T, fixturePath string) []unmarshal.NVDVulner...
function timeRef (line 1923) | func timeRef(ti time.Time) *time.Time {
function TestIsValidCWE (line 1927) | func TestIsValidCWE(t *testing.T) {
function TestGetReferences (line 2000) | func TestGetReferences(t *testing.T) {
FILE: grype/db/v6/build/transformers/openvex/transform.go
function AnnotatedTransform (line 20) | func AnnotatedTransform(wrapper unmarshal.AnnotatedOpenVEXVulnerability,...
function Transform (line 24) | func Transform(vulnerability unmarshal.OpenVEXVulnerability, state provi...
function transform (line 28) | func transform(vulnerability unmarshal.OpenVEXVulnerability, state provi...
function getPackageHandles (line 55) | func getPackageHandles(vuln *unmarshal.OpenVEXVulnerability, fixes []unm...
function getPackageHandle (line 99) | func getPackageHandle(product *govex.Product, vuln *unmarshal.OpenVEXVul...
function getPURL (line 139) | func getPURL(product *govex.Product) (purl *packageurl.PackageURL, err e...
function getAliases (line 157) | func getAliases(vuln *unmarshal.OpenVEXVulnerability) []string {
function getName (line 165) | func getName(vuln *unmarshal.OpenVEXVulnerability) string {
function getReferences (line 169) | func getReferences(vuln *unmarshal.OpenVEXVulnerability) []db.Reference {
function getPackageBlob (line 178) | func getPackageBlob(aliases []string, ver string, ty string, fixState db...
FILE: grype/db/v6/build/transformers/openvex/transform_test.go
function inputProviderState (line 26) | func inputProviderState() provider.State {
function TestOpenVEXTransform (line 36) | func TestOpenVEXTransform(t *testing.T) {
function Test_GetPackageHandles (line 301) | func Test_GetPackageHandles(t *testing.T) {
FILE: grype/db/v6/build/transformers/os/transform.go
type advisoryKey (line 27) | type advisoryKey struct
function Transform (line 32) | func Transform(vulnerability unmarshal.OSVulnerability, state provider.S...
function getAffectedPackages (line 59) | func getAffectedPackages(vuln unmarshal.OSVulnerability) []db.AffectedPa...
function getFix (line 106) | func getFix(fixedInEntry unmarshal.OSFixedIn) *db.Fix {
function getFixAvailability (line 150) | func getFixAvailability(fixedInEntry unmarshal.OSFixedIn) *db.FixAvailab...
function enforceConstraint (line 167) | func enforceConstraint(fixedVersion, vulnerableRange, format, vulnerabil...
function deriveConstraintFromFix (line 184) | func deriveConstraintFromFix(fixVersion, vulnerabilityID string) string {
type groupIndex (line 205) | type groupIndex struct
function groupFixedIns (line 216) | func groupFixedIns(vuln unmarshal.OSVulnerability) map[groupIndex][]unma...
function getPackageType (line 241) | func getPackageType(osName string) pkg.Type {
function getPackage (line 256) | func getPackage(group groupIndex) *db.Package {
type osInfo (line 264) | type osInfo struct
function getOSInfo (line 271) | func getOSInfo(group string) osInfo {
function normalizeOsName (line 302) | func normalizeOsName(id string) string {
function getOperatingSystem (line 313) | func getOperatingSystem(osName, osID, osVersion, channel string) *db.Ope...
function getReferences (line 343) | func getReferences(vuln unmarshal.OSVulnerability) []db.Reference {
function getAliases (line 373) | func getAliases(vuln unmarshal.OSVulnerability) []string {
function getSeverities (line 383) | func getSeverities(vuln unmarshal.OSVulnerability) []db.Severity {
FILE: grype/db/v6/build/transformers/os/transform_test.go
function inputProviderState (line 25) | func inputProviderState(name string) provider.State {
function expectedProvider (line 35) | func expectedProvider(name string) *db.Provider {
function TestTransform (line 45) | func TestTransform(t *testing.T) {
function TestGetOperatingSystem (line 1222) | func TestGetOperatingSystem(t *testing.T) {
function TestGetOSInfo (line 1297) | func TestGetOSInfo(t *testing.T) {
function TestGetFixAvailability (line 1386) | func TestGetFixAvailability(t *testing.T) {
function TestGetFixWithDetail (line 1451) | func TestGetFixWithDetail(t *testing.T) {
function TestGetFixWithDetailFixtures (line 1579) | func TestGetFixWithDetailFixtures(t *testing.T) {
function affectedPkgSlice (line 1658) | func affectedPkgSlice(a ...db.AffectedPackageHandle) []any {
function loadFixture (line 1666) | func loadFixture(t *testing.T, fixturePath string) []unmarshal.OSVulnera...
function timeRef (line 1680) | func timeRef(ti time.Time) *time.Time {
function strRef (line 1684) | func strRef(s string) *string {
FILE: grype/db/v6/build/transformers/osv/transform.go
constant almaLinux (line 25) | almaLinux = "almalinux"
function Transform (line 28) | func Transform(vulnerability unmarshal.OSVVulnerability, state provider....
function getAffectedPackages (line 76) | func getAffectedPackages(vuln unmarshal.OSVVulnerability) []db.AffectedP...
function getPackageQualifiers (line 119) | func getPackageQualifiers(affected models.Affected, cpes any, withCPE bo...
function extractRpmModularity (line 142) | func extractRpmModularity(affected models.Affected) string {
function getGrypeRangesFromRange (line 208) | func getGrypeRangesFromRange(r models.Range, ecosystem string) []db.Rang...
function normalizeConstraint (line 302) | func normalizeConstraint(constraint string, rangeType string) string {
function normalizeFix (line 309) | func normalizeFix(fix string, detail *db.FixDetail) *db.Fix {
function normalizeRangeType (line 323) | func normalizeRangeType(t models.RangeType, ecosystem string) string {
function getPackage (line 337) | func getPackage(p models.Package) *db.Package {
function getPackageTypeFromEcosystem (line 363) | func getPackageTypeFromEcosystem(ecosystem string) pkg.Type {
function getReferences (line 382) | func getReferences(vuln unmarshal.OSVVulnerability) []db.Reference {
function extractCVSSInfo (line 405) | func extractCVSSInfo(cvss string) (string, string, error) {
function normalizeSeverity (line 416) | func normalizeSeverity(severity models.Severity) (db.Severity, error) {
function getSeverities (line 439) | func getSeverities(vuln unmarshal.OSVVulnerability) ([]db.Severity, erro...
function getOperatingSystemFromEcosystem (line 465) | func getOperatingSystemFromEcosystem(ecosystem string) *db.OperatingSyst...
function normalizeOSName (line 514) | func normalizeOSName(osName string) string {
function isAdvisoryRecord (line 526) | func isAdvisoryRecord(vuln unmarshal.OSVVulnerability) bool {
function getUnaffectedPackages (line 555) | func getUnaffectedPackages(vuln unmarshal.OSVVulnerability) []db.Unaffec...
function getUnaffectedBlob (line 578) | func getUnaffectedBlob(aliases []string, ranges []models.Range, affected...
function getGrypeUnaffectedRangesFromRange (line 597) | func getGrypeUnaffectedRangesFromRange(r models.Range, ecosystem string)...
function extractFixAvailability (line 609) | func extractFixAvailability(r models.Range) map[string]db.FixAvailability {
function parseSingleFixEntry (line 640) | func parseSingleFixEntry(fixEntry any, fixByVersion map[string]db.FixAva...
function buildUnaffectedRangesFromEvents (line 659) | func buildUnaffectedRangesFromEvents(events []models.Event, fixByVersion...
function createUnaffectedRange (line 673) | func createUnaffectedRange(fixedVersion string, fixByVersion map[string]...
FILE: grype/db/v6/build/transformers/osv/transform_test.go
function inputProviderState (line 26) | func inputProviderState() provider.State {
function expectedProvider (line 36) | func expectedProvider() *db.Provider {
function timeRef (line 46) | func timeRef(t time.Time) *time.Time {
function loadFixture (line 50) | func loadFixture(t *testing.T, fixturePath string) []unmarshal.OSVVulner...
function affectedPkgSlice (line 64) | func affectedPkgSlice(a ...db.AffectedPackageHandle) []any {
function unaffectedPkgSlice (line 72) | func unaffectedPkgSlice(u ...db.UnaffectedPackageHandle) []any {
function TestTransform (line 80) | func TestTransform(t *testing.T) {
function Test_getGrypeRangesFromRange (line 308) | func Test_getGrypeRangesFromRange(t *testing.T) {
function Test_getPackage (line 477) | func Test_getPackage(t *testing.T) {
function Test_extractCVSSInfo (line 536) | func Test_extractCVSSInfo(t *testing.T) {
function Test_extractRpmModularity (line 593) | func Test_extractRpmModularity(t *testing.T) {
function Test_getPackageQualifiers (line 655) | func Test_getPackageQualifiers(t *testing.T) {
function stringRef (line 723) | func stringRef(s string) *string {
FILE: grype/db/v6/build/transformers/references.go
function DeduplicateReferences (line 7) | func DeduplicateReferences(references []db.Reference) []db.Reference {
function refsAreEqual (line 34) | func refsAreEqual(a, b db.Reference) bool {
FILE: grype/db/v6/build/writer.go
type writer (line 19) | type writer struct
method Write (line 81) | func (w *writer) Write(entries ...data.Entry) error {
method writeEntry (line 100) | func (w *writer) writeEntry(entry transformers.RelatedEntries) error {
method writeRelatedEntry (line 139) | func (w *writer) writeRelatedEntry(vulnHandle *db.VulnerabilityHandle,...
method writeAffectedPackage (line 182) | func (w *writer) writeAffectedPackage(vulnHandle *db.VulnerabilityHand...
method writeAffectedCPE (line 215) | func (w *writer) writeAffectedCPE(vulnHandle *db.VulnerabilityHandle, ...
method writeUnaffectedPackage (line 230) | func (w *writer) writeUnaffectedPackage(vulnHandle *db.VulnerabilityHa...
method writeUnaffectedCPE (line 244) | func (w *writer) writeUnaffectedCPE(vulnHandle *db.VulnerabilityHandle...
method fillInMissingSeverity (line 261) | func (w *writer) fillInMissingSeverity(handle *db.VulnerabilityHandle) {
method addToParentBatch (line 316) | func (w *writer) addToParentBatch(op func() error) error {
method addToChildBatch (line 330) | func (w *writer) addToChildBatch(op func() error) error {
method flushParentBatch (line 349) | func (w *writer) flushParentBatch() error {
method flushParentBatchLocked (line 356) | func (w *writer) flushParentBatchLocked() error {
method flushChildBatch (line 376) | func (w *writer) flushChildBatch() error {
method flushChildBatchLocked (line 383) | func (w *writer) flushChildBatchLocked() error {
method Close (line 402) | func (w *writer) Close() error {
method writeOperatingSystemEOL (line 469) | func (w *writer) writeOperatingSystemEOL(row db.OperatingSystemEOLHand...
type ProviderMetadata (line 40) | type ProviderMetadata struct
type Provider (line 44) | type Provider struct
function NewWriter (line 49) | func NewWriter(directory string, states provider.States, failOnMissingFi...
function filterUnknownSeverities (line 424) | func filterUnknownSeverities(sevs []db.Severity) []db.Severity {
function isKnownSeverity (line 434) | func isKnownSeverity(s db.Severity) bool {
function ensureFixDates (line 443) | func ensureFixDates(row *db.AffectedPackageHandle) error {
function isFixVersion (line 465) | func isFixVersion(v string) bool {
FILE: grype/db/v6/build/writer_test.go
function TestFillInMissingSeverity (line 19) | func TestFillInMissingSeverity(t *testing.T) {
function TestFilterUnknownSeverities (line 137) | func TestFilterUnknownSeverities(t *testing.T) {
function TestIsKnownSeverity (line 196) | func TestIsKnownSeverity(t *testing.T) {
function TestEnsureFixDates (line 242) | func TestEnsureFixDates(t *testing.T) {
function TestWrite_FailsOnMissingFixDate (line 562) | func TestWrite_FailsOnMissingFixDate(t *testing.T) {
function TestIsFixVersion (line 603) | func TestIsFixVersion(t *testing.T) {
function TestBatchedWritesEquivalence (line 664) | func TestBatchedWritesEquivalence(t *testing.T) {
function TestBatchAccumulation (line 727) | func TestBatchAccumulation(t *testing.T) {
function TestBatchMetrics (line 760) | func TestBatchMetrics(t *testing.T) {
function TestBatchSizeConfiguration (line 790) | func TestBatchSizeConfiguration(t *testing.T) {
function createTestEntries (line 830) | func createTestEntries(count int) []data.Entry {
FILE: grype/db/v6/cache.go
constant cpesTableCacheKey (line 9) | cpesTableCacheKey = "cpes"
constant packagesTableCacheKey (line 10) | packagesTableCacheKey = "packages"
constant operatingSystemsTableCacheKey (line 11) | operatingSystemsTableCacheKey = "operating_systems"
constant vulnerabilitiesTableCacheKey (line 12) | vulnerabilitiesTableCacheKey = "vulnerabilities"
constant cacheKey (line 15) | cacheKey = contextKey("multiModelCache")
type contextKey (line 17) | type contextKey
type cachable (line 19) | type cachable interface
type cacheIDManager (line 24) | type cacheIDManager interface
type cacheStringIDManager (line 29) | type cacheStringIDManager interface
function withCacheContext (line 34) | func withCacheContext(ctx context.Context, c *cache) context.Context {
function cacheFromContext (line 38) | func cacheFromContext(ctx context.Context) (*cache, bool) {
type cache (line 43) | type cache struct
method getID (line 56) | func (c *cache) getID(ca cachable) (ID, bool) {
method getString (line 66) | func (c *cache) getString(ca cachable) (string, bool) {
method set (line 76) | func (c *cache) set(ca cachable) {
method setStringEntry (line 87) | func (c *cache) setStringEntry(id string, ca cachable) {
method setIDEntry (line 101) | func (c *cache) setIDEntry(id ID, ca cachable) {
function newCache (line 49) | func newCache() *cache {
FILE: grype/db/v6/cache_test.go
type mockCachableID (line 10) | type mockCachableID struct
method cacheKey (line 16) | func (m *mockCachableID) cacheKey() string { return m.key }
method tableName (line 17) | func (m *mockCachableID) tableName() string { return m.table }
method rowID (line 18) | func (m *mockCachableID) rowID() ID { return m.id }
method setRowID (line 19) | func (m *mockCachableID) setRowID(id ID) { m.id = id }
type mockCachableString (line 21) | type mockCachableString struct
method cacheKey (line 27) | func (m *mockCachableString) cacheKey() string { return m.key }
method tableName (line 28) | func (m *mockCachableString) tableName() string { return m.table }
method rowID (line 29) | func (m *mockCachableString) rowID() string { return m.id }
method setRowID (line 30) | func (m *mockCachableString) setRowID(id string) { m.id = id }
function newTestCachableString (line 32) | func newTestCachableString(key, table, id string) *mockCachableString {
function newTestCachableID (line 36) | func newTestCachableID(key, table string, id ID) *mockCachableID {
function TestCache_GetString_Found (line 40) | func TestCache_GetString_Found(t *testing.T) {
function TestCache_GetString_NotFound (line 51) | func TestCache_GetString_NotFound(t *testing.T) {
function TestCache_Set_ID (line 60) | func TestCache_Set_ID(t *testing.T) {
function TestCache_Set_String (line 71) | func TestCache_Set_String(t *testing.T) {
function TestCache_Set_Panic (line 82) | func TestCache_Set_Panic(t *testing.T) {
function TestCache_SetStringEntry_New (line 91) | func TestCache_SetStringEntry_New(t *testing.T) {
function TestCache_SetStringEntry_Update (line 102) | func TestCache_SetStringEntry_Update(t *testing.T) {
function TestCache_SetIDEntry_New (line 114) | func TestCache_SetIDEntry_New(t *testing.T) {
function TestCache_SetIDEntry_Update (line 125) | func TestCache_SetIDEntry_Update(t *testing.T) {
function TestWithCacheContext (line 137) | func TestWithCacheContext(t *testing.T) {
function TestCacheFromContext_NotFound (line 146) | func TestCacheFromContext_NotFound(t *testing.T) {
FILE: grype/db/v6/cpe_store.go
type cpeHandleStore (line 14) | type cpeHandleStore interface
type cpeHandleAccessor (line 18) | type cpeHandleAccessor interface
type GetCPEOptions (line 22) | type GetCPEOptions struct
type cpeStore (line 31) | type cpeStore struct
method handleCPE (line 195) | func (s *cpeStore) handleCPE(query *gorm.DB, c *cpe.Attributes, allowB...
method handleVulnerabilityOptions (line 204) | func (s *cpeStore) handleVulnerabilityOptions(query *gorm.DB, configs ...
method handlePreload (line 214) | func (s *cpeStore) handlePreload(query *gorm.DB, config GetCPEOptions)...
function newCPEStore (line 36) | func newCPEStore(db *gorm.DB, bs *blobStore) *cpeStore {
function addCPEs (line 43) | func addCPEs[T cpeHandleStore](s *cpeStore, packages ...T) error {
function addCPEHandles (line 101) | func addCPEHandles[T cpeHandleStore](s *cpeStore, packages ...T) error {
function getCPEHandles (line 118) | func getCPEHandles[T cpeHandleStore]( // nolint:funlen
FILE: grype/db/v6/data.go
function KnownOperatingSystemSpecifierOverrides (line 10) | func KnownOperatingSystemSpecifierOverrides() []OperatingSystemSpecifier...
function KnownPackageSpecifierOverrides (line 102) | func KnownPackageSpecifierOverrides() []PackageSpecifierOverride {
function ptr (line 160) | func ptr[T any](v T) *T {
FILE: grype/db/v6/db.go
constant ModelVersion (line 21) | ModelVersion = 6
constant Revision (line 24) | Revision = 1
constant Addition (line 27) | Addition = 4
constant VulnerabilityDBFileName (line 43) | VulnerabilityDBFileName = "vulnerability.db"
constant batchSize (line 49) | batchSize = 300
type ReadWriter (line 54) | type ReadWriter interface
type Reader (line 59) | type Reader interface
type Writer (line 73) | type Writer interface
type Curator (line 86) | type Curator interface
type Config (line 94) | type Config struct
method DBFilePath (line 99) | func (c Config) DBFilePath() string {
function NewReader (line 103) | func NewReader(cfg Config) (Reader, error) {
function NewWriter (line 107) | func NewWriter(cfg Config) (ReadWriter, error) {
function Hydrater (line 111) | func Hydrater() func(string) error {
function NewLowLevelDB (line 126) | func NewLowLevelDB(dbFilePath string, empty, writable, debug bool) (*gor...
FILE: grype/db/v6/db_metadata_store.go
type DBMetadataStoreWriter (line 12) | type DBMetadataStoreWriter interface
type DBMetadataStoreReader (line 16) | type DBMetadataStoreReader interface
type dbMetadataStore (line 20) | type dbMetadataStore struct
method GetDBMetadata (line 30) | func (s *dbMetadataStore) GetDBMetadata() (*DBMetadata, error) {
method SetDBMetadata (line 37) | func (s *dbMetadataStore) SetDBMetadata() error {
function newDBMetadataStore (line 24) | func newDBMetadataStore(db *gorm.DB) *dbMetadataStore {
FILE: grype/db/v6/db_metadata_store_test.go
function TestDbMetadataStore_empty (line 11) | func TestDbMetadataStore_empty(t *testing.T) {
function TestDbMetadataStore_oldDb (line 22) | func TestDbMetadataStore_oldDb(t *testing.T) {
function TestDbMetadataStore (line 33) | func TestDbMetadataStore(t *testing.T) {
function setupTestStore (line 58) | func setupTestStore(t testing.TB, d ...string) *store {
function setupReadOnlyTestStore (line 80) | func setupReadOnlyTestStore(t testing.TB, dir string) *store {
FILE: grype/db/v6/description.go
type Description (line 16) | type Description struct
method String (line 92) | func (m Description) String() string {
type Time (line 24) | type Time struct
method MarshalJSON (line 28) | func (t Time) MarshalJSON() ([]byte, error) {
method UnmarshalJSON (line 32) | func (t *Time) UnmarshalJSON(data []byte) error {
method String (line 48) | func (t Time) String() string {
function DescriptionFromMetadata (line 52) | func DescriptionFromMetadata(m *DBMetadata) *Description {
function ReadDescription (line 62) | func ReadDescription(dbFilePath string) (*Description, error) {
FILE: grype/db/v6/description_test.go
function TestReadDescription (line 15) | func TestReadDescription(t *testing.T) {
function TestTime_JSONMarshalling (line 37) | func TestTime_JSONMarshalling(t *testing.T) {
function TestTime_JSONUnmarshalling (line 64) | func TestTime_JSONUnmarshalling(t *testing.T) {
FILE: grype/db/v6/distribution/client.go
type Config (line 25) | type Config struct
type Client (line 40) | type Client interface
type client (line 47) | type client struct
method IsUpdateAvailable (line 85) | func (c client) IsUpdateAvailable(current *v6.Description) (*Archive, ...
method isUpdateAvailable (line 107) | func (c client) isUpdateAvailable(current *v6.Description, candidate *...
method ResolveArchiveURL (line 130) | func (c client) ResolveArchiveURL(archive Archive) (string, error) {
method Download (line 150) | func (c client) Download(archiveURL, dest string, downloadProgress *pr...
method Latest (line 174) | func (c client) Latest() (*LatestDocument, error) {
method latestURL (line 195) | func (c client) latestURL() string {
function DefaultConfig (line 54) | func DefaultConfig() Config {
function NewClient (line 63) | func NewClient(cfg Config) (Client, error) {
function withClientTimeout (line 205) | func withClientTimeout(timeout time.Duration) func(*http.Client) {
function withUserAgent (line 211) | func withUserAgent(id clio.Identification) func(*http.Client) {
function defaultHTTPClient (line 217) | func defaultHTTPClient(fs afero.Fs, caCertPath string, postProcessor ......
function removeAllOrLog (line 242) | func removeAllOrLog(fs afero.Fs, dir string) {
function isSupersededBy (line 248) | func isSupersededBy(current *v6.Description, candidate v6.Description) b...
function newHTTPClientWithDefaultUserAgent (line 281) | func newHTTPClientWithDefaultUserAgent(baseTransport http.RoundTripper, ...
type roundTripperWithUserAgent (line 290) | type roundTripperWithUserAgent struct
method RoundTrip (line 295) | func (r roundTripperWithUserAgent) RoundTrip(req *http.Request) (*http...
FILE: grype/db/v6/distribution/client_test.go
type mockGetter (line 20) | type mockGetter struct
method GetFile (line 24) | func (m *mockGetter) GetFile(dst, src string, manuals ...*progress.Man...
method GetToDir (line 29) | func (m *mockGetter) GetToDir(dst, src string, manuals ...*progress.Ma...
function TestClient_Latest (line 34) | func TestClient_Latest(t *testing.T) {
function TestClient_Download (line 132) | func TestClient_Download(t *testing.T) {
function TestClient_IsUpdateAvailable (line 188) | func TestClient_IsUpdateAvailable(t *testing.T) {
function TestDatabaseDescription_IsSupersededBy (line 304) | func TestDatabaseDescription_IsSupersededBy(t *testing.T) {
function Test_latestURL (line 380) | func Test_latestURL(t *testing.T) {
FILE: grype/db/v6/distribution/latest.go
constant LatestFileName (line 19) | LatestFileName = "latest.json"
type LatestDocument (line 21) | type LatestDocument struct
method Write (line 103) | func (l LatestDocument) Write(writer io.Writer) error {
type Archive (line 29) | type Archive struct
function NewLatestDocument (line 41) | func NewLatestDocument(entries ...Archive) *LatestDocument {
function NewLatestFromReader (line 64) | func NewLatestFromReader(reader io.Reader) (*LatestDocument, error) {
function NewLatestFromFile (line 77) | func NewLatestFromFile(fs afero.Fs, path string) (*LatestDocument, error) {
function NewArchive (line 86) | func NewArchive(path string, t time.Time, model, revision, addition int)...
function calculateArchiveDigest (line 133) | func calculateArchiveDigest(dbFilePath string) (string, error) {
FILE: grype/db/v6/distribution/latest_test.go
function TestNewLatestDocument (line 19) | func TestNewLatestDocument(t *testing.T) {
function TestNewLatestFromReader (line 66) | func TestNewLatestFromReader(t *testing.T) {
function TestLatestDocument_Write (line 104) | func TestLatestDocument_Write(t *testing.T) {
function TestNewArchive (line 237) | func TestNewArchive(t *testing.T) {
FILE: grype/db/v6/distribution/status.go
type Status (line 3) | type Status
constant LifecycleStatus (line 5) | LifecycleStatus = StatusActive
constant StatusActive (line 9) | StatusActive Status = "active"
constant StatusDeprecated (line 12) | StatusDeprecated Status = "deprecated"
constant StatusEndOfLife (line 15) | StatusEndOfLife Status = "eol"
FILE: grype/db/v6/enumerations.go
type VulnerabilityStatus (line 7) | type VulnerabilityStatus
constant UnknownVulnerabilityStatus (line 10) | UnknownVulnerabilityStatus VulnerabilityStatus = ""
constant VulnerabilityActive (line 13) | VulnerabilityActive VulnerabilityStatus = "active"
constant VulnerabilityAnalyzing (line 16) | VulnerabilityAnalyzing VulnerabilityStatus = "analyzing"
constant VulnerabilityRejected (line 19) | VulnerabilityRejected VulnerabilityStatus = "rejected"
constant VulnerabilityDisputed (line 22) | VulnerabilityDisputed VulnerabilityStatus = "disputed"
type SeverityScheme (line 26) | type SeverityScheme
constant UnknownSeverityScheme (line 29) | UnknownSeverityScheme SeverityScheme = ""
constant SeveritySchemeCVSS (line 32) | SeveritySchemeCVSS SeverityScheme = "CVSS"
constant SeveritySchemeHML (line 35) | SeveritySchemeHML SeverityScheme = "HML"
constant SeveritySchemeCHML (line 38) | SeveritySchemeCHML SeverityScheme = "CHML"
constant SeveritySchemeCHMLN (line 41) | SeveritySchemeCHMLN SeverityScheme = "CHMLN"
type FixStatus (line 45) | type FixStatus
constant UnknownFixStatus (line 48) | UnknownFixStatus FixStatus = ""
constant FixedStatus (line 51) | FixedStatus FixStatus = "fixed"
constant NotFixedStatus (line 54) | NotFixedStatus FixStatus = "not-fixed"
constant WontFixStatus (line 57) | WontFixStatus FixStatus = "wont-fix"
constant NotAffectedFixStatus (line 60) | NotAffectedFixStatus FixStatus = "not-affected"
constant AdvisoryReferenceTag (line 65) | AdvisoryReferenceTag = "advisory"
function ParseVulnerabilityStatus (line 68) | func ParseVulnerabilityStatus(s string) VulnerabilityStatus {
function ParseSeverityScheme (line 83) | func ParseSeverityScheme(s string) SeverityScheme {
function ParseFixStatus (line 98) | func ParseFixStatus(s string) FixStatus {
function NormalizeReferenceTags (line 113) | func NormalizeReferenceTags(tags []string) []string {
function replaceAny (line 121) | func replaceAny(input string, newStr string, searchFor ...string) string {
FILE: grype/db/v6/enumerations_test.go
function TestParseVulnerabilityStatus (line 9) | func TestParseVulnerabilityStatus(t *testing.T) {
function TestParseSeverityScheme (line 30) | func TestParseSeverityScheme(t *testing.T) {
function TestParseFixStatus (line 50) | func TestParseFixStatus(t *testing.T) {
function TestReplaceAny (line 70) | func TestReplaceAny(t *testing.T) {
FILE: grype/db/v6/fillers.go
function fillAffectedPackageHandles (line 8) | func fillAffectedPackageHandles(reader Reader, handles []*AffectedPackag...
function affectedPackageHandleOperatingSystemRef (line 17) | func affectedPackageHandleOperatingSystemRef(t *AffectedPackageHandle) i...
function affectedPackageHandlePackageRef (line 24) | func affectedPackageHandlePackageRef(t *AffectedPackageHandle) idRef[Pac...
function affectedPackageHandleVulnerabilityHandleRef (line 31) | func affectedPackageHandleVulnerabilityHandleRef(t *AffectedPackageHandl...
function fillAffectedCPEHandles (line 39) | func fillAffectedCPEHandles(reader Reader, handles []*AffectedCPEHandle)...
function affectedCPEHandleCpeRef (line 47) | func affectedCPEHandleCpeRef(t *AffectedCPEHandle) idRef[Cpe] {
function affectedCPEHandleVulnerabilityHandleRef (line 54) | func affectedCPEHandleVulnerabilityHandleRef(t *AffectedCPEHandle) idRef...
function fillUnaffectedPackageHandles (line 62) | func fillUnaffectedPackageHandles(reader Reader, handles []*UnaffectedPa...
function unaffectedPackageHandleOperatingSystemRef (line 71) | func unaffectedPackageHandleOperatingSystemRef(t *UnaffectedPackageHandl...
function unaffectedPackageHandlePackageRef (line 78) | func unaffectedPackageHandlePackageRef(t *UnaffectedPackageHandle) idRef...
function unaffectedPackageHandleVulnerabilityHandleRef (line 85) | func unaffectedPackageHandleVulnerabilityHandleRef(t *UnaffectedPackageH...
function fillUnaffectedCPEHandles (line 93) | func fillUnaffectedCPEHandles(reader Reader, handles []*UnaffectedCPEHan...
function unaffectedCPEHandleCpeRef (line 101) | func unaffectedCPEHandleCpeRef(t *UnaffectedCPEHandle) idRef[Cpe] {
function unaffectedCPEHandleVulnerabilityHandleRef (line 108) | func unaffectedCPEHandleVulnerabilityHandleRef(t *UnaffectedCPEHandle) i...
function fillVulnerabilityHandles (line 116) | func fillVulnerabilityHandles[T any](reader Reader, handles []*T, vulnHa...
function vulnerabilityHandleID (line 137) | func vulnerabilityHandleID(h *VulnerabilityHandle) ID {
function cpeHandleID (line 141) | func cpeHandleID(h *Cpe) ID {
function operatingSystemID (line 145) | func operatingSystemID(h *OperatingSystem) ID {
function packageID (line 149) | func packageID(h *Package) ID {
function toBlobables (line 153) | func toBlobables[T blobable](handles []T) []blobable {
FILE: grype/db/v6/import_metadata.go
constant ImportMetadataFileName (line 18) | ImportMetadataFileName = "import.json"
type ImportMetadata (line 20) | type ImportMetadata struct
function ReadImportMetadata (line 26) | func ReadImportMetadata(fs afero.Fs, dir string) (*ImportMetadata, error) {
function CalculateDBDigest (line 54) | func CalculateDBDigest(fs afero.Fs, dbFilePath string) (string, error) {
function WriteImportMetadata (line 62) | func WriteImportMetadata(fs afero.Fs, dbDir, source string) (*ImportMeta...
function writeImportMetadata (line 78) | func writeImportMetadata(writer io.Writer, checksums, source string) (*I...
FILE: grype/db/v6/import_metadata_test.go
function TestReadImportMetadata (line 17) | func TestReadImportMetadata(t *testing.T) {
function TestWriteImportMetadata (line 82) | func TestWriteImportMetadata(t *testing.T) {
function TestCalculateDBDigest (line 131) | func TestCalculateDBDigest(t *testing.T) {
FILE: grype/db/v6/installation/curator.go
constant lastUpdateCheckFileName (line 33) | lastUpdateCheckFileName = "last_update_check"
type monitor (line 35) | type monitor struct
method SetCompleted (line 701) | func (m monitor) SetCompleted() {
type Config (line 42) | type Config struct
method DBFilePath (line 63) | func (c Config) DBFilePath() string {
method DBDirectoryPath (line 67) | func (c Config) DBDirectoryPath() string {
function DefaultConfig (line 53) | func DefaultConfig(id clio.Identification) Config {
type curator (line 71) | type curator struct
method Reader (line 87) | func (c curator) Reader() (db.Reader, error) {
method Status (line 160) | func (c curator) Status() vulnerability.ProviderStatus {
method Delete (line 203) | func (c curator) Delete() error {
method Update (line 208) | func (c curator) Update() (bool, error) {
method isUpdateCheckAllowed (line 259) | func (c curator) isUpdateCheckAllowed() bool {
method update (line 279) | func (c curator) update(current *db.Description) (*distribution.Archiv...
method durationSinceUpdateCheck (line 374) | func (c curator) durationSinceUpdateCheck() (*time.Duration, error) {
method setLastSuccessfulUpdateCheck (line 411) | func (c curator) setLastSuccessfulUpdateCheck() {
method Import (line 428) | func (c curator) Import(reference string) error {
method activate (line 494) | func (c curator) activate(dbDirPath, url string, mon monitor) error {
method hydrate (line 511) | func (c curator) hydrate(dbDirPath, from string, mon monitor) error {
method replaceDB (line 533) | func (c curator) replaceDB(dbDirPath string) error {
method validateIntegrity (line 561) | func (c curator) validateIntegrity(description *db.Description) (strin...
method validateAge (line 598) | func (c curator) validateAge(m *db.Description) error {
function NewCurator (line 78) | func NewCurator(cfg Config, downloader distribution.Client) (db.Curator,...
function isRehydrationNeeded (line 337) | func isRehydrationNeeded(fs afero.Fs, dirPath string, currentDBVersion *...
function isURL (line 489) | func isURL(reference string) bool {
function removeAllOrLog (line 619) | func removeAllOrLog(fs afero.Fs, dir string) {
function unarchive (line 625) | func unarchive(source, destination string) error {
function newMonitor (line 674) | func newMonitor() monitor {
type completionMonitor (line 708) | type completionMonitor struct
method SetCompleted (line 712) | func (m completionMonitor) SetCompleted() {
FILE: grype/db/v6/installation/curator_test.go
type mockClient (line 24) | type mockClient struct
method IsUpdateAvailable (line 28) | func (m *mockClient) IsUpdateAvailable(current *db.Description) (*dist...
method ResolveArchiveURL (line 40) | func (m *mockClient) ResolveArchiveURL(_ distribution.Archive) (string...
method Download (line 44) | func (m *mockClient) Download(url, dest string, downloadProgress *prog...
method Latest (line 49) | func (m *mockClient) Latest() (*distribution.LatestDocument, error) {
function newTestCurator (line 54) | func newTestCurator(t *testing.T) curator {
type setupConfig (line 66) | type setupConfig struct
type setupOption (line 70) | type setupOption
function withWorkingUpdateIntegrations (line 72) | func withWorkingUpdateIntegrations() setupOption {
function setupCuratorForUpdate (line 78) | func setupCuratorForUpdate(t *testing.T, opts ...setupOption) curator {
function writeTestDescriptionToDB (line 117) | func writeTestDescriptionToDB(t *testing.T, dir string, desc db.Descript...
function writeTestImportMetadata (line 149) | func writeTestImportMetadata(t *testing.T, fs afero.Fs, dir string, chec...
function writeTestImportMetadataWithCustomVersion (line 153) | func writeTestImportMetadataWithCustomVersion(t *testing.T, fs afero.Fs,...
function writeTestDB (line 172) | func writeTestDB(t *testing.T, fs afero.Fs, dir string) string {
function TestCurator_Update (line 190) | func TestCurator_Update(t *testing.T) {
function TestCurator_IsUpdateCheckAllowed (line 262) | func TestCurator_IsUpdateCheckAllowed(t *testing.T) {
function TestCurator_DurationSinceUpdateCheck (line 320) | func TestCurator_DurationSinceUpdateCheck(t *testing.T) {
function TestCurator_SetLastSuccessfulUpdateCheck (line 368) | func TestCurator_SetLastSuccessfulUpdateCheck(t *testing.T) {
function TestCurator_validateAge (line 419) | func TestCurator_validateAge(t *testing.T) {
function TestCurator_validateIntegrity (line 502) | func TestCurator_validateIntegrity(t *testing.T) {
function TestReplaceDB (line 575) | func TestReplaceDB(t *testing.T) {
function Test_isRehydrationNeeded (line 682) | func Test_isRehydrationNeeded(t *testing.T) {
function TestCurator_Update_UsesDBRootDirForDownloadTempBase (line 772) | func TestCurator_Update_UsesDBRootDirForDownloadTempBase(t *testing.T) {
function TestCurator_Update_CleansUpDownloadDirOnActivationFailure (line 819) | func TestCurator_Update_CleansUpDownloadDirOnActivationFailure(t *testin...
function TestCurator_Import_URL_UsesDBRootDirForDownloadTempBaseAndCleansUp (line 860) | func TestCurator_Import_URL_UsesDBRootDirForDownloadTempBaseAndCleansUp(...
function Test_unarchive (line 919) | func Test_unarchive(t *testing.T) {
function setupTestDB (line 949) | func setupTestDB(t *testing.T, dbDir string) db.ReadWriter {
function setupReadOnlyTestDB (line 958) | func setupReadOnlyTestDB(t *testing.T, dbDir string) db.Reader {
function testConfig (line 967) | func testConfig() Config {
FILE: grype/db/v6/log_dropped.go
function logDroppedVulnerability (line 12) | func logDroppedVulnerability(vuln string, reason any, fields logger.Fiel...
FILE: grype/db/v6/models.go
function Models (line 33) | func Models() []any {
type ID (line 69) | type ID
type Blob (line 73) | type Blob struct
method computeDigest (line 78) | func (b Blob) computeDigest() string {
type DBMetadata (line 89) | type DBMetadata struct
function newSchemaVerFromDBMetadata (line 96) | func newSchemaVerFromDBMetadata(m DBMetadata) schemaver.SchemaVer {
type Provider (line 105) | type Provider struct
method String (line 122) | func (p *Provider) String() string {
method cacheKey (line 133) | func (p *Provider) cacheKey() string {
method tableName (line 137) | func (p *Provider) tableName() string {
method rowID (line 141) | func (p *Provider) rowID() string {
method setRowID (line 145) | func (p *Provider) setRowID(i string) {
method BeforeCreate (line 149) | func (p *Provider) BeforeCreate(tx *gorm.DB) (err error) {
method AfterCreate (line 159) | func (p *Provider) AfterCreate(tx *gorm.DB) (err error) {
type VulnerabilityHandle (line 170) | type VulnerabilityHandle struct
method String (line 195) | func (v VulnerabilityHandle) String() string {
method getBlobValue (line 199) | func (v VulnerabilityHandle) getBlobValue() any {
method setBlobID (line 206) | func (v *VulnerabilityHandle) setBlobID(id ID) {
method getBlobID (line 210) | func (v VulnerabilityHandle) getBlobID() ID {
method setBlob (line 214) | func (v *VulnerabilityHandle) setBlob(rawBlobValue []byte) error {
method cacheKey (line 224) | func (v *VulnerabilityHandle) cacheKey() string {
method rowID (line 232) | func (v *VulnerabilityHandle) rowID() ID {
method tableName (line 236) | func (v *VulnerabilityHandle) tableName() string {
method setRowID (line 240) | func (v *VulnerabilityHandle) setRowID(i ID) {
method BeforeCreate (line 244) | func (v *VulnerabilityHandle) BeforeCreate(tx *gorm.DB) (err error) {
method AfterCreate (line 256) | func (v *VulnerabilityHandle) AfterCreate(tx *gorm.DB) (err error) {
type VulnerabilityAlias (line 263) | type VulnerabilityAlias struct
type packageHandle (line 275) | type packageHandle struct
method vulnerability (line 290) | func (ph packageHandle) vulnerability() string {
method String (line 302) | func (ph packageHandle) String() string {
method getBlobValue (line 332) | func (ph packageHandle) getBlobValue() any {
method setBlobID (line 339) | func (ph *packageHandle) setBlobID(id ID) {
method getBlobID (line 343) | func (ph packageHandle) getBlobID() ID {
method setBlob (line 347) | func (ph *packageHandle) setBlob(rawBlobValue []byte) error {
type AffectedPackageHandle (line 364) | type AffectedPackageHandle
method getPackageHandle (line 366) | func (ph *AffectedPackageHandle) getPackageHandle() *packageHandle {
method vulnerability (line 370) | func (ph AffectedPackageHandle) vulnerability() string { // nolint:unu...
method String (line 374) | func (ph AffectedPackageHandle) String() string {
method getBlobValue (line 378) | func (ph AffectedPackageHandle) getBlobValue() any {
method setBlobID (line 382) | func (ph *AffectedPackageHandle) setBlobID(id ID) {
method getBlobID (line 386) | func (ph AffectedPackageHandle) getBlobID() ID {
method setBlob (line 390) | func (ph *AffectedPackageHandle) setBlob(rawBlobValue []byte) error {
type UnaffectedPackageHandle (line 395) | type UnaffectedPackageHandle
method getPackageHandle (line 397) | func (ph *UnaffectedPackageHandle) getPackageHandle() *packageHandle {
method vulnerability (line 401) | func (ph UnaffectedPackageHandle) vulnerability() string { // nolint:u...
method String (line 405) | func (ph UnaffectedPackageHandle) String() string {
method getBlobValue (line 409) | func (ph UnaffectedPackageHandle) getBlobValue() any {
method setBlobID (line 413) | func (ph *UnaffectedPackageHandle) setBlobID(id ID) {
method getBlobID (line 417) | func (ph UnaffectedPackageHandle) getBlobID() ID {
method setBlob (line 421) | func (ph *UnaffectedPackageHandle) setBlob(rawBlobValue []byte) error {
type Package (line 426) | type Package struct
method String (line 439) | func (p Package) String() string {
method cacheKey (line 456) | func (p Package) cacheKey() string {
method rowID (line 465) | func (p Package) rowID() ID {
method tableName (line 469) | func (p *Package) tableName() string {
method setRowID (line 473) | func (p *Package) setRowID(i ID) {
method BeforeCreate (line 477) | func (p *Package) BeforeCreate(tx *gorm.DB) (err error) { // nolint:go...
method AfterCreate (line 517) | func (p *Package) AfterCreate(tx *gorm.DB) (err error) {
type PackageSpecifierOverride (line 528) | type PackageSpecifierOverride struct
type OperatingSystem (line 539) | type OperatingSystem struct
method VersionNumber (line 569) | func (o *OperatingSystem) VersionNumber() string {
method Version (line 579) | func (o *OperatingSystem) Version() string {
method String (line 603) | func (o OperatingSystem) String() string {
method cacheKey (line 607) | func (o OperatingSystem) cacheKey() string {
method rowID (line 611) | func (o OperatingSystem) rowID() ID {
method tableName (line 615) | func (o *OperatingSystem) tableName() string {
method setRowID (line 619) | func (o *OperatingSystem) setRowID(i ID) {
method clean (line 623) | func (o *OperatingSystem) clean() {
method BeforeCreate (line 628) | func (o *OperatingSystem) BeforeCreate(tx *gorm.DB) (err error) {
method AfterCreate (line 641) | func (o *OperatingSystem) AfterCreate(tx *gorm.DB) (err error) {
type OperatingSystemSpecifierOverride (line 649) | type OperatingSystemSpecifierOverride struct
method BeforeCreate (line 678) | func (os *OperatingSystemSpecifierOverride) BeforeCreate(_ *gorm.DB) (...
type cpeHandle (line 690) | type cpeHandle struct
method vulnerability (line 702) | func (ch cpeHandle) vulnerability() string {
method String (line 714) | func (ch cpeHandle) String() string {
method getBlobID (line 739) | func (ch cpeHandle) getBlobID() ID {
method getBlobValue (line 743) | func (ch cpeHandle) getBlobValue() any {
method setBlobID (line 750) | func (ch *cpeHandle) setBlobID(id ID) {
method setBlob (line 754) | func (ch *cpeHandle) setBlob(rawBlobValue []byte) error {
type AffectedCPEHandle (line 770) | type AffectedCPEHandle
method getCPEHandle (line 772) | func (ch *AffectedCPEHandle) getCPEHandle() *cpeHandle {
method vulnerability (line 776) | func (ch AffectedCPEHandle) vulnerability() string {
method String (line 780) | func (ch AffectedCPEHandle) String() string {
method getBlobID (line 784) | func (ch AffectedCPEHandle) getBlobID() ID {
method getBlobValue (line 788) | func (ch AffectedCPEHandle) getBlobValue() any {
method setBlobID (line 792) | func (ch *AffectedCPEHandle) setBlobID(id ID) {
method setBlob (line 796) | func (ch *AffectedCPEHandle) setBlob(rawBlobValue []byte) error {
type UnaffectedCPEHandle (line 800) | type UnaffectedCPEHandle
method getCPEHandle (line 802) | func (ch *UnaffectedCPEHandle) getCPEHandle() *cpeHandle {
method vulnerability (line 806) | func (ch UnaffectedCPEHandle) vulnerability() string { // nolint:unuse...
method String (line 810) | func (ch UnaffectedCPEHandle) String() string {
method getBlobID (line 814) | func (ch UnaffectedCPEHandle) getBlobID() ID {
method getBlobValue (line 818) | func (ch UnaffectedCPEHandle) getBlobValue() any {
method setBlobID (line 822) | func (ch *UnaffectedCPEHandle) setBlobID(id ID) {
method setBlob (line 826) | func (ch *UnaffectedCPEHandle) setBlob(rawBlobValue []byte) error {
type Cpe (line 830) | type Cpe struct
method String (line 847) | func (c Cpe) String() string {
method cacheKey (line 857) | func (c *Cpe) cacheKey() string {
method tableName (line 861) | func (c *Cpe) tableName() string {
method rowID (line 865) | func (c *Cpe) rowID() ID {
method setRowID (line 869) | func (c *Cpe) setRowID(i ID) {
method BeforeCreate (line 873) | func (c *Cpe) BeforeCreate(tx *gorm.DB) (err error) {
method AfterCreate (line 891) | func (c *Cpe) AfterCreate(tx *gorm.DB) (err error) {
type PackageCpe (line 899) | type PackageCpe struct
method TableName (line 904) | func (PackageCpe) TableName() string {
type KnownExploitedVulnerabilityHandle (line 910) | type KnownExploitedVulnerabilityHandle struct
method getBlobValue (line 919) | func (v KnownExploitedVulnerabilityHandle) getBlobValue() any {
method setBlobID (line 926) | func (v *KnownExploitedVulnerabilityHandle) setBlobID(id ID) {
method getBlobID (line 930) | func (v KnownExploitedVulnerabilityHandle) getBlobID() ID {
method setBlob (line 934) | func (v *KnownExploitedVulnerabilityHandle) setBlob(rawBlobValue []byt...
type EpssMetadata (line 944) | type EpssMetadata struct
type EpssHandle (line 948) | type EpssHandle struct
type CWEHandle (line 957) | type CWEHandle struct
method String (line 965) | func (c CWEHandle) String() string {
type OperatingSystemEOLHandle (line 971) | type OperatingSystemEOLHandle struct
method String (line 980) | func (o OperatingSystemEOLHandle) String() string {
FILE: grype/db/v6/models_test.go
function TestOperatingSystemAlias_VersionMutualExclusivity (line 11) | func TestOperatingSystemAlias_VersionMutualExclusivity(t *testing.T) {
function TestOperatingSystem_VersionNumber (line 61) | func TestOperatingSystem_VersionNumber(t *testing.T) {
function TestOperatingSystem_Version (line 91) | func TestOperatingSystem_Version(t *testing.T) {
function TestOperatingSystem_clean (line 136) | func TestOperatingSystem_clean(t *testing.T) {
FILE: grype/db/v6/name/java.go
type JavaResolver (line 12) | type JavaResolver struct
method Normalize (line 15) | func (r *JavaResolver) Normalize(name string) string {
method Names (line 19) | func (r *JavaResolver) Names(p grypePkg.Package) []string {
FILE: grype/db/v6/name/java_test.go
function TestJavaResolver_Normalize (line 12) | func TestJavaResolver_Normalize(t *testing.T) {
function TestJavaResolver_Names (line 50) | func TestJavaResolver_Names(t *testing.T) {
FILE: grype/db/v6/name/python.go
type PythonResolver (line 9) | type PythonResolver struct
method Normalize (line 12) | func (r *PythonResolver) Normalize(name string) string {
method Names (line 21) | func (r *PythonResolver) Names(p grypePkg.Package) []string {
FILE: grype/db/v6/name/python_test.go
function TestPythonResolver_Normalize (line 9) | func TestPythonResolver_Normalize(t *testing.T) {
FILE: grype/db/v6/name/resolver.go
type Resolver (line 8) | type Resolver interface
function FromType (line 13) | func FromType(t syftPkg.Type) Resolver {
function PackageNames (line 24) | func PackageNames(p grypePkg.Package) []string {
function Normalize (line 38) | func Normalize(name string, pkgType syftPkg.Type) string {
FILE: grype/db/v6/operating_system_store.go
type OSSpecifiers (line 16) | type OSSpecifiers
method String (line 93) | func (d OSSpecifiers) String() string {
method IsAny (line 104) | func (d OSSpecifiers) IsAny() bool {
type OSSpecifier (line 19) | type OSSpecifier struct
method clean (line 47) | func (d *OSSpecifier) clean() {
method String (line 52) | func (d *OSSpecifier) String() string {
method version (line 79) | func (d OSSpecifier) version() string {
method matchesVersionPattern (line 114) | func (d OSSpecifier) matchesVersionPattern(pattern string) bool {
type OperatingSystemStoreReader (line 132) | type OperatingSystemStoreReader interface
type OperatingSystemStoreWriter (line 136) | type OperatingSystemStoreWriter interface
type operatingSystemStore (line 142) | type operatingSystemStore struct
method addOsFromPackages (line 156) | func (s *operatingSystemStore) addOsFromPackages(packages ...*packageH...
method GetOperatingSystems (line 211) | func (s *operatingSystemStore) GetOperatingSystems(d OSSpecifier) ([]O...
method applyOSAlias (line 235) | func (s *operatingSystemStore) applyOSAlias(d *OSSpecifier) error {
method prepareQuery (line 338) | func (s *operatingSystemStore) prepareQuery(d OSSpecifier) *gorm.DB {
method searchForOSExactVersions (line 358) | func (s *operatingSystemStore) searchForOSExactVersions(query *gorm.DB...
method UpdateOperatingSystemEOL (line 425) | func (s *operatingSystemStore) UpdateOperatingSystemEOL(spec OSSpecifi...
function newOperatingSystemStore (line 148) | func newOperatingSystemStore(db *gorm.DB, bs *blobStore) *operatingSyste...
function applyOSSpecifierOverrides (line 252) | func applyOSSpecifierOverrides(d *OSSpecifier, overrides []OperatingSyst...
function applyOverride (line 283) | func applyOverride(d *OSSpecifier, override OperatingSystemSpecifierOver...
function canUseOverride (line 318) | func canUseOverride(override OperatingSystemSpecifierOverride, clientVer...
function trimZeroes (line 461) | func trimZeroes(s string) string {
FILE: grype/db/v6/operating_system_store_test.go
function TestOperatingSystemStore_ResolveOperatingSystem (line 14) | func TestOperatingSystemStore_ResolveOperatingSystem(t *testing.T) {
function TestOSSpecifier_String (line 384) | func TestOSSpecifier_String(t *testing.T) {
function TestTrimZeroes (line 461) | func TestTrimZeroes(t *testing.T) {
function TestOSSpecifier_clean (line 542) | func TestOSSpecifier_clean(t *testing.T) {
function TestApplyOverride (line 586) | func TestApplyOverride(t *testing.T) {
function TestApplyOSSpecifierOverrides (line 760) | func TestApplyOSSpecifierOverrides(t *testing.T) {
function strPtr (line 957) | func strPtr(s string) *string {
FILE: grype/db/v6/package_store.go
constant anyPkg (line 18) | anyPkg = "any"
constant anyOS (line 19) | anyOS = "any"
type GetPackageOptions (line 29) | type GetPackageOptions struct
type PackageSpecifiers (line 41) | type PackageSpecifiers
method String (line 74) | func (p PackageSpecifiers) String() string {
type PackageSpecifier (line 43) | type PackageSpecifier struct
method String (line 49) | func (p *PackageSpecifier) String() string {
type packageHandleStore (line 86) | type packageHandleStore interface
type packageHandleAccessor (line 90) | type packageHandleAccessor interface
type packageStore (line 94) | type packageStore struct
method handlePackage (line 291) | func (s *packageStore) handlePackage(query *gorm.DB, p *PackageSpecifi...
method handleVulnerabilityOptions (line 320) | func (s *packageStore) handleVulnerabilityOptions(query *gorm.DB, conf...
method handleOSOptions (line 329) | func (s *packageStore) handleOSOptions(query *gorm.DB, configs []*OSSp...
method applyPackageAlias (line 379) | func (s *packageStore) applyPackageAlias(d *PackageSpecifier) error {
method handlePreload (line 416) | func (s *packageStore) handlePreload(query *gorm.DB, config GetPackage...
function newPackageStore (line 100) | func newPackageStore(db *gorm.DB, bs *blobStore, oss *operatingSystemSto...
function addPackages (line 108) | func addPackages[T packageHandleStore](s *packageStore, packages ...T) (...
function addPackagesWithOS (line 179) | func addPackagesWithOS[T packageHandleStore](s *packageStore, packages ....
function getPackages (line 209) | func getPackages[T packageHandleStore]( //nolint:funlen
function handleCPEOptions (line 444) | func handleCPEOptions(query *gorm.DB, c *cpe.Attributes, allowBroad bool...
function queryCPEAttributeScope (line 457) | func queryCPEAttributeScope(query *gorm.DB, value string, dbColumn strin...
function hasOSSpecified (line 479) | func hasOSSpecified(d *OSSpecifier) bool {
FILE: grype/db/v6/provider_store.go
type ProviderStoreReader (line 12) | type ProviderStoreReader interface
type ProviderStoreWriter (line 18) | type ProviderStoreWriter interface
type providerStore (line 22) | type providerStore struct
method AddProvider (line 32) | func (s *providerStore) AddProvider(p Provider) error {
method GetProvider (line 41) | func (s *providerStore) GetProvider(name string) (*Provider, error) {
method AllProviders (line 53) | func (s *providerStore) AllProviders() ([]Provider, error) {
method fillProviders (line 69) | func (s *providerStore) fillProviders(handles []ref[string, Provider])...
function newProviderStore (line 26) | func newProviderStore(db *gorm.DB) *providerStore {
FILE: grype/db/v6/provider_store_test.go
function TestProviderStore (line 12) | func TestProviderStore(t *testing.T) {
function TestProviderStore_GetProvider (line 76) | func TestProviderStore_GetProvider(t *testing.T) {
FILE: grype/db/v6/refs.go
type ref (line 9) | type ref struct
type idRef (line 14) | type idRef
type refProvider (line 16) | type refProvider
type idProvider (line 18) | type idProvider
function fillRefs (line 20) | func fillRefs[T, R any](reader Reader, handles []*T, getRef refProvider[...
function ptrs (line 68) | func ptrs[T any](values []T) []*T {
type lowLevelReader (line 79) | type lowLevelReader interface
FILE: grype/db/v6/schema/main.go
function main (line 23) | func main() {
function generateSQLSchema (line 45) | func generateSQLSchema(version string) error {
function normalizeCreateTable (line 93) | func normalizeCreateTable(stmt string) string {
function querySchemaSorted (line 134) | func querySchemaSorted(db *sql.DB, objectType string) ([]string, error) {
function generateBlobSchema (line 174) | func generateBlobSchema(version string, comments map[string]map[string]s...
function buildUnifiedBlobSchema (line 181) | func buildUnifiedBlobSchema(version string, comments map[string]map[stri...
function mergeDefinitions (line 218) | func mergeDefinitions(target, source map[string]*jsonschema.Schema) {
function applyComments (line 224) | func applyComments(definitions map[string]*jsonschema.Schema, comments m...
function encode (line 256) | func encode(schema *jsonschema.Schema) []byte {
function writeFile (line 270) | func writeFile(content, component, version, extension string) error {
function parseCommentsFromPackages (line 331) | func parseCommentsFromPackages(pkgPatterns []string) map[string]map[stri...
function parseFileComments (line 356) | func parseFileComments(node *ast.File) map[string]map[string]string {
function cleanComment (line 410) | func cleanComment(comment string) string {
function getJSONTag (line 420) | func getJSONTag(field *ast.Field) string {
function repoRoot (line 432) | func repoRoot() string {
FILE: grype/db/v6/search_query.go
type searchQuery (line 14) | type searchQuery struct
function newSearchQuery (line 24) | func newSearchQuery(criteriaSet []vulnerability.Criteria) (*searchQuery,...
type searchQueryBuilder (line 36) | type searchQueryBuilder struct
method ApplyCriteria (line 50) | func (b *searchQueryBuilder) ApplyCriteria(criteriaSet []vulnerability...
method handlePackageName (line 84) | func (b *searchQueryBuilder) handlePackageName(c *search.PackageNameCr...
method handleUnaffected (line 91) | func (b *searchQueryBuilder) handleUnaffected(_ *search.UnaffectedCrit...
method handleEcosystem (line 95) | func (b *searchQueryBuilder) handleEcosystem(c *search.EcosystemCriter...
method handleID (line 116) | func (b *searchQueryBuilder) handleID(c *search.IDCriteria) {
method handleCPE (line 122) | func (b *searchQueryBuilder) handleCPE(c *search.CPECriteria) error {
method handleDistro (line 140) | func (b *searchQueryBuilder) handleDistro(c *search.DistroCriteria) {
method setDefaultOS (line 173) | func (b *searchQueryBuilder) setDefaultOS() {
method normalizePackageName (line 182) | func (b *searchQueryBuilder) normalizePackageName() {
method extractVersionMatcher (line 189) | func (b *searchQueryBuilder) extractVersionMatcher() {
method Build (line 210) | func (b *searchQueryBuilder) Build() (*searchQuery, []vulnerability.Cr...
function newSearchQueryBuilder (line 42) | func newSearchQueryBuilder() *searchQueryBuilder {
FILE: grype/db/v6/search_query_test.go
function TestNewSearchCriteria (line 15) | func TestNewSearchCriteria(t *testing.T) {
function TestQueryBuilder_ApplyCriteria (line 83) | func TestQueryBuilder_ApplyCriteria(t *testing.T) {
function TestQueryBuilder_CPEErrorHandling (line 180) | func TestQueryBuilder_CPEErrorHandling(t *testing.T) {
function TestQueryBuilder_PostProcess (line 200) | func TestQueryBuilder_PostProcess(t *testing.T) {
function TestQueryBuilder_Build (line 271) | func TestQueryBuilder_Build(t *testing.T) {
function TestQueryBuilder_ExactDistroCriteria (line 287) | func TestQueryBuilder_ExactDistroCriteria(t *testing.T) {
function TestQueryBuilder_IntegrationWithRealCriteria (line 347) | func TestQueryBuilder_IntegrationWithRealCriteria(t *testing.T) {
FILE: grype/db/v6/severity.go
function extractSeverities (line 11) | func extractSeverities(vuln *VulnerabilityHandle) (vulnerability.Severit...
function extractSeverity (line 27) | func extractSeverity(severity any) (vulnerability.Severity, error) {
function interpretCVSS (line 45) | func interpretCVSS(score float64, version string) vulnerability.Severity {
function interpretCVSSv2 (line 56) | func interpretCVSSv2(score float64) vulnerability.Severity {
function interpretCVSSv3Plus (line 75) | func interpretCVSSv3Plus(score float64) vulnerability.Severity {
function toCvss (line 97) | func toCvss(severities ...Severity) []vulnerability.Cvss {
function legacyCVSSType (line 134) | func legacyCVSSType(rank int) string {
FILE: grype/db/v6/severity_test.go
function TestExtractSeverity (line 12) | func TestExtractSeverity(t *testing.T) {
function TestExtractSeverities (line 129) | func TestExtractSeverities(t *testing.T) {
FILE: grype/db/v6/store.go
type store (line 12) | type store struct
method GetDB (line 29) | func (s *store) GetDB() *gorm.DB {
method attachBlobValue (line 33) | func (s *store) attachBlobValue(values ...blobable) error {
method Close (line 108) | func (s *store) Close() error {
function InitialData (line 37) | func InitialData() []any {
function newStore (line 51) | func newStore(cfg Config, empty, writable bool) (*store, error) {
function dropAllIndexes (line 144) | func dropAllIndexes(db *gorm.DB) error {
FILE: grype/db/v6/store_test.go
function TestStoreClose (line 12) | func TestStoreClose(t *testing.T) {
function Test_oldDbV5 (line 60) | func Test_oldDbV5(t *testing.T) {
function Test_oldDbWithMetadata (line 70) | func Test_oldDbWithMetadata(t *testing.T) {
FILE: grype/db/v6/unaffected_cpe_store.go
type UnaffectedCPEStoreWriter (line 9) | type UnaffectedCPEStoreWriter interface
type UnaffectedCPEStoreReader (line 13) | type UnaffectedCPEStoreReader interface
type unaffectedCPEStore (line 17) | type unaffectedCPEStore struct
method AddUnaffectedCPEs (line 31) | func (s *unaffectedCPEStore) AddUnaffectedCPEs(packages ...*Unaffected...
method GetUnaffectedCPEs (line 35) | func (s *unaffectedCPEStore) GetUnaffectedCPEs(cpe *cpe.Attributes, co...
function newUnaffectedCPEStore (line 23) | func newUnaffectedCPEStore(db *gorm.DB, bs *blobStore) *unaffectedCPESto...
FILE: grype/db/v6/unaffected_cpe_store_test.go
function TestUnaffectedCPEStore_AddUnaffectedCPEs (line 11) | func TestUnaffectedCPEStore_AddUnaffectedCPEs(t *testing.T) {
function TestUnaffectedCPEStore_GetCPEs (line 56) | func TestUnaffectedCPEStore_GetCPEs(t *testing.T) {
function TestUnaffectedCPEStore_GetExact (line 87) | func TestUnaffectedCPEStore_GetExact(t *testing.T) {
function TestUnaffectedCPEStore_Get_CaseInsensitive (line 107) | func TestUnaffectedCPEStore_Get_CaseInsensitive(t *testing.T) {
function TestUnaffectedCPEStore_PreventDuplicateCPEs (line 136) | func TestUnaffectedCPEStore_PreventDuplicateCPEs(t *testing.T) {
function testUnaffectedCPEHandle (line 211) | func testUnaffectedCPEHandle() *UnaffectedCPEHandle {
FILE: grype/db/v6/unaffected_package_store.go
type UnaffectedPackageStoreWriter (line 5) | type UnaffectedPackageStoreWriter interface
type UnaffectedPackageStoreReader (line 9) | type UnaffectedPackageStoreReader interface
type unaffectedPackageStore (line 12) | type unaffectedPackageStore struct
method AddUnaffectedPackages (line 26) | func (s *unaffectedPackageStore) AddUnaffectedPackages(packages ...*Un...
method GetUnaffectedPackages (line 30) | func (s *unaffectedPackageStore) GetUnaffectedPackages(pkg *PackageSpe...
function newUnaffectedPackageStore (line 18) | func newUnaffectedPackageStore(db *gorm.DB, bs *blobStore, oss *operatin...
FILE: grype/db/v6/unaffected_package_store_test.go
type unaffectedPackageHandlePreloadConfig (line 16) | type unaffectedPackageHandlePreloadConfig struct
function defaultUnaffectedPackageHandlePreloadCases (line 25) | func defaultUnaffectedPackageHandlePreloadCases() []unaffectedPackageHan...
function TestUnaffectedPackageStore_AddUnaffectedPackages (line 137) | func TestUnaffectedPackageStore_AddUnaffectedPackages(t *testing.T) {
function TestUnaffectedPackageStore_GetUnaffectedPackages_ByCPE (line 431) | func TestUnaffectedPackageStore_GetUnaffectedPackages_ByCPE(t *testing.T) {
function TestUnaffectedPackageStore_GetUnaffectedPackages_CaseInsensitive (line 597) | func TestUnaffectedPackageStore_GetUnaffectedPackages_CaseInsensitive(t ...
function TestUnaffectedPackageStore_GetUnaffectedPackages_MultipleVulnerabilitySpecs (line 737) | func TestUnaffectedPackageStore_GetUnaffectedPackages_MultipleVulnerabil...
function TestUnaffectedPackageStore_GetUnaffectedPackages (line 793) | func TestUnaffectedPackageStore_GetUnaffectedPackages(t *testing.T) {
function TestUnaffectedPackageStore_ApplyPackageAlias (line 948) | func TestUnaffectedPackageStore_ApplyPackageAlias(t *testing.T) {
function testDistro1UnaffectedPackage2Handle (line 988) | func testDistro1UnaffectedPackage2Handle() *UnaffectedPackageHandle {
function testDistro2UnaffectedPackage2Handle (line 1017) | func testDistro2UnaffectedPackage2Handle() *UnaffectedPackageHandle {
function testNonDistroUnaffectedPackage2Handle (line 1045) | func testNonDistroUnaffectedPackage2Handle() *UnaffectedPackageHandle {
FILE: grype/db/v6/vulnerability.go
constant nvdProvider (line 21) | nvdProvider = "nvd"
constant githubProvider (line 22) | githubProvider = "github"
constant v5NvdNamespace (line 23) | v5NvdNamespace = "nvd:cpe"
function newVulnerabilityFromAffectedPackageHandle (line 26) | func newVulnerabilityFromAffectedPackageHandle(affected AffectedPackageH...
function newVulnerabilityFromAffectedCPEHandle (line 39) | func newVulnerabilityFromAffectedCPEHandle(affected AffectedCPEHandle, a...
function newVulnerabilityFromUnaffectedPackageHandle (line 46) | func newVulnerabilityFromUnaffectedPackageHandle(unaffected UnaffectedPa...
function newVulnerabilityFromUnaffectedCPEHandle (line 63) | func newVulnerabilityFromUnaffectedCPEHandle(unaffected UnaffectedCPEHan...
function newVulnerabilityFromParts (line 74) | func newVulnerabilityFromParts(packageName string, vuln *VulnerabilityHa...
function getVersionConstraint (line 107) | func getVersionConstraint(affectedRanges []Range) (version.Constraint, e...
function getRelatedVulnerabilities (line 141) | func getRelatedVulnerabilities(vuln *VulnerabilityHandle, affected *Pack...
function getPackageQualifiers (line 190) | func getPackageQualifiers(affected *PackageBlob) []qualifier.Qualifier {
function MimicV5Namespace (line 201) | func MimicV5Namespace(vuln *VulnerabilityHandle, affected *AffectedPacka...
function mimicV5GithubNamespace (line 274) | func mimicV5GithubNamespace(provider, language string) string {
function toPackageQualifiers (line 301) | func toPackageQualifiers(qualifiers *PackageQualifiers) []qualifier.Qual...
function toFix (line 315) | func toFix(affectedRanges []Range) vulnerability.Fix {
function toAdvisories (line 359) | func toAdvisories(affectedRanges []Range) []vulnerability.Advisory {
function toCPEs (line 379) | func toCPEs(affectedPackageHandle *AffectedPackageHandle, affectedCPEHan...
FILE: grype/db/v6/vulnerability_decorator_store.go
type VulnerabilityDecoratorStoreWriter (line 14) | type VulnerabilityDecoratorStoreWriter interface
type VulnerabilityDecoratorStoreReader (line 20) | type VulnerabilityDecoratorStoreReader interface
type vulnerabilityDecoratorStore (line 26) | type vulnerabilityDecoratorStore struct
method AddEpss (line 54) | func (s *vulnerabilityDecoratorStore) AddEpss(epss ...*EpssHandle) err...
method AddCWE (line 74) | func (s *vulnerabilityDecoratorStore) AddCWE(cwe ...*CWEHandle) error {
method setEPSSMetadata (line 90) | func (s *vulnerabilityDecoratorStore) setEPSSMetadata(date time.Time) ...
method getEPSSMetadata (line 121) | func (s *vulnerabilityDecoratorStore) getEPSSMetadata() (*EpssMetadata...
method GetEpss (line 130) | func (s *vulnerabilityDecoratorStore) GetEpss(cve string) ([]EpssHandl...
method GetCWEs (line 175) | func (s *vulnerabilityDecoratorStore) GetCWEs(cve string) ([]CWEHandle...
method AddKnownExploitedVulnerabilities (line 210) | func (s *vulnerabilityDecoratorStore) AddKnownExploitedVulnerabilities...
method GetKnownExploitedVulnerabilities (line 230) | func (s *vulnerabilityDecoratorStore) GetKnownExploitedVulnerabilities...
type vulnerabilityDecoratorCapabilities (line 33) | type vulnerabilityDecoratorCapabilities struct
function newVulnerabilityDecoratorStore (line 39) | func newVulnerabilityDecoratorStore(db *gorm.DB, bs *blobStore, dbVersio...
FILE: grype/db/v6/vulnerability_decorator_store_test.go
function TestVulnerabilityDecoratorStore (line 16) | func TestVulnerabilityDecoratorStore(t *testing.T) {
function TestVulnerabilityDecoratorStore_AddKnownExploitedVulnerabilities_VersionCompatibility (line 142) | func TestVulnerabilityDecoratorStore_AddKnownExploitedVulnerabilities_Ve...
function TestVulnerabilityDecoratorStore_GetKnownExploitedVulnerabilities_VersionCompatibility (line 210) | func TestVulnerabilityDecoratorStore_GetKnownExploitedVulnerabilities_Ve...
function TestVulnerabilityDecoratorCapabilities_AllCapabilitiesCovered (line 297) | func TestVulnerabilityDecoratorCapabilities_AllCapabilitiesCovered(t *te...
function timeRef (line 380) | func timeRef(t time.Time) *time.Time {
FILE: grype/db/v6/vulnerability_provider.go
function NewVulnerabilityProvider (line 31) | func NewVulnerabilityProvider(rdr Reader) vulnerability.Provider {
type vulnerabilityProvider (line 37) | type vulnerabilityProvider struct
method VulnerabilityMetadata (line 42) | func (vp vulnerabilityProvider) VulnerabilityMetadata(ref vulnerabilit...
method getVulnerabilityMetadata (line 65) | func (vp vulnerabilityProvider) getVulnerabilityMetadata(vuln *Vulnera...
method fetchCWE (line 86) | func (vp vulnerabilityProvider) fetchCWE(cves []string) ([]vulnerabili...
method DataProvenance (line 131) | func (vp vulnerabilityProvider) DataProvenance() (map[string]vulnerabi...
method fetchVulnerability (line 151) | func (vp vulnerabilityProvider) fetchVulnerability(ref vulnerability.R...
method fetchKnownExploited (line 163) | func (vp vulnerabilityProvider) fetchKnownExploited(cves []string) ([]...
method fetchEpss (line 190) | func (vp vulnerabilityProvider) fetchEpss(cves []string) ([]vulnerabil...
method PackageSearchNames (line 211) | func (vp vulnerabilityProvider) PackageSearchNames(p pkg.Package) []st...
method Close (line 215) | func (
Condensed preview — 1026 files, each showing path, character count, and a content snippet. Download the .json file or copy for the full structured content (5,509K chars).
[
{
"path": ".binny.yaml",
"chars": 2284,
"preview": "tools:\n # we want to use a pinned version of binny to manage the toolchain (so binny manages itself!)\n - name: binny\n "
},
{
"path": ".bouncer.yaml",
"chars": 2205,
"preview": "permit:\n - BSD.*\n - CC0.*\n - MIT.*\n - Apache.*\n - MPL.*\n - ISC\n - WTFPL\n\nignore-packages:\n # packageurl-go is re"
},
{
"path": ".chronicle.yaml",
"chars": 93,
"preview": "enforce-v0: true # don't make breaking-change label bump major version before 1.0.\ntitle: \"\"\n"
},
{
"path": ".github/ISSUE_TEMPLATE/bug_report.md",
"chars": 837,
"preview": "---\nname: Bug report\nabout: Create a report to help us improve\ntitle: ''\nlabels: bug\nassignees: ''\n\n---\n\n**What happened"
},
{
"path": ".github/ISSUE_TEMPLATE/config.yml",
"chars": 250,
"preview": "contact_links:\n\n - name: Join our Discourse community 💬\n # link to our community Discourse site\n url: https://anc"
},
{
"path": ".github/ISSUE_TEMPLATE/feature_request.md",
"chars": 281,
"preview": "---\nname: Feature request\nabout: Suggest an idea for this project\ntitle: ''\nlabels: enhancement\nassignees: ''\n\n---\n\n**Wh"
},
{
"path": ".github/ISSUE_TEMPLATE/match_issue.md",
"chars": 1294,
"preview": "---\nname: Vulnerability Match Issue\nabout: Report an issue with vulnerability matching\ntitle: ''\nlabels: [ bug, false-po"
},
{
"path": ".github/actions/bootstrap/action.yaml",
"chars": 2366,
"preview": "name: \"Bootstrap\"\ndescription: \"Bootstrap all tools and dependencies\"\ninputs:\n go-version:\n description: \"Go version"
},
{
"path": ".github/dependabot.yaml",
"chars": 501,
"preview": "version: 2\nupdates:\n - package-ecosystem: \"github-actions\"\n directory: \"/\"\n schedule:\n interval: daily\n c"
},
{
"path": ".github/scripts/check-syft-version-is-release.sh",
"chars": 618,
"preview": "#!/usr/bin/env bash\nset -e\n\nversion=$(grep -E \"github.com/anchore/syft\" go.mod | awk '{print $NF}')\n\n# ensure that the v"
},
{
"path": ".github/scripts/ci-check.sh",
"chars": 239,
"preview": "#!/usr/bin/env bash\n\nred=$(tput setaf 1)\nbold=$(tput bold)\nnormal=$(tput sgr0)\n\n# assert we are running in CI (or die!)\n"
},
{
"path": ".github/scripts/coverage.py",
"chars": 861,
"preview": "#!/usr/bin/env python3\nimport subprocess\nimport sys\nimport shlex\n\n\nclass bcolors:\n HEADER = '\\033[95m'\n OKBLUE = '"
},
{
"path": ".github/scripts/db-schema-drift-check.sh",
"chars": 597,
"preview": "#!/usr/bin/env bash\nset -u\n\nif [ \"$(git status --porcelain | wc -l)\" -ne \"0\" ]; then\n echo \" 🔴 there are uncommitted c"
},
{
"path": ".github/scripts/go-mod-tidy-check.sh",
"chars": 974,
"preview": "#!/usr/bin/env bash\nset -eu\n\nORIGINAL_STATE_DIR=$(mktemp -d \"TEMP-original-state-XXXXXXXXX\")\nTIDY_STATE_DIR=$(mktemp -d "
},
{
"path": ".github/scripts/json-schema-drift-check.sh",
"chars": 434,
"preview": "#!/usr/bin/env bash\nset -u\n\nif [ \"$(git status --porcelain | wc -l)\" -ne \"0\" ]; then\n echo \" 🔴 there are uncommitted c"
},
{
"path": ".github/scripts/trigger-release.sh",
"chars": 1942,
"preview": "#!/usr/bin/env bash\nset -eu\n\nbold=$(tput bold)\nnormal=$(tput sgr0)\n\nGH_CLI=.tool/gh\n\nif ! [ -x \"$(command -v $GH_CLI)\" ]"
},
{
"path": ".github/workflows/codeql-analysis.yml",
"chars": 419,
"preview": "name: CodeQL Security Scan\n\non:\n workflow_dispatch:\n push:\n paths:\n - '**'\n - '!**.md'\n - '!LICENSE'\n "
},
{
"path": ".github/workflows/dependabot-automation.yaml",
"chars": 177,
"preview": "name: Dependabot Automation\non:\n pull_request:\n\npermissions:\n pull-requests: write\n\njobs:\n run:\n uses: anchore/wor"
},
{
"path": ".github/workflows/oss-project-board-add.yaml",
"chars": 305,
"preview": "name: Add to OSS board\n\npermissions:\n contents: read\n\non:\n issues:\n types:\n - opened\n - reopened\n - "
},
{
"path": ".github/workflows/release.yaml",
"chars": 11067,
"preview": "name: \"Release\"\non:\n workflow_dispatch:\n inputs:\n version:\n description: tag the latest commit on main w"
},
{
"path": ".github/workflows/remove-awaiting-response-label.yaml",
"chars": 311,
"preview": "name: \"Manage Awaiting Response Label\"\n\non:\n issue_comment:\n types: [created]\n\njobs:\n run:\n permissions:\n i"
},
{
"path": ".github/workflows/scorecards.yml",
"chars": 1437,
"preview": "name: Scorecards supply-chain security\non:\n # Only the default branch is supported.\n branch_protection_rule:\n push:\n "
},
{
"path": ".github/workflows/update-anchore-dependencies.yml",
"chars": 1673,
"preview": "name: PR to update Anchore dependencies\non:\n workflow_dispatch:\n inputs:\n repos:\n description: \"List of "
},
{
"path": ".github/workflows/update-bootstrap-tools.yml",
"chars": 2025,
"preview": "name: PR for latest versions of tools\non:\n schedule:\n - cron: \"0 8 * * *\" # 3 AM EST\n\n workflow_dispatch:\n\npermissi"
},
{
"path": ".github/workflows/update-generated-code.yml",
"chars": 2407,
"preview": "name: PR to update OS codename generated code\non:\n schedule:\n - cron: \"0 1 * * 1\" # every Monday at 1 AM UTC\n\n work"
},
{
"path": ".github/workflows/update-quality-gate-db.yml",
"chars": 1335,
"preview": "name: PR for upgrading quality gate test DB\non:\n schedule:\n - cron: \"0 16 1 * *\" # first day of each month @ 11 AM E"
},
{
"path": ".github/workflows/validate-github-actions.yaml",
"chars": 864,
"preview": "name: \"Validate GitHub Actions\"\n\non:\n pull_request:\n paths:\n - '.github/workflows/**'\n - '.github/actions/"
},
{
"path": ".github/workflows/validations.yaml",
"chars": 10894,
"preview": "name: \"Validations\"\n\non:\n workflow_dispatch:\n pull_request:\n push:\n branches:\n - main\n\npermissions:\n content"
},
{
"path": ".github/zizmor.yml",
"chars": 156,
"preview": "rules:\n unpinned-uses:\n config:\n policies:\n # anchore/workflows is an internal repository; using @main i"
},
{
"path": ".gitignore",
"chars": 1028,
"preview": "# AI\n.claude\nCLAUDE.MD\n\n# local development tailoring\ngo.work\ngo.work.sum\n.tool-versions\n.jj/\nmise.toml\nspecs/\n*.xxh64\n\n"
},
{
"path": ".gitmodules",
"chars": 182,
"preview": "[submodule \"test/quality/vulnerability-match-labels\"]\n\tpath = test/quality/vulnerability-match-labels\n\turl = https://git"
},
{
"path": ".golangci.yaml",
"chars": 3236,
"preview": "version: \"2\"\nlinters:\n # inverted configuration with `enable-all` and `disable` is not scalable during updates of gol"
},
{
"path": ".goreleaser.yaml",
"chars": 11239,
"preview": "version: 2\n\nrelease:\n prerelease: auto\n draft: false\n\nenv:\n # required to support multi architecture docker builds\n "
},
{
"path": "CODE_OF_CONDUCT.md",
"chars": 288,
"preview": "# Code of Conduct\n\nAll contributors for any Anchore project must follow the [Contributor Covenant Code of Conduct](https"
},
{
"path": "CONTRIBUTING.md",
"chars": 1246,
"preview": "# Contributing\n\nThank you for your interest in contributing to Grype!\n\nPlease see the [contribution guide](https://oss.a"
},
{
"path": "Dockerfile",
"chars": 1126,
"preview": "FROM gcr.io/distroless/static-debian12:latest AS build\n\nFROM scratch\n# needed for version check HTTPS request\nCOPY --fro"
},
{
"path": "Dockerfile.debug",
"chars": 981,
"preview": "FROM gcr.io/distroless/static-debian12:debug-nonroot\n\n# create the /tmp dir, which is needed for image content cache\nWOR"
},
{
"path": "Dockerfile.nonroot",
"chars": 975,
"preview": "FROM gcr.io/distroless/static-debian12:nonroot\n\n# create the /tmp dir, which is needed for image content cache\nWORKDIR /"
},
{
"path": "LICENSE",
"chars": 11357,
"preview": " Apache License\n Version 2.0, January 2004\n "
},
{
"path": "Makefile",
"chars": 1277,
"preview": "TOOL_DIR = .tool\nBINNY = $(TOOL_DIR)/binny\nTASK = $(TOOL_DIR)/task\n\n.DEFAULT_GOAL := make-default\n\n## Bootstrapping targ"
},
{
"path": "README.md",
"chars": 6161,
"preview": "<p align=\"center\">\n <img alt=\"Grype logo\" src=\"https://user-images.githubusercontent.com/5199289/136855393-d0a9eef9-c"
},
{
"path": "RELEASE.md",
"chars": 2074,
"preview": "# Release\n\nA release of grype comprises:\n- a new semver git tag from the current tip of the main branch\n- a new [github "
},
{
"path": "SECURITY.md",
"chars": 648,
"preview": "# Security Policy\n\n## Supported Versions\n\nSecurity updates are applied only to the most recent release, try to always be"
},
{
"path": "Taskfile.yaml",
"chars": 13563,
"preview": "version: \"3\"\nvars:\n OWNER: anchore\n PROJECT: grype\n\n # static file dirs\n TOOL_DIR: .tool\n TMP_DIR: .tmp\n\n # used f"
},
{
"path": "artifacthub-repo.yml",
"chars": 218,
"preview": "# See documentation here: https://github.com/artifacthub/hub/blob/v1.6.0/docs/metadata/artifacthub-repo.yml\nrepositoryID"
},
{
"path": "cmd/grype/cli/cli.go",
"chars": 4303,
"preview": "package cli\n\nimport (\n\t\"errors\"\n\t\"os\"\n\t\"runtime/debug\"\n\t\"strings\"\n\n\t\"github.com/charmbracelet/lipgloss\"\n\t\"github.com/mue"
},
{
"path": "cmd/grype/cli/cli_test.go",
"chars": 316,
"preview": "package cli\n\nimport (\n\t\"testing\"\n\n\t\"github.com/stretchr/testify/require\"\n\n\t\"github.com/anchore/clio\"\n)\n\nfunc Test_Comman"
},
{
"path": "cmd/grype/cli/commands/completion.go",
"chars": 3398,
"preview": "package commands\n\nimport (\n\t\"context\"\n\t\"os\"\n\t\"strings\"\n\n\t\"github.com/docker/docker/api/types/filters\"\n\t\"github.com/docke"
},
{
"path": "cmd/grype/cli/commands/db.go",
"chars": 484,
"preview": "package commands\n\nimport (\n\t\"github.com/spf13/cobra\"\n\n\t\"github.com/anchore/clio\"\n)\n\nconst (\n\tjsonOutputFormat = \"json\"\n"
},
{
"path": "cmd/grype/cli/commands/db_check.go",
"chars": 3797,
"preview": "package commands\n\nimport (\n\t\"encoding/json\"\n\t\"fmt\"\n\t\"io\"\n\t\"os\"\n\n\t\"github.com/spf13/cobra\"\n\n\t\"github.com/anchore/clio\"\n\t\""
},
{
"path": "cmd/grype/cli/commands/db_check_test.go",
"chars": 3424,
"preview": "package commands\n\nimport (\n\t\"bytes\"\n\t\"strings\"\n\t\"testing\"\n\t\"time\"\n\n\t\"github.com/stretchr/testify/assert\"\n\t\"github.com/st"
},
{
"path": "cmd/grype/cli/commands/db_delete.go",
"chars": 1319,
"preview": "package commands\n\nimport (\n\t\"fmt\"\n\n\t\"github.com/spf13/cobra\"\n\n\t\"github.com/anchore/clio\"\n\t\"github.com/anchore/grype/cmd/"
},
{
"path": "cmd/grype/cli/commands/db_import.go",
"chars": 1957,
"preview": "package commands\n\nimport (\n\t\"fmt\"\n\n\t\"github.com/spf13/cobra\"\n\n\t\"github.com/anchore/clio\"\n\t\"github.com/anchore/grype/cmd/"
},
{
"path": "cmd/grype/cli/commands/db_list.go",
"chars": 3505,
"preview": "package commands\n\nimport (\n\t\"encoding/json\"\n\t\"fmt\"\n\t\"io\"\n\t\"net/url\"\n\t\"os\"\n\n\t\"github.com/spf13/cobra\"\n\n\t\"github.com/ancho"
},
{
"path": "cmd/grype/cli/commands/db_list_test.go",
"chars": 4708,
"preview": "package commands\n\nimport (\n\t\"bytes\"\n\t\"encoding/json\"\n\t\"net/http\"\n\t\"net/http/httptest\"\n\t\"strings\"\n\t\"testing\"\n\t\"time\"\n\n\t\"g"
},
{
"path": "cmd/grype/cli/commands/db_providers.go",
"chars": 3830,
"preview": "package commands\n\nimport (\n\t\"encoding/json\"\n\t\"fmt\"\n\t\"io\"\n\t\"strings\"\n\t\"time\"\n\n\t\"github.com/spf13/cobra\"\n\n\t\"github.com/anc"
},
{
"path": "cmd/grype/cli/commands/db_providers_test.go",
"chars": 2077,
"preview": "package commands\n\nimport (\n\t\"bytes\"\n\t\"testing\"\n\t\"time\"\n\n\t\"github.com/stretchr/testify/require\"\n)\n\nfunc TestDisplayDBProv"
},
{
"path": "cmd/grype/cli/commands/db_search.go",
"chars": 7798,
"preview": "package commands\n\nimport (\n\t\"encoding/json\"\n\t\"errors\"\n\t\"fmt\"\n\t\"io\"\n\t\"regexp\"\n\t\"sort\"\n\t\"strings\"\n\n\t\"github.com/spf13/cobr"
},
{
"path": "cmd/grype/cli/commands/db_search_test.go",
"chars": 3924,
"preview": "package commands\n\nimport (\n\t\"testing\"\n\n\t\"github.com/google/go-cmp/cmp\"\n\t\"github.com/google/go-cmp/cmp/cmpopts\"\n\t\"github."
},
{
"path": "cmd/grype/cli/commands/db_search_vuln.go",
"chars": 6393,
"preview": "package commands\n\nimport (\n\t\"encoding/json\"\n\t\"fmt\"\n\t\"io\"\n\t\"sort\"\n\t\"strings\"\n\t\"time\"\n\n\t\"github.com/hashicorp/go-multierro"
},
{
"path": "cmd/grype/cli/commands/db_search_vuln_test.go",
"chars": 2550,
"preview": "package commands\n\nimport (\n\t\"testing\"\n\t\"time\"\n\n\t\"github.com/stretchr/testify/require\"\n\n\t\"github.com/anchore/grype/cmd/gr"
},
{
"path": "cmd/grype/cli/commands/db_status.go",
"chars": 2955,
"preview": "package commands\n\nimport (\n\t\"encoding/json\"\n\t\"fmt\"\n\t\"io\"\n\t\"os\"\n\t\"time\"\n\n\t\"github.com/spf13/cobra\"\n\n\t\"github.com/anchore/"
},
{
"path": "cmd/grype/cli/commands/db_status_test.go",
"chars": 3919,
"preview": "package commands\n\nimport (\n\t\"bytes\"\n\t\"errors\"\n\t\"strings\"\n\t\"testing\"\n\t\"time\"\n\n\t\"github.com/stretchr/testify/assert\"\n\t\"git"
},
{
"path": "cmd/grype/cli/commands/db_update.go",
"chars": 2029,
"preview": "package commands\n\nimport (\n\t\"fmt\"\n\n\t\"github.com/spf13/cobra\"\n\n\t\"github.com/anchore/clio\"\n\t\"github.com/anchore/grype/cmd/"
},
{
"path": "cmd/grype/cli/commands/explain.go",
"chars": 1954,
"preview": "package commands\n\nimport (\n\t\"encoding/json\"\n\t\"fmt\"\n\t\"os\"\n\n\t\"github.com/spf13/cobra\"\n\n\t\"github.com/anchore/clio\"\n\t\"github"
},
{
"path": "cmd/grype/cli/commands/internal/dbsearch/affected_packages.go",
"chars": 9039,
"preview": "package dbsearch\n\nimport (\n\t\"errors\"\n\t\"fmt\"\n\n\tv6 \"github.com/anchore/grype/grype/db/v6\"\n\t\"github.com/anchore/grype/inter"
},
{
"path": "cmd/grype/cli/commands/internal/dbsearch/affected_packages_test.go",
"chars": 31172,
"preview": "package dbsearch\n\nimport (\n\t\"bytes\"\n\t\"encoding/json\"\n\t\"testing\"\n\t\"time\"\n\n\t\"github.com/google/go-cmp/cmp\"\n\t\"github.com/st"
},
{
"path": "cmd/grype/cli/commands/internal/dbsearch/common.go",
"chars": 2148,
"preview": "package dbsearch\n\nimport v6 \"github.com/anchore/grype/grype/db/v6\"\n\nconst (\n\tfixStateFixed = \"fixed\"\n\tfixStateNotFixe"
},
{
"path": "cmd/grype/cli/commands/internal/dbsearch/matches.go",
"chars": 4167,
"preview": "package dbsearch\n\nimport (\n\t\"errors\"\n\t\"fmt\"\n\t\"sort\"\n\n\t\"github.com/hashicorp/go-multierror\"\n\n\tv6 \"github.com/anchore/gryp"
},
{
"path": "cmd/grype/cli/commands/internal/dbsearch/matches_test.go",
"chars": 7268,
"preview": "package dbsearch\n\nimport (\n\t\"testing\"\n\n\t\"github.com/stretchr/testify/assert\"\n\n\tv6 \"github.com/anchore/grype/grype/db/v6\""
},
{
"path": "cmd/grype/cli/commands/internal/dbsearch/versions.go",
"chars": 1183,
"preview": "package dbsearch\n\nconst (\n\t// MatchesSchemaVersion is the schema version for the `db search` command\n\tMatchesSchemaVersi"
},
{
"path": "cmd/grype/cli/commands/internal/dbsearch/vulnerabilities.go",
"chars": 9239,
"preview": "package dbsearch\n\nimport (\n\t\"errors\"\n\t\"fmt\"\n\t\"sort\"\n\t\"time\"\n\n\tv6 \"github.com/anchore/grype/grype/db/v6\"\n\t\"github.com/anc"
},
{
"path": "cmd/grype/cli/commands/internal/dbsearch/vulnerabilities_test.go",
"chars": 12301,
"preview": "package dbsearch\n\nimport (\n\t\"fmt\"\n\t\"testing\"\n\t\"time\"\n\n\t\"github.com/google/go-cmp/cmp\"\n\t\"github.com/google/go-cmp/cmp/cmp"
},
{
"path": "cmd/grype/cli/commands/internal/dbsearch/vulnerability_decorations.go",
"chars": 3684,
"preview": "package dbsearch\n\nimport (\n\t\"strings\"\n\t\"time\"\n\n\t\"github.com/hashicorp/go-multierror\"\n\t\"github.com/scylladb/go-set/strset"
},
{
"path": "cmd/grype/cli/commands/internal/jsonschema/main.go",
"chars": 6994,
"preview": "package main\n\nimport (\n\t\"bytes\"\n\t\"encoding/json\"\n\t\"fmt\"\n\t\"go/ast\"\n\t\"io\"\n\t\"os\"\n\t\"os/exec\"\n\t\"path/filepath\"\n\t\"reflect\"\n\t\"s"
},
{
"path": "cmd/grype/cli/commands/root.go",
"chars": 18817,
"preview": "package commands\n\nimport (\n\t\"context\"\n\t\"errors\"\n\t\"fmt\"\n\t\"strings\"\n\t\"time\"\n\n\t\"github.com/spf13/cobra\"\n\t\"github.com/wagood"
},
{
"path": "cmd/grype/cli/commands/root_test.go",
"chars": 9966,
"preview": "package commands\n\nimport (\n\t\"testing\"\n\n\t\"github.com/google/go-cmp/cmp\"\n\t\"github.com/google/go-cmp/cmp/cmpopts\"\n\t\"github."
},
{
"path": "cmd/grype/cli/commands/testdata/provider-metadata.json",
"chars": 217,
"preview": "{\n \"providers\": [\n {\n \"name\": \"provider1\",\n \"lastSuccessfulRun\": \"2024-10-16T01:33:16.844201Z\"\n },\n "
},
{
"path": "cmd/grype/cli/commands/update.go",
"chars": 2119,
"preview": "package commands\n\nimport (\n\t\"fmt\"\n\t\"io\"\n\t\"net/http\"\n\t\"strings\"\n\n\t\"github.com/anchore/clio\"\n\thashiVersion \"github.com/anc"
},
{
"path": "cmd/grype/cli/commands/update_test.go",
"chars": 5342,
"preview": "package commands\n\nimport (\n\t\"net/http\"\n\t\"net/http/httptest\"\n\t\"testing\"\n\n\t\"github.com/anchore/clio\"\n\thashiVersion \"github"
},
{
"path": "cmd/grype/cli/commands/util.go",
"chars": 2891,
"preview": "package commands\n\nimport (\n\t\"fmt\"\n\t\"io\"\n\t\"os\"\n\t\"strings\"\n\t\"sync\"\n\n\t\"github.com/hashicorp/go-multierror\"\n\t\"github.com/ole"
},
{
"path": "cmd/grype/cli/commands/util_test.go",
"chars": 3099,
"preview": "package commands\n\nimport (\n\t\"fmt\"\n\t\"sync\"\n\t\"sync/atomic\"\n\t\"testing\"\n\n\t\"github.com/hashicorp/go-multierror\"\n\t\"github.com/"
},
{
"path": "cmd/grype/cli/options/alerts.go",
"chars": 803,
"preview": "package options\n\nimport \"github.com/anchore/clio\"\n\n// Alerts configures how alerts are generated and displayed.\ntype Ale"
},
{
"path": "cmd/grype/cli/options/alerts_test.go",
"chars": 302,
"preview": "package options\n\nimport (\n\t\"testing\"\n\n\t\"github.com/stretchr/testify/assert\"\n)\n\nfunc TestDefaultAlerts(t *testing.T) {\n\ta"
},
{
"path": "cmd/grype/cli/options/database.go",
"chars": 4145,
"preview": "package options\n\nimport (\n\t\"time\"\n\n\t\"github.com/anchore/clio\"\n\t\"github.com/anchore/go-homedir\"\n\t\"github.com/anchore/gryp"
},
{
"path": "cmd/grype/cli/options/database_command.go",
"chars": 1550,
"preview": "package options\n\nimport (\n\t\"github.com/anchore/clio\"\n\t\"github.com/anchore/grype/grype/db/v6/distribution\"\n\t\"github.com/a"
},
{
"path": "cmd/grype/cli/options/database_search_bounds.go",
"chars": 564,
"preview": "package options\n\nimport (\n\t\"fmt\"\n\n\t\"github.com/anchore/clio\"\n)\n\ntype DBSearchBounds struct {\n\tRecordLimit int `yaml:\"lim"
},
{
"path": "cmd/grype/cli/options/database_search_format.go",
"chars": 887,
"preview": "package options\n\nimport (\n\t\"fmt\"\n\t\"strings\"\n\n\t\"github.com/scylladb/go-set/strset\"\n\n\t\"github.com/anchore/clio\"\n)\n\ntype DB"
},
{
"path": "cmd/grype/cli/options/database_search_os.go",
"chars": 2635,
"preview": "package options\n\nimport (\n\t\"fmt\"\n\t\"strings\"\n\t\"unicode\"\n\n\t\"github.com/anchore/clio\"\n\tv6 \"github.com/anchore/grype/grype/d"
},
{
"path": "cmd/grype/cli/options/database_search_os_test.go",
"chars": 2390,
"preview": "package options\n\nimport (\n\t\"testing\"\n\n\t\"github.com/google/go-cmp/cmp\"\n\t\"github.com/stretchr/testify/require\"\n\n\tv6 \"githu"
},
{
"path": "cmd/grype/cli/options/database_search_packages.go",
"chars": 2949,
"preview": "package options\n\nimport (\n\t\"errors\"\n\t\"fmt\"\n\t\"strings\"\n\n\t\"github.com/anchore/clio\"\n\tv6 \"github.com/anchore/grype/grype/db"
},
{
"path": "cmd/grype/cli/options/database_search_packages_test.go",
"chars": 2763,
"preview": "package options\n\nimport (\n\t\"testing\"\n\n\t\"github.com/google/go-cmp/cmp\"\n\t\"github.com/stretchr/testify/require\"\n\n\tv6 \"githu"
},
{
"path": "cmd/grype/cli/options/database_search_vulnerabilities.go",
"chars": 3453,
"preview": "package options\n\nimport (\n\t\"fmt\"\n\t\"time\"\n\n\t\"github.com/araddon/dateparse\"\n\n\t\"github.com/anchore/clio\"\n\tv6 \"github.com/an"
},
{
"path": "cmd/grype/cli/options/database_search_vulnerabilities_test.go",
"chars": 3726,
"preview": "package options\n\nimport (\n\t\"testing\"\n\t\"time\"\n\n\t\"github.com/google/go-cmp/cmp\"\n\t\"github.com/stretchr/testify/require\"\n\n\tv"
},
{
"path": "cmd/grype/cli/options/datasources.go",
"chars": 1705,
"preview": "package options\n\nimport (\n\t\"time\"\n\n\t\"github.com/anchore/clio\"\n\t\"github.com/anchore/grype/grype/matcher/java\"\n)\n\nconst (\n"
},
{
"path": "cmd/grype/cli/options/experimental.go",
"chars": 271,
"preview": "package options\n\n// Experimental options are opt-in features that are...\n// ...not stable\n// ...not yet fully supported\n"
},
{
"path": "cmd/grype/cli/options/fix_channels.go",
"chars": 2081,
"preview": "package options\n\nimport (\n\t\"fmt\"\n\t\"strings\"\n\n\t\"github.com/anchore/clio\"\n\t\"github.com/anchore/grype/grype/distro\"\n)\n\ntype"
},
{
"path": "cmd/grype/cli/options/grype.go",
"chars": 11258,
"preview": "package options\n\nimport (\n\t\"fmt\"\n\t\"strings\"\n\n\t\"github.com/anchore/clio\"\n\t\"github.com/anchore/grype/grype/match\"\n\t\"github"
},
{
"path": "cmd/grype/cli/options/grype_test.go",
"chars": 976,
"preview": "package options\n\nimport (\n\t\"testing\"\n\n\t\"github.com/stretchr/testify/assert\"\n)\n\nfunc Test_flatten(t *testing.T) {\n\ttests "
},
{
"path": "cmd/grype/cli/options/match.go",
"chars": 8703,
"preview": "package options\n\nimport (\n\t\"fmt\"\n\n\t\"github.com/anchore/clio\"\n\t\"github.com/anchore/grype/grype/version\"\n)\n\n// matchConfig"
},
{
"path": "cmd/grype/cli/options/match_test.go",
"chars": 5341,
"preview": "package options\n\nimport (\n\t\"testing\"\n\n\t\"github.com/stretchr/testify/assert\"\n\t\"github.com/stretchr/testify/require\"\n\n\t\"gi"
},
{
"path": "cmd/grype/cli/options/registry.go",
"chars": 4327,
"preview": "package options\n\nimport (\n\t\"os\"\n\n\t\"github.com/anchore/clio\"\n\t\"github.com/anchore/stereoscope/pkg/image\"\n)\n\ntype Registry"
},
{
"path": "cmd/grype/cli/options/registry_test.go",
"chars": 2727,
"preview": "package options\n\nimport (\n\t\"fmt\"\n\t\"testing\"\n\n\t\"github.com/stretchr/testify/assert\"\n\n\t\"github.com/anchore/stereoscope/pkg"
},
{
"path": "cmd/grype/cli/options/search.go",
"chars": 1693,
"preview": "package options\n\nimport (\n\t\"fmt\"\n\n\t\"github.com/anchore/clio\"\n\t\"github.com/anchore/syft/syft/cataloging\"\n\t\"github.com/anc"
},
{
"path": "cmd/grype/cli/options/secret.go",
"chars": 582,
"preview": "package options\n\nimport (\n\t\"fmt\"\n\n\t\"github.com/anchore/clio\"\n\t\"github.com/anchore/grype/internal/redact\"\n)\n\ntype secret "
},
{
"path": "cmd/grype/cli/options/sort_by.go",
"chars": 1158,
"preview": "package options\n\nimport (\n\t\"fmt\"\n\t\"strings\"\n\n\t\"github.com/scylladb/go-set/strset\"\n\n\t\"github.com/anchore/clio\"\n\t\"github.c"
},
{
"path": "cmd/grype/cli/ui/__snapshots__/handle_database_diff_started_test.snap",
"chars": 260,
"preview": "\n[TestHandler_handleDatabaseDiffStarted/DB_diff_started - 1]\n ⠋ Comparing Vulnerability DBs ━━━━━━━━━━━━━━━━━━━━ [c"
},
{
"path": "cmd/grype/cli/ui/__snapshots__/handle_update_vulnerability_database_test.snap",
"chars": 266,
"preview": "\n[TestHandler_handleUpdateVulnerabilityDatabase/downloading_DB - 1]\n ⠋ Vulnerability DB ━━━━━━━━━━━━━━━━━"
},
{
"path": "cmd/grype/cli/ui/__snapshots__/handle_vulnerability_scanning_started_test.snap",
"chars": 822,
"preview": "\n[TestHandler_handleVulnerabilityScanningStarted/vulnerability_scanning_in_progress/task_line - 1]\n ⠋ Scanning for vulne"
},
{
"path": "cmd/grype/cli/ui/handle_database_diff_started.go",
"chars": 1466,
"preview": "package ui\n\nimport (\n\t\"fmt\"\n\n\ttea \"github.com/charmbracelet/bubbletea\"\n\t\"github.com/wagoodman/go-partybus\"\n\t\"github.com/"
},
{
"path": "cmd/grype/cli/ui/handle_database_diff_started_test.go",
"chars": 2089,
"preview": "package ui\n\nimport (\n\t\"testing\"\n\t\"time\"\n\n\ttea \"github.com/charmbracelet/bubbletea\"\n\t\"github.com/gkampitakis/go-snaps/sna"
},
{
"path": "cmd/grype/cli/ui/handle_update_vulnerability_database.go",
"chars": 1718,
"preview": "package ui\n\nimport (\n\t\"fmt\"\n\n\ttea \"github.com/charmbracelet/bubbletea\"\n\t\"github.com/dustin/go-humanize\"\n\t\"github.com/wag"
},
{
"path": "cmd/grype/cli/ui/handle_update_vulnerability_database_test.go",
"chars": 1966,
"preview": "package ui\n\nimport (\n\t\"testing\"\n\t\"time\"\n\n\ttea \"github.com/charmbracelet/bubbletea\"\n\t\"github.com/gkampitakis/go-snaps/sna"
},
{
"path": "cmd/grype/cli/ui/handle_vulnerability_scanning_started.go",
"chars": 5723,
"preview": "package ui\n\nimport (\n\t\"fmt\"\n\t\"sort\"\n\t\"strings\"\n\t\"time\"\n\n\ttea \"github.com/charmbracelet/bubbletea\"\n\t\"github.com/charmbrac"
},
{
"path": "cmd/grype/cli/ui/handle_vulnerability_scanning_started_test.go",
"chars": 3694,
"preview": "package ui\n\nimport (\n\t\"sort\"\n\t\"testing\"\n\t\"time\"\n\n\ttea \"github.com/charmbracelet/bubbletea\"\n\t\"github.com/gkampitakis/go-s"
},
{
"path": "cmd/grype/cli/ui/handler.go",
"chars": 1380,
"preview": "package ui\n\nimport (\n\t\"sync\"\n\n\ttea \"github.com/charmbracelet/bubbletea\"\n\t\"github.com/wagoodman/go-partybus\"\n\n\t\"github.co"
},
{
"path": "cmd/grype/cli/ui/new_task_progress.go",
"chars": 483,
"preview": "package ui\n\nimport \"github.com/anchore/bubbly/bubbles/taskprogress\"\n\nfunc (m Handler) newTaskProgress(title taskprogress"
},
{
"path": "cmd/grype/cli/ui/util_test.go",
"chars": 1513,
"preview": "package ui\n\nimport (\n\t\"reflect\"\n\t\"sync\"\n\t\"testing\"\n\t\"unsafe\"\n\n\ttea \"github.com/charmbracelet/bubbletea\"\n)\n\nfunc runModel"
},
{
"path": "cmd/grype/internal/constants.go",
"chars": 60,
"preview": "package internal\n\nconst (\n\tNotProvided = \"[not provided]\"\n)\n"
},
{
"path": "cmd/grype/internal/ui/__snapshots__/post_ui_event_writer_test.snap",
"chars": 683,
"preview": "\n[Test_postUIEventWriter_write/no_events/stdout - 1]\n\n---\n\n[Test_postUIEventWriter_write/no_events/stderr - 1]\n\n---\n\n[Te"
},
{
"path": "cmd/grype/internal/ui/no_ui.go",
"chars": 861,
"preview": "package ui\n\nimport (\n\t\"os\"\n\n\t\"github.com/wagoodman/go-partybus\"\n\n\t\"github.com/anchore/clio\"\n\t\"github.com/anchore/grype/g"
},
{
"path": "cmd/grype/internal/ui/post_ui_event_writer.go",
"chars": 3482,
"preview": "package ui\n\nimport (\n\t\"fmt\"\n\t\"io\"\n\t\"strings\"\n\n\t\"github.com/charmbracelet/lipgloss\"\n\t\"github.com/hashicorp/go-multierror\""
},
{
"path": "cmd/grype/internal/ui/post_ui_event_writer_test.go",
"chars": 1993,
"preview": "package ui\n\nimport (\n\t\"bytes\"\n\t\"testing\"\n\n\t\"github.com/gkampitakis/go-snaps/snaps\"\n\t\"github.com/stretchr/testify/require"
},
{
"path": "cmd/grype/internal/ui/ui.go",
"chars": 5662,
"preview": "package ui\n\nimport (\n\t\"fmt\"\n\t\"os\"\n\t\"sync\"\n\t\"time\"\n\n\ttea \"github.com/charmbracelet/bubbletea\"\n\t\"github.com/wagoodman/go-p"
},
{
"path": "cmd/grype/main.go",
"chars": 789,
"preview": "package main\n\nimport (\n\t_ \"github.com/glebarez/sqlite\"\n\n\t\"github.com/anchore/clio\"\n\t\"github.com/anchore/grype/cmd/grype/"
},
{
"path": "go.mod",
"chars": 17928,
"preview": "module github.com/anchore/grype\n\ngo 1.25.8\n\nrequire (\n\tgithub.com/CycloneDX/cyclonedx-go v0.10.0\n\tgithub.com/Masterminds"
},
{
"path": "go.sum",
"chars": 156781,
"preview": "cel.dev/expr v0.25.1 h1:1KrZg61W6TWSxuNZ37Xy49ps13NUovb66QLprthtwi4=\ncel.dev/expr v0.25.1/go.mod h1:hrXvqGP6G6gyx8UAHSHJ"
},
{
"path": "grype/cpe/cpe.go",
"chars": 800,
"preview": "package cpe\n\nimport (\n\t\"github.com/facebookincubator/nvdtools/wfn\"\n\n\t\"github.com/anchore/grype/internal/log\"\n\t\"github.co"
},
{
"path": "grype/cpe/cpe_test.go",
"chars": 4579,
"preview": "package cpe\n\nimport (\n\t\"testing\"\n\n\t\"github.com/sergi/go-diff/diffmatchpatch\"\n\n\t\"github.com/anchore/syft/syft/cpe\"\n)\n\nfun"
},
{
"path": "grype/db/build.go",
"chars": 8103,
"preview": "package db\n\nimport (\n\t\"bytes\"\n\t\"fmt\"\n\t\"sort\"\n\t\"time\"\n\n\t\"github.com/dustin/go-humanize\"\n\t\"github.com/spf13/afero\"\n\n\t\"gith"
},
{
"path": "grype/db/data/entry.go",
"chars": 302,
"preview": "package data\n\n// Entry is a data structure responsible for capturing an individual writable entry from a data.Processor "
},
{
"path": "grype/db/data/processor.go",
"chars": 367,
"preview": "package data\n\nimport (\n\t\"io\"\n\n\t\"github.com/anchore/grype/grype/db/provider\"\n)\n\n// Processor takes individual feed group "
},
{
"path": "grype/db/data/severity.go",
"chars": 699,
"preview": "package data\n\nimport \"strings\"\n\ntype Severity string\n\nconst (\n\tSeverityUnknown Severity = \"Unknown\"\n\tSeverityNegligib"
},
{
"path": "grype/db/data/severity_test.go",
"chars": 745,
"preview": "package data\n\nimport (\n\t\"testing\"\n\n\t\"github.com/stretchr/testify/assert\"\n)\n\nfunc TestParseSeverity(t *testing.T) {\n\ttest"
},
{
"path": "grype/db/data/transformers.go",
"chars": 2088,
"preview": "package data\n\nimport (\n\t\"github.com/anchore/grype/grype/db/internal/provider/unmarshal\"\n\t\"github.com/anchore/grype/grype"
},
{
"path": "grype/db/data/writer.go",
"chars": 337,
"preview": "package data\n\n// Writer knows how to persist one or more data.Entry objects to a database. Note that the backing impleme"
},
{
"path": "grype/db/default_schema_version.go",
"chars": 107,
"preview": "package db\n\nimport db \"github.com/anchore/grype/grype/db/v6\"\n\nconst DefaultSchemaVersion = db.ModelVersion\n"
},
{
"path": "grype/db/generate.go",
"chars": 70,
"preview": "package db\n\n//go:generate go run ./internal/codename/generate/main.go\n"
},
{
"path": "grype/db/internal/codename/codename.go",
"chars": 680,
"preview": "package codename\n\nimport \"strings\"\n\nfunc LookupOS(osName, majorVersion, minorVersion string) string {\n\tmajorVersion = st"
},
{
"path": "grype/db/internal/codename/codename_test.go",
"chars": 2261,
"preview": "package codename\n\nimport (\n\t\"testing\"\n\n\t\"github.com/stretchr/testify/assert\"\n)\n\nfunc TestLookupOSCodename(t *testing.T) "
},
{
"path": "grype/db/internal/codename/codenames_generated.go",
"chars": 1743,
"preview": "// DO NOT EDIT: generated by grype/db/internal/codename/generate/main.go\n\npackage codename\n\nvar normalizedOSCodenames = "
},
{
"path": "grype/db/internal/codename/generate/main.go",
"chars": 3437,
"preview": "package main\n\nimport (\n\t\"encoding/json\"\n\t\"fmt\"\n\t\"io\"\n\t\"net/http\"\n\t\"os\"\n\t\"strings\"\n\n\t\"github.com/dave/jennifer/jen\"\n)\n\nco"
},
{
"path": "grype/db/internal/gormadapter/logger.go",
"chars": 1789,
"preview": "package gormadapter\n\nimport (\n\t\"context\"\n\t\"fmt\"\n\t\"time\"\n\n\t\"gorm.io/gorm/logger\"\n\n\tanchoreLogger \"github.com/anchore/go-l"
},
{
"path": "grype/db/internal/gormadapter/open.go",
"chars": 8195,
"preview": "package gormadapter\n\nimport (\n\t\"fmt\"\n\t\"os\"\n\t\"path/filepath\"\n\t\"strings\"\n\t\"time\"\n\n\t\"github.com/glebarez/sqlite\"\n\t\"gorm.io/"
},
{
"path": "grype/db/internal/gormadapter/open_test.go",
"chars": 5276,
"preview": "package gormadapter\n\nimport (\n\t\"os\"\n\t\"path/filepath\"\n\t\"testing\"\n\n\t\"github.com/stretchr/testify/require\"\n)\n\nfunc TestConf"
},
{
"path": "grype/db/internal/provider/unmarshal/annotated_openvex_vulnerability.go",
"chars": 662,
"preview": "package unmarshal\n\nimport (\n\t\"io\"\n\n\tgovex \"github.com/openvex/go-vex/pkg/vex\"\n)\n\ntype AnnotatedOpenVEXVulnerability stru"
},
{
"path": "grype/db/internal/provider/unmarshal/eol.go",
"chars": 3691,
"preview": "package unmarshal\n\nimport \"io\"\n\n// EndOfLifeDateRelease represents a single release entry from the endoflife.date API v1"
},
{
"path": "grype/db/internal/provider/unmarshal/epss.go",
"chars": 349,
"preview": "package unmarshal\n\nimport \"io\"\n\ntype EPSS struct {\n\tCVE string `json:\"cve\"`\n\tEPSS float64 `json:\"epss\"`\n\tP"
},
{
"path": "grype/db/internal/provider/unmarshal/errors.go",
"chars": 466,
"preview": "package unmarshal\n\nimport (\n\t\"encoding/json\"\n\t\"fmt\"\n)\n\nfunc handleJSONUnmarshalError(err error) error {\n\tif ute, ok := e"
},
{
"path": "grype/db/internal/provider/unmarshal/github_advisory.go",
"chars": 1780,
"preview": "package unmarshal\n\nimport (\n\t\"io\"\n)\n\ntype GitHubAdvisory struct {\n\tAdvisory struct {\n\t\tClassification string\n\t\tCVE "
},
{
"path": "grype/db/internal/provider/unmarshal/items_envelope.go",
"chars": 592,
"preview": "package unmarshal\n\nimport (\n\t\"encoding/json\"\n\t\"fmt\"\n\t\"io\"\n)\n\ntype ItemsEnvelope struct {\n\tSchema string `ya"
},
{
"path": "grype/db/internal/provider/unmarshal/known_exploited_vulnerability.go",
"chars": 965,
"preview": "package unmarshal\n\nimport \"io\"\n\ntype KnownExploitedVulnerability struct {\n\tCveID string `json:\"cv"
},
{
"path": "grype/db/internal/provider/unmarshal/match_exclusion.go",
"chars": 827,
"preview": "package unmarshal\n\nimport (\n\t\"io\"\n)\n\ntype MatchExclusion struct {\n\tID string `json:\"id\"`\n\tConstraints []struct "
},
{
"path": "grype/db/internal/provider/unmarshal/msrc_vulnerability.go",
"chars": 1146,
"preview": "package unmarshal\n\nimport (\n\t\"io\"\n)\n\n// MSRCVulnerability represents a single Msrc entry with vulnerability metadata\ntyp"
},
{
"path": "grype/db/internal/provider/unmarshal/nvd/cve.go",
"chars": 10447,
"preview": "package nvd\n\nimport (\n\t\"sort\"\n\n\t\"github.com/Masterminds/semver/v3\"\n\t\"github.com/jinzhu/copier\"\n\t\"golang.org/x/text/cases"
},
{
"path": "grype/db/internal/provider/unmarshal/nvd/cve_test.go",
"chars": 6683,
"preview": "package nvd\n\nimport (\n\t\"testing\"\n\n\t\"github.com/google/go-cmp/cmp\"\n\t\"github.com/google/go-cmp/cmp/cmpopts\"\n)\n\nfunc TestCv"
},
{
"path": "grype/db/internal/provider/unmarshal/nvd/cvss20/cvss20.go",
"chars": 5067,
"preview": "package cvss20\n\n// note: this was autogenerated with some manual tweaking\n\ntype Cvss20 struct {\n\t// AccessComplexity "
},
{
"path": "grype/db/internal/provider/unmarshal/nvd/cvss30/cvss30.go",
"chars": 7159,
"preview": "package cvss30\n\n// note: this was autogenerated with some manual tweaking\n\ntype Cvss30 struct {\n\t// AttackComplexity "
},
{
"path": "grype/db/internal/provider/unmarshal/nvd/cvss31/cvss31.go",
"chars": 7156,
"preview": "package cvss31\n\n// note: this was autogenerated with some manual tweaking\n\ntype Cvss31 struct {\n\t// AttackComplexity "
},
{
"path": "grype/db/internal/provider/unmarshal/nvd/cvss40/cvss40.go",
"chars": 3007,
"preview": "package cvss40\n\n// note: this was autogenerated with some manual tweaking\n\ntype Cvss40 struct {\n\tVersion string "
},
{
"path": "grype/db/internal/provider/unmarshal/nvd_vulnerability.go",
"chars": 287,
"preview": "package unmarshal\n\nimport (\n\t\"io\"\n\n\t\"github.com/anchore/grype/grype/db/internal/provider/unmarshal/nvd\"\n)\n\ntype (\n\tNVDVu"
},
{
"path": "grype/db/internal/provider/unmarshal/openvex_vulnerability.go",
"chars": 274,
"preview": "package unmarshal\n\nimport (\n\t\"io\"\n\n\tgovex \"github.com/openvex/go-vex/pkg/vex\"\n)\n\ntype OpenVEXVulnerability = govex.State"
},
{
"path": "grype/db/internal/provider/unmarshal/os_vulnerability.go",
"chars": 4345,
"preview": "package unmarshal\n\nimport (\n\t\"fmt\"\n\t\"io\"\n\t\"sort\"\n\t\"strings\"\n\t\"unicode\"\n\n\t\"github.com/anchore/grype/grype/version\"\n)\n\ntyp"
},
{
"path": "grype/db/internal/provider/unmarshal/os_vulnerability_test.go",
"chars": 5390,
"preview": "package unmarshal\n\nimport (\n\t\"testing\"\n\n\t\"github.com/stretchr/testify/assert\"\n)\n\nfunc Test_OSFixedIns_FilterToHighestMod"
},
{
"path": "grype/db/internal/provider/unmarshal/osv_vulnerability.go",
"chars": 264,
"preview": "package unmarshal\n\nimport (\n\t\"io\"\n\n\t\"github.com/google/osv-scanner/pkg/models\"\n)\n\ntype OSVVulnerability = models.Vulnera"
},
{
"path": "grype/db/internal/provider/unmarshal/single_or_multi.go",
"chars": 668,
"preview": "package unmarshal\n\nimport (\n\t\"bytes\"\n\t\"encoding/json\"\n\t\"fmt\"\n\t\"io\"\n)\n\nfunc unmarshalSingleOrMulti[T interface{}](reader "
},
{
"path": "grype/db/internal/sqlite/nullable_types.go",
"chars": 1120,
"preview": "package sqlite\n\nimport (\n\t\"database/sql\"\n\t\"encoding/json\"\n)\n\ntype NullString struct {\n\tsql.NullString\n}\n\nfunc NewNullStr"
},
{
"path": "grype/db/internal/sqlite/nullable_types_test.go",
"chars": 2663,
"preview": "package sqlite\n\nimport (\n\t\"testing\"\n\n\t\"github.com/stretchr/testify/assert\"\n)\n\nfunc TestToNullString(t *testing.T) {\n\ttes"
},
{
"path": "grype/db/internal/tarutil/file_entry.go",
"chars": 653,
"preview": "package tarutil\n\nimport (\n\t\"fmt\"\n\t\"io\"\n\t\"os\"\n)\n\nvar _ Entry = (*FileEntry)(nil)\n\ntype FileEntry struct {\n\tPath string\n}\n"
},
{
"path": "grype/db/internal/tarutil/file_entry_test.go",
"chars": 1972,
"preview": "package tarutil\n\nimport (\n\t\"archive/tar\"\n\t\"bytes\"\n\t\"os\"\n\t\"path/filepath\"\n\t\"testing\"\n\n\t\"github.com/google/uuid\"\n\t\"github."
},
{
"path": "grype/db/internal/tarutil/populate.go",
"chars": 718,
"preview": "package tarutil\n\n// PopulateWithPaths creates a compressed tar from the given paths.\nfunc PopulateWithPaths(tarPath stri"
},
{
"path": "grype/db/internal/tarutil/populate_test.go",
"chars": 1640,
"preview": "package tarutil\n\nimport (\n\t\"archive/tar\"\n\t\"compress/gzip\"\n\t\"io\"\n\t\"os\"\n\t\"path/filepath\"\n\t\"strings\"\n\t\"testing\"\n\n\t\"github.c"
},
{
"path": "grype/db/internal/tarutil/reader_entry.go",
"chars": 3809,
"preview": "package tarutil\n\nimport (\n\t\"archive/tar\"\n\t\"bytes\"\n\t\"fmt\"\n\t\"io\"\n\t\"os\"\n\n\t\"github.com/anchore/grype/internal/log\"\n)\n\nvar _ "
},
{
"path": "grype/db/internal/tarutil/reader_entry_test.go",
"chars": 4937,
"preview": "package tarutil\n\nimport (\n\t\"archive/tar\"\n\t\"bytes\"\n\t\"io\"\n\t\"io/fs\"\n\t\"os\"\n\t\"path/filepath\"\n\t\"strings\"\n\t\"testing\"\n\t\"time\"\n\n\t"
},
{
"path": "grype/db/internal/tarutil/tar.go",
"chars": 520,
"preview": "package tarutil\n\nimport (\n\t\"archive/tar\"\n\t\"io\"\n)\n\n// Writer represents a facade for writing entries to a tar file.\ntype "
},
{
"path": "grype/db/internal/tarutil/writer.go",
"chars": 4583,
"preview": "package tarutil\n\nimport (\n\t\"archive/tar\"\n\t\"bufio\"\n\t\"compress/gzip\"\n\t\"fmt\"\n\t\"io\"\n\t\"os\"\n\t\"os/exec\"\n\t\"strings\"\n\n\t\"github.co"
},
{
"path": "grype/db/internal/tarutil/writer_test.go",
"chars": 2179,
"preview": "package tarutil\n\nimport (\n\t\"archive/tar\"\n\t\"compress/gzip\"\n\t\"io\"\n\t\"os\"\n\t\"path/filepath\"\n\t\"strings\"\n\t\"testing\"\n\n\t\"github.c"
},
{
"path": "grype/db/internal/testutil/utils.go",
"chars": 147,
"preview": "package testutil\n\nimport (\n\t\"log\"\n\t\"os\"\n)\n\nfunc CloseFile(f *os.File) {\n\terr := f.Close()\n\n\tif err != nil {\n\t\tlog.Fatal("
},
{
"path": "grype/db/internal/versionutil/clean_fixed_in_version.go",
"chars": 205,
"preview": "package versionutil\n\nimport \"strings\"\n\nfunc CleanFixedInVersion(version string) string {\n\tswitch strings.TrimSpace(strin"
},
{
"path": "grype/db/internal/versionutil/constraint.go",
"chars": 737,
"preview": "package versionutil\n\nimport (\n\t\"regexp\"\n\t\"strings\"\n)\n\n// match examples:\n// >= 5.0.0\n// <= 6.1.2.beta\n// >= 5.0.0\n// < 6"
},
{
"path": "grype/db/internal/versionutil/constraint_test.go",
"chars": 539,
"preview": "package versionutil\n\nimport \"testing\"\n\nfunc TestEnforceSemVerConstraint(t *testing.T) {\n\ttests := []struct {\n\t\tvalue "
},
{
"path": "grype/db/package.go",
"chars": 707,
"preview": "package db\n\nimport (\n\t\"os\"\n\t\"path/filepath\"\n\n\tgrypeDBLegacyDistribution \"github.com/anchore/grype/grype/db/v5/distributi"
},
{
"path": "grype/db/package_legacy.go",
"chars": 4508,
"preview": "package db\n\nimport (\n\t\"fmt\"\n\t\"net/url\"\n\t\"os\"\n\t\"path\"\n\t\"path/filepath\"\n\t\"strings\"\n\t\"time\"\n\n\t\"github.com/scylladb/go-set/s"
},
{
"path": "grype/db/processors/annotated_openvex_processor.go",
"chars": 1341,
"preview": "package processors // nolint:dupl\n\nimport (\n\t\"io\"\n\n\t\"github.com/anchore/grype/grype/db/data\"\n\t\"github.com/anchore/grype/"
},
{
"path": "grype/db/processors/eol_processor.go",
"chars": 1292,
"preview": "//nolint:dupl\npackage processors\n\nimport (\n\t\"io\"\n\n\t\"github.com/anchore/grype/grype/db/data\"\n\t\"github.com/anchore/grype/g"
},
{
"path": "grype/db/processors/eol_processor_test.go",
"chars": 3147,
"preview": "package processors\n\nimport (\n\t\"os\"\n\t\"testing\"\n\n\t\"github.com/stretchr/testify/assert\"\n\t\"github.com/stretchr/testify/requi"
},
{
"path": "grype/db/processors/epss_processor.go",
"chars": 1286,
"preview": "//nolint:dupl\npackage processors\n\nimport (\n\t\"io\"\n\n\t\"github.com/anchore/grype/grype/db/data\"\n\t\"github.com/anchore/grype/g"
},
{
"path": "grype/db/processors/epss_processor_test.go",
"chars": 2053,
"preview": "package processors\n\nimport (\n\t\"os\"\n\t\"testing\"\n\n\t\"github.com/stretchr/testify/assert\"\n\t\"github.com/stretchr/testify/requi"
},
{
"path": "grype/db/processors/github_processor.go",
"chars": 1802,
"preview": "//nolint:dupl\npackage processors\n\nimport (\n\t\"io\"\n\n\t\"github.com/anchore/grype/grype/db/data\"\n\t\"github.com/anchore/grype/g"
},
{
"path": "grype/db/processors/github_processor_test.go",
"chars": 2058,
"preview": "package processors\n\nimport (\n\t\"os\"\n\t\"testing\"\n\n\t\"github.com/stretchr/testify/assert\"\n\t\"github.com/stretchr/testify/requi"
},
{
"path": "grype/db/processors/kev_processor.go",
"chars": 1359,
"preview": "//nolint:dupl\npackage processors\n\nimport (\n\t\"io\"\n\n\t\"github.com/anchore/grype/grype/db/data\"\n\t\"github.com/anchore/grype/g"
},
{
"path": "grype/db/processors/kev_processor_test.go",
"chars": 2127,
"preview": "package processors\n\nimport (\n\t\"os\"\n\t\"testing\"\n\n\t\"github.com/stretchr/testify/assert\"\n\t\"github.com/stretchr/testify/requi"
},
{
"path": "grype/db/processors/match_exclusion_processor.go",
"chars": 1376,
"preview": "//nolint:dupl\npackage processors\n\nimport (\n\t\"io\"\n\n\t\"github.com/anchore/grype/grype/db/data\"\n\t\"github.com/anchore/grype/g"
},
{
"path": "grype/db/processors/match_exclusion_processor_test.go",
"chars": 2029,
"preview": "package processors\n\nimport (\n\t\"os\"\n\t\"testing\"\n\n\t\"github.com/stretchr/testify/assert\"\n\t\"github.com/stretchr/testify/requi"
},
{
"path": "grype/db/processors/msrc_processor.go",
"chars": 1934,
"preview": "//nolint:dupl\npackage processors\n\nimport (\n\t\"io\"\n\n\t\"github.com/anchore/grype/grype/db/data\"\n\t\"github.com/anchore/grype/g"
},
{
"path": "grype/db/processors/msrc_processor_test.go",
"chars": 1966,
"preview": "package processors\n\nimport (\n\t\"os\"\n\t\"testing\"\n\n\t\"github.com/stretchr/testify/assert\"\n\t\"github.com/stretchr/testify/requi"
},
{
"path": "grype/db/processors/nvd_processor.go",
"chars": 1744,
"preview": "package processors\n\nimport (\n\t\"io\"\n\n\t\"github.com/anchore/grype/grype/db/data\"\n\t\"github.com/anchore/grype/grype/db/intern"
},
{
"path": "grype/db/processors/nvd_processor_test.go",
"chars": 1953,
"preview": "package processors\n\nimport (\n\t\"os\"\n\t\"testing\"\n\n\t\"github.com/stretchr/testify/assert\"\n\t\"github.com/stretchr/testify/requi"
},
{
"path": "grype/db/processors/openvex_processor.go",
"chars": 1343,
"preview": "package processors\n\nimport (\n\t\"io\"\n\n\t\"github.com/anchore/grype/grype/db/data\"\n\t\"github.com/anchore/grype/grype/db/intern"
},
{
"path": "grype/db/processors/openvex_processor_test.go",
"chars": 2198,
"preview": "package processors\n\nimport (\n\t\"os\"\n\t\"testing\"\n\n\t\"github.com/stretchr/testify/assert\"\n\t\"github.com/stretchr/testify/requi"
}
]
// ... and 826 more files (download for full content)
About this extraction
This page contains the full source code of the anchore/grype GitHub repository, extracted and formatted as plain text for AI agents and large language models (LLMs). The extraction includes 1026 files (4.6 MB), approximately 1.3M tokens, and a symbol index with 4164 extracted functions, classes, methods, constants, and types. Use this with OpenClaw, Claude, ChatGPT, Cursor, Windsurf, or any other AI tool that accepts text input. You can copy the full output to your clipboard or download it as a .txt file.
Extracted by GitExtract — free GitHub repo to text converter for AI. Built by Nikandr Surkov.