Commit 09867e481449ff3ca17bfc7132da42e839319511

Stefan Sperling 2019-08-13T17:01:23

properly parse timestamps in commit objects as UTC (patch by Hiltjo Posthuma)

diff --git a/got/got.c b/got/got.c
index 8c1f0a2..0ebd0d6 100644
--- a/got/got.c
+++ b/got/got.c
@@ -1361,7 +1361,15 @@ done:
 static char *
 get_datestr(time_t *time, char *datebuf)
 {
-	char *p, *s = ctime_r(time, datebuf);
+	struct tm mytm, *tm;
+	char *p, *s;
+
+	tm = gmtime_r(time, &mytm);
+	if (tm == NULL)
+		return NULL;
+	s = asctime_r(tm, datebuf);
+	if (s == NULL)
+		return NULL;
 	p = strchr(s, '\n');
 	if (p)
 		*p = '\0';
@@ -1439,7 +1447,8 @@ print_commit(struct got_commit_object *commit, struct got_object_id *id,
 	printf("from: %s\n", got_object_commit_get_author(commit));
 	committer_time = got_object_commit_get_committer_time(commit);
 	datestr = get_datestr(&committer_time, datebuf);
-	printf("date: %s UTC\n", datestr);
+	if (datestr)
+		printf("date: %s UTC\n", datestr);
 	author = got_object_commit_get_author(commit);
 	committer = got_object_commit_get_committer(commit);
 	if (strcmp(author, committer) != 0)
diff --git a/lib/object_parse.c b/lib/object_parse.c
index 3a47585..bf2e9f2 100644
--- a/lib/object_parse.c
+++ b/lib/object_parse.c
@@ -338,14 +338,11 @@ parse_commit_time(time_t *time, time_t *gmtoff, char *committer)
 	if (space == NULL)
 		return got_error(GOT_ERR_BAD_OBJ_DATA);
 
-	/* Timestamp parsed here is expressed in comitter's local time. */
+	/* Timestamp parsed here is expressed as UNIX timestamp (UTC). */
 	*time = strtonum(space + 1, 0, INT64_MAX, &errstr);
 	if (errstr)
 		return got_error(GOT_ERR_BAD_OBJ_DATA);
 
-	/* Express the time stamp in UTC. */
-	*time -= *gmtoff;
-
 	/* Strip off parsed time information, leaving just author and email. */
 	*space = '\0';
 
diff --git a/tog/tog.c b/tog/tog.c
index 0119a32..6f4b607 100644
--- a/tog/tog.c
+++ b/tog/tog.c
@@ -2432,7 +2432,15 @@ draw_file(struct tog_view *view, FILE *f, int *first_displayed_line,
 static char *
 get_datestr(time_t *time, char *datebuf)
 {
-	char *p, *s = ctime_r(time, datebuf);
+	struct tm mytm, *tm;
+	char *p, *s;
+
+	tm = gmtime_r(time, &mytm);
+	if (tm == NULL)
+		return NULL;
+	s = asctime_r(tm, datebuf);
+	if (s == NULL)
+		return NULL;
 	p = strchr(s, '\n');
 	if (p)
 		*p = '\0';
@@ -2444,7 +2452,7 @@ write_commit_info(struct got_object_id *commit_id,
     struct got_reflist_head *refs, struct got_repository *repo, FILE *outfile)
 {
 	const struct got_error *err = NULL;
-	char datebuf[26];
+	char datebuf[26], *datestr;
 	struct got_commit_object *commit;
 	char *id_str = NULL, *logmsg = NULL;
 	time_t committer_time;
@@ -2478,8 +2486,8 @@ write_commit_info(struct got_object_id *commit_id,
 		goto done;
 	}
 	committer_time = got_object_commit_get_committer_time(commit);
-	if (fprintf(outfile, "date: %s UTC\n",
-	    get_datestr(&committer_time, datebuf)) < 0) {
+	datestr = get_datestr(&committer_time, datebuf);
+	if (datestr && fprintf(outfile, "date: %s UTC\n", datestr) < 0) {
 		err = got_error_from_errno("fprintf");
 		goto done;
 	}