Restrict filenames to alphanumeric characters

This commit is contained in:
Bart De Vries 2023-07-06 14:56:33 +02:00
parent dc311cac7b
commit 46fc8904ec
4 changed files with 26 additions and 4 deletions

View File

@ -13,6 +13,7 @@
#include <QDir>
#include <QFile>
#include <QFileInfo>
#include <QRegularExpression>
#include <QSqlDatabase>
#include <QSqlError>
#include <QStandardPaths>
@ -191,7 +192,8 @@ bool Database::migrateTo8()
QString name = query.value(QStringLiteral("name")).toString();
// Generate directory name for enclosures based on feed name
QString dirBaseName = name.left(maxFilenameLength);
QString dirBaseName = name.remove(QRegularExpression(QStringLiteral("[^a-zA-Z0-9 ._()-]"))).simplified().left(maxFilenameLength);
dirBaseName = dirBaseName.isEmpty() ? QStringLiteral("Noname") : dirBaseName;
QString dirName = dirBaseName;
// Check for duplicate names
@ -226,8 +228,11 @@ bool Database::migrateTo8()
if (QFileInfo::exists(legacyPath) && QFileInfo(legacyPath).isFile()) {
// Generate filename based on episode name and url hash with feedname as subdirectory
QString enclosureFilenameBase = queryTitle.left(maxFilenameLength) + QStringLiteral(".")
QString enclosureFilenameBase = queryTitle.remove(QRegularExpression(QStringLiteral("[^a-zA-Z0-9 ._()-]"))).simplified().left(maxFilenameLength);
enclosureFilenameBase = enclosureFilenameBase.isEmpty() ? QStringLiteral("Noname") : enclosureFilenameBase;
enclosureFilenameBase += QStringLiteral(".")
+ QString::fromStdString(QCryptographicHash::hash(queryUrl.toUtf8(), QCryptographicHash::Md5).toHex().toStdString()).left(6);
QString enclosureFilenameExt = QFileInfo(QUrl::fromUserInput(queryUrl).fileName()).suffix();
QString enclosureFilename =

View File

@ -14,6 +14,7 @@
#include <QDir>
#include <QFile>
#include <QFileInfo>
#include <QRegularExpression>
#include <QStandardPaths>
#include "enclosure.h"
@ -138,8 +139,9 @@ QString StorageManager::enclosureDirPath(const QString &feedname) const
QString StorageManager::enclosurePath(const QString &name, const QString &url, const QString &feedname) const
{
// Generate filename based on episode name and url hash with feedname as subdirectory
QString enclosureFilenameBase = name.left(maxFilenameLength) + QStringLiteral(".")
QString enclosureFilenameBase = sanitizedFilePath(name) + QStringLiteral(".")
+ QString::fromStdString(QCryptographicHash::hash(url.toUtf8(), QCryptographicHash::Md5).toHex().toStdString()).left(6);
QString enclosureFilenameExt = QFileInfo(QUrl::fromUserInput(url).fileName()).suffix();
QString enclosureFilename = !enclosureFilenameExt.isEmpty() ? enclosureFilenameBase + QStringLiteral(".") + enclosureFilenameExt : enclosureFilenameBase;
@ -205,3 +207,16 @@ QString StorageManager::passwordFilePath(const QString &username) const
{
return QStandardPaths::writableLocation(QStandardPaths::AppDataLocation) + QStringLiteral("/") + username;
}
QString StorageManager::sanitizedFilePath(const QString &path) const
{
// NOTE: Any changes here require a database migration!
// Only keep alphanumeric ascii characters; this avoid any kind of issues
// with the many types of filesystems out there. Then remove excess whitespace
// and limit the length of the string.
QString newPath = path;
newPath = newPath.remove(QRegularExpression(QStringLiteral("[^a-zA-Z0-9 ._()-]"))).simplified().left(maxFilenameLength);
return newPath.isEmpty() ? QStringLiteral("Noname") : newPath;
}

View File

@ -56,6 +56,8 @@ public:
QString passwordFilePath(const QString &username) const;
QString sanitizedFilePath(const QString &path) const;
Q_SIGNALS:
void error(Error::Type type, const QString &url, const QString &id, const int errorId, const QString &errorString, const QString &title);

View File

@ -698,7 +698,7 @@ QString UpdateFeedJob::generateFeedDirname(const QString &name) const
{
// Generate directory name for enclosures based on feed name
// NOTE: Any changes here require a database migration!
QString dirBaseName = name.left(StorageManager::maxFilenameLength);
QString dirBaseName = StorageManager::instance().sanitizedFilePath(name);
QString dirName = dirBaseName;
QStringList dirNameList;