Hi All,
 Please find in attachment a new patch that replace a fix for a bug :

"echo -n | xargs -I% echo %" would SEG

Commit:
https://git.busybox.net/busybox/commit/findutils/xargs.c?id=6d777b75ed322ea5ef0d1674ddfee1b5713cb04f

Currently available solution fixes SEGV issue, but the execution of
'xargs -I' behavior is different than the xargs from (GNU findutils).

Please see the example:
~$ cat ~/tmp/xargs-test
--- start file xargs-test ---

line number 2

line number 4


--- end file xargs-test ---

* output from xargs (GNU findutils) 4.7.0:

~$ cat ~/tmp/xargs-test | /usr/bin/xargs -I % echo %
line number 2
line number 4
~$

* output xargs from BusyBox v1.30.1 (Ubuntu 1:1.30.1-4ubuntu6.1)
multi-call binary):

~$ cat ~/tmp/xargs-test | busybox xargs -I % echo %echo %
~$

I thing that xargs from GNY findutils is expected. The patch:
 0001-busybox-xargs-I-ignore-empty-lines.patch
remove the changes within the commit
6d777b75ed322ea5ef0d1674ddfee1b5713cb04f and introduce new behavior -
empty lines are ignored.

Regards,
 Franciszek

-- 
Franciszek Koltuniuk
w:      consult.red <https://consult.red>
e:      franciszek.koltun...@consult.red
>From e8038435e4c63af1b696f0f5ef60e5b16cf0000e Mon Sep 17 00:00:00 2001
From: Franciszek Koltuniuk <franciszek.koltun...@consult.red>
Date: Tue, 22 Sep 2020 15:18:48 +0200
Subject: [PATCH] busybox `xargs -I` - ignore empty lines

Make 'xargs -I' behaviur like GNU findutils - ignore empty lines and replace the fix for the SEGV bug:
commit: 6d777b75ed322ea5ef0d1674ddfee1b5713cb04f

$ echo -n | xargs -I % echo %
Segmentation fault
---
 findutils/xargs.c | 17 +++++++++++++----
 1 file changed, 13 insertions(+), 4 deletions(-)

diff --git a/findutils/xargs.c b/findutils/xargs.c
index ff04bfe7c..fd6abe1ee 100644
--- a/findutils/xargs.c
+++ b/findutils/xargs.c
@@ -106,6 +106,7 @@ struct globals {
 	char **argv;
 	const char *repl_str;
 	char eol_ch;
+	char eof;
 #endif
 	const char *eof_str;
 	int idx;
@@ -128,6 +129,7 @@ struct globals {
 	setup_common_bufsiz(); \
 	IF_FEATURE_XARGS_SUPPORT_REPL_STR(G.repl_str = "{}";) \
 	IF_FEATURE_XARGS_SUPPORT_REPL_STR(G.eol_ch = '\n';) \
+	IF_FEATURE_XARGS_SUPPORT_REPL_STR(G.eof = 0;) \
 	/* Even zero values are set because we are NOEXEC applet */ \
 	G.eof_str = NULL; \
 	G.idx = 0; \
@@ -467,8 +469,10 @@ static char* FAST_FUNC process_stdin_with_replace(int n_max_chars, int n_max_arg
 	while (1) {
 		int c = getchar();
 		if (c == EOF || c == G.eol_ch) {
-			if (p == buf)
+			if (p == buf) {
+				G.eof = (c == EOF); /* check for EOF */
 				goto ret; /* empty line */
+			}
 			c = '\0';
 		}
 		*p++ = c;
@@ -697,9 +701,6 @@ int xargs_main(int argc UNUSED_PARAM, char **argv)
 		G.args = NULL;
 		G.argv = argv;
 		read_args = process_stdin_with_replace;
-		/* Make -I imply -r. GNU findutils seems to do the same: */
-		/* (otherwise "echo -n | xargs -I% echo %" would SEGV) */
-		opt |= OPT_NO_EMPTY;
 	} else
 #endif
 	{
@@ -726,6 +727,14 @@ int xargs_main(int argc UNUSED_PARAM, char **argv)
 		if (!G.args[initial_idx]) { /* not even one ARG was added? */
 			if (*rem != '\0')
 				bb_simple_error_msg_and_die("argument line too long");
+#if ENABLE_FEATURE_XARGS_SUPPORT_REPL_STR
+			if (opt & (OPT_REPLSTR | OPT_REPLSTR1)) {
+				if(G.eof)
+					break; /* exit on EOF */
+				else
+					continue; /* ignore empty line - otherwise "echo -n | xargs -I% echo %" would SEGV */
+			}
+#endif
 			if (opt & OPT_NO_EMPTY)
 				break;
 		}
-- 
2.25.1


_______________________________________________
busybox mailing list
busybox@busybox.net
http://lists.busybox.net/mailman/listinfo/busybox

Reply via email to