func New (fs billy .Basic , base string ) billy .Filesystem {
return &ChrootHelper {
underlying : polyfill .New (fs ),
base : base ,
}
}
func (fs *ChrootHelper ) underlyingPath (filename string ) (string , error ) {
if isCrossBoundaries (filename ) {
return "" , billy .ErrCrossedBoundary
}
return fs .Join (fs .Root (), filename ), nil
}
func isCrossBoundaries (path string ) bool {
path = filepath .ToSlash (path )
path = filepath .Clean (path )
return strings .HasPrefix (path , ".." +string (filepath .Separator ))
}
func (fs *ChrootHelper ) Create (filename string ) (billy .File , error ) {
fullpath , err := fs .underlyingPath (filename )
if err != nil {
return nil , err
}
f , err := fs .underlying .Create (fullpath )
if err != nil {
return nil , err
}
return newFile (fs , f , filename ), nil
}
func (fs *ChrootHelper ) Open (filename string ) (billy .File , error ) {
fullpath , err := fs .underlyingPath (filename )
if err != nil {
return nil , err
}
f , err := fs .underlying .Open (fullpath )
if err != nil {
return nil , err
}
return newFile (fs , f , filename ), nil
}
func (fs *ChrootHelper ) OpenFile (filename string , flag int , mode os .FileMode ) (billy .File , error ) {
fullpath , err := fs .underlyingPath (filename )
if err != nil {
return nil , err
}
f , err := fs .underlying .OpenFile (fullpath , flag , mode )
if err != nil {
return nil , err
}
return newFile (fs , f , filename ), nil
}
func (fs *ChrootHelper ) Stat (filename string ) (os .FileInfo , error ) {
fullpath , err := fs .underlyingPath (filename )
if err != nil {
return nil , err
}
return fs .underlying .Stat (fullpath )
}
func (fs *ChrootHelper ) Rename (from , to string ) error {
var err error
from , err = fs .underlyingPath (from )
if err != nil {
return err
}
to , err = fs .underlyingPath (to )
if err != nil {
return err
}
return fs .underlying .Rename (from , to )
}
func (fs *ChrootHelper ) Remove (path string ) error {
fullpath , err := fs .underlyingPath (path )
if err != nil {
return err
}
return fs .underlying .Remove (fullpath )
}
func (fs *ChrootHelper ) Join (elem ...string ) string {
return fs .underlying .Join (elem ...)
}
func (fs *ChrootHelper ) TempFile (dir , prefix string ) (billy .File , error ) {
fullpath , err := fs .underlyingPath (dir )
if err != nil {
return nil , err
}
f , err := fs .underlying .(billy .TempFile ).TempFile (fullpath , prefix )
if err != nil {
return nil , err
}
return newFile (fs , f , fs .Join (dir , filepath .Base (f .Name ()))), nil
}
func (fs *ChrootHelper ) ReadDir (path string ) ([]os .FileInfo , error ) {
fullpath , err := fs .underlyingPath (path )
if err != nil {
return nil , err
}
return fs .underlying .(billy .Dir ).ReadDir (fullpath )
}
func (fs *ChrootHelper ) MkdirAll (filename string , perm os .FileMode ) error {
fullpath , err := fs .underlyingPath (filename )
if err != nil {
return err
}
return fs .underlying .(billy .Dir ).MkdirAll (fullpath , perm )
}
func (fs *ChrootHelper ) Lstat (filename string ) (os .FileInfo , error ) {
fullpath , err := fs .underlyingPath (filename )
if err != nil {
return nil , err
}
return fs .underlying .(billy .Symlink ).Lstat (fullpath )
}
func (fs *ChrootHelper ) Symlink (target , link string ) error {
target = filepath .FromSlash (target )