]>
Commit | Line | Data |
---|---|---|
b67e2c8c | 1 | /* |
bf95c10a | 2 | * Copyright (C) 1996-2022 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 | ||
d295d770 | 9 | #ifndef SQUID_CONFIGPARSER_H |
10 | #define SQUID_CONFIGPARSER_H | |
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 | |
582c2af2 | 22 | class wordlist; |
7e6eabbc | 23 | |
abd9dd91 AJ |
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 | */ | |
f53969cc | 32 | #define CONFIG_LINE_LIMIT 2048 |
abd9dd91 AJ |
33 | |
34 | /** | |
a9f20260 | 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. | |
9227a6e1 | 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. | |
a9f20260 | 43 | */ |
62e76326 | 44 | class ConfigParser |
45 | { | |
46 | ||
b67e2c8c | 47 | public: |
2eceb328 CT |
48 | /** |
49 | * Parsed tokens type: simple tokens, quoted tokens or function | |
50 | * like parameters. | |
51 | */ | |
bde7a8ce | 52 | enum TokenType {SimpleToken, QuotedToken, FunctionParameters}; |
2eceb328 | 53 | |
a9f20260 | 54 | void destruct(); |
2e6535ab AR |
55 | |
56 | /// stops parsing the current configuration directive | |
57 | void closeDirective(); | |
58 | ||
59 | /// rejects configuration due to a repeated directive | |
60 | void rejectDuplicateDirective(); | |
61 | ||
e227da8d AR |
62 | /// extracts and returns a required token |
63 | SBuf token(const char *expectedTokenDescription); | |
64 | ||
39d7714a AR |
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 | ||
e227da8d AR |
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 | ||
0fa036e3 AR |
76 | /// extracts and returns a regex (including any optional flags) |
77 | std::unique_ptr<RegexPattern> regex(const char *expectedRegexDescription); | |
78 | ||
f45dd259 | 79 | static void ParseUShort(unsigned short *var); |
3a69ddf3 | 80 | static void ParseBool(bool *var); |
b92a47f2 | 81 | static const char *QuoteString(const String &var); |
3a69ddf3 | 82 | static void ParseWordList(wordlist **list); |
2eceb328 CT |
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 | */ | |
d295d770 | 89 | static char * strtokFile(); |
2eceb328 CT |
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 | ||
bde7a8ce CT |
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 | /** | |
bde7a8ce CT |
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 | ||
2eceb328 CT |
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 | ||
32fd6d8a CT |
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 | ||
2eceb328 | 128 | /** |
bde7a8ce CT |
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. | |
2eceb328 | 133 | */ |
bde7a8ce | 134 | static char *PeekAtToken(); |
2eceb328 | 135 | |
2eceb328 CT |
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 | ||
7e6eabbc CT |
145 | static SBuf CurrentLocation(); |
146 | ||
2eceb328 | 147 | /// configuration_includes_quoted_values in squid.conf |
bde7a8ce CT |
148 | static bool RecognizeQuotedValues; |
149 | ||
150 | /** | |
151 | * Strict syntax mode. Does not allow not alphanumeric characters in unquoted tokens. | |
2f8abb64 | 152 | * Controlled by the configuration_includes_quoted_values in squid.conf but remains |
bde7a8ce CT |
153 | * false when the the legacy ConfigParser::NextQuotedToken() call forces |
154 | * RecognizeQuotedValues to be temporary true. | |
155 | */ | |
156 | static bool StrictMode; | |
2eceb328 CT |
157 | |
158 | protected: | |
159 | /** | |
160 | * Class used to store required information for the current | |
161 | * configuration file. | |
162 | */ | |
163 | class CfgFile | |
164 | { | |
165 | public: | |
aee3523a | 166 | CfgFile(): wordFile(nullptr), parsePos(nullptr), lineNo(0) { parseBuffer[0] = '\0';} |
2eceb328 CT |
167 | ~CfgFile(); |
168 | /// True if the configuration file is open | |
aee3523a | 169 | bool isOpen() {return wordFile != nullptr;} |
2eceb328 CT |
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 | |
bde7a8ce | 194 | const char *parsePos; ///< The next element position in parseBuffer string |
2eceb328 CT |
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 | ||
2eceb328 CT |
201 | /** |
202 | * Unquotes the token, which must be quoted. | |
bde7a8ce | 203 | * \param next if it is not NULL, it is set after the end of token. |
2eceb328 | 204 | */ |
aee3523a | 205 | static char *UnQuote(const char *token, const char **next = nullptr); |
2eceb328 CT |
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 | |
2eceb328 | 213 | */ |
bde7a8ce | 214 | static char *TokenParse(const char * &nextToken, TokenType &type); |
2eceb328 CT |
215 | |
216 | /// Wrapper method for TokenParse. | |
bde7a8ce | 217 | static char *NextElement(TokenType &type); |
2eceb328 CT |
218 | static std::stack<CfgFile *> CfgFiles; ///< The stack of open cfg files |
219 | static TokenType LastTokenType; ///< The type of last parsed element | |
bde7a8ce CT |
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 | |
2eceb328 | 223 | static bool AllowMacros_; |
bde7a8ce | 224 | static bool ParseQuotedOrToEol_; ///< The next tokens will be handled as quoted or to_eol token |
61a31961 | 225 | static bool RecognizeQuotedPair_; ///< The next tokens may contain quoted-pair (\-escaped) characters |
2f8abb64 | 226 | static bool PreviewMode_; ///< The next token will not popped from cfg files, will just previewd. |
f53969cc | 227 | static bool ParseKvPair_; ///<The next token will be handled as kv-pair token |
32fd6d8a | 228 | static enum ParsingStates {atParseKey, atParseValue} KvPairState_; ///< Parsing state while parsing kv-pair tokens |
b67e2c8c | 229 | }; |
230 | ||
8a648e8d | 231 | int parseConfigFile(const char *file_name); |
62ee09ca | 232 | |
d295d770 | 233 | #endif /* SQUID_CONFIGPARSER_H */ |
f53969cc | 234 |