@@ -25,6 +25,7 @@ import (
2525 "os"
2626 "path"
2727 "path/filepath"
28+ "strings"
2829 "testing"
2930)
3031
@@ -380,3 +381,71 @@ func tgzWithSymlinks(src string, buf io.Writer) error {
380381 }
381382 return nil
382383}
384+
385+ func TestUntar_withFilter (t * testing.T ) {
386+ // Build a gzipped tar with two files.
387+ var buf bytes.Buffer
388+ gw := gzip .NewWriter (& buf )
389+ tw := tar .NewWriter (gw )
390+ for name , data := range map [string ]string {"keep.txt" : "keep" , "skip.log" : "skip" } {
391+ tw .WriteHeader (& tar.Header {Name : name , Size : int64 (len (data )), Mode : 0o644 })
392+ tw .Write ([]byte (data ))
393+ }
394+ tw .Close ()
395+ gw .Close ()
396+
397+ dst := t .TempDir ()
398+ filter := func (p string , _ os.FileInfo ) bool {
399+ return filepath .Ext (p ) == ".log"
400+ }
401+ if err := Untar (& buf , dst , WithMaxUntarSize (- 1 ), WithFilter (filter )); err != nil {
402+ t .Fatalf ("Untar: %v" , err )
403+ }
404+
405+ if _ , err := os .Stat (filepath .Join (dst , "skip.log" )); err == nil {
406+ t .Error ("filtered file skip.log should not have been extracted" )
407+ }
408+ got , err := os .ReadFile (filepath .Join (dst , "keep.txt" ))
409+ if err != nil {
410+ t .Fatalf ("read keep.txt: %v" , err )
411+ }
412+ if string (got ) != "keep" {
413+ t .Errorf ("keep.txt: got %q, want %q" , string (got ), "keep" )
414+ }
415+ }
416+
417+ func TestUntar_withFilterDirectory (t * testing.T ) {
418+ // Build a gzipped tar with entries under two directories.
419+ var buf bytes.Buffer
420+ gw := gzip .NewWriter (& buf )
421+ tw := tar .NewWriter (gw )
422+ tw .WriteHeader (& tar.Header {Name : "skip/" , Mode : 0o755 , Typeflag : tar .TypeDir })
423+ s := "secret"
424+ tw .WriteHeader (& tar.Header {Name : "skip/secret.txt" , Size : int64 (len (s )), Mode : 0o644 })
425+ tw .Write ([]byte (s ))
426+ tw .WriteHeader (& tar.Header {Name : "keep/" , Mode : 0o755 , Typeflag : tar .TypeDir })
427+ k := "public"
428+ tw .WriteHeader (& tar.Header {Name : "keep/data.txt" , Size : int64 (len (k )), Mode : 0o644 })
429+ tw .Write ([]byte (k ))
430+ tw .Close ()
431+ gw .Close ()
432+
433+ dst := t .TempDir ()
434+ filter := func (p string , _ os.FileInfo ) bool {
435+ return strings .HasPrefix (p , "skip/" )
436+ }
437+ if err := Untar (& buf , dst , WithMaxUntarSize (- 1 ), WithFilter (filter )); err != nil {
438+ t .Fatalf ("Untar: %v" , err )
439+ }
440+
441+ if _ , err := os .Stat (filepath .Join (dst , "skip" , "secret.txt" )); err == nil {
442+ t .Error ("skip/secret.txt should not have been extracted" )
443+ }
444+ got , err := os .ReadFile (filepath .Join (dst , "keep" , "data.txt" ))
445+ if err != nil {
446+ t .Fatalf ("read keep/data.txt: %v" , err )
447+ }
448+ if string (got ) != "public" {
449+ t .Errorf ("keep/data.txt: got %q, want %q" , string (got ), "public" )
450+ }
451+ }
0 commit comments