bug-gnulib@gnu.org mirror (unofficial)
 help / color / mirror / Atom feed
From: Bruno Haible <bruno@clisp.org>
To: bug-gnulib@gnu.org, Paul Eggert <eggert@cs.ucla.edu>
Cc: Bjarni Ingi Gislason <bjarniig@simnet.is>
Subject: Re: Let's remove Gnulib's ctime module
Date: Mon, 05 Feb 2024 15:37:13 +0100	[thread overview]
Message-ID: <12647869.fRMHPE6dU6@nimes> (raw)
In-Reply-To: <cc3ca215-6258-42da-a3e7-dee5c13981e0@cs.ucla.edu>

Hi Paul,

> This recent bug relating to ctime suggests that the ctime module is more 
> trouble than it's worth now. I propose that we remove it. Proposed patch 
> attached (but not installed).

I disagree that the ctime module is "a maintenance hassle". In my view,
its maintenance takes much less effort than the average.

The reported problem was, at the root, a problem with the _GL_WARN_ON_USE
macro, that could have arisen with any other POSIX function as well.

Since my environment for native Windows is based on Cygwin (since that's
generally more reliable than MSYS2) and the ctime problem with $TZ is a
known one, I want to never encounter it again — even if I'm testing or
debugging a package that happens to use ctime.

