Update tar path resolution
Fixes bug for resolving symlinks which allowed fully resolving an existing symlink to a path, causing some symlinks to get overridden as symlinks to self. Updates logic to split name into parent path, resolve the parent path, then safely join back with the base name. Uses the split code to ensure parent directories are created in all cases. Replaces `rootJoin` with filepath.Join to the root, which already correctly cleans relative symlinks to the root. Signed-off-by: Derek McGowan <derek@mcgstyle.net>
This commit is contained in:
@@ -126,19 +126,30 @@ func Apply(ctx context.Context, root string, r io.Reader) (int64, error) {
|
||||
continue
|
||||
}
|
||||
|
||||
// Note as these operations are platform specific, so must the slash be.
|
||||
if !strings.HasSuffix(hdr.Name, string(os.PathSeparator)) {
|
||||
// Not the root directory, ensure that the parent directory exists.
|
||||
// This happened in some tests where an image had a tarfile without any
|
||||
// parent directories.
|
||||
parent := filepath.Dir(hdr.Name)
|
||||
parentPath, err := rootPath(root, parent)
|
||||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
// Split name and resolve symlinks for root directory.
|
||||
ppath, base := filepath.Split(hdr.Name)
|
||||
ppath, err = rootPath(root, ppath)
|
||||
if err != nil {
|
||||
return 0, errors.Wrap(err, "failed to get root path")
|
||||
}
|
||||
|
||||
// Join to root before joining to parent path to ensure relative links are
|
||||
// already resolved based on the root before adding to parent.
|
||||
path := filepath.Join(ppath, filepath.Join("/", base))
|
||||
if path == root {
|
||||
log.G(ctx).Debugf("file %q ignored: resolved to root", hdr.Name)
|
||||
continue
|
||||
}
|
||||
|
||||
// If file is not directly under root, ensure parent directory
|
||||
// exists or is created.
|
||||
if ppath != root {
|
||||
parentPath := ppath
|
||||
if base == "" {
|
||||
parentPath = filepath.Dir(path)
|
||||
}
|
||||
if _, err := os.Lstat(parentPath); err != nil && os.IsNotExist(err) {
|
||||
err = mkdirAll(parentPath, 0600)
|
||||
err = mkdirAll(parentPath, 0700)
|
||||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
@@ -173,13 +184,6 @@ func Apply(ctx context.Context, root string, r io.Reader) (int64, error) {
|
||||
}
|
||||
}
|
||||
|
||||
path, err := rootPath(root, hdr.Name)
|
||||
if err != nil {
|
||||
return 0, errors.Wrap(err, "failed to get root path")
|
||||
}
|
||||
|
||||
base := filepath.Base(path)
|
||||
|
||||
if strings.HasPrefix(base, whiteoutPrefix) {
|
||||
dir := filepath.Dir(path)
|
||||
if base == whiteoutOpaqueDir {
|
||||
|
Reference in New Issue
Block a user