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 a095f7b2249cbbfcfb8999952a8eb9d2975a2bd8
Author: opencode <[email protected]>
AuthorDate: Mon Oct 19 13:06:55 2026 +0200

    Expose the ForEach tag plugin loop variable as an Integer
    
    In numeric range mode, the ForEach tag plugin generated
    _jspx_page_context.setAttribute(var, String.valueOf(index)), so the
    loop variable was published as a String. The reference JSTL
    implementation, LoopTagSupport's ToEndIterator, boxes the index with
    Integer.valueOf and therefore publishes an Integer. EL type coercion
    hides the difference for plain output, but type sensitive expressions
    (method arguments, getClass checks, operand-type dependent comparisons)
    and any consumer of the scoped variable behave differently than under
    the reference implementation.
    
    Box the generated index with Integer.valueOf, matching the reference
    implementation. Add a test page and a test asserting the published
    type when the plugin is active.
    
    Found by code review.
---
 .../apache/jasper/tagplugins/jstl/core/ForEach.java  |  3 ++-
 .../jasper/tagplugins/jstl/core/TestForEach.java     | 17 +++++++++++++++++
 test/webapp/jstl/foreach-numeric-var.jsp             | 20 ++++++++++++++++++++
 3 files changed, 39 insertions(+), 1 deletion(-)

diff --git a/java/org/apache/jasper/tagplugins/jstl/core/ForEach.java 
b/java/org/apache/jasper/tagplugins/jstl/core/ForEach.java
index 66b8ff6304..89a162e340 100644
--- a/java/org/apache/jasper/tagplugins/jstl/core/ForEach.java
+++ b/java/org/apache/jasper/tagplugins/jstl/core/ForEach.java
@@ -72,7 +72,8 @@ public final class ForEach implements TagPlugin {
         if (hasVar /* && ctxt.hasEL() */) {
             ctxt.generateJavaSource("_jspx_page_context.setAttribute(");
             ctxt.generateAttribute("var");
-            ctxt.generateJavaSource(", String.valueOf(" + index + "));");
+            // The reference implementation exposes the index as an Integer.
+            ctxt.generateJavaSource(", Integer.valueOf(" + index + "));");
         }
         ctxt.generateBody();
         ctxt.generateJavaSource("}");
diff --git a/test/org/apache/jasper/tagplugins/jstl/core/TestForEach.java 
b/test/org/apache/jasper/tagplugins/jstl/core/TestForEach.java
index 3876c3b84a..7b2bd74c48 100644
--- a/test/org/apache/jasper/tagplugins/jstl/core/TestForEach.java
+++ b/test/org/apache/jasper/tagplugins/jstl/core/TestForEach.java
@@ -54,4 +54,21 @@ public class TestForEach extends AbstractTestTag {
         Assert.assertTrue(body.contains("OK - 2"));
         Assert.assertTrue(body.contains("OK - 3"));
     }
+
+
+    @Test
+    public void testNumericRangeVarType() throws Exception {
+        ByteChunk res = new ByteChunk();
+
+        int rc = getUrl("http://localhost:"; + getPort() +
+                "/test/jstl/foreach-numeric-var.jsp", res, null);
+
+        Assert.assertEquals(HttpServletResponse.SC_OK, rc);
+
+        // The reference implementation exposes the loop variable as an
+        // Integer, not a String.
+        String body = res.toString();
+        Assert.assertEquals(2, body.split("java\\.lang\\.Integer", -1).length 
- 1);
+        Assert.assertFalse(body, body.contains("java.lang.String"));
+    }
 }
diff --git a/test/webapp/jstl/foreach-numeric-var.jsp 
b/test/webapp/jstl/foreach-numeric-var.jsp
new file mode 100644
index 0000000000..9ae6444b9e
--- /dev/null
+++ b/test/webapp/jstl/foreach-numeric-var.jsp
@@ -0,0 +1,20 @@
+<%--
+ Licensed to the Apache Software Foundation (ASF) under one or more
+  contributor license agreements.  See the NOTICE file distributed with
+  this work for additional information regarding copyright ownership.
+  The ASF licenses this file to You under the Apache License, Version 2.0
+  (the "License"); you may not use this file except in compliance with
+  the License.  You may obtain a copy of the License at
+
+      http://www.apache.org/licenses/LICENSE-2.0
+
+  Unless required by applicable law or agreed to in writing, software
+  distributed under the License is distributed on an "AS IS" BASIS,
+  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+  See the License for the specific language governing permissions and
+  limitations under the License.
+--%>
+<%@ page session="false" contentType="text/html; charset=UTF-8"
+         pageEncoding="UTF-8" %>
+<%@ taglib uri="http://java.sun.com/jsp/jstl/core"; prefix="c" %>
+<c:forEach begin="1" end="2" var="i"><p><%= 
pageContext.getAttribute("i").getClass().getName() %></p></c:forEach>


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

Reply via email to