Skip to content

Commit 6df8004

Browse files
committed
WW-5352 Auto allowlist parameterized types!
1 parent 770d311 commit 6df8004

File tree

2 files changed

+39
-41
lines changed

2 files changed

+39
-41
lines changed

apps/showcase/src/main/resources/struts.xml

Lines changed: 0 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -36,11 +36,6 @@
3636

3737
<constant name="struts.allowlist.enable" value="true" />
3838
<constant name="struts.parameters.requireAnnotations" value="true" />
39-
<constant name="struts.allowlist.classes"
40-
value="
41-
org.apache.struts2.showcase.conversion.Person,
42-
org.apache.struts2.showcase.conversion.Address
43-
"/>
4439

4540
<constant name="struts.convention.package.locators.basePackage" value="org.apache.struts2.showcase" />
4641
<constant name="struts.convention.result.path" value="/WEB-INF" />

core/src/main/java/org/apache/struts2/interceptor/parameter/ParametersInterceptor.java

Lines changed: 39 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -52,6 +52,8 @@
5252
import java.lang.reflect.Field;
5353
import java.lang.reflect.Method;
5454
import java.lang.reflect.Modifier;
55+
import java.lang.reflect.ParameterizedType;
56+
import java.lang.reflect.Type;
5557
import java.util.Arrays;
5658
import java.util.Collection;
5759
import java.util.Comparator;
@@ -373,61 +375,62 @@ protected boolean hasValidAnnotatedMember(String rootProperty, Object action, lo
373375
}
374376

375377
protected boolean hasValidAnnotatedPropertyDescriptor(PropertyDescriptor propDesc, long paramDepth) {
376-
Class<?> rootType = getValidAnnotatedPropertyDescriptorType(propDesc, paramDepth);
377-
if (rootType != null) {
378-
if (paramDepth > 0) {
379-
threadAllowlist.allowClass(rootType);
380-
}
381-
return true;
382-
}
383-
return false;
384-
}
385-
386-
/**
387-
* @return getter return type or setter parameter type, if one corresponding to the <code>paramDepth</code> exists
388-
* with a valid annotation
389-
*/
390-
protected Class<?> getValidAnnotatedPropertyDescriptorType(PropertyDescriptor propDesc, long paramDepth) {
391378
Method relevantMethod = paramDepth == 0 ? propDesc.getWriteMethod() : propDesc.getReadMethod();
392379
if (relevantMethod == null) {
393-
return null;
380+
return false;
394381
}
395382
StrutsParameter annotation = getParameterAnnotation(relevantMethod);
396-
if (annotation != null && annotation.depth() >= paramDepth) {
397-
return paramDepth == 0 ? relevantMethod.getParameterTypes()[0] : relevantMethod.getReturnType();
383+
if (annotation == null || annotation.depth() < paramDepth) {
384+
return false;
385+
}
386+
if (paramDepth >= 1) {
387+
threadAllowlist.allowClass(relevantMethod.getReturnType());
398388
}
399-
return null;
389+
if (paramDepth >= 2) {
390+
allowlistReturnTypeIfParameterized(relevantMethod);
391+
}
392+
return true;
400393
}
401394

402-
protected boolean hasValidAnnotatedField(Object action, String fieldName, long paramDepth) {
403-
Class<?> rootType = getValidAnnotatedFieldType(action, fieldName, paramDepth);
404-
if (rootType != null) {
405-
if (paramDepth > 0) {
406-
threadAllowlist.allowClass(rootType);
407-
}
408-
return true;
395+
protected void allowlistReturnTypeIfParameterized(Method method) {
396+
allowlistParameterizedTypeArg(method.getGenericReturnType());
397+
}
398+
399+
protected void allowlistParameterizedTypeArg(Type genericType) {
400+
if (!(genericType instanceof ParameterizedType)) {
401+
return;
402+
}
403+
Type paramType = ((ParameterizedType) genericType).getActualTypeArguments()[0];
404+
if (paramType instanceof Class) {
405+
threadAllowlist.allowClass((Class<?>) paramType);
409406
}
410-
return false;
411407
}
412408

413-
/**
414-
* @return field type if a public field exists on the action with a valid annotation
415-
*/
416-
protected Class<?> getValidAnnotatedFieldType(Object action, String fieldName, long paramDepth) {
409+
protected boolean hasValidAnnotatedField(Object action, String fieldName, long paramDepth) {
417410
Field field;
418411
try {
419412
field = action.getClass().getDeclaredField(fieldName);
420413
} catch (NoSuchFieldException e) {
421-
return null;
414+
return false;
422415
}
423416
if (!Modifier.isPublic(field.getModifiers())) {
424-
return null;
417+
return false;
425418
}
426419
StrutsParameter annotation = getParameterAnnotation(field);
427-
if (annotation != null && annotation.depth() >= paramDepth) {
428-
return field.getType();
420+
if (annotation == null || annotation.depth() < paramDepth) {
421+
return false;
422+
}
423+
if (paramDepth >= 1) {
424+
threadAllowlist.allowClass(field.getType());
429425
}
430-
return null;
426+
if (paramDepth >= 2) {
427+
allowlistFieldIfParameterized(field);
428+
}
429+
return true;
430+
}
431+
432+
protected void allowlistFieldIfParameterized(Field field) {
433+
allowlistParameterizedTypeArg(field.getGenericType());
431434
}
432435

433436
/**

0 commit comments

Comments
 (0)