Summary
Clamp new_capacity to never go below size() in change_capacity(), enforcing the same invariant that std::vector maintains (capacity >= size).
Without this guard, if change_capacity() is called with new_capacity < size(), two problems arise:
- Indirect-to-direct transition:
memcpycopiessize()elements into the direct buffer which only holdsNelements — a heap buffer overflow. - Indirect-to-indirect realloc: the buffer shrinks below the number of live elements — subsequent access is out-of-bounds.
While no current caller triggers either case, the 1.5x growth computation (new_size + (new_size >> 1)) wraps around uint32_t when new_size > 0xAAAAAAAA, producing a small value that would hit this path. The clamp prevents this overflow from becoming a heap buffer overflow.
This is the same class of latent issue fixed in a7af72a697 ("prevector::swap: fix (unreached) data corruption").
Test plan
Verified with a standalone test exercising indirect-to-direct transitions, grow+shrink cycles, and the capacity >= size invariant. Existing PrevectorTestInt randomized tests are unaffected (the clamp is a no-op for all valid callers).