You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@tomcat.apache.org by ma...@apache.org on 2015/11/05 20:55:01 UTC

svn commit: r1712859 - in /tomcat/trunk: java/org/apache/jasper/ java/org/apache/jasper/compiler/ test/org/apache/el/ test/org/apache/jasper/compiler/ test/webapp/

Author: markt
Date: Thu Nov  5 19:55:00 2015
New Revision: 1712859

URL: http://svn.apache.org/viewvc?rev=1712859&view=rev
Log:
Further work on https://bz.apache.org/bugzilla/show_bug.cgi?id=57136
Add a configuration option that allows EL expressions in attribute values to use JSP attribute quoting or not. The default (and specification compliant behaviour) is not to.

Added:
    tomcat/trunk/test/webapp/el-misc-no-quote-attribute-el.jsp
      - copied unchanged from r1712812, tomcat/trunk/test/webapp/el-misc.jsp
    tomcat/trunk/test/webapp/el-misc-with-quote-attribute-el.jsp   (with props)
Removed:
    tomcat/trunk/test/webapp/el-misc.jsp
Modified:
    tomcat/trunk/java/org/apache/jasper/EmbeddedServletOptions.java
    tomcat/trunk/java/org/apache/jasper/JspC.java
    tomcat/trunk/java/org/apache/jasper/Options.java
    tomcat/trunk/java/org/apache/jasper/compiler/AttributeParser.java
    tomcat/trunk/java/org/apache/jasper/compiler/Parser.java
    tomcat/trunk/test/org/apache/el/TestELInJsp.java
    tomcat/trunk/test/org/apache/jasper/compiler/TestAttributeParser.java

Modified: tomcat/trunk/java/org/apache/jasper/EmbeddedServletOptions.java
URL: http://svn.apache.org/viewvc/tomcat/trunk/java/org/apache/jasper/EmbeddedServletOptions.java?rev=1712859&r1=1712858&r2=1712859&view=diff
==============================================================================
--- tomcat/trunk/java/org/apache/jasper/EmbeddedServletOptions.java (original)
+++ tomcat/trunk/java/org/apache/jasper/EmbeddedServletOptions.java Thu Nov  5 19:55:00 2015
@@ -205,6 +205,8 @@ public final class EmbeddedServletOption
      */
     private boolean strictQuoteEscaping = true;
 
+    private boolean quoteAttributeEL = false;
+
     public String getProperty(String name ) {
         return settings.getProperty( name );
     }
@@ -215,6 +217,15 @@ public final class EmbeddedServletOption
         }
     }
 
+    public void setQuoteAttributeEL(boolean b) {
+        this.quoteAttributeEL = b;
+    }
+
+    @Override
+    public boolean getQuoteAttributeEL() {
+        return quoteAttributeEL;
+    }
+
     /**
      * Are we keeping generated code around?
      */
@@ -765,6 +776,18 @@ public final class EmbeddedServletOption
             }
         }
 
+        String quoteAttributeEL = config.getInitParameter("quoteAttributeEL");
+        if (quoteAttributeEL != null) {
+            if (quoteAttributeEL.equalsIgnoreCase("true")) {
+                this.quoteAttributeEL = true;
+            } else if (quoteAttributeEL.equalsIgnoreCase("false")) {
+                this.quoteAttributeEL = false;
+            } else {
+                if (log.isWarnEnabled()) {
+                    log.warn(Localizer.getMessage("jsp.warning.quoteAttributeEL"));
+                }
+            }
+        }
 
         // Setup the global Tag Libraries location cache for this
         // web-application.

