MailJDTourDownloadDocsQualityTestsCoverage

Which source lines and branches the tests execute. Lines 91.5 %, branches 75.0 % (minimum 85 % and 72 %). main @ 399ffe3d · 21 October 2026 · pipeline 7238.

GCC Code Coverage Report


Directory: src/
Coverage: low: ≥ 0% medium: ≥ 75.0% high: ≥ 90.0%
Coverage Exec / Excl / Total
Lines: 91.1% 225 / 0 / 247
Functions: 100.0% 14 / 0 / 14
Branches: 80.9% 242 / 0 / 299

service/ManageSieveProtocol.cpp
Line Branch Exec Source
1 #include "ManageSieveProtocol.h"
2
3 #include <QRegularExpression>
4
5 namespace ManageSieve {
6
7 namespace {
8
9 22711 bool isAtomChar(char c) {
10
11/14
✓ Branch 2 → 3 taken 19087 times.
✓ Branch 2 → 10 taken 3624 times.
✓ Branch 3 → 4 taken 18409 times.
✓ Branch 3 → 10 taken 678 times.
✓ Branch 4 → 5 taken 18408 times.
✓ Branch 4 → 10 taken 1 time.
✓ Branch 5 → 6 taken 18408 times.
✗ Branch 5 → 10 not taken.
✓ Branch 6 → 7 taken 18391 times.
✓ Branch 6 → 10 taken 17 times.
✓ Branch 7 → 8 taken 18391 times.
✗ Branch 7 → 10 not taken.
✓ Branch 8 → 9 taken 18391 times.
✗ Branch 8 → 10 not taken.
22711 return c != ' ' && c != '\r' && c != '\n' && c != '(' && c != ')' && c != '"' && c != '{';
11 }
12
13 // Parses "{n}" or "{n+}" at `pos`. Returns false when malformed.
14 962 bool literalHeader(const QByteArray &buffer, int pos, qint64 *size, int *headerEnd) {
15 962 int i = pos + 1;
16 962 qint64 value = 0;
17 962 bool digits = false;
18
7/8
✓ Branch 8 → 9 taken 4052 times.
✗ Branch 8 → 14 not taken.
✓ Branch 10 → 11 taken 3792 times.
✓ Branch 10 → 14 taken 260 times.
✓ Branch 12 → 13 taken 3090 times.
✓ Branch 12 → 14 taken 702 times.
✓ Branch 15 → 3 taken 3090 times.
✓ Branch 15 → 16 taken 962 times.
4052 while (i < buffer.size() && buffer.at(i) >= '0' && buffer.at(i) <= '9') {
19 3090 value = value * 10 + (buffer.at(i) - '0');
20
1/2
✗ Branch 4 → 5 not taken.
✓ Branch 4 → 6 taken 3090 times.
3090 if (value > (qint64(1) << 40))
21 ✗ return false;
22 3090 digits = true;
23 3090 ++i;
24 }
25
5/6
✓ Branch 17 → 18 taken 962 times.
✗ Branch 17 → 21 not taken.
✓ Branch 19 → 20 taken 260 times.
✓ Branch 19 → 21 taken 702 times.
✓ Branch 22 → 23 taken 260 times.
✓ Branch 22 → 24 taken 702 times.
962 if (i < buffer.size() && buffer.at(i) == '+')
26 260 ++i;
27
4/8
✓ Branch 24 → 25 taken 962 times.
✗ Branch 24 → 29 not taken.
✓ Branch 26 → 27 taken 962 times.
✗ Branch 26 → 29 not taken.
✗ Branch 28 → 29 not taken.
✓ Branch 28 → 30 taken 962 times.
✗ Branch 31 → 32 not taken.
✓ Branch 31 → 33 taken 962 times.
962 if (!digits || i >= buffer.size() || buffer.at(i) != '}')
28 ✗ return false;
29 962 *size = value;
30 962 *headerEnd = i + 1;
31 962 return true;
32 }
33
34 } // namespace
35
36 18441 LineStatus readLine(const QByteArray &buffer, const LineLimits &limits, QList<Token> *tokens,
37 int *consumed, QString *error) {
38 18441 tokens->clear();
39 18441 int pos = 0;
40 18441 int lineBytes = 0; // bytes outside literals, for the line limit
41 while (true) {
42
2/2
✓ Branch 4 → 5 taken 1 time.
✓ Branch 4 → 12 taken 51296 times.
51297 if (lineBytes > limits.maxLine) {
43 1 *error = QStringLiteral("Response line too long");
44 1 return LineStatus::Error;
45 }
46
2/2
✓ Branch 13 → 14 taken 56 times.
✓ Branch 13 → 15 taken 51240 times.
51296 if (pos >= buffer.size())
47 56 return LineStatus::Incomplete;
48 51240 const char c = buffer.at(pos);
49
2/2
✓ Branch 16 → 17 taken 7322 times.
✓ Branch 16 → 18 taken 43918 times.
51240 if (c == ' ') {
50 7322 ++pos;
51 7322 ++lineBytes;
52
4/4
✓ Branch 18 → 19 taken 25802 times.
✓ Branch 18 → 20 taken 18116 times.
✓ Branch 19 → 20 taken 1 time.
✓ Branch 19 → 36 taken 25801 times.
43918 } else if (c == '\r' || c == '\n') {
53
2/2
✓ Branch 20 → 21 taken 18116 times.
✓ Branch 20 → 34 taken 1 time.
18117 if (c == '\r') {
54
2/2
✓ Branch 22 → 23 taken 4 times.
✓ Branch 22 → 24 taken 18112 times.
18116 if (pos + 1 >= buffer.size())
55 4 return LineStatus::Incomplete;
56
1/2
✗ Branch 25 → 26 not taken.
✓ Branch 25 → 33 taken 18112 times.
18112 if (buffer.at(pos + 1) != '\n') {
57 ✗ *error = QStringLiteral("Bare CR in response");
58 ✗ return LineStatus::Error;
59 }
60 18112 *consumed = pos + 2;
61 } else {
62 1 *consumed = pos + 1;
63 }
64 18113 return LineStatus::Complete;
65
4/4
✓ Branch 36 → 37 taken 25782 times.
✓ Branch 36 → 38 taken 19 times.
✓ Branch 37 → 38 taken 19 times.
✓ Branch 37 → 44 taken 25763 times.
25801 } else if (c == '(' || c == ')') {
66
3/3
✓ Branch 38 → 39 taken 19 times.
✓ Branch 38 → 40 taken 19 times.
✓ Branch 41 → 42 taken 38 times.
38 tokens->append({c == '(' ? Token::Kind::LeftParen : Token::Kind::RightParen, {}});
67 38 ++pos;
68 38 ++lineBytes;
69
2/2
✓ Branch 44 → 45 taken 20480 times.
✓ Branch 44 → 92 taken 5283 times.
25763 } else if (c == '"') {
70 20480 QByteArray value;
71 20480 int i = pos + 1;
72 20480 bool closed = false;
73
2/2
✓ Branch 80 → 46 taken 282371 times.
✓ Branch 80 → 81 taken 14 times.
282385 while (i < buffer.size()) {
74 282371 const char q = buffer.at(i);
75
5/6
✓ Branch 47 → 48 taken 2 times.
✓ Branch 47 → 51 taken 282369 times.
✓ Branch 49 → 50 taken 2 times.
✗ Branch 49 → 51 not taken.
✓ Branch 52 → 53 taken 2 times.
✓ Branch 52 → 56 taken 282369 times.
282371 if (q == '\\' && i + 1 < buffer.size()) {
76
1/1
✓ Branch 54 → 55 taken 2 times.
2 value.append(buffer.at(i + 1));
77 2 i += 2;
78
1/2
✗ Branch 56 → 57 not taken.
✓ Branch 56 → 58 taken 282369 times.
282369 } else if (q == '\\') {
79 ✗ return LineStatus::Incomplete;
80
2/2
✓ Branch 58 → 59 taken 20465 times.
✓ Branch 58 → 60 taken 261904 times.
282369 } else if (q == '"') {
81 20465 closed = true;
82 20465 ++i;
83 20465 break;
84
3/4
✓ Branch 60 → 61 taken 261903 times.
✓ Branch 60 → 62 taken 1 time.
✗ Branch 61 → 62 not taken.
✓ Branch 61 → 69 taken 261903 times.
261904 } else if (q == '\r' || q == '\n') {
85 1 *error = QStringLiteral("Line break inside a quoted string");
86 1 return LineStatus::Error;
87 } else {
88
1/1
✓ Branch 69 → 70 taken 261903 times.
261903 value.append(q);
89 261903 ++i;
90 }
91
1/2
✗ Branch 71 → 72 not taken.
✓ Branch 71 → 79 taken 261905 times.
261905 if (i - pos > limits.maxLine) {
92 ✗ *error = QStringLiteral("Quoted string too long");
93 ✗ return LineStatus::Error;
94 }
95 }
96
2/2
✓ Branch 81 → 82 taken 14 times.
✓ Branch 81 → 83 taken 20465 times.
20479 if (!closed)
97 14 return LineStatus::Incomplete;
98
1/1
✓ Branch 84 → 85 taken 20465 times.
20465 tokens->append({Token::Kind::String, value});
99 20465 lineBytes += i - pos;
100 20465 pos = i;
101
4/4
✓ Branch 88 → 89 taken 20465 times.
✓ Branch 88 → 91 taken 15 times.
✓ Branch 92 → 93 taken 962 times.
✓ Branch 92 → 145 taken 4321 times.
25763 } else if (c == '{') {
102 962 qint64 size = 0;
103 962 int headerEnd = 0;
104 962 const int close = buffer.indexOf('}', pos);
105
1/2
✗ Branch 94 → 95 not taken.
✓ Branch 94 → 100 taken 962 times.
962 if (close < 0)
106
0/2
✗ Branch 96 → 97 not taken.
✗ Branch 96 → 98 not taken.
252 return buffer.size() - pos > 32 ? LineStatus::Error : LineStatus::Incomplete;
107
1/2
✗ Branch 101 → 102 not taken.
✓ Branch 101 → 109 taken 962 times.
962 if (!literalHeader(buffer, pos, &size, &headerEnd)) {
108 ✗ *error = QStringLiteral("Malformed literal");
109 ✗ return LineStatus::Error;
110 }
111
2/2
✓ Branch 109 → 110 taken 2 times.
✓ Branch 109 → 117 taken 960 times.
962 if (size > limits.maxLiteral) {
112 2 *error = QStringLiteral("Literal too large");
113 2 return LineStatus::Error;
114 }
115 960 int dataStart = headerEnd;
116
3/6
✓ Branch 118 → 119 taken 960 times.
✗ Branch 118 → 122 not taken.
✓ Branch 120 → 121 taken 960 times.
✗ Branch 120 → 122 not taken.
✓ Branch 123 → 124 taken 960 times.
✗ Branch 123 → 125 not taken.
960 if (dataStart < buffer.size() && buffer.at(dataStart) == '\r')
117 960 ++dataStart;
118
1/2
✗ Branch 126 → 127 not taken.
✓ Branch 126 → 128 taken 960 times.
960 if (dataStart >= buffer.size())
119 ✗ return LineStatus::Incomplete;
120
1/2
✗ Branch 129 → 130 not taken.
✓ Branch 129 → 137 taken 960 times.
960 if (buffer.at(dataStart) != '\n') {
121 ✗ *error = QStringLiteral("Literal without line break");
122 ✗ return LineStatus::Error;
123 }
124 960 ++dataStart;
125
2/2
✓ Branch 138 → 139 taken 250 times.
✓ Branch 138 → 140 taken 710 times.
960 if (buffer.size() - dataStart < size)
126 250 return LineStatus::Incomplete;
127
1/1
✓ Branch 141 → 142 taken 710 times.
710 tokens->append({Token::Kind::String, buffer.mid(dataStart, static_cast<int>(size))});
128 710 lineBytes += headerEnd - pos;
129 710 pos = dataStart + static_cast<int>(size);
130 } else {
131 4321 int i = pos;
132
6/6
✓ Branch 148 → 149 taken 22711 times.
✓ Branch 148 → 153 taken 1 time.
✓ Branch 151 → 152 taken 18391 times.
✓ Branch 151 → 153 taken 4320 times.
✓ Branch 154 → 146 taken 18391 times.
✓ Branch 154 → 155 taken 4321 times.
22712 while (i < buffer.size() && isAtomChar(buffer.at(i)))
133 18391 ++i;
134
1/1
✓ Branch 156 → 157 taken 4321 times.
4321 tokens->append({Token::Kind::Atom, buffer.mid(pos, i - pos)});
135 4321 lineBytes += i - pos;
136 4321 pos = i;
137 }
138 32856 }
139 25496 }
140
141 34217 bool isFinalResponse(const QList<Token> &tokens) {
142
5/6
✓ Branch 3 → 4 taken 34217 times.
✗ Branch 3 → 6 not taken.
✓ Branch 5 → 6 taken 24954 times.
✓ Branch 5 → 7 taken 9263 times.
✓ Branch 8 → 9 taken 24954 times.
✓ Branch 8 → 10 taken 9263 times.
34217 if (tokens.isEmpty() || tokens.first().kind != Token::Kind::Atom)
143 24954 return false;
144
1/1
✓ Branch 11 → 12 taken 9263 times.
9263 const QByteArray word = tokens.first().text.toUpper();
145
5/6
✓ Branch 13 → 14 taken 95 times.
✓ Branch 13 → 18 taken 9168 times.
✓ Branch 15 → 16 taken 10 times.
✓ Branch 15 → 18 taken 85 times.
✓ Branch 17 → 18 taken 10 times.
✗ Branch 17 → 19 not taken.
9263 return word == "OK" || word == "NO" || word == "BYE";
146 9263 }
147
148 4632 Response parseResponse(const QList<Token> &tokens) {
149 4632 Response response;
150
2/3
✓ Branch 2 → 3 taken 4632 times.
✗ Branch 3 → 4 not taken.
✓ Branch 3 → 5 taken 4632 times.
4632 if (!isFinalResponse(tokens))
151 ✗ return response;
152
1/1
✓ Branch 6 → 7 taken 4632 times.
4632 const QByteArray word = tokens.first().text.toUpper();
153
2/2
✓ Branch 8 → 9 taken 4584 times.
✓ Branch 8 → 10 taken 48 times.
4680 response.status = word == "OK" ? Response::Status::Ok
154
2/2
✓ Branch 11 → 12 taken 43 times.
✓ Branch 11 → 13 taken 5 times.
48 : word == "NO" ? Response::Status::No
155 : Response::Status::Bye;
156 4632 int i = 1;
157
5/6
✓ Branch 16 → 17 taken 4632 times.
✗ Branch 16 → 20 not taken.
✓ Branch 18 → 19 taken 32 times.
✓ Branch 18 → 20 taken 4600 times.
✓ Branch 21 → 22 taken 32 times.
✓ Branch 21 → 46 taken 4600 times.
4632 if (i < tokens.size() && tokens.at(i).kind == Token::Kind::LeftParen) {
158 32 ++i;
159 32 bool first = true;
160
5/6
✓ Branch 39 → 40 taken 67 times.
✗ Branch 39 → 43 not taken.
✓ Branch 41 → 42 taken 35 times.
✓ Branch 41 → 43 taken 32 times.
✓ Branch 44 → 23 taken 35 times.
✓ Branch 44 → 45 taken 32 times.
67 while (i < tokens.size() && tokens.at(i).kind != Token::Kind::RightParen) {
161
1/1
✓ Branch 24 → 25 taken 35 times.
35 const QString value = QString::fromUtf8(tokens.at(i).text);
162
5/6
✓ Branch 25 → 26 taken 32 times.
✓ Branch 25 → 29 taken 3 times.
✓ Branch 27 → 28 taken 32 times.
✗ Branch 27 → 29 not taken.
✓ Branch 30 → 31 taken 32 times.
✓ Branch 30 → 35 taken 3 times.
35 if (first && tokens.at(i).kind == Token::Kind::Atom)
163
1/1
✓ Branch 31 → 32 taken 32 times.
32 response.code = value.toUpper();
164 else
165
1/1
✓ Branch 35 → 36 taken 3 times.
3 response.codeArgs.append(value);
166 35 first = false;
167 35 ++i;
168 35 }
169 32 ++i; // ")"
170 }
171
1/2
✓ Branch 56 → 47 taken 4632 times.
✗ Branch 56 → 57 not taken.
4632 for (; i < tokens.size(); ++i) {
172
1/2
✓ Branch 48 → 49 taken 4632 times.
✗ Branch 48 → 54 not taken.
4632 if (tokens.at(i).kind == Token::Kind::String) {
173
1/1
✓ Branch 50 → 51 taken 4632 times.
4632 response.text = QString::fromUtf8(tokens.at(i).text);
174 4632 break;
175 }
176 }
177 4632 return response;
178 4632 }
179
180 217 QStringList Capabilities::comparators() const {
181 217 QStringList result;
182
2/2
✓ Branch 14 → 4 taken 1934 times.
✓ Branch 14 → 15 taken 217 times.
2151 for (const QString &extension : sieveExtensions)
183
3/3
✓ Branch 6 → 7 taken 1934 times.
✓ Branch 7 → 8 taken 214 times.
✓ Branch 7 → 12 taken 1720 times.
1934 if (extension.startsWith(QLatin1String("comparator-")))
184
2/2
✓ Branch 8 → 9 taken 214 times.
✓ Branch 9 → 10 taken 214 times.
214 result.append(extension.mid(11));
185 217 return result;
186 ✗ }
187
188 216 QVariantMap Capabilities::toVariantMap() const {
189 return {
190 432 {QStringLiteral("implementation"), implementation},
191 432 {QStringLiteral("extensions"), sieveExtensions},
192 432 {QStringLiteral("sasl"), saslMechanisms},
193 432 {QStringLiteral("version"), version},
194 432 {QStringLiteral("maxRedirects"), maxRedirects},
195
1/1
✓ Branch 25 → 26 taken 216 times.
432 {QStringLiteral("comparators"), comparators()},
196 432 {QStringLiteral("checkScript"), hasCheckScript()},
197
2/4
✓ Branch 34 → 35 taken 1512 times.
✓ Branch 34 → 36 taken 216 times.
✗ Branch 54 → 55 not taken.
✗ Branch 54 → 56 not taken.
1944 };
198 1728 }
199
200 3446 void applyCapabilityLine(const QList<Token> &tokens, Capabilities *capabilities) {
201
3/6
✓ Branch 3 → 4 taken 3446 times.
✗ Branch 3 → 6 not taken.
✗ Branch 5 → 6 not taken.
✓ Branch 5 → 7 taken 3446 times.
✗ Branch 8 → 9 not taken.
✓ Branch 8 → 10 taken 3446 times.
3446 if (tokens.isEmpty() || tokens.first().kind != Token::Kind::String)
202 ✗ return;
203
2/2
✓ Branch 11 → 12 taken 3446 times.
✓ Branch 12 → 13 taken 3446 times.
3446 const QString name = QString::fromUtf8(tokens.first().text).toUpper();
204
3/3
✓ Branch 15 → 16 taken 3102 times.
✓ Branch 15 → 18 taken 344 times.
✓ Branch 17 → 19 taken 3102 times.
3446 const QString value = tokens.size() > 1 ? QString::fromUtf8(tokens.at(1).text) : QString();
205
1/1
✓ Branch 22 → 23 taken 3446 times.
3446 const QStringList words = value.split(QLatin1Char(' '), Qt::SkipEmptyParts);
206
2/2
✓ Branch 25 → 26 taken 687 times.
✓ Branch 25 → 27 taken 2759 times.
3446 if (name == QLatin1String("IMPLEMENTATION"))
207 687 capabilities->implementation = value;
208
2/2
✓ Branch 29 → 30 taken 687 times.
✓ Branch 29 → 31 taken 2072 times.
2759 else if (name == QLatin1String("SIEVE"))
209 687 capabilities->sieveExtensions = words;
210
2/2
✓ Branch 33 → 34 taken 687 times.
✓ Branch 33 → 45 taken 1385 times.
2072 else if (name == QLatin1String("SASL")) {
211
1/1
✓ Branch 34 → 35 taken 687 times.
687 capabilities->saslMechanisms.clear();
212
2/2
✓ Branch 43 → 37 taken 966 times.
✓ Branch 43 → 44 taken 687 times.
1653 for (const QString &word : words)
213
2/2
✓ Branch 38 → 39 taken 966 times.
✓ Branch 39 → 40 taken 966 times.
966 capabilities->saslMechanisms.append(word.toUpper());
214
2/2
✓ Branch 47 → 48 taken 344 times.
✓ Branch 47 → 49 taken 1041 times.
1385 } else if (name == QLatin1String("STARTTLS"))
215 344 capabilities->startTls = true;
216
2/2
✓ Branch 51 → 52 taken 678 times.
✓ Branch 51 → 53 taken 363 times.
1041 else if (name == QLatin1String("VERSION"))
217 678 capabilities->version = value;
218
2/2
✓ Branch 55 → 56 taken 44 times.
✓ Branch 55 → 58 taken 319 times.
363 else if (name == QLatin1String("MAXREDIRECTS"))
219
1/1
✓ Branch 56 → 57 taken 44 times.
44 capabilities->maxRedirects = value.toInt();
220
1/2
✓ Branch 60 → 61 taken 319 times.
✗ Branch 60 → 62 not taken.
319 else if (name == QLatin1String("NOTIFY"))
221 319 capabilities->notifyMethods = words;
222 ✗ else if (name == QLatin1String("LANGUAGE"))
223 ✗ capabilities->language = value;
224 ✗ else if (name == QLatin1String("OWNER"))
225 ✗ capabilities->owner = value;
226 ✗ else if (name == QLatin1String("UNAUTHENTICATE"))
227 ✗ capabilities->unauthenticate = true;
228 3446 }
229
230 10310 bool parseScriptEntry(const QList<Token> &tokens, ScriptEntry *entry) {
231
3/6
✓ Branch 3 → 4 taken 10310 times.
✗ Branch 3 → 6 not taken.
✗ Branch 5 → 6 not taken.
✓ Branch 5 → 7 taken 10310 times.
✗ Branch 8 → 9 not taken.
✓ Branch 8 → 10 taken 10310 times.
10310 if (tokens.isEmpty() || tokens.first().kind != Token::Kind::String)
232 ✗ return false;
233
1/1
✓ Branch 11 → 12 taken 10310 times.
10310 entry->name = QString::fromUtf8(tokens.first().text);
234
4/6
✓ Branch 15 → 16 taken 247 times.
✓ Branch 15 → 23 taken 10063 times.
✓ Branch 17 → 18 taken 247 times.
✗ Branch 17 → 23 not taken.
✓ Branch 21 → 22 taken 247 times.
✗ Branch 21 → 23 not taken.
10557 entry->active = tokens.size() > 1 && tokens.at(1).kind == Token::Kind::Atom &&
235
3/5
✓ Branch 19 → 20 taken 247 times.
✓ Branch 24 → 25 taken 247 times.
✓ Branch 24 → 26 taken 10063 times.
✗ Branch 29 → 30 not taken.
✗ Branch 29 → 31 not taken.
10557 tokens.at(1).text.toUpper() == "ACTIVE";
236 10310 return true;
237 }
238
239 10 QList<ServerError> parseServerErrors(const QString &text) {
240 static const QRegularExpression pattern(
241 12 QStringLiteral("line\\s+(\\d+)(?:\\s*[,:]?\\s*col(?:umn)?\\s*(\\d+))?\\s*:?\\s*(.*)"),
242
4/7
✓ Branch 2 → 3 taken 6 times.
✓ Branch 2 → 15 taken 4 times.
✓ Branch 4 → 5 taken 6 times.
✗ Branch 4 → 15 not taken.
✓ Branch 9 → 10 taken 6 times.
✗ Branch 74 → 75 not taken.
✗ Branch 74 → 76 not taken.
22 QRegularExpression::CaseInsensitiveOption);
243 10 QList<ServerError> errors;
244
1/1
✓ Branch 20 → 21 taken 10 times.
30 const QStringList lines = text.split(QRegularExpression(QStringLiteral("[\\r\\n]+")),
245
1/1
✓ Branch 21 → 22 taken 10 times.
10 Qt::SkipEmptyParts);
246
2/2
✓ Branch 63 → 27 taken 12 times.
✓ Branch 63 → 64 taken 10 times.
22 for (const QString &line : lines) {
247
1/1
✓ Branch 29 → 30 taken 12 times.
12 const QRegularExpressionMatch match = pattern.match(line);
248
3/3
✓ Branch 30 → 31 taken 12 times.
✓ Branch 31 → 32 taken 3 times.
✓ Branch 31 → 33 taken 9 times.
12 if (!match.hasMatch())
249 3 continue;
250 9 ServerError error;
251
2/2
✓ Branch 33 → 34 taken 9 times.
✓ Branch 34 → 35 taken 9 times.
9 error.line = match.captured(1).toInt();
252
2/2
✓ Branch 36 → 37 taken 9 times.
✓ Branch 37 → 38 taken 9 times.
9 error.column = match.captured(2).toInt();
253
2/2
✓ Branch 39 → 40 taken 9 times.
✓ Branch 40 → 41 taken 9 times.
9 error.message = match.captured(3).trimmed();
254
3/3
✓ Branch 45 → 46 taken 9 times.
✓ Branch 46 → 47 taken 8 times.
✓ Branch 46 → 53 taken 1 time.
9 if (error.message.startsWith(QLatin1String("error:"), Qt::CaseInsensitive))
255
2/2
✓ Branch 47 → 48 taken 8 times.
✓ Branch 48 → 49 taken 8 times.
8 error.message = error.message.mid(6).trimmed();
256
1/1
✓ Branch 53 → 54 taken 9 times.
9 errors.append(error);
257 12 }
258 10 return errors;
259 10 }
260
261 508 QByteArray literal(const QByteArray &value) {
262
4/4
✓ Branch 3 → 4 taken 508 times.
✓ Branch 4 → 5 taken 508 times.
✓ Branch 5 → 6 taken 508 times.
✓ Branch 6 → 7 taken 508 times.
508 return "{" + QByteArray::number(value.size()) + "+}\r\n" + value;
263 }
264
265 891 QByteArray quotedOrLiteral(const QByteArray &value) {
266 891 bool needsLiteral = value.size() > 1024;
267
2/2
✓ Branch 10 → 5 taken 6794 times.
✓ Branch 10 → 11 taken 891 times.
7685 for (const char c : value)
268
4/6
✓ Branch 5 → 6 taken 6794 times.
✗ Branch 5 → 8 not taken.
✓ Branch 6 → 7 taken 6793 times.
✓ Branch 6 → 8 taken 1 time.
✗ Branch 7 → 8 not taken.
✓ Branch 7 → 9 taken 6793 times.
6794 if (c == '\r' || c == '\n' || c == '\0')
269 1 needsLiteral = true;
270
2/2
✓ Branch 11 → 12 taken 1 time.
✓ Branch 11 → 14 taken 890 times.
891 if (needsLiteral)
271
1/1
✓ Branch 12 → 13 taken 1 time.
1 return literal(value);
272
1/1
✓ Branch 14 → 15 taken 890 times.
890 QByteArray out = "\"";
273
2/2
✓ Branch 22 → 17 taken 6791 times.
✓ Branch 22 → 23 taken 890 times.
7681 for (const char c : value) {
274
3/4
✓ Branch 17 → 18 taken 6789 times.
✓ Branch 17 → 19 taken 2 times.
✗ Branch 18 → 19 not taken.
✓ Branch 18 → 20 taken 6789 times.
6791 if (c == '"' || c == '\\')
275
1/1
✓ Branch 19 → 20 taken 2 times.
2 out.append('\\');
276
1/1
✓ Branch 20 → 21 taken 6791 times.
6791 out.append(c);
277 }
278
1/1
✓ Branch 23 → 24 taken 890 times.
890 out.append('"');
279 890 return out;
280 890 }
281
282 253 QByteArray authenticatePlain(const QByteArray &username, const QByteArray &password) {
283 253 QByteArray payload;
284
1/1
✓ Branch 4 → 5 taken 253 times.
253 payload.reserve(username.size() + password.size() + 2);
285
1/1
✓ Branch 5 → 6 taken 253 times.
253 payload.append('\0');
286
1/1
✓ Branch 6 → 7 taken 253 times.
253 payload.append(username);
287
1/1
✓ Branch 7 → 8 taken 253 times.
253 payload.append('\0');
288
1/1
✓ Branch 8 → 9 taken 253 times.
253 payload.append(password);
289
3/3
✓ Branch 10 → 11 taken 253 times.
✓ Branch 11 → 12 taken 253 times.
✓ Branch 12 → 13 taken 253 times.
253 QByteArray line = "AUTHENTICATE \"PLAIN\" \"" + payload.toBase64() + "\"\r\n";
290
1/1
✓ Branch 15 → 16 taken 253 times.
253 payload.fill('\0');
291 253 return line;
292 253 }
293
294 2009 QByteArray command(const QByteArray &name, const QList<QByteArray> &arguments) {
295 2009 QByteArray out = name;
296
2/2
✓ Branch 11 → 5 taken 1568 times.
✓ Branch 11 → 12 taken 2009 times.
3577 for (const QByteArray &argument : arguments)
297
2/2
✓ Branch 6 → 7 taken 1568 times.
✓ Branch 7 → 8 taken 1568 times.
1568 out += " " + argument;
298
1/1
✓ Branch 12 → 13 taken 2009 times.
4018 return out + "\r\n";
299 2009 }
300
301 } // namespace ManageSieve
302