diff options
Diffstat (limited to 'src/interfaces')
| -rw-r--r-- | src/interfaces/ecpg/pgtypeslib/dt.h | 28 | ||||
| -rw-r--r-- | src/interfaces/ecpg/pgtypeslib/timestamp.c | 6 |
2 files changed, 24 insertions, 10 deletions
diff --git a/src/interfaces/ecpg/pgtypeslib/dt.h b/src/interfaces/ecpg/pgtypeslib/dt.h index 145e2b7c4fb..c0c3ac19016 100644 --- a/src/interfaces/ecpg/pgtypeslib/dt.h +++ b/src/interfaces/ecpg/pgtypeslib/dt.h @@ -287,22 +287,32 @@ do { \ */ #define isleap(y) (((y) % 4) == 0 && (((y) % 100) != 0 || ((y) % 400) == 0)) -/* Julian date support for date2j() and j2date() - * - * IS_VALID_JULIAN checks the minimum date exactly, but is a bit sloppy - * about the maximum, since it's far enough out to not be especially - * interesting. +/* + * Julian date support --- see comments in backend's timestamp.h. */ #define JULIAN_MINYEAR (-4713) #define JULIAN_MINMONTH (11) #define JULIAN_MINDAY (24) #define JULIAN_MAXYEAR (5874898) +#define JULIAN_MAXMONTH (6) +#define JULIAN_MAXDAY (3) + +#define IS_VALID_JULIAN(y,m,d) \ + (((y) > JULIAN_MINYEAR || \ + ((y) == JULIAN_MINYEAR && ((m) >= JULIAN_MINMONTH))) && \ + ((y) < JULIAN_MAXYEAR || \ + ((y) == JULIAN_MAXYEAR && ((m) < JULIAN_MAXMONTH)))) + +#ifdef HAVE_INT64_TIMESTAMP +#define MIN_TIMESTAMP INT64CONST(-211813488000000000) +#define END_TIMESTAMP INT64CONST(9223371331200000000) +#else +#define MIN_TIMESTAMP (-211813488000.0) +#define END_TIMESTAMP 185330760393600.0 +#endif -#define IS_VALID_JULIAN(y,m,d) ((((y) > JULIAN_MINYEAR) \ - || (((y) == JULIAN_MINYEAR) && (((m) > JULIAN_MINMONTH) \ - || (((m) == JULIAN_MINMONTH) && ((d) >= JULIAN_MINDAY))))) \ - && ((y) < JULIAN_MAXYEAR)) +#define IS_VALID_TIMESTAMP(t) (MIN_TIMESTAMP <= (t) && (t) < END_TIMESTAMP) #define UTIME_MINYEAR (1901) #define UTIME_MINMONTH (12) diff --git a/src/interfaces/ecpg/pgtypeslib/timestamp.c b/src/interfaces/ecpg/pgtypeslib/timestamp.c index cf1fed2c00b..f746a90f8b1 100644 --- a/src/interfaces/ecpg/pgtypeslib/timestamp.c +++ b/src/interfaces/ecpg/pgtypeslib/timestamp.c @@ -61,7 +61,7 @@ tm2timestamp(struct tm * tm, fsec_t fsec, int *tzp, timestamp * result) time; #endif - /* Julian day routines are not correct for negative Julian days */ + /* Prevent overflow in Julian-day routines */ if (!IS_VALID_JULIAN(tm->tm_year, tm->tm_mon, tm->tm_mday)) return -1; @@ -83,6 +83,10 @@ tm2timestamp(struct tm * tm, fsec_t fsec, int *tzp, timestamp * result) if (tzp != NULL) *result = dt2local(*result, -(*tzp)); + /* final range check catches just-out-of-range timestamps */ + if (!IS_VALID_TIMESTAMP(*result)) + return -1; + return 0; } /* tm2timestamp() */ |
