@@ -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