This is the mail archive of the ecos-discuss@sources.redhat.com mailing list for the eCos project.


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

floating point output


Hi,

When using printf() and friends with special floating point numbers, i.e. x such
as finite(x) returns 0, a buffer overflow occurs. The attached patch adds checks
to the cvt() routine to handle the NaN & Inf cases separately. Is this the
correct thing to do or should the application test for special cases (I do not
have the C99 standard document to verify this).

Robin
Index: vfnprintf.cxx
===================================================================
RCS file: /usr/cvs/eCos/base/packages/language/c/libc/stdio/current/src/output/vfnprintf.cxx,v
retrieving revision 1.1.1.1
diff -C4 -r1.1.1.1 vfnprintf.cxx
*** vfnprintf.cxx	8 Mar 2001 08:57:18 -0000	1.1.1.1
--- vfnprintf.cxx	9 Aug 2001 17:22:43 -0000
***************
*** 729,750 ****
  static int
  cvt(double number, int prec, int flags, char *signp, int fmtch, char *startp,
      char *endp)
  {
!         char *p, *t;
          double fract;
          int dotrim, expcnt, gformat;
          double integer, tmp;
-         Cyg_libm_ieee_double_shape_type ieeefp;
  
          dotrim = expcnt = gformat = 0;
-         ieeefp.value = number;
-         if ( ieeefp.number.sign ){  // this checks for <0.0 and -0.0
-                 number = -number;
-                 *signp = '-';
-         } else
-                 *signp = 0;
- 
          fract = modf(number, &integer);
  
          /* get an extra slot for rounding. */
          t = ++startp;
--- 729,753 ----
  static int
  cvt(double number, int prec, int flags, char *signp, int fmtch, char *startp,
      char *endp)
  {
!     Cyg_libm_ieee_double_shape_type ieeefp;
!     char *t = startp;
! 
!     ieeefp.value = number;
!     *signp = 0;
!     if ( ieeefp.number.sign ){  // this checks for <0.0 and -0.0
!         number = -number;
!         *signp = '-';
!     }
! 
!     if (finite(number)) {
!         char *p;
          double fract;
          int dotrim, expcnt, gformat;
          double integer, tmp;
  
          dotrim = expcnt = gformat = 0;
          fract = modf(number, &integer);
  
          /* get an extra slot for rounding. */
          t = ++startp;
***************
*** 911,919 ****
                          if (*t != '.')
                                  ++t;
                  }
          }
!         return (t - startp);
  } // cvt()
  
  #endif // ifdef CYGSEM_LIBC_STDIO_PRINTF_FLOATING_POINT
  
--- 914,928 ----
                          if (*t != '.')
                                  ++t;
                  }
          }
!     } else if (isnan(number)) {
!         *signp = 0;
!         *t++ = 'n'; *t++ = 'a'; *t++ = 'n';
!     } else { // infinite
!         *t++ = 'i'; *t++ = 'n'; *t++ = 'f';
!     }
!     return (t - startp);
  } // cvt()
  
  #endif // ifdef CYGSEM_LIBC_STDIO_PRINTF_FLOATING_POINT
  

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