Skip to content

Commit

Permalink
osfs: Expand dot on BoundOS
Browse files Browse the repository at this point in the history
Signed-off-by: Paulo Gomes <[email protected]>
  • Loading branch information
pjbgf committed Aug 4, 2024
1 parent b7d9906 commit ce1ad5a
Show file tree
Hide file tree
Showing 2 changed files with 79 additions and 2 deletions.
41 changes: 41 additions & 0 deletions osfs/os_bound.go
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@
package osfs

import (
"errors"
"fmt"
"os"
"path/filepath"
Expand All @@ -29,6 +30,11 @@ import (
"github.com/go-git/go-billy/v5"
)

var (
ErrBaseDirCannotBeRemoved = errors.New("base dir cannot be removed")
ErrBaseDirCannotBeRenamed = errors.New("base dir cannot be renamed")
)

// BoundOS is a fs implementation based on the OS filesystem which is bound to
// a base dir.
// Prefer this fs implementation over ChrootOS.
Expand All @@ -54,6 +60,7 @@ func (fs *BoundOS) Create(filename string) (billy.File, error) {
}

func (fs *BoundOS) OpenFile(filename string, flag int, perm os.FileMode) (billy.File, error) {
filename = fs.expandDot(filename)
fn, err := fs.abs(filename)
if err != nil {
return nil, err
Expand All @@ -62,6 +69,7 @@ func (fs *BoundOS) OpenFile(filename string, flag int, perm os.FileMode) (billy.
}

func (fs *BoundOS) ReadDir(path string) ([]os.FileInfo, error) {
path = fs.expandDot(path)
dir, err := fs.abs(path)
if err != nil {
return nil, err
Expand All @@ -71,6 +79,12 @@ func (fs *BoundOS) ReadDir(path string) ([]os.FileInfo, error) {
}

func (fs *BoundOS) Rename(from, to string) error {
if from == "." || from == fs.baseDir {
return ErrBaseDirCannotBeRenamed
}

from = fs.expandDot(from)
to = fs.expandDot(to)
f, err := fs.abs(from)
if err != nil {
return err
Expand All @@ -89,6 +103,7 @@ func (fs *BoundOS) Rename(from, to string) error {
}

func (fs *BoundOS) MkdirAll(path string, perm os.FileMode) error {
path = fs.expandDot(path)
dir, err := fs.abs(path)
if err != nil {
return err
Expand All @@ -97,10 +112,12 @@ func (fs *BoundOS) MkdirAll(path string, perm os.FileMode) error {
}

func (fs *BoundOS) Open(filename string) (billy.File, error) {
filename = fs.expandDot(filename)
return fs.OpenFile(filename, os.O_RDONLY, 0)
}

func (fs *BoundOS) Stat(filename string) (os.FileInfo, error) {
filename = fs.expandDot(filename)
filename, err := fs.abs(filename)
if err != nil {
return nil, err
Expand All @@ -109,6 +126,10 @@ func (fs *BoundOS) Stat(filename string) (os.FileInfo, error) {
}

func (fs *BoundOS) Remove(filename string) error {
if filename == "." || filename == fs.baseDir {
return ErrBaseDirCannotBeRemoved
}

fn, err := fs.abs(filename)
if err != nil {
return err
Expand Down Expand Up @@ -136,6 +157,11 @@ func (fs *BoundOS) Join(elem ...string) string {
}

func (fs *BoundOS) RemoveAll(path string) error {
if path == "." || path == fs.baseDir {
return ErrBaseDirCannotBeRemoved
}

path = fs.expandDot(path)
dir, err := fs.abs(path)
if err != nil {
return err
Expand All @@ -144,6 +170,7 @@ func (fs *BoundOS) RemoveAll(path string) error {
}

func (fs *BoundOS) Symlink(target, link string) error {
link = fs.expandDot(link)
ln, err := fs.abs(link)
if err != nil {
return err
Expand All @@ -155,7 +182,20 @@ func (fs *BoundOS) Symlink(target, link string) error {
return os.Symlink(target, ln)
}

func (fs *BoundOS) expandDot(p string) string {
if p == "." {
return fs.baseDir
}
for _, prefix := range []string{"./", ".\\"} {
if strings.HasPrefix(p, prefix) {
return filepath.Join(fs.baseDir, strings.TrimPrefix(p, prefix))
}
}
return p
}

func (fs *BoundOS) Lstat(filename string) (os.FileInfo, error) {
filename = fs.expandDot(filename)
filename = filepath.Clean(filename)
if !filepath.IsAbs(filename) {
filename = filepath.Join(fs.baseDir, filename)
Expand All @@ -167,6 +207,7 @@ func (fs *BoundOS) Lstat(filename string) (os.FileInfo, error) {
}

func (fs *BoundOS) Readlink(link string) (string, error) {
link = fs.expandDot(link)
if !filepath.IsAbs(link) {
link = filepath.Clean(filepath.Join(fs.baseDir, link))
}
Expand Down
40 changes: 38 additions & 2 deletions osfs/os_bound_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,14 @@ func TestOpen(t *testing.T) {
},
filename: "test-file",
},
{
name: "file: dot rel same dir",
before: func(dir string) billy.Filesystem {
os.WriteFile(filepath.Join(dir, "test-file"), []byte("anything"), 0o600)
return newBoundOS(dir, true)
},
filename: "./test-file",
},
{
name: "file: rel path to above cwd",
before: func(dir string) billy.Filesystem {
Expand Down Expand Up @@ -160,6 +168,11 @@ func Test_Symlink(t *testing.T) {
link: "symlink",
target: filepath.FromSlash("/etc/passwd"),
},
{
name: "dot link to abs valid target",
link: "./symlink",
target: filepath.FromSlash("/etc/passwd"),
},
{
name: "link to abs inexistent target",
link: "symlink",
Expand Down Expand Up @@ -507,6 +520,14 @@ func TestLstat(t *testing.T) {
},
filename: "test-file",
},
{
name: "file: dot rel",
before: func(dir string) billy.Filesystem {
os.WriteFile(filepath.Join(dir, "test-file"), []byte("anything"), 0o600)
return newBoundOS(dir, true)
},
filename: "./test-file",
},
{
name: "file: abs",
before: func(dir string) billy.Filesystem {
Expand Down Expand Up @@ -610,6 +631,13 @@ func TestStat(t *testing.T) {
},
filename: "test-file",
},
{
name: "rel dot dir",
before: func(dir string) billy.Filesystem {
return newBoundOS(dir, true)
},
filename: ".",
},
{
name: "abs file",
before: func(dir string) billy.Filesystem {
Expand Down Expand Up @@ -674,6 +702,14 @@ func TestRemove(t *testing.T) {
filename: "inexistent",
wantErr: notFoundError(),
},
{
name: "same dot dir",
before: func(dir string) billy.Filesystem {
return newBoundOS(dir, true)
},
filename: ".",
wantErr: "base dir cannot be removed",
},
{
name: "same dir file",
before: func(dir string) billy.Filesystem {
Expand Down Expand Up @@ -1105,10 +1141,10 @@ func TestReadDir(t *testing.T) {
g.Expect(dirs).To(gomega.BeNil())
}

func TestInsideBaseDirEval(t*testing.T) {
func TestInsideBaseDirEval(t *testing.T) {
g := gomega.NewWithT(t)
fs := BoundOS{baseDir: "/"}
b, err := fs.insideBaseDirEval("a")
b, err := fs.insideBaseDirEval("a")
g.Expect(b).To(gomega.BeTrue())
g.Expect(err).To(gomega.BeNil())
}
Expand Down

0 comments on commit ce1ad5a

Please sign in to comment.