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