File indexing completed on 2024-06-23 05:13:54
0001 /* -*- mode: c++; c-basic-offset:4 -*- 0002 crypto/checksumsutils_p.cpp 0003 0004 This file is part of Kleopatra, the KDE keymanager 0005 SPDX-FileCopyrightText: 2010 Klarälvdalens Datakonsult AB 0006 0007 SPDX-License-Identifier: GPL-2.0-or-later 0008 */ 0009 0010 #include "checksumsutils_p.h" 0011 #include <Libkleo/ChecksumDefinition> 0012 0013 #include <QFile> 0014 #include <QTextStream> 0015 0016 std::vector<QRegularExpression> ChecksumsUtils::get_patterns(const std::vector<std::shared_ptr<Kleo::ChecksumDefinition>> &checksumDefinitions) 0017 { 0018 std::vector<QRegularExpression> result; 0019 for (const auto &cd : checksumDefinitions) { 0020 if (!cd) { 0021 continue; 0022 } 0023 const QStringList &patterns = cd->patterns(); 0024 result.reserve(result.size() + patterns.size()); 0025 std::transform(patterns.cbegin(), patterns.cend(), std::back_inserter(result), [](const QString &pattern) { 0026 return QRegularExpression(QRegularExpression::anchoredPattern(pattern), s_regex_cs); 0027 }); 0028 } 0029 0030 return result; 0031 } 0032 0033 static QString decode(const QString &encoded) 0034 { 0035 QString decoded; 0036 decoded.reserve(encoded.size()); 0037 bool shift = false; 0038 for (const QChar ch : encoded) 0039 if (shift) { 0040 switch (ch.toLatin1()) { 0041 case '\\': 0042 decoded += QLatin1Char('\\'); 0043 break; 0044 case 'n': 0045 decoded += QLatin1Char('\n'); 0046 break; 0047 default: 0048 qCDebug(KLEOPATRA_LOG) << "invalid escape sequence" << '\\' << ch << "(interpreted as '" << ch << "')"; 0049 decoded += ch; 0050 break; 0051 } 0052 shift = false; 0053 } else { 0054 if (ch == QLatin1Char('\\')) { 0055 shift = true; 0056 } else { 0057 decoded += ch; 0058 } 0059 } 0060 return decoded; 0061 } 0062 0063 std::vector<ChecksumsUtils::File> ChecksumsUtils::parse_sum_file(const QString &fileName) 0064 { 0065 std::vector<File> files; 0066 QFile f(fileName); 0067 if (!f.open(QIODevice::ReadOnly)) { 0068 return {}; 0069 } 0070 0071 QTextStream s(&f); 0072 static const QRegularExpression rx(QRegularExpression::anchoredPattern(uR"((\\?)([a-f0-9A-F]+) ([ *])([^\\n]+)\\n*)")); 0073 while (!s.atEnd()) { 0074 const QString line = s.readLine(); 0075 QRegularExpressionMatch match = rx.match(line); 0076 if (!match.hasMatch()) { 0077 continue; 0078 } 0079 0080 Q_ASSERT(!match.capturedView(4).endsWith(QLatin1Char('\n'))); 0081 const File file = { 0082 match.capturedView(1) == QLatin1Char('\\') ? decode(match.captured(4)) : match.captured(4), 0083 match.capturedView(2).toLatin1(), 0084 match.capturedView(3) == QLatin1Char('*'), 0085 }; 0086 files.push_back(file); 0087 } 0088 0089 return files; 0090 } 0091 0092 std::shared_ptr<Kleo::ChecksumDefinition> ChecksumsUtils::filename2definition(const QString &fileName, 0093 const std::vector<std::shared_ptr<Kleo::ChecksumDefinition>> &checksumDefinitions) 0094 { 0095 auto matchFileName = [&fileName](const std::shared_ptr<Kleo::ChecksumDefinition> &cd) { 0096 if (!cd) { 0097 return false; 0098 } 0099 0100 const QStringList &patterns = cd->patterns(); 0101 return std::any_of(patterns.cbegin(), patterns.cend(), [&fileName](const QString &pattern) { 0102 const QRegularExpression re(QRegularExpression::anchoredPattern(pattern), s_regex_cs); 0103 return re.match(fileName).hasMatch(); 0104 }); 0105 }; 0106 0107 auto it = std::find_if(checksumDefinitions.cbegin(), checksumDefinitions.cend(), matchFileName); 0108 0109 return it != checksumDefinitions.cend() ? *it : std::shared_ptr<Kleo::ChecksumDefinition>{}; 0110 }