Repository: incubator-freemarker
Updated Branches:
  refs/heads/3 ef9687577 -> dcb0e0634


Moved OptInTemplateClassResolver to core.util


Project: http://git-wip-us.apache.org/repos/asf/incubator-freemarker/repo
Commit: 
http://git-wip-us.apache.org/repos/asf/incubator-freemarker/commit/7308532a
Tree: http://git-wip-us.apache.org/repos/asf/incubator-freemarker/tree/7308532a
Diff: http://git-wip-us.apache.org/repos/asf/incubator-freemarker/diff/7308532a

Branch: refs/heads/3
Commit: 7308532af749ce827c4610c873626d3d68047d36
Parents: ef96875
Author: ddekany <[email protected]>
Authored: Sat Feb 25 07:46:32 2017 +0100
Committer: ddekany <[email protected]>
Committed: Sat Feb 25 07:46:52 2017 +0100

----------------------------------------------------------------------
 .../core/OptInTemplateClassResolver.java        | 156 -------------------
 .../core/util/OptInTemplateClassResolver.java   | 155 ++++++++++++++++++
 .../core/OptInTemplateClassResolverTest.java    |   1 +
 3 files changed, 156 insertions(+), 156 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/7308532a/src/main/java/org/apache/freemarker/core/OptInTemplateClassResolver.java
