diff --git a/internal/pkg/dir.go b/internal/pkg/dir.go index 3e7ad6c..e446c56 100644 --- a/internal/pkg/dir.go +++ b/internal/pkg/dir.go @@ -184,6 +184,8 @@ func Flatten(fsys fs.FS, root string, w io.Writer) (n int, err error) { return err } ent.Data = []byte(newpath) + } else if !ent.Mode.IsDir() { + return InvalidFileModeError(ent.Mode) } nr, err = ent.Encode(w) diff --git a/internal/pkg/dir_test.go b/internal/pkg/dir_test.go index 798d0d0..9f73fb1 100644 --- a/internal/pkg/dir_test.go +++ b/internal/pkg/dir_test.go @@ -18,7 +18,15 @@ func TestFlatten(t *testing.T) { fsys fs.FS entries []pkg.FlatEntry sum pkg.Checksum + err error }{ + {"bad type", fstest.MapFS{ + ".": {Mode: fs.ModeDir | 0700}, + "invalid": {Mode: fs.ModeCharDevice | 0400}, + }, nil, pkg.Checksum{}, pkg.InvalidFileModeError( + fs.ModeCharDevice | 0400, + )}, + {"empty", fstest.MapFS{ ".": {Mode: fs.ModeDir | 0700}, "checksum": {Mode: fs.ModeDir | 0700}, @@ -29,7 +37,7 @@ func TestFlatten(t *testing.T) { {Mode: fs.ModeDir | 0700, Path: "checksum"}, {Mode: fs.ModeDir | 0700, Path: "identifier"}, {Mode: fs.ModeDir | 0700, Path: "work"}, - }, pkg.MustDecode("E4vEZKhCcL2gPZ2Tt59FS3lDng-d_2SKa2i5G_RbDfwGn6EemptFaGLPUDiOa94C")}, + }, pkg.MustDecode("E4vEZKhCcL2gPZ2Tt59FS3lDng-d_2SKa2i5G_RbDfwGn6EemptFaGLPUDiOa94C"), nil}, {"sample cache file", fstest.MapFS{ ".": {Mode: fs.ModeDir | 0700}, @@ -59,7 +67,7 @@ func TestFlatten(t *testing.T) { {Mode: fs.ModeSymlink | 0777, Path: "identifier/vsAhtPNo4waRNOASwrQwcIPTqb3SBuJOXw2G4T1mNmVZM-wrQTRllmgXqcIIoRcX", Data: []byte("../checksum/vsAhtPNo4waRNOASwrQwcIPTqb3SBuJOXw2G4T1mNmVZM-wrQTRllmgXqcIIoRcX")}, {Mode: fs.ModeDir | 0700, Path: "work"}, - }, pkg.MustDecode("St9rlE-mGZ5gXwiv_hzQ_B8bZP-UUvSNmf4nHUZzCMOumb6hKnheZSe0dmnuc4Q2")}, + }, pkg.MustDecode("St9rlE-mGZ5gXwiv_hzQ_B8bZP-UUvSNmf4nHUZzCMOumb6hKnheZSe0dmnuc4Q2"), nil}, {"sample http get cure", fstest.MapFS{ ".": {Mode: fs.ModeDir | 0700}, @@ -81,7 +89,7 @@ func TestFlatten(t *testing.T) { {Mode: fs.ModeSymlink | 0777, Path: "identifier/NqVORkT6L9HX6Za7kT2zcibY10qFqBaxEjPiYFrBQX-ZFr3yxCzJxbKOP0zVjeWb", Data: []byte("../checksum/fLYGIMHgN1louE-JzITJZJo2SDniPu-IHBXubtvQWFO-hXnDVKNuscV7-zlyr5fU")}, {Mode: fs.ModeDir | 0700, Path: "work"}, - }, pkg.MustDecode("bqtn69RkV5E7V7GhhgCFjcvbxmaqrO8DywamM4Tyjf10F6EJBHjXiIa_tFRtF4iN")}, + }, pkg.MustDecode("bqtn69RkV5E7V7GhhgCFjcvbxmaqrO8DywamM4Tyjf10F6EJBHjXiIa_tFRtF4iN"), nil}, {"sample directory step simple", fstest.MapFS{ ".": {Mode: fs.ModeDir | 0500}, @@ -101,7 +109,7 @@ func TestFlatten(t *testing.T) { {Mode: fs.ModeSymlink | 0777, Path: "lib/libedac.so", Data: []byte("/proc/nonexistent/libedac.so")}, {Mode: fs.ModeDir | 0700, Path: "lib/pkgconfig"}, - }, pkg.MustDecode("qRN6in76LndiiOZJheHkwyW8UT1N5-f-bXvHfDvwrMw2fSkOoZdh8pWE1qhLk65b")}, + }, pkg.MustDecode("qRN6in76LndiiOZJheHkwyW8UT1N5-f-bXvHfDvwrMw2fSkOoZdh8pWE1qhLk65b"), nil}, {"sample directory step garbage", fstest.MapFS{ ".": {Mode: fs.ModeDir | 0500}, @@ -117,7 +125,7 @@ func TestFlatten(t *testing.T) { {Mode: 0400, Path: "lib/check", Data: []byte{}}, {Mode: fs.ModeDir | 0500, Path: "lib/pkgconfig"}, - }, pkg.MustDecode("CUx-3hSbTWPsbMfDhgalG4Ni_GmR9TnVX8F99tY_P5GtkYvczg9RrF5zO0jX9XYT")}, + }, pkg.MustDecode("CUx-3hSbTWPsbMfDhgalG4Ni_GmR9TnVX8F99tY_P5GtkYvczg9RrF5zO0jX9XYT"), nil}, {"sample directory", fstest.MapFS{ ".": {Mode: fs.ModeDir | 0700}, @@ -149,7 +157,7 @@ func TestFlatten(t *testing.T) { {Mode: fs.ModeSymlink | 0777, Path: "identifier/Zx5ZG9BAwegNT3zQwCySuI2ktCXxNgxirkGLFjW4FW06PtojYVaCdtEw8yuntPLa", Data: []byte("../checksum/qRN6in76LndiiOZJheHkwyW8UT1N5-f-bXvHfDvwrMw2fSkOoZdh8pWE1qhLk65b")}, {Mode: fs.ModeDir | 0700, Path: "work"}, - }, pkg.MustDecode("WVpvsVqVKg9Nsh744x57h51AuWUoUR2nnh8Md-EYBQpk6ziyTuUn6PLtF2e0Eu_d")}, + }, pkg.MustDecode("WVpvsVqVKg9Nsh744x57h51AuWUoUR2nnh8Md-EYBQpk6ziyTuUn6PLtF2e0Eu_d"), nil}, {"sample tar step unpack", fstest.MapFS{ ".": {Mode: fs.ModeDir | 0500}, @@ -181,7 +189,7 @@ func TestFlatten(t *testing.T) { {Mode: fs.ModeSymlink | 0777, Path: "identifier/Zx5ZG9BAwegNT3zQwCySuI2ktCXxNgxirkGLFjW4FW06PtojYVaCdtEw8yuntPLa", Data: []byte("../checksum/1TL00Qb8dcqayX7wTO8WNaraHvY6b-KCsctLDTrb64QBCmxj_-byK1HdIUwMaFEP")}, {Mode: fs.ModeDir | 0500, Path: "work"}, - }, pkg.MustDecode("cTw0h3AmYe7XudSoyEMByduYXqGi-N5ZkTZ0t9K5elsu3i_jNIVF5T08KR1roBFM")}, + }, pkg.MustDecode("cTw0h3AmYe7XudSoyEMByduYXqGi-N5ZkTZ0t9K5elsu3i_jNIVF5T08KR1roBFM"), nil}, {"sample tar", fstest.MapFS{ ".": {Mode: fs.ModeDir | 0700}, @@ -225,7 +233,7 @@ func TestFlatten(t *testing.T) { {Mode: fs.ModeDir | 0700, Path: "temp"}, {Mode: fs.ModeDir | 0700, Path: "work"}, - }, pkg.MustDecode("PrNWkHqtSmdtVecctlI9Xf63dQPIyyLBIMCtRAP2-VqF9u1oQ8ydV7-WPbzEvMkG")}, + }, pkg.MustDecode("PrNWkHqtSmdtVecctlI9Xf63dQPIyyLBIMCtRAP2-VqF9u1oQ8ydV7-WPbzEvMkG"), nil}, {"sample tar expand step unpack", fstest.MapFS{ ".": {Mode: fs.ModeDir | 0500}, @@ -235,7 +243,7 @@ func TestFlatten(t *testing.T) { {Mode: fs.ModeDir | 0500, Path: "."}, {Mode: fs.ModeSymlink | 0777, Path: "libedac.so", Data: []byte("/proc/nonexistent/libedac.so")}, - }, pkg.MustDecode("CH3AiUrCCcVOjOYLaMKKK1Da78989JtfHeIsxMzWOQFiN4mrCLDYpoDxLWqJWCUN")}, + }, pkg.MustDecode("CH3AiUrCCcVOjOYLaMKKK1Da78989JtfHeIsxMzWOQFiN4mrCLDYpoDxLWqJWCUN"), nil}, {"sample tar expand", fstest.MapFS{ ".": {Mode: fs.ModeDir | 0700}, @@ -261,7 +269,7 @@ func TestFlatten(t *testing.T) { {Mode: fs.ModeDir | 0700, Path: "temp"}, {Mode: fs.ModeDir | 0700, Path: "work"}, - }, pkg.MustDecode("YZUoGdMwmfW5sQWto9hQgMKah648rHKck8Ds_GGnqgCBpTAiZKOefpHCKnvktfYh")}, + }, pkg.MustDecode("YZUoGdMwmfW5sQWto9hQgMKah648rHKck8Ds_GGnqgCBpTAiZKOefpHCKnvktfYh"), nil}, {"testtool", fstest.MapFS{ ".": {Mode: fs.ModeDir | 0500}, @@ -271,7 +279,7 @@ func TestFlatten(t *testing.T) { {Mode: fs.ModeDir | 0500, Path: "."}, {Mode: 0400, Path: "check", Data: []byte{0}}, - }, pkg.MustDecode("GPa4aBakdSJd7Tz7LYj_VJFoojzyZinmVcG3k6M5xI6CZ821J5sXLhLDDuS47gi9")}, + }, pkg.MustDecode("GPa4aBakdSJd7Tz7LYj_VJFoojzyZinmVcG3k6M5xI6CZ821J5sXLhLDDuS47gi9"), nil}, {"sample exec container", fstest.MapFS{ ".": {Mode: fs.ModeDir | 0700}, @@ -305,7 +313,7 @@ func TestFlatten(t *testing.T) { {Mode: fs.ModeDir | 0700, Path: "temp"}, {Mode: fs.ModeDir | 0700, Path: "work"}, - }, pkg.MustDecode("7PoPpWLjFPXIymbuIYLZAzOpCYr-2PN4CZ11jFdO-mDlnZNgFO3JyOtK8HW8Jxvm")}, + }, pkg.MustDecode("7PoPpWLjFPXIymbuIYLZAzOpCYr-2PN4CZ11jFdO-mDlnZNgFO3JyOtK8HW8Jxvm"), nil}, {"testtool net", fstest.MapFS{ ".": {Mode: fs.ModeDir | 0500}, @@ -315,7 +323,7 @@ func TestFlatten(t *testing.T) { {Mode: fs.ModeDir | 0500, Path: "."}, {Mode: 0400, Path: "check", Data: []byte("net")}, - }, pkg.MustDecode("a1F_i9PVQI4qMcoHgTQkORuyWLkC1GLIxOhDt2JpU1NGAxWc5VJzdlfRK-PYBh3W")}, + }, pkg.MustDecode("a1F_i9PVQI4qMcoHgTQkORuyWLkC1GLIxOhDt2JpU1NGAxWc5VJzdlfRK-PYBh3W"), nil}, {"sample exec net container", fstest.MapFS{ ".": {Mode: fs.ModeDir | 0700}, @@ -349,7 +357,7 @@ func TestFlatten(t *testing.T) { {Mode: fs.ModeDir | 0700, Path: "temp"}, {Mode: fs.ModeDir | 0700, Path: "work"}, - }, pkg.MustDecode("bBQVFIt0FnOulljgpLnGtuzHSFgwiCMjc4pmc4rHRqXKQ60Q5aBVYp5f6aH9VdZi")}, + }, pkg.MustDecode("bBQVFIt0FnOulljgpLnGtuzHSFgwiCMjc4pmc4rHRqXKQ60Q5aBVYp5f6aH9VdZi"), nil}, {"sample exec container overlay root", fstest.MapFS{ ".": {Mode: fs.ModeDir | 0700}, @@ -379,7 +387,7 @@ func TestFlatten(t *testing.T) { {Mode: fs.ModeDir | 0700, Path: "temp"}, {Mode: fs.ModeDir | 0700, Path: "work"}, - }, pkg.MustDecode("gFT9kprYBqEJKifJIl2sHn_3TgULWVLTU4DrYAHiGcRmcdFRZ0YtjiROW820cAEc")}, + }, pkg.MustDecode("gFT9kprYBqEJKifJIl2sHn_3TgULWVLTU4DrYAHiGcRmcdFRZ0YtjiROW820cAEc"), nil}, {"sample exec container overlay temp", fstest.MapFS{ ".": {Mode: fs.ModeDir | 0700}, @@ -409,7 +417,7 @@ func TestFlatten(t *testing.T) { {Mode: fs.ModeDir | 0700, Path: "temp"}, {Mode: fs.ModeDir | 0700, Path: "work"}, - }, pkg.MustDecode("_r1IBeMWCkLwQ9Im9w0tV9_CWIOfQlXkkP2CogPHLmZp_AB6W3_8HVZqDV00dNAm")}, + }, pkg.MustDecode("_r1IBeMWCkLwQ9Im9w0tV9_CWIOfQlXkkP2CogPHLmZp_AB6W3_8HVZqDV00dNAm"), nil}, {"sample exec container overlay work", fstest.MapFS{ ".": {Mode: fs.ModeDir | 0700}, @@ -439,7 +447,7 @@ func TestFlatten(t *testing.T) { {Mode: fs.ModeDir | 0700, Path: "temp"}, {Mode: fs.ModeDir | 0700, Path: "work"}, - }, pkg.MustDecode("-DrfvuB9gUAT-Tgw6V1KjFyosYGMGKJW7KMZFF1Ew8jZ9LJ82FtXf0wTgM3fO0oD")}, + }, pkg.MustDecode("-DrfvuB9gUAT-Tgw6V1KjFyosYGMGKJW7KMZFF1Ew8jZ9LJ82FtXf0wTgM3fO0oD"), nil}, {"sample file short", fstest.MapFS{ ".": {Mode: fs.ModeDir | 0700}, @@ -460,7 +468,7 @@ func TestFlatten(t *testing.T) { {Mode: fs.ModeSymlink | 0777, Path: "identifier/lIx_W4M7tVOcQ8jh08EJOfXf4brRmkEEjvUa7c17vVUzlmtUxlhhrgqmc9aZhjbn", Data: []byte("../checksum/vsAhtPNo4waRNOASwrQwcIPTqb3SBuJOXw2G4T1mNmVZM-wrQTRllmgXqcIIoRcX")}, {Mode: fs.ModeDir | 0700, Path: "work"}, - }, pkg.MustDecode("hnrfmJtivNKcgtETsKnU9gP_OwPgpNY3DSUJnmxnmeOODSO-YBvEBiTgieY4AAd7")}, + }, pkg.MustDecode("hnrfmJtivNKcgtETsKnU9gP_OwPgpNY3DSUJnmxnmeOODSO-YBvEBiTgieY4AAd7"), nil}, } for _, tc := range testCases { t.Run(tc.name, func(t *testing.T) { @@ -470,8 +478,14 @@ func TestFlatten(t *testing.T) { t.Parallel() var buf bytes.Buffer - if _, err := pkg.Flatten(tc.fsys, ".", &buf); err != nil { - t.Fatalf("Flatten: error = %v", err) + if _, err := pkg.Flatten( + tc.fsys, + ".", + &buf, + ); !reflect.DeepEqual(err, tc.err) { + t.Fatalf("Flatten: error = %v, want %v", err, tc.err) + } else if tc.err != nil { + return } s := pkg.NewDirScanner(bytes.NewReader(buf.Bytes()), true) @@ -488,6 +502,10 @@ func TestFlatten(t *testing.T) { } }) + if tc.err != nil { + return + } + t.Run("hash", func(t *testing.T) { t.Parallel()