Fix the remaining EL / TCK issues. With this patch the EL TCK tests pass and my test...
authormarkt <markt@13f79535-47bb-0310-9956-ffa450edef68>
Sun, 19 Oct 2008 21:26:40 +0000 (21:26 +0000)
committermarkt <markt@13f79535-47bb-0310-9956-ffa450edef68>
Sun, 19 Oct 2008 21:26:40 +0000 (21:26 +0000)
git-svn-id: https://svn.apache.org/repos/asf/tomcat/trunk@706071 13f79535-47bb-0310-9956-ffa450edef68

java/org/apache/jasper/compiler/Generator.java

index afbf2d8..f9a28c0 100644 (file)
@@ -806,8 +806,8 @@ class Generator {
                 }
                 return v;
             } else if (attr.isELInterpreterInput()) {
-                v = JspUtil.interpreterCall(this.isTagFile, v, expectedType,
-                        attr.getEL().getMapName(), false);
+                v = attributeValueWithEL(this.isTagFile, v, expectedType,
+                        attr.getEL().getMapName());
                 if (encode) {
                     return "org.apache.jasper.runtime.JspRuntimeLibrary.URLEncode("
                             + v + ", request.getCharacterEncoding())";
@@ -824,6 +824,68 @@ class Generator {
             }
         }
 
+
+        /*
+         * When interpreting the EL attribute value, literals outside the EL
+         * must not be unescaped but the EL processor will unescape them.
+         * Therefore, make sure only the EL expressions are processed by the EL
+         * processor.
+         */
+        private String attributeValueWithEL(boolean isTag, String tx,
+                Class<?> expectedType, String mapName) {
+            if (tx==null) return null;
+            int size = tx.length();
+            StringBuffer output = new StringBuffer(size);
+            boolean el = false;
+            int i = 0;
+            int mark = 0;
+            char ch;
+            
+            while(i < size){
+                ch = tx.charAt(i);
+                
+                // Start of an EL expression
+                if (!el && i+1 < size && ch == '$' && tx.charAt(i+1)=='{') {
+                    if (mark < i) {
+                        if (output.length() > 0) {
+                            output.append(" + ");
+                        }
+                        output.append(quote(tx.substring(mark, i)));
+                    }
+                    mark = i;
+                    el = true;
+                    i += 2;
+                } else if (ch=='\\' && i+1 < size &&
+                        (tx.charAt(i+1)=='$' || tx.charAt(i+1)=='}')) { 
+                    // Skip an escaped $ or }
+                    i += 2;
+                } else if (el && ch=='}') {
+                    // End of an EL expression
+                    if (output.length() > 0) {
+                        output.append(" + ");
+                    }
+                    output.append(
+                            JspUtil.interpreterCall(isTag,
+                                    tx.substring(mark, i+1), expectedType,
+                                    mapName, false));
+                    mark = i + 1;
+                    el = false;
+                    ++i;
+                } else {
+                    // Nothing to see here - move to next character
+                    ++i;
+                }
+            }
+            if (!el && mark < i) {
+                if (output.length() > 0) {
+                    output.append(" + ");
+                }
+                output.append(quote(tx.substring(mark, i)));
+            }
+            return output.toString();
+        }
+
+
         /**
          * Prints the attribute value specified in the param action, in the form
          * of name=value string.
@@ -2836,8 +2898,8 @@ class Generator {
                     // run attrValue through the expression interpreter
                     String mapName = (attr.getEL() != null) ? attr.getEL()
                             .getMapName() : null;
-                    attrValue = JspUtil.interpreterCall(this.isTagFile,
-                            attrValue, c[0], mapName, false);
+                    attrValue = attributeValueWithEL(this.isTagFile,
+                            attrValue, c[0], mapName);
                 }
             } else {
                 attrValue = convertString(c[0], attrValue, localName,