Skip to content

Commit 1015d15

Browse files
willww64vvolandthaJeztah
committed
fix bug with config file being a relative symlink
- use filepath.EvalSymlink instead of check with filepath.IsAbs - allow for dangling symlinks - extract path from error when NotExist error occurs Co-authored-by: Paweł Gronowski <me@woland.xyz> Co-authored-by: Sebastiaan van Stijn <github@gone.nl> Signed-off-by: Will Wang <willww64@gmail.com> Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
1 parent ae922ec commit 1015d15

File tree

2 files changed

+36
-2
lines changed

2 files changed

+36
-2
lines changed

cli/config/configfile/file.go

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -169,10 +169,16 @@ func (configFile *ConfigFile) Save() (retErr error) {
169169
return errors.Wrap(err, "error closing temp file")
170170
}
171171

172-
// Handle situation where the configfile is a symlink
172+
// Handle situation where the configfile is a symlink, and allow for dangling symlinks
173173
cfgFile := configFile.Filename
174-
if f, err := os.Readlink(cfgFile); err == nil {
174+
if f, err := filepath.EvalSymlinks(cfgFile); err == nil {
175175
cfgFile = f
176+
} else if os.IsNotExist(err) {
177+
// extract the path from the error if the configfile does not exist or is a dangling symlink
178+
var pathError *os.PathError
179+
if errors.As(err, &pathError) {
180+
cfgFile = pathError.Path
181+
}
176182
}
177183

178184
// Try copying the current config file (if any) ownership and permissions

cli/config/configfile/file_test.go

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -538,6 +538,34 @@ func TestSaveWithSymlink(t *testing.T) {
538538
assert.Check(t, is.Equal(string(cfg), "{\n \"auths\": {}\n}"))
539539
}
540540

541+
func TestSaveWithRelativeSymlink(t *testing.T) {
542+
dir := fs.NewDir(t, t.Name(), fs.WithFile("real-config.json", `{}`))
543+
defer dir.Remove()
544+
545+
symLink := dir.Join("config.json")
546+
relativeRealFile := "real-config.json"
547+
realFile := dir.Join(relativeRealFile)
548+
err := os.Symlink(relativeRealFile, symLink)
549+
assert.NilError(t, err)
550+
551+
configFile := New(symLink)
552+
553+
err = configFile.Save()
554+
assert.NilError(t, err)
555+
556+
fi, err := os.Lstat(symLink)
557+
assert.NilError(t, err)
558+
assert.Assert(t, fi.Mode()&os.ModeSymlink != 0, "expected %s to be a symlink", symLink)
559+
560+
cfg, err := os.ReadFile(symLink)
561+
assert.NilError(t, err)
562+
assert.Check(t, is.Equal(string(cfg), "{\n \"auths\": {}\n}"))
563+
564+
cfg, err = os.ReadFile(realFile)
565+
assert.NilError(t, err)
566+
assert.Check(t, is.Equal(string(cfg), "{\n \"auths\": {}\n}"))
567+
}
568+
541569
func TestPluginConfig(t *testing.T) {
542570
configFile := New("test-plugin")
543571
defer os.Remove("test-plugin")

0 commit comments

Comments
 (0)