diff --git a/CONTRIBUTORS b/CONTRIBUTORS
index e6ab0018c..3e2ce0254 100644
--- a/CONTRIBUTORS
+++ b/CONTRIBUTORS
@@ -298,6 +298,7 @@ Robert Streich
Robert Watkins
Roberto Scaramuzzi
Robin Green
+Robin Power
Robin Verduijn
Rob Oxspring
Rob van Oostrum
diff --git a/contributors.xml b/contributors.xml
index 91cf53265..543e200f7 100644
--- a/contributors.xml
+++ b/contributors.xml
@@ -1201,6 +1201,10 @@
Robin
Green
+
+ Robin
+ Power
+
Robin
Verduijn
diff --git a/src/main/org/apache/tools/zip/ZipFile.java b/src/main/org/apache/tools/zip/ZipFile.java
index c10105062..0f09d0fd2 100644
--- a/src/main/org/apache/tools/zip/ZipFile.java
+++ b/src/main/org/apache/tools/zip/ZipFile.java
@@ -666,12 +666,14 @@ public class ZipFile {
*/
private void positionAtCentralDirectory()
throws IOException {
- boolean found = tryToLocateSignature(MIN_EOCD_SIZE + ZIP64_EOCDL_LENGTH,
- MAX_EOCD_SIZE + ZIP64_EOCDL_LENGTH,
- ZipOutputStream
- .ZIP64_EOCD_LOC_SIG);
+ positionAtEndOfCentralDirectoryRecord();
+ archive.seek(archive.getFilePointer() - ZIP64_EOCDL_LENGTH);
+ archive.readFully(WORD_BUF);
+ boolean found = Arrays.equals(ZipOutputStream.ZIP64_EOCD_LOC_SIG,
+ WORD_BUF);
if (!found) {
// not a ZIP64 archive
+ skipBytes(ZIP64_EOCDL_LENGTH - WORD);
positionAtCentralDirectory32();
} else {
positionAtCentralDirectory64();
@@ -686,7 +688,8 @@ public class ZipFile {
*/
private void positionAtCentralDirectory64()
throws IOException {
- skipBytes(ZIP64_EOCDL_LOCATOR_OFFSET);
+ skipBytes(ZIP64_EOCDL_LOCATOR_OFFSET
+ - WORD /* signature has already been read */);
archive.readFully(DWORD_BUF);
archive.seek(ZipEightByteInteger.getLongValue(DWORD_BUF));
archive.readFully(WORD_BUF);
@@ -706,15 +709,23 @@ public class ZipFile {
* record.
*/
private void positionAtCentralDirectory32()
+ throws IOException {
+ skipBytes(CFD_LOCATOR_OFFSET);
+ archive.readFully(WORD_BUF);
+ archive.seek(ZipLong.getValue(WORD_BUF));
+ }
+
+ /**
+ * Searches for the and positions the stream at the start of the
+ * "End of central dir record".
+ */
+ private void positionAtEndOfCentralDirectoryRecord()
throws IOException {
boolean found = tryToLocateSignature(MIN_EOCD_SIZE, MAX_EOCD_SIZE,
ZipOutputStream.EOCD_SIG);
if (!found) {
throw new ZipException("archive is not a ZIP archive");
}
- skipBytes(CFD_LOCATOR_OFFSET);
- archive.readFully(WORD_BUF);
- archive.seek(ZipLong.getValue(WORD_BUF));
}
/**