Issue #9979: Use PyUnicode_AsWideCharString() in time.strftime()
Allocate memory with PyMem_Alloc() instead of the PyBytes API. Prepare the surrogates support.
This commit is contained in:
parent
449057f2fa
commit
b29047876d
|
@ -394,10 +394,15 @@ time_strftime(PyObject *self, PyObject *args)
|
||||||
PyObject *tup = NULL;
|
PyObject *tup = NULL;
|
||||||
struct tm buf;
|
struct tm buf;
|
||||||
const time_char *fmt;
|
const time_char *fmt;
|
||||||
PyObject *format, *tmpfmt;
|
#ifdef HAVE_WCSFTIME
|
||||||
|
wchar_t *format;
|
||||||
|
#else
|
||||||
|
PyObject *format;
|
||||||
|
#endif
|
||||||
size_t fmtlen, buflen;
|
size_t fmtlen, buflen;
|
||||||
time_char *outbuf = 0;
|
time_char *outbuf = NULL;
|
||||||
size_t i;
|
size_t i;
|
||||||
|
PyObject *ret = NULL;
|
||||||
|
|
||||||
memset((void *) &buf, '\0', sizeof(buf));
|
memset((void *) &buf, '\0', sizeof(buf));
|
||||||
|
|
||||||
|
@ -482,19 +487,10 @@ time_strftime(PyObject *self, PyObject *args)
|
||||||
buf.tm_isdst = 1;
|
buf.tm_isdst = 1;
|
||||||
|
|
||||||
#ifdef HAVE_WCSFTIME
|
#ifdef HAVE_WCSFTIME
|
||||||
tmpfmt = PyBytes_FromStringAndSize(NULL,
|
format = PyUnicode_AsWideCharString((PyUnicodeObject*)format, NULL);
|
||||||
sizeof(wchar_t) * (PyUnicode_GetSize(format)+1));
|
if (format == NULL)
|
||||||
if (!tmpfmt)
|
|
||||||
return NULL;
|
return NULL;
|
||||||
/* This assumes that PyUnicode_AsWideChar doesn't do any UTF-16
|
fmt = format;
|
||||||
expansion. */
|
|
||||||
if (PyUnicode_AsWideChar((PyUnicodeObject*)format,
|
|
||||||
(wchar_t*)PyBytes_AS_STRING(tmpfmt),
|
|
||||||
PyUnicode_GetSize(format)+1) == (size_t)-1)
|
|
||||||
/* This shouldn't fail. */
|
|
||||||
Py_FatalError("PyUnicode_AsWideChar failed");
|
|
||||||
format = tmpfmt;
|
|
||||||
fmt = (wchar_t*)PyBytes_AS_STRING(format);
|
|
||||||
#else
|
#else
|
||||||
/* Convert the unicode string to an ascii one */
|
/* Convert the unicode string to an ascii one */
|
||||||
format = PyUnicode_AsEncodedString(format, TZNAME_ENCODING, NULL);
|
format = PyUnicode_AsEncodedString(format, TZNAME_ENCODING, NULL);
|
||||||
|
@ -528,8 +524,8 @@ time_strftime(PyObject *self, PyObject *args)
|
||||||
for (i = 1024; ; i += i) {
|
for (i = 1024; ; i += i) {
|
||||||
outbuf = (time_char *)PyMem_Malloc(i*sizeof(time_char));
|
outbuf = (time_char *)PyMem_Malloc(i*sizeof(time_char));
|
||||||
if (outbuf == NULL) {
|
if (outbuf == NULL) {
|
||||||
Py_DECREF(format);
|
PyErr_NoMemory();
|
||||||
return PyErr_NoMemory();
|
break;
|
||||||
}
|
}
|
||||||
buflen = format_time(outbuf, i, fmt, &buf);
|
buflen = format_time(outbuf, i, fmt, &buf);
|
||||||
if (buflen > 0 || i >= 256 * fmtlen) {
|
if (buflen > 0 || i >= 256 * fmtlen) {
|
||||||
|
@ -538,7 +534,6 @@ time_strftime(PyObject *self, PyObject *args)
|
||||||
More likely, the format yields an empty result,
|
More likely, the format yields an empty result,
|
||||||
e.g. an empty format, or %Z when the timezone
|
e.g. an empty format, or %Z when the timezone
|
||||||
is unknown. */
|
is unknown. */
|
||||||
PyObject *ret;
|
|
||||||
#ifdef HAVE_WCSFTIME
|
#ifdef HAVE_WCSFTIME
|
||||||
ret = PyUnicode_FromWideChar(outbuf, buflen);
|
ret = PyUnicode_FromWideChar(outbuf, buflen);
|
||||||
#else
|
#else
|
||||||
|
@ -546,19 +541,23 @@ time_strftime(PyObject *self, PyObject *args)
|
||||||
TZNAME_ENCODING, NULL);
|
TZNAME_ENCODING, NULL);
|
||||||
#endif
|
#endif
|
||||||
PyMem_Free(outbuf);
|
PyMem_Free(outbuf);
|
||||||
Py_DECREF(format);
|
break;
|
||||||
return ret;
|
|
||||||
}
|
}
|
||||||
PyMem_Free(outbuf);
|
PyMem_Free(outbuf);
|
||||||
#if defined _MSC_VER && _MSC_VER >= 1400 && defined(__STDC_SECURE_LIB__)
|
#if defined _MSC_VER && _MSC_VER >= 1400 && defined(__STDC_SECURE_LIB__)
|
||||||
/* VisualStudio .NET 2005 does this properly */
|
/* VisualStudio .NET 2005 does this properly */
|
||||||
if (buflen == 0 && errno == EINVAL) {
|
if (buflen == 0 && errno == EINVAL) {
|
||||||
PyErr_SetString(PyExc_ValueError, "Invalid format string");
|
PyErr_SetString(PyExc_ValueError, "Invalid format string");
|
||||||
Py_DECREF(format);
|
break;
|
||||||
return 0;
|
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
#ifdef HAVE_WCSFTIME
|
||||||
|
PyMem_Free(format);
|
||||||
|
#else
|
||||||
|
Py_DECREF(format);
|
||||||
|
#endif
|
||||||
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
#undef time_char
|
#undef time_char
|
||||||
|
|
Loading…
Reference in New Issue