-
Notifications
You must be signed in to change notification settings - Fork 24
Add an optional cap on the size of a spilled stream #729
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -40,6 +40,32 @@ public abstract class SeekableInputStream extends ASInputStream implements BaseP | |
|
|
||
| private static final int MAX_BUFFER_SIZE = 10240; | ||
|
|
||
| /** | ||
| * Optional hard cap, in bytes, on the size of a single stream that is spilled to a temporary file | ||
| * ({@code null} means no cap). It guards against a small input whose decoded content expands without | ||
| * bound (a "decompression bomb"): a stream that exceeds the cap is rejected with a | ||
| * {@link org.verapdf.exceptions.VeraPDFParserException} instead of being written out in full. The | ||
| * limit is wired into {@link #getSeekableStream(InputStream)}, which is the path taken by decoded | ||
| * object streams and other non-seekable input. Default {@code null}, so behaviour is unchanged. | ||
| */ | ||
| private static volatile Integer maxStreamSize = null; | ||
|
|
||
| /** | ||
| * Sets the hard cap in bytes for a single spilled stream. A non-positive value removes the cap. | ||
| * | ||
| * @param bytes maximum stream size in bytes, or a non-positive value to remove the cap | ||
| */ | ||
| public static void setMaxStreamSize(int bytes) { | ||
| maxStreamSize = bytes > 0 ? bytes : null; | ||
| } | ||
|
|
||
| /** | ||
| * @return the current spilled-stream cap in bytes, or {@code null} if no cap is set | ||
| */ | ||
| public static Integer getMaxStreamSize() { | ||
| return maxStreamSize; | ||
| } | ||
|
|
||
| /** | ||
| * Goes to a particular byte in stream. | ||
| * | ||
|
|
@@ -170,7 +196,7 @@ public static SeekableInputStream getSeekableStream(InputStream stream) throws I | |
| seekableStream.seekFromEnd(0); | ||
| return result; | ||
| } | ||
| return getSeekableStream(stream, null); | ||
| return getSeekableStream(stream, maxStreamSize); | ||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 🩺 Stability & Availability | 🟠 Major | ⚡ Quick win 🔎 Supported by static analysis🏁 Script executed: sed -n '190,255p' src/main/java/org/verapdf/io/SeekableInputStream.java
sed -n '105,130p;275,315p' src/main/java/org/verapdf/io/InternalInputStream.javaRepository: veraPDF/veraPDF-parser Length of output: 3724 🏁 Script executed: #!/bin/bash
printf '%s\n' '--- focused declarations ---'
rg -n -A18 -B8 'setMaxStreamSize|getMaxStreamSize|MAX_BUFFER_SIZE|maxStreamSize' src/main/java/org/verapdf/io/SeekableInputStream.java
printf '%s\n' '--- base to reviewed head relevant diff ---'
git diff --unified=25 d3a8571d0aac2d97c52844131d404ead74ff3e9d c68e37cc46feece77eee75048fca0a6ebb823460 -- src/main/java/org/verapdf/io/SeekableInputStream.java src/main/java/org/verapdf/io/InternalInputStream.javaRepository: veraPDF/veraPDF-parser Length of output: 9130 Use a non-overflowing counter in When Fixing only the initial threshold does not fix this spill-copy counter. Suggested fix- int totalRead = alreadyRead.length;
+ long totalRead = alreadyRead.length;🤖 Prompt for AI Agents |
||
| } | ||
|
|
||
| public static SeekableInputStream getSeekableStream(InputStream stream, Integer maxStreamSize) throws IOException { | ||
|
|
||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🎯 Functional Correctness | 🟡 Minor | ⚡ Quick win
Handle
Integer.MAX_VALUEwithout overflowing the read threshold.If a caller sets the cap to
Integer.MAX_VALUE, the overload computesmaxStreamSize + 1as a negativeint. It then skips the initial read loop and selectsInternalInputStreameven for a short input. Keep the threshold calculation within range so a large cap preserves the normal stream-selection behavior.🤖 Prompt for AI Agents