Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions src/main/java/org/apache/commons/beanutils2/BeanMap.java
Original file line number Diff line number Diff line change
Expand Up @@ -479,6 +479,11 @@ private void initialize() {
for (final PropertyDescriptor propertyDescriptor : propertyDescriptors) {
if (propertyDescriptor != null) {
final String name = propertyDescriptor.getName();
if ("class".equals(name) || "declaringClass".equals(name)) {
// These pseudo-properties expose the bean's ClassLoader; skip them to match the
// suppression PropertyUtilsBean applies by default (see SuppressPropertiesBeanIntrospector).
continue;
}
final Method readMethod = propertyDescriptor.getReadMethod();
final Method writeMethod = propertyDescriptor.getWriteMethod();
final Class<?> aType = propertyDescriptor.getPropertyType();
Expand Down
30 changes: 24 additions & 6 deletions src/test/java/org/apache/commons/beanutils2/BeanMapTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,9 @@
package org.apache.commons.beanutils2;

import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertFalse;
import static org.junit.jupiter.api.Assertions.assertNotNull;
import static org.junit.jupiter.api.Assertions.assertNull;
import static org.junit.jupiter.api.Assertions.assertTrue;
import static org.junit.jupiter.api.Assertions.fail;
import static org.junit.jupiter.api.Assumptions.assumeFalse;
Expand Down Expand Up @@ -176,7 +178,7 @@ protected Object computeIfAbsent(final String key, final Function<? super String
@Override
public Object[] getNewSampleValues() {
final Object[] values = { Integer.valueOf(223), Long.valueOf(23341928234L), Double.valueOf(23423.34), Float.valueOf(213332.12f),
Short.valueOf((short) 234), Byte.valueOf((byte) 20), Character.valueOf('b'), Integer.valueOf(232), "SomeNewStringValue", new Object(), null, };
Short.valueOf((short) 234), Byte.valueOf((byte) 20), Character.valueOf('b'), Integer.valueOf(232), "SomeNewStringValue", new Object(), };
return values;
}

Expand All @@ -188,21 +190,20 @@ public Object[] getNewSampleValues() {
// To:
// "some\2Value",
//
// Then, I manually added the "class" key, which is a property that exists for
// all beans (and all objects for that matter.
// The "class" pseudo-property is intentionally absent: it is suppressed so the bean's
// ClassLoader is not reachable through the map.
@Override
public String[] getSampleKeys() {
final String[] keys = { "someIntValue", "someLongValue", "someDoubleValue", "someFloatValue", "someShortValue", "someByteValue", "someCharValue",
"someIntegerValue", "someStringValue", "someObjectValue", "class", };
"someIntegerValue", "someStringValue", "someObjectValue", };
return keys;
}

// note to self: the sample values were created manually
@Override
public Object[] getSampleValues() {
final Object[] values = { Integer.valueOf(1234), Long.valueOf(1298341928234L), Double.valueOf(123423.34), Float.valueOf(1213332.12f),
Short.valueOf((short) 134), Byte.valueOf((byte) 10), Character.valueOf('a'), Integer.valueOf(1432), "SomeStringValue", objectInFullMap,
BeanWithProperties.class, };
Short.valueOf((short) 134), Byte.valueOf((byte) 10), Character.valueOf('a'), Integer.valueOf(1432), "SomeStringValue", objectInFullMap, };
return values;
}

Expand Down Expand Up @@ -283,6 +284,23 @@ void testBeanMapClone() {
}
}

/**
* The {@code class} and (for enums) {@code declaringClass} pseudo-properties expose the bean's {@link ClassLoader} and must not be reachable through the map,
* matching the suppression {@link PropertyUtilsBean} applies by default.
*/
@Test
void testClassPropertyNotExposed() {
final BeanMap map = new BeanMap(new BeanWithProperties());
assertFalse(map.containsKey("class"), "class must not be exposed as a property");
assertNull(map.get("class"));
assertNull(map.getReadMethod("class"));

final BeanMap enumMap = new BeanMap(java.time.DayOfWeek.MONDAY);
assertFalse(enumMap.containsKey("class"), "class must not be exposed as a property");
assertFalse(enumMap.containsKey("declaringClass"), "declaringClass must not be exposed as a property");
assertNull(enumMap.get("declaringClass"));
}

@Test
void testBeanMapPutAllWriteable() {
final BeanMap map1 = (BeanMap) makeFullMap();
Expand Down