@@ -10,6 +10,7 @@ import (
1010 "runtime"
1111 "strings"
1212 "sync"
13+ "time"
1314
1415 "github.com/chainguard-dev/clog"
1516 "github.com/chainguard-dev/malcontent/pkg/pool"
@@ -32,7 +33,7 @@ func IsValidPath(target, dir string) bool {
3233 return strings .HasPrefix (filepath .Clean (target ), filepath .Clean (dir ))
3334}
3435
35- func extractNestedArchive (ctx context.Context , d string , f string , extracted * sync.Map ) error {
36+ func extractNestedArchive (ctx context.Context , d string , f string , extracted * sync.Map , logger * clog. Logger ) error {
3637 if ctx .Err () != nil {
3738 return ctx .Err ()
3839 }
@@ -87,14 +88,28 @@ func extractNestedArchive(ctx context.Context, d string, f string, extracted *sy
8788 return nil
8889 }
8990
90- err = extract (ctx , d , fullPath )
91+ archivePath := filepath .Join (d , strings .TrimSuffix (f , programkind .GetExt (f )))
92+ // Some packages may have archives and files with colliding names
93+ // e.g., demo_page.css and demo_page.css.gz
94+ // the former is the uncompressed version of the latter
95+ // if we encounter this, replace the name with something that won't collide
96+ if _ , err := os .Stat (archivePath ); err == nil {
97+ logger .Debugf ("duplicate file name already exists, modifying directory name for %s" , archivePath )
98+ archivePath = fmt .Sprintf ("%s%d" , archivePath , time .Now ().UnixNano ())
99+ }
100+
101+ if err := os .MkdirAll (archivePath , 0o755 ); err != nil {
102+ return fmt .Errorf ("failed to create extraction directory: %w" , err )
103+ }
104+
105+ err = extract (ctx , archivePath , fullPath )
91106 if err != nil {
92107 return fmt .Errorf ("failed to extract archive: %w" , err )
93108 }
94109
95110 extracted .Store (f , true )
96111
97- if err := os .RemoveAll (fullPath ); err != nil {
112+ if err := os .Remove (fullPath ); err != nil {
98113 return fmt .Errorf ("failed to remove archive file: %w" , err )
99114 }
100115
@@ -109,7 +124,7 @@ func extractNestedArchive(ctx context.Context, d string, f string, extracted *sy
109124 }
110125 rel := file .Name ()
111126 if _ , alreadyProcessed := extracted .Load (rel ); ! alreadyProcessed {
112- if err := extractNestedArchive (ctx , d , rel , extracted ); err != nil {
127+ if err := extractNestedArchive (ctx , d , rel , extracted , logger ); err != nil {
113128 return fmt .Errorf ("process nested file %s: %w" , rel , err )
114129 }
115130 }
@@ -187,7 +202,7 @@ func ExtractArchiveToTempDir(ctx context.Context, path string) (string, error) {
187202
188203 ext := programkind .GetExt (path )
189204 if _ , ok := programkind .ArchiveMap [ext ]; ok {
190- if err := extractNestedArchive (ctx , tmpDir , rel , & extractedFiles ); err != nil {
205+ if err := extractNestedArchive (ctx , tmpDir , rel , & extractedFiles , logger ); err != nil {
191206 return err
192207 }
193208 }
0 commit comments