Skip to content

Commit 321de82

Browse files
authored
Merge pull request #383 from jglick/binary-name
Enforce use of `Outer$Inner` syntax in whitelists
2 parents 8bb5eda + 6bfedfa commit 321de82

File tree

2 files changed

+37
-5
lines changed

2 files changed

+37
-5
lines changed

src/main/java/org/jenkinsci/plugins/scriptsecurity/sandbox/whitelists/EnumeratingWhitelist.java

Lines changed: 30 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@
2424

2525
package org.jenkinsci.plugins.scriptsecurity.sandbox.whitelists;
2626

27+
import java.lang.reflect.Array;
2728
import java.lang.reflect.Constructor;
2829
import java.lang.reflect.Field;
2930
import java.lang.reflect.Method;
@@ -32,7 +33,6 @@
3233
import java.util.List;
3334
import java.util.concurrent.ConcurrentHashMap;
3435

35-
import org.apache.commons.lang.ClassUtils;
3636
import org.jenkinsci.plugins.scriptsecurity.sandbox.Whitelist;
3737

3838
import edu.umd.cs.findbugs.annotations.CheckForNull;
@@ -217,9 +217,35 @@ public static abstract class Signature implements Comparable<Signature> {
217217
return toString().hashCode();
218218
}
219219
abstract boolean exists() throws Exception;
220-
final Class<?> type(String name) throws Exception {
221-
// TODO this should be more strict: binary name is required for nested classes
222-
return ClassUtils.getClass(name);
220+
/** opposite of {@link #getName(Class)} */
221+
static final Class<?> type(String name) throws Exception {
222+
// ClassUtils.getClass is too lax: permits Outer.Inner where we require Outer$Inner.
223+
if (name.endsWith("[]")) {
224+
// https://stackoverflow.com/q/1679421/12916; TODO Java 12+ use Class.arrayType
225+
return Array.newInstance(type(name.substring(0, name.length() - 2)), 0).getClass();
226+
}
227+
switch (name) {
228+
case "boolean":
229+
return boolean.class;
230+
case "char":
231+
return char.class;
232+
case "byte":
233+
return byte.class;
234+
case "short":
235+
return short.class;
236+
case "int":
237+
return int.class;
238+
case "long":
239+
return long.class;
240+
case "float":
241+
return float.class;
242+
case "double":
243+
return double.class;
244+
case "void":
245+
return void.class;
246+
default:
247+
return Class.forName(name);
248+
}
223249
}
224250
final Class<?>[] types(String[] names) throws Exception {
225251
Class<?>[] r = new Class<?>[names.length];

src/test/java/org/jenkinsci/plugins/scriptsecurity/sandbox/whitelists/EnumeratingWhitelistTest.java

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -56,11 +56,14 @@ public void m(Object[] args) {}
5656
assertFalse(new EnumeratingWhitelist.FieldSignature(C.class, "other").matches(f));
5757
}
5858

59-
@Test public void getName() {
59+
@Test public void getName() throws Exception {
6060
assertEquals("java.lang.Object", EnumeratingWhitelist.getName(Object.class));
6161
assertEquals("java.lang.Object[]", EnumeratingWhitelist.getName(Object[].class));
6262
assertEquals("java.lang.Object[][]", EnumeratingWhitelist.getName(Object[][].class));
6363
assertEquals(EnumeratingWhitelistTest.class.getName() + "$C", EnumeratingWhitelist.getName(C.class));
64+
for (Class<?> c : new Class<?>[] {String.class, Map.Entry.class, int.class, String[].class, Map.Entry[].class, int[].class, String[][].class, Map.Entry[][].class, int[][].class}) {
65+
assertEquals(c, EnumeratingWhitelist.Signature.type(EnumeratingWhitelist.getName(c)));
66+
}
6467
}
6568

6669
@Test public void methodExists() throws Exception {
@@ -74,6 +77,9 @@ public void m(Object[] args) {}
7477
assertFalse(new EnumeratingWhitelist.MethodSignature(LinkedHashMap.class, "size").exists());
7578
assertFalse(new EnumeratingWhitelist.MethodSignature(HashMap.class, "size").exists());
7679
assertTrue(new EnumeratingWhitelist.MethodSignature(Map.class, "size").exists());
80+
assertTrue(new EnumeratingWhitelist.MethodSignature(Map.Entry.class, "getKey").exists());
81+
assertTrue(new EnumeratingWhitelist.MethodSignature("java.util.Map$Entry", "getKey", new String[0]).exists());
82+
assertThrows(ClassNotFoundException.class, new EnumeratingWhitelist.MethodSignature("java.util.Map.Entry", "getKey", new String[0])::exists);
7783
}
7884

7985
@Test

0 commit comments

Comments
 (0)