This is an automated email from the ASF dual-hosted git repository.

ddekany pushed a commit to branch 3
in repository https://gitbox.apache.org/repos/asf/freemarker.git


The following commit(s) were added to refs/heads/3 by this push:
     new bf4a0c1  Forward ported from 2.3-gae: 
MemberSelectorListMemberAccessPolicy related cleanup: Don't store the exception 
inside  the MemberSelector
bf4a0c1 is described below

commit bf4a0c1f071351dffefe918e74b5bc92cfe17bed
Author: ddekany <[email protected]>
AuthorDate: Mon Jan 13 21:13:44 2020 +0100

    Forward ported from 2.3-gae: MemberSelectorListMemberAccessPolicy related 
cleanup: Don't store the exception inside  the MemberSelector
---
 .../apache/freemarker/core/ConfigurationTest.java  |  11 +-
 .../core/model/impl/DefaultObjectWrapperTest.java  |   1 +
 ... MemberSelectorListMemberAccessPolicyTest.java} |  26 +++--
 .../core/model/impl/DefaultMemberAccessPolicy.java |  27 +++--
 .../impl/MemberSelectorListMemberAccessPolicy.java | 130 +++++++--------------
 5 files changed, 83 insertions(+), 112 deletions(-)

diff --git 
a/freemarker-core-test/src/test/java/org/apache/freemarker/core/ConfigurationTest.java
 
b/freemarker-core-test/src/test/java/org/apache/freemarker/core/ConfigurationTest.java
index 56d5390..6e3eab7 100644
--- 
a/freemarker-core-test/src/test/java/org/apache/freemarker/core/ConfigurationTest.java
+++ 
b/freemarker-core-test/src/test/java/org/apache/freemarker/core/ConfigurationTest.java
@@ -733,12 +733,19 @@ public class ConfigurationTest {
         assertEquals(1000L * 60 * 60 * 2, (Object) 
cfgB.getTemplateUpdateDelayMilliseconds());
     }
 
