Zero out all of struct tm before passing it to strptime

Hrvoje Niksic <[email protected]> Thu, 05 May 2005 23:48:30 +0200
Newsgroups gmane.comp.web.wget.patches
Message-ID <[email protected]>
Reading Solaris's strptime man page got me thinking about this.  Since
strptime uses existing data in struct tm, we need to zero it out so it
doesn't produce bogus values.  (Solaris strptime started doing this,
apparently because programmers didn't understand how strptime is
supposed to be used.)

Another thing that crossed my mind is that it needs to be zeroed out
every time *between* different calls to strptime, some of which may be
half-finished.


2005-05-05  Hrvoje Niksic  <[email protected]>

	* http.c (http_atotm): Zero out the whole struct tm being passed
	to strptime.

Index: src/http.c
===================================================================
RCS file: /pack/anoncvs/wget/src/http.c,v
retrieving revision 1.174
diff -u -r1.174 http.c
--- src/http.c	2005/05/03 15:24:29	1.174
+++ src/http.c	2005/05/05 21:46:02
@@ -2633,30 +2633,30 @@
 				   (google.com uses this for their cookies.) */
     "%a %b %d %T %Y"		/* asctime: Thu Jan 29 22:12:57 1998 */
   };
-
   int i;
-  struct tm t;
-
-  /* According to Roger Beeman, we need to initialize tm_isdst, since
-     strptime won't do it.  */
-  t.tm_isdst = 0;
-
-  /* Note that under foreign locales Solaris strptime() fails to
-     recognize English dates, which renders this function useless.  We
-     solve this by being careful not to affect LC_TIME when
-     initializing locale.
 
-     Another solution would be to temporarily set locale to C, invoke
-     strptime(), and restore it back.  This is slow and dirty,
-     however, and locale support other than LC_MESSAGES can mess other
-     things, so I rather chose to stick with just setting LC_MESSAGES.
-
-     GNU strptime does not have this problem because it recognizes
-     both international and local dates.  */
-
   for (i = 0; i < countof (time_formats); i++)
-    if (check_end (strptime (time_string, time_formats[i], &t)))
-      return mktime_from_utc (&t);
+    {
+      struct tm t;
+
+      /* Some versions of strptime use the existing contents of struct
+	 tm to recalculate the date according to format.  Zero it out
+	 to prevent garbage from the stack influencing strptime.  */
+      xzero (t);
+
+      /* Note that under non-English locales Solaris strptime() fails
+	 to recognize English dates, which renders it useless for this
+	 purpose.  We solve this by not setting LC_TIME when
+	 initializing locale.  Another solution would be to
+	 temporarily set locale to C, invoke strptime(), and restore
+	 it back, but that is somewhat slow and dirty.
+
+	 GNU strptime does not have this problem because it recognizes
+	 both international and local dates.  */
+
+      if (check_end (strptime (time_string, time_formats[i], &t)))
+	return mktime_from_utc (&t);
+    }
 
   /* All formats have failed.  */
   return -1;