src/share/classes/com/sun/tools/javac/file/ZipFileIndex.java

changeset 923
6970d9fb8e02
parent 839
a8437c34fdc7
child 1279
34e254ffd0e7
     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  }

mercurial