[Date Prev][Date Next] [Thread Prev][Thread Next] [Date Index] [Thread Index]

Bug#874798: libc6: mktime() does not set errno when it fails



Package: libc6
Version: 2.24-11+deb9u1
Severity: normal
Tags: upstream

When mktime() fails to convert a struct tm to a time_t, it returns -1.
It should also set errno to EOVERFLOW in order to distinguish the failure
from the legitimate case of converting "1 second before the epoch".

The following program, when run on a 32-bit system, shows that mktime
does not comply to the standard.  On recent amd64 systems, time_t is 64
bit long, therefore failure doesn't occur for the same broken down times.

Best regards,
	g.b.

#define _POSIX_C_SOURCE 200112L

#include <stdio.h>
#include <time.h>
#include <assert.h>
#include <errno.h>
#include <stdlib.h>

int main() {
    struct tm tm0;
    struct tm *ptm;
    time_t t;
    int eno;

    assert(sizeof t == 4);	/* need 32 bit to trigger failure in 1900 */

    /* nail timezone to UTC */
    setenv("TZ", "UTC", 1);
    tzset();

    t = -1;			/* 1 sec before epoch */
    ptm = gmtime_r(&t, &tm0);
    assert(ptm != NULL);
    errno = 0;
    t = mktime(&tm0);
    eno = errno;
    printf("struct TM: %d-%d-%d %02d:%02d:%02d (dst=%d)\n", 1900 + tm0.tm_year,
	   1 + tm0.tm_mon, tm0.tm_mday, tm0.tm_hour, tm0.tm_min,
	   tm0.tm_sec, tm0.tm_isdst);
    printf("mktime(): retval %ld (expected -1), "
	   "errno %d (expected 0)\n", (long) t, eno);

    tm0.tm_year = 0;		/* warp to year 1900 */
    /* bad conversion for 32-bit time_t, should return -1 and set errno */
    errno = 0;
    t = mktime(&tm0);
    eno = errno;
    printf("struct TM: %d-%d-%d %02d:%02d:%02d (dst=%d)\n", 1900 + tm0.tm_year,
	   1 + tm0.tm_mon, tm0.tm_mday, tm0.tm_hour, tm0.tm_min,
	   tm0.tm_sec, tm0.tm_isdst);
    printf("mktime(): retval %ld (expected -1), "
	   "errno %d (expected EOVERFLOW=%d)\n", (long) t, eno, EOVERFLOW);
    return 0;
}


-- System Information:
Debian Release: 9.1
  APT prefers stable
  APT policy: (500, 'stable')
Architecture: i386 (i686)

Kernel: Linux 4.9.0-3-686 (SMP w/1 CPU core)
Locale: LANG=en_US.UTF-8, LC_CTYPE=en_US.UTF-8 (charmap=UTF-8), LANGUAGE=en_US.UTF-8 (charmap=UTF-8)
Shell: /bin/sh linked to /bin/dash
Init: sysvinit (via /sbin/init)

Versions of packages libc6 depends on:
ii  libgcc1  1:6.3.0-18

libc6 recommends no packages.

Versions of packages libc6 suggests:
ii  debconf [debconf-2.0]  1.5.61
pn  glibc-doc              <none>
ii  libc-l10n              2.24-11+deb9u1
ii  locales                2.24-11+deb9u1

-- debconf information excluded


Reply to: