Skip to content

Commit

Permalink
A quick fix to handle symbolic links
Browse files Browse the repository at this point in the history
  • Loading branch information
another-rex committed Nov 7, 2024
1 parent 81d656a commit bd6749a
Show file tree
Hide file tree
Showing 3 changed files with 45 additions and 13 deletions.
21 changes: 14 additions & 7 deletions internal/image/image.go
Original file line number Diff line number Diff line change
Expand Up @@ -180,6 +180,7 @@ func LoadImage(imagePath string) (*Image, error) {
// filepath.Clean first to convert to OS specific file path
// TODO: Escape invalid characters on windows that's valid on linux
absoluteDiskPath := filepath.Join(dirPath, filepath.Clean(cleanedFilePath))
symlinkTarget := ""

var fileType fileType
// write out the file/dir to disk
Expand All @@ -191,8 +192,7 @@ func LoadImage(imagePath string) (*Image, error) {
}
}
fileType = Dir

default: // Assume if it's not a directory, it's a normal file
case tar.TypeReg:
// Write all files as read/writable by the current user, inaccessible by anyone else
// Actual permission bits are stored in FileNode
f, err := os.OpenFile(absoluteDiskPath, os.O_CREATE|os.O_RDWR, filePermission)
Expand All @@ -210,6 +210,11 @@ func LoadImage(imagePath string) (*Image, error) {
}
fileType = RegularFile
f.Close()
case tar.TypeSymlink:
fileType = Symlink
symlinkTarget = header.Linkname
default: // Assume if it's not a directory or normal file
// TODO: Handle these cases
}

// Each outer loop, we add a layer to each relevant output flattenedLayers slice
Expand Down Expand Up @@ -238,11 +243,13 @@ func LoadImage(imagePath string) (*Image, error) {
err := currentMap.fileNodeTrie.Insert(virtualPath, &FileNode{
rootImage: &outputImage,
// Select the original layer of the file
originLayer: &outputImage.layers[i],
virtualPath: virtualPath,
fileType: fileType,
isWhiteout: tombstone,
permission: fs.FileMode(header.Mode), //nolint:gosec
originLayer: &outputImage.layers[i],
virtualPath: virtualPath,
fileType: fileType,
linkTargetPath: symlinkTarget,
isWhiteout: tombstone,
// TODO: Fix file mode bits to contain the high bits
permission: fs.FileMode(header.Mode), //nolint:gosec
})

if err != nil {
Expand Down
30 changes: 24 additions & 6 deletions internal/image/layer.go
Original file line number Diff line number Diff line change
Expand Up @@ -18,17 +18,20 @@ type fileType int
const (
RegularFile fileType = iota
Dir
Symlink
)

// FileNode represents a file on a specific layer, mapping the contents to an extracted file on disk
type FileNode struct {
// TODO: Determine the performance implications of having a pointer to base image in every fileNode
rootImage *Image
fileType fileType
isWhiteout bool
originLayer *Layer
virtualPath string
permission fs.FileMode
rootImage *Image
// TODO: Filetype is redundant if permission is set correctly
fileType fileType
isWhiteout bool
originLayer *Layer
virtualPath string
linkTargetPath string
permission fs.FileMode
}

var _ fs.DirEntry = FileNode{}
Expand Down Expand Up @@ -82,6 +85,13 @@ func (f FileNodeFileInfo) Sys() any {

// Stat returns the FileInfo structure describing file.
func (f *FileNode) Stat() (fs.FileInfo, error) {
// TODO: Implement this properly
if f.fileType == Symlink {
return FileNodeFileInfo{
fileNode: f,
}, nil
}

baseFileInfo, err := os.Stat(f.absoluteDiskPath())
if err != nil {
return nil, err
Expand Down Expand Up @@ -121,6 +131,10 @@ func (filemap Layer) Open(path string) (fs.File, error) {
return nil, err
}

if node.fileType == Symlink {
return filemap.Open(node.linkTargetPath)
}

return node.Open()
}

Expand All @@ -130,6 +144,10 @@ func (filemap Layer) Stat(path string) (fs.FileInfo, error) {
return nil, err
}

if node.fileType == Symlink {
return filemap.Stat(node.linkTargetPath)
}

return node.Stat()
}

Expand Down
7 changes: 7 additions & 0 deletions pkg/osvscanner/osvscanner.go
Original file line number Diff line number Diff line change
Expand Up @@ -1118,6 +1118,13 @@ func patchPackageForRequest(pkg scannedPackage) scannedPackage {
}
}

// TODO: This should be done on the osv.dev side
// This is needed because Ubuntu ecosystem appends LTS
// but the scanner does not have this information.
if pkg.Ecosystem == "Ubuntu:20.04" {
pkg.Ecosystem = "Ubuntu:20.04:LTS"
}

return pkg
}

Expand Down

0 comments on commit bd6749a

Please sign in to comment.