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..301eca940 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, retsize_index; if (!PyArg_ParseTuple(args, "OOh|O:DeviceCapabilities", &obdevice, &obport, &capability, &obdevmode)) return NULL; @@ -2048,19 +2048,33 @@ 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) + // check if returned string contains null character + bool contains_null = false; + for (retsize_index = 0; retsize_index < retsize; retsize_index++) { + if (*(retname + retsize_index) == 0) { + contains_null = true; + break; + } + } + if (contains_null) { + // string will be automatically terminated at null character. tuple_item = PyWinObject_FromTCHAR(retname); - else // won't be null-terminated if string occupies entire space + } + else { + // specify string length. tuple_item = PyWinObject_FromTCHAR(retname, retsize); + } if (tuple_item == NULL) { Py_DECREF(ret); ret = NULL;