36
36
import java .util .jar .JarFile ;
37
37
import java .util .logging .Level ;
38
38
import java .util .logging .Logger ;
39
+
40
+ import org .jetbrains .annotations .Nullable ;
39
41
import org .opengrok .indexer .authorization .IAuthorizationPlugin ;
40
42
import org .opengrok .indexer .logger .LoggerFactory ;
41
43
import org .opengrok .indexer .util .IOUtils ;
@@ -49,6 +51,8 @@ public abstract class PluginFramework<PluginType> {
49
51
50
52
private static final Logger LOGGER = LoggerFactory .getLogger (PluginFramework .class );
51
53
54
+ private static final String CLASS_SUFFIX = ".class" ;
55
+
52
56
/**
53
57
* Class of the plugin type, necessary for instantiating and searching.
54
58
*/
@@ -248,16 +252,16 @@ protected List<Class<?>> getSuperclassesAndInterfaces(Class<?> clazz) {
248
252
* delegates the loading to the custom class loader
249
253
* {@link #loadClass(String)}.
250
254
*
251
- * @param classfiles list of files which possibly contain a java class
255
+ * @param fileList list of files which possibly contain a java class
252
256
* @see #handleLoadClass(String)
253
257
* @see #loadClass(String)
254
258
*/
255
- private void loadClassFiles (List <File > classfiles ) {
259
+ private void loadClassFiles (List <File > fileList ) {
256
260
PluginType plugin ;
257
261
258
- for (File file : classfiles ) {
262
+ for (File file : fileList ) {
259
263
String classname = getClassName (file );
260
- if (classname .isEmpty ()) {
264
+ if (classname == null || classname .isEmpty ()) {
261
265
continue ;
262
266
}
263
267
// Load the class in memory and try to find a configured space for this class.
@@ -274,23 +278,20 @@ private void loadClassFiles(List<File> classfiles) {
274
278
* delegates the loading to the custom class loader
275
279
* {@link #loadClass(String)}.
276
280
*
277
- * @param jarfiles list of jar files containing java classes
281
+ * @param fileList list of jar files containing java classes
278
282
* @see #handleLoadClass(String)
279
283
* @see #loadClass(String)
280
284
*/
281
- private void loadJarFiles (List <File > jarfiles ) {
285
+ private void loadJarFiles (List <File > fileList ) {
282
286
PluginType pf ;
283
287
284
- for (File file : jarfiles ) {
288
+ for (File file : fileList ) {
285
289
try (JarFile jar = new JarFile (file )) {
286
290
Enumeration <JarEntry > entries = jar .entries ();
287
291
while (entries .hasMoreElements ()) {
288
292
JarEntry entry = entries .nextElement ();
289
- if (!entry .getName ().endsWith (".class" )) {
290
- continue ;
291
- }
292
293
String classname = getClassName (entry );
293
- if (! entry . getName (). endsWith ( ".class" ) || classname .isEmpty ()) {
294
+ if (classname == null || classname .isEmpty ()) {
294
295
continue ;
295
296
}
296
297
// Load the class in memory and try to find a configured space for this class.
@@ -304,18 +305,40 @@ private void loadJarFiles(List<File> jarfiles) {
304
305
}
305
306
}
306
307
307
- private String getClassName (File f ) {
308
- String classname = f .getAbsolutePath ().substring (pluginDirectory .getAbsolutePath ().length () + 1 );
308
+ @ Nullable
309
+ private String getClassName (File file ) {
310
+ if (!file .getName ().endsWith (CLASS_SUFFIX )) {
311
+ return null ;
312
+ }
313
+
314
+ String classname = file .getAbsolutePath ().substring (pluginDirectory .getAbsolutePath ().length () + 1 );
309
315
classname = classname .replace (File .separatorChar , '.' ); // convert to package name
310
316
// no need to check for the index from lastIndexOf because we're in a branch
311
317
// where we expect the .class suffix
312
318
classname = classname .substring (0 , classname .lastIndexOf ('.' )); // strip .class
313
319
return classname ;
314
320
}
315
321
316
- private String getClassName (JarEntry f ) {
322
+ @ Nullable
323
+ private String getClassName (JarEntry jarEntry ) {
324
+ final String filePath = jarEntry .getName ();
325
+ if (!filePath .endsWith (CLASS_SUFFIX )) {
326
+ return null ;
327
+ }
328
+
329
+ File file = new File (pluginDirectory .getAbsolutePath (), filePath );
330
+ try {
331
+ if (!file .getCanonicalPath ().startsWith (pluginDirectory .getCanonicalPath () + File .separator )) {
332
+ LOGGER .log (Level .WARNING , "canonical path for jar entry {0} leads outside the origin" , filePath );
333
+ return null ;
334
+ }
335
+ } catch (IOException e ) {
336
+ LOGGER .log (Level .WARNING , "failed to get canonical path for {0}" , file );
337
+ return null ;
338
+ }
339
+
317
340
// java jar always uses / as separator
318
- String classname = f . getName () .replace ('/' , '.' ); // convert to package name
341
+ String classname = filePath .replace ('/' , '.' ); // convert to package name
319
342
return classname .substring (0 , classname .lastIndexOf ('.' )); // strip .class
320
343
}
321
344
@@ -364,7 +387,7 @@ public final void reload() {
364
387
365
388
// load all other possible plugin classes.
366
389
if (isLoadClassesEnabled ()) {
367
- loadClassFiles (IOUtils .listFilesRec (pluginDirectory , ".class" ));
390
+ loadClassFiles (IOUtils .listFilesRec (pluginDirectory , CLASS_SUFFIX ));
368
391
}
369
392
if (isLoadJarsEnabled ()) {
370
393
loadJarFiles (IOUtils .listFiles (pluginDirectory , ".jar" ));
0 commit comments