Coverage Report

Created: 2026-05-27 07:07

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/kmime/src/util_p.h
Line
Count
Source
1
/*
2
    SPDX-FileCopyrightText: 2007 Volker Krause <vkrause@kde.org>
3
4
    SPDX-License-Identifier: LGPL-2.0-or-later
5
*/
6
7
#pragma once
8
9
#include <qglobal.h>
10
11
class QByteArray;
12
class QByteArrayView;
13
class QString;
14
15
#include <cstdlib>
16
17
// @cond PRIVATE
18
19
/* Internal helper functions. Not part of the public API. */
20
21
namespace KMime
22
{
23
24
/**
25
 *  Consult the charset cache. Only used for reducing mem usage by
26
 *  keeping strings in a common repository.
27
 *  @param name
28
 */
29
[[nodiscard]] QByteArray cachedCharset(const QByteArray &name);
30
[[nodiscard]] QByteArray cachedCharset(QByteArrayView name);
31
32
/**
33
  Finds the header end in @p src. Aligns the @p dataBegin if needed.
34
  @param dataBegin beginning of the data part of the header
35
  @param folded true if the headder is folded into multiple lines
36
  @returns the end index of the header, -1 if the @p dataBegin was -1.
37
*/
38
qsizetype findHeaderLineEnd(QByteArrayView src, qsizetype &dataBegin, bool *folded = nullptr);
39
40
/**
41
  Tries to extract the header with name @p name from the string
42
  @p src, unfolding it if necessary.
43
44
  @param src  the source string.
45
  @param name the name of the header to search for.
46
47
  @return the first instance of the header @p name in @p src
48
          or a null QByteArray if no such header was found.
49
*/
50
QByteArray extractHeader(const QByteArray &src, const QByteArray &name);
51
52
/**
53
  Finds the first header of type @p name in @p src.
54
  @param end The end index of the header.
55
  @param dataBegin begin of the data part of the header, -1 if not found.
56
  @param folded true if the headder is folded into multiple lines
57
  @returns the begin index of the header, -1 if not found.
58
*/
59
qsizetype indexOfHeader(const QByteArray &src, const QByteArray &name, qsizetype &end, qsizetype &dataBegin, bool *folded = nullptr);
60
61
/**
62
 *  Uses current time, pid and random numbers to construct a string
63
 *  that aims to be unique on a per-host basis (ie. for the local
64
 *  part of a message-id or for multipart boundaries.
65
 *
66
 *  @return the unique string.
67
 *  @see multiPartBoundary
68
 */
69
extern QByteArray uniqueString();
70
71
/**
72
  Unfolds the given header if necessary.
73
  @param header The header to unfold.
74
*/
75
QByteArray unfoldHeader(const QByteArray &header);
76
QByteArray unfoldHeader(const char *header, size_t headerSize);
77
78
/**
79
  Folds the given header if necessary.
80
  @param header The header to fold.
81
*/
82
QByteArray foldHeader(const QByteArray &header);
83
84
/**
85
  Removes quote (DQUOTE) characters and decodes "quoted-pairs"
86
  (ie. backslash-escaped characters)
87
88
  @param str the string to work on.
89
  @see addQuotes
90
*/
91
void removeQuotes(QByteArray &str);
92
93
/**
94
  Removes quote (DQUOTE) characters and decodes "quoted-pairs"
95
  (ie. backslash-escaped characters)
96
97
  @param str the string to work on.
98
  @see addQuotes
99
*/
100
void removeQuotes(QString &str);
101
102
/**
103
  Converts the given string into a quoted-string if the string contains
104
  any special characters (ie. one of ()<>@,.;:[]=\").
105
106
  @param str us-ascii string to work on.
107
  @param forceQuotes if @c true, always add quote characters.
108
*/
109
void addQuotes(QByteArray &str, bool forceQuotes);
110
111
/**
112
 * Overloaded method, behaves same as the above.
113
 * @param str us-ascii string to work on.
114
 * @param forceQuotes if @c true, always add quote characters.
115
 * @since 4.5
116
 */
117
void addQuotes(QString &str, bool forceQuotes);
118
119
/**
120
 * Makes sure that the bidirectional state at the end of the string is the
121
 * same as at the beginning of the string.
122
 *
123
 * This is useful so that Unicode control characters that can change the text
124
 * direction can not spill over to following strings.
125
 *
126
 * As an example, consider a mailbox in the form "display name" <local@domain.com>.
127
 * If the display name here contains unbalanced control characters that change the
128
 * text direction, it would also have an effect on the addrspec, which could lead to
129
 * spoofing.
130
 *
131
 * By passing the display name to this function, one can make sure that no change of
132
 * the bidi state can spill over to the next strings, in this case the addrspec.
133
 *
134
 * Example: The string "Hello <RLO>World" is unbalanced, as it contains a right-to-left
135
 *          override character, which is never followed by a <PDF>, the "pop directional
136
 *          formatting" character. This function adds the missing <PDF> at the end, and
137
 *          the output of this function would be "Hello <RLO>World<PDF>".
138
 *
139
 * Example of spoofing:
140
 *   Consider "Firstname Lastname<RLO>" <moc.mitciv@attacker.com>. Because of the RLO,
141
 *   it is displayed as "Firstname Lastname <moc.rekcatta@victim.com>", which spoofs the
142
 *   domain name.
143
 *   By passing "Firstname Lastname<RLO>" to this function, one can balance the <RLO>,
144
 *   leading to "Firstname Lastname<RLO><PDF>", so the whole mailbox is displayed
145
 *   correctly as "Firstname Lastname" <moc.mitciv@attacker.com> again.
146
 *
147
 * See https://unicode.org/reports/tr9 for more information on bidi control chars.
148
 *
149
 * @param input the display name of a mailbox, which is checked for unbalanced Unicode
150
 *              direction control characters
151
 * @return the display name which now contains a balanced state of direction control
152
 *         characters
153
 *
154
 * Note that this function does not do any parsing related to mailboxes, it only works
155
 * on plain strings. Therefore, passing the complete mailbox will not lead to any results,
156
 * only the display name should be passed.
157
 *
158
 * @since 4.5
159
 */
160
QString balanceBidiState(const QString &input);
161
162
/**
163
 * Similar to the above function. Instead of trying to balance the Bidi chars, it outright
164
 * removes them from the string.
165
 *
166
 * @param input the display name of a mailbox, which is checked for unbalanced Unicode
167
 * direction control characters
168
 * Reason: KHTML seems to ignore the PDF character, so adding them doesn't fix things :(
169
 */
170
QString removeBidiControlChars(const QString &input);
171
172
//@cond PRIVATE
173
extern const unsigned char aTextMap[16];
174
extern const unsigned char tTextMap[16];
175
176
inline bool isOfSet(const unsigned char map[16], unsigned char ch)
177
82.0M
{
178
82.0M
    return (ch < 128) && (map[ ch / 8 ] & 0x80 >> ch % 8);
179
82.0M
}
180
inline bool isAText(char ch)
181
51.2M
{
182
51.2M
    return isOfSet(aTextMap, ch);
183
51.2M
}
184
inline bool isTText(char ch)
185
30.7M
{
186
30.7M
    return isOfSet(tTextMap, ch);
187
30.7M
}
188
//@endcond
189
190
}
191
192
// @endcond
193