@@ -1439,6 +1439,7 @@ textiowrapper_read_chunk(textio *self, Py_ssize_t size_hint)
14391439 PyObject * dec_buffer = NULL ;
14401440 PyObject * dec_flags = NULL ;
14411441 PyObject * input_chunk = NULL ;
1442+ Py_buffer input_chunk_buf ;
14421443 PyObject * decoded_chars , * chunk_size ;
14431444 Py_ssize_t nbytes , nchars ;
14441445 int eof ;
@@ -1470,6 +1471,15 @@ textiowrapper_read_chunk(textio *self, Py_ssize_t size_hint)
14701471 Py_DECREF (state );
14711472 return -1 ;
14721473 }
1474+
1475+ if (!PyBytes_Check (dec_buffer )) {
1476+ PyErr_Format (PyExc_TypeError ,
1477+ "decoder getstate() should have returned a bytes "
1478+ "object, not '%.200s'" ,
1479+ Py_TYPE (dec_buffer )-> tp_name );
1480+ Py_DECREF (state );
1481+ return -1 ;
1482+ }
14731483 Py_INCREF (dec_buffer );
14741484 Py_INCREF (dec_flags );
14751485 Py_DECREF (state );
@@ -1482,23 +1492,24 @@ textiowrapper_read_chunk(textio *self, Py_ssize_t size_hint)
14821492 chunk_size = PyLong_FromSsize_t (Py_MAX (self -> chunk_size , size_hint ));
14831493 if (chunk_size == NULL )
14841494 goto fail ;
1495+
14851496 input_chunk = PyObject_CallMethodObjArgs (self -> buffer ,
14861497 (self -> has_read1 ? _PyIO_str_read1 : _PyIO_str_read ),
14871498 chunk_size , NULL );
14881499 Py_DECREF (chunk_size );
14891500 if (input_chunk == NULL )
14901501 goto fail ;
1491- if (!PyBytes_Check (input_chunk )) {
1502+
1503+ if (PyObject_GetBuffer (input_chunk , & input_chunk_buf , 0 ) != 0 ) {
14921504 PyErr_Format (PyExc_TypeError ,
1493- "underlying %s() should have returned a bytes object, "
1505+ "underlying %s() should have returned a bytes-like object, "
14941506 "not '%.200s'" , (self -> has_read1 ? "read1" : "read" ),
14951507 Py_TYPE (input_chunk )-> tp_name );
14961508 goto fail ;
14971509 }
14981510
1499- nbytes = PyBytes_Size ( input_chunk ) ;
1511+ nbytes = input_chunk_buf . len ;
15001512 eof = (nbytes == 0 );
1501-
15021513 if (Py_TYPE (self -> decoder ) == & PyIncrementalNewlineDecoder_Type ) {
15031514 decoded_chars = _PyIncrementalNewlineDecoder_decode (
15041515 self -> decoder , input_chunk , eof );
@@ -1507,6 +1518,7 @@ textiowrapper_read_chunk(textio *self, Py_ssize_t size_hint)
15071518 decoded_chars = PyObject_CallMethodObjArgs (self -> decoder ,
15081519 _PyIO_str_decode , input_chunk , eof ? Py_True : Py_False , NULL );
15091520 }
1521+ PyBuffer_Release (& input_chunk_buf );
15101522
15111523 if (check_decoded (decoded_chars ) < 0 )
15121524 goto fail ;
@@ -1523,18 +1535,12 @@ textiowrapper_read_chunk(textio *self, Py_ssize_t size_hint)
15231535 /* At the snapshot point, len(dec_buffer) bytes before the read, the
15241536 * next input to be decoded is dec_buffer + input_chunk.
15251537 */
1526- PyObject * next_input = PyNumber_Add (dec_buffer , input_chunk );
1527- if (next_input == NULL )
1528- goto fail ;
1529- if (!PyBytes_Check (next_input )) {
1530- PyErr_Format (PyExc_TypeError ,
1531- "decoder getstate() should have returned a bytes "
1532- "object, not '%.200s'" ,
1533- Py_TYPE (next_input )-> tp_name );
1534- Py_DECREF (next_input );
1538+ PyObject * next_input = dec_buffer ;
1539+ PyBytes_Concat (& next_input , input_chunk );
1540+ if (next_input == NULL ) {
1541+ dec_buffer = NULL ; /* Reference lost to PyBytes_Concat */
15351542 goto fail ;
15361543 }
1537- Py_DECREF (dec_buffer );
15381544 Py_CLEAR (self -> snapshot );
15391545 self -> snapshot = Py_BuildValue ("NN" , dec_flags , next_input );
15401546 }
0 commit comments