Exception in thread "main" java.lang.StackOverflowError
at java.base/java.lang.StringBuilder.append(StringBuilder.java:179)
at java.base/java.lang.StringBuilder.append(StringBuilder.java:91)
at java.base/java.lang.AbstractStringBuilder.<init>(AbstractStringBuilder.java:112)
at java.base/java.lang.StringBuilder.<init>(StringBuilder.java:131)
at soot.jimple.internal.JLookupSwitchStmt.toString(JLookupSwitchStmt.java:81)
at java.base/java.lang.String.valueOf(String.java:4218)
at java.base/java.lang.StringBuilder.append(StringBuilder.java:173)
at soot.jimple.internal.JLookupSwitchStmt.toString(JLookupSwitchStmt.java:90)
at java.base/java.lang.String.valueOf(String.java:4218)
at java.base/java.lang.StringBuilder.append(StringBuilder.java:173)
at soot.jimple.internal.JLookupSwitchStmt.toString(JLookupSwitchStmt.java:90)
at java.base/java.lang.String.valueOf(String.java:4218)
at java.base/java.lang.StringBuilder.append(StringBuilder.java:173)
at soot.jimple.internal.JLookupSwitchStmt.toString(JLookupSwitchStmt.java:90)
at java.base/java.lang.String.valueOf(String.java:4218)
......
unitChain:
endless loop:
I found that the SOE was triggered when a case of JLookupSwitchStmt is goto another JLookupSwitchStmt. Therefore, I added an if statement, when the unit that a case goto is instanceof JLookupSwitchStmt, I decided the key value of JLookupSwitchStmt as the String value.
modified code in soot.jimple.internal.JLookupSwitchStmt.toString
@Override
public String toString() {
final char endOfLine = ' ';
StringBuilder buf = new StringBuilder(Jimple.LOOKUPSWITCH + "(");
buf.append(keyBox.getValue().toString()).append(')').append(endOfLine);
buf.append('{').append(endOfLine);
for (ListIterator<IntConstant> it = lookupValues.listIterator(); it.hasNext(); ) {
IntConstant c = it.next();
buf.append(" " + Jimple.CASE + " ").append(c).append(": " + Jimple.GOTO + " ");
Unit target = getTarget(it.previousIndex());
if (target instanceof JLookupSwitchStmt) {
// modification from here ******************************************************************
StringBuilder targetStringBuilder = new StringBuilder();
targetStringBuilder.append(Jimple.LOOKUPSWITCH + "(").append(((JLookupSwitchStmt) target).getKeyBox().getValue().toString()).append(')').append(endOfLine);
buf.append(target == this ? "self" : targetStringBuilder.toString()).append(';').append(endOfLine);
}else {
buf.append(target == this ? "self" : target).append(';').append(endOfLine);
}
// modification to here ******************************************************************
}
{
buf.append(" " + Jimple.DEFAULT + ": " + Jimple.GOTO + " ");
Unit target = getDefaultTarget();
buf.append(target == this ? "self" : target).append(';').append(endOfLine);
}
buf.append('}');
return buf.toString();
}
JLookupSwitchStmt contains endless loop, therefore it triggered SOE.
com.androidesk_317.zip
gradle:
java code:
debug information:
unitChain: endless loop:
I found that the SOE was triggered when a case of JLookupSwitchStmt is goto another JLookupSwitchStmt. Therefore, I added an if statement, when the unit that a case goto is instanceof JLookupSwitchStmt, I decided the key value of JLookupSwitchStmt as the String value.
modified code in soot.jimple.internal.JLookupSwitchStmt.toString
After modification: