Avoid stepping on free'd memory during recursive macro expansion
During macro expansion (with arguments), there is one global buffer (exp_buf) that keeps getting reallocated to fit all the macro's text that's currently being expanded. The problem with this scheme is that if a macro with arguments needs to be expanded from the macro text of another macro with arguments, it may happen that the second expansion forces the above exp_buf buffer to be reallocated. Which is fine until the previous macro processing resumes where (struct include_stack_t *)->str now points to uninitialised memory. Basically, the code that can trigger such behaviour is as follows: `define FOO(a) (a+3) `define BAR(b) (`FOO(b)+2) `BAR(x) Ofcourse, you need to get lucky to get the exp_buf to be realloced at the right point, but it's possible. I don't see the advantage in keeping all the expanding macro's text together, so my solution is to simply allocate a new buffer and pass it as (struct include_stack_t *)->str to the flex parsing function and free it at the end.
This commit is contained in:
parent
80c21adb4a
commit
c842cdbdc4
|
|
@ -64,13 +64,8 @@ struct include_stack_t
|
|||
/* If we are reparsing a macro expansion, file is 0 and this
|
||||
* member points to the string in progress
|
||||
*/
|
||||
const char* str;
|
||||
|
||||
/* If we are reparsing a macro expansion, this member indicates
|
||||
* the amount of space it occupies in the macro expansion buffer.
|
||||
* This will be zero for macros without arguments.
|
||||
*/
|
||||
int ebs;
|
||||
char* str;
|
||||
char* orig_str;
|
||||
|
||||
int stringify_flag;
|
||||
|
||||
|
|
@ -1372,6 +1367,7 @@ static void do_expand(int use_args)
|
|||
head = exp_buf_size - exp_buf_free;
|
||||
expand_using_args();
|
||||
tail = exp_buf_size - exp_buf_free;
|
||||
exp_buf_free += tail - head;
|
||||
|
||||
if (tail == head)
|
||||
return;
|
||||
|
|
@ -1384,12 +1380,10 @@ static void do_expand(int use_args)
|
|||
if (use_args)
|
||||
{
|
||||
isp->str = &exp_buf[head];
|
||||
isp->ebs = tail - head;
|
||||
}
|
||||
else
|
||||
{
|
||||
isp->str = cur_macro->value;
|
||||
isp->ebs = 0;
|
||||
}
|
||||
|
||||
/* Escape some characters if we are making a string version. */
|
||||
|
|
@ -1419,16 +1413,14 @@ static void do_expand(int use_args)
|
|||
}
|
||||
str_buf[idx] = 0;
|
||||
idx += 1;
|
||||
if (use_args) exp_buf_free += isp->ebs;
|
||||
exp_buf_grow_to_fit(idx);
|
||||
head = exp_buf_size - exp_buf_free;
|
||||
exp_buf_free -= idx;
|
||||
strcpy(&exp_buf[head], str_buf);
|
||||
isp->str = &exp_buf[head];
|
||||
isp->ebs = idx;
|
||||
free(str_buf);
|
||||
}
|
||||
|
||||
exp_buf_free -= idx;
|
||||
|
||||
isp->str = str_buf;
|
||||
} else
|
||||
isp->str = strdup(isp->str);
|
||||
|
||||
isp->orig_str = isp->str;
|
||||
isp->next = istack;
|
||||
istack->yybs = YY_CURRENT_BUFFER;
|
||||
istack = isp;
|
||||
|
|
@ -1617,7 +1609,7 @@ static int load_next_input()
|
|||
else
|
||||
line_mask_flag = 1;
|
||||
|
||||
exp_buf_free += isp->ebs;
|
||||
free(isp->orig_str);
|
||||
}
|
||||
|
||||
if (isp->stringify_flag) {
|
||||
|
|
@ -1794,7 +1786,6 @@ void reset_lexor(FILE* out, char* paths[])
|
|||
isp->path = strdup(paths[0]);
|
||||
isp->file = fopen(paths[0], "r");
|
||||
isp->str = 0;
|
||||
isp->ebs = 0;
|
||||
isp->lineno = 0;
|
||||
isp->stringify_flag = 0;
|
||||
isp->comment = NULL;
|
||||
|
|
@ -1824,7 +1815,6 @@ void reset_lexor(FILE* out, char* paths[])
|
|||
isp->path = strdup(paths[idx]);
|
||||
isp->file = 0;
|
||||
isp->str = 0;
|
||||
isp->ebs = 0;
|
||||
isp->next = 0;
|
||||
isp->lineno = 0;
|
||||
isp->stringify_flag = 0;
|
||||
|
|
|
|||
Loading…
Reference in New Issue