Cover CleanedAbs

This commit is contained in:
Jeffrey Regan
2019-01-25 12:21:03 -08:00
parent 028724df08
commit c21dfefbdf
7 changed files with 173 additions and 34 deletions

View File

@@ -102,9 +102,16 @@ func (fs *fakeFs) Open(name string) (File, error) {
return fs.m[name], nil return fs.m[name], nil
} }
// EvalSymlinks does nothing and cannot fail. // CleanedAbs does nothing and cannot fail.
func (fs *fakeFs) EvalSymlinks(path string) (string, error) { func (fs *fakeFs) CleanedAbs(path string) (string, string, error) {
return path, nil if fs.IsDir(path) {
return path, "", nil
}
d := filepath.Dir(path)
if d == path {
return d, "", nil
}
return d, filepath.Base(path), nil
} }
// Exists returns true if file is known. // Exists returns true if file is known.

View File

@@ -30,7 +30,7 @@ type FileSystem interface {
RemoveAll(name string) error RemoveAll(name string) error
Open(name string) (File, error) Open(name string) (File, error)
IsDir(name string) bool IsDir(name string) bool
EvalSymlinks(path string) (string, error) CleanedAbs(path string) (string, string, error)
Exists(name string) bool Exists(name string) bool
Glob(pattern string) ([]string, error) Glob(pattern string) ([]string, error)
ReadFile(name string) ([]byte, error) ReadFile(name string) ([]byte, error)

View File

@@ -17,7 +17,9 @@ limitations under the License.
package fs package fs
import ( import (
"fmt"
"io/ioutil" "io/ioutil"
"log"
"os" "os"
"path/filepath" "path/filepath"
) )
@@ -53,9 +55,41 @@ func (realFS) RemoveAll(name string) error {
// Open delegates to os.Open. // Open delegates to os.Open.
func (realFS) Open(name string) (File, error) { return os.Open(name) } func (realFS) Open(name string) (File, error) { return os.Open(name) }
// EvalSymlinks delegates to filepath.EvalSymlinks. // CleanedAbs returns a cleaned, absolute path
func (realFS) EvalSymlinks(path string) (string, error) { // with no symbolic links split into directory
return filepath.EvalSymlinks(path) // and file components. If the entire path is
// a directory, the file component is an empty
// string.
func (x realFS) CleanedAbs(path string) (string, string, error) {
absRoot, err := filepath.Abs(path)
if err != nil {
return "", "", fmt.Errorf(
"abs path error on '%s' : %v", path, err)
}
deLinked, err := filepath.EvalSymlinks(absRoot)
if err != nil {
return "", "", fmt.Errorf(
"evalsymlink failure on '%s' : %v", path, err)
}
if x.IsDir(deLinked) {
return deLinked, "", nil
}
d := filepath.Dir(deLinked)
if !x.IsDir(d) {
// Programmer/assumption error.
log.Fatalf("first part of '%s' not a directory", deLinked)
}
if d == deLinked {
// Programmer/assumption error.
log.Fatalf("d '%s' should be a subset of deLinked", d)
}
f := filepath.Base(deLinked)
if filepath.Join(d, f) != deLinked {
// Programmer/assumption error.
log.Fatalf("these should be equal: '%s', '%s'",
filepath.Join(d, f), deLinked)
}
return d, f, nil
} }
// Exists returns true if os.Stat succeeds. // Exists returns true if os.Stat succeeds.

View File

@@ -17,18 +17,17 @@ limitations under the License.
package fs package fs
import ( import (
"io/ioutil"
"os" "os"
"path" "path"
"path/filepath"
"reflect" "reflect"
"testing" "testing"
) )
func TestReadFilesRealFS(t *testing.T) { func makeTestDir(t *testing.T) (FileSystem, string) {
x := MakeRealFS() x := MakeRealFS()
testDir := "kustomize_testing_dir" testDir, err := ioutil.TempDir("", "kustomize_testing_dir")
err := x.Mkdir(testDir)
defer os.RemoveAll(testDir)
if err != nil { if err != nil {
t.Fatalf("unexpected error %s", err) t.Fatalf("unexpected error %s", err)
} }
@@ -38,8 +37,113 @@ func TestReadFilesRealFS(t *testing.T) {
if !x.IsDir(testDir) { if !x.IsDir(testDir) {
t.Fatalf("expected directory") t.Fatalf("expected directory")
} }
return x, testDir
}
err = x.WriteFile(path.Join(testDir, "foo"), []byte(`foo`)) func TestCleanedAbs_1(t *testing.T) {
x, testDir := makeTestDir(t)
defer os.RemoveAll(testDir)
d, f, err := x.CleanedAbs("")
if err != nil {
t.Fatalf("unexpected err=%v", err)
}
wd, err := os.Getwd()
if err != nil {
t.Fatalf("unexpected err=%v", err)
}
if d != wd {
t.Fatalf("unexpected d=%s", d)
}
if f != "" {
t.Fatalf("unexpected f=%s", f)
}
}
func TestCleanedAbs_2(t *testing.T) {
x, testDir := makeTestDir(t)
defer os.RemoveAll(testDir)
d, f, err := x.CleanedAbs("/")
if err != nil {
t.Fatalf("unexpected err=%v", err)
}
if d != "/" {
t.Fatalf("unexpected d=%s", d)
}
if f != "" {
t.Fatalf("unexpected f=%s", f)
}
}
func TestCleanedAbs_3(t *testing.T) {
x, testDir := makeTestDir(t)
defer os.RemoveAll(testDir)
err := x.WriteFile(
filepath.Join(testDir, "foo"), []byte(`foo`))
if err != nil {
t.Fatalf("unexpected err=%v", err)
}
d, f, err := x.CleanedAbs(filepath.Join(testDir, "foo"))
if err != nil {
t.Fatalf("unexpected err=%v", err)
}
if d != testDir {
t.Fatalf("unexpected d=%s", d)
}
if f != "foo" {
t.Fatalf("unexpected f=%s", f)
}
}
func TestCleanedAbs_4(t *testing.T) {
x, testDir := makeTestDir(t)
defer os.RemoveAll(testDir)
err := x.MkdirAll(filepath.Join(testDir, "d1", "d2"))
if err != nil {
t.Fatalf("unexpected err=%v", err)
}
err = x.WriteFile(
filepath.Join(testDir, "d1", "d2", "bar"),
[]byte(`bar`))
if err != nil {
t.Fatalf("unexpected err=%v", err)
}
d, f, err := x.CleanedAbs(
filepath.Join(testDir, "d1", "d2"))
if err != nil {
t.Fatalf("unexpected err=%v", err)
}
if d != filepath.Join(testDir, "d1", "d2") {
t.Fatalf("unexpected d=%s", d)
}
if f != "" {
t.Fatalf("unexpected f=%s", f)
}
d, f, err = x.CleanedAbs(
filepath.Join(testDir, "d1", "d2", "bar"))
if err != nil {
t.Fatalf("unexpected err=%v", err)
}
if d != filepath.Join(testDir, "d1", "d2") {
t.Fatalf("unexpected d=%s", d)
}
if f != "bar" {
t.Fatalf("unexpected f=%s", f)
}
}
func TestReadFilesRealFS(t *testing.T) {
x, testDir := makeTestDir(t)
defer os.RemoveAll(testDir)
err := x.WriteFile(path.Join(testDir, "foo"), []byte(`foo`))
if err != nil { if err != nil {
t.Fatalf("unexpected error %s", err) t.Fatalf("unexpected error %s", err)
} }

View File

@@ -123,11 +123,16 @@ func newFileLoaderAt(
return nil, fmt.Errorf( return nil, fmt.Errorf(
"loader root cannot be empty") "loader root cannot be empty")
} }
absRoot, err := cleanedAbs(root, fSys) absRoot, f, err := fSys.CleanedAbs(root)
if err != nil { if err != nil {
return nil, fmt.Errorf( return nil, fmt.Errorf(
"absolute path error in '%s' : %v", root, err) "absolute path error in '%s' : %v", root, err)
} }
if f != "" {
return nil, fmt.Errorf(
"got file '%s', but '%s' must be a directory to be a root",
f, root)
}
if err := isPathEqualToOrAbove(absRoot, roots); err != nil { if err := isPathEqualToOrAbove(absRoot, roots); err != nil {
return nil, err return nil, err
} }
@@ -143,22 +148,6 @@ func newFileLoaderAt(
}, nil }, nil
} }
// cleanedAbs returns a cleaned, absolute path
// with no symbolic links.
func cleanedAbs(path string, fSys fs.FileSystem) (string, error) {
absRoot, err := filepath.Abs(path)
if err != nil {
return "", fmt.Errorf(
"abs path error on '%s' : %v", path, err)
}
deLinked, err := fSys.EvalSymlinks(absRoot)
if err != nil {
return "", fmt.Errorf(
"evalsymlink failure on '%s' : %v", path, err)
}
return deLinked, nil
}
// New returns a new Loader, rooted relative to current loader, // New returns a new Loader, rooted relative to current loader,
// or rooted in a temp directory holding a git repo clone. // or rooted in a temp directory holding a git repo clone.
func (l *fileLoader) New(path string) (ifc.Loader, error) { func (l *fileLoader) New(path string) (ifc.Loader, error) {
@@ -226,11 +215,16 @@ func (l *fileLoader) Load(path string) ([]byte, error) {
if filepath.IsAbs(path) { if filepath.IsAbs(path) {
return nil, l.loadOutOfBounds(path) return nil, l.loadOutOfBounds(path)
} }
path, err := cleanedAbs( d, f, err := l.fSys.CleanedAbs(
filepath.Join(l.Root(), path), l.fSys) filepath.Join(l.Root(), path))
if err != nil { if err != nil {
return nil, err return nil, err
} }
if f == "" {
return nil, fmt.Errorf(
"'%s' must be a file (got d='%s')", path, d)
}
path = filepath.Join(d, f)
if !l.isInOrBelowRoot(path) { if !l.isInOrBelowRoot(path) {
return nil, l.loadOutOfBounds(path) return nil, l.loadOutOfBounds(path)
} }

View File

@@ -75,7 +75,7 @@ func TestNewFileLoaderAt_DemandsDirectory(t *testing.T) {
if err == nil { if err == nil {
t.Fatalf("Expected error - a file should not work.") t.Fatalf("Expected error - a file should not work.")
} }
if !strings.Contains(err.Error(), "does not exist or is not a directory") { if !strings.Contains(err.Error(), "must be a directory to be a root") {
t.Fatalf("unexpected err: %v", err) t.Fatalf("unexpected err: %v", err)
} }
} }

View File

@@ -145,7 +145,7 @@ func TestNewFromConfigMaps(t *testing.T) {
expected ResMap expected ResMap
} }
l := loadertest.NewFakeLoader("/whatever/project/") l := loadertest.NewFakeLoader("/whatever/project")
testCases := []testCase{ testCases := []testCase{
{ {
description: "construct config map from env", description: "construct config map from env",