diff --git a/CHANGES.txt b/CHANGES.txt index c8116259e..0fbad591b 100644 --- a/CHANGES.txt +++ b/CHANGES.txt @@ -12,6 +12,10 @@ Since build 300: * Shifted work in win32.lib.pywin32_bootstrap to Python's import system from manual path manipulations (@wkschwartz in #1651) +* Fixed a bug where win32print.DeviceCapabilities would return strings + containing the null character followed by junk characters. + (#1654, #1660, Lincoln Puzey) + Since build 228: ---------------- * Fixed a bug where win32com.client.VARIANT params were returned in the reverse diff --git a/win32/src/win32print/win32print.cpp b/win32/src/win32print/win32print.cpp index f6e730563..55bafc0e8 100644 --- a/win32/src/win32print/win32print.cpp +++ b/win32/src/win32print/win32print.cpp @@ -1887,7 +1887,7 @@ static PyObject *PyDeviceCapabilities(PyObject *self, PyObject *args) static DWORD papernamesize = 64; // same for DC_PAPERNAMES, DC_MEDIATYPENAMES, DC_MEDIAREADY, DC_FILEDEPENDENCIES static DWORD binnamesize = 24; // DC_BINNAMES static DWORD personalitysize = 32; // DC_PERSONALITY - DWORD retsize; + DWORD retsize, actual_ret_size ; if (!PyArg_ParseTuple(args, "OOh|O:DeviceCapabilities", &obdevice, &obport, &capability, &obdevmode)) return NULL; @@ -2048,19 +2048,24 @@ static PyObject *PyDeviceCapabilities(PyObject *self, PyObject *args) PyErr_Format(PyExc_MemoryError, "DeviceCapabilites: Unable to allocate %d bytes", bufsize); break; } - ZeroMemory(buf, bufsize); result = DeviceCapabilities(device, port, capability, buf, pdevmode); + // each string in buf can be null-terminated or take up all space and have length retsize. + // bytes after null character can be set to junk by DeviceCapabilities(). if (result == -1) break; ret = PyTuple_New(result); if (ret == NULL) break; retname = (TCHAR *)buf; + // process each returned string for (bufindex = 0; bufindex < result; bufindex++) { - if (*(retname + retsize - 1) == 0) - tuple_item = PyWinObject_FromTCHAR(retname); - else // won't be null-terminated if string occupies entire space - tuple_item = PyWinObject_FromTCHAR(retname, retsize); + // work out actual length of returned string + for (actual_ret_size = 0; actual_ret_size < retsize; actual_ret_size++) { + if (*(retname + actual_ret_size) == 0) { + break; + } + } + tuple_item = PyWinObject_FromTCHAR(retname, actual_ret_size); if (tuple_item == NULL) { Py_DECREF(ret); ret = NULL;