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;

`