mirror of
https://github.com/haraldk/TwelveMonkeys.git
synced 2026-05-01 00:00:02 -04:00
#329 JPEGImageReader endless loop fix
This commit is contained in:
+1
-1
@@ -90,7 +90,7 @@ class Application extends Segment {
|
||||
|
||||
default:
|
||||
// Generic APPn segment
|
||||
byte[] bytes = new byte[length - 2];
|
||||
byte[] bytes = new byte[Math.max(0, length - 2)];
|
||||
data.readFully(bytes);
|
||||
return new Application(marker, identifier, bytes);
|
||||
}
|
||||
|
||||
+16
-3
@@ -233,7 +233,14 @@ public final class JPEGImageReader extends ImageReaderBase {
|
||||
|
||||
@Override
|
||||
public Iterator<ImageTypeSpecifier> getImageTypes(int imageIndex) throws IOException {
|
||||
Iterator<ImageTypeSpecifier> types = delegate.getImageTypes(imageIndex);
|
||||
Iterator<ImageTypeSpecifier> types;
|
||||
try {
|
||||
types = delegate.getImageTypes(imageIndex);
|
||||
}
|
||||
catch (IndexOutOfBoundsException | NegativeArraySizeException ignore) {
|
||||
types = null;
|
||||
}
|
||||
|
||||
JPEGColorSpace csType = getSourceCSType(getJFIF(), getAdobeDCT(), getSOF());
|
||||
|
||||
if (types == null || !types.hasNext() || csType == JPEGColorSpace.CMYK || csType == JPEGColorSpace.YCCK) {
|
||||
@@ -302,7 +309,7 @@ public final class JPEGImageReader extends ImageReaderBase {
|
||||
return rawType;
|
||||
}
|
||||
}
|
||||
catch (IIOException | NullPointerException ignore) {
|
||||
catch (IIOException | NullPointerException | ArrayIndexOutOfBoundsException | NegativeArraySizeException ignore) {
|
||||
// Fall through
|
||||
}
|
||||
|
||||
@@ -933,7 +940,13 @@ public final class JPEGImageReader extends ImageReaderBase {
|
||||
return new JPEGLosslessDecoderWrapper(this).readRaster(segments, imageInput);
|
||||
}
|
||||
|
||||
return delegate.readRaster(imageIndex, param);
|
||||
try {
|
||||
return delegate.readRaster(imageIndex, param);
|
||||
}
|
||||
catch (IndexOutOfBoundsException knownIssue) {
|
||||
// com.sun.imageio.plugins.jpeg.JPEGBuffer doesn't do proper sanity check of input data.
|
||||
throw new IIOException("Corrupt JPEG data: Bad segment length", knownIssue);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
+18
-13
@@ -40,6 +40,7 @@ import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
|
||||
import static com.twelvemonkeys.imageio.metadata.jpeg.JPEGSegmentUtil.isKnownJPEGMarker;
|
||||
import static com.twelvemonkeys.lang.Validate.notNull;
|
||||
import static java.util.Arrays.copyOf;
|
||||
|
||||
@@ -105,24 +106,25 @@ final class JPEGSegmentImageInputStream extends ImageInputStreamImpl {
|
||||
|
||||
// Scan forward
|
||||
while (true) {
|
||||
long realPosition = stream.getStreamPosition();
|
||||
|
||||
int trash = 0;
|
||||
int marker = stream.readUnsignedByte();
|
||||
|
||||
// Skip bad padding before the marker
|
||||
while (marker != 0xff) {
|
||||
marker = stream.readUnsignedByte();
|
||||
trash++;
|
||||
realPosition++;
|
||||
}
|
||||
while (!isKnownJPEGMarker(marker)) {
|
||||
marker &= 0xff;
|
||||
|
||||
marker = 0xff00 | stream.readUnsignedByte();
|
||||
// Skip bad padding before the marker
|
||||
while (marker != 0xff) {
|
||||
marker = stream.readUnsignedByte();
|
||||
trash++;
|
||||
}
|
||||
|
||||
// Skip over 0xff padding between markers
|
||||
while (marker == 0xffff) {
|
||||
realPosition++;
|
||||
marker = 0xff00 | stream.readUnsignedByte();
|
||||
|
||||
// Skip over 0xff padding between markers
|
||||
while (marker == 0xffff) {
|
||||
marker = 0xff00 | stream.readUnsignedByte();
|
||||
trash++;
|
||||
}
|
||||
}
|
||||
|
||||
if (trash != 0) {
|
||||
@@ -131,6 +133,8 @@ final class JPEGSegmentImageInputStream extends ImageInputStreamImpl {
|
||||
processWarningOccured(String.format("Corrupt JPEG data: %d extraneous bytes before marker 0x%02x", trash, marker & 0xff));
|
||||
}
|
||||
|
||||
long realPosition = stream.getStreamPosition() - 2;
|
||||
|
||||
// We are now handling all important segments ourselves, except APP1/Exif and APP14/Adobe,
|
||||
// as these segments affects image decoding.
|
||||
boolean appSegmentMarker = isAppSegmentMarker(marker);
|
||||
@@ -380,6 +384,7 @@ final class JPEGSegmentImageInputStream extends ImageInputStreamImpl {
|
||||
fetchSegment();
|
||||
}
|
||||
catch (EOFException ignore) {
|
||||
segments.add(new Segment(0, segment.realEnd(), segment.end(), Integer.MAX_VALUE * 2L - segment.realEnd()));
|
||||
// This might happen if the segment lengths in the stream are bad.
|
||||
// We MUST leave internal state untouched in this case.
|
||||
// We ignore this exception here, but client code will get
|
||||
@@ -415,7 +420,7 @@ final class JPEGSegmentImageInputStream extends ImageInputStreamImpl {
|
||||
repositionAsNecessary();
|
||||
|
||||
long bytesLeft = segment.end() - streamPos; // If no more bytes after reposition, we're at EOF
|
||||
int count = bytesLeft == 0 ? -1 : segment.read(stream, b, off + total, (int) Math.min(len - total, bytesLeft));
|
||||
int count = bytesLeft <= 0 ? -1 : segment.read(stream, b, off + total, (int) Math.min(len - total, bytesLeft));
|
||||
|
||||
if (count == -1) {
|
||||
// EOF
|
||||
|
||||
Reference in New Issue
Block a user