[Python-checkins] r70073 - in python/branches/release30-maint: Modules/_ssl.c

benjamin.peterson python-checkins at python.org
Sat Feb 28 20:15:55 CET 2009


Author: benjamin.peterson
Date: Sat Feb 28 20:15:55 2009
New Revision: 70073

Log:
Merged revisions 70072 via svnmerge from 
svn+ssh://pythondev@svn.python.org/python/branches/py3k

........
  r70072 | benjamin.peterson | 2009-02-28 13:06:54 -0600 (Sat, 28 Feb 2009) | 1 line
  
  #4967 fix buggy read()
........


Modified:
   python/branches/release30-maint/   (props changed)
   python/branches/release30-maint/Modules/_ssl.c

Modified: python/branches/release30-maint/Modules/_ssl.c
==============================================================================
--- python/branches/release30-maint/Modules/_ssl.c	(original)
+++ python/branches/release30-maint/Modules/_ssl.c	Sat Feb 28 20:15:55 2009
@@ -1244,9 +1244,12 @@
 
 static PyObject *PySSL_SSLread(PySSLObject *self, PyObject *args)
 {
-	PyObject *buf = NULL;
+	PyObject *dest = NULL;
+	Py_buffer buf;
 	int buf_passed = 0;
 	int count = -1;
+	char *mem;
+	/* XXX this should use Py_ssize_t */
 	int len = 1024;
 	int sockstate;
 	int err;
@@ -1260,19 +1263,22 @@
                 return NULL;
         }
 
-	if (!PyArg_ParseTuple(args, "|Oi:read", &buf, &count))
+	if (!PyArg_ParseTuple(args, "|Oi:read", &dest, &count))
 		return NULL;
-        if ((buf == NULL) || (buf == Py_None)) {
-		if (!(buf = PyByteArray_FromStringAndSize((char *) 0, len)))
+        if ((dest == NULL) || (dest == Py_None)) {
+		if (!(dest = PyByteArray_FromStringAndSize((char *) 0, len)))
 			return NULL;
-        } else if (PyLong_Check(buf)) {
-		len = PyLong_AS_LONG(buf);
-		if (!(buf = PyByteArray_FromStringAndSize((char *) 0, len)))
+		mem = PyByteArray_AS_STRING(dest);
+        } else if (PyLong_Check(dest)) {
+		len = PyLong_AS_LONG(dest);
+		if (!(dest = PyByteArray_FromStringAndSize((char *) 0, len)))
 			return NULL;
+		mem = PyByteArray_AS_STRING(dest);
 	} else {
-		if (!PyByteArray_Check(buf))
+		if (PyObject_GetBuffer(dest, &buf, PyBUF_CONTIG) < 0)
 			return NULL;
-		len = PyByteArray_Size(buf);
+		mem = buf.buf;
+		len = buf.len;
 		if ((count > 0) && (count <= len))
 			len = count;
 		buf_passed = 1;
@@ -1293,18 +1299,11 @@
 		if (sockstate == SOCKET_HAS_TIMED_OUT) {
 			PyErr_SetString(PySSLErrorObject,
 					"The read operation timed out");
-			if (!buf_passed) {
-				Py_DECREF(buf);
-			}
-			return NULL;
+			goto error;
 		} else if (sockstate == SOCKET_TOO_LARGE_FOR_SELECT) {
 			PyErr_SetString(PySSLErrorObject,
 				"Underlying socket too large for select().");
-			if (!buf_passed) {
-				Py_DECREF(buf);
-			}
-			Py_DECREF(buf);
-			return NULL;
+			goto error;
 		} else if (sockstate == SOCKET_HAS_BEEN_CLOSED) {
 			count = 0;
 			goto done;
@@ -1313,15 +1312,11 @@
 	do {
 		err = 0;
 		PySSL_BEGIN_ALLOW_THREADS
-		count = SSL_read(self->ssl, PyByteArray_AsString(buf), len);
+		count = SSL_read(self->ssl, mem, len);
 		err = SSL_get_error(self->ssl, count);
 		PySSL_END_ALLOW_THREADS
-		if(PyErr_CheckSignals()) {
-			if (!buf_passed) {
-				Py_DECREF(buf);
-			}
-			return NULL;
-		}
+		if (PyErr_CheckSignals())
+			goto error;
 		if (err == SSL_ERROR_WANT_READ) {
 			sockstate =
 			  check_socket_and_wait_for_timeout(sock, 0);
@@ -1340,29 +1335,31 @@
 		if (sockstate == SOCKET_HAS_TIMED_OUT) {
 			PyErr_SetString(PySSLErrorObject,
 					"The read operation timed out");
-			if (!buf_passed) {
-				Py_DECREF(buf);
-			}
-			return NULL;
+			goto error;
 		} else if (sockstate == SOCKET_IS_NONBLOCKING) {
 			break;
 		}
 	} while (err == SSL_ERROR_WANT_READ || err == SSL_ERROR_WANT_WRITE);
 	if (count <= 0) {
-		if (!buf_passed) {
-			Py_DECREF(buf);
-		}
-		return PySSL_SetError(self, count, __FILE__, __LINE__);
+		PySSL_SetError(self, count, __FILE__, __LINE__);
+		goto error;
 	}
   done:
 	if (!buf_passed) {
-		PyObject *res = PyBytes_FromStringAndSize(
-			PyByteArray_AS_STRING(buf), count);
-		Py_DECREF(buf);
+		PyObject *res = PyBytes_FromStringAndSize(mem, count);
+		Py_DECREF(dest);
 		return res;
 	} else {
+		PyBuffer_Release(&buf);
 		return PyLong_FromLong(count);
 	}
+  error:
+	if (!buf_passed) {
+		Py_DECREF(dest);
+	} else {
+		PyBuffer_Release(&buf);
+	}
+	return NULL;
 }
 
 PyDoc_STRVAR(PySSL_SSLread_doc,


More information about the Python-checkins mailing list