summaryrefslogtreecommitdiff
path: root/interpolate.c
diff options
context:
space:
mode:
authorPierre Habouzit <madcoder@debian.org>2007-09-10 12:35:05 +0200
committerJunio C Hamano <gitster@pobox.com>2007-09-10 12:48:33 -0700
commit4acfd1b799acf43642a28a22cc794266c25129ef (patch)
treece3f9ee6de2a335e06d600b459c5679710a80f84 /interpolate.c
parentf1696ee398e92bcea3cdc7b3da85d8e0f77f6c50 (diff)
downloadgit-4acfd1b799acf43642a28a22cc794266c25129ef.tar.gz
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>
Diffstat (limited to 'interpolate.c')
-rw-r--r--interpolate.c20
1 files changed, 9 insertions, 11 deletions
diff --git a/interpolate.c b/interpolate.c
index 00826778fc..3de583238d 100644
--- a/interpolate.c
+++ b/interpolate.c
@@ -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;
}