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

rmaucher pushed a commit to branch 9.0.x
in repository https://gitbox.apache.org/repos/asf/tomcat.git

commit baa7e4fe8ea0f5524e266689ce497b5bf958c715
Author: opencode <[email protected]>
AuthorDate: Mon Oct 19 13:58:11 2026 +0200

    Compute the ForEach tag plugin's state flags per request
    
    The plugin instance is shared across concurrent page
    translations, so the hasVar/hasBegin/hasEnd/hasStep flags that
    control the loop are now computed as locals in doTag() and
    passed to the iteration helpers instead of being stored in
    instance fields, which allowed one request's settings to be
    observed by another request iterating concurrently.
    
    Found by code review.
---
 .../apache/jasper/tagplugins/jstl/core/ForEach.java    | 18 ++++++++++--------
 1 file changed, 10 insertions(+), 8 deletions(-)

diff --git a/java/org/apache/jasper/tagplugins/jstl/core/ForEach.java 
b/java/org/apache/jasper/tagplugins/jstl/core/ForEach.java
index e69446a0f2..57353edcde 100644
--- a/java/org/apache/jasper/tagplugins/jstl/core/ForEach.java
+++ b/java/org/apache/jasper/tagplugins/jstl/core/ForEach.java
@@ -30,8 +30,6 @@ public final class ForEach implements TagPlugin {
         // Default constructor
     }
 
-    private boolean hasVar, hasBegin, hasEnd, hasStep;
-
     @Override
     public void doTag(TagPluginContext ctxt) {
 
@@ -43,14 +41,17 @@ public final class ForEach implements TagPlugin {
             return;
         }
 
-        hasVar = ctxt.isAttributeSpecified("var");
-        hasBegin = ctxt.isAttributeSpecified("begin");
-        hasEnd = ctxt.isAttributeSpecified("end");
-        hasStep = ctxt.isAttributeSpecified("step");
+        // Local variables, not instance fields: a single plugin instance is
+        // shared by all translations of the web application, which may run
+        // concurrently.
+        boolean hasVar = ctxt.isAttributeSpecified("var");
+        boolean hasBegin = ctxt.isAttributeSpecified("begin");
+        boolean hasEnd = ctxt.isAttributeSpecified("end");
+        boolean hasStep = ctxt.isAttributeSpecified("step");
 
         boolean hasItems = ctxt.isAttributeSpecified("items");
         if (hasItems) {
-            doCollection(ctxt);
+            doCollection(ctxt, hasVar, hasBegin, hasEnd, hasStep);
             return;
         }
 
@@ -118,7 +119,8 @@ public final class ForEach implements TagPlugin {
     /**
      * Generate codes for Collections.
      */
-    private void doCollection(TagPluginContext ctxt) {
+    private void doCollection(TagPluginContext ctxt, boolean hasVar,
+            boolean hasBegin, boolean hasEnd, boolean hasStep) {
 
         ctxt.generateImport("java.util.*");
         generateIterators(ctxt);


---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]

Reply via email to