Fix #3651  various memory leaks when using the buffer interface

by Amaury Forgeot d'Arc
Reviewer: Antoine Pitrou
diff --git a/Python/getargs.c b/Python/getargs.c
index b7beb37..13c3f4b 100644
--- a/Python/getargs.c
+++ b/Python/getargs.c
@@ -1245,7 +1245,7 @@
 			/* Caller is interested in Py_buffer, and the object
 			   supports it directly. */
 			format++;
-			if (pb->bf_getbuffer(arg, (Py_buffer*)p, PyBUF_WRITABLE) < 0) {
+			if (PyObject_GetBuffer(arg, (Py_buffer*)p, PyBUF_WRITABLE) < 0) {
 				PyErr_Clear();
 				return converterr("read-write buffer", arg, msgbuf, bufsize);
 			}
@@ -1257,11 +1257,11 @@
 		/* Here we have processed w*, only w and w# remain. */
 		if (pb == NULL ||
 		    pb->bf_getbuffer == NULL ||
-                    ((temp = (*pb->bf_getbuffer)(arg, &view,
-                                                 PyBUF_SIMPLE)) != 0) ||
+                    ((temp = PyObject_GetBuffer(arg, &view,
+						PyBUF_SIMPLE)) != 0) ||
                     view.readonly == 1) {
-                        if (temp==0 && pb->bf_releasebuffer != NULL) {
-                                (*pb->bf_releasebuffer)(arg, &view);
+                        if (temp==0) {
+                                PyBuffer_Release(&view);
                         }
 			return converterr("single-segment read-write buffer",
 					  arg, msgbuf, bufsize);
@@ -1295,7 +1295,7 @@
 				"bytes or read-only character buffer",
 				arg, msgbuf, bufsize);
 
-		if ((*pb->bf_getbuffer)(arg, &view, PyBUF_SIMPLE) != 0)
+		if (PyObject_GetBuffer(arg, &view, PyBUF_SIMPLE) != 0)
 			return converterr("string or single-segment read-only buffer",
                                           arg, msgbuf, bufsize);
 
@@ -1306,6 +1306,8 @@
 				"string or pinned buffer",
 				arg, msgbuf, bufsize);
 
+		PyBuffer_Release(&view);
+
 		if (count < 0)
 			return converterr("(unspecified)", arg, msgbuf, bufsize);
 		{
@@ -1340,14 +1342,13 @@
 		return -1;
 	}
 
-	if ((*pb->bf_getbuffer)(arg, &view, PyBUF_SIMPLE) != 0) {
+	if (PyObject_GetBuffer(arg, &view, PyBUF_SIMPLE) != 0) {
 		*errmsg = "bytes or single-segment read-only buffer";
 		return -1;
 	}
         count = view.len;
         *p = view.buf;
-        if (pb->bf_releasebuffer != NULL)
-                (*pb->bf_releasebuffer)(arg, &view);
+	PyBuffer_Release(&view);
 	return count;
 }
 
@@ -1364,7 +1365,7 @@
 		return -1;
 	}
 	if (pb->bf_getbuffer) {
-		if (pb->bf_getbuffer(arg, view, 0) < 0) {
+		if (PyObject_GetBuffer(arg, view, 0) < 0) {
 			*errmsg = "convertible to a buffer";
 			return -1;
 		}