git: a7fa987abe1f - main - xargs: Limit -n to {ARG_MAX}

From: Dag-Erling Smørgrav <des_at_FreeBSD.org>
Date: Sat, 26 Jul 2025 16:45:48 UTC
The branch main has been updated by des:

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

commit a7fa987abe1fb0b25a7dd83dc81f14f64a82efc9
Author:     Dag-Erling Smørgrav <des@FreeBSD.org>
AuthorDate: 2025-07-26 16:44:35 +0000
Commit:     Dag-Erling Smørgrav <des@FreeBSD.org>
CommitDate: 2025-07-26 16:44:35 +0000

    xargs: Limit -n to {ARG_MAX}
    
    Since it's not possible to pass more than {ARG_MAX} bytes on the command
    line, it's also not possible to pass more than {ARG_MAX} individual
    arguments.  Therefore, {ARG_MAX} is a reasonable upper bound for the -n
    option.  This resolves both the arithmetic overflow issue and the CI OOM
    issue, so we can safely re-enable the test.
    
    Fixes:          eab91d008165
    Fixes:          2682a1552724
    MFC after:      1 week
    Reviewed by:    jlduran, emaste
    Differential Revision:  https://reviews.freebsd.org/D51536
---
 ObsoleteFiles.inc                                                 | 3 +++
 usr.bin/xargs/tests/Makefile                                      | 2 +-
 .../xargs/tests/{regress.n2147483647.out => regress.nargmax.out}  | 0
 usr.bin/xargs/tests/regress.sh                                    | 8 ++++----
 usr.bin/xargs/xargs.c                                             | 2 +-
 5 files changed, 9 insertions(+), 6 deletions(-)

diff --git a/ObsoleteFiles.inc b/ObsoleteFiles.inc
index 10f99c5d6047..00f889804013 100644
--- a/ObsoleteFiles.inc
+++ b/ObsoleteFiles.inc
@@ -51,6 +51,9 @@
 #   xargs -n1 | sort | uniq -d;
 # done
 
+# 20250726: Test case renamed
+OLD_FILES+=usr/tests/usr.bin/xargs/regress.n2147483647.out
+
 # 20250726: This file is now installed in /etc/dma
 OLD_FILES+=usr/share/examples/dma/auth.conf
 
diff --git a/usr.bin/xargs/tests/Makefile b/usr.bin/xargs/tests/Makefile
index b1e6782069de..1a9265b88b4e 100644
--- a/usr.bin/xargs/tests/Makefile
+++ b/usr.bin/xargs/tests/Makefile
@@ -17,7 +17,7 @@ ${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.nargmax.out
 ${PACKAGE}FILES+=		regress.n2P0.out
 ${PACKAGE}FILES+=		regress.n3.out
 ${PACKAGE}FILES+=		regress.normal.out
diff --git a/usr.bin/xargs/tests/regress.n2147483647.out b/usr.bin/xargs/tests/regress.nargmax.out
similarity index 100%
rename from usr.bin/xargs/tests/regress.n2147483647.out
rename to usr.bin/xargs/tests/regress.nargmax.out
diff --git a/usr.bin/xargs/tests/regress.sh b/usr.bin/xargs/tests/regress.sh
index 9b4839d2a8ec..e65a5a703505 100644
--- a/usr.bin/xargs/tests/regress.sh
+++ b/usr.bin/xargs/tests/regress.sh
@@ -1,5 +1,5 @@
 
-echo 1..21
+echo 1..23
 
 REGRESSION_START($1)
 
@@ -12,9 +12,8 @@ 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')
+argmax=$(sysctl -n kern.argmax)
+REGRESSION_TEST(`nargmax', `xargs -n$argmax <${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')
@@ -28,5 +27,6 @@ REGRESSION_TEST_FREEFORM(`parallel1', `echo /var/empty       /var/empty       |
 REGRESSION_TEST_FREEFORM(`parallel2', `echo /var/empty       /var/empty/nodir | xargs -n1 -P2 test -d; [ $? = 1 ]')
 REGRESSION_TEST_FREEFORM(`parallel3', `echo /var/empty/nodir /var/empty       | xargs -n1 -P2 test -d; [ $? = 1 ]')
 REGRESSION_TEST_FREEFORM(`parallel4', `echo /var/empty/nodir /var/empty/nodir | xargs -n1 -P2 test -d; [ $? = 1 ]')
+REGRESSION_TEST_FREEFORM(`ntoobig', `seq 42 | xargs -n$((argmax+1)); [ $? = 1 ]')
 
 REGRESSION_END()
diff --git a/usr.bin/xargs/xargs.c b/usr.bin/xargs/xargs.c
index 237beff26504..2a7f026e5066 100644
--- a/usr.bin/xargs/xargs.c
+++ b/usr.bin/xargs/xargs.c
@@ -166,7 +166,7 @@ main(int argc, char *argv[])
 			break;
 		case 'n':
 			nflag = 1;
-			nargs = (int)strtonum(optarg, 1, INT_MAX, &errstr);
+			nargs = (int)strtonum(optarg, 1, arg_max, &errstr);
 			if (errstr)
 				errx(1, "-%c %s: %s", ch, optarg, errstr);
 			break;