#677 Fixed integer overflow + added tests

This commit is contained in:
Harald Kuhr
2022-05-04 18:23:25 +02:00
parent aab5b062bd
commit ab13fdd09d
2 changed files with 160 additions and 62 deletions
@@ -30,20 +30,33 @@
package com.twelvemonkeys.imageio.plugins.tiff;
import com.twelvemonkeys.imageio.metadata.Directory;
import com.twelvemonkeys.imageio.metadata.Entry;
import com.twelvemonkeys.imageio.metadata.tiff.Rational;
import com.twelvemonkeys.imageio.metadata.tiff.TIFF;
import com.twelvemonkeys.imageio.metadata.tiff.TIFFReader;
import com.twelvemonkeys.imageio.stream.ByteArrayImageInputStream;
import com.twelvemonkeys.imageio.util.ImageWriterAbstractTest;
import com.twelvemonkeys.io.FastByteArrayOutputStream;
import com.twelvemonkeys.io.NullOutputStream;
import static com.twelvemonkeys.imageio.plugins.tiff.TIFFImageMetadataFormat.SUN_NATIVE_IMAGE_METADATA_FORMAT_NAME;
import static com.twelvemonkeys.imageio.plugins.tiff.TIFFImageMetadataTest.createTIFFFieldNode;
import static com.twelvemonkeys.imageio.util.ImageReaderAbstractTest.assertRGBEquals;
import static org.junit.Assert.*;
import static org.junit.Assume.assumeNotNull;
import static org.mockito.Mockito.*;
import org.junit.Test;
import org.w3c.dom.NodeList;
import java.awt.*;
import java.awt.color.ColorSpace;
import java.awt.image.*;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.IOException;
import java.io.OutputStream;
import java.net.URL;
import java.nio.ByteOrder;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import javax.imageio.*;
import javax.imageio.IIOImage;
import javax.imageio.ImageIO;
import javax.imageio.ImageReader;
import javax.imageio.ImageTypeSpecifier;
import javax.imageio.ImageWriteParam;
import javax.imageio.ImageWriter;
import javax.imageio.event.IIOWriteProgressListener;
import javax.imageio.metadata.IIOMetadata;
import javax.imageio.metadata.IIOMetadataFormatImpl;
@@ -53,22 +66,20 @@ import javax.imageio.stream.FileCacheImageOutputStream;
import javax.imageio.stream.FileImageOutputStream;
import javax.imageio.stream.ImageInputStream;
import javax.imageio.stream.ImageOutputStream;
import java.awt.*;
import java.awt.image.BufferedImage;
import java.awt.image.RenderedImage;
import java.io.*;
import java.net.URL;
import java.nio.ByteOrder;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import javax.imageio.stream.ImageOutputStreamImpl;
import static com.twelvemonkeys.imageio.plugins.tiff.TIFFImageMetadataFormat.SUN_NATIVE_IMAGE_METADATA_FORMAT_NAME;
import static com.twelvemonkeys.imageio.plugins.tiff.TIFFImageMetadataTest.createTIFFFieldNode;
import static com.twelvemonkeys.imageio.util.ImageReaderAbstractTest.assertRGBEquals;
import static org.junit.Assert.*;
import static org.junit.Assume.assumeNotNull;
import static org.mockito.Mockito.*;
import org.junit.Test;
import org.w3c.dom.NodeList;
import com.twelvemonkeys.imageio.metadata.Directory;
import com.twelvemonkeys.imageio.metadata.Entry;
import com.twelvemonkeys.imageio.metadata.tiff.Rational;
import com.twelvemonkeys.imageio.metadata.tiff.TIFF;
import com.twelvemonkeys.imageio.metadata.tiff.TIFFReader;
import com.twelvemonkeys.imageio.stream.ByteArrayImageInputStream;
import com.twelvemonkeys.imageio.util.ImageWriterAbstractTest;
import com.twelvemonkeys.io.FastByteArrayOutputStream;
import com.twelvemonkeys.io.NullOutputStream;
/**
* TIFFImageWriterTest
@@ -638,7 +649,12 @@ public class TIFFImageWriterTest extends ImageWriterAbstractTest<TIFFImageWriter
int maxH = Math.min(300, image.getHeight());
for (int y = 0; y < maxH; y++) {
for (int x = 0; x < image.getWidth(); x++) {
assertRGBEquals(String.format("Pixel differ: @%d,%d", x, y), orig.getRGB(x, y), image.getRGB(x, y), 0);
try {
assertRGBEquals("", orig.getRGB(x, y), image.getRGB(x, y), 0);
}
catch (AssertionError err) {
fail(String.format("Pixel differ: @%d,%d %s", x, y, err.getMessage()));
}
}
}
@@ -1266,6 +1282,50 @@ public class TIFFImageWriterTest extends ImageWriterAbstractTest<TIFFImageWriter
}
}
@Test
public void testShortOverflowHuge() throws IOException {
int width = 34769;
int height = 33769;
// Create a huge image without actually allocating memory...
DataBuffer buffer = new NullDataBuffer(DataBuffer.TYPE_USHORT, width * height);
WritableRaster raster = Raster.createWritableRaster(new ComponentSampleModel(buffer.getDataType(), width, height, 1, width, new int[] {0}), buffer, null);
ColorModel colorModel = new ComponentColorModel(ColorSpace.getInstance(ColorSpace.CS_GRAY), false, false, Transparency.OPAQUE, buffer.getDataType());
BufferedImage image = new BufferedImage(colorModel, raster, colorModel.isAlphaPremultiplied(), null);
// Write image without any exception
TIFFImageWriter writer = createWriter();
try (ImageOutputStream stream = new NullImageOutputStream()) {
writer.setOutput(stream);
writer.write(image);
}
finally {
writer.dispose();
}
}
@Test
public void testIntOverflowHuge() throws IOException {
int width = 34769;
int height = 33769;
// Create a huge image without actually allocating memory...
DataBuffer buffer = new NullDataBuffer(DataBuffer.TYPE_INT, width * height);
WritableRaster raster = Raster.createWritableRaster(new ComponentSampleModel(buffer.getDataType(), width, height, 1, width, new int[] {0}), buffer, null);
ColorModel colorModel = new ComponentColorModel(ColorSpace.getInstance(ColorSpace.CS_GRAY), false, false, Transparency.OPAQUE, buffer.getDataType());
BufferedImage image = new BufferedImage(colorModel, raster, colorModel.isAlphaPremultiplied(), null);
// Write image without any exception
TIFFImageWriter writer = createWriter();
try (ImageOutputStream stream = new NullImageOutputStream()) {
writer.setOutput(stream);
writer.write(image);
}
finally {
writer.dispose();
}
}
private static class ImageInfo {
final int width;
final int height;
@@ -1278,4 +1338,35 @@ public class TIFFImageWriterTest extends ImageWriterAbstractTest<TIFFImageWriter
this.compression = compression;
}
}
// Special purpose output stream that acts as a sink
private static class NullImageOutputStream extends ImageOutputStreamImpl {
@Override public void write(int b) {
}
@Override public void write(byte[] b, int off, int len) {
}
@Override public int read() throws IOException {
return 0;
}
@Override public int read(byte[] b, int off, int len) throws IOException {
return 0;
}
}
// Special purpose data buffer that does not require memory, to allow very large images
private static class NullDataBuffer extends DataBuffer {
public NullDataBuffer(int type, int size) {
super(type, size);
}
@Override public int getElem(int bank, int i) {
return 0;
}
@Override public void setElem(int bank, int i, int val) {
}
}
}