Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit 9ba6962

Browse files
committed
Issue #18344: Fix potential ref-leaks in _bufferedreader_read_all().
2 parents 24c05bc + 9ad51ec commit 9ba6962

2 files changed

Lines changed: 47 additions & 48 deletions

File tree

Misc/NEWS

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,8 @@ What's New in Python 3.4.0 Alpha 1?
1010
Core and Builtins
1111
-----------------
1212

13+
- Issue #18344: Fix potential ref-leaks in _bufferedreader_read_all().
14+
1315
- Issue #18342: Use the repr of a module name when an import fails when using
1416
``from ... import ...``.
1517

Modules/_io/bufferedio.c

Lines changed: 45 additions & 48 deletions
Original file line numberDiff line numberDiff line change
@@ -1479,7 +1479,7 @@ static PyObject *
14791479
_bufferedreader_read_all(buffered *self)
14801480
{
14811481
Py_ssize_t current_size;
1482-
PyObject *res, *data = NULL, *chunk, *chunks;
1482+
PyObject *res = NULL, *data = NULL, *tmp = NULL, *chunks = NULL;
14831483

14841484
/* First copy what we have in the current buffer. */
14851485
current_size = Py_SAFE_DOWNCAST(READAHEAD(self), Py_off_t, Py_ssize_t);
@@ -1492,85 +1492,82 @@ _bufferedreader_read_all(buffered *self)
14921492
}
14931493
/* We're going past the buffer's bounds, flush it */
14941494
if (self->writable) {
1495-
res = buffered_flush_and_rewind_unlocked(self);
1496-
if (res == NULL)
1497-
return NULL;
1498-
Py_CLEAR(res);
1495+
tmp = buffered_flush_and_rewind_unlocked(self);
1496+
if (tmp == NULL)
1497+
goto cleanup;
1498+
Py_CLEAR(tmp);
14991499
}
15001500
_bufferedreader_reset_buf(self);
15011501

15021502
if (PyObject_HasAttr(self->raw, _PyIO_str_readall)) {
1503-
chunk = PyObject_CallMethodObjArgs(self->raw, _PyIO_str_readall, NULL);
1504-
if (chunk == NULL)
1505-
return NULL;
1506-
if (chunk != Py_None && !PyBytes_Check(chunk)) {
1507-
Py_XDECREF(data);
1508-
Py_DECREF(chunk);
1503+
tmp = PyObject_CallMethodObjArgs(self->raw, _PyIO_str_readall, NULL);
1504+
if (tmp == NULL)
1505+
goto cleanup;
1506+
if (tmp != Py_None && !PyBytes_Check(tmp)) {
15091507
PyErr_SetString(PyExc_TypeError, "readall() should return bytes");
1510-
return NULL;
1508+
goto cleanup;
15111509
}
1512-
if (chunk == Py_None) {
1513-
if (current_size == 0)
1514-
return chunk;
1515-
else {
1516-
Py_DECREF(chunk);
1517-
return data;
1510+
if (tmp == Py_None) {
1511+
if (current_size == 0) {
1512+
res = Py_None;
1513+
goto cleanup;
1514+
} else {
1515+
res = data;
1516+
goto cleanup;
15181517
}
15191518
}
15201519
else if (current_size) {
1521-
PyBytes_Concat(&data, chunk);
1522-
Py_DECREF(chunk);
1523-
if (data == NULL)
1524-
return NULL;
1525-
return data;
1526-
} else
1527-
return chunk;
1520+
PyBytes_Concat(&data, tmp);
1521+
res = data;
1522+
goto cleanup;
1523+
}
1524+
else {
1525+
res = tmp;
1526+
goto cleanup;
1527+
}
15281528
}
15291529

15301530
chunks = PyList_New(0);
1531-
if (chunks == NULL) {
1532-
Py_XDECREF(data);
1533-
return NULL;
1534-
}
1531+
if (chunks == NULL)
1532+
goto cleanup;
15351533

15361534
while (1) {
15371535
if (data) {
1538-
if (PyList_Append(chunks, data) < 0) {
1539-
Py_DECREF(data);
1540-
Py_DECREF(chunks);
1541-
return NULL;
1542-
}
1543-
Py_DECREF(data);
1536+
if (PyList_Append(chunks, data) < 0)
1537+
goto cleanup;
1538+
Py_CLEAR(data);
15441539
}
15451540

15461541
/* Read until EOF or until read() would block. */
15471542
data = PyObject_CallMethodObjArgs(self->raw, _PyIO_str_read, NULL);
1548-
if (data == NULL) {
1549-
Py_DECREF(chunks);
1550-
return NULL;
1551-
}
1543+
if (data == NULL)
1544+
goto cleanup;
15521545
if (data != Py_None && !PyBytes_Check(data)) {
1553-
Py_DECREF(data);
1554-
Py_DECREF(chunks);
15551546
PyErr_SetString(PyExc_TypeError, "read() should return bytes");
1556-
return NULL;
1547+
goto cleanup;
15571548
}
15581549
if (data == Py_None || PyBytes_GET_SIZE(data) == 0) {
15591550
if (current_size == 0) {
1560-
Py_DECREF(chunks);
1561-
return data;
1551+
res = data;
1552+
goto cleanup;
15621553
}
15631554
else {
1564-
res = _PyBytes_Join(_PyIO_empty_bytes, chunks);
1565-
Py_DECREF(data);
1566-
Py_DECREF(chunks);
1567-
return res;
1555+
tmp = _PyBytes_Join(_PyIO_empty_bytes, chunks);
1556+
res = tmp;
1557+
goto cleanup;
15681558
}
15691559
}
15701560
current_size += PyBytes_GET_SIZE(data);
15711561
if (self->abs_pos != -1)
15721562
self->abs_pos += PyBytes_GET_SIZE(data);
15731563
}
1564+
cleanup:
1565+
/* res is either NULL or a borrowed ref */
1566+
Py_XINCREF(res);
1567+
Py_XDECREF(data);
1568+
Py_XDECREF(tmp);
1569+
Py_XDECREF(chunks);
1570+
return res;
15741571
}
15751572

15761573
/* Read n bytes from the buffer if it can, otherwise return None.

0 commit comments

Comments
 (0)