summaryrefslogtreecommitdiffstats
path: root/src/corelib/text
diff options
context:
space:
mode:
authorLars Knoll <lars.knoll@qt.io>2020-06-02 15:51:15 +0200
committerLars Knoll <lars.knoll@qt.io>2020-06-09 16:51:16 +0200
commitd2833a3ce5af725d66ef9338f2a61b766dd3cb2d (patch)
tree3b74823b5f2da7cfd179e4faeed1697c4ff14d09 /src/corelib/text
parentfd856532d7472ccc6daf6a95d5c28264d9e6adca (diff)
Ensure left/right/mid behave in a compatible way
QString and QStringRef did bounds checking for left/right/mid, whereas QStringView was asserting on out of bounds. Relax the behavior for QStringView and do bounds checking on pos/n as well. This removes a source of potentially hidden errors when porting from QStringRef (or QString) to QStringView. Unfortunately, one difference remains, where QByteArray::left/right() behaves differently (and somewhat more sane) than QString and QStringRef. We're keeping the difference here, as it has been around for many years. Mark left/right/mid as obsolete and to be replaced with the new first/last/slice methods. Change-Id: I18c203799ba78c928a4610a6038089f27696c22e Reviewed-by: MÃ¥rten Nordheim <marten.nordheim@qt.io>
Diffstat (limited to 'src/corelib/text')
-rw-r--r--src/corelib/text/qbytearray.cpp23
-rw-r--r--src/corelib/text/qstring.cpp53
-rw-r--r--src/corelib/text/qstring.h28
-rw-r--r--src/corelib/text/qstringview.cpp37
-rw-r--r--src/corelib/text/qstringview.h26
5 files changed, 99 insertions, 68 deletions
diff --git a/src/corelib/text/qbytearray.cpp b/src/corelib/text/qbytearray.cpp
index 008ce7298b..3f83e36d90 100644
--- a/src/corelib/text/qbytearray.cpp
+++ b/src/corelib/text/qbytearray.cpp
@@ -2914,13 +2914,17 @@ bool QByteArray::isLower() const
Returns a byte array that contains the first \a len bytes of this byte
array.
+ \obsolete Use first() instead in new code.
+
The entire byte array is returned if \a len is greater than
size().
+ Returns an empty QByteArray if \a len is smaller than 0.
+
Example:
\snippet code/src_corelib_text_qbytearray.cpp 27
- \sa startsWith(), right(), mid(), chopped(), chop(), truncate()
+ \sa first(), last(), startsWith(), chopped(), chop(), truncate()
*/
QByteArray QByteArray::left(int len) const
@@ -2935,15 +2939,18 @@ QByteArray QByteArray::left(int len) const
/*!
Returns a byte array that contains the last \a len bytes of this byte array.
+ \obsolete Use last() instead in new code.
+
The entire byte array is returned if \a len is greater than
size().
+ Returns an empty QByteArray if \a len is smaller than 0.
+
Example:
\snippet code/src_corelib_text_qbytearray.cpp 28
- \sa endsWith(), left(), mid(), chopped(), chop(), truncate()
+ \sa endsWith(), last(), first(), slice(), chopped(), chop(), truncate()
*/
-
QByteArray QByteArray::right(int len) const
{
if (len >= size())
@@ -2957,6 +2964,8 @@ QByteArray QByteArray::right(int len) const
Returns a byte array containing \a len bytes from this byte array,
starting at position \a pos.
+ \obsolete Use slice() instead in new code.
+
If \a len is -1 (the default), or \a pos + \a len >= size(),
returns a byte array containing all bytes starting at position \a
pos until the end of the byte array.
@@ -2964,13 +2973,15 @@ QByteArray QByteArray::right(int len) const
Example:
\snippet code/src_corelib_text_qbytearray.cpp 29
- \sa left(), right(), chopped(), chop(), truncate()
+ \sa first(), last(), slice(), chopped(), chop(), truncate()
*/
QByteArray QByteArray::mid(int pos, int len) const
{
+ qsizetype p = pos;
+ qsizetype l = len;
using namespace QtPrivate;
- switch (QContainerImplHelper::mid(size(), &pos, &len)) {
+ switch (QContainerImplHelper::mid(size(), &p, &l)) {
case QContainerImplHelper::Null:
return QByteArray();
case QContainerImplHelper::Empty:
@@ -2982,7 +2993,7 @@ QByteArray QByteArray::mid(int pos, int len) const
case QContainerImplHelper::Full:
return *this;
case QContainerImplHelper::Subset:
- return QByteArray(d.data() + pos, len);
+ return QByteArray(d.data() + p, l);
}
Q_UNREACHABLE();
return QByteArray();
diff --git a/src/corelib/text/qstring.cpp b/src/corelib/text/qstring.cpp
index 6707cc580e..5e3debcc34 100644
--- a/src/corelib/text/qstring.cpp
+++ b/src/corelib/text/qstring.cpp
@@ -4530,12 +4530,14 @@ QString QString::section(const QRegularExpression &re, int start, int end, Secti
Returns a substring that contains the \a n leftmost characters
of the string.
+ \obsolete Use first() instead in new code.
+
The entire string is returned if \a n is greater than or equal
to size(), or less than zero.
\snippet qstring/main.cpp 31
- \sa right(), mid(), startsWith(), chopped(), chop(), truncate()
+ \sa first(), last(), startsWith(), chopped(), chop(), truncate()
*/
QString QString::left(int n) const
{
@@ -4548,12 +4550,14 @@ QString QString::left(int n) const
Returns a substring that contains the \a n rightmost characters
of the string.
+ \obsolete Use last() instead in new code.
+
The entire string is returned if \a n is greater than or equal
to size(), or less than zero.
\snippet qstring/main.cpp 48
- \sa left(), mid(), endsWith(), chopped(), chop(), truncate()
+ \sa endsWith(), last(), first(), slice(), chopped(), chop(), truncate()
*/
QString QString::right(int n) const
{
@@ -4566,6 +4570,8 @@ QString QString::right(int n) const
Returns a string that contains \a n characters of this string,
starting at the specified \a position index.
+ \obsolete Use slice() instead in new code.
+
Returns a null string if the \a position index exceeds the
length of the string. If there are less than \a n characters
available in the string starting at the given \a position, or if
@@ -4576,13 +4582,15 @@ QString QString::right(int n) const
\snippet qstring/main.cpp 34
- \sa left(), right(), chopped(), chop(), truncate()
+ \sa first(), last(), slice(), chopped(), chop(), truncate()
*/
QString QString::mid(int position, int n) const
{
+ qsizetype p = position;
+ qsizetype l = n;
using namespace QtPrivate;
- switch (QContainerImplHelper::mid(size(), &position, &n)) {
+ switch (QContainerImplHelper::mid(size(), &p, &l)) {
case QContainerImplHelper::Null:
return QString();
case QContainerImplHelper::Empty:
@@ -4594,7 +4602,7 @@ QString QString::mid(int position, int n) const
case QContainerImplHelper::Full:
return *this;
case QContainerImplHelper::Subset:
- return QString(constData() + position, n);
+ return QString(constData() + p, l);
}
Q_UNREACHABLE();
return QString();
@@ -9375,28 +9383,17 @@ QString &QString::setRawData(const QChar *unicode, int size)
\sa crbegin(), rend(), cend()
*/
-/*! \fn QLatin1String QLatin1String::mid(int start) const
- \since 5.8
-
- Returns the substring starting at position \a start in this object,
- and extending to the end of the string.
-
- \note This function performs no error checking.
- The behavior is undefined when \a start < 0 or \a start > size().
-
- \sa left(), right(), chopped(), chop(), truncate()
-*/
-
/*! \fn QLatin1String QLatin1String::mid(int start, int length) const
\since 5.8
- \overload
Returns the substring of length \a length starting at position
\a start in this object.
- \note This function performs no error checking.
- The behavior is undefined when \a start < 0, \a length < 0,
- or \a start + \a length > size().
+ Returns a null string if the \a start index exceeds the
+ length of the string. If there are less than \a length characters
+ available in the string starting at \a start, or if
+ \a length is negative (default), the function returns all characters
+ that are available from \a start.
\sa left(), right(), chopped(), chop(), truncate()
*/
@@ -9407,8 +9404,8 @@ QString &QString::setRawData(const QChar *unicode, int size)
Returns the substring of length \a length starting at position
0 in this object.
- \note This function performs no error checking.
- The behavior is undefined when \a length < 0 or \a length > size().
+ The entire string is returned if \a length is greater than or equal
+ to size(), or less than zero.
\sa mid(), right(), chopped(), chop(), truncate()
*/
@@ -9419,8 +9416,8 @@ QString &QString::setRawData(const QChar *unicode, int size)
Returns the substring of length \a length starting at position
size() - \a length in this object.
- \note This function performs no error checking.
- The behavior is undefined when \a length < 0 or \a length > size().
+ The entire string is returned if \a length is greater than or equal
+ to size(), or less than zero.
\sa mid(), left(), chopped(), chop(), truncate()
*/
@@ -10777,8 +10774,10 @@ QStringRef QString::rightRef(int n) const
*/
QStringRef QStringRef::mid(int pos, int n) const
{
+ qsizetype p = pos;
+ qsizetype l = n;
using namespace QtPrivate;
- switch (QContainerImplHelper::mid(m_size, &pos, &n)) {
+ switch (QContainerImplHelper::mid(m_size, &p, &l)) {
case QContainerImplHelper::Null:
return QStringRef();
case QContainerImplHelper::Empty:
@@ -10786,7 +10785,7 @@ QStringRef QStringRef::mid(int pos, int n) const
case QContainerImplHelper::Full:
return *this;
case QContainerImplHelper::Subset:
- return QStringRef(m_string, pos + m_position, n);
+ return QStringRef(m_string, p + m_position, l);
}
Q_UNREACHABLE();
return QStringRef();
diff --git a/src/corelib/text/qstring.h b/src/corelib/text/qstring.h
index c0b23c9733..efd57328bb 100644
--- a/src/corelib/text/qstring.h
+++ b/src/corelib/text/qstring.h
@@ -179,14 +179,26 @@ public:
const_reverse_iterator rend() const noexcept { return const_reverse_iterator(begin()); }
const_reverse_iterator crend() const noexcept { return const_reverse_iterator(begin()); }
- Q_DECL_CONSTEXPR QLatin1String mid(int pos) const
- { return Q_ASSERT(pos >= 0), Q_ASSERT(pos <= size()), QLatin1String(m_data + pos, m_size - pos); }
- Q_DECL_CONSTEXPR QLatin1String mid(int pos, int n) const
- { return Q_ASSERT(pos >= 0), Q_ASSERT(n >= 0), Q_ASSERT(pos + n <= size()), QLatin1String(m_data + pos, n); }
- Q_DECL_CONSTEXPR QLatin1String left(int n) const
- { return Q_ASSERT(n >= 0), Q_ASSERT(n <= size()), QLatin1String(m_data, n); }
- Q_DECL_CONSTEXPR QLatin1String right(int n) const
- { return Q_ASSERT(n >= 0), Q_ASSERT(n <= size()), QLatin1String(m_data + m_size - n, n); }
+ constexpr QLatin1String mid(int pos, int n = -1) const
+ {
+ qsizetype p = pos;
+ qsizetype l = n;
+ using namespace QtPrivate;
+ auto result = QContainerImplHelper::mid(size(), &p, &l);
+ return result == QContainerImplHelper::Null ? QLatin1String() : QLatin1String(m_data + p, l);
+ }
+ constexpr QLatin1String left(int n) const
+ {
+ if (size_t(n) >= size_t(size()))
+ n = size();
+ return QLatin1String(m_data, n);
+ }
+ constexpr QLatin1String right(int n) const
+ {
+ if (size_t(n) >= size_t(size()))
+ n = size();
+ return QLatin1String(m_data + m_size - n, n);
+ }
Q_REQUIRED_RESULT Q_DECL_CONSTEXPR QLatin1String chopped(int n) const
{ return Q_ASSERT(n >= 0), Q_ASSERT(n <= size()), QLatin1String(m_data, m_size - n); }
diff --git a/src/corelib/text/qstringview.cpp b/src/corelib/text/qstringview.cpp
index b9dc9d2d41..42d18851c7 100644
--- a/src/corelib/text/qstringview.cpp
+++ b/src/corelib/text/qstringview.cpp
@@ -611,49 +611,48 @@ QT_BEGIN_NAMESPACE
*/
/*!
- \fn QStringView QStringView::mid(qsizetype start) const
-
- Returns the substring starting at position \a start in this object,
- and extending to the end of the string.
-
- \note The behavior is undefined when \a start < 0 or \a start > size().
-
- \sa left(), right(), chopped(), chop(), truncate()
-*/
-
-/*!
\fn QStringView QStringView::mid(qsizetype start, qsizetype length) const
- \overload
Returns the substring of length \a length starting at position
\a start in this object.
- \note The behavior is undefined when \a start < 0, \a length < 0,
- or \a start + \a length > size().
+ \obsolete Use slice() instead in new code.
- \sa left(), right(), chopped(), chop(), truncate()
+ Returns an empty string view if \a start exceeds the
+ length of the string. If there are less than \a length characters
+ available in the string starting at \a start, or if
+ \a length is negative (default), the function returns all characters that
+ are available from \a start.
+
+ \sa first(), last(), slice(), chopped(), chop(), truncate()
*/
/*!
\fn QStringView QStringView::left(qsizetype length) const
+ \obsolete Use first() instead in new code.
+
Returns the substring of length \a length starting at position
0 in this object.
- \note The behavior is undefined when \a length < 0 or \a length > size().
+ The entire string is returned if \a length is greater than or equal
+ to size(), or less than zero.
- \sa mid(), right(), chopped(), chop(), truncate()
+ \sa first(), last(), slice(), startsWith(), chopped(), chop(), truncate()
*/
/*!
\fn QStringView QStringView::right(qsizetype length) const
+ \obsolete Use last() instead in new code.
+
Returns the substring of length \a length starting at position
size() - \a length in this object.
- \note The behavior is undefined when \a length < 0 or \a length > size().
+ The entire string is returned if \a length is greater than or equal
+ to size(), or less than zero.
- \sa mid(), left(), chopped(), chop(), truncate()
+ \sa first(), last(), slice(), endsWith(), chopped(), chop(), truncate()
*/
/*!
diff --git a/src/corelib/text/qstringview.h b/src/corelib/text/qstringview.h
index 2b085c769d..6dbec21165 100644
--- a/src/corelib/text/qstringview.h
+++ b/src/corelib/text/qstringview.h
@@ -257,14 +257,24 @@ public:
Q_REQUIRED_RESULT Q_DECL_CONSTEXPR QChar at(qsizetype n) const { return (*this)[n]; }
- Q_REQUIRED_RESULT Q_DECL_CONSTEXPR QStringView mid(qsizetype pos) const
- { return Q_ASSERT(pos >= 0), Q_ASSERT(pos <= size()), QStringView(m_data + pos, m_size - pos); }
- Q_REQUIRED_RESULT Q_DECL_CONSTEXPR QStringView mid(qsizetype pos, qsizetype n) const
- { return Q_ASSERT(pos >= 0), Q_ASSERT(n >= 0), Q_ASSERT(pos + n <= size()), QStringView(m_data + pos, n); }
- Q_REQUIRED_RESULT Q_DECL_CONSTEXPR QStringView left(qsizetype n) const
- { return Q_ASSERT(n >= 0), Q_ASSERT(n <= size()), QStringView(m_data, n); }
- Q_REQUIRED_RESULT Q_DECL_CONSTEXPR QStringView right(qsizetype n) const
- { return Q_ASSERT(n >= 0), Q_ASSERT(n <= size()), QStringView(m_data + m_size - n, n); }
+ Q_REQUIRED_RESULT constexpr QStringView mid(qsizetype pos, qsizetype n = -1) const
+ {
+ using namespace QtPrivate;
+ auto result = QContainerImplHelper::mid(size(), &pos, &n);
+ return result == QContainerImplHelper::Null ? QStringView() : QStringView(m_data + pos, n);
+ }
+ Q_REQUIRED_RESULT constexpr QStringView left(qsizetype n) const
+ {
+ if (size_t(n) >= size_t(size()))
+ n = size();
+ return QStringView(m_data, n);
+ }
+ Q_REQUIRED_RESULT constexpr QStringView right(qsizetype n) const
+ {
+ if (size_t(n) >= size_t(size()))
+ n = size();
+ return QStringView(m_data + m_size - n, n);
+ }
Q_REQUIRED_RESULT constexpr QStringView first(qsizetype n) const
{ Q_ASSERT(n >= 0); Q_ASSERT(n <= size()); return QStringView(m_data, int(n)); }