Modified: tomcat/trunk/java/org/apache/jasper/JspC.java
URL: http://svn.apache.org/viewvc/tomcat/trunk/java/org/apache/jasper/JspC.java?rev=1712859&r1=1712858&r2=1712859&view=diff
==============================================================================
--- tomcat/trunk/java/org/apache/jasper/JspC.java (original)
+++ tomcat/trunk/java/org/apache/jasper/JspC.java Thu Nov  5 19:55:00 2015
@@ -137,6 +137,7 @@ public class JspC extends Task implement
     protected static final String SWITCH_VALIDATE_XML = "-validateXml";
     protected static final String SWITCH_NO_BLOCK_EXTERNAL = "-no-blockExternal";
     protected static final String SWITCH_NO_STRICT_QUOTE_ESCAPING = "-no-strictQuoteEscaping";
+    protected static final String SWITCH_QUOTE_ATTRIBUTE_EL = "-quoteAttributeEL";
     protected static final String SHOW_SUCCESS ="-s";
     protected static final String LIST_ERRORS = "-l";
     protected static final int INC_WEBXML = 10;
@@ -171,6 +172,7 @@ public class JspC extends Task implement
     protected boolean validateXml;
     protected boolean blockExternal = true;
     protected boolean strictQuoteEscaping = true;
+    protected boolean quoteAttributeEL = false;
     protected boolean xpoweredBy;
     protected boolean mappedFile = false;
     protected boolean poolingEnabled = true;
