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
This commit is contained in:
parent
62bca9c4df
commit
f058359ba5
@ -12,11 +12,12 @@
|
|||||||
__FBSDID("$FreeBSD$");
|
__FBSDID("$FreeBSD$");
|
||||||
|
|
||||||
#include <err.h>
|
#include <err.h>
|
||||||
|
#include <stdbool.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include <unistd.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
|
* 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.
|
* 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
|
* If replstr is NULL, then that internally is changed to a nil-string, so
|
||||||
* that we can still pretend to do somewhat meaningful substitution.
|
* 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)
|
strnsubst(char **str, const char *match, const char *replstr, size_t maxsize)
|
||||||
{
|
{
|
||||||
char *s1, *s2, *this;
|
char *s1, *s2, *this;
|
||||||
|
bool error = false;
|
||||||
|
|
||||||
s1 = *str;
|
s1 = *str;
|
||||||
if (s1 == NULL)
|
if (s1 == NULL)
|
||||||
return;
|
return false;
|
||||||
/*
|
/*
|
||||||
* If maxsize is 0 then set it to the length of s1, because we have
|
* 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
|
* 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) -
|
if ((strlen(s2) + strlen(s1) + strlen(replstr) -
|
||||||
strlen(match) + 1) > maxsize) {
|
strlen(match) + 1) > maxsize) {
|
||||||
strlcat(s2, s1, maxsize);
|
strlcat(s2, s1, maxsize);
|
||||||
|
error = true;
|
||||||
goto done;
|
goto done;
|
||||||
}
|
}
|
||||||
strncat(s2, s1, (uintptr_t)this - (uintptr_t)s1);
|
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);
|
strcat(s2, s1);
|
||||||
done:
|
done:
|
||||||
*str = s2;
|
*str = s2;
|
||||||
return;
|
return error;
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef TEST
|
#ifdef TEST
|
||||||
|
@ -61,6 +61,7 @@ __FBSDID("$FreeBSD$");
|
|||||||
#include <locale.h>
|
#include <locale.h>
|
||||||
#include <paths.h>
|
#include <paths.h>
|
||||||
#include <regex.h>
|
#include <regex.h>
|
||||||
|
#include <stdbool.h>
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
@ -73,7 +74,7 @@ static void prerun(int, char *[]);
|
|||||||
static int prompt(void);
|
static int prompt(void);
|
||||||
static void run(char **);
|
static void run(char **);
|
||||||
static void usage(void);
|
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 pid_t xwait(int block, int *status);
|
||||||
static void xexit(const char *, const int);
|
static void xexit(const char *, const int);
|
||||||
static void waitchildren(const char *, int);
|
static void waitchildren(const char *, int);
|
||||||
@ -517,7 +518,10 @@ prerun(int argc, char *argv[])
|
|||||||
while (--argc) {
|
while (--argc) {
|
||||||
*tmp = *avj++;
|
*tmp = *avj++;
|
||||||
if (repls && strstr(*tmp, replstr) != NULL) {
|
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)
|
if (repls > 0)
|
||||||
repls--;
|
repls--;
|
||||||
} else {
|
} else {
|
||||||
|
Loading…
Reference in New Issue
Block a user