Start line:  
End line:  

Snippet Preview

Snippet HTML Code

Stack Overflow Questions
  /*
   * 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.
  */
 
 package org.apache.jasper.compiler;
 
 import static org.jboss.web.JasperMessages.MESSAGES;

Converts a JSP attribute value into the unquoted equivalent. The attribute may contain EL expressions, in which case care needs to be taken to avoid any ambiguities. For example, consider the attribute values "${1+1}" and "\${1+1}". After unquoting, both appear as "${1+1}" but the first should evaluate to "2" and the second to "${1+1}". Literal \, $ and # need special treatment to ensure there is no ambiguity. The JSP attribute unquoting covers \\, \", \', \$, \#, %\>, <\%, &apos; and &quot;
 
 public class AttributeParser {
 
     /* System property that controls if the strict quoting rules are applied. */ 
     private static final boolean STRICT_QUOTE_ESCAPING = Boolean.valueOf(
             System.getProperty(
                     "org.apache.jasper.compiler.Parser.STRICT_QUOTE_ESCAPING",
                     "true")).booleanValue();

    
Parses the provided input String as a JSP attribute and returns an unquoted value.

Parameters:
input The input.
quote The quote character for the attribute or 0 for scripting expressions.
isELIgnored Is expression language being ignored on the page where the JSP attribute is defined.
isDeferredSyntaxAllowedAsLiteral Are deferred expressions treated as literals?
Returns:
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 inputchar quote,
             boolean isELIgnoredboolean isDeferredSyntaxAllowedAsLiteral) {
         return (new AttributeParser(inputquoteisELIgnored,
                 isDeferredSyntaxAllowedAsLiteral,
                 )).getUnquoted();
     }

    
Provided solely for unit test purposes and allows per call overriding of the STRICT_QUOTE_ESCAPING system property.

Parameters:
input The input.
quote The quote character for the attribute or 0 for scripting expressions.
isELIgnored Is expression language being ignored on the page where the JSP attribute is defined.
isDeferredSyntaxAllowedAsLiteral Are deferred expressions treated as literals?
strict The value to use for STRICT_QUOTE_ESCAPING.
Returns:
An unquoted JSP attribute that, if it contains expression language can be safely passed to the EL processor without fear of ambiguity.
 
     protected static String getUnquoted(String inputchar quote,
             boolean isELIgnoredboolean isDeferredSyntaxAllowedAsLiteral,
             boolean strict) {
         return (new AttributeParser(inputquoteisELIgnored,
                 isDeferredSyntaxAllowedAsLiteralstrict)).getUnquoted();
     }
 
     /* The quoted input string. */
     private final String input;
     
     /* The quote used for the attribute - null for scripting expressions. */
     private final char quote;
     
     /* Is expression language being ignored - affects unquoting. \$ and \# are
      * treated as literals rather than quoted values. */
     private final boolean isELIgnored;
     
     /* Are deferred expression treated as literals */
     private final boolean isDeferredSyntaxAllowedAsLiteral;
     
     /* Overrides the STRICT_QUOTE_ESCAPING. Used for Unit tests only. */
     private final boolean strict;
     
    /* The type ($ or #) of expression. Literals have a type of null. */
    private char type;
    
    /* The length of the quoted input string. */
    private final int size;
    
    /* Tracks the current position of the parser in the input String. */
    private int i = 0;
    
    /* Indicates if the last character returned by nextChar() was escaped. */
    private boolean lastChEscaped = false;
    
    /* The unquoted result. */
    private StringBuilder result;


    
For test purposes.

