Skip to content

Commit 6899624

Browse files
mkurzjhoeller
authored andcommitted
Correctly parse property name in path "map[key[foo]]"
1 parent 7b11c3b commit 6899624

File tree

3 files changed

+33
-1
lines changed

3 files changed

+33
-1
lines changed

spring-beans/src/main/java/org/springframework/beans/AbstractNestablePropertyAccessor.java

Lines changed: 24 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -933,7 +933,7 @@ private PropertyTokenHolder getPropertyNameTokens(String propertyName) {
933933
int keyStart = propertyName.indexOf(PROPERTY_KEY_PREFIX, searchIndex);
934934
searchIndex = -1;
935935
if (keyStart != -1) {
936-
int keyEnd = propertyName.indexOf(PROPERTY_KEY_SUFFIX, keyStart + PROPERTY_KEY_PREFIX.length());
936+
int keyEnd = getPropertyNameKeyEnd(propertyName, keyStart + PROPERTY_KEY_PREFIX.length());
937937
if (keyEnd != -1) {
938938
if (actualName == null) {
939939
actualName = propertyName.substring(0, keyStart);
@@ -958,6 +958,29 @@ private PropertyTokenHolder getPropertyNameTokens(String propertyName) {
958958
return tokens;
959959
}
960960

961+
private static int getPropertyNameKeyEnd(String propertyName, int startIndex) {
962+
int unclosedPrefixes = 0;
963+
int length = propertyName.length();
964+
for (int i = startIndex; i < length; i++) {
965+
switch (propertyName.charAt(i)) {
966+
case PropertyAccessor.PROPERTY_KEY_PREFIX_CHAR:
967+
// The property name contains opening prefix(es)
968+
unclosedPrefixes++;
969+
break;
970+
case PropertyAccessor.PROPERTY_KEY_SUFFIX_CHAR:
971+
if (unclosedPrefixes == 0) {
972+
// No unclosed prefix(es) in the property name (left), this is the suffix we are looking for
973+
return i;
974+
} else {
975+
// This suffix does not close the initial prefix, but one that occurred within the property name
976+
unclosedPrefixes--;
977+
}
978+
break;
979+
}
980+
}
981+
return -1;
982+
}
983+
961984
@Override
962985
public String toString() {
963986
StringBuilder sb = new StringBuilder(getClass().getName());

spring-beans/src/test/java/org/springframework/beans/AbstractPropertyAccessorTests.java

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1599,6 +1599,7 @@ public void getAndSetIndexedProperties() {
15991599
TestBean tb7 = ((TestBean) target.getSet().toArray()[1]);
16001600
TestBean tb4 = ((TestBean) target.getMap().get("key1"));
16011601
TestBean tb5 = ((TestBean) target.getMap().get("key.3"));
1602+
TestBean tb8 = ((TestBean) target.getMap().get("key5[foo]"));
16021603
assertEquals("name0", tb0.getName());
16031604
assertEquals("name1", tb1.getName());
16041605
assertEquals("name2", tb2.getName());
@@ -1607,6 +1608,7 @@ public void getAndSetIndexedProperties() {
16071608
assertEquals("name7", tb7.getName());
16081609
assertEquals("name4", tb4.getName());
16091610
assertEquals("name5", tb5.getName());
1611+
assertEquals("name8", tb8.getName());
16101612
assertEquals("name0", accessor.getPropertyValue("array[0].name"));
16111613
assertEquals("name1", accessor.getPropertyValue("array[1].name"));
16121614
assertEquals("name2", accessor.getPropertyValue("list[0].name"));
@@ -1619,6 +1621,9 @@ public void getAndSetIndexedProperties() {
16191621
assertEquals("name5", accessor.getPropertyValue("map[\"key.3\"].name"));
16201622
assertEquals("nameX", accessor.getPropertyValue("map[key4][0].name"));
16211623
assertEquals("nameY", accessor.getPropertyValue("map[key4][1].name"));
1624+
assertEquals("name8", accessor.getPropertyValue("map[key5[foo]].name"));
1625+
assertEquals("name8", accessor.getPropertyValue("map['key5[foo]'].name"));
1626+
assertEquals("name8", accessor.getPropertyValue("map[\"key5[foo]\"].name"));
16221627

16231628
MutablePropertyValues pvs = new MutablePropertyValues();
16241629
pvs.add("array[0].name", "name5");
@@ -1631,6 +1636,7 @@ public void getAndSetIndexedProperties() {
16311636
pvs.add("map['key.3'].name", "name0");
16321637
pvs.add("map[key4][0].name", "nameA");
16331638
pvs.add("map[key4][1].name", "nameB");
1639+
pvs.add("map[key5[foo]].name", "name10");
16341640
accessor.setPropertyValues(pvs);
16351641
assertEquals("name5", tb0.getName());
16361642
assertEquals("name4", tb1.getName());
@@ -1648,6 +1654,7 @@ public void getAndSetIndexedProperties() {
16481654
assertEquals("name0", accessor.getPropertyValue("map['key.3'].name"));
16491655
assertEquals("nameA", accessor.getPropertyValue("map[key4][0].name"));
16501656
assertEquals("nameB", accessor.getPropertyValue("map[key4][1].name"));
1657+
assertEquals("name10", accessor.getPropertyValue("map[key5[foo]].name"));
16511658
}
16521659

16531660
@Test

spring-beans/src/test/java/org/springframework/tests/sample/beans/IndexedTestBean.java

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -66,6 +66,7 @@ public void populate() {
6666
TestBean tb5 = new TestBean("name5", 0);
6767
TestBean tb6 = new TestBean("name6", 0);
6868
TestBean tb7 = new TestBean("name7", 0);
69+
TestBean tb8 = new TestBean("name8", 0);
6970
TestBean tbX = new TestBean("nameX", 0);
7071
TestBean tbY = new TestBean("nameY", 0);
7172
this.array = new TestBean[] {tb0, tb1};
@@ -83,6 +84,7 @@ public void populate() {
8384
list.add(tbX);
8485
list.add(tbY);
8586
this.map.put("key4", list);
87+
this.map.put("key5[foo]", tb8);
8688
}
8789

8890

0 commit comments

Comments
 (0)