Author: tilman
Date: Fri Apr 10 11:54:27 2026
New Revision: 1932958
Log:
PDFBOX-6189: Safely validate dimension to avoid OOM, by subbudvk; closes #437
Modified:
pdfbox/trunk/pdfbox/src/main/java/org/apache/pdfbox/filter/CCITTFaxFilter.java
pdfbox/trunk/pdfbox/src/main/java/org/apache/pdfbox/filter/Filter.java
Modified:
pdfbox/trunk/pdfbox/src/main/java/org/apache/pdfbox/filter/CCITTFaxFilter.java
==============================================================================
---
pdfbox/trunk/pdfbox/src/main/java/org/apache/pdfbox/filter/CCITTFaxFilter.java
Fri Apr 10 11:33:29 2026 (r1932957)
+++
pdfbox/trunk/pdfbox/src/main/java/org/apache/pdfbox/filter/CCITTFaxFilter.java
Fri Apr 10 11:54:27 2026 (r1932958)
@@ -59,8 +59,43 @@ final class CCITTFaxFilter extends Filte
// decompress data
int k = decodeParms.getInt(COSName.K, 0);
boolean encodedByteAlign =
decodeParms.getBoolean(COSName.ENCODED_BYTE_ALIGN, false);
- int arraySize = (cols + 7) / 8 * rows;
- // TODO possible options??
+ if (cols <= 0 || rows <= 0)
+ {
+ throw new IOException("Invalid CCITT image dimensions: cols=" +
cols + ", rows=" + rows);
+ }
+
+ long arraySizeLong = ((long) cols + 7) / 8 * rows;
+
+ long maxBytes = 256 * 1024 * 1024L;
+ String sysProp = System.getProperty(Filter.SYSPROP_CCITTFAX_MAXBYTES);
+
+ if (sysProp != null)
+ {
+ try
+ {
+ long parsed = Long.parseLong(sysProp);
+ if (parsed > 0)
+ {
+ maxBytes = parsed;
+ }
+ // else ignore zero/negative values
+ }
+ catch (NumberFormatException e)
+ {
+ // ignore invalid value, keep default
+ }
+ }
+
+ if (arraySizeLong > maxBytes)
+ {
+ throw new IOException(
+ "CCITT decode buffer too large (" + arraySizeLong + " bytes)
for cols=" + cols +
+ ", rows=" + rows + "; max allowed=" + maxBytes +
+ "; increase " + Filter.SYSPROP_CCITTFAX_MAXBYTES + " to
override"
+ );
+ }
+
+ int arraySize = (int) arraySizeLong;
byte[] decompressed = new byte[arraySize];
CCITTFaxDecoderStream s;
int type;
Modified: pdfbox/trunk/pdfbox/src/main/java/org/apache/pdfbox/filter/Filter.java
==============================================================================
--- pdfbox/trunk/pdfbox/src/main/java/org/apache/pdfbox/filter/Filter.java
Fri Apr 10 11:33:29 2026 (r1932957)
+++ pdfbox/trunk/pdfbox/src/main/java/org/apache/pdfbox/filter/Filter.java
Fri Apr 10 11:54:27 2026 (r1932958)
@@ -61,6 +61,16 @@ public abstract class Filter
public static final String SYSPROP_DEFLATELEVEL =
"org.apache.pdfbox.filter.deflatelevel";
/**
+ * CCITTFax decode buffer size cap System Property. Sets the maximum
number of bytes that
+ * CCITTFaxFilter is allowed to pre-allocate for a single image decode
buffer. PDF-controlled
+ * /Columns and /Rows values are validated against this limit before
allocation to prevent
+ * denial-of-service via crafted image dimensions. The default is 256 MB.
To raise the cap for
+ * high-resolution legitimate documents, use
+ * {@code System.setProperty(Filter.SYSPROP_CCITTFAX_MAXBYTES,
String.valueOf(512 * 1024 * 1024L));}
+ */
+ public static final String SYSPROP_CCITTFAX_MAXBYTES =
"org.apache.pdfbox.filter.ccittmaxbytes";
+
+ /**
* Constructor.
*/
protected Filter()