Bug 37029

Summary: TLD Validation error for HTML "param" element
Product: Taglibs Reporter: Michał Borowiecki <mihbor>
Component: Standard TaglibAssignee: Tomcat Developers Mailing List <dev>
Status: RESOLVED FIXED    
Severity: major    
Priority: P2    
Version: nightly   
Target Milestone: ---   
Hardware: Other   
OS: other   

Description Michał Borowiecki 2005-10-11 21:23:13 UTC
TLD Validator reports errors when it encounters the html "param" element.

Example:
<?xml version="1.0"?>
<html
    xmlns:jsp="http://java.sun.com/JSP/Page"
    xmlns:jstlc="http://java.sun.com/jsp/jstl/core"
    xmlns:jstlf="http://java.sun.com/jsp/jstl/fmt">

    <jstlc:if test="${true}">
        <applet code="some.package.SomeApplet.class" archive="applet.jar"
width="1" height="1">
            <param name="tx" value="${'blah'}"/>
        </applet>
    </jstlc:if>
</html>

causes the following error:

org.apache.jasper.JasperException: <h3>Validation error messages from
TagLibraryValidator for c</h3><p>4: Invalid use of "param" tag outside
legitimate parent tag</p><h3>Validation error messages from TagLibraryValidator
for fmt</h3><p>4: &lt;param&gt; outside &lt;message&gt;</p>
	org.apache.jasper.compiler.DefaultErrorHandler.jspError(DefaultErrorHandler.java:50)
	org.apache.jasper.compiler.ErrorDispatcher.dispatch(ErrorDispatcher.java:407)
	org.apache.jasper.compiler.ErrorDispatcher.jspError(ErrorDispatcher.java:72)
	org.apache.jasper.compiler.Validator.validateXmlView(Validator.java:1549)
	org.apache.jasper.compiler.Validator.validate(Validator.java:1495)
	org.apache.jasper.compiler.Compiler.generateJava(Compiler.java:157)
	org.apache.jasper.compiler.Compiler.compile(Compiler.java:286)
	org.apache.jasper.compiler.Compiler.compile(Compiler.java:267)
	org.apache.jasper.compiler.Compiler.compile(Compiler.java:255)
	org.apache.jasper.JspCompilationContext.compile(JspCompilationContext.java:556)
	org.apache.jasper.servlet.JspServletWrapper.service(JspServletWrapper.java:293)
	org.apache.jasper.servlet.JspServlet.serviceJspFile(JspServlet.java:291)
	org.apache.jasper.servlet.JspServlet.service(JspServlet.java:241)
	javax.servlet.http.HttpServlet.service(HttpServlet.java:802)
Comment 1 Kris Schneider 2005-10-11 22:05:23 UTC
Try adding the XHTML namespace to the <html> element:

<html
    xmlns="http://www.w3.org/1999/xhtml"
    xmlns:jsp="http://java.sun.com/JSP/Page"
    xmlns:jstlc="http://java.sun.com/jsp/jstl/core"
    xmlns:jstlf="http://java.sun.com/jsp/jstl/fmt">
...
Comment 2 Jan Luehe 2005-12-10 01:17:16 UTC
The html <param> is being treated incorrectly as an <fmt:param> tag,
because of this code in JstlBaseTLV:

    protected boolean isTag(String tagUri,
                            String tagLn,
                            String matchUri,
                            String matchLn) {
        if (tagUri == null
                || tagLn == null
                || matchUri == null
                || matchLn == null)
            return false;

        if (tagUri.length() > matchUri.length()) {
            return (tagUri.startsWith(matchUri)
                    && tagLn.equals(matchLn));
        } else {
            return (matchUri.startsWith(tagUri)
                    && tagLn.equals(matchLn));
        }

In the test case, isTag() is invoked with these args:

  tagUri=""
  tagLn="param"
  matchUri="http://java.sun.com/jsp/jstl/fmt"
  matchLn="param"

which means the "else" will return TRUE, since any string starts with
the empty string!

The fix is to return FALSE if the "tagUri" param is NULL or the EMPTY
string, as shown in these diffs:

--- JstlBaseTLV.java    8 Dec 2005 01:21:24 -0000
+++ JstlBaseTLV.java    10 Dec 2005 00:01:32 -0000
@@ -210,6 +210,7 @@
                            String matchUri,
                            String matchLn) {
        if (tagUri == null
+                || tagUri.length() == 0
                || tagLn == null
                || matchUri == null
                || matchLn == null)
Comment 3 Pierre Delisle 2005-12-17 21:05:11 UTC
Applied Jan's patch. Thanks Jan!