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
|
/* If we are reparsing a macro expansion, file is 0 and this
|
||||||
* member points to the string in progress
|
* member points to the string in progress
|
||||||
*/
|
*/
|
||||||
const char* str;
|
char* str;
|
||||||
|
char* orig_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;
|
|
||||||
|
|
||||||
int stringify_flag;
|
int stringify_flag;
|
||||||
|
|
||||||
|
|
@ -1372,6 +1367,7 @@ static void do_expand(int use_args)
|
||||||
head = exp_buf_size - exp_buf_free;
|
head = exp_buf_size - exp_buf_free;
|
||||||
expand_using_args();
|
expand_using_args();
|
||||||
tail = exp_buf_size - exp_buf_free;
|
tail = exp_buf_size - exp_buf_free;
|
||||||
|
exp_buf_free += tail - head;
|
||||||
|
|
||||||
if (tail == head)
|
if (tail == head)
|
||||||
return;
|
return;
|
||||||
|
|
@ -1384,12 +1380,10 @@ static void do_expand(int use_args)
|
||||||
if (use_args)
|
if (use_args)
|
||||||
{
|
{
|
||||||
isp->str = &exp_buf[head];
|
isp->str = &exp_buf[head];
|
||||||
isp->ebs = tail - head;
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
isp->str = cur_macro->value;
|
isp->str = cur_macro->value;
|
||||||
isp->ebs = 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Escape some characters if we are making a string version. */
|
/* 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;
|
str_buf[idx] = 0;
|
||||||
idx += 1;
|
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;
|
isp->next = istack;
|
||||||
istack->yybs = YY_CURRENT_BUFFER;
|
istack->yybs = YY_CURRENT_BUFFER;
|
||||||
istack = isp;
|
istack = isp;
|
||||||
|
|
@ -1617,7 +1609,7 @@ static int load_next_input()
|
||||||
else
|
else
|
||||||
line_mask_flag = 1;
|
line_mask_flag = 1;
|
||||||
|
|
||||||
exp_buf_free += isp->ebs;
|
free(isp->orig_str);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (isp->stringify_flag) {
|
if (isp->stringify_flag) {
|
||||||
|
|
@ -1794,7 +1786,6 @@ void reset_lexor(FILE* out, char* paths[])
|
||||||
isp->path = strdup(paths[0]);
|
isp->path = strdup(paths[0]);
|
||||||
isp->file = fopen(paths[0], "r");
|
isp->file = fopen(paths[0], "r");
|
||||||
isp->str = 0;
|
isp->str = 0;
|
||||||
isp->ebs = 0;
|
|
||||||
isp->lineno = 0;
|
isp->lineno = 0;
|
||||||
isp->stringify_flag = 0;
|
isp->stringify_flag = 0;
|
||||||
isp->comment = NULL;
|
isp->comment = NULL;
|
||||||
|
|
@ -1824,7 +1815,6 @@ void reset_lexor(FILE* out, char* paths[])
|
||||||
isp->path = strdup(paths[idx]);
|
isp->path = strdup(paths[idx]);
|
||||||
isp->file = 0;
|
isp->file = 0;
|
||||||
isp->str = 0;
|
isp->str = 0;
|
||||||
isp->ebs = 0;
|
|
||||||
isp->next = 0;
|
isp->next = 0;
|
||||||
isp->lineno = 0;
|
isp->lineno = 0;
|
||||||
isp->stringify_flag = 0;
|
isp->stringify_flag = 0;
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue