This is the mail archive of the newlib@sourceware.org mailing list for the newlib project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

Re: scanf and "-0x", "-nan", "inf"


Eric Blake <ebb9 <at> byu.net> writes:

> Bugs that I am still aware of:

On platforms with 32-bit long but 64-bit void* (yes, such horrid platforms 
exist, at least in the form of 64-bit Windows - what were they thinking?):
void *p = 0x1ffffff00;
void *q;
char buf[20];
sprintf(buf, "%p", p);
sscanf(buf, "%p", &q);
assert(p == q);

Fixed like so:

2007-05-22  Eric Blake  <ebb9@byu.net>

	* libc/stdio/vfprintf.c (_VFPRINTF_R): Don't truncate %p when
	sizeof(void*) is 8 but sizeof(long) is 4.
	* libc/stdio/vfscanf.c (__SVFSCANF_R): Likewise.

Index: libc/stdio/vfprintf.c
===================================================================
RCS file: /cvs/src/src/newlib/libc/stdio/vfprintf.c,v
retrieving revision 1.60
diff -u -p -r1.60 vfprintf.c
--- libc/stdio/vfprintf.c       18 May 2007 14:33:30 -0000      1.60
+++ libc/stdio/vfprintf.c       22 May 2007 16:49:34 -0000
@@ -1017,7 +1017,7 @@ reswitch: switch (ch) {
                         *      -- ANSI X3J11
                         */
                        /* NOSTRICT */
-                       _uquad = (u_long)(unsigned _POINTER_INT)GET_ARG (N, ap, 
void_ptr_t);
+                       _uquad = (uintptr_t) GET_ARG (N, ap, void_ptr_t);
                        base = HEX;
                        xdigs = "0123456789abcdef";
                        flags |= HEXPREFIX;
Index: libc/stdio/vfscanf.c
===================================================================
RCS file: /cvs/src/src/newlib/libc/stdio/vfscanf.c,v
retrieving revision 1.36
diff -u -p -r1.36 vfscanf.c
--- libc/stdio/vfscanf.c        18 May 2007 14:33:30 -0000      1.36
+++ libc/stdio/vfscanf.c        22 May 2007 16:49:34 -0000
@@ -993,7 +993,19 @@ _DEFUN(__SVFSCANF_R, (rptr, fp, fmt0, ap
              *p = 0;
              res = (*ccfn) (rptr, buf, (char **) NULL, base);
              if (flags & POINTER)
-               *(va_arg (ap, _PTR *)) = (_PTR) (unsigned _POINTER_INT) res;
+                {
+                  void **vp = GET_ARG (N, ap, void **);
+#ifndef _NO_LONGLONG
+                  if (sizeof (uintptr_t) > sizeof (u_long))
+                    {
+                      u_long_long resll;
+                      resll = _strtoull_r (rptr, buf, (char **) NULL, base);
+                      *vp = (void *) (uintptr_t) resll;
+                    }
+                  else
+#endif _NO_LONGLONG
+                    *vp = (void *) (uintptr_t) res;
+                }
 #ifdef _WANT_IO_C99_FORMATS
              else if (flags & CHAR)
                {





Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]