diff --git a/internal/constants.go b/internal/constants.go
index 794da714a..0f7c9cc0f 100644
--- a/internal/constants.go
+++ b/internal/constants.go
@@ -3,5 +3,5 @@ package internal
const (
// JSONSchemaVersion is the current schema version output by the JSON encoder
// This is roughly following the "SchemaVer" guidelines for versioning the JSON schema. Please see schema/json/README.md for details on how to increment.
- JSONSchemaVersion = "11.0.0"
+ JSONSchemaVersion = "11.0.1"
)
diff --git a/schema/json/schema-11.0.1.json b/schema/json/schema-11.0.1.json
new file mode 100644
index 000000000..cd3e2b8da
--- /dev/null
+++ b/schema/json/schema-11.0.1.json
@@ -0,0 +1,2003 @@
+{
+ "$schema": "https://json-schema.org/draft/2020-12/schema",
+ "$id": "anchore.io/schema/syft/json/11.0.1/document",
+ "$ref": "#/$defs/Document",
+ "$defs": {
+ "AlpmFileRecord": {
+ "properties": {
+ "path": {
+ "type": "string"
+ },
+ "type": {
+ "type": "string"
+ },
+ "uid": {
+ "type": "string"
+ },
+ "gid": {
+ "type": "string"
+ },
+ "time": {
+ "type": "string",
+ "format": "date-time"
+ },
+ "size": {
+ "type": "string"
+ },
+ "link": {
+ "type": "string"
+ },
+ "digest": {
+ "items": {
+ "$ref": "#/$defs/Digest"
+ },
+ "type": "array"
+ }
+ },
+ "type": "object"
+ },
+ "AlpmMetadata": {
+ "properties": {
+ "basepackage": {
+ "type": "string"
+ },
+ "package": {
+ "type": "string"
+ },
+ "version": {
+ "type": "string"
+ },
+ "description": {
+ "type": "string"
+ },
+ "architecture": {
+ "type": "string"
+ },
+ "size": {
+ "type": "integer"
+ },
+ "packager": {
+ "type": "string"
+ },
+ "url": {
+ "type": "string"
+ },
+ "validation": {
+ "type": "string"
+ },
+ "reason": {
+ "type": "integer"
+ },
+ "files": {
+ "items": {
+ "$ref": "#/$defs/AlpmFileRecord"
+ },
+ "type": "array"
+ },
+ "backup": {
+ "items": {
+ "$ref": "#/$defs/AlpmFileRecord"
+ },
+ "type": "array"
+ }
+ },
+ "type": "object",
+ "required": [
+ "basepackage",
+ "package",
+ "version",
+ "description",
+ "architecture",
+ "size",
+ "packager",
+ "url",
+ "validation",
+ "reason",
+ "files",
+ "backup"
+ ]
+ },
+ "ApkFileRecord": {
+ "properties": {
+ "path": {
+ "type": "string"
+ },
+ "ownerUid": {
+ "type": "string"
+ },
+ "ownerGid": {
+ "type": "string"
+ },
+ "permissions": {
+ "type": "string"
+ },
+ "digest": {
+ "$ref": "#/$defs/Digest"
+ }
+ },
+ "type": "object",
+ "required": [
+ "path"
+ ]
+ },
+ "ApkMetadata": {
+ "properties": {
+ "package": {
+ "type": "string"
+ },
+ "originPackage": {
+ "type": "string"
+ },
+ "maintainer": {
+ "type": "string"
+ },
+ "version": {
+ "type": "string"
+ },
+ "architecture": {
+ "type": "string"
+ },
+ "url": {
+ "type": "string"
+ },
+ "description": {
+ "type": "string"
+ },
+ "size": {
+ "type": "integer"
+ },
+ "installedSize": {
+ "type": "integer"
+ },
+ "pullDependencies": {
+ "items": {
+ "type": "string"
+ },
+ "type": "array"
+ },
+ "provides": {
+ "items": {
+ "type": "string"
+ },
+ "type": "array"
+ },
+ "pullChecksum": {
+ "type": "string"
+ },
+ "gitCommitOfApkPort": {
+ "type": "string"
+ },
+ "files": {
+ "items": {
+ "$ref": "#/$defs/ApkFileRecord"
+ },
+ "type": "array"
+ }
+ },
+ "type": "object",
+ "required": [
+ "package",
+ "originPackage",
+ "maintainer",
+ "version",
+ "architecture",
+ "url",
+ "description",
+ "size",
+ "installedSize",
+ "pullDependencies",
+ "provides",
+ "pullChecksum",
+ "gitCommitOfApkPort",
+ "files"
+ ]
+ },
+ "BinaryMetadata": {
+ "properties": {
+ "matches": {
+ "items": {
+ "$ref": "#/$defs/ClassifierMatch"
+ },
+ "type": "array"
+ }
+ },
+ "type": "object",
+ "required": [
+ "matches"
+ ]
+ },
+ "CargoPackageMetadata": {
+ "properties": {
+ "name": {
+ "type": "string"
+ },
+ "version": {
+ "type": "string"
+ },
+ "source": {
+ "type": "string"
+ },
+ "checksum": {
+ "type": "string"
+ },
+ "dependencies": {
+ "items": {
+ "type": "string"
+ },
+ "type": "array"
+ }
+ },
+ "type": "object",
+ "required": [
+ "name",
+ "version",
+ "source",
+ "checksum",
+ "dependencies"
+ ]
+ },
+ "ClassifierMatch": {
+ "properties": {
+ "classifier": {
+ "type": "string"
+ },
+ "location": {
+ "$ref": "#/$defs/Location"
+ }
+ },
+ "type": "object",
+ "required": [
+ "classifier",
+ "location"
+ ]
+ },
+ "CocoapodsMetadata": {
+ "properties": {
+ "checksum": {
+ "type": "string"
+ }
+ },
+ "type": "object",
+ "required": [
+ "checksum"
+ ]
+ },
+ "ConanLockMetadata": {
+ "properties": {
+ "ref": {
+ "type": "string"
+ },
+ "package_id": {
+ "type": "string"
+ },
+ "prev": {
+ "type": "string"
+ },
+ "requires": {
+ "items": {
+ "type": "string"
+ },
+ "type": "array"
+ },
+ "build_requires": {
+ "items": {
+ "type": "string"
+ },
+ "type": "array"
+ },
+ "py_requires": {
+ "items": {
+ "type": "string"
+ },
+ "type": "array"
+ },
+ "options": {
+ "patternProperties": {
+ ".*": {
+ "type": "string"
+ }
+ },
+ "type": "object"
+ },
+ "path": {
+ "type": "string"
+ },
+ "context": {
+ "type": "string"
+ }
+ },
+ "type": "object",
+ "required": [
+ "ref"
+ ]
+ },
+ "ConanMetadata": {
+ "properties": {
+ "ref": {
+ "type": "string"
+ }
+ },
+ "type": "object",
+ "required": [
+ "ref"
+ ]
+ },
+ "Coordinates": {
+ "properties": {
+ "path": {
+ "type": "string"
+ },
+ "layerID": {
+ "type": "string"
+ }
+ },
+ "type": "object",
+ "required": [
+ "path"
+ ]
+ },
+ "DartPubMetadata": {
+ "properties": {
+ "name": {
+ "type": "string"
+ },
+ "version": {
+ "type": "string"
+ },
+ "hosted_url": {
+ "type": "string"
+ },
+ "vcs_url": {
+ "type": "string"
+ }
+ },
+ "type": "object",
+ "required": [
+ "name",
+ "version"
+ ]
+ },
+ "Descriptor": {
+ "properties": {
+ "name": {
+ "type": "string"
+ },
+ "version": {
+ "type": "string"
+ },
+ "configuration": true
+ },
+ "type": "object",
+ "required": [
+ "name",
+ "version"
+ ]
+ },
+ "Digest": {
+ "properties": {
+ "algorithm": {
+ "type": "string"
+ },
+ "value": {
+ "type": "string"
+ }
+ },
+ "type": "object",
+ "required": [
+ "algorithm",
+ "value"
+ ]
+ },
+ "Document": {
+ "properties": {
+ "artifacts": {
+ "items": {
+ "$ref": "#/$defs/Package"
+ },
+ "type": "array"
+ },
+ "artifactRelationships": {
+ "items": {
+ "$ref": "#/$defs/Relationship"
+ },
+ "type": "array"
+ },
+ "files": {
+ "items": {
+ "$ref": "#/$defs/File"
+ },
+ "type": "array"
+ },
+ "secrets": {
+ "items": {
+ "$ref": "#/$defs/Secrets"
+ },
+ "type": "array"
+ },
+ "source": {
+ "$ref": "#/$defs/Source"
+ },
+ "distro": {
+ "$ref": "#/$defs/LinuxRelease"
+ },
+ "descriptor": {
+ "$ref": "#/$defs/Descriptor"
+ },
+ "schema": {
+ "$ref": "#/$defs/Schema"
+ }
+ },
+ "type": "object",
+ "required": [
+ "artifacts",
+ "artifactRelationships",
+ "source",
+ "distro",
+ "descriptor",
+ "schema"
+ ]
+ },
+ "DotnetDepsMetadata": {
+ "properties": {
+ "name": {
+ "type": "string"
+ },
+ "version": {
+ "type": "string"
+ },
+ "path": {
+ "type": "string"
+ },
+ "sha512": {
+ "type": "string"
+ },
+ "hashPath": {
+ "type": "string"
+ }
+ },
+ "type": "object",
+ "required": [
+ "name",
+ "version",
+ "path",
+ "sha512",
+ "hashPath"
+ ]
+ },
+ "DotnetPortableExecutableMetadata": {
+ "properties": {
+ "assemblyVersion": {
+ "type": "string"
+ },
+ "legalCopyright": {
+ "type": "string"
+ },
+ "comments": {
+ "type": "string"
+ },
+ "internalName": {
+ "type": "string"
+ },
+ "companyName": {
+ "type": "string"
+ },
+ "productName": {
+ "type": "string"
+ },
+ "productVersion": {
+ "type": "string"
+ }
+ },
+ "type": "object",
+ "required": [
+ "assemblyVersion",
+ "legalCopyright",
+ "companyName",
+ "productName",
+ "productVersion"
+ ]
+ },
+ "DpkgFileRecord": {
+ "properties": {
+ "path": {
+ "type": "string"
+ },
+ "digest": {
+ "$ref": "#/$defs/Digest"
+ },
+ "isConfigFile": {
+ "type": "boolean"
+ }
+ },
+ "type": "object",
+ "required": [
+ "path",
+ "isConfigFile"
+ ]
+ },
+ "DpkgMetadata": {
+ "properties": {
+ "package": {
+ "type": "string"
+ },
+ "source": {
+ "type": "string"
+ },
+ "version": {
+ "type": "string"
+ },
+ "sourceVersion": {
+ "type": "string"
+ },
+ "architecture": {
+ "type": "string"
+ },
+ "maintainer": {
+ "type": "string"
+ },
+ "installedSize": {
+ "type": "integer"
+ },
+ "provides": {
+ "items": {
+ "type": "string"
+ },
+ "type": "array"
+ },
+ "depends": {
+ "items": {
+ "type": "string"
+ },
+ "type": "array"
+ },
+ "preDepends": {
+ "items": {
+ "type": "string"
+ },
+ "type": "array"
+ },
+ "files": {
+ "items": {
+ "$ref": "#/$defs/DpkgFileRecord"
+ },
+ "type": "array"
+ }
+ },
+ "type": "object",
+ "required": [
+ "package",
+ "source",
+ "version",
+ "sourceVersion",
+ "architecture",
+ "maintainer",
+ "installedSize",
+ "files"
+ ]
+ },
+ "File": {
+ "properties": {
+ "id": {
+ "type": "string"
+ },
+ "location": {
+ "$ref": "#/$defs/Coordinates"
+ },
+ "metadata": {
+ "$ref": "#/$defs/FileMetadataEntry"
+ },
+ "contents": {
+ "type": "string"
+ },
+ "digests": {
+ "items": {
+ "$ref": "#/$defs/Digest"
+ },
+ "type": "array"
+ },
+ "licenses": {
+ "items": {
+ "$ref": "#/$defs/FileLicense"
+ },
+ "type": "array"
+ }
+ },
+ "type": "object",
+ "required": [
+ "id",
+ "location"
+ ]
+ },
+ "FileLicense": {
+ "properties": {
+ "value": {
+ "type": "string"
+ },
+ "spdxExpression": {
+ "type": "string"
+ },
+ "type": {
+ "type": "string"
+ },
+ "evidence": {
+ "$ref": "#/$defs/FileLicenseEvidence"
+ }
+ },
+ "type": "object",
+ "required": [
+ "value",
+ "spdxExpression",
+ "type"
+ ]
+ },
+ "FileLicenseEvidence": {
+ "properties": {
+ "confidence": {
+ "type": "integer"
+ },
+ "offset": {
+ "type": "integer"
+ },
+ "extent": {
+ "type": "integer"
+ }
+ },
+ "type": "object",
+ "required": [
+ "confidence",
+ "offset",
+ "extent"
+ ]
+ },
+ "FileMetadataEntry": {
+ "properties": {
+ "mode": {
+ "type": "integer"
+ },
+ "type": {
+ "type": "string"
+ },
+ "linkDestination": {
+ "type": "string"
+ },
+ "userID": {
+ "type": "integer"
+ },
+ "groupID": {
+ "type": "integer"
+ },
+ "mimeType": {
+ "type": "string"
+ },
+ "size": {
+ "type": "integer"
+ }
+ },
+ "type": "object",
+ "required": [
+ "mode",
+ "type",
+ "userID",
+ "groupID",
+ "mimeType",
+ "size"
+ ]
+ },
+ "GemMetadata": {
+ "properties": {
+ "name": {
+ "type": "string"
+ },
+ "version": {
+ "type": "string"
+ },
+ "files": {
+ "items": {
+ "type": "string"
+ },
+ "type": "array"
+ },
+ "authors": {
+ "items": {
+ "type": "string"
+ },
+ "type": "array"
+ },
+ "homepage": {
+ "type": "string"
+ }
+ },
+ "type": "object",
+ "required": [
+ "name",
+ "version"
+ ]
+ },
+ "GolangBinMetadata": {
+ "properties": {
+ "goBuildSettings": {
+ "patternProperties": {
+ ".*": {
+ "type": "string"
+ }
+ },
+ "type": "object"
+ },
+ "goCompiledVersion": {
+ "type": "string"
+ },
+ "architecture": {
+ "type": "string"
+ },
+ "h1Digest": {
+ "type": "string"
+ },
+ "mainModule": {
+ "type": "string"
+ },
+ "goCryptoSettings": {
+ "items": {
+ "type": "string"
+ },
+ "type": "array"
+ }
+ },
+ "type": "object",
+ "required": [
+ "goCompiledVersion",
+ "architecture"
+ ]
+ },
+ "GolangModMetadata": {
+ "properties": {
+ "h1Digest": {
+ "type": "string"
+ }
+ },
+ "type": "object"
+ },
+ "HackageMetadata": {
+ "properties": {
+ "name": {
+ "type": "string"
+ },
+ "version": {
+ "type": "string"
+ },
+ "pkgHash": {
+ "type": "string"
+ },
+ "snapshotURL": {
+ "type": "string"
+ }
+ },
+ "type": "object",
+ "required": [
+ "name",
+ "version"
+ ]
+ },
+ "IDLikes": {
+ "items": {
+ "type": "string"
+ },
+ "type": "array"
+ },
+ "JavaManifest": {
+ "properties": {
+ "main": {
+ "patternProperties": {
+ ".*": {
+ "type": "string"
+ }
+ },
+ "type": "object"
+ },
+ "namedSections": {
+ "patternProperties": {
+ ".*": {
+ "patternProperties": {
+ ".*": {
+ "type": "string"
+ }
+ },
+ "type": "object"
+ }
+ },
+ "type": "object"
+ }
+ },
+ "type": "object"
+ },
+ "JavaMetadata": {
+ "properties": {
+ "virtualPath": {
+ "type": "string"
+ },
+ "manifest": {
+ "$ref": "#/$defs/JavaManifest"
+ },
+ "pomProperties": {
+ "$ref": "#/$defs/PomProperties"
+ },
+ "pomProject": {
+ "$ref": "#/$defs/PomProject"
+ },
+ "digest": {
+ "items": {
+ "$ref": "#/$defs/Digest"
+ },
+ "type": "array"
+ }
+ },
+ "type": "object",
+ "required": [
+ "virtualPath"
+ ]
+ },
+ "KbPackageMetadata": {
+ "properties": {
+ "product_id": {
+ "type": "string"
+ },
+ "kb": {
+ "type": "string"
+ }
+ },
+ "type": "object",
+ "required": [
+ "product_id",
+ "kb"
+ ]
+ },
+ "License": {
+ "properties": {
+ "value": {
+ "type": "string"
+ },
+ "spdxExpression": {
+ "type": "string"
+ },
+ "type": {
+ "type": "string"
+ },
+ "urls": {
+ "items": {
+ "type": "string"
+ },
+ "type": "array"
+ },
+ "locations": {
+ "items": {
+ "$ref": "#/$defs/Location"
+ },
+ "type": "array"
+ }
+ },
+ "type": "object",
+ "required": [
+ "value",
+ "spdxExpression",
+ "type",
+ "urls",
+ "locations"
+ ]
+ },
+ "LinuxKernelMetadata": {
+ "properties": {
+ "name": {
+ "type": "string"
+ },
+ "architecture": {
+ "type": "string"
+ },
+ "version": {
+ "type": "string"
+ },
+ "extendedVersion": {
+ "type": "string"
+ },
+ "buildTime": {
+ "type": "string"
+ },
+ "author": {
+ "type": "string"
+ },
+ "format": {
+ "type": "string"
+ },
+ "rwRootFS": {
+ "type": "boolean"
+ },
+ "swapDevice": {
+ "type": "integer"
+ },
+ "rootDevice": {
+ "type": "integer"
+ },
+ "videoMode": {
+ "type": "string"
+ }
+ },
+ "type": "object",
+ "required": [
+ "name",
+ "architecture",
+ "version"
+ ]
+ },
+ "LinuxKernelModuleMetadata": {
+ "properties": {
+ "name": {
+ "type": "string"
+ },
+ "version": {
+ "type": "string"
+ },
+ "sourceVersion": {
+ "type": "string"
+ },
+ "path": {
+ "type": "string"
+ },
+ "description": {
+ "type": "string"
+ },
+ "author": {
+ "type": "string"
+ },
+ "license": {
+ "type": "string"
+ },
+ "kernelVersion": {
+ "type": "string"
+ },
+ "versionMagic": {
+ "type": "string"
+ },
+ "parameters": {
+ "patternProperties": {
+ ".*": {
+ "$ref": "#/$defs/LinuxKernelModuleParameter"
+ }
+ },
+ "type": "object"
+ }
+ },
+ "type": "object"
+ },
+ "LinuxKernelModuleParameter": {
+ "properties": {
+ "type": {
+ "type": "string"
+ },
+ "description": {
+ "type": "string"
+ }
+ },
+ "type": "object"
+ },
+ "LinuxRelease": {
+ "properties": {
+ "prettyName": {
+ "type": "string"
+ },
+ "name": {
+ "type": "string"
+ },
+ "id": {
+ "type": "string"
+ },
+ "idLike": {
+ "$ref": "#/$defs/IDLikes"
+ },
+ "version": {
+ "type": "string"
+ },
+ "versionID": {
+ "type": "string"
+ },
+ "versionCodename": {
+ "type": "string"
+ },
+ "buildID": {
+ "type": "string"
+ },
+ "imageID": {
+ "type": "string"
+ },
+ "imageVersion": {
+ "type": "string"
+ },
+ "variant": {
+ "type": "string"
+ },
+ "variantID": {
+ "type": "string"
+ },
+ "homeURL": {
+ "type": "string"
+ },
+ "supportURL": {
+ "type": "string"
+ },
+ "bugReportURL": {
+ "type": "string"
+ },
+ "privacyPolicyURL": {
+ "type": "string"
+ },
+ "cpeName": {
+ "type": "string"
+ },
+ "supportEnd": {
+ "type": "string"
+ }
+ },
+ "type": "object"
+ },
+ "Location": {
+ "properties": {
+ "path": {
+ "type": "string"
+ },
+ "layerID": {
+ "type": "string"
+ },
+ "annotations": {
+ "patternProperties": {
+ ".*": {
+ "type": "string"
+ }
+ },
+ "type": "object"
+ }
+ },
+ "type": "object",
+ "required": [
+ "path"
+ ]
+ },
+ "MixLockMetadata": {
+ "properties": {
+ "name": {
+ "type": "string"
+ },
+ "version": {
+ "type": "string"
+ },
+ "pkgHash": {
+ "type": "string"
+ },
+ "pkgHashExt": {
+ "type": "string"
+ }
+ },
+ "type": "object",
+ "required": [
+ "name",
+ "version",
+ "pkgHash",
+ "pkgHashExt"
+ ]
+ },
+ "NixStoreMetadata": {
+ "properties": {
+ "outputHash": {
+ "type": "string"
+ },
+ "output": {
+ "type": "string"
+ },
+ "files": {
+ "items": {
+ "type": "string"
+ },
+ "type": "array"
+ }
+ },
+ "type": "object",
+ "required": [
+ "outputHash",
+ "files"
+ ]
+ },
+ "NpmPackageJSONMetadata": {
+ "properties": {
+ "name": {
+ "type": "string"
+ },
+ "version": {
+ "type": "string"
+ },
+ "author": {
+ "type": "string"
+ },
+ "homepage": {
+ "type": "string"
+ },
+ "description": {
+ "type": "string"
+ },
+ "url": {
+ "type": "string"
+ },
+ "private": {
+ "type": "boolean"
+ }
+ },
+ "type": "object",
+ "required": [
+ "name",
+ "version",
+ "author",
+ "homepage",
+ "description",
+ "url",
+ "private"
+ ]
+ },
+ "NpmPackageLockJSONMetadata": {
+ "properties": {
+ "resolved": {
+ "type": "string"
+ },
+ "integrity": {
+ "type": "string"
+ }
+ },
+ "type": "object",
+ "required": [
+ "resolved",
+ "integrity"
+ ]
+ },
+ "Package": {
+ "properties": {
+ "id": {
+ "type": "string"
+ },
+ "name": {
+ "type": "string"
+ },
+ "version": {
+ "type": "string"
+ },
+ "type": {
+ "type": "string"
+ },
+ "foundBy": {
+ "type": "string"
+ },
+ "locations": {
+ "items": {
+ "$ref": "#/$defs/Location"
+ },
+ "type": "array"
+ },
+ "licenses": {
+ "$ref": "#/$defs/licenses"
+ },
+ "language": {
+ "type": "string"
+ },
+ "cpes": {
+ "items": {
+ "type": "string"
+ },
+ "type": "array"
+ },
+ "purl": {
+ "type": "string"
+ },
+ "metadataType": {
+ "type": "string"
+ },
+ "metadata": {
+ "anyOf": [
+ {
+ "type": "null"
+ },
+ {
+ "$ref": "#/$defs/AlpmMetadata"
+ },
+ {
+ "$ref": "#/$defs/ApkMetadata"
+ },
+ {
+ "$ref": "#/$defs/BinaryMetadata"
+ },
+ {
+ "$ref": "#/$defs/CargoPackageMetadata"
+ },
+ {
+ "$ref": "#/$defs/CocoapodsMetadata"
+ },
+ {
+ "$ref": "#/$defs/ConanLockMetadata"
+ },
+ {
+ "$ref": "#/$defs/ConanMetadata"
+ },
+ {
+ "$ref": "#/$defs/DartPubMetadata"
+ },
+ {
+ "$ref": "#/$defs/DotnetDepsMetadata"
+ },
+ {
+ "$ref": "#/$defs/DotnetPortableExecutableMetadata"
+ },
+ {
+ "$ref": "#/$defs/DpkgMetadata"
+ },
+ {
+ "$ref": "#/$defs/GemMetadata"
+ },
+ {
+ "$ref": "#/$defs/GolangBinMetadata"
+ },
+ {
+ "$ref": "#/$defs/GolangModMetadata"
+ },
+ {
+ "$ref": "#/$defs/HackageMetadata"
+ },
+ {
+ "$ref": "#/$defs/JavaMetadata"
+ },
+ {
+ "$ref": "#/$defs/KbPackageMetadata"
+ },
+ {
+ "$ref": "#/$defs/LinuxKernelMetadata"
+ },
+ {
+ "$ref": "#/$defs/LinuxKernelModuleMetadata"
+ },
+ {
+ "$ref": "#/$defs/MixLockMetadata"
+ },
+ {
+ "$ref": "#/$defs/NixStoreMetadata"
+ },
+ {
+ "$ref": "#/$defs/NpmPackageJSONMetadata"
+ },
+ {
+ "$ref": "#/$defs/NpmPackageLockJSONMetadata"
+ },
+ {
+ "$ref": "#/$defs/PhpComposerJSONMetadata"
+ },
+ {
+ "$ref": "#/$defs/PortageMetadata"
+ },
+ {
+ "$ref": "#/$defs/PythonPackageMetadata"
+ },
+ {
+ "$ref": "#/$defs/PythonPipfileLockMetadata"
+ },
+ {
+ "$ref": "#/$defs/PythonRequirementsMetadata"
+ },
+ {
+ "$ref": "#/$defs/RDescriptionFileMetadata"
+ },
+ {
+ "$ref": "#/$defs/RebarLockMetadata"
+ },
+ {
+ "$ref": "#/$defs/RpmMetadata"
+ },
+ {
+ "$ref": "#/$defs/SwiftPackageManagerMetadata"
+ }
+ ]
+ }
+ },
+ "type": "object",
+ "required": [
+ "id",
+ "name",
+ "version",
+ "type",
+ "foundBy",
+ "locations",
+ "licenses",
+ "language",
+ "cpes",
+ "purl"
+ ]
+ },
+ "PhpComposerAuthors": {
+ "properties": {
+ "name": {
+ "type": "string"
+ },
+ "email": {
+ "type": "string"
+ },
+ "homepage": {
+ "type": "string"
+ }
+ },
+ "type": "object",
+ "required": [
+ "name"
+ ]
+ },
+ "PhpComposerExternalReference": {
+ "properties": {
+ "type": {
+ "type": "string"
+ },
+ "url": {
+ "type": "string"
+ },
+ "reference": {
+ "type": "string"
+ },
+ "shasum": {
+ "type": "string"
+ }
+ },
+ "type": "object",
+ "required": [
+ "type",
+ "url",
+ "reference"
+ ]
+ },
+ "PhpComposerJSONMetadata": {
+ "properties": {
+ "name": {
+ "type": "string"
+ },
+ "version": {
+ "type": "string"
+ },
+ "source": {
+ "$ref": "#/$defs/PhpComposerExternalReference"
+ },
+ "dist": {
+ "$ref": "#/$defs/PhpComposerExternalReference"
+ },
+ "require": {
+ "patternProperties": {
+ ".*": {
+ "type": "string"
+ }
+ },
+ "type": "object"
+ },
+ "provide": {
+ "patternProperties": {
+ ".*": {
+ "type": "string"
+ }
+ },
+ "type": "object"
+ },
+ "require-dev": {
+ "patternProperties": {
+ ".*": {
+ "type": "string"
+ }
+ },
+ "type": "object"
+ },
+ "suggest": {
+ "patternProperties": {
+ ".*": {
+ "type": "string"
+ }
+ },
+ "type": "object"
+ },
+ "license": {
+ "items": {
+ "type": "string"
+ },
+ "type": "array"
+ },
+ "type": {
+ "type": "string"
+ },
+ "notification-url": {
+ "type": "string"
+ },
+ "bin": {
+ "items": {
+ "type": "string"
+ },
+ "type": "array"
+ },
+ "authors": {
+ "items": {
+ "$ref": "#/$defs/PhpComposerAuthors"
+ },
+ "type": "array"
+ },
+ "description": {
+ "type": "string"
+ },
+ "homepage": {
+ "type": "string"
+ },
+ "keywords": {
+ "items": {
+ "type": "string"
+ },
+ "type": "array"
+ },
+ "time": {
+ "type": "string"
+ }
+ },
+ "type": "object",
+ "required": [
+ "name",
+ "version",
+ "source",
+ "dist"
+ ]
+ },
+ "PomParent": {
+ "properties": {
+ "groupId": {
+ "type": "string"
+ },
+ "artifactId": {
+ "type": "string"
+ },
+ "version": {
+ "type": "string"
+ }
+ },
+ "type": "object",
+ "required": [
+ "groupId",
+ "artifactId",
+ "version"
+ ]
+ },
+ "PomProject": {
+ "properties": {
+ "path": {
+ "type": "string"
+ },
+ "parent": {
+ "$ref": "#/$defs/PomParent"
+ },
+ "groupId": {
+ "type": "string"
+ },
+ "artifactId": {
+ "type": "string"
+ },
+ "version": {
+ "type": "string"
+ },
+ "name": {
+ "type": "string"
+ },
+ "description": {
+ "type": "string"
+ },
+ "url": {
+ "type": "string"
+ }
+ },
+ "type": "object",
+ "required": [
+ "path",
+ "groupId",
+ "artifactId",
+ "version",
+ "name"
+ ]
+ },
+ "PomProperties": {
+ "properties": {
+ "path": {
+ "type": "string"
+ },
+ "name": {
+ "type": "string"
+ },
+ "groupId": {
+ "type": "string"
+ },
+ "artifactId": {
+ "type": "string"
+ },
+ "version": {
+ "type": "string"
+ },
+ "scope": {
+ "type": "string"
+ },
+ "extraFields": {
+ "patternProperties": {
+ ".*": {
+ "type": "string"
+ }
+ },
+ "type": "object"
+ }
+ },
+ "type": "object",
+ "required": [
+ "path",
+ "name",
+ "groupId",
+ "artifactId",
+ "version"
+ ]
+ },
+ "PortageFileRecord": {
+ "properties": {
+ "path": {
+ "type": "string"
+ },
+ "digest": {
+ "$ref": "#/$defs/Digest"
+ }
+ },
+ "type": "object",
+ "required": [
+ "path"
+ ]
+ },
+ "PortageMetadata": {
+ "properties": {
+ "installedSize": {
+ "type": "integer"
+ },
+ "files": {
+ "items": {
+ "$ref": "#/$defs/PortageFileRecord"
+ },
+ "type": "array"
+ }
+ },
+ "type": "object",
+ "required": [
+ "installedSize",
+ "files"
+ ]
+ },
+ "PythonDirectURLOriginInfo": {
+ "properties": {
+ "url": {
+ "type": "string"
+ },
+ "commitId": {
+ "type": "string"
+ },
+ "vcs": {
+ "type": "string"
+ }
+ },
+ "type": "object",
+ "required": [
+ "url"
+ ]
+ },
+ "PythonFileDigest": {
+ "properties": {
+ "algorithm": {
+ "type": "string"
+ },
+ "value": {
+ "type": "string"
+ }
+ },
+ "type": "object",
+ "required": [
+ "algorithm",
+ "value"
+ ]
+ },
+ "PythonFileRecord": {
+ "properties": {
+ "path": {
+ "type": "string"
+ },
+ "digest": {
+ "$ref": "#/$defs/PythonFileDigest"
+ },
+ "size": {
+ "type": "string"
+ }
+ },
+ "type": "object",
+ "required": [
+ "path"
+ ]
+ },
+ "PythonPackageMetadata": {
+ "properties": {
+ "name": {
+ "type": "string"
+ },
+ "version": {
+ "type": "string"
+ },
+ "author": {
+ "type": "string"
+ },
+ "authorEmail": {
+ "type": "string"
+ },
+ "platform": {
+ "type": "string"
+ },
+ "files": {
+ "items": {
+ "$ref": "#/$defs/PythonFileRecord"
+ },
+ "type": "array"
+ },
+ "sitePackagesRootPath": {
+ "type": "string"
+ },
+ "topLevelPackages": {
+ "items": {
+ "type": "string"
+ },
+ "type": "array"
+ },
+ "directUrlOrigin": {
+ "$ref": "#/$defs/PythonDirectURLOriginInfo"
+ }
+ },
+ "type": "object",
+ "required": [
+ "name",
+ "version",
+ "author",
+ "authorEmail",
+ "platform",
+ "sitePackagesRootPath"
+ ]
+ },
+ "PythonPipfileLockMetadata": {
+ "properties": {
+ "hashes": {
+ "items": {
+ "type": "string"
+ },
+ "type": "array"
+ },
+ "index": {
+ "type": "string"
+ }
+ },
+ "type": "object",
+ "required": [
+ "hashes",
+ "index"
+ ]
+ },
+ "PythonRequirementsMetadata": {
+ "properties": {
+ "name": {
+ "type": "string"
+ },
+ "extras": {
+ "items": {
+ "type": "string"
+ },
+ "type": "array"
+ },
+ "versionConstraint": {
+ "type": "string"
+ },
+ "url": {
+ "type": "string"
+ },
+ "markers": {
+ "type": "string"
+ }
+ },
+ "type": "object",
+ "required": [
+ "name",
+ "versionConstraint"
+ ]
+ },
+ "RDescriptionFileMetadata": {
+ "properties": {
+ "title": {
+ "type": "string"
+ },
+ "description": {
+ "type": "string"
+ },
+ "author": {
+ "type": "string"
+ },
+ "maintainer": {
+ "type": "string"
+ },
+ "url": {
+ "items": {
+ "type": "string"
+ },
+ "type": "array"
+ },
+ "repository": {
+ "type": "string"
+ },
+ "built": {
+ "type": "string"
+ },
+ "needsCompilation": {
+ "type": "boolean"
+ },
+ "imports": {
+ "items": {
+ "type": "string"
+ },
+ "type": "array"
+ },
+ "depends": {
+ "items": {
+ "type": "string"
+ },
+ "type": "array"
+ },
+ "suggests": {
+ "items": {
+ "type": "string"
+ },
+ "type": "array"
+ }
+ },
+ "type": "object"
+ },
+ "RebarLockMetadata": {
+ "properties": {
+ "name": {
+ "type": "string"
+ },
+ "version": {
+ "type": "string"
+ },
+ "pkgHash": {
+ "type": "string"
+ },
+ "pkgHashExt": {
+ "type": "string"
+ }
+ },
+ "type": "object",
+ "required": [
+ "name",
+ "version",
+ "pkgHash",
+ "pkgHashExt"
+ ]
+ },
+ "Relationship": {
+ "properties": {
+ "parent": {
+ "type": "string"
+ },
+ "child": {
+ "type": "string"
+ },
+ "type": {
+ "type": "string"
+ },
+ "metadata": true
+ },
+ "type": "object",
+ "required": [
+ "parent",
+ "child",
+ "type"
+ ]
+ },
+ "RpmMetadata": {
+ "properties": {
+ "name": {
+ "type": "string"
+ },
+ "version": {
+ "type": "string"
+ },
+ "epoch": {
+ "oneOf": [
+ {
+ "type": "integer"
+ },
+ {
+ "type": "null"
+ }
+ ]
+ },
+ "architecture": {
+ "type": "string"
+ },
+ "release": {
+ "type": "string"
+ },
+ "sourceRpm": {
+ "type": "string"
+ },
+ "size": {
+ "type": "integer"
+ },
+ "vendor": {
+ "type": "string"
+ },
+ "modularityLabel": {
+ "type": "string"
+ },
+ "files": {
+ "items": {
+ "$ref": "#/$defs/RpmdbFileRecord"
+ },
+ "type": "array"
+ }
+ },
+ "type": "object",
+ "required": [
+ "name",
+ "version",
+ "epoch",
+ "architecture",
+ "release",
+ "sourceRpm",
+ "size",
+ "vendor",
+ "modularityLabel",
+ "files"
+ ]
+ },
+ "RpmdbFileRecord": {
+ "properties": {
+ "path": {
+ "type": "string"
+ },
+ "mode": {
+ "type": "integer"
+ },
+ "size": {
+ "type": "integer"
+ },
+ "digest": {
+ "$ref": "#/$defs/Digest"
+ },
+ "userName": {
+ "type": "string"
+ },
+ "groupName": {
+ "type": "string"
+ },
+ "flags": {
+ "type": "string"
+ }
+ },
+ "type": "object",
+ "required": [
+ "path",
+ "mode",
+ "size",
+ "digest",
+ "userName",
+ "groupName",
+ "flags"
+ ]
+ },
+ "Schema": {
+ "properties": {
+ "version": {
+ "type": "string"
+ },
+ "url": {
+ "type": "string"
+ }
+ },
+ "type": "object",
+ "required": [
+ "version",
+ "url"
+ ]
+ },
+ "SearchResult": {
+ "properties": {
+ "classification": {
+ "type": "string"
+ },
+ "lineNumber": {
+ "type": "integer"
+ },
+ "lineOffset": {
+ "type": "integer"
+ },
+ "seekPosition": {
+ "type": "integer"
+ },
+ "length": {
+ "type": "integer"
+ },
+ "value": {
+ "type": "string"
+ }
+ },
+ "type": "object",
+ "required": [
+ "classification",
+ "lineNumber",
+ "lineOffset",
+ "seekPosition",
+ "length"
+ ]
+ },
+ "Secrets": {
+ "properties": {
+ "location": {
+ "$ref": "#/$defs/Coordinates"
+ },
+ "secrets": {
+ "items": {
+ "$ref": "#/$defs/SearchResult"
+ },
+ "type": "array"
+ }
+ },
+ "type": "object",
+ "required": [
+ "location",
+ "secrets"
+ ]
+ },
+ "Source": {
+ "properties": {
+ "id": {
+ "type": "string"
+ },
+ "name": {
+ "type": "string"
+ },
+ "version": {
+ "type": "string"
+ },
+ "type": {
+ "type": "string"
+ },
+ "metadata": true
+ },
+ "type": "object",
+ "required": [
+ "id",
+ "name",
+ "version",
+ "type",
+ "metadata"
+ ]
+ },
+ "SwiftPackageManagerMetadata": {
+ "properties": {
+ "revision": {
+ "type": "string"
+ }
+ },
+ "type": "object",
+ "required": [
+ "revision"
+ ]
+ },
+ "licenses": {
+ "items": {
+ "$ref": "#/$defs/License"
+ },
+ "type": "array"
+ }
+ }
+}
diff --git a/syft/formats/cyclonedxxml/encoder_test.go b/syft/formats/cyclonedxxml/encoder_test.go
index 5b8781aff..17e1eb597 100644
--- a/syft/formats/cyclonedxxml/encoder_test.go
+++ b/syft/formats/cyclonedxxml/encoder_test.go
@@ -57,7 +57,7 @@ func redactor(values ...string) testutils.Redactor {
`sha256:[A-Za-z0-9]{64}`: `sha256:redacted`,
// BOM refs
- `bom-ref="[a-zA-Z0-9\-:]+"`: `bom-ref:redacted`,
+ `bom-ref="[a-zA-Z0-9\-:]+"`: `bom-ref="redacted"`,
},
)
}
diff --git a/syft/formats/cyclonedxxml/test-fixtures/snapshot/TestCycloneDxDirectoryEncoder.golden b/syft/formats/cyclonedxxml/test-fixtures/snapshot/TestCycloneDxDirectoryEncoder.golden
index 592072d20..bbba18034 100644
--- a/syft/formats/cyclonedxxml/test-fixtures/snapshot/TestCycloneDxDirectoryEncoder.golden
+++ b/syft/formats/cyclonedxxml/test-fixtures/snapshot/TestCycloneDxDirectoryEncoder.golden
@@ -32,7 +32,7 @@
/some/path/pkg1
-
+
package-2
2.0.1
cpe:2.3:*:some:package:2:*:*:*:*:*:*:*
diff --git a/syft/formats/cyclonedxxml/test-fixtures/snapshot/TestCycloneDxImageEncoder.golden b/syft/formats/cyclonedxxml/test-fixtures/snapshot/TestCycloneDxImageEncoder.golden
index 95701d100..914602f17 100644
--- a/syft/formats/cyclonedxxml/test-fixtures/snapshot/TestCycloneDxImageEncoder.golden
+++ b/syft/formats/cyclonedxxml/test-fixtures/snapshot/TestCycloneDxImageEncoder.golden
@@ -34,7 +34,7 @@
/somefile-1.txt
-
+
package-2
2.0.1
cpe:2.3:*:some:package:2:*:*:*:*:*:*:*
diff --git a/syft/formats/spdxjson/test-fixtures/snapshot/TestSPDXJSONDirectoryEncoder.golden b/syft/formats/spdxjson/test-fixtures/snapshot/TestSPDXJSONDirectoryEncoder.golden
index dac57a1da..b5f1c29a7 100644
--- a/syft/formats/spdxjson/test-fixtures/snapshot/TestSPDXJSONDirectoryEncoder.golden
+++ b/syft/formats/spdxjson/test-fixtures/snapshot/TestSPDXJSONDirectoryEncoder.golden
@@ -39,7 +39,7 @@
},
{
"name": "package-2",
- "SPDXID": "SPDXRef-Package-deb-package-2-db4abfe497c180d3",
+ "SPDXID": "SPDXRef-Package-deb-package-2-ad5013466727018f",
"versionInfo": "2.0.1",
"supplier": "NOASSERTION",
"downloadLocation": "NOASSERTION",
@@ -78,7 +78,7 @@
},
{
"spdxElementId": "SPDXRef-DocumentRoot-Directory-some-path",
- "relatedSpdxElement": "SPDXRef-Package-deb-package-2-db4abfe497c180d3",
+ "relatedSpdxElement": "SPDXRef-Package-deb-package-2-ad5013466727018f",
"relationshipType": "CONTAINS"
},
{
diff --git a/syft/formats/spdxjson/test-fixtures/snapshot/TestSPDXJSONImageEncoder.golden b/syft/formats/spdxjson/test-fixtures/snapshot/TestSPDXJSONImageEncoder.golden
index 73e27667e..009333c6d 100644
--- a/syft/formats/spdxjson/test-fixtures/snapshot/TestSPDXJSONImageEncoder.golden
+++ b/syft/formats/spdxjson/test-fixtures/snapshot/TestSPDXJSONImageEncoder.golden
@@ -39,7 +39,7 @@
},
{
"name": "package-2",
- "SPDXID": "SPDXRef-Package-deb-package-2-958443e2d9304af4",
+ "SPDXID": "SPDXRef-Package-deb-package-2-f27313b22a5ba330",
"versionInfo": "2.0.1",
"supplier": "NOASSERTION",
"downloadLocation": "NOASSERTION",
@@ -92,7 +92,7 @@
},
{
"spdxElementId": "SPDXRef-DocumentRoot-Image-user-image-input",
- "relatedSpdxElement": "SPDXRef-Package-deb-package-2-958443e2d9304af4",
+ "relatedSpdxElement": "SPDXRef-Package-deb-package-2-f27313b22a5ba330",
"relationshipType": "CONTAINS"
},
{
diff --git a/syft/formats/spdxjson/test-fixtures/snapshot/TestSPDXRelationshipOrder.golden b/syft/formats/spdxjson/test-fixtures/snapshot/TestSPDXRelationshipOrder.golden
index 80e5b269a..260d4cba0 100644
--- a/syft/formats/spdxjson/test-fixtures/snapshot/TestSPDXRelationshipOrder.golden
+++ b/syft/formats/spdxjson/test-fixtures/snapshot/TestSPDXRelationshipOrder.golden
@@ -39,7 +39,7 @@
},
{
"name": "package-2",
- "SPDXID": "SPDXRef-Package-deb-package-2-958443e2d9304af4",
+ "SPDXID": "SPDXRef-Package-deb-package-2-f27313b22a5ba330",
"versionInfo": "2.0.1",
"supplier": "NOASSERTION",
"downloadLocation": "NOASSERTION",
@@ -214,7 +214,7 @@
},
{
"spdxElementId": "SPDXRef-DocumentRoot-Image-user-image-input",
- "relatedSpdxElement": "SPDXRef-Package-deb-package-2-958443e2d9304af4",
+ "relatedSpdxElement": "SPDXRef-Package-deb-package-2-f27313b22a5ba330",
"relationshipType": "CONTAINS"
},
{
diff --git a/syft/formats/spdxtagvalue/test-fixtures/snapshot/TestSPDXRelationshipOrder.golden b/syft/formats/spdxtagvalue/test-fixtures/snapshot/TestSPDXRelationshipOrder.golden
index 764ac9830..8b42da861 100644
--- a/syft/formats/spdxtagvalue/test-fixtures/snapshot/TestSPDXRelationshipOrder.golden
+++ b/syft/formats/spdxtagvalue/test-fixtures/snapshot/TestSPDXRelationshipOrder.golden
@@ -61,7 +61,7 @@ ExternalRef: PACKAGE-MANAGER purl pkg:oci/user-image-input@sha256:2731251dc34951
##### Package: package-2
PackageName: package-2
-SPDXID: SPDXRef-Package-deb-package-2-958443e2d9304af4
+SPDXID: SPDXRef-Package-deb-package-2-f27313b22a5ba330
PackageVersion: 2.0.1
PackageSupplier: NOASSERTION
PackageDownloadLocation: NOASSERTION
@@ -97,6 +97,6 @@ Relationship: SPDXRef-Package-python-package-1-125840abc1c66dd7 CONTAINS SPDXRef
Relationship: SPDXRef-Package-python-package-1-125840abc1c66dd7 CONTAINS SPDXRef-File-d1-f3-c6f5b29dca12661f
Relationship: SPDXRef-Package-python-package-1-125840abc1c66dd7 CONTAINS SPDXRef-File-f2-f9e49132a4b96ccd
Relationship: SPDXRef-DocumentRoot-Image-user-image-input CONTAINS SPDXRef-Package-python-package-1-125840abc1c66dd7
-Relationship: SPDXRef-DocumentRoot-Image-user-image-input CONTAINS SPDXRef-Package-deb-package-2-958443e2d9304af4
+Relationship: SPDXRef-DocumentRoot-Image-user-image-input CONTAINS SPDXRef-Package-deb-package-2-f27313b22a5ba330
Relationship: SPDXRef-DOCUMENT DESCRIBES SPDXRef-DocumentRoot-Image-user-image-input
diff --git a/syft/formats/spdxtagvalue/test-fixtures/snapshot/TestSPDXTagValueDirectoryEncoder.golden b/syft/formats/spdxtagvalue/test-fixtures/snapshot/TestSPDXTagValueDirectoryEncoder.golden
index e50194535..7cfc999cb 100644
--- a/syft/formats/spdxtagvalue/test-fixtures/snapshot/TestSPDXTagValueDirectoryEncoder.golden
+++ b/syft/formats/spdxtagvalue/test-fixtures/snapshot/TestSPDXTagValueDirectoryEncoder.golden
@@ -20,7 +20,7 @@ FilesAnalyzed: false
##### Package: package-2
PackageName: package-2
-SPDXID: SPDXRef-Package-deb-package-2-db4abfe497c180d3
+SPDXID: SPDXRef-Package-deb-package-2-ad5013466727018f
PackageVersion: 2.0.1
PackageSupplier: NOASSERTION
PackageDownloadLocation: NOASSERTION
@@ -50,6 +50,6 @@ ExternalRef: PACKAGE-MANAGER purl a-purl-2
##### Relationships
Relationship: SPDXRef-DocumentRoot-Directory-some-path CONTAINS SPDXRef-Package-python-package-1-9265397e5e15168a
-Relationship: SPDXRef-DocumentRoot-Directory-some-path CONTAINS SPDXRef-Package-deb-package-2-db4abfe497c180d3
+Relationship: SPDXRef-DocumentRoot-Directory-some-path CONTAINS SPDXRef-Package-deb-package-2-ad5013466727018f
Relationship: SPDXRef-DOCUMENT DESCRIBES SPDXRef-DocumentRoot-Directory-some-path
diff --git a/syft/formats/spdxtagvalue/test-fixtures/snapshot/TestSPDXTagValueImageEncoder.golden b/syft/formats/spdxtagvalue/test-fixtures/snapshot/TestSPDXTagValueImageEncoder.golden
index 3c640ea72..8c3d1f705 100644
--- a/syft/formats/spdxtagvalue/test-fixtures/snapshot/TestSPDXTagValueImageEncoder.golden
+++ b/syft/formats/spdxtagvalue/test-fixtures/snapshot/TestSPDXTagValueImageEncoder.golden
@@ -23,7 +23,7 @@ ExternalRef: PACKAGE-MANAGER purl pkg:oci/user-image-input@sha256:2731251dc34951
##### Package: package-2
PackageName: package-2
-SPDXID: SPDXRef-Package-deb-package-2-958443e2d9304af4
+SPDXID: SPDXRef-Package-deb-package-2-f27313b22a5ba330
PackageVersion: 2.0.1
PackageSupplier: NOASSERTION
PackageDownloadLocation: NOASSERTION
@@ -53,6 +53,6 @@ ExternalRef: PACKAGE-MANAGER purl a-purl-1
##### Relationships
Relationship: SPDXRef-DocumentRoot-Image-user-image-input CONTAINS SPDXRef-Package-python-package-1-125840abc1c66dd7
-Relationship: SPDXRef-DocumentRoot-Image-user-image-input CONTAINS SPDXRef-Package-deb-package-2-958443e2d9304af4
+Relationship: SPDXRef-DocumentRoot-Image-user-image-input CONTAINS SPDXRef-Package-deb-package-2-f27313b22a5ba330
Relationship: SPDXRef-DOCUMENT DESCRIBES SPDXRef-DocumentRoot-Image-user-image-input
diff --git a/syft/formats/syftjson/test-fixtures/snapshot/TestDirectoryEncoder.golden b/syft/formats/syftjson/test-fixtures/snapshot/TestDirectoryEncoder.golden
index 61bb2efe4..11674865f 100644
--- a/syft/formats/syftjson/test-fixtures/snapshot/TestDirectoryEncoder.golden
+++ b/syft/formats/syftjson/test-fixtures/snapshot/TestDirectoryEncoder.golden
@@ -41,7 +41,7 @@
}
},
{
- "id": "db4abfe497c180d3",
+ "id": "ad5013466727018f",
"name": "package-2",
"version": "2.0.1",
"type": "deb",
diff --git a/syft/formats/syftjson/test-fixtures/snapshot/TestEncodeFullJSONDocument.golden b/syft/formats/syftjson/test-fixtures/snapshot/TestEncodeFullJSONDocument.golden
index f83789be5..10a5cc12c 100644
--- a/syft/formats/syftjson/test-fixtures/snapshot/TestEncodeFullJSONDocument.golden
+++ b/syft/formats/syftjson/test-fixtures/snapshot/TestEncodeFullJSONDocument.golden
@@ -36,7 +36,7 @@
}
},
{
- "id": "9fd0b9f41034991d",
+ "id": "aa0ca2c331576dfd",
"name": "package-2",
"version": "2.0.1",
"type": "deb",
diff --git a/syft/formats/syftjson/test-fixtures/snapshot/TestImageEncoder.golden b/syft/formats/syftjson/test-fixtures/snapshot/TestImageEncoder.golden
index 518a90ab5..ba156fb88 100644
--- a/syft/formats/syftjson/test-fixtures/snapshot/TestImageEncoder.golden
+++ b/syft/formats/syftjson/test-fixtures/snapshot/TestImageEncoder.golden
@@ -37,7 +37,7 @@
}
},
{
- "id": "958443e2d9304af4",
+ "id": "f27313b22a5ba330",
"name": "package-2",
"version": "2.0.1",
"type": "deb",
diff --git a/syft/pkg/cataloger/deb/cataloger_test.go b/syft/pkg/cataloger/deb/cataloger_test.go
index 6e035be87..e547206e5 100644
--- a/syft/pkg/cataloger/deb/cataloger_test.go
+++ b/syft/pkg/cataloger/deb/cataloger_test.go
@@ -44,6 +44,11 @@ func TestDpkgCataloger(t *testing.T) {
Contains configuration files and directories required for
authentication to work on Debian systems. This package is required
on almost all installations.`,
+ Depends: []string{
+ "debconf (>= 0.5) | debconf-2.0",
+ "debconf (>= 1.5.19) | cdebconf",
+ "libpam-modules (>= 1.0.1-6)",
+ },
Files: []pkg.DpkgFileRecord{
{
Path: "/etc/pam.conf",
@@ -112,6 +117,7 @@ func TestDpkgCataloger(t *testing.T) {
SQLite is a C library that implements an SQL database engine.
Programs that link with the SQLite library can have SQL database
access without running a separate RDBMS process.`,
+ Depends: []string{"libc6 (>= 2.29)"},
Files: []pkg.DpkgFileRecord{
{Path: "/usr/lib/aarch64-linux-gnu/libsqlite3.so.0.8.6", Digest: &file.Digest{
Algorithm: "md5",
diff --git a/syft/pkg/cataloger/deb/package.go b/syft/pkg/cataloger/deb/package.go
index ebd72a77a..eb9b551c9 100644
--- a/syft/pkg/cataloger/deb/package.go
+++ b/syft/pkg/cataloger/deb/package.go
@@ -36,13 +36,15 @@ func newDpkgPackage(d pkg.DpkgMetadata, dbLocation file.Location, resolver file.
Metadata: d,
}
- // the current entry only has what may have been listed in the status file, however, there are additional
- // files that are listed in multiple other locations. We should retrieve them all and merge the file lists
- // together.
- mergeFileListing(resolver, dbLocation, &p)
+ if resolver != nil {
+ // the current entry only has what may have been listed in the status file, however, there are additional
+ // files that are listed in multiple other locations. We should retrieve them all and merge the file lists
+ // together.
+ mergeFileListing(resolver, dbLocation, &p)
- // fetch additional data from the copyright file to derive the license information
- addLicenses(resolver, dbLocation, &p)
+ // fetch additional data from the copyright file to derive the license information
+ addLicenses(resolver, dbLocation, &p)
+ }
p.SetID()
diff --git a/syft/pkg/cataloger/deb/parse_dpkg_db.go b/syft/pkg/cataloger/deb/parse_dpkg_db.go
index 0a7dccb2d..03c66c583 100644
--- a/syft/pkg/cataloger/deb/parse_dpkg_db.go
+++ b/syft/pkg/cataloger/deb/parse_dpkg_db.go
@@ -35,7 +35,7 @@ func parseDpkgDB(resolver file.Resolver, env *generic.Environment, reader file.L
pkgs = append(pkgs, newDpkgPackage(m, reader.Location, resolver, env.LinuxRelease))
}
- return pkgs, nil, nil
+ return pkgs, associateRelationships(pkgs), nil
}
// parseDpkgStatus is a parser function for Debian DB status contents, returning all Debian packages listed.
@@ -63,6 +63,22 @@ func parseDpkgStatus(reader io.Reader) ([]pkg.DpkgMetadata, error) {
return metadata, nil
}
+// dpkgExtractedMetadata is an adapter struct to capture the fields from the dpkg status file, however, the final
+// pkg.DpkgMetadata struct has different types for some fields (e.g. Provides, Depends, and PreDepends is []string, not a string).
+type dpkgExtractedMetadata struct {
+ Package string `mapstructure:"Package"`
+ Source string `mapstructure:"Source"`
+ Version string `mapstructure:"Version"`
+ SourceVersion string `mapstructure:"SourceVersion"`
+ Architecture string `mapstructure:"Architecture"`
+ Maintainer string `mapstructure:"Maintainer"`
+ InstalledSize int `mapstructure:"InstalledSize"`
+ Description string `mapstructure:"Description"`
+ Provides string `mapstructure:"Provides"`
+ Depends string `mapstructure:"Depends"`
+ PreDepends string `mapstructure:"PreDepends"` // note: original doc is Pre-Depends
+}
+
// parseDpkgStatusEntry returns an individual Dpkg entry, or returns errEndOfPackages if there are no more packages to parse from the reader.
func parseDpkgStatusEntry(reader *bufio.Reader) (*pkg.DpkgMetadata, error) {
var retErr error
@@ -77,22 +93,36 @@ func parseDpkgStatusEntry(reader *bufio.Reader) (*pkg.DpkgMetadata, error) {
retErr = err
}
- entry := pkg.DpkgMetadata{}
- err = mapstructure.Decode(dpkgFields, &entry)
+ raw := dpkgExtractedMetadata{}
+ err = mapstructure.Decode(dpkgFields, &raw)
if err != nil {
return nil, err
}
- sourceName, sourceVersion := extractSourceVersion(entry.Source)
+ sourceName, sourceVersion := extractSourceVersion(raw.Source)
if sourceVersion != "" {
- entry.SourceVersion = sourceVersion
- entry.Source = sourceName
+ raw.SourceVersion = sourceVersion
+ raw.Source = sourceName
}
- if entry.Package == "" {
+ if raw.Package == "" {
return nil, retErr
}
+ entry := pkg.DpkgMetadata{
+ Package: raw.Package,
+ Source: raw.Source,
+ Version: raw.Version,
+ SourceVersion: raw.SourceVersion,
+ Architecture: raw.Architecture,
+ Maintainer: raw.Maintainer,
+ InstalledSize: raw.InstalledSize,
+ Description: raw.Description,
+ Provides: splitPkgList(raw.Provides),
+ Depends: splitPkgList(raw.Depends),
+ PreDepends: splitPkgList(raw.PreDepends),
+ }
+
// there may be an optional conffiles section that we should persist as files
if conffilesSection, exists := dpkgFields["Conffiles"]; exists && conffilesSection != nil {
if sectionStr, ok := conffilesSection.(string); ok {
@@ -108,6 +138,17 @@ func parseDpkgStatusEntry(reader *bufio.Reader) (*pkg.DpkgMetadata, error) {
return &entry, retErr
}
+func splitPkgList(pkgList string) (ret []string) {
+ fields := strings.Split(pkgList, ",")
+ for _, field := range fields {
+ field = strings.TrimSpace(field)
+ if field != "" {
+ ret = append(ret, field)
+ }
+ }
+ return ret
+}
+
func extractAllFields(reader *bufio.Reader) (map[string]interface{}, error) {
dpkgFields := make(map[string]interface{})
var key string
@@ -195,3 +236,79 @@ func handleNewKeyValue(line string) (key string, val interface{}, err error) {
return "", nil, fmt.Errorf("cannot parse field from line: '%s'", line)
}
+
+// associateRelationships will create relationships between packages based on the "Depends", "Pre-Depends", and "Provides"
+// fields for installed packages. if there is an installed package that has a dependency that is (somehow) not installed,
+// then that relationship (between the installed and uninstalled package) will NOT be created.
+func associateRelationships(pkgs []pkg.Package) (relationships []artifact.Relationship) {
+ // map["provides" + "package"] -> packages that provide that package
+ lookup := make(map[string][]pkg.Package)
+
+ // read provided and add as keys for lookup keys as well as package names
+ for _, p := range pkgs {
+ meta, ok := p.Metadata.(pkg.DpkgMetadata)
+ if !ok {
+ log.Warnf("cataloger failed to extract dpkg 'provides' metadata for package %+v", p.Name)
+ continue
+ }
+ lookup[p.Name] = append(lookup[p.Name], p)
+ for _, provides := range meta.Provides {
+ k := stripVersionSpecifier(provides)
+ lookup[k] = append(lookup[k], p)
+ }
+ }
+
+ // read "Depends" and "Pre-Depends" and match with keys
+ for _, p := range pkgs {
+ meta, ok := p.Metadata.(pkg.DpkgMetadata)
+ if !ok {
+ log.Warnf("cataloger failed to extract dpkg 'dependency' metadata for package %+v", p.Name)
+ continue
+ }
+
+ var allDeps []string
+ allDeps = append(allDeps, meta.Depends...)
+ allDeps = append(allDeps, meta.PreDepends...)
+
+ for _, depSpecifier := range allDeps {
+ deps := splitPackageChoice(depSpecifier)
+ for _, dep := range deps {
+ for _, depPkg := range lookup[dep] {
+ relationships = append(relationships, artifact.Relationship{
+ From: depPkg,
+ To: p,
+ Type: artifact.DependencyOfRelationship,
+ })
+ }
+ }
+ }
+ }
+ return relationships
+}
+
+func stripVersionSpecifier(s string) string {
+ // examples:
+ // libgmp10 (>= 2:6.2.1+dfsg1) --> libgmp10
+ // libgmp10 --> libgmp10
+ // foo [i386] --> foo
+ // default-mta | mail-transport-agent --> default-mta | mail-transport-agent
+ // kernel-headers-2.2.10 [!hurd-i386] --> kernel-headers-2.2.10
+
+ items := internal.SplitAny(s, "[(<>=")
+ if len(items) == 0 {
+ return s
+ }
+
+ return strings.TrimSpace(items[0])
+}
+
+func splitPackageChoice(s string) (ret []string) {
+ fields := strings.Split(s, "|")
+ for _, field := range fields {
+ field = strings.TrimSpace(field)
+ if field != "" {
+ ret = append(ret, stripVersionSpecifier(field))
+ }
+ }
+ return ret
+}
diff --git a/syft/pkg/cataloger/deb/parse_dpkg_db_test.go b/syft/pkg/cataloger/deb/parse_dpkg_db_test.go
index 0a2c58bd8..b2d72f287 100644
--- a/syft/pkg/cataloger/deb/parse_dpkg_db_test.go
+++ b/syft/pkg/cataloger/deb/parse_dpkg_db_test.go
@@ -11,9 +11,11 @@ import (
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
+ "github.com/anchore/syft/syft/artifact"
"github.com/anchore/syft/syft/file"
"github.com/anchore/syft/syft/linux"
"github.com/anchore/syft/syft/pkg"
+ "github.com/anchore/syft/syft/pkg/cataloger/generic"
"github.com/anchore/syft/syft/pkg/cataloger/internal/pkgtest"
)
@@ -48,6 +50,18 @@ func Test_parseDpkgStatus(t *testing.T) {
* apt-cdrom to use removable media as a source for packages
* apt-config as an interface to the configuration settings
* apt-key as an interface to manage authentication keys`,
+ Provides: []string{"apt-transport-https (= 1.8.2)"},
+ Depends: []string{
+ "adduser",
+ "gpgv | gpgv2 | gpgv1",
+ "debian-archive-keyring",
+ "libapt-pkg5.0 (>= 1.7.0~alpha3~)",
+ "libc6 (>= 2.15)",
+ "libgcc1 (>= 1:3.0)",
+ "libgnutls30 (>= 3.6.6)",
+ "libseccomp2 (>= 1.0.1)",
+ "libstdc++6 (>= 5.2)",
+ },
Files: []pkg.DpkgFileRecord{
{
Path: "/etc/apt/apt.conf.d/01autoremove",
@@ -110,6 +124,18 @@ func Test_parseDpkgStatus(t *testing.T) {
* apt-cdrom to use removable media as a source for packages
* apt-config as an interface to the configuration settings
* apt-key as an interface to manage authentication keys`,
+ Provides: []string{"apt-transport-https (= 1.8.2)"},
+ Depends: []string{
+ "adduser",
+ "gpgv | gpgv2 | gpgv1",
+ "debian-archive-keyring",
+ "libapt-pkg5.0 (>= 1.7.0~alpha3~)",
+ "libc6 (>= 2.15)",
+ "libgcc1 (>= 1:3.0)",
+ "libgnutls30 (>= 3.6.6)",
+ "libseccomp2 (>= 1.0.1)",
+ "libstdc++6 (>= 5.2)",
+ },
Files: []pkg.DpkgFileRecord{},
},
},
@@ -135,7 +161,9 @@ func Test_parseDpkgStatus(t *testing.T) {
globe. It is updated periodically to reflect changes made by
political bodies to time zone boundaries, UTC offsets, and
daylight-saving rules.`,
- Files: []pkg.DpkgFileRecord{},
+ Provides: []string{"tzdata-buster"},
+ Depends: []string{"debconf (>= 0.5) | debconf-2.0"},
+ Files: []pkg.DpkgFileRecord{},
},
{
Package: "util-linux",
@@ -149,6 +177,14 @@ func Test_parseDpkgStatus(t *testing.T) {
important utilities included in this package allow you to view kernel
messages, create new filesystems, view block device information,
interface with real time clock, etc.`,
+ Depends: []string{"fdisk", "login (>= 1:4.5-1.1~)"},
+ PreDepends: []string{
+ "libaudit1 (>= 1:2.2.1)", "libblkid1 (>= 2.31.1)", "libc6 (>= 2.25)",
+ "libcap-ng0 (>= 0.7.9)", "libmount1 (>= 2.25)", "libpam0g (>= 0.99.7.1)",
+ "libselinux1 (>= 2.6-3~)", "libsmartcols1 (>= 2.33)", "libsystemd0",
+ "libtinfo6 (>= 6)", "libudev1 (>= 183)", "libuuid1 (>= 2.16)",
+ "zlib1g (>= 1:1.1.4)",
+ },
Files: []pkg.DpkgFileRecord{
{
Path: "/etc/default/hwclock",
@@ -397,3 +433,122 @@ func Test_handleNewKeyValue(t *testing.T) {
})
}
}
+
+func Test_stripVersionSpecifier(t *testing.T) {
+
+ tests := []struct {
+ name string
+ input string
+ want string
+ }{
+ {
+ name: "package name only",
+ input: "test",
+ want: "test",
+ },
+ {
+ name: "with version",
+ input: "test (1.2.3)",
+ want: "test",
+ },
+ {
+ name: "multiple packages",
+ input: "test | other",
+ want: "test | other",
+ },
+ {
+ name: "with architecture specifiers",
+ input: "test [amd64 i386]",
+ want: "test",
+ },
+ }
+ for _, tt := range tests {
+ t.Run(tt.name, func(t *testing.T) {
+ assert.Equal(t, tt.want, stripVersionSpecifier(tt.input))
+ })
+ }
+}
+
+func Test_associateRelationships(t *testing.T) {
+ tests := []struct {
+ name string
+ fixture string
+ wantRelationships map[string][]string
+ }{
+ {
+ name: "relationships for coreutils",
+ fixture: "test-fixtures/status/coreutils-relationships",
+ wantRelationships: map[string][]string{
+ "coreutils": {"libacl1", "libattr1", "libc6", "libgmp10", "libselinux1"},
+ "libacl1": {"libc6"},
+ "libattr1": {"libc6"},
+ "libc6": {"libgcc-s1"},
+ "libgcc-s1": {"gcc-12-base", "libc6"},
+ "libgmp10": {"libc6"},
+ "libpcre2-8-0": {"libc6"},
+ "libselinux1": {"libc6", "libpcre2-8-0"},
+ },
+ },
+ {
+ name: "relationships from dpkg example docs",
+ fixture: "test-fixtures/status/doc-examples",
+ wantRelationships: map[string][]string{
+ "made-up-package-1": {"kernel-headers-2.2.10", "hurd-dev", "gnumach-dev"},
+ "made-up-package-2": {"libluajit5.1-dev", "liblua5.1-dev"},
+ "made-up-package-3": {"foo", "bar"},
+ // note that the "made-up-package-4" depends on "made-up-package-5" but not via the direct
+ // package name, but through the "provides" virtual package name "virtual-package-5".
+ "made-up-package-4": {"made-up-package-5"},
+ // note that though there is a "default-mta | mail-transport-agent | not-installed"
+ // dependency choice we raise up the packages that are installed for every choice.
+ // In this case that means that "default-mta" and "mail-transport-agent".
+ "mutt": {"libc6", "default-mta", "mail-transport-agent"},
+ },
+ },
+ {
+ name: "relationships for libpam-runtime",
+ fixture: "test-fixtures/status/libpam-runtime",
+ wantRelationships: map[string][]string{
+ "libpam-runtime": {"debconf1", "debconf-2.0", "debconf2", "cdebconf", "libpam-modules"},
+ },
+ },
+ }
+ for _, tt := range tests {
+ t.Run(tt.name, func(t *testing.T) {
+ f, err := os.Open(tt.fixture)
+ require.NoError(t, err)
+
+ reader := file.NewLocationReadCloser(file.NewLocation(tt.fixture), f)
+
+ pkgs, relationships, err := parseDpkgDB(nil, &generic.Environment{}, reader)
+ require.NotEmpty(t, pkgs)
+ require.NotEmpty(t, relationships)
+ require.NoError(t, err)
+
+ if d := cmp.Diff(tt.wantRelationships, abstractRelationships(t, relationships)); d != "" {
+ t.Errorf("unexpected relationships (-want +got):\n%s", d)
+ }
+ })
+ }
+}
+
+func abstractRelationships(t testing.TB, relationships []artifact.Relationship) map[string][]string {
+ t.Helper()
+
+ abstracted := make(map[string][]string)
+ for _, relationship := range relationships {
+ fromPkg, ok := relationship.From.(pkg.Package)
+ if !ok {
+ continue
+ }
+ toPkg, ok := relationship.To.(pkg.Package)
+ if !ok {
+ continue
+ }
+
+ // we build this backwards since we use DependencyOfRelationship instead of DependsOn
+ abstracted[toPkg.Name] = append(abstracted[toPkg.Name], fromPkg.Name)
+ }
+
+ return abstracted
+}
diff --git a/syft/pkg/cataloger/deb/test-fixtures/status/coreutils-relationships b/syft/pkg/cataloger/deb/test-fixtures/status/coreutils-relationships
new file mode 100644
index 000000000..1097fea56
--- /dev/null
+++ b/syft/pkg/cataloger/deb/test-fixtures/status/coreutils-relationships
@@ -0,0 +1,114 @@
+Package: coreutils
+Essential: yes
+Status: install ok installed
+Priority: required
+Section: utils
+Installed-Size: 20272
+Maintainer: Michael Stone
+Architecture: arm64
+Multi-Arch: foreign
+Version: 9.1-1
+Pre-Depends: libacl1 (>= 2.2.23), libattr1 (>= 1:2.4.44), libc6 (>= 2.34), libgmp10 (>= 2:6.2.1+dfsg1), libselinux1 (>= 3.1~)
+
+Package: libacl1
+Status: install ok installed
+Priority: optional
+Section: libs
+Installed-Size: 101
+Maintainer: Guillem Jover
+Architecture: arm64
+Multi-Arch: same
+Source: acl
+Version: 2.3.1-3
+Depends: libc6 (>= 2.33)
+
+Package: libc6
+Status: install ok installed
+Priority: optional
+Section: libs
+Installed-Size: 23127
+Maintainer: GNU Libc Maintainers
+Architecture: arm64
+Multi-Arch: same
+Source: glibc
+Version: 2.36-9+deb12u1
+Depends: libgcc-s1
+Recommends: libidn2-0 (>= 2.0.5~)
+Suggests: glibc-doc, debconf | debconf-2.0, libc-l10n, locales, libnss-nis, libnss-nisplus
+Breaks: aide (<< 0.17.3-4+b3), busybox (<< 1.30.1-6), chrony (<< 4.2-3~), fakechroot (<< 2.19-3.5), firefox (<< 91~), firefox-esr (<< 91~), gnumach-image-1.8-486 (<< 2:1.8+git20210923~), gnumach-image-1.8-486-dbg (<< 2:1.8+git20210923~), gnumach-image-1.8-xen-486 (<< 2:1.8+git20210923~), gnumach-image-1.8-xen-486-dbg (<< 2:1.8+git20210923~), hurd (<< 1:0.9.git20220301-2), ioquake3 (<< 1.36+u20200211.f2c61c1~dfsg-2~), iraf-fitsutil (<< 2018.07.06-4), libgegl-0.4-0 (<< 0.4.18), libtirpc1 (<< 0.2.3), locales (<< 2.36), locales-all (<< 2.36), macs (<< 2.2.7.1-3~), nocache (<< 1.1-1~), nscd (<< 2.36), openarena (<< 0.8.8+dfsg-4~), openssh-server (<< 1:8.1p1-5), python3-iptables (<< 1.0.0-2), r-cran-later (<< 0.7.5+dfsg-2), tinydns (<< 1:1.05-14), valgrind (<< 1:3.19.0-1~), wcc (<< 0.0.2+dfsg-3)
+
+Package: libgcc-s1
+Protected: yes
+Status: install ok installed
+Priority: optional
+Section: libs
+Installed-Size: 147
+Maintainer: Debian GCC Maintainers
+Architecture: arm64
+Multi-Arch: same
+Source: gcc-12
+Version: 12.2.0-14
+Replaces: libgcc1 (<< 1:10)
+Provides: libgcc1 (= 1:12.2.0-14)
+Depends: gcc-12-base (= 12.2.0-14), libc6 (>= 2.35)
+
+Package: gcc-12-base
+Status: install ok installed
+Priority: optional
+Section: libs
+Installed-Size: 100
+Maintainer: Debian GCC Maintainers
+Architecture: arm64
+Multi-Arch: same
+Source: gcc-12
+Version: 12.2.0-14
+Breaks: gnat (<< 7)
+
+Package: libattr1
+Status: install ok installed
+Priority: optional
+Section: libs
+Installed-Size: 99
+Maintainer: Guillem Jover
+Architecture: arm64
+Multi-Arch: same
+Source: attr
+Version: 1:2.5.1-4
+Depends: libc6 (>= 2.17)
+
+Package: libgmp10
+Status: install ok installed
+Priority: optional
+Section: libs
+Installed-Size: 855
+Maintainer: Debian Science Team
+Architecture: arm64
+Multi-Arch: same
+Source: gmp
+Version: 2:6.2.1+dfsg1-1.1
+Depends: libc6 (>= 2.17)
+Breaks: libmath-gmp-perl (<< 2.20-1), libmath-prime-util-gmp-perl (<< 0.51-2), postgresql-pgmp (<< 1.0.3-1)
+
+Package: libselinux1
+Status: install ok installed
+Priority: optional
+Section: libs
+Installed-Size: 223
+Maintainer: Debian SELinux maintainers
+Architecture: arm64
+Multi-Arch: same
+Source: libselinux (3.4-1)
+Version: 3.4-1+b6
+Depends: libc6 (>= 2.34), libpcre2-8-0 (>= 10.22)
+
+Package: libpcre2-8-0
+Status: install ok installed
+Priority: optional
+Section: libs
+Installed-Size: 649
+Maintainer: Matthew Vernon
+Architecture: arm64
+Multi-Arch: same
+Source: pcre2
+Version: 10.42-1
+Depends: libc6 (>= 2.34)
diff --git a/syft/pkg/cataloger/deb/test-fixtures/status/doc-examples b/syft/pkg/cataloger/deb/test-fixtures/status/doc-examples
new file mode 100644
index 000000000..6b9fe186f
--- /dev/null
+++ b/syft/pkg/cataloger/deb/test-fixtures/status/doc-examples
@@ -0,0 +1,46 @@
+Package: mutt
+Version: 1.3.17-1
+Depends: libc6 (>= 2.2.1), default-mta | mail-transport-agent | not-installed
+
+Package: made-up-package-1
+Version: 1.0.0
+Source: glibc
+Depends: kernel-headers-2.2.10 [!hurd-i386],
+ hurd-dev [hurd-i386], gnumach-dev [hurd-i386]
+
+Package: made-up-package-2
+Version: 2.0.0
+Depends:
+ libluajit5.1-dev [i386 amd64 kfreebsd-i386 armel armhf powerpc mips],
+ liblua5.1-dev [hurd-i386 ia64 kfreebsd-amd64 s390x sparc],
+
+Package: made-up-package-3
+Version: 3.0.0
+Depends: foo [i386], bar [amd64]
+
+Package: made-up-package-4
+Version: 3.0.0
+Depends: virtual-package-5
+
+Package: made-up-package-5
+Provides: virtual-package-5 (=1.0)
+
+Package: foo
+
+Package: bar
+
+Package: kernel-headers-2.2.10
+
+Package: hurd-dev
+
+Package: gnumach-dev
+
+Package: default-mta
+
+Package: mail-transport-agent
+
+Package: libc6
+
+Package: libluajit5.1-dev
+
+Package: liblua5.1-dev
diff --git a/syft/pkg/cataloger/deb/test-fixtures/status/libpam-runtime b/syft/pkg/cataloger/deb/test-fixtures/status/libpam-runtime
new file mode 100644
index 000000000..73aaf6978
--- /dev/null
+++ b/syft/pkg/cataloger/deb/test-fixtures/status/libpam-runtime
@@ -0,0 +1,23 @@
+Package: libpam-runtime
+Status: install ok installed
+Priority: required
+Section: admin
+Installed-Size: 876
+Maintainer: Sam Hartman
+Architecture: all
+Multi-Arch: foreign
+Source: pam
+Version: 1.5.2-6+deb12u1
+Replaces: libpam0g-dev, libpam0g-util
+Depends: debconf1 (>= 0.5) | debconf-2.0, debconf2 (>= 1.5.19) | cdebconf, libpam-modules (>= 1.0.1-6)
+Conflicts: libpam0g-util
+
+Package: debconf1
+
+Package: debconf2
+
+Package: debconf-2.0
+
+Package: cdebconf
+
+Package: libpam-modules
diff --git a/syft/pkg/dpkg_metadata.go b/syft/pkg/dpkg_metadata.go
index 2ad5de2db..5b38be03b 100644
--- a/syft/pkg/dpkg_metadata.go
+++ b/syft/pkg/dpkg_metadata.go
@@ -14,16 +14,49 @@ var _ FileOwner = (*DpkgMetadata)(nil)
// DpkgMetadata represents all captured data for a Debian package DB entry; available fields are described
// at http://manpages.ubuntu.com/manpages/xenial/man1/dpkg-query.1.html in the --showformat section.
+// Additional information about how these fields are used can be found at
+// - https://www.debian.org/doc/debian-policy/ch-controlfields.html
+// - https://www.debian.org/doc/debian-policy/ch-relationships.html
+// - https://www.debian.org/doc/debian-policy/ch-binary.html#s-virtual-pkg
+// - https://www.debian.org/doc/debian-policy/ch-relationships.html#s-virtual
+
type DpkgMetadata struct {
- Package string `mapstructure:"Package" json:"package"`
- Source string `mapstructure:"Source" json:"source" cyclonedx:"source"`
- Version string `mapstructure:"Version" json:"version"`
- SourceVersion string `mapstructure:"SourceVersion" json:"sourceVersion" cyclonedx:"sourceVersion"`
- Architecture string `mapstructure:"Architecture" json:"architecture"`
- Maintainer string `mapstructure:"Maintainer" json:"maintainer"`
- InstalledSize int `mapstructure:"InstalledSize" json:"installedSize" cyclonedx:"installedSize"`
- Description string `mapstructure:"Description" hash:"ignore" json:"-"`
- Files []DpkgFileRecord `json:"files"`
+ Package string `json:"package"`
+ Source string `json:"source" cyclonedx:"source"`
+ Version string `json:"version"`
+ SourceVersion string `json:"sourceVersion" cyclonedx:"sourceVersion"`
+
+ // Architecture can include the following sets of values depending on context and the control file used:
+ // - a unique single word identifying a Debian machine architecture as described in Architecture specification string (https://www.debian.org/doc/debian-policy/ch-customized-programs.html#s-arch-spec) .
+ // - an architecture wildcard identifying a set of Debian machine architectures, see Architecture wildcards (https://www.debian.org/doc/debian-policy/ch-customized-programs.html#s-arch-wildcard-spec). any matches all Debian machine architectures and is the most frequently used.
+ // - "all", which indicates an architecture-independent package.
+ // - "source", which indicates a source package.
+ Architecture string `json:"architecture"`
+
+ // Maintainer is the package maintainer’s name and email address. The name must come first, then the email
+ // address inside angle brackets <> (in RFC822 format).
+ Maintainer string `json:"maintainer"`
+
+ InstalledSize int `json:"installedSize" cyclonedx:"installedSize"`
+
+ // Description contains a description of the binary package, consisting of two parts, the synopsis or the short
+ // description, and the long description (in a multiline format).
+ Description string `hash:"ignore" json:"-"`
+
+ // Provides is a virtual package that is provided by one or more packages. A virtual package is one which appears
+ // in the Provides control field of another package. The effect is as if the package(s) which provide a particular
+ // virtual package name had been listed by name everywhere the virtual package name appears. (See also Virtual packages)
+ Provides []string `json:"provides,omitempty"`
+
+ // Depends This declares an absolute dependency. A package will not be configured unless all of the packages listed in
+ // its Depends field have been correctly configured (unless there is a circular dependency).
+ Depends []string `json:"depends,omitempty"`
+
+ // PreDepends is like Depends, except that it also forces dpkg to complete installation of the packages named
+ // before even starting the installation of the package which declares the pre-dependency.
+ PreDepends []string `json:"preDepends,omitempty"`
+
+ Files []DpkgFileRecord `json:"files"`
}
// DpkgFileRecord represents a single file attributed to a debian package.