bug-gnu-emacs
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: Emacs current-time-string core dump on 64-bit hosts


From: Paul Eggert
Subject: Re: Emacs current-time-string core dump on 64-bit hosts
Date: Fri, 24 Mar 2006 12:45:02 -0800
User-agent: Gnus/5.1007 (Gnus v5.10.7) Emacs/21.4 (gnu/linux)

Richard Stallman <address@hidden> writes:

> Would you please put the new code directly into editfns.c?
> That would avoid the need for new files, makefile changes, etc.

OK, I've done this, and installed the following patch.  This patch is
simpler than what I submitted earlier, since it uses asctime rather
than formatting by hand.

2006-03-24  Paul Eggert  <address@hidden>

        * editfns.c: Do not use ctime, since it has undefined behavior
        with out-of-range time stamps.  This fixes a bug where
        (current-time-string '(2814749767106 0)) would make Emacs dump
        core on 64-bit Solaris 8.  The fix is to use localtime+asctime
        (checking for in-range results) instead of ctime.  Please see
        <http://www.opengroup.org/austin/mailarchives/ag/msg09294.html>
        for more details about this portability problem.
        (TM_YEAR_BASE): Move up, so the changes below can use it.
        (Fdecode_time, Fencode_time): Use TM_YEAR_BASE instead of 1900.
        (Fdecode_time): Cast tm_year to EMACS_INT, to avoid overflow when
        int is narrower than EMACS_INT.
        (Fcurrent_time_string): As with Fformat_time_string, report an
        invalid time specification if the argument is invalid.  Also,
        check for out-of-range time stamps; this prevents a buffer overrun
        that causes Emacs to dump core on 64-bit Solaris sparc, and it
        preserves the historic behavior of always returning a fixed-size
        string.

*** editfns.c   7 Feb 2006 09:08:53 -0000       1.409
--- editfns.c   24 Mar 2006 20:40:24 -0000      1.410
*************** Boston, MA 02110-1301, USA.  */
*** 72,77 ****
--- 72,79 ----
  extern char **environ;
  #endif
  
+ #define TM_YEAR_BASE 1900
+ 
  extern size_t emacs_strftimeu P_ ((char *, size_t, const char *,
                                   const struct tm *, int));
  static int tm_diff P_ ((struct tm *, struct tm *));
*************** DOW and ZONE.)  */)
*** 1722,1728 ****
    XSETFASTINT (list_args[2], decoded_time->tm_hour);
    XSETFASTINT (list_args[3], decoded_time->tm_mday);
    XSETFASTINT (list_args[4], decoded_time->tm_mon + 1);
!   XSETINT (list_args[5], decoded_time->tm_year + 1900);
    XSETFASTINT (list_args[6], decoded_time->tm_wday);
    list_args[7] = (decoded_time->tm_isdst)? Qt : Qnil;
  
--- 1724,1730 ----
    XSETFASTINT (list_args[2], decoded_time->tm_hour);
    XSETFASTINT (list_args[3], decoded_time->tm_mday);
    XSETFASTINT (list_args[4], decoded_time->tm_mon + 1);
!   XSETINT (list_args[5], TM_YEAR_BASE + (EMACS_INT) decoded_time->tm_year);
    XSETFASTINT (list_args[6], decoded_time->tm_wday);
    list_args[7] = (decoded_time->tm_isdst)? Qt : Qnil;
  
*************** usage: (encode-time SECOND MINUTE HOUR D
*** 1778,1784 ****
    tm.tm_hour = XINT (args[2]);
    tm.tm_mday = XINT (args[3]);
    tm.tm_mon = XINT (args[4]) - 1;
!   tm.tm_year = XINT (args[5]) - 1900;
    tm.tm_isdst = -1;
  
    if (CONSP (zone))
--- 1780,1786 ----
    tm.tm_hour = XINT (args[2]);
    tm.tm_mday = XINT (args[3]);
    tm.tm_mon = XINT (args[4]) - 1;
!   tm.tm_year = XINT (args[5]) - TM_YEAR_BASE;
    tm.tm_isdst = -1;
  
    if (CONSP (zone))
*************** but this is considered obsolete.  */)
*** 1844,1854 ****
  {
    time_t value;
    char buf[30];
    register char *tem;
  
    if (! lisp_time_argument (specified_time, &value, NULL))
!     value = -1;
!   tem = (char *) ctime (&value);
  
    strncpy (buf, tem, 24);
    buf[24] = 0;
--- 1846,1861 ----
  {
    time_t value;
    char buf[30];
+   struct tm *tm;
    register char *tem;
  
    if (! lisp_time_argument (specified_time, &value, NULL))
!     error ("Invalid time specification");
!   tm = localtime (&value);
!   if (! (tm && -999 - TM_YEAR_BASE <= tm->tm_year
!        && tm->tm_year <= 9999 - TM_YEAR_BASE))
!     error ("Specified time is not representable");
!   tem = asctime (tm);
  
    strncpy (buf, tem, 24);
    buf[24] = 0;
*************** but this is considered obsolete.  */)
*** 1856,1863 ****
    return build_string (buf);
  }
  
- #define TM_YEAR_BASE 1900
- 
  /* Yield A - B, measured in seconds.
     This function is copied from the GNU C Library.  */
  static int
--- 1863,1868 ----




reply via email to

[Prev in Thread] Current Thread [Next in Thread]