diff --git a/spring-core/src/main/java/org/springframework/util/PropertyPlaceholderHelper.java b/spring-core/src/main/java/org/springframework/util/PropertyPlaceholderHelper.java index 4b1b2c37b12a..06a2406ae507 100644 --- a/spring-core/src/main/java/org/springframework/util/PropertyPlaceholderHelper.java +++ b/spring-core/src/main/java/org/springframework/util/PropertyPlaceholderHelper.java @@ -135,9 +135,10 @@ protected String parseStringValue( int endIndex = findPlaceholderEndIndex(buf, startIndex); if (endIndex != -1) { String placeholder = buf.substring(startIndex + this.placeholderPrefix.length(), endIndex); - if (!visitedPlaceholders.add(placeholder)) { + String originalPlaceholder = placeholder; + if (!visitedPlaceholders.add(originalPlaceholder)) { throw new IllegalArgumentException( - "Circular placeholder reference '" + placeholder + "' in property definitions"); + "Circular placeholder reference '" + originalPlaceholder + "' in property definitions"); } // Recursive invocation, parsing placeholders contained in the placeholder key. placeholder = parseStringValue(placeholder, placeholderResolver, visitedPlaceholders); @@ -173,7 +174,7 @@ else if (this.ignoreUnresolvablePlaceholders) { throw new IllegalArgumentException("Could not resolve placeholder '" + placeholder + "'"); } - visitedPlaceholders.remove(placeholder); + visitedPlaceholders.remove(originalPlaceholder); } else { startIndex = -1; diff --git a/spring-core/src/test/java/org/springframework/util/PropertyPlaceholderHelperTests.java b/spring-core/src/test/java/org/springframework/util/PropertyPlaceholderHelperTests.java index 91f06b12f975..b19a0a178fed 100644 --- a/spring-core/src/test/java/org/springframework/util/PropertyPlaceholderHelperTests.java +++ b/spring-core/src/test/java/org/springframework/util/PropertyPlaceholderHelperTests.java @@ -65,6 +65,16 @@ public void testRecurseInPlaceholder() { props.setProperty("inner", "ar"); assertEquals("foo=bar", this.helper.replacePlaceholders(text, props)); + + // SPR-5369 + text = "${top}"; + props = new Properties(); + props.setProperty("top", "${child}+${child}"); + props.setProperty("child", "${${differentiator}.grandchild}"); + props.setProperty("differentiator", "first"); + props.setProperty("first.grandchild", "actualValue"); + + assertEquals("actualValue+actualValue", this.helper.replacePlaceholders(text, props)); } @Test