mirror of
https://github.com/git/git.git
synced 2026-03-13 18:33:25 +01:00
On Windows, if the native vsnprintf() fills the buffer, it does not add
the terminating NUL. The earlier commit f32edf6b tried to fix the
emulation, but the fix worked only if the formatted string fitted into
the buffer exactly. However, there are callers that do not try to resize
the buffer if it overflows, and in these cases the resulting string
remained without the trailing NUL. This patch adds the NUL in all cases.
Signed-off-by: Johannes Sixt <johannes.sixt@telecom.at>
54 lines
1.0 KiB
C
54 lines
1.0 KiB
C
#include "../git-compat-util.h"
|
|
|
|
/*
|
|
* The size parameter specifies the available space, i.e. includes
|
|
* the trailing NUL byte; but Windows's vsnprintf expects the
|
|
* number of characters to write without the trailing NUL.
|
|
*/
|
|
#ifndef SNPRINTF_SIZE_CORR
|
|
#define SNPRINTF_SIZE_CORR 0
|
|
#endif
|
|
|
|
#undef vsnprintf
|
|
int git_vsnprintf(char *str, size_t maxsize, const char *format, va_list ap)
|
|
{
|
|
char *s;
|
|
int ret = -1;
|
|
|
|
if (maxsize > 0) {
|
|
ret = vsnprintf(str, maxsize-SNPRINTF_SIZE_CORR, format, ap);
|
|
/* Windows does not NUL-terminate if result fills buffer */
|
|
str[maxsize-1] = 0;
|
|
}
|
|
if (ret != -1)
|
|
return ret;
|
|
|
|
s = NULL;
|
|
if (maxsize < 128)
|
|
maxsize = 128;
|
|
|
|
while (ret == -1) {
|
|
maxsize *= 4;
|
|
str = realloc(s, maxsize);
|
|
if (! str)
|
|
break;
|
|
s = str;
|
|
ret = vsnprintf(str, maxsize-SNPRINTF_SIZE_CORR, format, ap);
|
|
}
|
|
free(s);
|
|
return ret;
|
|
}
|
|
|
|
int git_snprintf(char *str, size_t maxsize, const char *format, ...)
|
|
{
|
|
va_list ap;
|
|
int ret;
|
|
|
|
va_start(ap, format);
|
|
ret = git_vsnprintf(str, maxsize, format, ap);
|
|
va_end(ap);
|
|
|
|
return ret;
|
|
}
|
|
|