File indexing completed on 2024-04-21 16:06:19
0001 /* 0002 SPDX-FileCopyrightText: 2007 Volker Krause <vkrause@kde.org> 0003 0004 SPDX-License-Identifier: LGPL-2.0-or-later 0005 */ 0006 0007 #pragma once 0008 0009 class QByteArray; 0010 class QByteArrayView; 0011 class QString; 0012 0013 #include <cstdlib> 0014 0015 // @cond PRIVATE 0016 0017 /* Internal helper functions. Not part of the public API. */ 0018 0019 namespace KMime 0020 { 0021 0022 /** 0023 * Consult the charset cache. Only used for reducing mem usage by 0024 * keeping strings in a common repository. 0025 * @param name 0026 */ 0027 extern QByteArray cachedCharset(const QByteArray &name); 0028 0029 /** 0030 Finds the header end in @p src. Aligns the @p dataBegin if needed. 0031 @param dataBegin beginning of the data part of the header 0032 @param folded true if the headder is folded into multiple lines 0033 @returns the end index of the header, -1 if the @p dataBegin was -1. 0034 */ 0035 extern int findHeaderLineEnd(QByteArrayView src, int &dataBegin, bool *folded = nullptr); 0036 0037 /** 0038 Tries to extract the header with name @p name from the string 0039 @p src, unfolding it if necessary. 0040 0041 @param src the source string. 0042 @param name the name of the header to search for. 0043 0044 @return the first instance of the header @p name in @p src 0045 or a null QByteArray if no such header was found. 0046 */ 0047 QByteArray extractHeader(const QByteArray &src, const QByteArray &name); 0048 0049 /** 0050 Finds the first header of type @p name in @p src. 0051 @param end The end index of the header. 0052 @param dataBegin begin of the data part of the header, -1 if not found. 0053 @param folded true if the headder is folded into multiple lines 0054 @returns the begin index of the header, -1 if not found. 0055 */ 0056 extern int indexOfHeader(const QByteArray &src, const QByteArray &name, int &end, int &dataBegin, bool *folded = nullptr); 0057 0058 /** 0059 * Uses current time, pid and random numbers to construct a string 0060 * that aims to be unique on a per-host basis (ie. for the local 0061 * part of a message-id or for multipart boundaries. 0062 * 0063 * @return the unique string. 0064 * @see multiPartBoundary 0065 */ 0066 extern QByteArray uniqueString(); 0067 0068 /** 0069 Unfolds the given header if necessary. 0070 @param header The header to unfold. 0071 */ 0072 QByteArray unfoldHeader(const QByteArray &header); 0073 QByteArray unfoldHeader(const char *header, size_t headerSize); 0074 0075 /** 0076 Folds the given header if necessary. 0077 @param header The header to fold. 0078 */ 0079 QByteArray foldHeader(const QByteArray &header); 0080 0081 /** 0082 Removes quote (DQUOTE) characters and decodes "quoted-pairs" 0083 (ie. backslash-escaped characters) 0084 0085 @param str the string to work on. 0086 @see addQuotes 0087 */ 0088 void removeQuotes(QByteArray &str); 0089 0090 /** 0091 Removes quote (DQUOTE) characters and decodes "quoted-pairs" 0092 (ie. backslash-escaped characters) 0093 0094 @param str the string to work on. 0095 @see addQuotes 0096 */ 0097 void removeQuotes(QString &str); 0098 0099 /** 0100 Converts the given string into a quoted-string if the string contains 0101 any special characters (ie. one of ()<>@,.;:[]=\"). 0102 0103 @param str us-ascii string to work on. 0104 @param forceQuotes if @c true, always add quote characters. 0105 */ 0106 void addQuotes(QByteArray &str, bool forceQuotes); 0107 0108 /** 0109 * Overloaded method, behaves same as the above. 0110 * @param str us-ascii string to work on. 0111 * @param forceQuotes if @c true, always add quote characters. 0112 * @since 4.5 0113 */ 0114 void addQuotes(QString &str, bool forceQuotes); 0115 0116 /** 0117 * Makes sure that the bidirectional state at the end of the string is the 0118 * same as at the beginning of the string. 0119 * 0120 * This is useful so that Unicode control characters that can change the text 0121 * direction can not spill over to following strings. 0122 * 0123 * As an example, consider a mailbox in the form "display name" <local@domain.com>. 0124 * If the display name here contains unbalanced control characters that change the 0125 * text direction, it would also have an effect on the addrspec, which could lead to 0126 * spoofing. 0127 * 0128 * By passing the display name to this function, one can make sure that no change of 0129 * the bidi state can spill over to the next strings, in this case the addrspec. 0130 * 0131 * Example: The string "Hello <RLO>World" is unbalanced, as it contains a right-to-left 0132 * override character, which is never followed by a <PDF>, the "pop directional 0133 * formatting" character. This function adds the missing <PDF> at the end, and 0134 * the output of this function would be "Hello <RLO>World<PDF>". 0135 * 0136 * Example of spoofing: 0137 * Consider "Firstname Lastname<RLO>" <moc.mitciv@attacker.com>. Because of the RLO, 0138 * it is displayed as "Firstname Lastname <moc.rekcatta@victim.com>", which spoofs the 0139 * domain name. 0140 * By passing "Firstname Lastname<RLO>" to this function, one can balance the <RLO>, 0141 * leading to "Firstname Lastname<RLO><PDF>", so the whole mailbox is displayed 0142 * correctly as "Firstname Lastname" <moc.mitciv@attacker.com> again. 0143 * 0144 * See https://unicode.org/reports/tr9 for more information on bidi control chars. 0145 * 0146 * @param input the display name of a mailbox, which is checked for unbalanced Unicode 0147 * direction control characters 0148 * @return the display name which now contains a balanced state of direction control 0149 * characters 0150 * 0151 * Note that this function does not do any parsing related to mailboxes, it only works 0152 * on plain strings. Therefore, passing the complete mailbox will not lead to any results, 0153 * only the display name should be passed. 0154 * 0155 * @since 4.5 0156 */ 0157 QString balanceBidiState(const QString &input); 0158 0159 /** 0160 * Similar to the above function. Instead of trying to balance the Bidi chars, it outright 0161 * removes them from the string. 0162 * 0163 * @param input the display name of a mailbox, which is checked for unbalanced Unicode 0164 * direction control characters 0165 * Reason: KHTML seems to ignore the PDF character, so adding them doesn't fix things :( 0166 */ 0167 QString removeBidiControlChars(const QString &input); 0168 0169 //@cond PRIVATE 0170 extern const unsigned char aTextMap[16]; 0171 extern const unsigned char tTextMap[16]; 0172 0173 inline bool isOfSet(const unsigned char map[16], unsigned char ch) 0174 { 0175 return (ch < 128) && (map[ ch / 8 ] & 0x80 >> ch % 8); 0176 } 0177 inline bool isAText(char ch) 0178 { 0179 return isOfSet(aTextMap, ch); 0180 } 0181 inline bool isTText(char ch) 0182 { 0183 return isOfSet(tTextMap, ch); 0184 } 0185 //@endcond 0186 0187 } 0188 0189 // @endcond 0190