diff options
author | Thomas Deutschmann <whissi@gentoo.org> | 2015-07-30 11:59:03 +0200 |
---|---|---|
committer | Sam James <sam@gentoo.org> | 2022-04-17 13:16:23 +0100 |
commit | 7108e0142406c63db9469b65cfe0767109568156 (patch) | |
tree | 1d0f241d5f177d0b1b388c25253c2d643be8a09f | |
parent | Make sure 'dvipdf' is being run securely (diff) | |
download | ghostscript-gpl-patches-7108e0142406c63db9469b65cfe0767109568156.tar.gz ghostscript-gpl-patches-7108e0142406c63db9469b65cfe0767109568156.tar.bz2 ghostscript-gpl-patches-7108e0142406c63db9469b65cfe0767109568156.zip |
Allow the build timestamp to be externally set
In order to make Ghostscript output reproducible, we need a way to
set the build timestamp to other values than the current time.
We now consistently use gp_get_realtime() instead of directly calling
time() or gp_get_usertime() and make gp_get_realtime() use the value
found in the SOURCE_DATE_EPOCH environment variable if set. Also,
environment timezone is fixed to UTC if SOURCE_DATE_EPOCH is used to
avoid variations.
Origin: https://salsa.debian.org/printing-team/ghostscript/-/blob/e4280f77c6f710a8b98ebe41e564e5fef9d23964/debian/patches/2010_add_build_timestamp_setting.patch
Signed-off-by: Thomas Deutschmann <whissi@gentoo.org>
Signed-off-by: Sam James <sam@gentoo.org>
-rw-r--r-- | base/gp_unix.c | 22 | ||||
-rw-r--r-- | devices/vector/gdevpdf.c | 4 | ||||
-rw-r--r-- | devices/vector/gdevpdfe.c | 4 | ||||
-rw-r--r-- | devices/vector/gdevpsu.c | 4 |
4 files changed, 31 insertions, 3 deletions
diff --git a/base/gp_unix.c b/base/gp_unix.c index 98db2ddf..8eee6a89 100644 --- a/base/gp_unix.c +++ b/base/gp_unix.c @@ -19,6 +19,7 @@ #ifdef __MINGW32__ # include "windows_.h" #endif +#include "errno_.h" #include "pipe_.h" #include "string_.h" #include "time_.h" @@ -148,6 +149,7 @@ void gp_get_realtime(long *pdt) { struct timeval tp; + const char *env; #if gettimeofday_no_timezone /* older versions of SVR4 */ { @@ -167,6 +169,26 @@ gp_get_realtime(long *pdt) } #endif + env = getenv("SOURCE_DATE_EPOCH"); + if (env) { + char *end; + long timestamp; + + errno = 0; + timestamp = strtol(env, &end, 10); + if (env == end || *end || errno != 0) { + lprintf("Ghostscript: SOURCE_DATE_EPOCH is not a number!\n"); + timestamp = 0; + } + + tp.tv_sec = timestamp; + tp.tv_usec = 0; + + /* We need to fix the environment timezone to get reproducible */ + /* results when parsing the result of gp_get_realtime. */ + setenv("TZ", "UTC", 1); + } + /* tp.tv_sec is #secs since Jan 1, 1970 */ pdt[0] = tp.tv_sec; diff --git a/devices/vector/gdevpdf.c b/devices/vector/gdevpdf.c index cb268f62..ef581dc0 100644 --- a/devices/vector/gdevpdf.c +++ b/devices/vector/gdevpdf.c @@ -427,6 +427,7 @@ pdf_initialize_ids(gx_device_pdf * pdev) */ { struct tm tms; + long secs_ns[2]; time_t t; char buf[1+2+4+2+2+2+2+2+1+2+1+2+1+1+1]; /* (D:yyyymmddhhmmssZhh'mm')\0 */ int timeoffset; @@ -438,7 +439,8 @@ pdf_initialize_ids(gx_device_pdf * pdev) timesign = 'Z'; timeoffset = 0; #else - time(&t); + gp_get_realtime(secs_ns); + t = secs_ns[0]; tms = *gmtime(&t); tms.tm_isdst = -1; timeoffset = (int)difftime(t, mktime(&tms)); /* tz+dst in seconds */ diff --git a/devices/vector/gdevpdfe.c b/devices/vector/gdevpdfe.c index ec011d8b..b54ad840 100644 --- a/devices/vector/gdevpdfe.c +++ b/devices/vector/gdevpdfe.c @@ -199,6 +199,7 @@ pdf_xmp_time(char *buf, int buf_length) { /* We don't write a day time because we don't have a time zone. */ struct tm tms; + long secs_ns[2]; time_t t; char buf1[4+1+2+1+2+1]; /* yyyy-mm-dd\0 */ @@ -206,7 +207,8 @@ pdf_xmp_time(char *buf, int buf_length) memset(&t, 0, sizeof(t)); memset(&tms, 0, sizeof(tms)); #else - time(&t); + gp_get_realtime(secs_ns); + t = secs_ns[0]; tms = *localtime(&t); #endif gs_snprintf(buf1, sizeof(buf1), diff --git a/devices/vector/gdevpsu.c b/devices/vector/gdevpsu.c index 83b8bdbb..4868246c 100644 --- a/devices/vector/gdevpsu.c +++ b/devices/vector/gdevpsu.c @@ -183,6 +183,7 @@ psw_begin_file_header(gp_file *f, const gx_device *dev, const gs_rect *pbbox, fprintf(f, "%%%%Creator: %s %ld (%s)\n", gs_product, (long)gs_revision, dev->dname); { + long secs_ns[2]; time_t t; struct tm tms; @@ -190,7 +191,8 @@ psw_begin_file_header(gp_file *f, const gx_device *dev, const gs_rect *pbbox, memset(&t, 0, sizeof(t)); memset(&tms, 0, sizeof(tms)); #else - time(&t); + gp_get_realtime(secs_ns); + t = secs_ns[0]; tms = *localtime(&t); #endif fprintf(f, "%%%%CreationDate: %d/%02d/%02d %02d:%02d:%02d\n", |