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

@@ -36,6 +36,7 @@
#include <QByteArray>
#include <QDebug>
#include <QFile>
#include <QRegularExpression>
#include <QThread>
@@ -133,17 +134,19 @@ BitTorrent::LoadResumeDataResult BitTorrent::BencodeResumeDataStorage::load(cons
const Path fastresumePath = path() / Path(idString + u".fastresume");
const Path torrentFilePath = path() / Path(idString + u".torrent");
QFile resumeDataFile {fastresumePath.data()};
if (!resumeDataFile.open(QIODevice::ReadOnly))
return nonstd::make_unexpected(tr("Cannot read file %1: %2").arg(fastresumePath.toString(), resumeDataFile.errorString()));
const auto resumeDataReadResult = Utils::IO::readFile(fastresumePath, MAX_TORRENT_SIZE);
if (!resumeDataReadResult)
return nonstd::make_unexpected(resumeDataReadResult.error().message);
QFile metadataFile {torrentFilePath.data()};
if (metadataFile.exists() && !metadataFile.open(QIODevice::ReadOnly))
return nonstd::make_unexpected(tr("Cannot read file %1: %2").arg(torrentFilePath.toString(), metadataFile.errorString()));
const QByteArray data = resumeDataFile.readAll();
const QByteArray metadata = (metadataFile.isOpen() ? metadataFile.readAll() : "");
const auto metadataReadResult = Utils::IO::readFile(torrentFilePath, MAX_TORRENT_SIZE);
if (!metadataReadResult)
{
if (metadataReadResult.error().status != Utils::IO::ReadError::NotExist)
return nonstd::make_unexpected(metadataReadResult.error().message);
}
const QByteArray data = resumeDataReadResult.value();
const QByteArray metadata = metadataReadResult.value_or(QByteArray());
return loadTorrentResumeData(data, metadata);
}
@@ -161,6 +164,8 @@ void BitTorrent::BencodeResumeDataStorage::doLoadAll() const
void BitTorrent::BencodeResumeDataStorage::loadQueue(const Path &queueFilename)
{
const int lineMaxLength = 48;
QFile queueFile {queueFilename.data()};
if (!queueFile.exists())
return;
@@ -175,7 +180,7 @@ void BitTorrent::BencodeResumeDataStorage::loadQueue(const Path &queueFilename)
int start = 0;
while (true)
{
const auto line = QString::fromLatin1(queueFile.readLine().trimmed());
const auto line = QString::fromLatin1(queueFile.readLine(lineMaxLength).trimmed());
if (line.isEmpty())
break;