mirror of
https://github.com/golang/go
synced 2024-09-30 09:18:35 -06:00
path/filepath: make Join("c:", "/a") return "c:/a" again
Historically, on Windows filepath.Join("c:", elt) does not insert a path separator between "c:" and elt, but preserves leading slashes in elt. Restore this behavior, which was inadvertently changed by CL 444280. Fixes #56988 Change-Id: Id728bf311f4093264f8c067d8b801ea9ebef5b5f Reviewed-on: https://go-review.googlesource.com/c/go/+/453497 Reviewed-by: Bryan Mills <bcmills@google.com> TryBot-Result: Gopher Robot <gobot@golang.org> Auto-Submit: Bryan Mills <bcmills@google.com> Reviewed-by: Roland Shoemaker <roland@golang.org> Run-TryBot: Damien Neil <dneil@google.com>
This commit is contained in:
parent
a79b55bb9a
commit
79559c1e7e
@ -353,7 +353,8 @@ var winjointests = []JoinTest{
|
||||
{[]string{`C:`, ``, ``, `b`}, `C:b`},
|
||||
{[]string{`C:`, ``}, `C:.`},
|
||||
{[]string{`C:`, ``, ``}, `C:.`},
|
||||
{[]string{`C:`, ``, `\a`}, `C:a`},
|
||||
{[]string{`C:`, `\a`}, `C:\a`},
|
||||
{[]string{`C:`, ``, `\a`}, `C:\a`},
|
||||
{[]string{`C:.`, `a`}, `C:a`},
|
||||
{[]string{`C:a`, `b`}, `C:a\b`},
|
||||
{[]string{`C:a`, `b`, `d`}, `C:a\b\d`},
|
||||
|
@ -222,31 +222,37 @@ func abs(path string) (string, error) {
|
||||
|
||||
func join(elem []string) string {
|
||||
var b strings.Builder
|
||||
appendSep := false
|
||||
var lastChar byte
|
||||
for _, e := range elem {
|
||||
// Strip leading slashes from everything after the first element,
|
||||
// to avoid creating a UNC path (any path starting with "\\") from
|
||||
// non-UNC elements.
|
||||
switch {
|
||||
case b.Len() == 0:
|
||||
// Add the first non-empty path element unchanged.
|
||||
case isSlash(lastChar):
|
||||
// If the path ends in a slash, strip any leading slashes from the next
|
||||
// path element to avoid creating a UNC path (any path starting with "\\")
|
||||
// from non-UNC elements.
|
||||
//
|
||||
// The correct behavior for Join when the first element is an incomplete UNC
|
||||
// path (for example, "\\") is underspecified. We currently join subsequent
|
||||
// elements so Join("\\", "host", "share") produces "\\host\share".
|
||||
for b.Len() > 0 && len(e) > 0 && isSlash(e[0]) {
|
||||
for len(e) > 0 && isSlash(e[0]) {
|
||||
e = e[1:]
|
||||
}
|
||||
if e == "" {
|
||||
continue
|
||||
}
|
||||
if appendSep {
|
||||
case lastChar == ':':
|
||||
// If the path ends in a colon, keep the path relative to the current directory
|
||||
// on a drive and don't add a separator. Preserve leading slashes in the next
|
||||
// path element, which may make the path absolute.
|
||||
//
|
||||
// Join(`C:`, `f`) = `C:f`
|
||||
// Join(`C:`, `\f`) = `C:\f`
|
||||
default:
|
||||
// In all other cases, add a separator between elements.
|
||||
b.WriteByte('\\')
|
||||
lastChar = '\\'
|
||||
}
|
||||
if len(e) > 0 {
|
||||
b.WriteString(e)
|
||||
appendSep = !isSlash(e[len(e)-1])
|
||||
if b.Len() == 2 && volumeNameLen(b.String()) == 2 {
|
||||
// If the string is two characters long and consists of nothing but
|
||||
// a volume name, this is either a drive ("C:") or the start of an
|
||||
// incomplete UNC path ("\\"). In either case, don't append a separator.
|
||||
appendSep = false
|
||||
lastChar = e[len(e)-1]
|
||||
}
|
||||
}
|
||||
if b.Len() == 0 {
|
||||
|
Loading…
Reference in New Issue
Block a user