| /* |
| * Copyright (C) 2010 Google Inc. |
| * |
| * Licensed 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 com.google.clearsilver.jsilver.autoescape; |
| |
| import com.google.clearsilver.jsilver.exceptions.JSilverAutoEscapingException; |
| |
| public enum EscapeMode { |
| ESCAPE_NONE("none", false), ESCAPE_HTML("html", false), ESCAPE_JS("js", false), ESCAPE_URL("url", |
| false), ESCAPE_IS_CONSTANT("constant", false), |
| |
| // These modes are used as starting modes, and a parser parses the |
| // subsequent template contents to determine the right escaping command to use. |
| ESCAPE_AUTO("auto", true), // Identical to ESCAPE_AUTO_HTML |
| ESCAPE_AUTO_HTML("auto_html", true), ESCAPE_AUTO_JS("auto_js", true), ESCAPE_AUTO_JS_UNQUOTED( |
| "auto_js_unquoted", true), ESCAPE_AUTO_STYLE("auto_style", true), ESCAPE_AUTO_ATTR( |
| "auto_attr", true), ESCAPE_AUTO_UNQUOTED_ATTR("auto_attr_unquoted", true), ESCAPE_AUTO_ATTR_URI( |
| "auto_attr_uri", true), ESCAPE_AUTO_UNQUOTED_ATTR_URI("auto_attr_uri_unquoted", true), ESCAPE_AUTO_ATTR_URI_START( |
| "auto_attr_uri_start", true), ESCAPE_AUTO_UNQUOTED_ATTR_URI_START( |
| "auto_attr_uri_start_unquoted", true), ESCAPE_AUTO_ATTR_JS("auto_attr_js", true), ESCAPE_AUTO_ATTR_UNQUOTED_JS( |
| "auto_attr_unquoted_js", true), ESCAPE_AUTO_UNQUOTED_ATTR_JS("auto_attr_js_unquoted", true), ESCAPE_AUTO_UNQUOTED_ATTR_UNQUOTED_JS( |
| "auto_attr_js_unquoted_js", true), ESCAPE_AUTO_ATTR_CSS("auto_attr_style", true), ESCAPE_AUTO_UNQUOTED_ATTR_CSS( |
| "auto_attr_style_unquoted", true); |
| |
| private String escapeCmd; |
| private boolean autoEscaper; |
| |
| private EscapeMode(String escapeCmd, boolean autoEscaper) { |
| this.escapeCmd = escapeCmd; |
| this.autoEscaper = autoEscaper; |
| } |
| |
| /** |
| * This function maps the type of escaping requested (escapeCmd) to the appropriate EscapeMode. If |
| * no explicit escaping is requested, but doAutoEscape is true, the function chooses auto escaping |
| * (EscapeMode.ESCAPE_AUTO). This mirrors the behaviour of ClearSilver. |
| * |
| * @param escapeCmd A string indicating type of escaping requested. |
| * @param doAutoEscape Whether auto escaping should be applied if escapeCmd is null. Corresponds |
| * to the Config.AutoEscape HDF variable. |
| * @return |
| */ |
| public static EscapeMode computeEscapeMode(String escapeCmd, boolean doAutoEscape) { |
| EscapeMode escapeMode; |
| |
| // If defined, the explicit escaping mode (configured using "Config.VarEscapeMode") |
| // takes preference over auto escaping |
| if (escapeCmd != null) { |
| for (EscapeMode e : EscapeMode.values()) { |
| if (e.escapeCmd.equals(escapeCmd)) { |
| return e; |
| } |
| } |
| throw new JSilverAutoEscapingException("Invalid escaping mode specified: " + escapeCmd); |
| |
| } else { |
| if (doAutoEscape) { |
| escapeMode = ESCAPE_AUTO; |
| } else { |
| escapeMode = ESCAPE_NONE; |
| } |
| return escapeMode; |
| } |
| } |
| |
| /** |
| * Calls {@link #computeEscapeMode(String, boolean)} with {@code doAutoEscape = false}. |
| * |
| * @param escapeCmd A string indicating type of escaping requested. |
| * @return EscapeMode |
| * @throws JSilverAutoEscapingException if {@code escapeCmd} is not recognized. |
| */ |
| public static EscapeMode computeEscapeMode(String escapeCmd) { |
| return computeEscapeMode(escapeCmd, false); |
| } |
| |
| /** |
| * Computes the EscapeMode of the result of concatenating two values. The EscapeModes of the two |
| * values are provided by {@code left} and {@code right} respectively. For now, if either of the |
| * values was escaped or a constant, we return {@code ESCAPE_IS_CONSTANT}. This is how ClearSilver |
| * behaves. |
| * |
| * @return {@code ESCAPE_NONE} if either of the values was not escaped or constant. {@code |
| * ESCAPE_IS_CONSTANT} otherwise. |
| */ |
| public static EscapeMode combineModes(EscapeMode left, EscapeMode right) { |
| if (left.equals(ESCAPE_NONE) || right.equals(ESCAPE_NONE)) { |
| // If either of the values has not been escaped, |
| // do not trust the result. |
| return ESCAPE_NONE; |
| } else { |
| // For now, indicate that this result is always safe in all contexts. |
| // This is what ClearSilver does. We may introduce a stricter autoescape |
| // rule later on which also requires that the escaping be the same as the |
| // context its used in. |
| return ESCAPE_IS_CONSTANT; |
| } |
| } |
| |
| public boolean isAutoEscapingMode() { |
| return autoEscaper; |
| } |
| |
| // TODO: Simplify enum names, and just use toString() instead. |
| public String getEscapeCommand() { |
| return escapeCmd; |
| } |
| } |