find: Fix segfault with very long path in -exec/-ok ... {} \;.
If the resulting argument is longer than MAXPATHLEN, realloc() was called to extend the space, but the new pointer was not correctly stored. Different from what OpenBSD has done, rewrite brace_subst() to calculate the necessary space first and realloc() at most once. As before, the e_len fields are not updated in case of a realloc. Therefore, a following long argument will do another realloc. PR: 201750 MFC after: 1 week
This commit is contained in:
parent
70c81b2077
commit
a2925a5ae3
Notes:
svn2git
2020-12-20 02:59:44 +00:00
svn path=/head/; revision=286344
@ -32,7 +32,7 @@
|
|||||||
|
|
||||||
#include <sys/cdefs.h>
|
#include <sys/cdefs.h>
|
||||||
|
|
||||||
void brace_subst(char *, char **, char *, int);
|
void brace_subst(char *, char **, char *, size_t);
|
||||||
PLAN *find_create(char ***);
|
PLAN *find_create(char ***);
|
||||||
int find_execute(PLAN *, char **);
|
int find_execute(PLAN *, char **);
|
||||||
PLAN *find_formplan(char **);
|
PLAN *find_formplan(char **);
|
||||||
|
@ -57,23 +57,33 @@ __FBSDID("$FreeBSD$");
|
|||||||
* Replace occurrences of {} in s1 with s2 and return the result string.
|
* Replace occurrences of {} in s1 with s2 and return the result string.
|
||||||
*/
|
*/
|
||||||
void
|
void
|
||||||
brace_subst(char *orig, char **store, char *path, int len)
|
brace_subst(char *orig, char **store, char *path, size_t len)
|
||||||
{
|
{
|
||||||
int plen;
|
const char *pastorigend, *p, *q;
|
||||||
char ch, *p;
|
char *dst;
|
||||||
|
size_t newlen, plen;
|
||||||
|
|
||||||
plen = strlen(path);
|
plen = strlen(path);
|
||||||
for (p = *store; (ch = *orig) != '\0'; ++orig)
|
newlen = strlen(orig) + 1;
|
||||||
if (ch == '{' && orig[1] == '}') {
|
pastorigend = orig + newlen;
|
||||||
while ((p - *store) + plen > len)
|
for (p = orig; (q = strstr(p, "{}")) != NULL; p = q + 2) {
|
||||||
if (!(*store = realloc(*store, len *= 2)))
|
if (plen > 2 && newlen + plen - 2 < newlen)
|
||||||
err(1, NULL);
|
errx(2, "brace_subst overflow");
|
||||||
memmove(p, path, plen);
|
newlen += plen - 2;
|
||||||
p += plen;
|
}
|
||||||
++orig;
|
if (newlen > len) {
|
||||||
} else
|
*store = reallocf(*store, newlen);
|
||||||
*p++ = ch;
|
if (*store == NULL)
|
||||||
*p = '\0';
|
err(2, NULL);
|
||||||
|
}
|
||||||
|
dst = *store;
|
||||||
|
for (p = orig; (q = strstr(p, "{}")) != NULL; p = q + 2) {
|
||||||
|
memcpy(dst, p, q - p);
|
||||||
|
dst += q - p;
|
||||||
|
memcpy(dst, path, plen);
|
||||||
|
dst += plen;
|
||||||
|
}
|
||||||
|
memcpy(dst, p, pastorigend - p);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
Loading…
Reference in New Issue
Block a user