-
Notifications
You must be signed in to change notification settings - Fork 364
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Fix global buffer overflow in IDLC #1900
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -965,18 +965,21 @@ static void put_a_line( | |
*/ | ||
{ | ||
size_t len; | ||
char * out_p; | ||
char * tp; | ||
|
||
if (no_output) | ||
return; | ||
len = strlen( out); | ||
tp = out_p = out + len - 2; /* Just before '\n' */ | ||
while (char_type[ *out_p & UCHARMAX] & SPA) | ||
out_p--; /* Remove trailing white spaces */ | ||
if (out_p < tp) { | ||
*++out_p = '\n'; | ||
*++out_p = EOS; | ||
if (len > 2) | ||
{ | ||
char * out_p; | ||
char * tp; | ||
tp = out_p = out + len - 2; /* Just before '\n' */ | ||
while (out_p > out && char_type[ *out_p & UCHARMAX] & SPA) | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. ... this can be changed to There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Not unless you can prove that the object that out points into has at least one byte preceding it: C99 6.5.6 Additive operators ¶8:
So in the case of There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Good point! I missed the undefined behavior wrt pointer subtraction. This could be rewritten by using an integer counter for number of chars to be stripped, but I agree that it's not worth the effort here. |
||
out_p--; /* Remove trailing white spaces */ | ||
if (out_p < tp && !(char_type[ *out_p & UCHARMAX] & SPA)) { | ||
*++out_p = '\n'; | ||
*++out_p = EOS; | ||
} | ||
} | ||
if (mcpp_fputs( out, MCPP_OUT) == EOF) | ||
cfatal( "File write error", NULL, 0L, NULL); /* _F_ */ | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
A line with just a whitespace char and a line-break is not trimmed (or is that intentional?). I think this could be
>= 2
and ..There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It is intentional, but it is good to double-check. From my reading of the code, the intent is that there is always at least a character, followed by a newline, followed by a terminating 0. This then makes the
-2
valid. The loop implies that the character is assumed to be a "non-whitespace" one.Firstly, this means that under the original assumptions, whether or not you actually do anything in the case of
len == 2
is irrelevant.The bug report only proves that the "non-whitespace" assumption is false. It doesn't prove that the character+
\n
+\0
assumption is false. So my decision to add a test forlen > 2
(or, equivalently under the original assumption,len >= 2
) is simply because it wasn't immediately obvious thatlen < 2
is truly impossible.So, the only surprising bit is that in the case of an input of the form: whitespace character+
\n
+\0
, it outputs the whitespace character. Considering that this is merely the preprocessor and the IDL lexer doesn't mind the white space, I figured this edge case didn't really matter.