Mail Archives: djgpp-workers/2002/12/11/12:14:15
Hello.
Eli Zaretskii wrote:
>
> Richard Dawe wrote:
[snip]
> > "The conversion specifiers A, E, F, G, and X are also valid and behave the
> > same as, respectively, a, e, f, g, and x."
> >
> > So we can't treat X as some Borland special-case, if we want to comply
> > with the C standard.
>
> Oh, yes we can: if the result is the same, the users won't notice.
>
> Do you see any difference between what v2.03 does with X and what C99
> says it should?
Yes:
2.03: Ignores the 'h' conversion width specifier and treats it like 'l', but
honours 'll'. This causes a buffer overflow (memory corruption) problem when
the width is less than 32b short). Note that the problem would also occur if
2.03 supported the 'hh' conversion width specifier for chars.
C99: X should behave like x. Should honour conversion width specifiers.
The 2.03-behaviour is caused by this code to handle captial type specifiers
(D, etc.) from src/libc/ansi/stdio/doscan.c:102-115:
/* The following if clause is an extension of ANSI/Posix spec: it
allows to use %D, %U, %I etc. to store value in a long (rather
than an int) and %lD, %lU etc. to store value in a long long.
This extension is supported by some compilers (e.g. Borland C).
Old pre-ANSI compilers, such as Turbo C 2.0, also interpreted
%E, %F and %G to store in a double (rather than a float), but
this contradicts the ANSI Standard, so we don't support it. */
if (ch == 'd' || ch == 'i' || ch == 'o' || ch == 'u' || ch == 'x')
{
if (size==LONG && ch != 'x') /* ANSI: %lX is long, not long long */
size = LONGDOUBLE;
else if (size != LONGDOUBLE)
size = LONG;
}
2.03 & %hX: size == SHORT => size == LONG after this code -> memory
corruption. (Something similar would happen for %hhX, if 2.03 supported it.)
Bye, Rich =]
--
Richard Dawe [ http://www.phekda.freeserve.co.uk/richdawe/ ]
- Raw text -