static PyObject * time_asctime(PyObject *self, PyObject *args) { PyObject *tup = NULL; struct tm buf; if (!PyArg_UnpackTuple(args, "asctime", 0, 1, &tup)) return NULL; if (tup == NULL) { time_t tt = time(NULL); buf = *localtime(&tt); } else if (!gettmarg(tup, &buf) || !checktm(&buf)) return NULL; return _asctime(&buf); }
static PyObject * time_mktime(PyObject *self, PyObject *tup) { struct tm buf; time_t tt; if (!gettmarg(tup, &buf)) return NULL; tt = mktime(&buf); if (tt == (time_t)(-1)) { PyErr_SetString(PyExc_OverflowError, "mktime argument out of range"); return NULL; } return PyFloat_FromDouble((double)tt); }
static PyObject * time_strftime(PyObject *self, PyObject *args) { PyObject *tup = NULL; struct tm buf; const char *fmt; size_t fmtlen, buflen; char *outbuf = 0; size_t i; memset((void *) &buf, '\0', sizeof(buf)); if (!PyArg_ParseTuple(args, "s|O:strftime", &fmt, &tup)) return NULL; if (tup == NULL) { time_t tt = time(NULL); buf = *localtime(&tt); } else if (!gettmarg(tup, &buf)) return NULL; fmtlen = strlen(fmt); /* I hate these functions that presume you know how big the output * will be ahead of time... */ for (i = 1024; ; i += i) { outbuf = malloc(i); if (outbuf == NULL) { return PyErr_NoMemory(); } buflen = strftime(outbuf, i, fmt, &buf); if (buflen > 0 || i >= 256 * fmtlen) { /* If the buffer is 256 times as long as the format, it's probably not failing for lack of room! More likely, the format yields an empty result, e.g. an empty format, or %Z when the timezone is unknown. */ PyObject *ret; ret = PyString_FromStringAndSize(outbuf, buflen); free(outbuf); return ret; } free(outbuf); } }
static PyObject * time_asctime(PyObject *self, PyObject *args) { PyObject *tup = NULL; struct tm buf; char *p; if (!PyArg_UnpackTuple(args, "asctime", 0, 1, &tup)) return NULL; if (tup == NULL) { time_t tt = time(NULL); buf = *localtime(&tt); } else if (!gettmarg(tup, &buf)) return NULL; p = asctime(&buf); if (p[24] == '\n') p[24] = '\0'; return PyString_FromString(p); }
static PyObject * time_mktime(PyObject *self, PyObject *tup) { struct tm buf; time_t tt; if (!gettmarg(tup, &buf)) return NULL; buf.tm_wday = -1; /* sentinel; original value ignored */ tt = mktime(&buf); /* Return value of -1 does not necessarily mean an error, but tm_wday * cannot remain set to -1 if mktime succedded. */ if (tt == (time_t)(-1) && buf.tm_wday == -1) { PyErr_SetString(PyExc_OverflowError, "mktime argument out of range"); return NULL; } return PyFloat_FromDouble((double)tt); }
static PyObject * time_mktime(PyObject *self, PyObject *args) { PyObject *tup; struct tm buf; time_t tt; if (!PyArg_ParseTuple(args, "O:mktime", &tup)) return NULL; tt = time(&tt); buf = *localtime(&tt); if (!gettmarg(tup, &buf)) return NULL; tt = mktime(&buf); if (tt == (time_t)(-1)) { PyErr_SetString(PyExc_OverflowError, "mktime argument out of range"); return NULL; } return PyFloat_FromDouble((double)tt); }
static PyObject * time_mktime(PyObject *self, PyObject *tup) { struct tm buf; time_t tt; if (!gettmarg(tup, &buf)) return NULL; #ifdef _AIX /* year < 1902 or year > 2037 */ if (buf.tm_year < 2 || buf.tm_year > 137) { /* Issue #19748: On AIX, mktime() doesn't report overflow error for * timestamp < -2^31 or timestamp > 2**31-1. */ PyErr_SetString(PyExc_OverflowError, "mktime argument out of range"); return NULL; } #else buf.tm_wday = -1; /* sentinel; original value ignored */ #endif tt = mktime(&buf); /* Return value of -1 does not necessarily mean an error, but tm_wday * cannot remain set to -1 if mktime succeeded. */ if (tt == (time_t)(-1) #ifndef _AIX /* Return value of -1 does not necessarily mean an error, but * tm_wday cannot remain set to -1 if mktime succeeded. */ && buf.tm_wday == -1 #else /* on AIX, tm_wday is always sets, even on error */ #endif ) { PyErr_SetString(PyExc_OverflowError, "mktime argument out of range"); return NULL; } return PyFloat_FromDouble((double)tt); }
static PyObject * time_strftime(PyObject *self, PyObject *args) { PyObject *tup = NULL; struct tm buf; const time_char *fmt; #ifdef HAVE_WCSFTIME wchar_t *format; #else PyObject *format; #endif PyObject *format_arg; size_t fmtlen, buflen; time_char *outbuf = NULL; size_t i; PyObject *ret = NULL; memset((void *) &buf, '\0', sizeof(buf)); /* Will always expect a unicode string to be passed as format. Given that there's no str type anymore in py3k this seems safe. */ if (!PyArg_ParseTuple(args, "U|O:strftime", &format_arg, &tup)) return NULL; if (tup == NULL) { time_t tt = time(NULL); if (pylocaltime(&tt, &buf) == -1) return NULL; } else if (!gettmarg(tup, &buf) || !checktm(&buf)) return NULL; #if defined(_MSC_VER) || defined(sun) || defined(_AIX) if (buf.tm_year + 1900 < 1 || 9999 < buf.tm_year + 1900) { PyErr_SetString(PyExc_ValueError, "strftime() requires year in [1; 9999]"); return NULL; } #endif /* Normalize tm_isdst just in case someone foolishly implements %Z based on the assumption that tm_isdst falls within the range of [-1, 1] */ if (buf.tm_isdst < -1) buf.tm_isdst = -1; else if (buf.tm_isdst > 1) buf.tm_isdst = 1; #ifdef HAVE_WCSFTIME format = PyUnicode_AsWideCharString(format_arg, NULL); if (format == NULL) return NULL; fmt = format; #else /* Convert the unicode string to an ascii one */ format = PyUnicode_EncodeLocale(format_arg, "surrogateescape"); if (format == NULL) return NULL; fmt = PyBytes_AS_STRING(format); #endif #if defined(MS_WINDOWS) && !defined(HAVE_WCSFTIME) /* check that the format string contains only valid directives */ for(outbuf = strchr(fmt, '%'); outbuf != NULL; outbuf = strchr(outbuf+2, '%')) { if (outbuf[1]=='#') ++outbuf; /* not documented by python, */ if (outbuf[1]=='\0' || !strchr("aAbBcdHIjmMpSUwWxXyYzZ%", outbuf[1])) { PyErr_SetString(PyExc_ValueError, "Invalid format string"); Py_DECREF(format); return NULL; } if ((outbuf[1] == 'y') && buf.tm_year < 0) { PyErr_SetString(PyExc_ValueError, "format %y requires year >= 1900 on Windows"); Py_DECREF(format); return NULL; } } #elif (defined(_AIX) || defined(sun)) && defined(HAVE_WCSFTIME) for(outbuf = wcschr(fmt, '%'); outbuf != NULL; outbuf = wcschr(outbuf+2, '%')) { if (outbuf[1] == L'\0') break; /* Issue #19634: On AIX, wcsftime("y", (1899, 1, 1, 0, 0, 0, 0, 0, 0)) returns "0/" instead of "99" */ if (outbuf[1] == L'y' && buf.tm_year < 0) { PyErr_SetString(PyExc_ValueError, "format %y requires year >= 1900 on AIX"); return NULL; } } #endif fmtlen = time_strlen(fmt); /* I hate these functions that presume you know how big the output * will be ahead of time... */ for (i = 1024; ; i += i) { #if defined _MSC_VER && _MSC_VER >= 1400 && defined(__STDC_SECURE_LIB__) int err; #endif outbuf = (time_char *)PyMem_Malloc(i*sizeof(time_char)); if (outbuf == NULL) { PyErr_NoMemory(); break; } buflen = format_time(outbuf, i, fmt, &buf); #if defined _MSC_VER && _MSC_VER >= 1400 && defined(__STDC_SECURE_LIB__) err = errno; #endif if (buflen > 0 || i >= 256 * fmtlen) { /* If the buffer is 256 times as long as the format, it's probably not failing for lack of room! More likely, the format yields an empty result, e.g. an empty format, or %Z when the timezone is unknown. */ #ifdef HAVE_WCSFTIME ret = PyUnicode_FromWideChar(outbuf, buflen); #else ret = PyUnicode_DecodeLocaleAndSize(outbuf, buflen, "surrogateescape"); #endif PyMem_Free(outbuf); break; } PyMem_Free(outbuf); #if defined _MSC_VER && _MSC_VER >= 1400 && defined(__STDC_SECURE_LIB__) /* VisualStudio .NET 2005 does this properly */ if (buflen == 0 && err == EINVAL) { PyErr_SetString(PyExc_ValueError, "Invalid format string"); break; } #endif } #ifdef HAVE_WCSFTIME PyMem_Free(format); #else Py_DECREF(format); #endif return ret; }
static PyObject * time_strftime(PyObject *self, PyObject *args) { PyObject *tup = NULL; struct tm buf; const char *fmt; size_t fmtlen, buflen; char *outbuf = 0; size_t i; memset((void *) &buf, '\0', sizeof(buf)); if (!PyArg_ParseTuple(args, "s|O:strftime", &fmt, &tup)) return NULL; if (tup == NULL) { time_t tt = time(NULL); buf = *localtime(&tt); } else if (!gettmarg(tup, &buf)) return NULL; /* Checks added to make sure strftime() does not crash Python by indexing blindly into some array for a textual representation by some bad index (fixes bug #897625). Also support values of zero from Python code for arguments in which that is out of range by forcing that value to the lowest value that is valid (fixed bug #1520914). Valid ranges based on what is allowed in struct tm: - tm_year: [0, max(int)] (1) - tm_mon: [0, 11] (2) - tm_mday: [1, 31] - tm_hour: [0, 23] - tm_min: [0, 59] - tm_sec: [0, 60] - tm_wday: [0, 6] (1) - tm_yday: [0, 365] (2) - tm_isdst: [-max(int), max(int)] (1) gettmarg() handles bounds-checking. (2) Python's acceptable range is one greater than the range in C, thus need to check against automatic decrement by gettmarg(). */ if (buf.tm_mon == -1) buf.tm_mon = 0; else if (buf.tm_mon < 0 || buf.tm_mon > 11) { PyErr_SetString(PyExc_ValueError, "month out of range"); return NULL; } if (buf.tm_mday == 0) buf.tm_mday = 1; else if (buf.tm_mday < 0 || buf.tm_mday > 31) { PyErr_SetString(PyExc_ValueError, "day of month out of range"); return NULL; } if (buf.tm_hour < 0 || buf.tm_hour > 23) { PyErr_SetString(PyExc_ValueError, "hour out of range"); return NULL; } if (buf.tm_min < 0 || buf.tm_min > 59) { PyErr_SetString(PyExc_ValueError, "minute out of range"); return NULL; } if (buf.tm_sec < 0 || buf.tm_sec > 61) { PyErr_SetString(PyExc_ValueError, "seconds out of range"); return NULL; } /* tm_wday does not need checking of its upper-bound since taking ``% 7`` in gettmarg() automatically restricts the range. */ if (buf.tm_wday < 0) { PyErr_SetString(PyExc_ValueError, "day of week out of range"); return NULL; } if (buf.tm_yday == -1) buf.tm_yday = 0; else if (buf.tm_yday < 0 || buf.tm_yday > 365) { PyErr_SetString(PyExc_ValueError, "day of year out of range"); return NULL; } if (buf.tm_isdst < -1 || buf.tm_isdst > 1) { PyErr_SetString(PyExc_ValueError, "daylight savings flag out of range"); return NULL; } fmtlen = strlen(fmt); /* I hate these functions that presume you know how big the output * will be ahead of time... */ for (i = 1024; ; i += i) { outbuf = (char *)malloc(i); if (outbuf == NULL) { return PyErr_NoMemory(); } buflen = strftime(outbuf, i, fmt, &buf); if (buflen > 0 || i >= 256 * fmtlen) { /* If the buffer is 256 times as long as the format, it's probably not failing for lack of room! More likely, the format yields an empty result, e.g. an empty format, or %Z when the timezone is unknown. */ PyObject *ret; ret = PyString_FromStringAndSize(outbuf, buflen); free(outbuf); return ret; } free(outbuf); #if defined _MSC_VER && _MSC_VER >= 1400 && defined(__STDC_SECURE_LIB__) /* VisualStudio .NET 2005 does this properly */ if (buflen == 0 && errno == EINVAL) { PyErr_SetString(PyExc_ValueError, "Invalid format string"); return 0; } #endif } }
static PyObject * winutil_strftime(PyObject *self, PyObject *args) { PyObject *tup = NULL; struct tm buf; const char *_fmt; size_t fmtlen, buflen; wchar_t *outbuf = NULL, *fmt = NULL; size_t i; memset((void *) &buf, '\0', sizeof(buf)); if (!PyArg_ParseTuple(args, "s|O:strftime", &_fmt, &tup)) return NULL; fmtlen = mbstowcs(NULL, _fmt, strlen(_fmt)); fmt = (wchar_t *)PyMem_Malloc((fmtlen+2)*sizeof(wchar_t)); if (fmt == NULL) return PyErr_NoMemory(); mbstowcs(fmt, _fmt, fmtlen+1); if (tup == NULL) { time_t tt = time(NULL); buf = *localtime(&tt); } else if (!gettmarg(tup, &buf)) goto end; if (buf.tm_mon == -1) buf.tm_mon = 0; else if (buf.tm_mon < 0 || buf.tm_mon > 11) { PyErr_SetString(PyExc_ValueError, "month out of range"); goto end; } if (buf.tm_mday == 0) buf.tm_mday = 1; else if (buf.tm_mday < 0 || buf.tm_mday > 31) { PyErr_SetString(PyExc_ValueError, "day of month out of range"); goto end; } if (buf.tm_hour < 0 || buf.tm_hour > 23) { PyErr_SetString(PyExc_ValueError, "hour out of range"); goto end; } if (buf.tm_min < 0 || buf.tm_min > 59) { PyErr_SetString(PyExc_ValueError, "minute out of range"); goto end; } if (buf.tm_sec < 0 || buf.tm_sec > 61) { PyErr_SetString(PyExc_ValueError, "seconds out of range"); goto end; } /* tm_wday does not need checking of its upper-bound since taking ``% 7`` in gettmarg() automatically restricts the range. */ if (buf.tm_wday < 0) { PyErr_SetString(PyExc_ValueError, "day of week out of range"); goto end; } if (buf.tm_yday == -1) buf.tm_yday = 0; else if (buf.tm_yday < 0 || buf.tm_yday > 365) { PyErr_SetString(PyExc_ValueError, "day of year out of range"); goto end; } if (buf.tm_isdst < -1 || buf.tm_isdst > 1) { PyErr_SetString(PyExc_ValueError, "daylight savings flag out of range"); goto end; } for (i = 5*fmtlen; ; i += i) { outbuf = (wchar_t *)PyMem_Malloc(i*sizeof(wchar_t)); if (outbuf == NULL) { PyErr_NoMemory(); goto end; } buflen = wcsftime(outbuf, i, fmt, &buf); if (buflen > 0 || i >= 256 * fmtlen) { /* If the buffer is 256 times as long as the format, it's probably not failing for lack of room! More likely, the format yields an empty result, e.g. an empty format, or %Z when the timezone is unknown. */ PyObject *ret; ret = PyUnicode_FromWideChar(outbuf, buflen); PyMem_Free(outbuf); PyMem_Free(fmt); return ret; } PyMem_Free(outbuf); #if defined _MSC_VER && _MSC_VER >= 1400 && defined(__STDC_SECURE_LIB__) /* VisualStudio .NET 2005 does this properly */ if (buflen == 0 && errno == EINVAL) { PyErr_SetString(PyExc_ValueError, "Invalid format string"); goto end; } #endif } end: PyMem_Free(fmt); return NULL; }
static PyObject * winutil_strftime(PyObject *self, PyObject *args) { PyObject *tup = NULL; struct tm buf; size_t buflen; wchar_t *outbuf = NULL; Py_UNICODE *fmt = NULL; int fmtlen; size_t i; memset((void *) &buf, 0, sizeof(buf)); if (!PyArg_ParseTuple(args, "u#|O:strftime", &fmt, &fmtlen, &tup)) return NULL; if (tup == NULL) { time_t tt = time(NULL); if(localtime_s(&buf, &tt) != 0) { PyErr_SetString(PyExc_ValueError, "Failed to get localtime()"); return NULL; } } else if (!gettmarg(tup, &buf)) return NULL; if (buf.tm_mon == -1) buf.tm_mon = 0; else if (buf.tm_mon < 0 || buf.tm_mon > 11) { PyErr_SetString(PyExc_ValueError, "month out of range"); return NULL; } if (buf.tm_mday == 0) buf.tm_mday = 1; else if (buf.tm_mday < 0 || buf.tm_mday > 31) { PyErr_SetString(PyExc_ValueError, "day of month out of range"); return NULL; } if (buf.tm_hour < 0 || buf.tm_hour > 23) { PyErr_SetString(PyExc_ValueError, "hour out of range"); return NULL; } if (buf.tm_min < 0 || buf.tm_min > 59) { PyErr_SetString(PyExc_ValueError, "minute out of range"); return NULL; } if (buf.tm_sec < 0 || buf.tm_sec > 61) { PyErr_SetString(PyExc_ValueError, "seconds out of range"); return NULL; } /* tm_wday does not need checking of its upper-bound since taking ``% 7`` in gettmarg() automatically restricts the range. */ if (buf.tm_wday < 0) { PyErr_SetString(PyExc_ValueError, "day of week out of range"); return NULL; } if (buf.tm_yday == -1) buf.tm_yday = 0; else if (buf.tm_yday < 0 || buf.tm_yday > 365) { PyErr_SetString(PyExc_ValueError, "day of year out of range"); return NULL; } if (buf.tm_isdst < -1 || buf.tm_isdst > 1) { PyErr_SetString(PyExc_ValueError, "daylight savings flag out of range"); return NULL; } for (i = 5*(unsigned int)fmtlen; ; i += i) { outbuf = (wchar_t *)PyMem_Malloc(i*sizeof(wchar_t)); if (outbuf == NULL) { PyErr_NoMemory(); return NULL; } buflen = wcsftime(outbuf, i, fmt, &buf); if (buflen > 0 || i >= 256 * (unsigned int)fmtlen) { /* If the buffer is 256 times as long as the format, it's probably not failing for lack of room! More likely, the format yields an empty result, e.g. an empty format, or %Z when the timezone is unknown. */ PyObject *ret; ret = PyUnicode_FromWideChar(outbuf, buflen); PyMem_Free(outbuf); return ret; } PyMem_Free(outbuf); /* VisualStudio .NET 2005 does this properly */ if (buflen == 0 && errno == EINVAL) { PyErr_SetString(PyExc_ValueError, "Invalid format string"); return NULL; } } return NULL; }