Jens-G opened a new pull request, #3950:
URL: https://github.com/apache/thrift/pull/3950

   [THRIFT-6366](https://issues.apache.org/jira/browse/THRIFT-6366)
   
   `thrift_binary_protocol` and `thrift_compact_protocol` read a string or 
binary with whatever length its header declares, and nothing bounded the size 
of a message as a whole. This PR applies the library's `max_message_size` 
setting (THRIFT-6283, 100 MB by default) to both protocols.
   
   **Change**
   - Both protocols read a message only up to `max_message_size`. That is the 
`max_message_size` option of `new/2` or of the protocol factory, or else the 
thrift application's setting as it is when the protocol is created.
   - Every read takes its bytes from what the message may still take, before 
they are read. A string whose declared length would take the message past the 
maximum is refused on its length alone.
   - `message_begin` sets that budget and `message_end` clears it. Between 
messages each read is held to the maximum on its own, so structs read without a 
message around them do not add up.
   - A refusal is `{error, {message_size_exceeds_maximum, Max}}`:
     - `message_begin` now returns it, and a failed name read no longer fails a 
match.
     - Inside a message it fails the read the way other read errors do, and the 
server closes that connection.
   - `thrift_client_util` passes a `max_message_size` client option on to the 
protocol, and the binary, compact and JSON protocol factories accept it. 
`thrift_socket_server` takes only atom protocols, so a server uses the 
application setting.
   - There is no separate check of container counts: every element takes at 
least one byte of the budget.
   
   **Behaviour change:** a message over 100 MB was accepted before and is now 
refused, unless the setting is raised. The ticket carries the Breaking-Change 
label.
   
   **Tests:** `lib/erl/test/test_thrift_max_message_size.erl` covers binary 
(with and without the version header) and compact.
   - A call at the maximum is read, and one a byte over it is refused.
   - A string past the maximum is refused before its bytes are read, counting 
the bytes taken from the transport.
   - An overlong message name is refused by `message_begin`.
   - Each message gets the whole maximum, and structs read outside a message do 
not add up.
   - Both the application setting and the option apply.
   - Over a socket, the server refuses an oversized call and keeps serving, and 
a client with the option refuses an oversized reply.
   
   On the base commit, 15 of these tests fail. With the change, the full suite 
(449 tests) passes on OTP 25 (rebar3 3.18), 27 and 28. `rebar3 fmt -c` passes 
on the changed files except `thrift_binary_protocol.erl`, which already fails 
it on master with two older `if` one-liners. Those lines are left as they are.
   
   - [x] Did you create an [Apache 
Jira](https://issues.apache.org/jira/projects/THRIFT/issues/) ticket? 
THRIFT-6366
   - [x] If a ticket exists: Does your pull request title follow the pattern 
"THRIFT-NNNN: describe my issue"?
   - [x] Did you squash your changes to a single commit?
   - [x] Did you do your best to avoid breaking changes? If one was needed, did 
you label the Jira ticket with "Breaking-Change"? It is labelled.
   
   🤖 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]

Reply via email to