42 std::ostringstream message;
50 message <<
" included from " << f->
filePath <<
" line " <<
55 message <<
" included from " <<
cfg_filename <<
" line " <<
57 std::string msg = message.str();
60 fatalf(
"Bungled %s line %d: %s",
70 static int fromFile = 0;
71 static FILE *wordFile =
nullptr;
83 }
else if (*t ==
'\"' || *t ==
'\'') {
85 debugs(3, 8,
"Quoted token found : " << t);
88 while (*t && *t !=
'\"' && *t !=
'\'')
93 if ((wordFile = fopen(fn,
"r")) ==
nullptr) {
99 setmode(fileno(wordFile),
O_TEXT);
109 if (fgets(buf,
sizeof(buf), wordFile) ==
nullptr) {
125 while (*t3 && *t3 !=
'#') {
126 t2 = t3 + strcspn(t3,
w_space);
135 }
while ( *t ==
'#' || !*t );
143 const char *errorStr =
nullptr;
144 const char *errorPos =
nullptr;
145 char quoteChar = *
token;
146 assert(quoteChar ==
'"' || quoteChar ==
'\'');
148 const char *s =
token + 1;
151 while (*s && *s != quoteChar && !errorStr && (
size_t)(d - UnQuoted) <
sizeof(UnQuoted) - 1) {
154 errorStr =
"Unterminated escape sequence";
171 errorStr =
"Unsupported escape sequence";
183 if (*s != quoteChar && !errorStr) {
184 errorStr =
"missing quote char at the end of quoted string";
191 if (!errorStr && *(s + 1) !=
'\0' && !strchr(
w_space "()#", *(s + 1))) {
192 errorStr =
"Expecting space after the end of quoted token";
231 if (!nextToken || *nextToken ==
'\0')
234 nextToken += strspn(nextToken,
w_space);
236 if (*nextToken ==
'#')
246 const char *tokenStart = nextToken;
261 nextToken += strcspn(nextToken, sep);
265 if (*(nextToken+1) && *(nextToken+1) !=
'\r' && *(nextToken+1) !=
'\n') {
267 nextToken += strcspn(nextToken, sep);
269 debugs(3,
DBG_CRITICAL,
"FATAL: Unescaped '\' character in regex pattern: " << tokenStart);
275 if (strncmp(tokenStart,
"parameters", nextToken - tokenStart) == 0)
290 char *
token =
nullptr;
291 if (nextToken - tokenStart) {
293 bool tokenIsNumber =
true;
294 for (
const char *s = tokenStart; s != nextToken; ++s) {
295 const bool isValidChar = isalnum(*s) || strchr(
".,()-=_/:+", *s) ||
296 (tokenIsNumber && *s ==
'%' && (s + 1 == nextToken));
299 tokenIsNumber =
false;
307 debugs(3,
DBG_CRITICAL,
"FATAL: Not alphanumeric character '"<< *s <<
"' in unquoted token " << tokenStart);
317 if (*nextToken !=
'\0' && *nextToken !=
'#') {
342 char *
token =
nullptr;
381 debugs(3,
DBG_CRITICAL,
"FATAL: can't open %s for reading parameters: includes are nested too deeply (>16)!\n" << path);
437 if (
const auto middle = strchr(currentToken,
'=')) {
438 if (middle == currentToken)
440 if (middle + 1 == currentToken + strlen(currentToken))
457 key = value =
nullptr;
469 debugs(3,
DBG_CRITICAL,
"ERROR: Failure while parsing key=value token. Value missing after: " << key);
480 debugs(3,
DBG_CRITICAL,
"FATAL: Can not read regex expression while configuration_includes_quoted_values is enabled");
489std::unique_ptr<RegexPattern>
493 throw TextException(
"Cannot read regex expression while configuration_includes_quoted_values is enabled",
Here());
496 int flags = REG_EXTENDED | REG_NOSUB;
499 const auto flagOrPattern =
token(expectedRegexDescription);
500 if (flagOrPattern.cmp(
"-i") == 0) {
502 pattern =
token(expectedRegexDescription);
503 }
else if (flagOrPattern.cmp(
"+i") == 0) {
505 pattern =
token(expectedRegexDescription);
507 pattern = flagOrPattern;
511 return std::unique_ptr<RegexPattern>(
new RegexPattern(pattern, flags));
524 peerNameTokenDescription,
" as ", name),
Here());
545 bool needQuote =
false;
547 for (
const char *l = s; !needQuote && *l !=
'\0'; ++l )
548 needQuote = !isalnum(*l);
555 for (; *s !=
'\0'; ++s) {
556 if (*s ==
'"' || *s ==
'\\')
583 if (
const auto extractedToken =
NextToken()) {
585 return SBuf(extractedToken);
595 if (strcmp(nextToken, keyword) == 0) {
622 debugs(3, 3,
"Parsing from " << path);
623 if ((
wordFile = fopen(path,
"r")) ==
nullptr) {
644 parseBuffer[0] =
'\0';
647 parsePos = parseBuffer;
648 currentLine = parseBuffer;
663 while (!(
token = nextElement(type))) {
673 const char *pos = parsePos;
static const char * SQUID_ERROR_TOKEN
#define CONFIG_LINE_LIMIT
#define Here()
source code location of the caller
size_t aclParseAclList(ConfigParser &, ACLList **config, const char *label)
const char * cfg_directive
During parsing, the name of the current squid.conf directive being parsed.
char config_input_line[BUFSIZ]
const char * cfg_filename
char * nextElement(TokenType &type)
std::string currentLine
The current line to parse.
std::string filePath
The file path.
FILE * wordFile
Pointer to the file.
char * parse(TokenType &type)
bool getFileLine()
Read the next line from the file.
bool startParse(char *path)
bool isOpen()
True if the configuration file is open.
int lineNo
Current line number.
bool optionalKvPair(char *&key, char *&value)
static const char * CfgLine
The current line to parse.
static TokenType LastTokenType
The type of last parsed element.
static SBuf CurrentLocation()
static char * RegexStrtokFile()
static const char * CfgPos
Pointer to the next element in cfgLine string.
static bool RecognizeQuotedPair_
The next tokens may contain quoted-pair (-escaped) characters.
void rejectDuplicateDirective()
rejects configuration due to a repeated directive
static char * NextQuotedToken()
static enum ConfigParser::ParsingStates KvPairState_
Parsing state while parsing kv-pair tokens.
static char * NextQuotedOrToEol()
ACLList * optionalAclList()
parses an [if [!]<acl>...] construct
std::unique_ptr< RegexPattern > regex(const char *expectedRegexDescription)
extracts and returns a regex (including any optional flags)
static std::queue< char * > CfgLineTokens_
Store the list of tokens for current configuration line.
static bool ParseKvPair_
The next token will be handled as kv-pair token.
static char * NextElement(TokenType &type)
Wrapper method for TokenParse.
static bool RecognizeQuotedValues
configuration_includes_quoted_values in squid.conf
static char * PeekAtToken()
static std::stack< CfgFile * > CfgFiles
The stack of open cfg files.
static bool ParseQuotedOrToEol_
The next tokens will be handled as quoted or to_eol token.
bool skipOptional(const char *keyword)
either extracts the given (optional) token or returns false
void closeDirective()
stops parsing the current configuration directive
static char * UnQuote(const char *token, const char **next=nullptr)
static bool NextKvPair(char *&key, char *&value)
CachePeer & cachePeer(const char *peerNameTokenDescription)
extracts a cache_peer name token and returns the corresponding CachePeer
static void SetCfgLine(char *line)
Set the configuration file line to parse.
static char * NextToken()
static char * strtokFile()
SBuf token(const char *expectedTokenDescription)
extracts and returns a required token
static const char * QuoteString(const String &var)
static char * TokenParse(const char *&nextToken, TokenType &type)
a source code location that is cheap to create, copy, and store
char const * termedBuf() const
void append(char const *buf, int len)
an std::runtime_error with thrower location info
#define debugs(SECTION, LEVEL, CONTENT)
void fatalf(const char *fmt,...)
CachePeer * findCachePeerByName(const char *const name)
cache_peer with a given name (or nil)
SBuf ToSBuf(Args &&... args)
slowly stream-prints all arguments into a freshly allocated SBuf
#define LOCAL_ARRAY(type, name, size)
char * xstrncpy(char *dst, const char *src, size_t n)
char * xstrndup(const char *s, size_t n)