git: 15991a682445 - stable/13 - xargs: fix -R so that it accepts negative numbers again

From: Dag-Erling Smørgrav <des_at_FreeBSD.org>
Date: Thu, 07 Sep 2023 14:51:02 UTC
The branch stable/13 has been updated by des:

URL: https://cgit.FreeBSD.org/src/commit/?id=15991a68244562e3aabca3defb542ec5ca684116

commit 15991a68244562e3aabca3defb542ec5ca684116
Author:     Daniel Tameling <tamelingdaniel@gmail.com>
AuthorDate: 2023-07-13 20:06:14 +0000
Commit:     Dag-Erling Smørgrav <des@FreeBSD.org>
CommitDate: 2023-09-07 08:56:26 +0000

    xargs: fix -R so that it accepts negative numbers again
    
    fbc445addf9 converted the parsing of arguments to strtonum but made
    the accepted range for -R too restrictive. As documented in the man
    page, it should accept negative numbers.
    
    Added a test for this, which was provided by Jose Luis Duran.
    
    Fixes:          fbc445addf9
    MFC after:      1 week
    Reviewed by:    des, kevans
    Differential Revision:  https://reviews.freebsd.org/D41021
    
    (cherry picked from commit 202adb2236104141dc02d512084a3cc4bbe734c7)
    
    xargs: disallow -R0 and -L0
    
    Both cases were interpreted as these flags are unset. This meant that
    -R0 got converted to -R5 and that -L0 didn't have any effect at all.
    Since make at most 0 replacements isn't useful and since call utility
    for every 0 lines read doesn't make sense, throw an error for these
    two cases.
    
    MFC after:      1 week
    Reviewed by:    des, kevans
    Differential Revision:  https://reviews.freebsd.org/D41022
    
    (cherry picked from commit 1048a870e3b6973a5be1193f3b45e6e867e8e1c0)
    
    xargs: Prevent overflow in linelen calculation if nargs is large.
    
    MFC after:      1 week
    Sponsored by:   Klara, Inc.
    Reviewed by:    kevans
    Differential Revision:  https://reviews.freebsd.org/D41023
    
    (cherry picked from commit eab91d008165e7bbf8ca7b87eabe4dc8bf3da191)
    
    xargs: Fix test case count.
    
    MFC after:      1 week
    Sponsored by:   Klara, Inc.
    
    (cherry picked from commit c65845d0bb2d17dc283ae5928f25e68212a30842)
    
    xargs: Install missing test output.
    
    Fixes:          eab91d008165e7bbf8ca7b87eabe4dc8bf3da191
    MFC after:      1 week
    Reviewed by:    des
    Differential Revision:  https://reviews.freebsd.org/D41033
    
    (cherry picked from commit d234c8228ced5ea3aa86bd2e9eca79b87d8e6441)
    
    xargs tests: Disable the test added in commit eab91d008165
    
    This test has been triggering OOM kills in CI runs since it triggers an
    allocation of 16GB.  Temporarily disable the test until the problem is
    solved one way or another.
    
    (cherry picked from commit 2682a15527241278c9aa46c4907d3b07460b8ec0)
---
 usr.bin/xargs/tests/Makefile                | 2 ++
 usr.bin/xargs/tests/regress.R-1.out         | 4 ++++
 usr.bin/xargs/tests/regress.n2147483647.out | 1 +
 usr.bin/xargs/tests/regress.sh              | 6 +++++-
 usr.bin/xargs/xargs.c                       | 8 +++++---
 5 files changed, 17 insertions(+), 4 deletions(-)

diff --git a/usr.bin/xargs/tests/Makefile b/usr.bin/xargs/tests/Makefile
index bfb2d171ba52..50545c11f90e 100644
--- a/usr.bin/xargs/tests/Makefile
+++ b/usr.bin/xargs/tests/Makefile
@@ -14,9 +14,11 @@ ${PACKAGE}FILES+=		regress.J.out
 ${PACKAGE}FILES+=		regress.L.out
 ${PACKAGE}FILES+=		regress.P1.out
 ${PACKAGE}FILES+=		regress.R.out
+${PACKAGE}FILES+=		regress.R-1.out
 ${PACKAGE}FILES+=		regress.in
 ${PACKAGE}FILES+=		regress.n1.out
 ${PACKAGE}FILES+=		regress.n2.out
+${PACKAGE}FILES+=		regress.n2147483647.out
 ${PACKAGE}FILES+=		regress.n2P0.out
 ${PACKAGE}FILES+=		regress.n3.out
 ${PACKAGE}FILES+=		regress.normal.out
