diff --git a/syft/pkg/cataloger/binary/classifier_cataloger_test.go b/syft/pkg/cataloger/binary/classifier_cataloger_test.go index 0839a2dca..3be5c2d0d 100644 --- a/syft/pkg/cataloger/binary/classifier_cataloger_test.go +++ b/syft/pkg/cataloger/binary/classifier_cataloger_test.go @@ -1392,6 +1392,17 @@ func Test_Cataloger_PositiveCases(t *testing.T) { Metadata: metadata("ffmpeg-binary"), }, }, + { + logicalFixture: "ffmpeg-shared-libs/5.1.4/linux-amd64", + expected: pkg.Package{ + Name: "ffmpeg", + Version: "5.1.4", + Type: "binary", + PURL: "pkg:generic/ffmpeg@5.1.4", + Locations: locations("libavcodec"), + Metadata: metadata("ffmpeg-library"), + }, + }, } for _, test := range tests { diff --git a/syft/pkg/cataloger/binary/classifiers.go b/syft/pkg/cataloger/binary/classifiers.go index 154175ddc..a58091c6b 100644 --- a/syft/pkg/cataloger/binary/classifiers.go +++ b/syft/pkg/cataloger/binary/classifiers.go @@ -639,6 +639,30 @@ func DefaultClassifiers() []binutils.Classifier { PURL: mustPURL("pkg:generic/ffmpeg@version"), CPEs: singleCPE("cpe:2.3:a:ffmpeg:ffmpeg:*:*:*:*:*:*:*:*", cpe.NVDDictionaryLookupSource), }, + { + Class: "ffmpeg-library", + FileGlob: "**/libav*", + EvidenceMatcher: binutils.MatchAny( + // Primary pattern: FFmpeg version found in most libraries + m.FileContentsVersionMatcher(`(?m)FFmpeg version (?P[0-9]+\.[0-9]+(\.[0-9]+)?)`), + // Fallback: library-specific version patterns for libavcodec and libavformat + m.FileContentsVersionMatcher(`(?m)Lavc(?P[0-9]+\.[0-9]+\.[0-9]+)`), + m.FileContentsVersionMatcher(`(?m)Lavf(?P[0-9]+\.[0-9]+\.[0-9]+)`), + ), + Package: "ffmpeg", + PURL: mustPURL("pkg:generic/ffmpeg@version"), + CPEs: singleCPE("cpe:2.3:a:ffmpeg:ffmpeg:*:*:*:*:*:*:*:*", cpe.NVDDictionaryLookupSource), + }, + { + Class: "ffmpeg-library", + FileGlob: "**/libswresample*", + EvidenceMatcher: m.FileContentsVersionMatcher( + // FFmpeg version pattern for libswresample + `(?m)FFmpeg version (?P[0-9]+\.[0-9]+(\.[0-9]+)?)`), + Package: "ffmpeg", + PURL: mustPURL("pkg:generic/ffmpeg@version"), + CPEs: singleCPE("cpe:2.3:a:ffmpeg:ffmpeg:*:*:*:*:*:*:*:*", cpe.NVDDictionaryLookupSource), + }, } return append(classifiers, defaultJavaClassifiers()...) diff --git a/syft/pkg/cataloger/binary/test-fixtures/classifiers/snippets/ffmpeg-shared-libs/5.1.4/linux-amd64/libavcodec b/syft/pkg/cataloger/binary/test-fixtures/classifiers/snippets/ffmpeg-shared-libs/5.1.4/linux-amd64/libavcodec new file mode 100644 index 000000000..f325e222a Binary files /dev/null and b/syft/pkg/cataloger/binary/test-fixtures/classifiers/snippets/ffmpeg-shared-libs/5.1.4/linux-amd64/libavcodec differ diff --git a/syft/pkg/cataloger/binary/test-fixtures/config.yaml b/syft/pkg/cataloger/binary/test-fixtures/config.yaml index 3f3c15513..aee3ec6b6 100644 --- a/syft/pkg/cataloger/binary/test-fixtures/config.yaml +++ b/syft/pkg/cataloger/binary/test-fixtures/config.yaml @@ -830,3 +830,15 @@ from-images: platform: linux/arm64 paths: - /usr/local/bin/ffmpeg + + - name: ffmpeg-shared-libs + version: 5.1.4 + images: + - ref: demisto/opencv:1.0.0.111908@sha256:abba3aab213990c666900a93db03420238527b757bf5825543cf7b4c5e11ac65 + platform: linux/amd64 + paths: + - /usr/local/lib/python3.11/site-packages/opencv_contrib_python.libs/libavcodec-9aae324f.so.59.37.100 + - /usr/local/lib/python3.11/site-packages/opencv_contrib_python.libs/libavformat-3ff1be5b.so.59.27.100 + - /usr/local/lib/python3.11/site-packages/opencv_contrib_python.libs/libavutil-a0a0531e.so.57.28.100 + - /usr/local/lib/python3.11/site-packages/opencv_contrib_python.libs/libswresample-2ec4394e.so.4.7.100 +