Use escape_arg in "adb backup".

This doesn't fix the injection vulnerability, but it makes "adb backup"
no worse than the other commands, and lets me fix them all at once.

Bug: 20323053
Change-Id: I39843c065d9d738b6b7943b2ffd660e4a031cc36
diff --git a/adb/commandline.cpp b/adb/commandline.cpp
index c6d7de6..2d41050 100644
--- a/adb/commandline.cpp
+++ b/adb/commandline.cpp
@@ -758,11 +758,10 @@
         cmd += " -v long";
     }
 
-    argc -= 1;
-    argv += 1;
+    --argc;
+    ++argv;
     while (argc-- > 0) {
-        cmd += " ";
-        cmd += escape_arg(*argv++);
+        cmd += " " + escape_arg(*argv++);
     }
 
     send_shell_command(transport, serial, cmd);
@@ -789,21 +788,17 @@
 }
 
 static int backup(int argc, const char** argv) {
-    char buf[4096];
-    char default_name[32];
-    const char* filename = strcpy(default_name, "./backup.ab");
-    int fd, outFd;
-    int i, j;
+    const char* filename = "./backup.ab";
 
     /* find, extract, and use any -f argument */
-    for (i = 1; i < argc; i++) {
+    for (int i = 1; i < argc; i++) {
         if (!strcmp("-f", argv[i])) {
             if (i == argc-1) {
                 fprintf(stderr, "adb: -f passed with no filename\n");
                 return usage();
             }
             filename = argv[i+1];
-            for (j = i+2; j <= argc; ) {
+            for (int j = i+2; j <= argc; ) {
                 argv[i++] = argv[j++];
             }
             argc -= 2;
@@ -816,20 +811,21 @@
 
     adb_unlink(filename);
     mkdirs(filename);
-    outFd = adb_creat(filename, 0640);
+    int outFd = adb_creat(filename, 0640);
     if (outFd < 0) {
         fprintf(stderr, "adb: unable to open file %s\n", filename);
         return -1;
     }
 
-    snprintf(buf, sizeof(buf), "backup");
-    for (argc--, argv++; argc; argc--, argv++) {
-        strncat(buf, ":", sizeof(buf) - strlen(buf) - 1);
-        strncat(buf, argv[0], sizeof(buf) - strlen(buf) - 1);
+    std::string cmd = "backup:";
+    --argc;
+    ++argv;
+    while (argc-- > 0) {
+        cmd += " " + escape_arg(*argv++);
     }
 
-    D("backup. filename=%s buf=%s\n", filename, buf);
-    fd = adb_connect(buf);
+    D("backup. filename=%s cmd=%s\n", filename, cmd.c_str());
+    int fd = adb_connect(cmd.c_str());
     if (fd < 0) {
         fprintf(stderr, "adb: unable to connect for backup\n");
         adb_close(outFd);
@@ -1226,8 +1222,7 @@
         argc -= 2;
         argv += 2;
         while (argc-- > 0) {
-            cmd += " ";
-            cmd += escape_arg(*argv++);
+            cmd += " " + escape_arg(*argv++);
         }
 
         while (true) {
@@ -1267,8 +1262,7 @@
         argc -= 2;
         argv += 2;
         while (argc-- > 0) {
-            cmd += " ";
-            cmd += escape_arg(*argv++);
+            cmd += " " + escape_arg(*argv++);
         }
 
         int fd = adb_connect(cmd.c_str());
@@ -1612,8 +1606,7 @@
     std::string cmd = "shell:pm";
 
     while (argc-- > 0) {
-        cmd += " ";
-        cmd += escape_arg(*argv++);
+        cmd += " " + escape_arg(*argv++);
     }
 
     send_shell_command(transport, serial, cmd);
@@ -1744,8 +1737,7 @@
 
     std::string cmd = android::base::StringPrintf("exec:pm install-create -S %" PRIu64, total_size);
     for (i = 1; i < first_apk; i++) {
-        cmd += " ";
-        cmd += escape_arg(argv[i]);
+        cmd += " " + escape_arg(argv[i]);
     }
 
     // Create install session
diff --git a/adb/services.cpp b/adb/services.cpp
index fa0e73f..ff13722 100644
--- a/adb/services.cpp
+++ b/adb/services.cpp
@@ -31,6 +31,8 @@
 #include <unistd.h>
 #endif
 
+#include <base/stringprintf.h>
+
 #if !ADB_HOST
 #include "base/file.h"
 #include "cutils/android_reboot.h"
@@ -499,19 +501,8 @@
     } else if(!strncmp(name, "unroot:", 7)) {
         ret = create_service_thread(restart_unroot_service, NULL);
     } else if(!strncmp(name, "backup:", 7)) {
-        char* arg = strdup(name + 7);
-        if (arg == NULL) return -1;
-        char* c = arg;
-        for (; *c != '\0'; c++) {
-            if (*c == ':')
-                *c = ' ';
-        }
-        char* cmd;
-        if (asprintf(&cmd, "/system/bin/bu backup %s", arg) != -1) {
-            ret = create_subproc_thread(cmd, SUBPROC_RAW);
-            free(cmd);
-        }
-        free(arg);
+        ret = create_subproc_thread(android::base::StringPrintf("/system/bin/bu backup %s",
+                                                                (name + 7)).c_str(), SUBPROC_RAW);
     } else if(!strncmp(name, "restore:", 8)) {
         ret = create_subproc_thread("/system/bin/bu restore", SUBPROC_RAW);
     } else if(!strncmp(name, "tcpip:", 6)) {