From 599a615cb84799e1a50764ebecb27b459f629a3f Mon Sep 17 00:00:00 2001
From: Silvan Jegen <s.jegen@gmail.com>
Date: Wed, 02 Jan 2019 01:01:49 +0100
Subject: [PATCH] Don't use a GNU-extension for $SOURCE_DATE_EPOCH parsing

Code gratefully copied from the link below.

https://reproducible-builds.org/docs/source-date-epoch/#c

---
 src/main.c | 44 +++++++++++++++++++++++++++++++++-----------

diff --git a/src/main.c b/src/main.c
index 645d52115a8c6a68b9b8a99ed69ab0082be96f49..eab674ee0681cf85441d02c452d0a62d8425c5d1 100644
--- a/src/main.c
+++ b/src/main.c
@@ -1,6 +1,8 @@
 #define _XOPEN_SOURCE 600
 #include <assert.h>
 #include <ctype.h>
+#include <errno.h>
+#include <limits.h>
 #include <stdbool.h>
 #include <stdio.h>
 #include <stdlib.h>
@@ -11,6 +13,7 @@ #include "unicode.h"
 #include "util.h"
 
 char *strstr(const char *haystack, const char *needle);
+char *strerror(int errnum);
 
 static int parse_section(struct parser *p) {
 	str_t *section = str_create();
@@ -67,23 +70,42 @@ 	int ex = 0;
 	str_t *extras[2] = { NULL };
 	int section = -1;
 	uint32_t ch;
+	time_t date_time;
 	char date[256];
 	char *source_date_epoch = getenv("SOURCE_DATE_EPOCH");
 	if (source_date_epoch != NULL) {
-		struct tm source_date_epoch_tm;
-		char *ret = strptime(source_date_epoch, "%s", &source_date_epoch_tm);
-		if (ret == NULL || *ret != '\0') {
-			fprintf(stderr,
-					"Error: $SOURCE_DATE_EPOCH is set but malformed.\n");
-			exit(1);
+		unsigned long long epoch;
+		char *endptr;
+		errno = 0;
+		epoch = strtoull(source_date_epoch, &endptr, 10);
+		if ((errno == ERANGE && (epoch == ULLONG_MAX || epoch == 0))
+				|| (errno != 0 && epoch == 0)) {
+			fprintf(stderr, "$SOURCE_DATE_EPOCH: strtoull: %s\n",
+					strerror(errno));
+			exit(EXIT_FAILURE);
+		}
+		if (endptr == source_date_epoch) {
+			fprintf(stderr, "$SOURCE_DATE_EPOCH: No digits were found: %s\n",
+					endptr);
+			exit(EXIT_FAILURE);
+		}
+		if (*endptr != '\0') {
+			fprintf(stderr, "$SOURCE_DATE_EPOCH: Trailing garbage: %s\n",
+					endptr);
+			exit(EXIT_FAILURE);
+		}
+		if (epoch > ULONG_MAX) {
+			fprintf(stderr, "$SOURCE_DATE_EPOCH: value must be smaller than or "
+					"equal to %lu but was found to be: %llu \n",
+					ULONG_MAX, epoch);
+			exit(EXIT_FAILURE);
 		}
-		strftime(date, sizeof(date), "%F", &source_date_epoch_tm);
+		date_time = epoch;
 	} else {
-		time_t now;
-		time(&now);
-		struct tm *now_tm = localtime(&now);
-		strftime(date, sizeof(date), "%F", now_tm);
+		date_time = time(NULL);
 	}
+	struct tm *date_tm = localtime(&date_time);
+	strftime(date, sizeof(date), "%F", date_tm);
 	while ((ch = parser_getch(p)) != UTF8_INVALID) {
 		if ((ch < 0x80 && isalnum(ch)) || ch == '_' || ch == '-' || ch == '.') {
 			int ret = str_append_ch(name, ch);

-- 
2.48.1