Uniformly escape shell arguments.

Arguments with embedded spaces need to be wrapped in quotes, which
changes the overall escaping strategy.  Instead of mixing the two
strategies, just always wrap arguments in quotes.

Bug: 15479704
Change-Id: I03eacfa1bd6c220d4ec6617b825ebb0c43c7221e
diff --git a/commandline.c b/commandline.c
index 4f2d40f..32121d3 100644
--- a/commandline.c
+++ b/commandline.c
@@ -545,39 +545,33 @@
     }
 }
 
-/** duplicate string and quote all \ " ( ) chars + space character. */
-static char *
-dupAndQuote(const char *s)
+/** Duplicate and escape given argument. */
+static char *escape_argv(const char *s)
 {
     const char *ts;
     size_t alloc_len;
     char *ret;
     char *dest;
 
-    ts = s;
-
-    alloc_len = 0;
-
-    for( ;*ts != '\0'; ts++) {
+    alloc_len = 2;
+    for (ts = s; *ts != '\0'; ts++) {
         alloc_len++;
-        if (*ts == ' ' || *ts == '"' || *ts == '\\' || *ts == '(' || *ts == ')') {
+        if (*ts == '"' || *ts == '\\') {
             alloc_len++;
         }
     }
 
-    ret = (char *)malloc(alloc_len + 1);
-
-    ts = s;
+    ret = (char *) malloc(alloc_len + 1);
     dest = ret;
 
-    for ( ;*ts != '\0'; ts++) {
-        if (*ts == ' ' || *ts == '"' || *ts == '\\' || *ts == '(' || *ts == ')') {
+    *dest++ = '"';
+    for (ts = s; *ts != '\0'; ts++) {
+        if (*ts == '"' || *ts == '\\') {
             *dest++ = '\\';
         }
-
         *dest++ = *ts;
     }
-
+    *dest++ = '"';
     *dest++ = '\0';
 
     return ret;
@@ -684,30 +678,24 @@
     char buf[4096];
 
     char *log_tags;
-    char *quoted_log_tags;
+    char *quoted;
 
     log_tags = getenv("ANDROID_LOG_TAGS");
-    quoted_log_tags = dupAndQuote(log_tags == NULL ? "" : log_tags);
-
+    quoted = escape_argv(log_tags == NULL ? "" : log_tags);
     snprintf(buf, sizeof(buf),
-        "shell:export ANDROID_LOG_TAGS=\"\%s\" ; exec logcat",
-        quoted_log_tags);
+            "shell:export ANDROID_LOG_TAGS=%s ; exec logcat", quoted);
+    free(quoted);
 
-    free(quoted_log_tags);
-
-    if (!strcmp(argv[0],"longcat")) {
-        strncat(buf, " -v long", sizeof(buf)-1);
+    if (!strcmp(argv[0], "longcat")) {
+        strncat(buf, " -v long", sizeof(buf) - 1);
     }
 
     argc -= 1;
     argv += 1;
     while(argc-- > 0) {
-        char *quoted;
-
-        quoted = dupAndQuote (*argv++);
-
-        strncat(buf, " ", sizeof(buf)-1);
-        strncat(buf, quoted, sizeof(buf)-1);
+        quoted = escape_argv(*argv++);
+        strncat(buf, " ", sizeof(buf) - 1);
+        strncat(buf, quoted, sizeof(buf) - 1);
         free(quoted);
     }
 
@@ -1219,7 +1207,7 @@
         argc -= 2;
         argv += 2;
         while (argc-- > 0) {
-            char *quoted = dupAndQuote(*argv++);
+            char *quoted = escape_argv(*argv++);
             strncat(buf, " ", sizeof(buf) - 1);
             strncat(buf, quoted, sizeof(buf) - 1);
             free(quoted);
@@ -1262,7 +1250,7 @@
         argc -= 2;
         argv += 2;
         while (argc-- > 0) {
-            char *quoted = dupAndQuote(*argv++);
+            char *quoted = escape_argv(*argv++);
             strncat(buf, " ", sizeof(buf) - 1);
             strncat(buf, quoted, sizeof(buf) - 1);
             free(quoted);
@@ -1687,12 +1675,9 @@
     snprintf(buf, sizeof(buf), "shell:pm");
 
     while(argc-- > 0) {
-        char *quoted;
-
-        quoted = dupAndQuote(*argv++);
-
-        strncat(buf, " ", sizeof(buf)-1);
-        strncat(buf, quoted, sizeof(buf)-1);
+        char *quoted = escape_argv(*argv++);
+        strncat(buf, " ", sizeof(buf) - 1);
+        strncat(buf, quoted, sizeof(buf) - 1);
         free(quoted);
     }
 
@@ -1724,7 +1709,7 @@
     char* quoted;
 
     snprintf(buf, sizeof(buf), "shell:rm ");
-    quoted = dupAndQuote(filename);
+    quoted = escape_argv(filename);
     strncat(buf, quoted, sizeof(buf)-1);
     free(quoted);