Skip site navigation (1)Skip section navigation (2)
Date:      Tue, 5 Jul 2022 15:18:28 GMT
From:      Tom Jones <thj@FreeBSD.org>
To:        src-committers@FreeBSD.org, dev-commits-src-all@FreeBSD.org, dev-commits-src-main@FreeBSD.org
Subject:   git: f058359ba5e0 - main - xargs: terminate if line replacement cannot be constructed
Message-ID:  <202207051518.265FISUN084048@gitrepo.freebsd.org>

next in thread | raw e-mail | index | archive | help
The branch main has been updated by thj:

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

commit f058359ba5e08c555d7e6f192217f890b83cd46c
Author:     Tom Jones <thj@FreeBSD.org>
AuthorDate: 2022-07-05 15:03:51 +0000
Commit:     Tom Jones <thj@FreeBSD.org>
CommitDate: 2022-07-05 15:18:05 +0000

    xargs: terminate if line replacement cannot be constructed
    
    If the line with replacement cannot be constructed xargs should
    terminate as documented in the man page
    
    We encounter this error, but gnu/xargs doesn't because they have a much
    larger limit for created outputs (~10000 lines).
    
    Reviewed by:    oshogbo
    Sponsored by:   Klara, Inc.
    Differential Revision:  https://reviews.freebsd.org/D35574
---
 usr.bin/xargs/strnsubst.c | 15 ++++++++++-----
 usr.bin/xargs/xargs.c     |  8 ++++++--
 2 files changed, 16 insertions(+), 7 deletions(-)

diff --git a/usr.bin/xargs/strnsubst.c b/usr.bin/xargs/strnsubst.c
index d826d33c0967..1fa35d453f49 100644
--- a/usr.bin/xargs/strnsubst.c
+++ b/usr.bin/xargs/strnsubst.c
@@ -12,11 +12,12 @@
 __FBSDID("$FreeBSD$");
 
 #include <err.h>
+#include <stdbool.h>
 #include <stdlib.h>
 #include <string.h>
 #include <unistd.h>
 
-void	strnsubst(char **, const char *, const char *, size_t);
+bool	strnsubst(char **, const char *, const char *, size_t);
 
 /*
  * Replaces str with a string consisting of str with match replaced with
@@ -26,16 +27,19 @@ void	strnsubst(char **, const char *, const char *, size_t);
  * str as well as the new contents are handled in an appropriate manner.
  * If replstr is NULL, then that internally is changed to a nil-string, so
  * that we can still pretend to do somewhat meaningful substitution.
- * No value is returned.
+ *
+ * Returns true if truncation was needed to do the replacement, true if
+ * truncation was not required.
  */
-void
+bool
 strnsubst(char **str, const char *match, const char *replstr, size_t maxsize)
 {
 	char *s1, *s2, *this;
+	bool error = false;
 
 	s1 = *str;
 	if (s1 == NULL)
-		return;
+		return false;
 	/*
 	 * If maxsize is 0 then set it to the length of s1, because we have
 	 * to duplicate s1.  XXX we maybe should double-check whether the match
@@ -67,6 +71,7 @@ strnsubst(char **str, const char *match, const char *replstr, size_t maxsize)
 		if ((strlen(s2) + strlen(s1) + strlen(replstr) -
 		    strlen(match) + 1) > maxsize) {
 			strlcat(s2, s1, maxsize);
+			error = true;
 			goto done;
 		}
 		strncat(s2, s1, (uintptr_t)this - (uintptr_t)s1);
@@ -76,7 +81,7 @@ strnsubst(char **str, const char *match, const char *replstr, size_t maxsize)
 	strcat(s2, s1);
 done:
 	*str = s2;
-	return;
+	return error;
 }
 
 #ifdef TEST
diff --git a/usr.bin/xargs/xargs.c b/usr.bin/xargs/xargs.c
index 2825a26f4dfa..7b664cfde1cc 100644
--- a/usr.bin/xargs/xargs.c
+++ b/usr.bin/xargs/xargs.c
@@ -61,6 +61,7 @@ __FBSDID("$FreeBSD$");
 #include <locale.h>
 #include <paths.h>
 #include <regex.h>
+#include <stdbool.h>
 #include <stdio.h>
 #include <stdlib.h>
 #include <string.h>
@@ -73,7 +74,7 @@ static void	prerun(int, char *[]);
 static int	prompt(void);
 static void	run(char **);
 static void	usage(void);
-void		strnsubst(char **, const char *, const char *, size_t);
+bool		strnsubst(char **, const char *, const char *, size_t);
 static pid_t	xwait(int block, int *status);
 static void	xexit(const char *, const int);
 static void	waitchildren(const char *, int);
@@ -517,7 +518,10 @@ prerun(int argc, char *argv[])
 	while (--argc) {
 		*tmp = *avj++;
 		if (repls && strstr(*tmp, replstr) != NULL) {
-			strnsubst(tmp++, replstr, inpline, (size_t)Sflag);
+			if (strnsubst(tmp++, replstr, inpline, (size_t)Sflag)) {
+				warnx("comamnd line cannot be assembled, too long");
+				xexit(*argv, 1);
+			}
 			if (repls > 0)
 				repls--;
 		} else {



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?202207051518.265FISUN084048>