From 018919aba81093e43d5c5c401a253b0707a8e86f Mon Sep 17 00:00:00 2001
From: Guido van Rossum <guido@python.org>
Date: Mon, 15 Jan 2007 00:07:32 +0000
Subject: Merged revisions 53434 via svnmerge from
 svn+ssh://pythondev@svn.python.org/python/trunk

........
  r53434 | guido.van.rossum | 2007-01-14 09:03:32 -0800 (Sun, 14 Jan 2007) | 3 lines

  Patch #1635058 by Mark Roberts: ensure that htonl and friends never accept or
  return negative numbers, per the underlying C implementation.
........
---
 Lib/test/test_socket.py | 14 ++++++++++++++
 Misc/ACKS               |  1 +
 Modules/socketmodule.c  | 18 ++++++++++++++----
 3 files changed, 29 insertions(+), 4 deletions(-)

diff --git a/Lib/test/test_socket.py b/Lib/test/test_socket.py
index e141257..ecfb1ed 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/Modules/socketmodule.c b/Modules/socketmodule.c
index 31efa0a..0f7c9ad 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);
 }
 
@@ -3505,7 +3510,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,
@@ -3522,7 +3527,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);
 }
 
@@ -3557,7 +3567,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,
-- 
cgit v0.12