diff --git a/usr.bin/xargs/tests/regress.R-1.out b/usr.bin/xargs/tests/regress.R-1.out
new file mode 100644
index 000000000000..7bdf58090c60
--- /dev/null
+++ b/usr.bin/xargs/tests/regress.R-1.out
@@ -0,0 +1,4 @@
+The quick brown quick brown quick brown quick brownquick brown quick brown quick brown
+The fox jumped fox jumped fox jumped fox jumpedfox jumped fox jumped fox jumped
+The over the lazy over the lazy over the lazy over the lazyover the lazy over the lazy over the lazy
+The dog dog dog dogdog dog dog
diff --git a/usr.bin/xargs/tests/regress.n2147483647.out b/usr.bin/xargs/tests/regress.n2147483647.out
new file mode 100644
index 000000000000..cc32a92a2199
--- /dev/null
+++ b/usr.bin/xargs/tests/regress.n2147483647.out
@@ -0,0 +1 @@
+quick brown fox jumped over the lazy dog
diff --git a/usr.bin/xargs/tests/regress.sh b/usr.bin/xargs/tests/regress.sh
index a0b4a98a2dd3..9b4839d2a8ec 100644
--- a/usr.bin/xargs/tests/regress.sh
+++ b/usr.bin/xargs/tests/regress.sh
@@ -1,5 +1,5 @@
 
-echo 1..20
+echo 1..21
 
 REGRESSION_START($1)
 
@@ -9,8 +9,12 @@ REGRESSION_TEST(`J', `xargs -J% echo The % again. <${SRCDIR}/regress.in')
 REGRESSION_TEST(`L', `xargs -L3 echo <${SRCDIR}/regress.in')
 REGRESSION_TEST(`P1', `xargs -P1 echo <${SRCDIR}/regress.in')
 REGRESSION_TEST(`R', `xargs -I% -R1 echo The % % % %% % % <${SRCDIR}/regress.in')
+REGRESSION_TEST(`R-1', `xargs -I% -R-1 echo The % % % %% % % <${SRCDIR}/regress.in')
 REGRESSION_TEST(`n1', `xargs -n1 echo <${SRCDIR}/regress.in')
 REGRESSION_TEST(`n2', `xargs -n2 echo <${SRCDIR}/regress.in')
+# This test may consume a large amount of memory, making it unsuited to CI
+# environments.  Disable it for now.
+#REGRESSION_TEST(`n2147483647', `xargs -n2147483647 <${SRCDIR}/regress.in')
 REGRESSION_TEST(`n2P0',`xargs -n2 -P0 echo <${SRCDIR}/regress.in | sort')
 REGRESSION_TEST(`n3', `xargs -n3 echo <${SRCDIR}/regress.in')
 REGRESSION_TEST(`0', `xargs -0 -n1 echo <${SRCDIR}/regress.0.in')
diff --git a/usr.bin/xargs/xargs.c b/usr.bin/xargs/xargs.c
index 01308e3ea29f..51f42ba2c842 100644
--- a/usr.bin/xargs/xargs.c
+++ b/usr.bin/xargs/xargs.c
@@ -172,7 +172,7 @@ main(int argc, char *argv[])
 			replstr = optarg;
 			break;
 		case 'L':
-			Lflag = (int)strtonum(optarg, 0, INT_MAX, &errstr);
+			Lflag = (int)strtonum(optarg, 1, INT_MAX, &errstr);
 			if (errstr)
 				errx(1, "-%c %s: %s", ch, optarg, errstr);
 			break;
@@ -198,9 +198,11 @@ main(int argc, char *argv[])
 			pflag = 1;
 			break;
 		case 'R':
-			Rflag = (int)strtonum(optarg, 0, INT_MAX, &errstr);
+			Rflag = (int)strtonum(optarg, INT_MIN, INT_MAX, &errstr);
 			if (errstr)
 				errx(1, "-%c %s: %s", ch, optarg, errstr);
+			if (!Rflag)
+				errx(1, "-%c %s: %s", ch, optarg, "must be non-zero");
 			break;
 		case 'r':
 			/* GNU compatibility */
@@ -253,7 +255,7 @@ main(int argc, char *argv[])
 	 * the maximum arguments to be read from stdin and the trailing
 	 * NULL.
 	 */
-	linelen = 1 + argc + nargs + 1;
+	linelen = 1 + argc + (size_t)nargs + 1;
 	if ((av = bxp = malloc(linelen * sizeof(char *))) == NULL)
 		errx(1, "malloc failed");