Add a macro to disable only some 8 bit/16 bit string conversions
This is an opt-in trade-off between type safety and user code convenience. QT_NO_CAST_FROM_ASCII is highly beneficial to avoid unintended conversions from 8 bit data with potentially "unsuitable" encodings to QString. However, it has the undesirable side-effect to require user code to wrap character and string literals in QLatin1Char(...) and QLatin1String(...) or use similar construction, cluttering the code significantly. This patch introduces a QT_RESTRICTED_CAST_FROM_ASCII macro that works almost as QT_NO_CAST_FROM_ASCII, except that it enables the QChar(char) constructor and adds an additional QString(const char (&ch)[N]) constructor that matches C++ string literals, but no arbitrary character pointers. This avoids a significant share of the need to clutter the user code by only a slight relaxation of the type-safety. [ChangeLog][QtCore][QString] Added QT_RESTRICTED_CAST_FROM_ASCII macro as less intrusive alternative to QT_NO_CAST_FROM_ASCII. Change-Id: Iac72f1f90f81fbcae9bfb1fe68b0fec6ffb36c50 Reviewed-by: Oswald Buddenhagen <oswald.buddenhagen@digia.com> Reviewed-by: Kai Koehne <kai.koehne@digia.com> Reviewed-by: Eike Ziller <eike.ziller@digia.com> Reviewed-by: Thiago Macieira <thiago.macieira@intel.com> Reviewed-by: Olivier Goffart <ogoffart@woboq.com>
This commit is contained in:
parent
3759749466
commit
7dd394a16c
@ -83,7 +83,9 @@ public:
|
||||
|
||||
#ifndef QT_NO_CAST_FROM_ASCII
|
||||
QT_ASCII_CAST_WARN Q_DECL_CONSTEXPR explicit QChar(char c) : ucs(uchar(c)) { }
|
||||
#ifndef QT_RESTRICTED_CAST_FROM_ASCII
|
||||
QT_ASCII_CAST_WARN Q_DECL_CONSTEXPR explicit QChar(uchar c) : ucs(c) { }
|
||||
#endif
|
||||
#endif
|
||||
// Unicode information
|
||||
|
||||
|
@ -731,13 +731,31 @@ inline char qToLower(char ch)
|
||||
|
||||
const QString::Null QString::null = { };
|
||||
|
||||
/*!
|
||||
\macro QT_RESTRICTED_CAST_FROM_ASCII
|
||||
\relates QString
|
||||
|
||||
Defining this macro disables most automatic conversions from source
|
||||
literals and 8-bit data to unicode QStrings, but allows the use of
|
||||
the \c{QChar(char)} and \c{QString(const char (&ch)[N]} constructors,
|
||||
and the \c{QString::operator=(const char (&ch)[N])} assignment operator
|
||||
giving most of the type-safety benefits of QT_NO_CAST_FROM_ASCII
|
||||
but does not require user code to wrap character and string literals
|
||||
with QLatin1Char, QLatin1String or similar.
|
||||
|
||||
Using this macro together with source strings outside the 7-bit range,
|
||||
non-literals, or literals with embedded NUL characters is undefined.
|
||||
|
||||
\sa QT_NO_CAST_FROM_ASCII, QT_NO_CAST_TO_ASCII
|
||||
*/
|
||||
|
||||
/*!
|
||||
\macro QT_NO_CAST_FROM_ASCII
|
||||
\relates QString
|
||||
|
||||
Disables automatic conversions from 8-bit strings (char *) to unicode QStrings
|
||||
|
||||
\sa QT_NO_CAST_TO_ASCII, QT_NO_CAST_FROM_BYTEARRAY
|
||||
\sa QT_NO_CAST_TO_ASCII, QT_RESTRICTED_CAST_FROM_ASCII, QT_NO_CAST_FROM_BYTEARRAY
|
||||
*/
|
||||
|
||||
/*!
|
||||
@ -746,7 +764,7 @@ const QString::Null QString::null = { };
|
||||
|
||||
disables automatic conversion from QString to 8-bit strings (char *)
|
||||
|
||||
\sa QT_NO_CAST_FROM_ASCII, QT_NO_CAST_FROM_BYTEARRAY
|
||||
\sa QT_NO_CAST_FROM_ASCII, QT_RESTRICTED_CAST_FROM_ASCII, QT_NO_CAST_FROM_BYTEARRAY
|
||||
*/
|
||||
|
||||
/*!
|
||||
@ -760,7 +778,7 @@ const QString::Null QString::null = { };
|
||||
Note: This only works for compilers that support warnings for
|
||||
deprecated API.
|
||||
|
||||
\sa QT_NO_CAST_TO_ASCII, QT_NO_CAST_FROM_ASCII
|
||||
\sa QT_NO_CAST_TO_ASCII, QT_NO_CAST_FROM_ASCII, QT_RESTRICTED_CAST_FROM_ASCII
|
||||
*/
|
||||
|
||||
/*!
|
||||
@ -994,6 +1012,9 @@ const QString::Null QString::null = { };
|
||||
\list
|
||||
\li \c QT_NO_CAST_FROM_ASCII disables automatic conversions from
|
||||
C string literals and pointers to Unicode.
|
||||
\li \c QT_RESTRICTED_CAST_FROM_ASCII allows automatic conversions
|
||||
from C characters and character arrays, but disables automatic
|
||||
conversions from character pointers to Unicode.
|
||||
\li \c QT_NO_CAST_TO_ASCII disables automatic conversion from QString
|
||||
to C strings.
|
||||
\endlist
|
||||
@ -1311,6 +1332,12 @@ const QString::Null QString::null = { };
|
||||
can be useful if you want to ensure that all user-visible strings
|
||||
go through QObject::tr(), for example.
|
||||
|
||||
\note Defining QT_RESTRICTED_CAST_FROM_ASCII also disables
|
||||
this constructor, but enables a \c{QString(const char (&ch)[N])}
|
||||
constructor instead. Using non-literal input, or input with
|
||||
embedded NUL characters, or non-7-bit characters is undefined
|
||||
in this case.
|
||||
|
||||
\sa fromLatin1(), fromLocal8Bit(), fromUtf8()
|
||||
*/
|
||||
|
||||
@ -1749,10 +1776,11 @@ QString &QString::operator=(const QString &other)
|
||||
Assigns \a str to this string. The const char pointer is converted
|
||||
to Unicode using the fromUtf8() function.
|
||||
|
||||
You can disable this operator by defining \c
|
||||
QT_NO_CAST_FROM_ASCII when you compile your applications. This
|
||||
can be useful if you want to ensure that all user-visible strings
|
||||
You can disable this operator by defining \c QT_NO_CAST_FROM_ASCII
|
||||
or \c QT_RESTRICTED_CAST_FROM_ASCII when you compile your applications.
|
||||
This can be useful if you want to ensure that all user-visible strings
|
||||
go through QObject::tr(), for example.
|
||||
|
||||
*/
|
||||
|
||||
/*! \fn QString &QString::operator=(char ch)
|
||||
|
@ -34,6 +34,10 @@
|
||||
#ifndef QSTRING_H
|
||||
#define QSTRING_H
|
||||
|
||||
#if defined(QT_NO_CAST_FROM_ASCII) && defined(QT_RESTRICTED_CAST_FROM_ASCII)
|
||||
#error QT_NO_CAST_FROM_ASCII and QT_RESTRICTED_CAST_FROM_ASCII must not be defined at the same time
|
||||
#endif
|
||||
|
||||
#include <QtCore/qchar.h>
|
||||
#include <QtCore/qbytearray.h>
|
||||
#include <QtCore/qrefcount.h>
|
||||
@ -93,7 +97,7 @@ public:
|
||||
inline bool operator>=(const QString &s) const;
|
||||
inline bool operator<=(const QString &s) const;
|
||||
|
||||
#ifndef QT_NO_CAST_FROM_ASCII
|
||||
#if !defined(QT_NO_CAST_FROM_ASCII) && !defined(QT_RESTRICTED_CAST_FROM_ASCII)
|
||||
inline QT_ASCII_CAST_WARN bool operator==(const char *s) const;
|
||||
inline QT_ASCII_CAST_WARN bool operator!=(const char *s) const;
|
||||
inline QT_ASCII_CAST_WARN bool operator<(const char *s) const;
|
||||
@ -107,7 +111,7 @@ public:
|
||||
inline QT_ASCII_CAST_WARN bool operator>(const QByteArray &s) const;
|
||||
inline QT_ASCII_CAST_WARN bool operator<=(const QByteArray &s) const;
|
||||
inline QT_ASCII_CAST_WARN bool operator>=(const QByteArray &s) const;
|
||||
#endif // QT_NO_CAST_FROM_ASCII
|
||||
#endif // !defined(QT_NO_CAST_FROM_ASCII) && !defined(QT_RESTRICTED_CAST_FROM_ASCII)
|
||||
|
||||
private:
|
||||
int m_size;
|
||||
@ -623,7 +627,16 @@ public:
|
||||
inline bool operator>=(QLatin1String s) const { return !operator<(s); }
|
||||
|
||||
// ASCII compatibility
|
||||
#ifndef QT_NO_CAST_FROM_ASCII
|
||||
#if defined(QT_RESTRICTED_CAST_FROM_ASCII)
|
||||
template <int N>
|
||||
inline QString(const char (&ch)[N])
|
||||
: d(fromAscii_helper(ch, N - 1))
|
||||
{}
|
||||
template <int N>
|
||||
inline QString &operator=(const char (&ch)[N])
|
||||
{ return (*this = fromLatin1(ch, N - 1)); }
|
||||
#endif
|
||||
#if !defined(QT_NO_CAST_FROM_ASCII) && !defined(QT_RESTRICTED_CAST_FROM_ASCII)
|
||||
inline QT_ASCII_CAST_WARN QString(const char *ch)
|
||||
: d(fromAscii_helper(ch, ch ? int(strlen(ch)) : -1))
|
||||
{}
|
||||
@ -1116,7 +1129,7 @@ inline bool QLatin1String::operator>=(const QString &s) const
|
||||
inline bool QLatin1String::operator<=(const QString &s) const
|
||||
{ return s >= *this; }
|
||||
|
||||
#ifndef QT_NO_CAST_FROM_ASCII
|
||||
#if !defined(QT_NO_CAST_FROM_ASCII) && !defined(QT_RESTRICTED_CAST_FROM_ASCII)
|
||||
inline bool QString::operator==(const char *s) const
|
||||
{ return QString::compare_helper(constData(), size(), s, -1) == 0; }
|
||||
inline bool QString::operator!=(const char *s) const
|
||||
@ -1207,7 +1220,7 @@ inline bool QByteArray::operator<=(const QString &s) const
|
||||
{ return QString::compare_helper(s.constData(), s.size(), constData(), qstrnlen(constData(), size())) <= 0; }
|
||||
inline bool QByteArray::operator>=(const QString &s) const
|
||||
{ return QString::compare_helper(s.constData(), s.size(), constData(), qstrnlen(constData(), size())) >= 0; }
|
||||
#endif // QT_NO_CAST_FROM_ASCII
|
||||
#endif // !defined(QT_NO_CAST_FROM_ASCII) && !defined(QT_RESTRICTED_CAST_FROM_ASCII)
|
||||
|
||||
#ifndef QT_NO_CAST_TO_ASCII
|
||||
inline QByteArray &QByteArray::append(const QString &s)
|
||||
@ -1235,7 +1248,7 @@ inline const QString operator+(const QString &s1, QChar s2)
|
||||
{ QString t(s1); t += s2; return t; }
|
||||
inline const QString operator+(QChar s1, const QString &s2)
|
||||
{ QString t(s1); t += s2; return t; }
|
||||
# ifndef QT_NO_CAST_FROM_ASCII
|
||||
# if !defined(QT_NO_CAST_FROM_ASCII) && !defined(QT_RESTRICTED_CAST_FROM_ASCII)
|
||||
inline QT_ASCII_CAST_WARN const QString operator+(const QString &s1, const char *s2)
|
||||
{ QString t(s1); t += QString::fromUtf8(s2); return t; }
|
||||
inline QT_ASCII_CAST_WARN const QString operator+(const char *s1, const QString &s2)
|
||||
@ -1388,7 +1401,7 @@ public:
|
||||
inline const QChar at(int i) const
|
||||
{ Q_ASSERT(uint(i) < uint(size())); return m_string->at(i + m_position); }
|
||||
|
||||
#ifndef QT_NO_CAST_FROM_ASCII
|
||||
#if !defined(QT_NO_CAST_FROM_ASCII) && !defined(QT_RESTRICTED_CAST_FROM_ASCII)
|
||||
// ASCII compatibility
|
||||
inline QT_ASCII_CAST_WARN bool operator==(const char *s) const;
|
||||
inline QT_ASCII_CAST_WARN bool operator!=(const char *s) const;
|
||||
@ -1462,7 +1475,7 @@ inline bool operator<=(const QStringRef &s1, const QStringRef &s2)
|
||||
inline bool operator>=(const QStringRef &s1, const QStringRef &s2)
|
||||
{ return !(s1 < s2); }
|
||||
|
||||
#ifndef QT_NO_CAST_FROM_ASCII
|
||||
#if !defined(QT_NO_CAST_FROM_ASCII) && !defined(QT_RESTRICTED_CAST_FROM_ASCII)
|
||||
inline QT_ASCII_CAST_WARN bool QStringRef::operator==(const char *s) const
|
||||
{ return QString::compare_helper(constData(), size(), s, -1) == 0; }
|
||||
inline QT_ASCII_CAST_WARN bool QStringRef::operator!=(const char *s) const
|
||||
@ -1488,7 +1501,7 @@ inline QT_ASCII_CAST_WARN bool operator>(const char *s1, const QStringRef &s2)
|
||||
{ return QString::compare_helper(s2.constData(), s2.size(), s1, -1) <= 0; }
|
||||
inline QT_ASCII_CAST_WARN bool operator>=(const char *s1, const QStringRef &s2)
|
||||
{ return QString::compare_helper(s2.constData(), s2.size(), s1, -1) >= 0; }
|
||||
#endif // QT_NO_CAST_FROM_ASCII
|
||||
#endif // !defined(QT_NO_CAST_FROM_ASCII) && !defined(QT_RESTRICTED_CAST_FROM_ASCII)
|
||||
|
||||
inline int QString::compare(const QStringRef &s, Qt::CaseSensitivity cs) const
|
||||
{ return QString::compare_helper(constData(), length(), s.constData(), s.length(), cs); }
|
||||
|
Loading…
Reference in New Issue
Block a user