• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

squinky86 / STIGQter / 41772281141

04 Nov 2026 04:16AM UTC coverage: 68.902% (-7.0%) from 75.946%
41772281141

push

github

squinky86
Refactor STIGQter and modernize build and update services

8082 of 13137 branches covered (61.52%)

Branch coverage included in aggregate %.

2404 of 2696 new or added lines in 30 files covered. (89.17%)

9 existing lines in 8 files now uncovered.

5914 of 7176 relevant lines covered (82.41%)

38491.09 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

81.01
/src/common.cpp
1
/*
2
 * STIGQter - STIG fun with Qt
3
 *
4
 * Copyright © 2018–2023 Jon Hood, http://www.hoodsecurity.com/
5
 *
6
 * This program is free software: you can redistribute it and/or modify
7
 * it under the terms of the GNU General Public License as published by
8
 * the Free Software Foundation, either version 3 of the License, or
9
 * (at your option) any later version.
10
 *
11
 * This program is distributed in the hope that it will be useful,
12
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14
 * GNU General Public License for more details.
15
 *
16
 * You should have received a copy of the GNU General Public License
17
 * along with this program.  If not, see <http://www.gnu.org/licenses/>.
18
 */
19

20
#include "common.h"
21
#include "dbmanager.h"
22

23
bool IgnoreWarnings = false;
24

25

26
#include <QApplication>
27
#include <QDebug>
28
#include <QFileInfo>
29
#include <QtGlobal>
30
#include <QMessageBox>
31
#include <QRegularExpression>
32
#include <QString>
33
#include <QThread>
34

35
/**
36
 * @brief MessageHandler
37
 * @param type
38
 * @param context
39
 * @param msg
40
 *
41
 * Logging of Qt messages occurs here. Set the LogLevel to 6 for full
42
 * debugging. Default is LogLevel 5.
43
 */
44
void MessageHandler(QtMsgType type, const QMessageLogContext &context, const QString &msg)
5 ✔
45
{
46
    int severity = 0;
5 ✔
47
    switch (type)
5 !
48
    {
49
    case QtDebugMsg:
1 ✔
50
        severity = 5;
1 ✔
51
        break;
1 ✔
52
    case QtInfoMsg:
1 ✔
53
        severity = 4;
1 ✔
54
        break;
1 ✔
55
    case QtWarningMsg:
1 ✔
56
        severity = 3;
1 ✔
57
        break;
1 ✔
58
    case QtCriticalMsg:
1 ✔
59
        severity = 2;
1 ✔
60
        break;
1 ✔
61
    case QtFatalMsg:
1 ✔
62
        severity = 1;
1 ✔
63
        break;
1 ✔
64
    //should not be any other types; "default" is for scenarios where new types are added later.
65
    //[[unlikely]] - uncomment when moving to >=Qt 5.14 and C++20
66
    default:
×
67
        severity = 0;
×
68
        break;
×
69
    }
70
    DbManager db;
5 ✔
71
    db.Log(severity, context.file + QStringLiteral(":") + QString::number(context.line) + QStringLiteral(" ") + context.function, msg);
15 ✔
72
}
5 ✔
73

74
/**
75
 * @brief GetCCINumber
76
 * @param cci
77
 * @return The numeric value of the CCI.
78
 *
79
 * Converts a string "CCI-######" to its integral format.
80
 */
81
int GetCCINumber(QString cci)
1,960 ✔
82
{
83
    cci = cci.trimmed();
1,960 ✔
84
    if (cci.startsWith(QStringLiteral("CCI-")))
1,960 !
85
        cci = cci.right(cci.length() - 4);
1,960 ✔
86
    return cci.toInt();
1,960 ✔
87
}
88

89
/**
90
 * @brief GetReleaseNumber
91
 * @param release
92
 * @return The release number from a STIG release string
93
 */
94
int GetReleaseNumber(const QString &release)
607 ✔
95
{
96
    static const QRegularExpression releasePattern(
97
        QStringLiteral("(?:^|\\b)(?:release\\s*:?|r)\\s*(\\d+)\\b"),
2 ✔
98
        QRegularExpression::CaseInsensitiveOption);
609 !
99
    const QRegularExpressionMatch match = releasePattern.match(release);
607 ✔
100
    if (!match.hasMatch())
607 !
101
        return -1;
×
102

103
    bool ok = false;
607 ✔
104
    const int releaseNumber = match.captured(1).toInt(&ok);
607 ✔
105
    return ok ? releaseNumber : -1;
607 !
106
}
607 ✔
107

108
/**
109
 * @brief GetUserAgent
110
 * @return The User-Agent to use when making web requests.
111
 */
112
QString GetUserAgent()
13 ✔
113
{
114
    return QString(QStringLiteral("STIGQter/")) + VERSION;
26 ✔
115
}
116

117
/**
118
 * @brief Excelify
119
 * @param s
120
 * @return The string @a s formatted in a way that Excel can
121
 * understand.
122
 */
