Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to properly escape triple nested quotes in JSP tags

We just upgraded Tomcat and the newer Tomcat doesn't like nested quotes in the tag, so we have to alternate between single and double quotes. For example,

We used to have,

<form id="search" action="<fmt:message key="search.url"/>">

Now we can change it to,

<form id="search" action="<fmt:message key='search.url'/>">

What should I do if the quotes are triply nested like this,

<form id="search" action="<fmt:message key='<c:out value="${requestScope.search_url}"/>'/>">

The above tag doesn't compile.

like image 710
ZZ Coder Avatar asked Aug 06 '09 20:08

ZZ Coder


People also ask

How do you escape quotes in Java?

The double quote character has to be escaped with a backslash in a Java string literal. Other characters that need special treatment include: Carriage return and newline: "\r" and "\n" Backslash: "\\"

How do you escape a quote?

You can put a backslash character followed by a quote ( \" or \' ). This is called an escape sequence and Python will remove the backslash, and put just the quote in the string. Here is an example. The backslashes protect the quotes, but are not printed.

How do you escape a double quote?

If you need to use the double quote inside the string, you can use the backslash character. Notice how the backslash in the second line is used to escape the double quote characters. And the single quote can be used without a backslash.

How do you escape double quotes in Java?

Double quotes characters can be escaped with backslash( \ ) in java.


4 Answers

If you don't want do update all your jsp:s just for the tomcat upgrade, set the system property "org.apache.jasper.compiler.Parser.STRICT_QUOTE_ESCAPING" to false.

Easiest way to this is by editing catalina.sh and adding the following to JAVA_OPTS:

-Dorg.apache.jasper.compiler.Parser.STRICT_QUOTE_ESCAPING=false  
like image 120
D. Wroblewski Avatar answered Oct 05 '22 01:10

D. Wroblewski


Several ways:

  1. <c:out> is actually not necessary if you don't need to XML-escape it:

    <form id="search" action="<fmt:message key='${requestScope.search_url}'/>">
    
  2. <fmt:message> has a var attribute which stores the result in page context:

    <fmt:message key="${requestScope.search_url}" var="search_url" />
    <form id="search" action="${search_url}">
    
  3. For the case <c:out> is mandatory (XML escaping and so on, I however question the value of XML escaping for message keys), it has a var attribute as well:

    <c:out value"${requestScope.search_url}" var="search_url" />
    <fmt:message key="${search_url}" var="search_url" />
    <form id="search" action="${search_url}">
    
like image 41
BalusC Avatar answered Oct 05 '22 02:10

BalusC


You've probably long since solved this problem, but in case anyone else runs across this:

That doesn't compile not because of the nested quotes, but because of the nested tags. You can't use a c:out inside the attribute of the fmt:message tag. However, you can get it to work by setting a temporary variable:

<c:set var="foo"><c:out value="${requestScope.search_url}"/></c:set>
<form id="search" action="<fmt:message key='${foo}'/>">

Also, calling your example "triply" nested quotes is misleading. The double quote characters surrounding the value of the action attribute of your form tag do NOT behave like quotes from the point of view of the jsp engine. Anything outside of a ${...} EL expression, or outside of a known jsp tag with a known prefix is treated as arbitrary bytes.

like image 38
Eric Avatar answered Oct 05 '22 01:10

Eric


I've not tried this, but elsewhere in Java you can just escape the nested quotes, then escape the \ for the double-nested quotes:

<form id="search" action="<fmt:message key=\"<c:out
    value=\\\"${requestScope.search_url}\\\"/>\"/>">

Edit: As it is an attribute, the above probably won't work, but a similar approach might work with single-quotes:

<form id="search" action="<fmt:message key='<c:out
    value=\'${requestScope.search_url}\'/>'/>">

Alternatively, use a method call and have it return the formatted String...

like image 37
Rich Seller Avatar answered Oct 05 '22 01:10

Rich Seller