aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRob Landley <rob@landley.net>2020-01-11 19:52:01 -0600
committerRob Landley <rob@landley.net>2020-01-11 19:52:01 -0600
commit0e4baaed4ec6e3f2df72a30a331dc54b669b1473 (patch)
tree165c72945e9ed9d0f2a902acc37c15e21b46a45f
parenta416d00d0e02dc82131223b199113b0382636e9b (diff)
downloadtoybox-0e4baaed4ec6e3f2df72a30a331dc54b669b1473.tar.gz
Fix a duplicate free() and a variable stomp, set s=s to fix "can never be
used uninitalized" warning, move flow control character detection to the right place, change scratch zeroing to the same way main() does it.
-rw-r--r--toys/pending/sh.c29
1 files changed, 14 insertions, 15 deletions
diff --git a/toys/pending/sh.c b/toys/pending/sh.c
index 32e33507..29c030e7 100644
--- a/toys/pending/sh.c
+++ b/toys/pending/sh.c
@@ -271,7 +271,7 @@ static void expand_arg_nobrace(struct sh_arg *arg, char *old, unsigned flags,
// Tilde expansion
if (!(flags&NO_TILDE) && *new == '~') {
struct passwd *pw = 0;
- char *s, *ss;
+ char *s, *ss, *sss;
// first expansion so don't need to free previous new
ss = 0;
@@ -280,8 +280,8 @@ static void expand_arg_nobrace(struct sh_arg *arg, char *old, unsigned flags,
if (!(ss = getvar("HOME")) || !*ss) pw = bufgetpwuid(getuid());
} else {
// TODO bufgetpwnam
- pw = getpwnam(new = xstrndup(new+1, (s-new)-1));
- free(new);
+ pw = getpwnam(sss = xstrndup(new+1, (s-new)-1));
+ free(sss);
}
if (pw && pw->pw_dir) ss = pw->pw_dir;
if (!ss || !*ss) ss = "/";
@@ -477,7 +477,6 @@ static void expand_arg(struct sh_arg *arg, char *old, unsigned flags,
// Expand exactly one arg, returning NULL if it split.
-// If return != new you need to free it.
static char *expand_one_arg(char *new, unsigned flags, struct arg_list **del)
{
struct sh_arg arg;
@@ -485,11 +484,9 @@ static char *expand_one_arg(char *new, unsigned flags, struct arg_list **del)
int i;
memset(&arg, 0, sizeof(arg));
- expand_arg(&arg, new, flags, 0);
- if (arg.c == 1) {
- s = *arg.v;
- if (del && s != new) dlist_add((void *)del, s);
- } else for (i = 0; i < arg.c; i++) free(arg.v[i]);
+ expand_arg(&arg, new, flags, del);
+ if (arg.c == 1) s = *arg.v;
+ else if (!del) for (i = 0; i < arg.c; i++) free(arg.v[i]);
free(arg.v);
return s;
@@ -624,7 +621,7 @@ void run_subshell(struct sh_pipeline *sp)
static struct sh_process *expand_redir(struct sh_arg *arg, int envlen, int *urd)
{
struct sh_process *pp;
- char *s, *ss, *sss, *cv = 0;
+ char *s = s, *ss, *sss, *cv = 0;
int j, to, from, here = 0;
TT.hfd = 10;
@@ -896,7 +893,6 @@ if (BUGBUG) { int i; dprintf(255, "envlen=%d arg->c=%d run=", envlen, arg->c); f
}
environ = env;
}
-
if (-1 == (pp->pid = xpopen_both(pp->arg.v, 0)))
perror_msg("%s: vfork", *pp->arg.v);
@@ -933,9 +929,6 @@ static char *parse_word(char *start)
// Redirections. 123<<file- parses as 2 args: "123<<" "file-".
s = end + redir_prefix(end);
if ((i = anystart(s, (void *)redirectors))) s += i;
- // Flow control characters that end pipeline segments
- else s = end + anystart(end, (char *[]){";;&", ";;", ";&", ";", "||",
- "|&", "|", "&&", "&", "(", ")", 0});
if (s != end) return (end == start) ? s : end;
// (( is a special quote at the start of a word
@@ -979,6 +972,11 @@ static char *parse_word(char *start)
if (isspace(*end)) break;
if (*end == ')') return end+(start==end);
+
+ // Flow control characters that end pipeline segments
+ s = end + anystart(end, (char *[]){";;&", ";;", ";&", ";", "||",
+ "|&", "|", "&&", "&", "(", ")", 0});
+ if (s != end) return (end == start) ? s : end;
}
// Things the same unquoted or in most non-single-quote contexts
@@ -1685,11 +1683,12 @@ dprintf(2, "TODO skipped running for((;;)), need math parser\n");
// Parse and run a self-contained command line with no prompt/continuation
static int sh_run(char *new)
{
- struct sh_function scratch = { 0 };
+ struct sh_function scratch;
int rc;
// TODO: parse with len? (End early?)
+ memset(&scratch, 0, sizeof(struct sh_function));
if (!parse_line(new, &scratch)) run_function(&scratch);
free_function(&scratch);
rc = toys.exitval;