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