@@ -61,6 +61,25 @@ public static Class<?> loadAndVerify(final String name) throws ClassNotFoundExce
6161 return loadAndVerify (name , defaultRestrictions ());
6262 }
6363
64+ /**
65+ * This method sandboxes the classloading to prevent possibly dangerous types from being loaded,
66+ * using the default restrictions.
67+ *
68+ * @param name the name of the type to load
69+ * @param initialize whether to initialize the class, passed to {@link Class#forName(String,
70+ * boolean, ClassLoader)}
71+ * @param loader the ClassLoader to use, passed to {@link Class#forName(String, boolean,
72+ * ClassLoader)}
73+ * @throws ClassNotFoundException if the class is not found
74+ * @return the result of {@link Class#forName(String)}, if it passes the default restrictions
75+ */
76+ public static Class <?> loadAndVerify (
77+ final String name , final boolean initialize , final ClassLoader loader )
78+ throws ClassNotFoundException {
79+ return loadAndVerify (
80+ name , defaultRestrictions (), () -> Class .forName (name , initialize , loader ));
81+ }
82+
6483 /**
6584 * This method sandboxes the classloading to prevent possibly dangerous types from being loaded.
6685 *
@@ -72,6 +91,14 @@ public static Class<?> loadAndVerify(final String name) throws ClassNotFoundExce
7291 public static Class <?> loadAndVerify (
7392 final String name , final Set <ReflectionRestrictions > restrictions )
7493 throws ClassNotFoundException {
94+ return loadAndVerify (name , restrictions , () -> Class .forName (name ));
95+ }
96+
97+ private static Class <?> loadAndVerify (
98+ final String name ,
99+ final Set <ReflectionRestrictions > restrictions ,
100+ final ClassSupplier classSupplier )
101+ throws ClassNotFoundException {
75102
76103 // we can do this check up front before we even load the type
77104 if (restrictions .contains (ReflectionRestrictions .MUST_NOT_INVOLVE_CODE_EXECUTION )) {
@@ -83,7 +110,7 @@ public static Class<?> loadAndVerify(
83110 }
84111
85112 // load the type so we can do the other checks
86- final Class <?> type = Class . forName ( name );
113+ final Class <?> type = classSupplier . get ( );
87114
88115 if (restrictions .contains (ReflectionRestrictions .MUST_BE_PUBLIC )) {
89116 final int modifiers = type .getModifiers ();
@@ -116,5 +143,9 @@ public static Class<?> loadAndVerify(
116143 "groovy." ,
117144 "org.python." );
118145
146+ private interface ClassSupplier {
147+ Class <?> get () throws ClassNotFoundException ;
148+ }
149+
119150 private static final String typeNotAllowedMessage = "type not allowed" ;
120151}
0 commit comments