Script 'mail_helper' called by obssrc
Hello community,

here is the log from the commit of package syft for openSUSE:Factory checked in 
at 2026-02-19 14:23:45
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Comparing /work/SRC/openSUSE:Factory/syft (Old)
 and      /work/SRC/openSUSE:Factory/.syft.new.1977 (New)
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Package is "syft"

Thu Feb 19 14:23:45 2026 rev:119 rq:1333874 version:1.42.1

Changes:
--------
--- /work/SRC/openSUSE:Factory/syft/syft.changes        2026-02-11 
18:49:39.707429070 +0100
+++ /work/SRC/openSUSE:Factory/.syft.new.1977/syft.changes      2026-02-19 
14:23:52.291946596 +0100
@@ -1,0 +2,21 @@
+Thu Feb 19 06:12:52 UTC 2026 - Johannes Kastl 
<[email protected]>
+
+- Update to version 1.42.1:
+  * Bug Fixes
+    - Use redhat as namespace for hummingbird rpms [#4615 @scoheb]
+    - False Positive: Emacs snap package version CVE-2024-39331
+      [#4485]
+  * Additional Changes
+    - call cleanup on tmpfile and replace some io.ReadAlls with
+      streams [#4629 @willmurphyscode]
+    - bumps go mod version to 1.25; ci takes latest patch [#4628
+      @spiffcs]
+  * Dependencies
+    - chore(deps): update tools to latest versions (#4614)
+    - chore(deps): bump the actions-minor-patch group across 1
+      directory with 2 updates (#4622)
+    - chore(deps): bump the go-minor-patch group with 2 updates
+      (#4621)
+    - chore(deps): update CPE dictionary index (#4623)
+
+-------------------------------------------------------------------

Old:
----
  syft-1.42.0.obscpio

New:
----
  syft-1.42.1.obscpio

++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Other differences:
------------------
++++++ syft.spec ++++++
--- /var/tmp/diff_new_pack.4X4nFr/_old  2026-02-19 14:23:54.768049326 +0100
+++ /var/tmp/diff_new_pack.4X4nFr/_new  2026-02-19 14:23:54.768049326 +0100
@@ -17,7 +17,7 @@
 
 
 Name:           syft
-Version:        1.42.0
+Version:        1.42.1
 Release:        0
 Summary:        CLI tool and library for generating a Software Bill of 
Materials
 License:        Apache-2.0
@@ -26,8 +26,8 @@
 Source1:        vendor.tar.gz
 BuildRequires:  bash-completion
 BuildRequires:  fish
-BuildRequires:  go >= 1.24
 BuildRequires:  zsh
+BuildRequires:  golang(API) >= 1.25
 
 %description
 A CLI tool and Go library for generating a Software Bill of Materials (SBOM)

++++++ _service ++++++
--- /var/tmp/diff_new_pack.4X4nFr/_old  2026-02-19 14:23:54.804050820 +0100
+++ /var/tmp/diff_new_pack.4X4nFr/_new  2026-02-19 14:23:54.808050986 +0100
@@ -3,7 +3,7 @@
     <param name="url">https://github.com/anchore/syft</param>
     <param name="scm">git</param>
     <param name="exclude">.git</param>
-    <param name="revision">v1.42.0</param>
+    <param name="revision">v1.42.1</param>
     <param name="versionformat">@PARENT_TAG@</param>
     <param name="versionrewrite-pattern">v(.*)</param>
     <param name="changesgenerate">enable</param>

++++++ _servicedata ++++++
--- /var/tmp/diff_new_pack.4X4nFr/_old  2026-02-19 14:23:54.828051816 +0100
+++ /var/tmp/diff_new_pack.4X4nFr/_new  2026-02-19 14:23:54.832051982 +0100
@@ -1,6 +1,6 @@
 <servicedata>
 <service name="tar_scm">
                 <param name="url">https://github.com/anchore/syft</param>
-              <param 
name="changesrevision">9872ff36ba5881f977b6e1b46c7bb33a1147f09e</param></service></servicedata>
+              <param 
name="changesrevision">0a3f7bb06ee168495ee54b8b66fccb22a056fe99</param></service></servicedata>
 (No newline at EOF)
 

++++++ syft-1.42.0.obscpio -> syft-1.42.1.obscpio ++++++
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/syft-1.42.0/.binny.yaml new/syft-1.42.1/.binny.yaml
--- old/syft-1.42.0/.binny.yaml 2026-02-10 18:19:56.000000000 +0100
+++ new/syft-1.42.1/.binny.yaml 2026-02-17 23:32:35.000000000 +0100
@@ -2,7 +2,7 @@
   # we want to use a pinned version of binny to manage the toolchain (so binny 
manages itself!)
   - name: binny
     version:
-      want: v0.11.2
+      want: v0.11.3
     method: github-release
     with:
       repo: anchore/binny
@@ -26,7 +26,7 @@
   # used for linting
   - name: golangci-lint
     version:
-      want: v2.8.0
+      want: v2.9.0
     method: github-release
     with:
       repo: golangci/golangci-lint
@@ -114,7 +114,7 @@
   # used to upload test fixture cache
   - name: yq
     version:
-      want: v4.52.2
+      want: v4.52.4
     method: github-release
     with:
       repo: mikefarah/yq
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/syft-1.42.0/.golangci.yaml 
new/syft-1.42.1/.golangci.yaml
--- old/syft-1.42.0/.golangci.yaml      2026-02-10 18:19:56.000000000 +0100
+++ new/syft-1.42.1/.golangci.yaml      2026-02-17 23:32:35.000000000 +0100
@@ -50,10 +50,9 @@
       - legacy
       - std-error-handling
     rules:
-      # internal/os contains OS feature detection logic; the name reflects its 
purpose
+      # we have multiple packages in syft that might overlap with the stblib; 
their names reflect their purpose
       - linters:
           - revive
-        path: internal/os/
         text: "var-naming: avoid package names that conflict"
     paths:
       - third_party$
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/syft-1.42.0/go.mod new/syft-1.42.1/go.mod
--- old/syft-1.42.0/go.mod      2026-02-10 18:19:56.000000000 +0100
+++ new/syft-1.42.1/go.mod      2026-02-17 23:32:35.000000000 +0100
@@ -1,10 +1,10 @@
 module github.com/anchore/syft
 
-go 1.24.6
+go 1.25
 
 require (
        github.com/BurntSushi/toml v1.6.0
-       github.com/CycloneDX/cyclonedx-go v0.9.3
+       github.com/CycloneDX/cyclonedx-go v0.10.0
        github.com/Masterminds/semver/v3 v3.4.0
        github.com/Masterminds/sprig/v3 v3.3.0
        github.com/OneOfOne/xxhash v1.2.8
@@ -29,7 +29,7 @@
        github.com/bitnami/go-version v0.0.0-20250131085805-b1f57a8634ef
        github.com/blakesmith/ar v0.0.0-20190502131153-809d4375e1fb
        github.com/bmatcuk/doublestar/v4 v4.10.0
-       github.com/charmbracelet/bubbles v0.21.0
+       github.com/charmbracelet/bubbles v0.21.1
        github.com/charmbracelet/bubbletea v1.3.10
        github.com/charmbracelet/lipgloss v1.1.0
        github.com/dave/jennifer v1.7.1
@@ -121,11 +121,11 @@
        github.com/bodgit/plumbing v1.3.0 // indirect
        github.com/bodgit/sevenzip v1.6.1 // indirect
        github.com/bodgit/windows v1.0.1 // indirect
-       github.com/charmbracelet/colorprofile 
v0.2.3-0.20250311203215-f60798e515dc // indirect
+       github.com/charmbracelet/colorprofile v0.4.1 // indirect
        github.com/charmbracelet/harmonica v0.2.0 // indirect
-       github.com/charmbracelet/x/ansi v0.10.1 // indirect
-       github.com/charmbracelet/x/cellbuf 
v0.0.13-0.20250311204145-2c3ea96c31dd // indirect
-       github.com/charmbracelet/x/term v0.2.1 // indirect
+       github.com/charmbracelet/x/ansi v0.11.5 // indirect
+       github.com/charmbracelet/x/cellbuf v0.0.15 // indirect
+       github.com/charmbracelet/x/term v0.2.2 // indirect
        github.com/cloudflare/circl v1.6.1 // indirect
        github.com/containerd/containerd/api v1.10.0 // indirect
        github.com/containerd/continuity v0.4.5 // indirect
@@ -177,7 +177,7 @@
        github.com/kr/pretty v0.3.1 // indirect
        github.com/kr/text v0.2.0 // indirect
        github.com/logrusorgru/aurora v2.0.3+incompatible // indirect
-       github.com/lucasb-eyer/go-colorful v1.2.0 // indirect
+       github.com/lucasb-eyer/go-colorful v1.3.0 // indirect
        github.com/maruel/natural v1.1.1 // indirect
        github.com/mattn/go-colorable v0.1.14 // indirect
        github.com/mattn/go-isatty v0.0.20 // indirect
@@ -307,9 +307,9 @@
        github.com/aws/smithy-go v1.24.0 // indirect
        github.com/bahlo/generic-list-go v0.2.0 // indirect
        github.com/buger/jsonparser v1.1.1 // indirect
-       github.com/clipperhouse/displaywidth v0.6.2 // indirect
+       github.com/clipperhouse/displaywidth v0.9.0 // indirect
        github.com/clipperhouse/stringish v0.1.1 // indirect
-       github.com/clipperhouse/uax29/v2 v2.3.0 // indirect
+       github.com/clipperhouse/uax29/v2 v2.5.0 // indirect
        github.com/cncf/xds/go v0.0.0-20250501225837-2ac532fd4443 // indirect
        github.com/containerd/cgroups/v3 v3.1.2 // indirect
        github.com/containerd/containerd/v2 v2.2.1 // indirect
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/syft-1.42.0/go.sum new/syft-1.42.1/go.sum
--- old/syft-1.42.0/go.sum      2026-02-10 18:19:56.000000000 +0100
+++ new/syft-1.42.1/go.sum      2026-02-17 23:32:35.000000000 +0100
@@ -81,8 +81,8 @@
 github.com/BurntSushi/toml v1.6.0 
h1:dRaEfpa2VI55EwlIW72hMRHdWouJeRF7TPYhI+AUQjk=
 github.com/BurntSushi/toml v1.6.0/go.mod 
h1:ukJfTF/6rtPPRCnwkur4qwRxa8vTRFBF0uk2lLoLwho=
 github.com/BurntSushi/xgb v0.0.0-20160522181843-27f122750802/go.mod 
h1:IVnqGOEym/WlBOVXweHU+Q+/VP0lqqI8lqeDx9IjBqo=
-github.com/CycloneDX/cyclonedx-go v0.9.3 
h1:Pyk/lwavPz7AaZNvugKFkdWOm93MzaIyWmBwmBo3aUI=
-github.com/CycloneDX/cyclonedx-go v0.9.3/go.mod 
h1:vcK6pKgO1WanCdd61qx4bFnSsDJQ6SbM2ZuMIgq86Jg=
+github.com/CycloneDX/cyclonedx-go v0.10.0 
h1:7xyklU7YD+CUyGzSFIARG18NYLsKVn4QFg04qSsu+7Y=
+github.com/CycloneDX/cyclonedx-go v0.10.0/go.mod 
h1:vUvbCXQsEm48OI6oOlanxstwNByXjCZ2wuleUlwGEO8=
 github.com/DataDog/datadog-go v3.2.0+incompatible/go.mod 
h1:LButxg5PwREeZtORoXG3tL4fMGNddJ+vMq1mwgfaqoQ=
 github.com/DataDog/zstd v1.5.5 h1:oWf5W7GtOLgp6bciQYDmhHHjdhYkALu6S/5Ni9ZgSvQ=
 github.com/DataDog/zstd v1.5.5/go.mod 
h1:g4AWEaM3yOg3HYfnJ3YIawPnVdXJh9QME85blwSAmyw=
@@ -215,8 +215,8 @@
 github.com/aws/smithy-go v1.24.0/go.mod 
h1:LEj2LM3rBRQJxPZTB4KuzZkaZYnZPnvgIhb4pu07mx0=
 github.com/aymanbagabas/go-osc52/v2 v2.0.1 
h1:HwpRHbFMcZLEVr42D4p7XBqjyuxQH5SMiErDT4WkJ2k=
 github.com/aymanbagabas/go-osc52/v2 v2.0.1/go.mod 
h1:uYgXzlJ7ZpABp8OJ+exZzJJhRNQ2ASbcXHWsFqH8hp8=
-github.com/aymanbagabas/go-udiff v0.2.0 
h1:TK0fH4MteXUDspT88n8CKzvK0X9O2xu9yQjWpi6yML8=
-github.com/aymanbagabas/go-udiff v0.2.0/go.mod 
h1:RE4Ex0qsGkTAJoQdQQCA0uG+nAzJO/pI/QwceO5fgrA=
+github.com/aymanbagabas/go-udiff v0.3.1 
h1:LV+qyBQ2pqe0u42ZsUEtPiCaUoqgA9gYRDs3vj1nolY=
+github.com/aymanbagabas/go-udiff v0.3.1/go.mod 
h1:G0fsKmG+P6ylD0r6N/KgQD/nWzgfnl8ZBcNLgcbrw8E=
 github.com/bahlo/generic-list-go v0.2.0 
h1:5sz/EEAK+ls5wF+NeqDpk5+iNdMDXrh3z3nPnH1Wvgk=
 github.com/bahlo/generic-list-go v0.2.0/go.mod 
h1:2KvAjgMlE5NNynlg/5iLrrCCZ2+5xWbdbCW3pNTGyYg=
 github.com/becheran/wildmatch-go v1.0.0 
h1:mE3dGGkTmpKtT4Z+88t8RStG40yN9T+kFEGj2PZFSzA=
@@ -252,24 +252,24 @@
 github.com/cespare/xxhash/v2 v2.1.2/go.mod 
h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs=
 github.com/cespare/xxhash/v2 v2.3.0 
h1:UL815xU9SqsFlibzuggzjXhog7bL6oX9BbNZnL2UFvs=
 github.com/cespare/xxhash/v2 v2.3.0/go.mod 
h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs=
-github.com/charmbracelet/bubbles v0.21.0 
h1:9TdC97SdRVg/1aaXNVWfFH3nnLAwOXr8Fn6u6mfQdFs=
-github.com/charmbracelet/bubbles v0.21.0/go.mod 
h1:HF+v6QUR4HkEpz62dx7ym2xc71/KBHg+zKwJtMw+qtg=
+github.com/charmbracelet/bubbles v0.21.1 
h1:nj0decPiixaZeL9diI4uzzQTkkz1kYY8+jgzCZXSmW0=
+github.com/charmbracelet/bubbles v0.21.1/go.mod 
h1:HHvIYRCpbkCJw2yo0vNX1O5loCwSr9/mWS8GYSg50Sk=
 github.com/charmbracelet/bubbletea v1.3.10 
h1:otUDHWMMzQSB0Pkc87rm691KZ3SWa4KUlvF9nRvCICw=
 github.com/charmbracelet/bubbletea v1.3.10/go.mod 
h1:ORQfo0fk8U+po9VaNvnV95UPWA1BitP1E0N6xJPlHr4=
-github.com/charmbracelet/colorprofile v0.2.3-0.20250311203215-f60798e515dc 
h1:4pZI35227imm7yK2bGPcfpFEmuY1gc2YSTShr4iJBfs=
-github.com/charmbracelet/colorprofile 
v0.2.3-0.20250311203215-f60798e515dc/go.mod 
h1:X4/0JoqgTIPSFcRA/P6INZzIuyqdFY5rm8tb41s9okk=
+github.com/charmbracelet/colorprofile v0.4.1 
h1:a1lO03qTrSIRaK8c3JRxJDZOvhvIeSco3ej+ngLk1kk=
+github.com/charmbracelet/colorprofile v0.4.1/go.mod 
h1:U1d9Dljmdf9DLegaJ0nGZNJvoXAhayhmidOdcBwAvKk=
 github.com/charmbracelet/harmonica v0.2.0 
h1:8NxJWRWg/bzKqqEaaeFNipOu77YR5t8aSwG4pgaUBiQ=
 github.com/charmbracelet/harmonica v0.2.0/go.mod 
h1:KSri/1RMQOZLbw7AHqgcBycp8pgJnQMYYT8QZRqZ1Ao=
 github.com/charmbracelet/lipgloss v1.1.0 
h1:vYXsiLHVkK7fp74RkV7b2kq9+zDLoEU4MZoFqR/noCY=
 github.com/charmbracelet/lipgloss v1.1.0/go.mod 
h1:/6Q8FR2o+kj8rz4Dq0zQc3vYf7X+B0binUUBwA0aL30=
-github.com/charmbracelet/x/ansi v0.10.1 
h1:rL3Koar5XvX0pHGfovN03f5cxLbCF2YvLeyz7D2jVDQ=
-github.com/charmbracelet/x/ansi v0.10.1/go.mod 
h1:3RQDQ6lDnROptfpWuUVIUG64bD2g2BgntdxH0Ya5TeE=
-github.com/charmbracelet/x/cellbuf v0.0.13-0.20250311204145-2c3ea96c31dd 
h1:vy0GVL4jeHEwG5YOXDmi86oYw2yuYUGqz6a8sLwg0X8=
-github.com/charmbracelet/x/cellbuf 
v0.0.13-0.20250311204145-2c3ea96c31dd/go.mod 
h1:xe0nKWGd3eJgtqZRaN9RjMtK7xUYchjzPr7q6kcvCCs=
+github.com/charmbracelet/x/ansi v0.11.5 
h1:NBWeBpj/lJPE3Q5l+Lusa4+mH6v7487OP8K0r1IhRg4=
+github.com/charmbracelet/x/ansi v0.11.5/go.mod 
h1:2JNYLgQUsyqaiLovhU2Rv/pb8r6ydXKS3NIttu3VGZQ=
+github.com/charmbracelet/x/cellbuf v0.0.15 
h1:ur3pZy0o6z/R7EylET877CBxaiE1Sp1GMxoFPAIztPI=
+github.com/charmbracelet/x/cellbuf v0.0.15/go.mod 
h1:J1YVbR7MUuEGIFPCaaZ96KDl5NoS0DAWkskup+mOY+Q=
 github.com/charmbracelet/x/exp/golden v0.0.0-20241011142426-46044092ad91 
h1:payRxjMjKgx2PaCWLZ4p3ro9y97+TVLZNaRZgJwSVDQ=
 github.com/charmbracelet/x/exp/golden 
v0.0.0-20241011142426-46044092ad91/go.mod 
h1:wDlXFlCrmJ8J+swcL/MnGUuYnqgQdW9rhSD61oNMb6U=
-github.com/charmbracelet/x/term v0.2.1 
h1:AQeHeLZ1OqSXhrAWpYUtZyX1T3zVxfpZuEQMIQaGIAQ=
-github.com/charmbracelet/x/term v0.2.1/go.mod 
h1:oQ4enTYFV7QN4m0i9mzHrViD7TQKvNEEkHUMCmsxdUg=
+github.com/charmbracelet/x/term v0.2.2 
h1:xVRT/S2ZcKdhhOuSP4t5cLi5o+JxklsoEObBSgfgZRk=
+github.com/charmbracelet/x/term v0.2.2/go.mod 
h1:kF8CY5RddLWrsgVwpw4kAa6TESp6EB5y3uxGLeCqzAI=
 github.com/chromedp/cdproto v0.0.0-20230802225258-3cf4e6d46a89/go.mod 
h1:GKljq0VrfU4D5yc+2qA6OVr8pmO/MBbPEWqWQ/oqGEs=
 github.com/chromedp/chromedp v0.9.2/go.mod 
h1:LkSXJKONWTCHAfQasKFUZI+mxqS4tZqhmtGzzhLsnLs=
 github.com/chromedp/sysutil v1.0.0/go.mod 
h1:kgWmDdq8fTzXYcKIBqIYvRRTnYb9aNS9moAV0xufSww=
@@ -282,12 +282,12 @@
 github.com/circonus-labs/circonus-gometrics v2.3.1+incompatible/go.mod 
h1:nmEj6Dob7S7YxXgwXpfOuvO54S+tGdZdw9fuRZt25Ag=
 github.com/circonus-labs/circonusllhist v0.1.3/go.mod 
h1:kMXHVDlOchFAehlya5ePtbp5jckzBHf4XRpQvBOLI+I=
 github.com/client9/misspell v0.3.4/go.mod 
h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw=
-github.com/clipperhouse/displaywidth v0.6.2 
h1:ZDpTkFfpHOKte4RG5O/BOyf3ysnvFswpyYrV7z2uAKo=
-github.com/clipperhouse/displaywidth v0.6.2/go.mod 
h1:R+kHuzaYWFkTm7xoMmK1lFydbci4X2CicfbGstSGg0o=
+github.com/clipperhouse/displaywidth v0.9.0 
h1:Qb4KOhYwRiN3viMv1v/3cTBlz3AcAZX3+y9OLhMtAtA=
+github.com/clipperhouse/displaywidth v0.9.0/go.mod 
h1:aCAAqTlh4GIVkhQnJpbL0T/WfcrJXHcj8C0yjYcjOZA=
 github.com/clipperhouse/stringish v0.1.1 
h1:+NSqMOr3GR6k1FdRhhnXrLfztGzuG+VuFDfatpWHKCs=
 github.com/clipperhouse/stringish v0.1.1/go.mod 
h1:v/WhFtE1q0ovMta2+m+UbpZ+2/HEXNWYXQgCt4hdOzA=
-github.com/clipperhouse/uax29/v2 v2.3.0 
h1:SNdx9DVUqMoBuBoW3iLOj4FQv3dN5mDtuqwuhIGpJy4=
-github.com/clipperhouse/uax29/v2 v2.3.0/go.mod 
h1:Wn1g7MK6OoeDT0vL+Q0SQLDz/KpfsVRgg6W7ihQeh4g=
+github.com/clipperhouse/uax29/v2 v2.5.0 
h1:x7T0T4eTHDONxFJsL94uKNKPHrclyFI0lm7+w94cO8U=
+github.com/clipperhouse/uax29/v2 v2.5.0/go.mod 
h1:Wn1g7MK6OoeDT0vL+Q0SQLDz/KpfsVRgg6W7ihQeh4g=
 github.com/cloudflare/circl v1.6.1 
h1:zqIqSPIndyBh1bjLVVDHMPpVKqp8Su/V+6MeDzzQBQ0=
 github.com/cloudflare/circl v1.6.1/go.mod 
h1:uddAzsPgqdMAYatqJ0lsjX1oECcQLIlRpzZh3pJrofs=
 github.com/cncf/udpa/go v0.0.0-20191209042840-269d4d468f6f/go.mod 
h1:M8M6+tZqaGXZJjfX53e64911xZQV5JYwmTeXPW+k8Sc=
@@ -683,8 +683,8 @@
 github.com/logrusorgru/aurora v0.0.0-20200102142835-e9ef32dff381/go.mod 
h1:7rIyQOR62GCctdiQpZ/zOJlFyk6y+94wXzv6RNZgaR4=
 github.com/logrusorgru/aurora v2.0.3+incompatible 
h1:tOpm7WcpBTn4fjmVfgpQq0EfczGlG91VSDkswnjF5A8=
 github.com/logrusorgru/aurora v2.0.3+incompatible/go.mod 
h1:7rIyQOR62GCctdiQpZ/zOJlFyk6y+94wXzv6RNZgaR4=
-github.com/lucasb-eyer/go-colorful v1.2.0 
h1:1nnpGOrhyZZuNyfu1QjKiUICQ74+3FNCN69Aj6K7nkY=
-github.com/lucasb-eyer/go-colorful v1.2.0/go.mod 
h1:R4dSotOR9KMtayYi1e77YzuveK+i7ruzyGqttikkLy0=
+github.com/lucasb-eyer/go-colorful v1.3.0 
h1:2/yBRLdWBZKrf7gB40FoiKfAWYQ0lqNcbuQwVHXptag=
+github.com/lucasb-eyer/go-colorful v1.3.0/go.mod 
h1:R4dSotOR9KMtayYi1e77YzuveK+i7ruzyGqttikkLy0=
 github.com/lyft/protoc-gen-star v0.5.3/go.mod 
h1:V0xaHgaf5oCCqmcxYcWiDfTiKsZsRc87/1qhoTACD8w=
 github.com/magiconair/properties v1.8.5/go.mod 
h1:y3VJvCyxH9uVvJTWEGAELF3aiYNyPKd5NZ3oSwXrF60=
 github.com/magiconair/properties v1.8.10 
h1:s31yESBquKXCV9a/ScB3ESkOjUYYv+X0rg8SYxI99mE=
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/syft-1.42.0/syft/pkg/cataloger/debian/parse_copyright.go 
new/syft-1.42.1/syft/pkg/cataloger/debian/parse_copyright.go
--- old/syft-1.42.0/syft/pkg/cataloger/debian/parse_copyright.go        
2026-02-10 18:19:56.000000000 +0100
+++ new/syft-1.42.1/syft/pkg/cataloger/debian/parse_copyright.go        
2026-02-17 23:32:35.000000000 +0100
@@ -1,6 +1,7 @@
 package debian
 
 import (
+       "bufio"
        "io"
        "regexp"
        "sort"
@@ -14,23 +15,32 @@
 // For more information see: 
https://www.debian.org/doc/packaging-manuals/copyright-format/1.0/#license-syntax
 
 var (
-       licensePattern                          = regexp.MustCompile(`^License: 
(?P<license>\S*)`)
-       commonLicensePathPattern                = 
regexp.MustCompile(`/usr/share/common-licenses/(?P<license>[0-9A-Za-z_.\-]+)`)
-       licenseFirstSentenceAfterHeadingPattern = 
regexp.MustCompile(`(?is)^[^\n]+?\n[-]+?\n+(?P<license>.*?\.)`)
-       licenseAgreementHeadingPattern          = 
regexp.MustCompile(`(?i)^\s*(?P<license>LICENSE AGREEMENT(?: FOR .+?)?)\s*$`)
+       licensePattern                 = regexp.MustCompile(`^License: 
(?P<license>\S*)`)
+       commonLicensePathPattern       = 
regexp.MustCompile(`/usr/share/common-licenses/(?P<license>[0-9A-Za-z_.\-]+)`)
+       licenseAgreementHeadingPattern = 
regexp.MustCompile(`(?i)^\s*(?P<license>LICENSE AGREEMENT(?: FOR .+?)?)\s*$`)
 )
 
 func parseLicensesFromCopyright(reader io.Reader) []string {
        findings := strset.New()
-       data, err := io.ReadAll(reader)
-       if err != nil {
-               // Fail-safe: return nothing if unable to read
-               return []string{}
-       }
+       scanner := bufio.NewScanner(reader)
+
+       // State machine replacing licenseFirstSentenceAfterHeadingPattern.
+       // That regex only matched at the start of the file: a non-empty 
heading,
+       // a line of dashes, blank lines, then text up to the first period.
+       const (
+               expectHeading = iota
+               expectDashes
+               skipBlanks
+               captureLicense
+               headingDone // matched or impossible — stop checking
+       )
+       headingState := expectHeading
+       var licenseText strings.Builder
 
-       content := string(data)
-       lines := strings.Split(content, "\n")
-       for _, line := range lines {
+       for scanner.Scan() {
+               line := scanner.Text()
+
+               // per-line regex checks (applied to every line)
                if value := findLicenseClause(licensePattern, line); value != 
"" {
                        findings.Add(value)
                }
@@ -40,13 +50,39 @@
                if value := findLicenseClause(licenseAgreementHeadingPattern, 
line); value != "" {
                        findings.Add(value)
                }
-       }
 
-       // some copyright files have a license declaration after the heading ex:
-       // End User License Agreement\n--------------------------
-       // we want to try and find these multi-line license declarations and 
make exceptions for them
-       if value := findLicenseClause(licenseFirstSentenceAfterHeadingPattern, 
content); value != "" {
-               findings.Add(value)
+               // multi-line heading detection (only at start of file)
+               switch headingState {
+               case expectHeading:
+                       if strings.TrimSpace(line) != "" {
+                               headingState = expectDashes
+                       } else {
+                               headingState = headingDone
+                       }
+               case expectDashes:
+                       trimmed := strings.TrimSpace(line)
+                       if len(trimmed) > 0 && strings.Trim(trimmed, "-") == "" 
{
+                               headingState = skipBlanks
+                       } else {
+                               headingState = headingDone
+                       }
+               case skipBlanks:
+                       if strings.TrimSpace(line) != "" {
+                               headingState = captureLicense
+                               licenseText.WriteString(line)
+                               if value := 
extractUpToFirstPeriod(licenseText.String()); value != "" {
+                                       findings.Add(value)
+                                       headingState = headingDone
+                               }
+                       }
+               case captureLicense:
+                       licenseText.WriteString(" ")
+                       licenseText.WriteString(line)
+                       if value := 
extractUpToFirstPeriod(licenseText.String()); value != "" {
+                               findings.Add(value)
+                               headingState = headingDone
+                       }
+               }
        }
 
        results := findings.List()
@@ -55,6 +91,15 @@
        return results
 }
 
+// extractUpToFirstPeriod returns the license text up to the first period,
+// processed through ensureIsSingleLicense, or "" if no period found yet.
+func extractUpToFirstPeriod(s string) string {
+       if idx := strings.Index(s, "."); idx >= 0 {
+               return ensureIsSingleLicense(s[:idx+1])
+       }
+       return ""
+}
+
 func findLicenseClause(pattern *regexp.Regexp, line string) string {
        valueGroup := "license"
        matchesByGroup := internal.MatchNamedCaptureGroups(pattern, line)
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/syft-1.42.0/syft/pkg/cataloger/debian/parse_deb_archive.go 
new/syft-1.42.1/syft/pkg/cataloger/debian/parse_deb_archive.go
--- old/syft-1.42.0/syft/pkg/cataloger/debian/parse_deb_archive.go      
2026-02-10 18:19:56.000000000 +0100
+++ new/syft-1.42.1/syft/pkg/cataloger/debian/parse_deb_archive.go      
2026-02-17 23:32:35.000000000 +0100
@@ -2,7 +2,6 @@
 
 import (
        "archive/tar"
-       "bytes"
        "context"
        "fmt"
        "io"
@@ -107,132 +106,77 @@
 func processControlTar(dcReader io.ReadCloser) (*pkg.DpkgArchiveEntry, error) {
        defer internal.CloseAndLogError(dcReader, "")
 
-       // Extract control, md5sums, and conffiles files from control.tar
        tarReader := tar.NewReader(dcReader)
-       controlFileContent, md5Content, confContent, err := 
readControlFiles(tarReader)
-       if err != nil {
-               return nil, fmt.Errorf("failed to read control files: %w", err)
-       }
-
-       if controlFileContent == nil {
-               return nil, fmt.Errorf("control file not found in archive")
-       }
 
-       metadata, err := newDpkgArchiveMetadata(controlFileContent, md5Content, 
confContent)
-       if err != nil {
-               return nil, fmt.Errorf("failed to create package metadata: %w", 
err)
-       }
-
-       return &metadata, nil
-}
-
-func newDpkgArchiveMetadata(controlFile, md5sums, confFiles []byte) 
(pkg.DpkgArchiveEntry, error) {
-       // parse the control file to get package metadata
-       metadata, err := parseControlFile(string(controlFile))
-       if err != nil {
-               return pkg.DpkgArchiveEntry{}, fmt.Errorf("failed to parse 
control file: %w", err)
-       }
-
-       // parse MD5 sums to get file records
+       var metadata *pkg.DpkgArchiveEntry
        var files []pkg.DpkgFileRecord
-       if len(md5sums) > 0 {
-               files = parseDpkgMD5Info(bytes.NewReader(md5sums))
-       }
-
-       // mark config files
-       if len(confFiles) > 0 {
-               markConfigFiles(confFiles, files)
-       }
-
-       metadata.Files = files
-       return metadata, nil
-}
-
-func decompressionStream(ctx context.Context, r io.Reader, filePath string) 
(io.ReadCloser, error) {
-       format, stream, err := archives.Identify(ctx, filePath, r)
-       if err != nil {
-               return nil, fmt.Errorf("failed to identify compression format: 
%w", err)
-       }
-
-       decompressor, ok := format.(archives.Decompressor)
-       if !ok {
-               return nil, fmt.Errorf("file format does not support 
decompression: %s", filePath)
-       }
-
-       rc, err := decompressor.OpenReader(stream)
-       if err != nil {
-               return nil, fmt.Errorf("failed to create decompression reader: 
%w", err)
-       }
+       var confFileRecords []pkg.DpkgFileRecord
 
-       return rc, nil
-}
-
-// readControlFiles extracts important files from the control.tar archive
-func readControlFiles(tarReader *tar.Reader) (controlFile, md5sums, conffiles 
[]byte, err error) {
        for {
                header, err := tarReader.Next()
                if err == io.EOF {
                        break
                }
                if err != nil {
-                       return nil, nil, nil, err
+                       return nil, fmt.Errorf("failed to read control tar: 
%w", err)
                }
 
                switch filepath.Base(header.Name) {
                case "control":
-                       controlFile, err = io.ReadAll(tarReader)
+                       // parseDpkgStatus already streams via bufio.Reader
+                       entries, err := parseDpkgStatus(tarReader)
                        if err != nil {
-                               return nil, nil, nil, err
+                               return nil, fmt.Errorf("failed to parse control 
file: %w", err)
                        }
-               case "md5sums":
-                       md5sums, err = io.ReadAll(tarReader)
-                       if err != nil {
-                               return nil, nil, nil, err
+                       if len(entries) == 0 {
+                               return nil, fmt.Errorf("no package entries 
found in control file")
                        }
+                       entry := pkg.DpkgArchiveEntry(entries[0])
+                       metadata = &entry
+               case "md5sums":
+                       // parseDpkgMD5Info already streams via bufio.Scanner
+                       files = parseDpkgMD5Info(tarReader)
                case "conffiles":
-                       conffiles, err = io.ReadAll(tarReader)
-                       if err != nil {
-                               return nil, nil, nil, err
+                       // parseDpkgConffileInfo already streams via 
bufio.Scanner
+                       confFileRecords = parseDpkgConffileInfo(tarReader)
+               }
+       }
+
+       if metadata == nil {
+               return nil, fmt.Errorf("control file not found in archive")
+       }
+
+       if len(confFileRecords) > 0 && len(files) > 0 {
+               configPaths := make(map[string]struct{}, len(confFileRecords))
+               for _, cf := range confFileRecords {
+                       configPaths[cf.Path] = struct{}{}
+               }
+               for i, f := range files {
+                       if _, isConfig := configPaths[f.Path]; isConfig {
+                               files[i].IsConfigFile = true
                        }
                }
        }
 
-       return controlFile, md5sums, conffiles, nil
+       metadata.Files = files
+       return metadata, nil
 }
 
-// parseControlFile parses the content of a debian control file into package 
metadata
-func parseControlFile(controlFileContent string) (pkg.DpkgArchiveEntry, error) 
{
-       // Reuse the existing dpkg status file parsing logic
-       reader := strings.NewReader(controlFileContent)
-
-       entries, err := parseDpkgStatus(reader)
+func decompressionStream(ctx context.Context, r io.Reader, filePath string) 
(io.ReadCloser, error) {
+       format, stream, err := archives.Identify(ctx, filePath, r)
        if err != nil {
-               return pkg.DpkgArchiveEntry{}, fmt.Errorf("failed to parse 
control file: %w", err)
+               return nil, fmt.Errorf("failed to identify compression format: 
%w", err)
        }
 
-       if len(entries) == 0 {
-               return pkg.DpkgArchiveEntry{}, fmt.Errorf("no package entries 
found in control file")
+       decompressor, ok := format.(archives.Decompressor)
+       if !ok {
+               return nil, fmt.Errorf("file format does not support 
decompression: %s", filePath)
        }
 
-       // We expect only one entry from a .deb control file
-       return pkg.DpkgArchiveEntry(entries[0]), nil
-}
-
-// markConfigFiles marks files that are listed in conffiles as configuration 
files
-func markConfigFiles(conffilesContent []byte, files []pkg.DpkgFileRecord) {
-       // Parse the conffiles content into DpkgFileRecord entries
-       confFiles := parseDpkgConffileInfo(bytes.NewReader(conffilesContent))
-
-       // Create a map for quick lookup of config files by path
-       configPathMap := make(map[string]struct{})
-       for _, confFile := range confFiles {
-               configPathMap[confFile.Path] = struct{}{}
+       rc, err := decompressor.OpenReader(stream)
+       if err != nil {
+               return nil, fmt.Errorf("failed to create decompression reader: 
%w", err)
        }
 
-       // Mark files as config files if they're in the conffiles list
-       for i := range files {
-               if _, exists := configPathMap[files[i].Path]; exists {
-                       files[i].IsConfigFile = true
-               }
-       }
+       return rc, nil
 }
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/syft-1.42.0/syft/pkg/cataloger/debian/parse_deb_archive_test.go 
new/syft-1.42.1/syft/pkg/cataloger/debian/parse_deb_archive_test.go
--- old/syft-1.42.0/syft/pkg/cataloger/debian/parse_deb_archive_test.go 
2026-02-10 18:19:56.000000000 +0100
+++ new/syft-1.42.1/syft/pkg/cataloger/debian/parse_deb_archive_test.go 
2026-02-17 23:32:35.000000000 +0100
@@ -3,140 +3,85 @@
 import (
        "archive/tar"
        "bytes"
+       "io"
        "testing"
 
        "github.com/stretchr/testify/assert"
        "github.com/stretchr/testify/require"
-
-       "github.com/anchore/syft/syft/file"
-       "github.com/anchore/syft/syft/pkg"
 )
 
-func TestReadControlFiles(t *testing.T) {
+func TestProcessControlTar(t *testing.T) {
        tarBytes := createTestTarWithControlFiles(t)
 
-       tarReader := bytes.NewReader(tarBytes)
-       reader := tar.NewReader(tarReader)
-
-       controlFile, md5sums, conffiles, err := readControlFiles(reader)
+       metadata, err := 
processControlTar(io.NopCloser(bytes.NewReader(tarBytes)))
 
        require.NoError(t, err)
-       assert.NotNil(t, controlFile, "expected control file to be found")
-       assert.NotNil(t, md5sums, "expected md5sums file to be found")
-       assert.NotNil(t, conffiles, "expected conffiles file to be found")
-
-       assert.Contains(t, string(controlFile), "Package: test-package")
-       assert.Contains(t, string(md5sums), "d41d8cd98f00b204e9800998ecf8427e")
-       assert.Contains(t, string(conffiles), "/etc/test")
+       require.NotNil(t, metadata)
+
+       assert.Equal(t, "test-package", metadata.Package)
+       assert.Equal(t, "1.0.0", metadata.Version)
+
+       // md5sums should have been parsed into file records
+       require.Len(t, metadata.Files, 1)
+       assert.Equal(t, "/usr/bin/test-command", metadata.Files[0].Path)
+       assert.Equal(t, "d41d8cd98f00b204e9800998ecf8427e", 
metadata.Files[0].Digest.Value)
+
+       // conffiles should have marked config files
+       assert.True(t, metadata.Files[0].IsConfigFile, "file listed in 
conffiles should be marked as config")
 }
 
-// createTestTarWithControlFiles creates a simple in-memory tar file with test 
control files
-func createTestTarWithControlFiles(t *testing.T) []byte {
+func TestProcessControlTar_ConfigFileMarking(t *testing.T) {
+       // Create a tar where conffiles lists paths that overlap with md5sums 
entries
        var buf bytes.Buffer
        tw := tar.NewWriter(&buf)
 
-       // Add control file
-       controlContent := `Package: test-package
-Version: 1.0.0
-Architecture: all
-Maintainer: Test <[email protected]>
-Description: Test package
-`
-       err := tw.WriteHeader(&tar.Header{
-               Name: "control",
-               Mode: 0644,
-               Size: int64(len(controlContent)),
-       })
-       require.NoError(t, err)
-       _, err = tw.Write([]byte(controlContent))
-       require.NoError(t, err)
+       controlContent := "Package: test-package\nVersion: 1.0.0\nArchitecture: 
all\n"
+       writeTarEntry(t, tw, "control", controlContent)
 
-       // Add md5sums file
-       md5Content := "d41d8cd98f00b204e9800998ecf8427e  usr/bin/test-command\n"
-       err = tw.WriteHeader(&tar.Header{
-               Name: "md5sums",
-               Mode: 0644,
-               Size: int64(len(md5Content)),
-       })
-       require.NoError(t, err)
-       _, err = tw.Write([]byte(md5Content))
-       require.NoError(t, err)
+       md5Content := "d41d8cd98f00b204e9800998ecf8427e  
usr/bin/test-command\n" +
+               "d41d8cd98f00b204e9800998ecf8427e  etc/test/config.conf\n" +
+               "d41d8cd98f00b204e9800998ecf8427e  usr/bin/other-command\n"
+       writeTarEntry(t, tw, "md5sums", md5Content)
 
-       // Add conffiles file
-       conffilesContent := "/etc/test/config.conf\n"
-       err = tw.WriteHeader(&tar.Header{
-               Name: "conffiles",
-               Mode: 0644,
-               Size: int64(len(conffilesContent)),
-       })
-       require.NoError(t, err)
-       _, err = tw.Write([]byte(conffilesContent))
-       require.NoError(t, err)
+       conffilesContent := "/usr/bin/test-command\n/etc/test/config.conf\n"
+       writeTarEntry(t, tw, "conffiles", conffilesContent)
 
-       // Close the tar writer
-       err = tw.Close()
+       require.NoError(t, tw.Close())
+
+       metadata, err := 
processControlTar(io.NopCloser(bytes.NewReader(buf.Bytes())))
        require.NoError(t, err)
+       require.Len(t, metadata.Files, 3)
 
-       return buf.Bytes()
+       assert.True(t, metadata.Files[0].IsConfigFile, "first file should be 
marked as config file")
+       assert.True(t, metadata.Files[1].IsConfigFile, "second file should be 
marked as config file")
+       assert.False(t, metadata.Files[2].IsConfigFile, "third file should not 
be marked as config file")
 }
 
-func TestMarkConfigFiles(t *testing.T) {
-       // Create test data
-       conffilesContent := 
[]byte("/usr/bin/test-command\n/etc/test/config.conf\n")
-
-       files := []pkg.DpkgFileRecord{
-               {
-                       Path: "/usr/bin/test-command",
-                       Digest: &file.Digest{
-                               Algorithm: "md5",
-                               Value:     "d41d8cd98f00b204e9800998ecf8427e",
-                       },
-               },
-               {
-                       Path: "/etc/test/config.conf",
-                       Digest: &file.Digest{
-                               Algorithm: "md5",
-                               Value:     "d41d8cd98f00b204e9800998ecf8427e",
-                       },
-               },
-               {
-                       Path: "/usr/bin/other-command",
-                       Digest: &file.Digest{
-                               Algorithm: "md5",
-                               Value:     "d41d8cd98f00b204e9800998ecf8427e",
-                       },
-               },
-       }
-
-       markConfigFiles(conffilesContent, files)
-
-       assert.True(t, files[0].IsConfigFile, "first file should be marked as 
config file")
-       assert.True(t, files[1].IsConfigFile, "second file should be marked as 
config file")
-       assert.False(t, files[2].IsConfigFile, "third file should not be marked 
as config file")
-}
+// createTestTarWithControlFiles creates a simple in-memory tar file with test 
control files
+func createTestTarWithControlFiles(t *testing.T) []byte {
+       var buf bytes.Buffer
+       tw := tar.NewWriter(&buf)
+
+       controlContent := "Package: test-package\nVersion: 1.0.0\nArchitecture: 
all\nMaintainer: Test <[email protected]>\nDescription: Test package\n"
+       writeTarEntry(t, tw, "control", controlContent)
+
+       md5Content := "d41d8cd98f00b204e9800998ecf8427e  usr/bin/test-command\n"
+       writeTarEntry(t, tw, "md5sums", md5Content)
 
-func TestParseControlFile(t *testing.T) {
-       controlContent := `Package: test-package
-Version: 1.2.3-4
-Architecture: amd64
-Maintainer: Test User <[email protected]>
-Installed-Size: 1234
-Depends: libc6, libtest
-Description: This is a test package
- More description text
- And even more details
-`
+       conffilesContent := "/usr/bin/test-command\n"
+       writeTarEntry(t, tw, "conffiles", conffilesContent)
 
-       metadata, err := parseControlFile(controlContent)
+       require.NoError(t, tw.Close())
+       return buf.Bytes()
+}
 
+func writeTarEntry(t *testing.T, tw *tar.Writer, name, content string) {
+       t.Helper()
+       require.NoError(t, tw.WriteHeader(&tar.Header{
+               Name: name,
+               Mode: 0644,
+               Size: int64(len(content)),
+       }))
+       _, err := tw.Write([]byte(content))
        require.NoError(t, err)
-       assert.Equal(t, "test-package", metadata.Package)
-       assert.Equal(t, "1.2.3-4", metadata.Version)
-       assert.Equal(t, "amd64", metadata.Architecture)
-       assert.Equal(t, "Test User <[email protected]>", metadata.Maintainer)
-       assert.Equal(t, 1234, metadata.InstalledSize)
-       assert.Contains(t, metadata.Description, "This is a test package")
-       assert.Len(t, metadata.Depends, 2)
-       assert.Contains(t, metadata.Depends, "libc6")
-       assert.Contains(t, metadata.Depends, "libtest")
 }
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/syft-1.42.0/syft/pkg/cataloger/internal/cpegenerate/dictionary/data/cpe-index.json
 
new/syft-1.42.1/syft/pkg/cataloger/internal/cpegenerate/dictionary/data/cpe-index.json
--- 
old/syft-1.42.0/syft/pkg/cataloger/internal/cpegenerate/dictionary/data/cpe-index.json
      2026-02-10 18:19:56.000000000 +0100
+++ 
new/syft-1.42.1/syft/pkg/cataloger/internal/cpegenerate/dictionary/data/cpe-index.json
      2026-02-17 23:32:35.000000000 +0100
@@ -4,6 +4,9 @@
       "aahframe.work": [
         "cpe:2.3:a:aahframework:aah:*:*:*:*:*:go:*:*"
       ],
+      "chainguard.dev/apko": [
+        "cpe:2.3:a:chainguard:apko:*:*:*:*:*:go:*:*"
+      ],
       "github.com/ClickHouse/ch-go": [
         "cpe:2.3:a:clickhouse:ch:*:*:*:*:*:go:*:*"
       ],
@@ -165,6 +168,9 @@
       "golang.org/x/net": [
         "cpe:2.3:a:golang:networking:*:*:*:*:*:go:*:*"
       ],
+      "golang.org/x/net/html": [
+        "cpe:2.3:a:go:html:*:*:*:*:*:go:*:*"
+      ],
       "golang.org/x/net/http2": [
         "cpe:2.3:a:golang:http2:*:*:*:*:*:*:*:*",
         "cpe:2.3:a:golang:http2:*:*:*:*:*:go:*:*"
@@ -2371,6 +2377,9 @@
       "@nuxt/devalue": [
         "cpe:2.3:a:nuxtjs:\\@nuxt\\/devalue:*:*:*:*:*:node.js:*:*"
       ],
+      "@nyariv/sandboxjs": [
+        "cpe:2.3:a:nyariv:sandboxjs:*:*:*:*:*:node.js:*:*"
+      ],
       "@octokit/webhooks": [
         "cpe:2.3:a:octokit:webhooks:*:*:*:*:*:node.js:*:*"
       ],
@@ -6014,6 +6023,9 @@
       "fonttools": [
         "cpe:2.3:a:fonttools:fonttools:*:*:*:*:*:python:*:*"
       ],
+      "geopandas": [
+        "cpe:2.3:a:geopandas:geopandas:*:*:*:*:*:python:*:*"
+      ],
       "global-workqueue": [
         
"cpe:2.3:a:global-workqueue_project:global-workqueue:*:*:*:*:*:python:*:*"
       ],
@@ -8807,7 +8819,8 @@
         "cpe:2.3:a:solidwp:solid_security:*:*:*:*:*:wordpress:*:*"
       ],
       "betterdocs": [
-        "cpe:2.3:a:wpdeveloper:betterdocs:*:*:*:*:*:wordpress:*:*"
+        "cpe:2.3:a:wpdeveloper:betterdocs:*:*:*:*:*:wordpress:*:*",
+        "cpe:2.3:a:wpdeveloper:betterdocs:*:*:*:*:free:wordpress:*:*"
       ],
       "betterlinks": [
         "cpe:2.3:a:wpdeveloper:betterlinks:*:*:*:*:free:wordpress:*:*"
@@ -15061,7 +15074,8 @@
         
"cpe:2.3:a:andreamarinucci:notification_for_telegram:*:*:*:*:*:wordpress:*:*"
       ],
       "notificationx": [
-        "cpe:2.3:a:wpdeveloper:notificationx:*:*:*:*:*:wordpress:*:*"
+        "cpe:2.3:a:wpdeveloper:notificationx:*:*:*:*:*:wordpress:*:*",
+        "cpe:2.3:a:wpdeveloper:notificationx:*:*:*:*:free:wordpress:*:*"
       ],
       "notifier": [
         "cpe:2.3:a:wanotifier:wanotifier:*:*:*:*:*:wordpress:*:*"
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/syft-1.42.0/syft/pkg/cataloger/redhat/package.go 
new/syft-1.42.1/syft/pkg/cataloger/redhat/package.go
--- old/syft-1.42.0/syft/pkg/cataloger/redhat/package.go        2026-02-10 
18:19:56.000000000 +0100
+++ new/syft-1.42.1/syft/pkg/cataloger/redhat/package.go        2026-02-17 
23:32:35.000000000 +0100
@@ -84,13 +84,13 @@
        }, nil
 }
 
-// packageURL returns the PURL for the specific RHEL package (see 
https://github.com/package-url/purl-spec)
+// packageURL returns the PURL for the specific RHEL or Hummingbird package 
(see https://github.com/package-url/purl-spec)
 func packageURL(name, arch string, epoch *int, srpm string, version, release 
string, distro *linux.Release) string {
        var namespace string
        if distro != nil {
                namespace = distro.ID
        }
-       if namespace == "rhel" {
+       if namespace == "rhel" || namespace == "hummingbird" {
                namespace = "redhat"
        }
        if strings.HasPrefix(namespace, "opensuse") {
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/syft-1.42.0/syft/pkg/cataloger/redhat/package_test.go 
new/syft-1.42.1/syft/pkg/cataloger/redhat/package_test.go
--- old/syft-1.42.0/syft/pkg/cataloger/redhat/package_test.go   2026-02-10 
18:19:56.000000000 +0100
+++ new/syft-1.42.1/syft/pkg/cataloger/redhat/package_test.go   2026-02-17 
23:32:35.000000000 +0100
@@ -56,6 +56,20 @@
                        expected: "pkg:rpm/p@v-r",
                },
                {
+                       name: "hummingbird distro maps to redhat namespace",
+                       distro: &linux.Release{
+                               ID:        "hummingbird",
+                               VersionID: "1.0",
+                       },
+                       metadata: pkg.RpmDBEntry{
+                               Name:    "p",
+                               Version: "v",
+                               Release: "r",
+                               Epoch:   nil,
+                       },
+                       expected: "pkg:rpm/redhat/p@v-r?distro=hummingbird-1.0",
+               },
+               {
                        name: "with upstream source rpm info",
                        distro: &linux.Release{
                                ID:        "rhel",
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/syft-1.42.0/syft/pkg/cataloger/snap/parse_kernel_changelog.go 
new/syft-1.42.1/syft/pkg/cataloger/snap/parse_kernel_changelog.go
--- old/syft-1.42.0/syft/pkg/cataloger/snap/parse_kernel_changelog.go   
2026-02-10 18:19:56.000000000 +0100
+++ new/syft-1.42.1/syft/pkg/cataloger/snap/parse_kernel_changelog.go   
2026-02-17 23:32:35.000000000 +0100
@@ -1,10 +1,10 @@
 package snap
 
 import (
+       "bufio"
        "compress/gzip"
        "context"
        "fmt"
-       "io"
        "regexp"
        "strings"
 
@@ -22,16 +22,28 @@
        majorVersion   string // e.g., "5.4"
 }
 
-// parseKernelChangelog parses changelog files from kernel snaps to extract 
kernel version
+// parseKernelChangelog parses changelog files from kernel snaps to extract 
kernel version.
+// The changelog is gzip-compressed and may be very large, so we stream it 
line-by-line
+// rather than reading it entirely into memory.
 func parseKernelChangelog(_ context.Context, _ file.Resolver, _ 
*generic.Environment, reader file.LocationReadCloser) ([]pkg.Package, 
[]artifact.Relationship, error) {
-       // The file should be gzipped
-       lines, err := readChangelogLines(reader)
+       gzReader, err := gzip.NewReader(reader)
        if err != nil {
-               return nil, nil, err
+               return nil, nil, fmt.Errorf("failed to create gzip reader for 
changelog: %w", err)
+       }
+       defer gzReader.Close()
+
+       scanner := bufio.NewScanner(gzReader)
+
+       // read the first line to extract kernel version
+       // Format: "linux (5.4.0-195.215) focal; urgency=medium"
+       if !scanner.Scan() {
+               if err := scanner.Err(); err != nil {
+                       return nil, nil, fmt.Errorf("failed to read changelog 
content: %w", err)
+               }
+               return nil, nil, fmt.Errorf("changelog file is empty")
        }
 
-       // pull from first line
-       versionInfo, err := extractKernelVersion(lines[0])
+       versionInfo, err := extractKernelVersion(scanner.Text())
        if err != nil {
                return nil, nil, err
        }
@@ -42,38 +54,21 @@
 
        packages := createMainKernelPackage(versionInfo, snapMetadata, 
reader.Location)
 
-       // Check for base kernel package
-       basePackage := findBaseKernelPackage(lines, versionInfo, snapMetadata, 
reader.Location)
-       if basePackage != nil {
-               packages = append(packages, *basePackage)
+       // stream remaining lines looking for the base kernel entry
+       baseKernelEntry := fmt.Sprintf("%s/linux:", 
strings.ReplaceAll(versionInfo.releaseVersion, ";", "/"))
+       for scanner.Scan() {
+               line := scanner.Text()
+               if strings.Contains(line, baseKernelEntry) {
+                       if basePackage := parseBaseKernelLine(line, 
versionInfo.majorVersion, snapMetadata, reader.Location); basePackage != nil {
+                               packages = append(packages, *basePackage)
+                       }
+                       break
+               }
        }
 
        return packages, nil, nil
 }
 
-// readChangelogLines reads and decompresses the changelog content
-func readChangelogLines(reader file.LocationReadCloser) ([]string, error) {
-       gzReader, err := gzip.NewReader(reader)
-       if err != nil {
-               return nil, fmt.Errorf("failed to create gzip reader for 
changelog: %w", err)
-       }
-       defer gzReader.Close()
-
-       content, err := io.ReadAll(gzReader)
-       if err != nil {
-               return nil, fmt.Errorf("failed to read changelog content: %w", 
err)
-       }
-
-       lines := strings.Split(string(content), "\n")
-       if len(lines) == 0 {
-               return nil, fmt.Errorf("changelog file is empty")
-       }
-
-       // Parse the first line to extract kernel version information
-       // Format: "linux (5.4.0-195.215) focal; urgency=medium"
-       return lines, nil
-}
-
 // extractKernelVersion parses version information from the first changelog 
line
 func extractKernelVersion(firstLine string) (*kernelVersionInfo, error) {
        // Format: "linux (5.4.0-195.215) focal; urgency=medium"
@@ -117,19 +112,6 @@
        return []pkg.Package{kernelPkg}
 }
 
-// findBaseKernelPackage searches for and creates base kernel package if 
present
-func findBaseKernelPackage(lines []string, versionInfo *kernelVersionInfo, 
snapMetadata pkg.SnapEntry, location file.Location) *pkg.Package {
-       baseKernelEntry := fmt.Sprintf("%s/linux:", 
strings.ReplaceAll(versionInfo.releaseVersion, ";", "/"))
-
-       for _, line := range lines {
-               if strings.Contains(line, baseKernelEntry) {
-                       return parseBaseKernelLine(line, 
versionInfo.majorVersion, snapMetadata, location)
-               }
-       }
-
-       return nil
-}
-
 // parseBaseKernelLine extracts base kernel version from a changelog line
 func parseBaseKernelLine(line string, majorVersion string, snapMetadata 
pkg.SnapEntry, location file.Location) *pkg.Package {
        baseKernelRegex := 
regexp.MustCompile(fmt.Sprintf(`(%s-[0-9]+)\.?[0-9]*`, 
regexp.QuoteMeta(majorVersion)))
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/syft-1.42.0/syft/pkg/cataloger/snap/parse_kernel_changelog_test.go 
new/syft-1.42.1/syft/pkg/cataloger/snap/parse_kernel_changelog_test.go
--- old/syft-1.42.0/syft/pkg/cataloger/snap/parse_kernel_changelog_test.go      
1970-01-01 01:00:00.000000000 +0100
+++ new/syft-1.42.1/syft/pkg/cataloger/snap/parse_kernel_changelog_test.go      
2026-02-17 23:32:35.000000000 +0100
@@ -0,0 +1,312 @@
+package snap
+
+import (
+       "bytes"
+       "compress/gzip"
+       "context"
+       "io"
+       "strings"
+       "testing"
+
+       "github.com/stretchr/testify/assert"
+       "github.com/stretchr/testify/require"
+
+       "github.com/anchore/syft/syft/file"
+       "github.com/anchore/syft/syft/pkg"
+       "github.com/anchore/syft/syft/pkg/cataloger/generic"
+)
+
+func gzipContent(t *testing.T, content string) []byte {
+       t.Helper()
+       var buf bytes.Buffer
+       w := gzip.NewWriter(&buf)
+       _, err := w.Write([]byte(content))
+       require.NoError(t, err)
+       require.NoError(t, w.Close())
+       return buf.Bytes()
+}
+
+func locationReadCloser(t *testing.T, data []byte) file.LocationReadCloser {
+       t.Helper()
+       return file.LocationReadCloser{
+               Location:   
file.NewLocation("test-fixtures/changelog.Debian.gz"),
+               ReadCloser: io.NopCloser(bytes.NewReader(data)),
+       }
+}
+
+func TestExtractKernelVersion(t *testing.T) {
+       tests := []struct {
+               name        string
+               firstLine   string
+               expected    *kernelVersionInfo
+               expectError string
+       }{
+               {
+                       name:      "standard focal kernel",
+                       firstLine: "linux (5.4.0-195.215) focal; 
urgency=medium",
+                       expected: &kernelVersionInfo{
+                               baseVersion:    "5.4.0-195",
+                               releaseVersion: "215",
+                               fullVersion:    "5.4.0-195.215",
+                               majorVersion:   "5.4",
+                       },
+               },
+               {
+                       name:      "noble kernel 6.x",
+                       firstLine: "linux (6.8.0-50.51) noble; urgency=medium",
+                       expected: &kernelVersionInfo{
+                               baseVersion:    "6.8.0-50",
+                               releaseVersion: "51",
+                               fullVersion:    "6.8.0-50.51",
+                               majorVersion:   "6.8",
+                       },
+               },
+               {
+                       name:      "jammy kernel",
+                       firstLine: "linux (5.15.0-130.140) jammy; 
urgency=medium",
+                       expected: &kernelVersionInfo{
+                               baseVersion:    "5.15.0-130",
+                               releaseVersion: "140",
+                               fullVersion:    "5.15.0-130.140",
+                               majorVersion:   "5.15",
+                       },
+               },
+               {
+                       name:        "empty string",
+                       firstLine:   "",
+                       expectError: "could not parse kernel version from 
changelog",
+               },
+               {
+                       name:        "no version match",
+                       firstLine:   "not a valid changelog line",
+                       expectError: "could not parse kernel version from 
changelog",
+               },
+               {
+                       name:        "missing release version",
+                       firstLine:   "linux (5.4.0-195) focal; urgency=medium",
+                       expectError: "could not parse kernel version from 
changelog",
+               },
+       }
+
+       for _, tt := range tests {
+               t.Run(tt.name, func(t *testing.T) {
+                       result, err := extractKernelVersion(tt.firstLine)
+                       if tt.expectError != "" {
+                               require.Error(t, err)
+                               assert.Contains(t, err.Error(), tt.expectError)
+                               return
+                       }
+                       require.NoError(t, err)
+                       assert.Equal(t, tt.expected.baseVersion, 
result.baseVersion)
+                       assert.Equal(t, tt.expected.releaseVersion, 
result.releaseVersion)
+                       assert.Equal(t, tt.expected.fullVersion, 
result.fullVersion)
+                       assert.Equal(t, tt.expected.majorVersion, 
result.majorVersion)
+               })
+       }
+}
+
+func TestCreateMainKernelPackage(t *testing.T) {
+       location := file.NewLocation("test-fixtures/changelog.Debian.gz")
+       versionInfo := &kernelVersionInfo{
+               baseVersion:    "5.4.0-195",
+               releaseVersion: "215",
+               fullVersion:    "5.4.0-195.215",
+               majorVersion:   "5.4",
+       }
+       snapMetadata := pkg.SnapEntry{
+               SnapType: pkg.SnapTypeKernel,
+       }
+
+       packages := createMainKernelPackage(versionInfo, snapMetadata, location)
+
+       require.Len(t, packages, 1)
+       p := packages[0]
+       assert.Equal(t, "linux-image-5.4.0-195-generic", p.Name)
+       assert.Equal(t, "5.4.0-195.215", p.Version)
+       assert.Equal(t, pkg.DebPkg, p.Type)
+
+       metadata, ok := p.Metadata.(pkg.SnapEntry)
+       require.True(t, ok)
+       assert.Equal(t, pkg.SnapTypeKernel, metadata.SnapType)
+}
+
+func TestParseBaseKernelLine(t *testing.T) {
+       location := file.NewLocation("test-fixtures/changelog.Debian.gz")
+       snapMetadata := pkg.SnapEntry{
+               SnapType: pkg.SnapTypeKernel,
+       }
+
+       tests := []struct {
+               name         string
+               line         string
+               majorVersion string
+               expectNil    bool
+               expectedName string
+               expectedVer  string
+       }{
+               {
+                       name:         "standard base kernel entry",
+                       line:         "    [ Ubuntu: 5.4-100.200 ]",
+                       majorVersion: "5.4",
+                       expectedName: "linux-image-5.4-100-generic",
+                       expectedVer:  "5.4-100.200",
+               },
+               {
+                       name:         "6.x base kernel entry",
+                       line:         "    [ Ubuntu: 6.8-40.41 ]",
+                       majorVersion: "6.8",
+                       expectedName: "linux-image-6.8-40-generic",
+                       expectedVer:  "6.8-40.41",
+               },
+               {
+                       name:         "no matching version",
+                       line:         "  * some random changelog text here",
+                       majorVersion: "5.4",
+                       expectNil:    true,
+               },
+               {
+                       name:         "empty line",
+                       line:         "",
+                       majorVersion: "5.4",
+                       expectNil:    true,
+               },
+       }
+
+       for _, tt := range tests {
+               t.Run(tt.name, func(t *testing.T) {
+                       result := parseBaseKernelLine(tt.line, tt.majorVersion, 
snapMetadata, location)
+                       if tt.expectNil {
+                               assert.Nil(t, result)
+                               return
+                       }
+                       require.NotNil(t, result)
+                       assert.Equal(t, tt.expectedName, result.Name)
+                       assert.Equal(t, tt.expectedVer, result.Version)
+                       assert.Equal(t, pkg.DebPkg, result.Type)
+
+                       metadata, ok := result.Metadata.(pkg.SnapEntry)
+                       require.True(t, ok)
+                       assert.Equal(t, pkg.SnapTypeKernel, metadata.SnapType)
+               })
+       }
+}
+
+func TestParseKernelChangelog(t *testing.T) {
+       // Realistic changelog content modeled on Ubuntu kernel changelogs.
+       // The first line declares the patched kernel version.
+       // Somewhere later a line references the base upstream kernel.
+       fullChangelog := strings.Join([]string{
+               "linux (5.4.0-195.215) focal; urgency=medium",
+               "",
+               "  * focal/linux: 5.4.0-195.215 -proposed tracker (LP: 
#2083390)",
+               "",
+               "  [ Ubuntu: 5.4-100.200 ]",
+               "",
+               "  * Some other entry",
+               "",
+               " -- Ubuntu Kernel Team <[email protected]>  Mon, 01 
Jan 2024 00:00:00 +0000",
+               "",
+       }, "\n")
+
+       // Changelog where the base kernel entry line uses the release version 
pattern
+       // The code builds: fmt.Sprintf("%s/linux:", releaseVersion) → 
"215/linux:"
+       changelogWithBaseEntry := strings.Join([]string{
+               "linux (5.4.0-195.215) focal; urgency=medium",
+               "",
+               "  * focal/linux: 5.4.0-195.215 -proposed tracker",
+               "",
+               "  215/linux: 5.4-100.200 base entry",
+               "",
+               " -- Ubuntu Kernel Team <[email protected]>  Mon, 01 
Jan 2024 00:00:00 +0000",
+               "",
+       }, "\n")
+
+       // Changelog with only the header line and no base kernel match
+       minimalChangelog := "linux (6.8.0-50.51) noble; urgency=medium\n"
+
+       tests := []struct {
+               name          string
+               input         []byte
+               expectedCount int
+               expectedNames []string
+               expectedVers  []string
+               expectError   bool
+               errorContains string
+       }{
+               {
+                       name:          "full changelog with base kernel via 
release version pattern",
+                       input:         gzipContent(t, changelogWithBaseEntry),
+                       expectedCount: 2,
+                       expectedNames: 
[]string{"linux-image-5.4.0-195-generic", "linux-image-5.4-100-generic"},
+                       expectedVers:  []string{"5.4.0-195.215", "5.4-100.200"},
+               },
+               {
+                       name:          "changelog without base kernel match 
returns only main package",
+                       input:         gzipContent(t, minimalChangelog),
+                       expectedCount: 1,
+                       expectedNames: []string{"linux-image-6.8.0-50-generic"},
+                       expectedVers:  []string{"6.8.0-50.51"},
+               },
+               {
+                       name:          "full changelog without matching release 
version pattern returns only main package",
+                       input:         gzipContent(t, fullChangelog),
+                       expectedCount: 1,
+                       expectedNames: 
[]string{"linux-image-5.4.0-195-generic"},
+                       expectedVers:  []string{"5.4.0-195.215"},
+               },
+               {
+                       name:          "invalid gzip data",
+                       input:         []byte("not gzip data"),
+                       expectError:   true,
+                       errorContains: "failed to create gzip reader",
+               },
+               {
+                       // The old (slurp) implementation produces "could not 
parse kernel version"
+                       // because strings.Split("", "\n") yields [""], not an 
empty slice.
+                       // The new (streaming) implementation produces 
"changelog file is empty"
+                       // because bufio.Scanner.Scan() returns false 
immediately.
+                       // Both correctly reject empty content; only the 
message differs.
+                       name:        "empty gzip content",
+                       input:       gzipContent(t, ""),
+                       expectError: true,
+               },
+               {
+                       name:          "gzip content with unparseable first 
line",
+                       input:         gzipContent(t, "this is not a valid 
kernel changelog\n"),
+                       expectError:   true,
+                       errorContains: "could not parse kernel version from 
changelog",
+               },
+       }
+
+       for _, tt := range tests {
+               t.Run(tt.name, func(t *testing.T) {
+                       reader := locationReadCloser(t, tt.input)
+
+                       packages, relationships, err := parseKernelChangelog(
+                               context.Background(), nil, 
&generic.Environment{}, reader,
+                       )
+
+                       if tt.expectError {
+                               require.Error(t, err)
+                               if tt.errorContains != "" {
+                                       assert.Contains(t, err.Error(), 
tt.errorContains)
+                               }
+                               return
+                       }
+
+                       require.NoError(t, err)
+                       assert.Nil(t, relationships)
+                       require.Len(t, packages, tt.expectedCount)
+
+                       for i, p := range packages {
+                               assert.Equal(t, tt.expectedNames[i], p.Name, 
"package %d name", i)
+                               assert.Equal(t, tt.expectedVers[i], p.Version, 
"package %d version", i)
+                               assert.Equal(t, pkg.DebPkg, p.Type, "package %d 
type", i)
+
+                               metadata, ok := p.Metadata.(pkg.SnapEntry)
+                               require.True(t, ok, "package %d metadata type", 
i)
+                               assert.Equal(t, pkg.SnapTypeKernel, 
metadata.SnapType, "package %d snap type", i)
+                       }
+               })
+       }
+}
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/syft-1.42.0/syft/source/filesource/file_source.go 
new/syft-1.42.1/syft/source/filesource/file_source.go
--- old/syft-1.42.0/syft/source/filesource/file_source.go       2026-02-10 
18:19:56.000000000 +0100
+++ new/syft-1.42.1/syft/source/filesource/file_source.go       2026-02-17 
23:32:35.000000000 +0100
@@ -76,6 +76,11 @@
 
        analysisPath, cleanupFn, err := fileAnalysisPath(cfg.Path, 
cfg.SkipExtractArchive)
        if err != nil {
+               if cleanupFn != nil {
+                       if cleanupErr := cleanupFn(); cleanupErr != nil {
+                               log.Warnf("failed to cleanup temporary 
directory: %v", cleanupErr)
+                       }
+               }
                return nil, fmt.Errorf("unable to extract file analysis 
path=%q: %w", cfg.Path, err)
        }
 
@@ -211,7 +216,7 @@
        if unarchiver, ok := envelopedUnarchiver.(archives.Extractor); err == 
nil && ok {
                analysisPath, cleanupFn, err = unarchiveToTmp(path, unarchiver)
                if err != nil {
-                       return "", nil, fmt.Errorf("unable to unarchive source 
file: %w", err)
+                       return "", cleanupFn, fmt.Errorf("unable to unarchive 
source file: %w", err)
                }
 
                log.Debugf("source path is an archive")

++++++ syft.obsinfo ++++++
--- /var/tmp/diff_new_pack.4X4nFr/_old  2026-02-19 14:24:00.140272212 +0100
+++ /var/tmp/diff_new_pack.4X4nFr/_new  2026-02-19 14:24:00.152272709 +0100
@@ -1,5 +1,5 @@
 name: syft
-version: 1.42.0
-mtime: 1770743996
-commit: 9872ff36ba5881f977b6e1b46c7bb33a1147f09e
+version: 1.42.1
+mtime: 1771367555
+commit: 0a3f7bb06ee168495ee54b8b66fccb22a056fe99
 

++++++ vendor.tar.gz ++++++
/work/SRC/openSUSE:Factory/syft/vendor.tar.gz 
/work/SRC/openSUSE:Factory/.syft.new.1977/vendor.tar.gz differ: char 15, line 1

Reply via email to