Fix many ByteSource.getInputStream() leaks, where
the stream returned wasn't closed in a finally block.
Jira issue key: SANSELAN-63
git-svn-id: https://svn.apache.org/repos/asf/commons/proper/sanselan/trunk@1294807 13f79535-47bb-0310-9956-ffa450edef68
diff --git a/src/main/java/org/apache/commons/sanselan/common/bytesource/ByteSource.java b/src/main/java/org/apache/commons/sanselan/common/bytesource/ByteSource.java
index 9edd76c..53c85e3 100644
--- a/src/main/java/org/apache/commons/sanselan/common/bytesource/ByteSource.java
+++ b/src/main/java/org/apache/commons/sanselan/common/bytesource/ByteSource.java
@@ -32,10 +32,19 @@
public final InputStream getInputStream(int start) throws IOException
{
- InputStream is = getInputStream();
-
- skipBytes(is, start);
-
+ InputStream is = null;
+ boolean succeeded = false;
+ try {
+ is = getInputStream();
+ skipBytes(is, start);
+ succeeded = true;
+ } finally {
+ if (!succeeded) {
+ if (is != null) {
+ is.close();
+ }
+ }
+ }
return is;
}
diff --git a/src/main/java/org/apache/commons/sanselan/formats/bmp/BmpImageParser.java b/src/main/java/org/apache/commons/sanselan/formats/bmp/BmpImageParser.java
index 71d69dd..db96fea 100644
--- a/src/main/java/org/apache/commons/sanselan/formats/bmp/BmpImageParser.java
+++ b/src/main/java/org/apache/commons/sanselan/formats/bmp/BmpImageParser.java
@@ -593,8 +593,19 @@
throw new ImageReadException("Unknown parameter: " + firstKey);
}
- ImageContents ic = readImageContents(byteSource.getInputStream(),
- FormatCompliance.getDefault(), verbose);
+ InputStream is = null;
+ ImageContents ic = null;
+ try {
+ is = byteSource.getInputStream();
+ ic = readImageContents(is, FormatCompliance.getDefault(), verbose);
+ } finally {
+ if (is != null) {
+ try {
+ is.close();
+ } catch (IOException ignore) {
+ }
+ }
+ }
if (ic == null)
throw new ImageReadException("Couldn't read BMP Data");
@@ -671,7 +682,18 @@
FormatCompliance result = new FormatCompliance(byteSource
.getDescription());
- readImageContents(byteSource.getInputStream(), result, verbose);
+ InputStream is = null;
+ try {
+ is = byteSource.getInputStream();
+ readImageContents(is, result, verbose);
+ } finally {
+ if (is != null) {
+ try {
+ is.close();
+ } catch (IOException ignore) {
+ }
+ }
+ }
return result;
}
@@ -679,7 +701,18 @@
public BufferedImage getBufferedImage(ByteSource byteSource, Map params)
throws ImageReadException, IOException
{
- return getBufferedImage(byteSource.getInputStream(), params);
+ InputStream is = null;
+ try {
+ is = byteSource.getInputStream();
+ return getBufferedImage(is, params);
+ } finally {
+ if (is != null) {
+ try {
+ is.close();
+ } catch (IOException ignore) {
+ }
+ }
+ }
}
public BufferedImage getBufferedImage(InputStream inputStream, Map params)
diff --git a/src/main/java/org/apache/commons/sanselan/formats/pcx/PcxImageParser.java b/src/main/java/org/apache/commons/sanselan/formats/pcx/PcxImageParser.java
index 9006d0e..f1e9559 100644
--- a/src/main/java/org/apache/commons/sanselan/formats/pcx/PcxImageParser.java
+++ b/src/main/java/org/apache/commons/sanselan/formats/pcx/PcxImageParser.java
@@ -372,8 +372,7 @@
{
stream = byteSource.getInputStream();
long toSkip = byteSource.getLength() - 769;
- while (toSkip > 0)
- toSkip -= stream.skip(toSkip);
+ skipBytes(stream, (int)toSkip);
return read256ColorPalette(stream);
}
finally
diff --git a/src/main/java/org/apache/commons/sanselan/formats/psd/PsdImageParser.java b/src/main/java/org/apache/commons/sanselan/formats/psd/PsdImageParser.java
index c7127ed..f5f94be 100644
--- a/src/main/java/org/apache/commons/sanselan/formats/psd/PsdImageParser.java
+++ b/src/main/java/org/apache/commons/sanselan/formats/psd/PsdImageParser.java
@@ -300,52 +300,63 @@
private InputStream getInputStream(ByteSource byteSource, int section)
throws ImageReadException, IOException
{
- InputStream is = byteSource.getInputStream();
+ InputStream is = null;
+ boolean notFound = false;
+ try {
+ is = byteSource.getInputStream();
- if (section == PSD_SECTION_HEADER)
- return is;
-
- skipBytes(is, PSD_HEADER_LENGTH);
- // is.skip(kHeaderLength);
-
- int ColorModeDataLength = read4Bytes("ColorModeDataLength", is,
- "Not a Valid PSD File");
-
- if (section == PSD_SECTION_COLOR_MODE)
- return is;
-
- skipBytes(is, ColorModeDataLength);
- // byte ColorModeData[] = readByteArray("ColorModeData",
- // ColorModeDataLength, is, "Not a Valid PSD File");
-
- int ImageResourcesLength = read4Bytes("ImageResourcesLength", is,
- "Not a Valid PSD File");
-
- if (section == PSD_SECTION_IMAGE_RESOURCES)
- return is;
-
- skipBytes(is, ImageResourcesLength);
- // byte ImageResources[] = readByteArray("ImageResources",
- // ImageResourcesLength, is, "Not a Valid PSD File");
-
- int LayerAndMaskDataLength = read4Bytes("LayerAndMaskDataLength", is,
- "Not a Valid PSD File");
-
- if (section == PSD_SECTION_LAYER_AND_MASK_DATA)
- return is;
-
- skipBytes(is, LayerAndMaskDataLength);
- // byte LayerAndMaskData[] = readByteArray("LayerAndMaskData",
- // LayerAndMaskDataLength, is, "Not a Valid PSD File");
-
- int Compression = read2Bytes("Compression", is, "Not a Valid PSD File");
-
- // byte ImageData[] = readByteArray("ImageData",
- // LayerAndMaskDataLength, is, "Not a Valid PSD File");
-
- if (section == PSD_SECTION_IMAGE_DATA)
- return is;
-
+ if (section == PSD_SECTION_HEADER)
+ return is;
+
+ skipBytes(is, PSD_HEADER_LENGTH);
+ // is.skip(kHeaderLength);
+
+ int ColorModeDataLength = read4Bytes("ColorModeDataLength", is,
+ "Not a Valid PSD File");
+
+ if (section == PSD_SECTION_COLOR_MODE)
+ return is;
+
+ skipBytes(is, ColorModeDataLength);
+ // byte ColorModeData[] = readByteArray("ColorModeData",
+ // ColorModeDataLength, is, "Not a Valid PSD File");
+
+ int ImageResourcesLength = read4Bytes("ImageResourcesLength", is,
+ "Not a Valid PSD File");
+
+ if (section == PSD_SECTION_IMAGE_RESOURCES)
+ return is;
+
+ skipBytes(is, ImageResourcesLength);
+ // byte ImageResources[] = readByteArray("ImageResources",
+ // ImageResourcesLength, is, "Not a Valid PSD File");
+
+ int LayerAndMaskDataLength = read4Bytes("LayerAndMaskDataLength", is,
+ "Not a Valid PSD File");
+
+ if (section == PSD_SECTION_LAYER_AND_MASK_DATA)
+ return is;
+
+ skipBytes(is, LayerAndMaskDataLength);
+ // byte LayerAndMaskData[] = readByteArray("LayerAndMaskData",
+ // LayerAndMaskDataLength, is, "Not a Valid PSD File");
+
+ int Compression = read2Bytes("Compression", is, "Not a Valid PSD File");
+
+ // byte ImageData[] = readByteArray("ImageData",
+ // LayerAndMaskDataLength, is, "Not a Valid PSD File");
+
+ if (section == PSD_SECTION_IMAGE_DATA)
+ return is;
+ notFound = true;
+ } finally {
+ if (notFound && is != null) {
+ try {
+ is.close();
+ } catch (IOException ignore) {
+ }
+ }
+ }
throw new ImageReadException("getInputStream: Unknown Section: "
+ section);
}
diff --git a/src/main/java/org/apache/commons/sanselan/icc/IccProfileParser.java b/src/main/java/org/apache/commons/sanselan/icc/IccProfileParser.java
index 7572acd..2597c82 100644
--- a/src/main/java/org/apache/commons/sanselan/icc/IccProfileParser.java
+++ b/src/main/java/org/apache/commons/sanselan/icc/IccProfileParser.java
@@ -344,33 +344,43 @@
// if (debug)
// Debug.debug("length: " + length);
- InputStream is = byteSource.getInputStream();
+ InputStream is = null;
+ try {
+ is = byteSource.getInputStream();
- int ProfileSize = read4Bytes("ProfileSize", is,
- "Not a Valid ICC Profile");
+ int ProfileSize = read4Bytes("ProfileSize", is,
+ "Not a Valid ICC Profile");
+
+ // if (length != ProfileSize)
+ // return null;
+
+ this.skipBytes(is, 4 * 5);
+
+ skipBytes(is, 12, "Not a Valid ICC Profile");
+
+ this.skipBytes(is, 4 * 3);
+
+ int DeviceManufacturer = read4Bytes("ProfileFileSignature", is,
+ "Not a Valid ICC Profile");
+ if (debug)
+ printCharQuad("DeviceManufacturer", DeviceManufacturer);
+
+ int DeviceModel = read4Bytes("DeviceModel", is,
+ "Not a Valid ICC Profile");
+ if (debug)
+ printCharQuad("DeviceModel", DeviceModel);
+
+ boolean result = ((DeviceManufacturer == IEC) && (DeviceModel == sRGB));
- // if (length != ProfileSize)
- // return null;
-
- this.skipBytes(is, 4 * 5);
-
- skipBytes(is, 12, "Not a Valid ICC Profile");
-
- this.skipBytes(is, 4 * 3);
-
- int DeviceManufacturer = read4Bytes("ProfileFileSignature", is,
- "Not a Valid ICC Profile");
- if (debug)
- printCharQuad("DeviceManufacturer", DeviceManufacturer);
-
- int DeviceModel = read4Bytes("DeviceModel", is,
- "Not a Valid ICC Profile");
- if (debug)
- printCharQuad("DeviceModel", DeviceModel);
-
- boolean result = ((DeviceManufacturer == IEC) && (DeviceModel == sRGB));
-
- return result;
+ return result;
+ } finally {
+ if (is != null) {
+ try {
+ is.close();
+ } catch (IOException ignore) {
+ }
+ }
+ }
}
catch (Exception e)
{
diff --git a/src/test/java/org/apache/commons/sanselan/common/bytesource/ByteSourceDataTest.java b/src/test/java/org/apache/commons/sanselan/common/bytesource/ByteSourceDataTest.java
index 8a64309..7802d56 100644
--- a/src/test/java/org/apache/commons/sanselan/common/bytesource/ByteSourceDataTest.java
+++ b/src/test/java/org/apache/commons/sanselan/common/bytesource/ByteSourceDataTest.java
@@ -82,13 +82,23 @@
// test cache during interrupted read cache by reading only first N bytes.
{
- InputStream is = byteSource.getInputStream();
- byte prefix[] = new byte[256];
- int read = is.read(prefix);
-
- assertTrue(read <= src.length);
- for (int i = 0; i < read; i++)
- assertTrue(src[i] == prefix[i]);
+ InputStream is = null;
+ try {
+ is = byteSource.getInputStream();
+ byte prefix[] = new byte[256];
+ int read = is.read(prefix);
+
+ assertTrue(read <= src.length);
+ for (int i = 0; i < read; i++)
+ assertTrue(src[i] == prefix[i]);
+ } finally {
+ if (is != null) {
+ try {
+ is.close();
+ } catch (IOException ignore) {
+ }
+ }
+ }
}
// test cache by completely reading InputStream N times.
@@ -112,12 +122,22 @@
int start = src.length / 2;
- InputStream is = byteSource.getInputStream(start);
- byte dst[] = IoUtils.getInputStreamBytes(is);
+ InputStream is = null;
+ try {
+ is = byteSource.getInputStream(start);
+ byte dst[] = IoUtils.getInputStreamBytes(is);
- assertTrue(src.length == dst.length + start);
- for (int i = 0; i < dst.length; i++)
- assertTrue(dst[i] == src[i + start]);
+ assertTrue(src.length == dst.length + start);
+ for (int i = 0; i < dst.length; i++)
+ assertTrue(dst[i] == src[i + start]);
+ } finally {
+ if (is != null) {
+ try {
+ is.close();
+ } catch (IOException ignored) {
+ }
+ }
+ }
}
}