Skip to content

Commit 8c15f77

Browse files
committedOct 6, 2022
8270915: GIFImageReader disregards ignoreMetadata flag which causes memory exhaustion
Reviewed-by: prr
1 parent 6029120 commit 8c15f77

File tree

1 file changed

+78
-49
lines changed

1 file changed

+78
-49
lines changed
 

‎src/java.desktop/share/classes/com/sun/imageio/plugins/gif/GIFImageReader.java

+78-49
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright (c) 2000, 2021, Oracle and/or its affiliates. All rights reserved.
2+
* Copyright (c) 2000, 2022, Oracle and/or its affiliates. All rights reserved.
33
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
44
*
55
* This code is free software; you can redistribute it and/or modify it
@@ -30,25 +30,27 @@
3030
import java.awt.image.BufferedImage;
3131
import java.awt.image.DataBuffer;
3232
import java.awt.image.WritableRaster;
33+
import java.awt.image.ColorModel;
34+
import java.awt.image.IndexColorModel;
35+
import java.awt.image.MultiPixelPackedSampleModel;
36+
import java.awt.image.PixelInterleavedSampleModel;
37+
import java.awt.image.SampleModel;
3338
import java.io.EOFException;
3439
import java.io.IOException;
3540
import java.nio.ByteOrder;
3641
import java.util.ArrayList;
3742
import java.util.Iterator;
3843
import java.util.List;
44+
3945
import javax.imageio.IIOException;
4046
import javax.imageio.ImageReader;
4147
import javax.imageio.ImageReadParam;
4248
import javax.imageio.ImageTypeSpecifier;
4349
import javax.imageio.metadata.IIOMetadata;
4450
import javax.imageio.spi.ImageReaderSpi;
4551
import javax.imageio.stream.ImageInputStream;
52+
4653
import com.sun.imageio.plugins.common.ReaderUtil;
47-
import java.awt.image.ColorModel;
48-
import java.awt.image.IndexColorModel;
49-
import java.awt.image.MultiPixelPackedSampleModel;
50-
import java.awt.image.PixelInterleavedSampleModel;
51-
import java.awt.image.SampleModel;
5254

5355
public class GIFImageReader extends ImageReader {
5456

@@ -654,12 +656,18 @@ private byte[] concatenateBlocks() throws IOException {
654656
if (length == 0) {
655657
break;
656658
}
659+
if (ignoreMetadata) {
660+
stream.skipBytes(length);
661+
continue;
662+
}
663+
byte[] subBlockData =
664+
ReaderUtil.staggeredReadByteStream(stream, length);
657665
byte[] newData = new byte[data.length + length];
658666
System.arraycopy(data, 0, newData, 0, data.length);
659-
stream.readFully(newData, data.length, length);
667+
System.arraycopy(subBlockData, 0, newData,
668+
data.length, length);
660669
data = newData;
661670
}
662-
663671
return data;
664672
}
665673

@@ -694,8 +702,9 @@ private void readMetadata() throws IIOException {
694702
if (localColorTableFlag) {
695703
// Read color table if any
696704
imageMetadata.localColorTable =
697-
new byte[3*numLCTEntries];
698-
stream.readFully(imageMetadata.localColorTable);
705+
ReaderUtil.
706+
staggeredReadByteStream(stream,
707+
(3 * numLCTEntries));
699708
} else {
700709
imageMetadata.localColorTable = null;
701710
}
@@ -726,66 +735,86 @@ private void readMetadata() throws IIOException {
726735
int terminator = stream.readUnsignedByte();
727736
} else if (label == 0x1) { // Plain text extension
728737
int length = stream.readUnsignedByte();
729-
imageMetadata.hasPlainTextExtension = true;
730-
imageMetadata.textGridLeft =
731-
stream.readUnsignedShort();
732-
imageMetadata.textGridTop =
733-
stream.readUnsignedShort();
734-
imageMetadata.textGridWidth =
735-
stream.readUnsignedShort();
736-
imageMetadata.textGridHeight =
737-
stream.readUnsignedShort();
738-
imageMetadata.characterCellWidth =
739-
stream.readUnsignedByte();
740-
imageMetadata.characterCellHeight =
741-
stream.readUnsignedByte();
742-
imageMetadata.textForegroundColor =
743-
stream.readUnsignedByte();
744-
imageMetadata.textBackgroundColor =
745-
stream.readUnsignedByte();
738+
if (!ignoreMetadata) {
739+
imageMetadata.hasPlainTextExtension = true;
740+
imageMetadata.textGridLeft =
741+
stream.readUnsignedShort();
742+
imageMetadata.textGridTop =
743+
stream.readUnsignedShort();
744+
imageMetadata.textGridWidth =
745+
stream.readUnsignedShort();
746+
imageMetadata.textGridHeight =
747+
stream.readUnsignedShort();
748+
imageMetadata.characterCellWidth =
749+
stream.readUnsignedByte();
750+
imageMetadata.characterCellHeight =
751+
stream.readUnsignedByte();
752+
imageMetadata.textForegroundColor =
753+
stream.readUnsignedByte();
754+
imageMetadata.textBackgroundColor =
755+
stream.readUnsignedByte();
756+
} else {
757+
stream.skipBytes(length);
758+
}
746759
imageMetadata.text = concatenateBlocks();
747760
} else if (label == 0xfe) { // Comment extension
748761
byte[] comment = concatenateBlocks();
749-
if (imageMetadata.comments == null) {
750-
imageMetadata.comments = new ArrayList<>();
762+
if (!ignoreMetadata) {
763+
if (imageMetadata.comments == null) {
764+
imageMetadata.comments = new ArrayList<>();
765+
}
766+
imageMetadata.comments.add(comment);
751767
}
752-
imageMetadata.comments.add(comment);
753768
} else if (label == 0xff) { // Application extension
754769
int blockSize = stream.readUnsignedByte();
770+
int offset = 0;
771+
byte[] blockData = new byte[0];
755772
byte[] applicationID = new byte[8];
756773
byte[] authCode = new byte[3];
757-
758-
// read available data
759-
byte[] blockData = new byte[blockSize];
760-
stream.readFully(blockData);
761-
762-
int offset = copyData(blockData, 0, applicationID);
763-
offset = copyData(blockData, offset, authCode);
774+
if (!ignoreMetadata) {
775+
// read available data
776+
blockData =
777+
ReaderUtil.staggeredReadByteStream(stream,
778+
blockSize);
779+
780+
offset =
781+
copyData(blockData, 0, applicationID);
782+
offset = copyData(blockData, offset, authCode);
783+
} else {
784+
stream.skipBytes(blockSize);
785+
}
764786

765787
byte[] applicationData = concatenateBlocks();
766788

767-
if (offset < blockSize) {
789+
if (!ignoreMetadata &&
790+
offset < blockSize) {
768791
int len = blockSize - offset;
769792
byte[] data =
770793
new byte[len + applicationData.length];
771794

772-
System.arraycopy(blockData, offset, data, 0, len);
773-
System.arraycopy(applicationData, 0, data, len,
795+
System.arraycopy(blockData, offset,
796+
data, 0, len);
797+
System.arraycopy(applicationData, 0,
798+
data, len,
774799
applicationData.length);
775800

776801
applicationData = data;
777802
}
778803

779-
// Init lists if necessary
780-
if (imageMetadata.applicationIDs == null) {
781-
imageMetadata.applicationIDs = new ArrayList<>();
782-
imageMetadata.authenticationCodes =
783-
new ArrayList<>();
784-
imageMetadata.applicationData = new ArrayList<>();
804+
if (!ignoreMetadata) {
805+
// Init lists if necessary
806+
if (imageMetadata.applicationIDs == null) {
807+
imageMetadata.applicationIDs =
808+
new ArrayList<>();
809+
imageMetadata.authenticationCodes =
810+
new ArrayList<>();
811+
imageMetadata.applicationData =
812+
new ArrayList<>();
813+
}
814+
imageMetadata.applicationIDs.add(applicationID);
815+
imageMetadata.authenticationCodes.add(authCode);
816+
imageMetadata.applicationData.add(applicationData);
785817
}
786-
imageMetadata.applicationIDs.add(applicationID);
787-
imageMetadata.authenticationCodes.add(authCode);
788-
imageMetadata.applicationData.add(applicationData);
789818
} else {
790819
// Skip over unknown extension blocks
791820
int length = 0;

0 commit comments

Comments
 (0)
Please sign in to comment.