Module Name:    src
Committed By:   christos
Date:           Tue Oct 14 20:35:40 UTC 2014

Modified Files:
        src/lib/libc/time: localtime.c

Log Message:
improve error checking (setting errno)


To generate a diff of this commit:
cvs rdiff -u -r1.87 -r1.88 src/lib/libc/time/localtime.c

Please note that diffs are not public domain; they are subject to the
copyright notices on the relevant files.

Modified files:

Index: src/lib/libc/time/localtime.c
diff -u src/lib/libc/time/localtime.c:1.87 src/lib/libc/time/localtime.c:1.88
--- src/lib/libc/time/localtime.c:1.87	Tue Oct  7 17:51:03 2014
+++ src/lib/libc/time/localtime.c	Tue Oct 14 16:35:40 2014
@@ -1,4 +1,4 @@
-/*	$NetBSD: localtime.c,v 1.87 2014/10/07 21:51:03 christos Exp $	*/
+/*	$NetBSD: localtime.c,v 1.88 2014/10/14 20:35:40 christos Exp $	*/
 
 /*
 ** This file is in the public domain, so clarified as of
@@ -10,7 +10,7 @@
 #if 0
 static char	elsieid[] = "@(#)localtime.c	8.17";
 #else
-__RCSID("$NetBSD: localtime.c,v 1.87 2014/10/07 21:51:03 christos Exp $");
+__RCSID("$NetBSD: localtime.c,v 1.88 2014/10/14 20:35:40 christos Exp $");
 #endif
 #endif /* LIBC_SCCS and not lint */
 
@@ -250,6 +250,7 @@ tzgetname(const timezone_t sp, int isdst
 		if (ttisp->tt_isdst == isdst)
 			return &sp->chars[ttisp->tt_abbrind];
 	}
+	errno = ESRCH;
 	return NULL;
 }
 
@@ -1353,8 +1354,10 @@ localsub(struct state const *sp, time_t 
 				newt += seconds;
 			else	newt -= seconds;
 			if (newt < sp->ats[0] ||
-				newt > sp->ats[sp->timecnt - 1])
-					return NULL;	/* "cannot happen" */
+				newt > sp->ats[sp->timecnt - 1]) {
+				errno = EINVAL;
+				return NULL;	/* "cannot happen" */
+			}
 			result = localsub(sp, &newt, offset, tmp);
 			if (result) {
 				int_fast64_t newy;
@@ -1363,8 +1366,10 @@ localsub(struct state const *sp, time_t 
 				if (t < sp->ats[0])
 					newy -= years;
 				else	newy += years;
-				if (! (INT_MIN <= newy && newy <= INT_MAX))
+				if (! (INT_MIN <= newy && newy <= INT_MAX)) {
+					errno = EOVERFLOW;
 					return NULL;
+				}
 				result->tm_year = (int)newy;
 			}
 			return result;
@@ -1398,7 +1403,7 @@ localsub(struct state const *sp, time_t 
 			tzname[result->tm_isdst] =
 			    __UNCONST(&sp->chars[ttisp->tt_abbrind]);
 #ifdef TM_ZONE
-		tmp->TM_ZONE = __UNCONST(&sp->chars[ttisp->tt_abbrind]);
+		result->TM_ZONE = __UNCONST(&sp->chars[ttisp->tt_abbrind]);
 #endif /* defined TM_ZONE */
 	}
 	return result;
@@ -1456,8 +1461,9 @@ gmtsub(struct state const *sp, const tim
 	** "UT+xxxx" or "UT-xxxx" if offset is non-zero,
 	** but this is no time for a treasure hunt.
 	*/
-	tmp->TM_ZONE = offset ? __UNCONST(wildabbr) : gmtptr ? gmtptr->chars :
-	    __UNCONST(gmt);
+	if (result)
+		result->TM_ZONE = offset ? __UNCONST(wildabbr) : gmtptr ?
+		    gmtptr->chars : __UNCONST(gmt);
 #endif /* defined TM_ZONE */
 	return result;
 }
@@ -1575,14 +1581,14 @@ timesub(time_t const *timep, int_fast32_
 		tdelta = tdays / DAYSPERLYEAR;
 		if (! ((! TYPE_SIGNED(time_t) || INT_MIN <= tdelta)
 		       && tdelta <= INT_MAX))
-			return NULL;
+		       goto overflow;
 		_DIAGASSERT(__type_fit(int, tdelta));
 		idelta = (int)tdelta;
 		if (idelta == 0)
 			idelta = (tdays < 0) ? -1 : 1;
 		newy = y;
 		if (increment_overflow(&newy, idelta))
-			return NULL;
+			goto overflow;
 		leapdays = leaps_thru_end_of(newy - 1) -
 			leaps_thru_end_of(y - 1);
 		tdays -= ((time_t) newy - y) * DAYSPERNYEAR;
@@ -1611,13 +1617,13 @@ timesub(time_t const *timep, int_fast32_
 	}
 	while (idays < 0) {
 		if (increment_overflow(&y, -1))
-			return NULL;
+			goto overflow;
 		idays += year_lengths[isleap(y)];
 	}
 	while (idays >= year_lengths[isleap(y)]) {
 		idays -= year_lengths[isleap(y)];
 		if (increment_overflow(&y, 1))
-			return NULL;
+			goto overflow;
 	}
 	tmp->tm_year = y;
 	if (increment_overflow(&tmp->tm_year, -TM_YEAR_BASE))
@@ -1652,6 +1658,9 @@ timesub(time_t const *timep, int_fast32_
 	tmp->TM_GMTOFF = offset;
 #endif /* defined TM_GMTOFF */
 	return tmp;
+overflow:
+	errno = EOVERFLOW;
+	return NULL;
 }
 
 char *
@@ -2131,7 +2140,6 @@ static time_t
 mktime_tzname(timezone_t sp, struct tm *tmp, bool setname)
 {
 	if (sp)
-/*###2133 [lint] warning argument has incompatible pointer type, arg #2 (pointer to function != pointer to function) [153]%%%*/
 		return time1(tmp, localsub, sp, setname);
 	else {
 		gmtcheck();

Reply via email to