Skip to content

Commit bd27f87

Browse files
authored
Merge pull request #44 from woky/list-implicit-directories
slicer: Fix checking directory paths for listing
2 parents c30c81f + e0f6604 commit bd27f87

File tree

3 files changed

+72
-14
lines changed

3 files changed

+72
-14
lines changed

internal/scripts/scripts.go

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
11
package scripts
22

33
import (
4-
"go.starlark.net/starlark"
54
"go.starlark.net/resolve"
5+
"go.starlark.net/starlark"
66

77
"fmt"
88
"io/ioutil"
@@ -98,7 +98,7 @@ func (c *ContentValue) RealPath(path string, what Check) (string, error) {
9898
return "", fmt.Errorf("content path must be absolute, got: %s", path)
9999
}
100100
cpath := filepath.Clean(path)
101-
if strings.HasSuffix(path, "/") {
101+
if cpath != "/" && strings.HasSuffix(path, "/") {
102102
cpath += "/"
103103
}
104104
if c.CheckRead != nil && what&CheckRead != 0 {

internal/slicer/slicer.go

Lines changed: 33 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -33,20 +33,24 @@ func Run(options *RunOptions) error {
3333
knownPaths["/"] = true
3434

3535
addKnownPath := func(path string) {
36-
path = filepath.Clean(path)
3736
if path[0] != '/' {
3837
panic("bug: tried to add relative path to known paths")
3938
}
39+
cleanPath := filepath.Clean(path)
40+
slashPath := cleanPath
41+
if path[len(path)-1] == '/' && cleanPath != "/" {
42+
slashPath += "/"
43+
}
4044
for {
41-
if _, ok := knownPaths[path]; ok {
45+
if _, ok := knownPaths[slashPath]; ok {
4246
break
4347
}
44-
knownPaths[path] = true
45-
path = filepath.Dir(path)
46-
if path == "/" {
48+
knownPaths[slashPath] = true
49+
cleanPath = filepath.Dir(cleanPath)
50+
if cleanPath == "/" {
4751
break
4852
}
49-
path += "/"
53+
slashPath = cleanPath + "/"
5054
}
5155
}
5256

@@ -84,6 +88,7 @@ func Run(options *RunOptions) error {
8488
}
8589
arch := archives[slice.Package].Options().Arch
8690
copyrightPath := "/usr/share/doc/" + slice.Package + "/copyright"
91+
addKnownPath(copyrightPath)
8792
hasCopyright := false
8893
for targetPath, pathInfo := range slice.Contents {
8994
if targetPath == "" {
@@ -92,7 +97,9 @@ func Run(options *RunOptions) error {
9297
if len(pathInfo.Arch) > 0 && !contains(pathInfo.Arch, arch) {
9398
continue
9499
}
95-
addKnownPath(targetPath)
100+
if pathInfo.Kind != setup.GlobPath {
101+
addKnownPath(targetPath)
102+
}
96103
pathInfos[targetPath] = pathInfo
97104
if pathInfo.Kind == setup.CopyPath || pathInfo.Kind == setup.GlobPath {
98105
sourcePath := pathInfo.Info
@@ -225,10 +232,27 @@ func Run(options *RunOptions) error {
225232
return nil
226233
}
227234
checkRead := func(path string) error {
235+
var err error
228236
if !knownPaths[path] {
229-
return fmt.Errorf("cannot read file which is not selected: %s", path)
237+
// we assume that path is clean and ends with slash if it designates a directory
238+
if path[len(path)-1] == '/' {
239+
if path == "/" {
240+
panic("internal error: content root (\"/\") is not selected")
241+
}
242+
if knownPaths[path[:len(path)-1]] {
243+
err = fmt.Errorf("content is not a directory: %s", path[:len(path)-1])
244+
} else {
245+
err = fmt.Errorf("cannot list directory which is not selected: %s", path)
246+
}
247+
} else {
248+
if knownPaths[path+"/"] {
249+
err = fmt.Errorf("content is not a file: %s", path)
250+
} else {
251+
err = fmt.Errorf("cannot read file which is not selected: %s", path)
252+
}
253+
}
230254
}
231-
return nil
255+
return err
232256
}
233257
content := &scripts.ContentValue{
234258
RootDir: targetDirAbs,

internal/slicer/slicer_test.go

Lines changed: 37 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -383,7 +383,7 @@ var slicerTests = []slicerTest{{
383383
content.list("/a/d")
384384
`,
385385
},
386-
error: `slice base-files_myslice: cannot read file which is not selected: /a/d`,
386+
error: `slice base-files_myslice: cannot list directory which is not selected: /a/d/`,
387387
}, {
388388
summary: "Cannot list file path as a directory",
389389
slices: []setup.SliceKey{{"base-files", "myslice"}},
@@ -398,7 +398,7 @@ var slicerTests = []slicerTest{{
398398
content.list("/a/b/c")
399399
`,
400400
},
401-
error: `slice base-files_myslice: readdirent /a/b/c: not a directory`,
401+
error: `slice base-files_myslice: content is not a directory: /a/b/c`,
402402
}, {
403403
summary: "Can list parent directories of globs",
404404
slices: []setup.SliceKey{{"base-files", "myslice"}},
@@ -427,7 +427,7 @@ var slicerTests = []slicerTest{{
427427
content.list("/etc")
428428
`,
429429
},
430-
error: `slice base-files_myslice: cannot read file which is not selected: /etc`,
430+
error: `slice base-files_myslice: cannot list directory which is not selected: /etc/`,
431431
}, {
432432
summary: "Duplicate copyright symlink is ignored",
433433
slices: []setup.SliceKey{{"copyright-symlink-openssl", "bins"}},
@@ -453,6 +453,40 @@ var slicerTests = []slicerTest{{
453453
/etc/ssl/openssl.cnf:
454454
`,
455455
},
456+
}, {
457+
summary: "Can list unclean directory paths",
458+
slices: []setup.SliceKey{{"base-files", "myslice"}},
459+
release: map[string]string{
460+
"slices/mydir/base-files.yaml": `
461+
package: base-files
462+
slices:
463+
myslice:
464+
contents:
465+
/a/b/c: {text: foo}
466+
/x/y/: {make: true}
467+
mutate: |
468+
content.list("/////")
469+
content.list("/a/")
470+
content.list("/a/b/../b/")
471+
content.list("/x///")
472+
content.list("/x/./././y")
473+
`,
474+
},
475+
}, {
476+
summary: "Cannot read directories",
477+
slices: []setup.SliceKey{{"base-files", "myslice"}},
478+
release: map[string]string{
479+
"slices/mydir/base-files.yaml": `
480+
package: base-files
481+
slices:
482+
myslice:
483+
contents:
484+
/x/y/: {make: true}
485+
mutate: |
486+
content.read("/x/y")
487+
`,
488+
},
489+
error: `slice base-files_myslice: content is not a file: /x/y`,
456490
}}
457491

458492
const defaultChiselYaml = `

0 commit comments

Comments
 (0)