Bug in vfprintf?
Jason Tishler
jason@tishler.net
Thu Jan 30 20:40:00 GMT 2003
Jeff,
On Tue, Jan 07, 2003 at 02:56:20PM -0500, J. Johnston wrote:
> Jason Tishler wrote:
> >On Mon, Jan 06, 2003 at 10:05:19PM -0500, Charles Wilson wrote:
> >>J. Johnston wrote:
> >>
> >>>Try the attached patch with your testsuite.
> >>
> >>That fixes it. Thanks.
> >
> >It also fixes the following too:
> >
> > http://cygwin.com/ml/cygwin/2003-01/msg00047.html
>
> Good. Patch has been checked in.
Changes to the Python regression test have uncovered another memory
overwrite problem in this area of newlib. The attached C program,
test_string5.c, is a minimal testcase that demonstrates the problem
(albeit, most likely only noticeable in a debugger).
Use the following invocation:
test_string5 '%.50f'
to trigger the problem.
The following is an excerpt from libc/stdio/vfprintf.c:
1022 static char *
1023 cvt(data, value, ndigits, flags, sign, decpt, ch, length)
...
1069 if ((ch != 'g' && ch != 'G') || flags & ALT) { /* Print ...
*>1070 bp = digits + ndigits;
1071 if (ch == 'f') {
1072 if (*digits == '0' && value)
1073 *decpt = -ndigits + 1;
*>1074 bp += *decpt;
1075 }
1076 if (value == 0) /* kludge for __dtoa irregularity */
1077 rve = bp;
1078 while (rve < bp)
1079 *rve++ = '0';
1080 }
I'm not sure of the root cause, but line 1074 pushes bp to past the end
of allocated memory which is 84 bytes in this testcase. The combination
of lines 1070 and 1074 cause the string to be padding to a field width
of 100 instead of the requested 50 which overwrites adjacent memory.
I can "fix" the problem by allocating more memory than necessary in
_ldtoa_r(), but that is probably not the best way to solve this problem.
I hope that this post will enable you to easily find the best solution.
If you are too busy to address this problem, let me know and I will try
to dig deeper and fix it myself.
Thanks,
Jason
--
PGP/GPG Key: http://www.tishler.net/jason/pubkey.asc or key servers
Fingerprint: 7A73 1405 7F2B E669 C19D 8784 1AFD E4CC ECF4 8EF6
-------------- next part --------------
#include <stdio.h>
int
main(int argc, char* argv[])
{
const char* format = argv[1];
double value = 10033002222963781815252827772780694713070670000000.0;
printf(format, value);
printf("\n");
return 0;
}
More information about the Newlib
mailing list