src/java.base/share/classes/java/util/zip/ZipFile.java
Print this page
@@ -1120,34 +1120,40 @@
comment = new byte[comlen];
if (readFullyAt(comment, 0, comlen, end.endpos + ENDHDR) != comlen) {
zerror("zip comment read failed");
}
}
- if (end.cenlen == ZIP64_MAGICVAL ||
- end.cenoff == ZIP64_MAGICVAL ||
- end.centot == ZIP64_MAGICCOUNT)
- {
- // need to find the zip64 end;
+ // must check for a zip64 end record; it is always permitted to be present
try {
byte[] loc64 = new byte[ZIP64_LOCHDR];
- if (readFullyAt(loc64, 0, loc64.length, end.endpos - ZIP64_LOCHDR)
+ if (end.endpos < ZIP64_LOCHDR ||
+ readFullyAt(loc64, 0, loc64.length, end.endpos - ZIP64_LOCHDR)
!= loc64.length || GETSIG(loc64) != ZIP64_LOCSIG) {
return end;
}
long end64pos = ZIP64_LOCOFF(loc64);
byte[] end64buf = new byte[ZIP64_ENDHDR];
if (readFullyAt(end64buf, 0, end64buf.length, end64pos)
!= end64buf.length || GETSIG(end64buf) != ZIP64_ENDSIG) {
return end;
}
- // end64 found, re-calcualte everything.
- end.cenlen = ZIP64_ENDSIZ(end64buf);
- end.cenoff = ZIP64_ENDOFF(end64buf);
- end.centot = (int)ZIP64_ENDTOT(end64buf); // assume total < 2g
+ // end64 candidate found,
+ long cenlen64 = ZIP64_ENDSIZ(end64buf);
+ long cenoff64 = ZIP64_ENDOFF(end64buf);
+ long centot64 = ZIP64_ENDTOT(end64buf);
+ // double-check
+ if (cenlen64 != end.cenlen && end.cenlen != ZIP64_MAGICVAL ||
+ cenoff64 != end.cenoff && end.cenoff != ZIP64_MAGICVAL ||
+ centot64 != end.centot && end.centot != ZIP64_MAGICCOUNT) {
+ return end;
+ }
+ // to use the end64 values
+ end.cenlen = cenlen64;
+ end.cenoff = cenoff64;
+ end.centot = (int)centot64; // assume total < 2g
end.endpos = end64pos;
} catch (IOException x) {} // no zip64 loc/end
- }
return end;
}
}
}
zerror("zip END header not found");