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 }