mirror of
https://github.com/openjdk/jdk.git
synced 2025-08-27 14:54:52 +02:00
8193682: Infinite loop in ZipOutputStream.close()
Reviewed-by: lancea, coffeys
This commit is contained in:
parent
abaa073bcb
commit
1e9ed54d36
4 changed files with 229 additions and 67 deletions
|
@ -234,9 +234,12 @@ public class DeflaterOutputStream extends FilterOutputStream {
|
|||
*/
|
||||
public void close() throws IOException {
|
||||
if (!closed) {
|
||||
finish();
|
||||
if (usesDefaultDeflater)
|
||||
def.end();
|
||||
try {
|
||||
finish();
|
||||
} finally {
|
||||
if (usesDefaultDeflater)
|
||||
def.end();
|
||||
}
|
||||
out.close();
|
||||
closed = true;
|
||||
}
|
||||
|
|
|
@ -157,24 +157,30 @@ public class GZIPOutputStream extends DeflaterOutputStream {
|
|||
*/
|
||||
public void finish() throws IOException {
|
||||
if (!def.finished()) {
|
||||
def.finish();
|
||||
while (!def.finished()) {
|
||||
int len = def.deflate(buf, 0, buf.length);
|
||||
if (def.finished() && len <= buf.length - TRAILER_SIZE) {
|
||||
// last deflater buffer. Fit trailer at the end
|
||||
writeTrailer(buf, len);
|
||||
len = len + TRAILER_SIZE;
|
||||
out.write(buf, 0, len);
|
||||
return;
|
||||
try {
|
||||
def.finish();
|
||||
while (!def.finished()) {
|
||||
int len = def.deflate(buf, 0, buf.length);
|
||||
if (def.finished() && len <= buf.length - TRAILER_SIZE) {
|
||||
// last deflater buffer. Fit trailer at the end
|
||||
writeTrailer(buf, len);
|
||||
len = len + TRAILER_SIZE;
|
||||
out.write(buf, 0, len);
|
||||
return;
|
||||
}
|
||||
if (len > 0)
|
||||
out.write(buf, 0, len);
|
||||
}
|
||||
if (len > 0)
|
||||
out.write(buf, 0, len);
|
||||
// if we can't fit the trailer at the end of the last
|
||||
// deflater buffer, we write it separately
|
||||
byte[] trailer = new byte[TRAILER_SIZE];
|
||||
writeTrailer(trailer, 0);
|
||||
out.write(trailer);
|
||||
} catch (IOException e) {
|
||||
if (usesDefaultDeflater)
|
||||
def.end();
|
||||
throw e;
|
||||
}
|
||||
// if we can't fit the trailer at the end of the last
|
||||
// deflater buffer, we write it separately
|
||||
byte[] trailer = new byte[TRAILER_SIZE];
|
||||
writeTrailer(trailer, 0);
|
||||
out.write(trailer);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -259,58 +259,64 @@ public class ZipOutputStream extends DeflaterOutputStream implements ZipConstant
|
|||
public void closeEntry() throws IOException {
|
||||
ensureOpen();
|
||||
if (current != null) {
|
||||
ZipEntry e = current.entry;
|
||||
switch (e.method) {
|
||||
case DEFLATED -> {
|
||||
def.finish();
|
||||
while (!def.finished()) {
|
||||
deflate();
|
||||
}
|
||||
if ((e.flag & 8) == 0) {
|
||||
// verify size, compressed size, and crc-32 settings
|
||||
if (e.size != def.getBytesRead()) {
|
||||
throw new ZipException(
|
||||
"invalid entry size (expected " + e.size +
|
||||
" but got " + def.getBytesRead() + " bytes)");
|
||||
try {
|
||||
ZipEntry e = current.entry;
|
||||
switch (e.method) {
|
||||
case DEFLATED -> {
|
||||
def.finish();
|
||||
while (!def.finished()) {
|
||||
deflate();
|
||||
}
|
||||
if ((e.flag & 8) == 0) {
|
||||
// verify size, compressed size, and crc-32 settings
|
||||
if (e.size != def.getBytesRead()) {
|
||||
throw new ZipException(
|
||||
"invalid entry size (expected " + e.size +
|
||||
" but got " + def.getBytesRead() + " bytes)");
|
||||
}
|
||||
if (e.csize != def.getBytesWritten()) {
|
||||
throw new ZipException(
|
||||
"invalid entry compressed size (expected " +
|
||||
e.csize + " but got " + def.getBytesWritten() + " bytes)");
|
||||
}
|
||||
if (e.crc != crc.getValue()) {
|
||||
throw new ZipException(
|
||||
"invalid entry CRC-32 (expected 0x" +
|
||||
Long.toHexString(e.crc) + " but got 0x" +
|
||||
Long.toHexString(crc.getValue()) + ")");
|
||||
}
|
||||
} else {
|
||||
e.size = def.getBytesRead();
|
||||
e.csize = def.getBytesWritten();
|
||||
e.crc = crc.getValue();
|
||||
writeEXT(e);
|
||||
}
|
||||
def.reset();
|
||||
written += e.csize;
|
||||
}
|
||||
if (e.csize != def.getBytesWritten()) {
|
||||
throw new ZipException(
|
||||
"invalid entry compressed size (expected " +
|
||||
e.csize + " but got " + def.getBytesWritten() + " bytes)");
|
||||
case STORED -> {
|
||||
// we already know that both e.size and e.csize are the same
|
||||
if (e.size != written - locoff) {
|
||||
throw new ZipException(
|
||||
"invalid entry size (expected " + e.size +
|
||||
" but got " + (written - locoff) + " bytes)");
|
||||
}
|
||||
if (e.crc != crc.getValue()) {
|
||||
throw new ZipException(
|
||||
"invalid entry crc-32 (expected 0x" +
|
||||
Long.toHexString(e.crc) + " but got 0x" +
|
||||
Long.toHexString(crc.getValue()) + ")");
|
||||
}
|
||||
}
|
||||
if (e.crc != crc.getValue()) {
|
||||
throw new ZipException(
|
||||
"invalid entry CRC-32 (expected 0x" +
|
||||
Long.toHexString(e.crc) + " but got 0x" +
|
||||
Long.toHexString(crc.getValue()) + ")");
|
||||
}
|
||||
} else {
|
||||
e.size = def.getBytesRead();
|
||||
e.csize = def.getBytesWritten();
|
||||
e.crc = crc.getValue();
|
||||
writeEXT(e);
|
||||
default -> throw new ZipException("invalid compression method");
|
||||
}
|
||||
def.reset();
|
||||
written += e.csize;
|
||||
crc.reset();
|
||||
current = null;
|
||||
} catch (IOException e) {
|
||||
if (usesDefaultDeflater && !(e instanceof ZipException))
|
||||
def.end();
|
||||
throw e;
|
||||
}
|
||||
case STORED -> {
|
||||
// we already know that both e.size and e.csize are the same
|
||||
if (e.size != written - locoff) {
|
||||
throw new ZipException(
|
||||
"invalid entry size (expected " + e.size +
|
||||
" but got " + (written - locoff) + " bytes)");
|
||||
}
|
||||
if (e.crc != crc.getValue()) {
|
||||
throw new ZipException(
|
||||
"invalid entry crc-32 (expected 0x" +
|
||||
Long.toHexString(e.crc) + " but got 0x" +
|
||||
Long.toHexString(crc.getValue()) + ")");
|
||||
}
|
||||
}
|
||||
default -> throw new ZipException("invalid compression method");
|
||||
}
|
||||
crc.reset();
|
||||
current = null;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue