7058607: GIF parser bugs found via zzuf fuzzing
authorbae
Mon, 14 Oct 2013 15:49:05 +0400
changeset 21222 69edb4f345a3
parent 21221 d80929154039
child 21223 daef7d30537c
7058607: GIF parser bugs found via zzuf fuzzing Reviewed-by: prr, vadim
jdk/src/share/classes/com/sun/imageio/plugins/gif/GIFImageReader.java
--- a/jdk/src/share/classes/com/sun/imageio/plugins/gif/GIFImageReader.java	Mon Oct 14 15:32:29 2013 +0400
+++ b/jdk/src/share/classes/com/sun/imageio/plugins/gif/GIFImageReader.java	Mon Oct 14 15:49:05 2013 +0400
@@ -115,6 +115,8 @@
     // The current interlace pass, starting with 0.
     int interlacePass = 0;
 
+    private byte[] fallbackColorTable = null;
+
     // End per-stream settings
 
     // Constants used to control interlacing.
@@ -239,10 +241,22 @@
         byte[] colorTable;
         if (imageMetadata.localColorTable != null) {
             colorTable = imageMetadata.localColorTable;
+            fallbackColorTable = imageMetadata.localColorTable;
         } else {
             colorTable = streamMetadata.globalColorTable;
         }
 
+        if (colorTable == null) {
+            if (fallbackColorTable == null) {
+                this.processWarningOccurred("Use default color table.");
+
+                // no color table, the spec allows to use any palette.
+                fallbackColorTable = getDefaultPalette();
+            }
+
+            colorTable = fallbackColorTable;
+        }
+
         // Normalize color table length to 2^1, 2^2, 2^4, or 2^8
         int length = colorTable.length/3;
         int bits;
@@ -1036,5 +1050,34 @@
         streamY = -1;
         rowsDone = 0;
         interlacePass = 0;
+
+        fallbackColorTable = null;
+    }
+
+    private static byte[] defaultPalette = null;
+
+    private static synchronized byte[] getDefaultPalette() {
+        if (defaultPalette == null) {
+            BufferedImage img = new BufferedImage(1, 1,
+                    BufferedImage.TYPE_BYTE_INDEXED);
+            IndexColorModel icm = (IndexColorModel) img.getColorModel();
+
+            final int size = icm.getMapSize();
+            byte[] r = new byte[size];
+            byte[] g = new byte[size];
+            byte[] b = new byte[size];
+            icm.getReds(r);
+            icm.getGreens(g);
+            icm.getBlues(b);
+
+            defaultPalette = new byte[size * 3];
+
+            for (int i = 0; i < size; i++) {
+                defaultPalette[3 * i + 0] = r[i];
+                defaultPalette[3 * i + 1] = g[i];
+                defaultPalette[3 * i + 2] = b[i];
+            }
+        }
+        return defaultPalette;
     }
 }