@@ -2276,7 +2276,6 @@ bytes_translate_impl(PyBytesObject *self, PyObject *table,
22762276 PyObject * input_obj = (PyObject * )self ;
22772277 const char * output_start , * del_table_chars = NULL ;
22782278 Py_ssize_t inlen , tablen , dellen = 0 ;
2279- PyObject * result ;
22802279 int trans_table [256 ];
22812280
22822281 if (PyBytes_Check (table )) {
@@ -2321,13 +2320,13 @@ bytes_translate_impl(PyBytesObject *self, PyObject *table,
23212320 }
23222321
23232322 inlen = PyBytes_GET_SIZE (input_obj );
2324- result = PyBytes_FromStringAndSize (( char * ) NULL , inlen );
2325- if (result == NULL ) {
2323+ PyBytesWriter * writer = PyBytesWriter_Create ( inlen );
2324+ if (writer == NULL ) {
23262325 PyBuffer_Release (& del_table_view );
23272326 PyBuffer_Release (& table_view );
23282327 return NULL ;
23292328 }
2330- output_start = output = PyBytes_AS_STRING ( result );
2329+ output_start = output = PyBytesWriter_GetData ( writer );
23312330 input = PyBytes_AS_STRING (input_obj );
23322331
23332332 if (dellen == 0 && table_chars != NULL ) {
@@ -2336,14 +2335,17 @@ bytes_translate_impl(PyBytesObject *self, PyObject *table,
23362335 c = Py_CHARMASK (* input ++ );
23372336 * output ++ = table_chars [c ];
23382337 }
2338+ PyObject * result = PyBytesWriter_Finish (writer );
2339+
23392340 /* Check if anything changed (for returning original object) */
23402341 /* We save this check until the end so that the compiler will */
23412342 /* unroll the loop above leading to MUCH faster code. */
2342- if (PyBytes_CheckExact (input_obj )) {
2343+ if (result != NULL && PyBytes_CheckExact (input_obj )) {
23432344 if (memcmp (PyBytes_AS_STRING (input_obj ), output_start , inlen ) == 0 ) {
23442345 Py_SETREF (result , Py_NewRef (input_obj ));
23452346 }
23462347 }
2348+
23472349 PyBuffer_Release (& del_table_view );
23482350 PyBuffer_Release (& table_view );
23492351 return result ;
@@ -2370,13 +2372,11 @@ bytes_translate_impl(PyBytesObject *self, PyObject *table,
23702372 changed = 1 ;
23712373 }
23722374 if (!changed && PyBytes_CheckExact (input_obj )) {
2373- Py_DECREF ( result );
2375+ PyBytesWriter_Discard ( writer );
23742376 return Py_NewRef (input_obj );
23752377 }
23762378 /* Fix the size of the resulting byte string */
2377- if (inlen > 0 )
2378- _PyBytes_Resize (& result , output - output_start );
2379- return result ;
2379+ return PyBytesWriter_FinishWithPointer (writer , output );
23802380}
23812381
23822382
@@ -3889,8 +3889,13 @@ PyBytesWriter_Resize(PyBytesWriter *writer, Py_ssize_t size)
38893889 PyErr_SetString (PyExc_ValueError , "size must be >= 0" );
38903890 return -1 ;
38913891 }
3892- if (byteswriter_resize (writer , size , 1 ) < 0 ) {
3893- return -1 ;
3892+ if (writer -> size < size ) {
3893+ if (byteswriter_resize (writer , size , 1 ) < 0 ) {
3894+ return -1 ;
3895+ }
3896+ }
3897+ else {
3898+ // The buffer is already large enough. Never shrink the buffer.
38943899 }
38953900 writer -> size = size ;
38963901#ifdef Py_DEBUG
@@ -3913,22 +3918,26 @@ _PyBytesWriter_ResizeAndUpdatePointer(PyBytesWriter *writer, Py_ssize_t size,
39133918
39143919
39153920int
3916- PyBytesWriter_Grow (PyBytesWriter * writer , Py_ssize_t size )
3921+ PyBytesWriter_Grow (PyBytesWriter * writer , Py_ssize_t grow )
39173922{
3918- if (size < 0 ) {
3919- PyErr_SetString (PyExc_ValueError , "size must be >= 0" );
3920- return -1 ;
3921- }
3922- if (size == 0 ) {
3923+ if (grow == 0 ) {
39233924 // Nothing to do
39243925 return 0 ;
39253926 }
39263927
3927- if (size > PY_SSIZE_T_MAX - writer -> size ) {
3928- PyErr_NoMemory ();
3929- return -1 ;
3928+ if (grow >= 0 ) {
3929+ if (grow > PY_SSIZE_T_MAX - writer -> size ) {
3930+ PyErr_NoMemory ();
3931+ return -1 ;
3932+ }
3933+ }
3934+ else {
3935+ if (writer -> size + grow < 0 ) {
3936+ PyErr_SetString (PyExc_ValueError , "invalid size" );
3937+ return -1 ;
3938+ }
39303939 }
3931- size = writer -> size + size ;
3940+ Py_ssize_t size = writer -> size + grow ;
39323941
39333942 if (byteswriter_resize (writer , size , 1 ) < 0 ) {
39343943 return -1 ;
0 commit comments