Parameters:
input
quote
strict
    private AttributeParser(String inputchar quote,
            boolean isELIgnoredboolean isDeferredSyntaxAllowedAsLiteral,
            boolean strict) {
        this. = input;
        this. = quote;
        this. = isELIgnored;
        this. =
            isDeferredSyntaxAllowedAsLiteral;
        this. = strict;
        this. = getType(input);
        this. = input.length();
         = new StringBuilder();
    }
    /*
     * Work through input looking for literals and expressions until the input
     * has all been read.
     */
    private String getUnquoted() {
        while ( < ) {
            parseLiteral();
            parseEL();
        }
        return .toString();
    }
    /*
     * This method gets the next unquoted character and looks for
     * - literals that need to be converted for EL processing
     *   \ -> type{'\\'}
     *   $ -> type{'$'}
     *   # -> type{'$'}
     * - start of EL
     *   ${
     *   #{
     * Note all the examples above *do not* include the escaping required to use
     * the values in Java code.
     */
    private void parseLiteral() {
        boolean foundEL = false;
        while ( <  && !foundEL) {
            char ch = nextChar();
            if (! && ch == '\\') {
                if ( == 0) {
                    .append("\\");
                } else {
                    .append();
                    .append("{'\\\\'}");
                }
            } else if (! && ch == '$' && ){
                if ( == 0) {
                    .append("\\$");
                } else {
                    .append();
                    .append("{'$'}");
                }
            } else if (! && ch == '#' && ){
                // Note if isDeferredSyntaxAllowedAsLiteral==true, \# will
                // not be treated as an escape
                if ( == 0) {
                    .append("\\#");
                } else {
                    .append();
                    .append("{'#'}");
                }
            } else if (ch == ){
                if ( < ) {
                    char next = .charAt();
                    if (next == '{') {
                        foundEL = true;
                        // Move back to start of EL
                        --;
                    } else {
                        .append(ch);
                    }
                } else {
                    .append(ch);
                }
            } else {
                .append(ch);
            }
        }
    }
    /*
     * For EL need to unquote everything but no need to convert anything. The
     * EL is terminated by '}'. The only other valid location for '}' is inside
     * a StringLiteral. The literals are delimited by '\'' or '\"'. The only
     * other valid location for '\'' or '\"' is also inside a StringLiteral. A
     * quote character inside a StringLiteral must be escaped if the same quote
     * character is used to delimit the StringLiteral.
     */
    private void parseEL() {
        boolean endEL = false;
        boolean insideLiteral = false;
        char literalQuote = 0;
        while ( <  && !endEL) {
            char ch = nextChar();
            if (ch == '\'' || ch == '\"') {
                if (insideLiteral) {
                    if (literalQuote == ch) {
                        insideLiteral = false;
                    }
                } else {
                    insideLiteral = true;
                    literalQuote = ch;
                }
                .append(ch);
            } else if (ch == '\\') {
                .append(ch);
                if (insideLiteral &&  < ) {
                    ch = nextChar();
                    .append(ch);
                }
            } else if (ch == '}') {
                if (!insideLiteral) {
                    endEL = true;
                }
                .append(ch);
            } else {
                .append(ch);
            }
        }
    }
    /*
     * Returns the next unquoted character and sets the lastChEscaped flag to
     * indicate if it was quoted/escaped or not.
     * &apos; is always unquoted to '
     * &quot; is always unquoted to "
     * \" is always unquoted to "
     * \' is always unquoted to '
     * \\ is always unquoted to \
     * \$ is unquoted to $ if EL is not being ignored
     * \# is unquoted to # if EL is not being ignored
     * <\% is always unquoted to <%
     * %\> is always unquoted to %>
     */
    private char nextChar() {
         = false;
        char ch = .charAt();
        
        if (ch == '&') {
            if ( + 5 <  && .charAt( + 1) == 'a' &&
                    .charAt( + 2) == 'p' && .charAt( + 3) == 'o' &&
                    .charAt( + 4) == 's' && .charAt( + 5) == ';') {
                ch = '\'';
                 += 6;
            } else if ( + 5 <  && .charAt( + 1) == 'q' &&
                    .charAt( + 2) == 'u' && .charAt( + 3) == 'o' &&
                    .charAt( + 4) == 't' && .charAt( + 5) == ';') {
                ch = '\"';
                 += 6;
            } else {
                ++;
            }
        } else if (ch == '\\' &&  + 1 < ) {
            ch = .charAt( + 1);
            if (ch == '\\' || ch == '\"' || ch == '\'' ||
                    (! &&
                            (ch == '$' ||
                                    (! &&
                                            ch == '#')))) {
                 += 2;
                 = true;
            } else {
                ch = '\\';
                ++;
            }
        } else if (ch == '<' && ( + 2 < ) && .charAt( + 1) == '\\' &&
                .charAt( + 2) == '%') {
            // Note this is a hack since nextChar only returns a single char
            // It is safe since <% does not require special treatment for EL
            // or for literals
            .append('<');
            +=3;
            return '%';
        } else if (ch == '%' &&  + 2 <  && .charAt( + 1) == '\\' &&
                .charAt( + 2) == '>') {
            // Note this is a hack since nextChar only returns a single char
            // It is safe since %> does not require special treatment for EL
            // or for literals
            .append('%');
            +=3;
            return '>';
        } else if (ch ==  && ) {
            throw .missingEscaping("" + );
        } else {
            ++;
        }
        return ch;
    }
    /*
     * Determines the type of expression by looking for the first unquoted ${
     * or #{.
     */
    private char getType(String value) {
        if (value == null) {
            return 0;
        }
        if () {
            return 0;
        }
        int j = 0;
        int len = value.length();
        char current;
        while (j < len) {
            current = value.charAt(j);
            if (current == '\\') {
                // Escape character - skip a character
                j++;
            } else if (current == '#' && !) {
                if (j < (len -1) && value.charAt(j + 1) == '{') {
                    return '#';
                }
            } else if (current == '$') {
                if (j < (len - 1) && value.charAt(j + 1) == '{') {
                    return '$';
                }
            }
            j++;
        }
        return 0;
    }
New to GrepCode? Check out our FAQ X