path/filepath: fix evaluation of symlinks to paths under /tmp on macOS

For symlinks created from symlinks under the root directory created
as the relative path (e.g., symbolic links under /tmp), we update vol and volLen.

Fixes #57905

Change-Id: I45affd1db3b93109de51bf19b181f3cdba061109
Reviewed-on: https://go-review.googlesource.com/c/go/+/461761
Run-TryBot: Bryan Mills <bcmills@google.com>
TryBot-Result: Gopher Robot <gobot@golang.org>
Reviewed-by: Bryan Mills <bcmills@google.com>
Auto-Submit: Bryan Mills <bcmills@google.com>
Reviewed-by: Ian Lance Taylor <iant@google.com>
diff --git a/src/path/filepath/path_test.go b/src/path/filepath/path_test.go
index 6647444..e6a9270 100644
--- a/src/path/filepath/path_test.go
+++ b/src/path/filepath/path_test.go
@@ -1193,6 +1193,37 @@
 	}
 }
 
+// Issue 57905.
+func TestRelativeSymlinkToAbsolute(t *testing.T) {
+	testenv.MustHaveSymlink(t)
+	// Not parallel: uses os.Chdir.
+
+	tmpDir := t.TempDir()
+	chdir(t, tmpDir)
+
+	// Create "link" in the current working directory as a symlink to an arbitrary
+	// absolute path. On macOS, this path is likely to begin with a symlink
+	// itself: generally either in /var (symlinked to "private/var") or /tmp
+	// (symlinked to "private/tmp").
+	if err := os.Symlink(tmpDir, "link"); err != nil {
+		t.Fatal(err)
+	}
+	t.Logf(`os.Symlink(%q, "link")`, tmpDir)
+
+	p, err := filepath.EvalSymlinks("link")
+	if err != nil {
+		t.Fatalf(`EvalSymlinks("link"): %v`, err)
+	}
+	want, err := filepath.EvalSymlinks(tmpDir)
+	if err != nil {
+		t.Fatalf(`EvalSymlinks(%q): %v`, tmpDir, err)
+	}
+	if p != want {
+		t.Errorf(`EvalSymlinks("link") = %q; want %q`, p, want)
+	}
+	t.Logf(`EvalSymlinks("link") = %q`, p)
+}
+
 // Test directories relative to temporary directory.
 // The tests are run in absTestDirs[0].
 var absTestDirs = []string{
diff --git a/src/path/filepath/symlink.go b/src/path/filepath/symlink.go
index 6fefd159..f9435e0 100644
--- a/src/path/filepath/symlink.go
+++ b/src/path/filepath/symlink.go
@@ -126,6 +126,8 @@
 			// Symlink to absolute path.
 			dest = link[:1]
 			end = 1
+			vol = link[:1]
+			volLen = 1
 		} else {
 			// Symlink to relative path; replace last
 			// path component in dest.