aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorGravatar Arun Prakash Jana <engineerarun@gmail.com>2019-01-06 00:02:55 +0530
committerGravatar Arun Prakash Jana <engineerarun@gmail.com>2019-01-06 00:02:55 +0530
commit6dc151e05dd25b27fde94429d17e4b6b873f0c70 (patch)
tree427619ff1253bcfdb61b654be102f88bfbe5875a
parentb811997120ff6a0c83e6b661463e1a16bededb05 (diff)
downloadnnn-6dc151e05dd25b27fde94429d17e4b6b873f0c70.tar.gz
Quote argument with sh -c
-rw-r--r--README.md2
-rw-r--r--src/nnn.c59
2 files changed, 50 insertions, 11 deletions
diff --git a/README.md b/README.md
index dd49ddb..9c5c7bb 100644
--- 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).
diff --git a/src/nnn.c b/src/nnn.c
index c6264af..7c473ab 100644
--- 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;