This is an automated email from the ASF dual-hosted git repository. rmaucher pushed a commit to branch 10.1.x in repository https://gitbox.apache.org/repos/asf/tomcat.git
commit 01817b9e15c0e933568f931525c13845272b04fc Author: opencode <[email protected]> AuthorDate: Mon Oct 19 11:01:42 2026 +0200 Use the canonical enum name in optimized tag setter code generation The optional ELInterpreterTagSetters optimization referenced the enum type of a tag attribute setter by Class.getName(). For a nested enum that returns the binary name with '$' separators, e.g. com.example.Tags$Status, which is not valid Java source, so a literal EL value like ${'ACTIVE'} for a setter taking a nested enum type made the generated JSP class fail to compile on first request. Use getCanonicalName() instead, matching the dot-separated name the non-optimized runtime path in JspUtil.interpreterCall already uses. Found by code review. --- .../optimizations/ELInterpreterTagSetters.java | 5 +++- .../optimizations/TestELInterpreterTagSetters.java | 29 +++++++++++++++++++++ test/webapp/WEB-INF/tag-setters.tld | 11 ++++++++ test/webapp/bug6nnnn/bug64872-nested-timeunit.jsp | 30 ++++++++++++++++++++++ 4 files changed, 74 insertions(+), 1 deletion(-) diff --git a/java/org/apache/jasper/optimizations/ELInterpreterTagSetters.java b/java/org/apache/jasper/optimizations/ELInterpreterTagSetters.java index 9841e4d5ad..18d88fc659 100644 --- a/java/org/apache/jasper/optimizations/ELInterpreterTagSetters.java +++ b/java/org/apache/jasper/optimizations/ELInterpreterTagSetters.java @@ -262,7 +262,10 @@ public class ELInterpreterTagSetters implements ELInterpreter { try { @SuppressWarnings({ "unchecked", "rawtypes" }) Enum<?> enumValue = Enum.valueOf((Class<? extends Enum>) expectedType, m.group(2)); - result = expectedType.getName() + "." + enumValue.name(); + // The canonical name (dot-separated) must be used here. The + // binary name returned by getName() contains '$' separators + // for nested types and is not valid Java source. + result = expectedType.getCanonicalName() + "." + enumValue.name(); } catch (IllegalArgumentException iae) { if (log.isDebugEnabled()) { log.debug(Localizer.getMessage("jsp.error.typeConversion", m.group(2), diff --git a/test/org/apache/jasper/optimizations/TestELInterpreterTagSetters.java b/test/org/apache/jasper/optimizations/TestELInterpreterTagSetters.java index 1cdf5bd2c8..e9add535aa 100644 --- a/test/org/apache/jasper/optimizations/TestELInterpreterTagSetters.java +++ b/test/org/apache/jasper/optimizations/TestELInterpreterTagSetters.java @@ -90,6 +90,7 @@ public class TestELInterpreterTagSetters extends TomcatBaseTest { parameterSets.add(new Object[] { elInterpreter, "float", "12.34", ZERO, TWO }); parameterSets.add(new Object[] { elInterpreter, "primitive-float", "12.34", ZERO, TWO }); parameterSets.add(new Object[] { elInterpreter, "timeunit", "SECONDS", ZERO, TWO }); + parameterSets.add(new Object[] { elInterpreter, "nested-timeunit", "SECONDS", ZERO, TWO }); parameterSets.add(new Object[] { elInterpreter, "string", "bar", ZERO, TWO }); } return parameterSets; @@ -473,6 +474,34 @@ public class TestELInterpreterTagSetters extends TomcatBaseTest { } + /* + * Enum nested in a class to check the generated code uses the canonical + * name of the enum type, not the binary name. + */ + public enum NestedTimeUnit { + SECONDS + } + + + public static class TagNestedTimeUnit extends SimpleTagSupport { + + private NestedTimeUnit foo; + + public NestedTimeUnit getFoo() { + return foo; + } + + public void setFoo(NestedTimeUnit foo) { + this.foo = foo; + } + + @Override + public void doTag() throws JspException, IOException { + getJspContext().getOut().print(foo); + } + } + + public static class TagBigDecimal extends SimpleTagSupport { private BigDecimal foo; diff --git a/test/webapp/WEB-INF/tag-setters.tld b/test/webapp/WEB-INF/tag-setters.tld index e02ae147bd..7158111a54 100644 --- a/test/webapp/WEB-INF/tag-setters.tld +++ b/test/webapp/WEB-INF/tag-setters.tld @@ -242,4 +242,15 @@ <type>java.util.concurrent.TimeUnit</type> </attribute> </tag> + <tag> + <name>tagNestedTimeUnit</name> + <tag-class>org.apache.jasper.optimizations.TestELInterpreterTagSetters$TagNestedTimeUnit</tag-class> + <body-content>scriptless</body-content> + <attribute> + <name>foo</name> + <required>true</required> + <rtexprvalue>true</rtexprvalue> + <type>org.apache.jasper.optimizations.TestELInterpreterTagSetters$NestedTimeUnit</type> + </attribute> + </tag> </taglib> \ No newline at end of file diff --git a/test/webapp/bug6nnnn/bug64872-nested-timeunit.jsp b/test/webapp/bug6nnnn/bug64872-nested-timeunit.jsp new file mode 100644 index 0000000000..621a80945b --- /dev/null +++ b/test/webapp/bug6nnnn/bug64872-nested-timeunit.jsp @@ -0,0 +1,30 @@ +<%-- + 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. +--%> +<%@ taglib uri="http://tomcat.apache.org/tag-setters" prefix="ts" %> +<html> + <head><title>Bug 64872 nested enum test case</title></head> + <body> + <% + for (int i=0; i < Integer.parseInt(request.getParameter("iterations")); i++) { + %> + <p>01 The value of foo is [<ts:tagNestedTimeUnit foo="${'SECONDS'}" />]</p> + <p>02 The value of foo is [<ts:tagNestedTimeUnit foo='${"SECONDS"}' />]</p> + <% + } + %> + </body> +</html> --------------------------------------------------------------------- To unsubscribe, e-mail: [email protected] For additional commands, e-mail: [email protected]
