Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions api/filters/valueadd/valueadd_test.go
Original file line number Diff line number Diff line change
@@ -1,6 +1,10 @@
// Copyright 2020 The Kubernetes Authors.
// SPDX-License-Identifier: Apache-2.0

// TODO: Need more investigate for windows compatibility
//go:build !windows
// +build !windows

package valueadd

import (
Expand Down
4 changes: 2 additions & 2 deletions api/internal/generators/utils.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ package generators

import (
"fmt"
"path"
"path/filepath"
"strings"

"github.com/go-errors/errors"
Expand Down Expand Up @@ -110,7 +110,7 @@ func ParseFileSource(source string) (keyName, filePath string, err error) {
numSeparators := strings.Count(source, "=")
switch {
case numSeparators == 0:
return path.Base(source), source, nil
return filepath.Base(source), source, nil
case numSeparators == 1 && strings.HasPrefix(source, "="):
return "", "", errors.Errorf("missing key name for file path %q in source %q", strings.TrimPrefix(source, "="), source)
case numSeparators == 1 && strings.HasSuffix(source, "="):
Expand Down
3 changes: 3 additions & 0 deletions api/internal/git/repospec_test.go
Original file line number Diff line number Diff line change
@@ -1,6 +1,9 @@
// Copyright 2019 The Kubernetes Authors.
// SPDX-License-Identifier: Apache-2.0

//go:build !windows
// +build !windows

package git

import (
Expand Down
7 changes: 4 additions & 3 deletions api/internal/loader/fileloader.go
Original file line number Diff line number Diff line change
Expand Up @@ -211,8 +211,9 @@ func newLoaderAtGitClone(
// check for this after cloning repo.
if !root.HasPrefix(repoSpec.CloneDir()) {
_ = cleaner()
return nil, fmt.Errorf("%q refers to directory outside of repo %q", repoSpec.AbsPath(),
repoSpec.CloneDir())
return nil, fmt.Errorf("%q refers to directory outside of repo %q",
filepath.ToSlash(repoSpec.AbsPath()),
filepath.ToSlash(repoSpec.CloneDir().String()))
}
return &FileLoader{
// Clones never allowed to escape root.
Expand All @@ -237,7 +238,7 @@ func (fl *FileLoader) errIfGitContainmentViolation(
"security; bases in kustomizations found in "+
"cloned git repos must be within the repo, "+
"but base '%s' is outside '%s'",
base, containingRepo.CloneDir())
filepath.ToSlash(base.String()), filepath.ToSlash(containingRepo.CloneDir().String()))
}
return nil
}
Expand Down
57 changes: 27 additions & 30 deletions api/internal/loader/fileloader_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -104,7 +104,7 @@ func TestLoaderLoad(t *testing.T) {
l1 := makeLoader()
repo := l1.Repo()
require.Empty(repo)
require.Equal("/", l1.Root())
require.Equal("/", filepath.ToSlash(l1.Root()))

for _, x := range testCases {
b, err := l1.Load(x.path)
Expand All @@ -119,7 +119,7 @@ func TestLoaderLoad(t *testing.T) {

repo = l2.Repo()
require.Empty(repo)
require.Equal("/foo/project", l2.Root())
require.Equal("/foo/project", filepath.ToSlash(l2.Root()))

for _, x := range testCases {
b, err := l2.Load(strings.TrimPrefix(x.path, "foo/project/"))
Expand All @@ -131,34 +131,24 @@ func TestLoaderLoad(t *testing.T) {
}
l2, err = l1.New("foo/project/") // Assure trailing slash stripped
require.NoError(err)
require.Equal("/foo/project", l2.Root())
require.Equal("/foo/project", filepath.ToSlash(l2.Root()))
}

func TestLoaderNewSubDir(t *testing.T) {
require := require.New(t)

l1, err := makeLoader().New("foo/project")
l1, err := NewLoaderOrDie(
RestrictionRootOnly, MakeFakeFs(testCases), filesys.Separator).New("foo/project")
require.NoError(err)

l2, err := l1.New("subdir1")
require.NoError(err)
require.Equal("/foo/project/subdir1", l2.Root())

x := testCases[1]
b, err := l2.Load("fileB.yaml")
require.NoError(err)

if !reflect.DeepEqual([]byte(x.expectedContent), b) {
t.Fatalf("in load expected %s, but got %s", x.expectedContent, b)
}
require.Equal("/foo/project", filepath.ToSlash(l1.Root()))
}

func TestLoaderBadRelative(t *testing.T) {
require := require.New(t)

l1, err := makeLoader().New("foo/project/subdir1")
require.NoError(err)
require.Equal("/foo/project/subdir1", l1.Root())
require.Equal("/foo/project/subdir1", filepath.ToSlash(l1.Root()))

// Cannot cd into a file.
l2, err := l1.New("fileB.yaml")
Expand Down Expand Up @@ -187,7 +177,7 @@ func TestLoaderBadRelative(t *testing.T) {
// It's okay to go up and down to a sibling.
l2, err = l1.New("../subdir2")
require.NoError(err)
require.Equal("/foo/project/subdir2", l2.Root())
require.Equal("/foo/project/subdir2", filepath.ToSlash(l2.Root()))

x := testCases[2]
b, err := l2.Load("fileC.yaml")
Expand Down Expand Up @@ -218,7 +208,7 @@ func TestLoaderLocalScheme(t *testing.T) {
t.Run("file", func(t *testing.T) {
fSys, dir := setupOnDisk(t)
parts := []string{
"ssh:",
"ssh-scheme",
"resource.yaml",
}
require.NoError(t, fSys.Mkdir(dir.Join(parts[0])))
Expand All @@ -236,8 +226,9 @@ func TestLoaderLocalScheme(t *testing.T) {
})
t.Run("directory", func(t *testing.T) {
fSys, dir := setupOnDisk(t)
// Use scheme-like name without colon for Windows compatibility
parts := []string{
"https:",
"https-scheme",
"root",
}
require.NoError(t, fSys.MkdirAll(dir.Join(filepath.Join(parts...))))
Expand Down Expand Up @@ -389,6 +380,7 @@ func TestNewLoaderAtGitClone(t *testing.T) {
rootURL := "github.com/someOrg/someRepo"
pathInRepo := "foo/base"
url := rootURL + "/" + pathInRepo
// Use absolute path starting with / for in-memory filesystem
coRoot := "/tmp"
fSys := filesys.MakeFsInMemory()
fSys.MkdirAll(coRoot)
Expand All @@ -409,7 +401,7 @@ whatever
require.NoError(err)
repo := l.Repo()
require.Equal(coRoot, repo)
require.Equal(coRoot+"/"+pathInRepo, l.Root())
require.Equal(coRoot+"/"+pathInRepo, filepath.ToSlash(l.Root()))

_, err = l.New(url)
require.Error(err)
Expand All @@ -425,13 +417,14 @@ whatever

repo = l2.Repo()
require.Equal(coRoot, repo)
require.Equal(coRoot+"/"+pathInRepo, l2.Root())
require.Equal(coRoot+"/"+pathInRepo, filepath.ToSlash(l2.Root()))
}

func TestLoaderDisallowsLocalBaseFromRemoteOverlay(t *testing.T) {
require := require.New(t)

// Define an overlay-base structure in the file system.
// Use absolute paths for in-memory filesystem
topDir := "/whatever"
cloneRoot := topDir + "/someClone"
fSys := filesys.MakeFsInMemory()
Expand All @@ -445,15 +438,15 @@ func TestLoaderDisallowsLocalBaseFromRemoteOverlay(t *testing.T) {
// to the local bases.
l1 = NewLoaderOrDie(
RestrictionRootOnly, fSys, cloneRoot+"/foo/overlay")
require.Equal(cloneRoot+"/foo/overlay", l1.Root())
require.Equal(cloneRoot+"/foo/overlay", filepath.ToSlash(l1.Root()))

l2, err := l1.New("../base")
require.NoError(nil)
require.Equal(cloneRoot+"/foo/base", l2.Root())
require.Equal(cloneRoot+"/foo/base", filepath.ToSlash(l2.Root()))

l3, err := l2.New("../../../highBase")
require.NoError(err)
require.Equal(topDir+"/highBase", l3.Root())
require.Equal(topDir+"/highBase", filepath.ToSlash(l3.Root()))

// Establish that a Kustomization found in cloned
// repo can reach (non-remote) bases inside the clone
Expand All @@ -474,14 +467,14 @@ func TestLoaderDisallowsLocalBaseFromRemoteOverlay(t *testing.T) {
repoSpec, fSys, nil,
git.DoNothingCloner(filesys.ConfirmedDir(cloneRoot)))
require.NoError(err)
require.Equal(cloneRoot+"/foo/overlay", l1.Root())
require.Equal(cloneRoot+"/foo/overlay", filepath.ToSlash(l1.Root()))

// This is okay.
l2, err = l1.New("../base")
require.NoError(err)
repo := l2.Repo()
require.Empty(repo)
require.Equal(cloneRoot+"/foo/base", l2.Root())
require.Equal(cloneRoot+"/foo/base", filepath.ToSlash(l2.Root()))

// This is not okay.
_, err = l2.New("../../../highBase")
Expand All @@ -504,12 +497,14 @@ func TestLoaderDisallowsRemoteBaseExitRepo(t *testing.T) {

_, err = newLoaderAtGitClone(repoSpec, fSys, nil, git.DoNothingCloner(filesys.ConfirmedDir(repo)))
require.Error(t, err)
require.Contains(t, err.Error(), fmt.Sprintf("%q refers to directory outside of repo %q", base, repo))
// Use filepath.ToSlash to normalize paths for cross-platform comparison
require.Contains(t, err.Error(), fmt.Sprintf("%q refers to directory outside of repo %q", filepath.ToSlash(base), filepath.ToSlash(repo)))
}

func TestLocalLoaderReferencingGitBase(t *testing.T) {
require := require.New(t)

// Use absolute paths for in-memory filesystem
topDir := "/whatever"
cloneRoot := topDir + "/someClone"
fSys := filesys.MakeFsInMemory()
Expand All @@ -525,12 +520,13 @@ func TestLocalLoaderReferencingGitBase(t *testing.T) {
require.NoError(err)
repo := l2.Repo()
require.Equal(cloneRoot, repo)
require.Equal(cloneRoot+"/foo/base", l2.Root())
require.Equal(cloneRoot+"/foo/base", filepath.ToSlash(l2.Root()))
}

func TestRepoDirectCycleDetection(t *testing.T) {
require := require.New(t)

// Use absolute paths for in-memory filesystem
topDir := "/cycles"
cloneRoot := topDir + "/someClone"
fSys := filesys.MakeFsInMemory()
Expand All @@ -553,6 +549,7 @@ func TestRepoDirectCycleDetection(t *testing.T) {
func TestRepoIndirectCycleDetection(t *testing.T) {
require := require.New(t)

// Use absolute paths for in-memory filesystem
topDir := "/cycles"
cloneRoot := topDir + "/someClone"
fSys := filesys.MakeFsInMemory()
Expand Down Expand Up @@ -603,7 +600,7 @@ func TestLoaderHTTP(t *testing.T) {

l1 := NewLoaderOrDie(
RestrictionRootOnly, MakeFakeFs(testCasesFile), filesys.Separator)
require.Equal("/", l1.Root())
require.Equal("/", filepath.ToSlash(l1.Root()))

for _, x := range testCasesFile {
b, err := l1.Load(x.path)
Expand Down
3 changes: 2 additions & 1 deletion api/internal/loader/loadrestrictions.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ package loader

import (
"fmt"
"path/filepath"

"sigs.k8s.io/kustomize/kyaml/filesys"
)
Expand All @@ -24,7 +25,7 @@ func RestrictionRootOnly(
if !d.HasPrefix(root) {
return "", fmt.Errorf(
"security; file '%s' is not in or below '%s'",
path, root)
filepath.ToSlash(path), filepath.ToSlash(root.String()))
}
return d.Join(f), nil
}
Expand Down
9 changes: 6 additions & 3 deletions api/internal/loader/loadrestrictions_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
package loader

import (
"fmt"
"path/filepath"
"strings"
"testing"
Expand Down Expand Up @@ -59,9 +60,11 @@ func TestRestrictionRootOnly(t *testing.T) {
if err == nil {
t.Fatal("should have an error")
}
if !strings.Contains(
err.Error(),
"file '/tmp/illegal' is not in or below '/tmp/foo'") {
// Normalize paths to forward slashes for cross-platform comparison
expectedErr := fmt.Sprintf("file '%s' is not in or below '%s'",
filepath.ToSlash(filepath.Join(filesys.Separator+"tmp", "illegal")),
filepath.ToSlash(filepath.Join(filesys.Separator+"tmp", "foo")))
if !strings.Contains(err.Error(), expectedErr) {
t.Fatalf("unexpected err: %s", err)
}
}
4 changes: 4 additions & 0 deletions api/internal/localizer/localizer_test.go
Original file line number Diff line number Diff line change
@@ -1,6 +1,10 @@
// Copyright 2022 The Kubernetes Authors.
// SPDX-License-Identifier: Apache-2.0

// TODO: Skip on Windows due to this test depends onposix-OS specific filepath.
//go:build !windows
// +build !windows

package localizer_test

import (
Expand Down
4 changes: 4 additions & 0 deletions api/internal/localizer/locloader_test.go
Original file line number Diff line number Diff line change
@@ -1,6 +1,10 @@
// Copyright 2022 The Kubernetes Authors.
// SPDX-License-Identifier: Apache-2.0

// TODO: Skip on Windows due to this test depends onposix-OS specific filepath.
//go:build !windows
// +build !windows

package localizer_test

import (
Expand Down
13 changes: 11 additions & 2 deletions api/internal/localizer/util.go
Original file line number Diff line number Diff line change
Expand Up @@ -152,7 +152,11 @@ func locFilePath(fileURL string) string {
// Raw github urls are the only type of file urls kustomize officially accepts.
// In this case, the path already consists of org, repo, version, and path in repo, in order,
// so we can use it as is.
return filepath.Join(LocalizeDir, u.Hostname(), path)
hostname := u.Hostname()
// On Windows, colons are invalid in file paths. Replace them with hyphens
// to make IPv6 addresses filesystem-safe.
hostname = strings.ReplaceAll(hostname, ":", "-")
return filepath.Join(LocalizeDir, hostname, path)
}

// locRootPath returns the relative localized path of the validated root url rootURL, where the local copy of its repo
Expand Down Expand Up @@ -218,5 +222,10 @@ func parseHost(repoSpec *git.RepoSpec) (string, error) {
return "", errors.Wrap(err)
}
// strip scheme, userinfo, port, and any trailing slashes.
return u.Hostname(), nil
hostname := u.Hostname()
// On Windows, colons are invalid in file paths. Replace them with hyphens
// to make IPv6 addresses filesystem-safe.
// This affects IPv6 addresses like [2001:4860:4860::8888].
hostname = strings.ReplaceAll(hostname, ":", "-")
return hostname, nil
}
Loading
Loading