Files
struts/plugins
ⳕⲛτⲉⲅⲥⲉⳏτⲟⲅ 🕵🏻 18955b98a4 WW-5644 fix(json): confine StrutsJSONWriter write state to the writing thread (#1776)
* fix(json): confine StrutsJSONWriter write state to the writing thread

JSONUtil obtains its JSONWriter once via @Inject and reuses that same
instance across every concurrent response handled by that JSONResult/
JSONInterceptor configuration. StrutsJSONWriter kept its output buffer,
cyclic-reference stack, root object, and expression-path state
(buf/stack/root/buildExpr/exprStack/excludeProperties/
includeProperties/excludeNullProperties) as plain instance fields, all
reset in place at the start of write().

Two concurrent write() calls on the same instance therefore race on
that reset: one call's in-progress buffer can be wiped and overwritten
by a second, unrelated concurrent call before the first call reads it
back via buf.toString(), so one request's serialized JSON can be
returned as a completely different, concurrently-served request's
response body.

Move buf/stack/root/buildExpr/exprStack/excludeProperties/
includeProperties/excludeNullProperties into a WriteState confined to
a ThreadLocal, scoped to a single write() call. Method signatures and
behavior are otherwise unchanged so existing StrutsJSONWriter
subclasses keep working; ignoreHierarchy/dateFormat/enumAsBean/
excludeProxyProperties stay as plain instance fields since they are
set to the same value on every call for a given writer configuration
and are safe to share.

* test(json): raise writer 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 it reliably (44,646/320,000 corrupted responses against
unpatched StrutsJSONWriter), and confirmed zero corruption against the
fix under the same load.

---------

Co-authored-by: g0w6y <g0w6y@users.noreply.github.com>
2026-07-14 08:49:07 +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.