File indexing completed on 2024-03-24 16:53:06

0001 /*  -*- c++ -*-
0002     kmime_header_parsing.h
0003 
0004     KMime, the KDE Internet mail/usenet news message library.
0005     SPDX-FileCopyrightText: 2001-2002 Marc Mutz <mutz@kde.org>
0006 
0007     SPDX-License-Identifier: LGPL-2.0-or-later
0008 */
0009 
0010 #pragma once
0011 
0012 #include "kmime_export.h"
0013 #include "kmime_types.h"
0014 
0015 #include <QString>
0016 #include <QPair>
0017 
0018 #include <QDateTime>
0019 
0020 template <typename K, typename V> class QMap;
0021 #include <QStringList>
0022 
0023 namespace KMime
0024 {
0025 
0026 namespace Headers
0027 {
0028 class Base;
0029 }
0030 
0031 namespace Types
0032 {
0033 
0034 } // namespace KMime::Types
0035 
0036 namespace HeaderParsing
0037 {
0038 
0039 /**
0040   Parses the encoded word.
0041 
0042   @param scursor pointer to the first character beyond the initial '=' of
0043   the input string.
0044   @param send pointer to end of input buffer.
0045   @param result the decoded string the encoded work represented.
0046   @param language The language parameter according to RFC 2231, section 5.
0047   @param usedCS    the used charset is returned here
0048   @param defaultCS the charset to use in case the detected
0049                    one isn't known to us.
0050 
0051   @return true if the input string was successfully decode; false otherwise.
0052 */
0053 [[nodiscard]] KMIME_EXPORT bool
0054 parseEncodedWord(const char *&scursor, const char *const send, QString &result,
0055                  QByteArray &language, QByteArray &usedCS,
0056                  const QByteArray &defaultCS = QByteArray());
0057 
0058 //
0059 // The parsing squad:
0060 //
0061 
0062 /** You may or may not have already started parsing into the
0063     atom. This function will go on where you left off.
0064  */
0065 [[nodiscard]] KMIME_EXPORT bool parseAtom(const char *&scursor,
0066                                           const char *const send,
0067                                           QByteArray &result,
0068                                           bool allow8Bit = false);
0069 
0070 /**
0071  * More efficient overload, to avoid a copy of the substring
0072  */
0073 [[nodiscard]] KMIME_EXPORT bool parseAtom(const char *&scursor,
0074                                           const char *const send,
0075                                           QPair<const char *, int> &result,
0076                                           bool allow8Bit = false);
0077 
0078 enum ParseTokenFlag {
0079     ParseTokenNoFlag = 0,
0080     ParseTokenAllow8Bit = 1,
0081     ParseTokenRelaxedTText = 2
0082 };
0083 Q_DECLARE_FLAGS(ParseTokenFlags, ParseTokenFlag)
0084 
0085 /** You may or may not have already started parsing into the
0086     token. This function will go on where you left off. */
0087 [[nodiscard]] KMIME_EXPORT bool
0088 parseToken(const char *&scursor, const char *const send, QByteArray &result,
0089            ParseTokenFlags flags = ParseTokenNoFlag);
0090 
0091 [[nodiscard]] KMIME_EXPORT bool
0092 parseToken(const char *&scursor, const char *const send,
0093            QPair<const char *, int> &result,
0094            ParseTokenFlags flags = ParseTokenNoFlag);
0095 
0096 /** @p scursor must be positioned after the opening openChar. */
0097 [[nodiscard]] KMIME_EXPORT bool
0098 parseGenericQuotedString(const char *&scursor, const char *const send,
0099                          QString &result, bool isCRLF,
0100                          const char openChar = '"', const char closeChar = '"');
0101 
0102 /** @p scursor must be positioned right after the opening '(' */
0103 [[nodiscard]] KMIME_EXPORT bool
0104 parseComment(const char *&scursor, const char *const send, QString &result,
0105              bool isCRLF = false, bool reallySave = true);
0106 
0107 /**
0108   Parses a phrase.
0109 
0110   You may or may not have already started parsing into the phrase, but
0111   only if it starts with atext. If you setup this function to parse a
0112   phrase starting with an encoded-word or quoted-string, @p scursor has
0113   to point to the char introducing the encoded-word or quoted-string, resp.
0114 
0115   @param scursor pointer to the first character beyond the initial '=' of
0116   the input string.
0117   @param send pointer to end of input buffer.
0118   @param result the parsed string.
0119 
0120   @return true if the input phrase was successfully parsed; false otherwise.
0121 */
0122 [[nodiscard]] KMIME_EXPORT bool parsePhrase(const char *&scursor,
0123                                             const char *const send,
0124                                             QString &result,
0125                                             bool isCRLF = false);
0126 
0127 /**
0128   Parses into the initial atom.
0129   You may or may not have already started parsing into the initial
0130   atom, but not up to it's end.
0131 
0132   @param scursor pointer to the first character beyond the initial '=' of
0133   the input string.
0134   @param send pointer to end of input buffer.
0135   @param result the parsed string.
0136 
0137   @return true if the input phrase was successfully parsed; false otherwise.
0138 */
0139 [[nodiscard]] KMIME_EXPORT bool parseDotAtom(const char *&scursor,
0140                                              const char *const send,
0141                                              QByteArray &result,
0142                                              bool isCRLF = false);
0143 
0144 /**
0145   Eats comment-folding-white-space, skips whitespace, folding and comments
0146   (even nested ones) and stops at the next non-CFWS character.  After
0147   calling this function, you should check whether @p scursor == @p send
0148   (end of header reached).
0149 
0150   If a comment with unbalanced parentheses is encountered, @p scursor
0151   is being positioned on the opening '(' of the outmost comment.
0152 
0153   @param scursor pointer to the first character beyond the initial '=' of
0154   the input string.
0155   @param send pointer to end of input buffer.
0156   @param isCRLF true if input string is terminated with a CRLF.
0157 */
0158 KMIME_EXPORT void eatCFWS(const char *&scursor, const char *const send,
0159                           bool isCRLF);
0160 
0161 [[nodiscard]] KMIME_EXPORT bool parseDomain(const char *&scursor,
0162                                             const char *const send,
0163                                             QString &result,
0164                                             bool isCRLF = false);
0165 
0166 [[nodiscard]] KMIME_EXPORT bool
0167 parseObsRoute(const char *&scursor, const char *const send, QStringList &result,
0168               bool isCRLF = false, bool save = false);
0169 
0170 [[nodiscard]] KMIME_EXPORT bool parseAddrSpec(const char *&scursor,
0171                                               const char *const send,
0172                                               Types::AddrSpec &result,
0173                                               bool isCRLF = false);
0174 
0175 [[nodiscard]] KMIME_EXPORT bool parseAngleAddr(const char *&scursor,
0176                                                const char *const send,
0177                                                Types::AddrSpec &result,
0178                                                bool isCRLF = false);
0179 
0180 /**
0181   Parses a single mailbox.
0182 
0183   RFC 2822, section 3.4 defines a mailbox as follows:
0184   <pre>mailbox := addr-spec / ([ display-name ] angle-addr)</pre>
0185 
0186   KMime also accepts the legacy format of specifying display names:
0187   <pre>mailbox := (addr-spec [ "(" display-name ")" ])
0188   / ([ display-name ] angle-addr)
0189   / (angle-addr "(" display-name ")")</pre>
0190 
0191   @param scursor pointer to the first character of the input string
0192   @param send pointer to end of input buffer
0193   @param result the parsing result
0194   @param isCRLF true if input string is terminated with a CRLF.
0195 */
0196 KMIME_EXPORT bool parseMailbox(const char *&scursor, const char *const send,
0197                                Types::Mailbox &result, bool isCRLF = false);
0198 
0199 [[nodiscard]] KMIME_EXPORT bool parseGroup(const char *&scursor,
0200                                            const char *const send,
0201                                            Types::Address &result,
0202                                            bool isCRLF = false);
0203 
0204 [[nodiscard]] KMIME_EXPORT bool parseAddress(const char *&scursor,
0205                                              const char *const send,
0206                                              Types::Address &result,
0207                                              bool isCRLF = false);
0208 
0209 [[nodiscard]] KMIME_EXPORT bool parseAddressList(const char *&scursor,
0210                                                  const char *const send,
0211                                                  Types::AddressList &result,
0212                                                  bool isCRLF = false);
0213 
0214 [[nodiscard]] KMIME_EXPORT bool
0215 parseParameterList(const char *&scursor, const char *const send,
0216                    QMap<QString, QString> &result, bool isCRLF = false);
0217 
0218 /**
0219  * Extract the charset embedded in the parameter list if there is one.
0220  *
0221  * @since 4.5
0222  */
0223 [[nodiscard]] KMIME_EXPORT bool
0224 parseParameterListWithCharset(const char *&scursor, const char *const send,
0225                               QMap<QString, QString> &result,
0226                               QByteArray &charset, bool isCRLF = false);
0227 
0228 /**
0229   Parses an integer number.
0230   @param scursor pointer to the first character of the input string
0231   @param send pointer to end of input buffer
0232   @param result the parsing result
0233   @returns The number of parsed digits (don't confuse with @p result!)
0234 */
0235 [[nodiscard]] KMIME_EXPORT int parseDigits(const char *&scursor,
0236                                            const char *const send, int &result);
0237 
0238 [[nodiscard]] KMIME_EXPORT bool
0239 parseTime(const char *&scursor, const char *const send, int &hour, int &min,
0240           int &sec, long int &secsEastOfGMT, bool &timeZoneKnown,
0241           bool isCRLF = false);
0242 
0243 [[nodiscard]] KMIME_EXPORT bool parseDateTime(const char *&scursor,
0244                                               const char *const send,
0245                                               QDateTime &result,
0246                                               bool isCRLF = false);
0247 [[nodiscard]] KMIME_EXPORT bool parseQDateTime(const char *&scursor,
0248                                                const char *const send,
0249                                                QDateTime &result,
0250                                                bool isCRLF = false);
0251 
0252 /** Parses the first header contained the given data.
0253  *  If a header is found @p head will be shortened to no longer
0254  *  include the corresponding data, ie. this method can be called
0255  *  iteratively on the same data until it returns @c null.
0256  *  @since 6.0
0257  */
0258 [[nodiscard]] KMIME_EXPORT std::unique_ptr<KMime::Headers::Base> parseNextHeader(QByteArrayView &head);
0259 
0260 /**
0261  * Extract the header header and the body from a complete content.
0262  * Internally, it will simply look for the first newline and use that as a
0263  * separator between the header and the body.
0264  *
0265  * @param content the complete mail
0266  * @param header return value for the extracted header
0267  * @param body return value for the extracted body
0268  * @since 4.6
0269  */
0270 KMIME_EXPORT void extractHeaderAndBody(const QByteArray &content,
0271                                        QByteArray &header, QByteArray &body);
0272 
0273 } // namespace HeaderParsing
0274 
0275 } // namespace KMime
0276 
0277 Q_DECLARE_OPERATORS_FOR_FLAGS(KMime::HeaderParsing::ParseTokenFlags)
0278 
0279