On platforms with 64-bit long, socket.setblocking(x) treated all x
which lower 32 bits are zero as False due to integer truncation.
Reported by ubsan.
self.skipTest('needs UINT_MAX < ULONG_MAX')
self.serv.setblocking(False)
- self.assertEqual(self.serv.gettimeout(), 0.0)
+ self.assert_sock_timeout(self.serv, 0.0)
self.serv.setblocking(_testcapi.UINT_MAX + 1)
- self.assertIsNone(self.serv.gettimeout())
+ self.assert_sock_timeout(self.serv, None)
_testSetBlocking_overflow = support.cpython_only(_testSetBlocking)
--- /dev/null
+Fix unexpected integer truncation in :meth:`socket.setblocking` which caused
+it to interpret multiples of ``2**32`` as ``False``.
static PyObject *
sock_setblocking(PySocketSockObject *s, PyObject *arg)
{
- long block;
+ long value;
+ int block;
- block = PyLong_AsLong(arg);
- if (block == -1 && PyErr_Occurred())
+ value = PyLong_AsLong(arg);
+ if (value == -1 && PyErr_Occurred())
return NULL;
+ block = (value != 0);
s->sock_timeout = _PyTime_FromSeconds(block ? -1 : 0);
if (internal_setblocking(s, block) == -1) {
return NULL;