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 12783284a8369d82f2e01cef71f68ace500a6b30
Author: opencode <[email protected]>
AuthorDate: Mon Oct 19 15:25:01 2026 +0200

    Fall back when the Set tag plugin has nowhere to set
    
    A c:set carrying a value but neither a var nor a target attribute is
    invalid, but the tag is complete as far as the tag library descriptor
    and its validator are concerned. The tag plugin generated the
    evaluation of the value and no further statement, so the value was
    computed and dropped and the page carried on, while the standard tag
    handler reports the missing target and fails the request.
    
    The plugin now falls back to the standard handler for that
    combination. Falling back is safe after code has already been
    generated for the tag, as that code is only reachable while the plug-in
    is in use, which the fallback turns off.
---
 .../apache/jasper/tagplugins/jstl/core/Set.java    |  7 +++++++
 .../jasper/tagplugins/jstl/core/TestSet.java       | 23 +++++++++++++++++++++
 test/webapp/jstl/set-no-var-target.jsp             | 24 ++++++++++++++++++++++
 webapps/docs/changelog.xml                         |  7 +++++++
 4 files changed, 61 insertions(+)

diff --git a/java/org/apache/jasper/tagplugins/jstl/core/Set.java 
b/java/org/apache/jasper/tagplugins/jstl/core/Set.java
index e4af208be5..e732a988bb 100644
--- a/java/org/apache/jasper/tagplugins/jstl/core/Set.java
+++ b/java/org/apache/jasper/tagplugins/jstl/core/Set.java
@@ -65,6 +65,13 @@ public class Set implements TagPlugin {
             ctxt.generateJavaSource(resultName + " = ");
             ctxt.generateAttribute("value");
             ctxt.generateJavaSource(";");
+            // Without a var or a target, nothing receives the value. The
+            // standard handler fails this use on the missing target, so let
+            // it handle the tag.
+            if (!hasVar && !hasTarget) {
+                ctxt.dontUseTagPlugin();
+                return;
+            }
         } else {
             ctxt.dontUseTagPlugin();
             return;
diff --git a/test/org/apache/jasper/tagplugins/jstl/core/TestSet.java 
b/test/org/apache/jasper/tagplugins/jstl/core/TestSet.java
index c2e9fec975..5f19693232 100644
--- a/test/org/apache/jasper/tagplugins/jstl/core/TestSet.java
+++ b/test/org/apache/jasper/tagplugins/jstl/core/TestSet.java
@@ -89,4 +89,27 @@ public class TestSet extends AbstractTestTag {
                         + "\"page\" scope is required but was \"request\"]"));
         Assert.assertTrue(body, body.contains("ERR2=[threw]"));
     }
+
+
+    /*
+     * A c:set with a value but neither var nor target sets nothing. The
+     * standard handler treats the absent target as an invalid target and
+     * fails, which the plugin has to keep doing.
+     */
+    @Test
+    public void testNoVarNoTarget() throws Exception {
+        ByteChunk res = new ByteChunk();
+
+        int rc = getUrl("http://localhost:"; + getPort() +
+                "/test/jstl/set-no-var-target.jsp", res, null);
+
+        Assert.assertEquals(HttpServletResponse.SC_OK, rc);
+
+        String body = res.toString();
+        Assert.assertTrue(body, body.contains("ERR=[threw]"));
+        Assert.assertTrue(body,
+                body.contains("ERRMSG=[Attempt to set the property of an 
invalid object in &lt;set&gt;.]"));
+        // A property makes no difference without a var or a target
+        Assert.assertTrue(body, body.contains("ERR2=[threw]"));
+    }
 }
diff --git a/test/webapp/jstl/set-no-var-target.jsp 
b/test/webapp/jstl/set-no-var-target.jsp
new file mode 100644
index 0000000000..f0e24b084d
--- /dev/null
+++ b/test/webapp/jstl/set-no-var-target.jsp
@@ -0,0 +1,24 @@
+<%--
+ 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:catch var="err"><c:set value="foo" /></c:catch>
+<p>ERR=[${err ne null ? 'threw' : 'silent'}]</p>
+<p>ERRMSG=[${err.message}]</p>
+<c:catch var="err2"><c:set value="foo" property="bar" /></c:catch>
+<p>ERR2=[${err2 ne null ? 'threw' : 'silent'}]</p>
diff --git a/webapps/docs/changelog.xml b/webapps/docs/changelog.xml
index 0cbffc4158..4bd586cb0c 100644
--- a/webapps/docs/changelog.xml
+++ b/webapps/docs/changelog.xml
@@ -459,6 +459,13 @@
         rejected for a deferred value, and mappings that would shadow a
         plain attribute are removed. (remm)
       </fix>
+      <fix>
+        The tag plugin for <code>c:set</code> now falls back to the standard
+        tag handler when the tag has a value but neither a
+        <code>var</code> nor a <code>target</code> attribute, so that the
+        invalid use fails as it does with the handler instead of being
+        silently ignored. (remm)
+      </fix>
     </changelog>
   </subsection>
   <subsection name="WebSocket">


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

Reply via email to