diff --git a/src/backend/utils/adt/datetime.c b/src/backend/utils/adt/datetime.c index 1408d67a4a49022e5c31c563ef30adb88e2089ba..184c8f441b016e88abff98b5840fdd0a5d533f53 100644 --- a/src/backend/utils/adt/datetime.c +++ b/src/backend/utils/adt/datetime.c @@ -2571,9 +2571,6 @@ DecodeNumberField(int len, char *str, int fmask, * Return 0 if okay (and set *tzp), a DTERR code if not okay. * * NB: this must *not* ereport on failure; see commands/variable.c. - * - * Note: we allow timezone offsets up to 13:59. There are places that - * use +1300 summer time. */ static int DecodeTimezone(char *str, int *tzp) @@ -2618,7 +2615,8 @@ DecodeTimezone(char *str, int *tzp) else min = 0; - if (hr < 0 || hr > 14) + /* Range-check the values; see notes in utils/timestamp.h */ + if (hr < 0 || hr > MAX_TZDISP_HOUR) return DTERR_TZDISP_OVERFLOW; if (min < 0 || min >= 60) return DTERR_TZDISP_OVERFLOW; diff --git a/src/include/utils/timestamp.h b/src/include/utils/timestamp.h index 1f73a2a081aa73b5425cd36a79491d2810bf2ae6..f8a4bdca1dd89463763b3bd42edfff983064a41a 100644 --- a/src/include/utils/timestamp.h +++ b/src/include/utils/timestamp.h @@ -89,6 +89,16 @@ typedef struct #define USECS_PER_SEC INT64CONST(1000000) #endif +/* + * We allow numeric timezone offsets up to 15:59:59 either way from Greenwich. + * Currently, the record holders for wackiest offsets in actual use are zones + * Asia/Manila, at -15:56:00 until 1844, and America/Metlakatla, at +15:13:42 + * until 1867. If we were to reject such values we would fail to dump and + * restore old timestamptz values with these zone settings. + */ +#define MAX_TZDISP_HOUR 15 /* maximum allowed hour part */ +#define TZDISP_LIMIT ((MAX_TZDISP_HOUR + 1) * SECS_PER_HOUR) + /* * Macros for fmgr-callable functions. *