From 41eaedd3613cebc83e6b9925499369992c7a7770 Mon Sep 17 00:00:00 2001 From: Neal Norwitz 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