From 485e2a4e43458a417603d4ed219af3e79854ef46 Mon Sep 17 00:00:00 2001 From: Arjen de Korte Date: Sat, 2 Jan 2021 17:57:18 +0100 Subject: [PATCH 1/7] phar: honor SOURCE_DATE_EPOCH for timestamps In order to build reproducible phars, honor SOURCE_DATE_EPOCH if set Signed-off-by: Arjen de Korte --- ext/phar/phar.c | 2 +- ext/phar/phar_internal.h | 13 +++++++++++++ ext/phar/stream.c | 2 +- ext/phar/tar.c | 2 +- ext/phar/util.c | 2 +- ext/phar/zip.c | 2 +- 6 files changed, 18 insertions(+), 5 deletions(-) diff --git a/ext/phar/phar.c b/ext/phar/phar.c index 6434a75a75cef..b5d28c8181abe 100644 --- a/ext/phar/phar.c +++ b/ext/phar/phar.c @@ -3002,7 +3002,7 @@ int phar_flush(phar_archive_data *phar, char *user_stub, zend_long len, int conv 4: metadata-len +: metadata */ - mytime = time(NULL); + mytime = source_date_epoch_time(NULL); phar_set_32(entry_buffer, entry->uncompressed_filesize); phar_set_32(entry_buffer+4, mytime); phar_set_32(entry_buffer+8, entry->compressed_filesize); diff --git a/ext/phar/phar_internal.h b/ext/phar/phar_internal.h index f959cb29bc683..de7ba32636172 100644 --- a/ext/phar/phar_internal.h +++ b/ext/phar/phar_internal.h @@ -425,6 +425,19 @@ static inline enum phar_fp_type phar_get_fp_type(phar_entry_info *entry) return PHAR_G(cached_fp)[entry->phar->phar_pos].manifest[entry->manifest_pos].fp_type; } +static inline time_t source_date_epoch_time(time_t *tloc) +{ + const char *sde; + time_t ts; + + sde = getenv("SOURCE_DATE_EPOCH"); + ts = (sde) ? strtol(sde, NULL, 10) : time(0); + if (tloc) { + *tloc = ts; + } + return ts; +} + static inline zend_off_t phar_get_fp_offset(phar_entry_info *entry) { if (!entry->is_persistent) { diff --git a/ext/phar/stream.c b/ext/phar/stream.c index 91ed30cf03eca..15a5fa29a14da 100644 --- a/ext/phar/stream.c +++ b/ext/phar/stream.c @@ -463,7 +463,7 @@ static int phar_stream_flush(php_stream *stream) /* {{{ */ phar_entry_data *data = (phar_entry_data *) stream->abstract; if (data->internal_file->is_modified) { - data->internal_file->timestamp = time(0); + data->internal_file->timestamp = source_date_epoch_time(0); ret = phar_flush(data->phar, 0, 0, 0, &error); if (error) { php_stream_wrapper_log_error(stream->wrapper, REPORT_ERRORS, "%s", error); diff --git a/ext/phar/tar.c b/ext/phar/tar.c index bae1a4bf7b51b..76773e4752d5a 100644 --- a/ext/phar/tar.c +++ b/ext/phar/tar.c @@ -971,7 +971,7 @@ int phar_tar_flush(phar_archive_data *phar, char *user_stub, zend_long len, int char halt_stub[] = "__HALT_COMPILER();"; entry.flags = PHAR_ENT_PERM_DEF_FILE; - entry.timestamp = time(NULL); + entry.timestamp = source_date_epoch_time(NULL); entry.is_modified = 1; entry.is_crc_checked = 1; entry.is_tar = 1; diff --git a/ext/phar/util.c b/ext/phar/util.c index b45251d14a71c..0bb95ea4804b0 100644 --- a/ext/phar/util.c +++ b/ext/phar/util.c @@ -574,7 +574,7 @@ phar_entry_data *phar_get_or_create_entry_data(char *fname, size_t fname_len, ch phar_add_virtual_dirs(phar, path, path_len); etemp.is_modified = 1; - etemp.timestamp = time(0); + etemp.timestamp = source_date_epoch_time(0); etemp.is_crc_checked = 1; etemp.phar = phar; etemp.filename = estrndup(path, path_len); diff --git a/ext/phar/zip.c b/ext/phar/zip.c index 1d7c5b2217fd0..eb515475f7d3d 100644 --- a/ext/phar/zip.c +++ b/ext/phar/zip.c @@ -1185,7 +1185,7 @@ int phar_zip_flush(phar_archive_data *phar, char *user_stub, zend_long len, int pass.error = &temperr; entry.flags = PHAR_ENT_PERM_DEF_FILE; - entry.timestamp = time(NULL); + entry.timestamp = source_date_epoch_time(NULL); entry.is_modified = 1; entry.is_zip = 1; entry.phar = phar; From e180df8555862e7e037b5569523d9993b83fdbf8 Mon Sep 17 00:00:00 2001 From: Arjen de Korte Date: Sat, 2 Jan 2021 18:43:39 +0100 Subject: [PATCH 2/7] Update phar_internal.h --- ext/phar/phar_internal.h | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/ext/phar/phar_internal.h b/ext/phar/phar_internal.h index de7ba32636172..25e113cc5b65f 100644 --- a/ext/phar/phar_internal.h +++ b/ext/phar/phar_internal.h @@ -427,11 +427,9 @@ static inline enum phar_fp_type phar_get_fp_type(phar_entry_info *entry) static inline time_t source_date_epoch_time(time_t *tloc) { - const char *sde; - time_t ts; + const char *sde = getenv("SOURCE_DATE_EPOCH"); + time_t ts = (sde) ? strtol(sde, NULL, 10) : time(0); - sde = getenv("SOURCE_DATE_EPOCH"); - ts = (sde) ? strtol(sde, NULL, 10) : time(0); if (tloc) { *tloc = ts; } From e057b79678ff3a850975dbc095f1c2430dce92d7 Mon Sep 17 00:00:00 2001 From: Arjen de Korte Date: Sun, 3 Jan 2021 23:16:18 +0100 Subject: [PATCH 3/7] phar_internal.h: prevent Epochalypse in conversion --- ext/phar/phar_internal.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ext/phar/phar_internal.h b/ext/phar/phar_internal.h index 25e113cc5b65f..de0e78870c018 100644 --- a/ext/phar/phar_internal.h +++ b/ext/phar/phar_internal.h @@ -428,7 +428,7 @@ static inline enum phar_fp_type phar_get_fp_type(phar_entry_info *entry) static inline time_t source_date_epoch_time(time_t *tloc) { const char *sde = getenv("SOURCE_DATE_EPOCH"); - time_t ts = (sde) ? strtol(sde, NULL, 10) : time(0); + time_t ts = (sde) ? strtoul(sde, NULL, 10) : time(0); if (tloc) { *tloc = ts; From b3526cd573bbc366bffb864db82f90b959053e21 Mon Sep 17 00:00:00 2001 From: Arjen de Korte Date: Mon, 4 Jan 2021 23:16:49 +0100 Subject: [PATCH 4/7] phap_internal.h: Use safe php_getenv() to read from environment Signed-off-by: Arjen de Korte --- ext/phar/phar_internal.h | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/ext/phar/phar_internal.h b/ext/phar/phar_internal.h index 25e113cc5b65f..dccdea140a9dc 100644 --- a/ext/phar/phar_internal.h +++ b/ext/phar/phar_internal.h @@ -425,9 +425,11 @@ static inline enum phar_fp_type phar_get_fp_type(phar_entry_info *entry) return PHAR_G(cached_fp)[entry->phar->phar_pos].manifest[entry->manifest_pos].fp_type; } +#define SOURCE_DATE_EPOCH "SOURCE_DATE_EPOCH" + static inline time_t source_date_epoch_time(time_t *tloc) { - const char *sde = getenv("SOURCE_DATE_EPOCH"); + const char *sde = php_getenv(SOURCE_DATE_EPOCH, strlen(SOURCE_DATE_EPOCH)); time_t ts = (sde) ? strtol(sde, NULL, 10) : time(0); if (tloc) { From f500c9fd118a453992878ad3daed02cd9a1cfc23 Mon Sep 17 00:00:00 2001 From: Arjen de Korte Date: Mon, 4 Jan 2021 23:44:17 +0100 Subject: [PATCH 5/7] phar_internal.h: fix use of zend_string Signed-off-by: Arjen de Korte --- ext/phar/phar_internal.h | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/ext/phar/phar_internal.h b/ext/phar/phar_internal.h index dccdea140a9dc..988b2b2a53dc2 100644 --- a/ext/phar/phar_internal.h +++ b/ext/phar/phar_internal.h @@ -429,9 +429,10 @@ static inline enum phar_fp_type phar_get_fp_type(phar_entry_info *entry) static inline time_t source_date_epoch_time(time_t *tloc) { - const char *sde = php_getenv(SOURCE_DATE_EPOCH, strlen(SOURCE_DATE_EPOCH)); - time_t ts = (sde) ? strtol(sde, NULL, 10) : time(0); + zend_string *sde = php_getenv(SOURCE_DATE_EPOCH, strlen(SOURCE_DATE_EPOCH)); + time_t ts = (ZSTR_LEN(sde)) ? strtol(ZSTR_VAL(sde), NULL, 10) : time(0); + zend_string_release(sde); if (tloc) { *tloc = ts; } From e0f0a8db4c2b7877f258cd4a59e07567456fd3f0 Mon Sep 17 00:00:00 2001 From: Arjen de Korte Date: Tue, 5 Jan 2021 20:19:07 +0100 Subject: [PATCH 6/7] phar_internal.h: use put_getenv to read SOURCE_DATE_EPOCH Sorry for the mess I created, rookie GitHub user here. Finally figured out how to build locally before submitting. --- ext/phar/phar_internal.h | 18 ++++++++++-------- 1 file changed, 10 insertions(+), 8 deletions(-) diff --git a/ext/phar/phar_internal.h b/ext/phar/phar_internal.h index 988b2b2a53dc2..d605bf6570c1d 100644 --- a/ext/phar/phar_internal.h +++ b/ext/phar/phar_internal.h @@ -425,18 +425,20 @@ static inline enum phar_fp_type phar_get_fp_type(phar_entry_info *entry) return PHAR_G(cached_fp)[entry->phar->phar_pos].manifest[entry->manifest_pos].fp_type; } -#define SOURCE_DATE_EPOCH "SOURCE_DATE_EPOCH" - static inline time_t source_date_epoch_time(time_t *tloc) { - zend_string *sde = php_getenv(SOURCE_DATE_EPOCH, strlen(SOURCE_DATE_EPOCH)); - time_t ts = (ZSTR_LEN(sde)) ? strtol(ZSTR_VAL(sde), NULL, 10) : time(0); + zend_string *str = php_getenv("SOURCE_DATE_EPOCH", sizeof("SOURCE_DATE_EPOCH")-1); + + if (str) { + time_t t = strtol(ZSTR_VAL(str), NULL, 10); - zend_string_release(sde); - if (tloc) { - *tloc = ts; + zend_string_release(str); + if (tloc) { + *tloc = t; + } + return t; } - return ts; + return time(tloc); } static inline zend_off_t phar_get_fp_offset(phar_entry_info *entry) From 303e4ecf055f540f9f10047d2ce2e13002b61f65 Mon Sep 17 00:00:00 2001 From: Arjen de Korte Date: Tue, 5 Jan 2021 21:12:46 +0100 Subject: [PATCH 7/7] phar_internal.h: Fix Epochalypse (again) Apparently this sneaked in again in one of my commits. Fixing again. Signed-off-by: Arjen de Korte --- ext/phar/phar_internal.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ext/phar/phar_internal.h b/ext/phar/phar_internal.h index d605bf6570c1d..4a8b85466433c 100644 --- a/ext/phar/phar_internal.h +++ b/ext/phar/phar_internal.h @@ -430,7 +430,7 @@ static inline time_t source_date_epoch_time(time_t *tloc) zend_string *str = php_getenv("SOURCE_DATE_EPOCH", sizeof("SOURCE_DATE_EPOCH")-1); if (str) { - time_t t = strtol(ZSTR_VAL(str), NULL, 10); + time_t t = strtoul(ZSTR_VAL(str), NULL, 10); zend_string_release(str); if (tloc) {