diff options
author | Tom Lane <tgl@sss.pgh.pa.us> | 2012-05-30 19:58:41 -0400 |
---|---|---|
committer | Tom Lane <tgl@sss.pgh.pa.us> | 2012-05-30 19:58:41 -0400 |
commit | fea3ea1f23fb7f72aad28a55a09a60897a08dd3d (patch) | |
tree | 016e1c7e1fa05979c7d76b6caa200c07d36445df | |
parent | 8db2e820c96a0ce33d3c15f476aa78bebce2c732 (diff) | |
download | postgresql-fea3ea1f23fb7f72aad28a55a09a60897a08dd3d.tar.gz postgresql-fea3ea1f23fb7f72aad28a55a09a60897a08dd3d.zip |
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.
-rw-r--r-- | src/backend/utils/adt/date.c | 5 | ||||
-rw-r--r-- | src/backend/utils/adt/datetime.c | 6 | ||||
-rw-r--r-- | src/include/utils/timestamp.h | 10 |
3 files changed, 14 insertions, 7 deletions
diff --git a/src/backend/utils/adt/date.c b/src/backend/utils/adt/date.c index e737e720f5b..51c6b6bacbf 100644 --- a/src/backend/utils/adt/date.c +++ b/src/backend/utils/adt/date.c @@ -1924,9 +1924,8 @@ timetz_recv(PG_FUNCTION_ARGS) result->zone = pq_getmsgint(buf, sizeof(result->zone)); - /* we allow GMT displacements up to 14:59:59, cf DecodeTimezone() */ - if (result->zone <= -15 * SECS_PER_HOUR || - result->zone >= 15 * SECS_PER_HOUR) + /* Check for sane GMT displacement; see notes in utils/timestamp.h */ + if (result->zone <= -TZDISP_LIMIT || result->zone >= TZDISP_LIMIT) ereport(ERROR, (errcode(ERRCODE_INVALID_TIME_ZONE_DISPLACEMENT_VALUE), errmsg("time zone displacement out of range"))); diff --git a/src/backend/utils/adt/datetime.c b/src/backend/utils/adt/datetime.c index 3d320ccdd58..452eb8532dd 100644 --- a/src/backend/utils/adt/datetime.c +++ b/src/backend/utils/adt/datetime.c @@ -2702,9 +2702,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) @@ -2749,7 +2746,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 >= MINS_PER_HOUR) return DTERR_TZDISP_OVERFLOW; diff --git a/src/include/utils/timestamp.h b/src/include/utils/timestamp.h index 9e51b58dde0..e311a8fb44e 100644 --- a/src/include/utils/timestamp.h +++ b/src/include/utils/timestamp.h @@ -101,6 +101,16 @@ typedef struct #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. * * For Timestamp, we make use of the same support routines as for int64 |