aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDenys Vlasenko <vda.linux@googlemail.com>2024-07-12 22:28:25 +0200
committerDenys Vlasenko <vda.linux@googlemail.com>2024-07-12 22:28:25 +0200
commit08fb86726b508eb99502a6681da94395c4e4580c (patch)
tree1039117d641d0b96668c9e6965d1d143eb69b6eb
parent0829fce079dae45737330114c27886cb8af85043 (diff)
downloadbusybox-w32-08fb86726b508eb99502a6681da94395c4e4580c.tar.gz
busybox-w32-08fb86726b508eb99502a6681da94395c4e4580c.tar.bz2
busybox-w32-08fb86726b508eb99502a6681da94395c4e4580c.zip
ash: remove limitation on fd# length
"echo text >&0000000000002" works as you would expect, "echo text >&9999999999" properly fails instead of creating a file named "9999999999". function old new delta expredir 219 232 +13 readtoken1 3045 3053 +8 parsefname 204 201 -3 isdigit_str9 45 - -45 ------------------------------------------------------------------------------ (add/remove: 0/1 grow/shrink: 2/1 up/down: 21/-48) Total: -27 bytes Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
-rw-r--r--shell/ash.c20
1 files changed, 13 insertions, 7 deletions
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);
557#define is_in_name(c) ((c) == '_' || isalnum((unsigned char)(c))) 557#define is_in_name(c) ((c) == '_' || isalnum((unsigned char)(c)))
558 558
559static int 559static int
560isdigit_str9(const char *str) 560isdigit_str(const char *str)
561{ 561{
562 int maxlen = 9 + 1; /* max 9 digits: 999999999 */ 562 while (isdigit(*str))
563 while (--maxlen && isdigit(*str))
564 str++; 563 str++;
565 return (*str == '\0'); 564 return (*str == '\0');
566} 565}
@@ -9661,7 +9660,7 @@ expredir(union node *n)
9661 if (fn.list == NULL) 9660 if (fn.list == NULL)
9662 ash_msg_and_raise_error("redir error"); 9661 ash_msg_and_raise_error("redir error");
9663#if BASH_REDIR_OUTPUT 9662#if BASH_REDIR_OUTPUT
9664 if (!isdigit_str9(fn.list->text)) { 9663 if (!isdigit_str(fn.list->text)) {
9665 /* >&file, not >&fd */ 9664 /* >&file, not >&fd */
9666 if (redir->nfile.fd != 1) /* 123>&file - BAD */ 9665 if (redir->nfile.fd != 1) /* 123>&file - BAD */
9667 ash_msg_and_raise_error("redir error"); 9666 ash_msg_and_raise_error("redir error");
@@ -12011,12 +12010,19 @@ fixredir(union node *n, const char *text, int err)
12011 if (!err) 12010 if (!err)
12012 n->ndup.vname = NULL; 12011 n->ndup.vname = NULL;
12013 12012
12013 if (LONE_DASH(text)) {
12014 n->ndup.dupfd = -1;
12015 return;
12016 }
12017
12014 fd = bb_strtou(text, NULL, 10); 12018 fd = bb_strtou(text, NULL, 10);
12015 if (!errno && fd >= 0) 12019 if (!errno && fd >= 0)
12016 n->ndup.dupfd = fd; 12020 n->ndup.dupfd = fd;
12017 else if (LONE_DASH(text))
12018 n->ndup.dupfd = -1;
12019 else { 12021 else {
12022 /* This also fails on very large numbers
12023 * which overflow "int" - bb_strtou() does not
12024 * silently truncate results to word width.
12025 */
12020 if (err) 12026 if (err)
12021 raise_error_syntax("bad fd number"); 12027 raise_error_syntax("bad fd number");
12022 n->ndup.vname = makename(); 12028 n->ndup.vname = makename();
@@ -12702,7 +12708,7 @@ readtoken1(int c, int syntax, char *eofmark, int striptabs)
12702 if ((c == '>' || c == '<' IF_BASH_REDIR_OUTPUT( || c == 0x100 + '>')) 12708 if ((c == '>' || c == '<' IF_BASH_REDIR_OUTPUT( || c == 0x100 + '>'))
12703 && quotef == 0 12709 && quotef == 0
12704 ) { 12710 ) {
12705 if (isdigit_str9(out)) { 12711 if (isdigit_str(out)) {
12706 PARSEREDIR(); /* passed as params: out, c */ 12712 PARSEREDIR(); /* passed as params: out, c */
12707 lasttoken = TREDIR; 12713 lasttoken = TREDIR;
12708 return lasttoken; 12714 return lasttoken;