artnaseef commented on code in PR #1800:
URL: https://github.com/apache/activemq/pull/1800#discussion_r2954791380


##########
activemq-client/src/main/java/org/apache/activemq/util/FactoryFinder.java:
##########
@@ -138,21 +161,117 @@ public static void setObjectFactory(ObjectFactory 
objectFactory) {
     // Instance methods and properties
     // ================================================================
     private final String path;
+    private final Class<T> requiredType;
+    private final Set<Class<? extends T>> allowedImpls;
 
-    public FactoryFinder(String path) {
-        this.path = path;
+    /**
+     *
+     * @param path The path to search for impls
+     * @param requiredType Required interface type that any impl must implement
+     * @param allowedImpls The list of allowed implementations. If null or 
asterisk
+     * then all impls of the requiredType are allowed.
+     */
+    public FactoryFinder(String path, Class<T> requiredType, String 
allowedImpls) {
+        this.path = Objects.requireNonNull(path);
+        this.requiredType = Objects.requireNonNull(requiredType);
+        this.allowedImpls = loadAllowedImpls(requiredType, allowedImpls);
     }
 
+    @SuppressWarnings("unchecked")
+    private static <T> Set<Class<? extends T>> loadAllowedImpls(Class<T> 
requiredType, String allowedImpls) {
+        // If allowedImpls is either null or an asterisk (allow all wild card) 
then set to null so we don't filter
+        // If allowedImpls is only an empty string we return an empty set 
meaning allow none
+        // Otherwise split/trim all values
+        return allowedImpls != null && !allowedImpls.equals("*") ?
+            Arrays.stream(allowedImpls.split("\\s*,\\s*"))
+                .filter(s -> !s.isEmpty())
+                .map(s -> {
+                    try {
+                        final Class<?> clazz = FactoryFinder.loadClass(s);
+                        if (!requiredType.isAssignableFrom(clazz)) {
+                            throw new IllegalArgumentException(
+                                    "Class " + clazz + " is not assignable to 
" + requiredType);
+                        }
+                        return (Class<? extends T>)clazz;
+                    } catch (ClassNotFoundException | IOException e) {
+                        throw new IllegalArgumentException(e);
+                    }
+                }).collect(Collectors.toUnmodifiableSet()) : null;
+    }
+
+
     /**
      * Creates a new instance of the given key
      *
      * @param key is the key to add to the path to find a text file containing
      *                the factory name
      * @return a newly created instance
      */
-    public Object newInstance(String key) throws IllegalAccessException, 
InstantiationException, IOException, ClassNotFoundException {
-        return objectFactory.create(path+key);
+    public T newInstance(String key) throws IllegalAccessException, 
InstantiationException, IOException, ClassNotFoundException {
+        return objectFactory.create(resolvePath(key), requiredType, 
allowedImpls);
     }
 
+    Set<Class<? extends T>> getAllowedImpls() {
+        return allowedImpls;
+    }
+
+    Class<T> getRequiredType() {
+        return requiredType;
+    }
+
+    private String resolvePath(final String key) throws InstantiationException 
{
+        // Normalize the base path with the given key. This
+        // will resolve/remove any relative ".." sections of the path.
+        // Example: "/dir1/dir2/dir3/../file" becomes "/dir1/dir2/file"
+        final Path resolvedPath = Path.of(path).resolve(key).normalize();
+
+        // Validate the resolved path is still within the original defined
+        // root path and throw an error of it is not.
+        if (!resolvedPath.startsWith(path)) {

Review Comment:
   If path is `/dir1/dir2`, this would match `/dir1/dir2a`, right?  Maybe 
adding a trailing slash to `path`?



-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: [email protected]

For queries about this service, please contact Infrastructure at:
[email protected]


---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]
For further information, visit: https://activemq.apache.org/contact


Reply via email to