001 /*
002 * Copyright (C) 2014 XStream Committers.
003 * All rights reserved.
004 *
005 * Created on 09. January 2014 by Joerg Schaible
006 */
007 package com.thoughtworks.xstream.security;
008
009 /**
010 * Permission for any type with a name matching one of the provided wildcard expressions.
011 *
012 * <p>
013 * Supported are patterns with path expressions using dot as separator:
014 * </p>
015 * <ul>
016 * <li>?: one non-control character except separator, e.g. for 'java.net.Inet?Address'</li>
017 * <li>*: arbitrary number of non-control characters except separator, e.g. for types in a package like 'java.lang.*'</li>
018 * <li>**: arbitrary number of non-control characters including separator, e.g. for types in a package and subpackages like 'java.lang.**'</li>
019 * </ul>
020 * <p>
021 * The complete range of UTF-8 characters is supported except control characters.
022 * </p>
023 *
024 * @author Jörg Schaible
025 * @since 1.4.7
026 */
027 public class WildcardTypePermission extends RegExpTypePermission {
028
029 /**
030 * @since 1.4.7
031 */
032 public WildcardTypePermission(final String[] patterns) {
033 super(getRegExpPatterns(patterns));
034 }
035
036 private static String[] getRegExpPatterns(final String[] wildcards) {
037 if (wildcards == null)
038 return null;
039 final String[] regexps = new String[wildcards.length];
040 for (int i = 0; i < wildcards.length; ++i) {
041 final String wildcardExpression = wildcards[i];
042 final StringBuffer result = new StringBuffer(wildcardExpression.length() * 2);
043 result.append("(?u)");
044 final int length = wildcardExpression.length();
045 for (int j = 0; j < length; j++) {
046 final char ch = wildcardExpression.charAt(j);
047 switch (ch) {
048 case '\\':
049 case '.':
050 case '+':
051 case '|':
052 case '[':
053 case ']':
054 case '(':
055 case ')':
056 case '^':
057 case '$':
058 result.append('\\').append(ch);
059 break;
060
061 case '?':
062 result.append('.');
063 break;
064
065 case '*':
066 // see "General Category Property" in http://www.unicode.org/reports/tr18/
067 if (j + 1 < length && wildcardExpression.charAt(j + 1) == '*') {
068 result.append("[\\P{C}]*");
069 j++;
070 } else {
071 result.append("[\\P{C}&&[^").append('.').append("]]*");
072 }
073 break;
074
075 default:
076 result.append(ch);
077 break;
078 }
079 }
080 regexps[i] = result.toString();
081 }
082 return regexps;
083 }
084 }