Skip to content

Commit d3d1817

Browse files
committed
Fix clashing names stack overflow
1 parent e7fe549 commit d3d1817

File tree

1 file changed

+20
-13
lines changed

1 file changed

+20
-13
lines changed

src/org/jetbrains/java/decompiler/modules/decompiler/vars/VarDefinitionHelper.java

Lines changed: 20 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1452,18 +1452,22 @@ public void remapClashingNames(Statement root, StructMethod mt) {
14521452
start += (md.params[i].stackSize - 1);
14531453
}
14541454

1455-
iterateClashingNames(root, mt, varDefinitions, liveVarDefs, nameMap);
1455+
Set<String> seenMethods = new HashSet<>();
1456+
seenMethods.add(InterpreterUtil.makeUniqueKey(mt.getName(), mt.getDescriptor()));
1457+
1458+
iterateClashingNames(root, mt, varDefinitions, liveVarDefs, nameMap, seenMethods);
14561459
}
14571460

1458-
private void iterateClashingNames(Statement stat, StructMethod mt, Map<Statement, Set<VarInMethod>> varDefinitions, Set<VarInMethod> liveVarDefs, Map<VarInMethod, String> nameMap) {
1461+
private void iterateClashingNames(Statement stat, StructMethod mt, Map<Statement, Set<VarInMethod>> varDefinitions,
1462+
Set<VarInMethod> liveVarDefs, Map<VarInMethod, String> nameMap, Set<String> seenMethods) {
14591463
Set<VarInMethod> curVarDefs = new HashSet<>();
14601464

14611465
boolean shouldRemoveAtEnd = false;
14621466

14631467
// Process var definitions as owned by the parent- they come before the statement, and so their scope extends past the actual statement.
14641468
for (Exprent exprent : stat.getVarDefinitions()) {
14651469
Set<VarInMethod> upDefs = new HashSet<>();
1466-
iterateClashingExprent(stat, mt, varDefinitions, exprent, liveVarDefs, upDefs, nameMap);
1470+
iterateClashingExprent(stat, mt, varDefinitions, exprent, liveVarDefs, upDefs, nameMap, seenMethods);
14671471
liveVarDefs.addAll(upDefs);
14681472
varDefinitions.put(stat.getParent(), upDefs);
14691473
}
@@ -1474,7 +1478,7 @@ private void iterateClashingNames(Statement stat, StructMethod mt, Map<Statement
14741478
BasicBlockStatement basic = stat.getBasichead();
14751479
for (Exprent exprent : basic.getExprents()) {
14761480
for (Exprent ex : exprent.getAllExprents(true, true)) {
1477-
iterateClashingExprent(basic, mt, varDefinitions, ex, liveVarDefs, upDefs, nameMap);
1481+
iterateClashingExprent(basic, mt, varDefinitions, ex, liveVarDefs, upDefs, nameMap, seenMethods);
14781482
}
14791483
}
14801484

@@ -1489,7 +1493,7 @@ private void iterateClashingNames(Statement stat, StructMethod mt, Map<Statement
14891493
// Sort order from getAllExprents here is crucial!
14901494
// Say, for example, "MyType t = method(t -> ....);"
14911495
// It is imperative that the lhs of the assign comes first, so that any defs in the rhs can be properly seen.
1492-
iterateClashingExprent(stat, mt, varDefinitions, ex, liveVarDefs, curVarDefs, nameMap);
1496+
iterateClashingExprent(stat, mt, varDefinitions, ex, liveVarDefs, curVarDefs, nameMap, seenMethods);
14931497
}
14941498
}
14951499
} else {
@@ -1499,7 +1503,7 @@ private void iterateClashingNames(Statement stat, StructMethod mt, Map<Statement
14991503
List<Exprent> exprents = ((Exprent) obj).getAllExprents(true, true);
15001504

15011505
for (Exprent exprent : exprents) {
1502-
iterateClashingExprent(stat, mt, varDefinitions, exprent, liveVarDefs, curVarDefs, nameMap);
1506+
iterateClashingExprent(stat, mt, varDefinitions, exprent, liveVarDefs, curVarDefs, nameMap, seenMethods);
15031507
}
15041508
}
15051509
}
@@ -1538,7 +1542,7 @@ private void iterateClashingNames(Statement stat, StructMethod mt, Map<Statement
15381542
}
15391543
}
15401544

1541-
iterateClashingNames(st, mt, varDefinitions, liveVarDefs, nameMap);
1545+
iterateClashingNames(st, mt, varDefinitions, liveVarDefs, nameMap, seenMethods);
15421546
}
15431547
}
15441548

