Bug 55198 - Quote entity in html element attribute evaluated in tagx if attribute contains EL expression
Summary: Quote entity in html element attribute evaluated in tagx if attribute contain...
Status: RESOLVED FIXED
Alias: None
Product: Tomcat 6
Classification: Unclassified
Component: Jasper (show other bugs)
Version: 6.0.37
Hardware: PC All
: P2 normal (vote)
Target Milestone: default
Assignee: Tomcat Developers Mailing List
URL:
Keywords:
Depends on:
Blocks:
 
Reported: 2013-07-05 04:32 UTC by Evan Greensmith
Modified: 2014-03-17 22:22 UTC (History)
0 users



Attachments
War demonstrating the issue (2.49 KB, application/octet-stream)
2013-07-05 04:32 UTC, Evan Greensmith
Details

Note You need to log in before you can comment on or make changes to this bug.
Description Evan Greensmith 2013-07-05 04:32:38 UTC
Created attachment 30535 [details]
War demonstrating the issue

Quote entity in html element attribute evaluated in tagx if attribute contains EL expression 

If your tagx file contains an html element such as
<a href="#" onclick="window.alert(&quot;Hello World!&quot;)">foobar</a>
It renders as
<a href="#" onclick="window.alert(&quot;Hello World!&quot;)">foobar</a>

If your tagx file contains an html element such as
<a href="#" onclick="window.alert(&quot;${text}!&quot;)">foobar</a>
It renders as (if text='foobar')
<a href="#" onclick="window.alert("foobar")">foobar</a>
Most browsers aren't too happy with this.

I would have expected this to render as
<a href="#" onclick="window.alert(&quot;foobar&quot;)">foobar</a>
I browsed through jsp 2.1 spec and couldn't identify anything that explicitly covered this, but I would expect valid xml output from a tagx file.

You don't see this behaviour if you use a tag file. We need to use tagx files to work around various problems in WebSphere and WebLogic containers.

A test war is attached. It is setup for servlet spec 2.5 and jsp 2.1 --- I am actually using a Tomcat 6 container, but thought I'd test this on the latest release.

The output I receive from the test war on tomcat 7.0.41:


<!DOCTYPE html>
<html>
	<head>
		<title>Test the output of tag and tagx containing quote entity in html element attribute</title>
	</head>
	<body>
		<p>.tag file gives:</p>
		



<ul>
	<li><a href="#" onclick="window.alert(&quot;Hello World!&quot;)">Click me to display &quot;Hello World!&quot;</a></li>
	<li><a href="#" onclick="window.alert(&quot;foobar&quot;)">Click me to display &quot;foobar&quot;</a></li>
</ul>

		<p>.tagx file gives:</p>
		<ul><li><a onclick="window.alert(&quot;Hello World!&quot;)" href="#">Click me to display "Hello World!"</a></li><li><a onclick="window.alert("foobar")" href="#">Click me to display "foobar"</a></li></ul>
	</body>
</html>
Comment 1 Mark Thomas 2013-07-05 16:50:20 UTC
Fixed in trunk and 7.0.x and will be included in 7.0.43 onwards.

