From e23f88bac26a0336951b7d6deb46b1ea11553633 Mon Sep 17 00:00:00 2001 From: Marc Mutz Date: Thu, 16 Feb 2023 08:42:27 +0100 Subject: [PATCH] QVarLengthArray: fix UBs in insert(it, n, v) ([basic.life], invariants) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit In the same vein as e24df8bc726d12e80f3f1d14834f9305586fcc98 for emplace(it, v) and insert(it, rv), this patch addresses the identical issues in insert(it, n, v). The solution is unsurprisingly the same: q_rotate() after a resize(size() + n, v). The 6.2- code will need to look different, because resize(n, v) didn't exist there. Change-Id: I1ce91969abc20f2a1e5d05a8545b009a2e0994f6 Reviewed-by: Fabian Kosmale Reviewed-by: Thiago Macieira Reviewed-by: MÃ¥rten Nordheim (cherry picked from commit fed5f2445480f7cf045e93761dc902f771cbf3da) Reviewed-by: Qt Cherry-pick Bot --- src/corelib/tools/qvarlengtharray.h | 28 ++++++---------------------- 1 file changed, 6 insertions(+), 22 deletions(-) diff --git a/src/corelib/tools/qvarlengtharray.h b/src/corelib/tools/qvarlengtharray.h index 6428c359c0e..d8dbe65b05c 100644 --- a/src/corelib/tools/qvarlengtharray.h +++ b/src/corelib/tools/qvarlengtharray.h @@ -862,28 +862,12 @@ Q_OUTOFLINE_TEMPLATE auto QVLABase::insert_impl(qsizetype prealloc, void *arr { Q_ASSERT_X(isValidIterator(before), "QVarLengthArray::insert", "The specified const_iterator argument 'before' is invalid"); - qsizetype offset = qsizetype(before - cbegin()); - if (n != 0) { - const T copy(t); // `t` could alias an element in [begin(), end()[ - resize_impl(prealloc, array, size() + n); - if constexpr (!QTypeInfo::isRelocatable) { - T *b = begin() + offset; - T *j = end(); - T *i = j - n; - while (i != b) - *--j = *--i; - i = b + n; - while (i != b) - *--i = copy; - } else { - T *b = begin() + offset; - T *i = b + n; - memmove(static_cast(i), static_cast(b), (size() - offset - n) * sizeof(T)); - while (i != b) - q20::construct_at(--i, copy); - } - } - return data() + offset; + const qsizetype offset = qsizetype(before - cbegin()); + resize_impl(prealloc, array, size() + n, t); + const auto b = begin() + offset; + const auto e = end(); + QtPrivate::q_rotate(b, e - n, e); + return b; } template