Fix a porting bug in strftime.c, triggered on theoretical
(but conforming) hosts where 0x7fffffff is of type unsigned long.
While we’re at it, give 2**31 - 1 a name to make this problem
less likely in the future, and use the name consistently.
* private.h (TWO_31_MINUS_1): New macro.
* strftime.c (MKTIME_FITS_IN):
* zic.c (ZIC32_MIN, ZIC32_MAX, addtype): Use it.
---
 private.h  | 5 ++++-
 strftime.c | 5 +++--
 zic.c      | 6 +++---
 3 files changed, 10 insertions(+), 6 deletions(-)

diff --git a/private.h b/private.h
index 55a8d548..7e1e350a 100644
--- a/private.h
+++ b/private.h
@@ -1083,7 +1083,10 @@ char *asctime_r(struct tm const *restrict, char 
*restrict);
 char *ctime_r(time_t const *, char *);
 #endif /* HAVE_INCOMPATIBLE_CTIME_R */
 
-/* Handy macros that are independent of tzfile implementation.  */
+/* Handy constants that are independent of tzfile implementation.  */
+
+/* 2**31 - 1 as a signed integer, and usable in #if.  */
+#define TWO_31_MINUS_1 2147483647
 
 enum {
   SECSPERMIN = 60,
diff --git a/strftime.c b/strftime.c
index 487a5234..c2490105 100644
--- a/strftime.c
+++ b/strftime.c
@@ -49,8 +49,9 @@
    and account for the tm_year origin (1900) and time_t origin (1970).  */
 #define MKTIME_FITS_IN(min, max) \
   ((min) < 0 \
-   && ((min) + 0x7fffffff) / 366 / 24 / 60 / 60 / 2 + 1970 - 1900 < INT_MIN \
-   && INT_MAX < ((max) - 0x7fffffff) / 366 / 24 / 60 / 60 / 2 + 1970 - 1900)
+   && (((min) + TWO_31_MINUS_1) / 366 / 24 / 60 / 60 / 2 + 1970 - 1900 \
+       < INT_MIN)                                              \
+   && INT_MAX < ((max) - TWO_31_MINUS_1) / 366 / 24 / 60 / 60 / 2 + 1970 - 
1900)
 
 /* MKTIME_MIGHT_OVERFLOW is true if mktime can fail due to time_t overflow
    or if it is not known whether mktime can fail,
diff --git a/zic.c b/zic.c
index b69414dd..d50ad012 100644
--- a/zic.c
+++ b/zic.c
@@ -31,8 +31,8 @@ typedef int_fast64_t  zic_t;
 static zic_t const
   ZIC_MIN = INT_FAST64_MIN,
   ZIC_MAX = INT_FAST64_MAX,
-  ZIC32_MIN = -1 - (zic_t) 0x7fffffff,
-  ZIC32_MAX = 0x7fffffff;
+  ZIC32_MIN = -1 - (zic_t) TWO_31_MINUS_1,
+  ZIC32_MAX = TWO_31_MINUS_1;
 #define SCNdZIC SCNdFAST64
 
 #ifndef ZIC_MAX_ABBR_LEN_WO_WARN
@@ -3761,7 +3761,7 @@ addtype(zic_t utoff, char const *abbr, bool isdst, bool 
ttisstd, bool ttisut)
        register int    i, j;
 
        /* RFC 9636 section 3.2 specifies this range for utoff.  */
-       if (! (-2147483647 <= utoff && utoff <= 2147483647)) {
+       if (! (-TWO_31_MINUS_1 <= utoff && utoff <= TWO_31_MINUS_1)) {
                error(_("UT offset out of range"));
                exit(EXIT_FAILURE);
        }
-- 
2.51.0

Reply via email to