Author: markt
Date: Fri Oct 24 16:28:48 2014
New Revision: 1634089

URL: http://svn.apache.org/r1634089
Log:
Ensure only \${ and \#{ are treated as escapes for ${ and #{ rather than \$ and 
\# being treated as escapes for $ and # when processing literal expressions in 
expression language.

Modified:
    tomcat/trunk/java/org/apache/el/parser/AstLiteralExpression.java
    tomcat/trunk/java/org/apache/jasper/compiler/ELParser.java
    tomcat/trunk/java/org/apache/jasper/compiler/JspDocumentParser.java
    tomcat/trunk/java/org/apache/jasper/compiler/Parser.java
    tomcat/trunk/test/org/apache/el/TestELEvaluation.java
    tomcat/trunk/test/org/apache/el/TestELInJsp.java
    tomcat/trunk/test/webapp/bug45nnn/bug45451.jspf
    tomcat/trunk/test/webapp/bug45nnn/bug45451d.jspx
    tomcat/trunk/webapps/docs/changelog.xml

Modified: tomcat/trunk/java/org/apache/el/parser/AstLiteralExpression.java
URL: 
http://svn.apache.org/viewvc/tomcat/trunk/java/org/apache/el/parser/AstLiteralExpression.java?rev=1634089&r1=1634088&r2=1634089&view=diff
==============================================================================
--- tomcat/trunk/java/org/apache/el/parser/AstLiteralExpression.java (original)
+++ tomcat/trunk/java/org/apache/el/parser/AstLiteralExpression.java Fri Oct 24 
16:28:48 2014
@@ -51,9 +51,10 @@ public final class AstLiteralExpression 
         StringBuilder buf = new StringBuilder(size);
         for (int i = 0; i < size; i++) {
             char c = image.charAt(i);
-            if (c == '\\' && i + 1 < size) {
+            if (c == '\\' && i + 2 < size) {
                 char c1 = image.charAt(i + 1);
-                if (c1 == '#' || c1 == '$')  {
+                char c2 = image.charAt(i + 2);
+                if ((c1 == '#' || c1 == '$') && c2 == '{')  {
                     c = c1;
                     i++;
                 }

Modified: tomcat/trunk/java/org/apache/jasper/compiler/ELParser.java
URL: 
http://svn.apache.org/viewvc/tomcat/trunk/java/org/apache/jasper/compiler/ELParser.java?rev=1634089&r1=1634088&r2=1634089&view=diff
==============================================================================
--- tomcat/trunk/java/org/apache/jasper/compiler/ELParser.java (original)
+++ tomcat/trunk/java/org/apache/jasper/compiler/ELParser.java Fri Oct 24 
16:28:48 2014
@@ -196,58 +196,39 @@ public class ELParser {
 
     /**
      * Skip until an EL expression ('${' || '#{') is reached, allowing escape
-     * sequences '\\' and '\$' and '\#'.
+     * sequences '\$' and '\#'.
      *
      * @return The text string up to the EL expression
      */
     private String skipUntilEL() {
-        char prev = 0;
         StringBuilder buf = new StringBuilder();
         while (hasNextChar()) {
             char ch = nextChar();
-            if (prev == '\\') {
-                if (ch == '$' || (!isDeferredSyntaxAllowedAsLiteral && ch == 
'#')) {
-                    prev = 0;
-                    buf.append(ch);
-                    continue;
-                } else if (ch == '\\') {
-                    // Not an escape (this time).
-                    // Optimisation - no need to set prev as it is unchanged
-                    buf.append('\\');
-                    continue;
+            if (ch == '\\') {
+                // Is this the start of a "\${" or "\#{" escape sequence?
+                char p0 = peek(0);
+                char p1 = peek(1);
+                if ((p0 == '$' || (p0 == '#' && 
!isDeferredSyntaxAllowedAsLiteral)) && p1 == '{') {
+                    buf.append(nextChar());
+                    buf.append(nextChar());
                 } else {
-                    // Not an escape
-                    prev = 0;
-                    buf.append('\\');
                     buf.append(ch);
-                    continue;
-                }
-            } else if (prev == '$'
-                    || (!isDeferredSyntaxAllowedAsLiteral && prev == '#')) {
-                if (ch == '{') {
-                    this.type = prev;
-                    prev = 0;
-                    break;
                 }
-                buf.append(prev);
-                prev = 0;
-            }
-            if (ch == '\\' || ch == '$'
-                    || (!isDeferredSyntaxAllowedAsLiteral && ch == '#')) {
-                prev = ch;
+            } else if ((ch == '$' || (ch == '#' && 
!isDeferredSyntaxAllowedAsLiteral)) &&
+                    peek(0) == '{') {
+                this.type = ch;
+                nextChar();
+                break;
             } else {
                 buf.append(ch);
             }
         }
-        if (prev != 0) {
-            buf.append(prev);
-        }
         return buf.toString();
     }
 
 
     /**
-     * Escape '\\', '$' and '#', inverting the unescaping performed in
+     * Escape '$' and '#', inverting the unescaping performed in
      * {@link #skipUntilEL()}.
      *
      * @param input Non-EL input to be escaped
@@ -438,6 +419,14 @@ public class ELParser {
         return expression.charAt(index++);
     }
 
+    private char peek(int advance) {
+        int target = index + advance;
+        if (target >= expression.length()) {
+            return (char) -1;
+        }
+        return expression.charAt(target);
+    }
+
     private int getIndex() {
         return index;
     }

Modified: tomcat/trunk/java/org/apache/jasper/compiler/JspDocumentParser.java
URL: 
http://svn.apache.org/viewvc/tomcat/trunk/java/org/apache/jasper/compiler/JspDocumentParser.java?rev=1634089&r1=1634088&r2=1634089&view=diff
==============================================================================
--- tomcat/trunk/java/org/apache/jasper/compiler/JspDocumentParser.java 
(original)
+++ tomcat/trunk/java/org/apache/jasper/compiler/JspDocumentParser.java Fri Oct 
24 16:28:48 2014
@@ -605,7 +605,11 @@ class JspDocumentParser
                         lastCh = ch;
                     }
                 } else if (lastCh == '\\' && (ch == '$' || ch == '#')) {
-                    if (pageInfo.isELIgnored()) {
+                    if (i + 1 < charBuffer.length() && charBuffer.charAt(i + 
1) == '{') {
+                        if (pageInfo.isELIgnored()) {
+                            ttext.write('\\');
+                        }
+                    } else {
                         ttext.write('\\');
                     }
                     ttext.write(ch);

Modified: tomcat/trunk/java/org/apache/jasper/compiler/Parser.java
URL: 
http://svn.apache.org/viewvc/tomcat/trunk/java/org/apache/jasper/compiler/Parser.java?rev=1634089&r1=1634088&r2=1634089&view=diff
==============================================================================
--- tomcat/trunk/java/org/apache/jasper/compiler/Parser.java (original)
+++ tomcat/trunk/java/org/apache/jasper/compiler/Parser.java Fri Oct 24 
16:28:48 2014
@@ -1275,7 +1275,7 @@ class Parser implements TagConstants {
 
     /*
      * Parse for a template text string until '<' or "${" or "#{" is 
encountered,
-     * recognizing escape sequences "<\%", "\$", and "\#".
+     * recognizing escape sequences "<\%", "\${", and "\#{".
      */
     private void parseTemplateText(Node parent) throws JasperException {
 
@@ -1292,39 +1292,53 @@ class Parser implements TagConstants {
         }
 
         while (reader.hasMoreInput()) {
-            int prev = ch;
             ch = reader.nextChar();
             if (ch == '<') {
-                reader.pushChar();
-                break;
-            } else if ((ch == '$' || ch == '#') && !pageInfo.isELIgnored()) {
-                if (!reader.hasMoreInput()) {
-                    ttext.write(ch);
+                // Check for "<\%"
+                if (reader.nextChar() == '\\') {
+                    if (reader.nextChar() == '%') {
+                        ttext.append('<');
+                        ttext.append('%');
+                    } else {
+                        reader.pushChar();
+                        reader.pushChar();
+                        reader.pushChar();
+                        break;
+                    }
+                } else {
+                    reader.pushChar();
+                    reader.pushChar();
                     break;
                 }
+            } else if (ch == '\\' && !pageInfo.isELIgnored()) {
+                int next = reader.nextChar();
+                if (next == '$' || next == '#') {
+                    if (reader.nextChar() == '{') {
+                        ttext.write(next);
+                        ttext.append('{');
+                    } else {
+                        ttext.append('\\');
+                        ttext.write(next);
+                        reader.pushChar();
+                    }
+                } else {
+                    ttext.append('\\');
+                    reader.pushChar();
+                }
+            } else if ((ch == '$' || ch == '#') && !pageInfo.isELIgnored()) {
                 if (reader.nextChar() == '{') {
                     reader.pushChar();
                     reader.pushChar();
                     break;
+                } else {
+                    reader.pushChar();
+                    ttext.write(ch);
                 }
+            } else {
                 ttext.write(ch);
-                reader.pushChar();
-                continue;
-            } else if (ch == '\\') {
-                if (!reader.hasMoreInput()) {
-                    ttext.write('\\');
-                    break;
-                }
-                char next = (char) reader.peekChar();
-                // Looking for \% or \$ or \#
-                if ((prev == '<' && next == '%') ||
-                        ((next == '$' || next == '#') &&
-                                !pageInfo.isELIgnored())) {
-                    ch = reader.nextChar();
-                }
             }
-            ttext.write(ch);
         }
+
         @SuppressWarnings("unused")
         Node unused = new Node.TemplateText(ttext.toString(), start, parent);
     }

Modified: tomcat/trunk/test/org/apache/el/TestELEvaluation.java
URL: 
http://svn.apache.org/viewvc/tomcat/trunk/test/org/apache/el/TestELEvaluation.java?rev=1634089&r1=1634088&r2=1634089&view=diff
==============================================================================
--- tomcat/trunk/test/org/apache/el/TestELEvaluation.java (original)
+++ tomcat/trunk/test/org/apache/el/TestELEvaluation.java Fri Oct 24 16:28:48 
2014
@@ -110,19 +110,19 @@ public class TestELEvaluation {
         assertEquals("\\", evaluateExpression("\\"));
         assertEquals("$", evaluateExpression("$"));
         assertEquals("#", evaluateExpression("#"));
-        assertEquals("$", evaluateExpression("\\$"));
-        assertEquals("#", evaluateExpression("\\#"));
-        assertEquals("\\$", evaluateExpression("\\\\$"));
-        assertEquals("\\#", evaluateExpression("\\\\#"));
+        assertEquals("\\$", evaluateExpression("\\$"));
+        assertEquals("\\#", evaluateExpression("\\#"));
+        assertEquals("\\\\$", evaluateExpression("\\\\$"));
+        assertEquals("\\\\#", evaluateExpression("\\\\#"));
         assertEquals("${", evaluateExpression("\\${"));
         assertEquals("#{", evaluateExpression("\\#{"));
         assertEquals("\\${", evaluateExpression("\\\\${"));
         assertEquals("\\#{", evaluateExpression("\\\\#{"));
 
-        // '\' is only an escape for '$' and '#'.
-        assertEquals("$", evaluateExpression("\\$"));
+        // '\' is only an escape for '${' and '#{'.
+        assertEquals("\\$", evaluateExpression("\\$"));
         assertEquals("${", evaluateExpression("\\${"));
-        assertEquals("$a", evaluateExpression("\\$a"));
+        assertEquals("\\$a", evaluateExpression("\\$a"));
         assertEquals("\\a", evaluateExpression("\\a"));
         assertEquals("\\\\", evaluateExpression("\\\\"));
     }

Modified: tomcat/trunk/test/org/apache/el/TestELInJsp.java
URL: 
http://svn.apache.org/viewvc/tomcat/trunk/test/org/apache/el/TestELInJsp.java?rev=1634089&r1=1634088&r2=1634089&view=diff
==============================================================================
--- tomcat/trunk/test/org/apache/el/TestELInJsp.java (original)
+++ tomcat/trunk/test/org/apache/el/TestELInJsp.java Fri Oct 24 16:28:48 2014
@@ -173,16 +173,18 @@ public class TestELInJsp extends TomcatB
         assertEcho(result, "01-${1+1}");
         assertEcho(result, "02-\\${1+1}");
         assertEcho(result, "03-\\\\${1+1}");
-        assertEcho(result, "04-2");
-        assertEcho(result, "05-${1+1}");
-        assertEcho(result, "06-\\2");
-        assertEcho(result, "07-\\${1+1}");
-        assertEcho(result, "08-\\\\2");
-        assertEcho(result, "09-2");
-        assertEcho(result, "10-#{1+1}");
-        assertEcho(result, "11-\\2");
-        assertEcho(result, "12-\\#{1+1}");
-        assertEcho(result, "13-\\\\2");
+        assertEcho(result, "04-\\$500");
+        assertEcho(result, "10-2");
+        assertEcho(result, "11-${1+1}");
+        assertEcho(result, "12-\\2");
+        assertEcho(result, "13-\\${1+1}");
+        assertEcho(result, "14-\\\\2");
+        assertEcho(result, "15-\\$500");
+        assertEcho(result, "20-2");
+        assertEcho(result, "21-#{1+1}");
+        assertEcho(result, "22-\\2");
+        assertEcho(result, "23-\\#{1+1}");
+        assertEcho(result, "24-\\\\2");
 
         res = getUrl("http://localhost:"; + getPort() + 
"/test/bug45nnn/bug45451c.jsp");
         result = res.toString();
@@ -193,16 +195,18 @@ public class TestELInJsp extends TomcatB
         assertEcho(result, "01-\\${1+1}");
         assertEcho(result, "02-\\\\${1+1}");
         assertEcho(result, "03-\\\\\\${1+1}");
-        assertEcho(result, "04-${1+1}");
-        assertEcho(result, "05-\\${1+1}");
-        assertEcho(result, "06-\\${1+1}");
-        assertEcho(result, "07-\\\\${1+1}");
-        assertEcho(result, "08-\\\\${1+1}");
-        assertEcho(result, "09-#{1+1}");
-        assertEcho(result, "10-\\#{1+1}");
-        assertEcho(result, "11-\\#{1+1}");
-        assertEcho(result, "12-\\\\#{1+1}");
-        assertEcho(result, "13-\\\\#{1+1}");
+        assertEcho(result, "04-\\$500");
+        assertEcho(result, "10-${1+1}");
+        assertEcho(result, "11-\\${1+1}");
+        assertEcho(result, "12-\\${1+1}");
+        assertEcho(result, "13-\\\\${1+1}");
+        assertEcho(result, "14-\\\\${1+1}");
+        assertEcho(result, "15-\\$500");
+        assertEcho(result, "20-#{1+1}");
+        assertEcho(result, "21-\\#{1+1}");
+        assertEcho(result, "22-\\#{1+1}");
+        assertEcho(result, "23-\\\\#{1+1}");
+        assertEcho(result, "24-\\\\#{1+1}");
 
         res = getUrl("http://localhost:"; + getPort() + 
"/test/bug45nnn/bug45451d.jspx");
         result = res.toString();
@@ -212,16 +216,18 @@ public class TestELInJsp extends TomcatB
         assertEcho(result, "01-${1+1}");
         assertEcho(result, "02-\\${1+1}");
         assertEcho(result, "03-\\\\${1+1}");
-        assertEcho(result, "04-2");
-        assertEcho(result, "05-${1+1}");
-        assertEcho(result, "06-\\${1+1}");
-        assertEcho(result, "07-\\\\${1+1}");
-        assertEcho(result, "08-\\\\\\${1+1}");
-        assertEcho(result, "09-2");
-        assertEcho(result, "10-#{1+1}");
-        assertEcho(result, "11-\\#{1+1}");
-        assertEcho(result, "12-\\\\#{1+1}");
-        assertEcho(result, "13-\\\\\\#{1+1}");
+        assertEcho(result, "04-\\$500");
+        assertEcho(result, "10-2");
+        assertEcho(result, "11-${1+1}");
+        assertEcho(result, "12-\\${1+1}");
+        assertEcho(result, "13-\\\\${1+1}");
+        assertEcho(result, "14-\\\\\\${1+1}");
+        assertEcho(result, "15-\\$500");
+        assertEcho(result, "20-2");
+        assertEcho(result, "21-#{1+1}");
+        assertEcho(result, "22-\\#{1+1}");
+        assertEcho(result, "23-\\\\#{1+1}");
+        assertEcho(result, "24-\\\\\\#{1+1}");
 
         res = getUrl("http://localhost:"; + getPort() + 
"/test/bug45nnn/bug45451e.jsp");
         result = res.toString();
@@ -232,16 +238,18 @@ public class TestELInJsp extends TomcatB
         assertEcho(result, "01-${1+1}");
         assertEcho(result, "02-\\${1+1}");
         assertEcho(result, "03-\\\\${1+1}");
-        assertEcho(result, "04-2");
-        assertEcho(result, "05-${1+1}");
-        assertEcho(result, "06-\\2");
-        assertEcho(result, "07-\\${1+1}");
-        assertEcho(result, "08-\\\\2");
-        assertEcho(result, "09-#{1+1}");
-        assertEcho(result, "10-\\#{1+1}");
-        assertEcho(result, "11-\\#{1+1}");
-        assertEcho(result, "12-\\\\#{1+1}");
-        assertEcho(result, "13-\\\\#{1+1}");
+        assertEcho(result, "04-\\$500");
+        assertEcho(result, "10-2");
+        assertEcho(result, "11-${1+1}");
+        assertEcho(result, "12-\\2");
+        assertEcho(result, "13-\\${1+1}");
+        assertEcho(result, "14-\\\\2");
+        assertEcho(result, "15-\\$500");
+        assertEcho(result, "20-#{1+1}");
+        assertEcho(result, "21-\\#{1+1}");
+        assertEcho(result, "22-\\#{1+1}");
+        assertEcho(result, "23-\\\\#{1+1}");
+        assertEcho(result, "24-\\\\#{1+1}");
     }
 
     @Test

Modified: tomcat/trunk/test/webapp/bug45nnn/bug45451.jspf
URL: 
http://svn.apache.org/viewvc/tomcat/trunk/test/webapp/bug45nnn/bug45451.jspf?rev=1634089&r1=1634088&r2=1634089&view=diff
==============================================================================
--- tomcat/trunk/test/webapp/bug45nnn/bug45451.jspf (original)
+++ tomcat/trunk/test/webapp/bug45nnn/bug45451.jspf Fri Oct 24 16:28:48 2014
@@ -18,13 +18,15 @@
 <p>01-\${1+1}</p>
 <p>02-\\${1+1}</p>
 <p>03-\\\${1+1}</p>
-<tags:echo echo="04-${1+1}" />
-<tags:echo echo="05-\${1+1}" />
-<tags:echo echo="06-\\${1+1}" />
-<tags:echo echo="07-\\\${1+1}" />
-<tags:echo echo="08-\\\\${1+1}" />
-<tags:echo-deferred echo="09-#{1+1}" />
-<tags:echo-deferred echo="10-\#{1+1}" />
-<tags:echo-deferred echo="11-\\#{1+1}" />
-<tags:echo-deferred echo="12-\\\#{1+1}" />
-<tags:echo-deferred echo="13-\\\\#{1+1}" />
\ No newline at end of file
+<p>04-\$500</p>
+<tags:echo echo="10-${1+1}" />
+<tags:echo echo="11-\${1+1}" />
+<tags:echo echo="12-\\${1+1}" />
+<tags:echo echo="13-\\\${1+1}" />
+<tags:echo echo="14-\\\\${1+1}" />
+<tags:echo echo="15-\$500" />
+<tags:echo-deferred echo="20-#{1+1}" />
+<tags:echo-deferred echo="21-\#{1+1}" />
+<tags:echo-deferred echo="22-\\#{1+1}" />
+<tags:echo-deferred echo="23-\\\#{1+1}" />
+<tags:echo-deferred echo="24-\\\\#{1+1}" />
\ No newline at end of file

Modified: tomcat/trunk/test/webapp/bug45nnn/bug45451d.jspx
URL: 
http://svn.apache.org/viewvc/tomcat/trunk/test/webapp/bug45nnn/bug45451d.jspx?rev=1634089&r1=1634088&r2=1634089&view=diff
==============================================================================
--- tomcat/trunk/test/webapp/bug45nnn/bug45451d.jspx (original)
+++ tomcat/trunk/test/webapp/bug45nnn/bug45451d.jspx Fri Oct 24 16:28:48 2014
@@ -25,16 +25,18 @@
     <p>01-\${1+1}</p>
     <p>02-\\${1+1}</p>
     <p>03-\\\${1+1}</p>
-    <tags:echo echo="04-${1+1}" />
-    <tags:echo echo="05-\${1+1}" />
-    <tags:echo echo="06-\\${1+1}" />
-    <tags:echo echo="07-\\\${1+1}" />
-    <tags:echo echo="08-\\\\${1+1}" />
-    <tags:echo-deferred echo="09-#{1+1}" />
-    <tags:echo-deferred echo="10-\#{1+1}" />
-    <tags:echo-deferred echo="11-\\#{1+1}" />
-    <tags:echo-deferred echo="12-\\\#{1+1}" />
-    <tags:echo-deferred echo="13-\\\\#{1+1}" />
+    <p>04-\$500</p>
+    <tags:echo echo="10-${1+1}" />
+    <tags:echo echo="11-\${1+1}" />
+    <tags:echo echo="12-\\${1+1}" />
+    <tags:echo echo="13-\\\${1+1}" />
+    <tags:echo echo="14-\\\\${1+1}" />
+    <tags:echo echo="15-\$500" />
+    <tags:echo-deferred echo="20-#{1+1}" />
+    <tags:echo-deferred echo="21-\#{1+1}" />
+    <tags:echo-deferred echo="22-\\#{1+1}" />
+    <tags:echo-deferred echo="23-\\\#{1+1}" />
+    <tags:echo-deferred echo="24-\\\\#{1+1}" />
   </body>
 </html>
 </jsp:root>
\ No newline at end of file

Modified: tomcat/trunk/webapps/docs/changelog.xml
URL: 
http://svn.apache.org/viewvc/tomcat/trunk/webapps/docs/changelog.xml?rev=1634089&r1=1634088&r2=1634089&view=diff
==============================================================================
--- tomcat/trunk/webapps/docs/changelog.xml (original)
+++ tomcat/trunk/webapps/docs/changelog.xml Fri Oct 24 16:28:48 2014
@@ -228,6 +228,13 @@
         an error. The second and subsequent calls for the same class will be
         ignored. (markt)
       </fix>
+      <fix>
+        <bug>57136</bug>: Ensure only <code>\${</code> and <code>\#{</code> are
+        treated as escapes for <code>${</code> and <code>#{</code> rather than
+        <code>\$</code> and <code>\#</code> being treated as escapes for
+        <code>$</code> and <code>#</code> when processing literal expressions 
in
+        expression language. (markt)
+      </fix>
     </changelog>
   </subsection>
   <subsection name="Cluster">



---------------------------------------------------------------------
To unsubscribe, e-mail: dev-unsubscr...@tomcat.apache.org
For additional commands, e-mail: dev-h...@tomcat.apache.org

Reply via email to