/* * Copyright (c) 2015, 2020, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License version 2 only, as * published by the Free Software Foundation. * * This code is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License * version 2 for more details (a copy is included in the LICENSE file that * accompanied this code). * * You should have received a copy of the GNU General Public License version * 2 along with this work; if not, write to the Free Software Foundation, * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. * * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA * or visit www.oracle.com if you need additional information or have any * questions.
*/
staticvoid test(int numEntry, int szMax, boolean addPrefix, boolean cleanOld) {
String name = "test-" + r.nextInt() + ".zip";
Zip zip = new Zip(name, numEntry, szMax, addPrefix, cleanOld); for (int i = 0; i < NN; i++) {
executor.submit(() -> doTest(zip));
}
}
// test scenario: // (1) open the ZipFile(zip) with OPEN_READ | OPEN_DELETE // (2) test the ZipFile works correctly // (3) check the zip is deleted after ZipFile gets closed staticvoid testDelete() throws Throwable {
String name = "testDelete-" + r.nextInt() + ".zip";
Zip zip = new Zip(name, r.nextInt(ENUM), r.nextInt(ESZ), false, true); try (ZipFile zf = new ZipFile(new File(zip.name),
ZipFile.OPEN_READ | ZipFile.OPEN_DELETE ))
{
doTest0(zip, zf);
}
Path p = Paths.get(name); if (Files.exists(p)) {
fail("Failed to delete " + name + " with OPEN_DELETE");
}
}
// test scenario: // (1) keep a ZipFile(zip1) alive (in ZipFile's cache), dont close it // (2) delete zip1 and create zip2 with the same name the zip1 with zip2 // (3) zip1 tests should fail, but no crash // (4) zip2 tasks should all get zip2, then pass normal testing. staticvoid testCachedDelete() throws Throwable {
String name = "testCachedDelete-" + r.nextInt() + ".zip";
Zip zip1 = new Zip(name, r.nextInt(ENUM), r.nextInt(ESZ), false, true);
try (ZipFile zf = new ZipFile(zip1.name)) { for (int i = 0; i < NN; i++) {
executor.submit(() -> verifyNoCrash(zip1));
} // delete the "zip1" and create a new one to test
Zip zip2 = new Zip(name, r.nextInt(ENUM), r.nextInt(ESZ), false, true); /* System.out.println("========================================"); System.out.printf(" zip1=%s, mt=%d, enum=%d%n ->attrs=[key=%s, sz=%d, mt=%d]%n", zip1.name, zip1.lastModified, zip1.entries.size(), zip1.attrs.fileKey(), zip1.attrs.size(), zip1.attrs.lastModifiedTime().toMillis()); System.out.printf(" zip2=%s, mt=%d, enum=%d%n ->attrs=[key=%s, sz=%d, mt=%d]%n", zip2.name, zip2.lastModified, zip2.entries.size(), zip2.attrs.fileKey(), zip2.attrs.size(), zip2.attrs.lastModifiedTime().toMillis());
*/ for (int i = 0; i < NN; i++) {
executor.submit(() -> doTest(zip2));
}
}
}
// overwrite the "zip1" and create a new one to test. So the two zip files // have the same fileKey, but probably different lastModified() staticvoid testCachedOverwrite() throws Throwable {
String name = "testCachedOverWrite-" + r.nextInt() + ".zip";
Zip zip1 = new Zip(name, r.nextInt(ENUM), r.nextInt(ESZ), false, true); try (ZipFile zf = new ZipFile(zip1.name)) { for (int i = 0; i < NN; i++) {
executor.submit(() -> verifyNoCrash(zip1));
} // overwrite the "zip1" with new contents
Zip zip2 = new Zip(name, r.nextInt(ENUM), r.nextInt(ESZ), false, false); for (int i = 0; i < NN; i++) {
executor.submit(() -> doTest(zip2));
}
}
}
// just check the entries and contents. since the file has been either overwritten // or deleted/rewritten, we only care if it crahes or not. staticvoid verifyNoCrash(Zip zip) throws RuntimeException { try (ZipFile zf = new ZipFile(zip.name)) {
List<ZipEntry> zlist = new ArrayList<>(zip.entries.keySet());
String[] elist = zf.stream().map(e -> e.getName()).toArray(String[]::new); if (!Arrays.equals(elist,
zlist.stream().map( e -> e.getName()).toArray(String[]::new)))
{ //System.out.printf("++++++ LIST NG [%s] entries.len=%d, expected=%d+++++++%n", // zf.getName(), elist.length, zlist.size()); return;
} for (ZipEntry ze : zlist) { byte[] zdata = zip.entries.get(ze);
ZipEntry e = zf.getEntry(ze.getName()); if (e != null) {
checkEqual(e, ze); if (!e.isDirectory()) { // check with readAllBytes try (InputStream is = zf.getInputStream(e)) { if (!Arrays.equals(zdata, is.readAllBytes())) { //System.out.printf("++++++ BYTES NG [%s]/[%s] ++++++++%n", // zf.getName(), ze.getName());
}
}
}
}
}
} catch (Throwable t) { // t.printStackTrace(); // fail(t.toString());
}
}
List<ZipEntry> list = new ArrayList<>(zip.entries.keySet()); // (1) check entry list, in expected order if (!check(Arrays.equals(
list.stream().map( e -> e.getName()).toArray(String[]::new),
zf.stream().map( e -> e.getName()).toArray(String[]::new)))) { return;
} // (2) shuffle, and check each entry and its bytes
Collections.shuffle(list); for (ZipEntry ze : list) { byte[] data = zip.entries.get(ze);
ZipEntry e = zf.getEntry(ze.getName());
checkEqual(e, ze); if (!e.isDirectory()) { // check with readAllBytes try (InputStream is = zf.getInputStream(e)) {
check(Arrays.equals(data, is.readAllBytes()));
} // check with smaller sized buf try (InputStream is = zf.getInputStream(e)) { byte[] buf = newbyte[(int)e.getSize()]; int sz = r.nextInt((int)e.getSize()/4 + 1) + 1; int off = 0; int n; while ((n = is.read(buf, off, buf.length - off)) > 0) {
off += n;
}
check(is.read() == -1);
check(Arrays.equals(data, buf));
}
}
}
}
privatestaticclass Zip { final String name; final Map<ZipEntry, byte[]> entries;
BasicFileAttributes attrs; long lastModified;
Zip(String name, int num, int szMax, boolean prefix, boolean clean) { this.name = name;
entries = new LinkedHashMap<>(num); try {
Path p = Paths.get(name); if (clean) {
Files.deleteIfExists(p);
}
paths.add(p);
} catch (Exception x) { thrownew RuntimeException(x);
}
try (FileOutputStream fos = new FileOutputStream(name);
BufferedOutputStream bos = new BufferedOutputStream(fos);
ZipOutputStream zos = new ZipOutputStream(bos))
{ if (prefix) { byte[] bytes = newbyte[r.nextInt(1000)];
r.nextBytes(bytes);
bos.write(bytes);
}
CRC32 crc = new CRC32(); for (int i = 0; i < num; i++) {
String ename = "entry-" + i + "-name-" + r.nextLong();
ZipEntry ze = new ZipEntry(ename); int method = r.nextBoolean() ? ZipEntry.STORED : ZipEntry.DEFLATED;
writeEntry(zos, crc, ze, method, szMax);
} // add some manifest entries for (int i = 0; i < r.nextInt(20); i++) {
String meta = "META-INF/" + "entry-" + i + "-metainf-" + r.nextLong();
ZipEntry ze = new ZipEntry(meta);
writeEntry(zos, crc, ze, ZipEntry.STORED, szMax);
}
} catch (Exception x) { thrownew RuntimeException(x);
} try { this.attrs = Files.readAttributes(Paths.get(name), BasicFileAttributes.class); this.lastModified = new File(name).lastModified();
} catch (Exception x) { thrownew RuntimeException(x);
}
}
privatevoid writeEntry(ZipOutputStream zos, CRC32 crc,
ZipEntry ze, int method, int szMax) throws IOException
{
ze.setMethod(method); byte[] data = newbyte[r.nextInt(szMax + 1)];
r.nextBytes(data); if (method == ZipEntry.STORED) { // must set size/csize/crc
ze.setSize(data.length);
ze.setCompressedSize(data.length);
crc.reset();
crc.update(data);
ze.setCrc(crc.getValue());
}
ze.setTime(System.currentTimeMillis());
ze.setComment(ze.getName());
zos.putNextEntry(ze);
zos.write(data);
zos.closeEntry();
entries.put(ze, data);
}
}
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung ist noch experimentell.