File 0002-CONFIGURATION-841-Fix-StackOverflow-with-a-cyclical-.patch of Package apache-commons-configuration
From 4ef2067d0c3ac10be0ac8aec794a2b2b742052c5 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Fridrich=20=C5=A0trba?= <fridrich.strba@bluewin.ch>
Date: Thu, 28 Mar 2024 08:59:09 +0100
Subject: [PATCH 2/2] [CONFIGURATION-841] Fix StackOverflow with a cyclical
object tree
---
.../configuration/PropertyConverter.java | 22 +++++++++++++------
.../configuration/TestPropertyConverter.java | 15 +++++++++++++
2 files changed, 30 insertions(+), 7 deletions(-)
diff --git a/src/main/java/org/apache/commons/configuration/PropertyConverter.java b/src/main/java/org/apache/commons/configuration/PropertyConverter.java
index 650c55b5..683327ac 100644
--- a/src/main/java/org/apache/commons/configuration/PropertyConverter.java
+++ b/src/main/java/org/apache/commons/configuration/PropertyConverter.java
@@ -33,11 +33,14 @@ import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Collection;
+import java.util.Collections;
import java.util.Date;
+import java.util.IdentityHashMap;
import java.util.Iterator;
import java.util.LinkedList;
import java.util.List;
import java.util.Locale;
+import java.util.Set;
import org.apache.commons.lang.BooleanUtils;
import org.apache.commons.lang.StringUtils;
@@ -944,7 +947,7 @@ public final class PropertyConverter
*/
public static Iterator<?> toIterator(Object value, char delimiter)
{
- return flatten(value, delimiter).iterator();
+ return flatten(value, delimiter, Collections.newSetFromMap(new IdentityHashMap<Object,Boolean>())).iterator();
}
/**
@@ -970,8 +973,9 @@ public final class PropertyConverter
* @return a "flat" collection containing all primitive values of
* the passed in object
*/
- private static Collection<?> flatten(Object value, char delimiter)
+ private static Collection<?> flatten(Object value, char delimiter, final Set<Object> dejaVu)
{
+ dejaVu.add(value);
if (value instanceof String)
{
String s = (String) value;
@@ -989,11 +993,11 @@ public final class PropertyConverter
}
else if (value instanceof Iterable)
{
- flattenIterator(result, ((Iterable<?>) value).iterator(), delimiter);
+ flattenIterator(result, ((Iterable<?>) value).iterator(), delimiter, dejaVu);
}
else if (value instanceof Iterator)
{
- flattenIterator(result, (Iterator<?>) value, delimiter);
+ flattenIterator(result, (Iterator<?>) value, delimiter, dejaVu);
}
else if (value != null)
{
@@ -1001,7 +1005,7 @@ public final class PropertyConverter
{
for (int len = Array.getLength(value), idx = 0; idx < len; idx++)
{
- result.addAll(flatten(Array.get(value, idx), delimiter));
+ result.addAll(flatten(Array.get(value, idx), delimiter, Collections.newSetFromMap(new IdentityHashMap<Object,Boolean>())));
}
}
else
@@ -1021,11 +1025,15 @@ public final class PropertyConverter
* @param it the iterator to process
* @param delimiter the delimiter for String values
*/
- private static void flattenIterator(Collection<Object> target, Iterator<?> it, char delimiter)
+ private static void flattenIterator(Collection<Object> target, Iterator<?> it, char delimiter, Set<Object> dejaVue)
{
while (it.hasNext())
{
- target.addAll(flatten(it.next(), delimiter));
+ final Object next = it.next();
+ if (!dejaVue.contains(next))
+ {
+ target.addAll(flatten(next, delimiter, dejaVue));
+ }
}
}
diff --git a/src/test/java/org/apache/commons/configuration/TestPropertyConverter.java b/src/test/java/org/apache/commons/configuration/TestPropertyConverter.java
index c1e7bbf1..d9f284ab 100644
--- a/src/test/java/org/apache/commons/configuration/TestPropertyConverter.java
+++ b/src/test/java/org/apache/commons/configuration/TestPropertyConverter.java
@@ -26,6 +26,7 @@ import java.lang.annotation.ElementType;
import java.math.BigDecimal;
import java.nio.file.FileSystems;
import java.nio.file.Path;
+import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
@@ -162,6 +163,20 @@ public class TestPropertyConverter
config.addProperty("foo", path);
}
+ @Test
+ public void testArrayListCycle()
+ {
+ PropertiesConfiguration config = new PropertiesConfiguration();
+ final ArrayList<Object> object = new ArrayList<Object>();
+ for (int i = 0; i < 16; i++)
+ {
+ object.add(i);
+ object.add(object);
+ object.add(new ArrayList<Object>(object));
+ }
+ config.addProperty("foo", object);
+ }
+
/**
* Tests the interpolation features.
*/
--
2.44.0