mirror of
https://github.com/jarun/nnn.git
synced 2025-01-15 21:36:42 +00:00
shell_escape: return strlen or -1 on failure
also check for `outlen < 3` since the function unconditionally writes at least 3 bytes.
This commit is contained in:
parent
1cf9654368
commit
94bac4ef98
33
src/nnn.c
33
src/nnn.c
|
@ -1335,21 +1335,23 @@ static char *bmtarget(const char *filepath, char *cwd, char *buf)
|
||||||
}
|
}
|
||||||
|
|
||||||
/* wraps the argument in single quotes so it can be safely fed to shell */
|
/* wraps the argument in single quotes so it can be safely fed to shell */
|
||||||
static bool shell_escape(char *output, size_t outlen, const char *s)
|
static ssize_t shell_escape(char *output, size_t outlen, const char *s)
|
||||||
{
|
{
|
||||||
size_t n = xstrlen(s), w = 0;
|
size_t n = xstrlen(s), w = 0;
|
||||||
|
|
||||||
if (s == output) {
|
if (s == output || outlen < 3) {
|
||||||
DPRINTF_S("s == output");
|
errno = EINVAL;
|
||||||
return FALSE;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
output[w++] = '\''; /* begin single quote */
|
output[w++] = '\''; /* begin single quote */
|
||||||
for (size_t r = 0; r < n; ++r) {
|
for (size_t r = 0; r < n; ++r) {
|
||||||
/* potentially too big: 4 for the single quote case, 2 from
|
/* potentially too big: 4 for the single quote case, 2 from
|
||||||
* outside the loop */
|
* outside the loop */
|
||||||
if (w + 6 >= outlen)
|
if (w + 6 >= outlen) {
|
||||||
return FALSE;
|
errno = ENAMETOOLONG;
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
switch (s[r]) {
|
switch (s[r]) {
|
||||||
/* the only thing that has special meaning inside single
|
/* the only thing that has special meaning inside single
|
||||||
|
@ -1366,8 +1368,8 @@ static bool shell_escape(char *output, size_t outlen, const char *s)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
output[w++] = '\''; /* end single quote */
|
output[w++] = '\''; /* end single quote */
|
||||||
output[w++] = '\0'; /* nul terminator */
|
output[w] = '\0'; /* nul terminator */
|
||||||
return TRUE;
|
return w;
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool set_tilde_in_path(char *path)
|
static bool set_tilde_in_path(char *path)
|
||||||
|
@ -2841,7 +2843,7 @@ static void archive_selection(const char *cmd, const char *archive)
|
||||||
|
|
||||||
static void write_lastdir(const char *curpath, const char *outfile)
|
static void write_lastdir(const char *curpath, const char *outfile)
|
||||||
{
|
{
|
||||||
bool tilde = false;
|
bool tilde = false, ok = false;
|
||||||
if (!outfile)
|
if (!outfile)
|
||||||
xstrsncpy(cfgpath + xstrlen(cfgpath), "/.lastd", 8);
|
xstrsncpy(cfgpath + xstrlen(cfgpath), "/.lastd", 8);
|
||||||
else
|
else
|
||||||
|
@ -2850,15 +2852,14 @@ static void write_lastdir(const char *curpath, const char *outfile)
|
||||||
int fd = open(outfile
|
int fd = open(outfile
|
||||||
? (tilde ? g_buf : outfile)
|
? (tilde ? g_buf : outfile)
|
||||||
: cfgpath, O_CREAT | O_WRONLY | O_TRUNC, S_IWUSR | S_IRUSR);
|
: cfgpath, O_CREAT | O_WRONLY | O_TRUNC, S_IWUSR | S_IRUSR);
|
||||||
|
if (fd >= 0) {
|
||||||
if (fd != -1 && shell_escape(g_buf, sizeof(g_buf), curpath)) {
|
memcpy(g_buf, "cd ", 3); // NOLINT
|
||||||
if (write(fd, "cd ", 3) == 3) {
|
ssize_t l = shell_escape(g_buf + 3, sizeof(g_buf) - 3, curpath);
|
||||||
if (write(fd, g_buf, strlen(g_buf)) != (ssize_t)strlen(g_buf)) {
|
ok = l >= 0 && write(fd, g_buf, l + 3) == l + 3;
|
||||||
DPRINTF_S("write failed!");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
close(fd);
|
close(fd);
|
||||||
}
|
}
|
||||||
|
if (!ok)
|
||||||
|
errexit();
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|
Loading…
Reference in a new issue