Skip to content

Commit

Permalink
feat(CI): Disallow unsafe implicit casts to QString
Browse files Browse the repository at this point in the history
Covers char* without size, and QByteArray.

Catches the case of QByteArray to QString implicit conversion like was
fixed in 47ee51c, but still allows
construction or assignment from string literals in source. Gives most
of the type safety of QT_NO_CAST_FROM_ASCII without having to wrap
every literal string in QStringLiteral.

No functional issues found during change.
  • Loading branch information
anthonybilinski committed Apr 5, 2022
1 parent b5aa5da commit 9571434
Show file tree
Hide file tree
Showing 28 changed files with 58 additions and 57 deletions.
1 change: 1 addition & 0 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -104,6 +104,7 @@ endif()

add_definitions(-DQT_NO_CAST_FROM_BYTEARRAY)
add_definitions(-DQT_NO_CAST_TO_ASCII)
add_definitions(-DQT_RESTRICTED_CAST_FROM_ASCII)

include(CheckAtomic)

Expand Down
2 changes: 1 addition & 1 deletion src/chatlog/chatwidget.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -690,7 +690,7 @@ QString ChatWidget::getSelectedText() const
QString msg = line->content[1]->getText();

out +=
QString(out.isEmpty() ? "[%2] %1: %3" : "\n[%2] %1: %3").arg(author, timestamp, msg);
QString(out.isEmpty() ? QStringLiteral("[%2] %1: %3") : QStringLiteral("\n[%2] %1: %3")).arg(author, timestamp, msg);
});

