QtMiscUtils: add isAsciiPrintable() helper

- isAsciiPrintable: borrowed the logic from isPrintable(uchar) in
  qdebug.cpp, now isPrintable(uchar) calls isAsciiPrintable

- Replace ::isspace() with ascii_isspace() from qlocale_p.h

Functions from ctype.h have a couple of issues:
- they're locale-dependent, which isn't what's required here, the code
  is only interested in ASCII
- their args should be representable as uchar or EOF otherwise it's
  undefined behavior

An Early-Warning could use something like:
grep -rP "\b(isalnum|isalpha|isblank|iscntrl|isdigit|islower|isgraph|\
         "isprint|ispunct|isspace|isupper|isxdigit|tolower|toupper)\b"

Pick-to: 6.5
Task-number: QTBUG-111262
Change-Id: I1f47f41bd56735297078ff0d0ddc2ebf999abf8b
Reviewed-by: Thiago Macieira <thiago.macieira@intel.com>
This commit is contained in:
Ahmad Samir 2023-03-15 17:27:21 +02:00
parent d184c66ad5
commit f6b780b583
6 changed files with 26 additions and 24 deletions

View File

@ -14,13 +14,10 @@
#include "qmetaobject.h" #include "qmetaobject.h"
#include <private/qtextstream_p.h> #include <private/qtextstream_p.h>
#include <private/qtools_p.h> #include <private/qtools_p.h>
#include <ctype.h>
QT_BEGIN_NAMESPACE QT_BEGIN_NAMESPACE
using QtMiscUtils::toHexUpper; using namespace QtMiscUtils;
using QtMiscUtils::toHexLower;
using QtMiscUtils::fromHex;
/* /*
Returns a human readable representation of the first \a maxSize Returns a human readable representation of the first \a maxSize
@ -35,7 +32,7 @@ QByteArray QtDebugUtils::toPrintable(const char *data, qint64 len, qsizetype max
QByteArray out; QByteArray out;
for (qsizetype i = 0; i < qMin(len, maxSize); ++i) { for (qsizetype i = 0; i < qMin(len, maxSize); ++i) {
char c = data[i]; char c = data[i];
if (isprint(c)) { if (isAsciiPrintable(c)) {
out += c; out += c;
} else { } else {
switch (c) { switch (c) {
@ -198,7 +195,7 @@ void QDebug::putUcs4(uint ucs4)
static inline bool isPrintable(char32_t ucs4) { return QChar::isPrint(ucs4); } static inline bool isPrintable(char32_t ucs4) { return QChar::isPrint(ucs4); }
static inline bool isPrintable(char16_t uc) { return QChar::isPrint(uc); } static inline bool isPrintable(char16_t uc) { return QChar::isPrint(uc); }
static inline bool isPrintable(uchar c) static inline bool isPrintable(uchar c)
{ return c >= ' ' && c < 0x7f; } { return isAsciiPrintable(c); }
template <typename Char> template <typename Char>
static inline void putEscapedString(QTextStreamPrivate *d, const Char *begin, size_t length, bool isUnicode = true) static inline void putEscapedString(QTextStreamPrivate *d, const Char *begin, size_t length, bool isUnicode = true)

View File

@ -10,16 +10,14 @@
#include "qstringlist.h" #include "qstringlist.h"
#include "qdir.h" #include "qdir.h"
#include "private/qbytearray_p.h" #include "private/qbytearray_p.h"
#include "private/qtools_p.h"
#include <algorithm> #include <algorithm>
#ifdef QIODEVICE_DEBUG
# include <ctype.h>
#endif
QT_BEGIN_NAMESPACE QT_BEGIN_NAMESPACE
using namespace Qt::StringLiterals; using namespace Qt::StringLiterals;
using namespace QtMiscUtils;
[[maybe_unused]] [[maybe_unused]]
static void debugBinaryString(const char *input, qint64 maxlen) static void debugBinaryString(const char *input, qint64 maxlen)
@ -38,7 +36,7 @@ static void debugBinaryString(const char *input, qint64 maxlen)
for (qsizetype j = tmp.size(); j < 16 + 1; ++j) for (qsizetype j = tmp.size(); j < 16 + 1; ++j)
printf(" "); printf(" ");
for (qsizetype j = 0; j < tmp.size(); ++j) for (qsizetype j = 0; j < tmp.size(); ++j)
printf("%c", isprint(int(uchar(tmp[j]))) ? tmp[j] : '.'); printf("%c", isAsciiPrintable(tmp[j]) ? tmp[j] : '.');
tmp.clear(); tmp.clear();
} }
} }
@ -1011,7 +1009,7 @@ qint64 QIODevice::read(char *data, qint64 maxSize)
*data = c; *data = c;
#if defined QIODEVICE_DEBUG #if defined QIODEVICE_DEBUG
printf("%p \tread 0x%hhx (%c) returning 1 (shortcut)\n", this, printf("%p \tread 0x%hhx (%c) returning 1 (shortcut)\n", this,
int(c), isprint(c) ? c : '?'); int(c), isAsciiPrintable(c) ? c : '?');
#endif #endif
if (d->buffer.isEmpty()) if (d->buffer.isEmpty())
readData(data, 0); readData(data, 0);
@ -1792,7 +1790,7 @@ void QIODevice::ungetChar(char c)
} }
#if defined QIODEVICE_DEBUG #if defined QIODEVICE_DEBUG
printf("%p QIODevice::ungetChar(0x%hhx '%c')\n", this, c, isprint(c) ? c : '?'); printf("%p QIODevice::ungetChar(0x%hhx '%c')\n", this, c, isAsciiPrintable(c) ? c : '?');
#endif #endif
d->buffer.ungetChar(c); d->buffer.ungetChar(c);

View File

@ -101,6 +101,11 @@ constexpr inline int caseCompareAscii(char lhs, char rhs) noexcept
return int(uchar(lhsLower)) - int(uchar(rhsLower)); return int(uchar(lhsLower)) - int(uchar(rhsLower));
} }
constexpr inline int isAsciiPrintable(char32_t ch) noexcept
{
return ch >= ' ' && ch < 0x7f;
}
constexpr inline int qt_lencmp(qsizetype lhs, qsizetype rhs) noexcept constexpr inline int qt_lencmp(qsizetype lhs, qsizetype rhs) noexcept
{ {
return lhs == rhs ? 0 : return lhs == rhs ? 0 :

View File

@ -11,8 +11,8 @@
#include <qloggingcategory.h> #include <qloggingcategory.h>
#include <qrgba64.h> #include <qrgba64.h>
#include <qvariant.h> #include <qvariant.h>
#include <private/qlocale_p.h>
#include <ctype.h> #include <private/qtools_p.h>
QT_BEGIN_NAMESPACE QT_BEGIN_NAMESPACE
@ -41,7 +41,7 @@ static int read_pbm_int(QIODevice *d, bool *ok)
for (;;) { for (;;) {
if (!d->getChar(&c)) // end of file if (!d->getChar(&c)) // end of file
break; break;
digit = isdigit((uchar) c); digit = QtMiscUtils::isAsciiDigit(c);
if (val != -1) { if (val != -1) {
if (digit) { if (digit) {
const int cValue = c - '0'; const int cValue = c - '0';
@ -59,7 +59,7 @@ static int read_pbm_int(QIODevice *d, bool *ok)
} }
if (digit) // first digit if (digit) // first digit
val = c - '0'; val = c - '0';
else if (isspace((uchar) c)) else if (ascii_isspace(c))
continue; continue;
else if (c == '#') else if (c == '#')
discard_pbm_line(d); discard_pbm_line(d);
@ -77,7 +77,7 @@ static bool read_pbm_header(QIODevice *device, char& type, int& w, int& h, int&
if (device->read(buf, 3) != 3) // read P[1-6]<white-space> if (device->read(buf, 3) != 3) // read P[1-6]<white-space>
return false; return false;
if (!(buf[0] == 'P' && isdigit((uchar) buf[1]) && isspace((uchar) buf[2]))) if (!(buf[0] == 'P' && QtMiscUtils::isAsciiDigit(buf[1]) && ascii_isspace(buf[2])))
return false; return false;
type = buf[1]; type = buf[1];

View File

@ -96,12 +96,14 @@
#include <qtgui_tracepoints_p.h> #include <qtgui_tracepoints_p.h>
#include <ctype.h> #include <private/qtools_p.h>
#include <limits> #include <limits>
QT_BEGIN_NAMESPACE QT_BEGIN_NAMESPACE
using namespace Qt::StringLiterals; using namespace Qt::StringLiterals;
using namespace QtMiscUtils;
// Helper macro for static functions to check on the existence of the application class. // Helper macro for static functions to check on the existence of the application class.
#define CHECK_QAPP_INSTANCE(...) \ #define CHECK_QAPP_INSTANCE(...) \
@ -263,13 +265,13 @@ static inline int nextGeometryToken(const QByteArray &a, int &pos, char *op)
*op = a.at(pos); *op = a.at(pos);
if (*op == '+' || *op == '-' || *op == 'x') if (*op == '+' || *op == '-' || *op == 'x')
pos++; pos++;
else if (isdigit(*op)) else if (isAsciiDigit(*op))
*op = 'x'; // If it starts with a digit, it is supposed to be a width specification. *op = 'x'; // If it starts with a digit, it is supposed to be a width specification.
else else
return -1; return -1;
const int numberPos = pos; const int numberPos = pos;
for ( ; pos < size && isdigit(a.at(pos)); ++pos) ; for ( ; pos < size && isAsciiDigit(a.at(pos)); ++pos) ;
bool ok; bool ok;
const int result = a.mid(numberPos, pos - numberPos).toInt(&ok); const int result = a.mid(numberPos, pos - numberPos).toInt(&ok);

View File

@ -7,8 +7,8 @@
#include <QtTest/private/qtestlog_p.h> #include <QtTest/private/qtestlog_p.h>
#include <QtTest/private/qteamcitylogger_p.h> #include <QtTest/private/qteamcitylogger_p.h>
#include <QtCore/qbytearray.h> #include <QtCore/qbytearray.h>
#include <private/qlocale_p.h>
#include <cctype>
#include <limits.h> #include <limits.h>
#include <stdarg.h> #include <stdarg.h>
#include <stdio.h> #include <stdio.h>
@ -235,7 +235,7 @@ void QTeamCityLogger::tcEscapedString(QTestCharBuffer *buf, const char *str) con
swallowSpace = false; swallowSpace = false;
break; break;
default: default:
if (std::isspace(ch)) { if (ascii_isspace(ch)) {
if (swallowSpace) if (swallowSpace)
continue; continue;
swallowSpace = true; swallowSpace = true;
@ -252,7 +252,7 @@ void QTeamCityLogger::tcEscapedString(QTestCharBuffer *buf, const char *str) con
Q_ASSERT(p[-1] == ' '); Q_ASSERT(p[-1] == ' ');
--p; --p;
} }
Q_ASSERT(p == buf->data() || !std::isspace(p[-1])); Q_ASSERT(p == buf->data() || !ascii_isspace(p[-1]));
*p = '\0'; *p = '\0';
} }