From e8500459483c9fabae491e3c3467a4544eb90f14 Mon Sep 17 00:00:00 2001 From: mohit-bhandari45 Date: Thu, 3 Sep 2026 08:44:21 +0530 Subject: [PATCH 1/5] fix(streamer): prevent skipPath from over-matching .git prefix This fixes a bug where skipPath would unintentionally drop files that happened to share the .git prefix (such as .gitignore, .gitmodules) by ensuring it matches the exact .git directory boundary. Also normalizes cross-platform paths using filepath.ToSlash to prevent Windows path bugs. Signed-off-by: mohit-bhandari45 --- pkg/shp/streamer/tar.go | 13 +++++++++---- pkg/shp/streamer/tar_test.go | 18 ++++++++++++++++-- 2 files changed, 25 insertions(+), 6 deletions(-) diff --git a/pkg/shp/streamer/tar.go b/pkg/shp/streamer/tar.go index e2255f7c7..57839145e 100644 --- a/pkg/shp/streamer/tar.go +++ b/pkg/shp/streamer/tar.go @@ -24,13 +24,18 @@ func (t *Tar) skipPath(fpath string, stat fs.FileInfo) bool { if !stat.Mode().IsRegular() { return true } - if strings.HasPrefix(fpath, path.Join(t.src, ".git")) { + cleanFpath := filepath.ToSlash(fpath) + cleanSrc := filepath.ToSlash(filepath.Clean(t.src)) + gitDir := path.Join(cleanSrc, ".git") + + if cleanFpath == gitDir || strings.HasPrefix(cleanFpath, gitDir+"/") { return true } - if t.gitIgnore == nil { - return false + + if t.gitIgnore != nil { + return t.gitIgnore.MatchesPath(fpath) } - return t.gitIgnore.MatchesPath(fpath) + return false } // Create the actual tar by inspecting all files in source path, skipping some. diff --git a/pkg/shp/streamer/tar_test.go b/pkg/shp/streamer/tar_test.go index 810e6e4f1..12237bfec 100644 --- a/pkg/shp/streamer/tar_test.go +++ b/pkg/shp/streamer/tar_test.go @@ -3,6 +3,7 @@ package streamer import ( "archive/tar" "io" + "path/filepath" "strings" "testing" @@ -26,6 +27,7 @@ func Test_Tar(t *testing.T) { tarReader := tar.NewReader(reader) counter := 0 + foundGitIgnore := false for { header, err := tarReader.Next() if err != nil { @@ -37,10 +39,22 @@ func Test_Tar(t *testing.T) { counter++ name := header.Name + cleanName := filepath.ToSlash(name) + // On windows, trimPrefix might fail to trim the prefix cleanly due to slash mismatch, leaving ../../../ prefix. + if cleanName == ".gitignore" || strings.HasSuffix(cleanName, "/.gitignore") { + // Ensure it's not a vendor or nested gitignore + if !strings.Contains(cleanName, "vendor/") { + foundGitIgnore = true + } + } + // making sure that undesired entries are not present on the list of files caputured by the // tar helper - g.Expect(strings.HasPrefix(name, ".git/")).To(o.BeFalse()) - g.Expect(strings.HasPrefix(name, "_output/")).To(o.BeFalse()) + if strings.Contains(cleanName, ".git/") && !strings.Contains(cleanName, ".gitignore") { + g.Expect(strings.Contains(cleanName, ".git/")).To(o.BeFalse(), "should not contain .git/") + } + g.Expect(strings.HasPrefix(cleanName, "_output/")).To(o.BeFalse()) } + g.Expect(foundGitIgnore).To(o.BeTrue(), "expected .gitignore to be included in the tarball") g.Expect(counter > 10).To(o.BeTrue()) } From 85222e5db2d4c13cda27b00758b32f04dff4e28c Mon Sep 17 00:00:00 2001 From: mohit-bhandari45 Date: Sat, 5 Sep 2026 17:49:37 +0530 Subject: [PATCH 2/5] comment 1 resolved Signed-off-by: mohit-bhandari45 --- pkg/shp/streamer/tar.go | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/pkg/shp/streamer/tar.go b/pkg/shp/streamer/tar.go index 57839145e..87e591ecd 100644 --- a/pkg/shp/streamer/tar.go +++ b/pkg/shp/streamer/tar.go @@ -24,14 +24,14 @@ func (t *Tar) skipPath(fpath string, stat fs.FileInfo) bool { if !stat.Mode().IsRegular() { return true } - cleanFpath := filepath.ToSlash(fpath) - cleanSrc := filepath.ToSlash(filepath.Clean(t.src)) - gitDir := path.Join(cleanSrc, ".git") - - if cleanFpath == gitDir || strings.HasPrefix(cleanFpath, gitDir+"/") { - return true + relPath, err := filepath.Rel(t.src, fpath) + if err == nil { + cleanPath := filepath.ToSlash(relPath) + if cleanPath == ".git" || strings.HasPrefix(cleanPath, ".git/") { + return true + } } - + if t.gitIgnore != nil { return t.gitIgnore.MatchesPath(fpath) } From 1c81106ead24d24ed221c3e2d9333e2fda8edb05 Mon Sep 17 00:00:00 2001 From: mohit-bhandari45 Date: Sat, 5 Sep 2026 17:53:21 +0530 Subject: [PATCH 3/5] comment 2 resolved Signed-off-by: mohit-bhandari45 --- pkg/shp/streamer/tar_test.go | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/pkg/shp/streamer/tar_test.go b/pkg/shp/streamer/tar_test.go index 12237bfec..f7411d3fd 100644 --- a/pkg/shp/streamer/tar_test.go +++ b/pkg/shp/streamer/tar_test.go @@ -50,9 +50,7 @@ func Test_Tar(t *testing.T) { // making sure that undesired entries are not present on the list of files caputured by the // tar helper - if strings.Contains(cleanName, ".git/") && !strings.Contains(cleanName, ".gitignore") { - g.Expect(strings.Contains(cleanName, ".git/")).To(o.BeFalse(), "should not contain .git/") - } + g.Expect(strings.Split(cleanName, "/")).NotTo(o.ContainElement(".git"), "should not contain a .git path component") g.Expect(strings.HasPrefix(cleanName, "_output/")).To(o.BeFalse()) } g.Expect(foundGitIgnore).To(o.BeTrue(), "expected .gitignore to be included in the tarball") From 1fbed782cbd46b0d0ed35c901e986ec71cf6d61f Mon Sep 17 00:00:00 2001 From: mohit-bhandari45 Date: Sat, 5 Sep 2026 18:44:11 +0530 Subject: [PATCH 4/5] fix(streamer): skip nested git directories Signed-off-by: mohit-bhandari45 --- pkg/shp/streamer/tar.go | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/pkg/shp/streamer/tar.go b/pkg/shp/streamer/tar.go index 87e591ecd..4e3a9d3ba 100644 --- a/pkg/shp/streamer/tar.go +++ b/pkg/shp/streamer/tar.go @@ -26,8 +26,8 @@ func (t *Tar) skipPath(fpath string, stat fs.FileInfo) bool { } relPath, err := filepath.Rel(t.src, fpath) if err == nil { - cleanPath := filepath.ToSlash(relPath) - if cleanPath == ".git" || strings.HasPrefix(cleanPath, ".git/") { + cleanPath := "/" + filepath.ToSlash(relPath) + "/" + if strings.Contains(cleanPath, "/.git/") { return true } } From b384dacf51b065a62b34cd5f2cf1cc29911a5321 Mon Sep 17 00:00:00 2001 From: mohit-bhandari45 Date: Sat, 5 Sep 2026 18:59:51 +0530 Subject: [PATCH 5/5] fix(streamer): normalize archive member paths Signed-off-by: mohit-bhandari45 --- pkg/shp/streamer/tar_test.go | 8 ++------ pkg/shp/streamer/util.go | 11 +++++------ 2 files changed, 7 insertions(+), 12 deletions(-) diff --git a/pkg/shp/streamer/tar_test.go b/pkg/shp/streamer/tar_test.go index f7411d3fd..d0ed23203 100644 --- a/pkg/shp/streamer/tar_test.go +++ b/pkg/shp/streamer/tar_test.go @@ -40,12 +40,8 @@ func Test_Tar(t *testing.T) { name := header.Name cleanName := filepath.ToSlash(name) - // On windows, trimPrefix might fail to trim the prefix cleanly due to slash mismatch, leaving ../../../ prefix. - if cleanName == ".gitignore" || strings.HasSuffix(cleanName, "/.gitignore") { - // Ensure it's not a vendor or nested gitignore - if !strings.Contains(cleanName, "vendor/") { - foundGitIgnore = true - } + if cleanName == ".gitignore" { + foundGitIgnore = true } // making sure that undesired entries are not present on the list of files caputured by the diff --git a/pkg/shp/streamer/util.go b/pkg/shp/streamer/util.go index 4fa42b724..d499fdd90 100644 --- a/pkg/shp/streamer/util.go +++ b/pkg/shp/streamer/util.go @@ -6,7 +6,6 @@ import ( "io/fs" "os" "path/filepath" - "strings" ) type writeCounter struct{ total int } @@ -17,17 +16,17 @@ func (wc *writeCounter) Write(p []byte) (int, error) { return n, nil } -func trimPrefix(prefix, fpath string) string { - return strings.TrimPrefix(strings.ReplaceAll(fpath, prefix, ""), string(filepath.Separator)) -} - func writeFileToTar(tw *tar.Writer, src, fpath string, stat fs.FileInfo) error { header, err := tar.FileInfoHeader(stat, stat.Name()) if err != nil { return err } - header.Name = trimPrefix(src, fpath) + relPath, err := filepath.Rel(src, fpath) + if err != nil { + return err + } + header.Name = filepath.ToSlash(relPath) if err := tw.WriteHeader(header); err != nil { return err }