diff options
author | Tom Lane <tgl@sss.pgh.pa.us> | 2023-03-09 16:49:03 -0500 |
---|---|---|
committer | Tom Lane <tgl@sss.pgh.pa.us> | 2023-03-09 16:49:03 -0500 |
commit | bcc704b52490492e6bd73c4444056b3e9644504d (patch) | |
tree | bc9b625207a9752b5728af4bbbeef347fc75c368 /src/backend/utils/adt | |
parent | 27b62377b47f9e7bf58613608bc718c86ea91e91 (diff) | |
download | postgresql-bcc704b52490492e6bd73c4444056b3e9644504d.tar.gz postgresql-bcc704b52490492e6bd73c4444056b3e9644504d.zip |
Reject combining "epoch" and "infinity" with other datetime fields.
Datetime input formerly accepted combinations such as
'1995-08-06 infinity', but this seems like a clear error.
Reject any combination of regular y/m/d/h/m/s fields with
these special tokens.
Joseph Koshakow, reviewed by Keisuke Kuroda and myself
Discussion: https://postgr.es/m/CAAvxfHdm8wwXwG_FFRaJ1nTHiMWb7YXS2YKCzCt8Q0a2ZoMcHg@mail.gmail.com
Diffstat (limited to 'src/backend/utils/adt')
-rw-r--r-- | src/backend/utils/adt/datetime.c | 40 |
1 files changed, 25 insertions, 15 deletions
diff --git a/src/backend/utils/adt/datetime.c b/src/backend/utils/adt/datetime.c index 01660637a24..a7558d39a0e 100644 --- a/src/backend/utils/adt/datetime.c +++ b/src/backend/utils/adt/datetime.c @@ -1431,8 +1431,17 @@ DecodeDateTime(char **field, int *ftype, int nf, *tzp = 0; break; - default: + case DTK_EPOCH: + case DTK_LATE: + case DTK_EARLY: + tmask = (DTK_DATE_M | DTK_TIME_M | DTK_M(TZ)); *dtype = val; + /* caller ignores tm for these dtype codes */ + break; + + default: + elog(ERROR, "unrecognized RESERV datetime token: %d", + val); } break; @@ -1567,22 +1576,23 @@ DecodeDateTime(char **field, int *ftype, int nf, fmask |= tmask; } /* end loop over fields */ - /* do final checking/adjustment of Y/M/D fields */ - dterr = ValidateDate(fmask, isjulian, is2digits, bc, tm); - if (dterr) - return dterr; - - /* handle AM/PM */ - if (mer != HR24 && tm->tm_hour > HOURS_PER_DAY / 2) - return DTERR_FIELD_OVERFLOW; - if (mer == AM && tm->tm_hour == HOURS_PER_DAY / 2) - tm->tm_hour = 0; - else if (mer == PM && tm->tm_hour != HOURS_PER_DAY / 2) - tm->tm_hour += HOURS_PER_DAY / 2; - - /* do additional checking for full date specs... */ + /* do additional checking for normal date specs (but not "infinity" etc) */ if (*dtype == DTK_DATE) { + /* do final checking/adjustment of Y/M/D fields */ + dterr = ValidateDate(fmask, isjulian, is2digits, bc, tm); + if (dterr) + return dterr; + + /* handle AM/PM */ + if (mer != HR24 && tm->tm_hour > HOURS_PER_DAY / 2) + return DTERR_FIELD_OVERFLOW; + if (mer == AM && tm->tm_hour == HOURS_PER_DAY / 2) + tm->tm_hour = 0; + else if (mer == PM && tm->tm_hour != HOURS_PER_DAY / 2) + tm->tm_hour += HOURS_PER_DAY / 2; + + /* check for incomplete input */ if ((fmask & DTK_DATE_M) != DTK_DATE_M) { if ((fmask & DTK_TIME_M) == DTK_TIME_M) |