Bug 4342 - scanf %lg problem with hex numbers
Summary: scanf %lg problem with hex numbers
Status: RESOLVED FIXED
Alias: None
Product: glibc
Classification: Unclassified
Component: libc (show other bugs)
Version: unspecified
: P2 normal
Target Milestone: ---
Assignee: Ulrich Drepper
URL:
Keywords:
Depends on:
Blocks:
 
Reported: 2007-04-10 22:22 UTC by Pierre Habouzit
Modified: 2007-04-27 19:29 UTC (History)
1 user (show)

See Also:
Host:
Target:
Build:
Last reconfirmed:


Attachments

Note You need to log in before you can comment on or make changes to this bug.
Description Pierre Habouzit 2007-04-10 22:22:10 UTC
scanf makes exponents specifiers mandatory whereas it should not. The code to 
reproduce the problem is:



#include <stdio.h>

int
main (void)
{
    double d = -999;
    int  ret;

    ret =  sscanf ("0x100", "%lg", &d);
    printf ("%d %g\n", ret, d);

    ret =  sscanf ("0x100p0", "%lg", &d);
    printf ("%d %g\n", ret, d);

    return 0;
}


expected output would be:
1 256
1 256

it gives currently:
0 -999
1 256
Comment 1 Jakub Jelinek 2007-04-23 13:44:47 UTC
That's how *scanf initially worked, till the
1999-08-13  Ulrich Drepper  <drepper@cygnus.com>

        * stdio-common/tstscanf.c: Add test for hexadecimal float parsing
        problem.

        * stdio-common/vfscanf.c: Don't recognize hexadecimal floats without
        exponent.

--- stdio-common/vfscanf.c      21 Jun 1999 13:35:40 -0000      1.67
+++ stdio-common/vfscanf.c      13 Aug 1999 19:41:26 -0000      1.68
@@ -1410,8 +1410,8 @@ __vfscanf (FILE *s, const char *format, 

          /* Have we read any character?  If we try to read a number
             in hexadecimal notation and we have read only the `0x'
-            prefix this is an error.  */
-         if (wpsize == 0 || (is_hexa && wpsize == 2))
+            prefix or no exponent this is an error.  */
+         if (wpsize == 0 || (is_hexa && (wpsize == 2 || ! got_e)))
            conv_error ();

        scan_float:
--- stdio-common/tstscanf.c     6 Jun 1999 09:18:57 -0000       1.12
+++ stdio-common/tstscanf.c     13 Aug 1999 22:39:01 -0000      1.13
@@ -250,5 +250,20 @@ main (int argc, char **argv)
       }
   }
 
+  fputs ("Test 8:\n", stdout);
+  {
+    double d = 123456.789;
+    int res;
+
+    res = sscanf ("0x1234", "%lf", &d);
+    printf ("res = %d, d = %f\n", res, d);
+
+    if (res != 0 || d != 123456.789)
+      {
+       fputs ("test failed!\n", stdout);
+       result = 1;
+      }
+  }
+
   exit (result);
 }  

change.  My reading of both ISO C99 and current POSIX suggests that indeed
the exponent is only optional.  While ISO C99 has a footnote:
"fscanf pushes back at most one input character onto the input stream.
Therefore, some sequences that are acceptable to strtod, strtol, etc., are
unacceptable to fscanf." I don't think this applies here, as the hexadecimal
float exponent part is structured the same as decimal exponent part, just with
a different letter (p vs. e) and as the decimal float has the exponent part
optional, there is no reason why it couldn't be optional even for hexadecimal
floats.
Comment 2 Ulrich Drepper 2007-04-27 20:29:15 UTC
I changed the code in cvs.
Comment 3 Sourceware Commits 2007-07-12 15:14:04 UTC
Subject: Bug 4342

CVSROOT:	/cvs/glibc
Module name:	libc
Branch: 	glibc-2_5-branch
Changes by:	jakub@sourceware.org	2007-07-12 15:13:48

Modified files:
	.              : ChangeLog 
	stdio-common   : tstscanf.c vfscanf.c 

Log message:
	2007-04-27  Ulrich Drepper  <drepper@redhat.com>
	
	[BZ #4342]
	* stdio-common/vfscanf.c (_IO_vfscanf_internal): Allow
	hexa-decimal floats without exponent.
	* stdio-common/tstscanf.c (main): Adjust Test 8 test for success.

Patches:
http://sourceware.org/cgi-bin/cvsweb.cgi/libc/ChangeLog.diff?cvsroot=glibc&only_with_tag=glibc-2_5-branch&r1=1.10362.2.75&r2=1.10362.2.76
http://sourceware.org/cgi-bin/cvsweb.cgi/libc/stdio-common/tstscanf.c.diff?cvsroot=glibc&only_with_tag=glibc-2_5-branch&r1=1.21&r2=1.21.10.1
http://sourceware.org/cgi-bin/cvsweb.cgi/libc/stdio-common/vfscanf.c.diff?cvsroot=glibc&only_with_tag=glibc-2_5-branch&r1=1.115&r2=1.115.2.1