]> granicus.if.org Git - python/commitdiff
Patch #1635058 by Mark Roberts: ensure that htonl and friends never accept or
authorGuido van Rossum <guido@python.org>
Sun, 14 Jan 2007 17:03:32 +0000 (17:03 +0000)
committerGuido van Rossum <guido@python.org>
Sun, 14 Jan 2007 17:03:32 +0000 (17:03 +0000)
return negative numbers, per the underlying C implementation.

Lib/test/test_socket.py
Misc/ACKS
Misc/NEWS
Modules/socketmodule.c

index 356b80199bb7e3b395f88c8a5af5072e37b44cd4..1357d54d1e70494d9ef107d8d68ac1869eef7d14 100644 (file)
@@ -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.
index b1981140b0a33b875c2f6945a44897433e390dea..7ea63cce7528f3e9ad3c2885cca8f60d422f565c 100644 (file)
--- 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
index 754ceae53f0d1f9a41da4ab90e4047de3524c477..37a1ab668c6a649c238aef9baf8d4f48209f6b2c 100644 (file)
--- 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.
 
index 8ec0ed73ca3c1de9bdf00ee1c4776b278c3de474..82461d4602e171d6b52058be45ead1eef7381538 100644 (file)
@@ -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,