diff options
-rw-r--r-- | Makefile | 8 | ||||
-rw-r--r-- | compat/gmtime.c | 29 | ||||
-rw-r--r-- | config.mak.uname | 1 | ||||
-rw-r--r-- | git-compat-util.h | 7 | ||||
-rwxr-xr-x | t/t4212-log-corrupt.sh | 6 |
5 files changed, 47 insertions, 4 deletions
@@ -342,6 +342,9 @@ all:: # Define DEFAULT_HELP_FORMAT to "man", "info" or "html" # (defaults to "man") if you want to have a different default when # "git help" is called without a parameter specifying the format. +# +# Define GMTIME_UNRELIABLE_ERRORS if your gmtime() function does not +# return NULL when it receives a bogus time_t. GIT-VERSION-FILE: FORCE @$(SHELL_PATH) ./GIT-VERSION-GEN @@ -1494,6 +1497,11 @@ ifneq (,$(XDL_FAST_HASH)) BASIC_CFLAGS += -DXDL_FAST_HASH endif +ifdef GMTIME_UNRELIABLE_ERRORS + COMPAT_OBJS += compat/gmtime.o + BASIC_CFLAGS += -DGMTIME_UNRELIABLE_ERRORS +endif + ifeq ($(TCLTK_PATH),) NO_TCLTK = NoThanks endif diff --git a/compat/gmtime.c b/compat/gmtime.c new file mode 100644 index 000000000..e8362dd2b --- /dev/null +++ b/compat/gmtime.c @@ -0,0 +1,29 @@ +#include "../git-compat-util.h" +#undef gmtime +#undef gmtime_r + +struct tm *git_gmtime(const time_t *timep) +{ + static struct tm result; + return git_gmtime_r(timep, &result); +} + +struct tm *git_gmtime_r(const time_t *timep, struct tm *result) +{ + struct tm *ret; + + memset(result, 0, sizeof(*result)); + ret = gmtime_r(timep, result); + + /* + * Rather than NULL, FreeBSD gmtime simply leaves the "struct tm" + * untouched when it encounters overflow. Since "mday" cannot otherwise + * be zero, we can test this very quickly. + */ + if (ret && !ret->tm_mday) { + ret = NULL; + errno = EOVERFLOW; + } + + return ret; +} diff --git a/config.mak.uname b/config.mak.uname index 7d31fad24..efaed94d5 100644 --- a/config.mak.uname +++ b/config.mak.uname @@ -188,6 +188,7 @@ ifeq ($(uname_S),FreeBSD) endif PYTHON_PATH = /usr/local/bin/python HAVE_PATHS_H = YesPlease + GMTIME_UNRELIABLE_ERRORS = UnfortunatelyYes endif ifeq ($(uname_S),OpenBSD) NO_STRCASESTR = YesPlease diff --git a/git-compat-util.h b/git-compat-util.h index cbd86c37f..d493a8c67 100644 --- a/git-compat-util.h +++ b/git-compat-util.h @@ -721,4 +721,11 @@ void warn_on_inaccessible(const char *path); /* Get the passwd entry for the UID of the current process. */ struct passwd *xgetpwuid_self(void); +#ifdef GMTIME_UNRELIABLE_ERRORS +struct tm *git_gmtime(const time_t *); +struct tm *git_gmtime_r(const time_t *, struct tm *); +#define gmtime git_gmtime +#define gmtime_r git_gmtime_r +#endif + #endif diff --git a/t/t4212-log-corrupt.sh b/t/t4212-log-corrupt.sh index 3fa171541..58b792bf2 100755 --- a/t/t4212-log-corrupt.sh +++ b/t/t4212-log-corrupt.sh @@ -82,11 +82,9 @@ test_expect_success 'date parser recognizes time_t overflow' ' ' # date is within 2^63-1, but enough to choke glibc's gmtime -test_expect_success 'absurdly far-in-future dates produce sentinel' ' +test_expect_success 'absurdly far-in-future date' ' commit=$(munge_author_date HEAD 999999999999999999) && - echo "Thu Jan 1 00:00:00 1970 +0000" >expect && - git log -1 --format=%ad $commit >actual && - test_cmp expect actual + git log -1 --format=%ad $commit ' test_done |