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