diff --git a/CREDITS b/CREDITS index f5888fb79..0461d2eca 100644 --- a/CREDITS +++ b/CREDITS @@ -765,7 +765,7 @@ I: 1598 N: Xuehai Pan W: https://github.com/XuehaiPan -I: 1948 +I: 1948, 2264 N: Saeed Rasooli W: https://github.com/ilius diff --git a/HISTORY.rst b/HISTORY.rst index 8a6b880d2..c0cfe9d2d 100644 --- a/HISTORY.rst +++ b/HISTORY.rst @@ -7,6 +7,8 @@ XXXX-XX-XX - 2241_, [NetBSD]: can't compile On NetBSD 10.99.3/amd64. (patch by Thomas Klausner) +- 2266_: if `Process`_ class is passed a very high PID, raise `NoSuchProcess`_ + instead of OverflowError. (patch by Xuehai Pan) 5.9.5 ===== diff --git a/psutil/__init__.py b/psutil/__init__.py index 2b0b3c6b0..bb3880840 100644 --- a/psutil/__init__.py +++ b/psutil/__init__.py @@ -340,6 +340,14 @@ def _init(self, pid, _ignore_nsp=False): if pid < 0: raise ValueError('pid must be a positive integer (got %s)' % pid) + try: + _psplatform.cext.check_pid_range(pid) + except OverflowError: + raise NoSuchProcess( + pid, + msg='process PID out of range (got %s)' % pid, + ) + self._pid = pid self._name = None self._exe = None diff --git a/psutil/_psutil_aix.c b/psutil/_psutil_aix.c index 8a1b8de94..ce89a7bd7 100644 --- a/psutil/_psutil_aix.c +++ b/psutil/_psutil_aix.c @@ -1019,6 +1019,7 @@ PsutilMethods[] = {"net_if_stats", psutil_net_if_stats, METH_VARARGS}, // --- others + {"check_pid_range", psutil_check_pid_range, METH_VARARGS}, {"set_debug", psutil_set_debug, METH_VARARGS}, {NULL, NULL, 0, NULL} diff --git a/psutil/_psutil_bsd.c b/psutil/_psutil_bsd.c index a1b4a3e5b..fde3916d3 100644 --- a/psutil/_psutil_bsd.c +++ b/psutil/_psutil_bsd.c @@ -106,6 +106,7 @@ static PyMethodDef mod_methods[] = { {"sensors_cpu_temperature", psutil_sensors_cpu_temperature, METH_VARARGS}, #endif // --- others + {"check_pid_range", psutil_check_pid_range, METH_VARARGS}, {"set_debug", psutil_set_debug, METH_VARARGS}, {NULL, NULL, 0, NULL} diff --git a/psutil/_psutil_common.c b/psutil/_psutil_common.c index 096e2f373..d8d78bf64 100644 --- a/psutil/_psutil_common.c +++ b/psutil/_psutil_common.c @@ -128,6 +128,27 @@ AccessDenied(const char *syscall) { return NULL; } +/* + * Raise OverflowError if Python int value overflowed when converting to pid_t. + * Raise ValueError if Python int value is negative. + * Otherwise, return None. + */ +PyObject * +psutil_check_pid_range(PyObject *self, PyObject *args) { +#ifdef PSUTIL_WINDOWS + DWORD pid; +#else + pid_t pid; +#endif + + if (!PyArg_ParseTuple(args, _Py_PARSE_PID, &pid)) + return NULL; + if (pid < 0) { + PyErr_SetString(PyExc_ValueError, "pid must be a positive integer"); + return NULL; + } + Py_RETURN_NONE; +} // Enable or disable PSUTIL_DEBUG messages. PyObject * diff --git a/psutil/_psutil_common.h b/psutil/_psutil_common.h index 591f5521f..a425f8685 100644 --- a/psutil/_psutil_common.h +++ b/psutil/_psutil_common.h @@ -99,6 +99,7 @@ PyObject* PyErr_SetFromOSErrnoWithSyscall(const char *syscall); // --- Global utils // ==================================================================== +PyObject* psutil_check_pid_range(PyObject *self, PyObject *args); PyObject* psutil_set_debug(PyObject *self, PyObject *args); int psutil_setup(void); diff --git a/psutil/_psutil_linux.c b/psutil/_psutil_linux.c index a6ee60254..3e6b3b900 100644 --- a/psutil/_psutil_linux.c +++ b/psutil/_psutil_linux.c @@ -518,6 +518,7 @@ static PyMethodDef mod_methods[] = { // --- linux specific {"linux_sysinfo", psutil_linux_sysinfo, METH_VARARGS}, // --- others + {"check_pid_range", psutil_check_pid_range, METH_VARARGS}, {"set_debug", psutil_set_debug, METH_VARARGS}, {NULL, NULL, 0, NULL} diff --git a/psutil/_psutil_osx.c b/psutil/_psutil_osx.c index dd7168eb7..369fbbfb4 100644 --- a/psutil/_psutil_osx.c +++ b/psutil/_psutil_osx.c @@ -54,6 +54,7 @@ static PyMethodDef mod_methods[] = { {"virtual_mem", psutil_virtual_mem, METH_VARARGS}, // --- others + {"check_pid_range", psutil_check_pid_range, METH_VARARGS}, {"set_debug", psutil_set_debug, METH_VARARGS}, {NULL, NULL, 0, NULL} diff --git a/psutil/_psutil_sunos.c b/psutil/_psutil_sunos.c index 5422005fe..11335993f 100644 --- a/psutil/_psutil_sunos.c +++ b/psutil/_psutil_sunos.c @@ -1659,6 +1659,7 @@ PsutilMethods[] = { {"users", psutil_users, METH_VARARGS}, // --- others + {"check_pid_range", psutil_check_pid_range, METH_VARARGS}, {"set_debug", psutil_set_debug, METH_VARARGS}, {NULL, NULL, 0, NULL} diff --git a/psutil/_psutil_windows.c b/psutil/_psutil_windows.c index 54678f755..bb6e12ff8 100644 --- a/psutil/_psutil_windows.c +++ b/psutil/_psutil_windows.c @@ -105,6 +105,7 @@ PsutilMethods[] = { {"QueryDosDevice", psutil_QueryDosDevice, METH_VARARGS}, // --- others + {"check_pid_range", psutil_check_pid_range, METH_VARARGS}, {"set_debug", psutil_set_debug, METH_VARARGS}, {NULL, NULL, 0, NULL} diff --git a/psutil/tests/test_misc.py b/psutil/tests/test_misc.py index a7b5d02d5..53c640121 100755 --- a/psutil/tests/test_misc.py +++ b/psutil/tests/test_misc.py @@ -60,6 +60,12 @@ class TestSpecialMethods(PsutilTestCase): + def test_check_pid_range(self): + with self.assertRaises(OverflowError): + psutil._psplatform.cext.check_pid_range(2 ** 128) + with self.assertRaises(psutil.NoSuchProcess): + psutil.Process(2 ** 128) + def test_process__repr__(self, func=repr): p = psutil.Process(self.spawn_testproc().pid) r = func(p)