-    public static final MemberAccessPolicy CONFIG_TEST_MEMBER_ACCESS_POLICY =
-            new 
WhitelistMemberAccessPolicy(MemberSelectorListMemberAccessPolicy.MemberSelector.parse(
+    public static final MemberAccessPolicy CONFIG_TEST_MEMBER_ACCESS_POLICY;
+    static {
+        try {
+            CONFIG_TEST_MEMBER_ACCESS_POLICY = new 
WhitelistMemberAccessPolicy(MemberSelectorListMemberAccessPolicy.MemberSelector.parse(
                     ImmutableList.<String>of(
                             File.class.getName() + ".getName()",
                             File.class.getName() + ".isFile()"),
+                    false,
                     ConfigurationTest.class.getClassLoader()));
+        } catch (ClassNotFoundException | NoSuchMethodException | 
NoSuchFieldException e) {
+            throw new RuntimeException(e);
+        }
+    }
 
     @Test
     public void testMemberAccessPolicySetting() throws TemplateException {
diff --git 
a/freemarker-core-test/src/test/java/org/apache/freemarker/core/model/impl/DefaultObjectWrapperTest.java
 
b/freemarker-core-test/src/test/java/org/apache/freemarker/core/model/impl/DefaultObjectWrapperTest.java
index 9a1dddb..f83a333 100644
--- 
a/freemarker-core-test/src/test/java/org/apache/freemarker/core/model/impl/DefaultObjectWrapperTest.java
+++ 
b/freemarker-core-test/src/test/java/org/apache/freemarker/core/model/impl/DefaultObjectWrapperTest.java
@@ -147,6 +147,7 @@ public class DefaultObjectWrapperTest {
                     new WhitelistMemberAccessPolicy(
                             WhitelistMemberAccessPolicy.MemberSelector.parse(
                                     Arrays.asList(SomeBean.class.getName() + 
".getX()"),
+                                    false,
                                     
DefaultObjectWrapperTest.class.getClassLoader()));
 
             DefaultObjectWrapper bw = new 
DefaultObjectWrapper.Builder(Configuration.VERSION_3_0_0)
diff --git 
a/freemarker-core-test/src/test/java/org/apache/freemarker/core/model/impl/MemberSelectorListAccessPolicyTest.java
 
b/freemarker-core-test/src/test/java/org/apache/freemarker/core/model/impl/MemberSelectorListMemberAccessPolicyTest.java
similarity index 96%
rename from 
freemarker-core-test/src/test/java/org/apache/freemarker/core/model/impl/MemberSelectorListAccessPolicyTest.java
rename to 
freemarker-core-test/src/test/java/org/apache/freemarker/core/model/impl/MemberSelectorListMemberAccessPolicyTest.java
index 1e667b2..b8aeedd 100644
--- 
a/freemarker-core-test/src/test/java/org/apache/freemarker/core/model/impl/MemberSelectorListAccessPolicyTest.java
+++ 
b/freemarker-core-test/src/test/java/org/apache/freemarker/core/model/impl/MemberSelectorListMemberAccessPolicyTest.java
@@ -27,7 +27,7 @@ import java.util.Arrays;
 
 import org.junit.Test;
 
-public class MemberSelectorListAccessPolicyTest {
+public class MemberSelectorListMemberAccessPolicyTest {
 
     @Test
     public void testEmpty() throws NoSuchMethodException, NoSuchFieldException 
{
@@ -427,17 +427,25 @@ public class MemberSelectorListAccessPolicyTest {
     }
 
     private static WhitelistMemberAccessPolicy 
newWhitelistMemberAccessPolicy(String... memberSelectors) {
-        return new WhitelistMemberAccessPolicy(
-                MemberSelectorListMemberAccessPolicy.MemberSelector.parse(
-                        Arrays.asList(memberSelectors),
-                        
MemberSelectorListAccessPolicyTest.class.getClassLoader()));
+        try {
+            return new WhitelistMemberAccessPolicy(
+                    MemberSelectorListMemberAccessPolicy.MemberSelector.parse(
+                            Arrays.asList(memberSelectors), false,
+                            
MemberSelectorListMemberAccessPolicyTest.class.getClassLoader()));
+        } catch (ClassNotFoundException | NoSuchMethodException | 
NoSuchFieldException e) {
+            throw new RuntimeException(e);
+        }
     }
 
     private static BlacklistMemberAccessPolicy 
newBlacklistMemberAccessPolicy(String... memberSelectors) {
-        return new BlacklistMemberAccessPolicy(
-                MemberSelectorListMemberAccessPolicy.MemberSelector.parse(
-                        Arrays.asList(memberSelectors),
-                        
MemberSelectorListAccessPolicyTest.class.getClassLoader()));
+        try {
+            return new BlacklistMemberAccessPolicy(
+                    MemberSelectorListMemberAccessPolicy.MemberSelector.parse(
+                            Arrays.asList(memberSelectors), false,
+                            
MemberSelectorListMemberAccessPolicyTest.class.getClassLoader()));
+        } catch (ClassNotFoundException | NoSuchMethodException | 
NoSuchFieldException e) {
+            throw new RuntimeException(e);
+        }
     }
 
     public static class C1 {
diff --git 
a/freemarker-core/src/main/java/org/apache/freemarker/core/model/impl/DefaultMemberAccessPolicy.java
 
b/freemarker-core/src/main/java/org/apache/freemarker/core/model/impl/DefaultMemberAccessPolicy.java
index 4713f2a..57659eb 100644
--- 
a/freemarker-core/src/main/java/org/apache/freemarker/core/model/impl/DefaultMemberAccessPolicy.java
+++ 
b/freemarker-core/src/main/java/org/apache/freemarker/core/model/impl/DefaultMemberAccessPolicy.java
@@ -99,17 +99,24 @@ public final class DefaultMemberAccessPolicy implements 
MemberAccessPolicy {
                             throw new IllegalStateException("Unhandled rule: " 
+ rule);
                         }
                     } else {
-                        MemberSelector memberSelector =
-                                MemberSelector.parse(line, classLoader);
-                        Class<?> upperBoundType = 
memberSelector.getUpperBoundType();
-                        if (upperBoundType != null) {
-                            if 
(!whitelistRuleFinalClasses.contains(upperBoundType)
-                                    && 
!whitelistRuleNonFinalClasses.contains(upperBoundType)
-                                    && 
!typesWithBlacklistUnlistedRule.contains(upperBoundType)) {
-                                throw new IllegalStateException("Type without 
rule: " + upperBoundType.getName());
+                        MemberSelector memberSelector;
+                        try {
+                            memberSelector = MemberSelector.parse(line, 
classLoader);
+                        } catch (ClassNotFoundException | 
NoSuchMethodException | NoSuchFieldException e) {
+                            // Can happen if we run on an older Java than the 
list was made for
+                            memberSelector = null;
+                        }
+                        if (memberSelector != null) {
+                            Class<?> upperBoundType = 
memberSelector.getUpperBoundType();
+                            if (upperBoundType != null) {
+                                if 
(!whitelistRuleFinalClasses.contains(upperBoundType)
+                                        && 
!whitelistRuleNonFinalClasses.contains(upperBoundType)
+                                        && 
!typesWithBlacklistUnlistedRule.contains(upperBoundType)) {
+                                    throw new IllegalStateException("Type 
without rule: " + upperBoundType.getName());
+                                }
+                                // We always do the same, as 
"blacklistUnlistedMembers" is also defined via a whitelist:
+                                whitelistMemberSelectors.add(memberSelector);
                             }
-                            // We always do the same, as 
"blacklistUnlistedMembers" is also defined via a whitelist:
-                            whitelistMemberSelectors.add(memberSelector);
                         }
                     }
                 }
diff --git 
a/freemarker-core/src/main/java/org/apache/freemarker/core/model/impl/MemberSelectorListMemberAccessPolicy.java
 
b/freemarker-core/src/main/java/org/apache/freemarker/core/model/impl/MemberSelectorListMemberAccessPolicy.java
index 6317b1a..de82405 100644
--- 
a/freemarker-core/src/main/java/org/apache/freemarker/core/model/impl/MemberSelectorListMemberAccessPolicy.java
+++ 
b/freemarker-core/src/main/java/org/apache/freemarker/core/model/impl/MemberSelectorListMemberAccessPolicy.java
@@ -30,8 +30,6 @@ import java.util.StringTokenizer;
 
 import org.apache.freemarker.core.util._ClassUtils;
 import org.apache.freemarker.core.util._NullArgumentException;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
 
 /**
  * Superclass for member-selector-list-based member access policies, like 
{@link WhitelistMemberAccessPolicy}.
@@ -65,9 +63,10 @@ import org.slf4j.LoggerFactory;
  * with different return types (which is possible on the bytecode level) but 
the same parameter types, then all
  * variants of it is matched, or none is. Similarly, the type of fields isn't 
used either, only the name of the field
  * matters.
+ *
+ * @since 2.3.30
  */
 public abstract class MemberSelectorListMemberAccessPolicy implements 
MemberAccessPolicy {
-    private static final Logger LOG = 
LoggerFactory.getLogger(MemberSelectorListMemberAccessPolicy.class);
 
     enum ListType {
         /** Only matched members will be exposed. */
@@ -85,15 +84,15 @@ public abstract class MemberSelectorListMemberAccessPolicy 
implements MemberAcce
     /**
      * A condition that matches some type members. See {@link 
MemberSelectorListMemberAccessPolicy} documentation for more.
      * Exactly one of these will be non-{@code null}:
-     * {@link #getMethod()}, {@link #getConstructor()}, {@link #getField()}, 
{@link #getException()}.
+     * {@link #getMethod()}, {@link #getConstructor()}, {@link #getField()}.
+     *
+     * @since 2.3.30
      */
     public final static class MemberSelector {
         private final Class<?> upperBoundType;
         private final Method method;
         private final Constructor<?> constructor;
         private final Field field;
-        private final Exception exception;
-        private final String exceptionMemberSelectorString;
 
         /**
          * Use if you want to match methods similar to the specified one, in 
types that are {@code instanceof} of
@@ -106,8 +105,6 @@ public abstract class MemberSelectorListMemberAccessPolicy 
implements MemberAcce
             this.method = method;
             this.constructor = null;
             this.field = null;
-            this.exception = null;
-            this.exceptionMemberSelectorString = null;
         }
 
         /**
@@ -121,8 +118,6 @@ public abstract class MemberSelectorListMemberAccessPolicy 
implements MemberAcce
             this.method = null;
             this.constructor = constructor;
             this.field = null;
-            this.exception = null;
-            this.exceptionMemberSelectorString = null;
         }
 
         /**
@@ -136,32 +131,10 @@ public abstract class 
MemberSelectorListMemberAccessPolicy implements MemberAcce
             this.method = null;
             this.constructor = null;
             this.field = field;
-            this.exception = null;
-            this.exceptionMemberSelectorString = null;
         }
 
         /**
-         * Used to store the result of a parsing that's failed for a reason 
that we can skip on runtime (typically,
-         * when a missing class or member was referred).
-         *
-         * @param upperBoundType {@code null} if resolving the upper bound 
type itself failed.
-         * @param exception Not {@code null}
-         * @param exceptionMemberSelectorString Not {@code null}; the selector 
whose resolution has failed, used in
-         *      the log message.
-         */
-        public MemberSelector(Class<?> upperBoundType, Exception exception, 
String exceptionMemberSelectorString) {
-            _NullArgumentException.check("exception", exception);
-            _NullArgumentException.check("exceptionMemberSelectorString", 
exceptionMemberSelectorString);
-            this.upperBoundType = upperBoundType;
-            this.method = null;
-            this.constructor = null;
-            this.field = null;
-            this.exception = exception;
-            this.exceptionMemberSelectorString = exceptionMemberSelectorString;
-        }
-
-        /**
-         * Maybe {@code null} if {@link #getException()} is non-{@code null}.
+         * Not {@code null}.
          */
         public Class<?> getUpperBoundType() {
             return upperBoundType;
@@ -169,7 +142,7 @@ public abstract class MemberSelectorListMemberAccessPolicy 
implements MemberAcce
 
         /**
          * Maybe {@code null};
-         * set if the selector matches methods similar to the returned one, 
and there was no exception.
+         * set if the selector matches methods similar to the returned one.
          */
         public Method getMethod() {
             return method;
@@ -177,7 +150,7 @@ public abstract class MemberSelectorListMemberAccessPolicy 
implements MemberAcce
 
         /**
          * Maybe {@code null};
-         * set if the selector matches constructors similar to the returned 
one, and there was no exception.
+         * set if the selector matches constructors similar to the returned 
one.
          */
         public Constructor<?> getConstructor() {
             return constructor;
@@ -185,27 +158,13 @@ public abstract class 
MemberSelectorListMemberAccessPolicy implements MemberAcce
 
         /**
          * Maybe {@code null};
-         * set if the selector matches fields similar to the returned one, and 
there was no exception.
+         * set if the selector matches fields similar to the returned one.
          */
         public Field getField() {
             return field;
         }
 
         /**
-         * Maybe {@code null}
-         */
-        public Exception getException() {
-            return exception;
-        }
-
-        /**
-         * Maybe {@code null}
-         */
-        public String getExceptionMemberSelectorString() {
-            return exceptionMemberSelectorString;
-        }
-
-        /**
          * Parses a member selector that was specified with a string.
          *
          * @param classLoader
@@ -223,9 +182,12 @@ public abstract class MemberSelectorListMemberAccessPolicy 
implements MemberAcce
          *      {@code []}. In the member name, like {@code 
com.example.MyClass.myMember}, the class refers to the so
          *      called "upper bound class". Regarding that and inheritance 
rules see the class level documentation.
          *
-         * @return The {@link MemberSelector}, which might has non-{@code 
null} {@link MemberSelector#exception}.
+         * @throws ClassNotFoundException If a type referred in the member 
selector can't be found.
+         * @throws NoSuchMethodException If the method or constructor referred 
in the member selector can't be found.
+         * @throws NoSuchFieldException If the field referred in the member 
selector can't be found.
          */
-        public static MemberSelector parse(String memberSelectorString, 
ClassLoader classLoader) {
+        public static MemberSelector parse(String memberSelectorString, 
ClassLoader classLoader) throws
+                ClassNotFoundException, NoSuchMethodException, 
NoSuchFieldException {
             if (memberSelectorString.contains("<") || 
memberSelectorString.contains(">")
                     || memberSelectorString.contains("...") || 
memberSelectorString.contains(";")) {
                 throw new IllegalArgumentException(
@@ -253,11 +215,7 @@ public abstract class MemberSelectorListMemberAccessPolicy 
implements MemberAcce
                 throw new IllegalArgumentException("Malformed whitelist entry 
(malformed upper bound class name): "
                         + memberSelectorString);
             }
-            try {
-                upperBoundClass = classLoader.loadClass(upperBoundClassStr);
-            } catch (ClassNotFoundException e) {
-                return new MemberSelector(null, e, cleanedStr);
-            }
+            upperBoundClass = classLoader.loadClass(upperBoundClassStr);
 
             String memberName = cleanedStr.substring(postClassDotIdx + 1, 
postMemberNameIdx);
             if (!isWellFormedJavaIdentifier(memberName)) {
@@ -290,27 +248,15 @@ public abstract class 
MemberSelectorListMemberAccessPolicy implements MemberAcce
                             throw new IllegalArgumentException(
                                     "Malformed whitelist entry (malformed 
argument class name): " + memberSelectorString);
                         }
-                        try {
-                            argClass = classLoader.loadClass(argClassName);
-                        } catch (ClassNotFoundException | SecurityException e) 
{
-                            return new MemberSelector(upperBoundClass, e, 
cleanedStr);
-                        }
+                        argClass = classLoader.loadClass(argClassName);
                     }
                     argTypes[i] = _ClassUtils.getArrayClass(argClass, 
arrayDimensions);
                 }
-                try {
-                    return memberName.equals(upperBoundClass.getSimpleName())
-                            ? new MemberSelector(upperBoundClass, 
upperBoundClass.getConstructor(argTypes))
-                            : new MemberSelector(upperBoundClass, 
upperBoundClass.getMethod(memberName, argTypes));
-                } catch (NoSuchMethodException | SecurityException e) {
-                    return new MemberSelector(upperBoundClass, e, cleanedStr);
-                }
+                return memberName.equals(upperBoundClass.getSimpleName())
+                        ? new MemberSelector(upperBoundClass, 
upperBoundClass.getConstructor(argTypes))
+                        : new MemberSelector(upperBoundClass, 
upperBoundClass.getMethod(memberName, argTypes));
             } else {
-                try {
-                    return new MemberSelector(upperBoundClass, 
upperBoundClass.getField(memberName));
-                } catch (NoSuchFieldException | SecurityException e) {
-                    return new MemberSelector(upperBoundClass, e, cleanedStr);
-                }
+                return new MemberSelector(upperBoundClass, 
upperBoundClass.getField(memberName));
             }
         }
 
@@ -318,13 +264,24 @@ public abstract class 
MemberSelectorListMemberAccessPolicy implements MemberAcce
          * Convenience method to parse all member selectors in the collection 
(see {@link #parse(String, ClassLoader)}),
          * while also filtering out blank and comment lines; see {@link 
#parse(String, ClassLoader)},
          * and {@link #isIgnoredLine(String)}.
+         *
+         * @param ignoreMissingClassOrMember If {@code true}, members 
selectors that throw exceptions because the
+         *      referred type or member can't be found will be silently 
ignored. If {@code true}, same exceptions
+         *      will be just thrown by this method.
          */
-        public static List<MemberSelector> parse(Collection<String> 
memberSelectors,
-                ClassLoader classLoader) {
-            List<MemberSelector> parsedMemberSelectors = new 
ArrayList<>(memberSelectors.size());
+        public static List<MemberSelector> parse(
+                Collection<String> memberSelectors, boolean 
ignoreMissingClassOrMember, ClassLoader classLoader)
+                throws ClassNotFoundException, NoSuchMethodException, 
NoSuchFieldException {
+            List<MemberSelector> parsedMemberSelectors = new 
ArrayList<MemberSelector>(memberSelectors.size());
             for (String memberSelector : memberSelectors) {
                 if (!isIgnoredLine(memberSelector)) {
-                    parsedMemberSelectors.add(parse(memberSelector, 
classLoader));
+                    try {
+                        parsedMemberSelectors.add(parse(memberSelector, 
classLoader));
+                    } catch (ClassNotFoundException | NoSuchFieldException | 
NoSuchMethodException e) {
+                        if (!ignoreMissingClassOrMember) {
+                            throw e;
+                        }
+                    }
                 }
             }
             return parsedMemberSelectors;
@@ -360,12 +317,7 @@ public abstract class MemberSelectorListMemberAccessPolicy 
implements MemberAcce
         fieldMatcher = new FieldMatcher();
         for (MemberSelector memberSelector : memberSelectors) {
             Class<?> upperBoundClass = memberSelector.upperBoundType;
-            if (memberSelector.exception != null) {
-                if (LOG.isDebugEnabled()) {
-                    LOG.debug("Member selector ignored due to error: " + 
memberSelector.getExceptionMemberSelectorString(),
-                            memberSelector.exception);
-                }
-            } else if (memberSelector.constructor != null) {
+            if (memberSelector.constructor != null) {
                 constructorMatcher.addMatching(upperBoundClass, 
memberSelector.constructor);
             } else if (memberSelector.method != null) {
                 methodMatcher.addMatching(upperBoundClass, 
memberSelector.method);
@@ -377,34 +329,30 @@ public abstract class 
MemberSelectorListMemberAccessPolicy implements MemberAcce
         }
     }
 
-    @Override
     public final ClassMemberAccessPolicy forClass(final Class<?> contextClass) 
{
         return new ClassMemberAccessPolicy() {
-            @Override
             public boolean isMethodExposed(Method method) {
                 return matchResultToIsExposedResult(
                         methodMatcher.matches(contextClass, method)
                                 || matchAnnotation != null
                                 && 
_MethodUtils.getInheritableAnnotation(contextClass, method, matchAnnotation)
-                                != null);
+                                        != null);
             }
 
-            @Override
             public boolean isConstructorExposed(Constructor<?> constructor) {
                 return matchResultToIsExposedResult(
                         constructorMatcher.matches(contextClass, constructor)
                                 || matchAnnotation != null
                                 && 
_MethodUtils.getInheritableAnnotation(contextClass, constructor, 
matchAnnotation)
-                                != null);
+                                        != null);
             }
 
-            @Override
             public boolean isFieldExposed(Field field) {
                 return matchResultToIsExposedResult(
                         fieldMatcher.matches(contextClass, field)
                                 || matchAnnotation != null
                                 && 
_MethodUtils.getInheritableAnnotation(contextClass, field, matchAnnotation)
-                                != null);
+                                        != null);
             }
         };
     }

Reply via email to