Skip to content

Commit 41eaedd

Browse files
committed
Fix refleaks from execfile('file that contains a # coding: line')
Also simplify logic a bit in fp_setreadl.
1 parent bb217d9 commit 41eaedd

1 file changed

Lines changed: 21 additions & 11 deletions

File tree

Parser/tokenizer.c

Lines changed: 21 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -369,6 +369,7 @@ fp_readl(char *s, int size, struct tok_state *tok)
369369
PyObject* bufobj = tok->decoding_buffer;
370370
const char *buf;
371371
Py_ssize_t buflen;
372+
int allocated = 0;
372373

373374
/* Ask for one less byte so we can terminate it */
374375
assert(size > 0);
@@ -377,21 +378,34 @@ fp_readl(char *s, int size, struct tok_state *tok)
377378
if (bufobj == NULL) {
378379
bufobj = PyObject_CallObject(tok->decoding_readline, NULL);
379380
if (bufobj == NULL)
380-
return error_ret(tok);
381+
goto error;
382+
allocated = 1;
383+
}
384+
if (PyObject_AsCharBuffer(bufobj, &buf, &buflen) < 0) {
385+
goto error;
381386
}
382-
if (PyObject_AsCharBuffer(bufobj, &buf, &buflen) < 0)
383-
return error_ret(tok);
384387
if (buflen > size) {
388+
Py_XDECREF(tok->decoding_buffer);
385389
tok->decoding_buffer = PyBytes_FromStringAndSize(buf+size,
386390
buflen-size);
387391
if (tok->decoding_buffer == NULL)
388-
return error_ret(tok);
392+
goto error;
389393
buflen = size;
390394
}
391395
memcpy(s, buf, buflen);
392396
s[buflen] = '\0';
393-
if (buflen == 0) return NULL; /* EOF */
397+
if (buflen == 0) /* EOF */
398+
s = NULL;
399+
if (allocated) {
400+
Py_DECREF(bufobj);
401+
}
394402
return s;
403+
404+
error:
405+
if (allocated) {
406+
Py_XDECREF(bufobj);
407+
}
408+
return error_ret(tok);
395409
}
396410

397411
/* Set the readline function for TOK to a StreamReader's
@@ -408,7 +422,6 @@ static int
408422
fp_setreadl(struct tok_state *tok, const char* enc)
409423
{
410424
PyObject *readline = NULL, *stream = NULL, *io = NULL;
411-
int ok = 0;
412425

413426
io = PyImport_ImportModule("io");
414427
if (io == NULL)
@@ -419,17 +432,14 @@ fp_setreadl(struct tok_state *tok, const char* enc)
419432
if (stream == NULL)
420433
goto cleanup;
421434

435+
Py_XDECREF(tok->decoding_readline);
422436
readline = PyObject_GetAttrString(stream, "readline");
423-
if (readline == NULL)
424-
goto cleanup;
425-
426437
tok->decoding_readline = readline;
427-
ok = 1;
428438

429439
cleanup:
430440
Py_XDECREF(stream);
431441
Py_XDECREF(io);
432-
return ok;
442+
return readline != NULL;
433443
}
434444

435445
/* Fetch the next byte from TOK. */

0 commit comments

Comments
 (0)