diff options
-rw-r--r-- | src/corelib/doc/snippets/code/src_corelib_tools_qbytearray.cpp | 8 | ||||
-rw-r--r-- | src/corelib/tools/qbytearray.cpp | 34 | ||||
-rw-r--r-- | src/corelib/tools/qbytearray.h | 41 | ||||
-rw-r--r-- | src/corelib/tools/qstring.cpp | 6 | ||||
-rw-r--r-- | src/corelib/tools/qstring.h | 25 |
5 files changed, 102 insertions, 12 deletions
diff --git a/src/corelib/doc/snippets/code/src_corelib_tools_qbytearray.cpp b/src/corelib/doc/snippets/code/src_corelib_tools_qbytearray.cpp index ec63e64fe9..11ab50687d 100644 --- a/src/corelib/doc/snippets/code/src_corelib_tools_qbytearray.cpp +++ b/src/corelib/doc/snippets/code/src_corelib_tools_qbytearray.cpp @@ -133,10 +133,10 @@ while (*data) { //! [9] -QByteArray ba; -for (int i = 0; i < 10; ++i) - ba[i] = 'A' + i; -// ba == "ABCDEFGHIJ" +QByteArray ba("Hello, world"); +cout << ba[0]; // prints H +ba[7] = 'W'; +// ba == "Hello, World" //! [9] diff --git a/src/corelib/tools/qbytearray.cpp b/src/corelib/tools/qbytearray.cpp index 720a91af49..c89fb078f7 100644 --- a/src/corelib/tools/qbytearray.cpp +++ b/src/corelib/tools/qbytearray.cpp @@ -1537,6 +1537,12 @@ QByteArray &QByteArray::operator=(const char *str) will apply to the character in the QByteArray from which you got the reference. + \note Before Qt 5.14 it was possible to use this operator to access + a character at an out-of-bounds position in the byte array, and + then assign to such position, causing the byte array to be + automatically resized. This behavior is deprecated, and will be + changed in a future version of Qt. + \sa at() */ @@ -5054,4 +5060,32 @@ QByteArray QByteArray::toPercentEncoding(const QByteArray &exclude, const QByteA \sa QStringLiteral */ +namespace QtPrivate { +namespace DeprecatedRefClassBehavior { +void warn(EmittingClass c) +{ + const char *emittingClassName = nullptr; + const char *containerClassName = nullptr; + switch (c) { + case EmittingClass::QByteRef: + emittingClassName = "QByteRef"; + containerClassName = "QByteArray"; + break; + case EmittingClass::QCharRef: + emittingClassName = "QCharRef"; + containerClassName = "QString"; + break; + } + + qWarning("Using %s with an index pointing outside" + " the valid range of a %s." + " The corresponding behavior is deprecated, and will be changed" + " in a future version of Qt.", + emittingClassName, + containerClassName); +} +} // namespace DeprecatedRefClassBehavior +} // namespace QtPrivate + + QT_END_NAMESPACE diff --git a/src/corelib/tools/qbytearray.h b/src/corelib/tools/qbytearray.h index d21cb9b363..5c7229e40d 100644 --- a/src/corelib/tools/qbytearray.h +++ b/src/corelib/tools/qbytearray.h @@ -528,6 +528,17 @@ inline void QByteArray::squeeze() } } +namespace QtPrivate { +namespace DeprecatedRefClassBehavior { + enum class EmittingClass { + QByteRef, + QCharRef, + }; + + Q_CORE_EXPORT Q_DECL_COLD_FUNCTION void warn(EmittingClass c); +} // namespace DeprecatedAssignmentOperatorBehavior +} // namespace QtPrivate + class #if QT_VERSION < QT_VERSION_CHECK(6, 0, 0) Q_CORE_EXPORT @@ -540,13 +551,33 @@ QByteRef { friend class QByteArray; public: inline operator char() const - { return i < a.d->size ? a.d->data()[i] : char(0); } + { + using namespace QtPrivate::DeprecatedRefClassBehavior; + if (Q_LIKELY(i < a.d->size)) + return a.d->data()[i]; +#ifdef QT_DEBUG + warn(EmittingClass::QByteRef); +#endif + return char(0); + } inline QByteRef &operator=(char c) - { if (i >= a.d->size) a.expand(i); else a.detach(); - a.d->data()[i] = c; return *this; } + { + using namespace QtPrivate::DeprecatedRefClassBehavior; + if (Q_UNLIKELY(i >= a.d->size)) { +#ifdef QT_DEBUG + warn(EmittingClass::QByteRef); +#endif + a.expand(i); + } else { + a.detach(); + } + a.d->data()[i] = c; + return *this; + } inline QByteRef &operator=(const QByteRef &c) - { if (i >= a.d->size) a.expand(i); else a.detach(); - a.d->data()[i] = c.a.d->data()[c.i]; return *this; } + { + return operator=(char(c)); + } inline bool operator==(char c) const { return a.d->data()[i] == c; } inline bool operator!=(char c) const diff --git a/src/corelib/tools/qstring.cpp b/src/corelib/tools/qstring.cpp index a5396bfb69..c73474684b 100644 --- a/src/corelib/tools/qstring.cpp +++ b/src/corelib/tools/qstring.cpp @@ -5782,6 +5782,12 @@ QString QString::trimmed_helper(QString &str) were a QChar &. If you assign to it, the assignment will apply to the character in the QString from which you got the reference. + \note Before Qt 5.14 it was possible to use this operator to access + a character at an out-of-bounds position in the string, and + then assign to such position, causing the string to be + automatically resized. This behavior is deprecated, and will be + changed in a future version of Qt. + \sa at() */ diff --git a/src/corelib/tools/qstring.h b/src/corelib/tools/qstring.h index 1abb91eabe..1feb8e186c 100644 --- a/src/corelib/tools/qstring.h +++ b/src/corelib/tools/qstring.h @@ -1060,10 +1060,29 @@ public: // all this is not documented: We just say "like QChar" and let it be. inline operator QChar() const - { return i < s.d->size ? s.d->data()[i] : 0; } + { + using namespace QtPrivate::DeprecatedRefClassBehavior; + if (Q_LIKELY(i < s.d->size)) + return s.d->data()[i]; +#ifdef QT_DEBUG + warn(EmittingClass::QCharRef); +#endif + return 0; + } inline QCharRef &operator=(QChar c) - { if (i >= s.d->size) s.resize(i + 1, QLatin1Char(' ')); else s.detach(); - s.d->data()[i] = c.unicode(); return *this; } + { + using namespace QtPrivate::DeprecatedRefClassBehavior; + if (Q_UNLIKELY(i >= s.d->size)) { +#ifdef QT_DEBUG + warn(EmittingClass::QCharRef); +#endif + s.resize(i + 1, QLatin1Char(' ')); + } else { + s.detach(); + } + s.d->data()[i] = c.unicode(); + return *this; + } // An operator= for each QChar cast constructors #ifndef QT_NO_CAST_FROM_ASCII |