You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@poi.apache.org by fa...@apache.org on 2022/03/12 13:57:51 UTC

svn commit: r1898876 - in /poi/trunk/poi/src: main/java/org/apache/poi/util/IOUtils.java test/java/org/apache/poi/util/TestIOUtils.java

Author: fanningpj
Date: Sat Mar 12 13:57:50 2022
New Revision: 1898876

URL: http://svn.apache.org/viewvc?rev=1898876&view=rev
Log:
handle case where toByteArray truncates stream because max len is less than stream len

Modified:
    poi/trunk/poi/src/main/java/org/apache/poi/util/IOUtils.java
    poi/trunk/poi/src/test/java/org/apache/poi/util/TestIOUtils.java

Modified: poi/trunk/poi/src/main/java/org/apache/poi/util/IOUtils.java
URL: http://svn.apache.org/viewvc/poi/trunk/poi/src/main/java/org/apache/poi/util/IOUtils.java?rev=1898876&r1=1898875&r2=1898876&view=diff
==============================================================================
--- poi/trunk/poi/src/main/java/org/apache/poi/util/IOUtils.java (original)
+++ poi/trunk/poi/src/main/java/org/apache/poi/util/IOUtils.java Sat Mar 12 13:57:50 2022
@@ -230,7 +230,7 @@ public final class IOUtils {
             checkLength(length, derivedMaxLength);
         }
 
-        final int derivedLen = Math.min(length, derivedMaxLength);
+        final int derivedLen = isLengthKnown ? Math.min(length, derivedMaxLength) : derivedMaxLength;
         final int byteArrayInitLen = calculateByteArrayInitLength(isLengthKnown, length, derivedMaxLength);
         final int internalBufferLen = DEFAULT_BUFFER_SIZE;
         try (UnsynchronizedByteArrayOutputStream baos = new UnsynchronizedByteArrayOutputStream(byteArrayInitLen)) {
@@ -242,18 +242,15 @@ public final class IOUtils {
                 if (readBytes > 0) {
                     baos.write(buffer, 0, readBytes);
                 }
-
                 checkByteSizeLimit(totalBytes);
             } while (totalBytes < derivedLen && readBytes > -1);
 
-            if (checkEOFException) {
-                if (derivedMaxLength != Integer.MAX_VALUE && totalBytes == derivedMaxLength) {
-                    throw new IOException("MaxLength (" + derivedMaxLength + ") reached - stream seems to be invalid.");
-                }
+            if (BYTE_ARRAY_MAX_OVERRIDE < 0 && readBytes > -1 && !isLengthKnown && stream.read() >= 0) {
+                throwRecordTruncationException(derivedMaxLength);
+            }
 
-                if (derivedLen != Integer.MAX_VALUE && totalBytes < derivedLen) {
-                    throw new EOFException("unexpected EOF - expected len: " + derivedLen + " - actual len: " + totalBytes);
-                }
+            if (checkEOFException && derivedLen != Integer.MAX_VALUE && totalBytes < derivedLen) {
+                throw new EOFException("unexpected EOF - expected len: " + derivedLen + " - actual len: " + totalBytes);
             }
 
             return baos.toByteArray();
@@ -586,7 +583,7 @@ public final class IOUtils {
      * Simple utility function to check that you haven't hit EOF
      * when reading a byte.
      *
-     * @param is inputstream to read
+     * @param is input stream to read
      * @return byte read, unless
      * @throws IOException on IOException or EOF if -1 is read
      */
@@ -608,4 +605,14 @@ public final class IOUtils {
                 length, maxLength));
 
     }
+
+    private static void throwRecordTruncationException(final int maxLength) {
+        throw new RecordFormatException(String.format(Locale.ROOT, "Tried to read data but the maximum length " +
+                "for this record type is %,d.\n" +
+                "If the file is not corrupt or large, please open an issue on bugzilla to request \n" +
+                "increasing the maximum allowable size for this record type.\n"+
+                "As a temporary workaround, consider setting a higher override value with " +
+                "IOUtils.setByteArrayMaxOverride()", maxLength));
+
+    }
 }

Modified: poi/trunk/poi/src/test/java/org/apache/poi/util/TestIOUtils.java
URL: http://svn.apache.org/viewvc/poi/trunk/poi/src/test/java/org/apache/poi/util/TestIOUtils.java?rev=1898876&r1=1898875&r2=1898876&view=diff
==============================================================================
--- poi/trunk/poi/src/test/java/org/apache/poi/util/TestIOUtils.java (original)
+++ poi/trunk/poi/src/test/java/org/apache/poi/util/TestIOUtils.java Sat Mar 12 13:57:50 2022
@@ -152,6 +152,30 @@ final class TestIOUtils {
     }
 
     @Test
+    void testToByteArrayMaxLengthWithByteArrayInitLenShort() throws IOException {
+        final byte[] array = new byte[]{1, 2, 3, 4, 5, 6, 7};
+        IOUtils.setMaxByteArrayInitSize(2);
+        try (ByteArrayInputStream is = new ByteArrayInputStream(array)) {
+            assertEquals(2, IOUtils.getMaxByteArrayInitSize());
+            assertArrayEquals(array, IOUtils.toByteArrayWithMaxLength(is, 7));
+        } finally {
+            IOUtils.setMaxByteArrayInitSize(-1);
+        }
+    }
+
+    @Test
+    void testToByteArrayMaxLengthWithByteArrayInitLenLong() throws IOException {
+        final byte[] array = new byte[]{1, 2, 3, 4, 5, 6, 7};
+        IOUtils.setMaxByteArrayInitSize(8192);
+        try (ByteArrayInputStream is = new ByteArrayInputStream(array)) {
+            assertEquals(8192, IOUtils.getMaxByteArrayInitSize());
+            assertArrayEquals(array, IOUtils.toByteArrayWithMaxLength(is, 7));
+        } finally {
+            IOUtils.setMaxByteArrayInitSize(-1);
+        }
+    }
+
+    @Test
     void testToByteArrayMaxLengthLongerThanArray() throws IOException {
         final byte[] array = new byte[]{1, 2, 3, 4, 5, 6, 7};
         try (ByteArrayInputStream is = new ByteArrayInputStream(array)) {
@@ -163,7 +187,18 @@ final class TestIOUtils {
     void testToByteArrayMaxLengthShorterThanArray() throws IOException {
         final byte[] array = new byte[]{1, 2, 3, 4, 5, 6, 7};
         try (ByteArrayInputStream is = new ByteArrayInputStream(array)) {
-            assertArrayEquals(new byte[]{1, 2, 3}, IOUtils.toByteArrayWithMaxLength(is, 3));
+            assertThrows(RecordFormatException.class, () -> IOUtils.toByteArrayWithMaxLength(is, 3));
+        }
+    }
+
+    @Test
+    void testToByteArrayMaxLengthShorterThanArrayWithByteArrayOverride() throws IOException {
+        final byte[] array = new byte[]{1, 2, 3, 4, 5, 6, 7};
+        IOUtils.setByteArrayMaxOverride(30 * 1024 * 1024);
+        try (ByteArrayInputStream is = new ByteArrayInputStream(array)) {
+            assertArrayEquals(array, IOUtils.toByteArrayWithMaxLength(is, 3));
+        } finally {
+            IOUtils.setByteArrayMaxOverride(-1);
         }
     }
 



---------------------------------------------------------------------
To unsubscribe, e-mail: commits-unsubscribe@poi.apache.org
For additional commands, e-mail: commits-help@poi.apache.org