FazBrowse GitHub Viewer | Trending |
URL:
| Home
Tools: [Download Repo ZIP]   [Original HTTPS Page]

gh-72660: Handle unsigned long win32 error codes by ameily · Pull Request #27959 · python/cpython · GitHub

/ cpython Public
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension .c  (2) .py  (3) .rst  (1) All 3 file types selected
Viewed files
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Unified
Split
Hide whitespace
Diff view
Unified
Split
Hide whitespace
4 changes: 3 additions & 1 deletion Lib/ctypes/__init__.py
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode characters
Original file line number Diff line number Diff line change
Expand Up @@ -481,7 +481,9 @@ def LoadLibrary(self, name):

def WinError(code=None, descr=None):
if code is None:
code = GetLastError()
# GetLastError returns a DWORD, cast large error codes
# to unsigned
code = GetLastError() & 0xffffffff
if descr is None:
descr = FormatError(code).strip()
return OSError(None, descr, None, code)
Expand Down
20 changes: 20 additions & 0 deletions Lib/test/test_ctypes/test_win32.py
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode characters
Original file line number Diff line number Diff line change
Expand Up @@ -90,6 +90,26 @@ def test_winerror(self):
self.assertEqual(e.errno, errno.EINVAL)
self.assertEqual(e.winerror, ERROR_INVALID_PARAMETER)

def test_winerror_dword(self):
# see Issue 28474
E_POINTER = 0x80000005
msg = FormatError(E_POINTER).strip()
args = (E_POINTER, msg, None, E_POINTER)

e = WinError(E_POINTER)
self.assertEqual(e.args, args)
self.assertEqual(e.errno, E_POINTER)
self.assertEqual(e.winerror, E_POINTER)

windll.kernel32.SetLastError(E_POINTER)
try:
raise WinError()
except OSError as exc:
e = exc
self.assertEqual(e.args, args)
self.assertEqual(e.errno, E_POINTER)
self.assertEqual(e.winerror, E_POINTER)

class Structures(unittest.TestCase):
def test_struct_by_value(self):
class POINT(Structure):
Expand Down
8 changes: 8 additions & 0 deletions Lib/test/test_exceptions.py
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode characters
Original file line number Diff line number Diff line change
Expand Up @@ -402,6 +402,14 @@ def test_WindowsError(self):
self.assertEqual(w.strerror, 'foo')
self.assertEqual(w.filename, None)
self.assertEqual(w.filename2, None)
# DWORD error code (issue #28474)
E_POINTER = 0x80000005
w = OSError(E_POINTER, 'foo', 'bar', E_POINTER)
self.assertEqual(w.errno, E_POINTER)
self.assertEqual(w.winerror, E_POINTER)
self.assertEqual(w.strerror, 'foo')
self.assertEqual(w.filename, 'bar')
self.assertEqual(w.filename2, None)

@unittest.skipUnless(sys.platform == 'win32',
'test specific to Windows')
Expand Down
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode characters
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
Improve handling and reporting of unsigned win32 error codes.
Patch by Adam Meily.
13 changes: 10 additions & 3 deletions Modules/_ctypes/callproc.c
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode characters
Original file line number Diff line number Diff line change
Expand Up @@ -1334,12 +1334,19 @@ static PyObject *format_error(PyObject *self, PyObject *args)
{
PyObject *result;
wchar_t *lpMsgBuf;
DWORD code = 0;
if (!PyArg_ParseTuple(args, "|i:FormatError", &code))
long long code = 0;

if (!PyArg_ParseTuple(args, "|L:FormatError", &code))
return NULL;

if((DWORD)code != code) {
PyErr_Format(PyExc_OverflowError, "error code %lld too big for int", code);
return NULL;
}

if (code == 0)
code = GetLastError();
lpMsgBuf = FormatError(code);
lpMsgBuf = FormatError((DWORD)code);
if (lpMsgBuf) {
result = PyUnicode_FromWideChar(lpMsgBuf, wcslen(lpMsgBuf));
LocalFree(lpMsgBuf);
Expand Down
14 changes: 10 additions & 4 deletions Objects/exceptions.c
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode characters
Original file line number Diff line number Diff line change
Expand Up @@ -1700,15 +1700,21 @@ oserror_parse_args(PyObject **p_args,
return -1;
#ifdef MS_WINDOWS
if (*winerror && PyLong_Check(*winerror)) {
long errcode, winerrcode;
long long errcode, winerrcode;
PyObject *newargs;
Py_ssize_t i;

winerrcode = PyLong_AsLong(*winerror);
winerrcode = PyLong_AsLongLong(*winerror);
if (winerrcode == -1 && PyErr_Occurred())
return -1;
errcode = winerror_to_errno(winerrcode);
*myerrno = PyLong_FromLong(errcode);

if(winerrcode < LONG_MIN || winerrcode > ULONG_MAX) {
Comment thread
zooba marked this conversation as resolved.
Outdated
PyErr_Format(PyExc_OverflowError, "error code %lld too big for int", winerrcode);
return -1;
}

errcode = (long long)winerror_to_errno((int)winerrcode);
*myerrno = PyLong_FromLongLong(errcode);
if (!*myerrno)
return -1;
newargs = PyTuple_New(nargs);
Expand Down

Back | FazBrowse Home | New Git URL