diff options
author | Tom Lane <tgl@sss.pgh.pa.us> | 2022-04-02 16:12:26 -0400 |
---|---|---|
committer | Tom Lane <tgl@sss.pgh.pa.us> | 2022-04-02 16:12:29 -0400 |
commit | e39f9904671082c5ad3a2c5acbdbd028fa93bf35 (patch) | |
tree | 6ab9ab1ed3b78bab977b0949e3cfcdb6af9f9cde /src/include/utils | |
parent | f7e4d5c64fb3977e3a773e7213472be1b59dab2f (diff) | |
download | postgresql-e39f9904671082c5ad3a2c5acbdbd028fa93bf35.tar.gz postgresql-e39f9904671082c5ad3a2c5acbdbd028fa93bf35.zip |
Fix overflow hazards in interval input and output conversions.
DecodeInterval (interval input) was careless about integer-overflow
hazards, allowing bogus results to be obtained for sufficiently
large input values. Also, since it initially converted the input
to a "struct tm", it was impossible to produce the full range of
representable interval values.
Meanwhile, EncodeInterval (interval output) and a few other
functions could suffer failures if asked to process sufficiently
large interval values, because they also relied on being able to
represent an interval in "struct tm" which is not designed to
handle that.
Fix all this stuff by introducing new struct types that are more
fit for purpose.
While this is clearly a bug fix, it's also an API break for any
code that's calling these functions directly. So back-patching
doesn't seem wise, especially in view of the lack of field
complaints.
Joe Koshakow, editorialized a bit by me
Discussion: https://postgr.es/m/CAAvxfHff0JLYHwyBrtMx_=6wr=k2Xp+D+-X3vEhHjJYMj+mQcg@mail.gmail.com
Diffstat (limited to 'src/include/utils')
-rw-r--r-- | src/include/utils/datetime.h | 6 | ||||
-rw-r--r-- | src/include/utils/timestamp.h | 5 |
2 files changed, 6 insertions, 5 deletions
diff --git a/src/include/utils/datetime.h b/src/include/utils/datetime.h index 0d158f3e4bb..0801858d601 100644 --- a/src/include/utils/datetime.h +++ b/src/include/utils/datetime.h @@ -300,9 +300,9 @@ extern int DecodeTimeOnly(char **field, int *ftype, int nf, int *dtype, struct pg_tm *tm, fsec_t *fsec, int *tzp); extern int DecodeInterval(char **field, int *ftype, int nf, int range, - int *dtype, struct pg_tm *tm, fsec_t *fsec); + int *dtype, struct pg_itm_in *itm_in); extern int DecodeISO8601Interval(char *str, - int *dtype, struct pg_tm *tm, fsec_t *fsec); + int *dtype, struct pg_itm_in *itm_in); extern void DateTimeParseError(int dterr, const char *str, const char *datatype) pg_attribute_noreturn(); @@ -315,7 +315,7 @@ extern int DetermineTimeZoneAbbrevOffsetTS(TimestampTz ts, const char *abbr, extern void EncodeDateOnly(struct pg_tm *tm, int style, char *str); extern void EncodeTimeOnly(struct pg_tm *tm, fsec_t fsec, bool print_tz, int tz, int style, char *str); extern void EncodeDateTime(struct pg_tm *tm, fsec_t fsec, bool print_tz, int tz, const char *tzn, int style, char *str); -extern void EncodeInterval(struct pg_tm *tm, fsec_t fsec, int style, char *str); +extern void EncodeInterval(struct pg_itm *itm, int style, char *str); extern void EncodeSpecialTimestamp(Timestamp dt, char *str); extern int ValidateDate(int fmask, bool isjulian, bool is2digits, bool bc, diff --git a/src/include/utils/timestamp.h b/src/include/utils/timestamp.h index c1a74f8e2b0..d33421d3809 100644 --- a/src/include/utils/timestamp.h +++ b/src/include/utils/timestamp.h @@ -88,8 +88,9 @@ extern int timestamp2tm(Timestamp dt, int *tzp, struct pg_tm *tm, fsec_t *fsec, const char **tzn, pg_tz *attimezone); extern void dt2time(Timestamp dt, int *hour, int *min, int *sec, fsec_t *fsec); -extern int interval2tm(Interval span, struct pg_tm *tm, fsec_t *fsec); -extern int tm2interval(struct pg_tm *tm, fsec_t fsec, Interval *span); +extern void interval2itm(Interval span, struct pg_itm *itm); +extern int itm2interval(struct pg_itm *itm, Interval *span); +extern int itmin2interval(struct pg_itm_in *itm_in, Interval *span); extern Timestamp SetEpochTimestamp(void); extern void GetEpochTime(struct pg_tm *tm); |