This is an automated email from the ASF dual-hosted git repository.
garydgregory pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/commons-collections.git
The following commit(s) were added to refs/heads/master by this push:
new 21d682119 Bump org.apache.commons:commons-parent from 104 to 105.
21d682119 is described below
commit 21d6821190e0325022510393f41faa8ec95b6397
Author: Gary Gregory <[email protected]>
AuthorDate: Mon Sep 7 14:48:33 2026 -0400
Bump org.apache.commons:commons-parent from 104 to 105.
- Fix AbstractReferenceMap.ReferenceEntry.setValue(V) to throw
NullPointerException on null input (contract).
- Legacy tests were previously skipped.
Before:
```
[INFO] Tests run: 18050, Failures: 0, Errors: 0, Skipped: 75
```
Now:
```
[INFO] Tests run: 22257, Failures: 0, Errors: 0, Skipped: 82
```
---
pom.xml | 2 +-
src/changes/changes.xml | 2 ++
.../collections4/map/AbstractReferenceMap.java | 6 +++--
.../commons/collections4/GuavaTestlibTest.java | 24 ++++++++++---------
.../commons/collections4/map/ReferenceMapTest.java | 27 ++++++++++++++++++++++
5 files changed, 47 insertions(+), 14 deletions(-)
diff --git a/pom.xml b/pom.xml
index 6be1dbe8d..de4443aa0 100644
--- a/pom.xml
+++ b/pom.xml
@@ -19,7 +19,7 @@
<parent>
<groupId>org.apache.commons</groupId>
<artifactId>commons-parent</artifactId>
- <version>104</version>
+ <version>105</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<artifactId>commons-collections4</artifactId>
diff --git a/src/changes/changes.xml b/src/changes/changes.xml
index 0edfc7365..f893895a7 100644
--- a/src/changes/changes.xml
+++ b/src/changes/changes.xml
@@ -34,8 +34,10 @@
<action type="fix" dev="ggregory" due-to="Naveed Khan, Gary Gregory">Fix
map and bidimap nextKey() skipping a key and throwing for keys not in the map
(#728).</action>
<action type="fix" dev="ggregory" due-to="Naveed Khan, Gary Gregory">Reset
last element in EnumerationIterator.remove() (#729).</action>
<action type="fix" dev="ggregory" due-to="Naveed Khan, Gary Gregory">Fix
TransformedMultiValuedMap.putAll(K, Iterable) NPE for null value transformer
(#731).</action>
+ <action type="fix" dev="ggregory" due-to="Gary Gregory">Fix
AbstractReferenceMap.ReferenceEntry.setValue(V) to throw NullPointerException
on null input (contract).</action>
<!-- ADD -->
<!-- UPDATE -->
+ <action type="update" dev="ggregory" due-to="Gary Gregory">Bump
org.apache.commons:commons-parent from 104 to 105.</action>
<action type="update" dev="ggregory" due-to="Gary Gregory">[test] Bump
com.google.guava:guava-testlib from 33.6.0-jre to 33.7.1-jre (#733).</action>
<action type="update" dev="ggregory" due-to="Gary Gregory">[test] Bump
org.easymock:easymock from 5.6.0 to 5.7.0 (#732).</action>
<!-- REMOVE -->
diff --git
a/src/main/java/org/apache/commons/collections4/map/AbstractReferenceMap.java
b/src/main/java/org/apache/commons/collections4/map/AbstractReferenceMap.java
index 7ef0095d2..554f0ea8b 100644
---
a/src/main/java/org/apache/commons/collections4/map/AbstractReferenceMap.java
+++
b/src/main/java/org/apache/commons/collections4/map/AbstractReferenceMap.java
@@ -335,12 +335,14 @@ public abstract class AbstractReferenceMap<K, V> extends
AbstractHashedMap<K, V>
/**
* Sets the value of the entry.
*
- * @param value The object to store
- * @return The previous value
+ * @param value The object to store, must not be null.
+ * @return The previous value.
+ * @throws NullPointerException if the value is null.
*/
@Override
@SuppressWarnings("unchecked")
public V setValue(final V value) {
+ Objects.requireNonNull(value, "value");
final V old = getValue();
if (parent.valueType != ReferenceStrength.HARD) {
((Reference<V>) this.value).clear();
diff --git
a/src/test/java/org/apache/commons/collections4/GuavaTestlibTest.java
b/src/test/java/org/apache/commons/collections4/GuavaTestlibTest.java
index 169bbed80..da5ffc78e 100644
--- a/src/test/java/org/apache/commons/collections4/GuavaTestlibTest.java
+++ b/src/test/java/org/apache/commons/collections4/GuavaTestlibTest.java
@@ -55,9 +55,9 @@ public final class GuavaTestlibTest extends TestCase {
public static Test suite() {
final TestSuite test = new TestSuite();
// Map
- test.addTest(suiteMap("HashedMap", HashedMap::new));
- test.addTest(suiteMap("LinkedMap", LinkedMap::new));
- test.addTest(suiteMap("LRUMap", LRUMap::new));
+ test.addTest(suiteMap("HashedMap", HashedMap::new,
MapFeature.ALLOWS_NULL_KEYS, MapFeature.ALLOWS_NULL_VALUES));
+ test.addTest(suiteMap("LinkedMap", LinkedMap::new,
MapFeature.ALLOWS_NULL_KEYS, MapFeature.ALLOWS_NULL_VALUES));
+ test.addTest(suiteMap("LRUMap", LRUMap::new,
MapFeature.ALLOWS_NULL_KEYS, MapFeature.ALLOWS_NULL_VALUES));
test.addTest(suiteMap("ReferenceMap", ReferenceMap::new));
// List
test.addTest(suiteList("TreeList", TreeList::new));
@@ -71,10 +71,10 @@ public final class GuavaTestlibTest extends TestCase {
/**
* Programmatically create a JUnit (3, 4) Test Suite for Guava testlib
tests with Lists.
- * @param name name of the test
- * @param factory factory to create new Lists
- * @param features test features used in the tests
- * @return A JUnit 3, 4 Test Suite
+ * @param name name of the test.
+ * @param factory factory to create new Lists.
+ * @param features test features used in the tests.
+ * @return A JUnit 3, 4 Test Suite.
*/
private static Test suiteList(final String name, final
Supplier<List<String>> factory, final Feature<?>... features) {
final ListTestSuiteBuilder<String> suite =
ListTestSuiteBuilder.using(new TestStringListGenerator() {
@@ -99,11 +99,12 @@ public final class GuavaTestlibTest extends TestCase {
/**
* Programmatically create a JUnit (3, 4) Test Suite for Guava testlib
tests with Maps.
- * @param name name of the test
- * @param factory factory to create new Maps
- * @return A JUnit 3, 4 Test Suite
+ * @param name name of the test.
+ * @param factory factory to create new Maps.
+ * @param features test features used in the tests.
+ * @return A JUnit 3, 4 Test Suite.
*/
- private static Test suiteMap(final String name, final Supplier<Map<String,
String>> factory) {
+ private static Test suiteMap(final String name, final Supplier<Map<String,
String>> factory, final Feature<?>... features) {
return MapTestSuiteBuilder.using(new TestStringMapGenerator() {
@Override
protected Map<String, String> create(final Map.Entry<String,
String>[] entries) {
@@ -118,6 +119,7 @@ public final class GuavaTestlibTest extends TestCase {
.withFeatures(
CollectionSize.ANY, MapFeature.GENERAL_PURPOSE,
MapFeature.ALLOWS_ANY_NULL_QUERIES,
CollectionFeature.SUPPORTS_ITERATOR_REMOVE)
+ .withFeatures(features)
.createTestSuite();
}
}
diff --git
a/src/test/java/org/apache/commons/collections4/map/ReferenceMapTest.java
b/src/test/java/org/apache/commons/collections4/map/ReferenceMapTest.java
index 40d9d4525..41a9ca836 100644
--- a/src/test/java/org/apache/commons/collections4/map/ReferenceMapTest.java
+++ b/src/test/java/org/apache/commons/collections4/map/ReferenceMapTest.java
@@ -34,11 +34,13 @@ import java.util.List;
import java.util.Map;
import java.util.function.Consumer;
+import org.apache.commons.collections4.MapIterator;
import org.apache.commons.collections4.map.AbstractHashedMap.HashEntry;
import org.apache.commons.collections4.map.AbstractReferenceMap.ReferenceEntry;
import
org.apache.commons.collections4.map.AbstractReferenceMap.ReferenceStrength;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.params.ParameterizedTest;
+import org.junit.jupiter.params.provider.EnumSource;
import org.junit.jupiter.params.provider.ValueSource;
/**
@@ -308,6 +310,18 @@ public class ReferenceMapTest<K, V> extends
AbstractIterableMapTest<K, V> {
assertThrows(InvalidObjectException.class, () ->
serializeDeserialize(map));
}
+ @ParameterizedTest
+ @EnumSource(ReferenceStrength.class)
+ void testEntrySetValueRejectsNull(final ReferenceStrength valueType) {
+ final ReferenceMap<String, String> map = new
ReferenceMap<>(ReferenceStrength.HARD, valueType);
+ map.put("key", "value");
+ final Map.Entry<String, String> entry =
map.entrySet().iterator().next();
+ assertThrows(NullPointerException.class, () -> entry.setValue(null));
+ assertEquals("value", entry.getValue());
+ assertEquals("value", map.get("key"));
+ assertEquals(1, map.size());
+ }
+
/**
* Test whether remove is not removing last entry after calling hasNext.
* <p>
@@ -326,6 +340,19 @@ public class ReferenceMapTest<K, V> extends
AbstractIterableMapTest<K, V> {
assertTrue(map.isEmpty(), "Expect empty but have entry: " + map);
}
+ @ParameterizedTest
+ @EnumSource(ReferenceStrength.class)
+ void testMapIteratorSetValueRejectsNull(final ReferenceStrength valueType)
{
+ final ReferenceMap<String, String> map = new
ReferenceMap<>(ReferenceStrength.HARD, valueType);
+ map.put("key", "value");
+ final MapIterator<String, String> iterator = map.mapIterator();
+ iterator.next();
+ assertThrows(NullPointerException.class, () ->
iterator.setValue(null));
+ assertEquals("value", iterator.getValue());
+ assertEquals("value", map.get("key"));
+ assertEquals(1, map.size());
+ }
+
@Test
@SuppressWarnings("unchecked")
void testNullHandling() {