diff options
| author | Péter Surányi <speter.go1@gmail.com> | 2013-02-20 16:19:52 +1100 |
|---|---|---|
| committer | Alex Brainman <alex.brainman@gmail.com> | 2013-02-20 16:19:52 +1100 |
| commit | b4109f801a2b51978e1ddc1918a4558a8d8ba36c (patch) | |
| tree | 7942302d167e708a2dac7991e43cb71726790925 /src/pkg/os/exec | |
| parent | e378aef1def490cec4b86e2d341a287b5286d01f (diff) | |
| download | go-b4109f801a2b51978e1ddc1918a4558a8d8ba36c.tar.xz | |
path/filepath, os/exec: unquote PATH elements on Windows
On Windows, directory names in PATH can be fully or partially quoted
in double quotes ('"'), but the path names as used by most APIs must
be unquoted. In addition, quoted names can contain the semicolon
(';') character, which is otherwise used as ListSeparator.
This CL changes SplitList in path/filepath and LookPath in os/exec
to only treat unquoted semicolons as separators, and to unquote the
separated elements.
(In addition, fix harmless test bug I introduced for LookPath on Unix.)
Related discussion thread:
https://groups.google.com/d/msg/golang-nuts/PXCr10DsRb4/sawZBM7scYgJ
R=rsc, minux.ma, mccoyst, alex.brainman, iant
CC=golang-dev
https://golang.org/cl/7181047
Diffstat (limited to 'src/pkg/os/exec')
| -rw-r--r-- | src/pkg/os/exec/lp_unix_test.go | 5 | ||||
| -rw-r--r-- | src/pkg/os/exec/lp_windows.go | 35 |
2 files changed, 38 insertions, 2 deletions
diff --git a/src/pkg/os/exec/lp_unix_test.go b/src/pkg/os/exec/lp_unix_test.go index 3cba13e427..625d784864 100644 --- a/src/pkg/os/exec/lp_unix_test.go +++ b/src/pkg/os/exec/lp_unix_test.go @@ -32,7 +32,10 @@ func TestLookPathUnixEmptyPath(t *testing.T) { if err != nil { t.Fatal("OpenFile failed: ", err) } - defer f.Close() + err = f.Close() + if err != nil { + t.Fatal("Close failed: ", err) + } pathenv := os.Getenv("PATH") defer os.Setenv("PATH", pathenv) diff --git a/src/pkg/os/exec/lp_windows.go b/src/pkg/os/exec/lp_windows.go index d8351d7e6d..7c7289bcee 100644 --- a/src/pkg/os/exec/lp_windows.go +++ b/src/pkg/os/exec/lp_windows.go @@ -72,7 +72,7 @@ func LookPath(file string) (f string, err error) { return } if pathenv := os.Getenv(`PATH`); pathenv != `` { - for _, dir := range strings.Split(pathenv, `;`) { + for _, dir := range splitList(pathenv) { if f, err = findExecutable(dir+`\`+file, exts); err == nil { return } @@ -80,3 +80,36 @@ func LookPath(file string) (f string, err error) { } return ``, &Error{file, ErrNotFound} } + +func splitList(path string) []string { + // The same implementation is used in SplitList in path/filepath; + // consider changing path/filepath when changing this. + + if path == "" { + return []string{} + } + + // Split path, respecting but preserving quotes. + list := []string{} + start := 0 + quo := false + for i := 0; i < len(path); i++ { + switch c := path[i]; { + case c == '"': + quo = !quo + case c == os.PathListSeparator && !quo: + list = append(list, path[start:i]) + start = i + 1 + } + } + list = append(list, path[start:]) + + // Remove quotes. + for i, s := range list { + if strings.Contains(s, `"`) { + list[i] = strings.Replace(s, `"`, ``, -1) + } + } + + return list +} |
