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
@ -32,7 +32,7 @@
|
||||
|
||||
#include <sys/cdefs.h>
|
||||
|
||||
void brace_subst(char *, char **, char *, int);
|
||||
void brace_subst(char *, char **, char *, size_t);
|
||||
PLAN *find_create(char ***);
|
||||
int find_execute(PLAN *, char **);
|
||||
PLAN *find_formplan(char **);
|
||||
|
@ -57,23 +57,33 @@ __FBSDID("$FreeBSD$");
|
||||
* Replace occurrences of {} in s1 with s2 and return the result string.
|
||||
*/
|
||||
void
|
||||
brace_subst(char *orig, char **store, char *path, int len)
|
||||
brace_subst(char *orig, char **store, char *path, size_t len)
|
||||
{
|
||||
int plen;
|
||||
char ch, *p;
|
||||
const char *pastorigend, *p, *q;
|
||||
char *dst;
|
||||
size_t newlen, plen;
|
||||
|
||||
plen = strlen(path);
|
||||
for (p = *store; (ch = *orig) != '\0'; ++orig)
|
||||
if (ch == '{' && orig[1] == '}') {
|
||||
while ((p - *store) + plen > len)
|
||||
if (!(*store = realloc(*store, len *= 2)))
|
||||
err(1, NULL);
|
||||
memmove(p, path, plen);
|
||||
p += plen;
|
||||
++orig;
|
||||
} else
|
||||
*p++ = ch;
|
||||
*p = '\0';
|
||||
newlen = strlen(orig) + 1;
|
||||
pastorigend = orig + newlen;
|
||||
for (p = orig; (q = strstr(p, "{}")) != NULL; p = q + 2) {
|
||||
if (plen > 2 && newlen + plen - 2 < newlen)
|
||||
errx(2, "brace_subst overflow");
|
||||
newlen += plen - 2;
|
||||
}
|
||||
if (newlen > len) {
|
||||
*store = reallocf(*store, newlen);
|
||||
if (*store == NULL)
|
||||
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