diff options
author | Pierre Habouzit <madcoder@debian.org> | 2007-09-10 12:35:05 +0200 |
---|---|---|
committer | Junio C Hamano <gitster@pobox.com> | 2007-09-10 12:48:33 -0700 |
commit | 4acfd1b799acf43642a28a22cc794266c25129ef (patch) | |
tree | ce3f9ee6de2a335e06d600b459c5679710a80f84 /interpolate.c | |
parent | f1696ee398e92bcea3cdc7b3da85d8e0f77f6c50 (diff) | |
download | git-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.c | 20 |
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; } |