k3s/vendor/github.com/flosch/pongo2/template_loader.go

158 lines
4.3 KiB
Go
Raw Normal View History

2019-11-08 21:45:10 +00:00
package pongo2
import (
"bytes"
"io"
"io/ioutil"
"log"
"os"
"path/filepath"
"github.com/juju/errors"
)
// LocalFilesystemLoader represents a local filesystem loader with basic
// BaseDirectory capabilities. The access to the local filesystem is unrestricted.
type LocalFilesystemLoader struct {
baseDir string
}
// MustNewLocalFileSystemLoader creates a new LocalFilesystemLoader instance
// and panics if there's any error during instantiation. The parameters
// are the same like NewLocalFileSystemLoader.
func MustNewLocalFileSystemLoader(baseDir string) *LocalFilesystemLoader {
fs, err := NewLocalFileSystemLoader(baseDir)
if err != nil {
log.Panic(err)
}
return fs
}
// NewLocalFileSystemLoader creates a new LocalFilesystemLoader and allows
// templatesto be loaded from disk (unrestricted). If any base directory
// is given (or being set using SetBaseDir), this base directory is being used
// for path calculation in template inclusions/imports. Otherwise the path
// is calculated based relatively to the including template's path.
func NewLocalFileSystemLoader(baseDir string) (*LocalFilesystemLoader, error) {
fs := &LocalFilesystemLoader{}
if baseDir != "" {
if err := fs.SetBaseDir(baseDir); err != nil {
return nil, err
}
}
return fs, nil
}
// SetBaseDir sets the template's base directory. This directory will
// be used for any relative path in filters, tags and From*-functions to determine
// your template. See the comment for NewLocalFileSystemLoader as well.
func (fs *LocalFilesystemLoader) SetBaseDir(path string) error {
// Make the path absolute
if !filepath.IsAbs(path) {
abs, err := filepath.Abs(path)
if err != nil {
return err
}
path = abs
}
// Check for existence
fi, err := os.Stat(path)
if err != nil {
return err
}
if !fi.IsDir() {
return errors.Errorf("The given path '%s' is not a directory.", path)
}
fs.baseDir = path
return nil
}
// Get reads the path's content from your local filesystem.
func (fs *LocalFilesystemLoader) Get(path string) (io.Reader, error) {
buf, err := ioutil.ReadFile(path)
if err != nil {
return nil, err
}
return bytes.NewReader(buf), nil
}
// Abs resolves a filename relative to the base directory. Absolute paths are allowed.
// When there's no base dir set, the absolute path to the filename
// will be calculated based on either the provided base directory (which
// might be a path of a template which includes another template) or
// the current working directory.
func (fs *LocalFilesystemLoader) Abs(base, name string) string {
if filepath.IsAbs(name) {
return name
}
// Our own base dir has always priority; if there's none
// we use the path provided in base.
var err error
if fs.baseDir == "" {
if base == "" {
base, err = os.Getwd()
if err != nil {
panic(err)
}
return filepath.Join(base, name)
}
return filepath.Join(filepath.Dir(base), name)
}
return filepath.Join(fs.baseDir, name)
}
// SandboxedFilesystemLoader is still WIP.
type SandboxedFilesystemLoader struct {
*LocalFilesystemLoader
}
// NewSandboxedFilesystemLoader creates a new sandboxed local file system instance.
func NewSandboxedFilesystemLoader(baseDir string) (*SandboxedFilesystemLoader, error) {
fs, err := NewLocalFileSystemLoader(baseDir)
if err != nil {
return nil, err
}
return &SandboxedFilesystemLoader{
LocalFilesystemLoader: fs,
}, nil
}
// Move sandbox to a virtual fs
/*
if len(set.SandboxDirectories) > 0 {
defer func() {
// Remove any ".." or other crap
resolvedPath = filepath.Clean(resolvedPath)
// Make the path absolute
absPath, err := filepath.Abs(resolvedPath)
if err != nil {
panic(err)
}
resolvedPath = absPath
// Check against the sandbox directories (once one pattern matches, we're done and can allow it)
for _, pattern := range set.SandboxDirectories {
matched, err := filepath.Match(pattern, resolvedPath)
if err != nil {
panic("Wrong sandbox directory match pattern (see http://golang.org/pkg/path/filepath/#Match).")
}
if matched {
// OK!
return
}
}
// No pattern matched, we have to log+deny the request
set.logf("Access attempt outside of the sandbox directories (blocked): '%s'", resolvedPath)
resolvedPath = ""
}()
}
*/