Also, according to your doc changes (which I'm mostly committing in your name),
a program that makes sure to use ctime() only for dates between 1900 and
2100 is fine.

> * doc/posix-functions/ctime_r.texi (ctime_r): Remove now-incorrect
> commentary that I think is about old SunOS ctime_r.

That comment was not about SunOS. It was my attempt at understanding
and documenting why ctime_r was still not adequate. I had written:

  The input buffer should be at least 26 bytes in size.  The output
  string is locale-independent.  However, years can have more than 4
  digits if @code{time_t} is sufficiently wide, so the length of the
  required output buffer is not easy to determine.  Increasing the
  buffer size when @code{ctime_r} returns @code{NULL} is not necessarily
  sufficient.  The @code{NULL} return value could mean some other error
  condition, which will not go away by increasing the buffer size.

26 bytes is not enough. But 50 should be enough. Can we give the advice
that it's OK to invoke it with a buffer of size 50?


2024-02-05  Paul Eggert  <eggert@cs.ucla.edu>

	doc: Extend doc of *ctime functions.
	* doc/posix-functions/ctime.texi (ctime): Document why we got into
	this mess.
	* doc/posix-functions/asctime.texi (asctime):
	* doc/posix-functions/asctime_r.texi (asctime_r):
	* doc/posix-functions/ctime_r.texi (ctime_r):
	Refer to ctime’s buffer overflow doc.

diff --git a/doc/posix-functions/asctime.texi b/doc/posix-functions/asctime.texi
index c212a76118..7b19deaa22 100644
--- a/doc/posix-functions/asctime.texi
+++ b/doc/posix-functions/asctime.texi
@@ -18,5 +18,7 @@
 removed in a future version.
 Portable applications can use @code{strftime} (or even @code{sprintf}) instead.
 @item
-This function may overflow its internal buffer if an invalid year is passed.
+This function may overflow its internal buffer if its argument
+specifies a time before the year 1000 or after the year 9999.
+@xref{ctime}.
 @end itemize
diff --git a/doc/posix-functions/asctime_r.texi b/doc/posix-functions/asctime_r.texi
index 3b19860363..ae527bd197 100644
--- a/doc/posix-functions/asctime_r.texi
+++ b/doc/posix-functions/asctime_r.texi
@@ -25,6 +25,7 @@
 removed in a future version.
 Use the function @code{strftime} (or even @code{sprintf}) instead.
 @item
-This function may put more than 26 bytes into the argument buffer if an
-invalid year is passed.
+This function may overflow its output buffer if its argument
+specifies a time before the year 1000 or after the year 9999.
+@xref{ctime}.
 @end itemize
diff --git a/doc/posix-functions/ctime.texi b/doc/posix-functions/ctime.texi
index bab929c08c..76c6e0ffe0 100644
--- a/doc/posix-functions/ctime.texi
+++ b/doc/posix-functions/ctime.texi
@@ -22,7 +22,27 @@
 Portable applications can use @code{localtime_r} and @code{strftime}
 (or even @code{sprintf}) instead.
 @item
-This function may overflow its internal buffer if an invalid year is passed.
+This function may overflow its internal buffer if its argument
+specifies a time before the year 1000 or after the year 9999.
+
+Here is some history about this.
+This function was safe to use decades ago when @code{time_t} was narrow
+and there was no @code{strftime} or internationalization.
+Code could call @code{ctime} and then select the parts needed.
+For example, in Unix 7th Edition @file{/usr/src/cmd/ls.c} (1979):
+
+@example
+cp = ctime(&p->lmtime);
+if(p->lmtime < year)
+        printf(" %-7.7s %-4.4s ", cp+4, cp+20); else
+        printf(" %-12.12s ", cp+4);
+@end example
+
+This has well-defined behavior if @code{time_t} is only 32 bits
+and so was OK for circa 1979 platforms.
+However, today's platforms have a @code{time_t} so wide
+that the year might not be in the range [1000, 9999],
+and ISO C says that in this case the behavior of @code{ctime} is undefined.
 @item
 The @code{ctime} function need not be reentrant, and consequently is
 not required to be thread safe.  Implementations of @code{ctime}
diff --git a/doc/posix-functions/ctime_r.texi b/doc/posix-functions/ctime_r.texi
index 8b5dd136cc..be157cb643 100644
--- a/doc/posix-functions/ctime_r.texi
+++ b/doc/posix-functions/ctime_r.texi
@@ -26,8 +26,9 @@
 Use the functions @code{localtime_r} and @code{strftime}
 (or even @code{sprintf}) instead.
 @item
-This function may put more than 26 bytes into the argument buffer if an
-invalid year is passed.
+This function may overflow its output buffer if its argument
+specifies a time before the year 1000 or after the year 9999.
+@xref{ctime}.
 @end itemize
 
 @code{ctime_r} takes a pre-allocated buffer and length of the buffer,





  parent reply	other threads:[~2024-02-05 14:37 UTC|newest]

Thread overview: 38+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2024-02-03 13:25 lib/time.in.h, ctime has portability problems; with clang and groff Bjarni Ingi Gislason
2024-02-03 21:43 ` Paul Eggert
2024-02-03 21:46   ` Let's remove Gnulib's ctime module Paul Eggert
2024-02-05  8:16     ` Simon Josefsson via Gnulib discussion list
2024-02-05  8:59       ` Paul Eggert
2024-02-05  9:48         ` Simon Josefsson via Gnulib discussion list
2024-02-05 10:52           ` Simon Josefsson via Gnulib discussion list
2024-02-06  5:14             ` Paul Eggert
2024-02-06  8:04               ` Simon Josefsson via Gnulib discussion list
2024-02-08 17:00                 ` Bruno Haible
2024-02-08 18:22                   ` Paul Eggert
2024-02-08 19:20                     ` Simon Josefsson via Gnulib discussion list
2024-02-08 23:39                       ` Paul Eggert
2024-02-09  8:39                         ` Simon Josefsson via Gnulib discussion list
2024-02-09  9:00                           ` Paul Eggert
2024-02-09 15:22                             ` Bruno Haible
2024-02-10 10:33                             ` Simon Josefsson via Gnulib discussion list
2024-02-11  1:50                               ` Paul Eggert
2024-02-09 15:13                         ` Bruno Haible
2024-02-09  0:20                       ` Paul Eggert
2024-02-09 15:06                       ` Bruno Haible
2024-02-10  4:22                         ` Paul Eggert
2024-02-10  9:53                           ` Bruno Haible
2024-02-10 10:47                             ` Simon Josefsson via Gnulib discussion list
2024-02-10 20:36                               ` Paul Eggert
2024-02-09 15:00                     ` Bruno Haible
2024-02-10  4:43                       ` Paul Eggert
2024-02-10 10:03                         ` Bruno Haible
2024-02-11  1:58                           ` Paul Eggert
2024-02-11 10:16                             ` Bruno Haible
2024-02-08  9:02       ` obsolescent ctime Bruno Haible
2024-02-09  2:20         ` Paul Eggert
2024-02-05 14:37     ` Bruno Haible [this message]
2024-02-06  6:59       ` Let's remove Gnulib's ctime module Paul Eggert
2024-02-06  8:37         ` Bruno Haible
2024-02-05 14:02   ` lib/time.in.h, ctime has portability problems; with clang and groff Bruno Haible
2024-02-05 13:41 ` Bruno Haible
2024-02-06  5:27   ` Paul Eggert

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

  List information: https://lists.gnu.org/mailman/listinfo/bug-gnulib

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=12647869.fRMHPE6dU6@nimes \
    --to=bruno@clisp.org \
    --cc=bjarniig@simnet.is \
    --cc=bug-gnulib@gnu.org \
    --cc=eggert@cs.ucla.edu \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).