This is an automated email from the ASF dual-hosted git repository.

jamesbognar pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/juneau.git


The following commit(s) were added to refs/heads/master by this push:
     new bc3d4caf28 Fix intermittent JsonValueSafety schema-traversal deadline 
race under CI load
bc3d4caf28 is described below

commit bc3d4caf28ddf32122cbcbc4074917e191fd16ab
Author: James Bognar <[email protected]>
AuthorDate: Wed Aug 5 18:27:18 2026 -0700

    Fix intermittent JsonValueSafety schema-traversal deadline race under CI 
load
    
    Reorder check() so the per-iteration depth/node-count validation runs before
    the wall-clock deadline check. A structurally-oversized input now 
deterministically
    reports its node-count (or depth) violation instead of racing the 100ms 
deadline,
    which under CI reactor load could trip first and emit "traversal exceeded" 
instead.
    The DoS guarantee is preserved (bounded work per iteration; deadline still 
enforced,
    at most one iteration later). Hardens both MCP schema-check paths at once.
    
    Co-authored-by: Cursor <[email protected]>
---
 .../main/java/org/apache/juneau/commons/utils/JsonValueSafety.java  | 6 ++++--
 1 file changed, 4 insertions(+), 2 deletions(-)

diff --git 
a/juneau-core/juneau-commons/src/main/java/org/apache/juneau/commons/utils/JsonValueSafety.java
 
b/juneau-core/juneau-commons/src/main/java/org/apache/juneau/commons/utils/JsonValueSafety.java
index bf500dabe4..caa01f7c18 100644
--- 
a/juneau-core/juneau-commons/src/main/java/org/apache/juneau/commons/utils/JsonValueSafety.java
+++ 
b/juneau-core/juneau-commons/src/main/java/org/apache/juneau/commons/utils/JsonValueSafety.java
@@ -87,12 +87,14 @@ public final class JsonValueSafety {
                stack.push(new Framed(root, 1));
                var nodes = 0;
                while (! stack.isEmpty()) {
-                       if (System.nanoTime() >= deadlineNanos)
-                               throw iaex("%s traversal exceeded %s ms", 
label, MAX_TRAVERSAL_MILLIS);
+                       // Bounded per-iteration work runs before the deadline 
check so a structurally-oversized input
+                       // deterministically reports its depth/node-count 
violation instead of racing the wall clock.
                        var frame = stack.pop();
                        if (frame.depth() > MAX_DEPTH)
                                throw iaex("%s exceeds maximum nesting depth of 
%s", label, MAX_DEPTH);
                        nodes = visitFrame(frame, label, seen, stack, nodes);
+                       if (System.nanoTime() >= deadlineNanos)
+                               throw iaex("%s traversal exceeded %s ms", 
label, MAX_TRAVERSAL_MILLIS);
                }
        }
 

Reply via email to