@@ -387,6 +389,8 @@ public class JspC extends Task implement
                 setBlockExternal(false);
             } else if (tok.equals(SWITCH_NO_STRICT_QUOTE_ESCAPING)) {
                 setStrictQuoteEscaping(false);
+            } else if (tok.equals(SWITCH_QUOTE_ATTRIBUTE_EL)) {
+                setQuoteAttributeEL(true);
             } else {
                 if (tok.startsWith("-")) {
                     throw new JasperException("Unrecognized option: " + tok +
@@ -903,6 +907,15 @@ public class JspC extends Task implement
         return strictQuoteEscaping;
     }
 
+    public void setQuoteAttributeEL(boolean b) {
+        quoteAttributeEL = b;
+    }
+
+    @Override
+    public boolean getQuoteAttributeEL() {
+        return quoteAttributeEL;
+    }
+
     public void setListErrors( boolean b ) {
         listErrors = b;
     }

Modified: tomcat/trunk/java/org/apache/jasper/Options.java
URL: http://svn.apache.org/viewvc/tomcat/trunk/java/org/apache/jasper/Options.java?rev=1712859&r1=1712858&r2=1712859&view=diff
==============================================================================
--- tomcat/trunk/java/org/apache/jasper/Options.java (original)
+++ tomcat/trunk/java/org/apache/jasper/Options.java Thu Nov  5 19:55:00 2015
@@ -237,4 +237,10 @@ public interface Options {
      *         the JSP specification should be applied to scriplet expression.
      */
     public boolean getStrictQuoteEscaping();
+
+    /**
+     * @return {@code true} if EL expressions used within attributes should have
+     *         the quoting rules in JSP.1.6 applied to the expression.
+     */
+    public boolean getQuoteAttributeEL();
 }

Modified: tomcat/trunk/java/org/apache/jasper/compiler/AttributeParser.java
URL: http://svn.apache.org/viewvc/tomcat/trunk/java/org/apache/jasper/compiler/AttributeParser.java?rev=1712859&r1=1712858&r2=1712859&view=diff
==============================================================================
--- tomcat/trunk/java/org/apache/jasper/compiler/AttributeParser.java (original)
+++ tomcat/trunk/java/org/apache/jasper/compiler/AttributeParser.java Thu Nov  5 19:55:00 2015
@@ -41,15 +41,16 @@ public class AttributeParser {
      *                      Are deferred expressions treated as literals?
      * @param strict        Should the rules of JSP.1.6 for escpaing quotes be
      *                      strictly applied?
+     * @param quoteAttributeEL
      * @return              An unquoted JSP attribute that, if it contains
      *                      expression language can be safely passed to the EL
      *                      processor without fear of ambiguity.
      */
     public static String getUnquoted(String input, char quote,
             boolean isELIgnored, boolean isDeferredSyntaxAllowedAsLiteral,
-            boolean strict) {
+            boolean strict, boolean quoteAttributeEL) {
         return (new AttributeParser(input, quote, isELIgnored,
-                isDeferredSyntaxAllowedAsLiteral, strict)).getUnquoted();
+                isDeferredSyntaxAllowedAsLiteral, strict, quoteAttributeEL)).getUnquoted();
     }
 
     /* The quoted input string. */
@@ -70,6 +71,8 @@ public class AttributeParser {
      */
     private final boolean strict;
 
+    private final boolean quoteAttributeEL;
+
     /* The type ($ or #) of expression. Literals have a type of null. */
     private final char type;
 
@@ -94,13 +97,14 @@ public class AttributeParser {
      */
     private AttributeParser(String input, char quote,
             boolean isELIgnored, boolean isDeferredSyntaxAllowedAsLiteral,
-            boolean strict) {
+            boolean strict, boolean quoteAttributeEL) {
         this.input = input;
         this.quote = quote;
         this.isELIgnored = isELIgnored;
         this.isDeferredSyntaxAllowedAsLiteral =
             isDeferredSyntaxAllowedAsLiteral;
         this.strict = strict;
+        this.quoteAttributeEL = quoteAttributeEL;
         this.type = getType(input);
         this.size = input.length();
         result = new StringBuilder(size);
@@ -189,7 +193,12 @@ public class AttributeParser {
         boolean insideLiteral = false;
         char literalQuote = 0;
         while (i < size && !endEL) {
-            char ch = input.charAt(i++);
+            char ch;
+            if (quoteAttributeEL) {
+                ch = nextChar();
+            } else {
+                ch = input.charAt(i++);
+            }
             if (ch == '\'' || ch == '\"') {
                 if (insideLiteral) {
                     if (literalQuote == ch) {
@@ -203,7 +212,11 @@ public class AttributeParser {
             } else if (ch == '\\') {
                 result.append(ch);
                 if (insideLiteral && size < i) {
-                    ch = input.charAt(i++);
+                    if (quoteAttributeEL) {
+                        ch = nextChar();
+                    } else {
+                        ch = input.charAt(i++);
+                    }
                     result.append(ch);
                 }
             } else if (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=1712859&r1=1712858&r2=1712859&view=diff
==============================================================================
--- tomcat/trunk/java/org/apache/jasper/compiler/Parser.java (original)
+++ tomcat/trunk/java/org/apache/jasper/compiler/Parser.java Thu Nov  5 19:55:00 2015
@@ -264,8 +264,11 @@ class Parser implements TagConstants {
      * ('%>"' | TRANSLATION_ERROR)
      */
     private String parseAttributeValue(String qName, String watch, boolean ignoreEL) throws JasperException {
+        boolean quoteAttributeEL = ctxt.getOptions().getQuoteAttributeEL();
         Mark start = reader.mark();
-        Mark stop = reader.skipUntilIgnoreEsc(watch, ignoreEL);
+        // In terms of finding the end of the value, quoting EL is equivalent to
+        // ignoring it.
+        Mark stop = reader.skipUntilIgnoreEsc(watch, ignoreEL || quoteAttributeEL);
         if (stop == null) {
             err.jspError(start, "jsp.error.attribute.unterminated", qName);
         }
@@ -282,7 +285,8 @@ class Parser implements TagConstants {
             ret = AttributeParser.getUnquoted(reader.getText(start, stop),
                     quote, isElIgnored,
                     pageInfo.isDeferredSyntaxAllowedAsLiteral(),
-                    ctxt.getOptions().getStrictQuoteEscaping());
+                    ctxt.getOptions().getStrictQuoteEscaping(),
+                    quoteAttributeEL);
         } catch (IllegalArgumentException iae) {
             err.jspError(start, iae.getMessage());
         }

Modified: tomcat/trunk/test/org/apache/el/TestELInJsp.java
URL: http://svn.apache.org/viewvc/tomcat/trunk/test/org/apache/el/TestELInJsp.java?rev=1712859&r1=1712858&r2=1712859&view=diff
==============================================================================
--- tomcat/trunk/test/org/apache/el/TestELInJsp.java (original)
+++ tomcat/trunk/test/org/apache/el/TestELInJsp.java Thu Nov  5 19:55:00 2015
@@ -16,6 +16,7 @@
  */
 package org.apache.el;
 
+import java.io.File;
 import java.math.BigDecimal;
 import java.util.Collections;
 
@@ -24,7 +25,11 @@ import javax.servlet.DispatcherType;
 import org.junit.Assert;
 import org.junit.Test;
 
+import org.apache.catalina.Wrapper;
+import org.apache.catalina.core.StandardContext;
+import org.apache.catalina.startup.Tomcat;
 import org.apache.catalina.startup.TomcatBaseTest;
+import org.apache.jasper.servlet.JasperInitializer;
 import org.apache.tomcat.util.buf.ByteChunk;
 
 /**
@@ -289,10 +294,43 @@ public class TestELInJsp extends TomcatB
     }
 
     @Test
-    public void testELMisc() throws Exception {
-        getTomcatInstanceTestWebapp(false, true);
+    public void testELMiscNoQuoteAttributeEL() throws Exception {
+        doTestELMisc(false);
+    }
+
+    @Test
+    public void testELMiscWithQuoteAttributeEL() throws Exception {
+        doTestELMisc(true);
+    }
+
+    private void doTestELMisc(boolean quoteAttributeEL) throws Exception {
+        Tomcat tomcat = getTomcatInstance();
+
+        // Create the context (don't use addWebapp as we want to modify the
+        // JSP Servlet settings).
+        File appDir = new File("test/webapp");
+        StandardContext ctxt = (StandardContext) tomcat.addContext(
+                null, "/test", appDir.getAbsolutePath());
+
+        ctxt.addServletContainerInitializer(new JasperInitializer(), null);
+
+        // Configure the defaults and then tweak the JSP servlet settings
+        // Note: Min value for maxLoadedJsps is 2
+        Tomcat.initWebappDefaults(ctxt);
+        Wrapper w = (Wrapper) ctxt.findChild("jsp");
+
+        String jspName;
+        if (quoteAttributeEL) {
+            jspName = "/test/el-misc-with-quote-attribute-el.jsp";
+            w.addInitParameter("quoteAttributeEL", "true");
+        } else {
+            jspName = "/test/el-misc-no-quote-attribute-el.jsp";
+            w.addInitParameter("quoteAttributeEL", "false");
+        }
+
+        tomcat.start();
 
-        ByteChunk res = getUrl("http://localhost:" + getPort() + "/test/el-misc.jsp");
+        ByteChunk res = getUrl("http://localhost:" + getPort() + jspName);
         String result = res.toString();
 
         assertEcho(result, "00-\\\\\\\"${'hello world'}");

Modified: tomcat/trunk/test/org/apache/jasper/compiler/TestAttributeParser.java
URL: http://svn.apache.org/viewvc/tomcat/trunk/test/org/apache/jasper/compiler/TestAttributeParser.java?rev=1712859&r1=1712858&r2=1712859&view=diff
==============================================================================
--- tomcat/trunk/test/org/apache/jasper/compiler/TestAttributeParser.java (original)
+++ tomcat/trunk/test/org/apache/jasper/compiler/TestAttributeParser.java Thu Nov  5 19:55:00 2015
@@ -171,14 +171,14 @@ public class TestAttributeParser {
         ctx.setFunctionMapper(new FMapper());
         ValueExpression ve = exprFactory.createValueExpression(ctx,
                 AttributeParser.getUnquoted(expression, quote, false, false,
-                        false),
+                        false, false),
                 String.class);
         return (String) ve.getValue(ctx);
     }
 
     private String parseScriptExpression(String expression, char quote) {
         return AttributeParser.getUnquoted(expression, quote, false, false,
-                false);
+                false, false);
     }
 
     public static class FMapper extends FunctionMapper {

Added: tomcat/trunk/test/webapp/el-misc-with-quote-attribute-el.jsp
URL: http://svn.apache.org/viewvc/tomcat/trunk/test/webapp/el-misc-with-quote-attribute-el.jsp?rev=1712859&view=auto
==============================================================================
--- tomcat/trunk/test/webapp/el-misc-with-quote-attribute-el.jsp (added)
+++ tomcat/trunk/test/webapp/el-misc-with-quote-attribute-el.jsp Thu Nov  5 19:55:00 2015
@@ -0,0 +1,44 @@
+<%--
+ Licensed to the Apache Software Foundation (ASF) under one or more
+  contributor license agreements.  See the NOTICE file distributed with
+  this work for additional information regarding copyright ownership.
+  The ASF licenses this file to You under the Apache License, Version 2.0
+  (the "License"); you may not use this file except in compliance with
+  the License.  You may obtain a copy of the License at
+
+      http://www.apache.org/licenses/LICENSE-2.0
+
+  Unless required by applicable law or agreed to in writing, software
+  distributed under the License is distributed on an "AS IS" BASIS,
+  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+  See the License for the specific language governing permissions and
+  limitations under the License.
+--%>
+<%@ taglib prefix="tags" tagdir="/WEB-INF/tags" %>
+<html>
+  <head><title>Misc EL test cases</title></head>
+  <body>
+    <p>00-\\\"\${'hello world'}</p>
+    <p>01-\\\"\\${'hello world'}</p>
+    <tags:echo echo="02-\\\"\${'hello world'}" />
+    <tags:echo echo="03-\\\"\\${'hello world'}" />
+    <tags:echo echo="${'2'}az-04" />
+    <tags:echo echo="05-a${'2'}z" />
+    <tags:echo echo="06-az${'2'}" />
+    <tags:echo echo="${\"2\"}az-07" />
+    <tags:echo echo="08-a${\"2\"}z" />
+    <tags:echo echo="09-az${\"2\"}" />
+    <tags:echo echo="10-\${'foo'}${'bar'}" />
+    <tags:echo echo="11-${\"\\\\\"}\"}" />
+    <tags:echo echo="12-${'foo'}\\${'bar'}\\${'baz'}" />
+    <tags:echo echo="13-${'foo'}\\${\"bar\"}\\${'baz'}" />
+    <tags:echo echo="14-${\"foo\"}\\${'bar'}\\${\"baz\"}" />
+    <tags:echo echo='15-${\'foo\'}\\${"bar"}\\${\'baz\'}' />
+    <tags:echo echo='16-${"foo"}\\${\'bar\'}\\${"baz"}' />
+    <tags:echo echo='17-${"foo"}\\${"&"}${"apos;bar"}${"&"}${"apos;"}\\${"&"}${"quot;baz"}${"&"}${"quot;"}' />
+    <tags:echo echo='18-${((x,y)->x+y)(1,2)}' />
+    <tags:echo echo='19-${{1,2,3,4}.stream().max().orElse(-1)}' />
+    <p>20-${{1,2,3,4}.stream().max().orElse(-1)}</p>
+    <tags:echo echo='21-${{1,2,3,4}.stream().sorted().map(u->{"value":u+10}).toList()}' />
+    <p>22-${{1,2,3,4}.stream().sorted().map(u->{"value":u+10}).toList()}</p>  </body>
+</html>
\ No newline at end of file

Propchange: tomcat/trunk/test/webapp/el-misc-with-quote-attribute-el.jsp
------------------------------------------------------------------------------
    svn:eol-style = native



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