You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@commons.apache.org by ki...@apache.org on 2021/05/09 04:36:42 UTC

[commons-imaging] branch master updated: [IMAGING-302] Throw ImageReadException if the JPEG parser is given an image with a negative number of segments in SOF0Segment

This is an automated email from the ASF dual-hosted git repository.

kinow pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/commons-imaging.git


The following commit(s) were added to refs/heads/master by this push:
     new 197ed25  [IMAGING-302] Throw ImageReadException if the JPEG parser is given an image with a negative number of segments in SOF0Segment
     new f9043c5  Merge pull request #147 from kinow/IMAGING-302
197ed25 is described below

commit 197ed2560bdaaa7cea31b064557220673e65bbd7
Author: Bruno P. Kinoshita <ki...@apache.org>
AuthorDate: Sun May 9 15:52:40 2021 +1200

    [IMAGING-302] Throw ImageReadException if the JPEG parser is given an image with a negative number of segments in SOF0Segment
---
 src/changes/changes.xml                            |   3 +++
 .../imaging/formats/jpeg/segments/SofnSegment.java |   8 +++++--
 .../commons/imaging/formats/jpeg/JpegReadTest.java |  24 +++++++++++++++++++++
 ...se-minimized-ImagingJpegFuzzer-4548690447564800 | Bin 0 -> 12 bytes
 4 files changed, 33 insertions(+), 2 deletions(-)

diff --git a/src/changes/changes.xml b/src/changes/changes.xml
index a0ed065..b8881d0 100644
--- a/src/changes/changes.xml
+++ b/src/changes/changes.xml
@@ -129,6 +129,9 @@ The <action> type attribute can be add,update,fix,remove.
       <action issue="IMAGING-301" dev="kinow" type="update" due-to="OSS-Fuzz">
         Throw ImageReadException if the GIF parser is given an image with invalid Lzw table instead of throwing IndexOutOfBoundsException.
       </action>
+      <action issue="IMAGING-302" dev="kinow" type="update" due-to="OSS-Fuzz">
+        Throw ImageReadException if the JPEG parser is given an image with a negative number of segments in SOF0Segment.
+      </action>
     </release>
     <release version="1.0-alpha2" date="2020-08-01" description="Second 1.0 alpha release">
       <action issue="IMAGING-258" dev="kinow" type="update" due-to="Gary Lucas">
diff --git a/src/main/java/org/apache/commons/imaging/formats/jpeg/segments/SofnSegment.java b/src/main/java/org/apache/commons/imaging/formats/jpeg/segments/SofnSegment.java
index df319ca..748c868 100644
--- a/src/main/java/org/apache/commons/imaging/formats/jpeg/segments/SofnSegment.java
+++ b/src/main/java/org/apache/commons/imaging/formats/jpeg/segments/SofnSegment.java
@@ -25,6 +25,7 @@ import java.io.InputStream;
 import java.util.logging.Level;
 import java.util.logging.Logger;
 
+import org.apache.commons.imaging.ImageReadException;
 import org.apache.commons.imaging.formats.jpeg.JpegConstants;
 
 public class SofnSegment extends Segment {
@@ -52,12 +53,12 @@ public class SofnSegment extends Segment {
         }
     }
 
-    public SofnSegment(final int marker, final byte[] segmentData) throws IOException {
+    public SofnSegment(final int marker, final byte[] segmentData) throws IOException, ImageReadException {
         this(marker, segmentData.length, new ByteArrayInputStream(segmentData));
     }
 
     public SofnSegment(final int marker, final int markerLength, final InputStream is)
-            throws IOException {
+            throws IOException, ImageReadException {
         super(marker, markerLength);
 
         if (LOGGER.isLoggable(Level.FINEST)) {
@@ -69,6 +70,9 @@ public class SofnSegment extends Segment {
         width = read2Bytes("Image_Width", is, "Not a Valid JPEG File", getByteOrder());
         numberOfComponents = readByte("Number_of_components", is,
                 "Not a Valid JPEG File");
+        if (numberOfComponents < 0) {
+            throw new ImageReadException("The number of components in a SOF0Segment cannot be less than 0!");
+        }
         components = new Component[numberOfComponents];
         for (int i = 0; i < numberOfComponents; i++) {
             final int componentIdentifier = readByte("ComponentIdentifier", is,
diff --git a/src/test/java/org/apache/commons/imaging/formats/jpeg/JpegReadTest.java b/src/test/java/org/apache/commons/imaging/formats/jpeg/JpegReadTest.java
index cbab4a3..20b221e 100644
--- a/src/test/java/org/apache/commons/imaging/formats/jpeg/JpegReadTest.java
+++ b/src/test/java/org/apache/commons/imaging/formats/jpeg/JpegReadTest.java
@@ -19,9 +19,12 @@ package org.apache.commons.imaging.formats.jpeg;
 
 import static org.junit.jupiter.api.Assertions.assertEquals;
 import static org.junit.jupiter.api.Assertions.assertNotNull;
+import static org.junit.jupiter.api.Assertions.assertThrows;
 
 import java.awt.image.BufferedImage;
 import java.io.File;
+import java.io.IOException;
+import java.util.Collections;
 import java.util.HashMap;
 import java.util.Map;
 import java.util.stream.Stream;
@@ -31,7 +34,9 @@ import org.apache.commons.imaging.ImageReadException;
 import org.apache.commons.imaging.Imaging;
 import org.apache.commons.imaging.ImagingConstants;
 import org.apache.commons.imaging.common.ImageMetadata;
+import org.apache.commons.imaging.common.bytesource.ByteSourceFile;
 import org.apache.commons.imaging.internal.Debug;
+import org.junit.jupiter.api.Test;
 import org.junit.jupiter.params.ParameterizedTest;
 import org.junit.jupiter.params.provider.MethodSource;
 
@@ -67,4 +72,23 @@ public class JpegReadTest extends JpegBaseTest {
         }
     }
 
+    /**
+     * The JPEG image data may contain a negative number of segments,
+     * in which case the parser could throw a NegativeArraySizeException.
+     *
+     * <p>This test case verifies that we are handling that scenario, and
+     * throwing an ImageReadException instead.</p>
+     *
+     * <p>See Google OSS Fuzz issue 33458</p>
+     *
+     * @throws IOException if it fails to read the test image
+     */
+    @Test
+    public void testUncaughtExceptionOssFuzz33458() throws IOException {
+        final String input = "/images/jpeg/oss-fuzz-33458/clusterfuzz-testcase-minimized-ImagingJpegFuzzer-4548690447564800";
+        final String file = JpegReadTest.class.getResource(input).getFile();
+        final JpegImageParser parser = new JpegImageParser();
+        assertThrows(ImageReadException.class, () -> parser.getBufferedImage(new ByteSourceFile(new File(file)), Collections.emptyMap()));
+    }
+
 }
diff --git a/src/test/resources/images/jpeg/oss-fuzz-33458/clusterfuzz-testcase-minimized-ImagingJpegFuzzer-4548690447564800 b/src/test/resources/images/jpeg/oss-fuzz-33458/clusterfuzz-testcase-minimized-ImagingJpegFuzzer-4548690447564800
new file mode 100644
index 0000000..6c1dad1
Binary files /dev/null and b/src/test/resources/images/jpeg/oss-fuzz-33458/clusterfuzz-testcase-minimized-ImagingJpegFuzzer-4548690447564800 differ