@@ -225,41 +225,36 @@ PyByteArray_AsString(PyObject *self)
225225
226226
227227static int
228- bytearray_realign_data_lock_held (PyByteArrayObject * self , Py_ssize_t new_size , Py_ssize_t alloc )
228+ bytearray_realign_data_lock_held (PyByteArrayObject * self ,
229+ Py_ssize_t new_size , Py_ssize_t alloc )
229230{
230231 _Py_CRITICAL_SECTION_ASSERT_OBJECT_LOCKED (self );
231232 assert (1 <= new_size && new_size <= alloc );
232233
233234 Py_ssize_t size = Py_SIZE (self );
234- size_t logical_offset = (size_t ) (self -> ob_start - self -> ob_bytes );
235-
236- if (logical_offset == 0 || new_size >= size ) {
237- /* Re-align data to the start of the allocation. */
238- if (logical_offset != 0 ) {
239- /* optimization tradeoff: This is faster than a new allocation when
240- the number of bytes being removed in a resize is small; for
241- large size changes it may be better to just make a new bytes
242- object as _PyBytes_Resize will do a malloc + memcpy internally.
243- */
244- memmove (self -> ob_bytes , self -> ob_start , size );
245- self -> ob_start = self -> ob_bytes ;
246- }
247235
248- if (_PyBytes_ResizeKeepOnError (& self -> ob_bytes_object , alloc ) < 0 ) {
249- bytearray_write_trailing_null_byte (self );
250- return -1 ;
251- }
252- }
253- else {
254- // Using memmove() would be unsafe, since _PyBytes_ResizeKeepOnError()
255- // failure code path would be unable to restore the bytearray to its
256- // previous state.
257- PyObject * resized = PyBytes_FromStringAndSize (NULL , alloc );
258- if (resized == NULL ) {
259- return -1 ;
236+ /* Re-align data to the start of the allocation. */
237+ char * old_start = self -> ob_start ;
238+ if (self -> ob_start != self -> ob_bytes ) {
239+ /* optimization tradeoff: This is faster than a new allocation when
240+ the number of bytes being removed in a resize is small; for
241+ large size changes it may be better to just make a new bytes
242+ object as _PyBytes_Resize will do a malloc + memcpy internally.
243+ */
244+ Py_ssize_t move = Py_MIN (new_size , size );
245+ memmove (self -> ob_bytes , self -> ob_start , move );
246+ self -> ob_start = self -> ob_bytes ;
247+ }
248+
249+ if (_PyBytes_ResizeKeepOnError (& self -> ob_bytes_object , alloc ) < 0 ) {
250+ if (new_size < size ) {
251+ // Move remaining bytes
252+ Py_ssize_t moved = new_size ;
253+ Py_ssize_t remaining = size - moved ;
254+ memmove (self -> ob_bytes + moved , old_start + moved , remaining );
260255 }
261- memcpy ( PyBytes_AS_STRING ( resized ), self -> ob_start , new_size );
262- Py_SETREF ( self -> ob_bytes_object , resized ) ;
256+ bytearray_write_trailing_null_byte ( self );
257+ return -1 ;
263258 }
264259 return 0 ;
265260}
0 commit comments