зеркало из https://github.com/microsoft/git.git
Change semantics of interpolate to work like snprintf.
Also fix many off-by-ones and a useless memset. Signed-off-by: Pierre Habouzit <madcoder@debian.org> Signed-off-by: Junio C Hamano <gitster@pobox.com>
This commit is contained in:
Родитель
f1696ee398
Коммит
4acfd1b799
9
commit.c
9
commit.c
|
@ -923,15 +923,14 @@ long format_commit_message(const struct commit *commit, const void *format,
|
|||
|
||||
do {
|
||||
char *buf = *buf_p;
|
||||
unsigned long space = *space_p;
|
||||
unsigned long len;
|
||||
|
||||
space = interpolate(buf, space, format,
|
||||
len = interpolate(buf, *space_p, format,
|
||||
table, ARRAY_SIZE(table));
|
||||
if (!space)
|
||||
if (len < *space_p)
|
||||
break;
|
||||
buf = xrealloc(buf, space);
|
||||
ALLOC_GROW(buf, len + 1, *space_p);
|
||||
*buf_p = buf;
|
||||
*space_p = space;
|
||||
} while (1);
|
||||
interp_clear_table(table, ARRAY_SIZE(table));
|
||||
|
||||
|
|
|
@ -44,9 +44,8 @@ void interp_clear_table(struct interp *table, int ninterps)
|
|||
* { "%%", "%"},
|
||||
* }
|
||||
*
|
||||
* Returns 0 on a successful substitution pass that fits in result,
|
||||
* Returns a number of bytes needed to hold the full substituted
|
||||
* string otherwise.
|
||||
* Returns the length of the substituted string (not including the final \0).
|
||||
* Like with snprintf, if the result is >= reslen, then it overflowed.
|
||||
*/
|
||||
|
||||
unsigned long interpolate(char *result, unsigned long reslen,
|
||||
|
@ -61,8 +60,6 @@ unsigned long interpolate(char *result, unsigned long reslen,
|
|||
int i;
|
||||
char c;
|
||||
|
||||
memset(result, 0, reslen);
|
||||
|
||||
while ((c = *src)) {
|
||||
if (c == '%') {
|
||||
/* Try to match an interpolation string. */
|
||||
|
@ -78,9 +75,9 @@ unsigned long interpolate(char *result, unsigned long reslen,
|
|||
value = interps[i].value;
|
||||
valuelen = strlen(value);
|
||||
|
||||
if (newlen + valuelen + 1 < reslen) {
|
||||
if (newlen + valuelen < reslen) {
|
||||
/* Substitute. */
|
||||
strncpy(dest, value, valuelen);
|
||||
memcpy(dest, value, valuelen);
|
||||
dest += valuelen;
|
||||
}
|
||||
newlen += valuelen;
|
||||
|
@ -95,8 +92,9 @@ unsigned long interpolate(char *result, unsigned long reslen,
|
|||
newlen++;
|
||||
}
|
||||
|
||||
if (newlen + 1 < reslen)
|
||||
return 0;
|
||||
else
|
||||
return newlen + 2;
|
||||
/* XXX: the previous loop always keep room for the ending NUL,
|
||||
we just need to check if there was room for a NUL in the first place */
|
||||
if (reslen > 0)
|
||||
*dest = '\0';
|
||||
return newlen;
|
||||
}
|
||||
|
|
Загрузка…
Ссылка в новой задаче