Fix buffer limit in PlanB Filter - clear() missing after flip()#5548
Open
stroomworks4092 wants to merge 1 commit into
Open
Fix buffer limit in PlanB Filter - clear() missing after flip()#5548stroomworks4092 wants to merge 1 commit into
stroomworks4092 wants to merge 1 commit into
Conversation
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary of Changes
In stroom-planb/stroom-planb-impl/src/main/java/stroom/planb/impl/pipeline/PlanBFilter.java:
Why this was necessary
The stagingValueOutputStream (a ByteBufferPoolOutput) is reused for every XML fragment in the stream. When getByteBuffer() is called and then flip() is used to read the data, the buffer's limit is set to the current position
(the size of the data written).
Without a subsequent clear(), the buffer's limit remains restricted to that small size. When the stream is reset for the next fragment and more data is written, the underlying buffer's restricted limit eventually causes a
crash or failure because the stream expects to be able to use the full capacity of the buffer.
'
1 // Before
2 case XML -> {
3 final ByteBuffer value = stagingValueOutputStream.getByteBuffer();
4 value.flip();
5 yield ValXml.create(ByteBufferUtils.getBytes(value));
6 }
7
8 // After
9 case XML -> {
10 final ByteBuffer value = stagingValueOutputStream.getByteBuffer();
11 value.flip();
12 final Val val = ValXml.create(ByteBufferUtils.getBytes(value));
13 value.clear(); // Correctly resets the limit and position for reuse
14 yield val;
15 }
'
The data safety is guaranteed because ValXml.create(ByteBufferUtils.getBytes(value)) creates a complete copy of the bytes into a new byte[] array before the source buffer is cleared.
See https://docs.oracle.com/en/java/javase/25/docs/api/java.base/java/nio/ByteBuffer.html#flip() for details on flip() and clear().