moth

Monarch Of The Hill game server
git clone https://git.woozle.org/neale/moth.git

moth / pkg / transpile
Neale Pickett  ·  2021-03-26

basepath.go

 1package transpile
 2
 3import (
 4	"os"
 5	"path/filepath"
 6	"runtime"
 7	"strings"
 8
 9	"github.com/spf13/afero"
10)
11
12// RecursiveBasePathFs is an overloaded afero.BasePathFs that has a recursive RealPath().
13type RecursiveBasePathFs struct {
14	afero.Fs
15	source afero.Fs
16	path   string
17}
18
19// NewRecursiveBasePathFs returns a new RecursiveBasePathFs.
20func NewRecursiveBasePathFs(source afero.Fs, path string) *RecursiveBasePathFs {
21	ret := &RecursiveBasePathFs{
22		source: source,
23		path:   path,
24	}
25	if path == "" {
26		ret.Fs = source
27	} else {
28		ret.Fs = afero.NewBasePathFs(source, path)
29	}
30	return ret
31}
32
33// RealPath returns the real path to a file, "breaking out" of the RecursiveBasePathFs.
34func (b *RecursiveBasePathFs) RealPath(name string) (path string, err error) {
35	if err := validateBasePathName(name); err != nil {
36		return name, err
37	}
38
39	bpath := filepath.Clean(b.path)
40	path = filepath.Clean(filepath.Join(bpath, name))
41
42	switch pfs := b.source.(type) {
43	case *RecursiveBasePathFs:
44		return pfs.RealPath(path)
45	case *afero.BasePathFs:
46		return pfs.RealPath(path)
47	case *afero.OsFs:
48		return path, nil
49	}
50
51	if !strings.HasPrefix(path, bpath) {
52		return name, os.ErrNotExist
53	}
54
55	return path, nil
56}
57
58func validateBasePathName(name string) error {
59	if runtime.GOOS != "windows" {
60		// Not much to do here;
61		// the virtual file paths all look absolute on *nix.
62		return nil
63	}
64
65	// On Windows a common mistake would be to provide an absolute OS path
66	// We could strip out the base part, but that would not be very portable.
67	if filepath.IsAbs(name) {
68		return os.ErrNotExist
69	}
70
71	return nil
72}