]> Sergey Matveev's repositories - nnn.git/commitdiff
Quote argument with sh -c
authorArun Prakash Jana <engineerarun@gmail.com>
Sat, 5 Jan 2019 18:32:55 +0000 (00:02 +0530)
committerArun Prakash Jana <engineerarun@gmail.com>
Sat, 5 Jan 2019 18:32:55 +0000 (00:02 +0530)
README.md
src/nnn.c

index dd49ddb0a22b51eb9fb4441a133933064d8cc85f..9c5c7bb0e7318a53f690868e307aacd04bf0014c 100644 (file)
--- a/README.md
+++ b/README.md
@@ -136,7 +136,7 @@ Stripped binary (or script) size and memory usage of `nnn` and some other simila
 <b>   1M</b>   50496  <b>15328</b>   4076 S   0.2   vifm
 <b>   1M</b>   72152  <b>12468</b>   7336 S   0.2   mc
 <b>  70K</b>   16068  <b> 4620</b>   2408 S   0.1   ncdu
-<b>  52K</b>   15712  <b> 4368</b>   2512 S   0.1   nnn -S
+<b>  55K</b>   15712  <b> 4368</b>   2512 S   0.1   nnn -S
 </pre>
 
 Intrigued? Find out [HOW](https://github.com/jarun/nnn/wiki/performance-factors).
index c6264af5c91542585e688cb75c36b012ed55cf71..7c473ab793d8bc2f942fcb2bed4d8e7df82e7565 100644 (file)
--- a/src/nnn.c
+++ b/src/nnn.c
@@ -385,6 +385,7 @@ static char * const utils[] = {
 #define STR_INVBM_KEY 3
 #define STR_COPY_ID 4
 #define STR_DATE_ID 5
+#define STR_UNSAFE 6
 
 static const char messages[][16] = {
        "nftw failed",
@@ -393,6 +394,7 @@ static const char messages[][16] = {
        "invalid key",
        "copy not set",
        "%F %T %z",
+       "unsafe cmd",
 };
 
 /* Forward declarations */
@@ -879,6 +881,49 @@ static void spawn(const char *file, const char *arg1, const char *arg2, const ch
        }
 }
 
+/*
+ * Quotes argument and spawns a shell command
+ * Uses g_buf
+ */
+static bool quote_run_sh_cmd(const char *cmd, const char *arg, const char *path)
+{
+       const char *ptr;
+       size_t r;
+
+       if (!cmd)
+               return FALSE;
+
+       r = xstrlcpy(g_buf, cmd, CMD_LEN_MAX);
+
+       if (arg) {
+               if (r >= CMD_LEN_MAX - 4) { /* space for at least 4 chars - space'c' */
+                       printmsg(messages[6]);
+                       return FALSE;
+               }
+
+               for (ptr = arg; *ptr; ++ptr)
+                       if (*ptr == '\'') {
+                               printmsg(messages[6]);
+                               return FALSE;
+                       }
+
+               g_buf[r - 1] = ' ';
+               g_buf[r] = '\'';
+               r += xstrlcpy(g_buf + r + 1, arg, CMD_LEN_MAX - 1 - r);
+               if (r >= CMD_LEN_MAX - 1) {
+                       printmsg(messages[6]);
+                       return FALSE;
+               }
+
+               g_buf[r] = '\'';
+               g_buf[r + 1] = '\0';
+       }
+
+       DPRINTF_S(g_buf);
+       spawn("sh", "-c", g_buf, path, F_NORMAL);
+       return TRUE;
+}
+
 /* Get program name from env var, else return fallback program */
 static char *xgetenv(const char *name, char *fallback)
 {
@@ -2717,11 +2762,8 @@ nochange:
                                if (cfg.useeditor &&
                                    get_output(g_buf, CMD_LEN_MAX, "file", FILE_OPTS, newpath, FALSE) &&
                                    strstr(g_buf, "text/") == g_buf) {
-                                       r = xstrlcpy(g_buf, editor, CMD_LEN_MAX);
-                                       g_buf[r - 1] = ' ';
-                                       xstrlcpy(g_buf + r, newpath, CMD_LEN_MAX - r);
-                                       DPRINTF_S(g_buf);
-                                       spawn("sh", "-c", g_buf, path, F_NORMAL);
+                                       if (!quote_run_sh_cmd(editor, newpath, path))
+                                               goto nochange;
                                        continue;
                                }
 
@@ -3027,11 +3069,8 @@ nochange:
                                r = show_help(path);
                                break;
                        case SEL_RUNEDIT:
-                               r = xstrlcpy(g_buf, editor, CMD_LEN_MAX);
-                               g_buf[r - 1] = ' ';
-                               xstrlcpy(g_buf + r, dents[cur].name, CMD_LEN_MAX - r);
-                               r = TRUE;
-                               spawn("sh", "-c", g_buf, path, F_NORMAL);
+                               if (!quote_run_sh_cmd(editor, dents[cur].name, path))
+                                       goto nochange;
                                break;
                        case SEL_RUNPAGE:
                                r = TRUE;