github.com/opencontainers/runtime-tools@v0.9.0/filepath/abs.go (about)

     1  package filepath
     2  
     3  import (
     4  	"regexp"
     5  	"strings"
     6  )
     7  
     8  var windowsAbs = regexp.MustCompile(`^[a-zA-Z]:\\.*$`)
     9  
    10  // Abs is a version of path/filepath's Abs with an explicit operating
    11  // system and current working directory.
    12  func Abs(os, path, cwd string) (_ string, err error) {
    13  	if IsAbs(os, path) {
    14  		return Clean(os, path), nil
    15  	}
    16  	return Clean(os, Join(os, cwd, path)), nil
    17  }
    18  
    19  // IsAbs is a version of path/filepath's IsAbs with an explicit
    20  // operating system.
    21  func IsAbs(os, path string) bool {
    22  	if os == "windows" {
    23  		// FIXME: copy hideous logic from Go's
    24  		// src/path/filepath/path_windows.go into somewhere where we can
    25  		// put 3-clause BSD licensed code.
    26  		return windowsAbs.MatchString(path)
    27  	}
    28  	sep := Separator(os)
    29  
    30  	// POSIX has [1]:
    31  	//
    32  	// > If a pathname begins with two successive <slash> characters,
    33  	// > the first component following the leading <slash> characters
    34  	// > may be interpreted in an implementation-defined manner,
    35  	// > although more than two leading <slash> characters shall be
    36  	// > treated as a single <slash> character.
    37  	//
    38  	// And Boost treats // as non-absolute [2], but Linux [3,4], Python
    39  	// [5] and Go [6] all treat // as absolute.
    40  	//
    41  	// [1]: http://pubs.opengroup.org/onlinepubs/9699919799/basedefs/V1_chap04.html#tag_04_13
    42  	// [2]: https://github.com/boostorg/filesystem/blob/boost-1.64.0/test/path_test.cpp#L861
    43  	// [3]: http://man7.org/linux/man-pages/man7/path_resolution.7.html
    44  	// [4]: https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/tree/Documentation/filesystems/path-lookup.md?h=v4.12#n41
    45  	// [5]: https://github.com/python/cpython/blob/v3.6.1/Lib/posixpath.py#L64-L66
    46  	// [6]: https://go.googlesource.com/go/+/go1.8.3/src/path/path.go#199
    47  	return strings.HasPrefix(path, string(sep))
    48  }