Debugger: Correctly display > 2 byte characters in strings

The "escapeUnprintable" function previously iterated through the
QString QChar by QChar. Since QChar only represents UTF-16 it would
erroneously split 4 byte characters into two characters that were
no longer printable.

To workaround, we first convert the QString to a UTF32 ByteArray
and iterate over each of the characters. This allows us to
correctly distinguish between non- printable characters.

Change-Id: I5552a79a91678994868441e67f967c68329aa1ce
Reviewed-by: hjk <hjk@qt.io>
This commit is contained in:
Marcus Tillmanns
2022-08-09 16:12:23 +02:00
parent cd919e6f61
commit a1fd70c1a4

View File

@@ -30,6 +30,8 @@
#include "watchdata.h"
#include <QDebug>
#include <QStringEncoder>
#include <QStringDecoder>
#include <string.h>
#include <ctype.h>
@@ -242,35 +244,40 @@ QString formatToolTipAddress(quint64 a)
QString escapeUnprintable(const QString &str, int unprintableBase)
{
if (unprintableBase == 0)
return str;
QStringEncoder toUtf32(QStringEncoder::Utf32);
QStringDecoder toQString(QStringDecoder::Utf32);
QByteArray arr = toUtf32(str);
QByteArrayView arrayView(arr);
QString encoded;
if (unprintableBase == -1) {
for (const QChar c : str) {
int u = c.unicode();
if (c.isPrint())
encoded += c;
else if (u == '\r')
encoded += "\\r";
else if (u == '\t')
encoded += "\\t";
else if (u == '\n')
encoded += "\\n";
else
encoded += QString("\\%1").arg(u, 3, 8, QLatin1Char('0'));
while (arrayView.size() >= 4) {
char32_t c;
memcpy(&c, arrayView.constData(), sizeof(char32_t));
if (QChar::isPrint(c))
encoded += toQString(arrayView.sliced(0, 4));
else {
if (unprintableBase == -1) {
if (c == '\r')
encoded += "\\r";
else if (c == '\t')
encoded += "\\t";
else if (c == '\n')
encoded += "\\n";
else
encoded += QString("\\%1").arg(c, 3, 8, QLatin1Char('0'));
} else if (unprintableBase == 8) {
encoded += QString("\\%1").arg(c, 3, 8, QLatin1Char('0'));
} else {
encoded += QString("\\u%1").arg(c, 4, 16, QLatin1Char('0'));
}
}
return encoded;
arrayView = arrayView.sliced(4);
}
for (const QChar c : str) {
if (c.isPrint())
encoded += c;
else if (unprintableBase == 8)
encoded += QString("\\%1").arg(c.unicode(), 3, 8, QLatin1Char('0'));
else
encoded += QString("\\u%1").arg(c.unicode(), 4, 16, QLatin1Char('0'));
}
return encoded;
}