src/jdk.zipfs/share/classes/jdk/nio/zipfs/ZipFileSystem.java
Print this page
*** 77,86 ****
--- 77,87 ----
// is to use BAOS for better performance
private boolean readOnly = false; // readonly file system
private static final boolean isWindows = AccessController.doPrivileged(
(PrivilegedAction<Boolean>) () -> System.getProperty("os.name")
.startsWith("Windows"));
+ private final boolean forceEnd64;
ZipFileSystem(ZipFileSystemProvider provider,
Path zfpath,
Map<String, ?> env) throws IOException
{
*** 89,104 ****
// default encoding for name/comment
String nameEncoding = env.containsKey("encoding") ?
(String)env.get("encoding") : "UTF-8";
this.noExtt = "false".equals(env.get("zipinfo-time"));
this.useTempFile = TRUE.equals(env.get("useTempFile"));
this.provider = provider;
this.zfpath = zfpath;
if (Files.notExists(zfpath)) {
if (createNew) {
try (OutputStream os = Files.newOutputStream(zfpath, CREATE_NEW, WRITE)) {
! new END().write(os, 0);
}
} else {
throw new FileSystemNotFoundException(zfpath.toString());
}
}
--- 90,106 ----
// default encoding for name/comment
String nameEncoding = env.containsKey("encoding") ?
(String)env.get("encoding") : "UTF-8";
this.noExtt = "false".equals(env.get("zipinfo-time"));
this.useTempFile = TRUE.equals(env.get("useTempFile"));
+ this.forceEnd64 = "true".equals(env.get("forceZIP64End"));
this.provider = provider;
this.zfpath = zfpath;
if (Files.notExists(zfpath)) {
if (createNew) {
try (OutputStream os = Files.newOutputStream(zfpath, CREATE_NEW, WRITE)) {
! new END().write(os, 0, forceEnd64);
}
} else {
throw new FileSystemNotFoundException(zfpath.toString());
}
}
*** 998,1029 ****
end.centot = ENDTOT(buf);
end.cenlen = ENDSIZ(buf);
end.cenoff = ENDOFF(buf);
end.comlen = ENDCOM(buf);
end.endpos = pos + i;
! if (end.cenlen == ZIP64_MINVAL ||
! end.cenoff == ZIP64_MINVAL ||
! end.centot == ZIP64_MINVAL32)
! {
! // need to find the zip64 end;
byte[] loc64 = new byte[ZIP64_LOCHDR];
! if (readFullyAt(loc64, 0, loc64.length, end.endpos - ZIP64_LOCHDR)
! != loc64.length) {
return end;
}
long end64pos = ZIP64_LOCOFF(loc64);
byte[] end64buf = new byte[ZIP64_ENDHDR];
if (readFullyAt(end64buf, 0, end64buf.length, end64pos)
! != end64buf.length) {
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
! end.endpos = end64pos;
}
return end;
}
}
}
zerror("zip END header not found");
--- 1000,1039 ----
end.centot = ENDTOT(buf);
end.cenlen = ENDSIZ(buf);
end.cenoff = ENDOFF(buf);
end.comlen = ENDCOM(buf);
end.endpos = pos + i;
! // try if there is zip64 end;
byte[] loc64 = new byte[ZIP64_LOCHDR];
! if (end.endpos < ZIP64_LOCHDR ||
! readFullyAt(loc64, 0, loc64.length, end.endpos - ZIP64_LOCHDR)
! != loc64.length ||
! !locator64SigAt(loc64, 0)) {
return end;
}
long end64pos = ZIP64_LOCOFF(loc64);
byte[] end64buf = new byte[ZIP64_ENDHDR];
if (readFullyAt(end64buf, 0, end64buf.length, end64pos)
! != end64buf.length ||
! !end64SigAt(end64buf, 0)) {
return end;
}
! // end64 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_MINVAL ||
! cenoff64 != end.cenoff && end.cenoff != ZIP64_MINVAL ||
! centot64 != end.centot && end.centot != ZIP64_MINVAL32) {
! return end;
}
+ // to use the end64 values
+ end.cenlen = cenlen64;
+ end.cenoff = cenoff64;
+ end.centot = (int)centot64; // assume total < 2g
+ end.endpos = end64pos;
return end;
}
}
}
zerror("zip END header not found");
*** 1190,1200 ****
return written;
}
// sync the zip file system, if there is any udpate
private void sync() throws IOException {
! //System.out.printf("->sync(%s) starting....!%n", toString());
// check ex-closer
if (!exChClosers.isEmpty()) {
for (ExChannelCloser ecc : exChClosers) {
if (ecc.streams.isEmpty()) {
ecc.ch.close();
--- 1200,1210 ----
return written;
}
// sync the zip file system, if there is any udpate
private void sync() throws IOException {
! // System.out.printf("->sync(%s) starting....!%n", toString());
// check ex-closer
if (!exChClosers.isEmpty()) {
for (ExChannelCloser ecc : exChClosers) {
if (ecc.streams.isEmpty()) {
ecc.ch.close();
*** 1280,1290 ****
for (Entry entry : elist) {
written += entry.writeCEN(os);
}
end.centot = elist.size();
end.cenlen = written - end.cenoff;
! end.write(os, written);
}
if (!streams.isEmpty()) {
//
// TBD: ExChannelCloser should not be necessary if we only
// sync when being closed, all streams should have been
--- 1290,1300 ----
for (Entry entry : elist) {
written += entry.writeCEN(os);
}
end.centot = elist.size();
end.cenlen = written - end.cenoff;
! end.write(os, written, forceEnd64);
}
if (!streams.isEmpty()) {
//
// TBD: ExChannelCloser should not be necessary if we only
// sync when being closed, all streams should have been
*** 1710,1721 ****
/* members of Zip64 end of central directory locator */
// int diskNum;
long endpos;
// int disktot;
! void write(OutputStream os, long offset) throws IOException {
! boolean hasZip64 = false;
long xlen = cenlen;
long xoff = cenoff;
if (xlen >= ZIP64_MINVAL) {
xlen = ZIP64_MINVAL;
hasZip64 = true;
--- 1720,1731 ----
/* members of Zip64 end of central directory locator */
// int diskNum;
long endpos;
// int disktot;
! void write(OutputStream os, long offset, boolean forceEnd64) throws IOException {
! boolean hasZip64 = forceEnd64; // false;
long xlen = cenlen;
long xoff = cenoff;
if (xlen >= ZIP64_MINVAL) {
xlen = ZIP64_MINVAL;
hasZip64 = true;
*** 1736,1747 ****
writeLong(os, ZIP64_ENDHDR - 12); // size of zip64 end
writeShort(os, 45); // version made by
writeShort(os, 45); // version needed to extract
writeInt(os, 0); // number of this disk
writeInt(os, 0); // central directory start disk
! writeLong(os, centot); // number of directory entires on disk
! writeLong(os, centot); // number of directory entires
writeLong(os, cenlen); // length of central directory
writeLong(os, cenoff); // offset of central directory
//zip64 end of central directory locator
writeInt(os, ZIP64_LOCSIG); // zip64 END locator signature
--- 1746,1757 ----
writeLong(os, ZIP64_ENDHDR - 12); // size of zip64 end
writeShort(os, 45); // version made by
writeShort(os, 45); // version needed to extract
writeInt(os, 0); // number of this disk
writeInt(os, 0); // central directory start disk
! writeLong(os, centot); // number of directory entries on disk
! writeLong(os, centot); // number of directory entries
writeLong(os, cenlen); // length of central directory
writeLong(os, cenoff); // offset of central directory
//zip64 end of central directory locator
writeInt(os, ZIP64_LOCSIG); // zip64 END locator signature