----------------------------------------------------------------------
diff --git 
a/src/main/java/org/apache/freemarker/core/OptInTemplateClassResolver.java 
b/src/main/java/org/apache/freemarker/core/OptInTemplateClassResolver.java
deleted file mode 100644
index 50e79d9..0000000
--- a/src/main/java/org/apache/freemarker/core/OptInTemplateClassResolver.java
+++ /dev/null
@@ -1,156 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you 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 org.apache.freemarker.core;
-
-import java.util.ArrayList;
-import java.util.Collections;
-import java.util.HashSet;
-import java.util.Iterator;
-import java.util.List;
-import java.util.Set;
-
-import org.apache.freemarker.core.util._ClassUtil;
-import org.apache.freemarker.core.util._StringUtil;
-
-/**
- * A {@link 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. 
-     *
-     * @param allowedClasses the {@link Set} of {@link String}-s that contains
-     *     the full-qualified names of the allowed classes.
-     *     Can be <code>null</code> (means not class is allowed).
-     * @param trustedTemplates the {@link List} of {@link String}-s that 
contains
-     *     template names (i.e., template root directory relative paths)
-     *     and prefix patterns (like <code>"include/*"</code>) of templates
-     *     for which {@link TemplateClassResolver#UNRESTRICTED_RESOLVER} will 
be 
-     *     used (which is not as safe as {@link OptInTemplateClassResolver}).
-     *     The list items need not start with <code>"/"</code> (if they are, it
-     *     will be removed). List items ending with <code>"*"</code> are 
treated
-     *     as prefixes (i.e. <code>"foo*"</code> matches <code>"foobar"</code>,
-     *     <code>"foo/bar/baaz"</code>, <code>"foowhatever/bar/baaz"</code>,
-     *     etc.). The <code>"*"</code> 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 <code>?new</code>) that wants to get the class. 
Thus,
-     *     if a trusted template includes a non-trusted template, the
-     *     <code>allowedClasses</code> restriction will apply in the included
-     *     template.
-     *     This parameter can be <code>null</code> (means no trusted 
templates).
-     */
-    public OptInTemplateClassResolver(
-            Set allowedClasses, List<String> trustedTemplates) {
-        this.allowedClasses = allowedClasses != null ? allowedClasses : 
Collections.EMPTY_SET;
-        if (trustedTemplates != null) {
-            trustedTemplateNames = new HashSet();
-            trustedTemplatePrefixes = new ArrayList();
-            
-            Iterator<String> it = trustedTemplates.iterator();
-            while (it.hasNext()) {
-                String li = it.next();
-                if (li.startsWith("/")) li = li.substring(1);
-                if (li.endsWith("*")) {
-                    trustedTemplatePrefixes.add(li.substring(0, li.length() - 
1));
-                } else {
-                    trustedTemplateNames.add(li);
-                }
-            }
-        } else {
-            trustedTemplateNames = Collections.EMPTY_SET;
-            trustedTemplatePrefixes = Collections.EMPTY_LIST;
-        }
-    }
-
-    @Override
-    public Class resolve(String className, Environment env, Template template)
-    throws TemplateException {
-        String templateName = safeGetTemplateName(template);
-        
-        if (templateName != null
-                && (trustedTemplateNames.contains(templateName)
-                        || hasMatchingPrefix(templateName))) {
-            return 
TemplateClassResolver.UNRESTRICTED_RESOLVER.resolve(className, env, template);
-        } else {
-            if (!allowedClasses.contains(className)) {
-                throw new _MiscTemplateException(env,
-                        "Instantiating ", className, " is not allowed in the 
template for security reasons. (If you "
-                        + "run into this problem when using ?new in a 
template, you may want to check the \"",
-                        Configurable.NEW_BUILTIN_CLASS_RESOLVER_KEY,
-                        "\" setting in the FreeMarker configuration.)");
-            } else {
-                try {
-                    return _ClassUtil.forName(className);
-                } catch (ClassNotFoundException e) {
-                    throw new _MiscTemplateException(e, env);
-                }
-            }
-        }
-    }
-
-    /**
-     * 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 == null) return null;
-        
-        String name = template.getName();
-        if (name == null) return null;
-
-        // Detect exploits, return null if one is suspected:
-        String decodedName = name;
-        if (decodedName.indexOf('%') != -1) {
-            decodedName = _StringUtil.replace(decodedName, "%2e", ".", false, 
false);
-            decodedName = _StringUtil.replace(decodedName, "%2E", ".", false, 
false);
-            decodedName = _StringUtil.replace(decodedName, "%2f", "/", false, 
false);
-            decodedName = _StringUtil.replace(decodedName, "%2F", "/", false, 
false);
-            decodedName = _StringUtil.replace(decodedName, "%5c", "\\", false, 
false);
-            decodedName = _StringUtil.replace(decodedName, "%5C", "\\", false, 
false);
-        }
-        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 < trustedTemplatePrefixes.size(); i++) {
-            String prefix = (String) trustedTemplatePrefixes.get(i);
-            if (name.startsWith(prefix)) return true;
-        }
-        return false;
-    }
-
-}

http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/7308532a/src/main/java/org/apache/freemarker/core/util/OptInTemplateClassResolver.java
----------------------------------------------------------------------
diff --git 
a/src/main/java/org/apache/freemarker/core/util/OptInTemplateClassResolver.java 
b/src/main/java/org/apache/freemarker/core/util/OptInTemplateClassResolver.java
new file mode 100644
index 0000000..5cd4427
--- /dev/null
+++ 
b/src/main/java/org/apache/freemarker/core/util/OptInTemplateClassResolver.java
@@ -0,0 +1,155 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you 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 org.apache.freemarker.core.util;
+
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.HashSet;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Set;
+
+import org.apache.freemarker.core.*;
+
+/**
+ * A {@link 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. 
+     *
+     * @param allowedClasses the {@link Set} of {@link String}-s that contains
+     *     the full-qualified names of the allowed classes.
+     *     Can be <code>null</code> (means not class is allowed).
+     * @param trustedTemplates the {@link List} of {@link String}-s that 
contains
+     *     template names (i.e., template root directory relative paths)
+     *     and prefix patterns (like <code>"include/*"</code>) of templates
+     *     for which {@link TemplateClassResolver#UNRESTRICTED_RESOLVER} will 
be 
+     *     used (which is not as safe as {@link OptInTemplateClassResolver}).
+     *     The list items need not start with <code>"/"</code> (if they are, it
+     *     will be removed). List items ending with <code>"*"</code> are 
treated
+     *     as prefixes (i.e. <code>"foo*"</code> matches <code>"foobar"</code>,
+     *     <code>"foo/bar/baaz"</code>, <code>"foowhatever/bar/baaz"</code>,
+     *     etc.). The <code>"*"</code> 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 <code>?new</code>) that wants to get the class. 
Thus,
+     *     if a trusted template includes a non-trusted template, the
+     *     <code>allowedClasses</code> restriction will apply in the included
+     *     template.
+     *     This parameter can be <code>null</code> (means no trusted 
templates).
+     */
+    public OptInTemplateClassResolver(
+            Set allowedClasses, List<String> trustedTemplates) {
+        this.allowedClasses = allowedClasses != null ? allowedClasses : 
Collections.EMPTY_SET;
+        if (trustedTemplates != null) {
+            trustedTemplateNames = new HashSet();
+            trustedTemplatePrefixes = new ArrayList();
+            
+            Iterator<String> it = trustedTemplates.iterator();
+            while (it.hasNext()) {
+                String li = it.next();
+                if (li.startsWith("/")) li = li.substring(1);
+                if (li.endsWith("*")) {
+                    trustedTemplatePrefixes.add(li.substring(0, li.length() - 
1));
+                } else {
+                    trustedTemplateNames.add(li);
+                }
+            }
+        } else {
+            trustedTemplateNames = Collections.EMPTY_SET;
+            trustedTemplatePrefixes = Collections.EMPTY_LIST;
+        }
+    }
+
+    @Override
+    public Class resolve(String className, Environment env, Template template)
+    throws TemplateException {
+        String templateName = safeGetTemplateName(template);
+        
+        if (templateName != null
+                && (trustedTemplateNames.contains(templateName)
+                        || hasMatchingPrefix(templateName))) {
+            return 
TemplateClassResolver.UNRESTRICTED_RESOLVER.resolve(className, env, template);
+        } else {
+            if (!allowedClasses.contains(className)) {
+                throw new _MiscTemplateException(env,
+                        "Instantiating ", className, " is not allowed in the 
template for security reasons. (If you "
+                        + "run into this problem when using ?new in a 
template, you may want to check the \"",
+                        Configurable.NEW_BUILTIN_CLASS_RESOLVER_KEY,
+                        "\" setting in the FreeMarker configuration.)");
+            } else {
+                try {
+                    return _ClassUtil.forName(className);
+                } catch (ClassNotFoundException e) {
+                    throw new _MiscTemplateException(e, env);
+                }
+            }
+        }
+    }
+
+    /**
+     * 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 == null) return null;
+        
+        String name = template.getName();
+        if (name == null) return null;
+
+        // Detect exploits, return null if one is suspected:
+        String decodedName = name;
+        if (decodedName.indexOf('%') != -1) {
+            decodedName = _StringUtil.replace(decodedName, "%2e", ".", false, 
false);
+            decodedName = _StringUtil.replace(decodedName, "%2E", ".", false, 
false);
+            decodedName = _StringUtil.replace(decodedName, "%2f", "/", false, 
false);
+            decodedName = _StringUtil.replace(decodedName, "%2F", "/", false, 
false);
+            decodedName = _StringUtil.replace(decodedName, "%5c", "\\", false, 
false);
+            decodedName = _StringUtil.replace(decodedName, "%5C", "\\", false, 
false);
+        }
+        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 < trustedTemplatePrefixes.size(); i++) {
+            String prefix = (String) trustedTemplatePrefixes.get(i);
+            if (name.startsWith(prefix)) return true;
+        }
+        return false;
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/7308532a/src/test/java/org/apache/freemarker/core/OptInTemplateClassResolverTest.java
----------------------------------------------------------------------
diff --git 
a/src/test/java/org/apache/freemarker/core/OptInTemplateClassResolverTest.java 
b/src/test/java/org/apache/freemarker/core/OptInTemplateClassResolverTest.java
index 6e4c3cc..669facb 100644
--- 
a/src/test/java/org/apache/freemarker/core/OptInTemplateClassResolverTest.java
+++ 
b/src/test/java/org/apache/freemarker/core/OptInTemplateClassResolverTest.java
@@ -26,6 +26,7 @@ import java.util.Set;
 
 import junit.framework.AssertionFailedError;
 import junit.framework.TestCase;
+import org.apache.freemarker.core.util.OptInTemplateClassResolver;
 
 public class OptInTemplateClassResolverTest extends TestCase {
 

Reply via email to