time_t truncation occurrence in tzcode
Due to an update of the Coverity Scan analyzer itself, it has identified a new issue in timezone code. In version 2022c (the excerpt is copypasted from an own project, so line numbers don't mean much), it has flagged: <<< 1757 while (year_lengths[isleap(y)] <= idays) { 1758 int tdelta = idays / DAYSPERLYEAR; 1759 int_fast32_t ydelta = tdelta + !tdelta; 1760 time_t newy = y + ydelta; 1761 register int leapdays; 1762 leapdays = leaps_thru_end_of(newy - 1) - 1763 leaps_thru_end_of(y - 1); 1764 idays -= ydelta * DAYSPERNYEAR; 1765 idays -= leapdays; 1766 y = newy; 1767 } 1768 1769 if (!TYPE_SIGNED(time_t) && y < TM_YEAR_BASE) { CID 1491244 (#1 of 1): Use of 32-bit time_t (Y2K38_SAFETY) 1. store_truncates_time_t: A time_t value is stored in an integer with too few bits to accommodate it. The expression y is cast to int. 1770 int signed_y = y; ^^^^^^^^^^^^ 1771 tmp->tm_year = signed_y - TM_YEAR_BASE; 1772 } else if ((!TYPE_SIGNED(time_t) || INT_MIN + TM_YEAR_BASE <= y) 1773 && y - TM_YEAR_BASE <= INT_MAX) 1774 tmp->tm_year = y - TM_YEAR_BASE; 1775 else { 1776 errno = EOVERFLOW; 1777 return NULL; 1778 } 1779 tmp->tm_yday = idays;
On e.g. x86_64-linux-gnu, time_t is 64 bits (signed) wide, and while the specific code path is not executed on that particular platform, the warning about a truncation to a 32-bit signed int seems justified.
On 2022-08-18 17:19:07+0200, Jan Engelhardt via tz <tz@iana.org> wrote:
Due to an update of the Coverity Scan analyzer itself, it has identified a new issue in timezone code. In version 2022c (the excerpt is copypasted from an own project, so line numbers don't mean much), it has flagged:
[...]
1769 if (!TYPE_SIGNED(time_t) && y < TM_YEAR_BASE) { CID 1491244 (#1 of 1): Use of 32-bit time_t (Y2K38_SAFETY) 1. store_truncates_time_t: A time_t value is stored in an integer with too few bits to accommodate it. The expression y is cast to int. 1770 int signed_y = y; ^^^^^^^^^^^^ On e.g. x86_64-linux-gnu, time_t is 64 bits (signed) wide, and while the specific code path is not executed on that particular platform, the warning about a truncation to a 32-bit signed int seems justified.
IIUC, CFLAGS="-Dtime_tz=int64_t" is your friends. -- Danh
On 8/18/22 08:19, Jan Engelhardt via tz wrote:
1769 if (!TYPE_SIGNED(time_t) && y < TM_YEAR_BASE) { CID 1491244 (#1 of 1): Use of 32-bit time_t (Y2K38_SAFETY) 1. store_truncates_time_t: A time_t value is stored in an integer with too few bits to accommodate it. The expression y is cast to int. 1770 int signed_y = y; ^^^^^^^^^^^^
The Coverity warning is clearly a false alarm. y is a time_t, so if time_t is unsigned and y < TM_YEAR_BASE, then 0≤ y<1900, and therefore assigning y to an int cannot possibly truncate y's value. If Coverity formerly didn't issue a false alarm here, it's a regression in Coverity. Perhaps you could file a bug with the Coverity maintainers. You might also mention a terminology glitch: the false alarm says "y is cast to int" but there's no cast in that line.
participants (3)
-
Jan Engelhardt -
Paul Eggert -
Đoàn Trần Công Danh