]> git.ipfire.org Git - thirdparty/squid.git/blame - src/ConfigParser.h
Maintenance: automate header guards 2/3 (#1655)
[thirdparty/squid.git] / src / ConfigParser.h
CommitLineData
b67e2c8c 1/*
b8ae064d 2 * Copyright (C) 1996-2023 The Squid Software Foundation and contributors
b67e2c8c 3 *
bbc27441
AJ
4 * Squid software is distributed under GPLv2+ license and includes
5 * contributions from numerous individuals and organizations.
6 * Please see the COPYING and CONTRIBUTORS files for details.
b67e2c8c 7 */
8
ff9d9458
FC
9#ifndef SQUID_SRC_CONFIGPARSER_H
10#define SQUID_SRC_CONFIGPARSER_H
d295d770 11
e227da8d 12#include "acl/forward.h"
0fa036e3 13#include "base/forward.h"
7e6eabbc 14#include "sbuf/forward.h"
63ed43c5 15#include "SquidString.h"
074d6a40 16
0fa036e3 17#include <memory>
33810b1d 18#include <queue>
2eceb328 19#include <stack>
33810b1d 20#include <string>
62e76326 21
a555a85b 22class CachePeer;
582c2af2 23class wordlist;
7e6eabbc 24
abd9dd91
AJ
25/**
26 * Limit to how long any given config line may be.
27 * This affects squid.conf and all included files.
28 *
29 * Behaviour when setting larger than 2KB is unknown.
30 * The config parser read mechanism can cope, but the other systems
31 * receiving the data from its buffers on such lines may not.
32 */
f53969cc 33#define CONFIG_LINE_LIMIT 2048
abd9dd91
AJ
34
35/**
a9f20260 36 * A configuration file Parser. Instances of this class track
37 * parsing state and perform tokenisation. Syntax is currently
38 * taken care of outside this class.
9227a6e1 39 *
40 * One reason for this class is to allow testing of configuration
41 * using modules without linking cache_cf.o in - because that drags
42 * in all of squid by reference. Instead the tokeniser only is
43 * brought in.
a9f20260 44 */
62e76326 45class ConfigParser
46{
47
b67e2c8c 48public:
2eceb328
CT
49 /**
50 * Parsed tokens type: simple tokens, quoted tokens or function
51 * like parameters.
52 */
bde7a8ce 53 enum TokenType {SimpleToken, QuotedToken, FunctionParameters};
2eceb328 54
a9f20260 55 void destruct();
2e6535ab
AR
56
57 /// stops parsing the current configuration directive
58 void closeDirective();
59
60 /// rejects configuration due to a repeated directive
61 void rejectDuplicateDirective();
62
e227da8d
AR
63 /// extracts and returns a required token
64 SBuf token(const char *expectedTokenDescription);
65
39d7714a
AR
66 /// extracts an optional key=value token or returns false
67 /// rejects configurations with empty keys or empty values
68 /// key and value have lifetime of the current line/directive
69 bool optionalKvPair(char * &key, char * &value);
70
e227da8d
AR
71 /// either extracts the given (optional) token or returns false
72 bool skipOptional(const char *keyword);
73
74 /// parses an [if [!]<acl>...] construct
75 Acl::Tree *optionalAclList();
76
0fa036e3
AR
77 /// extracts and returns a regex (including any optional flags)
78 std::unique_ptr<RegexPattern> regex(const char *expectedRegexDescription);
79
a555a85b
AR
80 /// extracts a cache_peer name token and returns the corresponding CachePeer
81 CachePeer &cachePeer(const char *peerNameTokenDescription);
82
f45dd259 83 static void ParseUShort(unsigned short *var);
3a69ddf3 84 static void ParseBool(bool *var);
b92a47f2 85 static const char *QuoteString(const String &var);
3a69ddf3 86 static void ParseWordList(wordlist **list);
2eceb328
CT
87
88 /**
89 * Backward compatibility wrapper for the ConfigParser::NextToken method.
90 * If the configuration_includes_quoted_values configuration parameter is
91 * set to 'off' this interprets the quoted tokens as filenames.
92 */
d295d770 93 static char * strtokFile();
2eceb328
CT
94
95 /**
96 * Returns the body of the next element. The element is either a token or
97 * a quoted string with optional escape sequences and/or macros. The body
98 * of a quoted string element does not include quotes or escape sequences.
99 * Future code will want to see Elements and not just their bodies.
100 */
101 static char *NextToken();
102
bde7a8ce
CT
103 /**
104 * Backward compatibility wrapper for ConfigParser::RegexPattern method.
105 * If the configuration_includes_quoted_values configuration parameter is
106 * set to 'off' this interprets the quoted tokens as filenames.
107 */
108 static char *RegexStrtokFile();
109
110 /**
bde7a8ce
CT
111 * Parse the next token with support for quoted values enabled even if
112 * the configuration_includes_quoted_values is set to off
113 */
114 static char *NextQuotedToken();
115
2eceb328
CT
116 /// \return true if the last parsed token was quoted
117 static bool LastTokenWasQuoted() {return (LastTokenType == ConfigParser::QuotedToken);}
118
119 /**
120 * \return the next quoted string or the raw string data until the end of line.
121 * This method allows %macros in unquoted strings to keep compatibility
122 * for the logformat option.
123 */
124 static char *NextQuotedOrToEol();
125
32fd6d8a
CT
126 /**
127 * the next key value pair which must be separated by "="
128 * \return true on success, false otherwise
129 */
130 static bool NextKvPair(char * &key, char * &value);
131
2eceb328 132 /**
bde7a8ce
CT
133 * Preview the next token. The next NextToken() and strtokFile() call
134 * will return the same token.
135 * On parse error (eg invalid characters in token) will return an
136 * error message as token.
2eceb328 137 */
bde7a8ce 138 static char *PeekAtToken();
2eceb328 139
2eceb328
CT
140 /// Set the configuration file line to parse.
141 static void SetCfgLine(char *line);
142
143 /// Allow %macros inside quoted strings
144 static void EnableMacros() {AllowMacros_ = true;}
145
146 /// Do not allow %macros inside quoted strings
147 static void DisableMacros() {AllowMacros_ = false;}
148
7e6eabbc
CT
149 static SBuf CurrentLocation();
150
2eceb328 151 /// configuration_includes_quoted_values in squid.conf
bde7a8ce
CT
152 static bool RecognizeQuotedValues;
153
154 /**
155 * Strict syntax mode. Does not allow not alphanumeric characters in unquoted tokens.
2f8abb64 156 * Controlled by the configuration_includes_quoted_values in squid.conf but remains
bde7a8ce
CT
157 * false when the the legacy ConfigParser::NextQuotedToken() call forces
158 * RecognizeQuotedValues to be temporary true.
159 */
160 static bool StrictMode;
2eceb328
CT
161
162protected:
163 /**
164 * Class used to store required information for the current
165 * configuration file.
166 */
167 class CfgFile
168 {
169 public:
aee3523a 170 CfgFile(): wordFile(nullptr), parsePos(nullptr), lineNo(0) { parseBuffer[0] = '\0';}
2eceb328
CT
171 ~CfgFile();
172 /// True if the configuration file is open
aee3523a 173 bool isOpen() {return wordFile != nullptr;}
2eceb328
CT
174
175 /**
176 * Open the file given by 'path' and initializes the CfgFile object
177 * to start parsing
178 */
179 bool startParse(char *path);
180
181 /**
182 * Do the next parsing step:
183 * reads the next line from file if required.
184 * \return the body of next element or a NULL pointer if there are no more token elements in the file.
185 * \param type will be filled with the ConfigParse::TokenType for any element found, or left unchanged if NULL is returned.
186 */
187 char *parse(TokenType &type);
188
189 private:
190 bool getFileLine(); ///< Read the next line from the file
191 /**
192 * Return the body of the next element. If the wasQuoted is given
193 * set to true if the element was quoted.
194 */
195 char *nextElement(TokenType &type);
196 FILE *wordFile; ///< Pointer to the file.
197 char parseBuffer[CONFIG_LINE_LIMIT]; ///< Temporary buffer to store data to parse
bde7a8ce 198 const char *parsePos; ///< The next element position in parseBuffer string
2eceb328
CT
199 public:
200 std::string filePath; ///< The file path
201 std::string currentLine; ///< The current line to parse
202 int lineNo; ///< Current line number
203 };
204
2eceb328
CT
205 /**
206 * Unquotes the token, which must be quoted.
bde7a8ce 207 * \param next if it is not NULL, it is set after the end of token.
2eceb328 208 */
aee3523a 209 static char *UnQuote(const char *token, const char **next = nullptr);
2eceb328
CT
210
211 /**
212 * Does the real tokens parsing job: Ignore comments, unquote an
213 * element if required.
214 * \return the next token, or NULL if there are no available tokens in the nextToken string.
215 * \param nextToken updated to point to the pos after parsed token.
216 * \param type The token type
2eceb328 217 */
bde7a8ce 218 static char *TokenParse(const char * &nextToken, TokenType &type);
2eceb328
CT
219
220 /// Wrapper method for TokenParse.
bde7a8ce 221 static char *NextElement(TokenType &type);
2eceb328
CT
222 static std::stack<CfgFile *> CfgFiles; ///< The stack of open cfg files
223 static TokenType LastTokenType; ///< The type of last parsed element
bde7a8ce
CT
224 static const char *CfgLine; ///< The current line to parse
225 static const char *CfgPos; ///< Pointer to the next element in cfgLine string
226 static std::queue<char *> CfgLineTokens_; ///< Store the list of tokens for current configuration line
2eceb328 227 static bool AllowMacros_;
bde7a8ce 228 static bool ParseQuotedOrToEol_; ///< The next tokens will be handled as quoted or to_eol token
61a31961 229 static bool RecognizeQuotedPair_; ///< The next tokens may contain quoted-pair (\-escaped) characters
2f8abb64 230 static bool PreviewMode_; ///< The next token will not popped from cfg files, will just previewd.
f53969cc 231 static bool ParseKvPair_; ///<The next token will be handled as kv-pair token
32fd6d8a 232 static enum ParsingStates {atParseKey, atParseValue} KvPairState_; ///< Parsing state while parsing kv-pair tokens
b67e2c8c 233};
234
8a648e8d 235int parseConfigFile(const char *file_name);
62ee09ca 236
ff9d9458 237#endif /* SQUID_SRC_CONFIGPARSER_H */
f53969cc 238