From 649a1252b7b95a73858e5d593fcbce3c4f86185d Mon Sep 17 00:00:00 2001
From: Michael Meskes <meskes@postgresql.org>
Date: Wed, 4 Feb 2009 08:51:10 +0000
Subject: [PATCH] Added result checks for calls to gmtime().

---
 src/interfaces/ecpg/pgtypeslib/datetime.c  | 11 +++--
 src/interfaces/ecpg/pgtypeslib/dt.h        |  4 +-
 src/interfaces/ecpg/pgtypeslib/dt_common.c | 48 +++++++++++++++-------
 src/interfaces/ecpg/pgtypeslib/timestamp.c | 14 +++++--
 4 files changed, 54 insertions(+), 23 deletions(-)

diff --git a/src/interfaces/ecpg/pgtypeslib/datetime.c b/src/interfaces/ecpg/pgtypeslib/datetime.c
index 3910859d348..9dc900e9b25 100644
--- a/src/interfaces/ecpg/pgtypeslib/datetime.c
+++ b/src/interfaces/ecpg/pgtypeslib/datetime.c
@@ -1,4 +1,4 @@
-/* $PostgreSQL: pgsql/src/interfaces/ecpg/pgtypeslib/datetime.c,v 1.34 2007/11/15 21:14:45 momjian Exp $ */
+/* $PostgreSQL: pgsql/src/interfaces/ecpg/pgtypeslib/datetime.c,v 1.35 2009/02/04 08:51:09 meskes Exp $ */
 
 #include "postgres_fe.h"
 
@@ -87,7 +87,11 @@ PGTYPESdate_from_asc(char *str, char **endptr)
 			break;
 
 		case DTK_EPOCH:
-			GetEpochTime(tm);
+			if (GetEpochTime(tm) < 0)
+			{
+				errno = PGTYPES_DATE_BAD_DATE;
+				return INT_MIN;
+			}
 			break;
 
 		default:
@@ -153,7 +157,8 @@ PGTYPESdate_today(date * d)
 	struct tm	ts;
 
 	GetCurrentDateTime(&ts);
-	*d = date2j(ts.tm_year, ts.tm_mon, ts.tm_mday) - date2j(2000, 1, 1);
+	if (errno == 0)
+		*d = date2j(ts.tm_year, ts.tm_mon, ts.tm_mday) - date2j(2000, 1, 1);
 	return;
 }
 
diff --git a/src/interfaces/ecpg/pgtypeslib/dt.h b/src/interfaces/ecpg/pgtypeslib/dt.h
index 0008211fad0..ac0b1369029 100644
--- a/src/interfaces/ecpg/pgtypeslib/dt.h
+++ b/src/interfaces/ecpg/pgtypeslib/dt.h
@@ -1,4 +1,4 @@
-/* $PostgreSQL: pgsql/src/interfaces/ecpg/pgtypeslib/dt.h,v 1.40 2008/11/26 16:31:02 meskes Exp $ */
+/* $PostgreSQL: pgsql/src/interfaces/ecpg/pgtypeslib/dt.h,v 1.41 2009/02/04 08:51:09 meskes Exp $ */
 
 #ifndef DT_H
 #define DT_H
@@ -342,7 +342,7 @@ int			tm2timestamp(struct tm *, fsec_t, int *, timestamp *);
 int			DecodeUnits(int field, char *lowtoken, int *val);
 bool		CheckDateTokenTables(void);
 int			EncodeDateOnly(struct tm *, int, char *, bool);
-void		GetEpochTime(struct tm *);
+int		GetEpochTime(struct tm *);
 int			ParseDateTime(char *, char *, char **, int *, int, int *, char **);
 int			DecodeDateTime(char **, int *, int, int *, struct tm *, fsec_t *, bool);
 void		j2date(int, int *, int *, int *);
diff --git a/src/interfaces/ecpg/pgtypeslib/dt_common.c b/src/interfaces/ecpg/pgtypeslib/dt_common.c
index d3e5396dc41..dc3ef05826f 100644
--- a/src/interfaces/ecpg/pgtypeslib/dt_common.c
+++ b/src/interfaces/ecpg/pgtypeslib/dt_common.c
@@ -1,4 +1,4 @@
-/* $PostgreSQL: pgsql/src/interfaces/ecpg/pgtypeslib/dt_common.c,v 1.45 2009/02/02 15:35:28 meskes Exp $ */
+/* $PostgreSQL: pgsql/src/interfaces/ecpg/pgtypeslib/dt_common.c,v 1.46 2009/02/04 08:51:09 meskes Exp $ */
 
 #include "postgres_fe.h"
 
