aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRon Yorston <rmy@pobox.com>2021-08-17 08:26:36 +0100
committerRon Yorston <rmy@pobox.com>2021-08-17 08:26:36 +0100
commitf13defb1c8f892ecf3e8dd5dbe486cc2b53e6f03 (patch)
tree15c9c174532e433e5632637c541d09e591c01d60
parent41f31584037be6b9d74a89245dff9ad8f0db146f (diff)
parent540aa116615713ad53e5ac98850993162e27c32d (diff)
downloadbusybox-w32-f13defb1c8f892ecf3e8dd5dbe486cc2b53e6f03.tar.gz
busybox-w32-f13defb1c8f892ecf3e8dd5dbe486cc2b53e6f03.tar.bz2
busybox-w32-f13defb1c8f892ecf3e8dd5dbe486cc2b53e6f03.zip
Merge branch 'busybox' into merge
-rw-r--r--archival/tar.c23
-rw-r--r--configs/android_502_defconfig2
-rw-r--r--configs/android_ndk_defconfig1
-rw-r--r--coreutils/cp.c4
-rw-r--r--coreutils/dd.c4
-rw-r--r--coreutils/touch.c2
-rw-r--r--editors/vi.c1
-rw-r--r--networking/traceroute.c7
-rwxr-xr-xscripts/randomtest2
-rwxr-xr-xscripts/randomtest.loop11
-rw-r--r--shell/ash.c17
-rw-r--r--shell/ash_test/ash-psubst/falsetick.right24
-rwxr-xr-xshell/ash_test/ash-psubst/falsetick.tests19
-rw-r--r--shell/ash_test/ash-psubst/falsetick2.right1
-rwxr-xr-xshell/ash_test/ash-psubst/falsetick2.tests3
-rw-r--r--shell/ash_test/ash-vars/var6.right2
-rwxr-xr-xshell/ash_test/ash-vars/var6.tests5
-rw-r--r--shell/ash_test/ash-vars/var_nested1.right3
-rwxr-xr-xshell/ash_test/ash-vars/var_nested1.tests16
-rw-r--r--shell/ash_test/ash-vars/var_nested2.right1
-rwxr-xr-xshell/ash_test/ash-vars/var_nested2.tests2
-rw-r--r--shell/hush.c117
-rw-r--r--shell/hush_test/hush-psubst/falsetick.right3
-rwxr-xr-xshell/hush_test/hush-psubst/falsetick.tests3
-rw-r--r--shell/hush_test/hush-psubst/falsetick3.right3
-rwxr-xr-xshell/hush_test/hush-psubst/falsetick3.tests3
-rw-r--r--shell/hush_test/hush-quoting/dollar_squote_bash1.right10
-rwxr-xr-xshell/hush_test/hush-quoting/dollar_squote_bash1.tests8
-rw-r--r--shell/hush_test/hush-quoting/dollar_squote_bash2.right6
-rwxr-xr-xshell/hush_test/hush-quoting/dollar_squote_bash2.tests10
-rwxr-xr-xshell/hush_test/hush-vars/var6.tests7
-rw-r--r--shell/hush_test/hush-vars/var_bash7.right1
-rwxr-xr-xshell/hush_test/hush-vars/var_bash7.tests1
-rw-r--r--shell/match.c3
-rwxr-xr-xtestsuite/awk.tests2
-rwxr-xr-xtestsuite/cut.tests2
-rw-r--r--testsuite/dd/dd-count-bytes2
-rwxr-xr-xtestsuite/tar.tests17
-rw-r--r--util-linux/fdisk_sun.c8
-rw-r--r--util-linux/taskset.c4
40 files changed, 301 insertions, 59 deletions
diff --git a/archival/tar.c b/archival/tar.c
index 8cd371173..67c90e6fd 100644
--- a/archival/tar.c
+++ b/archival/tar.c
@@ -509,6 +509,9 @@ static int FAST_FUNC writeFileToTarball(struct recursive_state *state,
509 if (header_name[0] == '\0') 509 if (header_name[0] == '\0')
510 return TRUE; 510 return TRUE;
511 511
512 if (exclude_file(tbInfo->excludeList, header_name))
513 return SKIP; /* "do not recurse on this directory", no error message printed */
514
512 /* It is against the rules to archive a socket */ 515 /* It is against the rules to archive a socket */
513 if (S_ISSOCK(statbuf->st_mode)) { 516 if (S_ISSOCK(statbuf->st_mode)) {
514 bb_error_msg("%s: socket ignored", fileName); 517 bb_error_msg("%s: socket ignored", fileName);
@@ -548,9 +551,6 @@ static int FAST_FUNC writeFileToTarball(struct recursive_state *state,
548 } 551 }
549#endif 552#endif
550 553
551 if (exclude_file(tbInfo->excludeList, header_name))
552 return SKIP;
553
554# if !ENABLE_FEATURE_TAR_GNU_EXTENSIONS 554# if !ENABLE_FEATURE_TAR_GNU_EXTENSIONS
555 if (strlen(header_name) >= NAME_SIZE) { 555 if (strlen(header_name) >= NAME_SIZE) {
556 bb_simple_error_msg("names longer than "NAME_SIZE_STR" chars not supported"); 556 bb_simple_error_msg("names longer than "NAME_SIZE_STR" chars not supported");
@@ -563,13 +563,13 @@ static int FAST_FUNC writeFileToTarball(struct recursive_state *state,
563 /* open the file we want to archive, and make sure all is well */ 563 /* open the file we want to archive, and make sure all is well */
564 inputFileFd = open_or_warn(fileName, O_RDONLY); 564 inputFileFd = open_or_warn(fileName, O_RDONLY);
565 if (inputFileFd < 0) { 565 if (inputFileFd < 0) {
566 return FALSE; 566 return FALSE; /* make recursive_action() return FALSE */
567 } 567 }
568 } 568 }
569 569
570 /* Add an entry to the tarball */ 570 /* Add an entry to the tarball */
571 if (writeTarHeader(tbInfo, header_name, fileName, statbuf) == FALSE) { 571 if (writeTarHeader(tbInfo, header_name, fileName, statbuf) == FALSE) {
572 return FALSE; 572 return FALSE; /* make recursive_action() return FALSE */
573 } 573 }
574 574
575 /* If it was a regular file, write out the body */ 575 /* If it was a regular file, write out the body */
@@ -1153,14 +1153,15 @@ int tar_main(int argc UNUSED_PARAM, char **argv)
1153 tar_handle->ah_flags &= ~ARCHIVE_RESTORE_DATE; 1153 tar_handle->ah_flags &= ~ARCHIVE_RESTORE_DATE;
1154 1154
1155#if ENABLE_FEATURE_TAR_FROM 1155#if ENABLE_FEATURE_TAR_FROM
1156 /* Convert each -X EXCLFILE to list of to-be-rejected glob patterns */
1156 tar_handle->reject = append_file_list_to_list(tar_handle->reject); 1157 tar_handle->reject = append_file_list_to_list(tar_handle->reject);
1157# if ENABLE_FEATURE_TAR_LONG_OPTIONS 1158# if ENABLE_FEATURE_TAR_LONG_OPTIONS
1158 /* Append excludes to reject */ 1159 /* Append --exclude=GLOBPATTERNs to reject */
1159 while (excludes) { 1160 if (excludes) {
1160 llist_t *next = excludes->link; 1161 llist_t **p2next = &tar_handle->reject;
1161 excludes->link = tar_handle->reject; 1162 while (*p2next)
1162 tar_handle->reject = excludes; 1163 p2next = &((*p2next)->link);
1163 excludes = next; 1164 *p2next = excludes;
1164 } 1165 }
1165# endif 1166# endif
1166 tar_handle->accept = append_file_list_to_list(tar_handle->accept); 1167 tar_handle->accept = append_file_list_to_list(tar_handle->accept);
diff --git a/configs/android_502_defconfig b/configs/android_502_defconfig
index 503157c12..104e70f23 100644
--- a/configs/android_502_defconfig
+++ b/configs/android_502_defconfig
@@ -33,7 +33,6 @@
33## Assorted header problems: 33## Assorted header problems:
34## # CONFIG_HOSTID is not set 34## # CONFIG_HOSTID is not set
35## # CONFIG_FEATURE_SYNC_FANCY is not set - syncfs() 35## # CONFIG_FEATURE_SYNC_FANCY is not set - syncfs()
36## # CONFIG_FEATURE_TOUCH_NODEREF is not set - lutimes()
37## # CONFIG_LOGNAME is not set - getlogin_r() 36## # CONFIG_LOGNAME is not set - getlogin_r()
38## # CONFIG_LOADFONT is not set 37## # CONFIG_LOADFONT is not set
39## # CONFIG_SETFONT is not set 38## # CONFIG_SETFONT is not set
@@ -269,7 +268,6 @@ CONFIG_SYNC=y
269CONFIG_TEST=y 268CONFIG_TEST=y
270CONFIG_FEATURE_TEST_64=y 269CONFIG_FEATURE_TEST_64=y
271CONFIG_TOUCH=y 270CONFIG_TOUCH=y
272# CONFIG_FEATURE_TOUCH_NODEREF is not set
273CONFIG_FEATURE_TOUCH_SUSV3=y 271CONFIG_FEATURE_TOUCH_SUSV3=y
274CONFIG_TR=y 272CONFIG_TR=y
275CONFIG_FEATURE_TR_CLASSES=y 273CONFIG_FEATURE_TR_CLASSES=y
diff --git a/configs/android_ndk_defconfig b/configs/android_ndk_defconfig
index 03d497d2e..425593454 100644
--- a/configs/android_ndk_defconfig
+++ b/configs/android_ndk_defconfig
@@ -193,7 +193,6 @@ CONFIG_SYNC=y
193CONFIG_TEST=y 193CONFIG_TEST=y
194CONFIG_FEATURE_TEST_64=y 194CONFIG_FEATURE_TEST_64=y
195CONFIG_TOUCH=y 195CONFIG_TOUCH=y
196# CONFIG_FEATURE_TOUCH_NODEREF is not set
197CONFIG_FEATURE_TOUCH_SUSV3=y 196CONFIG_FEATURE_TOUCH_SUSV3=y
198CONFIG_TR=y 197CONFIG_TR=y
199CONFIG_FEATURE_TR_CLASSES=y 198CONFIG_FEATURE_TR_CLASSES=y
diff --git a/coreutils/cp.c b/coreutils/cp.c
index 50ca1ccea..ee40af50b 100644
--- a/coreutils/cp.c
+++ b/coreutils/cp.c
@@ -121,14 +121,12 @@ int cp_main(int argc, char **argv)
121 int d_flags; 121 int d_flags;
122 int flags; 122 int flags;
123 int status; 123 int status;
124 enum {
125#if ENABLE_FEATURE_CP_LONG_OPTIONS 124#if ENABLE_FEATURE_CP_LONG_OPTIONS
125 enum {
126 /*OPT_rmdest = FILEUTILS_RMDEST = 1 << FILEUTILS_CP_OPTBITS */ 126 /*OPT_rmdest = FILEUTILS_RMDEST = 1 << FILEUTILS_CP_OPTBITS */
127 OPT_parents = 1 << (FILEUTILS_CP_OPTBITS+1), 127 OPT_parents = 1 << (FILEUTILS_CP_OPTBITS+1),
128 OPT_reflink = 1 << (FILEUTILS_CP_OPTBITS+2), 128 OPT_reflink = 1 << (FILEUTILS_CP_OPTBITS+2),
129#endif
130 }; 129 };
131#if ENABLE_FEATURE_CP_LONG_OPTIONS
132# if ENABLE_FEATURE_CP_REFLINK 130# if ENABLE_FEATURE_CP_REFLINK
133 char *reflink = NULL; 131 char *reflink = NULL;
134# endif 132# endif
diff --git a/coreutils/dd.c b/coreutils/dd.c
index b476ed24f..a3c9ababf 100644
--- a/coreutils/dd.c
+++ b/coreutils/dd.c
@@ -56,8 +56,8 @@
56//kbuild:lib-$(CONFIG_DD) += dd.o 56//kbuild:lib-$(CONFIG_DD) += dd.o
57 57
58//usage:#define dd_trivial_usage 58//usage:#define dd_trivial_usage
59//usage: "[if=FILE] [of=FILE] [" IF_FEATURE_DD_IBS_OBS("ibs=N obs=N/") "bs=N] [count=N] [skip=N] [seek=N]\n" 59//usage: "[if=FILE] [of=FILE] [" IF_FEATURE_DD_IBS_OBS("ibs=N obs=N/") "bs=N] [count=N] [skip=N] [seek=N]"
60//usage: IF_FEATURE_DD_IBS_OBS( 60//usage: IF_FEATURE_DD_IBS_OBS("\n"
61//usage: " [conv=notrunc|noerror|sync|fsync]\n" 61//usage: " [conv=notrunc|noerror|sync|fsync]\n"
62//usage: " [iflag=skip_bytes|count_bytes|fullblock|direct] [oflag=seek_bytes|append|direct]" 62//usage: " [iflag=skip_bytes|count_bytes|fullblock|direct] [oflag=seek_bytes|append|direct]"
63//usage: ) 63//usage: )
diff --git a/coreutils/touch.c b/coreutils/touch.c
index ec12eb7cf..78100ba1d 100644
--- a/coreutils/touch.c
+++ b/coreutils/touch.c
@@ -127,6 +127,7 @@ int touch_main(int argc UNUSED_PARAM, char **argv)
127#endif 127#endif
128 ); 128 );
129 129
130#if ENABLE_FEATURE_TOUCH_SUSV3
130 timebuf[0].tv_nsec = timebuf[1].tv_nsec = UTIME_NOW; 131 timebuf[0].tv_nsec = timebuf[1].tv_nsec = UTIME_NOW;
131 if (opts & OPT_r) { 132 if (opts & OPT_r) {
132 struct stat stbuf; 133 struct stat stbuf;
@@ -160,6 +161,7 @@ int touch_main(int argc UNUSED_PARAM, char **argv)
160 timebuf[1].tv_nsec = UTIME_OMIT; 161 timebuf[1].tv_nsec = UTIME_OMIT;
161 if ((opts & (OPT_a|OPT_m)) == OPT_m) 162 if ((opts & (OPT_a|OPT_m)) == OPT_m)
162 timebuf[0].tv_nsec = UTIME_OMIT; 163 timebuf[0].tv_nsec = UTIME_OMIT;
164#endif
163 165
164 argv += optind; 166 argv += optind;
165 do { 167 do {
diff --git a/editors/vi.c b/editors/vi.c
index a079be3fe..c5dff3fee 100644
--- a/editors/vi.c
+++ b/editors/vi.c
@@ -320,6 +320,7 @@ struct globals {
320#define autoindent (0) 320#define autoindent (0)
321#define expandtab (0) 321#define expandtab (0)
322#define err_method (0) 322#define err_method (0)
323#define ignorecase (0)
323#endif 324#endif
324 325
325#if ENABLE_FEATURE_VI_READONLY 326#if ENABLE_FEATURE_VI_READONLY
diff --git a/networking/traceroute.c b/networking/traceroute.c
index 057f8591a..4bbe1ab8e 100644
--- a/networking/traceroute.c
+++ b/networking/traceroute.c
@@ -713,11 +713,16 @@ packet4_ok(int read_len, int seq)
713 up = (struct udphdr *)((char *)hip + hlen); 713 up = (struct udphdr *)((char *)hip + hlen);
714 if (hlen + 12 <= read_len 714 if (hlen + 12 <= read_len
715 && hip->ip_p == IPPROTO_UDP 715 && hip->ip_p == IPPROTO_UDP
716// Off: since we do not form the entire IP packet, 716#if !defined(__FreeBSD__)
717// Disabled source check: since we do not form the entire IP packet,
717// but defer it to kernel, we can't set source port, 718// but defer it to kernel, we can't set source port,
718// and thus can't check it here in the reply 719// and thus can't check it here in the reply
720 /* && up->source == ident */
721 && up->dest == htons(port + seq)
722#else
719 /* && up->uh_sport == ident */ 723 /* && up->uh_sport == ident */
720 && up->uh_dport == htons(port + seq) 724 && up->uh_dport == htons(port + seq)
725#endif
721 ) { 726 ) {
722 return (type == ICMP_TIMXCEED ? -1 : code + 1); 727 return (type == ICMP_TIMXCEED ? -1 : code + 1);
723 } 728 }
diff --git a/scripts/randomtest b/scripts/randomtest
index 76550d267..f6e0c9d8c 100755
--- a/scripts/randomtest
+++ b/scripts/randomtest
@@ -83,7 +83,6 @@ if test x"$LIBC" = x"uclibc"; then
83 \ 83 \
84 | grep -v CONFIG_FEATURE_2_4_MODULES \ 84 | grep -v CONFIG_FEATURE_2_4_MODULES \
85 | grep -v CONFIG_FEATURE_SYNC_FANCY \ 85 | grep -v CONFIG_FEATURE_SYNC_FANCY \
86 | grep -v CONFIG_FEATURE_TOUCH_NODEREF \
87 | grep -v CONFIG_NANDWRITE \ 86 | grep -v CONFIG_NANDWRITE \
88 | grep -v CONFIG_NANDDUMP \ 87 | grep -v CONFIG_NANDDUMP \
89 | grep -v CONFIG_BLKDISCARD \ 88 | grep -v CONFIG_BLKDISCARD \
@@ -100,7 +99,6 @@ if test x"$LIBC" = x"uclibc"; then
100 echo '# CONFIG_PIE is not set' >>.config 99 echo '# CONFIG_PIE is not set' >>.config
101 echo '# CONFIG_FEATURE_2_4_MODULES is not set' >>.config 100 echo '# CONFIG_FEATURE_2_4_MODULES is not set' >>.config
102 echo '# CONFIG_FEATURE_SYNC_FANCY is not set' >>.config 101 echo '# CONFIG_FEATURE_SYNC_FANCY is not set' >>.config
103 echo '# CONFIG_FEATURE_TOUCH_NODEREF is not set' >>.config
104 # My uclibc installation does not support some needed APIs... 102 # My uclibc installation does not support some needed APIs...
105 echo '# CONFIG_NANDWRITE is not set' >>.config 103 echo '# CONFIG_NANDWRITE is not set' >>.config
106 echo '# CONFIG_NANDDUMP is not set' >>.config 104 echo '# CONFIG_NANDDUMP is not set' >>.config
diff --git a/scripts/randomtest.loop b/scripts/randomtest.loop
index edfbc5c58..c6d2cdcda 100755
--- a/scripts/randomtest.loop
+++ b/scripts/randomtest.loop
@@ -6,13 +6,18 @@ run_testsuite=true
6run_single_test=false 6run_single_test=false
7run_single_test=true 7run_single_test=true
8 8
9test -d "$1" || { echo "'$1' is not a directory"; exit 1; }
10test -x "$1/scripts/randomtest" || { echo "No scripts/randomtest in '$1'"; exit 1; }
11
12export LIBC="uclibc" 9export LIBC="uclibc"
13export CROSS_COMPILER_PREFIX="i686-" 10export CROSS_COMPILER_PREFIX="i686-"
14export MAKEOPTS="-j9" 11export MAKEOPTS="-j9"
15 12
13test -d "$1" || { echo "'$1' is not a directory"; exit 1; }
14test -x "$1/scripts/randomtest" || { echo "No scripts/randomtest in '$1'"; exit 1; }
15
16test "$SKIP_MOUNT_MAND_TESTS" = "1" || {
17 echo "SKIP_MOUNT_MAND_TESTS not set, some mount tests will fail"
18 echo "if current kernel has CONFIG_MANDATORY_FILE_LOCKING off."
19}
20
16cnt=0 21cnt=0
17fail=0 22fail=0
18while sleep 1; do 23while sleep 1; do
diff --git a/shell/ash.c b/shell/ash.c
index 28f74e8a8..c9eaaf52a 100644
--- a/shell/ash.c
+++ b/shell/ash.c
@@ -7855,7 +7855,7 @@ subevalvar(char *start, char *str, int strloc,
7855 while (idx <= end) { 7855 while (idx <= end) {
7856 try_to_match: 7856 try_to_match:
7857 if (no_meta_len == 0) { 7857 if (no_meta_len == 0) {
7858 /* pattern has meta chars, have to glob; or ENABLE_ASH_OPTIMIZE_FOR_SIZE */ 7858 /* pattern has meta chars, have to glob; or ENABLE_ASH_OPTIMIZE_FOR_SIZE */
7859 loc = scanright(idx, rmesc, rmescend, str, quotes, /*match_at_start:*/ 1); 7859 loc = scanright(idx, rmesc, rmescend, str, quotes, /*match_at_start:*/ 1);
7860 } else { 7860 } else {
7861 /* Testcase for very slow replace (performs about 22k replaces): 7861 /* Testcase for very slow replace (performs about 22k replaces):
@@ -7863,16 +7863,19 @@ subevalvar(char *start, char *str, int strloc,
7863 * x=$x$x;x=$x$x;x=$x$x;x=$x$x;x=$x$x;x=$x$x;x=$x$x;x=$x$x;x=$x$x;x=$x$x;echo ${#x} 7863 * x=$x$x;x=$x$x;x=$x$x;x=$x$x;x=$x$x;x=$x$x;x=$x$x;x=$x$x;x=$x$x;x=$x$x;echo ${#x}
7864 * echo "${x//:/|}" 7864 * echo "${x//:/|}"
7865 */ 7865 */
7866 size_t n;
7867 if (strncmp(rmesc, str, no_meta_len) != 0) 7866 if (strncmp(rmesc, str, no_meta_len) != 0)
7868 goto no_match; 7867 goto no_match;
7869 n = no_meta_len;
7870 loc = idx; 7868 loc = idx;
7871 do { 7869 if (!quotes) {
7872 if (quotes && (unsigned char)*loc == CTLESC) 7870 loc += no_meta_len;
7871 } else {
7872 size_t n = no_meta_len;
7873 do {
7874 if ((unsigned char)*loc == CTLESC)
7875 loc++;
7873 loc++; 7876 loc++;
7874 loc++; 7877 } while (--n != 0);
7875 } while (--n != 0); 7878 }
7876 } 7879 }
7877 //bb_error_msg("scanright('%s'):'%s'", str, loc); 7880 //bb_error_msg("scanright('%s'):'%s'", str, loc);
7878 if (!loc) { 7881 if (!loc) {
diff --git a/shell/ash_test/ash-psubst/falsetick.right b/shell/ash_test/ash-psubst/falsetick.right
new file mode 100644
index 000000000..0335254a8
--- /dev/null
+++ b/shell/ash_test/ash-psubst/falsetick.right
@@ -0,0 +1,24 @@
10
20
30
40
52
62
72
82
9./falsetick.tests: line 12: can't create /does/not/exist: nonexistent directory
101
11./falsetick.tests: line 13: can't create /does/not/exist: nonexistent directory
121
13./falsetick.tests: line 14: can't create /does/not/exist: nonexistent directory
141
15./falsetick.tests: line 15: can't create /does/not/exist: nonexistent directory
161
17./falsetick.tests: line 16: can't create /does/not/exist: nonexistent directory
181
19./falsetick.tests: line 17: can't create /does/not/exist: nonexistent directory
201
21./falsetick.tests: line 18: can't create /does/not/exist: nonexistent directory
221
23./falsetick.tests: line 19: can't create /does/not/exist: nonexistent directory
241
diff --git a/shell/ash_test/ash-psubst/falsetick.tests b/shell/ash_test/ash-psubst/falsetick.tests
new file mode 100755
index 000000000..d2b93695e
--- /dev/null
+++ b/shell/ash_test/ash-psubst/falsetick.tests
@@ -0,0 +1,19 @@
1# Exitcode 0 (`` has no exitcode, but assignment has):
2true; a=``; echo $?
3false; a=``; echo $?
4true; a=$(); echo $?
5false; a=$(); echo $?
6# Exitcode 2 (`cmd` expansion sets exitcode after assignment set it to 0):
7true; a=`exit 2`; echo $?
8false; a=`exit 2`; echo $?
9true; a=$(exit 2); echo $?
10false; a=$(exit 2); echo $?
11# Exitcode 1 (redirect sets exitcode to 1 on error after them):
12true; a=`` >/does/not/exist; echo $?
13false; a=`` >/does/not/exist; echo $?
14true; a=$() >/does/not/exist; echo $?
15false; a=$() >/does/not/exist; echo $?
16true; a=`exit 2` >/does/not/exist; echo $?
17false; a=`exit 2` >/does/not/exist; echo $?
18true; a=$(exit 2) >/does/not/exist; echo $?
19false; a=$(exit 2) >/does/not/exist; echo $?
diff --git a/shell/ash_test/ash-psubst/falsetick2.right b/shell/ash_test/ash-psubst/falsetick2.right
new file mode 100644
index 000000000..670f560f1
--- /dev/null
+++ b/shell/ash_test/ash-psubst/falsetick2.right
@@ -0,0 +1 @@
Two:2 v:[]
diff --git a/shell/ash_test/ash-psubst/falsetick2.tests b/shell/ash_test/ash-psubst/falsetick2.tests
new file mode 100755
index 000000000..cfbd1a5de
--- /dev/null
+++ b/shell/ash_test/ash-psubst/falsetick2.tests
@@ -0,0 +1,3 @@
1v=v
2v=`exit 2` `false`
3echo Two:$? v:"[$v]"
diff --git a/shell/ash_test/ash-vars/var6.right b/shell/ash_test/ash-vars/var6.right
new file mode 100644
index 000000000..b37417fa1
--- /dev/null
+++ b/shell/ash_test/ash-vars/var6.right
@@ -0,0 +1,2 @@
1SHELL: line 1: syntax error: bad substitution
2SHELL: line 1: syntax error: bad substitution
diff --git a/shell/ash_test/ash-vars/var6.tests b/shell/ash_test/ash-vars/var6.tests
new file mode 100755
index 000000000..626e60ee1
--- /dev/null
+++ b/shell/ash_test/ash-vars/var6.tests
@@ -0,0 +1,5 @@
1# reject invalid vars
2# (set argv0 to "SHELL" to avoid "/path/to/shell: blah" in error messages)
3"$THIS_SH" -c 'echo ${1q}' SHELL
4"$THIS_SH" -c 'echo ${&}' SHELL
5#"$THIS_SH" -c 'echo ${$}' SHELL -- this is valid as it's the same as $$
diff --git a/shell/ash_test/ash-vars/var_nested1.right b/shell/ash_test/ash-vars/var_nested1.right
new file mode 100644
index 000000000..f4bc5f4b6
--- /dev/null
+++ b/shell/ash_test/ash-vars/var_nested1.right
@@ -0,0 +1,3 @@
1Expected:AB Actual:AB
2Expected:Ab Actual:Ab
3Expected:ab Actual:ab
diff --git a/shell/ash_test/ash-vars/var_nested1.tests b/shell/ash_test/ash-vars/var_nested1.tests
new file mode 100755
index 000000000..59e4a14fa
--- /dev/null
+++ b/shell/ash_test/ash-vars/var_nested1.tests
@@ -0,0 +1,16 @@
1f() { a=A; b=B; }
2
3a=a
4b=b
5f
6echo Expected:AB Actual:$a$b
7
8a=a
9b=b
10b= f
11echo Expected:Ab Actual:$a$b
12
13a=a
14b=b
15a= b= f
16echo Expected:ab Actual:$a$b
diff --git a/shell/ash_test/ash-vars/var_nested2.right b/shell/ash_test/ash-vars/var_nested2.right
new file mode 100644
index 000000000..c930d971c
--- /dev/null
+++ b/shell/ash_test/ash-vars/var_nested2.right
@@ -0,0 +1 @@
aB
diff --git a/shell/ash_test/ash-vars/var_nested2.tests b/shell/ash_test/ash-vars/var_nested2.tests
new file mode 100755
index 000000000..e8865861e
--- /dev/null
+++ b/shell/ash_test/ash-vars/var_nested2.tests
@@ -0,0 +1,2 @@
1# the bug was easier to trigger in one-liner form
2a=a; b=b; f() { a=A; b=B; }; a= f; echo $a$b
diff --git a/shell/hush.c b/shell/hush.c
index 1aa0a400d..27092c12f 100644
--- a/shell/hush.c
+++ b/shell/hush.c
@@ -384,6 +384,7 @@
384#define BASH_PATTERN_SUBST ENABLE_HUSH_BASH_COMPAT 384#define BASH_PATTERN_SUBST ENABLE_HUSH_BASH_COMPAT
385#define BASH_SUBSTR ENABLE_HUSH_BASH_COMPAT 385#define BASH_SUBSTR ENABLE_HUSH_BASH_COMPAT
386#define BASH_SOURCE ENABLE_HUSH_BASH_COMPAT 386#define BASH_SOURCE ENABLE_HUSH_BASH_COMPAT
387#define BASH_DOLLAR_SQUOTE ENABLE_HUSH_BASH_COMPAT
387#define BASH_HOSTNAME_VAR ENABLE_HUSH_BASH_COMPAT 388#define BASH_HOSTNAME_VAR ENABLE_HUSH_BASH_COMPAT
388#define BASH_EPOCH_VARS ENABLE_HUSH_BASH_COMPAT 389#define BASH_EPOCH_VARS ENABLE_HUSH_BASH_COMPAT
389#define BASH_TEST2 (ENABLE_HUSH_BASH_COMPAT && ENABLE_HUSH_TEST) 390#define BASH_TEST2 (ENABLE_HUSH_BASH_COMPAT && ENABLE_HUSH_TEST)
@@ -4919,6 +4920,101 @@ static int add_till_closing_bracket(o_string *dest, struct in_str *input, unsign
4919} 4920}
4920#endif /* ENABLE_HUSH_TICK || ENABLE_FEATURE_SH_MATH || ENABLE_HUSH_DOLLAR_OPS */ 4921#endif /* ENABLE_HUSH_TICK || ENABLE_FEATURE_SH_MATH || ENABLE_HUSH_DOLLAR_OPS */
4921 4922
4923#if BASH_DOLLAR_SQUOTE
4924/* Return code: 1 for "found and parsed", 0 for "seen something else" */
4925# if BB_MMU
4926#define parse_dollar_squote(as_string, dest, input) \
4927 parse_dollar_squote(dest, input)
4928#define as_string NULL
4929# endif
4930static int parse_dollar_squote(o_string *as_string, o_string *dest, struct in_str *input)
4931{
4932 int start;
4933 int ch = i_peek_and_eat_bkslash_nl(input); /* first character after the $ */
4934 debug_printf_parse("parse_dollar_squote entered: ch='%c'\n", ch);
4935 if (ch != '\'')
4936 return 0;
4937
4938 dest->has_quoted_part = 1;
4939 start = dest->length;
4940
4941 ch = i_getch(input); /* eat ' */
4942 nommu_addchr(as_string, ch);
4943 while (1) {
4944 ch = i_getch(input);
4945 nommu_addchr(as_string, ch);
4946 if (ch == EOF) {
4947 syntax_error_unterm_ch('\'');
4948 return 0;
4949 }
4950 if (ch == '\'')
4951 break;
4952 if (ch == SPECIAL_VAR_SYMBOL) {
4953 /* Convert raw ^C to corresponding special variable reference */
4954 o_addchr(dest, SPECIAL_VAR_SYMBOL);
4955 o_addchr(dest, SPECIAL_VAR_QUOTED_SVS);
4956 /* will addchr() another SPECIAL_VAR_SYMBOL (see after the if() block) */
4957 } else if (ch == '\\') {
4958 static const char C_escapes[] ALIGN1 = "nrbtfav""x\\01234567";
4959
4960 ch = i_getch(input);
4961 nommu_addchr(as_string, ch);
4962 if (strchr(C_escapes, ch)) {
4963 char buf[4];
4964 char *p = buf;
4965 int cnt = 2;
4966
4967 buf[0] = ch;
4968 if ((unsigned char)(ch - '0') <= 7) { /* \ooo */
4969 do {
4970 ch = i_peek(input);
4971 if ((unsigned char)(ch - '0') > 7)
4972 break;
4973 *++p = ch = i_getch(input);
4974 nommu_addchr(as_string, ch);
4975 } while (--cnt != 0);
4976 } else if (ch == 'x') { /* \xHH */
4977 do {
4978 ch = i_peek(input);
4979 if (!isxdigit(ch))
4980 break;
4981 *++p = ch = i_getch(input);
4982 nommu_addchr(as_string, ch);
4983 } while (--cnt != 0);
4984 if (cnt == 2) { /* \x but next char is "bad" */
4985 ch = 'x';
4986 goto unrecognized;
4987 }
4988 } /* else simple seq like \\ or \t */
4989 *++p = '\0';
4990 p = buf;
4991 ch = bb_process_escape_sequence((void*)&p);
4992 //bb_error_msg("buf:'%s' ch:%x", buf, ch);
4993 if (ch == '\0')
4994 continue; /* bash compat: $'...\0...' emits nothing */
4995 } else { /* unrecognized "\z": encode both chars unless ' or " */
4996 if (ch != '\'' && ch != '"') {
4997 unrecognized:
4998 o_addqchr(dest, '\\');
4999 }
5000 }
5001 } /* if (\...) */
5002 o_addqchr(dest, ch);
5003 }
5004
5005 if (dest->length == start) {
5006 /* $'', $'\0', $'\000\x00' and the like */
5007 o_addchr(dest, SPECIAL_VAR_SYMBOL);
5008 o_addchr(dest, SPECIAL_VAR_SYMBOL);
5009 }
5010
5011 return 1;
5012# undef as_string
5013}
5014#else
5015# define parse_dollar_squote(as_string, dest, input) 0
5016#endif /* BASH_DOLLAR_SQUOTE */
5017
4922/* Return code: 0 for OK, 1 for syntax error */ 5018/* Return code: 0 for OK, 1 for syntax error */
4923#if BB_MMU 5019#if BB_MMU
4924#define parse_dollar(as_string, dest, input, quote_mask) \ 5020#define parse_dollar(as_string, dest, input, quote_mask) \
@@ -4931,7 +5027,7 @@ static int parse_dollar(o_string *as_string,
4931{ 5027{
4932 int ch = i_peek_and_eat_bkslash_nl(input); /* first character after the $ */ 5028 int ch = i_peek_and_eat_bkslash_nl(input); /* first character after the $ */
4933 5029
4934 debug_printf_parse("parse_dollar entered: ch='%c'\n", ch); 5030 debug_printf_parse("parse_dollar entered: ch='%c' quote_mask:0x%x\n", ch, quote_mask);
4935 if (isalpha(ch)) { 5031 if (isalpha(ch)) {
4936 make_var: 5032 make_var:
4937 ch = i_getch(input); 5033 ch = i_getch(input);
@@ -5247,6 +5343,8 @@ static int encode_string(o_string *as_string,
5247 goto again; 5343 goto again;
5248 } 5344 }
5249 if (ch == '$') { 5345 if (ch == '$') {
5346 //if (parse_dollar_squote(as_string, dest, input))
5347 // goto again;
5250 if (!parse_dollar(as_string, dest, input, /*quote_mask:*/ 0x80)) { 5348 if (!parse_dollar(as_string, dest, input, /*quote_mask:*/ 0x80)) {
5251 debug_printf_parse("encode_string return 0: " 5349 debug_printf_parse("encode_string return 0: "
5252 "parse_dollar returned 0 (error)\n"); 5350 "parse_dollar returned 0 (error)\n");
@@ -5723,6 +5821,8 @@ static struct pipe *parse_stream(char **pstring,
5723 o_addchr(&ctx.word, ch); 5821 o_addchr(&ctx.word, ch);
5724 continue; /* get next char */ 5822 continue; /* get next char */
5725 case '$': 5823 case '$':
5824 if (parse_dollar_squote(&ctx.as_string, &ctx.word, input))
5825 continue; /* get next char */
5726 if (!parse_dollar(&ctx.as_string, &ctx.word, input, /*quote_mask:*/ 0)) { 5826 if (!parse_dollar(&ctx.as_string, &ctx.word, input, /*quote_mask:*/ 0)) {
5727 debug_printf_parse("parse_stream parse error: " 5827 debug_printf_parse("parse_stream parse error: "
5728 "parse_dollar returned 0 (error)\n"); 5828 "parse_dollar returned 0 (error)\n");
@@ -5850,7 +5950,6 @@ static struct pipe *parse_stream(char **pstring,
5850 if (ctx.ctx_res_w == RES_MATCH) 5950 if (ctx.ctx_res_w == RES_MATCH)
5851 goto case_semi; 5951 goto case_semi;
5852#endif 5952#endif
5853
5854 case '}': 5953 case '}':
5855 /* proper use of this character is caught by end_trigger: 5954 /* proper use of this character is caught by end_trigger:
5856 * if we see {, we call parse_group(..., end_trigger='}') 5955 * if we see {, we call parse_group(..., end_trigger='}')
@@ -6166,6 +6265,8 @@ static char *encode_then_expand_vararg(const char *str, int handle_squotes, int
6166 continue; 6265 continue;
6167 } 6266 }
6168 if (ch == '$') { 6267 if (ch == '$') {
6268 if (parse_dollar_squote(NULL, &dest, &input))
6269 continue;
6169 if (!parse_dollar(NULL, &dest, &input, /*quote_mask:*/ 0x80)) { 6270 if (!parse_dollar(NULL, &dest, &input, /*quote_mask:*/ 0x80)) {
6170 debug_printf_parse("%s: error: parse_dollar returned 0 (error)\n", __func__); 6271 debug_printf_parse("%s: error: parse_dollar returned 0 (error)\n", __func__);
6171 goto ret; 6272 goto ret;
@@ -6365,6 +6466,18 @@ static arith_t expand_and_evaluate_arith(const char *arg, const char **errmsg_p)
6365/* ${var/[/]pattern[/repl]} helpers */ 6466/* ${var/[/]pattern[/repl]} helpers */
6366static char *strstr_pattern(char *val, const char *pattern, int *size) 6467static char *strstr_pattern(char *val, const char *pattern, int *size)
6367{ 6468{
6469 int sz = strcspn(pattern, "*?[\\");
6470 if (pattern[sz] == '\0') {
6471 /* Optimization for trivial patterns.
6472 * Testcase for very slow replace (performs about 22k replaces):
6473 * x=::::::::::::::::::::::
6474 * x=$x$x;x=$x$x;x=$x$x;x=$x$x;x=$x$x;x=$x$x;x=$x$x;x=$x$x;x=$x$x;x=$x$x;echo ${#x}
6475 * echo "${x//:/|}"
6476 */
6477 *size = sz;
6478 return strstr(val, pattern);
6479 }
6480
6368 while (1) { 6481 while (1) {
6369 char *end = scan_and_match(val, pattern, SCAN_MOVE_FROM_RIGHT + SCAN_MATCH_LEFT_HALF); 6482 char *end = scan_and_match(val, pattern, SCAN_MOVE_FROM_RIGHT + SCAN_MATCH_LEFT_HALF);
6370 debug_printf_varexp("val:'%s' pattern:'%s' end:'%s'\n", val, pattern, end); 6483 debug_printf_varexp("val:'%s' pattern:'%s' end:'%s'\n", val, pattern, end);
diff --git a/shell/hush_test/hush-psubst/falsetick.right b/shell/hush_test/hush-psubst/falsetick.right
index 0b98fb778..d2d1a2880 100644
--- a/shell/hush_test/hush-psubst/falsetick.right
+++ b/shell/hush_test/hush-psubst/falsetick.right
@@ -22,6 +22,3 @@ hush: can't open '/does/not/exist': No such file or directory
221 221
23hush: can't open '/does/not/exist': No such file or directory 23hush: can't open '/does/not/exist': No such file or directory
241 241
25hush: can't open '/does/not/exist': No such file or directory
261
27Done: a=b
diff --git a/shell/hush_test/hush-psubst/falsetick.tests b/shell/hush_test/hush-psubst/falsetick.tests
index 44d2eae8b..d2b93695e 100755
--- a/shell/hush_test/hush-psubst/falsetick.tests
+++ b/shell/hush_test/hush-psubst/falsetick.tests
@@ -17,6 +17,3 @@ true; a=`exit 2` >/does/not/exist; echo $?
17false; a=`exit 2` >/does/not/exist; echo $? 17false; a=`exit 2` >/does/not/exist; echo $?
18true; a=$(exit 2) >/does/not/exist; echo $? 18true; a=$(exit 2) >/does/not/exist; echo $?
19false; a=$(exit 2) >/does/not/exist; echo $? 19false; a=$(exit 2) >/does/not/exist; echo $?
20# ...and assignment still happens despite redirect error:
21true; a=$(echo b) >/does/not/exist; echo $?
22echo "Done: a=$a"
diff --git a/shell/hush_test/hush-psubst/falsetick3.right b/shell/hush_test/hush-psubst/falsetick3.right
new file mode 100644
index 000000000..327849a31
--- /dev/null
+++ b/shell/hush_test/hush-psubst/falsetick3.right
@@ -0,0 +1,3 @@
1hush: can't open '/does/not/exist': No such file or directory
21
3Done: a=b
diff --git a/shell/hush_test/hush-psubst/falsetick3.tests b/shell/hush_test/hush-psubst/falsetick3.tests
new file mode 100755
index 000000000..cd185335e
--- /dev/null
+++ b/shell/hush_test/hush-psubst/falsetick3.tests
@@ -0,0 +1,3 @@
1# assignment still happens despite redirect error
2true; a=$(echo b) >/does/not/exist; echo $?
3echo "Done: a=$a"
diff --git a/shell/hush_test/hush-quoting/dollar_squote_bash1.right b/shell/hush_test/hush-quoting/dollar_squote_bash1.right
new file mode 100644
index 000000000..9f4e25efa
--- /dev/null
+++ b/shell/hush_test/hush-quoting/dollar_squote_bash1.right
@@ -0,0 +1,10 @@
1a b
2$'a\tb'
3a
4b c
5def
6a'b c"d e\f
7a3b c3b e33f
8a\80b c08b
9a3b c30b
10x y
diff --git a/shell/hush_test/hush-quoting/dollar_squote_bash1.tests b/shell/hush_test/hush-quoting/dollar_squote_bash1.tests
new file mode 100755
index 000000000..6fc411b93
--- /dev/null
+++ b/shell/hush_test/hush-quoting/dollar_squote_bash1.tests
@@ -0,0 +1,8 @@
1echo $'a\tb'
2echo "$'a\tb'"
3echo $'a\nb' $'c\nd''ef'
4echo $'a\'b' $'c\"d' $'e\\f'
5echo $'a\63b' $'c\063b' $'e\0633f'
6echo $'a\80b' $'c\608b'
7echo $'a\x33b' $'c\x330b'
8echo $'x\x9y'
diff --git a/shell/hush_test/hush-quoting/dollar_squote_bash2.right b/shell/hush_test/hush-quoting/dollar_squote_bash2.right
new file mode 100644
index 000000000..f7a1731dd
--- /dev/null
+++ b/shell/hush_test/hush-quoting/dollar_squote_bash2.right
@@ -0,0 +1,6 @@
1strstrstrstrstrstrstrstrstrstrstrstrstrstrstrstrstr
2strstrstrstrstrstrstrstrstrstrstrstrstrstrstrstrstr
380:\
481:\
582:\
6Done:0
diff --git a/shell/hush_test/hush-quoting/dollar_squote_bash2.tests b/shell/hush_test/hush-quoting/dollar_squote_bash2.tests
new file mode 100755
index 000000000..449772813
--- /dev/null
+++ b/shell/hush_test/hush-quoting/dollar_squote_bash2.tests
@@ -0,0 +1,10 @@
1# Embedded NULs
2echo $'str\x00'strstrstrstrstrstrstrstrstrstrstrstrstrstrstrstr
3echo $'str\000'strstrstrstrstrstrstrstrstrstrstrstrstrstrstrstr
4
5# The chars after '\' are hex 0x80,81,82...
6echo 80:$'\'
7echo 81:$'\'
8echo 82:$'\'
9
10echo Done:$?
diff --git a/shell/hush_test/hush-vars/var6.tests b/shell/hush_test/hush-vars/var6.tests
index aea36d62d..626e60ee1 100755
--- a/shell/hush_test/hush-vars/var6.tests
+++ b/shell/hush_test/hush-vars/var6.tests
@@ -1,4 +1,5 @@
1# reject invalid vars 1# reject invalid vars
2"$THIS_SH" -c 'echo ${1q}' 2# (set argv0 to "SHELL" to avoid "/path/to/shell: blah" in error messages)
3"$THIS_SH" -c 'echo ${&}' 3"$THIS_SH" -c 'echo ${1q}' SHELL
4#"$THIS_SH" -c 'echo ${$}' -- this is valid as it's the same as $$ 4"$THIS_SH" -c 'echo ${&}' SHELL
5#"$THIS_SH" -c 'echo ${$}' SHELL -- this is valid as it's the same as $$
diff --git a/shell/hush_test/hush-vars/var_bash7.right b/shell/hush_test/hush-vars/var_bash7.right
new file mode 100644
index 000000000..223b7836f
--- /dev/null
+++ b/shell/hush_test/hush-vars/var_bash7.right
@@ -0,0 +1 @@
B
diff --git a/shell/hush_test/hush-vars/var_bash7.tests b/shell/hush_test/hush-vars/var_bash7.tests
new file mode 100755
index 000000000..c4ce03f7f
--- /dev/null
+++ b/shell/hush_test/hush-vars/var_bash7.tests
@@ -0,0 +1 @@
x=AB; echo "${x#$'\x41'}"
diff --git a/shell/match.c b/shell/match.c
index ee8abb2db..90f77546d 100644
--- a/shell/match.c
+++ b/shell/match.c
@@ -64,11 +64,10 @@ char* FAST_FUNC scan_and_match(char *string, const char *pattern, unsigned flags
64 } 64 }
65 65
66 while (loc != end) { 66 while (loc != end) {
67 char c;
68 int r; 67 int r;
69 68
70 c = *loc;
71 if (flags & SCAN_MATCH_LEFT_HALF) { 69 if (flags & SCAN_MATCH_LEFT_HALF) {
70 char c = *loc;
72 *loc = '\0'; 71 *loc = '\0';
73 r = fnmatch(pattern, string, 0); 72 r = fnmatch(pattern, string, 0);
74 //bb_error_msg("fnmatch('%s','%s',0):%d", pattern, string, r); 73 //bb_error_msg("fnmatch('%s','%s',0):%d", pattern, string, r);
diff --git a/testsuite/awk.tests b/testsuite/awk.tests
index f53b1efe2..dc2ae2e11 100755
--- a/testsuite/awk.tests
+++ b/testsuite/awk.tests
@@ -410,7 +410,7 @@ testing "awk printf('%c') can output NUL" \
410 "awk '{printf(\"hello%c null\n\", 0)}'" "hello\0 null\n" "" "\n" 410 "awk '{printf(\"hello%c null\n\", 0)}'" "hello\0 null\n" "" "\n"
411SKIP= 411SKIP=
412 412
413optional FEATURE_AWK_GNU_EXTENSIONS 413optional FEATURE_AWK_GNU_EXTENSIONS DESKTOP
414testing "awk printf('%-10c') can output NUL" \ 414testing "awk printf('%-10c') can output NUL" \
415 "awk 'BEGIN { printf \"[%-10c]\n\", 0 }' | od -tx1" "\ 415 "awk 'BEGIN { printf \"[%-10c]\n\", 0 }' | od -tx1" "\
4160000000 5b 00 20 20 20 20 20 20 20 20 20 5d 0a 4160000000 5b 00 20 20 20 20 20 20 20 20 20 5d 0a
diff --git a/testsuite/cut.tests b/testsuite/cut.tests
index d705b91c3..2458c019c 100755
--- a/testsuite/cut.tests
+++ b/testsuite/cut.tests
@@ -66,6 +66,7 @@ testing "cut with -d -f(a) -s" "cut -da -f3 -s input" "n\nsium:Jim\n\ncion:Ed\n"
66testing "cut with -d -f(a) -s -n" "cut -da -f3 -s -n input" "n\nsium:Jim\n\ncion:Ed\n" "$input" "" 66testing "cut with -d -f(a) -s -n" "cut -da -f3 -s -n input" "n\nsium:Jim\n\ncion:Ed\n" "$input" ""
67 67
68# substitute for awk 68# substitute for awk
69optional FEATURE_CUT_REGEX
69testing "cut -DF" "cut -DF 2,7,5" \ 70testing "cut -DF" "cut -DF 2,7,5" \
70 "said and your\nare\nis demand. supply\nforecast :\nyou you better,\n\nEm: Took hate\n" "" \ 71 "said and your\nare\nis demand. supply\nforecast :\nyou you better,\n\nEm: Took hate\n" "" \
71"Bother, said Pooh. It's your husband, and he has a gun. 72"Bother, said Pooh. It's your husband, and he has a gun.
@@ -75,6 +76,7 @@ Weather forecast for tonight : dark.
75Apple: you can buy better, but you can't pay more. 76Apple: you can buy better, but you can't pay more.
76Subcalifragilisticexpialidocious. 77Subcalifragilisticexpialidocious.
77Auntie Em: Hate you, hate Kansas. Took the dog. Dorothy." 78Auntie Em: Hate you, hate Kansas. Took the dog. Dorothy."
79SKIP=
78 80
79testing "cut empty field" "cut -d ':' -f 1-3" "a::b\n" "" "a::b\n" 81testing "cut empty field" "cut -d ':' -f 1-3" "a::b\n" "" "a::b\n"
80testing "cut empty field 2" "cut -d ':' -f 3-5" "b::c\n" "" "a::b::c:d\n" 82testing "cut empty field 2" "cut -d ':' -f 3-5" "b::c\n" "" "a::b::c:d\n"
diff --git a/testsuite/dd/dd-count-bytes b/testsuite/dd/dd-count-bytes
index 0730cba5e..ae1b6c50a 100644
--- a/testsuite/dd/dd-count-bytes
+++ b/testsuite/dd/dd-count-bytes
@@ -1 +1,3 @@
1# FEATURE: CONFIG_FEATURE_DD_IBS_OBS
2
1test "$(echo I WANT | busybox dd count=3 iflag=count_bytes 2>/dev/null)" = "I W" 3test "$(echo I WANT | busybox dd count=3 iflag=count_bytes 2>/dev/null)" = "I W"
diff --git a/testsuite/tar.tests b/testsuite/tar.tests
index d71a34910..0f2e89112 100755
--- a/testsuite/tar.tests
+++ b/testsuite/tar.tests
@@ -3,6 +3,7 @@
3# Licensed under GPLv2, see file LICENSE in this source tree. 3# Licensed under GPLv2, see file LICENSE in this source tree.
4 4
5. ./testing.sh 5. ./testing.sh
6test -f "$bindir/.config" && . "$bindir/.config"
6 7
7unset LANG 8unset LANG
8unset LANGUAGE 9unset LANGUAGE
@@ -12,7 +13,7 @@ umask 022
12 13
13# testing "test name" "script" "expected result" "file input" "stdin" 14# testing "test name" "script" "expected result" "file input" "stdin"
14 15
15testing "Empty file is not a tarball" '\ 16testing "tar Empty file is not a tarball" '\
16tar xvf - 2>&1; echo $? 17tar xvf - 2>&1; echo $?
17' "\ 18' "\
18tar: short read 19tar: short read
@@ -25,7 +26,7 @@ optional FEATURE_SEAMLESS_GZ GUNZIP
25# In NOMMU case, "invalid magic" message comes from gunzip child process. 26# In NOMMU case, "invalid magic" message comes from gunzip child process.
26# Otherwise, it comes from tar. 27# Otherwise, it comes from tar.
27# Need to fix output up to avoid false positive. 28# Need to fix output up to avoid false positive.
28testing "Empty file is not a tarball.tar.gz" '\ 29testing "tar Empty file is not a tarball.tar.gz" '\
29{ tar xvzf - 2>&1; echo $?; } | grep -Fv "invalid magic" 30{ tar xvzf - 2>&1; echo $?; } | grep -Fv "invalid magic"
30' "\ 31' "\
31tar: short read 32tar: short read
@@ -34,7 +35,7 @@ tar: short read
34"" "" 35"" ""
35SKIP= 36SKIP=
36 37
37testing "Two zeroed blocks is a ('truncated') empty tarball" '\ 38testing "tar Two zeroed blocks is a ('truncated') empty tarball" '\
38dd if=/dev/zero bs=512 count=2 2>/dev/null | tar xvf - 2>&1; echo $? 39dd if=/dev/zero bs=512 count=2 2>/dev/null | tar xvf - 2>&1; echo $?
39' "\ 40' "\
400 410
@@ -42,7 +43,7 @@ dd if=/dev/zero bs=512 count=2 2>/dev/null | tar xvf - 2>&1; echo $?
42"" "" 43"" ""
43SKIP= 44SKIP=
44 45
45testing "Twenty zeroed blocks is an empty tarball" '\ 46testing "tar Twenty zeroed blocks is an empty tarball" '\
46dd if=/dev/zero bs=512 count=20 2>/dev/null | tar xvf - 2>&1; echo $? 47dd if=/dev/zero bs=512 count=20 2>/dev/null | tar xvf - 2>&1; echo $?
47' "\ 48' "\
480 490
@@ -313,9 +314,10 @@ l4/V8LDoe90yiWJhOJvIypgEfxdyRThQkBVn/bI=
313SKIP= 314SKIP=
314cd .. || exit 1; rm -rf tar.tempdir 2>/dev/null 315cd .. || exit 1; rm -rf tar.tempdir 2>/dev/null
315 316
317if test x"$CONFIG_UNICODE_USING_LOCALE" != x"y"; then
316mkdir tar.tempdir && cd tar.tempdir || exit 1 318mkdir tar.tempdir && cd tar.tempdir || exit 1
317optional UNICODE_SUPPORT FEATURE_TAR_GNU_EXTENSIONS FEATURE_SEAMLESS_BZ2 FEATURE_TAR_AUTODETECT 319optional UNICODE_SUPPORT FEATURE_TAR_GNU_EXTENSIONS FEATURE_SEAMLESS_BZ2 FEATURE_TAR_AUTODETECT
318testing "Pax-encoded UTF8 names and symlinks" '\ 320testing "tar Pax-encoded UTF8 names and symlinks" '\
319tar xvf ../tar.utf8.tar.bz2 2>&1; echo $? 321tar xvf ../tar.utf8.tar.bz2 2>&1; echo $?
320export LANG=en_US.UTF-8 322export LANG=en_US.UTF-8
321ls -l etc/ssl/certs/* | sed "s:.*etc/:etc/:" | sort 323ls -l etc/ssl/certs/* | sed "s:.*etc/:etc/:" | sort
@@ -334,10 +336,11 @@ etc/ssl/certs/f80cc7f6.0 -> EBG_Elektronik_Sertifika_Hizmet_Sağlayıcısı.pem
334"" "" 336"" ""
335SKIP= 337SKIP=
336cd .. || exit 1; rm -rf tar.tempdir 2>/dev/null 338cd .. || exit 1; rm -rf tar.tempdir 2>/dev/null
339fi
337 340
338mkdir tar.tempdir && cd tar.tempdir || exit 1 341mkdir tar.tempdir && cd tar.tempdir || exit 1
339optional FEATURE_SEAMLESS_BZ2 FEATURE_TAR_AUTODETECT LS 342optional FEATURE_SEAMLESS_BZ2 FEATURE_TAR_AUTODETECT LS
340testing "Symlink attack: create symlink and then write through it" '\ 343testing "tar Symlink attack: create symlink and then write through it" '\
341exec 2>&1 344exec 2>&1
342uudecode -o input && tar xvf input; echo $? 345uudecode -o input && tar xvf input; echo $?
343ls /tmp/bb_test_evilfile 346ls /tmp/bb_test_evilfile
@@ -367,7 +370,7 @@ cd .. || exit 1; rm -rf tar.tempdir 2>/dev/null
367 370
368mkdir tar.tempdir && cd tar.tempdir || exit 1 371mkdir tar.tempdir && cd tar.tempdir || exit 1
369optional FEATURE_TAR_CREATE 372optional FEATURE_TAR_CREATE
370testing "Symlinks and hardlinks coexist" '\ 373testing "tar Symlinks and hardlinks coexist" '\
371mkdir dir 374mkdir dir
372>dir/a 375>dir/a
373ln -s ../dir/a dir/b 376ln -s ../dir/a dir/b
diff --git a/util-linux/fdisk_sun.c b/util-linux/fdisk_sun.c
index 427b9487b..66e434833 100644
--- a/util-linux/fdisk_sun.c
+++ b/util-linux/fdisk_sun.c
@@ -292,10 +292,10 @@ create_sunlabel(void)
292 } else { 292 } else {
293 g_heads = read_int(1, g_heads, 1024, 0, "Heads"); 293 g_heads = read_int(1, g_heads, 1024, 0, "Heads");
294 g_sectors = read_int(1, g_sectors, 1024, 0, "Sectors/track"); 294 g_sectors = read_int(1, g_sectors, 1024, 0, "Sectors/track");
295 if (g_cylinders) 295 if (g_cylinders)
296 g_cylinders = read_int(1, g_cylinders - 2, 65535, 0, "Cylinders"); 296 g_cylinders = read_int(1, g_cylinders - 2, 65535, 0, "Cylinders");
297 else 297 else
298 g_cylinders = read_int(1, 0, 65535, 0, "Cylinders"); 298 g_cylinders = read_int(1, 0, 65535, 0, "Cylinders");
299 sunlabel->nacyl = SUN_SSWAP16(read_int(0, 2, 65535, 0, "Alternate cylinders")); 299 sunlabel->nacyl = SUN_SSWAP16(read_int(0, 2, 65535, 0, "Alternate cylinders"));
300 sunlabel->pcylcount = SUN_SSWAP16(read_int(0, g_cylinders + SUN_SSWAP16(sunlabel->nacyl), 65535, 0, "Physical cylinders")); 300 sunlabel->pcylcount = SUN_SSWAP16(read_int(0, g_cylinders + SUN_SSWAP16(sunlabel->nacyl), 65535, 0, "Physical cylinders"));
301 sunlabel->rspeed = SUN_SSWAP16(read_int(1, 5400, 100000, 0, "Rotation speed (rpm)")); 301 sunlabel->rspeed = SUN_SSWAP16(read_int(1, 5400, 100000, 0, "Rotation speed (rpm)"));
diff --git a/util-linux/taskset.c b/util-linux/taskset.c
index afe2f04d2..d2ef9b98f 100644
--- a/util-linux/taskset.c
+++ b/util-linux/taskset.c
@@ -218,7 +218,7 @@ static int process_pid_str(const char *pid_str, unsigned opts, char *aff)
218 ul *mask; 218 ul *mask;
219 unsigned mask_size_in_bytes; 219 unsigned mask_size_in_bytes;
220 const char *current_new; 220 const char *current_new;
221 pid_t pid = xatoi_positive(pid_str); 221 pid_t pid = !pid_str ? 0 : xatou_range(pid_str, 1, INT_MAX); /* disallow "0": "taskset -p 0" should fail */
222 222
223 mask_size_in_bytes = SZOF_UL; 223 mask_size_in_bytes = SZOF_UL;
224 current_new = "current"; 224 current_new = "current";
@@ -343,7 +343,7 @@ int taskset_main(int argc UNUSED_PARAM, char **argv)
343 /* <aff> <cmd...> */ 343 /* <aff> <cmd...> */
344 if (!*argv) 344 if (!*argv)
345 bb_show_usage(); 345 bb_show_usage();
346 process_pid_str("0", opts, aff); 346 process_pid_str(NULL, opts, aff);
347 BB_EXECVP_or_die(argv); 347 BB_EXECVP_or_die(argv);
348 } 348 }
349 349