QString: Respect precision when reading data for %.*s format string
If we disregard the precision we may read a very large string that we subsequently discard. Furthermore, people use this to read non-null-terminated strings, which randomly crashes. Change-Id: Ifa255dbe71c82d3d4fb46adfef7a9dc74bd40cee Reviewed-by: Oswald Buddenhagen <oswald.buddenhagen@gmx.de> Reviewed-by: Thiago Macieira <thiago.macieira@intel.com> (cherry picked from commit e99e07cb5c939ca5bbb1dfdeb66c862d6cd4f2f2) Reviewed-by: Fabian Kosmale <fabian.kosmale@qt.io>
This commit is contained in:
parent
e69252f39c
commit
de51871f99
@ -6772,13 +6772,17 @@ QString QString::vasprintf(const char *cformat, va_list ap)
|
|||||||
if (length_mod == lm_l) {
|
if (length_mod == lm_l) {
|
||||||
const ushort *buff = va_arg(ap, const ushort*);
|
const ushort *buff = va_arg(ap, const ushort*);
|
||||||
const ushort *ch = buff;
|
const ushort *ch = buff;
|
||||||
while (*ch != 0)
|
while (precision != 0 && *ch != 0) {
|
||||||
++ch;
|
++ch;
|
||||||
|
--precision;
|
||||||
|
}
|
||||||
subst.setUtf16(buff, ch - buff);
|
subst.setUtf16(buff, ch - buff);
|
||||||
} else
|
} else if (precision == -1) {
|
||||||
subst = QString::fromUtf8(va_arg(ap, const char*));
|
subst = QString::fromUtf8(va_arg(ap, const char*));
|
||||||
if (precision != -1)
|
} else {
|
||||||
subst.truncate(precision);
|
const char *buff = va_arg(ap, const char*);
|
||||||
|
subst = QString::fromUtf8(buff, qstrnlen(buff, precision));
|
||||||
|
}
|
||||||
++c;
|
++c;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -584,6 +584,7 @@ private slots:
|
|||||||
void isValidUtf16_data();
|
void isValidUtf16_data();
|
||||||
void isValidUtf16();
|
void isValidUtf16();
|
||||||
void unicodeStrings();
|
void unicodeStrings();
|
||||||
|
void vasprintfWithPrecision();
|
||||||
};
|
};
|
||||||
|
|
||||||
template <class T> const T &verifyZeroTermination(const T &t) { return t; }
|
template <class T> const T &verifyZeroTermination(const T &t) { return t; }
|
||||||
@ -6937,6 +6938,35 @@ void tst_QString::isValidUtf16()
|
|||||||
QTEST(string.isValidUtf16(), "valid");
|
QTEST(string.isValidUtf16(), "valid");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static QString doVasprintf(const char *msg, ...) {
|
||||||
|
va_list args;
|
||||||
|
va_start(args, msg);
|
||||||
|
const QString result = QString::vasprintf(msg, args);
|
||||||
|
va_end(args);
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
void tst_QString::vasprintfWithPrecision()
|
||||||
|
{
|
||||||
|
{
|
||||||
|
const char *msg = "Endpoint %.*s with";
|
||||||
|
static const char arg0[3] = { 'a', 'b', 'c' };
|
||||||
|
static const char arg1[4] = { 'a', 'b', 'c', '\0' };
|
||||||
|
QCOMPARE(doVasprintf(msg, 3, arg0), QStringLiteral("Endpoint abc with"));
|
||||||
|
QCOMPARE(doVasprintf(msg, 9, arg1), QStringLiteral("Endpoint abc with"));
|
||||||
|
QCOMPARE(doVasprintf(msg, 0, nullptr), QStringLiteral("Endpoint with"));
|
||||||
|
}
|
||||||
|
|
||||||
|
{
|
||||||
|
const char *msg = "Endpoint %.*ls with";
|
||||||
|
static const ushort arg0[3] = { 'a', 'b', 'c' };
|
||||||
|
static const ushort arg1[4] = { 'a', 'b', 'c', '\0' };
|
||||||
|
QCOMPARE(doVasprintf(msg, 3, arg0), QStringLiteral("Endpoint abc with"));
|
||||||
|
QCOMPARE(doVasprintf(msg, 9, arg1), QStringLiteral("Endpoint abc with"));
|
||||||
|
QCOMPARE(doVasprintf(msg, 0, nullptr), QStringLiteral("Endpoint with"));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
QTEST_APPLESS_MAIN(tst_QString)
|
QTEST_APPLESS_MAIN(tst_QString)
|
||||||
|
|
||||||
#include "tst_qstring.moc"
|
#include "tst_qstring.moc"
|
||||||
|
Loading…
x
Reference in New Issue
Block a user