From 839f1ad02a24d7e04ad06af239cd89ac0f03c5b2 Mon Sep 17 00:00:00 2001 From: PJ Fanning Date: Sat, 19 Feb 2022 12:21:04 +0000 Subject: [PATCH] refactor some stream code git-svn-id: https://svn.apache.org/repos/asf/poi/trunk@1898216 13f79535-47bb-0310-9956-ffa450edef68 --- .../java/org/apache/poi/hslf/blip/Bitmap.java | 7 ++- .../java/org/apache/poi/hslf/blip/PICT.java | 62 ++++++++++--------- 2 files changed, 36 insertions(+), 33 deletions(-) diff --git a/poi-scratchpad/src/main/java/org/apache/poi/hslf/blip/Bitmap.java b/poi-scratchpad/src/main/java/org/apache/poi/hslf/blip/Bitmap.java index adb7fc1982..d00ea092b2 100644 --- a/poi-scratchpad/src/main/java/org/apache/poi/hslf/blip/Bitmap.java +++ b/poi-scratchpad/src/main/java/org/apache/poi/hslf/blip/Bitmap.java @@ -19,11 +19,12 @@ package org.apache.poi.hslf.blip; import java.awt.Dimension; import java.awt.image.BufferedImage; -import java.io.ByteArrayInputStream; import java.io.IOException; +import java.io.InputStream; import javax.imageio.ImageIO; +import org.apache.commons.io.input.UnsynchronizedByteArrayInputStream; import org.apache.poi.ddf.EscherBSERecord; import org.apache.poi.ddf.EscherContainerRecord; import org.apache.poi.hslf.usermodel.HSLFPictureData; @@ -90,8 +91,8 @@ public abstract class Bitmap extends HSLFPictureData { @Override public Dimension getImageDimension() { - try { - BufferedImage bi = ImageIO.read(new ByteArrayInputStream(getData())); + try (InputStream is = new UnsynchronizedByteArrayInputStream(getData())){ + BufferedImage bi = ImageIO.read(is); return new Dimension( (int)Units.pixelToPoints(bi.getWidth()), (int)Units.pixelToPoints(bi.getHeight()) diff --git a/poi-scratchpad/src/main/java/org/apache/poi/hslf/blip/PICT.java b/poi-scratchpad/src/main/java/org/apache/poi/hslf/blip/PICT.java index 8ae0496e4f..041206fe7b 100644 --- a/poi-scratchpad/src/main/java/org/apache/poi/hslf/blip/PICT.java +++ b/poi-scratchpad/src/main/java/org/apache/poi/hslf/blip/PICT.java @@ -20,12 +20,13 @@ package org.apache.poi.hslf.blip; import static org.apache.logging.log4j.util.Unbox.box; import java.awt.Dimension; -import java.io.ByteArrayInputStream; import java.io.EOFException; import java.io.IOException; +import java.io.InputStream; import java.util.Arrays; import java.util.zip.InflaterInputStream; +import org.apache.commons.io.input.UnsynchronizedByteArrayInputStream; import org.apache.commons.io.output.UnsynchronizedByteArrayOutputStream; import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.Logger; @@ -84,41 +85,42 @@ public final class PICT extends Metafile { } private byte[] read(byte[] data, int pos) throws IOException { - ByteArrayInputStream bis = new ByteArrayInputStream(data); Header header = new Header(); header.read(data, pos); long bs_exp = (long)pos + header.getSize(); - long bs_act = IOUtils.skipFully(bis, bs_exp); - if (bs_exp != bs_act) { - throw new EOFException(); - } - byte[] chunk = new byte[4096]; - try (UnsynchronizedByteArrayOutputStream out = new UnsynchronizedByteArrayOutputStream(header.getWmfSize())) { - try (InflaterInputStream inflater = new InflaterInputStream(bis)) { - int count; - while ((count = inflater.read(chunk)) >= 0) { - out.write(chunk, 0, count); - // PICT zip-stream can be erroneous, so we clear the array to determine - // the maximum of read bytes, after the inflater crashed - Arrays.fill(chunk, (byte) 0); - } - } catch (Exception e) { - int lastLen = chunk.length - 1; - while (lastLen >= 0 && chunk[lastLen] == 0) { - lastLen--; - } - if (++lastLen > 0) { - if (header.getWmfSize() > out.size()) { - // sometimes the wmfsize is smaller than the amount of already successfully read bytes - // in this case we take the lastLen as-is, otherwise we truncate it to the given size - lastLen = Math.min(lastLen, header.getWmfSize() - out.size()); + try (InputStream bis = new UnsynchronizedByteArrayInputStream(data)) { + long bs_act = IOUtils.skipFully(bis, bs_exp); + if (bs_exp != bs_act) { + throw new EOFException(); + } + byte[] chunk = new byte[4096]; + try (UnsynchronizedByteArrayOutputStream out = new UnsynchronizedByteArrayOutputStream(header.getWmfSize())) { + try (InflaterInputStream inflater = new InflaterInputStream(bis)) { + int count; + while ((count = inflater.read(chunk)) >= 0) { + out.write(chunk, 0, count); + // PICT zip-stream can be erroneous, so we clear the array to determine + // the maximum of read bytes, after the inflater crashed + Arrays.fill(chunk, (byte) 0); } - out.write(chunk, 0, lastLen); + } catch (Exception e) { + int lastLen = chunk.length - 1; + while (lastLen >= 0 && chunk[lastLen] == 0) { + lastLen--; + } + if (++lastLen > 0) { + if (header.getWmfSize() > out.size()) { + // sometimes the wmfsize is smaller than the amount of already successfully read bytes + // in this case we take the lastLen as-is, otherwise we truncate it to the given size + lastLen = Math.min(lastLen, header.getWmfSize() - out.size()); + } + out.write(chunk, 0, lastLen); + } + // End of picture marker for PICT is 0x00 0xFF + LOG.atError().withThrowable(e).log("PICT zip-stream is invalid, read as much as possible. Uncompressed length of header: {} / Read bytes: {}", box(header.getWmfSize()), box(out.size())); } - // End of picture marker for PICT is 0x00 0xFF - LOG.atError().withThrowable(e).log("PICT zip-stream is invalid, read as much as possible. Uncompressed length of header: {} / Read bytes: {}", box(header.getWmfSize()), box(out.size())); + return out.toByteArray(); } - return out.toByteArray(); } } -- 2.39.5