copier.Get(): ensure that directory entries end in "/"

Make sure that entries with Typeflag == TypeDir always end with a "/",
adding it as a suffix.

Signed-off-by: Nalin Dahyabhai <nalin@redhat.com>
This commit is contained in:
Nalin Dahyabhai 2025-08-08 14:59:17 -04:00 committed by openshift-cherrypick-robot
parent 9933e79661
commit f42946075a
3 changed files with 56 additions and 53 deletions

View File

@ -1699,6 +1699,9 @@ func copierHandlerGetOne(srcfi os.FileInfo, symlinkTarget, name, contentPath str
if options.ChmodDirs != nil { if options.ChmodDirs != nil {
hdr.Mode = int64(*options.ChmodDirs) hdr.Mode = int64(*options.ChmodDirs)
} }
if !strings.HasSuffix(hdr.Name, "/") {
hdr.Name += "/"
}
} else { } else {
if options.ChownFiles != nil { if options.ChownFiles != nil {
hdr.Uid, hdr.Gid = options.ChownFiles.UID, options.ChownFiles.GID hdr.Uid, hdr.Gid = options.ChownFiles.UID, options.ChownFiles.GID

View File

@ -184,7 +184,7 @@ func TestGetNoCrossDevice(t *testing.T) {
tr := tar.NewReader(&buf) tr := tar.NewReader(&buf)
th, err := tr.Next() // should be the "subdir" directory th, err := tr.Next() // should be the "subdir" directory
require.NoError(t, err, "error reading first entry archived") require.NoError(t, err, "error reading first entry archived")
assert.Equal(t, "subdir", th.Name, `first entry in archive was not named "subdir"`) assert.Equal(t, "subdir/", th.Name, `first entry in archive was not named "subdir/"`)
th, err = tr.Next() th, err = tr.Next()
assert.Error(t, err, "should not have gotten a second entry in archive") assert.Error(t, err, "should not have gotten a second entry in archive")

View File

@ -912,22 +912,22 @@ func testGetMultiple(t *testing.T) {
{Name: "non-archive-a", Typeflag: tar.TypeReg, Size: 1199, Mode: 0o600}, {Name: "non-archive-a", Typeflag: tar.TypeReg, Size: 1199, Mode: 0o600},
{Name: "hlink-0", Typeflag: tar.TypeLink, Linkname: "file-0", Size: 123456789, Mode: 0o600}, {Name: "hlink-0", Typeflag: tar.TypeLink, Linkname: "file-0", Size: 123456789, Mode: 0o600},
{Name: "something-a", Typeflag: tar.TypeReg, Size: 34, Mode: 0o600}, {Name: "something-a", Typeflag: tar.TypeReg, Size: 34, Mode: 0o600},
{Name: "subdir-a", Typeflag: tar.TypeDir, Mode: 0o700}, {Name: "subdir-a/", Typeflag: tar.TypeDir, Mode: 0o700},
{Name: "subdir-a/file-n", Typeflag: tar.TypeReg, Size: 108, Mode: 0o660}, {Name: "subdir-a/file-n", Typeflag: tar.TypeReg, Size: 108, Mode: 0o660},
{Name: "subdir-a/file-o", Typeflag: tar.TypeReg, Size: 45, Mode: 0o660}, {Name: "subdir-a/file-o", Typeflag: tar.TypeReg, Size: 45, Mode: 0o660},
{Name: "subdir-a/file-a", Typeflag: tar.TypeSymlink, Linkname: "../file-a", Size: 23, Mode: 0o600}, {Name: "subdir-a/file-a", Typeflag: tar.TypeSymlink, Linkname: "../file-a", Size: 23, Mode: 0o600},
{Name: "subdir-a/file-b", Typeflag: tar.TypeSymlink, Linkname: "../../file-b", Size: 23, Mode: 0o600}, {Name: "subdir-a/file-b", Typeflag: tar.TypeSymlink, Linkname: "../../file-b", Size: 23, Mode: 0o600},
{Name: "subdir-a/file-c", Typeflag: tar.TypeReg, Size: 56, Mode: 0o600}, {Name: "subdir-a/file-c", Typeflag: tar.TypeReg, Size: 56, Mode: 0o600},
{Name: "subdir-b", Typeflag: tar.TypeDir, Mode: 0o700}, {Name: "subdir-b/", Typeflag: tar.TypeDir, Mode: 0o700},
{Name: "subdir-b/file-n", Typeflag: tar.TypeReg, Size: 216, Mode: 0o660}, {Name: "subdir-b/file-n", Typeflag: tar.TypeReg, Size: 216, Mode: 0o660},
{Name: "subdir-b/file-o", Typeflag: tar.TypeReg, Size: 67, Mode: 0o660}, {Name: "subdir-b/file-o", Typeflag: tar.TypeReg, Size: 67, Mode: 0o660},
{Name: "subdir-c", Typeflag: tar.TypeDir, Mode: 0o700}, {Name: "subdir-c/", Typeflag: tar.TypeDir, Mode: 0o700},
{Name: "subdir-c/file-p", Typeflag: tar.TypeReg, Size: 432, Mode: 0o666}, {Name: "subdir-c/file-p", Typeflag: tar.TypeReg, Size: 432, Mode: 0o666},
{Name: "subdir-c/file-q", Typeflag: tar.TypeReg, Size: 78, Mode: 0o666}, {Name: "subdir-c/file-q", Typeflag: tar.TypeReg, Size: 78, Mode: 0o666},
{Name: "subdir-d", Typeflag: tar.TypeDir, Mode: 0o700}, {Name: "subdir-d/", Typeflag: tar.TypeDir, Mode: 0o700},
{Name: "subdir-d/hlink-0", Typeflag: tar.TypeLink, Linkname: "../file-0", Size: 123456789, Mode: 0o600}, {Name: "subdir-d/hlink-0", Typeflag: tar.TypeLink, Linkname: "../file-0", Size: 123456789, Mode: 0o600},
{Name: "subdir-e", Typeflag: tar.TypeDir, Mode: 0o700}, {Name: "subdir-e/", Typeflag: tar.TypeDir, Mode: 0o700},
{Name: "subdir-e/subdir-f", Typeflag: tar.TypeDir, Mode: 0o700}, {Name: "subdir-e/subdir-f/", Typeflag: tar.TypeDir, Mode: 0o700},
{Name: "subdir-e/subdir-f/hlink-b", Typeflag: tar.TypeLink, Linkname: "../../file-b", Size: 23, Mode: 0o600}, {Name: "subdir-e/subdir-f/hlink-b", Typeflag: tar.TypeLink, Linkname: "../../file-b", Size: 23, Mode: 0o600},
}, },
contents: map[string][]byte{ contents: map[string][]byte{
@ -952,22 +952,22 @@ func testGetMultiple(t *testing.T) {
"something-a", "something-a",
"archive-a", "archive-a",
"non-archive-a", "non-archive-a",
"subdir-a", "subdir-a/",
"subdir-a/file-n", "subdir-a/file-n",
"subdir-a/file-o", "subdir-a/file-o",
"subdir-a/file-a", "subdir-a/file-a",
"subdir-a/file-b", "subdir-a/file-b",
"subdir-a/file-c", "subdir-a/file-c",
"subdir-b", "subdir-b/",
"subdir-b/file-n", "subdir-b/file-n",
"subdir-b/file-o", "subdir-b/file-o",
"subdir-c", "subdir-c/",
"subdir-c/file-p", "subdir-c/file-p",
"subdir-c/file-q", "subdir-c/file-q",
"subdir-d", "subdir-d/",
"subdir-d/hlink-0", "subdir-d/hlink-0",
"subdir-e", "subdir-e/",
"subdir-e/subdir-f", "subdir-e/subdir-f/",
"subdir-e/subdir-f/hlink-b", "subdir-e/subdir-f/hlink-b",
}, },
}, },
@ -995,7 +995,7 @@ func testGetMultiple(t *testing.T) {
"file-q", // from subdir-c "file-q", // from subdir-c
"file-q", // from link-c -> subdir-c "file-q", // from link-c -> subdir-c
"hlink-0", // from subdir-d "hlink-0", // from subdir-d
"subdir-f", // from subdir-e "subdir-f/", // from subdir-e
"subdir-f/hlink-b", // from subdir-e "subdir-f/hlink-b", // from subdir-e
}, },
}, },
@ -1019,16 +1019,16 @@ func testGetMultiple(t *testing.T) {
"link-c", "link-c",
"hlink-0", "hlink-0",
// "subdir-a/file-c", // strings.HasPrefix("**/*-c", "subdir-a/") is false // "subdir-a/file-c", // strings.HasPrefix("**/*-c", "subdir-a/") is false
"subdir-b", "subdir-b/",
"subdir-b/file-n", "subdir-b/file-n",
"subdir-b/file-o", "subdir-b/file-o",
"subdir-c", "subdir-c/",
"subdir-c/file-p", "subdir-c/file-p",
"subdir-c/file-q", "subdir-c/file-q",
"subdir-d", "subdir-d/",
"subdir-d/hlink-0", "subdir-d/hlink-0",
"subdir-e", "subdir-e/",
"subdir-e/subdir-f", "subdir-e/subdir-f/",
"subdir-e/subdir-f/hlink-b", "subdir-e/subdir-f/hlink-b",
}, },
}, },
@ -1048,7 +1048,7 @@ func testGetMultiple(t *testing.T) {
"file-q", // from link-c -> subdir-c "file-q", // from link-c -> subdir-c
"hlink-0", "hlink-0",
"hlink-0", "hlink-0",
"subdir-f", "subdir-f/",
"subdir-f/hlink-b", "subdir-f/hlink-b",
}, },
}, },
@ -1066,22 +1066,22 @@ func testGetMultiple(t *testing.T) {
"something-a", "something-a",
"archive-a", "archive-a",
"non-archive-a", "non-archive-a",
"subdir-a", "subdir-a/",
"subdir-a/file-a", "subdir-a/file-a",
"subdir-a/file-b", "subdir-a/file-b",
"subdir-a/file-c", "subdir-a/file-c",
"subdir-a/file-n", "subdir-a/file-n",
"subdir-a/file-o", "subdir-a/file-o",
"subdir-b", "subdir-b/",
"subdir-b/file-n", "subdir-b/file-n",
"subdir-b/file-o", "subdir-b/file-o",
"subdir-c", "subdir-c/",
"subdir-c/file-p", "subdir-c/file-p",
"subdir-c/file-q", "subdir-c/file-q",
"subdir-d", "subdir-d/",
"subdir-d/hlink-0", "subdir-d/hlink-0",
"subdir-e", "subdir-e/",
"subdir-e/subdir-f", "subdir-e/subdir-f/",
"subdir-e/subdir-f/hlink-b", "subdir-e/subdir-f/hlink-b",
}, },
}, },
@ -1110,7 +1110,7 @@ func testGetMultiple(t *testing.T) {
"something-a", "something-a",
"archive-a", "archive-a",
"non-archive-a", "non-archive-a",
"subdir-f", "subdir-f/",
"subdir-f/hlink-b", "subdir-f/hlink-b",
}, },
}, },
@ -1133,7 +1133,7 @@ func testGetMultiple(t *testing.T) {
items: []string{ items: []string{
// "subdir-a/file-c", // strings.HasPrefix("**/*-c", "subdir-a/") is false // "subdir-a/file-c", // strings.HasPrefix("**/*-c", "subdir-a/") is false
"link-c", "link-c",
"subdir-c", "subdir-c/",
"subdir-c/file-p", "subdir-c/file-p",
"subdir-c/file-q", "subdir-c/file-q",
}, },
@ -1241,7 +1241,7 @@ func testGetMultiple(t *testing.T) {
name: "subdirectory", name: "subdirectory",
pattern: "subdir-e", pattern: "subdir-e",
items: []string{ items: []string{
"subdir-f", "subdir-f/",
"subdir-f/hlink-b", "subdir-f/hlink-b",
}, },
}, },
@ -1275,7 +1275,7 @@ func testGetMultiple(t *testing.T) {
name: "subdir-without-name", name: "subdir-without-name",
pattern: "subdir-e", pattern: "subdir-e",
items: []string{ items: []string{
"subdir-f", "subdir-f/",
"subdir-f/hlink-b", "subdir-f/hlink-b",
}, },
}, },
@ -1284,8 +1284,8 @@ func testGetMultiple(t *testing.T) {
pattern: "subdir-e", pattern: "subdir-e",
keepDirectoryNames: true, keepDirectoryNames: true,
items: []string{ items: []string{
"subdir-e", "subdir-e/",
"subdir-e/subdir-f", "subdir-e/subdir-f/",
"subdir-e/subdir-f/hlink-b", "subdir-e/subdir-f/hlink-b",
}, },
}, },
@ -1336,7 +1336,7 @@ func testGetMultiple(t *testing.T) {
"archive-a", "archive-a",
"non-archive-a", "non-archive-a",
"something-a", "something-a",
"subdir-b", "subdir-b/",
"subdir-b/file-n", "subdir-b/file-n",
"subdir-b/file-o", "subdir-b/file-o",
"subdir-b/file-a", "subdir-b/file-a",
@ -1391,11 +1391,11 @@ func testGetMultiple(t *testing.T) {
"something-a", "something-a",
"archive-a", "archive-a",
"non-archive-a", "non-archive-a",
"subdir-a", "subdir-a/",
"subdir-b", "subdir-b/",
"subdir-c", "subdir-c/",
"subdir-d", "subdir-d/",
"subdir-e", "subdir-e/",
"subdir-a/file-n", "subdir-a/file-n",
"subdir-a/file-o", "subdir-a/file-o",
"subdir-a/file-a", "subdir-a/file-a",
@ -1408,7 +1408,7 @@ func testGetMultiple(t *testing.T) {
"subdir-c/file-q", "subdir-c/file-q",
"subdir-c/file-q", "subdir-c/file-q",
"subdir-d/hlink-0", "subdir-d/hlink-0",
"subdir-e/subdir-f", "subdir-e/subdir-f/",
"subdir-e/subdir-f/hlink-b", "subdir-e/subdir-f/hlink-b",
}, },
}, },
@ -1420,11 +1420,11 @@ func testGetMultiple(t *testing.T) {
items: []string{ items: []string{
"file-0", "file-0",
"file-b", "file-b",
"subdir-a", "subdir-a/",
"subdir-b", "subdir-b/",
"subdir-c", "subdir-c/",
"subdir-d", "subdir-d/",
"subdir-e", "subdir-e/",
"subdir-a/file-c", "subdir-a/file-c",
"subdir-b/file-n", "subdir-b/file-n",
"subdir-b/file-o", "subdir-b/file-o",
@ -1434,7 +1434,7 @@ func testGetMultiple(t *testing.T) {
"subdir-c/file-q", "subdir-c/file-q",
"hlink-0", "hlink-0",
"subdir-d/hlink-0", "subdir-d/hlink-0",
"subdir-e/subdir-f", "subdir-e/subdir-f/",
"subdir-e/subdir-f/hlink-b", "subdir-e/subdir-f/hlink-b",
}, },
}, },
@ -1448,7 +1448,7 @@ func testGetMultiple(t *testing.T) {
"something-a", "something-a",
"archive-a", "archive-a",
"non-archive-a", "non-archive-a",
"subdir-a", "subdir-a/",
"subdir-a/file-n", "subdir-a/file-n",
"subdir-a/file-o", "subdir-a/file-o",
"subdir-a/file-a", "subdir-a/file-a",
@ -1461,7 +1461,7 @@ func testGetMultiple(t *testing.T) {
pattern: "/subdir-b/*", pattern: "/subdir-b/*",
parents: true, parents: true,
items: []string{ items: []string{
"subdir-b", "subdir-b/",
"subdir-b/file-n", "subdir-b/file-n",
"subdir-b/file-o", "subdir-b/file-o",
}, },
@ -1471,18 +1471,18 @@ func testGetMultiple(t *testing.T) {
pattern: "../../subdir-b/*", pattern: "../../subdir-b/*",
parents: true, parents: true,
items: []string{ items: []string{
"subdir-b", "subdir-b/",
"subdir-b/file-n", "subdir-b/file-n",
"subdir-b/file-o", "subdir-b/file-o",
}, },
}, },
{ {
name: "dir-with-parents", name: "dir-with-parents",
pattern: "subdir-e/subdir-f", pattern: "subdir-e/subdir-f/",
parents: true, parents: true,
items: []string{ items: []string{
"subdir-e", "subdir-e/",
"subdir-e/subdir-f", "subdir-e/subdir-f/",
"subdir-e/subdir-f/hlink-b", "subdir-e/subdir-f/hlink-b",
}, },
}, },
@ -1491,8 +1491,8 @@ func testGetMultiple(t *testing.T) {
pattern: "subdir-e/subdir-f/hlink-b", pattern: "subdir-e/subdir-f/hlink-b",
parents: true, parents: true,
items: []string{ items: []string{
"subdir-e", "subdir-e/",
"subdir-e/subdir-f", "subdir-e/subdir-f/",
"subdir-e/subdir-f/hlink-b", "subdir-e/subdir-f/hlink-b",
}, },
}, },