diff --git a/shell/ash.c b/shell/ash.c index 39455c7c5..9da3e956a 100644 --- a/shell/ash.c +++ b/shell/ash.c @@ -557,10 +557,9 @@ static void trace_vprintf(const char *fmt, va_list va); #define is_in_name(c) ((c) == '_' || isalnum((unsigned char)(c))) static int -isdigit_str9(const char *str) +isdigit_str(const char *str) { - int maxlen = 9 + 1; /* max 9 digits: 999999999 */ - while (--maxlen && isdigit(*str)) + while (isdigit(*str)) str++; return (*str == '\0'); } @@ -9661,7 +9660,7 @@ expredir(union node *n) if (fn.list == NULL) ash_msg_and_raise_error("redir error"); #if BASH_REDIR_OUTPUT - if (!isdigit_str9(fn.list->text)) { + if (!isdigit_str(fn.list->text)) { /* >&file, not >&fd */ if (redir->nfile.fd != 1) /* 123>&file - BAD */ ash_msg_and_raise_error("redir error"); @@ -12011,12 +12010,19 @@ fixredir(union node *n, const char *text, int err) if (!err) n->ndup.vname = NULL; + if (LONE_DASH(text)) { + n->ndup.dupfd = -1; + return; + } + fd = bb_strtou(text, NULL, 10); if (!errno && fd >= 0) n->ndup.dupfd = fd; - else if (LONE_DASH(text)) - n->ndup.dupfd = -1; else { + /* This also fails on very large numbers + * which overflow "int" - bb_strtou() does not + * silently truncate results to word width. + */ if (err) raise_error_syntax("bad fd number"); n->ndup.vname = makename(); @@ -12702,7 +12708,7 @@ readtoken1(int c, int syntax, char *eofmark, int striptabs) if ((c == '>' || c == '<' IF_BASH_REDIR_OUTPUT( || c == 0x100 + '>')) && quotef == 0 ) { - if (isdigit_str9(out)) { + if (isdigit_str(out)) { PARSEREDIR(); /* passed as params: out, c */ lasttoken = TREDIR; return lasttoken;