diff --git a/Modules/posixmodule.c b/Modules/posixmodule.c --- a/Modules/posixmodule.c +++ b/Modules/posixmodule.c @@ -6622,12 +6622,24 @@ posix_confstr(PyObject *self, PyObject * PyObject *result = NULL; int name; char buffer[256]; + char *allocated = NULL; if (PyArg_ParseTuple(args, "O&:confstr", conv_confstr_confname, &name)) { - int len; + char *recvbuf = buffer; + size_t len, buflen = sizeof(buffer); errno = 0; - len = confstr(name, buffer, sizeof(buffer)); + while ((len = confstr(name, recvbuf, buflen)) > buflen) { + recvbuf = PyMem_Realloc(allocated, len); + if (recvbuf == NULL) { + PyErr_NoMemory(); + goto finally; + } + allocated = recvbuf; + buflen = len; + errno = 0; + } + if (len == 0) { if (errno) { posix_error(); @@ -6638,15 +6650,11 @@ posix_confstr(PyObject *self, PyObject * } } else { - if ((unsigned int)len >= sizeof(buffer)) { - result = PyUnicode_FromStringAndSize(NULL, len-1); - if (result != NULL) - confstr(name, _PyUnicode_AsString(result), len); - } - else - result = PyUnicode_FromStringAndSize(buffer, len-1); + result = PyUnicode_FromStringAndSize(recvbuf, len - 1); } } +finally: + PyMem_Free(allocated); return result; } #endif