@@ -1555,7 +1559,7 @@ private void iterateClashingNames(Statement stat, StructMethod mt, Map<Statement
15551559
// Process deferred statements
15561560
if (iterate) {
15571561
for (Statement st : deferred) {
1558-
iterateClashingNames(st, mt, varDefinitions, liveVarDefs, nameMap);
1562+
iterateClashingNames(st, mt, varDefinitions, liveVarDefs, nameMap, seenMethods);
15591563
}
15601564
}
15611565

@@ -1575,7 +1579,8 @@ private void clearStatement(Map<Statement, Set<VarInMethod>> varDefinitions, Set
15751579
}
15761580
}
15771581

1578-
private void iterateClashingExprent(Statement stat, StructMethod mt, Map<Statement, Set<VarInMethod>> varDefinitions, Exprent exprent, Set<VarInMethod> liveVarDefs, Set<VarInMethod> curVarDefs, Map<VarInMethod, String> nameMap) {
1582+
private void iterateClashingExprent(Statement stat, StructMethod mt, Map<Statement, Set<VarInMethod>> varDefinitions, Exprent exprent,
1583+
Set<VarInMethod> liveVarDefs, Set<VarInMethod> curVarDefs, Map<VarInMethod, String> nameMap, Set<String> seenMethods) {
15791584
if (exprent instanceof NewExprent) {
15801585
NewExprent newExprent = (NewExprent) exprent;
15811586
// Check if this is a lambda with a body
@@ -1584,7 +1589,8 @@ private void iterateClashingExprent(Statement stat, StructMethod mt, Map<Stateme
15841589
if (node != null && node.getWrapper() != null) {
15851590
MethodWrapper mw = node.getWrapper().getMethods().getWithKey(node.lambdaInformation.content_method_key);
15861591
StructMethod mt2 = node.getWrapper().getClassStruct().getMethod(node.lambdaInformation.content_method_key);
1587-
if (mt2 != null && mw != null) {
1592+
if (mt2 != null && mw != null && !seenMethods.contains(InterpreterUtil.makeUniqueKey(mt2.getName(), mt2.getDescriptor()))) {
1593+
seenMethods.add(InterpreterUtil.makeUniqueKey(mt2.getName(), mt2.getDescriptor()));
15881594
// Propagate current data through to lambda
15891595
VarDefinitionHelper vardef = new VarDefinitionHelper(mw.root, mt2, mw.varproc, false);
15901596

@@ -1616,7 +1622,7 @@ private void iterateClashingExprent(Statement stat, StructMethod mt, Map<Stateme
16161622
}
16171623

16181624
// Iterate clashing names with the lambda's body, with the context of the outer method
1619-
vardef.iterateClashingNames(mw.root, mt2, varDefinitions, liveVarDefs, nameMap);
1625+
vardef.iterateClashingNames(mw.root, mt2, varDefinitions, liveVarDefs, nameMap, seenMethods);
16201626

16211627
for (Entry<VarVersionPair, String> e : vardef.getClashingNames().entrySet()) {
16221628
mw.varproc.setClashingName(e.getKey(), e.getValue());
@@ -1636,7 +1642,8 @@ private void iterateClashingExprent(Statement stat, StructMethod mt, Map<Stateme
16361642
for (String mthKey : node.getWrapper().getMethods().getLstKeys()) {
16371643
MethodWrapper mw = node.getWrapper().getMethods().getWithKey(mthKey);
16381644
StructMethod mt2 = node.getWrapper().getClassStruct().getMethod(mthKey);
1639-
if (mt2 != null && mw != null && !mt2.hasModifier(CodeConstants.ACC_SYNTHETIC)) {
1645+
if (mt2 != null && mw != null && !mt2.hasModifier(CodeConstants.ACC_SYNTHETIC) && !seenMethods.contains(InterpreterUtil.makeUniqueKey(mt2.getName(), mt2.getDescriptor()))) {
1646+
seenMethods.add(InterpreterUtil.makeUniqueKey(mt2.getName(), mt2.getDescriptor()));
16401647
// Propagate current data through to method
16411648
VarDefinitionHelper vardef = new VarDefinitionHelper(mw.root, mt2, mw.varproc, false);
16421649

@@ -1669,7 +1676,7 @@ private void iterateClashingExprent(Statement stat, StructMethod mt, Map<Stateme
16691676
}
16701677

16711678
// Iterate clashing names with the lambda's body, with the context of the outer method
1672-
vardef.iterateClashingNames(mw.root, mt2, varDefinitions, liveVarDefs, nameMap);
1679+
vardef.iterateClashingNames(mw.root, mt2, varDefinitions, liveVarDefs, nameMap, seenMethods);
16731680

16741681
for (Entry<VarVersionPair, String> e : vardef.getClashingNames().entrySet()) {
16751682
mw.varproc.setClashingName(e.getKey(), e.getValue());

0 commit comments

Comments
 (0)