Skip to content

THRIFT-6055: Limit recursion depth in JavaME struct/exception read/write#3560

Open
Jens-G wants to merge 1 commit into
apache:masterfrom
Jens-G:javame-recursion-depth
Open

THRIFT-6055: Limit recursion depth in JavaME struct/exception read/write#3560
Jens-G wants to merge 1 commit into
apache:masterfrom
Jens-G:javame-recursion-depth

Conversation

@Jens-G
Copy link
Copy Markdown
Member

@Jens-G Jens-G commented May 28, 2026

THRIFT-6055: Limit recursion depth in the JavaME library

Change

Adds a recursionDepth_ counter (incrementRecursionDepth/decrementRecursionDepth) to TProtocol, bounded at 64, plus a DEPTH_LIMIT type on TProtocolException; the JavaME generator brackets each generated struct read/write body with try/finally. Previously the generated read()/write() path had no limit. Exceptions are generated through the same path, so they are bounded too.

Test

A generated-code round-trip regression test (lib/javame/test/TestRecursionDepth.java) over the binary and JSON protocols: chains at the limit round-trip; chains one past it (write and read) are rejected with DEPTH_LIMIT; a wide structure confirms the counter is decremented per sibling; a cyclic graph is rejected; and a recursive exception round-trips at the limit and is rejected one past it on both write and read. The over-limit read payload is hand-serialized through the real recursive field (id 1, type STRUCT) so the reader recurses through the guarded path rather than the (unbounded) skip().

Note on unions

The recursive types come from a JavaME-local test/RecursionDepth.thrift rather than the shared test/Recursive.thrift. The shared file also defines a recursive union and a service, and JavaME has no TUnion runtime class — a generated union does not even compile (javac: cannot find symbol: class TUnion). Unions are therefore unsupported in JavaME independently of this change; structs and exceptions are what the guard can (and now demonstrably does) cover.

JavaME has no build harness/CI; validated locally under OpenJDK 17 (compile lib/javame/src minus THttpClient.java + gen-javame + the test): 18/18 checks pass. skip() (TProtocolUtil.maxSkipDepth) stays separately unbounded as before.

🤖 Generated with Claude Code

@Jens-G Jens-G requested review from fishy and mhlakhani as code owners May 28, 2026 11:47
@mergeable mergeable Bot added java Pull requests that update Java code compiler labels May 28, 2026
@Jens-G Jens-G marked this pull request as draft May 28, 2026 22:45
@Jens-G Jens-G force-pushed the javame-recursion-depth branch from ba1349e to 307d156 Compare May 30, 2026 11:22
@Jens-G Jens-G changed the title THRIFT-6055: Limit struct read/write recursion depth in JavaME library THRIFT-6055: Limit recursion depth in JavaME struct read/write May 30, 2026
@Jens-G Jens-G marked this pull request as ready for review May 30, 2026 11:22
@Jens-G Jens-G force-pushed the javame-recursion-depth branch from 307d156 to 982b0ee Compare May 30, 2026 11:26
Client: javame

Add a recursionDepth_ counter with incrementRecursionDepth() and
decrementRecursionDepth() to TProtocol, bounded at 64, plus a DEPTH_LIMIT
type on TProtocolException, and update the JavaME generator to bracket each
generated struct read/write body with try/finally so the counter is always
restored. This bounds the work performed for deeply nested or cyclic
structs, which previously had no limit in the generated read()/write() path.
Exceptions are generated through the same read/write path, so they are
bounded too.

Add a generated-code round-trip regression test
(lib/javame/test/TestRecursionDepth.java) over the binary and JSON
protocols: chains at the limit round-trip, chains one past it (write and
read) are rejected with DEPTH_LIMIT, a wide structure confirms the counter
is decremented for each sibling, a cyclic graph is rejected, and a recursive
exception round-trips at the limit and is rejected one past it on both write
and read.

The recursive types come from a JavaME-local test/RecursionDepth.thrift
rather than the shared test/Recursive.thrift: the shared file also defines a
recursive union and a service, and JavaME has no TUnion runtime class, so a
generated union does not even compile (javac: "cannot find symbol: class
TUnion"). Unions are therefore unsupported in JavaME independently of this
change; structs and exceptions are what the guard can and does cover.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
@Jens-G Jens-G force-pushed the javame-recursion-depth branch from 982b0ee to 82b8dde Compare June 1, 2026 18:42
@Jens-G Jens-G changed the title THRIFT-6055: Limit recursion depth in JavaME struct read/write THRIFT-6055: Limit recursion depth in JavaME struct/exception read/write Jun 1, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

compiler java Pull requests that update Java code

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant