diff --git a/python/repeated.c b/python/repeated.c index 1286f28c0f..f6e16c0df9 100644 --- a/python/repeated.c +++ b/python/repeated.c @@ -354,11 +354,18 @@ static int PyUpb_RepeatedContainer_DeleteSubscript(upb_array* arr, step = -step; } size_t dst = start; - size_t src = start + 1; - for (Py_ssize_t i = 0; i < count; i++, dst += step, src += step + 1) { - upb_array_move(arr, dst, src, step); + size_t src = step ? start + 1 : start + count; + if (step) { + // Move elements between steps. + for (Py_ssize_t i = 0; i < count; i++, dst += step, src += step + 1) { + upb_array_move(arr, dst, src, step); + } } - upb_array_resize(arr, upb_array_size(arr) - count, NULL); + // Move tail. + size_t tail = upb_array_size(arr) - src; + assert(dst + tail == upb_array_size(arr) - count); + upb_array_move(arr, dst, src, upb_array_size(arr) - src); + upb_array_resize(arr, dst + tail, NULL); return 0; } diff --git a/upb/reflection.c b/upb/reflection.c index 024d1753a9..1792adba36 100644 --- a/upb/reflection.c +++ b/upb/reflection.c @@ -373,7 +373,7 @@ bool upb_array_append(upb_array *arr, upb_msgval val, upb_arena *arena) { return true; } -bool upb_array_move(upb_array* arr, size_t dst_idx, size_t src_idx, +void upb_array_move(upb_array* arr, size_t dst_idx, size_t src_idx, size_t count) { char* data = _upb_array_ptr(arr); int lg2 = arr->data & 7; diff --git a/upb/reflection.h b/upb/reflection.h index 12ada97f59..55aaa04112 100644 --- a/upb/reflection.h +++ b/upb/reflection.h @@ -136,7 +136,7 @@ bool upb_array_append(upb_array *array, upb_msgval val, upb_arena *arena); /* Moves elements within the array using memmove(). Like memmove(), the source * and destination elements may be overlapping. */ -bool upb_array_move(upb_array* array, size_t dst_idx, size_t src_idx, +void upb_array_move(upb_array* array, size_t dst_idx, size_t src_idx, size_t count); /* Inserts one or more empty elements into the array. Existing elements are