Skip to content

Commit 168cd1c

Browse files
committed
Only search directories, if pluginDir property is set and valid
1 parent 59d3a25 commit 168cd1c

2 files changed

Lines changed: 59 additions & 18 deletions

File tree

src/main/java/org/cryptomator/integrations/common/ClassLoaderFactory.java

Lines changed: 13 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,6 @@
1818
class ClassLoaderFactory {
1919

2020
private static final Logger LOG = LoggerFactory.getLogger(ClassLoaderFactory.class);
21-
private static final String USER_HOME = System.getProperty("user.home");
2221
private static final String PLUGIN_DIR_KEY = "cryptomator.pluginDir";
2322
private static final String JAR_SUFFIX = ".jar";
2423

@@ -30,14 +29,20 @@ class ClassLoaderFactory {
3029
*/
3130
@Contract(value = "-> new", pure = true)
3231
public static URLClassLoader forPluginDir() {
33-
String val = System.getProperty(PLUGIN_DIR_KEY, "");
34-
final Path p;
35-
if (val.startsWith("~/")) {
36-
p = Path.of(USER_HOME).resolve(val.substring(2));
37-
} else {
38-
p = Path.of(val);
32+
String val = System.getProperty(PLUGIN_DIR_KEY);
33+
if (val == null) {
34+
return URLClassLoader.newInstance(new URL[0]);
35+
}
36+
37+
try {
38+
if (val.isBlank()) {
39+
throw new IllegalArgumentException("Plugin dir path is blank");
40+
}
41+
return forPluginDirWithPath(Path.of(val)); //Path.of might throw InvalidPathException
42+
} catch (IllegalArgumentException e) {
43+
LOG.debug("{} contains illegal value. Skipping plugin directory.", PLUGIN_DIR_KEY, e);
44+
return URLClassLoader.newInstance(new URL[0]);
3945
}
40-
return forPluginDirWithPath(p);
4146
}
4247

4348
@VisibleForTesting

src/test/java/org/cryptomator/integrations/common/ClassLoaderFactoryTest.java

Lines changed: 46 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,16 @@
11
package org.cryptomator.integrations.common;
22

3+
import org.junit.jupiter.api.AfterEach;
34
import org.junit.jupiter.api.Assertions;
45
import org.junit.jupiter.api.BeforeEach;
56
import org.junit.jupiter.api.DisplayName;
67
import org.junit.jupiter.api.Nested;
78
import org.junit.jupiter.api.Test;
89
import org.junit.jupiter.api.io.TempDir;
10+
import org.junit.jupiter.params.ParameterizedTest;
11+
import org.junit.jupiter.params.provider.EmptySource;
12+
import org.junit.jupiter.params.provider.ValueSource;
13+
import org.mockito.MockedStatic;
914
import org.mockito.Mockito;
1015

1116
import java.io.ByteArrayInputStream;
@@ -17,6 +22,9 @@
1722
import java.util.Arrays;
1823
import java.util.Comparator;
1924

25+
import static org.mockito.ArgumentMatchers.any;
26+
import static org.mockito.Mockito.never;
27+
2028
public class ClassLoaderFactoryTest {
2129

2230
@Nested
@@ -91,21 +99,49 @@ public void testReadPluginDirFromSysProp() {
9199
}
92100
}
93101

94-
@Test
95-
@DisplayName("read path from cryptomator.pluginDir and replace ~/ with user.home")
96-
public void testReadPluginDirFromSysPropAndReplaceHome() {
97-
var ucl = Mockito.mock(URLClassLoader.class, "ucl");
98-
var relPath = "~/there/will/be/plugins";
99-
var absPath = Path.of(System.getProperty("user.home")).resolve("there/will/be/plugins");
100-
try (var mockedClass = Mockito.mockStatic(ClassLoaderFactory.class)) {
102+
@Nested
103+
@DisplayName("when the system property contains invalid values")
104+
public class InvalidSystemProperty {
105+
106+
MockedStatic<ClassLoaderFactory> mockedClass;
107+
108+
@BeforeEach
109+
public void beforeEach() {
110+
mockedClass = Mockito.mockStatic(ClassLoaderFactory.class);
101111
mockedClass.when(() -> ClassLoaderFactory.forPluginDir()).thenCallRealMethod();
102-
mockedClass.when(() -> ClassLoaderFactory.forPluginDirWithPath(absPath)).thenReturn(ucl);
112+
mockedClass.when(() -> ClassLoaderFactory.forPluginDirWithPath(any())).thenReturn(null);
113+
}
103114

104-
System.setProperty("cryptomator.pluginDir", relPath);
115+
@AfterEach
116+
public void afterEach() {
117+
mockedClass.close();
118+
}
119+
120+
121+
@Test
122+
@DisplayName("Undefined cryptomator.pluginDir returns empty URLClassLoader")
123+
public void testUndefinedSysProp() {
124+
System.clearProperty("cryptomator.pluginDir");
105125
var result = ClassLoaderFactory.forPluginDir();
106126

107-
Assertions.assertSame(ucl, result);
127+
mockedClass.verify(() -> ClassLoaderFactory.forPluginDirWithPath(any()), never());
128+
Assertions.assertNotNull(result);
129+
Assertions.assertEquals(0, result.getURLs().length);
108130
}
131+
132+
@ParameterizedTest
133+
@DisplayName("Property cryptomator.pluginDir filled with blanks returns empty URLClassLoader")
134+
@EmptySource
135+
@ValueSource(strings = {"\t\t", " "})
136+
public void testBlankSysProp(String propValue) {
137+
System.setProperty("cryptomator.pluginDir", propValue);
138+
var result = ClassLoaderFactory.forPluginDir();
139+
140+
mockedClass.verify(() -> ClassLoaderFactory.forPluginDirWithPath(any()), never());
141+
Assertions.assertNotNull(result);
142+
Assertions.assertEquals(0, result.getURLs().length);
143+
}
144+
109145
}
110146

111147
@Test

0 commit comments

Comments
 (0)