提交 4acfd1b7 编写于 作者: P Pierre Habouzit 提交者: Junio C Hamano

Change semantics of interpolate to work like snprintf.

  Also fix many off-by-ones and a useless memset.
Signed-off-by: NPierre Habouzit <madcoder@debian.org>
Signed-off-by: NJunio C Hamano <gitster@pobox.com>
上级 f1696ee3
......@@ -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;
}
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册