diff --git a/src/crypto/checksumsutils_p.h b/src/crypto/checksumsutils_p.h index df2b01fb7..719bfe292 100644 --- a/src/crypto/checksumsutils_p.h +++ b/src/crypto/checksumsutils_p.h @@ -1,136 +1,151 @@ /* -*- mode: c++; c-basic-offset:4 -*- crypto/createchecksumscontroller.cpp This file is part of Kleopatra, the KDE keymanager SPDX-FileCopyrightText: 2010 Klarälvdalens Datakonsult AB SPDX-License-Identifier: GPL-2.0-or-later */ #ifndef CHECKSUMSUTILS_P #define CHECKSUMSUTILS_P #include #include "kleopatra_debug.h" #include #include #include #ifdef Q_OS_UNIX // Can we use QAbstractFileEngine::caseSensitive()? static const Qt::CaseSensitivity fs_cs = Qt::CaseSensitive; static const QRegularExpression::PatternOption s_regex_cs = QRegularExpression::NoPatternOption; #else static const Qt::CaseSensitivity fs_cs = Qt::CaseInsensitive; static const QRegularExpression::PatternOption s_regex_cs = QRegularExpression::CaseInsensitiveOption; #endif using namespace Kleo; -static QList get_patterns(const std::vector< std::shared_ptr > &checksumDefinitions) +static QList get_patterns(const std::vector> &checksumDefinitions) { QList result; - for (const auto &cd : checksumDefinitions) - if (cd) { - const auto patterns = cd->patterns(); - for (const QString &pattern : patterns) { - result.push_back(QRegularExpression(QRegularExpression::anchoredPattern(pattern), s_regex_cs)); - } + auto addRegex = [&result](const std::shared_ptr &cd) { + if (!cd) { + return; } + const QStringList &patterns = cd->patterns(); + result.reserve(result.size() + patterns.size()); + std::transform(patterns.cbegin(), patterns.cend(), std::back_inserter(result), [](const QString &pattern) { + return QRegularExpression(QRegularExpression::anchoredPattern(pattern), s_regex_cs); + }); + }; + + for (const auto &cd : checksumDefinitions) { + addRegex(cd); + } + return result; } namespace { struct matches_any : std::unary_function { const QList m_regexps; explicit matches_any(const QList ®exps) : m_regexps(regexps) {} bool operator()(const QString &s) const { return std::any_of(m_regexps.cbegin(), m_regexps.cend(), - [s](const QRegularExpression &rx) { return rx.match(s).hasMatch(); }); + [&s](const QRegularExpression &rx) { return rx.match(s).hasMatch(); }); } }; } namespace { struct File { QString name; QByteArray checksum; bool binary; }; } static QString decode(const QString &encoded) { QString decoded; decoded.reserve(encoded.size()); bool shift = false; - for (QChar ch : encoded) + for (const QChar ch : encoded) if (shift) { switch (ch.toLatin1()) { case '\\': decoded += QLatin1Char('\\'); break; case 'n': decoded += QLatin1Char('\n'); break; default: qCDebug(KLEOPATRA_LOG) << "invalid escape sequence" << '\\' << ch << "(interpreted as '" << ch << "')"; decoded += ch; break; } shift = false; } else { if (ch == QLatin1Char('\\')) { shift = true; } else { decoded += ch; } } return decoded; } static std::vector parse_sum_file(const QString &fileName) { std::vector files; QFile f(fileName); - if (f.open(QIODevice::ReadOnly)) { - QTextStream s(&f); - static const QRegularExpression rx(QRegularExpression::anchoredPattern(QLatin1String("(\\?)([a-f0-9A-F]+) ([ *])([^\n]+)\n*"))); - while (!s.atEnd()) { - const QString line = s.readLine(); - QRegularExpressionMatch match = rx.match(line); - if (match.hasMatch()) { - Q_ASSERT(!match.capturedView(4).endsWith(QLatin1Char('\n'))); - const File file = { - match.capturedView(1) == QLatin1String("\\") ? decode(match.captured(4)) : match.captured(4), - match.capturedView(2).toLatin1(), - match.capturedView(3) == QLatin1String("*"), - }; - files.push_back(file); - } + if (!f.open(QIODevice::ReadOnly)) { + return {}; + } + + QTextStream s(&f); + static const QRegularExpression rx(QRegularExpression::anchoredPattern(QLatin1String("(\\?)([a-f0-9A-F]+) ([ *])([^\n]+)\n*"))); + while (!s.atEnd()) { + const QString line = s.readLine(); + QRegularExpressionMatch match = rx.match(line); + if (!match.hasMatch()) { + continue; } + + Q_ASSERT(!match.capturedView(4).endsWith(QLatin1Char('\n'))); + const File file = { + match.capturedView(1) == QLatin1Char('\\') ? decode(match.captured(4)) : match.captured(4), + match.capturedView(2).toLatin1(), + match.capturedView(3) == QLatin1Char('*'), + }; + files.push_back(file); } + return files; } static std::shared_ptr filename2definition(const QString &fileName, - const std::vector< std::shared_ptr > &checksumDefinitions) + const std::vector> &checksumDefinitions) { - - for (const std::shared_ptr &cd : checksumDefinitions) { - if (cd) { - const auto patterns = cd->patterns(); - for (const QString &pattern : patterns) { - const QRegularExpression re(QRegularExpression::anchoredPattern(pattern), s_regex_cs); - if (re.match(fileName).hasMatch()) { - return cd; - } - } + auto fileNameMatch = [&fileName](const std::shared_ptr &cd) { + if (!cd) { + return false; } - } - return std::shared_ptr(); + + const QStringList &patterns = cd->patterns(); + return std::any_of(patterns.cbegin(), patterns.cend(), [&fileName](const QString &pattern) { + const QRegularExpression re(QRegularExpression::anchoredPattern(pattern), s_regex_cs); + return re.match(fileName).hasMatch(); + }); + }; + + auto it = std::find_if(checksumDefinitions.cbegin(), checksumDefinitions.cend(), fileNameMatch); + + return it != checksumDefinitions.cend() ? *it : std::shared_ptr{}; } #endif // CHECKSUMSUTILS_P