|
20 | 20 | import org.slf4j.LoggerFactory; |
21 | 21 |
|
22 | 22 | import heros.solver.Pair; |
| 23 | +import soot.ArrayType; |
23 | 24 | import soot.Body; |
24 | 25 | import soot.BooleanType; |
25 | 26 | import soot.ByteType; |
|
39 | 40 | import soot.PointsToAnalysis; |
40 | 41 | import soot.RefType; |
41 | 42 | import soot.Scene; |
| 43 | +import soot.ShortType; |
42 | 44 | import soot.SootClass; |
43 | 45 | import soot.SootMethod; |
44 | 46 | import soot.SootMethodRef; |
@@ -627,6 +629,8 @@ private static List<Stmt> patchStringConcatInstruction(Stmt callSite, DynamicInv |
627 | 629 | SootMethodRef toStringRef = scene.getObjectType().getSootClass().getMethod("java.lang.String toString()") |
628 | 630 | .makeRef(); |
629 | 631 |
|
| 632 | + SootClass scArrays = Scene.v().getSootClass("java.util.Arrays"); |
| 633 | + |
630 | 634 | List<Stmt> newStmts = new ArrayList<>(); |
631 | 635 | NumberedString calleeSubSig = diexpr.getBootstrapMethodRef().getSubSignature(); |
632 | 636 | if (calleeSubSig.equals(scene.getSubSigNumberer().findOrAdd(SIG_CONCAT_CONSTANTS)) |
@@ -657,15 +661,56 @@ else if (argType instanceof BooleanType) |
657 | 661 | appendRef = scStringBuilder.getMethod("java.lang.StringBuilder append(boolean)").makeRef(); |
658 | 662 | else if (argType instanceof CharType) |
659 | 663 | appendRef = scStringBuilder.getMethod("java.lang.StringBuilder append(char)").makeRef(); |
| 664 | + else if (argType instanceof ShortType) |
| 665 | + appendRef = scStringBuilder.getMethod("java.lang.StringBuilder append(short)").makeRef(); |
660 | 666 | else if (argType instanceof IntType) |
661 | 667 | appendRef = scStringBuilder.getMethod("java.lang.StringBuilder append(int)").makeRef(); |
662 | 668 | else if (argType instanceof LongType) |
663 | 669 | appendRef = scStringBuilder.getMethod("java.lang.StringBuilder append(long)").makeRef(); |
664 | 670 | else if (argType instanceof FloatType) |
665 | 671 | appendRef = scStringBuilder.getMethod("java.lang.StringBuilder append(float)").makeRef(); |
666 | 672 | else if (argType instanceof DoubleType) |
667 | | - appendRef = scStringBuilder.getMethod("java.lang.StringBuilder append(doble)").makeRef(); |
668 | | - else { |
| 673 | + appendRef = scStringBuilder.getMethod("java.lang.StringBuilder append(double)").makeRef(); |
| 674 | + else if (argType instanceof ArrayType) { |
| 675 | + // For an array argument, we need to Arrays.toString() first |
| 676 | + ArrayType at = (ArrayType) argType; |
| 677 | + Type elementType = at.getElementType(); |
| 678 | + |
| 679 | + Local sarg = lg.generateLocal(RefType.v("java.lang.String")); |
| 680 | + SootMethodRef elementToStringRef = null; |
| 681 | + if (elementType instanceof RefType) |
| 682 | + elementToStringRef = scArrays.getMethod("java.lang.String toString(java.lang.Object[])") |
| 683 | + .makeRef(); |
| 684 | + else if (elementType instanceof ByteType) |
| 685 | + elementToStringRef = scArrays.getMethod("java.lang.String toString(byte[])").makeRef(); |
| 686 | + else if (elementType instanceof BooleanType) |
| 687 | + elementToStringRef = scArrays.getMethod("java.lang.String toString(boolean[])").makeRef(); |
| 688 | + else if (elementType instanceof CharType) |
| 689 | + elementToStringRef = scArrays.getMethod("java.lang.String toString(char[])").makeRef(); |
| 690 | + else if (elementType instanceof ShortType) |
| 691 | + elementToStringRef = scArrays.getMethod("java.lang.String toString(short[])").makeRef(); |
| 692 | + else if (elementType instanceof IntType) |
| 693 | + elementToStringRef = scArrays.getMethod("java.lang.String toString(int[])").makeRef(); |
| 694 | + else if (elementType instanceof LongType) |
| 695 | + elementToStringRef = scArrays.getMethod("java.lang.String toString(long[])").makeRef(); |
| 696 | + else if (elementType instanceof FloatType) |
| 697 | + elementToStringRef = scArrays.getMethod("java.lang.String toString(float[])").makeRef(); |
| 698 | + else if (elementType instanceof DoubleType) |
| 699 | + elementToStringRef = scArrays.getMethod("java.lang.String toString(double[])").makeRef(); |
| 700 | + else { |
| 701 | + throw new RuntimeException(String.format( |
| 702 | + "Invalid array element type %s for string concatenation in dynamic invocation", |
| 703 | + elementType.toString())); |
| 704 | + } |
| 705 | + |
| 706 | + Stmt toStringStmt = jimple.newAssignStmt(sarg, |
| 707 | + jimple.newStaticInvokeExpr(elementToStringRef, Collections.singletonList(arg))); |
| 708 | + toStringStmt.addTag(SimulatedCodeElementTag.TAG); |
| 709 | + newStmts.add(toStringStmt); |
| 710 | + |
| 711 | + arg = sarg; |
| 712 | + appendRef = scStringBuilder.getMethod("java.lang.StringBuilder append(java.lang.String)").makeRef(); |
| 713 | + } else { |
669 | 714 | throw new RuntimeException(String.format( |
670 | 715 | "Invalid type %s for string concatenation in dynamic invocation", argType.toString())); |
671 | 716 | } |
|
0 commit comments