Start line:  
End line:  

Snippet Preview

Snippet HTML Code

Stack Overflow Questions
  package freemarker.core;
  
  import java.util.HashSet;
  import java.util.Iterator;
  import java.util.List;
  import java.util.Set;
  
A TemplateClassResolver that resolves only the classes whose name was specified in the constructor.
 
 public class OptInTemplateClassResolver implements TemplateClassResolver {
     
     private final Set/*<String>*/ allowedClasses;
     private final List/*<String>*/ trustedTemplatePrefixes;
     private final Set/*<String>*/ trustedTemplateNames;
    
    
Creates a new instance.

Parameters:
allowedClasses the java.util.Set of java.lang.String-s that contains the full-qualified names of the allowed classes. Can be null (means not class is allowed).
trustedTemplates the java.util.List of java.lang.String-s that contains template names (i.e., template root directory relative paths) and prefix patterns (like "include/*") of templates for which TemplateClassResolver.SAFER_RESOLVER will be used (which is not as safe as OptInTemplateClassResolver). The list items need not start with "/" (if they are, it will be removed). List items ending with "*" are treated as prefixes (i.e. "foo*" matches "foobar", "foo/bar/baaz", "foowhatever/bar/baaz", etc.). The "*" has no special meaning anywhere else. The matched template name is the name (template root directory relative path) of the template that directly (lexically) contains the operation (like ?new) that wants to get the class. Thus, if a trusted template includes a non-trusted template, the allowedClasses restriction will apply in the included template. This parameter can be null (means no trusted templates).
 
     public OptInTemplateClassResolver(
             Set allowedClassesList trustedTemplates) {
         this. = allowedClasses != null ? allowedClasses : .;
         if (trustedTemplates != null) {
              = new HashSet();
              = new ArrayList();
             
             Iterator it = trustedTemplates.iterator();
             while (it.hasNext()) {
                 String li = (Stringit.next();
                 if (li.startsWith("/")) li = li.substring(1);
                 if (li.endsWith("*")) {
                     .add(li.substring(0, li.length() - 1));
                 } else {
                     .add(li);
                 }
             }
         } else {
              = .;
              = .;
         }
     }
 
     public Class resolve(String classNameEnvironment envTemplate template)
     throws TemplateException {
         String templateName = safeGetTemplateName(template);
         
         if (templateName != null
                 && (.contains(templateName)
                         || hasMatchingPrefix(templateName))) {
             return ..resolve(classNameenvtemplate);
         } else {
             if (!.contains(className)) {
                 throw new TemplateException(
                         "Instantiating " + className + " is not allowed in the " +
                         "template for security reasons. (If you meet this problem " +
                         "when using ?new in a template, you may want to look " +
                         "at the \"" + . +
                         "\" setting in the FreeMarker configuration.)",
                         env);
             } else {
                 try {
                     return ClassUtil.forName(className);
                 } catch (ClassNotFoundException e) {
                     throw new TemplateException(eenv);
                 }
             }
         }
     }

    
Extract the template name from the template object which will be matched against the trusted template names and pattern.
    protected String safeGetTemplateName(Template template) {
        if (template == nullreturn null;
        
        String name = template.getName();
        if (name == nullreturn null;
        // Detect exploits, return null if one is suspected:
        String decodedName = name;
        if (decodedName.indexOf('%') != -1) {
            decodedName = StringUtil.replace(decodedName"%2e""."falsefalse);
            decodedName = StringUtil.replace(decodedName"%2E""."falsefalse);
            decodedName = StringUtil.replace(decodedName"%2f""/"falsefalse);
            decodedName = StringUtil.replace(decodedName"%2F""/"falsefalse);
            decodedName = StringUtil.replace(decodedName"%5c""\\"falsefalse);
            decodedName = StringUtil.replace(decodedName"%5C""\\"falsefalse);
        }
        int dotDotIdx = decodedName.indexOf("..");
        if (dotDotIdx != -1) {
            int before = dotDotIdx - 1 >= 0 ? decodedName.charAt(dotDotIdx - 1) : -1;
            int after = dotDotIdx + 2 < decodedName.length() ? decodedName.charAt(dotDotIdx + 2) : -1;
            if ((before == -1 || before == '/' || before == '\\')
                    && (after == -1 || after == '/' || after == '\\')) {
                return null;
            }
        }
        
        return name.startsWith("/") ? name.substring(1) : name;
    }
    private boolean hasMatchingPrefix(String name) {
        for (int i = 0; i < .size(); i++) {
            String prefix = (String.get(i);
            if (name.startsWith(prefix)) return true;
        }
        return false;
    }
New to GrepCode? Check out our FAQ X