mirror of
https://github.com/anchore/syft.git
synced 2026-11-03 07:56:36 +01:00
Add JVM cataloger (#3217)
* add jvm cataloger Signed-off-by: Alex Goodman <wagoodman@users.noreply.github.com> * simplify version selection Signed-off-by: Alex Goodman <wagoodman@users.noreply.github.com> * CPEs from JVM cataloger should be declared Signed-off-by: Alex Goodman <wagoodman@users.noreply.github.com> * ensure package overlap is enabled for sensitive use cases Signed-off-by: Alex Goodman <wagoodman@users.noreply.github.com> * more permissive glob Signed-off-by: Alex Goodman <wagoodman@users.noreply.github.com> --------- Signed-off-by: Alex Goodman <wagoodman@users.noreply.github.com>
This commit is contained in:
@@ -140,6 +140,40 @@ func (r ChrootContext) ToNativePath(chrootPath string) (string, error) {
|
||||
return responsePath, nil
|
||||
}
|
||||
|
||||
func (r ChrootContext) ToNativeGlob(chrootPath string) (string, error) {
|
||||
// split on any *
|
||||
parts := strings.Split(chrootPath, "*")
|
||||
if len(parts) == 0 || parts[0] == "" {
|
||||
// either this is an empty string or a path that starts with * so there is nothing we can do
|
||||
return chrootPath, nil
|
||||
}
|
||||
|
||||
if len(parts) == 1 {
|
||||
// this has no glob, treat it like a path
|
||||
return r.ToNativePath(chrootPath)
|
||||
}
|
||||
|
||||
responsePath := parts[0]
|
||||
|
||||
if filepath.IsAbs(responsePath) {
|
||||
// don't allow input to potentially hop above root path
|
||||
responsePath = path.Join(r.root, responsePath)
|
||||
} else {
|
||||
// ensure we take into account any relative difference between the root path and the CWD for relative requests
|
||||
responsePath = path.Join(r.cwdRelativeToRoot, responsePath)
|
||||
}
|
||||
|
||||
var err error
|
||||
responsePath, err = filepath.Abs(responsePath)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
|
||||
parts[0] = strings.TrimRight(responsePath, "/") + "/"
|
||||
|
||||
return strings.Join(parts, "*"), nil
|
||||
}
|
||||
|
||||
// ToChrootPath takes a path from the underlying fs domain and converts it to a path that is relative to the current root context.
|
||||
func (r ChrootContext) ToChrootPath(nativePath string) string {
|
||||
responsePath := nativePath
|
||||
|
||||
@@ -479,3 +479,98 @@ func Test_ChrootContext_RequestResponse(t *testing.T) {
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func TestToNativeGlob(t *testing.T) {
|
||||
tests := []struct {
|
||||
name string
|
||||
chrootContext ChrootContext
|
||||
chrootPath string
|
||||
expectedResult string
|
||||
expectedError error
|
||||
}{
|
||||
{
|
||||
name: "ignore empty path",
|
||||
chrootContext: ChrootContext{
|
||||
root: "/root",
|
||||
cwdRelativeToRoot: "/cwd",
|
||||
},
|
||||
chrootPath: "",
|
||||
expectedResult: "",
|
||||
expectedError: nil,
|
||||
},
|
||||
{
|
||||
name: "ignore if just a path",
|
||||
chrootContext: ChrootContext{
|
||||
root: "/root",
|
||||
cwdRelativeToRoot: "/cwd",
|
||||
},
|
||||
chrootPath: "/some/path/file.txt",
|
||||
expectedResult: "/root/some/path/file.txt",
|
||||
expectedError: nil,
|
||||
},
|
||||
{
|
||||
name: "ignore starting with glob",
|
||||
chrootContext: ChrootContext{
|
||||
root: "/root",
|
||||
cwdRelativeToRoot: "/cwd",
|
||||
},
|
||||
chrootPath: "*/relative/path/*",
|
||||
expectedResult: "*/relative/path/*",
|
||||
expectedError: nil,
|
||||
},
|
||||
{
|
||||
name: "absolute path with glob",
|
||||
chrootContext: ChrootContext{
|
||||
root: "/root",
|
||||
cwdRelativeToRoot: "/cwd",
|
||||
},
|
||||
chrootPath: "/some/path/*",
|
||||
expectedResult: "/root/some/path/*",
|
||||
expectedError: nil,
|
||||
},
|
||||
{
|
||||
name: "relative path with glob",
|
||||
chrootContext: ChrootContext{
|
||||
root: "/root",
|
||||
cwdRelativeToRoot: "/cwd",
|
||||
},
|
||||
chrootPath: "relative/path/*",
|
||||
expectedResult: "/cwd/relative/path/*",
|
||||
expectedError: nil,
|
||||
},
|
||||
{
|
||||
name: "relative path with no root",
|
||||
chrootContext: ChrootContext{
|
||||
root: "",
|
||||
cwdRelativeToRoot: "/cwd",
|
||||
},
|
||||
chrootPath: "relative/path/*",
|
||||
expectedResult: "/cwd/relative/path/*",
|
||||
expectedError: nil,
|
||||
},
|
||||
{
|
||||
name: "globs everywhere",
|
||||
chrootContext: ChrootContext{
|
||||
root: "/root",
|
||||
cwdRelativeToRoot: "/cwd",
|
||||
},
|
||||
chrootPath: "relative/path/**/file*.txt",
|
||||
expectedResult: "/cwd/relative/path/**/file*.txt",
|
||||
expectedError: nil,
|
||||
},
|
||||
}
|
||||
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
result, err := tt.chrootContext.ToNativeGlob(tt.chrootPath)
|
||||
|
||||
if tt.expectedError != nil {
|
||||
assert.Error(t, err)
|
||||
assert.Equal(t, tt.expectedError, err)
|
||||
} else {
|
||||
assert.NoError(t, err)
|
||||
assert.Equal(t, tt.expectedResult, result)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
@@ -145,13 +145,21 @@ func (r Directory) FilesByPath(userPaths ...string) ([]file.Location, error) {
|
||||
return references, nil
|
||||
}
|
||||
|
||||
func (r Directory) requestGlob(pattern string) (string, error) {
|
||||
return r.chroot.ToNativeGlob(pattern)
|
||||
}
|
||||
|
||||
// FilesByGlob returns all file.References that match the given path glob pattern from any layer in the image.
|
||||
func (r Directory) FilesByGlob(patterns ...string) ([]file.Location, error) {
|
||||
uniqueFileIDs := stereoscopeFile.NewFileReferenceSet()
|
||||
uniqueLocations := make([]file.Location, 0)
|
||||
|
||||
for _, pattern := range patterns {
|
||||
refVias, err := r.searchContext.SearchByGlob(pattern, filetree.FollowBasenameLinks)
|
||||
requestGlob, err := r.requestGlob(pattern)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
refVias, err := r.searchContext.SearchByGlob(requestGlob, filetree.FollowBasenameLinks)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
@@ -27,6 +27,7 @@ func AllTypes() []any {
|
||||
pkg.HackageStackYamlEntry{},
|
||||
pkg.HackageStackYamlLockEntry{},
|
||||
pkg.JavaArchive{},
|
||||
pkg.JavaVMInstallation{},
|
||||
pkg.LinuxKernel{},
|
||||
pkg.LinuxKernelModule{},
|
||||
pkg.LuaRocksPackage{},
|
||||
|
||||
@@ -81,6 +81,7 @@ var jsonTypes = makeJSONTypes(
|
||||
jsonNames(pkg.HackageStackYamlLockEntry{}, "haskell-hackage-stack-lock-entry", "HackageMetadataType"),
|
||||
jsonNamesWithoutLookup(pkg.HackageStackYamlEntry{}, "haskell-hackage-stack-entry", "HackageMetadataType"), // the legacy value is split into two types, where the other is preferred
|
||||
jsonNames(pkg.JavaArchive{}, "java-archive", "JavaMetadata"),
|
||||
jsonNames(pkg.JavaVMInstallation{}, "java-jvm-installation"),
|
||||
jsonNames(pkg.MicrosoftKbPatch{}, "microsoft-kb-patch", "KbPatchMetadata"),
|
||||
jsonNames(pkg.LinuxKernel{}, "linux-kernel-archive", "LinuxKernel"),
|
||||
jsonNames(pkg.LinuxKernelModule{}, "linux-kernel-module", "LinuxKernelModule"),
|
||||
|
||||
Reference in New Issue
Block a user