From 41eaedd3613cebc83e6b9925499369992c7a7770 Mon Sep 17 00:00:00 2001
From: Neal Norwitz <nnorwitz@gmail.com>
Date: Sun, 12 Aug 2007 00:03:22 +0000
Subject: Fix refleaks from execfile('file that contains a # coding: line')
 Also simplify logic a bit in fp_setreadl.

---
 Parser/tokenizer.c | 32 +++++++++++++++++++++-----------
 1 file changed, 21 insertions(+), 11 deletions(-)

diff --git a/Parser/tokenizer.c b/Parser/tokenizer.c
index 284082d..2e700bc 100644
--- a/Parser/tokenizer.c
+++ b/Parser/tokenizer.c
@@ -369,6 +369,7 @@ fp_readl(char *s, int size, struct tok_state *tok)
 	PyObject* bufobj = tok->decoding_buffer;
 	const char *buf;
 	Py_ssize_t buflen;
+	int allocated = 0;
 
 	/* Ask for one less byte so we can terminate it */
 	assert(size > 0);
@@ -377,21 +378,34 @@ fp_readl(char *s, int size, struct tok_state *tok)
 	if (bufobj == NULL) {
 		bufobj = PyObject_CallObject(tok->decoding_readline, NULL);
 		if (bufobj == NULL)
-			return error_ret(tok);
+			goto error;
+		allocated = 1;
+	}
+        if (PyObject_AsCharBuffer(bufobj, &buf, &buflen) < 0) {
+		goto error;
 	}
-        if (PyObject_AsCharBuffer(bufobj, &buf, &buflen) < 0)
-		return error_ret(tok);
 	if (buflen > size) {
+		Py_XDECREF(tok->decoding_buffer);
 		tok->decoding_buffer = PyBytes_FromStringAndSize(buf+size,
 								 buflen-size);
 		if (tok->decoding_buffer == NULL)
-			return error_ret(tok);
+			goto error;
 		buflen = size;
 	}
 	memcpy(s, buf, buflen);
 	s[buflen] = '\0';
-	if (buflen == 0) return NULL; /* EOF */
+	if (buflen == 0) /* EOF */
+		s = NULL;
+	if (allocated) {
+		Py_DECREF(bufobj);
+	}
 	return s;
+
+error:
+	if (allocated) {
+		Py_XDECREF(bufobj);
+	}
+	return error_ret(tok);
 }
 
 /* Set the readline function for TOK to a StreamReader's
@@ -408,7 +422,6 @@ static int
 fp_setreadl(struct tok_state *tok, const char* enc)
 {
 	PyObject *readline = NULL, *stream = NULL, *io = NULL;
-	int ok = 0;
 
 	io = PyImport_ImportModule("io");
 	if (io == NULL)
@@ -419,17 +432,14 @@ fp_setreadl(struct tok_state *tok, const char* enc)
 	if (stream == NULL)
 		goto cleanup;
 
+	Py_XDECREF(tok->decoding_readline);
 	readline = PyObject_GetAttrString(stream, "readline");
-	if (readline == NULL)
-		goto cleanup;
-
 	tok->decoding_readline = readline;
-	ok = 1;
 
   cleanup:
 	Py_XDECREF(stream);
 	Py_XDECREF(io);
-	return ok;
+	return readline != NULL;
 }
 
 /* Fetch the next byte from TOK. */
-- 
cgit v0.12

