From mboxrd@z Thu Jan 1 00:00:00 1970 Path: news.gmane.org!not-for-mail From: Paul Eggert Newsgroups: gmane.emacs.bugs Subject: Re: Emacs current-time-string core dump on 64-bit hosts Date: Mon, 27 Mar 2006 12:49:36 -0800 Message-ID: <87d5g71ulb.fsf@penguin.cs.ucla.edu> References: <87k6arnqsx.fsf@penguin.cs.ucla.edu> <87fyle6luu.fsf@penguin.cs.ucla.edu> <877j6j1re8.fsf@penguin.cs.ucla.edu> <87y7yxsluy.fsf@penguin.cs.ucla.edu> NNTP-Posting-Host: main.gmane.org Mime-Version: 1.0 Content-Type: text/plain; charset=us-ascii X-Trace: sea.gmane.org 1143530562 27115 80.91.229.2 (28 Mar 2006 07:22:42 GMT) X-Complaints-To: usenet@sea.gmane.org NNTP-Posting-Date: Tue, 28 Mar 2006 07:22:42 +0000 (UTC) Cc: bug-gnu-emacs@gnu.org Original-X-From: bug-gnu-emacs-bounces+geb-bug-gnu-emacs=m.gmane.org@gnu.org Tue Mar 28 09:22:41 2006 Return-path: Envelope-to: geb-bug-gnu-emacs@m.gmane.org Original-Received: from lists.gnu.org ([199.232.76.165]) by ciao.gmane.org with esmtp (Exim 4.43) id 1FO8XH-0003zk-Cd for geb-bug-gnu-emacs@m.gmane.org; Tue, 28 Mar 2006 09:22:39 +0200 Original-Received: from localhost ([127.0.0.1] helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.43) id 1FO8XG-0005Im-MZ for geb-bug-gnu-emacs@m.gmane.org; Tue, 28 Mar 2006 02:22:38 -0500 Original-Received: from mailman by lists.gnu.org with tmda-scanned (Exim 4.43) id 1FNyej-0001PX-Gh for bug-gnu-emacs@gnu.org; Mon, 27 Mar 2006 15:49:41 -0500 Original-Received: from exim by lists.gnu.org with spam-scanned (Exim 4.43) id 1FNyei-0001Ow-Fh for bug-gnu-emacs@gnu.org; Mon, 27 Mar 2006 15:49:40 -0500 Original-Received: from [199.232.76.173] (helo=monty-python.gnu.org) by lists.gnu.org with esmtp (Exim 4.43) id 1FNyei-0001Os-DM for bug-gnu-emacs@gnu.org; Mon, 27 Mar 2006 15:49:40 -0500 Original-Received: from [131.179.128.19] (helo=kiwi.cs.ucla.edu) by monty-python.gnu.org with esmtp (Exim 4.52) id 1FNygG-0007Wl-6r; Mon, 27 Mar 2006 15:51:16 -0500 Original-Received: from penguin.cs.ucla.edu (Penguin.CS.UCLA.EDU [131.179.64.200]) by kiwi.cs.ucla.edu (8.11.7p1+Sun/8.11.7/UCLACS-5.2) with ESMTP id k2RKnb800675; Mon, 27 Mar 2006 12:49:37 -0800 (PST) Original-Received: from eggert by penguin.cs.ucla.edu with local (Exim 4.50) id 1FNyee-0005Et-Sz; Mon, 27 Mar 2006 12:49:36 -0800 Original-To: rms@gnu.org In-Reply-To: (Richard Stallman's message of "Mon, 27 Mar 2006 03:35:55 -0500") User-Agent: Gnus/5.1007 (Gnus v5.10.7) Emacs/21.4 (gnu/linux) X-Mailman-Approved-At: Tue, 28 Mar 2006 02:22:37 -0500 X-BeenThere: bug-gnu-emacs@gnu.org X-Mailman-Version: 2.1.5 Precedence: list List-Id: "Bug reports for GNU Emacs, the Swiss army knife of text editors" List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Original-Sender: bug-gnu-emacs-bounces+geb-bug-gnu-emacs=m.gmane.org@gnu.org Errors-To: bug-gnu-emacs-bounces+geb-bug-gnu-emacs=m.gmane.org@gnu.org Xref: news.gmane.org gmane.emacs.bugs:15001 Archived-At: Richard Stallman writes: > Ok, you can install this change. > > However, we don't want any of these changes to be operative on the GNU > system because all they do is cause trouble. On the GNU system, large > year numbers work. Why interfere with their use? > > So I think you should conditionalize them. OK, I conditionalized them, and installed the following revised change. 2006-03-27 Paul Eggert * lib-src/b2m.c: Include . (TM_YEAR_IN_ASCTIME_RANGE): New macro. (main): Check for out-of-range time stamps. * lib-src/fakemail.c: Likewise. --- b2m.c 7 May 2004 15:26:21 -0000 1.30 +++ b2m.c 27 Mar 2006 20:34:18 -0000 @@ -26,6 +26,7 @@ #undef static #endif +#include #include #include #include @@ -44,6 +45,17 @@ typedef int logical; +/* True if TM_YEAR is a struct tm's tm_year value that is acceptable + to asctime. Glibc asctime returns a useful string unless TM_YEAR + is nearly INT_MAX, but the C Standard lets C libraries overrun a + buffer if TM_YEAR needs more than 4 bytes. */ +#ifdef __GLIBC__ +# define TM_YEAR_IN_ASCTIME_RANGE(tm_year) ((tm_year) <= INT_MAX - 1900) +#else +# define TM_YEAR_IN_ASCTIME_RANGE(tm_year) \ + (-999 - 1900 <= (tm_year) && (tm_year) <= 9999 - 1900) +#endif + /* * A `struct linebuffer' is a structure which holds a line of text. * `readline' reads a line from a stream into a linebuffer and works @@ -87,6 +99,7 @@ main (argc, argv) { logical labels_saved, printing, header; time_t ltoday; + struct tm *tm; char *labels, *p, *today; struct linebuffer data; @@ -131,7 +144,13 @@ main (argc, argv) labels_saved = printing = header = FALSE; ltoday = time (0); - today = ctime (<oday); + /* Convert to a string, checking for out-of-range time stamps. + Don't use 'ctime', as that might dump core if the hardware clock + is set to a bizarre value. */ + tm = localtime (<oday); + if (! (tm && TM_YEAR_IN_ASCTIME_RANGE (tm->tm_year))) + fatal ("current time is out of range"); + today = asctime (tm); data.size = 200; data.buffer = xnew (200, char); --- fakemail.c 6 Feb 2006 11:28:28 -0000 1.35 +++ fakemail.c 27 Mar 2006 20:34:18 -0000 @@ -53,6 +53,7 @@ main () #include "ntlib.h" #endif +#include #include #include #include @@ -70,6 +71,17 @@ main () #define true 1 #define false 0 +/* True if TM_YEAR is a struct tm's tm_year value that is acceptable + to asctime. Glibc asctime returns a useful string unless TM_YEAR + is nearly INT_MAX, but the C Standard lets C libraries overrun a + buffer if TM_YEAR needs more than 4 bytes. */ +#ifdef __GLIBC__ +# define TM_YEAR_IN_ASCTIME_RANGE(tm_year) ((tm_year) <= INT_MAX - 1900) +#else +# define TM_YEAR_IN_ASCTIME_RANGE(tm_year) \ + (-999 - 1900 <= (tm_year) && (tm_year) <= 9999 - 1900) +#endif + /* Various lists */ struct line_record @@ -354,6 +366,7 @@ make_file_preface () { char *the_string, *temp; long idiotic_interface; + struct tm *tm; long prefix_length; long user_length; long date_length; @@ -361,7 +374,13 @@ make_file_preface () prefix_length = strlen (FROM_PREFIX); time (&idiotic_interface); - the_date = ctime (&idiotic_interface); + /* Convert to a string, checking for out-of-range time stamps. + Don't use 'ctime', as that might dump core if the hardware clock + is set to a bizarre value. */ + tm = localtime (&idiotic_interface); + if (! (tm && TM_YEAR_IN_ASCTIME_RANGE (tm->tm_year))) + fatal ("current time is out of range", 0); + the_date = asctime (tm); /* the_date has an unwanted newline at the end */ date_length = strlen (the_date) - 1; the_date[date_length] = '\0';