Skip to content

Commit 97d3126

Browse files
committed
mingw: abort on invalid strftime formats
On Windows, strftime() does not silently ignore invalid formats, but warns about them and then returns 0 and sets errno to EINVAL. Unfortunately, Git does not expect such a behavior, as it disagrees with strftime()'s semantics on Linux. As a consequence, Git misinterprets the return value 0 as "I need more space" and grows the buffer. As the larger buffer does not fix the format, the buffer grows and grows and grows until we are out of memory and abort. Ideally, we would switch off the parameter validation just for strftime(), but we cannot even override the invalid parameter handler via _set_thread_local_invalid_parameter_handler() using MINGW because that function is not declared. Even _set_invalid_parameter_handler(), which *is* declared, does not help, as it simply does... nothing. So let's just bite the bullet and override strftime() for MINGW and abort on an invalid format string. While this does not provide the best user experience, it is the best we can do. See https://msdn.microsoft.com/en-us/library/fe06s4ak.aspx for more details. This fixes #863 Signed-off-by: Johannes Schindelin <[email protected]>
1 parent af8e259 commit 97d3126

File tree

2 files changed

+14
-0
lines changed

2 files changed

+14
-0
lines changed

compat/mingw.c

+11
Original file line numberDiff line numberDiff line change
@@ -761,6 +761,17 @@ int mingw_utime (const char *file_name, const struct utimbuf *times)
761761
return rc;
762762
}
763763

764+
#undef strftime
765+
size_t mingw_strftime(char *s, size_t max,
766+
const char *format, const struct tm *tm)
767+
{
768+
size_t ret = strftime(s, max, format, tm);
769+
770+
if (!ret && errno == EINVAL)
771+
die("invalid strftime format: '%s'", format);
772+
return ret;
773+
}
774+
764775
unsigned int sleep (unsigned int seconds)
765776
{
766777
Sleep(seconds*1000);

compat/mingw.h

+3
Original file line numberDiff line numberDiff line change
@@ -361,6 +361,9 @@ int mingw_fstat(int fd, struct stat *buf);
361361

362362
int mingw_utime(const char *file_name, const struct utimbuf *times);
363363
#define utime mingw_utime
364+
size_t mingw_strftime(char *s, size_t max,
365+
const char *format, const struct tm *tm);
366+
#define strftime mingw_strftime
364367

365368
pid_t mingw_spawnvpe(const char *cmd, const char **argv, char **env,
366369
const char *dir,

0 commit comments

Comments
 (0)