1.1 --- a/src/share/classes/com/sun/tools/javac/file/ZipFileIndex.java Mon Mar 07 13:45:06 2011 -0800 1.2 +++ b/src/share/classes/com/sun/tools/javac/file/ZipFileIndex.java Mon Mar 07 17:39:42 2011 -0800 1.3 @@ -492,8 +492,30 @@ 1.4 public ZipDirectory(RandomAccessFile zipRandomFile, long start, long end, ZipFileIndex index) throws IOException { 1.5 this.zipRandomFile = zipRandomFile; 1.6 this.zipFileIndex = index; 1.7 + hasValidHeader(); 1.8 + findCENRecord(start, end); 1.9 + } 1.10 1.11 - findCENRecord(start, end); 1.12 + /* 1.13 + * the zip entry signature should be at offset 0, otherwise allow the 1.14 + * calling logic to take evasive action by throwing ZipFormatException. 1.15 + */ 1.16 + private boolean hasValidHeader() throws IOException { 1.17 + final long pos = zipRandomFile.getFilePointer(); 1.18 + try { 1.19 + if (zipRandomFile.read() == 'P') { 1.20 + if (zipRandomFile.read() == 'K') { 1.21 + if (zipRandomFile.read() == 0x03) { 1.22 + if (zipRandomFile.read() == 0x04) { 1.23 + return true; 1.24 + } 1.25 + } 1.26 + } 1.27 + } 1.28 + } finally { 1.29 + zipRandomFile.seek(pos); 1.30 + } 1.31 + throw new ZipFormatException("invalid zip magic"); 1.32 } 1.33 1.34 /* 1.35 @@ -529,7 +551,13 @@ 1.36 zipDir = new byte[get4ByteLittleEndian(endbuf, i + 12) + 2]; 1.37 zipDir[0] = endbuf[i + 10]; 1.38 zipDir[1] = endbuf[i + 11]; 1.39 - zipRandomFile.seek(start + get4ByteLittleEndian(endbuf, i + 16)); 1.40 + int sz = get4ByteLittleEndian(endbuf, i + 16); 1.41 + // a negative offset or the entries field indicates a 1.42 + // potential zip64 archive 1.43 + if (sz < 0 || get2ByteLittleEndian(zipDir, 0) == 0xffff) { 1.44 + throw new ZipFormatException("detected a zip64 archive"); 1.45 + } 1.46 + zipRandomFile.seek(start + sz); 1.47 zipRandomFile.readFully(zipDir, 2, zipDir.length - 2); 1.48 return; 1.49 } else { 1.50 @@ -1127,4 +1155,18 @@ 1.51 } 1.52 } 1.53 1.54 + /* 1.55 + * Exception primarily used to implement a failover, used exclusively here. 1.56 + */ 1.57 + 1.58 + static final class ZipFormatException extends IOException { 1.59 + private static final long serialVersionUID = 8000196834066748623L; 1.60 + protected ZipFormatException(String message) { 1.61 + super(message); 1.62 + } 1.63 + 1.64 + protected ZipFormatException(String message, Throwable cause) { 1.65 + super(message, cause); 1.66 + } 1.67 + } 1.68 }