scdoc2mdoc

A fork of scdoc to output mdoc(7)
git clone git://git.sgregoratto.me/scdoc2mdoc
Log | Files | Refs | README | LICENSE

commit 599a615cb84799e1a50764ebecb27b459f629a3f
parent 2e2ccda87fda3e5ed890a4a75e2c2ad4e387c960
Author: Silvan Jegen <s.jegen@gmail.com>
Date:   Wed,  2 Jan 2019 01:01:49 +0100

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

Diffstat:
Msrc/main.c | 44+++++++++++++++++++++++++++++++++-----------
1 file changed, 33 insertions(+), 11 deletions(-)

diff --git 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 "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 @@ static void parse_preamble(struct parser *p) { 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); } - strftime(date, sizeof(date), "%F", &source_date_epoch_tm); + 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); + } + 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);