aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRon Yorston <rmy@pobox.com>2020-02-25 10:06:11 +0000
committerRon Yorston <rmy@pobox.com>2020-02-25 10:06:11 +0000
commite2a5b8e5e936891142cb630d145e67882711fd13 (patch)
tree94f685ed6e14582e7d0dfd140699082315f959f4
parent35da75bde8885d1922701a36baa61bc8b01f14d4 (diff)
parentc2058ec98cf3f6722be4436cae07a386e3c7b48d (diff)
downloadbusybox-w32-e2a5b8e5e936891142cb630d145e67882711fd13.tar.gz
busybox-w32-e2a5b8e5e936891142cb630d145e67882711fd13.tar.bz2
busybox-w32-e2a5b8e5e936891142cb630d145e67882711fd13.zip
Merge branch 'busybox' into merge
-rw-r--r--shell/ash.c110
-rw-r--r--shell/ash_test/ash-heredoc/heredoc_side_effects.right1
-rwxr-xr-xshell/ash_test/ash-heredoc/heredoc_side_effects.tests5
-rw-r--r--shell/ash_test/ash-quoting/negative_arith.right2
-rwxr-xr-xshell/ash_test/ash-quoting/negative_arith.tests8
-rw-r--r--shell/hush.c24
-rw-r--r--shell/hush_test/hush-quoting/negative_arith.right2
-rwxr-xr-xshell/hush_test/hush-quoting/negative_arith.tests8
8 files changed, 101 insertions, 59 deletions
diff --git a/shell/ash.c b/shell/ash.c
index 252061dae..690796740 100644
--- a/shell/ash.c
+++ b/shell/ash.c
@@ -1842,15 +1842,16 @@ popstackmark(struct stackmark *mark)
1842 * part of the block that has been used. 1842 * part of the block that has been used.
1843 */ 1843 */
1844static void 1844static void
1845growstackblock(void) 1845growstackblock(size_t min)
1846{ 1846{
1847 size_t newlen; 1847 size_t newlen;
1848 1848
1849 newlen = g_stacknleft * 2; 1849 newlen = g_stacknleft * 2;
1850 if (newlen < g_stacknleft) 1850 if (newlen < g_stacknleft)
1851 ash_msg_and_raise_error(bb_msg_memory_exhausted); 1851 ash_msg_and_raise_error(bb_msg_memory_exhausted);
1852 if (newlen < 128) 1852 min = SHELL_ALIGN(min | 128);
1853 newlen += 128; 1853 if (newlen < min)
1854 newlen += min;
1854 1855
1855 if (g_stacknxt == g_stackp->space && g_stackp != &stackbase) { 1856 if (g_stacknxt == g_stackp->space && g_stackp != &stackbase) {
1856 struct stack_block *sp; 1857 struct stack_block *sp;
@@ -1900,16 +1901,15 @@ static void *
1900growstackstr(void) 1901growstackstr(void)
1901{ 1902{
1902 size_t len = stackblocksize(); 1903 size_t len = stackblocksize();
1903 growstackblock(); 1904 growstackblock(0);
1904 return (char *)stackblock() + len; 1905 return (char *)stackblock() + len;
1905} 1906}
1906 1907
1907static char * 1908static char *
1908growstackto(size_t len) 1909growstackto(size_t len)
1909{ 1910{
1910 while (stackblocksize() < len) 1911 if (stackblocksize() < len)
1911 growstackblock(); 1912 growstackblock(len);
1912
1913 return stackblock(); 1913 return stackblock();
1914} 1914}
1915 1915
@@ -5962,29 +5962,36 @@ stoppedjobs(void)
5962 * the pipe without forking. 5962 * the pipe without forking.
5963 */ 5963 */
5964/* openhere needs this forward reference */ 5964/* openhere needs this forward reference */
5965static void expandhere(union node *arg, int fd); 5965static void expandhere(union node *arg);
5966static int 5966static int
5967openhere(union node *redir) 5967openhere(union node *redir)
5968{ 5968{
5969 char *p;
5969 int pip[2]; 5970 int pip[2];
5970 size_t len = 0; 5971 size_t len = 0;
5971 IF_PLATFORM_MINGW32(struct forkshell fs); 5972 IF_PLATFORM_MINGW32(struct forkshell fs);
5972 5973
5973 if (pipe(pip) < 0) 5974 if (pipe(pip) < 0)
5974 ash_msg_and_raise_perror("can't create pipe"); 5975 ash_msg_and_raise_perror("can't create pipe");
5975 if (redir->type == NHERE) { 5976
5976 len = strlen(redir->nhere.doc->narg.text); 5977 p = redir->nhere.doc->narg.text;
5977 if (len <= PIPE_BUF) { 5978 if (redir->type == NXHERE) {
5978 full_write(pip[1], redir->nhere.doc->narg.text, len); 5979 expandhere(redir->nhere.doc);
5979 goto out; 5980 p = stackblock();
5980 }
5981 } 5981 }
5982
5983 len = strlen(p);
5984 if (len <= PIPE_BUF) {
5985 xwrite(pip[1], p, len);
5986 goto out;
5987 }
5988
5982#if ENABLE_PLATFORM_MINGW32 5989#if ENABLE_PLATFORM_MINGW32
5983 memset(&fs, 0, sizeof(fs)); 5990 memset(&fs, 0, sizeof(fs));
5984 fs.fpid = FS_OPENHERE; 5991 fs.fpid = FS_OPENHERE;
5985 fs.n = redir;
5986 fs.fd[0] = pip[0]; 5992 fs.fd[0] = pip[0];
5987 fs.fd[1] = pip[1]; 5993 fs.fd[1] = pip[1];
5994 fs.path = p;
5988 spawn_forkshell(&fs, NULL, NULL, FORK_NOJOB); 5995 spawn_forkshell(&fs, NULL, NULL, FORK_NOJOB);
5989#else 5996#else
5990 if (forkshell((struct job *)NULL, (union node *)NULL, FORK_NOJOB) == 0) { 5997 if (forkshell((struct job *)NULL, (union node *)NULL, FORK_NOJOB) == 0) {
@@ -5995,10 +6002,7 @@ openhere(union node *redir)
5995 ignoresig(SIGHUP); //signal(SIGHUP, SIG_IGN); 6002 ignoresig(SIGHUP); //signal(SIGHUP, SIG_IGN);
5996 ignoresig(SIGTSTP); //signal(SIGTSTP, SIG_IGN); 6003 ignoresig(SIGTSTP); //signal(SIGTSTP, SIG_IGN);
5997 signal(SIGPIPE, SIG_DFL); 6004 signal(SIGPIPE, SIG_DFL);
5998 if (redir->type == NHERE) 6005 xwrite(pip[1], p, len);
5999 full_write(pip[1], redir->nhere.doc->narg.text, len);
6000 else /* NXHERE */
6001 expandhere(redir->nhere.doc, pip[1]);
6002 _exit(EXIT_SUCCESS); 6006 _exit(EXIT_SUCCESS);
6003 } 6007 }
6004#endif 6008#endif
@@ -6602,26 +6606,6 @@ static struct ifsregion *ifslastp;
6602static struct arglist exparg; 6606static struct arglist exparg;
6603 6607
6604/* 6608/*
6605 * Our own itoa().
6606 * cvtnum() is used even if math support is off (to prepare $? values and such).
6607 */
6608static int
6609cvtnum(arith_t num)
6610{
6611 int len;
6612
6613 /* 32-bit and wider ints require buffer size of bytes*3 (or less) */
6614 len = sizeof(arith_t) * 3;
6615 /* If narrower: worst case, 1-byte ints: need 5 bytes: "-127<NUL>" */
6616 if (sizeof(arith_t) < 4) len += 2;
6617
6618 expdest = makestrspace(len, expdest);
6619 len = fmtstr(expdest, len, ARITH_FMT, num);
6620 STADJUST(len, expdest);
6621 return len;
6622}
6623
6624/*
6625 * Break the argument string into pieces based upon IFS and add the 6609 * Break the argument string into pieces based upon IFS and add the
6626 * strings to the argument list. The regions of the string to be 6610 * strings to the argument list. The regions of the string to be
6627 * searched for IFS characters have been stored by recordregion. 6611 * searched for IFS characters have been stored by recordregion.
@@ -6878,16 +6862,18 @@ preglob(const char *pattern, int flag)
6878/* 6862/*
6879 * Put a string on the stack. 6863 * Put a string on the stack.
6880 */ 6864 */
6881static void 6865static size_t
6882memtodest(const char *p, size_t len, int flags) 6866memtodest(const char *p, size_t len, int flags)
6883{ 6867{
6884 int syntax = flags & EXP_QUOTED ? DQSYNTAX : BASESYNTAX; 6868 int syntax = flags & EXP_QUOTED ? DQSYNTAX : BASESYNTAX;
6885 char *q; 6869 char *q;
6870 char *s;
6886 6871
6887 if (!len) 6872 if (!len)
6888 return; 6873 return 0;
6889 6874
6890 q = makestrspace(len * 2, expdest); 6875 q = makestrspace(len * 2, expdest);
6876 s = q;
6891 6877
6892 do { 6878 do {
6893 unsigned char c = *p++; 6879 unsigned char c = *p++;
@@ -6906,6 +6892,7 @@ memtodest(const char *p, size_t len, int flags)
6906 } while (--len); 6892 } while (--len);
6907 6893
6908 expdest = q; 6894 expdest = q;
6895 return q - s;
6909} 6896}
6910 6897
6911static size_t 6898static size_t
@@ -6917,6 +6904,22 @@ strtodest(const char *p, int flags)
6917} 6904}
6918 6905
6919/* 6906/*
6907 * Our own itoa().
6908 * cvtnum() is used even if math support is off (to prepare $? values and such).
6909 */
6910static int
6911cvtnum(arith_t num, int flags)
6912{
6913 /* 32-bit and wider ints require buffer size of bytes*3 (or less) */
6914 /* If narrower: worst case, 1-byte ints: need 5 bytes: "-127<NUL>" */
6915 int len = (sizeof(arith_t) >= 4) ? sizeof(arith_t) * 3 : sizeof(arith_t) * 3 + 2;
6916 char buf[len];
6917
6918 len = fmtstr(buf, len, ARITH_FMT, num);
6919 return memtodest(buf, len, flags);
6920}
6921
6922/*
6920 * Record the fact that we have to scan this region of the 6923 * Record the fact that we have to scan this region of the
6921 * string for IFS characters. 6924 * string for IFS characters.
6922 */ 6925 */
@@ -7225,7 +7228,7 @@ expari(int flag)
7225 if (flag & QUOTES_ESC) 7228 if (flag & QUOTES_ESC)
7226 rmescapes(p + 1, 0, NULL); 7229 rmescapes(p + 1, 0, NULL);
7227 7230
7228 len = cvtnum(ash_arith(p + 1)); 7231 len = cvtnum(ash_arith(p + 1), flag);
7229 7232
7230 if (!(flag & EXP_QUOTED)) 7233 if (!(flag & EXP_QUOTED))
7231 recordregion(begoff, begoff + len, 0); 7234 recordregion(begoff, begoff + len, 0);
@@ -7870,7 +7873,7 @@ varvalue(char *name, int varflags, int flags, int quoted)
7870 if (num == 0) 7873 if (num == 0)
7871 return -1; 7874 return -1;
7872 numvar: 7875 numvar:
7873 len = cvtnum(num); 7876 len = cvtnum(num, flags);
7874 goto check_1char_name; 7877 goto check_1char_name;
7875 case '-': 7878 case '-':
7876 expdest = makestrspace(NOPTS, expdest); 7879 expdest = makestrspace(NOPTS, expdest);
@@ -8036,7 +8039,7 @@ evalvar(char *p, int flag)
8036 varunset(p, var, 0, 0); 8039 varunset(p, var, 0, 0);
8037 8040
8038 if (subtype == VSLENGTH) { 8041 if (subtype == VSLENGTH) {
8039 cvtnum(varlen > 0 ? varlen : 0); 8042 cvtnum(varlen > 0 ? varlen : 0, flag);
8040 goto record; 8043 goto record;
8041 } 8044 }
8042 8045
@@ -8567,10 +8570,9 @@ expandarg(union node *arg, struct arglist *arglist, int flag)
8567 * Expand shell variables and backquotes inside a here document. 8570 * Expand shell variables and backquotes inside a here document.
8568 */ 8571 */
8569static void 8572static void
8570expandhere(union node *arg, int fd) 8573expandhere(union node *arg)
8571{ 8574{
8572 expandarg(arg, (struct arglist *)NULL, EXP_QUOTED); 8575 expandarg(arg, (struct arglist *)NULL, EXP_QUOTED);
8573 full_write(fd, stackblock(), expdest - (char *)stackblock());
8574} 8576}
8575 8577
8576/* 8578/*
@@ -12331,7 +12333,7 @@ list(int nlflag)
12331 12333
12332 n1 = NULL; 12334 n1 = NULL;
12333 for (;;) { 12335 for (;;) {
12334 switch (peektoken()) { 12336 switch (readtoken()) {
12335 case TNL: 12337 case TNL:
12336 if (!(nlflag & 1)) 12338 if (!(nlflag & 1))
12337 break; 12339 break;
@@ -12342,9 +12344,12 @@ list(int nlflag)
12342 if (!n1 && (nlflag & 1)) 12344 if (!n1 && (nlflag & 1))
12343 n1 = NODE_EOF; 12345 n1 = NODE_EOF;
12344 parseheredoc(); 12346 parseheredoc();
12347 tokpushback++;
12348 lasttoken = TEOF;
12345 return n1; 12349 return n1;
12346 } 12350 }
12347 12351
12352 tokpushback++;
12348 checkkwd = CHKNL | CHKKWD | CHKALIAS; 12353 checkkwd = CHKNL | CHKKWD | CHKALIAS;
12349 if (nlflag == 2 && ((1 << peektoken()) & tokendlist)) 12354 if (nlflag == 2 && ((1 << peektoken()) & tokendlist))
12350 return n1; 12355 return n1;
@@ -13601,9 +13606,9 @@ parsebackq: {
13601 if (readtoken() != TRP) 13606 if (readtoken() != TRP)
13602 raise_error_unexpected_syntax(TRP); 13607 raise_error_unexpected_syntax(TRP);
13603 setinputstring(nullstr); 13608 setinputstring(nullstr);
13604 parseheredoc();
13605 } 13609 }
13606 13610
13611 parseheredoc();
13607 heredoclist = saveheredoclist; 13612 heredoclist = saveheredoclist;
13608 13613
13609 (*nlpp)->n = n; 13614 (*nlpp)->n = n;
@@ -15473,7 +15478,8 @@ int ash_main(int argc UNUSED_PARAM, char **argv)
15473static void 15478static void
15474forkshell_openhere(struct forkshell *fs) 15479forkshell_openhere(struct forkshell *fs)
15475{ 15480{
15476 union node *redir = fs->n; 15481 const char *p = fs->path;
15482 size_t len = strlen(p);
15477 int pip[2]; 15483 int pip[2];
15478 15484
15479 pip[0] = fs->fd[0]; 15485 pip[0] = fs->fd[0];
@@ -15487,11 +15493,7 @@ forkshell_openhere(struct forkshell *fs)
15487 ignoresig(SIGHUP); //signal(SIGHUP, SIG_IGN); 15493 ignoresig(SIGHUP); //signal(SIGHUP, SIG_IGN);
15488 ignoresig(SIGTSTP); //signal(SIGTSTP, SIG_IGN); 15494 ignoresig(SIGTSTP); //signal(SIGTSTP, SIG_IGN);
15489 signal(SIGPIPE, SIG_DFL); 15495 signal(SIGPIPE, SIG_DFL);
15490 if (redir->type == NHERE) { 15496 xwrite(pip[1], p, len);
15491 size_t len = strlen(redir->nhere.doc->narg.text);
15492 full_write(pip[1], redir->nhere.doc->narg.text, len);
15493 } else /* NXHERE */
15494 expandhere(redir->nhere.doc, pip[1]);
15495 _exit(EXIT_SUCCESS); 15497 _exit(EXIT_SUCCESS);
15496} 15498}
15497 15499
diff --git a/shell/ash_test/ash-heredoc/heredoc_side_effects.right b/shell/ash_test/ash-heredoc/heredoc_side_effects.right
new file mode 100644
index 000000000..53b2c03c1
--- /dev/null
+++ b/shell/ash_test/ash-heredoc/heredoc_side_effects.right
@@ -0,0 +1 @@
NO BUG
diff --git a/shell/ash_test/ash-heredoc/heredoc_side_effects.tests b/shell/ash_test/ash-heredoc/heredoc_side_effects.tests
new file mode 100755
index 000000000..3fb622ae4
--- /dev/null
+++ b/shell/ash_test/ash-heredoc/heredoc_side_effects.tests
@@ -0,0 +1,5 @@
1unset a
2cat <<EOF >/dev/null
3${a=NO}
4EOF
5echo $a BUG
diff --git a/shell/ash_test/ash-quoting/negative_arith.right b/shell/ash_test/ash-quoting/negative_arith.right
new file mode 100644
index 000000000..e7e51eee7
--- /dev/null
+++ b/shell/ash_test/ash-quoting/negative_arith.right
@@ -0,0 +1,2 @@
1tempfile0.tmp tempfile9.tmp
2tempfile0.tmp tempfile1.tmp tempfile9.tmp
diff --git a/shell/ash_test/ash-quoting/negative_arith.tests b/shell/ash_test/ash-quoting/negative_arith.tests
new file mode 100755
index 000000000..8e47ca111
--- /dev/null
+++ b/shell/ash_test/ash-quoting/negative_arith.tests
@@ -0,0 +1,8 @@
1>tempfile0.tmp
2>tempfile1.tmp
3>tempfile9.tmp
4# The [...] is interpreted as: "any of the chars 0, -, and 9"
5echo tempfile[0"$((-9))"].tmp
6# The [...] is [0-9], interpreted as: "any digit"
7echo tempfile[0$((-9))].tmp
8rm tempfile?.tmp
diff --git a/shell/hush.c b/shell/hush.c
index 357a354e2..0a92f5da7 100644
--- a/shell/hush.c
+++ b/shell/hush.c
@@ -3007,7 +3007,10 @@ static void x_mode_flush(void)
3007static void o_addqchr(o_string *o, int ch) 3007static void o_addqchr(o_string *o, int ch)
3008{ 3008{
3009 int sz = 1; 3009 int sz = 1;
3010 char *found = strchr("*?[\\" MAYBE_BRACES, ch); 3010 /* '-' is included because of this case:
3011 * >filename0 >filename1 >filename9; v='-'; echo filename[0"$v"9]
3012 */
3013 char *found = strchr("*?[-\\" MAYBE_BRACES, ch);
3011 if (found) 3014 if (found)
3012 sz++; 3015 sz++;
3013 o_grow_by(o, sz); 3016 o_grow_by(o, sz);
@@ -3024,7 +3027,7 @@ static void o_addQchr(o_string *o, int ch)
3024{ 3027{
3025 int sz = 1; 3028 int sz = 1;
3026 if ((o->o_expflags & EXP_FLAG_ESC_GLOB_CHARS) 3029 if ((o->o_expflags & EXP_FLAG_ESC_GLOB_CHARS)
3027 && strchr("*?[\\" MAYBE_BRACES, ch) 3030 && strchr("*?[-\\" MAYBE_BRACES, ch)
3028 ) { 3031 ) {
3029 sz++; 3032 sz++;
3030 o->data[o->length] = '\\'; 3033 o->data[o->length] = '\\';
@@ -3041,7 +3044,7 @@ static void o_addqblock(o_string *o, const char *str, int len)
3041 while (len) { 3044 while (len) {
3042 char ch; 3045 char ch;
3043 int sz; 3046 int sz;
3044 int ordinary_cnt = strcspn(str, "*?[\\" MAYBE_BRACES); 3047 int ordinary_cnt = strcspn(str, "*?[-\\" MAYBE_BRACES);
3045 if (ordinary_cnt > len) /* paranoia */ 3048 if (ordinary_cnt > len) /* paranoia */
3046 ordinary_cnt = len; 3049 ordinary_cnt = len;
3047 o_addblock(o, str, ordinary_cnt); 3050 o_addblock(o, str, ordinary_cnt);
@@ -3052,7 +3055,7 @@ static void o_addqblock(o_string *o, const char *str, int len)
3052 3055
3053 ch = *str++; 3056 ch = *str++;
3054 sz = 1; 3057 sz = 1;
3055 if (ch) { /* it is necessarily one of "*?[\\" MAYBE_BRACES */ 3058 if (ch) { /* it is necessarily one of "*?[-\\" MAYBE_BRACES */
3056 sz++; 3059 sz++;
3057 o->data[o->length] = '\\'; 3060 o->data[o->length] = '\\';
3058 o->length++; 3061 o->length++;
@@ -5049,7 +5052,7 @@ static int parse_dollar(o_string *as_string,
5049 ch = i_getch(input); 5052 ch = i_getch(input);
5050 nommu_addchr(as_string, ch); 5053 nommu_addchr(as_string, ch);
5051 o_addchr(dest, SPECIAL_VAR_SYMBOL); 5054 o_addchr(dest, SPECIAL_VAR_SYMBOL);
5052 o_addchr(dest, /*quote_mask |*/ '+'); 5055 o_addchr(dest, quote_mask | '+');
5053 if (!BB_MMU) 5056 if (!BB_MMU)
5054 pos = dest->length; 5057 pos = dest->length;
5055 if (!add_till_closing_bracket(dest, input, ')' | DOUBLE_CLOSE_CHAR_FLAG)) 5058 if (!add_till_closing_bracket(dest, input, ')' | DOUBLE_CLOSE_CHAR_FLAG))
@@ -6851,6 +6854,17 @@ static NOINLINE int expand_vars_to_list(o_string *output, int n, char *arg)
6851 res = expand_and_evaluate_arith(arg, NULL); 6854 res = expand_and_evaluate_arith(arg, NULL);
6852 debug_printf_subst("ARITH RES '"ARITH_FMT"'\n", res); 6855 debug_printf_subst("ARITH RES '"ARITH_FMT"'\n", res);
6853 sprintf(arith_buf, ARITH_FMT, res); 6856 sprintf(arith_buf, ARITH_FMT, res);
6857 if (res < 0
6858 && first_ch == (char)('+'|0x80)
6859 /* && (output->o_expflags & EXP_FLAG_ESC_GLOB_CHARS) */
6860 ) {
6861 /* Quoted negative ariths, like filename[0"$((-9))"],
6862 * should not be interpreted as glob ranges.
6863 * Convert leading '-' to '\-':
6864 */
6865 o_grow_by(output, 1);
6866 output->data[output->length++] = '\\';
6867 }
6854 o_addstr(output, arith_buf); 6868 o_addstr(output, arith_buf);
6855 break; 6869 break;
6856 } 6870 }
diff --git a/shell/hush_test/hush-quoting/negative_arith.right b/shell/hush_test/hush-quoting/negative_arith.right
new file mode 100644
index 000000000..e7e51eee7
--- /dev/null
+++ b/shell/hush_test/hush-quoting/negative_arith.right
@@ -0,0 +1,2 @@
1tempfile0.tmp tempfile9.tmp
2tempfile0.tmp tempfile1.tmp tempfile9.tmp
diff --git a/shell/hush_test/hush-quoting/negative_arith.tests b/shell/hush_test/hush-quoting/negative_arith.tests
new file mode 100755
index 000000000..8e47ca111
--- /dev/null
+++ b/shell/hush_test/hush-quoting/negative_arith.tests
@@ -0,0 +1,8 @@
1>tempfile0.tmp
2>tempfile1.tmp
3>tempfile9.tmp
4# The [...] is interpreted as: "any of the chars 0, -, and 9"
5echo tempfile[0"$((-9))"].tmp
6# The [...] is [0-9], interpreted as: "any digit"
7echo tempfile[0$((-9))].tmp
8rm tempfile?.tmp