---------
Signed-off-by: Christopher Phillips <32073428+spiffcs@users.noreply.github.com>
Signed-off-by: Alex Goodman <wagoodman@users.noreply.github.com>
Co-authored-by: Alex Goodman <wagoodman@users.noreply.github.com>
* report each hardlink as its own file when scanning images
image scans previously collapsed a set of hardlinks onto a single file, so only
one path per inode showed up in results. dir scans report every hardlink path,
which made image vs dir SBOMs of the same filesystem diverge (and produce
different SPDX `packageVerificationCode` values for packages that own hardlinked
files).
now both image resolvers (squash and all-layers) surface each hardlink at its
own path as a regular file bound to the target's content, matching dir scans.
user-facing impact:
- SBOMs for images containing hardlinks will list more `file` entries
- SPDX `packageVerificationCode` values change for affected packages, now
matching the equivalent `dir:` scan
- adds `file.NewVirtualLocationFromImage` to the public API
fixes#5019
Signed-off-by: Alex Goodman <wagoodman@users.noreply.github.com>
* fix busybox test assertion
Signed-off-by: Alex Goodman <wagoodman@users.noreply.github.com>
---------
Signed-off-by: Alex Goodman <wagoodman@users.noreply.github.com>
parseErlangString advances past a backslash escape and then checks
len(data) >= *i before reading the escaped byte. That condition is
almost always true (it only turns false once *i runs off the end),
so the intended out-of-range guard fires on the very first escape
character it sees instead of only at EOF. Any rebar.lock or OTP
resource file containing a backslash in a quoted string (a Windows
git path, an escaped quote, anything) fails to parse and the whole
file, and every package in it, gets dropped.
Flip the comparison to *i >= len(data) so the guard only trips when
the escape is genuinely truncated, and add a regression test for a
string with an escaped quote.
Signed-off-by: Arpit Jain <arpitjain099@gmail.com>
* Prevent duplicate Go packages after source replacement resolution
Source analysis already applies module replacements through go/packages. Avoid synthesizing the same replacement again from go.mod while retaining fallback synthesis for modules that source analysis did not resolve.
Constraint: Preserve unimported and local-path replacement cataloging.
Rejected: Deduplicate only during final assembly | That retains redundant license lookup and ambiguous metadata ownership.
Confidence: high
Scope-risk: narrow
Directive: Keep go.mod fallback packages limited to modules absent from source analysis.
Tested: Focused replacement regression, related Go module parser tests, go vet, gofmt, and diff checks.
Not-tested: Docker-backed full cataloger fixtures; local root storage was exhausted by image generation.
Signed-off-by: ychampion <ychampion@users.noreply.github.com>
* Keep replacement fixtures with the Go module test data
Constraint: The maintainer reserves internal/gotestdata for fixtures that need special Go tooling discovery.
Rejected: Leave this fixture in gotestdata | The regression opens its module explicitly and does not need the special location.
Confidence: high
Scope-risk: narrow
Directive: Use internal/gotestdata only when a fixture must avoid Go testdata discovery rules.
Tested: replacement regression repeated 10 times; Go module parser table; go vet for the Go cataloger; gofmt; diff checks.
Not-tested: Full cataloger package; three unrelated parser fixtures fail identically on exact prior head in this environment.
Signed-off-by: ychampion <ychampion@users.noreply.github.com>
---------
Signed-off-by: ychampion <ychampion@users.noreply.github.com>
Co-authored-by: ychampion <ychampion@users.noreply.github.com>
* Add multi-platform OCI image support
Signed-off-by: Jason Paulos <jasonpaulos@users.noreply.github.com>
* Reduce calls to PrepareMultiplatformFixtureImage in TestMultiPlatformOCIImageSelection
Signed-off-by: Jason Paulos <jasonpaulos@users.noreply.github.com>
* Use smaller image for testing & update stereoscope fork
Signed-off-by: Jason Paulos <jasonpaulos@users.noreply.github.com>
* bump to stereoscope@main after 548 merge
Signed-off-by: Alex Goodman <wagoodman@users.noreply.github.com>
---------
Signed-off-by: Jason Paulos <jasonpaulos@users.noreply.github.com>
Signed-off-by: Alex Goodman <wagoodman@users.noreply.github.com>
Co-authored-by: Alex Goodman <wagoodman@users.noreply.github.com>
---------
Signed-off-by: Christopher Phillips <32073428+spiffcs@users.noreply.github.com>
Signed-off-by: Alex Goodman <wagoodman@users.noreply.github.com>
Co-authored-by: Alex Goodman <wagoodman@users.noreply.github.com>
Closes#4587
Adds a single info-level log line at the end of every `syft scan` run that reports the total scan wall-clock time, e.g.:
[0003] INFO scan completed in 2.017s
Per maintainer guidance on the issue, the line is logged at INFO so it surfaces with `-v` (alongside the existing per-cataloger timing) and stays out of the default TUI / stdout. Useful for users who leave long scans running and want the overall time at a glance, without having to wrap the invocation in `time`.
Signed-off-by: Chris (ChrisJr404) <11917633+ChrisJr404@users.noreply.github.com>
Co-authored-by: Chris (ChrisJr404) <11917633+ChrisJr404@users.noreply.github.com>
---------
Signed-off-by: Christopher Phillips <32073428+spiffcs@users.noreply.github.com>
Signed-off-by: Alex Goodman <wagoodman@users.noreply.github.com>
Co-authored-by: Alex Goodman <wagoodman@users.noreply.github.com>
The CycloneDX decoder was filtering on a hard-coded set of component
types (application/framework/library/machine-learning-model). Anything
else — including "firmware" — fell through silently, so a BOM
describing u-boot or other firmware ended up with no packages and
grype reported no matches (anchore/grype#2537).
@kzantow confirmed in the issue thread that firmware should be
included and gave this section as the spot to update.
Add ComponentTypeFirmware to the case list and a regression test that
constructs a single-firmware-component BOM and asserts the decoded
SBOM contains the package.
Closesanchore/grype#2537
Signed-off-by: Chris (ChrisJr404) <11917633+ChrisJr404@users.noreply.github.com>
Co-authored-by: Chris (ChrisJr404) <11917633+ChrisJr404@users.noreply.github.com>
* fix: correct Spring LDAP group ID in purl generation
The Spring LDAP artifacts use the group ID org.springframework.ldap
(not org.springframework). This caused syft to generate incorrect purls
like pkg:maven/spring-ldap-core/spring-ldap-core@3.1.4 instead of the
correct pkg:maven/org.springframework.ldap/spring-ldap-core@3.1.4.
Add all Spring LDAP artifacts to the DefaultArtifactIDToGroupID map:
- spring-ldap
- spring-ldap-core
- spring-ldap-core-tiger
- spring-ldap-ldif-core
- spring-ldap-odm
- spring-ldap-test
Closes#4030
Signed-off-by: Jonas Boos <jonasboos@users.noreply.github.com>
Signed-off-by: Alex Goodman <wagoodman@users.noreply.github.com>
* fix formatting
Signed-off-by: Alex Goodman <wagoodman@users.noreply.github.com>
* add test
Signed-off-by: Alex Goodman <wagoodman@users.noreply.github.com>
---------
Signed-off-by: Jonas Boos <jonasboos@users.noreply.github.com>
Signed-off-by: Alex Goodman <wagoodman@users.noreply.github.com>
Co-authored-by: Jonas Boos <jonasboos@users.noreply.github.com>
Co-authored-by: Alex Goodman <wagoodman@users.noreply.github.com>
Update the binary classifier cataloger developer README to match the
current workflow:
- Testing section used the non-existent flag -must-use-full-binaries
against .../testdata/...; the real flag is -must-use-original-binaries
and Test_Cataloger_PositiveCases lives in the binary package. Fix the
command and add a single-fixture variant.
- Point add-snippet references at the make target and note the (Y/n/q)
prompt requires y to write the snippet.
- Fix the test file name (classifier_cataloger_test.go) and document the
go generate ./internal/capabilities step for new classifiers.
Fixes#4510
Signed-off-by: alliasgher <alliasgher123@gmail.com>
GHC boot-lib constraints (any.base installed) have no ' ==', so fields[1] panicked with index out of range and the recover dropped all Haskell packages. Skip constraint lines without a version.
Signed-off-by: Synvoya <16019863+Synvoya@users.noreply.github.com>
Co-authored-by: Synvoya <16019863+Synvoya@users.noreply.github.com>
The hand-written rockspec parser reads a byte past the end of the buffer
in two spots when a comment runs right up to the end of the file.
In parseRockspecBlock, when a block starts with a leading comment that
consumes the rest of the file, the SkipWhitespace afterward leaves the
index at len(data) and the following `c = data[*i]` reads out of range.
In parseComment, `data[*i]` is read after the index is advanced to check
for a CR/LF pair, so a bare carriage return as the last byte reads past
the end.
Both cases show up with a rockspec whose final line is a comment ending
in a lone \r with no trailing newline. That is malformed but harmless
input, and the panic aborts the whole Lua cataloger, so every valid Lua
package in the same scan gets dropped. Guard both reads with a length
check and return cleanly at EOF. Added table cases covering a
comment-only file and a trailing comment, both ending in a bare CR.
Signed-off-by: arpitjain099 <arpitjain099@gmail.com>
deno.lock npm keys append resolved peer dependencies after the version,
separated by "_" (e.g. "typedoc@0.28.19_typescript@6.0.3" or the scoped
"@scope/name@1.2.3_@scope+peer@4.5.6"). parseDenoNpmNameVersion split on the
last "@", capturing a peer's "@" and producing a garbage package name plus
the peer's version (and a corrupt PURL that breaks vulnerability matching).
Strip the peer suffix (the first "_" after the version "@") before splitting
name@version; a semver version never contains "_".
Signed-off-by: Synvoya <16019863+Synvoya@users.noreply.github.com>
Co-authored-by: Synvoya <16019863+Synvoya@users.noreply.github.com>
---------
Signed-off-by: Christopher Phillips <32073428+spiffcs@users.noreply.github.com>
Signed-off-by: Alex Goodman <wagoodman@users.noreply.github.com>
Co-authored-by: Alex Goodman <wagoodman@users.noreply.github.com>
* swift: emit canonical purls without .git suffix or repeated name
Reported in anchore/syft#3961: the purl syft emits for Swift packages
parsed out of Package.resolved keeps the repository URLs .git suffix
and then re-appends the package name, producing
pkg:swift/github.com/apple/swift-nio-ssl.git/swift-nio-ssl@2.0.0
NVD / Grype cannot match that purl against the known
swift-nio-ssl@2.0.0 CVE (GHSA-frg3-gpcx-968f), so every Swift SBOM
produced by syft silently loses vulnerability coverage. cdxgen and
the wider purl ecosystem use the shorter form
pkg:swift/github.com/apple/swift-nio-ssl@2.0.0
which Grype does match.
Replace the ad-hoc strings.Replace with swiftNamespaceFromSourceURL,
which trims the common URL schemes, strips the ".git" suffix, and
drops a trailing /<name> segment so the namespace is only the
organisation path (e.g. github.com/apple). Existing test expectations
are updated to the new purl shape.
Fixes#3961
Signed-off-by: Sai Asish Y <say.apm35@gmail.com>
Signed-off-by: Alex Goodman <wagoodman@users.noreply.github.com>
* Revert unrelated consul binary classifier changes
The swift purl commit (ff5ffc37) accidentally bundled removal of the
consul GitDescribe and NUL-wrapped version matchers plus the 1.12.9 and
1.7.14 fixtures/test cases. That drops version detection for consul
binaries not carrying the CONSUL_VERSION string. Restore the binary
cataloger to its pre-commit state so this branch is swift-only.
Signed-off-by: Alex Goodman <wagoodman@users.noreply.github.com>
* swift: strip repeated name segment case-insensitively
Package.resolved identities are lowercased while the repo URL path may be
mixed-case (e.g. github.com/Apple/Swift-NIO vs identity swift-nio). The
case-sensitive TrimSuffix left the repo segment in the namespace for such
repos, reintroducing the duplicated-name purl. Compare the trailing segment
with EqualFold and add unit coverage for swiftPackageManagerPackageURL.
Signed-off-by: Alex Goodman <wagoodman@users.noreply.github.com>
---------
Signed-off-by: Sai Asish Y <say.apm35@gmail.com>
Signed-off-by: Alex Goodman <wagoodman@users.noreply.github.com>
Co-authored-by: Alex Goodman <wagoodman@users.noreply.github.com>