Browse Source

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>
maint
Pierre Habouzit 18 years ago committed by Junio C Hamano
parent
commit
4acfd1b799
  1. 9
      commit.c
  2. 20
      interpolate.c

9
commit.c

@ -923,15 +923,14 @@ long format_commit_message(const struct commit *commit, const void *format, @@ -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));


20
interpolate.c

@ -44,9 +44,8 @@ void interp_clear_table(struct interp *table, int ninterps) @@ -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, @@ -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, @@ -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, @@ -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;
}

Loading…
Cancel
Save