| /* |
| * 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.functions.escape; |
| |
| import com.google.clearsilver.jsilver.functions.TextFilter; |
| |
| import java.io.IOException; |
| |
| /** |
| * This function will be used to sanitize variables in 'style' attributes. It strips out any |
| * characters that are not part of a whitelist of safe characters. This replicates the autoescaping |
| * behavior of Clearsilver. |
| * |
| * It does not extend SimpleEscapingFunction because SimpleEscapingFunction requires a blacklist of |
| * characters to escape. The StyleAttrEscapeFunction instead applies a whitelist, and strips out any |
| * characters not in the whitelist. |
| */ |
| public class StyleEscapeFunction implements TextFilter { |
| |
| private static final boolean[] UNQUOTED_VALID_CHARS; |
| private static final boolean[] VALID_CHARS; |
| private static final int MAX_CHARS = 0x80; |
| |
| static { |
| // Allow characters likely to occur inside a style property value. |
| // Refer http://www.w3.org/TR/CSS21/ for more details. |
| String SPECIAL_CHARS = "_.,!#%- "; |
| String UNQUOTED_SPECIAL_CHARS = "_.,!#%-"; |
| |
| VALID_CHARS = new boolean[MAX_CHARS]; |
| UNQUOTED_VALID_CHARS = new boolean[MAX_CHARS]; |
| |
| for (int n = 0; n < MAX_CHARS; n++) { |
| VALID_CHARS[n] = false; |
| UNQUOTED_VALID_CHARS[n] = false; |
| |
| if (Character.isLetterOrDigit(n)) { |
| VALID_CHARS[n] = true; |
| UNQUOTED_VALID_CHARS[n] = true; |
| } else { |
| if (SPECIAL_CHARS.indexOf(n) != -1) { |
| VALID_CHARS[n] = true; |
| } |
| |
| if (UNQUOTED_SPECIAL_CHARS.indexOf(n) != -1) { |
| UNQUOTED_VALID_CHARS[n] = true; |
| } |
| } |
| } |
| } |
| |
| private final boolean[] validChars; |
| |
| /** |
| * isUnquoted should be true if the function is escaping a string that will appear inside an |
| * unquoted style attribute. |
| * |
| */ |
| public StyleEscapeFunction(boolean isUnquoted) { |
| if (isUnquoted) { |
| validChars = UNQUOTED_VALID_CHARS; |
| } else { |
| validChars = VALID_CHARS; |
| } |
| } |
| |
| public void filter(String in, Appendable out) throws IOException { |
| for (char c : in.toCharArray()) { |
| if (c < MAX_CHARS && validChars[c]) { |
| out.append(c); |
| } else if (c >= MAX_CHARS) { |
| out.append(c); |
| } |
| } |
| } |
| |
| public void dumpInfo() { |
| for (int i = 0; i < MAX_CHARS; i++) { |
| System.out.println(i + "(" + (char) i + ")" + " :" + VALID_CHARS[i]); |
| } |
| } |
| } |