@@ -42,14 +42,25 @@ static Py_ssize_t _PyBytesWriter_ResizeToAllocated(PyBytesWriter *writer);
4242
4343
4444// Return a reference to the immortal empty bytes string singleton.
45- static inline PyObject * bytes_get_empty (void )
45+ static inline PyObject *
46+ bytes_get_empty (void )
4647{
4748 PyObject * empty = & EMPTY -> ob_base .ob_base ;
4849 assert (_Py_IsImmortal (empty ));
4950 return empty ;
5051}
5152
5253
54+ // The function cannot fail
55+ static inline PyObject *
56+ bytes_get_char (uint8_t ch )
57+ {
58+ PyObject * obj = (PyObject * )CHARACTER (ch );
59+ assert (_Py_IsImmortal (obj ));
60+ return obj ;
61+ }
62+
63+
5364static inline void
5465set_ob_shash (PyBytesObject * a , Py_hash_t hash )
5566{
@@ -130,9 +141,7 @@ PyBytes_FromStringAndSize(const char *str, Py_ssize_t size)
130141 return NULL ;
131142 }
132143 if (size == 1 && str != NULL ) {
133- op = CHARACTER (* str & 255 );
134- assert (_Py_IsImmortal (op ));
135- return (PyObject * )op ;
144+ return bytes_get_char ((uint8_t )* str );
136145 }
137146 if (size == 0 ) {
138147 return bytes_get_empty ();
@@ -166,9 +175,7 @@ PyBytes_FromString(const char *str)
166175 return bytes_get_empty ();
167176 }
168177 else if (size == 1 ) {
169- op = CHARACTER (* str & 255 );
170- assert (_Py_IsImmortal (op ));
171- return (PyObject * )op ;
178+ return bytes_get_char ((uint8_t )* str );
172179 }
173180
174181 /* Inline PyObject_NewVar */
@@ -3347,6 +3354,53 @@ _PyBytes_IsMutable(PyObject *self)
33473354#endif
33483355
33493356
3357+ static inline int
3358+ bytes_resize_inplace (PyObject * * pv , Py_ssize_t newsize )
3359+ {
3360+ PyObject * v = * pv ;
3361+ // Do not test _PyObject_IsUniquelyReferenced(). The function is used by
3362+ // PyBytesWriter_FinishWithSize() and its caller can have its own lock.
3363+ assert (Py_REFCNT (v ) == 1 );
3364+ assert (PyBytes_GET_SIZE (v ) >= 1 );
3365+ assert (newsize >= 1 );
3366+
3367+ // Only mutable bytes can be resized in-place
3368+ assert (_PyBytes_IsMutable (v ));
3369+
3370+ if ((size_t )newsize > (size_t )PY_SSIZE_T_MAX - PyBytesObject_SIZE ) {
3371+ PyErr_SetString (PyExc_OverflowError ,
3372+ "byte string is too large" );
3373+ return -1 ;
3374+ }
3375+
3376+ #ifdef Py_TRACE_REFS
3377+ _Py_ForgetReference (v );
3378+ #endif
3379+ _PyReftracerTrack (v , PyRefTracer_DESTROY );
3380+
3381+ PyObject * result = PyObject_Realloc (v , PyBytesObject_SIZE + newsize );
3382+ if (result == NULL ) {
3383+ #ifdef Py_TRACE_REFS
3384+ _Py_AddToAllObjects (v );
3385+ #endif
3386+ _PyReftracerTrack (v , PyRefTracer_CREATE );
3387+
3388+ PyErr_NoMemory ();
3389+ return -1 ;
3390+ }
3391+
3392+ * pv = result ;
3393+ v = result ;
3394+ _Py_NewReferenceNoTotal (v );
3395+ PyBytesObject * sv = (PyBytesObject * )v ;
3396+ Py_SET_SIZE (sv , newsize );
3397+ sv -> ob_sval [newsize ] = '\0' ;
3398+ set_ob_shash (sv , -1 ); /* invalidate cached hash value */
3399+ assert (_PyBytes_IsMutable (* pv ));
3400+ return 0 ;
3401+ }
3402+
3403+
33503404/* The following function breaks the notion that bytes are immutable:
33513405 it changes the size of a bytes object. You can think of it
33523406 as creating a new bytes object and destroying the old one, only
@@ -3410,40 +3464,7 @@ _PyBytes_ResizeKeepOnError(PyObject **pv, Py_ssize_t newsize)
34103464 return 0 ;
34113465 }
34123466
3413- // Only mutable bytes can be resized in-place
3414- assert (_PyBytes_IsMutable (v ));
3415-
3416- if ((size_t )newsize > (size_t )PY_SSIZE_T_MAX - PyBytesObject_SIZE ) {
3417- PyErr_SetString (PyExc_OverflowError ,
3418- "byte string is too large" );
3419- return -1 ;
3420- }
3421-
3422- #ifdef Py_TRACE_REFS
3423- _Py_ForgetReference (v );
3424- #endif
3425- _PyReftracerTrack (v , PyRefTracer_DESTROY );
3426-
3427- result = (PyObject * )PyObject_Realloc (v , PyBytesObject_SIZE + newsize );
3428- if (result == NULL ) {
3429- #ifdef Py_TRACE_REFS
3430- _Py_AddToAllObjects (v );
3431- #endif
3432- _PyReftracerTrack (v , PyRefTracer_CREATE );
3433-
3434- PyErr_NoMemory ();
3435- return -1 ;
3436- }
3437-
3438- * pv = result ;
3439- v = result ;
3440- _Py_NewReferenceNoTotal (v );
3441- PyBytesObject * sv = (PyBytesObject * )v ;
3442- Py_SET_SIZE (sv , newsize );
3443- sv -> ob_sval [newsize ] = '\0' ;
3444- set_ob_shash (sv , -1 ); /* invalidate cached hash value */
3445- assert (_PyBytes_IsMutable (* pv ));
3446- return 0 ;
3467+ return bytes_resize_inplace (pv , newsize );
34473468}
34483469
34493470
@@ -3903,9 +3924,6 @@ PyBytesWriter_FinishWithSize(PyBytesWriter *writer, Py_ssize_t size)
39033924{
39043925 assert (byteswriter_check_consistency (writer ));
39053926
3906- // Check for negative size here to raise ValueError in all cases, rather
3907- // than having a different exception depending on the code path. For
3908- // example, _PyBytes_Resize() raises SystemError on negative size.
39093927 if (size < 0 ) {
39103928 PyErr_Format (PyExc_ValueError , "size must be positive" );
39113929 goto error ;
@@ -3919,6 +3937,13 @@ PyBytesWriter_FinishWithSize(PyBytesWriter *writer, Py_ssize_t size)
39193937 PyObject * result ;
39203938 if (size == 0 && !writer -> use_bytearray ) {
39213939 result = bytes_get_empty ();
3940+ if (writer -> obj != NULL ) {
3941+ #ifdef Py_DEBUG
3942+ byteswriter_reset_trailing_byte (writer );
3943+ #endif
3944+ Py_DECREF (writer -> obj );
3945+ writer -> obj = NULL ;
3946+ }
39223947 }
39233948 else if (writer -> obj != NULL ) {
39243949 // Truncate the bytes/bytearray object if needed
@@ -3935,14 +3960,11 @@ PyBytesWriter_FinishWithSize(PyBytesWriter *writer, Py_ssize_t size)
39353960 }
39363961 else {
39373962 if (size == 1 ) {
3938- // Get the single byte singleton
39393963 unsigned char ch = PyBytes_AS_STRING (writer -> obj )[0 ];
3940- PyObject * op = (PyObject * )CHARACTER (ch );
3941- assert (_Py_IsImmortal (op ));
3942- Py_SETREF (writer -> obj , op );
3964+ Py_SETREF (writer -> obj , bytes_get_char (ch ));
39433965 }
39443966 else if (size != PyBytes_GET_SIZE (writer -> obj )) {
3945- if (_PyBytes_Resize (& writer -> obj , size )) {
3967+ if (bytes_resize_inplace (& writer -> obj , size )) {
39463968 goto error ;
39473969 }
39483970 }
@@ -3953,23 +3975,26 @@ PyBytesWriter_FinishWithSize(PyBytesWriter *writer, Py_ssize_t size)
39533975 }
39543976 else {
39553977 // Create an object from the small buffer
3978+ const char * buffer = (const char * )writer -> small_buffer ;
39563979 if (writer -> use_bytearray ) {
3957- result = PyByteArray_FromStringAndSize (writer -> small_buffer , size );
3980+ result = PyByteArray_FromStringAndSize (buffer , size );
39583981 }
39593982 else {
3960- // The function returns single byte singleton if size equals 1
3961- result = PyBytes_FromStringAndSize (writer -> small_buffer , size );
3983+ if (size == 1 ) {
3984+ result = bytes_get_char ((uint8_t )buffer [0 ]);
3985+ }
3986+ else {
3987+ result = _PyBytes_FromSize (size , 0 );
3988+ if (result == NULL ) {
3989+ goto error ;
3990+ }
3991+ memcpy (PyBytes_AS_STRING (result ), buffer , size );
3992+ }
39623993 }
39633994 }
39643995
3965- #ifdef Py_DEBUG
3966- // Reset the writer, so byteswriter_check_consistency() doesn't fail
3967- // in PyBytesWriter_Discard().
3968- writer -> size = 0 ;
3969- byteswriter_write_canary_byte (writer );
3970- #endif
3971-
3972- PyBytesWriter_Discard (writer );
3996+ assert (writer -> obj == NULL );
3997+ _Py_FREELIST_FREE (bytes_writers , writer , PyMem_Free );
39733998 return result ;
39743999
39754000error :
0 commit comments