From 3bf67857fcf70d9eea56eed4af7c925671e8eaea Mon Sep 17 00:00:00 2001
From: aidanchiu1112 <108113174+aidanchiu1112@users.noreply.github.com>
Date: Wed, 14 Jun 2023 10:49:52 -0700
Subject: [PATCH] Merge pull request from GHSA-qcwq-55hx-v3vh

* asserted chunksize should be in the bounds of 0-java.outofmmeoryexception

* asserted chunksize should be in the bounds of 0-java.outofmmeoryexception

* https://github.com/xerial/snappy-java-ghsa-qcwq-55hx-v3vh/pull/2

* advisory-fix-3

* added and changed method name for happy and sad cases in SnappyTest.java

* removed expected error for happy case in unit testing

* added another unit test case in SnappyTest.java and fixed comments in SnappyInputStream.java

* switched SnappyError to INVALID_CHUNK_SIZE

* Updated unit tests

Origin: https://github.com/xerial/snappy-java/commit/3bf67857fcf70d9eea56eed4af7c925671e8eaea

---
 .../org/xerial/snappy/SnappyInputStream.java  | 13 ++++-
 .../java/org/xerial/snappy/SnappyTest.java    | 47 +++++++++++++++++++
 2 files changed, 59 insertions(+), 1 deletion(-)

diff --git a/src/main/java/org/xerial/snappy/SnappyInputStream.java b/src/main/java/org/xerial/snappy/SnappyInputStream.java
index 19a68c6..f499c66 100755
--- a/src/main/java/org/xerial/snappy/SnappyInputStream.java
+++ b/src/main/java/org/xerial/snappy/SnappyInputStream.java
@@ -417,9 +417,20 @@ public class SnappyInputStream
             }
         }
 
+        // chunkSize is negative
+        if (chunkSize < 0) {
+            throw new SnappyError(SnappyErrorCode.INVALID_CHUNK_SIZE, "chunkSize is too big or negative : " + chunkSize);
+        }
+
         // extend the compressed data buffer size
         if (compressed == null || chunkSize > compressed.length) {
-            compressed = new byte[chunkSize];
+            // chunkSize exceeds limit
+            try {
+                compressed = new byte[chunkSize];
+            }
+            catch (java.lang.OutOfMemoryError e) {
+                throw new SnappyError(SnappyErrorCode.INVALID_CHUNK_SIZE, e.getMessage());
+            }
         }
         readBytes = 0;
         while (readBytes < chunkSize) {
diff --git a/src/test/java/org/xerial/snappy/SnappyTest.java b/src/test/java/org/xerial/snappy/SnappyTest.java
index 18b39e9..730dae9 100755
--- a/src/test/java/org/xerial/snappy/SnappyTest.java
+++ b/src/test/java/org/xerial/snappy/SnappyTest.java
@@ -26,6 +26,7 @@ package org.xerial.snappy;
 
 import static org.junit.Assert.*;
 
+import java.io.ByteArrayInputStream;
 import java.io.IOException;
 import java.nio.ByteBuffer;
 
@@ -329,4 +330,50 @@ public class SnappyTest
             _logger.debug(e);
         }
     }
+
+    /*
+    Tests happy cases for SnappyInputStream.read method
+    - {0}
+     */
+    @Test
+    public void isValidChunkLengthForSnappyInputStreamIn()
+            throws Exception {
+        byte[] data = {0};
+        SnappyInputStream in = new SnappyInputStream(new ByteArrayInputStream(data));
+        byte[] out = new byte[50];
+        in.read(out);
+    }
+
+    /*
+    Tests sad cases for SnappyInputStream.read method
+    - Expects a java.lang.NegativeArraySizeException catched into a SnappyError
+    - {-126, 'S', 'N', 'A', 'P', 'P', 'Y', 0, 0, 0, 0, 0, 0, 0, 0, 0,(byte) 0x7f, (byte) 0xff, (byte) 0xff, (byte) 0xff}
+     */
+    @Test(expected = SnappyError.class)
+    public void isInvalidChunkLengthForSnappyInputStreamInNegative()
+            throws Exception {
+        byte[] data = {-126, 'S', 'N', 'A', 'P', 'P', 'Y', 0, 0, 0, 0, 0, 0, 0, 0, 0,(byte) 0x7f, (byte) 0xff, (byte) 0xff, (byte) 0xff};
+        SnappyInputStream in = new SnappyInputStream(new ByteArrayInputStream(data));
+        byte[] out = new byte[50];
+        in.read(out);
+    }
+
+    /*
+    Tests sad cases for SnappyInputStream.read method
+    - Expects a java.lang.OutOfMemoryError
+    - {-126, 'S', 'N', 'A', 'P', 'P', 'Y', 0, 0, 0, 0, 0, 0, 0, 0, 0,(byte) 0x7f, (byte) 0xff, (byte) 0xff, (byte) 0xff}
+     */
+    @Test(expected = SnappyError.class)
+    public void isInvalidChunkLengthForSnappyInputStreamOutOfMemory()
+            throws Exception {
+        byte[] data = {-126, 'S', 'N', 'A', 'P', 'P', 'Y', 0, 0, 0, 0, 0, 0, 0, 0, 0, (byte) 0x7f, (byte) 0xff, (byte) 0xff, (byte) 0xff};
+        SnappyInputStream in = new SnappyInputStream(new ByteArrayInputStream(data));
+        byte[] out = new byte[50];
+        try {
+            in.read(out);
+        } catch (Exception ignored) {
+            // Exception here will be catched
+            // But OutOfMemoryError will not be caught, and will still be thrown
+        }
+    }
 }
-- 
2.33.0

