Skip to content
This repository has been archived by the owner on Feb 21, 2022. It is now read-only.

Commit

Permalink
cmd/plg: fix slice overwriting on expansion
Browse files Browse the repository at this point in the history
  • Loading branch information
gbrlsnchs committed May 1, 2020
1 parent 73f6141 commit 96ad402
Show file tree
Hide file tree
Showing 6 changed files with 427 additions and 7 deletions.
225 changes: 225 additions & 0 deletions cmd/plg/check_test.go
Expand Up @@ -973,6 +973,231 @@ func TestCheck(t *testing.T) {
conflicts: true,
err: nil,
},
{
// NOTE(gbrlsnchs): Bug caught on my own dotfiles.
name: "bug expand",
drv: fstest.InMemoryDriver{
CurrentDir: "home/dotfiles",
Files: map[string]fstest.File{
"home": {
Linkname: "",
Perm: os.ModePerm,
Data: nil,
Children: map[string]fstest.File{
"dotfiles": {
Linkname: "",
Perm: os.ModePerm,
Data: nil,
Children: map[string]fstest.File{
"root": {
Linkname: "",
Perm: os.ModePerm,
Data: nil,
Children: map[string]fstest.File{
"dir": {
Linkname: "",
Perm: os.ModePerm,
Data: nil,
Children: map[string]fstest.File{
"subdir": {
Linkname: "",
Perm: os.ModePerm,
Data: nil,
Children: map[string]fstest.File{
"target_1": {
Linkname: "",
Perm: os.ModePerm,
Data: nil,
Children: map[string]fstest.File{
"foo": {Data: []byte("foo")},
"bar": {Data: []byte("bar")},
},
},
"target_2": {
Linkname: "",
Perm: os.ModePerm,
Data: nil,
Children: map[string]fstest.File{
"baz": {Data: []byte("baz")},
},
},
},
},
},
},
},
},
"bug_expand.yml": {
Linkname: "",
Perm: os.ModePerm,
Data: yamlData(config.Config{
Targets: []string{"root"},
Options: map[string]*config.Config{
"root": {
BaseDir: fstest.AbsPath("etc"),
Targets: []string{"dir"},
Options: map[string]*config.Config{
"dir": {
Targets: []string{"subdir"},
Flatten: true,
},
},
Flatten: true,
},
},
}),
Children: nil,
},
},
},
},
},
"etc": {
Linkname: "",
Perm: os.ModePerm,
Data: nil,
Children: map[string]fstest.File{
"subdir": {
Linkname: "",
Perm: os.ModePerm,
Data: nil,
Children: map[string]fstest.File{
"target_1": {
Linkname: "",
Perm: os.ModePerm,
Data: nil,
Children: map[string]fstest.File{
"foo": {Data: []byte("foo")},
"bar": {Data: []byte("bar")},
},
},
"target_2": {
Linkname: "",
Perm: os.ModePerm,
Data: nil,
Children: map[string]fstest.File{
"qux": {Data: []byte("qux")},
},
},
},
},
},
},
},
},
cmd: checkCmd{},
want: fstest.InMemoryDriver{
CurrentDir: "home/dotfiles",
Files: map[string]fstest.File{
"home": {
Linkname: "",
Perm: os.ModePerm,
Data: nil,
Children: map[string]fstest.File{
"dotfiles": {
Linkname: "",
Perm: os.ModePerm,
Data: nil,
Children: map[string]fstest.File{
"root": {
Linkname: "",
Perm: os.ModePerm,
Data: nil,
Children: map[string]fstest.File{
"dir": {
Linkname: "",
Perm: os.ModePerm,
Data: nil,
Children: map[string]fstest.File{
"subdir": {
Linkname: "",
Perm: os.ModePerm,
Data: nil,
Children: map[string]fstest.File{
"target_1": {
Linkname: "",
Perm: os.ModePerm,
Data: nil,
Children: map[string]fstest.File{
"foo": {Data: []byte("foo")},
"bar": {Data: []byte("bar")},
},
},
"target_2": {
Linkname: "",
Perm: os.ModePerm,
Data: nil,
Children: map[string]fstest.File{
"baz": {Data: []byte("baz")},
},
},
},
},
},
},
},
},
"bug_expand.yml": {
Linkname: "",
Perm: os.ModePerm,
Data: yamlData(config.Config{
Targets: []string{"root"},
Options: map[string]*config.Config{
"root": {
BaseDir: fstest.AbsPath("etc"),
Targets: []string{"dir"},
Options: map[string]*config.Config{
"dir": {
Targets: []string{"subdir"},
Flatten: true,
},
},
Flatten: true,
},
},
}),
Children: nil,
},
},
},
},
},
"etc": {
Linkname: "",
Perm: os.ModePerm,
Data: nil,
Children: map[string]fstest.File{
"subdir": {
Linkname: "",
Perm: os.ModePerm,
Data: nil,
Children: map[string]fstest.File{
"target_1": {
Linkname: "",
Perm: os.ModePerm,
Data: nil,
Children: map[string]fstest.File{
"foo": {Data: []byte("foo")},
"bar": {Data: []byte("bar")},
},
},
"target_2": {
Linkname: "",
Perm: os.ModePerm,
Data: nil,
Children: map[string]fstest.File{
"qux": {Data: []byte("qux")},
},
},
},
},
},
},
},
},
conflicts: false,
err: nil,
},
}
for _, tc := range testCases {
t.Run(tc.name, func(t *testing.T) {
Expand Down
9 changes: 9 additions & 0 deletions cmd/plg/testdata/TestCheck/bug_expand/combined.golden
@@ -0,0 +1,9 @@
.
└── root (SKIP)
└── dir (SKIP)
└── subdir (EXPAND)
├── target_1 (EXPAND)
│ ├── bar <- ~etc/subdir/target_1/bar (CONFLICT)
│ └── foo <- ~etc/subdir/target_1/foo (CONFLICT)
└── target_2 (EXPAND)
└── baz <- ~etc/subdir/target_2/baz (READY)
9 changes: 9 additions & 0 deletions cmd/plg/testdata/TestCheck/bug_expand/stdout.golden
@@ -0,0 +1,9 @@
.
└── root (SKIP)
└── dir (SKIP)
└── subdir (EXPAND)
├── target_1 (EXPAND)
│ ├── bar <- ~etc/subdir/target_1/bar (CONFLICT)
│ └── foo <- ~etc/subdir/target_1/foo (CONFLICT)
└── target_2 (EXPAND)
└── baz <- ~etc/subdir/target_2/baz (READY)
6 changes: 4 additions & 2 deletions linker/linker.go
Expand Up @@ -145,14 +145,16 @@ func expand(n *parser.Node, children []fs.FileInfo) {
}
n.Children = make([]*parser.Node, len(children))
for i, c := range children {
tg := append(make([]string, 0, len(n.Target.Path) + 1), n.Target.Path...)
ln := append(make([]string, 0, len(n.Link.Path) + 1), n.Link.Path...)
n.Children[i] = &parser.Node{
Target: parser.File{
BaseDir: n.Target.BaseDir,
Path: append(n.Target.Path, c.Name()),
Path: append(tg, c.Name()),
},
Link: parser.File{
BaseDir: n.Link.BaseDir,
Path: append(n.Link.Path, c.Name()),
Path: append(ln, c.Name()),
},
Children: nil,
}
Expand Down

0 comments on commit 96ad402

Please sign in to comment.