Files
struts/plugins
ⳕⲛτⲉⲅⲥⲉⳏτⲟⲅ 🕵🏻 75a285a106 WW-5643 fix(json): confine StrutsJSONReader parse state to the parsing thread (#1775)
* fix(json): confine StrutsJSONReader parse state to the parsing thread

JSONInterceptor obtains its JSONReader once via @Inject and reuses that
same instance across every concurrent request handled by that
interceptor. StrutsJSONReader kept its parse cursor, token buffer and
nesting-depth counter (used to enforce maxDepth/maxElements/
maxStringLength/maxKeyLength) as plain instance fields, so two
concurrent read() calls on the same instance tore each other's state:
one request's depth counter could be decremented by an unrelated
concurrent request finishing its own parse, letting payloads deeper
than the configured maxDepth through, and the shared character cursor
and string/number buffer let fragments of one request's JSON body leak
into a different, concurrently-parsed request's result.

Move the cursor, current character, token, buffer and depth into a
ParseState confined to a ThreadLocal, scoped to a single read() call.
Method signatures and behavior are otherwise unchanged so existing
StrutsJSONReader subclasses keep working; the limit fields
(maxElements/maxDepth/maxStringLength/maxKeyLength) stay as plain
instance fields since they are set to the same value on every call for
a given interceptor configuration and are safe to share.

* test(json): raise reader concurrency test to 16 threads for reliable repro

Verified independently that the 2-thread version can miss the race on
machines with more cores than contending threads (with no CPU
contention, the OS scheduler has no need to preempt either thread
mid-call, so the corruption window is rarely hit): 0 reproductions in
8 reruns against unpatched code on a 10-core machine. Sixteen threads
reproduced both symptoms reliably against unpatched StrutsJSONReader
(81 cross-thread data leaks and 79 maxDepth bypasses out of 160,000
attempts), and confirmed zero of either against the fix under the
same load. Combined the two prior tests into one, since both symptoms
come from the same shared parse state and are naturally checked
together per thread.

---------

Co-authored-by: g0w6y <g0w6y@users.noreply.github.com>
2026-07-14 08:48:46 +02:00
..
2026-06-26 07:18:26 +02:00
2026-06-26 07:18:26 +02:00
2026-06-26 07:18:26 +02:00
2026-06-26 07:18:26 +02:00
2026-06-26 07:18:26 +02:00
2026-06-26 07:18:26 +02:00
2026-06-26 07:18:26 +02:00
2026-06-26 07:18:26 +02:00
2026-06-26 07:18:26 +02:00
2026-06-26 07:18:26 +02:00
2026-06-26 07:18:26 +02:00
2026-06-26 07:18:26 +02:00
2026-06-26 07:18:26 +02:00
2026-06-26 07:18:26 +02:00
2026-06-26 07:18:26 +02:00
2026-06-26 07:18:26 +02:00

Struts 2 Plugins

A set of officially supported plugins which are provided with the framework, you can read more about them in the documentation.