Date: Tue, 12 Nov 2024 12:54:34 -0500 From: Tom Lane via tz <tz@iana.org> Message-ID: <1212112.1731434074@sss.pgh.pa.us> | strftime() in the 2024b tzcode distribution includes | | if (!p) { | errno = EOVERFLOW; | return 0; | } | | AFAICS this is dead code, It shouldn't be. | except maybe in the case that the call | passes s = NULL, maxsize = 0, which doesn't seem like a case that | the code intends to support (and EOVERFLOW would be a rather odd | choice of error code if that's the idea). POSIX requires ERANGE in that case (maxsize == 0 regardless of anything else, since there would not be room for even the terminating '\0'). (The C standard just requires an error, since it doesn't have errno or any of its values). | newstrftime.3.txt | offers a clue about the intent: | | This function may fail if: | | [EOVERFLOW] | The format includes an %s conversion and the number of seconds | since the Epoch cannot be represented in a time_t. That can happen whenever sizeof(int) >= sizeof(time_t) (and in some cases wen sizeof(int) < sizeof(time_t) but not by very much - which are extermely unlikely in any practical system). It doesn't happen on most modern systems with 64 bit time_t and 32 bit int -- but not everything is like that. | But the %s conversion code never returns zero. That sounds to be what is broken. | There's a suggestive comment there: | | /* If mktime fails, %s expands to the | value of (time_t) -1 as a failure | marker; this is better in practice | than strftime failing. */ Whoever thought that is, frankly, a fool. Pandering to broken application code with "anything will do" is never the right solution, the broken code doesn't get fixed, and its users just get nonsense results. That should be undone. POSIX actually says: [EOVERFLOW] The format string includes a %s conversion and the number of seconds since the Epoch cannot be represented in a time_t. Doing that is required. C doesn't have a %s conversion, so it says nothing about this case, but certainly allows strftime to return 0 in error cases. It isn't even as if this was a case like asctime() or ctime() used to be, where they returned a pointer to the resulting string, so apps would just do things like printf("%s", ctime(&time)); (or asctime(&tm)) since these "never fail" (which they do, or at least ctime() could). Code like that doesn't work with strftime() as it doesn't return the buffer, but the length - so there's no reason at all for applications to fail to check it, after all it can also fail if the supplied buffer just isn't big enough. kre