-
-
Notifications
You must be signed in to change notification settings - Fork 30.9k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
WinError(): Python int too large to convert to C long #72660
Comments
// callproc.c
static PyObject *format_error(PyObject *self, PyObject *args)
{
PyObject *result;
wchar_t *lpMsgBuf;
DWORD code = 0;
if (!PyArg_ParseTuple(args, "|i:FormatError", &code))
^ Here the format string should be "|I:FormatError"
return NULL;
if (code == 0)
code = GetLastError();
lpMsgBuf = FormatError(code);
if (lpMsgBuf) {
result = PyUnicode_FromWideChar(lpMsgBuf, wcslen(lpMsgBuf));
LocalFree(lpMsgBuf);
} else {
result = PyUnicode_FromString("<no description>");
}
return result;
} |
You can't use I as a format code safely; it silently ignores/wraps overflow on the conversion, where i raises on overflow. The unsigned converters are basically useless for resilient code in 99% of cases. I *think* I remember some private utility functions for doing this using O& though, not sure if they're available in callproc.c... |
I report this issue because the function WlanScan(https://msdn.microsoft.com/zh-cn/library/windows/desktop/ms706783(v=vs.85).aspx) returns a error code 0x80342002 when the WLAN is disabled on Windows 10. ctypes.WinError() raise an exception of 'Python int too large to convert to C long' when handle this error code. |
Here is the full list of windows error code: |
All HRESULT values are, since the topmost bit indicates that it's an error, but all the others should be 16-bit positive integers IIRC. I don't think this function is meant to work with HRESULTs, but I could be wrong - fairly sure it's meant for Win32 error codes, though I'd have to dig into the format function it calls. What function are you calling that produces an HRESULT from GetLastError? |
Kelvin is calling WlanScan 1, which returns an error code that apparently can include HRESULT (signed) values cast as DWORD (unsigned) values, including 0x80342002 (ERROR_NDIS_DOT11_POWER_STATE_INVALID). ctypes.FormatError calls FormatMessage 2 with the flag FORMAT_MESSAGE_FROM_SYSTEM. About half of the system error codes defined in winerror.h consist of COM HRESULT codes. But, to clarify Kelvin's link 3, this does not include NTSTATUS values from kernel-mode system calls. NTSTATUS values require the ntdll.dll message table. A workaround in this case is to use the default c_int restype to return the error as a signed integer: >>> ctypes.FormatError(0x80342002 - 2**32)
"The wireless local area network interface is powered down and doesn't
support the requested operation." A similar workaround works for setting the exit code to an HRESULT or NTSTATUS error code: >>> hex(subprocess.call('python -c "import os; os._exit(0xC0000001)"'))
Traceback (most recent call last):
File "<string>", line 1, in <module>
OverflowError: Python int too large to convert to C long
'0x1'
>>> hex(subprocess.call('python -c "import sys; sys.exit(0xC0000001)"'))
'0xffffffff'
>>> hex(subprocess.call('python -c "import os; os._exit(0xC0000001 - 2**32)"'))
'0xc0000001'
>>> hex(subprocess.call('python -c "import sys; sys.exit(0xC0000001 - 2**32)"'))
'0xc0000001' |
format_error() can use format "L" (long long) and then check for a value in the accepted range |
I can potentially take a stab at writing up a PR for this. I've also seen this affecting other locations that eventually call FormatMessage, including:
I will most likely look into fixing all three. |
Note: these values reflect the state of the issue at the time it was migrated and might not reflect the current state.
Show more details
GitHub fields:
bugs.python.org fields:
The text was updated successfully, but these errors were encountered: