summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--Lib/test/test_socket.py14
-rw-r--r--Misc/ACKS1
-rw-r--r--Misc/NEWS3
-rw-r--r--Modules/socketmodule.c28
4 files changed, 42 insertions, 4 deletions
diff --git a/Lib/test/test_socket.py b/Lib/test/test_socket.py
index 356b801..1357d54 100644
--- a/Lib/test/test_socket.py
+++ b/Lib/test/test_socket.py
@@ -310,6 +310,20 @@ class GeneralModuleTests(unittest.TestCase):
self.assertEqual(swapped & mask, mask)
self.assertRaises(OverflowError, func, 1L<<34)
+ def testNtoHErrors(self):
+ good_values = [ 1, 2, 3, 1L, 2L, 3L ]
+ bad_values = [ -1, -2, -3, -1L, -2L, -3L ]
+ for k in good_values:
+ socket.ntohl(k)
+ socket.ntohs(k)
+ socket.htonl(k)
+ socket.htons(k)
+ for k in bad_values:
+ self.assertRaises(OverflowError, socket.ntohl, k)
+ self.assertRaises(OverflowError, socket.ntohs, k)
+ self.assertRaises(OverflowError, socket.htonl, k)
+ self.assertRaises(OverflowError, socket.htons, k)
+
def testGetServBy(self):
eq = self.assertEqual
# Find one service that exists, then check all the related interfaces.
diff --git a/Misc/ACKS b/Misc/ACKS
index b198114..7ea63cc 100644
--- a/Misc/ACKS
+++ b/Misc/ACKS
@@ -521,6 +521,7 @@ Armin Rigo
Nicholas Riley
Jean-Claude Rimbault
Anthony Roach
+Mark Roberts
Andy Robinson
Jim Robinson
Kevin Rodgers
diff --git a/Misc/NEWS b/Misc/NEWS
index 754ceae..37a1ab6 100644
--- a/Misc/NEWS
+++ b/Misc/NEWS
@@ -301,6 +301,9 @@ Library
Extension Modules
-----------------
+- Patch #1635058: ensure that htonl and friends never accept or
+ return negative numbers, per the underlying C implementation.
+
- Patch #1544279: Improve thread-safety of the socket module by moving
the sock_addr_t storage out of the socket object.
diff --git a/Modules/socketmodule.c b/Modules/socketmodule.c
index 8ec0ed7..82461d4 100644
--- a/Modules/socketmodule.c
+++ b/Modules/socketmodule.c
@@ -3468,7 +3468,12 @@ socket_ntohs(PyObject *self, PyObject *args)
if (!PyArg_ParseTuple(args, "i:ntohs", &x1)) {
return NULL;
}
- x2 = (int)ntohs((short)x1);
+ if (x1 < 0) {
+ PyErr_SetString(PyExc_OverflowError,
+ "can't convert negative number to unsigned long");
+ return NULL;
+ }
+ x2 = (unsigned int)ntohs((unsigned short)x1);
return PyInt_FromLong(x2);
}
@@ -3487,6 +3492,11 @@ socket_ntohl(PyObject *self, PyObject *arg)
x = PyInt_AS_LONG(arg);
if (x == (unsigned long) -1 && PyErr_Occurred())
return NULL;
+ if ((long)x < 0) {
+ PyErr_SetString(PyExc_OverflowError,
+ "can't convert negative number to unsigned long");
+ return NULL;
+ }
}
else if (PyLong_Check(arg)) {
x = PyLong_AsUnsignedLong(arg);
@@ -3510,7 +3520,7 @@ socket_ntohl(PyObject *self, PyObject *arg)
arg->ob_type->tp_name);
if (x == (unsigned long) -1 && PyErr_Occurred())
return NULL;
- return PyInt_FromLong(ntohl(x));
+ return PyLong_FromUnsignedLong(ntohl(x));
}
PyDoc_STRVAR(ntohl_doc,
@@ -3527,7 +3537,12 @@ socket_htons(PyObject *self, PyObject *args)
if (!PyArg_ParseTuple(args, "i:htons", &x1)) {
return NULL;
}
- x2 = (int)htons((short)x1);
+ if (x1 < 0) {
+ PyErr_SetString(PyExc_OverflowError,
+ "can't convert negative number to unsigned long");
+ return NULL;
+ }
+ x2 = (unsigned int)htons((unsigned short)x1);
return PyInt_FromLong(x2);
}
@@ -3546,6 +3561,11 @@ socket_htonl(PyObject *self, PyObject *arg)
x = PyInt_AS_LONG(arg);
if (x == (unsigned long) -1 && PyErr_Occurred())
return NULL;
+ if ((long)x < 0) {
+ PyErr_SetString(PyExc_OverflowError,
+ "can't convert negative number to unsigned long");
+ return NULL;
+ }
}
else if (PyLong_Check(arg)) {
x = PyLong_AsUnsignedLong(arg);
@@ -3567,7 +3587,7 @@ socket_htonl(PyObject *self, PyObject *arg)
return PyErr_Format(PyExc_TypeError,
"expected int/long, %s found",
arg->ob_type->tp_name);
- return PyInt_FromLong(htonl(x));
+ return PyLong_FromUnsignedLong(htonl((unsigned long)x));
}
PyDoc_STRVAR(htonl_doc,