diff --git a/.binny.yaml b/.binny.yaml index 3d7fab25b..329961d50 100644 --- a/.binny.yaml +++ b/.binny.yaml @@ -1,7 +1,7 @@ tools: - name: binny version: - want: v0.6.2 + want: v0.6.3 method: github-release with: repo: anchore/binny @@ -83,7 +83,7 @@ tools: - name: task version: - want: v3.32.0 + want: v3.33.1 method: github-release with: repo: go-task/task diff --git a/.github/workflows/codeql-analysis.yml b/.github/workflows/codeql-analysis.yml index 023fd3d49..9aaf6ca7c 100644 --- a/.github/workflows/codeql-analysis.yml +++ b/.github/workflows/codeql-analysis.yml @@ -45,7 +45,7 @@ jobs: # Initializes the CodeQL tools for scanning. - name: Initialize CodeQL - uses: github/codeql-action/init@b374143c1149a9115d881581d29b8390bbcbb59c #v3.22.11 + uses: github/codeql-action/init@012739e5082ff0c22ca6d6ab32e07c36df03c4a4 #v3.22.12 with: languages: ${{ matrix.language }} # If you wish to specify custom queries, you can do so here or in a config file. @@ -56,7 +56,7 @@ jobs: # Autobuild attempts to build any compiled languages (C/C++, C#, or Java). # If this step fails, then you should remove it and run the build manually (see below) - name: Autobuild - uses: github/codeql-action/autobuild@b374143c1149a9115d881581d29b8390bbcbb59c #v3.22.11 + uses: github/codeql-action/autobuild@012739e5082ff0c22ca6d6ab32e07c36df03c4a4 #v3.22.12 # â„šī¸ Command-line programs to run using the OS shell. # 📚 https://git.io/JvXDl @@ -70,4 +70,4 @@ jobs: # make release - name: Perform CodeQL Analysis - uses: github/codeql-action/analyze@b374143c1149a9115d881581d29b8390bbcbb59c #v3.22.11 + uses: github/codeql-action/analyze@012739e5082ff0c22ca6d6ab32e07c36df03c4a4 #v3.22.12 diff --git a/go.mod b/go.mod index d4629f12a..606b1cda5 100644 --- a/go.mod +++ b/go.mod @@ -16,7 +16,7 @@ require ( github.com/anchore/go-testutils v0.0.0-20200925183923-d5f45b0d3c04 github.com/anchore/go-version v1.2.2-0.20200701162849-18adb9c92b9b github.com/anchore/packageurl-go v0.1.1-0.20230104203445-02e0a6721501 - github.com/anchore/stereoscope v0.0.0-20231215220732-4b999b76ca89 + github.com/anchore/stereoscope v0.0.0-20231220161148-590920dabc54 // we are hinting brotli to latest due to warning when installing archiver v3: // go: warning: github.com/andybalholm/brotli@v1.0.1: retracted by module author: occasional panics and data corruption github.com/aquasecurity/go-pep440-version v0.0.0-20210121094942-22b2f8951d46 @@ -91,7 +91,7 @@ require ( github.com/Masterminds/goutils v1.1.1 // indirect github.com/Masterminds/semver/v3 v3.2.0 // indirect github.com/Microsoft/go-winio v0.6.1 // indirect - github.com/Microsoft/hcsshim v0.11.1 // indirect + github.com/Microsoft/hcsshim v0.11.4 // indirect github.com/ProtonMail/go-crypto v0.0.0-20230828082145-3c4c8a2d2371 // indirect github.com/adrg/xdg v0.4.0 // indirect github.com/anchore/go-struct-converter v0.0.0-20221118182256-c68fdcfa2092 // indirect @@ -104,7 +104,7 @@ require ( github.com/cloudflare/circl v1.3.3 // indirect github.com/containerd/cgroups v1.1.0 // indirect github.com/containerd/console v1.0.4-0.20230313162750-1ae8d489ac81 // indirect - github.com/containerd/containerd v1.7.8 // indirect + github.com/containerd/containerd v1.7.11 // indirect github.com/containerd/continuity v0.4.2 // indirect github.com/containerd/fifo v1.1.0 // indirect github.com/containerd/log v0.1.0 // indirect @@ -123,12 +123,13 @@ require ( github.com/edsrzf/mmap-go v1.1.0 // indirect github.com/emirpasic/gods v1.18.1 // indirect github.com/felixge/fgprof v0.9.3 // indirect + github.com/felixge/httpsnoop v1.0.3 // indirect github.com/fsnotify/fsnotify v1.6.0 // indirect github.com/gabriel-vasile/mimetype v1.4.0 // indirect github.com/gkampitakis/ciinfo v0.3.0 // indirect github.com/gkampitakis/go-diff v1.3.2 // indirect github.com/go-git/gcfg v1.5.1-0.20230307220236-3a3c6141e376 // indirect - github.com/go-logr/logr v1.2.3 // indirect + github.com/go-logr/logr v1.2.4 // indirect github.com/go-logr/stdr v1.2.2 // indirect github.com/go-restruct/restruct v1.2.0-alpha // indirect github.com/gogo/protobuf v1.3.2 // indirect @@ -210,11 +211,13 @@ require ( github.com/xo/terminfo v0.0.0-20210125001918-ca9a967f8778 // indirect go.mozilla.org/pkcs7 v0.0.0-20210826202110-33d05740a352 // indirect go.opencensus.io v0.24.0 // indirect - go.opentelemetry.io/otel v1.14.0 // indirect - go.opentelemetry.io/otel/trace v1.14.0 // indirect + go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.45.0 // indirect + go.opentelemetry.io/otel v1.19.0 // indirect + go.opentelemetry.io/otel/metric v1.19.0 // indirect + go.opentelemetry.io/otel/trace v1.19.0 // indirect go.uber.org/atomic v1.9.0 // indirect go.uber.org/multierr v1.9.0 // indirect - golang.org/x/crypto v0.16.0 // indirect + golang.org/x/crypto v0.17.0 // indirect golang.org/x/exp v0.0.0-20230905200255-921286631fa9 // indirect golang.org/x/sync v0.5.0 // indirect golang.org/x/sys v0.15.0 // indirect diff --git a/go.sum b/go.sum index 109384eef..e3b78a5cc 100644 --- a/go.sum +++ b/go.sum @@ -74,8 +74,8 @@ github.com/Masterminds/sprig/v3 v3.2.3/go.mod h1:rXcFaZ2zZbLRJv/xSysmlgIM1u11eBa github.com/Microsoft/go-winio v0.5.2/go.mod h1:WpS1mjBmmwHBEWmogvA2mj8546UReBk4v8QkMxJ6pZY= github.com/Microsoft/go-winio v0.6.1 h1:9/kr64B9VUZrLm5YYwbGtUJnMgqWVOdUAXu6Migciow= github.com/Microsoft/go-winio v0.6.1/go.mod h1:LRdKpFKfdobln8UmuiYcKPot9D2v6svN5+sAH+4kjUM= -github.com/Microsoft/hcsshim v0.11.1 h1:hJ3s7GbWlGK4YVV92sO88BQSyF4ZLVy7/awqOlPxFbA= -github.com/Microsoft/hcsshim v0.11.1/go.mod h1:nFJmaO4Zr5Y7eADdFOpYswDDlNVbvcIJJNJLECr5JQg= +github.com/Microsoft/hcsshim v0.11.4 h1:68vKo2VN8DE9AdN4tnkWnmdhqdbpUFM8OF3Airm7fz8= +github.com/Microsoft/hcsshim v0.11.4/go.mod h1:smjE4dvqPX9Zldna+t5FG3rnoHhaB7QYxPRqGcpAD9w= github.com/OneOfOne/xxhash v1.2.2/go.mod h1:HSdplMjZKSmBqAxg5vPj2TmRDmfkzw+cTzAElWljhcU= github.com/ProtonMail/go-crypto v0.0.0-20230828082145-3c4c8a2d2371 h1:kkhsdkhsCvIsutKu5zLMgWtgh9YxGCNAw8Ad8hjwfYg= github.com/ProtonMail/go-crypto v0.0.0-20230828082145-3c4c8a2d2371/go.mod h1:EjAoLdwvbIOoOQr3ihjnSoLZRtE8azugULFRteWMNc0= @@ -107,8 +107,8 @@ github.com/anchore/go-version v1.2.2-0.20200701162849-18adb9c92b9b h1:e1bmaoJfZV github.com/anchore/go-version v1.2.2-0.20200701162849-18adb9c92b9b/go.mod h1:Bkc+JYWjMCF8OyZ340IMSIi2Ebf3uwByOk6ho4wne1E= github.com/anchore/packageurl-go v0.1.1-0.20230104203445-02e0a6721501 h1:AV7qjwMcM4r8wFhJq3jLRztew3ywIyPTRapl2T1s9o8= github.com/anchore/packageurl-go v0.1.1-0.20230104203445-02e0a6721501/go.mod h1:Blo6OgJNiYF41ufcgHKkbCKF2MDOMlrqhXv/ij6ocR4= -github.com/anchore/stereoscope v0.0.0-20231215220732-4b999b76ca89 h1:dymFMCwnENqLr74KQppq8zHKwOPL0M1ToYAU+KVfTew= -github.com/anchore/stereoscope v0.0.0-20231215220732-4b999b76ca89/go.mod h1:GKAnytSVV1hoqB5r5Gd9M5Ph3Rzqq0zPdEJesewjC2w= +github.com/anchore/stereoscope v0.0.0-20231220161148-590920dabc54 h1:i2YK5QEs9H2YB3B2zv+AGR44ves0nmAGOD07lMphH14= +github.com/anchore/stereoscope v0.0.0-20231220161148-590920dabc54/go.mod h1:IylG7ofLoUKHwS1XDF6rPhOmaE3GgpAgsMdvvYfooTU= github.com/andreyvit/diff v0.0.0-20170406064948-c7f18ee00883/go.mod h1:rCTlJbsFo29Kk6CurOXKm700vrz8f0KW0JNfpkRJY/8= github.com/andybalholm/brotli v1.0.1/go.mod h1:loMXtMfwqflxFJPmdbJO0a3KNoPuLBgiu3qAvBg8x/Y= github.com/andybalholm/brotli v1.0.4 h1:V7DdXeJtZscaqfNuAdSRuRFzuiKlHSC/Zh3zl9qY3JY= @@ -180,8 +180,8 @@ github.com/containerd/cgroups v1.1.0/go.mod h1:6ppBcbh/NOOUU+dMKrykgaBnK9lCIBxHq github.com/containerd/console v1.0.3/go.mod h1:7LqA/THxQ86k76b8c/EMSiaJ3h1eZkMkXar0TQ1gf3U= github.com/containerd/console v1.0.4-0.20230313162750-1ae8d489ac81 h1:q2hJAaP1k2wIvVRd/hEHD7lacgqrCPS+k8g1MndzfWY= github.com/containerd/console v1.0.4-0.20230313162750-1ae8d489ac81/go.mod h1:YynlIjWYF8myEu6sdkwKIvGQq+cOckRm6So2avqoYAk= -github.com/containerd/containerd v1.7.8 h1:RkwgOW3AVUT3H/dyT0W03Dc8AzlpMG65lX48KftOFSM= -github.com/containerd/containerd v1.7.8/go.mod h1:L/Hn9qylJtUFT7cPeM0Sr3fATj+WjHwRQ0lyrYk3OPY= +github.com/containerd/containerd v1.7.11 h1:lfGKw3eU35sjV0aG2eYZTiwFEY1pCzxdzicHP3SZILw= +github.com/containerd/containerd v1.7.11/go.mod h1:5UluHxHTX2rdvYuZ5OJTC5m/KJNs0Zs9wVoJm9zf5ZE= github.com/containerd/continuity v0.4.2 h1:v3y/4Yz5jwnvqPKJJ+7Wf93fyWoCB3F5EclWG023MDM= github.com/containerd/continuity v0.4.2/go.mod h1:F6PTNCKepoxEaXLQp3wDAjygEnImnZ/7o4JzpodfroQ= github.com/containerd/fifo v1.1.0 h1:4I2mbh5stb1u6ycIABlBw9zgtlK8viPI9QkQNRQEEmY= @@ -263,6 +263,8 @@ github.com/fatih/set v0.2.1 h1:nn2CaJyknWE/6txyUDGwysr3G5QC6xWB/PtVjPBbeaA= github.com/fatih/set v0.2.1/go.mod h1:+RKtMCH+favT2+3YecHGxcc0b4KyVWA1QWWJUs4E0CI= github.com/felixge/fgprof v0.9.3 h1:VvyZxILNuCiUCSXtPtYmmtGvb65nqXh2QFWc0Wpf2/g= github.com/felixge/fgprof v0.9.3/go.mod h1:RdbpDgzqYVh/T9fPELJyV7EYJuHB55UTEULNun8eiPw= +github.com/felixge/httpsnoop v1.0.3 h1:s/nj+GCswXYzN5v2DpNMuMQYe+0DDwt5WVCU6CWBdXk= +github.com/felixge/httpsnoop v1.0.3/go.mod h1:m8KPJKqk1gH5J9DgRY2ASl2lWCfGKXixSwevea8zH2U= github.com/frankban/quicktest v1.11.3/go.mod h1:wRf/ReqHper53s+kmmSZizM8NamnL3IM0I9ntUbOk+k= github.com/frankban/quicktest v1.14.4 h1:g2rn0vABPOOXmZUj+vbmUp0lPoXEMuhTpIluN0XL9UY= github.com/frankban/quicktest v1.14.4/go.mod h1:4ptaffx2x8+WTWXmUCuVU6aPUX1/Mz7zb5vbUoiM6w0= @@ -300,8 +302,8 @@ github.com/go-kit/kit v0.9.0/go.mod h1:xBxKIO96dXMWWy0MnWVtmwkA9/13aqxPnvrjFYMA2 github.com/go-logfmt/logfmt v0.3.0/go.mod h1:Qt1PoO58o5twSAckw1HlFXLmHsOX5/0LbT9GBnD5lWE= github.com/go-logfmt/logfmt v0.4.0/go.mod h1:3RMwSq7FuexP4Kalkev3ejPJsZTpXXBr9+V4qmtdjCk= github.com/go-logr/logr v1.2.2/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A= -github.com/go-logr/logr v1.2.3 h1:2DntVwHkVopvECVRSlL5PSo9eG+cAkDCuckLubN+rq0= -github.com/go-logr/logr v1.2.3/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A= +github.com/go-logr/logr v1.2.4 h1:g01GSCwiDw2xSZfjJ2/T9M+S6pFdcNtFYsp+Y43HYDQ= +github.com/go-logr/logr v1.2.4/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A= github.com/go-logr/stdr v1.2.2 h1:hSWxHoqTgW2S2qGc0LTAI563KZ5YKYRhT3MFKZMbjag= github.com/go-logr/stdr v1.2.2/go.mod h1:mMo/vtBO5dYbehREoey6XUKy/eSumjCCveDpRre4VKE= github.com/go-restruct/restruct v1.2.0-alpha h1:2Lp474S/9660+SJjpVxoKuWX09JsXHSrdV7Nv3/gkvc= @@ -828,10 +830,14 @@ go.opencensus.io v0.22.5/go.mod h1:5pWMHQbX5EPX2/62yrJeAkowc+lfs/XD7Uxpq3pI6kk= go.opencensus.io v0.23.0/go.mod h1:XItmlyltB5F7CS4xOC1DcqMoFqwtC6OG2xF7mCv7P7E= go.opencensus.io v0.24.0 h1:y73uSU6J157QMP2kn2r30vwW1A2W2WFwSCGnAVxeaD0= go.opencensus.io v0.24.0/go.mod h1:vNK8G9p7aAivkbmorf4v+7Hgx+Zs0yY+0fOtgBfjQKo= -go.opentelemetry.io/otel v1.14.0 h1:/79Huy8wbf5DnIPhemGB+zEPVwnN6fuQybr/SRXa6hM= -go.opentelemetry.io/otel v1.14.0/go.mod h1:o4buv+dJzx8rohcUeRmWUZhqupFvzWis188WlggnNeU= -go.opentelemetry.io/otel/trace v1.14.0 h1:wp2Mmvj41tDsyAJXiWDWpfNsOiIyd38fy85pyKcFq/M= -go.opentelemetry.io/otel/trace v1.14.0/go.mod h1:8avnQLK+CG77yNLUae4ea2JDQ6iT+gozhnZjy/rw9G8= +go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.45.0 h1:x8Z78aZx8cOF0+Kkazoc7lwUNMGy0LrzEMxTm4BbTxg= +go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.45.0/go.mod h1:62CPTSry9QZtOaSsE3tOzhx6LzDhHnXJ6xHeMNNiM6Q= +go.opentelemetry.io/otel v1.19.0 h1:MuS/TNf4/j4IXsZuJegVzI1cwut7Qc00344rgH7p8bs= +go.opentelemetry.io/otel v1.19.0/go.mod h1:i0QyjOq3UPoTzff0PJB2N66fb4S0+rSbSB15/oyH9fY= +go.opentelemetry.io/otel/metric v1.19.0 h1:aTzpGtV0ar9wlV4Sna9sdJyII5jTVJEvKETPiOKwvpE= +go.opentelemetry.io/otel/metric v1.19.0/go.mod h1:L5rUsV9kM1IxCj1MmSdS+JQAcVm319EUrDVLrt7jqt8= +go.opentelemetry.io/otel/trace v1.19.0 h1:DFVQmlVbfVeOuBRrwdtaehRrWiL1JoVs9CPIQ1Dzxpg= +go.opentelemetry.io/otel/trace v1.19.0/go.mod h1:mfaSyvGyEJEI0nyV2I4qhNQnbBOUUmYZpYojqMnX2vo= go.opentelemetry.io/proto/otlp v0.7.0/go.mod h1:PqfVotwruBrMGOCsRd/89rSnXhoiJIqeYNgFYFoEGnI= go.uber.org/atomic v1.7.0/go.mod h1:fEN4uk6kAWBTFdckzkM89CLk9XfWZrxpCo0nPH17wJc= go.uber.org/atomic v1.9.0 h1:ECmE8Bn/WFTYwEW/bpKD3M8VtR/zQVbavAoalC1PYyE= @@ -859,8 +865,8 @@ golang.org/x/crypto v0.0.0-20220622213112-05595931fe9d/go.mod h1:IxCIyHEi3zRg3s0 golang.org/x/crypto v0.3.0/go.mod h1:hebNnKkNXi2UzZN1eVRvBB7co0a+JxK6XbPiWVs/3J4= golang.org/x/crypto v0.3.1-0.20221117191849-2c476679df9a/go.mod h1:hebNnKkNXi2UzZN1eVRvBB7co0a+JxK6XbPiWVs/3J4= golang.org/x/crypto v0.7.0/go.mod h1:pYwdfH91IfpZVANVyUOhSIPZaFoJGxTFbZhFTx+dXZU= -golang.org/x/crypto v0.16.0 h1:mMMrFzRSCF0GvB7Ne27XVtVAaXLrPmgPC7/v0tkwHaY= -golang.org/x/crypto v0.16.0/go.mod h1:gCAAfMLgwOJRpTjQ2zCCt2OcSfYMTeZVSRtQlPC7Nq4= +golang.org/x/crypto v0.17.0 h1:r8bRNjWL3GshPW3gkd+RpvzWrZAwPS49OmTGZ/uhM4k= +golang.org/x/crypto v0.17.0/go.mod h1:gCAAfMLgwOJRpTjQ2zCCt2OcSfYMTeZVSRtQlPC7Nq4= golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= golang.org/x/exp v0.0.0-20190306152737-a1d7652674e8/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= golang.org/x/exp v0.0.0-20190510132918-efd6b22b2522/go.mod h1:ZjyILWgesfNpC6sMxTJOJm9Kp84zZh5NQWvqDGG3Qr8= diff --git a/syft/pkg/cataloger/binary/cataloger_test.go b/syft/pkg/cataloger/binary/cataloger_test.go index 3efc05255..1056b412c 100644 --- a/syft/pkg/cataloger/binary/cataloger_test.go +++ b/syft/pkg/cataloger/binary/cataloger_test.go @@ -793,6 +793,17 @@ func Test_Cataloger_PositiveCases(t *testing.T) { Metadata: metadata("bash-binary"), }, }, + { + logicalFixture: "openssl/3.1.4/linux-amd64", + expected: pkg.Package{ + Name: "openssl", + Version: "3.1.4", + Type: "binary", + PURL: "pkg:generic/openssl@3.1.4", + Locations: locations("openssl"), + Metadata: metadata("openssl-binary"), + }, + }, } for _, test := range tests { diff --git a/syft/pkg/cataloger/binary/default_classifiers.go b/syft/pkg/cataloger/binary/default_classifiers.go index 34f35e90b..67ea6bf69 100644 --- a/syft/pkg/cataloger/binary/default_classifiers.go +++ b/syft/pkg/cataloger/binary/default_classifiers.go @@ -338,6 +338,17 @@ var defaultClassifiers = []classifier{ PURL: mustPURL("pkg:generic/bash@version"), CPEs: singleCPE("cpe:2.3:a:gnu:bash:*:*:*:*:*:*:*:*"), }, + { + Class: "openssl-binary", + FileGlob: "**/openssl", + EvidenceMatcher: fileContentsVersionMatcher( + // [NUL]OpenSSL 3.1.4' + `\x00OpenSSL (?P[0-9]+\.[0-9]+\.[0-9]+(-alpha[0-9]|-beta[0-9]|-rc[0-9])?)`, + ), + Package: "openssl", + PURL: mustPURL("pkg:generic/openssl@version"), + CPEs: singleCPE("cpe:2.3:a:openssl:openssl:*:*:*:*:*:*:*:*"), + }, } // in both binaries and shared libraries, the version pattern is [NUL]3.11.2[NUL] diff --git a/syft/pkg/cataloger/binary/test-fixtures/.gitignore b/syft/pkg/cataloger/binary/test-fixtures/.gitignore index 18a7c41bd..5478b80ea 100644 --- a/syft/pkg/cataloger/binary/test-fixtures/.gitignore +++ b/syft/pkg/cataloger/binary/test-fixtures/.gitignore @@ -1,3 +1,9 @@ classifiers/dynamic classifiers/bin -cache.fingerprint \ No newline at end of file +cache.fingerprint + +# allow for lb patterns (rust, pytho, php and more) +!lib*.so + +# allow for go-hint file +!VERSION* \ No newline at end of file diff --git a/syft/pkg/cataloger/binary/test-fixtures/classifiers/snippets/.gitignore b/syft/pkg/cataloger/binary/test-fixtures/classifiers/snippets/.gitignore deleted file mode 100644 index 0a755729c..000000000 --- a/syft/pkg/cataloger/binary/test-fixtures/classifiers/snippets/.gitignore +++ /dev/null @@ -1,5 +0,0 @@ -# allow for lb patterns (rust, pytho, php and more) -!lib*.so - -# allow for go-hint file -!VERSION* \ No newline at end of file diff --git a/syft/pkg/cataloger/binary/test-fixtures/classifiers/snippets/openssl/3.1.4/linux-amd64/openssl b/syft/pkg/cataloger/binary/test-fixtures/classifiers/snippets/openssl/3.1.4/linux-amd64/openssl new file mode 100644 index 000000000..7d2ffbb0b Binary files /dev/null and b/syft/pkg/cataloger/binary/test-fixtures/classifiers/snippets/openssl/3.1.4/linux-amd64/openssl differ diff --git a/syft/pkg/cataloger/erlang/erlang_parser.go b/syft/pkg/cataloger/erlang/erlang_parser.go index 048768cb5..829b0c143 100644 --- a/syft/pkg/cataloger/erlang/erlang_parser.go +++ b/syft/pkg/cataloger/erlang/erlang_parser.go @@ -2,6 +2,7 @@ package erlang import ( "bytes" + "errors" "fmt" "io" "strings" @@ -12,6 +13,8 @@ type erlangNode struct { value interface{} } +var errSkipComments = errors.New("") + func (e erlangNode) Slice() []erlangNode { out, ok := e.value.([]erlangNode) if ok { @@ -56,6 +59,10 @@ func parseErlang(reader io.Reader) (erlangNode, error) { i := 0 for i < len(data) { item, err := parseErlangBlock(data, &i) + if err == errSkipComments { + skipWhitespace(data, &i) + continue + } if err != nil { return node(nil), fmt.Errorf("%w\n%s", err, printError(data, i)) } @@ -141,11 +148,26 @@ func parseErlangNode(data []byte, i *int) (erlangNode, error) { c := data[*i] switch c { case '[', '{': + offset := *i + 1 + skipWhitespace(data, &offset) + c2 := data[offset] + + // Add support for empty lists + if (c == '[' && c2 == ']') || (c == '{' && c2 == '}') { + *i = offset + 1 + return node(nil), nil + } + return parseErlangList(data, i) case '"': + fallthrough + case '\'': return parseErlangString(data, i) case '<': return parseErlangAngleString(data, i) + case '%': + parseErlangComment(data, i) + return node(nil), errSkipComments } if isLiteral(c) { @@ -205,7 +227,7 @@ func parseErlangString(data []byte, i *int) (erlangNode, error) { buf.WriteByte(c) *i++ } - return node(buf.String()), nil + return node(nil), fmt.Errorf("unterminated string at %d", *i) } func parseErlangList(data []byte, i *int) (erlangNode, error) { @@ -216,6 +238,10 @@ func parseErlangList(data []byte, i *int) (erlangNode, error) { for *i < len(data) { item, err := parseErlangNode(data, i) if err != nil { + if err == errSkipComments { + skipWhitespace(data, i) + continue + } return node(nil), err } out.value = append(out.value.([]erlangNode), item) @@ -225,6 +251,9 @@ func parseErlangList(data []byte, i *int) (erlangNode, error) { case ',': *i++ continue + case '%': + // Starts a new comment node + continue case ']', '}': *i++ return out, nil @@ -234,3 +263,19 @@ func parseErlangList(data []byte, i *int) (erlangNode, error) { } return out, nil } + +func parseErlangComment(data []byte, i *int) { + for *i < len(data) { + c := data[*i] + + *i++ + + // Rest of a line is a comment. Deals with CR, LF and CR/LF + if c == '\n' { + break + } else if c == '\r' && data[*i] == '\n' { + *i++ + break + } + } +} diff --git a/syft/pkg/cataloger/erlang/erlang_parser_test.go b/syft/pkg/cataloger/erlang/erlang_parser_test.go index 68225fb9b..adb031ddb 100644 --- a/syft/pkg/cataloger/erlang/erlang_parser_test.go +++ b/syft/pkg/cataloger/erlang/erlang_parser_test.go @@ -38,6 +38,21 @@ func Test_parseErlang(t *testing.T) { {<<"bcrypt">>, <<"3418821BC17CE6E96A4A77D1A88D7485BF783E212069FACFC79510AFBFF95352">>}, {<<"unicode_util_compat">>, <<"25EEE6D67DF61960CF6A794239566599B09E17E668D3700247BC498638152521">>}]} ].`, + }, + { + name: "empty list", + content: ` +{test, [ + {with_space, [ ]}, + {without_space, []} +]}`, + }, + { + name: "valid strings", + content: ` +{strings, [ + "foo", 'bar' +]}`, }, { name: "invalid string content", @@ -46,6 +61,14 @@ func Test_parseErlang(t *testing.T) { {"1.2.0 ">>}, ].`, + }, + { + name: "string mismach", + wantErr: require.Error, + content: ` +{bad_string, [ + 'foo" + ]}`, }, { name: "invalid content", @@ -54,6 +77,25 @@ func Test_parseErlang(t *testing.T) { {"1.2.0"}. ].`, }, + { + name: "valid comments", + content: ` +{ comments, [ + { foo, bar }, + %% this is a comment + % this is also a comment + { hello, 'bar' }, %%inline comment + { baz } +]}`, + }, + { + name: "starts with a comments", + content: ` +%% starts with comment +{ comments, [ + { foo, bar } +]}`, + }, } for _, test := range tests { diff --git a/syft/pkg/cataloger/haskell/parse_stack_lock.go b/syft/pkg/cataloger/haskell/parse_stack_lock.go index 40dc6aa6c..62ee5bc16 100644 --- a/syft/pkg/cataloger/haskell/parse_stack_lock.go +++ b/syft/pkg/cataloger/haskell/parse_stack_lock.go @@ -63,6 +63,9 @@ func parseStackLock(_ file.Resolver, _ *generic.Environment, reader file.Locatio } for _, pack := range lockFile.Packages { + if pack.Completed.Hackage == "" { + continue + } pkgName, pkgVersion, pkgHash := parseStackPackageEncoding(pack.Completed.Hackage) pkgs = append( pkgs, @@ -80,13 +83,20 @@ func parseStackLock(_ file.Resolver, _ *generic.Environment, reader file.Locatio return pkgs, nil, nil } + func parseStackPackageEncoding(pkgEncoding string) (name, version, hash string) { lastDashIdx := strings.LastIndex(pkgEncoding, "-") + if lastDashIdx == -1 { + name = pkgEncoding + return + } name = pkgEncoding[:lastDashIdx] remainingEncoding := pkgEncoding[lastDashIdx+1:] encodingSplits := strings.Split(remainingEncoding, "@") version = encodingSplits[0] - startHash, endHash := strings.Index(encodingSplits[1], ":")+1, strings.Index(encodingSplits[1], ",") - hash = encodingSplits[1][startHash:endHash] + if len(encodingSplits) > 1 { + startHash, endHash := strings.Index(encodingSplits[1], ":")+1, strings.Index(encodingSplits[1], ",") + hash = encodingSplits[1][startHash:endHash] + } return } diff --git a/syft/pkg/cataloger/haskell/test-fixtures/stack.yaml.lock b/syft/pkg/cataloger/haskell/test-fixtures/stack.yaml.lock index a18542255..220765043 100644 --- a/syft/pkg/cataloger/haskell/test-fixtures/stack.yaml.lock +++ b/syft/pkg/cataloger/haskell/test-fixtures/stack.yaml.lock @@ -67,6 +67,19 @@ packages: sha256: 557c438345de19f82bf01d676100da2a191ef06f624e7a4b90b09ac17cbb52a5 original: hackage: ptr-0.16.8.2@sha256:708ebb95117f2872d2c5a554eb6804cf1126e86abe793b2673f913f14e5eb1ac,3959 +- completed: + commit: a5847301404583e16d55cd4d051b8e605d704fbc + git: https://github.com/runtimeverification/haskell-backend.git + name: kore + pantry-tree: + sha256: 30a502eda589be5af735b1b59760ce3e0235c0cae8961978a46b3564dd8db32b + size: 44685 + subdir: kore + version: 0.60.0.0 + original: + commit: a5847301404583e16d55cd4d051b8e605d704fbc + git: https://github.com/runtimeverification/haskell-backend.git + subdir: kore snapshots: - completed: size: 618951