bpo-23325: Fix SIG_IGN and SIG_DFL int comparison in signal module (G… · python/cpython@c8a47e7 (original) (raw)
`@@ -177,6 +177,17 @@ get_signal_state(PyObject *module)
`
177
177
`}
`
178
178
``
179
179
``
``
180
`+
static inline int
`
``
181
`+
compare_handler(PyObject *func, PyObject *dfl_ign_handler)
`
``
182
`+
{
`
``
183
`+
assert(PyLong_CheckExact(dfl_ign_handler));
`
``
184
`+
if (!PyLong_CheckExact(func)) {
`
``
185
`+
return 0;
`
``
186
`+
}
`
``
187
`+
// Assume that comparison of two PyLong objects will never fail.
`
``
188
`+
return PyObject_RichCompareBool(func, dfl_ign_handler, Py_EQ) == 1;
`
``
189
`+
}
`
``
190
+
180
191
`#ifdef HAVE_GETITIMER
`
181
192
`/* auxiliary functions for setitimer */
`
182
193
`static int
`
`@@ -528,21 +539,18 @@ signal_signal_impl(PyObject *module, int signalnum, PyObject *handler)
`
528
539
`"signal number out of range");
`
529
540
`return NULL;
`
530
541
` }
`
531
``
`-
if (handler == modstate->ignore_handler) {
`
``
542
`+
if (PyCallable_Check(handler)) {
`
``
543
`+
func = signal_handler;
`
``
544
`+
} else if (compare_handler(handler, modstate->ignore_handler)) {
`
532
545
`func = SIG_IGN;
`
533
``
`-
}
`
534
``
`-
else if (handler == modstate->default_handler) {
`
``
546
`+
} else if (compare_handler(handler, modstate->default_handler)) {
`
535
547
`func = SIG_DFL;
`
536
``
`-
}
`
537
``
`-
else if (!PyCallable_Check(handler)) {
`
``
548
`+
} else {
`
538
549
`_PyErr_SetString(tstate, PyExc_TypeError,
`
539
550
`"signal handler must be signal.SIG_IGN, "
`
540
551
`"signal.SIG_DFL, or a callable object");
`
541
552
`return NULL;
`
542
553
` }
`
543
``
`-
else {
`
544
``
`-
func = signal_handler;
`
545
``
`-
}
`
546
554
``
547
555
`/* Check for pending signals before changing signal handler */
`
548
556
`if (_PyErr_CheckSignalsTstate(tstate)) {
`
`@@ -1752,8 +1760,8 @@ _PySignal_Fini(void)
`
1752
1760
`set_handler(signum, NULL);
`
1753
1761
`if (func != NULL
`
1754
1762
`&& func != Py_None
`
1755
``
`-
&& func != state->default_handler
`
1756
``
`-
&& func != state->ignore_handler)
`
``
1763
`+
&& !compare_handler(func, state->default_handler)
`
``
1764
`+
&& !compare_handler(func, state->ignore_handler))
`
1757
1765
` {
`
1758
1766
`PyOS_setsig(signum, SIG_DFL);
`
1759
1767
` }
`
`@@ -1824,8 +1832,9 @@ _PyErr_CheckSignalsTstate(PyThreadState *tstate)
`
1824
1832
` * (see bpo-43406).
`
1825
1833
` */
`
1826
1834
`PyObject *func = get_handler(i);
`
1827
``
`-
if (func == NULL || func == Py_None || func == state->ignore_handler ||
`
1828
``
`-
func == state->default_handler) {
`
``
1835
`+
if (func == NULL || func == Py_None ||
`
``
1836
`+
compare_handler(func, state->ignore_handler) ||
`
``
1837
`+
compare_handler(func, state->default_handler)) {
`
1829
1838
`/* No Python signal handler due to aforementioned race condition.
`
1830
1839
` * We can't call raise() as it would break the assumption
`
1831
1840
` * that PyErr_SetInterrupt() only simulates an incoming
`
`@@ -1893,7 +1902,8 @@ PyErr_SetInterruptEx(int signum)
`
1893
1902
``
1894
1903
`signal_state_t *state = &signal_global_state;
`
1895
1904
`PyObject *func = get_handler(signum);
`
1896
``
`-
if (func != state->ignore_handler && func != state->default_handler) {
`
``
1905
`+
if (!compare_handler(func, state->ignore_handler)
`
``
1906
`+
&& !compare_handler(func, state->default_handler)) {
`
1897
1907
`trip_signal(signum);
`
1898
1908
` }
`
1899
1909
`return 0;
`