KItinerary

uper-strings.cpp
1/*
2 SPDX-FileCopyrightText: 2022 Volker Krause <vkrause@kde.org>
3 SPDX-License-Identifier: LGPL-2.0-or-later
4*/
5
6#include <kitinerary_version.h>
7
8#include <../lib/asn1/bitvectorview.cpp>
9
10#include <QCommandLineParser>
11#include <QCoreApplication>
12#include <QFile>
13
14#include <iostream>
15
16using namespace KItinerary;
17
18static bool isPlausibleChar(uint8_t c)
19{
20 return c >= 0x20 && !std::iscntrl(c);
21}
22
23struct Result {
24 BitVectorView::size_type offset;
25 QByteArray::size_type length;
26 QByteArray data;
27};
28
29int main(int argc, char **argv)
30{
31 QCoreApplication::setApplicationName(QStringLiteral("uper-strings"));
32 QCoreApplication::setApplicationVersion(QStringLiteral(KITINERARY_VERSION_STRING));
33 QCoreApplication::setOrganizationDomain(QStringLiteral("kde.org"));
34 QCoreApplication::setOrganizationName(QStringLiteral("KDE"));
35 QCoreApplication app(argc, argv);
36
37 QCommandLineParser parser;
38 parser.setApplicationDescription(QStringLiteral("Find strings in uPER encoded content."));
39 parser.addHelpOption();
40 parser.addVersionOption();
41 parser.addPositionalArgument(QStringLiteral("input"), QStringLiteral("File to read data from, omit for using stdin."));
42 parser.process(app);
43
44 QFile file;
45 if (parser.positionalArguments().isEmpty()) {
46 file.open(stdin, QFile::ReadOnly);
47 } else {
48 file.setFileName(parser.positionalArguments().at(0));
49 if (!file.open(QFile::ReadOnly)) {
50 std::cerr << qPrintable(file.errorString()) << std::endl;
51 return 1;
52 }
53 }
54
55 const auto buffer = file.readAll();
56 const auto view = BitVectorView(std::string_view(buffer.constData(), buffer.size()));
57
58 // search for IA5Strings
59 std::vector<Result> results;
60 QByteArray candidate;
61 for (int i = 0; i < 7; ++i) {
62 BitVectorView::size_type j = i;
63 for (; j < view.size() - 7; j += 7) {
64 auto c = view.valueAtMSB<uint8_t>(j, 7);
65 if (isPlausibleChar(c)) {
66 candidate.push_back((char)c);
67 continue;
68 }
69
70 if (candidate.size() <= 2) {
71 candidate.clear();
72 continue;
73 }
74
75 results.push_back({j - candidate.size() * 7, candidate.size() * 7, candidate});
76 candidate.clear();
77 }
78 if (candidate.size() > 2) {
79 results.push_back({j - candidate.size() * 7, candidate.size() * 7, candidate});
80 }
81 candidate.clear();
82 }
83
84 std::sort(results.begin(), results.end(), [](const auto &lhs, const auto &rhs) { return lhs.offset < rhs.offset; });
85 std::cout << "IA5String candidates:" << std::endl;
86 for (const auto &res : results) {
87 std::cout << res.offset << ": " << res.data.constData() << std::endl;
88 }
89
90 // search for UTF8String
91 results.clear();
92 for (int i = 0; i < 8; ++i) {
93 BitVectorView::size_type j = i;
94 for (; j < view.size() - 8; j += 8) {
95 auto c = view.valueAtMSB<uint8_t>(j, 8);
96 if (isPlausibleChar(c)) {
97 candidate.push_back((char)c);
98 continue;
99 }
100
101 if (candidate.size() <= 2) {
102 candidate.clear();
103 continue;
104 }
105
106 results.push_back({j - candidate.size() * 8, candidate.size() * 8, candidate});
107 candidate.clear();
108 }
109 if (candidate.size() > 2) {
110 results.push_back({j - candidate.size() * 8, candidate.size() * 8, candidate});
111 }
112 candidate.clear();
113 }
114
115 std::sort(results.begin(), results.end(), [](const auto &lhs, const auto &rhs) { return lhs.offset < rhs.offset; });
116 std::cout << std::endl << "UTF8String candidates:" << std::endl;
117 for (const auto &res : results) {
118 std::cout << res.offset << ": " << qPrintable(QString::fromUtf8(res.data.constData())) << std::endl;
119 }
120}
Non-owning bit-level view for working with data that isn't byte-aligned.
Classes for reservation/travel data models, data extraction and data augmentation.
Definition berelement.h:17
void clear()
void push_back(QByteArrayView str)
qsizetype size() const const
QCommandLineOption addHelpOption()
void addPositionalArgument(const QString &name, const QString &description, const QString &syntax)
QCommandLineOption addVersionOption()
QStringList positionalArguments() const const
void process(const QCoreApplication &app)
void setApplicationDescription(const QString &description)
void setApplicationName(const QString &application)
void setApplicationVersion(const QString &version)
void setOrganizationDomain(const QString &orgDomain)
void setOrganizationName(const QString &orgName)
bool open(FILE *fh, OpenMode mode, FileHandleFlags handleFlags)
void setFileName(const QString &name)
QString errorString() const const
QByteArray readAll()
const_reference at(qsizetype i) const const
bool isEmpty() const const
QString fromUtf8(QByteArrayView str)
This file is part of the KDE documentation.
Documentation copyright © 1996-2025 The KDE developers.
Generated on Fri Apr 11 2025 11:58:39 by doxygen 1.13.2 written by Dimitri van Heesch, © 1997-2006

KDE's Doxygen guidelines are available online.