gcc -E -traditional broken
Neil Booth
neil@daikokuya.demon.co.uk
Mon Dec 11 15:15:00 GMT 2000
Zack Weinberg wrote:-
> As long as you're sure that that's sufficient. The code path I saw it
> going through was like this:
>
> rescan sees 'defined'
> rescan calls macroexpand
> macroexpand calls special_symbol
> special_symbol advances past '[(] macroname [)]'
> and inserts " 0 " or " 1 " into the output
Here is where it went wrong - it does a SKIP_WHITE_SPACE regardless of
whether it's looking for the ')' or not. That's where the buffer
overflow occurred:-
while (is_idchar (*ip->bufp))
++ip->bufp;
SKIP_WHITE_SPACE (ip->bufp);
if (paren) {
if (*ip->bufp != ')')
goto oops;
++ip->bufp;
}
> macroexpand returns without stacking a new buffer
> rescan assumes that if macroexpand didn't stack a new buffer,
> it didn't move ibp either, so it need not recheck
> against limit
> rescan walks past the end of the buffer.
>
> However, rescan is a steaming pile of spaghetti
You can say that again, but extend to the whole code :-) If I'm
*really* bored one day I might try and clean up tradcpp.c, but that
would be a sad day indeed. A good reason I'm not keen on reworking it
is a complete lack of testcases, and the fact that I don't know the
traditional rules.
> I just discovered that tradcpp silently ignores #error, which means
> that tr-defined.c can give false passes. On the #assert argument, it
> probably makes sense to add #error to tradcpp; this should be
> relatively easy.
Ugh. Yes, I'll add that to my todo list before committing your
testcases.
Neil.
More information about the Gcc-bugs
mailing list