Don't read unlimited data from files

It now guards against reading infinite files such as `/dev/zero`.
And most readings are bound with a (lax) limit.
As a side effect, more checking are done when reading a file and
overall the reading procedure is more robust.

PR #19095.
This commit is contained in:
Chocobo1
2023-06-14 13:38:19 +08:00
committed by GitHub
parent 81bc910d68
commit 79ca2e145f
24 changed files with 370 additions and 199 deletions

View File

@@ -31,7 +31,6 @@
#include "feed_serializer.h"
#include <QFile>
#include <QJsonArray>
#include <QJsonDocument>
#include <QJsonObject>
@@ -46,23 +45,21 @@ const int ARTICLEDATALIST_TYPEID = qRegisterMetaType<QVector<QVariantHash>>();
void RSS::Private::FeedSerializer::load(const Path &dataFileName, const QString &url)
{
QFile file {dataFileName.data()};
const int fileMaxSize = 10 * 1024 * 1024;
const auto readResult = Utils::IO::readFile(dataFileName, fileMaxSize);
if (!readResult)
{
if (readResult.error().status == Utils::IO::ReadError::NotExist)
{
emit loadingFinished({});
return;
}
if (!file.exists())
{
emit loadingFinished({});
}
else if (file.open(QFile::ReadOnly))
{
emit loadingFinished(loadArticles(file.readAll(), url));
file.close();
}
else
{
LogMsg(tr("Couldn't read RSS Session data from %1. Error: %2")
.arg(dataFileName.toString(), file.errorString())
, Log::WARNING);
LogMsg(tr("Failed to read RSS session data. %1").arg(readResult.error().message), Log::WARNING);
return;
}
emit loadingFinished(loadArticles(readResult.value(), url));
}
void RSS::Private::FeedSerializer::store(const Path &dataFileName, const QVector<QVariantHash> &articlesData)

View File

@@ -48,6 +48,7 @@
#include "../logger.h"
#include "../profile.h"
#include "../utils/fs.h"
#include "../utils/io.h"
#include "rss_article.h"
#include "rss_autodownloadrule.h"
#include "rss_feed.h"
@@ -493,21 +494,21 @@ void AutoDownloader::processJob(const QSharedPointer<ProcessingJob> &job)
void AutoDownloader::load()
{
QFile rulesFile {(m_fileStorage->storageDir() / Path(RULES_FILE_NAME)).data()};
const qint64 maxFileSize = 10 * 1024 * 1024;
const auto readResult = Utils::IO::readFile((m_fileStorage->storageDir() / Path(RULES_FILE_NAME)), maxFileSize);
if (!readResult)
{
if (readResult.error().status == Utils::IO::ReadError::NotExist)
{
loadRulesLegacy();
return;
}
if (!rulesFile.exists())
{
loadRulesLegacy();
}
else if (rulesFile.open(QFile::ReadOnly))
{
loadRules(rulesFile.readAll());
}
else
{
LogMsg(tr("Couldn't read RSS AutoDownloader rules from %1. Error: %2")
.arg(rulesFile.fileName(), rulesFile.errorString()), Log::CRITICAL);
LogMsg((tr("Failed to read RSS AutoDownloader rules. %1").arg(readResult.error().message)), Log::WARNING);
return;
}
loadRules(readResult.value());
}
void AutoDownloader::loadRules(const QByteArray &data)

View File

@@ -45,6 +45,7 @@
#include "../profile.h"
#include "../settingsstorage.h"
#include "../utils/fs.h"
#include "../utils/io.h"
#include "rss_article.h"
#include "rss_feed.h"
#include "rss_folder.h"
@@ -261,33 +262,35 @@ Item *Session::itemByPath(const QString &path) const
void Session::load()
{
QFile itemsFile {(m_confFileStorage->storageDir() / Path(FEEDS_FILE_NAME)).data()};
if (!itemsFile.exists())
{
loadLegacy();
return;
}
const int fileMaxSize = 10 * 1024 * 1024;
const Path path = m_confFileStorage->storageDir() / Path(FEEDS_FILE_NAME);
if (!itemsFile.open(QFile::ReadOnly))
const auto readResult = Utils::IO::readFile(path, fileMaxSize);
if (!readResult)
{
LogMsg(tr("Couldn't read RSS session data. File: \"%1\". Error: \"%2\"")
.arg(itemsFile.fileName(), itemsFile.errorString()), Log::WARNING);
if (readResult.error().status == Utils::IO::ReadError::NotExist)
{
loadLegacy();
return;
}
LogMsg(tr("Failed to read RSS session data. %1").arg(readResult.error().message), Log::WARNING);
return;
}
QJsonParseError jsonError;
const QJsonDocument jsonDoc = QJsonDocument::fromJson(itemsFile.readAll(), &jsonError);
const QJsonDocument jsonDoc = QJsonDocument::fromJson(readResult.value(), &jsonError);
if (jsonError.error != QJsonParseError::NoError)
{
LogMsg(tr("Couldn't parse RSS session data. File: \"%1\". Error: \"%2\"")
.arg(itemsFile.fileName(), jsonError.errorString()), Log::WARNING);
LogMsg(tr("Failed to parse RSS session data. File: \"%1\". Error: \"%2\"")
.arg(path.toString(), jsonError.errorString()), Log::WARNING);
return;
}
if (!jsonDoc.isObject())
{
LogMsg(tr("Couldn't load RSS session data. File: \"%1\". Error: Invalid data format.")
.arg(itemsFile.fileName()), Log::WARNING);
LogMsg(tr("Failed to load RSS session data. File: \"%1\". Error: \"Invalid data format.\"")
.arg(path.toString()), Log::WARNING);
return;
}