@@ -982,7 +982,7 @@ EncodeDateTime(struct tm * tm, fsec_t fsec, int *tzp, char **tzn, int style, cha
 	return TRUE;
 }	/* EncodeDateTime() */
 
-void
+int
 GetEpochTime(struct tm * tm)
 {
 	struct tm  *t0;
@@ -990,14 +990,19 @@ GetEpochTime(struct tm * tm)
 
 	t0 = gmtime(&epoch);
 
-	tm->tm_year = t0->tm_year + 1900;
-	tm->tm_mon = t0->tm_mon + 1;
-	tm->tm_mday = t0->tm_mday;
-	tm->tm_hour = t0->tm_hour;
-	tm->tm_min = t0->tm_min;
-	tm->tm_sec = t0->tm_sec;
+	if (t0)
+	{
+		tm->tm_year = t0->tm_year + 1900;
+		tm->tm_mon = t0->tm_mon + 1;
+		tm->tm_mday = t0->tm_mday;
+		tm->tm_hour = t0->tm_hour;
+		tm->tm_min = t0->tm_min;
+		tm->tm_sec = t0->tm_sec;
+
+		return 0;
+	}
 
-	return;
+	return -1;
 }	/* GetEpochTime() */
 
 static void
@@ -1006,11 +1011,18 @@ abstime2tm(AbsoluteTime _time, int *tzp, struct tm * tm, char **tzn)
 	time_t		time = (time_t) _time;
 	struct tm  *tx;
 
+	errno = 0;
 	if (tzp != NULL)
 		tx = localtime((time_t *) &time);
 	else
 		tx = gmtime((time_t *) &time);
 
+	if (!tx)
+	{
+		errno = PGTYPES_TS_BAD_TIMESTAMP;
+		return;
+	}
+
 	tm->tm_year = tx->tm_year + 1900;
 	tm->tm_mon = tx->tm_mon + 1;
 	tm->tm_mday = tx->tm_mday;
@@ -2852,12 +2864,18 @@ PGTYPEStimestamp_defmt_scan(char **str, char *fmt, timestamp * d,
 					time_t		et = (time_t) scan_val.luint_val;
 
 					tms = gmtime(&et);
-					*year = tms->tm_year + 1900;
-					*month = tms->tm_mon + 1;
-					*day = tms->tm_mday;
-					*hour = tms->tm_hour;
-					*minute = tms->tm_min;
-					*second = tms->tm_sec;
+
+					if (tms)
+					{
+						*year = tms->tm_year + 1900;
+						*month = tms->tm_mon + 1;
+						*day = tms->tm_mday;
+						*hour = tms->tm_hour;
+						*minute = tms->tm_min;
+						*second = tms->tm_sec;
+					}
+					else
+						err = 1;
 				}
 				break;
 			case 'S':
diff --git a/src/interfaces/ecpg/pgtypeslib/timestamp.c b/src/interfaces/ecpg/pgtypeslib/timestamp.c
index 74995b5ca2a..e4ff8b664ec 100644
--- a/src/interfaces/ecpg/pgtypeslib/timestamp.c
+++ b/src/interfaces/ecpg/pgtypeslib/timestamp.c
@@ -1,5 +1,5 @@
 /*
- * $PostgreSQL: pgsql/src/interfaces/ecpg/pgtypeslib/timestamp.c,v 1.42 2008/05/17 01:28:25 adunstan Exp $ 
+ * $PostgreSQL: pgsql/src/interfaces/ecpg/pgtypeslib/timestamp.c,v 1.43 2009/02/04 08:51:10 meskes Exp $ 
  */
 #include "postgres_fe.h"
 
@@ -91,11 +91,18 @@ tm2timestamp(struct tm * tm, fsec_t fsec, int *tzp, timestamp * result)
 static timestamp
 SetEpochTimestamp(void)
 {
+#ifdef HAVE_INT64_TIMESTAMP
+	int64		noresult = 0;
+#else
+	double		noresult = 0.0;
+#endif
 	timestamp	dt;
 	struct tm	tt,
 			   *tm = &tt;
 
-	GetEpochTime(tm);
+	if (GetEpochTime(tm) < 0)
+		return noresult;
+
 	tm2timestamp(tm, 0, NULL, &dt);
 	return dt;
 }	/* SetEpochTimestamp() */
@@ -372,7 +379,8 @@ PGTYPEStimestamp_current(timestamp * ts)
 	struct tm	tm;
 
 	GetCurrentDateTime(&tm);
-	tm2timestamp(&tm, 0, NULL, ts);
+	if (errno == 0)
+		tm2timestamp(&tm, 0, NULL, ts);
 	return;
 }
 
-- 
GitLab