Skip to content

Commit

Permalink
Recognize circular links
Browse files Browse the repository at this point in the history
  • Loading branch information
MDrakos committed Nov 14, 2024
1 parent fbf7ca2 commit b3fd6ae
Showing 1 changed file with 35 additions and 0 deletions.
35 changes: 35 additions & 0 deletions internal/smartlink/smartlink.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import (
"github.com/ActiveState/cli/internal/errs"
"github.com/ActiveState/cli/internal/fileutils"
"github.com/ActiveState/cli/internal/logging"
"github.com/ActiveState/cli/internal/multilog"
)

// LinkContents will link the contents of src to desc
Expand Down Expand Up @@ -55,6 +56,15 @@ func Link(src, dest string) error {
return errs.Wrap(err, "could not read directory %s", src)
}
for _, entry := range entries {
circular, err := isCircularLink(filepath.Join(src, entry.Name()))
if err != nil {
return errs.Wrap(err, "could not check for circular link")
}
if circular {
multilog.Error("Build contains a circular symlink: %s -> %s", filepath.Join(src, entry.Name()), dest)
continue
}

if err := Link(filepath.Join(src, entry.Name()), filepath.Join(dest, entry.Name())); err != nil {
return errs.Wrap(err, "sub link failed")
}
Expand All @@ -80,6 +90,31 @@ func Link(src, dest string) error {
return nil
}

func isCircularLink(src string) (bool, error) {
if !fileutils.IsSymlink(src) {
return false, nil
}

target, err := os.Readlink(src)
if err != nil {
return false, errs.Wrap(err, "could not read symlink %s", src)
}

if !filepath.IsAbs(target) {
resolved, err := fileutils.ResolveUniquePath(src)
if err != nil {
return false, errs.Wrap(err, "Could not resolve src path")
}
target = resolved
}

if fileutils.IsDir(src) && filepath.Dir(src) == target {
return true, nil
}

return false, nil
}

// UnlinkContents will unlink the contents of src to dest if the links exist
// WARNING: on windows smartlinks are hard links, and relating hard links back to their source is non-trivial, so instead
// we just delete the target path. If the user modified the target in any way their changes will be lost.
Expand Down

0 comments on commit b3fd6ae

Please sign in to comment.