1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123
|
package test
import (
"os"
. "gopkg.in/check.v1"
. "github.com/go-git/go-billy/v5"
"github.com/go-git/go-billy/v5/util"
)
// ChrootSuite is a convenient test suite to validate any implementation of
// billy.Chroot
type ChrootSuite struct {
FS interface {
Basic
Chroot
}
}
func (s *ChrootSuite) TestCreateWithChroot(c *C) {
fs, _ := s.FS.Chroot("foo")
f, err := fs.Create("bar")
c.Assert(err, IsNil)
c.Assert(f.Close(), IsNil)
c.Assert(f.Name(), Equals, "bar")
f, err = s.FS.Open("foo/bar")
c.Assert(err, IsNil)
c.Assert(f.Name(), Equals, s.FS.Join("foo", "bar"))
c.Assert(f.Close(), IsNil)
}
func (s *ChrootSuite) TestOpenWithChroot(c *C) {
fs, _ := s.FS.Chroot("foo")
f, err := fs.Create("bar")
c.Assert(err, IsNil)
c.Assert(f.Close(), IsNil)
c.Assert(f.Name(), Equals, "bar")
f, err = fs.Open("bar")
c.Assert(err, IsNil)
c.Assert(f.Name(), Equals, "bar")
c.Assert(f.Close(), IsNil)
}
func (s *ChrootSuite) TestOpenOutOffBoundary(c *C) {
err := util.WriteFile(s.FS, "bar", nil, 0644)
c.Assert(err, IsNil)
fs, _ := s.FS.Chroot("foo")
f, err := fs.Open("../bar")
c.Assert(err, Equals, ErrCrossedBoundary)
c.Assert(f, IsNil)
}
func (s *ChrootSuite) TestStatOutOffBoundary(c *C) {
err := util.WriteFile(s.FS, "bar", nil, 0644)
c.Assert(err, IsNil)
fs, _ := s.FS.Chroot("foo")
f, err := fs.Stat("../bar")
c.Assert(err, Equals, ErrCrossedBoundary)
c.Assert(f, IsNil)
}
func (s *ChrootSuite) TestStatWithChroot(c *C) {
files := []string{"foo", "bar", "qux/baz", "qux/qux"}
for _, name := range files {
err := util.WriteFile(s.FS, name, nil, 0644)
c.Assert(err, IsNil)
}
// Some implementations detect directories based on a prefix
// for all files; it's easy to miss path separator handling there.
fi, err := s.FS.Stat("qu")
c.Assert(os.IsNotExist(err), Equals, true, Commentf("error: %s", err))
c.Assert(fi, IsNil)
fi, err = s.FS.Stat("qux")
c.Assert(err, IsNil)
c.Assert(fi.Name(), Equals, "qux")
c.Assert(fi.IsDir(), Equals, true)
qux, _ := s.FS.Chroot("qux")
fi, err = qux.Stat("baz")
c.Assert(err, IsNil)
c.Assert(fi.Name(), Equals, "baz")
c.Assert(fi.IsDir(), Equals, false)
fi, err = qux.Stat("/baz")
c.Assert(err, IsNil)
c.Assert(fi.Name(), Equals, "baz")
c.Assert(fi.IsDir(), Equals, false)
}
func (s *ChrootSuite) TestRenameOutOffBoundary(c *C) {
err := util.WriteFile(s.FS, "foo/foo", nil, 0644)
c.Assert(err, IsNil)
err = util.WriteFile(s.FS, "bar", nil, 0644)
c.Assert(err, IsNil)
fs, _ := s.FS.Chroot("foo")
err = fs.Rename("../bar", "foo")
c.Assert(err, Equals, ErrCrossedBoundary)
err = fs.Rename("foo", "../bar")
c.Assert(err, Equals, ErrCrossedBoundary)
}
func (s *ChrootSuite) TestRemoveOutOffBoundary(c *C) {
err := util.WriteFile(s.FS, "bar", nil, 0644)
c.Assert(err, IsNil)
fs, _ := s.FS.Chroot("foo")
err = fs.Remove("../bar")
c.Assert(err, Equals, ErrCrossedBoundary)
}
func (s *FilesystemSuite) TestRoot(c *C) {
c.Assert(s.FS.Root(), Not(Equals), "")
}
|