aboutsummaryrefslogtreecommitdiff
path: root/libgo/go/path
diff options
context:
space:
mode:
authorIan Lance Taylor <ian@gcc.gnu.org>2019-03-18 20:27:59 +0000
committerIan Lance Taylor <ian@gcc.gnu.org>2019-03-18 20:27:59 +0000
commita8b58d84bf4fd9c925a835ba39c1c552383bc61b (patch)
tree97d68e0e70fb780b04f3171a0f53102a39c23f41 /libgo/go/path
parent891cd9e3b9a89b0461fb838d38c51b6fab596337 (diff)
downloadgcc-a8b58d84bf4fd9c925a835ba39c1c552383bc61b.zip
gcc-a8b58d84bf4fd9c925a835ba39c1c552383bc61b.tar.gz
gcc-a8b58d84bf4fd9c925a835ba39c1c552383bc61b.tar.bz2
libgo: update to Go 1.12.1
Reviewed-on: https://go-review.googlesource.com/c/gofrontend/+/167749 From-SVN: r269780
Diffstat (limited to 'libgo/go/path')
-rw-r--r--libgo/go/path/filepath/path.go11
-rw-r--r--libgo/go/path/filepath/path_test.go103
-rw-r--r--libgo/go/path/filepath/symlink.go10
3 files changed, 112 insertions, 12 deletions
diff --git a/libgo/go/path/filepath/path.go b/libgo/go/path/filepath/path.go
index bbb9030..aba1717 100644
--- a/libgo/go/path/filepath/path.go
+++ b/libgo/go/path/filepath/path.go
@@ -96,19 +96,14 @@ func Clean(path string) string {
}
return originalPath + "."
}
-
- n := len(path)
- if volLen > 2 && n == 1 && os.IsPathSeparator(path[0]) {
- // UNC volume name with trailing slash.
- return FromSlash(originalPath[:volLen])
- }
rooted := os.IsPathSeparator(path[0])
// Invariants:
// reading from path; r is index of next byte to process.
- // writing to out; w is index of next byte to write.
- // dotdot is index in out where .. must stop, either because
+ // writing to buf; w is index of next byte to write.
+ // dotdot is index in buf where .. must stop, either because
// it is the leading slash or it is a leading ../../.. prefix.
+ n := len(path)
out := lazybuf{path: path, volAndPath: originalPath, volLen: volLen}
r, dotdot := 0, 0
if rooted {
diff --git a/libgo/go/path/filepath/path_test.go b/libgo/go/path/filepath/path_test.go
index deeb47e..22632a0 100644
--- a/libgo/go/path/filepath/path_test.go
+++ b/libgo/go/path/filepath/path_test.go
@@ -93,9 +93,6 @@ var wincleantests = []PathTest{
{`//host/share/foo/../baz`, `\\host\share\baz`},
{`\\a\b\..\c`, `\\a\b\c`},
{`\\a\b`, `\\a\b`},
- {`\\a\b\`, `\\a\b`},
- {`\\folder\share\foo`, `\\folder\share\foo`},
- {`\\folder\share\foo\`, `\\folder\share\foo`},
}
func TestClean(t *testing.T) {
@@ -1417,3 +1414,103 @@ func TestIssue29372(t *testing.T) {
}
}
}
+
+// Issue 30520 part 1.
+func TestEvalSymlinksAboveRoot(t *testing.T) {
+ testenv.MustHaveSymlink(t)
+
+ t.Parallel()
+
+ tmpDir, err := ioutil.TempDir("", "TestEvalSymlinksAboveRoot")
+ if err != nil {
+ t.Fatal(err)
+ }
+ defer os.RemoveAll(tmpDir)
+
+ evalTmpDir, err := filepath.EvalSymlinks(tmpDir)
+ if err != nil {
+ t.Fatal(err)
+ }
+
+ if err := os.Mkdir(filepath.Join(evalTmpDir, "a"), 0777); err != nil {
+ t.Fatal(err)
+ }
+ if err := os.Symlink(filepath.Join(evalTmpDir, "a"), filepath.Join(evalTmpDir, "b")); err != nil {
+ t.Fatal(err)
+ }
+ if err := ioutil.WriteFile(filepath.Join(evalTmpDir, "a", "file"), nil, 0666); err != nil {
+ t.Fatal(err)
+ }
+
+ // Count the number of ".." elements to get to the root directory.
+ vol := filepath.VolumeName(evalTmpDir)
+ c := strings.Count(evalTmpDir[len(vol):], string(os.PathSeparator))
+ var dd []string
+ for i := 0; i < c+2; i++ {
+ dd = append(dd, "..")
+ }
+
+ wantSuffix := strings.Join([]string{"a", "file"}, string(os.PathSeparator))
+
+ // Try different numbers of "..".
+ for _, i := range []int{c, c + 1, c + 2} {
+ check := strings.Join([]string{evalTmpDir, strings.Join(dd[:i], string(os.PathSeparator)), evalTmpDir[len(vol)+1:], "b", "file"}, string(os.PathSeparator))
+ if resolved, err := filepath.EvalSymlinks(check); err != nil {
+ t.Errorf("EvalSymlinks(%q) failed: %v", check, err)
+ } else if !strings.HasSuffix(resolved, wantSuffix) {
+ t.Errorf("EvalSymlinks(%q) = %q does not end with %q", check, resolved, wantSuffix)
+ } else {
+ t.Logf("EvalSymlinks(%q) = %q", check, resolved)
+ }
+ }
+}
+
+// Issue 30520 part 2.
+func TestEvalSymlinksAboveRootChdir(t *testing.T) {
+ testenv.MustHaveSymlink(t)
+
+ tmpDir, err := ioutil.TempDir("", "TestEvalSymlinksAboveRootChdir")
+ if err != nil {
+ t.Fatal(err)
+ }
+ defer os.RemoveAll(tmpDir)
+
+ wd, err := os.Getwd()
+ if err != nil {
+ t.Fatal(err)
+ }
+ defer os.Chdir(wd)
+
+ if err := os.Chdir(tmpDir); err != nil {
+ t.Fatal(err)
+ }
+
+ subdir := filepath.Join("a", "b")
+ if err := os.MkdirAll(subdir, 0777); err != nil {
+ t.Fatal(err)
+ }
+ if err := os.Symlink(subdir, "c"); err != nil {
+ t.Fatal(err)
+ }
+ if err := ioutil.WriteFile(filepath.Join(subdir, "file"), nil, 0666); err != nil {
+ t.Fatal(err)
+ }
+
+ subdir = filepath.Join("d", "e", "f")
+ if err := os.MkdirAll(subdir, 0777); err != nil {
+ t.Fatal(err)
+ }
+ if err := os.Chdir(subdir); err != nil {
+ t.Fatal(err)
+ }
+
+ check := filepath.Join("..", "..", "..", "c", "file")
+ wantSuffix := filepath.Join("a", "b", "file")
+ if resolved, err := filepath.EvalSymlinks(check); err != nil {
+ t.Errorf("EvalSymlinks(%q) failed: %v", check, err)
+ } else if !strings.HasSuffix(resolved, wantSuffix) {
+ t.Errorf("EvalSymlinks(%q) = %q does not end with %q", check, resolved, wantSuffix)
+ } else {
+ t.Logf("EvalSymlinks(%q) = %q", check, resolved)
+ }
+}
diff --git a/libgo/go/path/filepath/symlink.go b/libgo/go/path/filepath/symlink.go
index 4b41039..de043c1 100644
--- a/libgo/go/path/filepath/symlink.go
+++ b/libgo/go/path/filepath/symlink.go
@@ -44,18 +44,26 @@ func walkSymlinks(path string) (string, error) {
} else if path[start:end] == ".." {
// Back up to previous component if possible.
// Note that volLen includes any leading slash.
+
+ // Set r to the index of the last slash in dest,
+ // after the volume.
var r int
for r = len(dest) - 1; r >= volLen; r-- {
if os.IsPathSeparator(dest[r]) {
break
}
}
- if r < volLen {
+ if r < volLen || dest[r+1:] == ".." {
+ // Either path has no slashes
+ // (it's empty or just "C:")
+ // or it ends in a ".." we had to keep.
+ // Either way, keep this "..".
if len(dest) > volLen {
dest += pathSeparator
}
dest += ".."
} else {
+ // Discard everything since the last slash.
dest = dest[:r]
}
continue