Skip to content

Commit 3a4ef1f

Browse files
committed
[GR-36071] Don't resolve primitive types via Class.forName or JNI FindClass.
PullRequest: graal/12830
2 parents cb30554 + 5ff0b1c commit 3a4ef1f

File tree

9 files changed

+27
-11
lines changed

9 files changed

+27
-11
lines changed

substratevm/src/com.oracle.svm.configure/src/com/oracle/svm/configure/config/ParserConfigurationAdapter.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -47,7 +47,7 @@ public TypeResult<ConfigurationCondition> resolveCondition(String typeName) {
4747
}
4848

4949
@Override
50-
public TypeResult<ConfigurationType> resolveType(ConfigurationCondition condition, String typeName) {
50+
public TypeResult<ConfigurationType> resolveType(ConfigurationCondition condition, String typeName, boolean allowPrimitives) {
5151
ConfigurationType type = configuration.get(condition, typeName);
5252
ConfigurationType result = type != null ? type : new ConfigurationType(condition, typeName);
5353
return TypeResult.forType(typeName, result);

substratevm/src/com.oracle.svm.core/src/com/oracle/svm/core/configure/ReflectionConfigurationParser.java

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -84,9 +84,9 @@ private void parseClass(EconomicMap<String, Object> data) {
8484
}
8585
ConfigurationCondition condition = conditionResult.get();
8686

87-
TypeResult<T> result = delegate.resolveType(condition, className);
87+
TypeResult<T> result = delegate.resolveType(condition, className, false);
8888
if (!result.isPresent()) {
89-
handleError("Could not resolve " + className + " for reflection configuration.", result.getException());
89+
handleError("Could not resolve class " + className + " for reflection configuration.", result.getException());
9090
return;
9191
}
9292
T clazz = result.get();
@@ -256,7 +256,7 @@ private List<T> parseMethodParameters(T clazz, String methodName, List<Object> t
256256
List<T> result = new ArrayList<>();
257257
for (Object type : types) {
258258
String typeName = asString(type, "types");
259-
TypeResult<T> typeResult = delegate.resolveType(ConfigurationCondition.alwaysTrue(), typeName);
259+
TypeResult<T> typeResult = delegate.resolveType(ConfigurationCondition.alwaysTrue(), typeName, true);
260260
if (!typeResult.isPresent()) {
261261
handleError("Could not register method " + formatMethod(clazz, methodName) + " for reflection.", typeResult.getException());
262262
return null;

substratevm/src/com.oracle.svm.core/src/com/oracle/svm/core/configure/ReflectionConfigurationParserDelegate.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,7 @@ public interface ReflectionConfigurationParserDelegate<T> {
3434

3535
TypeResult<ConfigurationCondition> resolveCondition(String typeName);
3636

37-
TypeResult<T> resolveType(ConfigurationCondition condition, String typeName);
37+
TypeResult<T> resolveType(ConfigurationCondition condition, String typeName, boolean allowPrimitives);
3838

3939
void registerType(T type);
4040

substratevm/src/com.oracle.svm.core/src/com/oracle/svm/core/hub/ClassForNameSupport.java

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,7 @@ static ClassForNameSupport singleton() {
4444

4545
@Platforms(Platform.HOSTED_ONLY.class)
4646
public static void registerClass(Class<?> clazz) {
47+
assert !clazz.isPrimitive() : "primitive classes cannot be looked up by name";
4748
if (PredefinedClassesSupport.isPredefined(clazz)) {
4849
return; // must be defined at runtime before it can be looked up
4950
}

substratevm/src/com.oracle.svm.hosted/src/com/oracle/svm/hosted/ImageClassLoader.java

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -271,8 +271,13 @@ public Class<?> findClassOrFail(String name) {
271271

272272
/** Find class, return result encoding class or failure reason. */
273273
public TypeResult<Class<?>> findClass(String name) {
274+
return findClass(name, true);
275+
}
276+
277+
/** Find class, return result encoding class or failure reason. */
278+
public TypeResult<Class<?>> findClass(String name, boolean allowPrimitives) {
274279
try {
275-
if (name.indexOf('.') == -1) {
280+
if (allowPrimitives && name.indexOf('.') == -1) {
276281
switch (name) {
277282
case "boolean":
278283
return TypeResult.forClass(boolean.class);

substratevm/src/com.oracle.svm.hosted/src/com/oracle/svm/hosted/config/ReflectionRegistryAdapter.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -65,9 +65,9 @@ public TypeResult<ConfigurationCondition> resolveCondition(String typeName) {
6565
}
6666

6767
@Override
68-
public TypeResult<ConditionalElement<Class<?>>> resolveType(ConfigurationCondition condition, String typeName) {
68+
public TypeResult<ConditionalElement<Class<?>>> resolveType(ConfigurationCondition condition, String typeName, boolean allowPrimitives) {
6969
String name = canonicalizeTypeName(typeName);
70-
TypeResult<Class<?>> clazz = classLoader.findClass(name);
70+
TypeResult<Class<?>> clazz = classLoader.findClass(name, allowPrimitives);
7171
if (!clazz.isPresent()) {
7272
Throwable classLookupException = clazz.getException();
7373
if (classLookupException instanceof LinkageError || ClassLoadingExceptionSupport.Options.ExitOnUnknownClassLoadingFailure.getValue()) {

substratevm/src/com.oracle.svm.hosted/src/com/oracle/svm/hosted/jni/JNIAccessFeature.java

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -333,6 +333,9 @@ public void duringAnalysis(DuringAnalysisAccess a) {
333333
}
334334

335335
private static JNIAccessibleClass addClass(Class<?> classObj, DuringAnalysisAccessImpl access) {
336+
if (classObj.isPrimitive()) {
337+
return null; // primitives cannot be looked up by name and have no methods or fields
338+
}
336339
if (SubstitutionReflectivityFilter.shouldExclude(classObj, access.getMetaAccess(), access.getUniverse())) {
337340
return null;
338341
}

substratevm/src/com.oracle.svm.hosted/src/com/oracle/svm/hosted/reflect/ReflectionDataBuilder.java

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -540,7 +540,7 @@ private void makeTypeReachable(DuringAnalysisAccessImpl access, Type type) {
540540
return;
541541
}
542542
processedTypes.add(type);
543-
if (type instanceof Class<?> && !SubstitutionReflectivityFilter.shouldExclude((Class<?>) type, access.getMetaAccess(), access.getUniverse())) {
543+
if (type instanceof Class<?> && !shouldExcludeClass(access, (Class<?>) type)) {
544544
Class<?> clazz = (Class<?>) type;
545545
makeAnalysisTypeReachable(access, access.getMetaAccess().lookupJavaType(clazz));
546546

@@ -689,8 +689,15 @@ private void processRegisteredElements(DuringAnalysisAccessImpl access) {
689689
}
690690
}
691691

692+
private static boolean shouldExcludeClass(DuringAnalysisAccessImpl access, Class<?> clazz) {
693+
if (clazz.isPrimitive()) {
694+
return true; // primitives cannot be looked up by name and have no methods or fields
695+
}
696+
return SubstitutionReflectivityFilter.shouldExclude(clazz, access.getMetaAccess(), access.getUniverse());
697+
}
698+
692699
private void processClass(DuringAnalysisAccessImpl access, Class<?> clazz) {
693-
if (SubstitutionReflectivityFilter.shouldExclude(clazz, access.getMetaAccess(), access.getUniverse())) {
700+
if (shouldExcludeClass(access, clazz)) {
694701
return;
695702
}
696703

substratevm/src/com.oracle.svm.hosted/src/com/oracle/svm/hosted/snippets/ReflectionPlugins.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -326,7 +326,7 @@ private boolean processClassForName(GraphBuilderContext b, ResolvedJavaMethod ta
326326
boolean initialize = (Boolean) initializeValue;
327327
Supplier<String> targetParameters = () -> className + ", " + initialize;
328328

329-
TypeResult<Class<?>> typeResult = imageClassLoader.findClass(className);
329+
TypeResult<Class<?>> typeResult = imageClassLoader.findClass(className, false);
330330
if (!typeResult.isPresent()) {
331331
Throwable e = typeResult.getException();
332332
return throwException(b, targetMethod, targetParameters, e.getClass(), e.getMessage());

0 commit comments

Comments
 (0)