From d2676618c099cb1acddc51fac4c206ee4d6cbc39 Mon Sep 17 00:00:00 2001 From: ahrav Date: Fri, 15 Sep 2023 04:37:15 -0700 Subject: [PATCH] [bug] - correclty handle nested archived directories (#1778) --- pkg/handlers/archive.go | 2 +- pkg/handlers/archive_test.go | 23 +++++++++++ pkg/handlers/handlers.go | 56 +++++++++++++------------- pkg/handlers/testdata/dir-archive.zip | Bin 0 -> 1821 bytes 4 files changed, 53 insertions(+), 28 deletions(-) create mode 100644 pkg/handlers/testdata/dir-archive.zip diff --git a/pkg/handlers/archive.go b/pkg/handlers/archive.go index d46016656..b1257be7e 100644 --- a/pkg/handlers/archive.go +++ b/pkg/handlers/archive.go @@ -78,7 +78,7 @@ func (a *Archive) FromFile(originalCtx context.Context, data io.Reader) chan []b if errors.Is(err, archiver.ErrNoMatch) { return } - logger.V(2).Info("Error unarchiving chunk.") + logger.Error(err, "error unarchiving chunk.") } }() return archiveChan diff --git a/pkg/handlers/archive_test.go b/pkg/handlers/archive_test.go index f70eab293..5c371faa6 100644 --- a/pkg/handlers/archive_test.go +++ b/pkg/handlers/archive_test.go @@ -9,6 +9,7 @@ import ( "regexp" "strings" "testing" + "time" diskbufferreader "github.com/bill-rich/disk-buffer-reader" "github.com/stretchr/testify/assert" @@ -248,3 +249,25 @@ func TestOpenInvalidArchive(t *testing.T) { err := a.openArchive(ctx, 0, reader, archiveChan) assert.Error(t, err) } + +func TestNestedDirArchive(t *testing.T) { + file, err := os.Open("testdata/dir-archive.zip") + assert.Nil(t, err) + defer file.Close() + + ctx, cancel := logContext.WithTimeout(logContext.Background(), 5*time.Second) + defer cancel() + sourceChan := make(chan *sources.Chunk, 1) + + go func() { + defer close(sourceChan) + HandleFile(ctx, file, &sources.Chunk{}, sourceChan) + }() + + count := 0 + want := 4 + for range sourceChan { + count++ + } + assert.Equal(t, want, count) +} diff --git a/pkg/handlers/handlers.go b/pkg/handlers/handlers.go index cce0fe1bf..5ff59a7a7 100644 --- a/pkg/handlers/handlers.go +++ b/pkg/handlers/handlers.go @@ -47,42 +47,44 @@ func HandleFile(ctx context.Context, file io.Reader, chunkSkel *sources.Chunk, c // an io.MultiReader, which is used by the SpecializedHandler. reReader, err := diskbufferreader.New(file) if err != nil { - aCtx.Logger().Error(err, "error creating re-reader reader") + aCtx.Logger().Error(err, "error creating reusable reader") return false } - defer reReader.Close() - // Check if the handler implements SpecializedHandler and process accordingly. - if specialHandler, ok := h.(SpecializedHandler); ok { - file, isSpecial, err := specialHandler.HandleSpecialized(aCtx, reReader) - if isSpecial { - return handleChunks(aCtx, h.FromFile(ctx, file), chunkSkel, chunksChan) - } - - if err != nil { - aCtx.Logger().Error(err, "error handling file") - } + if success := processHandler(aCtx, h, reReader, chunkSkel, chunksChan); success { + return true } - - if err := reReader.Reset(); err != nil { - aCtx.Logger().Error(err, "error resetting re-reader") - return false - } - if _, isType := h.IsFiletype(aCtx, reReader); !isType { - continue - } - - if err := reReader.Reset(); err != nil { - aCtx.Logger().Error(err, "error resetting re-reader") - return false - } - reReader.Stop() - return handleChunks(aCtx, h.FromFile(ctx, reReader), chunkSkel, chunksChan) } return false } +func processHandler(ctx logContext.Context, h Handler, reReader *diskbufferreader.DiskBufferReader, chunkSkel *sources.Chunk, chunksChan chan *sources.Chunk) bool { + defer reReader.Close() + defer reReader.Stop() + + if specialHandler, ok := h.(SpecializedHandler); ok { + file, isSpecial, err := specialHandler.HandleSpecialized(ctx, reReader) + if isSpecial { + return handleChunks(ctx, h.FromFile(ctx, file), chunkSkel, chunksChan) + } + if err != nil { + ctx.Logger().Error(err, "error handling file") + } + } + + if _, err := reReader.Seek(0, io.SeekStart); err != nil { + ctx.Logger().Error(err, "error seeking to start of file") + return false + } + + if _, isType := h.IsFiletype(ctx, reReader); !isType { + return false + } + + return handleChunks(ctx, h.FromFile(ctx, reReader), chunkSkel, chunksChan) +} + func handleChunks(ctx context.Context, handlerChan chan []byte, chunkSkel *sources.Chunk, chunksChan chan *sources.Chunk) bool { for { select { diff --git a/pkg/handlers/testdata/dir-archive.zip b/pkg/handlers/testdata/dir-archive.zip new file mode 100644 index 0000000000000000000000000000000000000000..501eee4e62962aa87debeb82c3c488921a3cd52e GIT binary patch literal 1821 zcmWIWW@Zs#00F)-y>KuCO0X~}FeK$C>4%2!GO(|yXHJFT(h6<{MwYLP3=CkM0bmn2 z7&sWXkxXEbU|`^dnxN+r93NbgUz7?qYB|s-7)CSd?TmwdhYTbd{`YCdb`-Mv`s^|J z=%r-M!xyJ^PQ1V+`GP_+w_e{gg93J^L);5&q zwvK^eWxoxx13LrPOi|uxP8(~S9mOX*T{2v>PnyeoXI0_v)5j;}NW9#u-N0@4BX7?B z`a}UfCW*ZhhYF>5cN+zw9+W*#5TR zcXMR>fzOlG%)=SKyTphqzjHks(~uRC{j&Y>#>llZQ^QPGO*WF2c3T>j=62LXUAXt1 zyzKm#EpmtC#QksX;XKGvwom2D9*+~CMYc_ua18 zUuS#PeXsnYzrRBl+gUNoaouaZDXcWnLq(ctoyV3f_cA?HCh@Ao%1hjG@;4Ul(atcv z?(S~9rFCAK+6_O))frvaF7o6qTt2h#qEf{Vg&${G{54#F@?Td^QJqxptT=hzyZ_Hu zpZ_n^`Gns&>nJV4@yOP@z_(rK45AyUR51le=-pu*zPo|2!UZy5C{e@H^BRHH~ zZl81O0Qv#s58OT!Knf=eUz$L}Y{>YMkx7IZcR2?P2rzi-2%?B9^&lp~%01+40V?-k zU`eAB)I{v*A5;>e1!90Vs?o^F8kDbKU`eAb69d_~3}y?+G;CP}X3Ja08$eq?K|)-H zLAV{1Wss8^D9gaWl14dZh^ZJ!3r7Zmxfc}R=q7`bDhw=XWMDzK7sGTM2{*u-l?`M9 P8xSf2{re1P1_J{CjtLa( literal 0 HcmV?d00001