aboutsummaryrefslogtreecommitdiff
path: root/src/include/utils
diff options
context:
space:
mode:
authorTom Lane <tgl@sss.pgh.pa.us>2022-04-02 16:12:26 -0400
committerTom Lane <tgl@sss.pgh.pa.us>2022-04-02 16:12:29 -0400
commite39f9904671082c5ad3a2c5acbdbd028fa93bf35 (patch)
tree6ab9ab1ed3b78bab977b0949e3cfcdb6af9f9cde /src/include/utils
parentf7e4d5c64fb3977e3a773e7213472be1b59dab2f (diff)
downloadpostgresql-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.h6
-rw-r--r--src/include/utils/timestamp.h5
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);