Author: tilman
Date: Sat Sep 12 10:30:40 2026
New Revision: 1938143

Log:
PDFBOX-5660: increase chunk-size cap for large streams, by Valery Bokov; closes 
#528

Modified:
   pdfbox/branches/3.0/pdfbox/src/main/java/org/apache/pdfbox/filter/Filter.java

Modified: 
pdfbox/branches/3.0/pdfbox/src/main/java/org/apache/pdfbox/filter/Filter.java
==============================================================================
--- 
pdfbox/branches/3.0/pdfbox/src/main/java/org/apache/pdfbox/filter/Filter.java   
    Sat Sep 12 08:30:27 2026        (r1938142)
+++ 
pdfbox/branches/3.0/pdfbox/src/main/java/org/apache/pdfbox/filter/Filter.java   
    Sat Sep 12 10:30:40 2026        (r1938143)
@@ -268,7 +268,7 @@ public abstract class Filter
         }
         InputStream input = encoded;
         RandomAccessReadWriteBuffer randomAccessWriteBuffer = null;
-        OutputStream output = null;
+        OutputStream output;
         // apply filters
         for (int i = 0; i < filterList.size(); i++)
         {
@@ -279,14 +279,20 @@ public abstract class Filter
                 length = randomAccessWriteBuffer.length();
             }
             // we don't know the size of the decoded stream, just estimate a 4 
times bigger size than the encoded stream
-            // use the estimated stream size as chunk size, use the default 
chunk size as limit to avoid to big values
-            if (length <= 0 || length >= 
RandomAccessReadBuffer.DEFAULT_CHUNK_SIZE_4KB / 4)
+            // use the estimated stream size as chunk size, capped to avoid 
excessive per-chunk
+            // preallocation, but without collapsing back to the tiny default 
for large streams -
+            // that would otherwise force thousands of small chunk allocations
+            if (length <= 0)
             {
                 length = RandomAccessReadBuffer.DEFAULT_CHUNK_SIZE_4KB;
             }
             else
             {
-                length = length * 4;
+                // upper bound for the chunk size estimated from the encoded 
stream length in decode(), to
+                // avoid thousands of small chunk allocations for large 
streams while still bounding the
+                // worst-case preallocation for a single chunk
+                final int maxEstimatedChunkSize = 1 << 20;
+                length = Math.min(length, maxEstimatedChunkSize / 4) * 4;
             }
             randomAccessWriteBuffer = new RandomAccessReadWriteBuffer((int) 
length);
             output = new RandomAccessOutputStream(randomAccessWriteBuffer);

Reply via email to