123
QString Excelify(const QString &s)
82,404 ✔
124
{
125
    //Excel is limited to 32,767 characters per-cell
126
    QString ret = s.left(32767);
82,404 ✔
127
    //STIG Rule SV-222447r508029_rule - Prevent CSV Injection
128
    if (ret.startsWith('=') || ret.startsWith('+') || ret.startsWith('-') || ret.startsWith('@'))
82,404 !
129
    {
130
        ret.prepend('\'');
×
131
    }
132
    return ret;
82,404 ✔
UNCOV
133
}
×
134

135
/**
136
 * @brief Pluralize
137
 * @param count
138
 * @param plural
139
 * @param singular
140
 * @return @c @a plural when @a count indicates that plural usage is
141
 * appropriate. Otherwise, @c @a singular.
142
 */
143
QString Pluralize(const int count, const QString &plural, const QString &singular)
6 ✔
144
{
145
    return (count == 1) ? singular : plural;
6 !
146
}
147

148
/**
149
 * @brief PrintTrueFalse
150
 * @param tf
151
 * @return human-readable boolean.
152
 */
153
QString PrintTrueFalse(bool tf)
1,720 ✔
154
{
155
    return tf ? QStringLiteral("true") : QStringLiteral("false");
5,160 ✔
156
}
157

158
QString Sanitize(QString s)
40 ✔
159
{
160
    s = s.replace(QStringLiteral("\r\n"), QStringLiteral("\n"));
80 ✔
161
    s = s.replace(QStringLiteral("\n"), QStringLiteral(" "));
80 ✔
162
    return s;
40 ✔
163
}
164

165
QString SanitizeFile(QString s)
21 ✔
166
{
167
    //UTF replacements have trouble with QStrings
168
    s = s.replace(QStringLiteral("/"), QStringLiteral(" ̸"));
42 ✔
169
    s = s.replace(QStringLiteral("\\"), QStringLiteral("-"));
42 ✔
170
    s = s.replace(QStringLiteral("?"), QStringLiteral("-"));
42 ✔
171
    s = s.replace(QStringLiteral("*"), QStringLiteral("-"));
42 ✔
172
    s = s.replace(QStringLiteral("\""), QStringLiteral("-"));
42 ✔
173
    s = s.replace(QStringLiteral("<"), QStringLiteral("-"));
42 ✔
174
    s = s.replace(QStringLiteral(">"), QStringLiteral("-"));
42 ✔
175
    s = s.replace(QStringLiteral("|"), QStringLiteral("-"));
42 ✔
176
    s = s.replace(QStringLiteral(":"), QStringLiteral("-"));
42 ✔
177
    s = s.replace(QStringLiteral("#"), QStringLiteral("-"));
42 ✔
178
    s = s.replace(QStringLiteral("%"), QStringLiteral("-"));
42 ✔
179
    s = s.replace(QStringLiteral("$"), QStringLiteral("-"));
42 ✔
180
    s = s.replace(QStringLiteral("!"), QStringLiteral("-"));
42 ✔
181
    s = s.replace(QStringLiteral("{"), QStringLiteral("-"));
42 ✔
182
    s = s.replace(QStringLiteral("}"), QStringLiteral("-"));
42 ✔
183
    s = s.replace(QStringLiteral("@"), QStringLiteral("-"));
42 ✔
184
    return s;
21 ✔
185
}
186

187
/**
188
 * @brief TrimFileName
189
 * @param fileName
190
 * @return The fileName without any leading directory structure.
191
 */
192
QString TrimFileName(const QString &fileName)
10 ✔
193
{
194
    QFileInfo fi(fileName);
10 ✔
195
    return fi.fileName();
20 ✔
196
}
10 ✔
197

198
/**
199
 * @brief Warning
200
 * @param title
201
 * @param message
202
 * @param quiet
203
 * @param level
204
 *
205
 * When @a quiet is not @c true, displays a warning box with the
206
 * provided @a title and @a message. The title and message are always
207
 * printed on the console/debug log.
208
 */
209
void Warning(const QString &title, const QString &message, const bool quiet, const int level)
423 ✔
210
{
211
    DbManager db;
423 ✔
212
    db.Log(level, QString(), title + ": " + message);
423 ✔
213
    if (!IgnoreWarnings && !quiet && (QThread::currentThread() == QApplication::instance()->thread())) //make sure we're in the GUI thread before popping a message box
423 !
214
    {
215
        int ret = QMessageBox::warning(nullptr, title, message, QMessageBox::Ignore | QMessageBox::Ok);
×
216
        //if ignoring messages, move to quiet mode
217
        if (ret == QMessageBox::Ignore)
×
218
        {
219
            IgnoreWarnings = true;
×
220
        }
221
    }
222
}
423 ✔
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE TRIAL · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2026 Coveralls, Inc