[RFA] __svfscanf_r: Fix zero exponent handling (was Re: [RFA] strtod: Fix sign bug if exponent is invalid (was Re: [cw@gamma-rs.ch: error in scanf reading %le format and 00 exponent]))
Corinna Vinschen
vinschen@redhat.com
Thu Mar 31 19:28:00 GMT 2005
On Mar 31 20:12, Corinna Vinschen wrote:
> On Mar 7 11:14, Christopher Faylor wrote:
> > ----- Forwarded message from "Charles L. Werner" -----
> > #include <stdio.h>
> > main()
> > {
> > double a;
> > while(1){
> > printf("input: ");
> > scanf("%le",&a);
> > printf("a: %le\n",a);
> > }
> > }
> >
> > input: -.11e+00
> > a: 1.100000e-01 !akkk
> >
> > input: -1.1e+00
> > a: 1.100000e+00 !akkk
> [...]
> In __svfscanf_r, the expression "-1.1e+00" is copied over to buf, the buffer
> used in a later call to strtod. The problem here is that all leading zeros
> in the exponent are skipped, not copied. The result here is that the
> expression given to _strtod_r has an invalid exponent:
>
> "-1.1e+"
> [...]
Attached is a patch to __svfscanf_r which solves the above part of the
problem. It copies the first zero in the exponent and notes this fact.
Then, if a non-zero digit follows, it sets p back to overwrite the leading
zero again. The latter overwriting could be savely dropped, since the
leading zero wouldn't hurt strtod. I added it to this patch anyway for
cleanness.
Corinna
* libc/stdio/vfscanf.c (FZINEXP): New flag value.
(__SVFSCANF_R): Copy over first zero in exponent to buf. Overwrite
if non-zero digit follows.
Index: libc/stdio/vfscanf.c
===================================================================
RCS file: /cvs/src/src/newlib/libc/stdio/vfscanf.c,v
retrieving revision 1.28
diff -u -p -r1.28 vfscanf.c
--- libc/stdio/vfscanf.c 8 Feb 2005 01:33:17 -0000 1.28
+++ libc/stdio/vfscanf.c 31 Mar 2005 19:25:36 -0000
@@ -194,6 +194,7 @@ extern _LONG_DOUBLE _strtold _PARAMS((ch
#define PFXOK 0x200 /* 0x prefix is (still) legal */
#define NZDIGITS 0x400 /* no zero digits detected */
#define NNZDIGITS 0x800 /* no non-zero digits detected */
+#define FZINEXP 0x1000 /* first leading zero in exponent detected */
/*
* Conversion types.
@@ -1020,6 +1021,13 @@ _DEFUN(__SVFSCANF_R, (rptr, fp, fmt0, ap
width_left--;
width++;
}
+ if (!(flags & (EXPOK | FZINEXP)))
+ {
+ /* Found first leading zero in exponent.
+ Don't skip it in output. */
+ flags |= FZINEXP;
+ goto fok;
+ }
goto fskip;
}
/* Fall through. */
@@ -1035,6 +1043,13 @@ _DEFUN(__SVFSCANF_R, (rptr, fp, fmt0, ap
if (nancount == 0)
{
flags &= ~(SIGNOK | NDIGITS);
+ /* Drop leading zero in exponent if a non-zero
+ digit follows. */
+ if (flags & FZINEXP)
+ {
+ --p;
+ flags &= ~FZINEXP;
+ }
goto fok;
}
break;
--
Corinna Vinschen
Cygwin Project Co-Leader
Red Hat, Inc.
More information about the Newlib
mailing list