blob: 1ddbd391d61d2e2f9731f4df69033fce82fc942b [file] [log] [blame]
/*
* 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;
}
}