return out;
Expand Down
2 changes: 1 addition & 1 deletion src/chatlog/content/filetransferwidget.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -328,7 +328,7 @@ void FileTransferWidget::updateFileProgress(ToxFile const& file)
if (speed > 0) {
// ETA
QTime toGo = QTime(0, 0).addSecs(remainingTime);
QString format = toGo.hour() > 0 ? "hh:mm:ss" : "mm:ss";
QString format = toGo.hour() > 0 ? QStringLiteral("hh:mm:ss") : QStringLiteral("mm:ss");
ui->etaLabel->setText(toGo.toString(format));
} else {
ui->etaLabel->setText("");
Expand Down
2 changes: 1 addition & 1 deletion src/core/chatid.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -77,7 +77,7 @@ bool ChatId::operator<(const ChatId& other) const
*/
QString ChatId::toString() const
{
return id.toHex().toUpper();
return QString::fromUtf8(id.toHex()).toUpper();
}

/**
Expand Down
2 changes: 1 addition & 1 deletion src/core/corefile.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -379,7 +379,7 @@ void CoreFile::onFileReceiveCallback(Tox* tox, uint32_t friendId, uint32_t fileI
#endif
qDebug() << QString("Received file request %1:%2 kind %3").arg(friendId).arg(fileId).arg(kind);

ToxFile file{fileId, friendId, filename.getBytes(), "", filesize, ToxFile::RECEIVING};
ToxFile file{fileId, friendId, filename.getQString(), "", filesize, ToxFile::RECEIVING};
file.fileKind = kind;
file.resumeFileId.resize(TOX_FILE_ID_LENGTH);
Tox_Err_File_Get fileGetErr;
Expand Down
6 changes: 3 additions & 3 deletions src/core/toxid.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -114,7 +114,7 @@ ToxId::ToxId(const uint8_t* rawId, int len)

void ToxId::constructToxId(const QByteArray& rawId)
{
if (rawId.length() == ToxId::size && isToxId(rawId.toHex().toUpper())) {
if (rawId.length() == ToxId::size && isToxId(QString::fromUtf8(rawId.toHex()).toUpper())) {
toxId = QByteArray(rawId); // construct from full toxid
} else {
assert(!"ToxId constructed with invalid input");
Expand Down Expand Up @@ -149,7 +149,7 @@ bool ToxId::operator!=(const ToxId& other) const
*/
QString ToxId::toString() const
{
return toxId.toHex().toUpper();
return QString::fromUtf8(toxId.toHex()).toUpper();
}

/**
Expand Down Expand Up @@ -194,7 +194,7 @@ ToxPk ToxId::getPublicKey() const
QString ToxId::getNoSpamString() const
{
if (toxId.length() == ToxId::size) {
return toxId.mid(ToxPk::size, ToxId::nospamSize).toHex().toUpper();
return QString::fromUtf8(toxId.mid(ToxPk::size, ToxId::nospamSize).toHex()).toUpper();
}

return {};
Expand Down
2 changes: 1 addition & 1 deletion src/core/toxlogger.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ QByteArray cleanPath(const char *file)
{
// for privacy, make the path relative to the c-toxcore source directory
const QRegularExpression pathCleaner(QLatin1String{"[\\s|\\S]*c-toxcore."});
QByteArray cleanedPath = QString{file}.remove(pathCleaner).toUtf8();
QByteArray cleanedPath = QString::fromUtf8(file).remove(pathCleaner).toUtf8();
cleanedPath.append('\0');
return cleanedPath;
}
Expand Down
2 changes: 1 addition & 1 deletion src/ipc.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,7 @@ namespace
qWarning() << "Failed to get current username. Will use a global IPC.";
user = "";
}
return QString("qtox-" IPC_PROTOCOL_VERSION "-") + user;
return QString("qtox-" IPC_PROTOCOL_VERSION "-") + QString::fromUtf8(user);
}
} // namespace

Expand Down
10 changes: 5 additions & 5 deletions src/main.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -95,7 +95,7 @@ void cleanup()
void logMessageHandler(QtMsgType type, const QMessageLogContext& ctxt, const QString& msg)
{
// Silence qWarning spam due to bug in QTextBrowser (trying to open a file for base64 images)
if (ctxt.function == QString("virtual bool QFSFileEngine::open(QIODevice::OpenMode)")
if (QString::fromUtf8(ctxt.function) == QString("virtual bool QFSFileEngine::open(QIODevice::OpenMode)")
&& msg == QString("QFSFileEngine::open: No file name specified")) {
return;
}
Expand All @@ -119,7 +119,7 @@ void logMessageHandler(QtMsgType type, const QMessageLogContext& ctxt, const QSt
return;
}

QString file = ctxt.file;
QString file = QString::fromUtf8(ctxt.file);
// We're not using QT_MESSAGELOG_FILE here, because that can be 0, NULL, or
// nullptr in release builds.
QString path = QString(__FILE__);
Expand Down Expand Up @@ -199,7 +199,7 @@ bool toxURIEventHandler(const QByteArray& eventData, void* userData)
return false;
}

uriDialog->handleToxURI(eventData);
uriDialog->handleToxURI(QString::fromUtf8(eventData));
return true;
}

Expand Down Expand Up @@ -438,9 +438,9 @@ int main(int argc, char* argv[])

// Event was not handled by already running instance therefore we handle it ourselves
if (eventType == "uri") {
uriDialog->handleToxURI(firstParam.toUtf8());
uriDialog->handleToxURI(firstParam);
} else if (eventType == "save") {
toxSave->handleToxSave(firstParam.toUtf8());
toxSave->handleToxSave(firstParam);
}

QObject::connect(a.get(), &QApplication::aboutToQuit, cleanup);
Expand Down
4 changes: 2 additions & 2 deletions src/model/message.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -47,11 +47,11 @@ namespace {
}
--splitPos;
}
splittedMsgs.append(QString{ba_message.left(splitPos + 1)});
splittedMsgs.append(QString::fromUtf8(ba_message.left(splitPos + 1)));
ba_message = ba_message.mid(splitPos + 1);
}

splittedMsgs.append(QString{ba_message});
splittedMsgs.append(QString::fromUtf8(ba_message));
return splittedMsgs;
}
}
Expand Down
2 changes: 1 addition & 1 deletion src/net/bootstrapnodeupdater.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -163,7 +163,7 @@ QList<DhtServer> loadNodesFile(QString file)
return {};
}

QString nodesJson = nodesFile.readAll();
QString nodesJson = QString::fromUtf8(nodesFile.readAll());
nodesFile.close();

auto jsonDoc = QJsonDocument::fromJson(nodesJson.toUtf8());
Expand Down
10 changes: 5 additions & 5 deletions src/persistence/db/rawdatabase.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -696,7 +696,7 @@ QString RawDatabase::deriveKey(const QString& password)
const std::unique_ptr<Tox_Pass_Key, PassKeyDeleter> key(tox_pass_key_derive_with_salt(
reinterpret_cast<const uint8_t*>(passData.data()),
static_cast<std::size_t>(passData.size()), expandConstant, nullptr));
return QByteArray(reinterpret_cast<char*>(key.get()) + 32, 32).toHex();
return QString::fromUtf8(QByteArray(reinterpret_cast<char*>(key.get()) + 32, 32).toHex());
}

/**
Expand Down Expand Up @@ -724,7 +724,7 @@ QString RawDatabase::deriveKey(const QString& password, const QByteArray& salt)
reinterpret_cast<const uint8_t*>(passData.data()),
static_cast<std::size_t>(passData.size()),
reinterpret_cast<const uint8_t*>(salt.constData()), nullptr));
return QByteArray(reinterpret_cast<char*>(key.get()) + 32, 32).toHex();
return QString::fromUtf8(QByteArray(reinterpret_cast<char*>(key.get()) + 32, 32).toHex());
}

/**
Expand Down Expand Up @@ -876,7 +876,7 @@ void RawDatabase::process()
*/
QString RawDatabase::anonymizeQuery(const QByteArray& query)
{
QString queryString(query);
QString queryString = QString::fromUtf8(query);
queryString.replace(QRegularExpression("chat.public_key='[A-F0-9]{64}'"),
"char.public_key='<HERE IS PUBLIC KEY>'");
queryString.replace(QRegularExpression("timestamp BETWEEN \\d{5,} AND \\d{5,}"),
Expand Down Expand Up @@ -935,8 +935,8 @@ void RawDatabase::regexp(sqlite3_context* ctx, int argc, sqlite3_value** argv, c
{
std::ignore = argc;
QRegularExpression regex;
const QString str1(reinterpret_cast<const char*>(sqlite3_value_text(argv[0])));
const QString str2(reinterpret_cast<const char*>(sqlite3_value_text(argv[1])));
const QString str1 = QString::fromUtf8(reinterpret_cast<const char*>(sqlite3_value_text(argv[0])));
const QString str2 = QString::fromUtf8(reinterpret_cast<const char*>(sqlite3_value_text(argv[1])));

regex.setPattern(str1);
regex.setPatternOptions(cs);
Expand Down
2 changes: 1 addition & 1 deletion src/persistence/profile.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -553,7 +553,7 @@ QString Profile::avatarPath(const ToxPk& owner, bool forceUnencrypted)
QByteArray hash(hashSize, 0);
crypto_generichash(reinterpret_cast<uint8_t*>(hash.data()), hashSize, reinterpret_cast<uint8_t*>(idData.data()), idData.size(),
reinterpret_cast<uint8_t*>(pubkeyData.data()), pubkeyData.size());
return paths.getSettingsDirPath() + "avatars/" + hash.toHex().toUpper() + ".png";
return paths.getSettingsDirPath() + "avatars/" + QString::fromUtf8(hash.toHex()).toUpper() + ".png";
}

/**
Expand Down
2 changes: 1 addition & 1 deletion src/persistence/serialize.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@ QString dataToString(QByteArray data)
data.remove(0, i);
data.truncate(strlen);

return QString(data);
return QString::fromUtf8(data);
}

uint64_t dataToUint64(const QByteArray& data)
Expand Down
2 changes: 1 addition & 1 deletion src/persistence/toxsave.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ bool ToxSave::toxSaveEventHandler(const QByteArray& eventData, void* userData)
return false;
}

toxSave->handleToxSave(eventData);
toxSave->handleToxSave(QString::fromUtf8(eventData));
return true;
}

Expand Down
4 changes: 2 additions & 2 deletions src/platform/camera/directshow.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -99,7 +99,7 @@ QVector<QPair<QString, QString>> DirectShow::getDeviceList()
goto fail;
devHumanName = wcharToUtf8(var.bstrVal);

devices += {QString("video=") + devIdString, devHumanName};
devices += {QString("video=") + QString::fromUtf8(devIdString), QString::fromUtf8(devHumanName)};

fail:
if (olestr && coMalloc)
Expand Down Expand Up @@ -156,7 +156,7 @@ static IBaseFilter* getDevFilter(QString devName)
if (devIdString[i] == ':')
devIdString[i] = '_';

if (devName != devIdString)
if (devName.toUtf8().constData() != devIdString)
goto fail;

if (m->BindToObject(nullptr, nullptr, IID_IBaseFilter, reinterpret_cast<void**>(&devFilter)) != S_OK)
Expand Down
4 changes: 2 additions & 2 deletions src/platform/camera/v4l2.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -195,7 +195,7 @@ QVector<QPair<QString, QString>> v4l2::getDeviceList()
dirent* e;
while ((e = readdir(dir)))
if (!strncmp(e->d_name, "video", 5) || !strncmp(e->d_name, "vbi", 3))
deviceFiles += QString("/dev/") + e->d_name;
deviceFiles += QString("/dev/") + QString::fromUtf8(e->d_name);
closedir(dir);

for (QString file : deviceFiles) {
Expand All @@ -210,7 +210,7 @@ QVector<QPair<QString, QString>> v4l2::getDeviceList()
close(fd);

if (caps.device_caps & V4L2_CAP_VIDEO_CAPTURE)
devices += {file, reinterpret_cast<const char*>(caps.card)};
devices += {file, QString::fromUtf8(reinterpret_cast<const char*>(caps.card))};
}
return devices;
}
Expand Down
28 changes: 14 additions & 14 deletions src/video/cameradevice.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -195,7 +195,7 @@ CameraDevice* CameraDevice::open(QString devName, VideoMode mode)
devName += QString("+%1,%2").arg(QString().setNum(mode.x), QString().setNum(mode.y));

av_dict_set(&options, "framerate", framerate.c_str(), 0);
} else if (iformat->name == QString("video4linux2,v4l2") && mode) {
} else if (QString::fromUtf8(iformat->name) == QString("video4linux2,v4l2") && mode) {
av_dict_set(&options, "video_size", videoSize.c_str(), 0);
av_dict_set(&options, "framerate", framerate.c_str(), 0);
const std::string pixelFormatStr = v4l2::getPixelFormatString(mode.pixel_format).toStdString();
Expand All @@ -215,13 +215,13 @@ CameraDevice* CameraDevice::open(QString devName, VideoMode mode)
av_dict_set(&options, "offset_x", offsetX.c_str(), 0);
av_dict_set(&options, "offset_y", offsetY.c_str(), 0);
av_dict_set(&options, "video_size", videoSize.c_str(), 0);
} else if (iformat->name == QString("dshow") && mode) {
} else if (QString::fromUtf8(iformat->name) == QString("dshow") && mode) {
av_dict_set(&options, "video_size", videoSize.c_str(), 0);
av_dict_set(&options, "framerate", framerate.c_str(), 0);
}
#endif
#ifdef Q_OS_OSX
else if (iformat->name == QString("avfoundation")) {
else if (QString::fromUtf8(iformat->name) == QString("avfoundation")) {
if (mode) {
av_dict_set(&options, "video_size", videoSize.c_str(), 0);
av_dict_set(&options, "framerate", framerate.c_str(), 0);
Expand Down Expand Up @@ -330,8 +330,8 @@ QVector<QPair<QString, QString>> CameraDevice::getRawDeviceListGeneric()
devices.resize(devlist->nb_devices);
for (int i = 0; i < devlist->nb_devices; ++i) {
AVDeviceInfo* dev = devlist->devices[i];
devices[i].first = dev->device_name;
devices[i].second = dev->device_description;
devices[i].first = QString::fromUtf8(dev->device_name);
devices[i].second = QString::fromUtf8(dev->device_description);
}
avdevice_free_list_devices(&devlist);
return devices;
Expand All @@ -354,34 +354,34 @@ QVector<QPair<QString, QString>> CameraDevice::getDeviceList()
if (!iformat)
;
#ifdef Q_OS_WIN
else if (iformat->name == QString("dshow"))
else if (QString::fromUtf8(iformat->name) == QString("dshow"))
devices += DirectShow::getDeviceList();
#endif
#if USING_V4L
else if (iformat->name == QString("video4linux2,v4l2"))
else if (QString::fromUtf8(iformat->name) == QString("video4linux2,v4l2"))
devices += v4l2::getDeviceList();
#endif
#ifdef Q_OS_OSX
else if (iformat->name == QString("avfoundation"))
else if (QString::fromUtf8(iformat->name) == QString("avfoundation"))
devices += avfoundation::getDeviceList();
#endif
else
devices += getRawDeviceListGeneric();

if (idesktopFormat) {
if (idesktopFormat->name == QString("x11grab")) {
if (QString::fromUtf8(idesktopFormat->name) == QString("x11grab")) {
QString dev = "x11grab#";
QByteArray display = qgetenv("DISPLAY");

if (display.isNull())
dev += ":0";
else
dev += display.constData();
dev += QString::fromUtf8(display.constData());

devices.push_back(QPair<QString, QString>{
dev, QObject::tr("Desktop", "Desktop as a camera input for screen sharing")});
}
if (idesktopFormat->name == QString("gdigrab"))
if (QString::fromUtf8(idesktopFormat->name) == QString("gdigrab"))
devices.push_back(QPair<QString, QString>{
"gdigrab#desktop",
QObject::tr("Desktop", "Desktop as a camera input for screen sharing")});
Expand Down Expand Up @@ -459,15 +459,15 @@ QVector<VideoMode> CameraDevice::getVideoModes(QString devName)
else if (isScreen(devName))
return getScreenModes();
#ifdef Q_OS_WIN
else if (iformat->name == QString("dshow"))
else if (QString::fromUtf8(iformat->name) == QString("dshow"))
return DirectShow::getDeviceModes(devName);
#endif
#if USING_V4L
else if (iformat->name == QString("video4linux2,v4l2"))
else if (QString::fromUtf8(iformat->name) == QString("video4linux2,v4l2"))
return v4l2::getDeviceModes(devName);
#endif
#ifdef Q_OS_OSX
else if (iformat->name == QString("avfoundation"))
else if (QString::fromUtf8(iformat->name) == QString("avfoundation"))
return avfoundation::getDeviceModes(devName);
#endif
else
Expand Down
2 changes: 1 addition & 1 deletion src/widget/form/chatform.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -288,7 +288,7 @@ void ChatForm::onTextEditChanged()
void ChatForm::onAttachClicked()
{
QStringList paths = QFileDialog::getOpenFileNames(Q_NULLPTR, tr("Send a file"),
QDir::homePath(), nullptr, nullptr);
QDir::homePath(), QString(), nullptr);

if (paths.isEmpty()) {
return;
Expand Down
2 changes: 1 addition & 1 deletion src/widget/form/profileform.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -302,7 +302,7 @@ QString ProfileForm::getSupportedImageFilter()
{
QString res;
for (auto type : QImageReader::supportedImageFormats()) {
res += QString("*.%1 ").arg(QString(type));
res += QString("*.%1 ").arg(QString::fromUtf8(type));
}

return tr("Images (%1)", "filetype filter").arg(res.left(res.size() - 1));
Expand Down
2 changes: 1 addition & 1 deletion src/widget/form/settings/aboutform.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -157,7 +157,7 @@ void AboutForm::replaceVersions()
"Replaces `%2` in the `A list of all known…`"))));

bodyUI->clickToReport->setText(
createLink("https://github.com/qTox/qTox/issues/new?body=" + QUrl(issueBody).toEncoded(),
createLink("https://github.com/qTox/qTox/issues/new?body=" + QString::fromUtf8(QUrl(issueBody).toEncoded()),
QString("<b>%1</b>").arg(tr("Click here to report a bug."))));


Expand Down
2 changes: 1 addition & 1 deletion src/widget/friendwidget.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -434,7 +434,7 @@ void FriendWidget::onAvatarRemoved(const ToxPk& friendPk)

isDefaultAvatar = true;

const QString path = QString(":/img/contact%1.svg").arg(isActive() ? "_dark" : "");
const QString path = QString(":/img/contact%1.svg").arg(isActive() ? QStringLiteral("_dark") : QString());
avatar->setPixmap(QPixmap(path));
}

Expand Down
2 changes: 1 addition & 1 deletion src/widget/imagepreviewwidget.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -98,7 +98,7 @@ QString getToolTipDisplayingImage(const QPixmap& image)
previewImage.save(&buffer, "PNG");
buffer.close();

return "<img src=data:image/png;base64," + imageData.toBase64() + "/>";
return "<img src=data:image/png;base64," + QString::fromUtf8(imageData.toBase64()) + "/>";
}

} // namespace
Expand Down
Loading

0 comments on commit 9571434

Please sign in to comment.