question: private void readCentralDir ( ) throws IOException { long scanOffset = ras . length ( ) - ENDHDR ; if ( scanOffset < 0 ) { throw new ZipException ( "File too short to be a zip file: " + ras . length ( ) ) ; } ras . setPosition ( 0 ) ; final int headerMagic = ras . readS32_LE ( ) ; if ( headerMagic != LOCSIG ) { throw new ZipException ( "Not a zip archive" ) ; } long stopOffset = scanOffset - 65536 ; if ( stopOffset < 0 ) { stopOffset = 0 ; } while ( true ) { ras . setPosition ( scanOffset ) ; if ( ras . readS32_LE ( ) == ENDSIG ) { break ; } scanOffset -- ; if ( scanOffset < stopOffset ) { throw new ZipException ( "End Of Central Directory signature not found" ) ; } } byte [ ] eocd = ras . readBytes ( ENDHDR - 4 ) ; BufferIterator it = HeapBufferIterator . iterator ( eocd , 0 , eocd . length , ByteOrder . LITTLE_ENDIAN ) ; int diskNumber = it . readShort ( ) & 0xffff ; int diskWithCentralDir = it . readShort ( ) & 0xffff ; int numEntries = it . readShort ( ) & 0xffff ; int totalNumEntries = it . readShort ( ) & 0xffff ; long centralDirSize = ( ( long ) it . readInt ( ) ) & 0xffffffffL ; long centralDirOffset = ( ( long ) it . readInt ( ) ) & 0xffffffffL ; int commentLength = it . readShort ( ) & 0xffff ; if ( numEntries != totalNumEntries || diskNumber != 0 || diskWithCentralDir != 0 ) { throw new ZipException ( "Spanned archives not supported" ) ; } if ( commentLength > 0 ) { byte [ ] commentBytes = ras . readBytes ( commentLength ) ; comment = new String ( commentBytes , 0 , commentBytes . length , StandardCharsets . UTF_8 ) ; } RASlice slice = ras . slice ( centralDirOffset , centralDirOffset + centralDirSize ) ; byte [ ] hdrBuf = new byte [ CENHDR ] ; for ( int i = 0 ; i < numEntries ; ++ i ) { ZipEntry newEntry = new ZipEntry ( hdrBuf , slice . createInputStream ( ) ) ; if ( newEntry . localHeaderRelOffset >= centralDirOffset ) { throw new ZipException ( "Local file header offset is after central directory" ) ; } String entryName = newEntry . getName ( ) ; if ( entries . put ( entryName , newEntry ) != null ) { throw new ZipException ( "Duplicate entry name: " + entryName ) ; } } }
target:  Find the central directory and read the contents. <p> <p>The central directory can be followed by a variable-length comment field, so we have to scan through it backwards.  The comment is at most 64K, plus we have 18 bytes for the end-of-central-dir stuff itself, plus apparently sometimes people throw random junk on the end just for the fun of it. <p> <p>This is all a little wobbly.  If the wrong value ends up in the EOCD area, we're hosed. This appears to be the way that everybody handles it though, so we're in good company if this fails.