Fixes file descriptor leak when parser ends with error.
Thanks to MrBr for the bugreport.
This commit is contained in:
parent
4e7c974d22
commit
0c3d9dacaf
3 changed files with 31 additions and 5 deletions
|
@ -275,9 +275,6 @@ cf_hash(byte *c)
|
|||
* match - these do not have fd and flex buffer yet).
|
||||
*
|
||||
* FIXME: Most of these ifs and include functions are really sysdep/unix.
|
||||
*
|
||||
* FIXME: Resources (fd, flex buffers and glob data) in IFS stack
|
||||
* are not freed when cf_error() is called.
|
||||
*/
|
||||
|
||||
static struct include_file_stack *
|
||||
|
@ -316,13 +313,36 @@ enter_ifs(struct include_file_stack *new)
|
|||
yy_switch_to_buffer(new->buffer);
|
||||
}
|
||||
|
||||
/**
|
||||
* cf_lex_unwind - unwind lexer state during error
|
||||
*
|
||||
* cf_lex_unwind() frees the internal state on IFS stack when the lexical
|
||||
* analyzer is terminated by cf_error().
|
||||
*/
|
||||
void
|
||||
cf_lex_unwind(void)
|
||||
{
|
||||
struct include_file_stack *n;
|
||||
|
||||
for (n = ifs; n != ifs_head; n = n->prev)
|
||||
{
|
||||
/* Memory is freed automatically */
|
||||
if (n->buffer)
|
||||
yy_delete_buffer(n->buffer);
|
||||
if (n->fd)
|
||||
close(n->fd);
|
||||
}
|
||||
|
||||
ifs = ifs_head;
|
||||
}
|
||||
|
||||
static void
|
||||
cf_include(char *arg, int alen)
|
||||
{
|
||||
struct include_file_stack *base_ifs = ifs;
|
||||
int new_depth, rv, i;
|
||||
char *patt;
|
||||
glob_t g;
|
||||
glob_t g = {};
|
||||
|
||||
new_depth = ifs->depth + 1;
|
||||
if (new_depth > MAX_INCLUDE_DEPTH)
|
||||
|
@ -370,7 +390,10 @@ cf_include(char *arg, int alen)
|
|||
struct stat fs;
|
||||
|
||||
if (stat(fname, &fs) < 0)
|
||||
cf_error("Unable to stat included file %s: %m", fname);
|
||||
{
|
||||
globfree(&g);
|
||||
cf_error("Unable to stat included file %s: %m", fname);
|
||||
}
|
||||
|
||||
if (fs.st_mode & S_IFDIR)
|
||||
continue;
|
||||
|
|
|
@ -502,6 +502,7 @@ cf_error(char *msg, ...)
|
|||
new_config->err_msg = cfg_strdup(buf);
|
||||
new_config->err_lino = ifs->lino;
|
||||
new_config->err_file_name = ifs->file_name;
|
||||
cf_lex_unwind();
|
||||
longjmp(conf_jmpbuf, 1);
|
||||
}
|
||||
|
||||
|
|
|
@ -139,6 +139,8 @@ extern struct include_file_stack *ifs;
|
|||
|
||||
int cf_lex(void);
|
||||
void cf_lex_init(int is_cli, struct config *c);
|
||||
void cf_lex_unwind(void);
|
||||
|
||||
struct symbol *cf_find_symbol(byte *c);
|
||||
struct symbol *cf_default_name(char *template, int *counter);
|
||||
struct symbol *cf_define_symbol(struct symbol *symbol, int type, void *def);
|
||||
|
|
Loading…
Reference in a new issue