QString: preserve embedded NULs when converting from QByteArray
Unearthed an off-by-one error in a QByteArray::fromRawData() call in tst_qtextdocumentfragment. Fixed by porting to QStringLiteral. [ChangeLog][Important Behavior Changes] All conversions from QByteArray to QString now preserve embedded NULs. This is done in order to provide a faster conversion from QByteArray to QString that does not involve a call to strlen. If you need the old behavior, convert from QByteArray::constData() instead. If you are porting from Qt 4, we suggest to make your source compile with QT_NO_CAST_FROM_BYTEARRAY before porting to Qt 5. Change-Id: Ibca40f503920fee6f3a5f0d74a04b38b8849796f Reviewed-by: Thiago Macieira <thiago.macieira@intel.com>
This commit is contained in:
parent
6f145707eb
commit
e486d69133
@ -84,7 +84,7 @@ class QLatin1String
|
||||
public:
|
||||
Q_DECL_CONSTEXPR inline explicit QLatin1String(const char *s) : m_size(s ? int(strlen(s)) : 0), m_data(s) {}
|
||||
Q_DECL_CONSTEXPR inline explicit QLatin1String(const char *s, int sz) : m_size(sz), m_data(s) {}
|
||||
inline explicit QLatin1String(const QByteArray &s) : m_size(int(qstrnlen(s.constData(), s.size()))), m_data(s.constData()) {}
|
||||
inline explicit QLatin1String(const QByteArray &s) : m_size(s.size()), m_data(s.constData()) {}
|
||||
|
||||
inline const char *latin1() const { return m_data; }
|
||||
inline int size() const { return m_size; }
|
||||
@ -534,11 +534,11 @@ public:
|
||||
return fromLocal8Bit_helper(str, (str && size == -1) ? int(strlen(str)) : size);
|
||||
}
|
||||
static inline QString fromLatin1(const QByteArray &str)
|
||||
{ return str.isNull() ? QString() : fromLatin1(str.data(), qstrnlen(str.constData(), str.size())); }
|
||||
{ return str.isNull() ? QString() : fromLatin1(str.data(), str.size()); }
|
||||
static inline QString fromUtf8(const QByteArray &str)
|
||||
{ return str.isNull() ? QString() : fromUtf8(str.data(), qstrnlen(str.constData(), str.size())); }
|
||||
{ return str.isNull() ? QString() : fromUtf8(str.data(), str.size()); }
|
||||
static inline QString fromLocal8Bit(const QByteArray &str)
|
||||
{ return str.isNull() ? QString() : fromLocal8Bit(str.data(), qstrnlen(str.constData(), str.size())); }
|
||||
{ return str.isNull() ? QString() : fromLocal8Bit(str.data(), str.size()); }
|
||||
static QString fromUtf16(const ushort *, int size = -1);
|
||||
static QString fromUcs4(const uint *, int size = -1);
|
||||
static QString fromRawData(const QChar *, int size);
|
||||
@ -650,7 +650,7 @@ public:
|
||||
: d(fromAscii_helper(ch, ch ? int(strlen(ch)) : -1))
|
||||
{}
|
||||
inline QT_ASCII_CAST_WARN QString(const QByteArray &a)
|
||||
: d(fromAscii_helper(a.constData(), qstrnlen(a.constData(), a.size())))
|
||||
: d(fromAscii_helper(a.constData(), a.size()))
|
||||
{}
|
||||
inline QT_ASCII_CAST_WARN QString &operator=(const char *ch)
|
||||
{ return (*this = fromUtf8(ch)); }
|
||||
@ -1211,30 +1211,30 @@ inline QT_ASCII_CAST_WARN bool QLatin1String::operator>=(const QByteArray &s) co
|
||||
{ return QString::fromUtf8(s) <= *this; }
|
||||
|
||||
inline QT_ASCII_CAST_WARN bool QString::operator==(const QByteArray &s) const
|
||||
{ return QString::compare_helper(constData(), size(), s.constData(), qstrnlen(s.constData(), s.size())) == 0; }
|
||||
{ return QString::compare_helper(constData(), size(), s.constData(), s.size()) == 0; }
|
||||
inline QT_ASCII_CAST_WARN bool QString::operator!=(const QByteArray &s) const
|
||||
{ return QString::compare_helper(constData(), size(), s.constData(), qstrnlen(s.constData(), s.size())) != 0; }
|
||||
{ return QString::compare_helper(constData(), size(), s.constData(), s.size()) != 0; }
|
||||
inline QT_ASCII_CAST_WARN bool QString::operator<(const QByteArray &s) const
|
||||
{ return QString::compare_helper(constData(), size(), s.constData(), qstrnlen(s.constData(), s.size())) < 0; }
|
||||
{ return QString::compare_helper(constData(), size(), s.constData(), s.size()) < 0; }
|
||||
inline QT_ASCII_CAST_WARN bool QString::operator>(const QByteArray &s) const
|
||||
{ return QString::compare_helper(constData(), size(), s.constData(), qstrnlen(s.constData(), s.size())) > 0; }
|
||||
{ return QString::compare_helper(constData(), size(), s.constData(), s.size()) > 0; }
|
||||
inline QT_ASCII_CAST_WARN bool QString::operator<=(const QByteArray &s) const
|
||||
{ return QString::compare_helper(constData(), size(), s.constData(), qstrnlen(s.constData(), s.size())) <= 0; }
|
||||
{ return QString::compare_helper(constData(), size(), s.constData(), s.size()) <= 0; }
|
||||
inline QT_ASCII_CAST_WARN bool QString::operator>=(const QByteArray &s) const
|
||||
{ return QString::compare_helper(constData(), size(), s.constData(), qstrnlen(s.constData(), s.size())) >= 0; }
|
||||
{ return QString::compare_helper(constData(), size(), s.constData(), s.size()) >= 0; }
|
||||
|
||||
inline bool QByteArray::operator==(const QString &s) const
|
||||
{ return QString::compare_helper(s.constData(), s.size(), constData(), qstrnlen(constData(), size())) == 0; }
|
||||
{ return QString::compare_helper(s.constData(), s.size(), constData(), size()) == 0; }
|
||||
inline bool QByteArray::operator!=(const QString &s) const
|
||||
{ return QString::compare_helper(s.constData(), s.size(), constData(), qstrnlen(constData(), size())) != 0; }
|
||||
{ return QString::compare_helper(s.constData(), s.size(), constData(), size()) != 0; }
|
||||
inline bool QByteArray::operator<(const QString &s) const
|
||||
{ return QString::compare_helper(s.constData(), s.size(), constData(), qstrnlen(constData(), size())) < 0; }
|
||||
{ return QString::compare_helper(s.constData(), s.size(), constData(), size()) < 0; }
|
||||
inline bool QByteArray::operator>(const QString &s) const
|
||||
{ return QString::compare_helper(s.constData(), s.size(), constData(), qstrnlen(constData(), size())) > 0; }
|
||||
{ return QString::compare_helper(s.constData(), s.size(), constData(), size()) > 0; }
|
||||
inline bool QByteArray::operator<=(const QString &s) const
|
||||
{ return QString::compare_helper(s.constData(), s.size(), constData(), qstrnlen(constData(), size())) <= 0; }
|
||||
{ return QString::compare_helper(s.constData(), s.size(), constData(), size()) <= 0; }
|
||||
inline bool QByteArray::operator>=(const QString &s) const
|
||||
{ return QString::compare_helper(s.constData(), s.size(), constData(), qstrnlen(constData(), size())) >= 0; }
|
||||
{ return QString::compare_helper(s.constData(), s.size(), constData(), size()) >= 0; }
|
||||
#endif // !defined(QT_NO_CAST_FROM_ASCII) && !defined(QT_RESTRICTED_CAST_FROM_ASCII)
|
||||
|
||||
#ifndef QT_NO_CAST_TO_ASCII
|
||||
|
@ -828,7 +828,7 @@ void tst_QString::constructorQByteArray_data()
|
||||
ba1[5] = 'e';
|
||||
ba1[6] = 'f';
|
||||
|
||||
QTest::newRow( "2" ) << ba1 << QString("abc");
|
||||
QTest::newRow( "2" ) << ba1 << QStringLiteral("abc\0def");
|
||||
|
||||
QTest::newRow( "3" ) << QByteArray::fromRawData("abcd", 3) << QString("abc");
|
||||
QTest::newRow( "4" ) << QByteArray("\xc3\xa9") << QString("\xc3\xa9");
|
||||
@ -849,12 +849,6 @@ void tst_QString::constructorQByteArray()
|
||||
QCOMPARE( strBA, expected );
|
||||
|
||||
// test operator= too
|
||||
if (src.constData()[src.length()] == '\0') {
|
||||
str1.clear();
|
||||
str1 = src.constData();
|
||||
QCOMPARE( str1, expected );
|
||||
}
|
||||
|
||||
strBA.clear();
|
||||
strBA = src;
|
||||
QCOMPARE( strBA, expected );
|
||||
@ -2177,14 +2171,6 @@ void tst_QString::append_bytearray()
|
||||
|
||||
QTEST( str, "res" );
|
||||
}
|
||||
|
||||
QFETCH( QByteArray, ba );
|
||||
if (ba.constData()[ba.length()] == '\0') {
|
||||
QFETCH( QString, str );
|
||||
|
||||
str.append(ba.constData());
|
||||
QTEST( str, "res" );
|
||||
}
|
||||
}
|
||||
|
||||
void tst_QString::operator_pluseq_bytearray_data()
|
||||
@ -2210,14 +2196,6 @@ void tst_QString::operator_pluseq_bytearray()
|
||||
|
||||
QTEST( str, "res" );
|
||||
}
|
||||
|
||||
QFETCH( QByteArray, ba );
|
||||
if (ba.constData()[ba.length()] == '\0') {
|
||||
QFETCH( QString, str );
|
||||
|
||||
str += ba.constData();
|
||||
QTEST( str, "res" );
|
||||
}
|
||||
}
|
||||
|
||||
void tst_QString::operator_eqeq_bytearray_data()
|
||||
@ -2232,11 +2210,6 @@ void tst_QString::operator_eqeq_bytearray()
|
||||
|
||||
QVERIFY(expected == src);
|
||||
QVERIFY(!(expected != src));
|
||||
|
||||
if (src.constData()[src.length()] == '\0') {
|
||||
QVERIFY(expected == src.constData());
|
||||
QVERIFY(!(expected != src.constData()));
|
||||
}
|
||||
}
|
||||
|
||||
void tst_QString::swap()
|
||||
@ -2271,7 +2244,7 @@ void tst_QString::prepend_bytearray_data()
|
||||
// byte array with only a 0
|
||||
ba.resize( 1 );
|
||||
ba[0] = 0;
|
||||
QTest::newRow( "emptyString" ) << QString("foobar ") << ba << QString("foobar ");
|
||||
QTest::newRow( "emptyString" ) << QString("foobar ") << ba << QStringLiteral("\0foobar ");
|
||||
|
||||
// empty byte array
|
||||
ba.resize( 0 );
|
||||
@ -2301,14 +2274,6 @@ void tst_QString::prepend_bytearray()
|
||||
|
||||
QTEST( str, "res" );
|
||||
}
|
||||
|
||||
QFETCH( QByteArray, ba );
|
||||
if (ba.constData()[ba.length()] == '\0') {
|
||||
QFETCH( QString, str );
|
||||
|
||||
str.prepend(ba.constData());
|
||||
QTEST( str, "res" );
|
||||
}
|
||||
}
|
||||
|
||||
void tst_QString::replace_uint_uint()
|
||||
|
@ -1378,8 +1378,8 @@ void tst_QTextDocumentFragment::html_listStart1()
|
||||
{
|
||||
// don't create a block for the <ul> element, even if there's some whitespace between
|
||||
// it and the <li>
|
||||
const char html[] = "<ul> <li>list item</li><ul>";
|
||||
cursor.insertFragment(QTextDocumentFragment::fromHtml(QByteArray::fromRawData(html, sizeof(html) / sizeof(html[0]))));
|
||||
const QString html = QStringLiteral("<ul> <li>list item</li><ul>");
|
||||
cursor.insertFragment(QTextDocumentFragment::fromHtml(html));
|
||||
|
||||
QCOMPARE(doc->blockCount(), 1);
|
||||
}
|
||||
@ -1387,8 +1387,8 @@ void tst_QTextDocumentFragment::html_listStart1()
|
||||
void tst_QTextDocumentFragment::html_listStart2()
|
||||
{
|
||||
// unlike with html_listStart1 we want a block showing the 'buggy' text here
|
||||
const char html[] = "<ul>buggy, but text should appear<li>list item</li><ul>";
|
||||
cursor.insertFragment(QTextDocumentFragment::fromHtml(QByteArray::fromRawData(html, sizeof(html) / sizeof(html[0]))));
|
||||
const QString html = QStringLiteral("<ul>buggy, but text should appear<li>list item</li><ul>");
|
||||
cursor.insertFragment(QTextDocumentFragment::fromHtml(html));
|
||||
|
||||
QCOMPARE(doc->blockCount(), 2);
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user