@@ -628,10 +628,11 @@ func (b *readBuf) sub(n int) readBuf {
628
628
}
629
629
630
630
// A fileListEntry is a File and its ename.
631
- // If file == nil, the fileListEntry describes a directory, without metadata.
631
+ // If file == nil, the fileListEntry describes a directory without metadata.
632
632
type fileListEntry struct {
633
- name string
634
- file * File // nil for directories
633
+ name string
634
+ file * File
635
+ isDir bool
635
636
}
636
637
637
638
type fileInfoDirEntry interface {
@@ -640,20 +641,26 @@ type fileInfoDirEntry interface {
640
641
}
641
642
642
643
func (e * fileListEntry ) stat () fileInfoDirEntry {
643
- if e . file != nil {
644
+ if ! e . isDir {
644
645
return headerFileInfo {& e .file .FileHeader }
645
646
}
646
647
return e
647
648
}
648
649
649
650
// Only used for directories.
650
- func (f * fileListEntry ) Name () string { _ , elem , _ := split (f .name ); return elem }
651
- func (f * fileListEntry ) Size () int64 { return 0 }
652
- func (f * fileListEntry ) ModTime () time.Time { return time.Time {} }
653
- func (f * fileListEntry ) Mode () fs.FileMode { return fs .ModeDir | 0555 }
654
- func (f * fileListEntry ) Type () fs.FileMode { return fs .ModeDir }
655
- func (f * fileListEntry ) IsDir () bool { return true }
656
- func (f * fileListEntry ) Sys () interface {} { return nil }
651
+ func (f * fileListEntry ) Name () string { _ , elem , _ := split (f .name ); return elem }
652
+ func (f * fileListEntry ) Size () int64 { return 0 }
653
+ func (f * fileListEntry ) Mode () fs.FileMode { return fs .ModeDir | 0555 }
654
+ func (f * fileListEntry ) Type () fs.FileMode { return fs .ModeDir }
655
+ func (f * fileListEntry ) IsDir () bool { return true }
656
+ func (f * fileListEntry ) Sys () interface {} { return nil }
657
+
658
+ func (f * fileListEntry ) ModTime () time.Time {
659
+ if f .file == nil {
660
+ return time.Time {}
661
+ }
662
+ return f .file .FileHeader .Modified .UTC ()
663
+ }
657
664
658
665
func (f * fileListEntry ) Info () (fs.FileInfo , error ) { return f , nil }
659
666
@@ -673,15 +680,32 @@ func toValidName(name string) string {
673
680
func (r * Reader ) initFileList () {
674
681
r .fileListOnce .Do (func () {
675
682
dirs := make (map [string ]bool )
683
+ knownDirs := make (map [string ]bool )
676
684
for _ , file := range r .File {
685
+ isDir := len (file .Name ) > 0 && file .Name [len (file .Name )- 1 ] == '/'
677
686
name := toValidName (file .Name )
678
687
for dir := path .Dir (name ); dir != "." ; dir = path .Dir (dir ) {
679
688
dirs [dir ] = true
680
689
}
681
- r .fileList = append (r .fileList , fileListEntry {name , file })
690
+ entry := fileListEntry {
691
+ name : name ,
692
+ file : file ,
693
+ isDir : isDir ,
694
+ }
695
+ r .fileList = append (r .fileList , entry )
696
+ if isDir {
697
+ knownDirs [name ] = true
698
+ }
682
699
}
683
700
for dir := range dirs {
684
- r .fileList = append (r .fileList , fileListEntry {dir + "/" , nil })
701
+ if ! knownDirs [dir ] {
702
+ entry := fileListEntry {
703
+ name : dir ,
704
+ file : nil ,
705
+ isDir : true ,
706
+ }
707
+ r .fileList = append (r .fileList , entry )
708
+ }
685
709
}
686
710
687
711
sort .Slice (r .fileList , func (i , j int ) bool { return fileEntryLess (r .fileList [i ].name , r .fileList [j ].name ) })
@@ -705,7 +729,7 @@ func (r *Reader) Open(name string) (fs.File, error) {
705
729
if e == nil || ! fs .ValidPath (name ) {
706
730
return nil , & fs.PathError {Op : "open" , Path : name , Err : fs .ErrNotExist }
707
731
}
708
- if e .file == nil || strings . HasSuffix ( e . file . Name , "/" ) {
732
+ if e .isDir {
709
733
return & openDir {e , r .openReadDir (name ), 0 }, nil
710
734
}
711
735
rc , err := e .file .Open ()
@@ -730,7 +754,7 @@ func split(name string) (dir, elem string, isDir bool) {
730
754
return name [:i ], name [i + 1 :], isDir
731
755
}
732
756
733
- var dotFile = & fileListEntry {name : "./" }
757
+ var dotFile = & fileListEntry {name : "./" , isDir : true }
734
758
735
759
func (r * Reader ) openLookup (name string ) * fileListEntry {
736
760
if name == "." {
0 commit comments