mirror of
https://github.com/openjdk/jdk.git
synced 2026-03-05 13:40:18 +00:00
8145014: "IIOException: Couldn't seek!" when calling TIFFImageReader.getNumImages()
In locateImage() break and decrement image count for zero-entry IFDs and on encountering an EOF. Reviewed-by: prr
This commit is contained in:
parent
79b2dd4b8d
commit
d41cfa354a
@ -35,6 +35,7 @@ import java.awt.image.ComponentColorModel;
|
||||
import java.awt.image.Raster;
|
||||
import java.awt.image.RenderedImage;
|
||||
import java.awt.image.SampleModel;
|
||||
import java.io.EOFException;
|
||||
import java.io.IOException;
|
||||
import java.nio.ByteOrder;
|
||||
import java.util.ArrayList;
|
||||
@ -189,8 +190,8 @@ public class TIFFImageReader extends ImageReader {
|
||||
|
||||
// Seek to start of first IFD
|
||||
long offset = stream.readUnsignedInt();
|
||||
imageStartPosition.add(Long.valueOf(offset));
|
||||
stream.seek(offset);
|
||||
imageStartPosition.add(Long.valueOf(offset));
|
||||
} catch (IOException e) {
|
||||
throw new IIOException("I/O error reading header!", e);
|
||||
}
|
||||
@ -201,10 +202,10 @@ public class TIFFImageReader extends ImageReader {
|
||||
private int locateImage(int imageIndex) throws IIOException {
|
||||
readHeader();
|
||||
|
||||
try {
|
||||
// Find closest known index
|
||||
int index = Math.min(imageIndex, imageStartPosition.size() - 1);
|
||||
// Find closest known index
|
||||
int index = Math.min(imageIndex, imageStartPosition.size() - 1);
|
||||
|
||||
try {
|
||||
// Seek to that position
|
||||
Long l = imageStartPosition.get(index);
|
||||
stream.seek(l.longValue());
|
||||
@ -212,6 +213,11 @@ public class TIFFImageReader extends ImageReader {
|
||||
// Skip IFDs until at desired index or last image found
|
||||
while (index < imageIndex) {
|
||||
int count = stream.readUnsignedShort();
|
||||
// If zero-entry IFD, decrement the index and exit the loop
|
||||
if (count == 0) {
|
||||
imageIndex = index > 0 ? index - 1 : 0;
|
||||
break;
|
||||
}
|
||||
stream.skipBytes(12 * count);
|
||||
|
||||
long offset = stream.readUnsignedInt();
|
||||
@ -219,12 +225,17 @@ public class TIFFImageReader extends ImageReader {
|
||||
return index;
|
||||
}
|
||||
|
||||
imageStartPosition.add(Long.valueOf(offset));
|
||||
stream.seek(offset);
|
||||
imageStartPosition.add(Long.valueOf(offset));
|
||||
++index;
|
||||
}
|
||||
} catch (IOException e) {
|
||||
throw new IIOException("Couldn't seek!", e);
|
||||
} catch (EOFException eofe) {
|
||||
forwardWarningMessage("Ignored " + eofe);
|
||||
|
||||
// Ran off the end of stream: decrement index
|
||||
imageIndex = index > 0 ? index - 1 : 0;
|
||||
} catch (IOException ioe) {
|
||||
throw new IIOException("Couldn't seek!", ioe);
|
||||
}
|
||||
|
||||
if (currIndex != imageIndex) {
|
||||
|
||||
196
jdk/test/javax/imageio/plugins/tiff/BogusSecondImageTest.java
Normal file
196
jdk/test/javax/imageio/plugins/tiff/BogusSecondImageTest.java
Normal file
@ -0,0 +1,196 @@
|
||||
/*
|
||||
* Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @test
|
||||
* @bug 8145014
|
||||
* @summary Verify reader correctly fails for zero-entry IFDs and EOFs
|
||||
* encountered in locateImage().
|
||||
*/
|
||||
|
||||
import java.awt.Image;
|
||||
import java.awt.image.*;
|
||||
import java.io.*;
|
||||
import java.util.Iterator;
|
||||
import javax.imageio.*;
|
||||
import javax.imageio.stream.*;
|
||||
|
||||
public class BogusSecondImageTest {
|
||||
public static void main(String[] args) throws Throwable {
|
||||
int failures = 0;
|
||||
|
||||
try {
|
||||
testZeroEntryIFD();
|
||||
} catch (Exception e) {
|
||||
System.out.printf("Failed testZeroEntryIFD: %s%n", e);
|
||||
failures++;
|
||||
}
|
||||
|
||||
try {
|
||||
testOutOfStreamIFD();
|
||||
} catch (Exception e) {
|
||||
System.out.printf("Failed testOutOfStreamIFD: %s%n", e);
|
||||
failures++;
|
||||
}
|
||||
|
||||
if (failures == 0) {
|
||||
System.out.println("Test succeeded");
|
||||
} else {
|
||||
throw new RuntimeException
|
||||
("Test failed with " + failures + " errors");
|
||||
}
|
||||
}
|
||||
|
||||
private static void testZeroEntryIFD() throws Exception {
|
||||
// Create an image.
|
||||
File f = createImageFile();
|
||||
|
||||
ImageOutputStream s = new FileImageOutputStream(f);
|
||||
long length = s.length();
|
||||
|
||||
// Skip the endianness and magic number
|
||||
s.skipBytes(4);
|
||||
|
||||
// Read and seek to offset of 0th IFD
|
||||
long ifd0 = s.readUnsignedInt();
|
||||
s.seek(ifd0);
|
||||
|
||||
// Read number of 0th IFD entries and skip over them
|
||||
int entries0 = s.readUnsignedShort();
|
||||
s.skipBytes(12*entries0);
|
||||
|
||||
// Write the offset of the 1st IFD as the current file length
|
||||
s.write((int)length);
|
||||
|
||||
// Seek to the 1st IFD and write a zero entry count to it
|
||||
s.seek(length);
|
||||
s.writeShort(0);
|
||||
s.close();
|
||||
|
||||
try {
|
||||
Load(f);
|
||||
} catch (Exception e) {
|
||||
throw e;
|
||||
} finally {
|
||||
f.delete();
|
||||
}
|
||||
}
|
||||
|
||||
private static void testOutOfStreamIFD() throws Exception {
|
||||
// Create an image.
|
||||
File f = createImageFile();
|
||||
ImageOutputStream s = new FileImageOutputStream(f);
|
||||
long length = s.length();
|
||||
|
||||
// Skip the endianness and magic number
|
||||
s.skipBytes(4);
|
||||
|
||||
// Read and seek to offset of 0th IFD
|
||||
long ifd0 = s.readUnsignedInt();
|
||||
s.seek(ifd0);
|
||||
|
||||
// Read number of 0th IFD entries and skip over them
|
||||
int entries0 = s.readUnsignedShort();
|
||||
s.skipBytes(12*entries0);
|
||||
|
||||
// Write the offset of the 1st IFD as the current file length + 7
|
||||
s.write((int)length + 7);
|
||||
s.close();
|
||||
|
||||
try {
|
||||
Load(f);
|
||||
} catch (Exception e) {
|
||||
throw e;
|
||||
} finally {
|
||||
f.delete();
|
||||
}
|
||||
}
|
||||
|
||||
private static File createImageFile() throws Exception {
|
||||
BufferedImage im =
|
||||
new BufferedImage(100, 100, BufferedImage.TYPE_BYTE_GRAY);
|
||||
File f = File.createTempFile("BogusSecondImage", "tif", new File("."));
|
||||
f.deleteOnExit();
|
||||
if (!ImageIO.write(im, "TIFF", f)) {
|
||||
throw new RuntimeException("Failed to write " + f);
|
||||
}
|
||||
return f;
|
||||
}
|
||||
|
||||
private final static boolean printTrace = false;
|
||||
|
||||
public static void Load(File file) {
|
||||
if (!file.exists()) {
|
||||
throw new IllegalArgumentException(file + " does not exist");
|
||||
} else if (!file.isFile()) {
|
||||
throw new IllegalArgumentException(file + " is not a regular file");
|
||||
} else if (!file.canRead()) {
|
||||
throw new IllegalArgumentException(file + " cannot be read");
|
||||
}
|
||||
|
||||
ImageInputStream input = null;
|
||||
try {
|
||||
input = ImageIO.createImageInputStream(file);
|
||||
} catch (Throwable e) {
|
||||
System.err.println("NOK: createImageInputStream()\t" + e.getMessage());
|
||||
if (printTrace) { e.printStackTrace(); }
|
||||
return;
|
||||
}
|
||||
|
||||
Iterator<ImageReader> readers = ImageIO.getImageReadersByFormatName("TIFF");
|
||||
if (!readers.hasNext()) { throw new RuntimeException("No readers available for TIFF"); }
|
||||
ImageReader reader = readers.next();
|
||||
reader.setInput(input);
|
||||
|
||||
Image images[] = null;
|
||||
int numImages = 0;
|
||||
|
||||
int failures = 0;
|
||||
try {
|
||||
numImages = reader.getNumImages(true);
|
||||
images = new Image[numImages];
|
||||
} catch (Throwable e) {
|
||||
failures++;
|
||||
System.err.println("NOK: getNumImages()\t" + e.getMessage());
|
||||
if (printTrace) { e.printStackTrace(); }
|
||||
}
|
||||
System.out.printf("numImages %d%n", numImages);
|
||||
|
||||
for (int i = 0; i < numImages; i++) {
|
||||
System.out.printf("reading image %d%n", i);
|
||||
try {
|
||||
images[i] = reader.read(i);
|
||||
} catch (Throwable e) {
|
||||
failures++;
|
||||
System.err.println("NOK: read()\t" + e.getMessage());
|
||||
if (printTrace) { e.printStackTrace(); }
|
||||
}
|
||||
}
|
||||
|
||||
if (failures == 0) {
|
||||
System.err.println("OK");
|
||||
} else {
|
||||
throw new RuntimeException("NOK");
|
||||
}
|
||||
}
|
||||
}
|
||||
Loading…
x
Reference in New Issue
Block a user