/** *Bug6252735ZipEntrycontainswasteful"temporarystorage"fieldsintroduced *aregression.ThevalueofthegeneralpurposeflagbitinaLOCheaderis *writtenincorrectly,becauseitiscomputedonstaledata. *<p> *Withthebugpresent,zipbytes2iswrittenincorrectly:whentheLOC *headeriswritten,(flag(e)&8)==8.Thisiscorrect:thedatawillbe *compressed,sowedon'thavedatalength,etc.yet;thatshouldbewritten *intheDataDescriptorafterthedataitselfiswritten.However,whenthe *ZipOutputStreamthatwrapszipbytes2isclosed,thedatalength_is_ *available,therefore(flag(e)&8)=0),thereforetheDataDescriptoris *notwritten.Thisiswhy,withthebug,zipbytes1.length==sizeof(ext *header)+zipbytes2.length. *<p> *TheresultisaninvalidLOCheaderinzipbytes2.Sowhenweagainuse *copyZip,weattempttoreadadatalengthnotfromtheLOCheaderbutfrom *thenon-existentEXTheader,andatthatpositioninthefileissome *arbitraryandincorrectvalue.
*/ publicclass DataDescriptor { staticvoid copyZip(ZipInputStream in, ZipOutputStream out) throws IOException { byte[] buffer = newbyte[1 << 14]; for (ZipEntry ze; (ze = in.getNextEntry()) != null; ) {
out.putNextEntry(ze); // When the bug is present, it shows up here. The second call to // copyZip will throw an exception while reading data. for (int nr; 0 < (nr = in.read(buffer)); ) {
out.write(buffer, 0, nr);
}
}
in.close();
}
privatestaticvoid realMain(String[] args) throws Throwable { // Create zip output in byte array zipbytes
ByteArrayOutputStream baos = new ByteArrayOutputStream();
ZipOutputStream zos = new ZipOutputStream(baos);
ZipEntry e = new ZipEntry("testdir/foo"); byte[] data = "entry data".getBytes("ASCII");
zos.putNextEntry(e);
zos.write(data);
zos.close(); byte[] zipbytes1 = baos.toByteArray(); int length1 = zipbytes1.length;
System.out.println("zip bytes pre-copy length=" + length1);
// Make a ZipInputStream around zipbytes, and use // copyZip to get a new byte array.
ZipInputStream zis = new ZipInputStream( new ByteArrayInputStream(zipbytes1));
baos.reset();
zos = new ZipOutputStream(baos);
copyZip(zis, zos);
zos.close(); byte[] zipbytes2 = baos.toByteArray(); int length2 = zipbytes2.length; // When the bug is present, pre- and post-copy lengths are different!
System.out.println("zip bytes post-copy length=" + length2);
// Now use copyZip again on the bytes resulting from the previous // copy. When the bug is present, copyZip will get an exception this // time.
baos.reset();
zos = new ZipOutputStream(baos);
copyZip(new ZipInputStream(new ByteArrayInputStream(zipbytes2)), zos);
zos.close(); byte[] zipbytes3 = baos.toByteArray(); int length3 = zipbytes3.length;
System.out.println("zip bytes post-copy length=" + length3);
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 und die Messung sind noch experimentell.