This is the mail archive of the guile@sources.redhat.com mailing list for the Guile project.


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

Guile bug: strftime


On both Intel Red Hat 6.2 and Sparc Solaris 2.6, the strftime primitive
has a bug: if the string it would have otherwise produced would have
been greater than 50 characters in length, a null string is returned.

Cause of the problem is the assumption that strftime follows the
(apparently now obsolete) convention of returning size of the return
buffer if it didn't have enough space to format its result.  On at
least Linux and Solaris (I don't have access to others, sorry), strftime
returns 0 in such a case.

Try:
(strftime "This string is long enough to make a bug manifest itself: %c"
(localtime (current-time)))
to see a demonstration of the bug.

The attached diff to libguile/stime.c assumes that there's no significant
instances of systems that don't use a 0 return from strftime to indicate
lack of space; if this assumption of mine is incorrect, then something
will have to be done with autoconf and #ifdef to accommodate such systems.

-- 
           David W. Barts (davidb@scn.org) / http://www.scn.org/~davidb
                               Oakland, CA, USA
*** stime.c.old	Mon Jun 12 05:28:24 2000
--- stime.c	Sat Jul 22 18:39:49 2000
***************
*** 62,67 ****
--- 62,71 ----
  #  include <sys/types.h>
  # endif
  
+ #ifdef HAVE_STRING_H
+ #include <string.h>
+ #endif
+ 
  # ifdef TIME_WITH_SYS_TIME
  #  include <sys/time.h>
  #  include <time.h>
***************
*** 560,566 ****
  
    char *tbuf;
    int size = 50;
!   char *fmt;
    int len;
    SCM result;
  
--- 564,570 ----
  
    char *tbuf;
    int size = 50;
!   char *fmt, *myfmt;
    int len;
    SCM result;
  
***************
*** 571,576 ****
--- 575,590 ----
    fmt = SCM_ROCHARS (format);
    len = SCM_ROLENGTH (format);
  
+   /* Ugly hack: strftime now returns 0 if its buffer is too small,
+      but some valid time strings (e.g. "%p") can sometimes produce
+      a zero-byte output string!  Workaround is to prepend a junk
+      character to the format string, so that valid returns are always
+      nonzero. */
+   myfmt = SCM_MUST_MALLOC (len+2);
+   *myfmt = 'x';
+   strncpy(myfmt+1, fmt, len);
+   myfmt[len+1] = 0;
+ 
    tbuf = SCM_MUST_MALLOC (size);
    {
  #if !defined (HAVE_TM_ZONE)
***************
*** 603,609 ****
      tzset ();
  #endif
  
!     while ((len = strftime (tbuf, size, fmt, &t)) == size)
        {
  	scm_must_free (tbuf);
  	size *= 2;
--- 617,623 ----
      tzset ();
  #endif
  
!     while ((len = strftime (tbuf, size, myfmt, &t)) == 0)
        {
  	scm_must_free (tbuf);
  	size *= 2;
***************
*** 619,626 ****
  #endif
      }
  
!   result = scm_makfromstr (tbuf, len, 0);
    scm_must_free (tbuf);
    return result;
  }
  #undef FUNC_NAME
--- 633,641 ----
  #endif
      }
  
!   result = scm_makfromstr (tbuf+1, len-1, 0);
    scm_must_free (tbuf);
+   scm_must_free(myfmt);
    return result;
  }
  #undef FUNC_NAME

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