diff options
author | Ian Lance Taylor <ian@gcc.gnu.org> | 2019-03-18 20:27:59 +0000 |
---|---|---|
committer | Ian Lance Taylor <ian@gcc.gnu.org> | 2019-03-18 20:27:59 +0000 |
commit | a8b58d84bf4fd9c925a835ba39c1c552383bc61b (patch) | |
tree | 97d68e0e70fb780b04f3171a0f53102a39c23f41 /libgo/go/path | |
parent | 891cd9e3b9a89b0461fb838d38c51b6fab596337 (diff) | |
download | gcc-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.go | 11 | ||||
-rw-r--r-- | libgo/go/path/filepath/path_test.go | 103 | ||||
-rw-r--r-- | libgo/go/path/filepath/symlink.go | 10 |
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 |