1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114
|
package main
import (
"fmt"
"strings"
)
const NAME_COLLISION_TAG = "program-name-collision"
type nameCollisionErr struct {
pkg string
programName string
otherProgramName string
isBashBuiltin bool
}
func (n nameCollisionErr) Error() string {
if n.isBashBuiltin {
return fmt.Sprintf("%s: %s %s (bash builtin command)", n.pkg, NAME_COLLISION_TAG, n.programName)
}
return fmt.Sprintf("%s: %s %s %s", n.pkg, NAME_COLLISION_TAG, n.programName, n.otherProgramName)
}
type collisionChecker struct {
sysDirs []string
acceptList map[string]string
bashBuiltins map[string]bool
bashAcceptList map[string]bool
emit bool
}
func newCollisionChecker(tags tagFilter) collisionChecker {
cc := collisionChecker{
sysDirs: []string{"/usr/sbin", "/usr/bin", "/sbin", "/bin", "/usr/games"},
acceptList: map[string]string{
// molly-guard: bugs #733213, #660064
"/usr/sbin/halt": "molly-guard",
"/usr/sbin/poweroff": "molly-guard",
"/usr/sbin/reboot": "molly-guard",
"/usr/sbin/shutdown": "molly-guard",
// safe-rm
"/usr/bin/rm": "safe-rm",
},
// Do not edit the following line manually: run
// private/update-bash-builtin-commands instead.
bashBuiltins: strToBoolMap(". [ alias bg bind break builtin caller case cd command compgen complete compopt continue coproc declare dirs disown echo enable eval exec exit export false fc fg for function getopts hash help history if jobs kill let local logout mapfile popd printf pushd pwd read readarray readonly return select set shift shopt source suspend test time times trap true type typeset ulimit umask unalias unset until variables wait while"),
bashAcceptList: strToBoolMap("coreutils time procps"),
emit: tags.shouldEmit(NAME_COLLISION_TAG),
}
return cc
}
func (cc collisionChecker) check(pkg2files map[string][]string) []error {
var tags []error
for pkg, files := range pkg2files {
pkgFiles := strSliceToBoolMap(files)
for _, file := range files {
for _, sdir := range cc.sysDirs {
suffix, ok := cutPrefix(file, sdir+"/")
if !ok {
continue
}
if !pathExists(file) {
continue
}
if !cc.bashAcceptList[pkg] && cc.bashBuiltins[suffix] {
tags = append(tags, nameCollisionErr{
pkg: pkg,
programName: file,
isBashBuiltin: true,
})
}
for _, dDir := range cc.sysDirs {
dFile := dDir + "/" + suffix
_, acceptListed := cc.acceptList[dFile]
if !pathExists(dFile) ||
pkgFiles[dFile] ||
acceptListed ||
cc.acceptList[file] == pkg ||
sameFile(file, dFile) {
continue
}
tags = append(tags, nameCollisionErr{
pkg: pkg,
programName: file,
otherProgramName: dFile,
})
}
break
}
}
}
return tags
}
func strToBoolMap(s string) map[string]bool {
return strSliceToBoolMap(strings.Split(s, " "))
}
func strSliceToBoolMap(keys []string) map[string]bool {
m := make(map[string]bool, len(keys))
for _, k := range keys {
m[k] = true
}
return m
}
|