@@ -646,29 +646,40 @@ impl<R: Read + Seek> ZipArchive<R> {
646646 // End of the probed region, initially set to the end of the file
647647 let file_len = reader. seek ( io:: SeekFrom :: End ( 0 ) ) ?;
648648 let mut end_exclusive = file_len;
649+ let mut last_err = None ;
649650
650651 loop {
651652 // Find the EOCD and possibly EOCD64 entries and determine the archive offset.
652- let cde = spec:: find_central_directory (
653+ let cde = match spec:: find_central_directory (
653654 reader,
654655 config. archive_offset ,
655656 end_exclusive,
656657 file_len,
657- ) ?;
658+ ) {
659+ Ok ( cde) => cde,
660+ Err ( e) => {
661+ // return the previous error first (if there is)
662+ return Err ( last_err. unwrap_or ( e) ) ;
663+ }
664+ } ;
658665
659666 // Turn EOCD into internal representation.
660- let Ok ( shared ) = CentralDirectoryInfo :: try_from ( & cde)
667+ match CentralDirectoryInfo :: try_from ( & cde)
661668 . and_then ( |info| Self :: read_central_header ( info, config, reader) )
662- else {
663- // The next EOCD candidate should start before the current one.
664- end_exclusive = cde. eocd . position ;
665- continue ;
669+ {
670+ Ok ( shared) => {
671+ return Ok ( shared. build (
672+ cde. eocd . data . zip_file_comment ,
673+ cde. eocd64 . map ( |v| v. data . extensible_data_sector ) ,
674+ ) ) ;
675+ }
676+ Err ( e) => {
677+ last_err = Some ( e) ;
678+ }
666679 } ;
667-
668- return Ok ( shared. build (
669- cde. eocd . data . zip_file_comment ,
670- cde. eocd64 . map ( |v| v. data . extensible_data_sector ) ,
671- ) ) ;
680+ // Something went wrong while decoding the cde, try to find a new one
681+ end_exclusive = cde. eocd . position ;
682+ continue ;
672683 }
673684 }
674685
0 commit comments