chore(deps): bump github.com/go-git/go-billy/v5 from 5.4.1 to 5.5.0 (#2746)

Bumps [github.com/go-git/go-billy/v5](https://github.com/go-git/go-billy) from 5.4.1 to 5.5.0.
- [Release notes](https://github.com/go-git/go-billy/releases)
- [Commits](https://github.com/go-git/go-billy/compare/v5.4.1...v5.5.0)

---
updated-dependencies:
- dependency-name: github.com/go-git/go-billy/v5
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
This commit is contained in:
dependabot[bot] 2023-09-12 10:37:01 -07:00 committed by GitHub
parent 15532c44d1
commit 29dc5ba23f
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
16 changed files with 777 additions and 122 deletions

3
go.mod
View File

@ -18,7 +18,7 @@ require (
github.com/chrismellard/docker-credential-acr-env v0.0.0-20230304212654-82a0ddb27589
github.com/containerd/cgroups v1.1.0 // indirect
github.com/docker/docker v23.0.5+incompatible
github.com/go-git/go-billy/v5 v5.4.1
github.com/go-git/go-billy/v5 v5.5.0
github.com/go-git/go-git/v5 v5.8.1
github.com/golang/mock v1.6.0
github.com/google/go-cmp v0.5.9
@ -163,6 +163,7 @@ require (
github.com/aws/aws-sdk-go-v2/service/ecr v1.18.10 // indirect
github.com/aws/aws-sdk-go-v2/service/ecrpublic v1.16.1 // indirect
github.com/cloudflare/circl v1.3.3 // indirect
github.com/cyphar/filepath-securejoin v0.2.4 // indirect
github.com/fsnotify/fsnotify v1.6.0 // indirect
github.com/google/go-querystring v1.1.0 // indirect
github.com/google/s2a-go v0.1.7 // indirect

12
go.sum
View File

@ -215,9 +215,10 @@ github.com/coreos/go-systemd/v22 v22.5.0 h1:RrqgGjYQKalulkV8NGVIfkXQf6YYmOyiJKk8
github.com/coreos/go-systemd/v22 v22.5.0/go.mod h1:Y58oyj3AT4RCenI/lSvhwexgC+NSVTIJ3seZv2GcEnc=
github.com/cpuguy83/go-md2man/v2 v2.0.0-20190314233015-f79a8a8ca69d/go.mod h1:maD7wRr/U5Z6m/iR4s+kqSMx2CaBsrgA7czyZG/E6dU=
github.com/cpuguy83/go-md2man/v2 v2.0.2/go.mod h1:tgQtvFlXSQOSOSIRvRPT7W67SCa46tRHOmNcaadrF8o=
github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E=
github.com/creack/pty v1.1.18 h1:n56/Zwd5o6whRC5PMGretI4IdRLlmBXYNjScPaBgsbY=
github.com/cyphar/filepath-securejoin v0.2.3/go.mod h1:aPGpWjXOXUn2NCNjFvBE6aRxGGx79pTxQpKOJNYHHl4=
github.com/cyphar/filepath-securejoin v0.2.4 h1:Ugdm7cg7i6ZK6x3xDF1oEu1nfkyfH53EtKeQYTC3kyg=
github.com/cyphar/filepath-securejoin v0.2.4/go.mod h1:aPGpWjXOXUn2NCNjFvBE6aRxGGx79pTxQpKOJNYHHl4=
github.com/danieljoos/wincred v1.1.2/go.mod h1:GijpziifJoIBfYh+S7BbkdUTU4LfM+QnGqR5Vl2tAx0=
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
@ -265,8 +266,8 @@ github.com/ghodss/yaml v1.0.0/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeME
github.com/gliderlabs/ssh v0.3.5 h1:OcaySEmAQJgyYcArR+gGGTHCyE7nvhEMTlYY+Dp8CpY=
github.com/go-git/gcfg v1.5.1-0.20230307220236-3a3c6141e376 h1:+zs/tPmkDkHx3U66DAb0lQFJrpS6731Oaa12ikc+DiI=
github.com/go-git/gcfg v1.5.1-0.20230307220236-3a3c6141e376/go.mod h1:an3vInlBmSxCcxctByoQdvwPiA7DTK7jaaFDBTtu0ic=
github.com/go-git/go-billy/v5 v5.4.1 h1:Uwp5tDRkPr+l/TnbHOQzp+tmJfLceOlbVucgpTz8ix4=
github.com/go-git/go-billy/v5 v5.4.1/go.mod h1:vjbugF6Fz7JIflbVpl1hJsGjSHNltrSw45YK/ukIvQg=
github.com/go-git/go-billy/v5 v5.5.0 h1:yEY4yhzCDuMGSv83oGxiBotRzhwhNr8VZyphhiu+mTU=
github.com/go-git/go-billy/v5 v5.5.0/go.mod h1:hmexnoNsr2SJU1Ju67OaNz5ASJY3+sHgFRpCtpDCKow=
github.com/go-git/go-git-fixtures/v4 v4.3.2-0.20230305113008-0c11038e723f h1:Pz0DHeFij3XFhoBRGUDPzSJ+w2UcK5/0JvF8DRI58r8=
github.com/go-git/go-git/v5 v5.8.1 h1:Zo79E4p7TRk0xoRgMq0RShiTHGKcKI4+DI6BfJc/Q+A=
github.com/go-git/go-git/v5 v5.8.1/go.mod h1:FHFuoD6yGz5OSKEBK+aWN9Oah0q54Jxl0abmj6GnqAo=
@ -460,7 +461,6 @@ github.com/kr/pretty v0.3.1 h1:flRD4NNwYAUpkphVc1HcthR4KEIFJ65n8Mw5qdRn3LE=
github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ=
github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI=
github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY=
github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE=
github.com/magiconair/properties v1.8.5 h1:b6kJs+EmPFMYGkow9GiUyCyOvIwYetYJ3fSaWak/Gls=
github.com/magiconair/properties v1.8.5/go.mod h1:y3VJvCyxH9uVvJTWEGAELF3aiYNyPKd5NZ3oSwXrF60=
github.com/matryer/is v1.2.0 h1:92UTHpy8CDwaJ08GqLDzhhuixiBUUD1p3AU6PHddz4A=
@ -518,7 +518,7 @@ github.com/morikuni/aec v1.0.0/go.mod h1:BbKIizmSmc5MMPqRYbxO4ZU0S0+P200+tUnFx7P
github.com/mrunalp/fileutils v0.5.0/go.mod h1:M1WthSahJixYnrXQl/DFQuteStB1weuxD2QJNHXfbSQ=
github.com/mwitkow/go-conntrack v0.0.0-20161129095857-cc309e4a2223/go.mod h1:qRWi+5nqEBWmkhHvq77mSJWrCKwh8bxhgT7d/eI7P4U=
github.com/mwitkow/go-conntrack v0.0.0-20190716064945-2f068394615f/go.mod h1:qRWi+5nqEBWmkhHvq77mSJWrCKwh8bxhgT7d/eI7P4U=
github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e/go.mod h1:zD1mROLANZcx1PVRCS0qkT7pwLkGfwJo4zjcN/Tysno=
github.com/onsi/gomega v1.27.10 h1:naR28SdDFlqrG6kScpT8VWpu1xWY5nJRCF3XaYyBjhI=
github.com/opencontainers/go-digest v1.0.0 h1:apOUWs51W5PlhuyGyz9FCeeBIOUDA/6nW8Oi/yOhh5U=
github.com/opencontainers/go-digest v1.0.0/go.mod h1:0JzlMkj0TRzQZfJkVvzbP0HBR3IKzErnv2BNG4W4MAM=
github.com/opencontainers/image-spec v1.1.0-rc3 h1:fzg1mXZFj8YdPeNkRXMg+zb88BFV0Ys52cJydRwBkb8=
@ -580,7 +580,7 @@ github.com/prometheus/procfs v0.8.0 h1:ODq8ZFEaYeCaZOJlZZdJA2AbQR98dSHSM1KW/You5
github.com/prometheus/procfs v0.8.0/go.mod h1:z7EfXMXOkbkqb9IINtpCn86r/to3BnA0uaxHdg830/4=
github.com/rogpeppe/fastuuid v1.2.0/go.mod h1:jVj6XXZzXRy/MSR5jhDC/2q6DgLz+nrA6LYCDYWNEvQ=
github.com/rogpeppe/go-internal v1.3.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4=
github.com/rogpeppe/go-internal v1.9.0 h1:73kH8U+JUqXU8lRuOHeVHaa/SZPifC7BkcraZVejAe8=
github.com/rogpeppe/go-internal v1.11.0 h1:cWPaGQEPrBb5/AsnsZesgZZ9yb1OQ+GOISoDNXVBh4M=
github.com/rootless-containers/rootlesskit v1.1.0 h1:cRaRIYxY8oce4eE/zeAUZhgKu/4tU1p9YHN4+suwV7M=
github.com/rootless-containers/rootlesskit v1.1.0/go.mod h1:H+o9ndNe7tS91WqU0/+vpvc+VaCd7TCIWaJjnV0ujUo=
github.com/russross/blackfriday/v2 v2.0.1/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM=

28
vendor/github.com/cyphar/filepath-securejoin/LICENSE generated vendored Normal file
View File

@ -0,0 +1,28 @@
Copyright (C) 2014-2015 Docker Inc & Go Authors. All rights reserved.
Copyright (C) 2017 SUSE LLC. All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are
met:
* Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above
copyright notice, this list of conditions and the following disclaimer
in the documentation and/or other materials provided with the
distribution.
* Neither the name of Google Inc. nor the names of its
contributors may be used to endorse or promote products derived from
this software without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

79
vendor/github.com/cyphar/filepath-securejoin/README.md generated vendored Normal file
View File

@ -0,0 +1,79 @@
## `filepath-securejoin` ##
[![Build Status](https://github.com/cyphar/filepath-securejoin/actions/workflows/ci.yml/badge.svg)](https://github.com/cyphar/filepath-securejoin/actions/workflows/ci.yml)
An implementation of `SecureJoin`, a [candidate for inclusion in the Go
standard library][go#20126]. The purpose of this function is to be a "secure"
alternative to `filepath.Join`, and in particular it provides certain
guarantees that are not provided by `filepath.Join`.
> **NOTE**: This code is *only* safe if you are not at risk of other processes
> modifying path components after you've used `SecureJoin`. If it is possible
> for a malicious process to modify path components of the resolved path, then
> you will be vulnerable to some fairly trivial TOCTOU race conditions. [There
> are some Linux kernel patches I'm working on which might allow for a better
> solution.][lwn-obeneath]
>
> In addition, with a slightly modified API it might be possible to use
> `O_PATH` and verify that the opened path is actually the resolved one -- but
> I have not done that yet. I might add it in the future as a helper function
> to help users verify the path (we can't just return `/proc/self/fd/<foo>`
> because that doesn't always work transparently for all users).
This is the function prototype:
```go
func SecureJoin(root, unsafePath string) (string, error)
```
This library **guarantees** the following:
* If no error is set, the resulting string **must** be a child path of
`root` and will not contain any symlink path components (they will all be
expanded).
* When expanding symlinks, all symlink path components **must** be resolved
relative to the provided root. In particular, this can be considered a
userspace implementation of how `chroot(2)` operates on file paths. Note that
these symlinks will **not** be expanded lexically (`filepath.Clean` is not
called on the input before processing).
* Non-existent path components are unaffected by `SecureJoin` (similar to
`filepath.EvalSymlinks`'s semantics).
* The returned path will always be `filepath.Clean`ed and thus not contain any
`..` components.
A (trivial) implementation of this function on GNU/Linux systems could be done
with the following (note that this requires root privileges and is far more
opaque than the implementation in this library, and also requires that
`readlink` is inside the `root` path):
```go
package securejoin
import (
"os/exec"
"path/filepath"
)
func SecureJoin(root, unsafePath string) (string, error) {
unsafePath = string(filepath.Separator) + unsafePath
cmd := exec.Command("chroot", root,
"readlink", "--canonicalize-missing", "--no-newline", unsafePath)
output, err := cmd.CombinedOutput()
if err != nil {
return "", err
}
expanded := string(output)
return filepath.Join(root, expanded), nil
}
```
[lwn-obeneath]: https://lwn.net/Articles/767547/
[go#20126]: https://github.com/golang/go/issues/20126
### License ###
The license of this project is the same as Go, which is a BSD 3-clause license
available in the `LICENSE` file.

1
vendor/github.com/cyphar/filepath-securejoin/VERSION generated vendored Normal file
View File

@ -0,0 +1 @@
0.2.4

125
vendor/github.com/cyphar/filepath-securejoin/join.go generated vendored Normal file
View File

@ -0,0 +1,125 @@
// Copyright (C) 2014-2015 Docker Inc & Go Authors. All rights reserved.
// Copyright (C) 2017 SUSE LLC. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
// Package securejoin is an implementation of the hopefully-soon-to-be-included
// SecureJoin helper that is meant to be part of the "path/filepath" package.
// The purpose of this project is to provide a PoC implementation to make the
// SecureJoin proposal (https://github.com/golang/go/issues/20126) more
// tangible.
package securejoin
import (
"bytes"
"errors"
"os"
"path/filepath"
"strings"
"syscall"
)
// IsNotExist tells you if err is an error that implies that either the path
// accessed does not exist (or path components don't exist). This is
// effectively a more broad version of os.IsNotExist.
func IsNotExist(err error) bool {
// Check that it's not actually an ENOTDIR, which in some cases is a more
// convoluted case of ENOENT (usually involving weird paths).
return errors.Is(err, os.ErrNotExist) || errors.Is(err, syscall.ENOTDIR) || errors.Is(err, syscall.ENOENT)
}
// SecureJoinVFS joins the two given path components (similar to Join) except
// that the returned path is guaranteed to be scoped inside the provided root
// path (when evaluated). Any symbolic links in the path are evaluated with the
// given root treated as the root of the filesystem, similar to a chroot. The
// filesystem state is evaluated through the given VFS interface (if nil, the
// standard os.* family of functions are used).
//
// Note that the guarantees provided by this function only apply if the path
// components in the returned string are not modified (in other words are not
// replaced with symlinks on the filesystem) after this function has returned.
// Such a symlink race is necessarily out-of-scope of SecureJoin.
//
// Volume names in unsafePath are always discarded, regardless if they are
// provided via direct input or when evaluating symlinks. Therefore:
//
// "C:\Temp" + "D:\path\to\file.txt" results in "C:\Temp\path\to\file.txt"
func SecureJoinVFS(root, unsafePath string, vfs VFS) (string, error) {
// Use the os.* VFS implementation if none was specified.
if vfs == nil {
vfs = osVFS{}
}
unsafePath = filepath.FromSlash(unsafePath)
var path bytes.Buffer
n := 0
for unsafePath != "" {
if n > 255 {
return "", &os.PathError{Op: "SecureJoin", Path: root + string(filepath.Separator) + unsafePath, Err: syscall.ELOOP}
}
if v := filepath.VolumeName(unsafePath); v != "" {
unsafePath = unsafePath[len(v):]
}
// Next path component, p.
i := strings.IndexRune(unsafePath, filepath.Separator)
var p string
if i == -1 {
p, unsafePath = unsafePath, ""
} else {
p, unsafePath = unsafePath[:i], unsafePath[i+1:]
}
// Create a cleaned path, using the lexical semantics of /../a, to
// create a "scoped" path component which can safely be joined to fullP
// for evaluation. At this point, path.String() doesn't contain any
// symlink components.
cleanP := filepath.Clean(string(filepath.Separator) + path.String() + p)
if cleanP == string(filepath.Separator) {
path.Reset()
continue
}
fullP := filepath.Clean(root + cleanP)
// Figure out whether the path is a symlink.
fi, err := vfs.Lstat(fullP)
if err != nil && !IsNotExist(err) {
return "", err
}
// Treat non-existent path components the same as non-symlinks (we
// can't do any better here).
if IsNotExist(err) || fi.Mode()&os.ModeSymlink == 0 {
path.WriteString(p)
path.WriteRune(filepath.Separator)
continue
}
// Only increment when we actually dereference a link.
n++
// It's a symlink, expand it by prepending it to the yet-unparsed path.
dest, err := vfs.Readlink(fullP)
if err != nil {
return "", err
}
// Absolute symlinks reset any work we've already done.
if filepath.IsAbs(dest) {
path.Reset()
}
unsafePath = dest + string(filepath.Separator) + unsafePath
}
// We have to clean path.String() here because it may contain '..'
// components that are entirely lexical, but would be misleading otherwise.
// And finally do a final clean to ensure that root is also lexically
// clean.
fullP := filepath.Clean(string(filepath.Separator) + path.String())
return filepath.Clean(root + fullP), nil
}
// SecureJoin is a wrapper around SecureJoinVFS that just uses the os.* library
// of functions as the VFS. If in doubt, use this function over SecureJoinVFS.
func SecureJoin(root, unsafePath string) (string, error) {
return SecureJoinVFS(root, unsafePath, nil)
}

41
vendor/github.com/cyphar/filepath-securejoin/vfs.go generated vendored Normal file
View File

@ -0,0 +1,41 @@
// Copyright (C) 2017 SUSE LLC. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
package securejoin
import "os"
// In future this should be moved into a separate package, because now there
// are several projects (umoci and go-mtree) that are using this sort of
// interface.
// VFS is the minimal interface necessary to use SecureJoinVFS. A nil VFS is
// equivalent to using the standard os.* family of functions. This is mainly
// used for the purposes of mock testing, but also can be used to otherwise use
// SecureJoin with VFS-like system.
type VFS interface {
// Lstat returns a FileInfo describing the named file. If the file is a
// symbolic link, the returned FileInfo describes the symbolic link. Lstat
// makes no attempt to follow the link. These semantics are identical to
// os.Lstat.
Lstat(name string) (os.FileInfo, error)
// Readlink returns the destination of the named symbolic link. These
// semantics are identical to os.Readlink.
Readlink(name string) (string, error)
}
// osVFS is the "nil" VFS, in that it just passes everything through to the os
// module.
type osVFS struct{}
// Lstat returns a FileInfo describing the named file. If the file is a
// symbolic link, the returned FileInfo describes the symbolic link. Lstat
// makes no attempt to follow the link. These semantics are identical to
// os.Lstat.
func (o osVFS) Lstat(name string) (os.FileInfo, error) { return os.Lstat(name) }
// Readlink returns the destination of the named symbolic link. These
// semantics are identical to os.Readlink.
func (o osVFS) Readlink(name string) (string, error) { return os.Readlink(name) }

View File

@ -1,140 +1,123 @@
//go:build !js
// +build !js
// Package osfs provides a billy filesystem for the OS.
package osfs // import "github.com/go-git/go-billy/v5/osfs"
package osfs
import (
"io/ioutil"
"fmt"
"io/fs"
"os"
"path/filepath"
"sync"
"github.com/go-git/go-billy/v5"
"github.com/go-git/go-billy/v5/helper/chroot"
)
const (
defaultDirectoryMode = 0755
defaultCreateMode = 0666
defaultDirectoryMode = 0o755
defaultCreateMode = 0o666
)
// Default Filesystem representing the root of the os filesystem.
var Default = &OS{}
// OS is a filesystem based on the os filesystem.
type OS struct{}
var Default = &ChrootOS{}
// New returns a new OS filesystem.
func New(baseDir string) billy.Filesystem {
return chroot.New(Default, baseDir)
// By default paths are deduplicated, but still enforced
// under baseDir. For more info refer to WithDeduplicatePath.
func New(baseDir string, opts ...Option) billy.Filesystem {
o := &options{
deduplicatePath: true,
}
for _, opt := range opts {
opt(o)
}
if o.Type == BoundOSFS {
return newBoundOS(baseDir, o.deduplicatePath)
}
return newChrootOS(baseDir)
}
func (fs *OS) Create(filename string) (billy.File, error) {
return fs.OpenFile(filename, os.O_RDWR|os.O_CREATE|os.O_TRUNC, defaultCreateMode)
// WithBoundOS returns the option of using a Bound filesystem OS.
func WithBoundOS() Option {
return func(o *options) {
o.Type = BoundOSFS
}
}
func (fs *OS) OpenFile(filename string, flag int, perm os.FileMode) (billy.File, error) {
if flag&os.O_CREATE != 0 {
if err := fs.createDir(filename); err != nil {
// WithChrootOS returns the option of using a Chroot filesystem OS.
func WithChrootOS() Option {
return func(o *options) {
o.Type = ChrootOSFS
}
}
// WithDeduplicatePath toggles the deduplication of the base dir in the path.
// This occurs when absolute links are being used.
// Assuming base dir /base/dir and an absolute symlink /base/dir/target:
//
// With DeduplicatePath (default): /base/dir/target
// Without DeduplicatePath: /base/dir/base/dir/target
//
// This option is only used by the BoundOS OS type.
func WithDeduplicatePath(enabled bool) Option {
return func(o *options) {
o.deduplicatePath = enabled
}
}
type options struct {
Type
deduplicatePath bool
}
type Type int
const (
ChrootOSFS Type = iota
BoundOSFS
)
func readDir(dir string) ([]os.FileInfo, error) {
entries, err := os.ReadDir(dir)
if err != nil {
return nil, err
}
infos := make([]fs.FileInfo, 0, len(entries))
for _, entry := range entries {
fi, err := entry.Info()
if err != nil {
return nil, err
}
infos = append(infos, fi)
}
f, err := os.OpenFile(filename, flag, perm)
if err != nil {
return nil, err
}
return &file{File: f}, err
return infos, nil
}
func (fs *OS) createDir(fullpath string) error {
dir := filepath.Dir(fullpath)
if dir != "." {
if err := os.MkdirAll(dir, defaultDirectoryMode); err != nil {
return err
}
}
return nil
}
func (fs *OS) ReadDir(path string) ([]os.FileInfo, error) {
l, err := ioutil.ReadDir(path)
if err != nil {
return nil, err
}
var s = make([]os.FileInfo, len(l))
for i, f := range l {
s[i] = f
}
return s, nil
}
func (fs *OS) Rename(from, to string) error {
if err := fs.createDir(to); err != nil {
return err
}
return rename(from, to)
}
func (fs *OS) MkdirAll(path string, perm os.FileMode) error {
return os.MkdirAll(path, defaultDirectoryMode)
}
func (fs *OS) Open(filename string) (billy.File, error) {
return fs.OpenFile(filename, os.O_RDONLY, 0)
}
func (fs *OS) Stat(filename string) (os.FileInfo, error) {
return os.Stat(filename)
}
func (fs *OS) Remove(filename string) error {
return os.Remove(filename)
}
func (fs *OS) TempFile(dir, prefix string) (billy.File, error) {
if err := fs.createDir(dir + string(os.PathSeparator)); err != nil {
return nil, err
}
f, err := ioutil.TempFile(dir, prefix)
func tempFile(dir, prefix string) (billy.File, error) {
f, err := os.CreateTemp(dir, prefix)
if err != nil {
return nil, err
}
return &file{File: f}, nil
}
func (fs *OS) Join(elem ...string) string {
return filepath.Join(elem...)
}
func (fs *OS) RemoveAll(path string) error {
return os.RemoveAll(filepath.Clean(path))
}
func (fs *OS) Lstat(filename string) (os.FileInfo, error) {
return os.Lstat(filepath.Clean(filename))
}
func (fs *OS) Symlink(target, link string) error {
if err := fs.createDir(link); err != nil {
return err
func openFile(fn string, flag int, perm os.FileMode, createDir func(string) error) (billy.File, error) {
if flag&os.O_CREATE != 0 {
if createDir == nil {
return nil, fmt.Errorf("createDir func cannot be nil if file needs to be opened in create mode")
}
if err := createDir(fn); err != nil {
return nil, err
}
}
return os.Symlink(target, link)
}
func (fs *OS) Readlink(link string) (string, error) {
return os.Readlink(link)
}
// Capabilities implements the Capable interface.
func (fs *OS) Capabilities() billy.Capability {
return billy.DefaultCapabilities
f, err := os.OpenFile(fn, flag, perm)
if err != nil {
return nil, err
}
return &file{File: f}, err
}
// file is a wrapper for an os.File which adds support for file locking.

261
vendor/github.com/go-git/go-billy/v5/osfs/os_bound.go generated vendored Normal file
View File

@ -0,0 +1,261 @@
//go:build !js
// +build !js
/*
Copyright 2022 The Flux authors.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
package osfs
import (
"fmt"
"os"
"path/filepath"
"strings"
securejoin "github.com/cyphar/filepath-securejoin"
"github.com/go-git/go-billy/v5"
)
// BoundOS is a fs implementation based on the OS filesystem which is bound to
// a base dir.
// Prefer this fs implementation over ChrootOS.
//
// Behaviours of note:
// 1. Read and write operations can only be directed to files which descends
// from the base dir.
// 2. Symlinks don't have their targets modified, and therefore can point
// to locations outside the base dir or to non-existent paths.
// 3. Readlink and Lstat ensures that the link file is located within the base
// dir, evaluating any symlinks that file or base dir may contain.
type BoundOS struct {
baseDir string
deduplicatePath bool
}
func newBoundOS(d string, deduplicatePath bool) billy.Filesystem {
return &BoundOS{baseDir: d, deduplicatePath: deduplicatePath}
}
func (fs *BoundOS) Create(filename string) (billy.File, error) {
return fs.OpenFile(filename, os.O_RDWR|os.O_CREATE|os.O_TRUNC, defaultCreateMode)
}
func (fs *BoundOS) OpenFile(filename string, flag int, perm os.FileMode) (billy.File, error) {
fn, err := fs.abs(filename)
if err != nil {
return nil, err
}
return openFile(fn, flag, perm, fs.createDir)
}
func (fs *BoundOS) ReadDir(path string) ([]os.FileInfo, error) {
dir, err := fs.abs(path)
if err != nil {
return nil, err
}
return readDir(dir)
}
func (fs *BoundOS) Rename(from, to string) error {
f, err := fs.abs(from)
if err != nil {
return err
}
t, err := fs.abs(to)
if err != nil {
return err
}
// MkdirAll for target name.
if err := fs.createDir(t); err != nil {
return err
}
return os.Rename(f, t)
}
func (fs *BoundOS) MkdirAll(path string, perm os.FileMode) error {
dir, err := fs.abs(path)
if err != nil {
return err
}
return os.MkdirAll(dir, perm)
}
func (fs *BoundOS) Open(filename string) (billy.File, error) {
return fs.OpenFile(filename, os.O_RDONLY, 0)
}
func (fs *BoundOS) Stat(filename string) (os.FileInfo, error) {
filename, err := fs.abs(filename)
if err != nil {
return nil, err
}
return os.Stat(filename)
}
func (fs *BoundOS) Remove(filename string) error {
fn, err := fs.abs(filename)
if err != nil {
return err
}
return os.Remove(fn)
}
// TempFile creates a temporary file. If dir is empty, the file
// will be created within the OS Temporary dir. If dir is provided
// it must descend from the current base dir.
func (fs *BoundOS) TempFile(dir, prefix string) (billy.File, error) {
if dir != "" {
var err error
dir, err = fs.abs(dir)
if err != nil {
return nil, err
}
}
return tempFile(dir, prefix)
}
func (fs *BoundOS) Join(elem ...string) string {
return filepath.Join(elem...)
}
func (fs *BoundOS) RemoveAll(path string) error {
dir, err := fs.abs(path)
if err != nil {
return err
}
return os.RemoveAll(dir)
}
func (fs *BoundOS) Symlink(target, link string) error {
ln, err := fs.abs(link)
if err != nil {
return err
}
// MkdirAll for containing dir.
if err := fs.createDir(ln); err != nil {
return err
}
return os.Symlink(target, ln)
}
func (fs *BoundOS) Lstat(filename string) (os.FileInfo, error) {
filename = filepath.Clean(filename)
if !filepath.IsAbs(filename) {
filename = filepath.Join(fs.baseDir, filename)
}
if ok, err := fs.insideBaseDirEval(filename); !ok {
return nil, err
}
return os.Lstat(filename)
}
func (fs *BoundOS) Readlink(link string) (string, error) {
if !filepath.IsAbs(link) {
link = filepath.Clean(filepath.Join(fs.baseDir, link))
}
if ok, err := fs.insideBaseDirEval(link); !ok {
return "", err
}
return os.Readlink(link)
}
// Chroot returns a new OS filesystem, with the base dir set to the
// result of joining the provided path with the underlying base dir.
func (fs *BoundOS) Chroot(path string) (billy.Filesystem, error) {
joined, err := securejoin.SecureJoin(fs.baseDir, path)
if err != nil {
return nil, err
}
return New(joined), nil
}
// Root returns the current base dir of the billy.Filesystem.
// This is required in order for this implementation to be a drop-in
// replacement for other upstream implementations (e.g. memory and osfs).
func (fs *BoundOS) Root() string {
return fs.baseDir
}
func (fs *BoundOS) createDir(fullpath string) error {
dir := filepath.Dir(fullpath)
if dir != "." {
if err := os.MkdirAll(dir, defaultDirectoryMode); err != nil {
return err
}
}
return nil
}
// abs transforms filename to an absolute path, taking into account the base dir.
// Relative paths won't be allowed to ascend the base dir, so `../file` will become
// `/working-dir/file`.
//
// Note that if filename is a symlink, the returned address will be the target of the
// symlink.
func (fs *BoundOS) abs(filename string) (string, error) {
if filename == fs.baseDir {
filename = string(filepath.Separator)
}
path, err := securejoin.SecureJoin(fs.baseDir, filename)
if err != nil {
return "", nil
}
if fs.deduplicatePath {
vol := filepath.VolumeName(fs.baseDir)
dup := filepath.Join(fs.baseDir, fs.baseDir[len(vol):])
if strings.HasPrefix(path, dup+string(filepath.Separator)) {
return fs.abs(path[len(dup):])
}
}
return path, nil
}
// insideBaseDir checks whether filename is located within
// the fs.baseDir.
func (fs *BoundOS) insideBaseDir(filename string) (bool, error) {
if filename == fs.baseDir {
return true, nil
}
if !strings.HasPrefix(filename, fs.baseDir+string(filepath.Separator)) {
return false, fmt.Errorf("path outside base dir")
}
return true, nil
}
// insideBaseDirEval checks whether filename is contained within
// a dir that is within the fs.baseDir, by first evaluating any symlinks
// that either filename or fs.baseDir may contain.
func (fs *BoundOS) insideBaseDirEval(filename string) (bool, error) {
dir, err := filepath.EvalSymlinks(filepath.Dir(filename))
if dir == "" || os.IsNotExist(err) {
dir = filepath.Dir(filename)
}
wd, err := filepath.EvalSymlinks(fs.baseDir)
if wd == "" || os.IsNotExist(err) {
wd = fs.baseDir
}
if filename != wd && dir != wd && !strings.HasPrefix(dir, wd+string(filepath.Separator)) {
return false, fmt.Errorf("path outside base dir")
}
return true, nil
}

112
vendor/github.com/go-git/go-billy/v5/osfs/os_chroot.go generated vendored Normal file
View File

@ -0,0 +1,112 @@
//go:build !js
// +build !js
package osfs
import (
"os"
"path/filepath"
"github.com/go-git/go-billy/v5"
"github.com/go-git/go-billy/v5/helper/chroot"
)
// ChrootOS is a legacy filesystem based on a "soft chroot" of the os filesystem.
// Although this is still the default os filesystem, consider using BoundOS instead.
//
// Behaviours of note:
// 1. A "soft chroot" translates the base dir to "/" for the purposes of the
// fs abstraction.
// 2. Symlinks targets may be modified to be kept within the chroot bounds.
// 3. Some file modes does not pass-through the fs abstraction.
// 4. The combination of 1 and 2 may cause go-git to think that a Git repository
// is dirty, when in fact it isn't.
type ChrootOS struct{}
func newChrootOS(baseDir string) billy.Filesystem {
return chroot.New(&ChrootOS{}, baseDir)
}
func (fs *ChrootOS) Create(filename string) (billy.File, error) {
return fs.OpenFile(filename, os.O_RDWR|os.O_CREATE|os.O_TRUNC, defaultCreateMode)
}
func (fs *ChrootOS) OpenFile(filename string, flag int, perm os.FileMode) (billy.File, error) {
return openFile(filename, flag, perm, fs.createDir)
}
func (fs *ChrootOS) createDir(fullpath string) error {
dir := filepath.Dir(fullpath)
if dir != "." {
if err := os.MkdirAll(dir, defaultDirectoryMode); err != nil {
return err
}
}
return nil
}
func (fs *ChrootOS) ReadDir(dir string) ([]os.FileInfo, error) {
return readDir(dir)
}
func (fs *ChrootOS) Rename(from, to string) error {
if err := fs.createDir(to); err != nil {
return err
}
return rename(from, to)
}
func (fs *ChrootOS) MkdirAll(path string, perm os.FileMode) error {
return os.MkdirAll(path, defaultDirectoryMode)
}
func (fs *ChrootOS) Open(filename string) (billy.File, error) {
return fs.OpenFile(filename, os.O_RDONLY, 0)
}
func (fs *ChrootOS) Stat(filename string) (os.FileInfo, error) {
return os.Stat(filename)
}
func (fs *ChrootOS) Remove(filename string) error {
return os.Remove(filename)
}
func (fs *ChrootOS) TempFile(dir, prefix string) (billy.File, error) {
if err := fs.createDir(dir + string(os.PathSeparator)); err != nil {
return nil, err
}
return tempFile(dir, prefix)
}
func (fs *ChrootOS) Join(elem ...string) string {
return filepath.Join(elem...)
}
func (fs *ChrootOS) RemoveAll(path string) error {
return os.RemoveAll(filepath.Clean(path))
}
func (fs *ChrootOS) Lstat(filename string) (os.FileInfo, error) {
return os.Lstat(filepath.Clean(filename))
}
func (fs *ChrootOS) Symlink(target, link string) error {
if err := fs.createDir(link); err != nil {
return err
}
return os.Symlink(target, link)
}
func (fs *ChrootOS) Readlink(link string) (string, error) {
return os.Readlink(link)
}
// Capabilities implements the Capable interface.
func (fs *ChrootOS) Capabilities() billy.Capability {
return billy.DefaultCapabilities
}

View File

@ -1,3 +1,4 @@
//go:build js
// +build js
package osfs
@ -16,6 +17,9 @@ var globalMemFs = memfs.New()
var Default = memfs.New()
// New returns a new OS filesystem.
func New(baseDir string) billy.Filesystem {
func New(baseDir string, _ ...Option) billy.Filesystem {
return chroot.New(Default, Default.Join("/", baseDir))
}
type options struct {
}

View File

@ -0,0 +1,3 @@
package osfs
type Option func(*options)

View File

@ -1,3 +1,4 @@
//go:build plan9
// +build plan9
package osfs
@ -83,3 +84,8 @@ func dirwstat(name string, d *syscall.Dir) error {
}
return nil
}
func umask(new int) func() {
return func() {
}
}

View File

@ -1,9 +1,11 @@
//go:build !plan9 && !windows && !js
// +build !plan9,!windows,!js
package osfs
import (
"os"
"syscall"
"golang.org/x/sys/unix"
)
@ -25,3 +27,12 @@ func (f *file) Unlock() error {
func rename(from, to string) error {
return os.Rename(from, to)
}
// umask sets umask to a new value, and returns a func which allows the
// caller to reset it back to what it was originally.
func umask(new int) func() {
old := syscall.Umask(new)
return func() {
syscall.Umask(old)
}
}

View File

@ -1,3 +1,4 @@
//go:build windows
// +build windows
package osfs
@ -10,15 +11,6 @@ import (
"golang.org/x/sys/windows"
)
type fileInfo struct {
os.FileInfo
name string
}
func (fi *fileInfo) Name() string {
return fi.name
}
var (
kernel32DLL = windows.NewLazySystemDLL("kernel32.dll")
lockFileExProc = kernel32DLL.NewProc("LockFileEx")
@ -59,3 +51,8 @@ func (f *file) Unlock() error {
func rename(from, to string) error {
return os.Rename(from, to)
}
func umask(new int) func() {
return func() {
}
}

7
vendor/modules.txt vendored
View File

@ -316,6 +316,9 @@ github.com/containerd/typeurl
# github.com/coreos/go-systemd/v22 v22.5.0
## explicit; go 1.12
github.com/coreos/go-systemd/v22/dbus
# github.com/cyphar/filepath-securejoin v0.2.4
## explicit; go 1.13
github.com/cyphar/filepath-securejoin
# github.com/dimchansky/utfbom v1.1.1
## explicit
github.com/dimchansky/utfbom
@ -448,8 +451,8 @@ github.com/go-git/gcfg
github.com/go-git/gcfg/scanner
github.com/go-git/gcfg/token
github.com/go-git/gcfg/types
# github.com/go-git/go-billy/v5 v5.4.1
## explicit; go 1.13
# github.com/go-git/go-billy/v5 v5.5.0
## explicit; go 1.19
github.com/go-git/go-billy/v5
github.com/go-git/go-billy/v5/helper/chroot
github.com/go-git/go-billy/v5/helper/polyfill