diff options
Diffstat (limited to 'src/cmd/goinstall')
-rw-r--r-- | src/cmd/goinstall/download.go | 19 | ||||
-rw-r--r-- | src/cmd/goinstall/main.go | 11 | ||||
-rw-r--r-- | src/cmd/goinstall/make.go | 23 | ||||
-rw-r--r-- | src/cmd/goinstall/parse.go | 12 |
4 files changed, 45 insertions, 20 deletions
diff --git a/src/cmd/goinstall/download.go b/src/cmd/goinstall/download.go index 889f9d857..88befc0dc 100644 --- a/src/cmd/goinstall/download.go +++ b/src/cmd/goinstall/download.go @@ -9,7 +9,7 @@ package main import ( "http" "os" - "path" + "path/filepath" "regexp" "strings" ) @@ -42,7 +42,7 @@ func download(pkg string) (string, os.Error) { return "", os.ErrorString("invalid path (contains ..)") } if m := bitbucket.FindStringSubmatch(pkg); m != nil { - if err := vcsCheckout(&hg, root+m[1], "http://"+m[1], m[1]); err != nil { + if err := vcsCheckout(&hg, m[1], "http://"+m[1], m[1]); err != nil { return "", err } return root + pkg, nil @@ -58,7 +58,7 @@ func download(pkg string) (string, os.Error) { // regexp only allows hg, svn to get through panic("missing case in download: " + pkg) } - if err := vcsCheckout(v, root+m[1], "https://"+m[1], m[1]); err != nil { + if err := vcsCheckout(v, m[1], "https://"+m[1], m[1]); err != nil { return "", err } return root + pkg, nil @@ -67,7 +67,7 @@ func download(pkg string) (string, os.Error) { if strings.HasSuffix(m[1], ".git") { return "", os.ErrorString("repository " + pkg + " should not have .git suffix") } - if err := vcsCheckout(&git, root+m[1], "http://"+m[1]+".git", m[1]); err != nil { + if err := vcsCheckout(&git, m[1], "http://"+m[1]+".git", m[1]); err != nil { return "", err } return root + pkg, nil @@ -75,7 +75,7 @@ func download(pkg string) (string, os.Error) { if m := launchpad.FindStringSubmatch(pkg); m != nil { // Either lp.net/<project>[/<series>[/<path>]] // or lp.net/~<user or team>/<project>/<branch>[/<path>] - if err := vcsCheckout(&bzr, root+m[1], "https://"+m[1], m[1]); err != nil { + if err := vcsCheckout(&bzr, m[1], "https://"+m[1], m[1]); err != nil { return "", err } return root + pkg, nil @@ -172,17 +172,18 @@ func (v *vcs) updateRepo(dst string) os.Error { // exists and -u was specified on the command line) // the repository at tag/branch "release". If there is no // such tag or branch, it falls back to the repository tip. -func vcsCheckout(vcs *vcs, dst, repo, dashpath string) os.Error { - dir, err := os.Stat(dst + "/" + vcs.metadir) +func vcsCheckout(vcs *vcs, pkgprefix, repo, dashpath string) os.Error { + dst := filepath.Join(root, filepath.FromSlash(pkgprefix)) + dir, err := os.Stat(filepath.Join(dst, vcs.metadir)) if err == nil && !dir.IsDirectory() { return os.ErrorString("not a directory: " + dst) } if err != nil { - parent, _ := path.Split(dst) + parent, _ := filepath.Split(dst) if err := os.MkdirAll(parent, 0777); err != nil { return err } - if err := run("/", nil, vcs.cmd, vcs.clone, repo, dst); err != nil { + if err := run(string(filepath.Separator), nil, vcs.cmd, vcs.clone, repo, dst); err != nil { return err } if err := vcs.updateRepo(dst); err != nil { diff --git a/src/cmd/goinstall/main.go b/src/cmd/goinstall/main.go index f13aeb3bc..34441be45 100644 --- a/src/cmd/goinstall/main.go +++ b/src/cmd/goinstall/main.go @@ -15,7 +15,7 @@ import ( "io" "io/ioutil" "os" - "path" + "path/filepath" "runtime" "strings" ) @@ -34,7 +34,7 @@ var ( parents = make(map[string]string) root = runtime.GOROOT() visit = make(map[string]status) - logfile = path.Join(root, "goinstall.log") + logfile = filepath.Join(root, "goinstall.log") installedPkgs = make(map[string]bool) allpkg = flag.Bool("a", false, "install all previously installed packages") @@ -59,7 +59,7 @@ func main() { fmt.Fprintf(os.Stderr, "%s: no $GOROOT\n", argv0) os.Exit(1) } - root += "/src/pkg/" + root += filepath.FromSlash("/src/pkg/") // special case - "unsafe" is already installed visit["unsafe"] = done @@ -160,7 +160,7 @@ func install(pkg, parent string) { dir = pkg local = true } else if isStandardPath(pkg) { - dir = path.Join(root, pkg) + dir = filepath.Join(root, filepath.FromSlash(pkg)) local = true } else { var err os.Error @@ -216,7 +216,8 @@ func install(pkg, parent string) { // Is this a local path? /foo ./foo ../foo . .. func isLocalPath(s string) bool { - return strings.HasPrefix(s, "/") || strings.HasPrefix(s, "./") || strings.HasPrefix(s, "../") || s == "." || s == ".." + const sep = string(filepath.Separator) + return strings.HasPrefix(s, sep) || strings.HasPrefix(s, "."+sep) || strings.HasPrefix(s, ".."+sep) || s == "." || s == ".." } // Is this a standard package path? strings container/vector etc. diff --git a/src/cmd/goinstall/make.go b/src/cmd/goinstall/make.go index 8d4d6c5d2..e2d99bb47 100644 --- a/src/cmd/goinstall/make.go +++ b/src/cmd/goinstall/make.go @@ -44,6 +44,9 @@ func domake(dir, pkg string, local bool) (err os.Error) { // installing as package pkg. It includes all *.go files in the directory // except those in package main and those ending in _test.go. func makeMakefile(dir, pkg string) ([]byte, os.Error) { + if !safeName(pkg) { + return nil, os.ErrorString("unsafe name: " + pkg) + } dirInfo, err := scanDir(dir, false) if err != nil { return nil, err @@ -58,16 +61,25 @@ func makeMakefile(dir, pkg string) ([]byte, os.Error) { cgoFiles := dirInfo.cgoFiles isCgo := make(map[string]bool, len(cgoFiles)) for _, file := range cgoFiles { + if !safeName(file) { + return nil, os.ErrorString("bad name: " + file) + } isCgo[file] = true } oFiles := make([]string, 0, len(dirInfo.cFiles)) for _, file := range dirInfo.cFiles { + if !safeName(file) { + return nil, os.ErrorString("unsafe name: " + file) + } oFiles = append(oFiles, file[:len(file)-2]+".o") } goFiles := make([]string, 0, len(dirInfo.goFiles)) for _, file := range dirInfo.goFiles { + if !safeName(file) { + return nil, os.ErrorString("unsafe name: " + file) + } if !isCgo[file] { goFiles = append(goFiles, file) } @@ -81,6 +93,17 @@ func makeMakefile(dir, pkg string) ([]byte, os.Error) { return buf.Bytes(), nil } +var safeBytes = []byte("+-./0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ_abcdefghijklmnopqrstuvwxyz") + +func safeName(s string) bool { + for i := 0; i < len(s); i++ { + if c := s[i]; c < 0x80 && bytes.IndexByte(safeBytes, c) < 0 { + return false + } + } + return true +} + // makedata is the data type for the makefileTemplate. type makedata struct { Pkg string // package import path diff --git a/src/cmd/goinstall/parse.go b/src/cmd/goinstall/parse.go index 679edfabc..014b8fcb2 100644 --- a/src/cmd/goinstall/parse.go +++ b/src/cmd/goinstall/parse.go @@ -7,13 +7,13 @@ package main import ( - "path" - "os" - "log" - "strings" - "strconv" "go/ast" "go/parser" + "log" + "os" + "path/filepath" + "strconv" + "strings" ) @@ -64,7 +64,7 @@ func scanDir(dir string, allowMain bool) (info *dirInfo, err os.Error) { if !strings.HasSuffix(d.Name, ".go") || strings.HasSuffix(d.Name, "_test.go") { continue } - filename := path.Join(dir, d.Name) + filename := filepath.Join(dir, d.Name) pf, err := parser.ParseFile(fset, filename, nil, parser.ImportsOnly) if err != nil { return nil, err |