8270915: GIFImageReader disregards ignoreMetadata flag which causes memory exhaustion
Reviewed-by: prr
This commit is contained in:
parent
6029120a5f
commit
8c15f77aba
@ -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;
|
||||||
|
Loading…
x
Reference in New Issue
Block a user