include/rtl/strbuf.hxx | 11 +------- include/rtl/stringutils.hxx | 19 ++++++++++++++ include/rtl/ustrbuf.hxx | 58 +++++++++++--------------------------------- 3 files changed, 36 insertions(+), 52 deletions(-)
New commits: commit 30e52b155cb21d0ad61acb0a857fbe52c88a6816 Author: Mike Kaganski <mike.kagan...@collabora.com> AuthorDate: Fri Aug 30 10:47:05 2024 +0200 Commit: Mike Kaganski <mike.kagan...@collabora.com> CommitDate: Fri Aug 30 20:59:16 2024 +0200 Simplify a bit Change-Id: Icaf2e821984d9cdb16dbc4910b65b9b2b824435a Reviewed-on: https://gerrit.libreoffice.org/c/core/+/172583 Reviewed-by: Mike Kaganski <mike.kagan...@collabora.com> Tested-by: Jenkins diff --git a/include/rtl/strbuf.hxx b/include/rtl/strbuf.hxx index 5fa769241444..dd37ecfce673 100644 --- a/include/rtl/strbuf.hxx +++ b/include/rtl/strbuf.hxx @@ -112,11 +112,7 @@ public: explicit OStringBuffer(T length, std::enable_if_t<std::is_integral_v<T>, int> = 0) : OStringBuffer(static_cast<sal_Int32>(length)) { - assert( - length >= 0 - && static_cast<std::make_unsigned_t<T>>(length) - <= static_cast<std::make_unsigned_t<sal_Int32>>( - std::numeric_limits<sal_Int32>::max())); + assert(libreoffice_internal::IsValidStrLen(length)); } // avoid (obvious) bugs explicit OStringBuffer(bool) = delete; @@ -142,11 +138,8 @@ public: #if defined LIBO_INTERNAL_ONLY OStringBuffer(std::string_view sv) : pData(nullptr) - , nCapacity( sv.length() + 16 ) + , nCapacity(libreoffice_internal::ThrowIfInvalidStrLen(sv.length(), 16) + 16) { - if (sv.size() > sal_uInt32(std::numeric_limits<sal_Int32>::max())) { - throw std::bad_alloc(); - } rtl_stringbuffer_newFromStr_WithLength( &pData, sv.data(), sv.length() ); } #else diff --git a/include/rtl/stringutils.hxx b/include/rtl/stringutils.hxx index 622542c7dab8..3a4775ba6d80 100644 --- a/include/rtl/stringutils.hxx +++ b/include/rtl/stringutils.hxx @@ -20,6 +20,8 @@ #include <cstddef> #if defined LIBO_INTERNAL_ONLY +#include <limits> +#include <new> #include <type_traits> #endif @@ -115,6 +117,23 @@ using OUStringChar = OUStringChar_ const; namespace libreoffice_internal { +#if defined LIBO_INTERNAL_ONLY +template <typename I, std::enable_if_t<std::is_integral_v<I>, int> = 0> +constexpr bool IsValidStrLen(I i, sal_Int32 margin = 0) +{ + assert(margin >= 0); + constexpr sal_uInt32 maxLen = std::numeric_limits<sal_Int32>::max(); + return i >= 0 && static_cast<std::make_unsigned_t<I>>(i) <= maxLen - margin; +} +template <typename I, std::enable_if_t<std::is_integral_v<I>, int> = 0> +sal_Int32 ThrowIfInvalidStrLen(I i, sal_Int32 margin = 0) +{ + if (!IsValidStrLen(i, margin)) + throw std::bad_alloc(); + return i; +} +#endif + /* These templates use SFINAE (Substitution failure is not an error) to help distinguish the various plain C string types: char*, const char*, char[N], const char[N], char[] and const char[]. diff --git a/include/rtl/ustrbuf.hxx b/include/rtl/ustrbuf.hxx index 30aa1959a67d..693ad905910f 100644 --- a/include/rtl/ustrbuf.hxx +++ b/include/rtl/ustrbuf.hxx @@ -114,11 +114,7 @@ public: explicit OUStringBuffer(T length, std::enable_if_t<std::is_integral_v<T>, int> = 0) : OUStringBuffer(static_cast<sal_Int32>(length)) { - assert( - length >= 0 - && static_cast<std::make_unsigned_t<T>>(length) - <= static_cast<std::make_unsigned_t<sal_Int32>>( - std::numeric_limits<sal_Int32>::max())); + assert(libreoffice_internal::IsValidStrLen(length)); } // avoid (obvious) bugs explicit OUStringBuffer(bool) = delete; @@ -144,11 +140,8 @@ public: #if defined LIBO_INTERNAL_ONLY OUStringBuffer(std::u16string_view sv) : pData(nullptr) - , nCapacity( sv.length() + 16 ) + , nCapacity(libreoffice_internal::ThrowIfInvalidStrLen(sv.length(), 16) + 16) { - if (sv.size() > sal_uInt32(std::numeric_limits<sal_Int32>::max())) { - throw std::bad_alloc(); - } rtl_uStringbuffer_newFromStr_WithLength( &pData, sv.data(), sv.length() ); } #else @@ -245,10 +238,8 @@ public: */ template< std::size_t N > OUStringBuffer( OUStringNumber< N >&& n ) - : pData(NULL) - , nCapacity( n.length + 16 ) + : OUStringBuffer(std::u16string_view(n)) { - rtl_uStringbuffer_newFromStr_WithLength( &pData, n.buf, n.length ); } #endif @@ -349,21 +340,9 @@ public: typename libreoffice_internal::ConstCharArrayDetector< T, OUStringBuffer &>::TypeUtf16 operator =(T & literal) { - sal_Int32 const n - = libreoffice_internal::ConstCharArrayDetector<T>::length; - if (n >= nCapacity) { - ensureCapacity(n + 16); //TODO: check for overflow - } - // For OUStringChar, which is covered by this template's ConstCharArrayDetector TypeUtf16 - // check, toPointer does not return a NUL-terminated string, so we can't just memcpy n+1 - // elements but rather need to add the terminating NUL manually: - std::memcpy( - pData->buffer, - libreoffice_internal::ConstCharArrayDetector<T>::toPointer(literal), - n * sizeof (sal_Unicode)); - pData->buffer[n] = ' - pData->length = n; - return *this; + return operator=( + std::u16string_view(libreoffice_internal::ConstCharArrayDetector<T>::toPointer(literal), + libreoffice_internal::ConstCharArrayDetector<T>::length)); } #endif @@ -969,10 +948,7 @@ public: #if defined LIBO_INTERNAL_ONLY OUStringBuffer & insert(sal_Int32 offset, std::u16string_view str) { - if (str.size() > sal_uInt32(std::numeric_limits<sal_Int32>::max())) { - throw std::bad_alloc(); - } - return insert( offset, str.data(), str.length() ); + return insert(offset, str.data(), libreoffice_internal::ThrowIfInvalidStrLen(str.length())); } #else OUStringBuffer & insert(sal_Int32 offset, const OUString & str) @@ -1148,8 +1124,7 @@ public: */ OUStringBuffer & insert(sal_Int32 offset, char c) { - sal_Unicode u = c; - return insert( offset, &u, 1 ); + return insert(offset, sal_Unicode(c)); } /** @@ -1491,12 +1466,10 @@ public: typename libreoffice_internal::ConstCharArrayDetector<T, sal_Int32>::TypeUtf16 indexOf(T & literal, sal_Int32 fromIndex = 0) const { - assert(fromIndex >= 0); - auto n = rtl_ustr_indexOfStr_WithLength( - pData->buffer + fromIndex, pData->length - fromIndex, - libreoffice_internal::ConstCharArrayDetector<T>::toPointer(literal), - libreoffice_internal::ConstCharArrayDetector<T>::length); - return n < 0 ? n : n + fromIndex; + return indexOf( + std::u16string_view(libreoffice_internal::ConstCharArrayDetector<T>::toPointer(literal), + libreoffice_internal::ConstCharArrayDetector<T>::length), + fromIndex); } #endif @@ -1588,10 +1561,9 @@ public: typename libreoffice_internal::ConstCharArrayDetector<T, sal_Int32>::TypeUtf16 lastIndexOf(T & literal) const { - return rtl_ustr_lastIndexOfStr_WithLength( - pData->buffer, pData->length, - libreoffice_internal::ConstCharArrayDetector<T>::toPointer(literal), - libreoffice_internal::ConstCharArrayDetector<T>::length); + return lastIndexOf( + std::u16string_view(libreoffice_internal::ConstCharArrayDetector<T>::toPointer(literal), + libreoffice_internal::ConstCharArrayDetector<T>::length)); } #endif