mirror of
https://github.com/qbittorrent/qBittorrent.git
synced 2024-11-24 10:16:00 +03:00
Fix wrong behavior when reading text
Also add another 'file read error' status. Closes #19254. PR #19262.
This commit is contained in:
parent
08a771468d
commit
80791e328d
7 changed files with 45 additions and 11 deletions
2
.gitattributes
vendored
2
.gitattributes
vendored
|
@ -5,3 +5,5 @@ core.eol=lf
|
||||||
*.png binary
|
*.png binary
|
||||||
*.qm binary
|
*.qm binary
|
||||||
*.zip binary
|
*.zip binary
|
||||||
|
|
||||||
|
test/testdata/crlf.txt text eol=crlf
|
||||||
|
|
|
@ -33,19 +33,19 @@ repos:
|
||||||
args: ["--fix=lf"]
|
args: ["--fix=lf"]
|
||||||
exclude: |
|
exclude: |
|
||||||
(?x)^(
|
(?x)^(
|
||||||
compile_commands.json |
|
|
||||||
src/webui/www/private/css/lib/.* |
|
src/webui/www/private/css/lib/.* |
|
||||||
src/webui/www/private/scripts/lib/.*
|
src/webui/www/private/scripts/lib/.* |
|
||||||
|
test/testdata/crlf.txt
|
||||||
)$
|
)$
|
||||||
|
|
||||||
- id: end-of-file-fixer
|
- id: end-of-file-fixer
|
||||||
name: Check trailing newlines
|
name: Check trailing newlines
|
||||||
exclude: |
|
exclude: |
|
||||||
(?x)^(
|
(?x)^(
|
||||||
compile_commands.json |
|
|
||||||
configure |
|
configure |
|
||||||
src/webui/www/private/css/lib/.* |
|
src/webui/www/private/css/lib/.* |
|
||||||
src/webui/www/private/scripts/lib/.*
|
src/webui/www/private/scripts/lib/.* |
|
||||||
|
test/testdata/crlf.txt
|
||||||
)$
|
)$
|
||||||
exclude_types:
|
exclude_types:
|
||||||
- svg
|
- svg
|
||||||
|
|
|
@ -89,16 +89,37 @@ nonstd::expected<QByteArray, Utils::IO::ReadError> Utils::IO::readFile(const Pat
|
||||||
return nonstd::make_unexpected(ReadError {ReadError::ExceedSize, message});
|
return nonstd::make_unexpected(ReadError {ReadError::ExceedSize, message});
|
||||||
}
|
}
|
||||||
|
|
||||||
// Do not use `QIODevice::readAll()` it won't stop when reading `/dev/zero`
|
#if (QT_VERSION >= QT_VERSION_CHECK(6, 5, 0))
|
||||||
const QByteArray data = file.read(fileSize);
|
QByteArray ret {fileSize, Qt::Uninitialized};
|
||||||
if (const qint64 dataSize = data.size(); dataSize != fileSize)
|
#else
|
||||||
|
QByteArray ret {static_cast<int>(fileSize), Qt::Uninitialized};
|
||||||
|
#endif
|
||||||
|
const qint64 actualSize = file.read(ret.data(), fileSize);
|
||||||
|
|
||||||
|
if (actualSize < 0)
|
||||||
{
|
{
|
||||||
const QString message = QCoreApplication::translate("Utils::IO", "Read size mismatch. File: \"%1\". Expected: %2. Actual: %3")
|
const QString message = QCoreApplication::translate("Utils::IO", "File read error. File: \"%1\". Error: \"%2\"")
|
||||||
.arg(file.fileName(), QString::number(fileSize), QString::number(dataSize));
|
.arg(file.fileName(), file.errorString());
|
||||||
return nonstd::make_unexpected(ReadError {ReadError::SizeMismatch, message});
|
return nonstd::make_unexpected(ReadError {ReadError::Failed, message});
|
||||||
}
|
}
|
||||||
|
|
||||||
return data;
|
if (actualSize < fileSize)
|
||||||
|
{
|
||||||
|
// `QIODevice::Text` will convert CRLF to LF on-the-fly and affects return value
|
||||||
|
// of `qint64 QIODevice::read(char *data, qint64 maxSize)`
|
||||||
|
if (additionalMode.testFlag(QIODevice::Text))
|
||||||
|
{
|
||||||
|
ret.truncate(actualSize);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
const QString message = QCoreApplication::translate("Utils::IO", "Read size mismatch. File: \"%1\". Expected: %2. Actual: %3")
|
||||||
|
.arg(file.fileName(), QString::number(fileSize), QString::number(actualSize));
|
||||||
|
return nonstd::make_unexpected(ReadError {ReadError::SizeMismatch, message});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
nonstd::expected<void, QString> Utils::IO::saveToFile(const Path &path, const QByteArray &data)
|
nonstd::expected<void, QString> Utils::IO::saveToFile(const Path &path, const QByteArray &data)
|
||||||
|
|
|
@ -89,6 +89,7 @@ namespace Utils::IO
|
||||||
{
|
{
|
||||||
NotExist,
|
NotExist,
|
||||||
ExceedSize,
|
ExceedSize,
|
||||||
|
Failed, // `read()` operation failed
|
||||||
SizeMismatch
|
SizeMismatch
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -516,6 +516,7 @@ void WebApplication::sendFile(const Path &path)
|
||||||
LogMsg(message, Log::WARNING);
|
LogMsg(message, Log::WARNING);
|
||||||
throw InternalServerErrorHTTPError(readResult.error().message);
|
throw InternalServerErrorHTTPError(readResult.error().message);
|
||||||
|
|
||||||
|
case Utils::IO::ReadError::Failed:
|
||||||
case Utils::IO::ReadError::SizeMismatch:
|
case Utils::IO::ReadError::SizeMismatch:
|
||||||
LogMsg(message, Log::WARNING);
|
LogMsg(message, Log::WARNING);
|
||||||
throw InternalServerErrorHTTPError(readResult.error().message);
|
throw InternalServerErrorHTTPError(readResult.error().message);
|
||||||
|
|
2
test/testdata/crlf.txt
vendored
Normal file
2
test/testdata/crlf.txt
vendored
Normal file
|
@ -0,0 +1,2 @@
|
||||||
|
|
||||||
|
|
|
@ -77,6 +77,13 @@ private slots:
|
||||||
QCOMPARE(readResult.value(), size10Data);
|
QCOMPARE(readResult.value(), size10Data);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
{
|
||||||
|
const Path crlfFile = testFolder / Path(u"crlf.txt"_s);
|
||||||
|
const auto readResult = Utils::IO::readFile(crlfFile, -1, QIODevice::Text);
|
||||||
|
QCOMPARE(readResult.has_value(), true);
|
||||||
|
QCOMPARE(readResult.value(), "\n\n");
|
||||||
|
}
|
||||||
|
|
||||||
{
|
{
|
||||||
const Path nonExistFile = testFolder / Path(u".non_existent_file_1234"_s);
|
const Path nonExistFile = testFolder / Path(u".non_existent_file_1234"_s);
|
||||||
const auto readResult = Utils::IO::readFile(nonExistFile, 1);
|
const auto readResult = Utils::IO::readFile(nonExistFile, 1);
|
||||||
|
|
Loading…
Reference in a new issue