bug-gnulib
[Top][All Lists]
Advanced

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

Re: Let's remove Gnulib's ctime module


From: Bruno Haible
Subject: Re: Let's remove Gnulib's ctime module
Date: Mon, 05 Feb 2024 15:37:13 +0100

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,






reply via email to

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