8270915: GIFImageReader disregards ignoreMetadata flag which causes memory exhaustion

Reviewed-by: prr
This commit is contained in:
Jayathirth D V 2022-10-06 05:43:43 +00:00
parent 6029120a5f
commit 8c15f77aba

View File

@ -1,5 +1,5 @@
/* /*
* Copyright (c) 2000, 2021, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2000, 2022, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
@ -30,12 +30,18 @@ import java.awt.Rectangle;
import java.awt.image.BufferedImage; import java.awt.image.BufferedImage;
import java.awt.image.DataBuffer; import java.awt.image.DataBuffer;
import java.awt.image.WritableRaster; import java.awt.image.WritableRaster;
import java.awt.image.ColorModel;
import java.awt.image.IndexColorModel;
import java.awt.image.MultiPixelPackedSampleModel;
import java.awt.image.PixelInterleavedSampleModel;
import java.awt.image.SampleModel;
import java.io.EOFException; import java.io.EOFException;
import java.io.IOException; import java.io.IOException;
import java.nio.ByteOrder; import java.nio.ByteOrder;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Iterator; import java.util.Iterator;
import java.util.List; import java.util.List;
import javax.imageio.IIOException; import javax.imageio.IIOException;
import javax.imageio.ImageReader; import javax.imageio.ImageReader;
import javax.imageio.ImageReadParam; import javax.imageio.ImageReadParam;
@ -43,12 +49,8 @@ import javax.imageio.ImageTypeSpecifier;
import javax.imageio.metadata.IIOMetadata; import javax.imageio.metadata.IIOMetadata;
import javax.imageio.spi.ImageReaderSpi; import javax.imageio.spi.ImageReaderSpi;
import javax.imageio.stream.ImageInputStream; import javax.imageio.stream.ImageInputStream;
import com.sun.imageio.plugins.common.ReaderUtil; import com.sun.imageio.plugins.common.ReaderUtil;
import java.awt.image.ColorModel;
import java.awt.image.IndexColorModel;
import java.awt.image.MultiPixelPackedSampleModel;
import java.awt.image.PixelInterleavedSampleModel;
import java.awt.image.SampleModel;
public class GIFImageReader extends ImageReader { public class GIFImageReader extends ImageReader {
@ -654,12 +656,18 @@ public class GIFImageReader extends ImageReader {
if (length == 0) { if (length == 0) {
break; break;
} }
if (ignoreMetadata) {
stream.skipBytes(length);
continue;
}
byte[] subBlockData =
ReaderUtil.staggeredReadByteStream(stream, length);
byte[] newData = new byte[data.length + length]; byte[] newData = new byte[data.length + length];
System.arraycopy(data, 0, newData, 0, data.length); System.arraycopy(data, 0, newData, 0, data.length);
stream.readFully(newData, data.length, length); System.arraycopy(subBlockData, 0, newData,
data.length, length);
data = newData; data = newData;
} }
return data; return data;
} }
@ -694,8 +702,9 @@ public class GIFImageReader extends ImageReader {
if (localColorTableFlag) { if (localColorTableFlag) {
// Read color table if any // Read color table if any
imageMetadata.localColorTable = imageMetadata.localColorTable =
new byte[3*numLCTEntries]; ReaderUtil.
stream.readFully(imageMetadata.localColorTable); staggeredReadByteStream(stream,
(3 * numLCTEntries));
} else { } else {
imageMetadata.localColorTable = null; imageMetadata.localColorTable = null;
} }
@ -726,66 +735,86 @@ public class GIFImageReader extends ImageReader {
int terminator = stream.readUnsignedByte(); int terminator = stream.readUnsignedByte();
} else if (label == 0x1) { // Plain text extension } else if (label == 0x1) { // Plain text extension
int length = stream.readUnsignedByte(); int length = stream.readUnsignedByte();
imageMetadata.hasPlainTextExtension = true; if (!ignoreMetadata) {
imageMetadata.textGridLeft = imageMetadata.hasPlainTextExtension = true;
stream.readUnsignedShort(); imageMetadata.textGridLeft =
imageMetadata.textGridTop = stream.readUnsignedShort();
stream.readUnsignedShort(); imageMetadata.textGridTop =
imageMetadata.textGridWidth = stream.readUnsignedShort();
stream.readUnsignedShort(); imageMetadata.textGridWidth =
imageMetadata.textGridHeight = stream.readUnsignedShort();
stream.readUnsignedShort(); imageMetadata.textGridHeight =
imageMetadata.characterCellWidth = stream.readUnsignedShort();
stream.readUnsignedByte(); imageMetadata.characterCellWidth =
imageMetadata.characterCellHeight = stream.readUnsignedByte();
stream.readUnsignedByte(); imageMetadata.characterCellHeight =
imageMetadata.textForegroundColor = stream.readUnsignedByte();
stream.readUnsignedByte(); imageMetadata.textForegroundColor =
imageMetadata.textBackgroundColor = stream.readUnsignedByte();
stream.readUnsignedByte(); imageMetadata.textBackgroundColor =
stream.readUnsignedByte();
} else {
stream.skipBytes(length);
}
imageMetadata.text = concatenateBlocks(); imageMetadata.text = concatenateBlocks();
} else if (label == 0xfe) { // Comment extension } else if (label == 0xfe) { // Comment extension
byte[] comment = concatenateBlocks(); byte[] comment = concatenateBlocks();
if (imageMetadata.comments == null) { if (!ignoreMetadata) {
imageMetadata.comments = new ArrayList<>(); if (imageMetadata.comments == null) {
imageMetadata.comments = new ArrayList<>();
}
imageMetadata.comments.add(comment);
} }
imageMetadata.comments.add(comment);
} else if (label == 0xff) { // Application extension } else if (label == 0xff) { // Application extension
int blockSize = stream.readUnsignedByte(); int blockSize = stream.readUnsignedByte();
int offset = 0;
byte[] blockData = new byte[0];
byte[] applicationID = new byte[8]; byte[] applicationID = new byte[8];
byte[] authCode = new byte[3]; byte[] authCode = new byte[3];
if (!ignoreMetadata) {
// read available data
blockData =
ReaderUtil.staggeredReadByteStream(stream,
blockSize);
// read available data offset =
byte[] blockData = new byte[blockSize]; copyData(blockData, 0, applicationID);
stream.readFully(blockData); offset = copyData(blockData, offset, authCode);
} else {
int offset = copyData(blockData, 0, applicationID); stream.skipBytes(blockSize);
offset = copyData(blockData, offset, authCode); }
byte[] applicationData = concatenateBlocks(); byte[] applicationData = concatenateBlocks();
if (offset < blockSize) { if (!ignoreMetadata &&
offset < blockSize) {
int len = blockSize - offset; int len = blockSize - offset;
byte[] data = byte[] data =
new byte[len + applicationData.length]; new byte[len + applicationData.length];
System.arraycopy(blockData, offset, data, 0, len); System.arraycopy(blockData, offset,
System.arraycopy(applicationData, 0, data, len, data, 0, len);
System.arraycopy(applicationData, 0,
data, len,
applicationData.length); applicationData.length);
applicationData = data; applicationData = data;
} }
// Init lists if necessary if (!ignoreMetadata) {
if (imageMetadata.applicationIDs == null) { // Init lists if necessary
imageMetadata.applicationIDs = new ArrayList<>(); if (imageMetadata.applicationIDs == null) {
imageMetadata.authenticationCodes = imageMetadata.applicationIDs =
new ArrayList<>(); new ArrayList<>();
imageMetadata.applicationData = new ArrayList<>(); imageMetadata.authenticationCodes =
new ArrayList<>();
imageMetadata.applicationData =
new ArrayList<>();
}
imageMetadata.applicationIDs.add(applicationID);
imageMetadata.authenticationCodes.add(authCode);
imageMetadata.applicationData.add(applicationData);
} }
imageMetadata.applicationIDs.add(applicationID);
imageMetadata.authenticationCodes.add(authCode);
imageMetadata.applicationData.add(applicationData);
} else { } else {
// Skip over unknown extension blocks // Skip over unknown extension blocks
int length = 0; int length = 0;