Skip to content

Commit 9b0875a

Browse files
committed
Expand the allowed range of timezone offsets to +/-15:59:59 from Greenwich.
We used to only allow offsets less than +/-13 hours, then it was +/14, then it was +/-15. That's still not good enough though, as per today's bug report from Patric Bechtel. This time I actually looked through the Olson timezone database to find the largest offsets used anywhere. The winners are Asia/Manila, at -15:56:00 until 1844, and America/Metlakatla, at +15:13:42 until 1867. So we'd better allow offsets less than +/-16 hours. Given the history, we are way overdue to have some greppable #define symbols controlling this, so make some ... and also remove an obsolete comment that didn't get fixed the last time. Back-patch to all supported branches.
1 parent b1d01f9 commit 9b0875a

File tree

3 files changed

+14
-7
lines changed

3 files changed

+14
-7
lines changed

src/backend/utils/adt/date.c

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1924,9 +1924,8 @@ timetz_recv(PG_FUNCTION_ARGS)
19241924

19251925
result->zone = pq_getmsgint(buf, sizeof(result->zone));
19261926

1927-
/* we allow GMT displacements up to 14:59:59, cf DecodeTimezone() */
1928-
if (result->zone <= -15 * SECS_PER_HOUR ||
1929-
result->zone >= 15 * SECS_PER_HOUR)
1927+
/* Check for sane GMT displacement; see notes in utils/timestamp.h */
1928+
if (result->zone <= -TZDISP_LIMIT || result->zone >= TZDISP_LIMIT)
19301929
ereport(ERROR,
19311930
(errcode(ERRCODE_INVALID_TIME_ZONE_DISPLACEMENT_VALUE),
19321931
errmsg("time zone displacement out of range")));

src/backend/utils/adt/datetime.c

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2699,9 +2699,6 @@ DecodeNumberField(int len, char *str, int fmask,
26992699
* Return 0 if okay (and set *tzp), a DTERR code if not okay.
27002700
*
27012701
* NB: this must *not* ereport on failure; see commands/variable.c.
2702-
*
2703-
* Note: we allow timezone offsets up to 13:59. There are places that
2704-
* use +1300 summer time.
27052702
*/
27062703
static int
27072704
DecodeTimezone(char *str, int *tzp)
@@ -2746,7 +2743,8 @@ DecodeTimezone(char *str, int *tzp)
27462743
else
27472744
min = 0;
27482745

2749-
if (hr < 0 || hr > 14)
2746+
/* Range-check the values; see notes in utils/timestamp.h */
2747+
if (hr < 0 || hr > MAX_TZDISP_HOUR)
27502748
return DTERR_TZDISP_OVERFLOW;
27512749
if (min < 0 || min >= 60)
27522750
return DTERR_TZDISP_OVERFLOW;

src/include/utils/timestamp.h

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -100,6 +100,16 @@ typedef struct
100100
#define USECS_PER_SEC INT64CONST(1000000)
101101
#endif
102102

103+
/*
104+
* We allow numeric timezone offsets up to 15:59:59 either way from Greenwich.
105+
* Currently, the record holders for wackiest offsets in actual use are zones
106+
* Asia/Manila, at -15:56:00 until 1844, and America/Metlakatla, at +15:13:42
107+
* until 1867. If we were to reject such values we would fail to dump and
108+
* restore old timestamptz values with these zone settings.
109+
*/
110+
#define MAX_TZDISP_HOUR 15 /* maximum allowed hour part */
111+
#define TZDISP_LIMIT ((MAX_TZDISP_HOUR + 1) * SECS_PER_HOUR)
112+
103113
/*
104114
* Macros for fmgr-callable functions.
105115
*

0 commit comments

Comments
 (0)