Jens-G opened a new pull request, #3784:
URL: https://github.com/apache/thrift/pull/3784
`TAsyncMethodCall` sizes the response frame from the four bytes the peer
sends ahead of it, with no check of any kind:
```java
if (sizeBuffer.remaining() == 0) {
state = State.READING_RESPONSE_BODY;
frameBuffer =
ByteBuffer.allocate(TFramedTransport.decodeFrameSize(sizeBufferArray));
}
```
`decodeFrameSize` returns a signed `int`, so the peer picks anything from
`-2147483648` to `2147483647` and `ByteBuffer.allocate` is handed it. A
negative one raises `IllegalArgumentException` — not a `TTransportException` —
which reaches the callback as it is; a large positive one is allocated, and
`ByteBuffer.allocate` zeroes the array, so the memory is resident rather than
reserved.
### It is the odd one out
`lib/java` reads a frame size in four places. Three of them are guarded:
| | negative | over `maxFrameSize` | other |
|---|---|---|---|
| `TFramedTransport.readFrame` | ✅ | ✅ | |
| `TFastFramedTransport.readFrame` | ✅ | ✅ | |
| `AbstractNonblockingServer.FrameBuffer` | ✅ (`<= 0`) | ✅ | also defers
past `MAX_READ_BUFFER_BYTES` |
| `TAsyncMethodCall.doReadingResponseSize` | ❌ | ❌ | |
This applies the same two checks, with the same messages, so the two ways of
reading a framed response agree.
### Compatibility — worth a release note
`maxFrameSize` defaults to 16384000, so an async client now refuses a
response frame larger than that where it used to allocate it.
`TNonblockingTransport.setMaxFrameSize` raises the bound with it.
### Tests
`TestTAsyncMethodCallFrameSize` drives a real `TAsyncMethodCall` against a
socket that answers with a frame size and no body. The assertions are about the
buffer that was allocated, not merely that the call failed — a response body
that never arrives ends the call either way, so *"did it fail?"* passes on the
unmodified library too.
Two fail before the change:
```
allocated 65536 for a frame that is over the maximum
a negative size reached ByteBuffer.allocate:
java.lang.IllegalArgumentException: capacity < 0: (-1 < 0)
```
The third reads a frame of exactly the maximum end to end and passes either
way.
Full `gradle test spotlessCheck`: BUILD SUCCESSFUL.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
--
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
To unsubscribe, e-mail: [email protected]
For queries about this service, please contact Infrastructure at:
[email protected]