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