Skip to content

Commit a314da9

Browse files
committed
Don't instantiate class from user-specified string.
Users could specify a formatIdentifier, and we would try to load that as a fully qualified class name, which could be dangerous. Now we use reflection to find all DocIndexers and add them to a map, which we use to find the appropriate class for a formatIdentifier.
1 parent 07e9a8b commit a314da9

2 files changed

Lines changed: 34 additions & 17 deletions

File tree

engine/pom.xml

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -106,6 +106,13 @@
106106
<version>8.5.15</version>
107107
</dependency>
108108

109+
<!-- Reflections for classpath scanning (for DocIndexer classes) -->
110+
<dependency>
111+
<groupId>org.reflections</groupId>
112+
<artifactId>reflections</artifactId>
113+
<version>0.10.2</version>
114+
</dependency>
115+
109116
<!-- Jackson JSON/YAML reading -->
110117
<dependency>
111118
<groupId>com.fasterxml.jackson.core</groupId>
Lines changed: 27 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,12 @@
11
package nl.inl.blacklab.index;
22

3+
import java.util.ArrayList;
4+
import java.util.List;
5+
import java.util.Map;
6+
7+
import org.reflections.Reflections;
8+
import org.reflections.scanners.SubTypesScanner;
9+
310
import nl.inl.blacklab.exceptions.BlackLabRuntimeException;
411

512
/**
@@ -13,28 +20,31 @@ public class FinderInputFormatClass implements FinderInputFormat {
1320
public InputFormat find(String formatIdentifier) {
1421
// Is it a fully qualified class name?
1522
Class<? extends DocIndexerLegacy> docIndexerClass = null;
16-
try {
17-
docIndexerClass = getDocIndexerClass(formatIdentifier);
18-
} catch (Exception e1) {
19-
try {
20-
// No. Is it a class in the BlackLab indexers package?
21-
docIndexerClass = getDocIndexerClass("nl.inl.blacklab.indexers." + formatIdentifier);
22-
} catch (Exception e) {
23-
// Couldn't be resolved. That's okay, maybe another factory will support this key.
23+
docIndexerClass = getLegacyDocIndexers().get(formatIdentifier);
24+
return docIndexerClass == null ? null : DocumentFormats.add(formatIdentifier, docIndexerClass);
25+
}
26+
27+
private static Map<String, Class<? extends DocIndexerLegacy>> legacyDocIndexers = null;
28+
29+
/**
30+
* Find all legacy DocIndexers and store them in a map.
31+
* @return a map of format identifiers to DocIndexerLegacy classes
32+
*/
33+
private synchronized static Map<String, Class<? extends DocIndexerLegacy>> getLegacyDocIndexers() {
34+
if (legacyDocIndexers == null) {
35+
Reflections reflections = new Reflections("", new SubTypesScanner(false));
36+
for (Class<? extends DocIndexerLegacy> cl: reflections.getSubTypesOf(DocIndexerLegacy.class)) {
37+
String qualifiedName = cl.getName();
38+
legacyDocIndexers.put(qualifiedName, cl);
39+
if (qualifiedName.startsWith("nl.inl.blacklab.indexers."))
40+
legacyDocIndexers.put(cl.getSimpleName(), cl);
2441
}
2542
}
26-
if (docIndexerClass != null) {
27-
return DocumentFormats.add(formatIdentifier, docIndexerClass);
28-
}
29-
return null;
43+
return legacyDocIndexers;
3044
}
3145

3246
private static Class<? extends DocIndexerLegacy> getDocIndexerClass(String formatIdentifier) throws ClassNotFoundException {
33-
Class<?> aClass = Class.forName(formatIdentifier);
34-
if (!DocIndexerLegacy.class.isAssignableFrom(aClass)) {
35-
throw new BlackLabRuntimeException("Class " + formatIdentifier + " is not a DocIndexer");
36-
}
37-
return (Class<? extends DocIndexerLegacy>) aClass;
47+
return getLegacyDocIndexers().get(formatIdentifier);
3848
}
3949

4050
}

0 commit comments

Comments
 (0)