提交 58fa6e63 编写于 作者: S sherman

7077769: (zipfs) ZipFileSystem.writeCEN() writes wrong "data size" for ZIP64...

7077769: (zipfs) ZipFileSystem.writeCEN() writes wrong "data size" for ZIP64 extended information extra field
Summary: fixed the wrong size when writing out the cen table for ZIP64
Reviewed-by: alanb
上级 5e7ec2bc
...@@ -31,6 +31,7 @@ ...@@ -31,6 +31,7 @@
package com.sun.nio.zipfs; package com.sun.nio.zipfs;
import java.io.BufferedOutputStream;
import java.io.ByteArrayInputStream; import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream; import java.io.ByteArrayOutputStream;
import java.io.EOFException; import java.io.EOFException;
...@@ -1165,7 +1166,6 @@ public class ZipFileSystem extends FileSystem { ...@@ -1165,7 +1166,6 @@ public class ZipFileSystem extends FileSystem {
// sync the zip file system, if there is any udpate // sync the zip file system, if there is any udpate
private void sync() throws IOException { private void sync() throws IOException {
//System.out.printf("->sync(%s) starting....!%n", toString()); //System.out.printf("->sync(%s) starting....!%n", toString());
// check ex-closer // check ex-closer
if (!exChClosers.isEmpty()) { if (!exChClosers.isEmpty()) {
for (ExChannelCloser ecc : exChClosers) { for (ExChannelCloser ecc : exChClosers) {
...@@ -1179,7 +1179,8 @@ public class ZipFileSystem extends FileSystem { ...@@ -1179,7 +1179,8 @@ public class ZipFileSystem extends FileSystem {
if (!hasUpdate) if (!hasUpdate)
return; return;
Path tmpFile = createTempFileInSameDirectoryAs(zfpath); Path tmpFile = createTempFileInSameDirectoryAs(zfpath);
OutputStream os = Files.newOutputStream(tmpFile, WRITE); try (OutputStream os = new BufferedOutputStream(Files.newOutputStream(tmpFile, WRITE)))
{
ArrayList<Entry> elist = new ArrayList<>(inodes.size()); ArrayList<Entry> elist = new ArrayList<>(inodes.size());
long written = 0; long written = 0;
byte[] buf = new byte[8192]; byte[] buf = new byte[8192];
...@@ -1255,8 +1256,7 @@ public class ZipFileSystem extends FileSystem { ...@@ -1255,8 +1256,7 @@ public class ZipFileSystem extends FileSystem {
end.centot = elist.size(); end.centot = elist.size();
end.cenlen = written - end.cenoff; end.cenlen = written - end.cenoff;
end.write(os, written); end.write(os, written);
os.close(); }
if (!streams.isEmpty()) { if (!streams.isEmpty()) {
// //
// TBD: ExChannelCloser should not be necessary if we only // TBD: ExChannelCloser should not be necessary if we only
...@@ -1959,7 +1959,7 @@ public class ZipFileSystem extends FileSystem { ...@@ -1959,7 +1959,7 @@ public class ZipFileSystem extends FileSystem {
writeBytes(os, name); writeBytes(os, name);
if (elen64 != 0) { if (elen64 != 0) {
writeShort(os, EXTID_ZIP64);// Zip64 extra writeShort(os, EXTID_ZIP64);// Zip64 extra
writeShort(os, elen64); // size of "this" extra block writeShort(os, elen64 - 4); // size of "this" extra block
if (size0 == ZIP64_MINVAL) if (size0 == ZIP64_MINVAL)
writeLong(os, size); writeLong(os, size);
if (csize0 == ZIP64_MINVAL) if (csize0 == ZIP64_MINVAL)
......
...@@ -25,9 +25,14 @@ ...@@ -25,9 +25,14 @@
import java.io.*; import java.io.*;
import java.nio.*; import java.nio.*;
import java.nio.file.*;
import java.nio.file.attribute.*;
import java.nio.file.spi.*;
import java.util.*; import java.util.*;
import java.util.zip.*; import java.util.zip.*;
import static java.nio.file.StandardCopyOption.*;
public class LargeZip { public class LargeZip {
// If true, don't delete large ZIP file created for test. // If true, don't delete large ZIP file created for test.
static final boolean debug = System.getProperty("debug") != null; static final boolean debug = System.getProperty("debug") != null;
...@@ -39,7 +44,6 @@ public class LargeZip { ...@@ -39,7 +44,6 @@ public class LargeZip {
static long fileSize = 6L * 1024L * 1024L * 1024L; // 6GB static long fileSize = 6L * 1024L * 1024L * 1024L; // 6GB
static boolean userFile = false; static boolean userFile = false;
static byte[] data; static byte[] data;
static File largeFile; static File largeFile;
static String lastEntryName; static String lastEntryName;
...@@ -77,8 +81,10 @@ public class LargeZip { ...@@ -77,8 +81,10 @@ public class LargeZip {
check(!testDir.exists() && testDir.mkdirs()); check(!testDir.exists() && testDir.mkdirs());
largeFile = new File(testDir, "largezip.zip"); largeFile = new File(testDir, "largezip.zip");
createLargeZip(); createLargeZip();
} else {
if (args.length > 1)
updateLargeZip(args[1]); // add new entry with zfs
} }
readLargeZip1(); readLargeZip1();
readLargeZip2(); readLargeZip2();
...@@ -115,36 +121,53 @@ public class LargeZip { ...@@ -115,36 +121,53 @@ public class LargeZip {
} }
} }
private static byte buf[] = new byte[4096];
static void checkEntry(ZipEntry e, InputStream is) throws Throwable {
long N = 0;
int n = 0;
while ((n = is.read(buf)) >= 0) {
N += n;
}
check(N == e.getSize());
}
static void readLargeZip1() throws Throwable { static void readLargeZip1() throws Throwable {
ZipFile zipFile = new ZipFile(largeFile); ZipFile zipFile = new ZipFile(largeFile);
ZipEntry entry = null; ZipEntry entry = null;
String entryName = null; String entryName = null;
int count = 0; int count = 0;
System.out.println("ZipFile:");
Enumeration<? extends ZipEntry> entries = zipFile.entries(); Enumeration<? extends ZipEntry> entries = zipFile.entries();
while (entries.hasMoreElements()) { while (entries.hasMoreElements()) {
entry = entries.nextElement(); entry = entries.nextElement();
entryName = entry.getName(); entryName = entry.getName();
System.out.println(" checking " + entryName);
if (!entry.isDirectory()) {
try (InputStream zeis = zipFile.getInputStream(entry)) {
checkEntry(entry, zeis);
}
}
count++; count++;
} }
System.out.println("Number of entries read: " + count); System.out.println("Number of entries read: " + count);
System.out.println("Last entry read is " + entryName);
check(!entry.isDirectory()); check(!entry.isDirectory());
if (check(entryName.equals(lastEntryName))) { if (userFile || check(entryName.equals(lastEntryName))) {
ByteArrayOutputStream baos = new ByteArrayOutputStream(); ByteArrayOutputStream baos = new ByteArrayOutputStream();
InputStream is = zipFile.getInputStream(entry); InputStream is = zipFile.getInputStream(entry);
byte buf[] = new byte[4096];
int len; int len;
while ((len = is.read(buf)) >= 0) { while ((len = is.read(buf)) >= 0) {
baos.write(buf, 0, len); baos.write(buf, 0, len);
} }
baos.close(); baos.close();
is.close(); is.close();
if (!userFile)
check(Arrays.equals(data, baos.toByteArray())); check(Arrays.equals(data, baos.toByteArray()));
} }
} }
static void readLargeZip2() throws Throwable { static void readLargeZip2() throws Throwable {
System.out.println("ZipInputStream:");
try (FileInputStream fis = new FileInputStream(largeFile); try (FileInputStream fis = new FileInputStream(largeFile);
BufferedInputStream bis = new BufferedInputStream(fis); BufferedInputStream bis = new BufferedInputStream(fis);
ZipInputStream zis = new ZipInputStream(bis)) ZipInputStream zis = new ZipInputStream(bis))
...@@ -154,17 +177,22 @@ public class LargeZip { ...@@ -154,17 +177,22 @@ public class LargeZip {
int count = 0; int count = 0;
while ((entry = zis.getNextEntry()) != null) { while ((entry = zis.getNextEntry()) != null) {
entryName = entry.getName(); entryName = entry.getName();
System.out.println(" checking " + entryName +
", method=" + entry.getMethod());
if (entryName.equals(lastEntryName)) { if (entryName.equals(lastEntryName)) {
break; break;
} }
if (!entry.isDirectory()) {
checkEntry(entry, zis);
}
count++; count++;
} }
System.out.println("Number of entries read: " + count); System.out.println("Number of entries read: " + count);
System.out.println("Last entry read is " + entryName); System.out.println("Last entry read is " + entryName);
if (!userFile) {
check(!entry.isDirectory()); check(!entry.isDirectory());
ByteArrayOutputStream baos = new ByteArrayOutputStream(); ByteArrayOutputStream baos = new ByteArrayOutputStream();
byte buf[] = new byte[4096]; byte buf[] = new byte[4096];
int len; int len;
while ((len = zis.read(buf)) >= 0) { while ((len = zis.read(buf)) >= 0) {
...@@ -175,6 +203,47 @@ public class LargeZip { ...@@ -175,6 +203,47 @@ public class LargeZip {
check(zis.getNextEntry() == null); check(zis.getNextEntry() == null);
} }
} }
}
private static void updateFile(FileSystem fs, Path src) throws IOException {
Path dst = fs.getPath(src.toString());
Path parent = dst.getParent();
if (parent != null && Files.notExists(parent))
Files.createDirectories(parent);
Files.copy(src, dst, REPLACE_EXISTING);
}
private static FileSystemProvider getZipFSProvider() {
for (FileSystemProvider provider : FileSystemProvider.installedProviders()) {
if ("jar".equalsIgnoreCase(provider.getScheme()))
return provider;
}
return null;
}
static void updateLargeZip(String pName) throws Throwable {
FileSystemProvider provider = getZipFSProvider();
if (provider == null) {
System.err.println("ZIP filesystem provider is not installed");
System.exit(1);
}
Map<String, Object> env = env = new HashMap<>();
try (FileSystem fs = provider.newFileSystem(largeFile.toPath(), env)) {
Path path = FileSystems.getDefault().getPath(pName);
Files.walkFileTree(
path,
new SimpleFileVisitor<Path>() {
@Override
public FileVisitResult visitFile(Path file,
BasicFileAttributes attrs)
throws IOException
{
updateFile(fs, file);
return FileVisitResult.CONTINUE;
}
});
}
}
//--------------------- Infrastructure --------------------------- //--------------------- Infrastructure ---------------------------
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册