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 a2e083c5b596e044141fefb81caf6819de855f23 Author: opencode <[email protected]> AuthorDate: Mon Oct 19 10:08:16 2026 +0200 Reject jsp:element with multiple name attributes The JspAttribute array built for a jsp:element action was sized as the number of XML-style attributes minus one plus the number of named attributes, which assumes that exactly one XML-style attribute with the local name 'name' is present. XML permits two attributes with the same local name as long as they use different namespace prefixes, for example: <jsp:element name="e" p:name="f"/> Both attributes matched the check that excludes the 'name' attribute from the array, so the array was over-allocated and the trailing null entry was passed on by setJspAttributes() only to trigger a NullPointerException later while collecting or generating code. Count the attributes with the local name 'name' before allocating the array and report the use of more than one as a translation error, since jsp:element has exactly one 'name' attribute. Pages with a single 'name' attribute, including those using a prefixed name attribute, are handled exactly as before. Found by code review. --- java/org/apache/jasper/compiler/Validator.java | 17 ++++++++++++++++- .../apache/jasper/resources/LocalStrings.properties | 1 + test/org/apache/jasper/compiler/TestValidator.java | 20 ++++++++++++++++++++ test/webapp/jsp/parsing/element-duplicate-name.jspx | 20 ++++++++++++++++++++ 4 files changed, 57 insertions(+), 1 deletion(-) diff --git a/java/org/apache/jasper/compiler/Validator.java b/java/org/apache/jasper/compiler/Validator.java index dfda3dc112..32ed3cd0e5 100644 --- a/java/org/apache/jasper/compiler/Validator.java +++ b/java/org/apache/jasper/compiler/Validator.java @@ -816,9 +816,24 @@ class Validator { Node.Nodes namedAttrs = n.getNamedAttributeNodes(); + /* + * XML allows attributes with the same local name as long as they + * use different namespace prefixes so the number of 'name' + * attributes must be counted rather than assumed to be one. + */ + int nameAttrCount = 0; + for (int i = 0; i < xmlAttrLen; i++) { + if ("name".equals(attrs.getLocalName(i))) { + nameAttrCount++; + } + } + if (nameAttrCount > 1) { + err.jspError(n, "jsp.error.jspelement.duplicate.name"); + } + // XML-style 'name' attribute, which is mandatory, must not be // included in JspAttribute array - int jspAttrSize = xmlAttrLen - 1 + namedAttrs.size(); + int jspAttrSize = xmlAttrLen - nameAttrCount + namedAttrs.size(); Node.JspAttribute[] jspAttrs = new Node.JspAttribute[jspAttrSize]; int jspAttrIndex = 0; diff --git a/java/org/apache/jasper/resources/LocalStrings.properties b/java/org/apache/jasper/resources/LocalStrings.properties index bab1da9ea7..f82467d793 100644 --- a/java/org/apache/jasper/resources/LocalStrings.properties +++ b/java/org/apache/jasper/resources/LocalStrings.properties @@ -112,6 +112,7 @@ jsp.error.jspbody.required=Must use jsp:body to specify tag body for [{0}] if js jsp.error.jspc.missingTarget=Missing target: Must specify -webapp or -uriroot, or one or more JSP pages jsp.error.jspc.no_uriroot=The uriroot is not specified and cannot be located with the specified JSP file(s) jsp.error.jspc.uriroot_not_dir=The -uriroot option must specify a pre-existing directory +jsp.error.jspelement.duplicate.name=XML-style 'name' attribute appears more than once jsp.error.jspelement.missing.name=Mandatory XML-style 'name' attribute missing jsp.error.jspoutput.conflict=<jsp:output>: illegal to have multiple occurrences of [{0}] with different values (old: [{1}], new: [{2}]) jsp.error.jspoutput.doctypenamesystem=<jsp:output>: 'doctype-root-element' and 'doctype-system' attributes must appear together diff --git a/test/org/apache/jasper/compiler/TestValidator.java b/test/org/apache/jasper/compiler/TestValidator.java index b2ad3535f7..c37b677756 100644 --- a/test/org/apache/jasper/compiler/TestValidator.java +++ b/test/org/apache/jasper/compiler/TestValidator.java @@ -83,6 +83,26 @@ public class TestValidator extends TomcatBaseTest { Assert.assertTrue(result, result.contains("123: message with an id")); } + @Test + public void testDuplicateJspElementName() throws Exception { + getTomcatInstanceTestWebapp(false, true); + + ByteChunk res = new ByteChunk(); + + int rc = getUrl("http://localhost:" + getPort() + "/test/jsp/parsing/element-duplicate-name.jspx", res, null); + + Assert.assertEquals(HttpServletResponse.SC_INTERNAL_SERVER_ERROR, rc); + + // XML allows two attributes with the local name 'name' as long as + // they use different namespace prefixes. jsp:element must report that + // as a translation error. It previously sized the JspAttribute array + // for a single 'name' attribute which left a null entry that later + // triggered a NullPointerException. + String result = res.toString(); + Assert.assertTrue(result, result.contains("attribute appears more than once")); + Assert.assertFalse(result, result.contains("NullPointerException")); + } + @Test public void testTldVersions22() throws Exception { Tomcat tomcat = getTomcatInstance(); diff --git a/test/webapp/jsp/parsing/element-duplicate-name.jspx b/test/webapp/jsp/parsing/element-duplicate-name.jspx new file mode 100644 index 0000000000..6c0fe404fe --- /dev/null +++ b/test/webapp/jsp/parsing/element-duplicate-name.jspx @@ -0,0 +1,20 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- + 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. +--> +<jsp:root xmlns:jsp="http://java.sun.com/JSP/Page" xmlns:p="urn:test" version="2.0"> + <jsp:element name="e" p:name="f"/> +</jsp:root> --------------------------------------------------------------------- To unsubscribe, e-mail: [email protected] For additional commands, e-mail: [email protected]
