TMI-120: Fix IIOOBE when file has no image. Will throw exceptions when trying to read or get metadata.

This commit is contained in:
Harald Kuhr 2015-03-19 21:57:03 +01:00
parent 11f33741d4
commit 406ae28da7
3 changed files with 38 additions and 2 deletions

View File

@ -49,6 +49,7 @@ import javax.imageio.event.IIOReadUpdateListener;
import javax.imageio.event.IIOReadWarningListener;
import javax.imageio.metadata.IIOMetadata;
import javax.imageio.metadata.IIOMetadataFormatImpl;
import javax.imageio.metadata.IIOMetadataNode;
import javax.imageio.spi.ImageReaderSpi;
import javax.imageio.stream.ImageInputStream;
import javax.imageio.stream.MemoryCacheImageInputStream;
@ -100,6 +101,7 @@ import java.util.List;
public class JPEGImageReader extends ImageReaderBase {
// TODO: Allow automatic rotation based on EXIF rotation field?
// TODO: Create a simplified native metadata format that is closer to the actual JPEG stream AND supports EXIF in a sensible way
// TODO: As we already parse the SOF segments, maybe we should stop delegating getWidth/getHeight etc?
final static boolean DEBUG = "true".equalsIgnoreCase(System.getProperty("com.twelvemonkeys.imageio.plugins.jpeg.debug"));
@ -197,7 +199,13 @@ public class JPEGImageReader extends ImageReaderBase {
@Override
public int getNumImages(boolean allowSearch) throws IOException {
return delegate.getNumImages(allowSearch);
try {
return delegate.getNumImages(allowSearch);
}
catch (ArrayIndexOutOfBoundsException ignore) {
// This will happen if we find a "tables only" image, with no more images in stream.
return 0;
}
}
@Override
@ -1086,7 +1094,11 @@ public class JPEGImageReader extends ImageReaderBase {
}
catch (IndexOutOfBoundsException knownIssue) {
// TMI-101: com.sun.imageio.plugins.jpeg.JPEGBuffer doesn't do proper sanity check of input data.
throw new IIOException("Corrupt JPEG data: Bad segment offset/length", knownIssue);
throw new IIOException("Corrupt JPEG data: Bad segment length", knownIssue);
}
catch (NegativeArraySizeException knownIssue) {
// Most likely from com.sun.imageio.plugins.jpeg.SOSMarkerSegment
throw new IIOException("Corrupt JPEG data: Bad component count", knownIssue);
}
if (imageMetadata != null && Arrays.asList(imageMetadata.getMetadataFormatNames()).contains(JPEGImage10MetadataCleaner.JAVAX_IMAGEIO_JPEG_IMAGE_1_0)) {
@ -1400,6 +1412,14 @@ public class JPEGImageReader extends ImageReaderBase {
reader.setInput(input);
// For a tables-only image, we can't read image, but we should get metadata.
if (reader.getNumImages(true) == 0) {
IIOMetadata streamMetadata = reader.getStreamMetadata();
IIOMetadataNode streamNativeTree = (IIOMetadataNode) streamMetadata.getAsTree(streamMetadata.getNativeMetadataFormatName());
new XMLSerializer(System.out, System.getProperty("file.encoding")).serialize(streamNativeTree, false);
continue;
}
try {
ImageReadParam param = reader.getDefaultReadParam();
// if (args.length > 1) {

View File

@ -1360,6 +1360,22 @@ public class JPEGImageReaderTest extends ImageReaderAbstractTestCase<JPEGImageRe
return sortedNodes;
}
@Test
public void testGetNumImagesBogusDataPrepended() throws IOException {
// The JPEGImageReader (incorrectly) interprets this image to be a "tables only" image.
JPEGImageReader reader = createReader();
try {
reader.setInput(ImageIO.createImageInputStream(getClassLoaderResource("/broken-jpeg/broken-bogus-data-prepended-real-jfif-start-at-4801.jpg")));
assertEquals(-1, reader.getNumImages(false)); // Ok
assertEquals(0, reader.getNumImages(true)); // Should throw IIOException or return 0
}
finally {
reader.dispose();
}
}
@Test
public void testNegativeSOSComponentCount() throws IOException {
// The data in the stream looks like this:

Binary file not shown.

After

Width:  |  Height:  |  Size: 530 KiB