diff options
Diffstat (limited to 'util/configlexer.lex')
-rw-r--r-- | util/configlexer.lex | 64 |
1 files changed, 48 insertions, 16 deletions
diff --git a/util/configlexer.lex b/util/configlexer.lex index 4694cdd821e7..d3b081342011 100644 --- a/util/configlexer.lex +++ b/util/configlexer.lex @@ -39,43 +39,67 @@ void ub_c_error(const char *message); struct inc_state { char* filename; int line; + YY_BUFFER_STATE buffer; + struct inc_state* next; }; -static struct inc_state parse_stack[MAXINCLUDES]; -static YY_BUFFER_STATE include_stack[MAXINCLUDES]; -static int config_include_stack_ptr = 0; +static struct inc_state* config_include_stack = NULL; +static int inc_depth = 0; static int inc_prev = 0; static int num_args = 0; +void init_cfg_parse(void) +{ + config_include_stack = NULL; + inc_depth = 0; + inc_prev = 0; + num_args = 0; +} static void config_start_include(const char* filename) { FILE *input; + struct inc_state* s; + char* nm; + if(inc_depth++ > 100000) { + ub_c_error_msg("too many include files"); + return; + } if(strlen(filename) == 0) { ub_c_error_msg("empty include file name"); return; } - if(config_include_stack_ptr >= MAXINCLUDES) { - ub_c_error_msg("includes nested too deeply, skipped (>%d)", MAXINCLUDES); + s = (struct inc_state*)malloc(sizeof(*s)); + if(!s) { + ub_c_error_msg("include %s: malloc failure", filename); return; } if(cfg_parser->chroot && strncmp(filename, cfg_parser->chroot, strlen(cfg_parser->chroot)) == 0) { filename += strlen(cfg_parser->chroot); } + nm = strdup(filename); + if(!nm) { + ub_c_error_msg("include %s: strdup failure", filename); + free(s); + return; + } input = fopen(filename, "r"); if(!input) { ub_c_error_msg("cannot open include file '%s': %s", filename, strerror(errno)); + free(s); + free(nm); return; } - LEXOUT(("switch_to_include_file(%s) ", filename)); - parse_stack[config_include_stack_ptr].filename = cfg_parser->filename; - parse_stack[config_include_stack_ptr].line = cfg_parser->line; - include_stack[config_include_stack_ptr] = YY_CURRENT_BUFFER; - cfg_parser->filename = strdup(filename); + LEXOUT(("switch_to_include_file(%s)\n", filename)); + s->filename = cfg_parser->filename; + s->line = cfg_parser->line; + s->buffer = YY_CURRENT_BUFFER; + s->next = config_include_stack; + config_include_stack = s; + cfg_parser->filename = nm; cfg_parser->line = 1; yy_switch_to_buffer(yy_create_buffer(input, YY_BUF_SIZE)); - ++config_include_stack_ptr; } static void config_start_include_glob(const char* filename) @@ -107,6 +131,8 @@ static void config_start_include_glob(const char* filename) if(r) { /* some error */ globfree(&g); + if(r == GLOB_NOMATCH) + return; /* no matches for pattern */ config_start_include(filename); /* let original deal with it */ return; } @@ -124,12 +150,16 @@ static void config_start_include_glob(const char* filename) static void config_end_include(void) { - --config_include_stack_ptr; + struct inc_state* s = config_include_stack; + --inc_depth; + if(!s) return; free(cfg_parser->filename); - cfg_parser->filename = parse_stack[config_include_stack_ptr].filename; - cfg_parser->line = parse_stack[config_include_stack_ptr].line; + cfg_parser->filename = s->filename; + cfg_parser->line = s->line; yy_delete_buffer(YY_CURRENT_BUFFER); - yy_switch_to_buffer(include_stack[config_include_stack_ptr]); + yy_switch_to_buffer(s->buffer); + config_include_stack = s->next; + free(s); } #ifndef yy_set_bol /* compat definition, for flex 2.4.6 */ @@ -291,6 +321,7 @@ python{COLON} { YDVAR(0, VAR_PYTHON) } domain-insecure{COLON} { YDVAR(1, VAR_DOMAIN_INSECURE) } minimal-responses{COLON} { YDVAR(1, VAR_MINIMAL_RESPONSES) } rrset-roundrobin{COLON} { YDVAR(1, VAR_RRSET_ROUNDROBIN) } +max-udp-size{COLON} { YDVAR(1, VAR_MAX_UDP_SIZE) } <INITIAL,val>{NEWLINE} { LEXOUT(("NL\n")); cfg_parser->line++; } /* Quoted strings. Strip leading and ending quotes */ @@ -364,8 +395,9 @@ rrset-roundrobin{COLON} { YDVAR(1, VAR_RRSET_ROUNDROBIN) } BEGIN(inc_prev); } <INITIAL,val><<EOF>> { + LEXOUT(("LEXEOF ")); yy_set_bol(1); /* Set beginning of line, so "^" rules match. */ - if (config_include_stack_ptr == 0) { + if (!config_include_stack) { yyterminate(); } else { fclose(yyin); |