Skip to content

Commit a1967e8

Browse files
committed
Fix generic mapping stack overflow
1 parent d3d1817 commit a1967e8

File tree

4 files changed

+68
-7
lines changed

4 files changed

+68
-7
lines changed

src/org/jetbrains/java/decompiler/modules/decompiler/exps/InvocationExprent.java

Lines changed: 17 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -307,7 +307,7 @@ else if (!bounds.containsKey(from)) {
307307
}
308308
}
309309

310-
if (ok && isMappingInBounds(from, to, named, bounds)) {
310+
if (ok && isMappingInBounds(from, to, named, bounds, new HashSet<>())) {
311311
upperBoundsMap.put(from, to);
312312
}
313313
}
@@ -1570,12 +1570,12 @@ private boolean processGenericMapping(VarType from, VarType to, Map<VarType, Lis
15701570
}
15711571

15721572
private void putGenericMapping(VarType from, VarType to, Map<VarType, List<VarType>> named, Map<VarType, List<VarType>> bounds) {
1573-
if (isMappingInBounds(from, to, named, bounds)) {
1573+
if (isMappingInBounds(from, to, named, bounds, new HashSet<>())) {
15741574
genericsMap.put(from, to);
15751575
}
15761576
}
15771577

1578-
private boolean isMappingInBounds(VarType from, VarType to, Map<VarType, List<VarType>> named, Map<VarType, List<VarType>> bounds) {
1578+
private boolean isMappingInBounds(VarType from, VarType to, Map<VarType, List<VarType>> named, Map<VarType, List<VarType>> bounds, Set<Pair<VarType, VarType>> recursivelySeen) {
15791579
if (!bounds.containsKey(from)) {
15801580
return false;
15811581
}
@@ -1612,7 +1612,11 @@ private boolean isMappingInBounds(VarType from, VarType to, Map<VarType, List<Va
16121612
}
16131613
}
16141614

1615-
return isMappingInBounds(bound, newTo, named, bounds);
1615+
Pair<VarType, VarType> pair = Pair.of(bound, newTo);
1616+
if (!recursivelySeen.contains(pair)) {
1617+
recursivelySeen.add(pair);
1618+
return isMappingInBounds(bound, newTo, named, bounds, recursivelySeen);
1619+
}
16161620
}
16171621

16181622
if (newTo.type.ordinal() < CodeType.OBJECT.ordinal()) {
@@ -1654,9 +1658,15 @@ private boolean isMappingInBounds(VarType from, VarType to, Map<VarType, List<Va
16541658
}
16551659

16561660
// T extends Comparable<S>, S extends Object
1657-
if (bounds.containsKey(boundArg) && isMappingInBounds(boundArg, newArg, named, bounds)) {
1658-
toAdd.put(boundArg, newArg);
1659-
continue;
1661+
if (bounds.containsKey(boundArg)) {
1662+
Pair<VarType, VarType> pair = Pair.of(bound, newTo);
1663+
if (!recursivelySeen.contains(pair)) {
1664+
recursivelySeen.add(pair);
1665+
if (isMappingInBounds(boundArg, newArg, named, bounds, recursivelySeen)) {
1666+
toAdd.put(boundArg, newArg);
1667+
continue;
1668+
}
1669+
}
16601670
}
16611671
return false;
16621672
}

test/org/jetbrains/java/decompiler/SingleClassesTest.java

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -716,6 +716,7 @@ private void registerDefault() {
716716
register(JAVA_8, "TestExtraneousImports");
717717
register(JAVA_17, "TestSwitchOnEnumFake");
718718
register(JAVA_16, "TestSwitchExpressionReturnType");
719+
register(JAVA_8, "TestGenericMapping");
719720

720721
}
721722

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
package pkg;
2+
3+
public class TestGenericMapping {
4+
class EntityA<Q extends TestGenericMapping.EntityA<Q, R>, R extends TestGenericMapping.EntityB<Q, R>> {
5+
public void doSomething(Q q) {
6+
}// 6
7+
}
8+
9+
public class EntityB<S extends TestGenericMapping.EntityA<S, T>, T extends TestGenericMapping.EntityB<S, T>> {
10+
public void doSomething(S t) {
11+
t.doSomething(t);// 11
12+
}// 12
13+
}
14+
}
15+
16+
class 'pkg/TestGenericMapping$EntityA' {
17+
method 'doSomething (Lpkg/TestGenericMapping$EntityA;)V' {
18+
0 5
19+
}
20+
}
21+
22+
class 'pkg/TestGenericMapping$EntityB' {
23+
method 'doSomething (Lpkg/TestGenericMapping$EntityA;)V' {
24+
0 10
25+
1 10
26+
2 10
27+
3 10
28+
4 10
29+
5 11
30+
}
31+
}
32+
33+
Lines mapping:
34+
6 <-> 6
35+
11 <-> 11
36+
12 <-> 12
Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
package pkg;
2+
3+
public class TestGenericMapping {
4+
class EntityA<Q extends EntityA<Q, R>, R extends EntityB<Q, R>> {
5+
public void doSomething(final Q q) {
6+
}
7+
}
8+
9+
public class EntityB<S extends EntityA<S, T>, T extends EntityB<S, T>> {
10+
public void doSomething(final S t) {
11+
t.doSomething(t);
12+
}
13+
}
14+
}

0 commit comments

Comments
 (0)