private static boolean validateEndRecord ( File file , FileChannel channel , long startEndRecord , long endSig ) throws IOException { try { channel . position ( startEndRecord ) ; final ByteBuffer endDirHeader = getByteBuffer ( ENDLEN ) ; read ( endDirHeader , channel ) ; if ( endDirHeader . limit ( ) < ENDLEN ) { // Couldn't read the full end of central directory record header return false ; } else if ( getUnsignedInt ( endDirHeader , 0 ) != endSig ) { return false ; } long pos = getUnsignedInt ( endDirHeader , END_CENSTART ) ; // TODO deal with Zip64 if ( pos == ZIP64_MARKER ) { return false ; } ByteBuffer cdfhBuffer = getByteBuffer ( CENLEN ) ; read ( cdfhBuffer , channel , pos ) ; long header = getUnsignedInt ( cdfhBuffer , 0 ) ; if ( header == CENSIG ) { long firstLoc = getUnsignedInt ( cdfhBuffer , CEN_LOC_OFFSET ) ; long firstSize = getUnsignedInt ( cdfhBuffer , CENSIZ ) ; if ( firstLoc == 0 ) { // normal case -- first bytes are the first local file if ( ! validateLocalFileRecord ( channel , 0 , firstSize ) ) { return false ; } } else { // confirm that firstLoc is indeed the first local file long fileFirstLoc = scanForLocSig ( channel ) ; if ( firstLoc != fileFirstLoc ) { if ( fileFirstLoc == 0 ) { return false ; } else { // scanForLocSig() found a LOCSIG, but not at position zero and not // at the expected position. // With a file like this, we can't tell if we're in a nested zip // or we're in an outer zip and had the bad luck to find random bytes // that look like LOCSIG. return false ; } } } // At this point, endDirHeader points to the correct end of central dir record. // Just need to validate the record is complete, including any comment int commentLen = getUnsignedShort ( endDirHeader , END_COMMENTLEN ) ; long commentEnd = startEndRecord + ENDLEN + commentLen ; return commentEnd <= channel . size ( ) ; } return false ; } catch ( EOFException eof ) { // pos or firstLoc weren't really positions and moved us to an invalid location return false ; } }
Validates that the data structure at position startEndRecord has a field in the expected position that points to the start of the first central directory file and if so that the file has a complete end of central directory record comment at the end .