2013-12-17 07:52:32 -07:00
|
|
|
// Copyright 2013 The Go Authors. All rights reserved.
|
|
|
|
// Use of this source code is governed by a BSD-style
|
|
|
|
// license that can be found in the LICENSE file.
|
|
|
|
|
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
2013-02-19 22:19:52 -07:00
|
|
|
package filepath_test
|
|
|
|
|
|
|
|
import (
|
|
|
|
"io/ioutil"
|
|
|
|
"os"
|
|
|
|
"os/exec"
|
|
|
|
"path/filepath"
|
|
|
|
"reflect"
|
|
|
|
"testing"
|
|
|
|
)
|
|
|
|
|
|
|
|
func TestWinSplitListTestsAreValid(t *testing.T) {
|
|
|
|
comspec := os.Getenv("ComSpec")
|
|
|
|
if comspec == "" {
|
|
|
|
t.Fatal("%ComSpec% must be set")
|
|
|
|
}
|
|
|
|
|
|
|
|
for ti, tt := range winsplitlisttests {
|
|
|
|
testWinSplitListTestIsValid(t, ti, tt, comspec)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
func testWinSplitListTestIsValid(t *testing.T, ti int, tt SplitListTest,
|
|
|
|
comspec string) {
|
|
|
|
|
|
|
|
const (
|
|
|
|
cmdfile = `printdir.cmd`
|
|
|
|
perm os.FileMode = 0700
|
|
|
|
)
|
|
|
|
|
|
|
|
tmp, err := ioutil.TempDir("", "testWinSplitListTestIsValid")
|
|
|
|
if err != nil {
|
|
|
|
t.Fatalf("TempDir failed: %v", err)
|
|
|
|
}
|
|
|
|
defer os.RemoveAll(tmp)
|
|
|
|
|
|
|
|
for i, d := range tt.result {
|
|
|
|
if d == "" {
|
|
|
|
continue
|
|
|
|
}
|
|
|
|
if cd := filepath.Clean(d); filepath.VolumeName(cd) != "" ||
|
|
|
|
cd[0] == '\\' || cd == ".." || (len(cd) >= 3 && cd[0:3] == `..\`) {
|
|
|
|
t.Errorf("%d,%d: %#q refers outside working directory", ti, i, d)
|
|
|
|
return
|
|
|
|
}
|
|
|
|
dd := filepath.Join(tmp, d)
|
|
|
|
if _, err := os.Stat(dd); err == nil {
|
|
|
|
t.Errorf("%d,%d: %#q already exists", ti, i, d)
|
|
|
|
return
|
|
|
|
}
|
|
|
|
if err = os.MkdirAll(dd, perm); err != nil {
|
|
|
|
t.Errorf("%d,%d: MkdirAll(%#q) failed: %v", ti, i, dd, err)
|
|
|
|
return
|
|
|
|
}
|
|
|
|
fn, data := filepath.Join(dd, cmdfile), []byte("@echo "+d+"\r\n")
|
|
|
|
if err = ioutil.WriteFile(fn, data, perm); err != nil {
|
|
|
|
t.Errorf("%d,%d: WriteFile(%#q) failed: %v", ti, i, fn, err)
|
|
|
|
return
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
for i, d := range tt.result {
|
|
|
|
if d == "" {
|
|
|
|
continue
|
|
|
|
}
|
|
|
|
exp := []byte(d + "\r\n")
|
|
|
|
cmd := &exec.Cmd{
|
|
|
|
Path: comspec,
|
|
|
|
Args: []string{`/c`, cmdfile},
|
|
|
|
Env: []string{`Path=` + tt.list},
|
|
|
|
Dir: tmp,
|
|
|
|
}
|
2013-02-28 20:49:55 -07:00
|
|
|
out, err := cmd.CombinedOutput()
|
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
2013-02-19 22:19:52 -07:00
|
|
|
switch {
|
|
|
|
case err != nil:
|
2013-02-28 20:49:55 -07:00
|
|
|
t.Errorf("%d,%d: execution error %v\n%q", ti, i, err, out)
|
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
2013-02-19 22:19:52 -07:00
|
|
|
return
|
|
|
|
case !reflect.DeepEqual(out, exp):
|
|
|
|
t.Errorf("%d,%d: expected %#q, got %#q", ti, i, exp, out)
|
|
|
|
return
|
|
|
|
default:
|
|
|
|
// unshadow cmdfile in next directory
|
|
|
|
err = os.Remove(filepath.Join(tmp, d, cmdfile))
|
|
|
|
if err != nil {
|
|
|
|
t.Fatalf("Remove test command failed: %v", err)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|