Skip to content

Commit

Permalink
Fixed win32print.DeviceCapabilities() returning strings with junk in …
Browse files Browse the repository at this point in the history
…them.

Previously this code would ZeroMemory() the output buffer before passing it to DeviceCapabilities(),
and then assume that only characters in each string would be changed, i.e. the characters following
the null-terminator would remain null.
So it would only check if the last character in each string was null, to check if the string was null-terminated.

This assumption is wrong - sometimes DeviceCapabilities() sets the characters after null to junk.

Now every character in the returned buffer is checked for being null before falling back to the case where the
string takes up all available space.

#1654
  • Loading branch information
LincolnPuzey committed Feb 1, 2021
1 parent f3f55ab commit e858c8a
Show file tree
Hide file tree
Showing 2 changed files with 15 additions and 6 deletions.
4 changes: 4 additions & 0 deletions CHANGES.txt
Expand Up @@ -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
Expand Down
17 changes: 11 additions & 6 deletions win32/src/win32print/win32print.cpp
Expand Up @@ -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;
Expand Down Expand Up @@ -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;
Expand Down

0 comments on commit e858c8a

Please sign in to comment.