diff -r d31b4de433b7 Modules/_io/winconsoleio.c --- a/Modules/_io/winconsoleio.c Tue Sep 20 23:00:59 2016 +0200 +++ b/Modules/_io/winconsoleio.c Wed Sep 21 05:32:07 2016 +0000 @@ -513,12 +513,12 @@ DWORD n = 0; while (self->buf[0] && len--) { - n += 1; - buf[0] = self->buf[0]; + buf[n] = self->buf[0]; self->buf[0] = self->buf[1]; self->buf[1] = self->buf[2]; self->buf[2] = self->buf[3]; self->buf[3] = 0; + n += 1; } return n; @@ -786,53 +786,72 @@ PyMem_Free(subbuf); - /* when the read starts with ^Z or is empty we break */ - if (n == 0 || buf[len] == '\x1a') + /* when the read is empty we break */ + if (n == 0) break; len += n; } - if (len == 0 || buf[0] == '\x1a' && _buflen(self) == 0) { - /* when the result starts with ^Z we return an empty buffer */ + rn = _buflen(self); + + if (len == 0 && rn == 0) { + /* return an empty buffer */ PyMem_Free(buf); return PyBytes_FromStringAndSize(NULL, 0); } - Py_BEGIN_ALLOW_THREADS - bytes_size = WideCharToMultiByte(CP_UTF8, 0, buf, len, - NULL, 0, NULL, NULL); - Py_END_ALLOW_THREADS + if (len == 0) { + bytes_size = rn; + } else { + Py_BEGIN_ALLOW_THREADS + bytes_size = WideCharToMultiByte(CP_UTF8, 0, buf, len, + NULL, 0, NULL, NULL); + Py_END_ALLOW_THREADS - if (!bytes_size) { - DWORD err = GetLastError(); + if (!bytes_size) { + DWORD err = GetLastError(); + PyMem_Free(buf); + return PyErr_SetFromWindowsErr(err); + } + + bytes_size += rn; + } + + bytes = PyBytes_FromStringAndSize(NULL, bytes_size); + if (!bytes) { PyMem_Free(buf); - return PyErr_SetFromWindowsErr(err); + return NULL; } - bytes_size += _buflen(self); - bytes = PyBytes_FromStringAndSize(NULL, bytes_size); rn = _copyfrombuf(self, PyBytes_AS_STRING(bytes), bytes_size); - Py_BEGIN_ALLOW_THREADS - bytes_size = WideCharToMultiByte(CP_UTF8, 0, buf, len, - &PyBytes_AS_STRING(bytes)[rn], bytes_size - rn, NULL, NULL); - Py_END_ALLOW_THREADS + if (len == 0) { + bytes_size = rn; + } else { + Py_BEGIN_ALLOW_THREADS + bytes_size = WideCharToMultiByte(CP_UTF8, 0, buf, len, + &PyBytes_AS_STRING(bytes)[rn], bytes_size - rn, NULL, NULL); + Py_END_ALLOW_THREADS - if (!bytes_size) { - DWORD err = GetLastError(); - PyMem_Free(buf); - Py_CLEAR(bytes); - return PyErr_SetFromWindowsErr(err); + if (!bytes_size) { + DWORD err = GetLastError(); + PyMem_Free(buf); + Py_DECREF(bytes); + return PyErr_SetFromWindowsErr(err); + } + + bytes_size += rn; } PyMem_Free(buf); - if (bytes_size < (size_t)PyBytes_GET_SIZE(bytes)) { - if (_PyBytes_Resize(&bytes, n * sizeof(wchar_t)) < 0) { - Py_CLEAR(bytes); - return NULL; - } + + if (bytes_size < (size_t)PyBytes_GET_SIZE(bytes) && + _PyBytes_Resize(&bytes, bytes_size) < 0) { + Py_DECREF(bytes); + return NULL; } + return bytes; }