From 2ee9604dbcf693a2b540ae6c3a0175a66071c0db Mon Sep 17 00:00:00 2001
From: Wladimir Palant <fqcgithub@palant.de>
Date: Mon, 1 Mar 2021 20:20:01 +0100
Subject: [PATCH] Made MethodLogger use extended format strings as well

---
 README.md                                     |  2 +
 .../apkInstrumentation/MethodLogger.java      | 41 ++++++-------------
 .../apkInstrumentation/UnitSequence.java      | 24 +++++++++++
 3 files changed, 39 insertions(+), 28 deletions(-)

diff --git a/README.md b/README.md
index 444ebdd..4c1cf2d 100644
--- a/README.md
+++ b/README.md
@@ -40,6 +40,7 @@ Some components will allow specifying extended format strings for data to be log
 * `result`: Call result if available
 * `this`: Instance reference
 * `argNN`: Argument value where NN is the argument’s zero-based position
+* `args`: Comma-separated list of all arguments (stringified)
 
 In addition, the format specifier `%x` is treated specially: `System.identityHashCode()` will be called on the corresponding input and the result hex-formatted.
 
@@ -74,6 +75,7 @@ Configuration options:
 * `MethodLogger.enabled`: add to enable this component
 * `MethodLogger.filter`: (optional) restricts functionality to a set of methods, for value format see Method filters section above
 * `MethodLogger.tag`: (optional) log tag to be used (default is `MethodLogger`)
+* `MethodLogger.format`: (optional) extended format string to be used, see Extended format strings section above (default is `Entered method {method:%s} ({args:%s})`)
 
 ## AssignmentRemover component
 
diff --git a/src/info/palant/apkInstrumentation/MethodLogger.java b/src/info/palant/apkInstrumentation/MethodLogger.java
index e88fd18..ef19bd0 100644
--- a/src/info/palant/apkInstrumentation/MethodLogger.java
+++ b/src/info/palant/apkInstrumentation/MethodLogger.java
@@ -6,19 +6,19 @@
 
 package info.palant.apkInstrumentation;
 
-import java.util.List;
 import java.util.Map;
 import java.util.Properties;
+import java.util.stream.Collectors;
 
 import soot.Body;
 import soot.BodyTransformer;
-import soot.Local;
-import soot.jimple.StringConstant;
+import soot.Value;
 
 public class MethodLogger extends BodyTransformer
 {
   private final MethodConfig filter;
   private String tag;
+  private String format;
 
   public MethodLogger(Properties config)
   {
@@ -31,6 +31,10 @@ public MethodLogger(Properties config)
     this.tag = config.getProperty("MethodLogger.tag");
     if (tag == null)
       this.tag = "MethodLogger";
+
+    this.format = config.getProperty("MethodLogger.format");
+    if (this.format == null)
+      this.format = "Entered method {method:%s} ({args:%s})";
   }
 
   @Override
@@ -40,31 +44,12 @@ protected void internalTransform(Body body, String phaseName, Map<String, String
       return;
 
     UnitSequence units = new UnitSequence(body);
-
-    List<Local> parameters = body.getParameterLocals();
-    if (parameters.size() > 0)
-    {
-      Local message = units.newObject(
-        "java.lang.StringBuilder",
-        StringConstant.v("Entered method " + body.getMethod().getSignature() + " with parameters: ")
-      );
-
-      boolean first = true;
-      for (Local parameter: parameters)
-      {
-        if (first)
-          first = false;
-        else
-          units.call(message, "append", StringConstant.v(", "));
-
-        units.call(message, "append", units.stringify(parameter));
-      }
-
-      units.log(this.tag, units.stringify(message));
-    }
-    else
-      units.log(this.tag, StringConstant.v("Entered method " + body.getMethod().getSignature()));
-
+    units.log(this.tag, units.extendedFormat(
+      this.format,
+      null,
+      body.getThisLocal(),
+      body.getParameterLocals().stream().map(local -> (Value)local).collect(Collectors.toList())
+    ));
     units.insertBefore();
   }
 }
diff --git a/src/info/palant/apkInstrumentation/UnitSequence.java b/src/info/palant/apkInstrumentation/UnitSequence.java
index c14aebc..d2763fe 100644
--- a/src/info/palant/apkInstrumentation/UnitSequence.java
+++ b/src/info/palant/apkInstrumentation/UnitSequence.java
@@ -245,6 +245,30 @@ else if (matcher.group(1).equals("result"))
         arg = result;
       else if (matcher.group(1).equals("this"))
         arg = thisRef;
+      else if (matcher.group(1).equals("args"))
+      {
+        if (argValues.size() == 0)
+          arg = StringConstant.v("");
+        else if (argValues.size() == 1)
+          arg = this.stringify(argValues.get(0));
+        else
+        {
+          Local builder = this.newObject("java.lang.StringBuilder");
+
+          boolean first = true;
+          for (Value argValue: argValues)
+          {
+            if (first)
+              first = false;
+            else
+              this.call(builder, "append", StringConstant.v(", "));
+
+            this.call(builder, "append", this.stringify(argValue));
+          }
+
+          arg = this.stringify(builder);
+        }
+      }
       else if (matcher.group(1).startsWith("arg"))
         arg = argValues.get(Integer.parseInt(matcher.group(1).substring(3)));
       else