Since you are using 6.0.x, I have moved this to 6.0.x and proposed the fix for back-porting.
Comment 2 Evan Greensmith 2013-07-08 00:13:31 UTC
(In reply to Mark Thomas from comment #1)
> Fixed in trunk and 7.0.x and will be included in 7.0.43 onwards.
> 
> Since you are using 6.0.x, I have moved this to 6.0.x and proposed the fix
> for back-porting.

Thanks Mark.

I can also confirm that I see the same output in 6.0.37, with the final link in the test case rendered as 

<a onclick="window.alert("foobar")" href="#">
Comment 3 Mark Thomas 2013-07-10 19:25:35 UTC
Please be aware that a contributor spotted that the tagx file provided as part fo the test case is not valid. No elements at all may be present inside a <jsp:text> element. Tomcat 7 & 8 will be updated to enforce this specification requirement.

This issue, however, remains valid and the fix is not affected.
Comment 4 Evan Greensmith 2013-07-10 22:54:42 UTC
(In reply to Mark Thomas from comment #3)
> Please be aware that a contributor spotted that the tagx file provided as
> part fo the test case is not valid. No elements at all may be present inside
> a <jsp:text> element. Tomcat 7 & 8 will be updated to enforce this
> specification requirement.
> 

Thanks for the heads up Mark.

I can't see the <jsp:text> element in the clickme.tagx. Is there something that is being converted to a <jsp:text> which ends up with elements inside?
Comment 5 Konstantin Kolinko 2013-11-05 03:27:30 UTC
For the record, the change in 7.0.43 for this bug is r1500065

It changed how EL output is escaped in tag attributes - see bug 55735.
I think this change in EL escaping was an inadvertent one, as the original issue is about static content. It did not say about escaping of EL output.

As this issue is an older one, I will comment on the specification here.


1. Reading the JSP specification

JSP 2.3 (JSP2.3MR.pdf) chapter JSP.6.3.9 "Template Content" says how static
content shall be rendered:

It says about XML fragments that
"The interpretation of such an XML element is to pass its textual representation to the
current value of out, after the whitespace processing described in Section JSP.6.2.3."


Testing this feature, I see an odd behaviour. A simple example would be a
JSPX page like this:

[[[
<jsp:root version="2.0" xmlns:jsp="http://java.sun.com/JSP/Page">
<jsp:directive.page contentType="text/plain" />
<foo bar="&lt;HH&gt;" baz="&quot;JJ&quot;" foo="&amp;">
&lt;LL&gt;
</foo>
</jsp:root>
]]]


I expect it to render &lt;HH&gt;, &quot;JJ&quot;, &amp; and &lt;LL&gt;,
as that is a textual representation of the above XML, but
in all 7.0.47, 7.0.42 and 6.0.37 it renders:

 foo="&" baz="&quot;JJ&quot;" bar="<HH>" and <LL>

Somehow only the quotes are rendered correctly.


2. It would be nice to expand what is written in JSP.6.2.3. to the EL expressions in those XML fragments, so that Tomcat renders well-formed XML,
but it is likely that such an interpretation is wrong.

If I do such expansion, I would say that

- ELs in attributes of tags in XML fragments have to have their text content escaped

- ELs in tag bodies of tags in XML fragments have to have their text content escaped

- ELs in the body of <jsp:text/> elements shall be rendered as is, without escaping.

As per JSP.6.2.3 <jsp:text/> generates arbitrary content.

- ELs in <![CDATA[...]]> blocks:

The easy way is to render the content of CDATA blocks as text. In this case the usual escaping rules apply.

(If CDATA were rendered CDATA as CDATA, the usual escaping rules do not apply, but one would have to beware of ']]>' in EL output).


It would be nice to interpret the specification this way and throw away a number of escapeXml calls, but it is likely that such an interpretation is wrong.


With r1500065 the ELs in attributes of tags in XML fragments
are now escaped automatically.

My own example is that the code like this in JSPX files

<a href="${fn:escapeXml(url)}">...</a>

now produces URLs that are escaped twice, with &ampamp;s.
This is the issue reported in bug 55735.


This change has not changed how ELs are handled in tag bodies. Only attributes were affected.

Looking at textRotate.jspx in the Tomcat examples web application, it does not expect that ${name} expression were escaped automatically. It explicitly calls escapeXml().
Comment 6 Mark Thomas 2013-11-05 23:03:50 UTC
I've updated the back-port proposal to include a fix for the regression identified in bug 55735.

Regarding the 

<foo bar="&lt;HH&gt;" baz="&quot;JJ&quot;" foo="&amp;">
&lt;LL&gt;
</foo>

issue, I have a fix for that but it strikes me as the sort of thing that could break lots of stuff. I suggest opening a new issue for that against Tomcat 8, fixing it there and seeing what feedback we get before we back-port it.
Comment 7 Mark Thomas 2014-01-08 13:23:41 UTC
This has been fixed in 6.0.x and will be included in 6.0.38 onwards.
Comment 8 Konstantin Kolinko 2014-03-17 22:22:36 UTC
For reference:

(In reply to Evan Greensmith from comment #0)
>
> If your tagx file contains an html element such as
> <a href="#" onclick="window.alert(&quot;Hello World!&quot;)">foobar</a>
> It renders as
> <a href="#" onclick="window.alert(&quot;Hello World!&quot;)">foobar</a>
> 

Technically, the textual value of the attribute of an xml tag, as returned by XML parser here is [window.alert("Hello World!")].

The legacy behaviour - in 7.0.42 here is that when printing the tag attributes the double quotes are replaced  (") -> (&quot;). In the tag next no replacements are performed.

This behaviour is applied to the double quotes only, but not to other special symbols.

Using the OP's test.war if I replace the first (non-EL) tag in clickme.tag and clickme.tagx with the following:

<li><a href="#" onclick="window.alert(&quot;&lt;&amp;&gt;&#039;Hello World!&quot;)">Click me to display &quot;&lt;&amp;&gt;&#039;Hello World!&quot;</a></li>

Tomcat 7.0.42 renders it as following:

- for clickme.tag:

<li><a href="#" onclick="window.alert(&quot;&lt;&amp;&gt;&#039;Hello World!&quot;)">Click me to display &quot;&lt;&amp;&gt;&#039;Hello World!&quot;</a></li>

- for clickme.tagx:

<li><a onclick="window.alert(&quot;<&>'Hello World!&quot;)" href="#">Click me to display "<&>'Hello World!"</a></li>

Note that tag file renders as the source is, tagx file renders the texts as returned by XML parser, only replacing "->&quot; in tag attribute, but nowhere else.

I am not saying that this is correct. I am just documenting the legacy behaviour.


In the code, the place responsible for s/"/&quot;/ replacement is
Generator$GenerateVisitor.visit(Node.UninterpretedTag n),

    out.print(DOUBLE_QUOTE);
    out.print(attrs.getValue(i).replace("\"", "&quot;"));
    out.print(DOUBLE_QUOTE);

If attribute value does not contain double quote chars (e.g. xml-escaping has already been applied to it during previous processing), it will be printed as is.


For reference,
regressions related to an attempt to fix this issue thus far are:
https://issues.apache.org/bugzilla/show_bug.cgi?id=56265
https://issues.apache.org/bugzilla/show_bug.cgi?id=56029
https://issues.apache.org/bugzilla/show_bug.cgi?id=55735