Script 'mail_helper' called by obssrc
Hello community,

here is the log from the commit of package syft for openSUSE:Factory checked in 
at 2023-03-10 22:07:24
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Comparing /work/SRC/openSUSE:Factory/syft (Old)
 and      /work/SRC/openSUSE:Factory/.syft.new.31432 (New)
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Package is "syft"

Fri Mar 10 22:07:24 2023 rev:31 rq:1070559 version:0.74.1

Changes:
--------
--- /work/SRC/openSUSE:Factory/syft/syft.changes        2023-03-03 
22:31:17.552001903 +0100
+++ /work/SRC/openSUSE:Factory/.syft.new.31432/syft.changes     2023-03-10 
22:07:31.161170586 +0100
@@ -1,0 +2,20 @@
+Thu Mar 09 15:31:12 UTC 2023 - ka...@b1-systems.de
+
+- Update to version 0.74.1:
+  * Update syft bootstrap tools to latest versions. (#1658)
+  * fix: improved Python binary detection (#1648)
+  * fix: suppress some known incorrect vendor candidates for npm
+    CPEs (#1659)
+  * fix: sanitize SPDX LicenseRefs (#1657)
+  * chore(deps): bump golang.org/x/mod from 0.8.0 to 0.9.0 (#1655)
+  * chore(deps): bump golang.org/x/net from 0.7.0 to 0.8.0 (#1653)
+  * chore(deps): bump github.com/spf13/afero from 1.9.4 to 1.9.5
+    (#1654)
+  * chore(deps): bump golang.org/x/term from 0.5.0 to 0.6.0 (#1656)
+  * fix: dotnet PURL types are invalid (#1649)
+  * feat: disable cpe vendor wildcards to reduce false positives
+    (#1647)
+  * read relative etc/apk/repositories for alpine version when no
+    OS provided (#1615)
+
+-------------------------------------------------------------------

Old:
----
  syft-0.74.0.tar.gz

New:
----
  syft-0.74.1.tar.gz

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

Other differences:
------------------
++++++ syft.spec ++++++
--- /var/tmp/diff_new_pack.H5okv1/_old  2023-03-10 22:07:32.901178507 +0100
+++ /var/tmp/diff_new_pack.H5okv1/_new  2023-03-10 22:07:32.905178525 +0100
@@ -19,7 +19,7 @@
 %define __arch_install_post export NO_BRP_STRIP_DEBUG=true
 
 Name:           syft
-Version:        0.74.0
+Version:        0.74.1
 Release:        0
 Summary:        CLI tool and library for generating a Software Bill of 
Materials
 License:        Apache-2.0

++++++ _service ++++++
--- /var/tmp/diff_new_pack.H5okv1/_old  2023-03-10 22:07:32.949178725 +0100
+++ /var/tmp/diff_new_pack.H5okv1/_new  2023-03-10 22:07:32.953178744 +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">v0.74.0</param>
+    <param name="revision">v0.74.1</param>
     <param name="versionformat">@PARENT_TAG@</param>
     <param name="changesgenerate">enable</param>
     <param name="versionrewrite-pattern">v(.*)</param>
@@ -16,7 +16,7 @@
     <param name="compression">gz</param>
   </service>
   <service name="go_modules" mode="disabled">
-    <param name="archive">syft-0.74.0.tar.gz</param>
+    <param name="archive">syft-0.74.1.tar.gz</param>
   </service>
 </services>
 

++++++ _servicedata ++++++
--- /var/tmp/diff_new_pack.H5okv1/_old  2023-03-10 22:07:32.981178871 +0100
+++ /var/tmp/diff_new_pack.H5okv1/_new  2023-03-10 22:07:32.981178871 +0100
@@ -1,6 +1,6 @@
 <servicedata>
 <service name="tar_scm">
                 <param name="url">https://github.com/anchore/syft</param>
-              <param 
name="changesrevision">5f90d0371873faf5eb8f2e748909b32294be6263</param></service></servicedata>
+              <param 
name="changesrevision">41cbbe09b205e3b80e8a57d4f7a509b5f938557d</param></service></servicedata>
 (No newline at EOF)
 

++++++ syft-0.74.0.tar.gz -> syft-0.74.1.tar.gz ++++++
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/syft-0.74.0/.github/workflows/validations.yaml 
new/syft-0.74.1/.github/workflows/validations.yaml
--- old/syft-0.74.0/.github/workflows/validations.yaml  2023-03-01 
21:35:01.000000000 +0100
+++ new/syft-0.74.1/.github/workflows/validations.yaml  2023-03-07 
18:54:32.000000000 +0100
@@ -54,6 +54,13 @@
           path: syft/pkg/cataloger/golang/test-fixtures/archs/binaries
           key: ${{ runner.os }}-unit-go-binaries-cache-${{ hashFiles( 
'syft/pkg/cataloger/golang/test-fixtures/archs/binaries.fingerprint' ) }}
 
+      - name: Restore binary cataloger test-fixture cache
+        id: unit-binary-cataloger-cache
+        uses: actions/cache@v3
+        with:
+          path: syft/pkg/cataloger/binary/test-fixtures/classifiers/dynamic
+          key: ${{ runner.os }}-unit-binary-cataloger-cache-${{ hashFiles( 
'syft/pkg/cataloger/binary/test-fixtures/cache.fingerprint' ) }}
+
       - name: Run unit tests
         run: make unit
 
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/syft-0.74.0/Makefile new/syft-0.74.1/Makefile
--- old/syft-0.74.0/Makefile    2023-03-01 21:35:01.000000000 +0100
+++ new/syft-0.74.1/Makefile    2023-03-07 18:54:32.000000000 +0100
@@ -14,7 +14,7 @@
 GOSIMPORTS_VERSION := v0.3.7
 BOUNCER_VERSION := v0.4.0
 CHRONICLE_VERSION := v0.6.0
-GORELEASER_VERSION := v1.15.2
+GORELEASER_VERSION := v1.16.0
 YAJSV_VERSION := v1.4.1
 COSIGN_VERSION := v1.13.1
 QUILL_VERSION := v0.2.0
@@ -189,6 +189,10 @@
        cd test/integration/test-fixtures && \
                make cache.fingerprint
 
+       # for BINARY test fixtures
+       cd syft/pkg/cataloger/binary/test-fixtures && \
+               make cache.fingerprint
+
        # for JAVA BUILD test fixtures
        cd syft/pkg/cataloger/java/test-fixtures/java-builds && \
                make packages.fingerprint
@@ -214,6 +218,7 @@
        $(call title,Generating test fixtures)
        cd syft/pkg/cataloger/java/test-fixtures/java-builds && make
        cd syft/pkg/cataloger/rpm/test-fixtures && make
+       cd syft/pkg/cataloger/binary/test-fixtures && make
 
 .PHONY: show-test-image-cache
 show-test-image-cache:  ## Show all docker and image tar cache
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/syft-0.74.0/go.mod new/syft-0.74.1/go.mod
--- old/syft-0.74.0/go.mod      2023-03-01 21:35:01.000000000 +0100
+++ new/syft-0.74.1/go.mod      2023-03-07 18:54:32.000000000 +0100
@@ -32,7 +32,7 @@
        github.com/sergi/go-diff v1.3.1
        github.com/sirupsen/logrus v1.9.0
        github.com/spdx/tools-golang v0.5.0-rc1
-       github.com/spf13/afero v1.9.4
+       github.com/spf13/afero v1.9.5
        github.com/spf13/cobra v1.6.1
        github.com/spf13/pflag v1.0.5
        github.com/spf13/viper v1.15.0
@@ -42,9 +42,9 @@
        github.com/wagoodman/go-progress v0.0.0-20230301185719-21920a456ad5
        github.com/wagoodman/jotframe v0.0.0-20211129225309-56b0d0a4aebb
        github.com/xeipuuv/gojsonschema v1.2.0
-       golang.org/x/mod v0.8.0
-       golang.org/x/net v0.7.0
-       golang.org/x/term v0.5.0
+       golang.org/x/mod v0.9.0
+       golang.org/x/net v0.8.0
+       golang.org/x/term v0.6.0
        gopkg.in/yaml.v2 v2.4.0
 )
 
@@ -126,9 +126,9 @@
        github.com/xi2/xz v0.0.0-20171230120015-48954b6210f8 // indirect
        github.com/xo/terminfo v0.0.0-20210125001918-ca9a967f8778 // indirect
        golang.org/x/sync v0.1.0 // indirect
-       golang.org/x/sys v0.5.0 // indirect
-       golang.org/x/text v0.7.0 // indirect
-       golang.org/x/tools v0.2.0 // indirect
+       golang.org/x/sys v0.6.0 // indirect
+       golang.org/x/text v0.8.0 // indirect
+       golang.org/x/tools v0.6.0 // indirect
        golang.org/x/xerrors v0.0.0-20220907171357-04be3eba64a2 // indirect
        google.golang.org/genproto v0.0.0-20221227171554-f9683d7f8bef // 
indirect
        google.golang.org/grpc v1.52.0 // indirect
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/syft-0.74.0/go.sum new/syft-0.74.1/go.sum
--- old/syft-0.74.0/go.sum      2023-03-01 21:35:01.000000000 +0100
+++ new/syft-0.74.1/go.sum      2023-03-07 18:54:32.000000000 +0100
@@ -519,8 +519,8 @@
 github.com/spdx/tools-golang v0.5.0-rc1/go.mod 
h1:LI6onw172PdO57Ob/hgnLDD4Y2PMnroeNT3wO/2WJJI=
 github.com/spf13/afero v1.3.3/go.mod 
h1:5KUK8ByomD5Ti5Artl0RtHeI5pTF7MIDuXL3yY520V4=
 github.com/spf13/afero v1.6.0/go.mod 
h1:Ai8FlHk4v/PARR026UzYexafAt9roJ7LcLMAmO6Z93I=
-github.com/spf13/afero v1.9.4 h1:Sd43wM1IWz/s1aVXdOBkjJvuP8UdyqioeE4AmM0QsBs=
-github.com/spf13/afero v1.9.4/go.mod 
h1:iUV7ddyEEZPO5gA3zD4fJt6iStLlL+Lg4m2cihcDf8Y=
+github.com/spf13/afero v1.9.5 h1:stMpOSZFs//0Lv29HduCmli3GUfpFoF3Y1Q/aXj/wVM=
+github.com/spf13/afero v1.9.5/go.mod 
h1:UBogFpq8E9Hx+xc5CNTTEpTnuHVmXDwZcZcE1eb/UhQ=
 github.com/spf13/cast v1.3.1/go.mod 
h1:Qx5cxh0v+4UWYiBimWS+eyWzqEqokIECu5etghLkUJE=
 github.com/spf13/cast v1.4.1/go.mod 
h1:Qx5cxh0v+4UWYiBimWS+eyWzqEqokIECu5etghLkUJE=
 github.com/spf13/cast v1.5.0 h1:rj3WzYc11XZaIZMPKmwP96zkFEnnAmV8s6XbB2aY32w=
@@ -627,7 +627,7 @@
 golang.org/x/crypto v0.0.0-20210421170649-83a5a9bb288b/go.mod 
h1:T9bdIzuCu7OtxOm1hfPfRQxPLYneinmdGuTeoZ9dtd4=
 golang.org/x/crypto v0.0.0-20210817164053-32db794688a5/go.mod 
h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc=
 golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod 
h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc=
-golang.org/x/crypto v0.0.0-20211108221036-ceb1ce70b4fa/go.mod 
h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc=
+golang.org/x/crypto v0.0.0-20220722155217-630584e8d5aa/go.mod 
h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4=
 golang.org/x/crypto v0.3.0 h1:a06MkbcxBrEFc0w0QIZWXrH/9cCX6KJyWbBOIwAn+7A=
 golang.org/x/crypto v0.3.0/go.mod 
h1:hebNnKkNXi2UzZN1eVRvBB7co0a+JxK6XbPiWVs/3J4=
 golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod 
h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
@@ -670,8 +670,8 @@
 golang.org/x/mod v0.4.2/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
 golang.org/x/mod v0.5.0/go.mod h1:5OXOZSfqPIIbmVBIIKWRFfZjPR0E5r58TLhUjH0a2Ro=
 golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod 
h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4=
-golang.org/x/mod v0.8.0 h1:LUYupSeNrTNCGzR/hVBk2NHZO4hXcVaW1k4Qx7rjPx8=
-golang.org/x/mod v0.8.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs=
+golang.org/x/mod v0.9.0 h1:KENHtAZL2y3NLMYZeHY9DW8HW8V+kQyJsY/V9JlKvCs=
+golang.org/x/mod v0.9.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs=
 golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod 
h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
 golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod 
h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
 golang.org/x/net v0.0.0-20181023162649-9b4f9f5ad519/go.mod 
h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
@@ -715,10 +715,11 @@
 golang.org/x/net v0.0.0-20210503060351-7fd8e65b6420/go.mod 
h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=
 golang.org/x/net v0.0.0-20210505024714-0287a6fb4125/go.mod 
h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=
 golang.org/x/net v0.0.0-20210813160813-60bc85c4be6d/go.mod 
h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=
+golang.org/x/net v0.0.0-20211112202133-69e39bad7dc2/go.mod 
h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=
 golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod 
h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c=
 golang.org/x/net v0.2.0/go.mod h1:KqCZLdyyvdV855qA2rE3GC2aiw5xGR5TEjj8smXukLY=
-golang.org/x/net v0.7.0 h1:rJrUqqhjsgNp7KqAIc25s9pZnjU7TUcSY7HcVZjdn1g=
-golang.org/x/net v0.7.0/go.mod h1:2Tu9+aMcznHK/AK1HMvgo6xiTLG5rD5rZLDS+rp2Bjs=
+golang.org/x/net v0.8.0 h1:Zrh2ngAOFYneWTAIAPethzeaQLuHwhuBkuV6ZiRnUaQ=
+golang.org/x/net v0.8.0/go.mod h1:QVkue5JL9kW//ek3r6jTKnTFis1tRmNAW2P1shuFdJc=
 golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod 
h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U=
 golang.org/x/oauth2 v0.0.0-20190226205417-e64efc72b421/go.mod 
h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
 golang.org/x/oauth2 v0.0.0-20190604053449-0f29369cfe45/go.mod 
h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
@@ -824,15 +825,15 @@
 golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab/go.mod 
h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
 golang.org/x/sys v0.0.0-20220908164124-27713097b956/go.mod 
h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
 golang.org/x/sys v0.2.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
-golang.org/x/sys v0.5.0 h1:MUK/U/4lj1t1oPg0HfuXDN/Z1wv31ZJ/YcPiGccS4DU=
-golang.org/x/sys v0.5.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
+golang.org/x/sys v0.6.0 h1:MVltZSvRTcU2ljQOhs94SXPftV6DCNnZViHeQps87pQ=
+golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
 golang.org/x/term v0.0.0-20201117132131-f5c789dd3221/go.mod 
h1:Nr5EML6q2oocZ2LXRh80K7BxOlk5/8JxuGnuhpl+muw=
 golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod 
h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
 golang.org/x/term v0.0.0-20210615171337-6886f2dfbf5b/go.mod 
h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8=
 golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod 
h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8=
 golang.org/x/term v0.2.0/go.mod h1:TVmDHMZPmdnySmBfhjOoOdhjzdE1h4u1VwSiw2l1Nuc=
-golang.org/x/term v0.5.0 h1:n2a8QNdAb0sZNpU9R1ALUXBbY+w51fCQDN+7EdxNBsY=
-golang.org/x/term v0.5.0/go.mod h1:jMB1sMXY+tzblOD4FWmEbocvup2/aLOaQEp7JmGp78k=
+golang.org/x/term v0.6.0 h1:clScbb1cHjoCkyRbWwBEUZ5H/tIFu5TAXIqaZD0Gcjw=
+golang.org/x/term v0.6.0/go.mod h1:m6U89DPEgQRMq3DNkDClhWw02AUbt2daBVO4cn4Hv9U=
 golang.org/x/text v0.0.0-20170915032832-14c0d48ead0c/go.mod 
h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
 golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
 golang.org/x/text v0.3.1-0.20180807135948-17ff2d5776d2/go.mod 
h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
@@ -843,8 +844,8 @@
 golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
 golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ=
 golang.org/x/text v0.4.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8=
-golang.org/x/text v0.7.0 h1:4BRB4x83lYWy72KwLD/qYDuTu7q9PjSagHvijDw7cLo=
-golang.org/x/text v0.7.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8=
+golang.org/x/text v0.8.0 h1:57P1ETyNKtuIjB4SRd15iJxuhj8Gc416Y78H3qgMh68=
+golang.org/x/text v0.8.0/go.mod h1:e1OnstbJyHTd6l/uOt8jFFHp6TRDWZR/bV3emEE/zU8=
 golang.org/x/time v0.0.0-20181108054448-85acf8d2951c/go.mod 
h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
 golang.org/x/time v0.0.0-20190308202827-9d24e82272b4/go.mod 
h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
 golang.org/x/time v0.0.0-20191024005414-555d28b269f0/go.mod 
h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
@@ -908,8 +909,8 @@
 golang.org/x/tools v0.1.4/go.mod 
h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk=
 golang.org/x/tools v0.1.5/go.mod 
h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk=
 golang.org/x/tools v0.1.12/go.mod 
h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc=
-golang.org/x/tools v0.2.0 h1:G6AHpWxTMGY1KyEYoAQ5WTtIekUUvDNjan3ugu60JvE=
-golang.org/x/tools v0.2.0/go.mod 
h1:y4OqIKeOV/fWJetJ8bXPU1sEVniLMIyDAZWeHdV+NTA=
+golang.org/x/tools v0.6.0 h1:BOw41kyTf3PuCW1pVQf8+Cyg8pMlkYB1oo9iJ6D/lKM=
+golang.org/x/tools v0.6.0/go.mod 
h1:Xwgl3UAJ/d3gWutnCtw505GrjyAbvKui8lOU390QaIU=
 golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod 
h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
 golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod 
h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
 golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod 
h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/syft-0.74.0/syft/formats/common/spdxhelpers/license.go 
new/syft-0.74.1/syft/formats/common/spdxhelpers/license.go
--- old/syft-0.74.0/syft/formats/common/spdxhelpers/license.go  2023-03-01 
21:35:01.000000000 +0100
+++ new/syft-0.74.1/syft/formats/common/spdxhelpers/license.go  2023-03-07 
18:54:32.000000000 +0100
@@ -24,6 +24,12 @@
        // take all licenses and assume an AND expression; for information 
about license expressions see 
https://spdx.github.io/spdx-spec/appendix-IV-SPDX-license-expressions/
        parsedLicenses := parseLicenses(p.Licenses)
 
+       for i, v := range parsedLicenses {
+               if strings.HasPrefix(v, spdxlicense.LicenseRefPrefix) {
+                       parsedLicenses[i] = SanitizeElementID(v)
+               }
+       }
+
        if len(parsedLicenses) == 0 {
                return NOASSERTION
        }
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/syft-0.74.0/syft/formats/common/spdxhelpers/license_test.go 
new/syft-0.74.1/syft/formats/common/spdxhelpers/license_test.go
--- old/syft-0.74.0/syft/formats/common/spdxhelpers/license_test.go     
2023-03-01 21:35:01.000000000 +0100
+++ new/syft-0.74.1/syft/formats/common/spdxhelpers/license_test.go     
2023-03-07 18:54:32.000000000 +0100
@@ -65,6 +65,17 @@
                        },
                        expected: "GPL-2.0-only",
                },
+               {
+                       name: "includes valid LicenseRef-",
+                       input: pkg.Package{
+                               Licenses: []string{
+                                       "one thing first",
+                                       "two things/#$^second",
+                                       "MIT",
+                               },
+                       },
+                       expected: "LicenseRef-one-thing-first AND 
LicenseRef-two-things----second AND MIT",
+               },
        }
        for _, test := range tests {
                t.Run(test.name, func(t *testing.T) {
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/syft-0.74.0/syft/formats/common/spdxhelpers/to_format_model.go 
new/syft-0.74.1/syft/formats/common/spdxhelpers/to_format_model.go
--- old/syft-0.74.0/syft/formats/common/spdxhelpers/to_format_model.go  
2023-03-01 21:35:01.000000000 +0100
+++ new/syft-0.74.1/syft/formats/common/spdxhelpers/to_format_model.go  
2023-03-07 18:54:32.000000000 +0100
@@ -514,8 +514,8 @@
 
 func toOtherLicenses(catalog *pkg.Catalog) []*spdx.OtherLicense {
        licenses := map[string]bool{}
-       for _, pkg := range catalog.Sorted() {
-               for _, license := range parseLicenses(pkg.Licenses) {
+       for _, p := range catalog.Sorted() {
+               for _, license := range parseLicenses(p.Licenses) {
                        if strings.HasPrefix(license, 
spdxlicense.LicenseRefPrefix) {
                                licenses[license] = true
                        }
@@ -526,7 +526,7 @@
                // separate the actual ID from the prefix
                name := strings.TrimPrefix(license, 
spdxlicense.LicenseRefPrefix)
                result = append(result, &spdx.OtherLicense{
-                       LicenseIdentifier: license,
+                       LicenseIdentifier: SanitizeElementID(license),
                        LicenseName:       name,
                        ExtractedText:     NONE, // we probably should have 
some extracted text here, but this is good enough for now
                })
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/syft-0.74.0/syft/formats/common/spdxhelpers/to_format_model_test.go 
new/syft-0.74.1/syft/formats/common/spdxhelpers/to_format_model_test.go
--- old/syft-0.74.0/syft/formats/common/spdxhelpers/to_format_model_test.go     
2023-03-01 21:35:01.000000000 +0100
+++ new/syft-0.74.1/syft/formats/common/spdxhelpers/to_format_model_test.go     
2023-03-07 18:54:32.000000000 +0100
@@ -369,7 +369,7 @@
 }
 
 func Test_H1Digest(t *testing.T) {
-       sbom := sbom.SBOM{}
+       s := sbom.SBOM{}
        tests := []struct {
                name           string
                pkg            pkg.Package
@@ -416,7 +416,7 @@
        for _, test := range tests {
                t.Run(test.name, func(t *testing.T) {
                        catalog := pkg.NewCatalog(test.pkg)
-                       pkgs := toPackages(catalog, sbom)
+                       pkgs := toPackages(catalog, s)
                        require.Len(t, pkgs, 1)
                        for _, p := range pkgs {
                                if test.expectedDigest == "" {
@@ -431,3 +431,67 @@
                })
        }
 }
+
+func Test_OtherLicenses(t *testing.T) {
+       tests := []struct {
+               name     string
+               pkg      pkg.Package
+               expected []*spdx.OtherLicense
+       }{
+               {
+                       name: "no licenseRef",
+                       pkg: pkg.Package{
+                               Licenses: []string{
+                                       "MIT",
+                               },
+                       },
+                       expected: nil,
+               },
+               {
+                       name: "single licenseRef",
+                       pkg: pkg.Package{
+                               Licenses: []string{
+                                       "un known",
+                               },
+                       },
+                       expected: []*spdx.OtherLicense{
+                               {
+                                       LicenseIdentifier: 
"LicenseRef-un-known",
+                                       LicenseName:       "un known",
+                                       ExtractedText:     NONE,
+                               },
+                       },
+               },
+               {
+                       name: "multiple licenseRef",
+                       pkg: pkg.Package{
+                               Licenses: []string{
+                                       "un known",
+                                       "not known %s",
+                                       "MIT",
+                               },
+                       },
+                       expected: []*spdx.OtherLicense{
+                               {
+                                       LicenseIdentifier: 
"LicenseRef-un-known",
+                                       LicenseName:       "un known",
+                                       ExtractedText:     NONE,
+                               },
+                               {
+                                       LicenseIdentifier: 
"LicenseRef-not-known--s",
+                                       LicenseName:       "not known %s",
+                                       ExtractedText:     NONE,
+                               },
+                       },
+               },
+       }
+
+       for _, test := range tests {
+               t.Run(test.name, func(t *testing.T) {
+                       catalog := pkg.NewCatalog(test.pkg)
+                       otherLicenses := toOtherLicenses(catalog)
+                       require.Len(t, otherLicenses, len(test.expected))
+                       require.Equal(t, test.expected, otherLicenses)
+               })
+       }
+}
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/syft-0.74.0/syft/pkg/cataloger/apkdb/cataloger_test.go 
new/syft-0.74.1/syft/pkg/cataloger/apkdb/cataloger_test.go
--- old/syft-0.74.0/syft/pkg/cataloger/apkdb/cataloger_test.go  2023-03-01 
21:35:01.000000000 +0100
+++ new/syft-0.74.1/syft/pkg/cataloger/apkdb/cataloger_test.go  2023-03-07 
18:54:32.000000000 +0100
@@ -24,6 +24,7 @@
                        pkgtest.NewCatalogTester().
                                FromDirectory(t, test.fixture).
                                ExpectsResolverContentQueries(test.expected).
+                               
IgnoreUnfulfilledPathResponses("etc/apk/repositories").
                                TestCataloger(t, NewApkdbCataloger())
                })
        }
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/syft-0.74.0/syft/pkg/cataloger/apkdb/parse_apk_db.go 
new/syft-0.74.1/syft/pkg/cataloger/apkdb/parse_apk_db.go
--- old/syft-0.74.0/syft/pkg/cataloger/apkdb/parse_apk_db.go    2023-03-01 
21:35:01.000000000 +0100
+++ new/syft-0.74.1/syft/pkg/cataloger/apkdb/parse_apk_db.go    2023-03-07 
18:54:32.000000000 +0100
@@ -3,7 +3,9 @@
 import (
        "bufio"
        "fmt"
+       "io"
        "path"
+       "regexp"
        "strconv"
        "strings"
 
@@ -20,11 +22,15 @@
 // integrity check
 var _ generic.Parser = parseApkDB
 
+var (
+       repoRegex = 
regexp.MustCompile(`(?m)^https://.*\.alpinelinux\.org/alpine/v([^/]+)/([a-zA-Z0-9_]+)$`)
+)
+
 // parseApkDB parses packages from a given APK installed DB file. For more
 // information on specific fields, see 
https://wiki.alpinelinux.org/wiki/Apk_spec.
 //
-//nolint:funlen
-func parseApkDB(_ source.FileResolver, env *generic.Environment, reader 
source.LocationReadCloser) ([]pkg.Package, []artifact.Relationship, error) {
+//nolint:funlen,gocognit
+func parseApkDB(resolver source.FileResolver, env *generic.Environment, reader 
source.LocationReadCloser) ([]pkg.Package, []artifact.Relationship, error) {
        scanner := bufio.NewScanner(reader)
 
        var apks []pkg.ApkMetadata
@@ -101,6 +107,19 @@
        if env != nil {
                r = env.LinuxRelease
        }
+       // this is somewhat ugly, but better than completely failing when we 
can't find the release,
+       // e.g. embedded deeper in the tree, like containers or chroots.
+       // but we now have no way of handling different repository sources. On 
the other hand,
+       // we never could before this. At least now, we can handle some.
+       // This should get fixed with 
https://gitlab.alpinelinux.org/alpine/apk-tools/-/issues/10875
+       if r == nil {
+               // find the repositories file from the relative directory of 
the DB file
+               releases := findReleases(resolver, reader.Location.RealPath)
+
+               if len(releases) > 0 {
+                       r = &releases[0]
+               }
+       }
 
        pkgs := make([]pkg.Package, 0, len(apks))
        for _, apk := range apks {
@@ -110,6 +129,58 @@
        return pkgs, discoverPackageDependencies(pkgs), nil
 }
 
+func findReleases(resolver source.FileResolver, dbPath string) []linux.Release 
{
+       if resolver == nil {
+               return nil
+       }
+
+       reposLocation := path.Clean(path.Join(path.Dir(dbPath), 
"../../../etc/apk/repositories"))
+       locations, err := resolver.FilesByPath(reposLocation)
+       if err != nil {
+               log.Tracef("unable to find APK repositories file %q: %+v", 
reposLocation, err)
+               return nil
+       }
+
+       if len(locations) == 0 {
+               return nil
+       }
+       location := locations[0]
+
+       reposReader, err := resolver.FileContentsByLocation(location)
+       if err != nil {
+               log.Tracef("unable to fetch contents for APK repositories file 
%q: %+v", reposLocation, err)
+               return nil
+       }
+
+       return parseReleasesFromAPKRepository(source.LocationReadCloser{
+               Location:   location,
+               ReadCloser: reposReader,
+       })
+}
+
+func parseReleasesFromAPKRepository(reader source.LocationReadCloser) 
[]linux.Release {
+       var releases []linux.Release
+
+       reposB, err := io.ReadAll(reader)
+       if err != nil {
+               log.Tracef("unable to read APK repositories file %q: %+v", 
reader.Location.RealPath, err)
+               return nil
+       }
+
+       parts := repoRegex.FindAllStringSubmatch(string(reposB), -1)
+       for _, part := range parts {
+               if len(part) >= 3 {
+                       releases = append(releases, linux.Release{
+                               Name:      "Alpine Linux",
+                               ID:        "alpine",
+                               VersionID: part[1],
+                       })
+               }
+       }
+
+       return releases
+}
+
 func parseApkField(line string) *apkField {
        parts := strings.SplitN(line, ":", 2)
        if len(parts) != 2 {
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/syft-0.74.0/syft/pkg/cataloger/apkdb/parse_apk_db_test.go 
new/syft-0.74.1/syft/pkg/cataloger/apkdb/parse_apk_db_test.go
--- old/syft-0.74.0/syft/pkg/cataloger/apkdb/parse_apk_db_test.go       
2023-03-01 21:35:01.000000000 +0100
+++ new/syft-0.74.1/syft/pkg/cataloger/apkdb/parse_apk_db_test.go       
2023-03-07 18:54:32.000000000 +0100
@@ -1,8 +1,10 @@
 package apkdb
 
 import (
+       "io"
        "os"
        "path/filepath"
+       "strings"
        "testing"
 
        "github.com/google/go-cmp/cmp"
@@ -1186,3 +1188,49 @@
                })
        }
 }
+
+func TestParseReleasesFromAPKRepository(t *testing.T) {
+       tests := []struct {
+               repos string
+               want  []linux.Release
+               desc  string
+       }{
+               {
+                       "https://foo.alpinelinux.org/alpine/v3.14/main";,
+                       []linux.Release{
+                               {Name: "Alpine Linux", ID: "alpine", VersionID: 
"3.14"},
+                       },
+                       "single repo",
+               },
+               {
+                       `https://foo.alpinelinux.org/alpine/v3.14/main
+https://foo.alpinelinux.org/alpine/v3.14/community`,
+                       []linux.Release{
+                               {Name: "Alpine Linux", ID: "alpine", VersionID: 
"3.14"},
+                               {Name: "Alpine Linux", ID: "alpine", VersionID: 
"3.14"},
+                       },
+                       "multiple repos",
+               },
+               {
+                       ``,
+                       nil,
+                       "empty",
+               },
+               {
+                       `https://foo.bar.org/alpine/v3.14/main
+https://foo.them.org/alpine/v3.14/community`,
+                       nil,
+                       "invalid repos",
+               },
+       }
+       for _, tt := range tests {
+               t.Run(tt.desc, func(t *testing.T) {
+                       reposReader := io.NopCloser(strings.NewReader(tt.repos))
+                       got := 
parseReleasesFromAPKRepository(source.LocationReadCloser{
+                               Location:   source.NewLocation("test"),
+                               ReadCloser: reposReader,
+                       })
+                       assert.Equal(t, tt.want, got)
+               })
+       }
+}
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/syft-0.74.0/syft/pkg/cataloger/binary/cataloger.go 
new/syft-0.74.1/syft/pkg/cataloger/binary/cataloger.go
--- old/syft-0.74.0/syft/pkg/cataloger/binary/cataloger.go      2023-03-01 
21:35:01.000000000 +0100
+++ new/syft-0.74.1/syft/pkg/cataloger/binary/cataloger.go      2023-03-07 
18:54:32.000000000 +0100
@@ -74,12 +74,7 @@
                return nil, err
        }
        for _, location := range locations {
-               reader, err := resolver.FileContentsByLocation(location)
-               if err != nil {
-                       return nil, err
-               }
-               locationReader := source.NewLocationReadCloser(location, reader)
-               pkgs, err := cls.EvidenceMatcher(cls, locationReader)
+               pkgs, err := cls.EvidenceMatcher(resolver, cls, location)
                if err != nil {
                        return nil, err
                }
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/syft-0.74.0/syft/pkg/cataloger/binary/cataloger_test.go 
new/syft-0.74.1/syft/pkg/cataloger/binary/cataloger_test.go
--- old/syft-0.74.0/syft/pkg/cataloger/binary/cataloger_test.go 2023-03-01 
21:35:01.000000000 +0100
+++ new/syft-0.74.1/syft/pkg/cataloger/binary/cataloger_test.go 2023-03-07 
18:54:32.000000000 +0100
@@ -4,8 +4,11 @@
        "errors"
        "fmt"
        "io"
+       "strings"
        "testing"
 
+       "github.com/google/go-cmp/cmp"
+       "github.com/google/go-cmp/cmp/cmpopts"
        "github.com/stretchr/testify/assert"
        "github.com/stretchr/testify/require"
 
@@ -69,25 +72,6 @@
                        },
                },
                {
-                       name:       "positive-python-duplicates",
-                       fixtureDir: 
"test-fixtures/classifiers/positive/python-duplicates",
-                       expected: pkg.Package{
-                               Name:      "python",
-                               Version:   "3.8.16",
-                               Type:      "binary",
-                               PURL:      "pkg:generic/python@3.8.16",
-                               Locations: locations("dir/python3.8", 
"python3.8", "libpython3.8.so", "patchlevel.h"),
-                               Metadata: pkg.BinaryMetadata{
-                                       Matches: []pkg.ClassifierMatch{
-                                               match("python-binary", 
"dir/python3.8"),
-                                               match("python-binary", 
"python3.8"),
-                                               match("python-binary-lib", 
"libpython3.8.so"),
-                                               match("cpython-source", 
"patchlevel.h"),
-                                       },
-                               },
-                       },
-               },
-               {
                        name:       "positive-traefik-2.9.6",
                        fixtureDir: 
"test-fixtures/classifiers/positive/traefik-2.9.6",
                        expected: pkg.Package{
@@ -315,25 +299,81 @@
                        },
                },
                {
+                       name:       "positive-python-3.11.2-from-shared-lib",
+                       fixtureDir: 
"test-fixtures/classifiers/dynamic/python-binary-shared-lib-3.11",
+                       expected: pkg.Package{
+                               Name:      "python",
+                               Version:   "3.11.2",
+                               PURL:      "pkg:generic/python@3.11.2",
+                               Locations: locations("python3", 
"libpython3.11.so.1.0"),
+                               Metadata: pkg.BinaryMetadata{
+                                       Matches: []pkg.ClassifierMatch{
+                                               match("python-binary", 
"python3"),
+                                               match("python-binary", 
"libpython3.11.so.1.0"),
+                                               match("python-binary-lib", 
"libpython3.11.so.1.0"),
+                                       },
+                               },
+                       },
+               },
+               {
+                       name:       
"positive-python-3.9-from-shared-redhat-lib",
+                       fixtureDir: 
"test-fixtures/classifiers/dynamic/python-binary-shared-lib-redhat-3.9",
+                       expected: pkg.Package{
+                               Name:      "python",
+                               Version:   "3.9.13",
+                               PURL:      "pkg:generic/python@3.9.13",
+                               Locations: locations("python3.9", 
"libpython3.9.so.1.0"),
+                               Metadata: pkg.BinaryMetadata{
+                                       Matches: []pkg.ClassifierMatch{
+                                               match("python-binary", 
"python3.9"),
+                                               match("python-binary", 
"libpython3.9.so.1.0"),
+                                               match("python-binary-lib", 
"libpython3.9.so.1.0"),
+                                       },
+                               },
+                       },
+               },
+               {
+                       name:       "positive-python-binary-with-version-3.9",
+                       fixtureDir: 
"test-fixtures/classifiers/dynamic/python-binary-with-version-3.9",
+                       expected: pkg.Package{
+                               Name:      "python",
+                               Version:   "3.9.2",
+                               PURL:      "pkg:generic/python@3.9.2",
+                               Locations: locations("python3.9"),
+                               Metadata: pkg.BinaryMetadata{
+                                       Matches: []pkg.ClassifierMatch{
+                                               match("python-binary", 
"python3.9"),
+                                       },
+                               },
+                       },
+               },
+               {
                        name:       "positive-python3.6",
                        fixtureDir: 
"test-fixtures/classifiers/positive/python-binary-3.6",
                        expected: pkg.Package{
                                Name:      "python",
-                               Version:   "3.6.3a-vZ9",
-                               PURL:      "pkg:generic/python@3.6.3a-vZ9",
+                               Version:   "3.6.3",
+                               PURL:      "pkg:generic/python@3.6.3",
                                Locations: locations("python3.6"),
                                Metadata:  metadata("python-binary"),
                        },
                },
                {
-                       name:       "positive-patchlevel.h",
-                       fixtureDir: 
"test-fixtures/classifiers/positive/python-source-3.9",
+                       name:       "positive-python-duplicates",
+                       fixtureDir: 
"test-fixtures/classifiers/positive/python-duplicates",
                        expected: pkg.Package{
                                Name:      "python",
-                               Version:   "3.9-aZ5",
-                               PURL:      "pkg:generic/python@3.9-aZ5",
-                               Locations: locations("patchlevel.h"),
-                               Metadata:  metadata("cpython-source"),
+                               Version:   "3.8.16",
+                               Type:      "binary",
+                               PURL:      "pkg:generic/python@3.8.16",
+                               Locations: locations("dir/python3.8", 
"python3.8", "libpython3.8.so"),
+                               Metadata: pkg.BinaryMetadata{
+                                       Matches: []pkg.ClassifierMatch{
+                                               match("python-binary", 
"dir/python3.8"),
+                                               match("python-binary", 
"python3.8"),
+                                               match("python-binary-lib", 
"libpython3.8.so"),
+                                       },
+                               },
                        },
                },
                {
@@ -491,17 +531,6 @@
                        require.NoError(t, err)
 
                        for _, p := range packages {
-                               expectedLocations := 
test.expected.Locations.ToSlice()
-                               gotLocations := p.Locations.ToSlice()
-                               require.Len(t, gotLocations, 
len(expectedLocations))
-
-                               for i, expectedLocation := range 
expectedLocations {
-                                       gotLocation := gotLocations[i]
-                                       if expectedLocation.RealPath != 
gotLocation.RealPath {
-                                               t.Fatalf("locations do not 
match; expected: %v got: %v", expectedLocations, gotLocations)
-                                       }
-                               }
-
                                assertPackagesAreEqual(t, test.expected, p)
                        }
                })
@@ -611,6 +640,21 @@
 }
 
 func assertPackagesAreEqual(t *testing.T, expected pkg.Package, p pkg.Package) 
{
+       var failMessages []string
+       expectedLocations := expected.Locations.ToSlice()
+       gotLocations := p.Locations.ToSlice()
+
+       if len(expectedLocations) != len(gotLocations) {
+               failMessages = append(failMessages, "locations are not equal 
length")
+       } else {
+               for i, expectedLocation := range expectedLocations {
+                       gotLocation := gotLocations[i]
+                       if expectedLocation.RealPath != gotLocation.RealPath {
+                               failMessages = append(failMessages, 
fmt.Sprintf("locations do not match; expected: %v got: %v", 
expectedLocation.RealPath, gotLocation.RealPath))
+                       }
+               }
+       }
+
        m1 := expected.Metadata.(pkg.BinaryMetadata).Matches
        m2 := p.Metadata.(pkg.BinaryMetadata).Matches
        matches := true
@@ -633,17 +677,26 @@
        } else {
                matches = false
        }
+
+       if !matches {
+               failMessages = append(failMessages, "classifier matches not 
equal")
+       }
        if expected.Name != p.Name ||
                expected.Version != p.Version ||
-               expected.PURL != p.PURL ||
-               !matches {
-               assert.Failf(t, "packages not equal", "%v != %v", 
stringifyPkg(expected), stringifyPkg(p))
+               expected.PURL != p.PURL {
+               failMessages = append(failMessages, "packages do not match")
        }
-}
 
-func stringifyPkg(p pkg.Package) string {
-       matches := p.Metadata.(pkg.BinaryMetadata).Matches
-       return fmt.Sprintf("(name=%s, version=%s, purl=%s, matches=%+v)", 
p.Name, p.Version, p.PURL, matches)
+       if len(failMessages) > 0 {
+               assert.Failf(t, strings.Join(failMessages, "; "), "diff: %s",
+                       cmp.Diff(expected, p,
+                               cmp.Transformer("Locations", func(l 
source.LocationSet) []source.Location {
+                                       return l.ToSlice()
+                               }),
+                               cmpopts.IgnoreUnexported(pkg.Package{}, 
source.Location{}),
+                               cmpopts.IgnoreFields(pkg.Package{}, "CPEs", 
"FoundBy", "MetadataType", "Type"),
+                       ))
+       }
 }
 
 type panicyResolver struct {
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/syft-0.74.0/syft/pkg/cataloger/binary/classifier.go 
new/syft-0.74.1/syft/pkg/cataloger/binary/classifier.go
--- old/syft-0.74.0/syft/pkg/cataloger/binary/classifier.go     2023-03-01 
21:35:01.000000000 +0100
+++ new/syft-0.74.1/syft/pkg/cataloger/binary/classifier.go     2023-03-07 
18:54:32.000000000 +0100
@@ -2,6 +2,9 @@
 
 import (
        "bytes"
+       "debug/elf"
+       "debug/macho"
+       "debug/pe"
        "fmt"
        "io"
        "reflect"
@@ -10,6 +13,7 @@
 
        "github.com/anchore/packageurl-go"
        "github.com/anchore/syft/internal"
+       "github.com/anchore/syft/internal/log"
        "github.com/anchore/syft/syft/cpe"
        "github.com/anchore/syft/syft/pkg"
        "github.com/anchore/syft/syft/pkg/cataloger/internal/unionreader"
@@ -49,12 +53,12 @@
 }
 
 // evidenceMatcher is a function called to catalog Packages that match some 
sort of evidence
-type evidenceMatcher func(classifier classifier, reader 
source.LocationReadCloser) ([]pkg.Package, error)
+type evidenceMatcher func(resolver source.FileResolver, classifier classifier, 
location source.Location) ([]pkg.Package, error)
 
 func evidenceMatchers(matchers ...evidenceMatcher) evidenceMatcher {
-       return func(classifier classifier, reader source.LocationReadCloser) 
([]pkg.Package, error) {
+       return func(resolver source.FileResolver, classifier classifier, 
location source.Location) ([]pkg.Package, error) {
                for _, matcher := range matchers {
-                       match, err := matcher(classifier, reader)
+                       match, err := matcher(resolver, classifier, location)
                        if err != nil {
                                return nil, err
                        }
@@ -68,12 +72,12 @@
 
 func fileNameTemplateVersionMatcher(fileNamePattern string, contentTemplate 
string) evidenceMatcher {
        pat := regexp.MustCompile(fileNamePattern)
-       return func(classifier classifier, reader source.LocationReadCloser) 
([]pkg.Package, error) {
-               if !pat.MatchString(reader.RealPath) {
+       return func(resolver source.FileResolver, classifier classifier, 
location source.Location) ([]pkg.Package, error) {
+               if !pat.MatchString(location.RealPath) {
                        return nil, nil
                }
 
-               filepathNamedGroupValues := 
internal.MatchNamedCaptureGroups(pat, reader.RealPath)
+               filepathNamedGroupValues := 
internal.MatchNamedCaptureGroups(pat, location.RealPath)
 
                tmpl, err := template.New("").Parse(contentTemplate)
                if err != nil {
@@ -91,26 +95,70 @@
                        return nil, fmt.Errorf("unable to compile rendered 
regex=%q: %w", patternBuf.String(), err)
                }
 
-               contents, err := getContents(reader)
+               contents, err := getContents(resolver, location)
                if err != nil {
                        return nil, fmt.Errorf("unable to get read contents for 
file: %w", err)
                }
 
                matchMetadata := internal.MatchNamedCaptureGroups(tmplPattern, 
string(contents))
-               return singlePackage(classifier, reader, matchMetadata), nil
+               return singlePackage(classifier, location, matchMetadata), nil
        }
 }
 
 func fileContentsVersionMatcher(pattern string) evidenceMatcher {
        pat := regexp.MustCompile(pattern)
-       return func(classifier classifier, reader source.LocationReadCloser) 
([]pkg.Package, error) {
-               contents, err := getContents(reader)
+       return func(resolver source.FileResolver, classifier classifier, 
location source.Location) ([]pkg.Package, error) {
+               contents, err := getContents(resolver, location)
                if err != nil {
                        return nil, fmt.Errorf("unable to get read contents for 
file: %w", err)
                }
 
                matchMetadata := internal.MatchNamedCaptureGroups(pat, 
string(contents))
-               return singlePackage(classifier, reader, matchMetadata), nil
+               return singlePackage(classifier, location, matchMetadata), nil
+       }
+}
+
+//nolint:gocognit
+func sharedLibraryLookup(sharedLibraryPattern string, sharedLibraryMatcher 
evidenceMatcher) evidenceMatcher {
+       pat := regexp.MustCompile(sharedLibraryPattern)
+       return func(resolver source.FileResolver, classifier classifier, 
location source.Location) (packages []pkg.Package, _ error) {
+               libs, err := sharedLibraries(resolver, location)
+               if err != nil {
+                       return nil, err
+               }
+               for _, lib := range libs {
+                       if !pat.MatchString(lib) {
+                               continue
+                       }
+
+                       locations, err := resolver.FilesByGlob("**/" + lib)
+                       if err != nil {
+                               return nil, err
+                       }
+                       for _, libraryLication := range locations {
+                               pkgs, err := sharedLibraryMatcher(resolver, 
classifier, libraryLication)
+                               if err != nil {
+                                       return nil, err
+                               }
+                               for _, p := range pkgs {
+                                       // set the source binary as the first 
location
+                                       locationSet := 
source.NewLocationSet(location)
+                                       
locationSet.Add(p.Locations.ToSlice()...)
+                                       p.Locations = locationSet
+                                       meta, _ := 
p.Metadata.(pkg.BinaryMetadata)
+                                       p.Metadata = pkg.BinaryMetadata{
+                                               Matches: 
append([]pkg.ClassifierMatch{
+                                                       {
+                                                               Classifier: 
classifier.Class,
+                                                               Location:   
location,
+                                                       },
+                                               }, meta.Matches...),
+                                       }
+                                       packages = append(packages, p)
+                               }
+                       }
+               }
+               return packages, nil
        }
 }
 
@@ -122,7 +170,7 @@
        return p
 }
 
-func singlePackage(classifier classifier, reader source.LocationReadCloser, 
matchMetadata map[string]string) []pkg.Package {
+func singlePackage(classifier classifier, location source.Location, 
matchMetadata map[string]string) []pkg.Package {
        version, ok := matchMetadata["version"]
        if !ok {
                return nil
@@ -140,7 +188,7 @@
        p := pkg.Package{
                Name:         classifier.Package,
                Version:      version,
-               Locations:    source.NewLocationSet(reader.Location),
+               Locations:    source.NewLocationSet(location),
                Type:         pkg.BinaryPkg,
                CPEs:         cpes,
                FoundBy:      catalogerName,
@@ -149,7 +197,7 @@
                        Matches: []pkg.ClassifierMatch{
                                {
                                        Classifier: classifier.Class,
-                                       Location:   reader.Location,
+                                       Location:   location,
                                },
                        },
                },
@@ -174,8 +222,13 @@
        return []pkg.Package{p}
 }
 
-func getContents(reader source.LocationReadCloser) ([]byte, error) {
-       unionReader, err := unionreader.GetUnionReader(reader.ReadCloser)
+func getContents(resolver source.FileResolver, location source.Location) 
([]byte, error) {
+       reader, err := resolver.FileContentsByLocation(location)
+       if err != nil {
+               return nil, err
+       }
+
+       unionReader, err := unionreader.GetUnionReader(reader)
        if err != nil {
                return nil, fmt.Errorf("unable to get union reader for file: 
%w", err)
        }
@@ -195,3 +248,43 @@
                cpe.Must(cpeString),
        }
 }
+
+// sharedLibraries returns a list of all shared libraries found within a 
binary, currently
+// supporting: elf, macho, and windows pe
+func sharedLibraries(resolver source.FileResolver, location source.Location) 
([]string, error) {
+       contents, err := getContents(resolver, location)
+       if err != nil {
+               return nil, err
+       }
+
+       r := bytes.NewReader(contents)
+
+       e, _ := elf.NewFile(r)
+       if e != nil {
+               symbols, err := e.ImportedLibraries()
+               if err != nil {
+                       log.Debugf("unable to read elf binary at: %s -- %s", 
location.RealPath, err)
+               }
+               return symbols, nil
+       }
+
+       m, _ := macho.NewFile(r)
+       if m != nil {
+               symbols, err := m.ImportedLibraries()
+               if err != nil {
+                       log.Debugf("unable to read macho binary at: %s -- %s", 
location.RealPath, err)
+               }
+               return symbols, nil
+       }
+
+       p, _ := pe.NewFile(r)
+       if p != nil {
+               symbols, err := p.ImportedLibraries()
+               if err != nil {
+                       log.Debugf("unable to read pe binary at: %s -- %s", 
location.RealPath, err)
+               }
+               return symbols, nil
+       }
+
+       return nil, nil
+}
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/syft-0.74.0/syft/pkg/cataloger/binary/classifier_test.go 
new/syft-0.74.1/syft/pkg/cataloger/binary/classifier_test.go
--- old/syft-0.74.0/syft/pkg/cataloger/binary/classifier_test.go        
2023-03-01 21:35:01.000000000 +0100
+++ new/syft-0.74.1/syft/pkg/cataloger/binary/classifier_test.go        
2023-03-07 18:54:32.000000000 +0100
@@ -67,10 +67,8 @@
                        locations, err := resolver.FilesByPath(test.fixture)
                        require.NoError(t, err)
                        require.Len(t, locations, 1)
-                       location := locations[0]
-                       readCloser, err := 
resolver.FileContentsByLocation(location)
-                       require.NoError(t, err)
-                       pkgs, err := 
test.classifier.EvidenceMatcher(test.classifier, 
source.NewLocationReadCloser(location, readCloser))
+
+                       pkgs, err := test.classifier.EvidenceMatcher(resolver, 
test.classifier, locations[0])
                        require.NoError(t, err)
 
                        require.Len(t, pkgs, 1)
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/syft-0.74.0/syft/pkg/cataloger/binary/default_classifiers.go 
new/syft-0.74.1/syft/pkg/cataloger/binary/default_classifiers.go
--- old/syft-0.74.0/syft/pkg/cataloger/binary/default_classifiers.go    
2023-03-01 21:35:01.000000000 +0100
+++ new/syft-0.74.1/syft/pkg/cataloger/binary/default_classifiers.go    
2023-03-07 18:54:32.000000000 +0100
@@ -9,22 +9,16 @@
        {
                Class:    "python-binary",
                FileGlob: "**/python*",
-               EvidenceMatcher: fileNameTemplateVersionMatcher(
-                       `(.*/|^)python(?P<version>[0-9]+\.[0-9]+)$`,
-                       `(?m)(?P<version>{{ .version 
}}\.[0-9]+[-_a-zA-Z0-9]*)`),
-               Package: "python",
-               PURL:    mustPURL("pkg:generic/python@version"),
-               CPEs: []cpe.CPE{
-                       
cpe.Must("cpe:2.3:a:python_software_foundation:python:*:*:*:*:*:*:*:*"),
-                       cpe.Must("cpe:2.3:a:python:python:*:*:*:*:*:*:*:*"),
-               },
-       },
-       {
-               Class:    "python-binary-lib",
-               FileGlob: "**/libpython*.so*",
-               EvidenceMatcher: fileNameTemplateVersionMatcher(
-                       `(.*/|^)libpython(?P<version>[0-9]+\.[0-9]+).so.*$`,
-                       `(?m)(?P<version>{{ .version 
}}\.[0-9]+[-_a-zA-Z0-9]*)`),
+               EvidenceMatcher: evidenceMatchers(
+                       // try to find version information from libpython 
shared libraries
+                       sharedLibraryLookup(
+                               `^libpython[0-9]+(?:\.[0-9]+)+\.so.*$`,
+                               libpythonMatcher),
+                       // check for version information in the binary
+                       fileNameTemplateVersionMatcher(
+                               
`(?:.*/|^)python(?P<version>[0-9]+(?:\.[0-9]+)+)$`,
+                               pythonVersionTemplate),
+               ),
                Package: "python",
                PURL:    mustPURL("pkg:generic/python@version"),
                CPEs: []cpe.CPE{
@@ -33,12 +27,11 @@
                },
        },
        {
-               Class:    "cpython-source",
-               FileGlob: "**/patchlevel.h",
-               EvidenceMatcher: fileContentsVersionMatcher(
-                       
`(?m)#define\s+PY_VERSION\s+"?(?P<version>[0-9\.\-_a-zA-Z]+)"?`),
-               Package: "python",
-               PURL:    mustPURL("pkg:generic/python@version"),
+               Class:           "python-binary-lib",
+               FileGlob:        "**/libpython*.so*",
+               EvidenceMatcher: libpythonMatcher,
+               Package:         "python",
+               PURL:            mustPURL("pkg:generic/python@version"),
                CPEs: []cpe.CPE{
                        
cpe.Must("cpe:2.3:a:python_software_foundation:python:*:*:*:*:*:*:*:*"),
                        cpe.Must("cpe:2.3:a:python:python:*:*:*:*:*:*:*:*"),
@@ -228,3 +221,11 @@
                CPEs:    singleCPE("cpe:2.3:a:rust-lang:rust:*:*:*:*:*:*:*:*"),
        },
 }
+
+// in both binaries and shared libraries, the version pattern is 
[NUL]3.11.2[NUL]
+var pythonVersionTemplate = `(?m)\x00(?P<version>{{ .version 
}}[-._a-zA-Z0-9]*)\x00`
+
+var libpythonMatcher = fileNameTemplateVersionMatcher(
+       `(?:.*/|^)libpython(?P<version>[0-9]+(?:\.[0-9]+)+)\.so.*$`,
+       pythonVersionTemplate,
+)
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/syft-0.74.0/syft/pkg/cataloger/binary/test-fixtures/.gitignore 
new/syft-0.74.1/syft/pkg/cataloger/binary/test-fixtures/.gitignore
--- old/syft-0.74.0/syft/pkg/cataloger/binary/test-fixtures/.gitignore  
1970-01-01 01:00:00.000000000 +0100
+++ new/syft-0.74.1/syft/pkg/cataloger/binary/test-fixtures/.gitignore  
2023-03-07 18:54:32.000000000 +0100
@@ -0,0 +1 @@
+classifiers/dynamic
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/syft-0.74.0/syft/pkg/cataloger/binary/test-fixtures/Makefile 
new/syft-0.74.1/syft/pkg/cataloger/binary/test-fixtures/Makefile
--- old/syft-0.74.0/syft/pkg/cataloger/binary/test-fixtures/Makefile    
1970-01-01 01:00:00.000000000 +0100
+++ new/syft-0.74.1/syft/pkg/cataloger/binary/test-fixtures/Makefile    
2023-03-07 18:54:32.000000000 +0100
@@ -0,0 +1,38 @@
+.PHONY: all
+all: \
+       classifiers/dynamic/python-binary-shared-lib-3.11 \
+       classifiers/dynamic/python-binary-shared-lib-redhat-3.9 \
+       classifiers/dynamic/python-binary-with-version-3.9
+
+classifiers/dynamic/python-binary-shared-lib-3.11:
+       $(eval $@_image := 
"python:3.11-slim@sha256:0b106e1d2bf485c2a41474bc9cd5103e9eea4e179f40f10741b53b127059221e")
+       ./get-image-file.sh $($@_image) \
+               /usr/local/bin/python3.11 \
+               $@/python3
+       ./get-image-file.sh $($@_image) \
+               /usr/local/lib/libpython3.11.so.1.0 \
+               $@/libpython3.11.so.1.0
+
+classifiers/dynamic/python-binary-shared-lib-redhat-3.9:
+       $(eval $@_image := 
"registry.access.redhat.com/ubi8/python-39@sha256:f3cf958b96ce016b63e3e163e488f52e42891304dafef5a0811563f22e3cbad0")
+       ./get-image-file.sh $($@_image) \
+               /usr/bin/python3.9 \
+               $@/python3.9
+       ./get-image-file.sh $($@_image) \
+               /usr/lib64/libpython3.9.so.1.0 \
+               $@/libpython3.9.so.1.0
+
+classifiers/dynamic/python-binary-with-version-3.9:
+       $(eval $@_image := 
"python:3.9.16-bullseye@sha256:93fb93c461a2e47a2176706fad1f39eaacd5dd40e19c0b018699a28c03eb2e2a")
+       ./get-image-file.sh $($@_image) \
+               /usr/bin/python3.9 \
+               $@/python3.9
+
+.PHONY: clean
+clean:
+       rm -rf classifiers/dynamic
+
+.PHONY: cache.fingerprint
+cache.fingerprint: # for CI
+       $(title,Install test fixture fingerprint)
+       @find ./classifiers/dynamic/* -type f -exec md5sum {} + | awk '{print 
$1}' | sort | tee /dev/stderr | md5sum | tee cache.fingerprint >> 
cache.fingerprint
Binary files 
old/syft-0.74.0/syft/pkg/cataloger/binary/test-fixtures/classifiers/positive/python-binary-3.6/python3.6
 and 
new/syft-0.74.1/syft/pkg/cataloger/binary/test-fixtures/classifiers/positive/python-binary-3.6/python3.6
 differ
Binary files 
old/syft-0.74.0/syft/pkg/cataloger/binary/test-fixtures/classifiers/positive/python-duplicates/dir/python3.8
 and 
new/syft-0.74.1/syft/pkg/cataloger/binary/test-fixtures/classifiers/positive/python-duplicates/dir/python3.8
 differ
Binary files 
old/syft-0.74.0/syft/pkg/cataloger/binary/test-fixtures/classifiers/positive/python-duplicates/libpython3.8.so
 and 
new/syft-0.74.1/syft/pkg/cataloger/binary/test-fixtures/classifiers/positive/python-duplicates/libpython3.8.so
 differ
Binary files 
old/syft-0.74.0/syft/pkg/cataloger/binary/test-fixtures/classifiers/positive/python-duplicates/python3.8
 and 
new/syft-0.74.1/syft/pkg/cataloger/binary/test-fixtures/classifiers/positive/python-duplicates/python3.8
 differ
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/syft-0.74.0/syft/pkg/cataloger/binary/test-fixtures/classifiers/positive/python-source-3.9/patchlevel.h
 
new/syft-0.74.1/syft/pkg/cataloger/binary/test-fixtures/classifiers/positive/python-source-3.9/patchlevel.h
--- 
old/syft-0.74.0/syft/pkg/cataloger/binary/test-fixtures/classifiers/positive/python-source-3.9/patchlevel.h
 2023-03-01 21:35:01.000000000 +0100
+++ 
new/syft-0.74.1/syft/pkg/cataloger/binary/test-fixtures/classifiers/positive/python-source-3.9/patchlevel.h
 1970-01-01 01:00:00.000000000 +0100
@@ -1,7 +0,0 @@
-# note: this SHOULD match as python 3.9
-
-some source code...
-
-#define    PY_VERSION   3.9-aZ5
-
-more source!
\ No newline at end of file
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/syft-0.74.0/syft/pkg/cataloger/binary/test-fixtures/get-image-file.sh 
new/syft-0.74.1/syft/pkg/cataloger/binary/test-fixtures/get-image-file.sh
--- old/syft-0.74.0/syft/pkg/cataloger/binary/test-fixtures/get-image-file.sh   
1970-01-01 01:00:00.000000000 +0100
+++ new/syft-0.74.1/syft/pkg/cataloger/binary/test-fixtures/get-image-file.sh   
2023-03-07 18:54:32.000000000 +0100
@@ -0,0 +1,15 @@
+#!/usr/bin/env bash
+set -uxe
+
+CTRID=$(docker create $1)
+
+function cleanup() {
+  docker rm "${CTRID}"
+}
+
+trap cleanup EXIT
+set +e
+
+mkdir -p $(dirname $3)
+
+docker cp ${CTRID}:$2 $3
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/syft-0.74.0/syft/pkg/cataloger/common/cpe/candidate_by_package_type.go 
new/syft-0.74.1/syft/pkg/cataloger/common/cpe/candidate_by_package_type.go
--- old/syft-0.74.0/syft/pkg/cataloger/common/cpe/candidate_by_package_type.go  
2023-03-01 21:35:01.000000000 +0100
+++ new/syft-0.74.1/syft/pkg/cataloger/common/cpe/candidate_by_package_type.go  
2023-03-07 18:54:32.000000000 +0100
@@ -350,6 +350,27 @@
                        candidateKey{PkgName: "redis"},
                        candidateRemovals{VendorsToRemove: []string{"redis"}},
                },
+               // NPM packages
+               {
+                       pkg.NpmPkg,
+                       candidateKey{PkgName: "redis"},
+                       candidateRemovals{VendorsToRemove: []string{"redis"}},
+               },
+               {
+                       pkg.NpmPkg,
+                       candidateKey{PkgName: "php"},
+                       candidateRemovals{VendorsToRemove: []string{"php"}},
+               },
+               {
+                       pkg.NpmPkg,
+                       candidateKey{PkgName: "delegate"},
+                       candidateRemovals{VendorsToRemove: 
[]string{"delegate"}},
+               },
+               {
+                       pkg.NpmPkg,
+                       candidateKey{PkgName: "docker"},
+                       candidateRemovals{VendorsToRemove: []string{"docker"}},
+               },
        })
 
 // buildCandidateLookup is a convenience function for creating the 
defaultCandidateAdditions set
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/syft-0.74.0/syft/pkg/cataloger/common/cpe/generate.go 
new/syft-0.74.1/syft/pkg/cataloger/common/cpe/generate.go
--- old/syft-0.74.0/syft/pkg/cataloger/common/cpe/generate.go   2023-03-01 
21:35:01.000000000 +0100
+++ new/syft-0.74.1/syft/pkg/cataloger/common/cpe/generate.go   2023-03-07 
18:54:32.000000000 +0100
@@ -93,13 +93,6 @@
                }
        }
 
-       // some ecosystems do not have enough metadata to determine the vendor 
accurately, in which case we selectively
-       // allow * as a candidate. Note: do NOT allow Java packages to have * 
vendors.
-       switch p.Language {
-       case pkg.Ruby, pkg.JavaScript:
-               vendors.addValue(wfn.Any)
-       }
-
        switch p.MetadataType {
        case pkg.RpmMetadataType:
                vendors.union(candidateVendorsForRPM(p))
@@ -111,8 +104,15 @@
                vendors.union(candidateVendorsForJava(p))
        case pkg.ApkMetadataType:
                vendors.union(candidateVendorsForAPK(p))
+       case pkg.NpmPackageJSONMetadataType:
+               vendors.union(candidateVendorsForJavascript(p))
        }
 
+       // We should no longer be generating vendor candidates with these 
values ["" and "*"]
+       // (since CPEs will match any other value)
+       vendors.removeByValue("")
+       vendors.removeByValue("*")
+
        // try swapping hyphens for underscores, vice versa, and removing 
separators altogether
        addDelimiterVariations(vendors)
 
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/syft-0.74.0/syft/pkg/cataloger/common/cpe/generate_test.go 
new/syft-0.74.1/syft/pkg/cataloger/common/cpe/generate_test.go
--- old/syft-0.74.0/syft/pkg/cataloger/common/cpe/generate_test.go      
2023-03-01 21:35:01.000000000 +0100
+++ new/syft-0.74.1/syft/pkg/cataloger/common/cpe/generate_test.go      
2023-03-07 18:54:32.000000000 +0100
@@ -117,15 +117,20 @@
                {
                        name: "javascript language",
                        p: pkg.Package{
-                               Name:     "name",
-                               Version:  "3.2",
-                               FoundBy:  "some-analyzer",
-                               Language: pkg.JavaScript,
-                               Type:     pkg.DebPkg,
+                               Name:         "name",
+                               Version:      "3.2",
+                               FoundBy:      "some-analyzer",
+                               Language:     pkg.JavaScript,
+                               MetadataType: pkg.NpmPackageJSONMetadataType,
+                               Metadata: pkg.NpmPackageJSONMetadata{
+                                       Author: "jon",
+                                       URL:    
"https://github.com/bob/npm-name";,
+                               },
                        },
                        expected: []string{
                                "cpe:2.3:a:name:name:3.2:*:*:*:*:*:*:*",
-                               "cpe:2.3:a:*:name:3.2:*:*:*:*:*:*:*",
+                               "cpe:2.3:a:jon:name:3.2:*:*:*:*:*:*:*",
+                               "cpe:2.3:a:bob:name:3.2:*:*:*:*:*:*:*",
                        },
                },
                {
@@ -142,10 +147,10 @@
                                                "someones name",
                                                "someones.elses.n...@gmail.com",
                                        },
+                                       Homepage: 
"https://github.com/tom/ruby-name";,
                                },
                        },
                        expected: []string{
-                               "cpe:2.3:a:*:name:3.2:*:*:*:*:*:*:*",
                                "cpe:2.3:a:name:name:3.2:*:*:*:*:*:*:*",
                                "cpe:2.3:a:ruby-lang:name:3.2:*:*:*:*:*:*:*",
                                "cpe:2.3:a:ruby:name:3.2:*:*:*:*:*:*:*",
@@ -154,6 +159,7 @@
                                
"cpe:2.3:a:someones-name:name:3.2:*:*:*:*:*:*:*",
                                
"cpe:2.3:a:someones_elses_name:name:3.2:*:*:*:*:*:*:*",
                                
"cpe:2.3:a:someones_name:name:3.2:*:*:*:*:*:*:*",
+                               "cpe:2.3:a:tom:name:3.2:*:*:*:*:*:*:*",
                        },
                },
                {
@@ -641,7 +647,6 @@
                                },
                        },
                        expected: []string{
-                               "cpe:2.3:a:*:bundler:2.1.4:*:*:*:*:*:*:*",
                                "cpe:2.3:a:bundler:bundler:2.1.4:*:*:*:*:*:*:*",
                                
"cpe:2.3:a:ruby-lang:bundler:2.1.4:*:*:*:*:*:*:*",
                                "cpe:2.3:a:ruby:bundler:2.1.4:*:*:*:*:*:*:*",
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/syft-0.74.0/syft/pkg/cataloger/common/cpe/javascript.go 
new/syft-0.74.1/syft/pkg/cataloger/common/cpe/javascript.go
--- old/syft-0.74.0/syft/pkg/cataloger/common/cpe/javascript.go 1970-01-01 
01:00:00.000000000 +0100
+++ new/syft-0.74.1/syft/pkg/cataloger/common/cpe/javascript.go 2023-03-07 
18:54:32.000000000 +0100
@@ -0,0 +1,32 @@
+package cpe
+
+import "github.com/anchore/syft/syft/pkg"
+
+func candidateVendorsForJavascript(p pkg.Package) fieldCandidateSet {
+       if p.MetadataType != pkg.NpmPackageJSONMetadataType {
+               return nil
+       }
+
+       vendors := newFieldCandidateSet()
+       metadata, ok := p.Metadata.(pkg.NpmPackageJSONMetadata)
+       if !ok {
+               return nil
+       }
+
+       if metadata.Author != "" {
+               vendors.add(fieldCandidate{
+                       value:                 
normalizePersonName(stripEmailSuffix(metadata.Author)),
+                       disallowSubSelections: true,
+               })
+       }
+
+       if metadata.URL != "" {
+               vendors.union(candidateVendorsFromURL(metadata.URL))
+       }
+
+       if metadata.Homepage != "" {
+               vendors.union(candidateVendorsFromURL(metadata.Homepage))
+       }
+
+       return vendors
+}
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/syft-0.74.0/syft/pkg/cataloger/common/cpe/ruby.go 
new/syft-0.74.1/syft/pkg/cataloger/common/cpe/ruby.go
--- old/syft-0.74.0/syft/pkg/cataloger/common/cpe/ruby.go       2023-03-01 
21:35:01.000000000 +0100
+++ new/syft-0.74.1/syft/pkg/cataloger/common/cpe/ruby.go       2023-03-07 
18:54:32.000000000 +0100
@@ -17,5 +17,10 @@
                        disallowSubSelections: true,
                })
        }
+
+       if metadata.Homepage != "" {
+               vendors.union(candidateVendorsFromURL(metadata.Homepage))
+       }
+
        return vendors
 }
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/syft-0.74.0/syft/pkg/cataloger/common/cpe/vendors_from_url.go 
new/syft-0.74.1/syft/pkg/cataloger/common/cpe/vendors_from_url.go
--- old/syft-0.74.0/syft/pkg/cataloger/common/cpe/vendors_from_url.go   
2023-03-01 21:35:01.000000000 +0100
+++ new/syft-0.74.1/syft/pkg/cataloger/common/cpe/vendors_from_url.go   
2023-03-07 18:54:32.000000000 +0100
@@ -21,7 +21,7 @@
        }
 
        vendorExtractionPatterns = []*regexp.Regexp{
-               
regexp.MustCompile(`^https://(?:github|gitlab)\.com/(?P<vendor>[\w\-]*?)/.*$`),
+               
regexp.MustCompile(`^(?:https|http|git)://(?:github|gitlab)\.com/(?P<vendor>[\w\-]*?)/.*$`),
        }
 )
 
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/syft-0.74.0/syft/pkg/cataloger/common/cpe/vendors_from_url_test.go 
new/syft-0.74.1/syft/pkg/cataloger/common/cpe/vendors_from_url_test.go
--- old/syft-0.74.0/syft/pkg/cataloger/common/cpe/vendors_from_url_test.go      
2023-03-01 21:35:01.000000000 +0100
+++ new/syft-0.74.1/syft/pkg/cataloger/common/cpe/vendors_from_url_test.go      
2023-03-07 18:54:32.000000000 +0100
@@ -52,6 +52,16 @@
                        url:      
"https://github.com/armadillo/abcxyz-12345/a/b/c/d/e/f/g";,
                        expected: []string{"armadillo"},
                },
+               {
+                       name:     "github username from git://",
+                       url:      "git://github.com/abc/xyz.git",
+                       expected: []string{"abc"},
+               },
+               {
+                       name:     "github username from http://";,
+                       url:      "http://github.com/abc/xyz.git";,
+                       expected: []string{"abc"},
+               },
        }
        for _, test := range tests {
                t.Run(test.name, func(t *testing.T) {
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/syft-0.74.0/syft/pkg/cataloger/dotnet/package.go 
new/syft-0.74.1/syft/pkg/cataloger/dotnet/package.go
--- old/syft-0.74.0/syft/pkg/cataloger/dotnet/package.go        2023-03-01 
21:35:01.000000000 +0100
+++ new/syft-0.74.1/syft/pkg/cataloger/dotnet/package.go        2023-03-07 
18:54:32.000000000 +0100
@@ -45,7 +45,17 @@
        var qualifiers packageurl.Qualifiers
 
        return packageurl.NewPackageURL(
-               packageurl.TypeDotnet,
+               // This originally was packageurl.TypeDotnet, but this isn't a 
valid PURL type, according to:
+               // 
https://github.com/package-url/purl-spec/blob/master/PURL-TYPES.rst
+               // Some history:
+               //   https://github.com/anchore/packageurl-go/pull/8 added the 
type to Anchore's fork
+               //   due to this PR: https://github.com/anchore/syft/pull/951
+               // There were questions about "dotnet" being the right purlType 
at the time, but it was
+               // acknowledged that scanning a dotnet file does not 
necessarily mean the packages found
+               // are nuget packages and so the alternate type was added. 
Since this is still an invalid
+               // PURL type, however, we will use TypeNuget and revisit at 
such time there is a better
+               // official PURL type available.
+               packageurl.TypeNuget,
                "",
                m.Name,
                m.Version,
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/syft-0.74.0/syft/pkg/cataloger/dotnet/parse_dotnet_deps_test.go 
new/syft-0.74.1/syft/pkg/cataloger/dotnet/parse_dotnet_deps_test.go
--- old/syft-0.74.0/syft/pkg/cataloger/dotnet/parse_dotnet_deps_test.go 
2023-03-01 21:35:01.000000000 +0100
+++ new/syft-0.74.1/syft/pkg/cataloger/dotnet/parse_dotnet_deps_test.go 
2023-03-07 18:54:32.000000000 +0100
@@ -16,7 +16,7 @@
                {
                        Name:         "AWSSDK.Core",
                        Version:      "3.7.10.6",
-                       PURL:         "pkg:dotnet/AWSSDK.Core@3.7.10.6",
+                       PURL:         "pkg:nuget/AWSSDK.Core@3.7.10.6",
                        Locations:    fixtureLocationSet,
                        Language:     pkg.Dotnet,
                        Type:         pkg.DotnetPkg,
@@ -32,7 +32,7 @@
                {
                        Name:         
"Microsoft.Extensions.DependencyInjection.Abstractions",
                        Version:      "6.0.0",
-                       PURL:         
"pkg:dotnet/Microsoft.Extensions.DependencyInjection.Abstractions@6.0.0",
+                       PURL:         
"pkg:nuget/Microsoft.Extensions.DependencyInjection.Abstractions@6.0.0",
                        Locations:    fixtureLocationSet,
                        Language:     pkg.Dotnet,
                        Type:         pkg.DotnetPkg,
@@ -48,7 +48,7 @@
                {
                        Name:         
"Microsoft.Extensions.DependencyInjection",
                        Version:      "6.0.0",
-                       PURL:         
"pkg:dotnet/Microsoft.Extensions.DependencyInjection@6.0.0",
+                       PURL:         
"pkg:nuget/Microsoft.Extensions.DependencyInjection@6.0.0",
                        Locations:    fixtureLocationSet,
                        Language:     pkg.Dotnet,
                        Type:         pkg.DotnetPkg,
@@ -64,7 +64,7 @@
                {
                        Name:         
"Microsoft.Extensions.Logging.Abstractions",
                        Version:      "6.0.0",
-                       PURL:         
"pkg:dotnet/Microsoft.Extensions.Logging.Abstractions@6.0.0",
+                       PURL:         
"pkg:nuget/Microsoft.Extensions.Logging.Abstractions@6.0.0",
                        Locations:    fixtureLocationSet,
                        Language:     pkg.Dotnet,
                        Type:         pkg.DotnetPkg,
@@ -80,7 +80,7 @@
                {
                        Name:         "Microsoft.Extensions.Logging",
                        Version:      "6.0.0",
-                       PURL:         
"pkg:dotnet/Microsoft.Extensions.Logging@6.0.0",
+                       PURL:         
"pkg:nuget/Microsoft.Extensions.Logging@6.0.0",
                        Locations:    fixtureLocationSet,
                        Language:     pkg.Dotnet,
                        Type:         pkg.DotnetPkg,
@@ -97,7 +97,7 @@
                {
                        Name:         "Microsoft.Extensions.Options",
                        Version:      "6.0.0",
-                       PURL:         
"pkg:dotnet/Microsoft.Extensions.Options@6.0.0",
+                       PURL:         
"pkg:nuget/Microsoft.Extensions.Options@6.0.0",
                        Locations:    fixtureLocationSet,
                        Language:     pkg.Dotnet,
                        Type:         pkg.DotnetPkg,
@@ -113,7 +113,7 @@
                {
                        Name:         "Microsoft.Extensions.Primitives",
                        Version:      "6.0.0",
-                       PURL:         
"pkg:dotnet/Microsoft.Extensions.Primitives@6.0.0",
+                       PURL:         
"pkg:nuget/Microsoft.Extensions.Primitives@6.0.0",
                        Locations:    fixtureLocationSet,
                        Language:     pkg.Dotnet,
                        Type:         pkg.DotnetPkg,
@@ -129,7 +129,7 @@
                {
                        Name:         "Newtonsoft.Json",
                        Version:      "13.0.1",
-                       PURL:         "pkg:dotnet/Newtonsoft.Json@13.0.1",
+                       PURL:         "pkg:nuget/Newtonsoft.Json@13.0.1",
                        Locations:    fixtureLocationSet,
                        Language:     pkg.Dotnet,
                        Type:         pkg.DotnetPkg,
@@ -145,7 +145,7 @@
                {
                        Name:         "Serilog.Sinks.Console",
                        Version:      "4.0.1",
-                       PURL:         "pkg:dotnet/Serilog.Sinks.Console@4.0.1",
+                       PURL:         "pkg:nuget/Serilog.Sinks.Console@4.0.1",
                        Locations:    fixtureLocationSet,
                        Language:     pkg.Dotnet,
                        Type:         pkg.DotnetPkg,
@@ -161,7 +161,7 @@
                {
                        Name:         "Serilog",
                        Version:      "2.10.0",
-                       PURL:         "pkg:dotnet/Serilog@2.10.0",
+                       PURL:         "pkg:nuget/Serilog@2.10.0",
                        Locations:    fixtureLocationSet,
                        Language:     pkg.Dotnet,
                        Type:         pkg.DotnetPkg,
@@ -177,7 +177,7 @@
                {
                        Name:         "System.Diagnostics.DiagnosticSource",
                        Version:      "6.0.0",
-                       PURL:         
"pkg:dotnet/System.Diagnostics.DiagnosticSource@6.0.0",
+                       PURL:         
"pkg:nuget/System.Diagnostics.DiagnosticSource@6.0.0",
                        Locations:    fixtureLocationSet,
                        Language:     pkg.Dotnet,
                        Type:         pkg.DotnetPkg,
@@ -193,7 +193,7 @@
                {
                        Name:         "System.Runtime.CompilerServices.Unsafe",
                        Version:      "6.0.0",
-                       PURL:         
"pkg:dotnet/System.Runtime.CompilerServices.Unsafe@6.0.0",
+                       PURL:         
"pkg:nuget/System.Runtime.CompilerServices.Unsafe@6.0.0",
                        Locations:    fixtureLocationSet,
                        Language:     pkg.Dotnet,
                        Type:         pkg.DotnetPkg,

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

Reply via email to