]>
Commit | Line | Data |
---|---|---|
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 | 22 | class CachePeer; |
582c2af2 | 23 | class 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 | 45 | class ConfigParser |
46 | { | |
47 | ||
b67e2c8c | 48 | public: |
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 | |
162 | protected: | |
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 | 235 | int parseConfigFile(const char *file_name); |
62ee09ca | 236 | |
ff9d9458 | 237 | #endif /* SQUID_SRC_CONFIGPARSER_H */ |
f53969cc | 238 |