QString::from{Utf8,Latin1,Local8Bit}(QByteArray): preserve nullness of argument

Currently, calling these functions with a null QByteArray will return
a non-null QString because QByteArray::data() never returns nullptr.

This behavior leads to inconsistencies between QString::append overloads,
in particular the QByteArray vs. all others (null + null test always
returns a null QString, except for the QByteArray overload before this
change).

It also is inconsistent with the const char* overloads of these methods,
which explicitly preserve nullness (as verified by test cases).

Fixed by an explicit check for nullness and return of null QString.

Alternative would have been to check for nullness and pass nullptr
instead of ba.data() to the _helper() functions, which do the correct
thing in that case. But since we'd have the check anyway and with the
chosen strategy we can avoid a call to a non-inline method, I opted
against that.

[ChangeLog][QtCore][QString] fromLatin1(), fromAscii(), fromUtf8() and
fromLocal8Bit() now return a null QString when called with a null
QByteArray.

Change-Id: I5f2c0bad27fb73c7d535085af0271823bf6ed1da
Reviewed-by: Thiago Macieira <thiago.macieira@intel.com>
This commit is contained in:
Marc Mutz 2014-10-11 21:37:56 +02:00
parent ffedd0cf64
commit 6f145707eb
2 changed files with 33 additions and 3 deletions

View File

@ -534,11 +534,11 @@ public:
return fromLocal8Bit_helper(str, (str && size == -1) ? int(strlen(str)) : size);
}
static inline QString fromLatin1(const QByteArray &str)
{ return fromLatin1(str.data(), qstrnlen(str.constData(), str.size())); }
{ return str.isNull() ? QString() : fromLatin1(str.data(), qstrnlen(str.constData(), str.size())); }
static inline QString fromUtf8(const QByteArray &str)
{ return fromUtf8(str.data(), qstrnlen(str.constData(), str.size())); }
{ return str.isNull() ? QString() : fromUtf8(str.data(), qstrnlen(str.constData(), str.size())); }
static inline QString fromLocal8Bit(const QByteArray &str)
{ return fromLocal8Bit(str.data(), qstrnlen(str.constData(), str.size())); }
{ return str.isNull() ? QString() : fromLocal8Bit(str.data(), qstrnlen(str.constData(), 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);

View File

@ -183,6 +183,7 @@ private slots:
void fromLocal8Bit();
void local8Bit_data();
void local8Bit();
void nullFromLocal8Bit();
void fromLatin1Roundtrip_data();
void fromLatin1Roundtrip();
void toLatin1Roundtrip_data();
@ -3697,6 +3698,12 @@ void tst_QString::nullFromUtf8()
a = QString::fromUtf8("");
QVERIFY(!a.isNull());
QVERIFY(a.isEmpty());
a = QString::fromUtf8(QByteArray());
QVERIFY(a.isNull());
QVERIFY(a.isEmpty());
a = QString::fromUtf8(QByteArray(""));
QVERIFY(!a.isNull());
QVERIFY(a.isEmpty());
}
void tst_QString::fromLocal8Bit_data()
@ -3779,6 +3786,23 @@ void tst_QString::local8Bit()
QCOMPARE(local8Bit.toLocal8Bit(), QByteArray(result));
}
void tst_QString::nullFromLocal8Bit()
{
QString a;
a = QString::fromLocal8Bit(0);
QVERIFY(a.isNull());
QVERIFY(a.isEmpty());
a = QString::fromLocal8Bit("");
QVERIFY(!a.isNull());
QVERIFY(a.isEmpty());
a = QString::fromLocal8Bit(QByteArray());
QVERIFY(a.isNull());
QVERIFY(a.isEmpty());
a = QString::fromLocal8Bit(QByteArray(""));
QVERIFY(!a.isNull());
QVERIFY(a.isEmpty());
}
void tst_QString::stringRef_local8Bit_data()
{
local8Bit_data();
@ -3945,6 +3969,12 @@ void tst_QString::fromLatin1()
a = QString::fromLatin1( "" );
QVERIFY( !a.isNull() );
QVERIFY( a.isEmpty() );
a = QString::fromLatin1(QByteArray());
QVERIFY(a.isNull());
QVERIFY(a.isEmpty());
a = QString::fromLatin1(QByteArray(""));
QVERIFY(!a.isNull());
QVERIFY(a.isEmpty());
a = QString::fromLatin1(0, 0);
QVERIFY(a.isNull());