From de68c68b5525c1c6a6563c49a782a2d66af5ac29 Mon Sep 17 00:00:00 2001 From: CentOS Sources Date: Nov 01 2019 12:23:24 +0000 Subject: import rh-php72-php-7.2.24-1.el7 --- diff --git a/.gitignore b/.gitignore index 125a466..bc3d9be 100644 --- a/.gitignore +++ b/.gitignore @@ -1 +1 @@ -SOURCES/php-7.2.10.tar.xz +SOURCES/php-7.2.24.tar.xz diff --git a/.rh-php72-php.metadata b/.rh-php72-php.metadata index aa4796e..6c8d691 100644 --- a/.rh-php72-php.metadata +++ b/.rh-php72-php.metadata @@ -1 +1 @@ -ac2d6ae8c332649d2ad9265f0227237f938a9e21 SOURCES/php-7.2.10.tar.xz +d31628bdc89a724a2a0950c2ed7d79b40cf489a7 SOURCES/php-7.2.24.tar.xz diff --git a/SOURCES/php-5.4.0-phpize.patch b/SOURCES/php-5.4.0-phpize.patch deleted file mode 100644 index e666e45..0000000 --- a/SOURCES/php-5.4.0-phpize.patch +++ /dev/null @@ -1,34 +0,0 @@ ---- php-5.4.0RC5/scripts/phpize.in.orig 2012-01-18 17:13:54.018022983 +0100 -+++ php-5.4.0RC5/scripts/phpize.in 2012-01-18 17:14:40.614024941 +0100 -@@ -162,6 +162,15 @@ - $PHP_AUTOHEADER || exit 1 - } - -+phpize_check_headers() -+{ -+ if test ! -f $includedir/main/php.h; then -+ echo "Can't find PHP headers in $includedir" -+ echo "The php-devel package is required for use of this command." -+ exit 1 -+ fi -+} -+ - # Main script - - case "$1" in -@@ -180,12 +189,15 @@ - - # Version - --version|-v) -+ phpize_check_headers - phpize_print_api_numbers - exit 0 - ;; - - # Default - *) -+ phpize_check_headers -+ - phpize_check_configm4 0 - - phpize_check_build_files diff --git a/SOURCES/php-7.2.10-fileinfo.patch b/SOURCES/php-7.2.10-fileinfo.patch deleted file mode 100644 index 16e107d..0000000 --- a/SOURCES/php-7.2.10-fileinfo.patch +++ /dev/null @@ -1,119 +0,0 @@ -From c621182c42a36975970586cfc294bc5a80ba08cb Mon Sep 17 00:00:00 2001 -From: Anatol Belski -Date: Sun, 4 Nov 2018 16:56:43 +0100 -Subject: [PATCH] Backport 7f5f4601 for 7.2 - ---- - ext/fileinfo/libmagic/apprentice.c | 7 ++++--- - ext/fileinfo/libmagic/softmagic.c | 31 ++++++++++++------------------ - 2 files changed, 16 insertions(+), 22 deletions(-) - -diff --git a/ext/fileinfo/libmagic/apprentice.c b/ext/fileinfo/libmagic/apprentice.c -index e55f59bbb8c5..fae2abb811d5 100644 ---- a/ext/fileinfo/libmagic/apprentice.c -+++ b/ext/fileinfo/libmagic/apprentice.c -@@ -2524,18 +2524,19 @@ getvalue(struct magic_set *ms, struct magic *m, const char **p, int action) - return -1; - } - if (m->type == FILE_REGEX) { -- /* XXX do we need this? */ -- /*zval pattern; -+ zval pattern; - int options = 0; - pcre_cache_entry *pce; - - convert_libmagic_pattern(&pattern, m->value.s, strlen(m->value.s), options); - - if ((pce = pcre_get_compiled_regex_cache(Z_STR(pattern))) == NULL) { -+ zval_dtor(&pattern); - return -1; - } -+ zval_dtor(&pattern); - -- return 0;*/ -+ return 0; - } - return 0; - case FILE_FLOAT: -diff --git a/ext/fileinfo/libmagic/softmagic.c b/ext/fileinfo/libmagic/softmagic.c -index d07d49e7a016..4b10e846644f 100644 ---- a/ext/fileinfo/libmagic/softmagic.c -+++ b/ext/fileinfo/libmagic/softmagic.c -@@ -1203,28 +1203,21 @@ mcopy(struct magic_set *ms, union VALUETYPE *p, int type, int indir, - return 0; - } - -- /* bytecnt checks are to be kept for PHP, see cve-2014-3538. -- PCRE might get stuck if the input buffer is too big. */ -- linecnt = m->str_range; -- bytecnt = linecnt * 80; -- -- if (bytecnt == 0) { -- bytecnt = 1 << 14; -+ if (m->str_flags & REGEX_LINE_COUNT) { -+ linecnt = m->str_range; -+ bytecnt = linecnt * 80; -+ } else { -+ linecnt = 0; -+ bytecnt = m->str_range; - } - -- if (bytecnt > nbytes) { -- bytecnt = nbytes; -- } -- if (offset > bytecnt) { -- offset = bytecnt; -- } -- if (s == NULL) { -- ms->search.s_len = 0; -- ms->search.s = NULL; -- return 0; -- } -+ if (bytecnt == 0 || bytecnt > nbytes - offset) -+ bytecnt = nbytes - offset; -+ if (bytecnt > ms->regex_max) -+ bytecnt = ms->regex_max; -+ - buf = RCAST(const char *, s) + offset; -- end = last = RCAST(const char *, s) + bytecnt; -+ end = last = RCAST(const char *, s) + bytecnt + offset; - /* mget() guarantees buf <= last */ - for (lines = linecnt, b = buf; lines && b < end && - ((b = CAST(const char *, -From 0e33c2822c913e7cb0d9d04b08d3d9439bda6e4c Mon Sep 17 00:00:00 2001 -From: Anatol Belski -Date: Mon, 5 Nov 2018 21:28:04 +0100 -Subject: [PATCH] Declare function proto in header - ---- - ext/fileinfo/libmagic/file.h | 3 +++ - ext/fileinfo/libmagic/funcs.c | 2 -- - 2 files changed, 3 insertions(+), 2 deletions(-) - -diff --git a/ext/fileinfo/libmagic/file.h b/ext/fileinfo/libmagic/file.h -index bfc49f57d5d8..cb9bd87293f2 100644 ---- a/ext/fileinfo/libmagic/file.h -+++ b/ext/fileinfo/libmagic/file.h -@@ -488,6 +488,9 @@ protected int file_os2_apptype(struct magic_set *, const char *, const void *, - size_t); - #endif /* __EMX__ */ - -+public void -+convert_libmagic_pattern(zval *pattern, char *val, int len, int options); -+ - typedef struct { - char *buf; - uint32_t offset; -diff --git a/ext/fileinfo/libmagic/funcs.c b/ext/fileinfo/libmagic/funcs.c -index 40ea81d3df39..f49129e7d80b 100644 ---- a/ext/fileinfo/libmagic/funcs.c -+++ b/ext/fileinfo/libmagic/funcs.c -@@ -56,8 +56,6 @@ FILE_RCSID("@(#)$File: funcs.c,v 1.92 2017/04/07 20:10:24 christos Exp $") - # define PREG_OFFSET_CAPTURE (1<<8) - #endif - --extern public void convert_libmagic_pattern(zval *pattern, char *val, int len, int options); -- - protected int - file_printf(struct magic_set *ms, const char *fmt, ...) - { diff --git a/SOURCES/php-7.2.10-mysql8.patch b/SOURCES/php-7.2.10-mysql8.patch deleted file mode 100644 index d82cfe7..0000000 --- a/SOURCES/php-7.2.10-mysql8.patch +++ /dev/null @@ -1,676 +0,0 @@ -From 03740ef7dffcc80530a89ebde3ccf5464f7f18e6 Mon Sep 17 00:00:00 2001 -From: Nikita Popov -Date: Tue, 4 Sep 2018 05:45:45 +0200 -Subject: [PATCH] Revert all MySQL auth related changes - -Per bug #76651 these changes do not appear to work correctly in -some cases. As no immediate fix seems to be forthcoming, I'm -reverting these changes. - -Revert "Fixed invalid free introduced by d6e81f0bfd0cb90586dd83d4fd47a4302605261a (avoid keeping "invalid" pointer)" - -This reverts commit 11507c0e1bfa17a96480f3648397f6975c31551e. - -Revert "Fix mysqlnd build without openssl" - -This reverts commit 6c9db02ff7812c298d1e7e292ba731d9d3a66790. - -Revert "Fix VC compilation as variable size array is not supported" - -This reverts commit f96df64cb2219fda42ca875483f874cf3052647c. - -Revert "Fix MySQL 8 auth" - -This reverts commit d6e81f0bfd0cb90586dd83d4fd47a4302605261a. ---- - ext/mysqlnd/mysqlnd_auth.c | 293 +---------------------------- - ext/mysqlnd/mysqlnd_auth.h | 23 ++- - ext/mysqlnd/mysqlnd_connection.c | 4 - - ext/mysqlnd/mysqlnd_enum_n_def.h | 1 - - ext/mysqlnd/mysqlnd_structs.h | 10 - - ext/mysqlnd/mysqlnd_wireprotocol.c | 113 +---------- - ext/mysqlnd/mysqlnd_wireprotocol.h | 10 - - 7 files changed, 29 insertions(+), 425 deletions(-) - -diff --git a/ext/mysqlnd/mysqlnd_auth.c b/ext/mysqlnd/mysqlnd_auth.c -index 66e93cf63669..3ba447cfdf91 100644 ---- a/ext/mysqlnd/mysqlnd_auth.c -+++ b/ext/mysqlnd/mysqlnd_auth.c -@@ -89,7 +89,6 @@ mysqlnd_run_authentication( - } - } - -- - { - zend_uchar * switch_to_auth_protocol_data = NULL; - size_t switch_to_auth_protocol_data_len = 0; -@@ -114,11 +113,10 @@ mysqlnd_run_authentication( - DBG_INF_FMT("salt(%d)=[%.*s]", plugin_data_len, plugin_data_len, plugin_data); - /* The data should be allocated with malloc() */ - if (auth_plugin) { -- scrambled_data = auth_plugin->methods.get_auth_data( -- NULL, &scrambled_data_len, conn, user, passwd, -- passwd_len, plugin_data, plugin_data_len, -- session_options, conn->protocol_frame_codec->data, -- mysql_flags); -+ scrambled_data = -+ auth_plugin->methods.get_auth_data(NULL, &scrambled_data_len, conn, user, passwd, passwd_len, -+ plugin_data, plugin_data_len, session_options, -+ conn->protocol_frame_codec->data, mysql_flags); - } - - if (conn->error_info->error_no) { -@@ -129,7 +127,6 @@ mysqlnd_run_authentication( - charset_no, - first_call, - requested_protocol, -- auth_plugin, plugin_data, plugin_data_len, - scrambled_data, scrambled_data_len, - &switch_to_auth_protocol, &switch_to_auth_protocol_len, - &switch_to_auth_protocol_data, &switch_to_auth_protocol_data_len -@@ -251,9 +248,6 @@ mysqlnd_auth_handshake(MYSQLND_CONN_DATA * conn, - unsigned int server_charset_no, - zend_bool use_full_blown_auth_packet, - const char * const auth_protocol, -- struct st_mysqlnd_authentication_plugin * auth_plugin, -- const zend_uchar * const orig_auth_plugin_data, -- const size_t orig_auth_plugin_data_len, - const zend_uchar * const auth_plugin_data, - const size_t auth_plugin_data_len, - char ** switch_to_auth_protocol, -@@ -324,11 +318,6 @@ mysqlnd_auth_handshake(MYSQLND_CONN_DATA * conn, - conn->charset = mysqlnd_find_charset_nr(auth_packet->charset_no); - } - -- if (auth_plugin && auth_plugin->methods.handle_server_response) { -- auth_plugin->methods.handle_server_response(auth_plugin, conn, -- orig_auth_plugin_data, orig_auth_plugin_data_len, passwd, passwd_len); -- } -- - if (FAIL == PACKET_READ(auth_resp_packet) || auth_resp_packet->response_code >= 0xFE) { - if (auth_resp_packet->response_code == 0xFE) { - /* old authentication with new server !*/ -@@ -624,8 +613,7 @@ static struct st_mysqlnd_authentication_plugin mysqlnd_native_auth_plugin = - } - }, - {/* methods */ -- mysqlnd_native_auth_get_auth_data, -- NULL -+ mysqlnd_native_auth_get_auth_data - } - }; - -@@ -674,8 +662,7 @@ static struct st_mysqlnd_authentication_plugin mysqlnd_pam_authentication_plugin - } - }, - {/* methods */ -- mysqlnd_pam_auth_get_auth_data, -- NULL -+ mysqlnd_pam_auth_get_auth_data - } - }; - -@@ -859,283 +846,17 @@ static struct st_mysqlnd_authentication_plugin mysqlnd_sha256_authentication_plu - } - }, - {/* methods */ -- mysqlnd_sha256_auth_get_auth_data, -- NULL -+ mysqlnd_sha256_auth_get_auth_data - } - }; - #endif - --/*************************************** CACHING SHA2 Password *******************************/ -- --#undef L64 -- --#include "ext/hash/php_hash.h" --#include "ext/hash/php_hash_sha.h" -- --#define SHA256_LENGTH 32 -- --/* {{{ php_mysqlnd_scramble_sha2 */ --void php_mysqlnd_scramble_sha2(zend_uchar * const buffer, const zend_uchar * const scramble, const zend_uchar * const password, const size_t password_len) --{ -- PHP_SHA256_CTX context; -- zend_uchar sha1[SHA256_LENGTH]; -- zend_uchar sha2[SHA256_LENGTH]; -- -- /* Phase 1: hash password */ -- PHP_SHA256Init(&context); -- PHP_SHA256Update(&context, password, password_len); -- PHP_SHA256Final(sha1, &context); -- -- /* Phase 2: hash sha1 */ -- PHP_SHA256Init(&context); -- PHP_SHA256Update(&context, (zend_uchar*)sha1, SHA256_LENGTH); -- PHP_SHA256Final(sha2, &context); -- -- /* Phase 3: hash scramble + sha2 */ -- PHP_SHA256Init(&context); -- PHP_SHA256Update(&context, (zend_uchar*)sha2, SHA256_LENGTH); -- PHP_SHA256Update(&context, scramble, SCRAMBLE_LENGTH); -- PHP_SHA256Final(buffer, &context); -- -- /* let's crypt buffer now */ -- php_mysqlnd_crypt(buffer, (const zend_uchar *)sha1, (const zend_uchar *)buffer, SHA256_LENGTH); --} --/* }}} */ -- -- --/* {{{ mysqlnd_native_auth_get_auth_data */ --static zend_uchar * --mysqlnd_caching_sha2_get_auth_data(struct st_mysqlnd_authentication_plugin * self, -- size_t * auth_data_len, -- MYSQLND_CONN_DATA * conn, const char * const user, const char * const passwd, -- const size_t passwd_len, zend_uchar * auth_plugin_data, size_t auth_plugin_data_len, -- const MYSQLND_SESSION_OPTIONS * const session_options, -- const MYSQLND_PFC_DATA * const pfc_data, -- zend_ulong mysql_flags -- ) --{ -- zend_uchar * ret = NULL; -- DBG_ENTER("mysqlnd_caching_sha2_get_auth_data"); -- DBG_INF_FMT("salt(%d)=[%.*s]", auth_plugin_data_len, auth_plugin_data_len, auth_plugin_data); -- *auth_data_len = 0; -- -- DBG_INF("First auth step: send hashed password"); -- /* copy scrambled pass*/ -- if (passwd && passwd_len) { -- ret = malloc(SHA256_LENGTH + 1); -- *auth_data_len = SHA256_LENGTH; -- php_mysqlnd_scramble_sha2((zend_uchar*)ret, auth_plugin_data, (zend_uchar*)passwd, passwd_len); -- ret[SHA256_LENGTH] = '\0'; -- DBG_INF_FMT("hash(%d)=[%.*s]", *auth_data_len, *auth_data_len, ret); -- } -- -- DBG_RETURN(ret); --} --/* }}} */ -- --#ifdef MYSQLND_HAVE_SSL --static RSA * --mysqlnd_caching_sha2_get_key(MYSQLND_CONN_DATA *conn) --{ -- RSA * ret = NULL; -- const MYSQLND_PFC_DATA * const pfc_data = conn->protocol_frame_codec->data; -- const char * fname = (pfc_data->sha256_server_public_key && pfc_data->sha256_server_public_key[0] != '\0')? -- pfc_data->sha256_server_public_key: -- MYSQLND_G(sha256_server_public_key); -- php_stream * stream; -- DBG_ENTER("mysqlnd_cached_sha2_get_key"); -- DBG_INF_FMT("options_s256_pk=[%s] MYSQLND_G(sha256_server_public_key)=[%s]", -- pfc_data->sha256_server_public_key? pfc_data->sha256_server_public_key:"n/a", -- MYSQLND_G(sha256_server_public_key)? MYSQLND_G(sha256_server_public_key):"n/a"); -- if (!fname || fname[0] == '\0') { -- MYSQLND_PACKET_CACHED_SHA2_RESULT *req_packet = NULL; -- MYSQLND_PACKET_SHA256_PK_REQUEST_RESPONSE *pk_resp_packet = NULL; -- -- do { -- DBG_INF("requesting the public key from the server"); -- req_packet = conn->payload_decoder_factory->m.get_cached_sha2_result_packet(conn->payload_decoder_factory, FALSE); -- pk_resp_packet = conn->payload_decoder_factory->m.get_sha256_pk_request_response_packet(conn->payload_decoder_factory, FALSE); -- req_packet->request = 1; -- -- if (! PACKET_WRITE(req_packet)) { -- DBG_ERR_FMT("Error while sending public key request packet"); -- php_error(E_WARNING, "Error while sending public key request packet. PID=%d", getpid()); -- SET_CONNECTION_STATE(&conn->state, CONN_QUIT_SENT); -- break; -- } -- if (FAIL == PACKET_READ(pk_resp_packet) || NULL == pk_resp_packet->public_key) { -- DBG_ERR_FMT("Error while receiving public key"); -- php_error(E_WARNING, "Error while receiving public key. PID=%d", getpid()); -- SET_CONNECTION_STATE(&conn->state, CONN_QUIT_SENT); -- break; -- } -- DBG_INF_FMT("Public key(%d):\n%s", pk_resp_packet->public_key_len, pk_resp_packet->public_key); -- /* now extract the public key */ -- { -- BIO * bio = BIO_new_mem_buf(pk_resp_packet->public_key, pk_resp_packet->public_key_len); -- ret = PEM_read_bio_RSA_PUBKEY(bio, NULL, NULL, NULL); -- BIO_free(bio); -- } -- } while (0); -- PACKET_FREE(req_packet); -- PACKET_FREE(pk_resp_packet); -- -- DBG_INF_FMT("ret=%p", ret); -- DBG_RETURN(ret); -- -- SET_CLIENT_ERROR(conn->error_info, CR_UNKNOWN_ERROR, UNKNOWN_SQLSTATE, -- "caching_sha2_server_public_key is not set for the connection or as mysqlnd.sha256_server_public_key"); -- DBG_ERR("server_public_key is not set"); -- DBG_RETURN(NULL); -- } else { -- zend_string * key_str; -- DBG_INF_FMT("Key in a file. [%s]", fname); -- stream = php_stream_open_wrapper((char *) fname, "rb", REPORT_ERRORS, NULL); -- -- if (stream) { -- if ((key_str = php_stream_copy_to_mem(stream, PHP_STREAM_COPY_ALL, 0)) != NULL) { -- BIO * bio = BIO_new_mem_buf(ZSTR_VAL(key_str), ZSTR_LEN(key_str)); -- ret = PEM_read_bio_RSA_PUBKEY(bio, NULL, NULL, NULL); -- BIO_free(bio); -- DBG_INF("Successfully loaded"); -- DBG_INF_FMT("Public key:%*.s", ZSTR_LEN(key_str), ZSTR_VAL(key_str)); -- zend_string_release(key_str); -- } -- php_stream_close(stream); -- } -- } -- DBG_RETURN(ret); -- --} --#endif -- -- --/* {{{ mysqlnd_caching_sha2_get_key */ --static size_t --mysqlnd_caching_sha2_get_and_use_key(MYSQLND_CONN_DATA *conn, -- const zend_uchar * auth_plugin_data, size_t auth_plugin_data_len, -- unsigned char **crypted, -- const char * const passwd, -- const size_t passwd_len) --{ --#ifdef MYSQLND_HAVE_SSL -- static RSA *server_public_key; -- server_public_key = mysqlnd_caching_sha2_get_key(conn); -- -- DBG_ENTER("mysqlnd_caching_sha2_get_and_use_key("); -- -- if (server_public_key) { -- int server_public_key_len; -- char xor_str[passwd_len + 1]; -- memcpy(xor_str, passwd, passwd_len); -- xor_str[passwd_len] = '\0'; -- mysqlnd_xor_string(xor_str, passwd_len, (char *) auth_plugin_data, auth_plugin_data_len); -- -- server_public_key_len = RSA_size(server_public_key); -- /* -- Because RSA_PKCS1_OAEP_PADDING is used there is a restriction on the passwd_len. -- RSA_PKCS1_OAEP_PADDING is recommended for new applications. See more here: -- http://www.openssl.org/docs/crypto/RSA_public_encrypt.html -- */ -- if ((size_t) server_public_key_len - 41 <= passwd_len) { -- /* password message is to long */ -- SET_CLIENT_ERROR(conn->error_info, CR_UNKNOWN_ERROR, UNKNOWN_SQLSTATE, "password is too long"); -- DBG_ERR("password is too long"); -- DBG_RETURN(0); -- } -- -- *crypted = emalloc(server_public_key_len); -- RSA_public_encrypt(passwd_len + 1, (zend_uchar *) xor_str, *crypted, server_public_key, RSA_PKCS1_OAEP_PADDING); -- DBG_RETURN(server_public_key_len); -- } -- DBG_RETURN(0); --#else -- DBG_ENTER("mysqlnd_caching_sha2_get_and_use_key("); -- php_error_docref(NULL, E_WARNING, "PHP was built without openssl extension, can't send password encrypted"); -- DBG_RETURN(0); --#endif --} --/* }}} */ -- --/* {{{ mysqlnd_native_auth_get_auth_data */ --static void --mysqlnd_caching_sha2_handle_server_response(struct st_mysqlnd_authentication_plugin *self, -- MYSQLND_CONN_DATA * conn, -- const zend_uchar * auth_plugin_data, size_t auth_plugin_data_len, -- const char * const passwd, -- const size_t passwd_len) --{ -- DBG_ENTER("mysqlnd_caching_sha2_handle_server_response"); -- MYSQLND_PACKET_CACHED_SHA2_RESULT *result_packet; -- result_packet = conn->payload_decoder_factory->m.get_cached_sha2_result_packet(conn->payload_decoder_factory, FALSE); -- -- if (FAIL == PACKET_READ(result_packet)) { -- DBG_VOID_RETURN; -- } -- -- switch (result_packet->response_code) { -- case 3: -- DBG_INF("fast path suceeded"); -- PACKET_FREE(result_packet); -- DBG_VOID_RETURN; -- case 4: -- if (conn->vio->data->ssl || conn->unix_socket.s) { -- DBG_INF("fast path failed, doing full auth via SSL"); -- result_packet->password = (zend_uchar *)passwd; -- result_packet->password_len = passwd_len + 1; -- PACKET_WRITE(result_packet); -- } else { -- DBG_INF("fast path failed, doing full auth without SSL"); -- result_packet->password_len = mysqlnd_caching_sha2_get_and_use_key(conn, auth_plugin_data, auth_plugin_data_len, &result_packet->password, passwd, passwd_len); -- PACKET_WRITE(result_packet); -- efree(result_packet->password); -- } -- PACKET_FREE(result_packet); -- DBG_VOID_RETURN; -- case 2: -- // The server tried to send a key, which we didn't expect -- // fall-through -- default: -- php_error_docref(NULL, E_WARNING, "Unexpected server respose while doing caching_sha2 auth: %i", result_packet->response_code); -- } -- -- PACKET_FREE(result_packet); -- -- DBG_VOID_RETURN; --} --/* }}} */ -- --static struct st_mysqlnd_authentication_plugin mysqlnd_caching_sha2_auth_plugin = --{ -- { -- MYSQLND_PLUGIN_API_VERSION, -- "auth_plugin_caching_sha2_password", -- MYSQLND_VERSION_ID, -- PHP_MYSQLND_VERSION, -- "PHP License 3.01", -- "Johannes Schlüter ", -- { -- NULL, /* no statistics , will be filled later if there are some */ -- NULL, /* no statistics */ -- }, -- { -- NULL /* plugin shutdown */ -- } -- }, -- {/* methods */ -- mysqlnd_caching_sha2_get_auth_data, -- mysqlnd_caching_sha2_handle_server_response -- } --}; -- -- - /* {{{ mysqlnd_register_builtin_authentication_plugins */ - void - mysqlnd_register_builtin_authentication_plugins(void) - { - mysqlnd_plugin_register_ex((struct st_mysqlnd_plugin_header *) &mysqlnd_native_auth_plugin); - mysqlnd_plugin_register_ex((struct st_mysqlnd_plugin_header *) &mysqlnd_pam_authentication_plugin); -- mysqlnd_plugin_register_ex((struct st_mysqlnd_plugin_header *) &mysqlnd_caching_sha2_auth_plugin); - #ifdef MYSQLND_HAVE_SSL - mysqlnd_plugin_register_ex((struct st_mysqlnd_plugin_header *) &mysqlnd_sha256_authentication_plugin); - #endif -diff --git a/ext/mysqlnd/mysqlnd_auth.h b/ext/mysqlnd/mysqlnd_auth.h -index 3ddb5a5f70fe..8fc369abca43 100644 ---- a/ext/mysqlnd/mysqlnd_auth.h -+++ b/ext/mysqlnd/mysqlnd_auth.h -@@ -31,9 +31,26 @@ mysqlnd_auth_handshake(MYSQLND_CONN_DATA * conn, - unsigned int server_charset_no, - zend_bool use_full_blown_auth_packet, - const char * const auth_protocol, -- struct st_mysqlnd_authentication_plugin * auth_plugin, -- const zend_uchar * const orig_auth_plugin_data, -- const size_t orig_auth_plugin_data_len, -+ const zend_uchar * const auth_plugin_data, -+ const size_t auth_plugin_data_len, -+ char ** switch_to_auth_protocol, -+ size_t * switch_to_auth_protocol_len, -+ zend_uchar ** switch_to_auth_protocol_data, -+ size_t * switch_to_auth_protocol_data_len -+ ); -+ -+enum_func_status -+mysqlnd_auth_handshake(MYSQLND_CONN_DATA * conn, -+ const char * const user, -+ const char * const passwd, -+ const size_t passwd_len, -+ const char * const db, -+ const size_t db_len, -+ const MYSQLND_SESSION_OPTIONS * const session_options, -+ zend_ulong mysql_flags, -+ unsigned int server_charset_no, -+ zend_bool use_full_blown_auth_packet, -+ const char * const auth_protocol, - const zend_uchar * const auth_plugin_data, - const size_t auth_plugin_data_len, - char ** switch_to_auth_protocol, -diff --git a/ext/mysqlnd/mysqlnd_connection.c b/ext/mysqlnd/mysqlnd_connection.c -index 2f458149a6cd..654673f500c0 100644 ---- a/ext/mysqlnd/mysqlnd_connection.c -+++ b/ext/mysqlnd/mysqlnd_connection.c -@@ -678,13 +678,9 @@ MYSQLND_METHOD(mysqlnd_conn_data, connect)(MYSQLND_CONN_DATA * conn, - - { - const MYSQLND_CSTRING scheme = { transport.s, transport.l }; -- /* This will be overwritten below with a copy, but we can use it during authentication */ -- conn->unix_socket.s = (char *)socket_or_pipe.s; - if (FAIL == conn->m->connect_handshake(conn, &scheme, &username, &password, &database, mysql_flags)) { -- conn->unix_socket.s = NULL; - goto err; - } -- conn->unix_socket.s = NULL; - } - - { -diff --git a/ext/mysqlnd/mysqlnd_enum_n_def.h b/ext/mysqlnd/mysqlnd_enum_n_def.h -index 0a3022058d1d..4b3ae4fff36f 100644 ---- a/ext/mysqlnd/mysqlnd_enum_n_def.h -+++ b/ext/mysqlnd/mysqlnd_enum_n_def.h -@@ -618,7 +618,6 @@ enum mysqlnd_packet_type - PROT_CHG_USER_RESP_PACKET, - PROT_SHA256_PK_REQUEST_PACKET, - PROT_SHA256_PK_REQUEST_RESPONSE_PACKET, -- PROT_CACHED_SHA2_RESULT_PACKET, - PROT_LAST /* should always be last */ - }; - -diff --git a/ext/mysqlnd/mysqlnd_structs.h b/ext/mysqlnd/mysqlnd_structs.h -index bd09b5b0dffd..81b24066460a 100644 ---- a/ext/mysqlnd/mysqlnd_structs.h -+++ b/ext/mysqlnd/mysqlnd_structs.h -@@ -970,7 +970,6 @@ struct st_mysqlnd_packet_chg_user_resp; - struct st_mysqlnd_packet_auth_pam; - struct st_mysqlnd_packet_sha256_pk_request; - struct st_mysqlnd_packet_sha256_pk_request_response; --struct st_mysqlnd_packet_cached_sha2_result; - - typedef struct st_mysqlnd_packet_greet * (*func_mysqlnd_protocol_payload_decoder_factory__get_greet_packet)(MYSQLND_PROTOCOL_PAYLOAD_DECODER_FACTORY * const factory, const zend_bool persistent); - typedef struct st_mysqlnd_packet_auth * (*func_mysqlnd_protocol_payload_decoder_factory__get_auth_packet)(MYSQLND_PROTOCOL_PAYLOAD_DECODER_FACTORY * const factory, const zend_bool persistent); -@@ -987,7 +986,6 @@ typedef struct st_mysqlnd_packet_prepare_response *(*func_mysqlnd_protocol_paylo - typedef struct st_mysqlnd_packet_chg_user_resp*(*func_mysqlnd_protocol_payload_decoder_factory__get_change_user_response_packet)(MYSQLND_PROTOCOL_PAYLOAD_DECODER_FACTORY * const factory, const zend_bool persistent); - typedef struct st_mysqlnd_packet_sha256_pk_request *(*func_mysqlnd_protocol_payload_decoder_factory__get_sha256_pk_request_packet)(MYSQLND_PROTOCOL_PAYLOAD_DECODER_FACTORY * const factory, const zend_bool persistent); - typedef struct st_mysqlnd_packet_sha256_pk_request_response *(*func_mysqlnd_protocol_payload_decoder_factory__get_sha256_pk_request_response_packet)(MYSQLND_PROTOCOL_PAYLOAD_DECODER_FACTORY * const factory, const zend_bool persistent); --typedef struct st_mysqlnd_packet_cached_sha2_result *(*func_mysqlnd_protocol_payload_decoder_factory__get_cached_sha2_result_packet)(MYSQLND_PROTOCOL_PAYLOAD_DECODER_FACTORY * const factory, const zend_bool persistent); - - typedef enum_func_status (*func_mysqlnd_protocol_payload_decoder_factory__send_command)( - MYSQLND_PROTOCOL_PAYLOAD_DECODER_FACTORY * payload_decoder_factory, -@@ -1045,7 +1043,6 @@ MYSQLND_CLASS_METHODS_TYPE(mysqlnd_protocol_payload_decoder_factory) - func_mysqlnd_protocol_payload_decoder_factory__get_change_user_response_packet get_change_user_response_packet; - func_mysqlnd_protocol_payload_decoder_factory__get_sha256_pk_request_packet get_sha256_pk_request_packet; - func_mysqlnd_protocol_payload_decoder_factory__get_sha256_pk_request_response_packet get_sha256_pk_request_response_packet; -- func_mysqlnd_protocol_payload_decoder_factory__get_cached_sha2_result_packet get_cached_sha2_result_packet; - - func_mysqlnd_protocol_payload_decoder_factory__send_command send_command; - func_mysqlnd_protocol_payload_decoder_factory__send_command_handle_response send_command_handle_response; -@@ -1358,18 +1355,11 @@ typedef zend_uchar * (*func_auth_plugin__get_auth_data)(struct st_mysqlnd_authen - const MYSQLND_PFC_DATA * const pfc_data, zend_ulong mysql_flags - ); - --typedef void (*func_auth_plugin__handle_server_response)(struct st_mysqlnd_authentication_plugin * self, -- MYSQLND_CONN_DATA * conn, -- const zend_uchar * auth_plugin_data, size_t auth_plugin_data_len, -- const char * const passwd, -- const size_t passwd_len); -- - struct st_mysqlnd_authentication_plugin - { - struct st_mysqlnd_plugin_header plugin_header; - struct { - func_auth_plugin__get_auth_data get_auth_data; -- func_auth_plugin__handle_server_response handle_server_response; - } methods; - }; - -diff --git a/ext/mysqlnd/mysqlnd_wireprotocol.c b/ext/mysqlnd/mysqlnd_wireprotocol.c -index c5039c3d722e..29f89e88e052 100644 ---- a/ext/mysqlnd/mysqlnd_wireprotocol.c -+++ b/ext/mysqlnd/mysqlnd_wireprotocol.c -@@ -2269,85 +2269,7 @@ php_mysqlnd_sha256_pk_request_response_free_mem(void * _packet, zend_bool stack_ - } - /* }}} */ - --static --size_t php_mysqlnd_cached_sha2_result_write(void * _packet) --{ -- MYSQLND_PACKET_CACHED_SHA2_RESULT * packet= (MYSQLND_PACKET_CACHED_SHA2_RESULT *) _packet; -- MYSQLND_ERROR_INFO * error_info = packet->header.error_info; -- MYSQLND_PFC * pfc = packet->header.protocol_frame_codec; -- MYSQLND_VIO * vio = packet->header.vio; -- MYSQLND_STATS * stats = packet->header.stats; --#ifndef _MSC_VER -- zend_uchar buffer[MYSQLND_HEADER_SIZE + packet->password_len + 1]; --#else -- ALLOCA_FLAG(use_heap) -- zend_uchar *buffer = do_alloca(MYSQLND_HEADER_SIZE + packet->password_len + 1, use_heap); --#endif -- size_t sent; -- -- DBG_ENTER("php_mysqlnd_cached_sha2_result_write"); -- -- if (packet->request == 1) { -- int1store(buffer + MYSQLND_HEADER_SIZE, '\2'); -- sent = pfc->data->m.send(pfc, vio, buffer, 1, stats, error_info); -- } else { -- memcpy(buffer + MYSQLND_HEADER_SIZE, packet->password, packet->password_len); -- sent = pfc->data->m.send(pfc, vio, buffer, packet->password_len, stats, error_info); -- } -- --#ifdef _MSC_VER -- free_alloca(buffer, use_heap); --#endif -- -- DBG_RETURN(sent); --} -- --static enum_func_status --php_mysqlnd_cached_sha2_result_read(void * _packet) --{ -- MYSQLND_PACKET_CACHED_SHA2_RESULT * packet= (MYSQLND_PACKET_CACHED_SHA2_RESULT *) _packet; -- MYSQLND_ERROR_INFO * error_info = packet->header.error_info; -- MYSQLND_PFC * pfc = packet->header.protocol_frame_codec; -- MYSQLND_VIO * vio = packet->header.vio; -- MYSQLND_STATS * stats = packet->header.stats; -- MYSQLND_CONNECTION_STATE * connection_state = packet->header.connection_state; -- zend_uchar buf[SHA256_PK_REQUEST_RESP_BUFFER_SIZE]; -- zend_uchar *p = buf; -- const zend_uchar * const begin = buf; -- -- DBG_ENTER("php_mysqlnd_cached_sha2_result_read"); -- if (FAIL == mysqlnd_read_packet_header_and_body(&(packet->header), pfc, vio, stats, error_info, connection_state, buf, sizeof(buf), "PROT_CACHED_SHA2_RESULT_PACKET", PROT_CACHED_SHA2_RESULT_PACKET)) { -- DBG_RETURN(FAIL); -- } -- BAIL_IF_NO_MORE_DATA; -- -- p++; -- packet->response_code = uint1korr(p); -- BAIL_IF_NO_MORE_DATA; - -- p++; -- packet->result = uint1korr(p); -- BAIL_IF_NO_MORE_DATA; -- -- DBG_RETURN(PASS); -- --premature_end: -- DBG_ERR_FMT("OK packet %d bytes shorter than expected", p - begin - packet->header.size); -- php_error_docref(NULL, E_WARNING, "SHA256_PK_REQUEST_RESPONSE packet "MYSQLND_SZ_T_SPEC" bytes shorter than expected", -- p - begin - packet->header.size); -- DBG_RETURN(FAIL); --} -- --static void --php_mysqlnd_cached_sha2_result_free_mem(void * _packet, zend_bool stack_allocation) --{ -- MYSQLND_PACKET_CACHED_SHA2_RESULT * p = (MYSQLND_PACKET_CACHED_SHA2_RESULT *) _packet; -- -- if (!stack_allocation) { -- mnd_pefree(p, p->header.persistent); -- } --} --/* }}} */ - /* {{{ packet_methods */ - static - mysqlnd_packet_methods packet_methods[PROT_LAST] = -@@ -2441,15 +2363,9 @@ mysqlnd_packet_methods packet_methods[PROT_LAST] = - php_mysqlnd_sha256_pk_request_response_read, - NULL, /* write */ - php_mysqlnd_sha256_pk_request_response_free_mem, -- }, /* PROT_SHA256_PK_REQUEST_RESPONSE_PACKET */ -- { -- sizeof(MYSQLND_PACKET_CACHED_SHA2_RESULT), -- php_mysqlnd_cached_sha2_result_read, -- php_mysqlnd_cached_sha2_result_write, -- php_mysqlnd_cached_sha2_result_free_mem -- } /* PROT_CACHED_SHA2_RESULT_PACKET */ -+ } /* PROT_SHA256_PK_REQUEST_RESPONSE_PACKET */ - }; --/* }}} */ -+/* }}} */ - - - /* {{{ mysqlnd_protocol::get_greet_packet */ -@@ -2798,30 +2714,6 @@ MYSQLND_METHOD(mysqlnd_protocol, get_sha256_pk_request_response_packet)(MYSQLND_ - } - /* }}} */ - --/* {{{ mysqlnd_protocol::init_cached_sha2_result_packet */ --static struct st_mysqlnd_packet_cached_sha2_result * --MYSQLND_METHOD(mysqlnd_protocol, get_cached_sha2_result_packet) --(MYSQLND_PROTOCOL_PAYLOAD_DECODER_FACTORY * const factory, const zend_bool persistent) --{ -- struct st_mysqlnd_packet_cached_sha2_result * packet = mnd_pecalloc(1, packet_methods[PROT_CACHED_SHA2_RESULT_PACKET].struct_size, persistent); -- DBG_ENTER("mysqlnd_protocol::init_cached_sha2_result_packet"); -- if (packet) { -- memset(packet, 0, sizeof(*packet)); -- packet->header.m = &packet_methods[PROT_CACHED_SHA2_RESULT_PACKET]; -- packet->header.factory = factory; -- -- packet->header.protocol_frame_codec = factory->conn->protocol_frame_codec; -- packet->header.vio = factory->conn->vio; -- packet->header.stats = factory->conn->stats; -- packet->header.error_info = factory->conn->error_info; -- packet->header.connection_state = &factory->conn->state; -- -- packet->header.persistent = persistent; -- } -- DBG_RETURN(packet); --} --/* }}} */ -- - - /* {{{ mysqlnd_protocol::send_command */ - static enum_func_status -@@ -3052,7 +2944,6 @@ MYSQLND_CLASS_METHODS_START(mysqlnd_protocol_payload_decoder_factory) - MYSQLND_METHOD(mysqlnd_protocol, get_change_user_response_packet), - MYSQLND_METHOD(mysqlnd_protocol, get_sha256_pk_request_packet), - MYSQLND_METHOD(mysqlnd_protocol, get_sha256_pk_request_response_packet), -- MYSQLND_METHOD(mysqlnd_protocol, get_cached_sha2_result_packet), - - MYSQLND_METHOD(mysqlnd_protocol, send_command), - MYSQLND_METHOD(mysqlnd_protocol, send_command_handle_response), -diff --git a/ext/mysqlnd/mysqlnd_wireprotocol.h b/ext/mysqlnd/mysqlnd_wireprotocol.h -index c749afeb75f5..d6855580b4e0 100644 ---- a/ext/mysqlnd/mysqlnd_wireprotocol.h -+++ b/ext/mysqlnd/mysqlnd_wireprotocol.h -@@ -292,16 +292,6 @@ typedef struct st_mysqlnd_packet_sha256_pk_request_response { - size_t public_key_len; - } MYSQLND_PACKET_SHA256_PK_REQUEST_RESPONSE; - --typedef struct st_mysqlnd_packet_cached_sha2_result { -- MYSQLND_PACKET_HEADER header; -- uint8_t response_code; -- uint8_t result; -- uint8_t request; -- zend_uchar * password; -- size_t password_len; --} MYSQLND_PACKET_CACHED_SHA2_RESULT; -- -- - - zend_ulong php_mysqlnd_net_field_length(const zend_uchar **packet); - zend_uchar * php_mysqlnd_net_store_length(zend_uchar *packet, const uint64_t length); diff --git a/SOURCES/php-7.2.12-phpize.patch b/SOURCES/php-7.2.12-phpize.patch new file mode 100644 index 0000000..77913a5 --- /dev/null +++ b/SOURCES/php-7.2.12-phpize.patch @@ -0,0 +1,35 @@ +diff -up php-7.2.12RC1/scripts/phpize.in.headers php-7.2.12RC1/scripts/phpize.in +--- php-7.2.12RC1/scripts/phpize.in.headers 2018-10-23 11:47:43.000000000 +0200 ++++ php-7.2.12RC1/scripts/phpize.in 2018-10-23 11:49:51.651818777 +0200 +@@ -162,6 +162,15 @@ phpize_autotools() + $PHP_AUTOHEADER || exit 1 + } + ++phpize_check_headers() ++{ ++ if test ! -f $includedir/main/php.h; then ++ echo "Can't find PHP headers in $includedir" ++ echo "The php-devel package is required for use of this command." ++ exit 1 ++ fi ++} ++ + # Main script + + case "$1" in +@@ -180,12 +189,15 @@ case "$1" in + + # Version + --version|-v) ++ phpize_check_headers + phpize_print_api_numbers + exit 0 + ;; + + # Default + *) ++ phpize_check_headers ++ + phpize_check_configm4 0 + + phpize_check_build_files diff --git a/SOURCES/php-7.2.16-systzdata-v17.patch b/SOURCES/php-7.2.16-systzdata-v17.patch new file mode 100644 index 0000000..640bff2 --- /dev/null +++ b/SOURCES/php-7.2.16-systzdata-v17.patch @@ -0,0 +1,658 @@ +# License: MIT +# http://opensource.org/licenses/MIT + +Add support for use of the system timezone database, rather +than embedding a copy. Discussed upstream but was not desired. + +History: +r17: adapt for autotool change in 7.2.16RC1 +r16: adapt for timelib 2017.06 (in 7.2.3RC1) +r15: adapt for timelib 2017.05beta7 (in 7.2.0RC1) +r14: improve check for valid tz file +r13: adapt for upstream changes to use PHP allocator +r12: adapt for upstream changes for new zic +r11: use canonical names to avoid more case sensitivity issues + round lat/long from zone.tab towards zero per builtin db +r10: make timezone case insensitive +r9: fix another compile error without --with-system-tzdata configured (Michael Heimpold) +r8: fix compile error without --with-system-tzdata configured +r7: improve check for valid timezone id to exclude directories +r6: fix fd leak in r5, fix country code/BC flag use in + timezone_identifiers_list() using system db, + fix use of PECL timezonedb to override system db, +r5: reverts addition of "System/Localtime" fake tzname. + updated for 5.3.0, parses zone.tab to pick up mapping between + timezone name, country code and long/lat coords +r4: added "System/Localtime" tzname which uses /etc/localtime +r3: fix a crash if /usr/share/zoneinfo doesn't exist (Raphael Geissert) +r2: add filesystem trawl to set up name alias index +r1: initial revision + +diff -up php-7.2.16RC1/ext/date/config0.m4.systzdata php-7.2.16RC1/ext/date/config0.m4 +--- php-7.2.16RC1/ext/date/config0.m4.systzdata 2019-02-19 11:22:22.223741585 +0100 ++++ php-7.2.16RC1/ext/date/config0.m4 2019-02-19 11:23:05.089111556 +0100 +@@ -10,6 +10,19 @@ io.h + dnl Check for strtoll, atoll + AC_CHECK_FUNCS(strtoll atoll) + ++PHP_ARG_WITH(system-tzdata, for use of system timezone data, ++[ --with-system-tzdata[=DIR] to specify use of system timezone data], ++no, no) ++ ++if test "$PHP_SYSTEM_TZDATA" != "no"; then ++ AC_DEFINE(HAVE_SYSTEM_TZDATA, 1, [Define if system timezone data is used]) ++ ++ if test "$PHP_SYSTEM_TZDATA" != "yes"; then ++ AC_DEFINE_UNQUOTED(HAVE_SYSTEM_TZDATA_PREFIX, "$PHP_SYSTEM_TZDATA", ++ [Define for location of system timezone data]) ++ fi ++fi ++ + PHP_DATE_CFLAGS="-I@ext_builddir@/lib -DZEND_ENABLE_STATIC_TSRMLS_CACHE=1 -DHAVE_TIMELIB_CONFIG_H=1" + timelib_sources="lib/astro.c lib/dow.c lib/parse_date.c lib/parse_tz.c + lib/timelib.c lib/tm2unixtime.c lib/unixtime2tm.c lib/parse_iso_intervals.c lib/interval.c" +diff -up php-7.2.16RC1/ext/date/lib/parse_tz.c.systzdata php-7.2.16RC1/ext/date/lib/parse_tz.c +--- php-7.2.16RC1/ext/date/lib/parse_tz.c.systzdata 2019-02-19 11:13:22.000000000 +0100 ++++ php-7.2.16RC1/ext/date/lib/parse_tz.c 2019-02-19 11:19:40.245313535 +0100 +@@ -25,8 +25,21 @@ + #include "timelib.h" + #include "timelib_private.h" + ++#ifdef HAVE_SYSTEM_TZDATA ++#include ++#include ++#include ++#include ++#include ++ ++#include "php_scandir.h" ++ ++#else + #define TIMELIB_SUPPORTS_V2DATA + #include "timezonedb.h" ++#endif ++ ++#include + + #if (defined(__APPLE__) || defined(__APPLE_CC__)) && (defined(__BIG_ENDIAN__) || defined(__LITTLE_ENDIAN__)) + # if defined(__LITTLE_ENDIAN__) +@@ -67,6 +80,11 @@ static int read_php_preamble(const unsig + { + uint32_t version; + ++ if (memcmp(*tzf, "TZif", 4) == 0) { ++ *tzf += 20; ++ return 0; ++ } ++ + /* read ID */ + version = (*tzf)[3] - '0'; + *tzf += 4; +@@ -374,7 +392,429 @@ void timelib_dump_tzinfo(timelib_tzinfo + } + } + +-static int seek_to_tz_position(const unsigned char **tzf, char *timezone, const timelib_tzdb *tzdb) ++#ifdef HAVE_SYSTEM_TZDATA ++ ++#ifdef HAVE_SYSTEM_TZDATA_PREFIX ++#define ZONEINFO_PREFIX HAVE_SYSTEM_TZDATA_PREFIX ++#else ++#define ZONEINFO_PREFIX "/usr/share/zoneinfo" ++#endif ++ ++/* System timezone database pointer. */ ++static const timelib_tzdb *timezonedb_system; ++ ++/* Hash table entry for the cache of the zone.tab mapping table. */ ++struct location_info { ++ char code[2]; ++ double latitude, longitude; ++ char name[64]; ++ char *comment; ++ struct location_info *next; ++}; ++ ++/* Cache of zone.tab. */ ++static struct location_info **system_location_table; ++ ++/* Size of the zone.tab hash table; a random-ish prime big enough to ++ * prevent too many collisions. */ ++#define LOCINFO_HASH_SIZE (1021) ++ ++/* Compute a case insensitive hash of str */ ++static uint32_t tz_hash(const char *str) ++{ ++ const unsigned char *p = (const unsigned char *)str; ++ uint32_t hash = 5381; ++ int c; ++ ++ while ((c = tolower(*p++)) != '\0') { ++ hash = (hash << 5) ^ hash ^ c; ++ } ++ ++ return hash % LOCINFO_HASH_SIZE; ++} ++ ++/* Parse an ISO-6709 date as used in zone.tab. Returns end of the ++ * parsed string on success, or NULL on parse error. On success, ++ * writes the parsed number to *result. */ ++static char *parse_iso6709(char *p, double *result) ++{ ++ double v, sign; ++ char *pend; ++ size_t len; ++ ++ if (*p == '+') ++ sign = 1.0; ++ else if (*p == '-') ++ sign = -1.0; ++ else ++ return NULL; ++ ++ p++; ++ for (pend = p; *pend >= '0' && *pend <= '9'; pend++) ++ ;; ++ ++ /* Annoying encoding used by zone.tab has no decimal point, so use ++ * the length to determine the format: ++ * ++ * 4 = DDMM ++ * 5 = DDDMM ++ * 6 = DDMMSS ++ * 7 = DDDMMSS ++ */ ++ len = pend - p; ++ if (len < 4 || len > 7) { ++ return NULL; ++ } ++ ++ /* p => [D]DD */ ++ v = (p[0] - '0') * 10.0 + (p[1] - '0'); ++ p += 2; ++ if (len == 5 || len == 7) ++ v = v * 10.0 + (*p++ - '0'); ++ /* p => MM[SS] */ ++ v += (10.0 * (p[0] - '0') ++ + p[1] - '0') / 60.0; ++ p += 2; ++ /* p => [SS] */ ++ if (len > 5) { ++ v += (10.0 * (p[0] - '0') ++ + p[1] - '0') / 3600.0; ++ p += 2; ++ } ++ ++ /* Round to five decimal place, not because it's a good idea, ++ * but, because the builtin data uses rounded data, so, match ++ * that. */ ++ *result = trunc(v * sign * 100000.0) / 100000.0; ++ ++ return p; ++} ++ ++/* This function parses the zone.tab file to build up the mapping of ++ * timezone to country code and geographic location, and returns a ++ * hash table. The hash table is indexed by the function: ++ * ++ * tz_hash(timezone-name) ++ */ ++static struct location_info **create_location_table(void) ++{ ++ struct location_info **li, *i; ++ char zone_tab[PATH_MAX]; ++ char line[512]; ++ FILE *fp; ++ ++ strncpy(zone_tab, ZONEINFO_PREFIX "/zone.tab", sizeof zone_tab); ++ ++ fp = fopen(zone_tab, "r"); ++ if (!fp) { ++ return NULL; ++ } ++ ++ li = calloc(LOCINFO_HASH_SIZE, sizeof *li); ++ ++ while (fgets(line, sizeof line, fp)) { ++ char *p = line, *code, *name, *comment; ++ uint32_t hash; ++ double latitude, longitude; ++ ++ while (isspace(*p)) ++ p++; ++ ++ if (*p == '#' || *p == '\0' || *p == '\n') ++ continue; ++ ++ if (!isalpha(p[0]) || !isalpha(p[1]) || p[2] != '\t') ++ continue; ++ ++ /* code => AA */ ++ code = p; ++ p[2] = 0; ++ p += 3; ++ ++ /* coords => [+-][D]DDMM[SS][+-][D]DDMM[SS] */ ++ p = parse_iso6709(p, &latitude); ++ if (!p) { ++ continue; ++ } ++ p = parse_iso6709(p, &longitude); ++ if (!p) { ++ continue; ++ } ++ ++ if (!p || *p != '\t') { ++ continue; ++ } ++ ++ /* name = string */ ++ name = ++p; ++ while (*p != '\t' && *p && *p != '\n') ++ p++; ++ ++ *p++ = '\0'; ++ ++ /* comment = string */ ++ comment = p; ++ while (*p != '\t' && *p && *p != '\n') ++ p++; ++ ++ if (*p == '\n' || *p == '\t') ++ *p = '\0'; ++ ++ hash = tz_hash(name); ++ i = malloc(sizeof *i); ++ memcpy(i->code, code, 2); ++ strncpy(i->name, name, sizeof i->name); ++ i->comment = strdup(comment); ++ i->longitude = longitude; ++ i->latitude = latitude; ++ i->next = li[hash]; ++ li[hash] = i; ++ /* printf("%s [%u, %f, %f]\n", name, hash, latitude, longitude); */ ++ } ++ ++ fclose(fp); ++ ++ return li; ++} ++ ++/* Return location info from hash table, using given timezone name. ++ * Returns NULL if the name could not be found. */ ++const struct location_info *find_zone_info(struct location_info **li, ++ const char *name) ++{ ++ uint32_t hash = tz_hash(name); ++ const struct location_info *l; ++ ++ if (!li) { ++ return NULL; ++ } ++ ++ for (l = li[hash]; l; l = l->next) { ++ if (timelib_strcasecmp(l->name, name) == 0) ++ return l; ++ } ++ ++ return NULL; ++} ++ ++/* Filter out some non-tzdata files and the posix/right databases, if ++ * present. */ ++static int index_filter(const struct dirent *ent) ++{ ++ return strcmp(ent->d_name, ".") != 0 ++ && strcmp(ent->d_name, "..") != 0 ++ && strcmp(ent->d_name, "posix") != 0 ++ && strcmp(ent->d_name, "posixrules") != 0 ++ && strcmp(ent->d_name, "right") != 0 ++ && strstr(ent->d_name, ".list") == NULL ++ && strstr(ent->d_name, ".tab") == NULL; ++} ++ ++static int sysdbcmp(const void *first, const void *second) ++{ ++ const timelib_tzdb_index_entry *alpha = first, *beta = second; ++ ++ return timelib_strcasecmp(alpha->id, beta->id); ++} ++ ++ ++/* Create the zone identifier index by trawling the filesystem. */ ++static void create_zone_index(timelib_tzdb *db) ++{ ++ size_t dirstack_size, dirstack_top; ++ size_t index_size, index_next; ++ timelib_tzdb_index_entry *db_index; ++ char **dirstack; ++ ++ /* LIFO stack to hold directory entries to scan; each slot is a ++ * directory name relative to the zoneinfo prefix. */ ++ dirstack_size = 32; ++ dirstack = malloc(dirstack_size * sizeof *dirstack); ++ dirstack_top = 1; ++ dirstack[0] = strdup(""); ++ ++ /* Index array. */ ++ index_size = 64; ++ db_index = malloc(index_size * sizeof *db_index); ++ index_next = 0; ++ ++ do { ++ struct dirent **ents; ++ char name[PATH_MAX], *top; ++ int count; ++ ++ /* Pop the top stack entry, and iterate through its contents. */ ++ top = dirstack[--dirstack_top]; ++ snprintf(name, sizeof name, ZONEINFO_PREFIX "/%s", top); ++ ++ count = php_scandir(name, &ents, index_filter, php_alphasort); ++ ++ while (count > 0) { ++ struct stat st; ++ const char *leaf = ents[count - 1]->d_name; ++ ++ snprintf(name, sizeof name, ZONEINFO_PREFIX "/%s/%s", ++ top, leaf); ++ ++ if (strlen(name) && stat(name, &st) == 0) { ++ /* Name, relative to the zoneinfo prefix. */ ++ const char *root = top; ++ ++ if (root[0] == '/') root++; ++ ++ snprintf(name, sizeof name, "%s%s%s", root, ++ *root ? "/": "", leaf); ++ ++ if (S_ISDIR(st.st_mode)) { ++ if (dirstack_top == dirstack_size) { ++ dirstack_size *= 2; ++ dirstack = realloc(dirstack, ++ dirstack_size * sizeof *dirstack); ++ } ++ dirstack[dirstack_top++] = strdup(name); ++ } ++ else { ++ if (index_next == index_size) { ++ index_size *= 2; ++ db_index = realloc(db_index, ++ index_size * sizeof *db_index); ++ } ++ ++ db_index[index_next++].id = strdup(name); ++ } ++ } ++ ++ free(ents[--count]); ++ } ++ ++ if (count != -1) free(ents); ++ free(top); ++ } while (dirstack_top); ++ ++ qsort(db_index, index_next, sizeof *db_index, sysdbcmp); ++ ++ db->index = db_index; ++ db->index_size = index_next; ++ ++ free(dirstack); ++} ++ ++#define FAKE_HEADER "1234\0??\1??" ++#define FAKE_UTC_POS (7 - 4) ++ ++/* Create a fake data segment for database 'sysdb'. */ ++static void fake_data_segment(timelib_tzdb *sysdb, ++ struct location_info **info) ++{ ++ size_t n; ++ char *data, *p; ++ ++ data = malloc(3 * sysdb->index_size + 7); ++ ++ p = mempcpy(data, FAKE_HEADER, sizeof(FAKE_HEADER) - 1); ++ ++ for (n = 0; n < sysdb->index_size; n++) { ++ const struct location_info *li; ++ timelib_tzdb_index_entry *ent; ++ ++ ent = (timelib_tzdb_index_entry *)&sysdb->index[n]; ++ ++ /* Lookup the timezone name in the hash table. */ ++ if (strcmp(ent->id, "UTC") == 0) { ++ ent->pos = FAKE_UTC_POS; ++ continue; ++ } ++ ++ li = find_zone_info(info, ent->id); ++ if (li) { ++ /* If found, append the BC byte and the ++ * country code; set the position for this ++ * section of timezone data. */ ++ ent->pos = (p - data) - 4; ++ *p++ = '\1'; ++ *p++ = li->code[0]; ++ *p++ = li->code[1]; ++ } ++ else { ++ /* If not found, the timezone data can ++ * point at the header. */ ++ ent->pos = 0; ++ } ++ } ++ ++ sysdb->data = (unsigned char *)data; ++} ++ ++/* Returns true if the passed-in stat structure describes a ++ * probably-valid timezone file. */ ++static int is_valid_tzfile(const struct stat *st, int fd) ++{ ++ if (fd) { ++ char buf[20]; ++ if (read(fd, buf, 20)!=20) { ++ return 0; ++ } ++ lseek(fd, SEEK_SET, 0); ++ if (memcmp(buf, "TZif", 4)) { ++ return 0; ++ } ++ } ++ return S_ISREG(st->st_mode) && st->st_size > 20; ++} ++ ++/* To allow timezone names to be used case-insensitively, find the ++ * canonical name for this timezone, if possible. */ ++static const char *canonical_tzname(const char *timezone) ++{ ++ if (timezonedb_system) { ++ timelib_tzdb_index_entry *ent, lookup; ++ ++ lookup.id = (char *)timezone; ++ ++ ent = bsearch(&lookup, timezonedb_system->index, ++ timezonedb_system->index_size, sizeof lookup, ++ sysdbcmp); ++ if (ent) { ++ return ent->id; ++ } ++ } ++ ++ return timezone; ++} ++ ++/* Return the mmap()ed tzfile if found, else NULL. On success, the ++ * length of the mapped data is placed in *length. */ ++static char *map_tzfile(const char *timezone, size_t *length) ++{ ++ char fname[PATH_MAX]; ++ struct stat st; ++ char *p; ++ int fd; ++ ++ if (timezone[0] == '\0' || strstr(timezone, "..") != NULL) { ++ return NULL; ++ } ++ ++ snprintf(fname, sizeof fname, ZONEINFO_PREFIX "/%s", canonical_tzname(timezone)); ++ ++ fd = open(fname, O_RDONLY); ++ if (fd == -1) { ++ return NULL; ++ } else if (fstat(fd, &st) != 0 || !is_valid_tzfile(&st, fd)) { ++ close(fd); ++ return NULL; ++ } ++ ++ *length = st.st_size; ++ p = mmap(NULL, st.st_size, PROT_READ, MAP_SHARED, fd, 0); ++ close(fd); ++ ++ return p != MAP_FAILED ? p : NULL; ++} ++ ++#endif ++ ++static int inmem_seek_to_tz_position(const unsigned char **tzf, char *timezone, const timelib_tzdb *tzdb) + { + int left = 0, right = tzdb->index_size - 1; + +@@ -400,9 +840,48 @@ static int seek_to_tz_position(const uns + return 0; + } + ++static int seek_to_tz_position(const unsigned char **tzf, char *timezone, ++ char **map, size_t *maplen, ++ const timelib_tzdb *tzdb) ++{ ++#ifdef HAVE_SYSTEM_TZDATA ++ if (tzdb == timezonedb_system) { ++ char *orig; ++ ++ orig = map_tzfile(timezone, maplen); ++ if (orig == NULL) { ++ return 0; ++ } ++ ++ (*tzf) = (unsigned char *)orig; ++ *map = orig; ++ return 1; ++ } ++ else ++#endif ++ { ++ return inmem_seek_to_tz_position(tzf, timezone, tzdb); ++ } ++} ++ + const timelib_tzdb *timelib_builtin_db(void) + { ++#ifdef HAVE_SYSTEM_TZDATA ++ if (timezonedb_system == NULL) { ++ timelib_tzdb *tmp = malloc(sizeof *tmp); ++ ++ tmp->version = "0.system"; ++ tmp->data = NULL; ++ create_zone_index(tmp); ++ system_location_table = create_location_table(); ++ fake_data_segment(tmp, system_location_table); ++ timezonedb_system = tmp; ++ } ++ ++ return timezonedb_system; ++#else + return &timezonedb_builtin; ++#endif + } + + const timelib_tzdb_index_entry *timelib_timezone_identifiers_list(const timelib_tzdb *tzdb, int *count) +@@ -414,7 +893,30 @@ const timelib_tzdb_index_entry *timelib_ + int timelib_timezone_id_is_valid(char *timezone, const timelib_tzdb *tzdb) + { + const unsigned char *tzf; +- return (seek_to_tz_position(&tzf, timezone, tzdb)); ++ ++#ifdef HAVE_SYSTEM_TZDATA ++ if (tzdb == timezonedb_system) { ++ char fname[PATH_MAX]; ++ struct stat st; ++ ++ if (timezone[0] == '\0' || strstr(timezone, "..") != NULL) { ++ return 0; ++ } ++ ++ if (system_location_table) { ++ if (find_zone_info(system_location_table, timezone) != NULL) { ++ /* found in cache */ ++ return 1; ++ } ++ } ++ ++ snprintf(fname, sizeof fname, ZONEINFO_PREFIX "/%s", canonical_tzname(timezone)); ++ ++ return stat(fname, &st) == 0 && is_valid_tzfile(&st, 0); ++ } ++#endif ++ ++ return (inmem_seek_to_tz_position(&tzf, timezone, tzdb)); + } + + static int skip_64bit_preamble(const unsigned char **tzf, timelib_tzinfo *tz) +@@ -456,12 +958,14 @@ static timelib_tzinfo* timelib_tzinfo_ct + timelib_tzinfo *timelib_parse_tzfile(char *timezone, const timelib_tzdb *tzdb, int *error_code) + { + const unsigned char *tzf; ++ char *memmap = NULL; ++ size_t maplen; + timelib_tzinfo *tmp; + int version; + int transitions_result, types_result; + unsigned int type; /* TIMELIB_TZINFO_PHP or TIMELIB_TZINFO_ZONEINFO */ + +- if (seek_to_tz_position(&tzf, timezone, tzdb)) { ++ if (seek_to_tz_position(&tzf, timezone, &memmap, &maplen, tzdb)) { + tmp = timelib_tzinfo_ctor(timezone); + + version = read_preamble(&tzf, tmp, &type); +@@ -484,6 +988,29 @@ timelib_tzinfo *timelib_parse_tzfile(cha + timelib_tzinfo_dtor(tmp); + return NULL; + } ++ ++#ifdef HAVE_SYSTEM_TZDATA ++ if (memmap) { ++ const struct location_info *li; ++ ++ /* TZif-style - grok the location info from the system database, ++ * if possible. */ ++ ++ if ((li = find_zone_info(system_location_table, timezone)) != NULL) { ++ tmp->location.comments = timelib_strdup(li->comment); ++ strncpy(tmp->location.country_code, li->code, 2); ++ tmp->location.longitude = li->longitude; ++ tmp->location.latitude = li->latitude; ++ tmp->bc = 1; ++ } ++ else { ++ set_default_location_and_comments(&tzf, tmp); ++ } ++ ++ /* Now done with the mmap segment - discard it. */ ++ munmap(memmap, maplen); ++ } else { ++#endif + if (version == 2 || version == 3) { + if (!skip_64bit_preamble(&tzf, tmp)) { + /* 64 bit preamble is not in place */ +@@ -501,6 +1028,9 @@ timelib_tzinfo *timelib_parse_tzfile(cha + } else { + set_default_location_and_comments(&tzf, tmp); + } ++#ifdef HAVE_SYSTEM_TZDATA ++ } ++#endif + } else { + *error_code = TIMELIB_ERROR_NO_SUCH_TIMEZONE; + tmp = NULL; diff --git a/SOURCES/php-7.2.3-systzdata-v16.patch b/SOURCES/php-7.2.3-systzdata-v16.patch deleted file mode 100644 index e488beb..0000000 --- a/SOURCES/php-7.2.3-systzdata-v16.patch +++ /dev/null @@ -1,654 +0,0 @@ -# License: MIT -# http://opensource.org/licenses/MIT - -Add support for use of the system timezone database, rather -than embedding a copy. Discussed upstream but was not desired. - -History: -r16: adapt for timelib 2017.06 (in 7.2.3RC1) -r15: adapt for timelib 2017.05beta7 (in 7.2.0RC1) -r14: improve check for valid tz file -r13: adapt for upstream changes to use PHP allocator -r12: adapt for upstream changes for new zic -r11: use canonical names to avoid more case sensitivity issues - round lat/long from zone.tab towards zero per builtin db -r10: make timezone case insensitive -r9: fix another compile error without --with-system-tzdata configured (Michael Heimpold) -r8: fix compile error without --with-system-tzdata configured -r7: improve check for valid timezone id to exclude directories -r6: fix fd leak in r5, fix country code/BC flag use in - timezone_identifiers_list() using system db, - fix use of PECL timezonedb to override system db, -r5: reverts addition of "System/Localtime" fake tzname. - updated for 5.3.0, parses zone.tab to pick up mapping between - timezone name, country code and long/lat coords -r4: added "System/Localtime" tzname which uses /etc/localtime -r3: fix a crash if /usr/share/zoneinfo doesn't exist (Raphael Geissert) -r2: add filesystem trawl to set up name alias index -r1: initial revision - -diff -up php-7.2.3RC1/ext/date/lib/parse_tz.c.systzdata php-7.2.3RC1/ext/date/lib/parse_tz.c ---- php-7.2.3RC1/ext/date/lib/parse_tz.c.systzdata 2018-02-13 20:18:34.000000000 +0100 -+++ php-7.2.3RC1/ext/date/lib/parse_tz.c 2018-02-14 06:14:23.484804852 +0100 -@@ -25,8 +25,21 @@ - #include "timelib.h" - #include "timelib_private.h" - -+#ifdef HAVE_SYSTEM_TZDATA -+#include -+#include -+#include -+#include -+#include -+ -+#include "php_scandir.h" -+ -+#else - #define TIMELIB_SUPPORTS_V2DATA - #include "timezonedb.h" -+#endif -+ -+#include - - #if (defined(__APPLE__) || defined(__APPLE_CC__)) && (defined(__BIG_ENDIAN__) || defined(__LITTLE_ENDIAN__)) - # if defined(__LITTLE_ENDIAN__) -@@ -67,6 +80,11 @@ static int read_php_preamble(const unsig - { - uint32_t version; - -+ if (memcmp(*tzf, "TZif", 4) == 0) { -+ *tzf += 20; -+ return 0; -+ } -+ - /* read ID */ - version = (*tzf)[3] - '0'; - *tzf += 4; -@@ -374,7 +392,429 @@ void timelib_dump_tzinfo(timelib_tzinfo - } - } - --static int seek_to_tz_position(const unsigned char **tzf, char *timezone, const timelib_tzdb *tzdb) -+#ifdef HAVE_SYSTEM_TZDATA -+ -+#ifdef HAVE_SYSTEM_TZDATA_PREFIX -+#define ZONEINFO_PREFIX HAVE_SYSTEM_TZDATA_PREFIX -+#else -+#define ZONEINFO_PREFIX "/usr/share/zoneinfo" -+#endif -+ -+/* System timezone database pointer. */ -+static const timelib_tzdb *timezonedb_system; -+ -+/* Hash table entry for the cache of the zone.tab mapping table. */ -+struct location_info { -+ char code[2]; -+ double latitude, longitude; -+ char name[64]; -+ char *comment; -+ struct location_info *next; -+}; -+ -+/* Cache of zone.tab. */ -+static struct location_info **system_location_table; -+ -+/* Size of the zone.tab hash table; a random-ish prime big enough to -+ * prevent too many collisions. */ -+#define LOCINFO_HASH_SIZE (1021) -+ -+/* Compute a case insensitive hash of str */ -+static uint32_t tz_hash(const char *str) -+{ -+ const unsigned char *p = (const unsigned char *)str; -+ uint32_t hash = 5381; -+ int c; -+ -+ while ((c = tolower(*p++)) != '\0') { -+ hash = (hash << 5) ^ hash ^ c; -+ } -+ -+ return hash % LOCINFO_HASH_SIZE; -+} -+ -+/* Parse an ISO-6709 date as used in zone.tab. Returns end of the -+ * parsed string on success, or NULL on parse error. On success, -+ * writes the parsed number to *result. */ -+static char *parse_iso6709(char *p, double *result) -+{ -+ double v, sign; -+ char *pend; -+ size_t len; -+ -+ if (*p == '+') -+ sign = 1.0; -+ else if (*p == '-') -+ sign = -1.0; -+ else -+ return NULL; -+ -+ p++; -+ for (pend = p; *pend >= '0' && *pend <= '9'; pend++) -+ ;; -+ -+ /* Annoying encoding used by zone.tab has no decimal point, so use -+ * the length to determine the format: -+ * -+ * 4 = DDMM -+ * 5 = DDDMM -+ * 6 = DDMMSS -+ * 7 = DDDMMSS -+ */ -+ len = pend - p; -+ if (len < 4 || len > 7) { -+ return NULL; -+ } -+ -+ /* p => [D]DD */ -+ v = (p[0] - '0') * 10.0 + (p[1] - '0'); -+ p += 2; -+ if (len == 5 || len == 7) -+ v = v * 10.0 + (*p++ - '0'); -+ /* p => MM[SS] */ -+ v += (10.0 * (p[0] - '0') -+ + p[1] - '0') / 60.0; -+ p += 2; -+ /* p => [SS] */ -+ if (len > 5) { -+ v += (10.0 * (p[0] - '0') -+ + p[1] - '0') / 3600.0; -+ p += 2; -+ } -+ -+ /* Round to five decimal place, not because it's a good idea, -+ * but, because the builtin data uses rounded data, so, match -+ * that. */ -+ *result = trunc(v * sign * 100000.0) / 100000.0; -+ -+ return p; -+} -+ -+/* This function parses the zone.tab file to build up the mapping of -+ * timezone to country code and geographic location, and returns a -+ * hash table. The hash table is indexed by the function: -+ * -+ * tz_hash(timezone-name) -+ */ -+static struct location_info **create_location_table(void) -+{ -+ struct location_info **li, *i; -+ char zone_tab[PATH_MAX]; -+ char line[512]; -+ FILE *fp; -+ -+ strncpy(zone_tab, ZONEINFO_PREFIX "/zone.tab", sizeof zone_tab); -+ -+ fp = fopen(zone_tab, "r"); -+ if (!fp) { -+ return NULL; -+ } -+ -+ li = calloc(LOCINFO_HASH_SIZE, sizeof *li); -+ -+ while (fgets(line, sizeof line, fp)) { -+ char *p = line, *code, *name, *comment; -+ uint32_t hash; -+ double latitude, longitude; -+ -+ while (isspace(*p)) -+ p++; -+ -+ if (*p == '#' || *p == '\0' || *p == '\n') -+ continue; -+ -+ if (!isalpha(p[0]) || !isalpha(p[1]) || p[2] != '\t') -+ continue; -+ -+ /* code => AA */ -+ code = p; -+ p[2] = 0; -+ p += 3; -+ -+ /* coords => [+-][D]DDMM[SS][+-][D]DDMM[SS] */ -+ p = parse_iso6709(p, &latitude); -+ if (!p) { -+ continue; -+ } -+ p = parse_iso6709(p, &longitude); -+ if (!p) { -+ continue; -+ } -+ -+ if (!p || *p != '\t') { -+ continue; -+ } -+ -+ /* name = string */ -+ name = ++p; -+ while (*p != '\t' && *p && *p != '\n') -+ p++; -+ -+ *p++ = '\0'; -+ -+ /* comment = string */ -+ comment = p; -+ while (*p != '\t' && *p && *p != '\n') -+ p++; -+ -+ if (*p == '\n' || *p == '\t') -+ *p = '\0'; -+ -+ hash = tz_hash(name); -+ i = malloc(sizeof *i); -+ memcpy(i->code, code, 2); -+ strncpy(i->name, name, sizeof i->name); -+ i->comment = strdup(comment); -+ i->longitude = longitude; -+ i->latitude = latitude; -+ i->next = li[hash]; -+ li[hash] = i; -+ /* printf("%s [%u, %f, %f]\n", name, hash, latitude, longitude); */ -+ } -+ -+ fclose(fp); -+ -+ return li; -+} -+ -+/* Return location info from hash table, using given timezone name. -+ * Returns NULL if the name could not be found. */ -+const struct location_info *find_zone_info(struct location_info **li, -+ const char *name) -+{ -+ uint32_t hash = tz_hash(name); -+ const struct location_info *l; -+ -+ if (!li) { -+ return NULL; -+ } -+ -+ for (l = li[hash]; l; l = l->next) { -+ if (timelib_strcasecmp(l->name, name) == 0) -+ return l; -+ } -+ -+ return NULL; -+} -+ -+/* Filter out some non-tzdata files and the posix/right databases, if -+ * present. */ -+static int index_filter(const struct dirent *ent) -+{ -+ return strcmp(ent->d_name, ".") != 0 -+ && strcmp(ent->d_name, "..") != 0 -+ && strcmp(ent->d_name, "posix") != 0 -+ && strcmp(ent->d_name, "posixrules") != 0 -+ && strcmp(ent->d_name, "right") != 0 -+ && strstr(ent->d_name, ".list") == NULL -+ && strstr(ent->d_name, ".tab") == NULL; -+} -+ -+static int sysdbcmp(const void *first, const void *second) -+{ -+ const timelib_tzdb_index_entry *alpha = first, *beta = second; -+ -+ return timelib_strcasecmp(alpha->id, beta->id); -+} -+ -+ -+/* Create the zone identifier index by trawling the filesystem. */ -+static void create_zone_index(timelib_tzdb *db) -+{ -+ size_t dirstack_size, dirstack_top; -+ size_t index_size, index_next; -+ timelib_tzdb_index_entry *db_index; -+ char **dirstack; -+ -+ /* LIFO stack to hold directory entries to scan; each slot is a -+ * directory name relative to the zoneinfo prefix. */ -+ dirstack_size = 32; -+ dirstack = malloc(dirstack_size * sizeof *dirstack); -+ dirstack_top = 1; -+ dirstack[0] = strdup(""); -+ -+ /* Index array. */ -+ index_size = 64; -+ db_index = malloc(index_size * sizeof *db_index); -+ index_next = 0; -+ -+ do { -+ struct dirent **ents; -+ char name[PATH_MAX], *top; -+ int count; -+ -+ /* Pop the top stack entry, and iterate through its contents. */ -+ top = dirstack[--dirstack_top]; -+ snprintf(name, sizeof name, ZONEINFO_PREFIX "/%s", top); -+ -+ count = php_scandir(name, &ents, index_filter, php_alphasort); -+ -+ while (count > 0) { -+ struct stat st; -+ const char *leaf = ents[count - 1]->d_name; -+ -+ snprintf(name, sizeof name, ZONEINFO_PREFIX "/%s/%s", -+ top, leaf); -+ -+ if (strlen(name) && stat(name, &st) == 0) { -+ /* Name, relative to the zoneinfo prefix. */ -+ const char *root = top; -+ -+ if (root[0] == '/') root++; -+ -+ snprintf(name, sizeof name, "%s%s%s", root, -+ *root ? "/": "", leaf); -+ -+ if (S_ISDIR(st.st_mode)) { -+ if (dirstack_top == dirstack_size) { -+ dirstack_size *= 2; -+ dirstack = realloc(dirstack, -+ dirstack_size * sizeof *dirstack); -+ } -+ dirstack[dirstack_top++] = strdup(name); -+ } -+ else { -+ if (index_next == index_size) { -+ index_size *= 2; -+ db_index = realloc(db_index, -+ index_size * sizeof *db_index); -+ } -+ -+ db_index[index_next++].id = strdup(name); -+ } -+ } -+ -+ free(ents[--count]); -+ } -+ -+ if (count != -1) free(ents); -+ free(top); -+ } while (dirstack_top); -+ -+ qsort(db_index, index_next, sizeof *db_index, sysdbcmp); -+ -+ db->index = db_index; -+ db->index_size = index_next; -+ -+ free(dirstack); -+} -+ -+#define FAKE_HEADER "1234\0??\1??" -+#define FAKE_UTC_POS (7 - 4) -+ -+/* Create a fake data segment for database 'sysdb'. */ -+static void fake_data_segment(timelib_tzdb *sysdb, -+ struct location_info **info) -+{ -+ size_t n; -+ char *data, *p; -+ -+ data = malloc(3 * sysdb->index_size + 7); -+ -+ p = mempcpy(data, FAKE_HEADER, sizeof(FAKE_HEADER) - 1); -+ -+ for (n = 0; n < sysdb->index_size; n++) { -+ const struct location_info *li; -+ timelib_tzdb_index_entry *ent; -+ -+ ent = (timelib_tzdb_index_entry *)&sysdb->index[n]; -+ -+ /* Lookup the timezone name in the hash table. */ -+ if (strcmp(ent->id, "UTC") == 0) { -+ ent->pos = FAKE_UTC_POS; -+ continue; -+ } -+ -+ li = find_zone_info(info, ent->id); -+ if (li) { -+ /* If found, append the BC byte and the -+ * country code; set the position for this -+ * section of timezone data. */ -+ ent->pos = (p - data) - 4; -+ *p++ = '\1'; -+ *p++ = li->code[0]; -+ *p++ = li->code[1]; -+ } -+ else { -+ /* If not found, the timezone data can -+ * point at the header. */ -+ ent->pos = 0; -+ } -+ } -+ -+ sysdb->data = (unsigned char *)data; -+} -+ -+/* Returns true if the passed-in stat structure describes a -+ * probably-valid timezone file. */ -+static int is_valid_tzfile(const struct stat *st, int fd) -+{ -+ if (fd) { -+ char buf[20]; -+ if (read(fd, buf, 20)!=20) { -+ return 0; -+ } -+ lseek(fd, SEEK_SET, 0); -+ if (memcmp(buf, "TZif", 4)) { -+ return 0; -+ } -+ } -+ return S_ISREG(st->st_mode) && st->st_size > 20; -+} -+ -+/* To allow timezone names to be used case-insensitively, find the -+ * canonical name for this timezone, if possible. */ -+static const char *canonical_tzname(const char *timezone) -+{ -+ if (timezonedb_system) { -+ timelib_tzdb_index_entry *ent, lookup; -+ -+ lookup.id = (char *)timezone; -+ -+ ent = bsearch(&lookup, timezonedb_system->index, -+ timezonedb_system->index_size, sizeof lookup, -+ sysdbcmp); -+ if (ent) { -+ return ent->id; -+ } -+ } -+ -+ return timezone; -+} -+ -+/* Return the mmap()ed tzfile if found, else NULL. On success, the -+ * length of the mapped data is placed in *length. */ -+static char *map_tzfile(const char *timezone, size_t *length) -+{ -+ char fname[PATH_MAX]; -+ struct stat st; -+ char *p; -+ int fd; -+ -+ if (timezone[0] == '\0' || strstr(timezone, "..") != NULL) { -+ return NULL; -+ } -+ -+ snprintf(fname, sizeof fname, ZONEINFO_PREFIX "/%s", canonical_tzname(timezone)); -+ -+ fd = open(fname, O_RDONLY); -+ if (fd == -1) { -+ return NULL; -+ } else if (fstat(fd, &st) != 0 || !is_valid_tzfile(&st, fd)) { -+ close(fd); -+ return NULL; -+ } -+ -+ *length = st.st_size; -+ p = mmap(NULL, st.st_size, PROT_READ, MAP_SHARED, fd, 0); -+ close(fd); -+ -+ return p != MAP_FAILED ? p : NULL; -+} -+ -+#endif -+ -+static int inmem_seek_to_tz_position(const unsigned char **tzf, char *timezone, const timelib_tzdb *tzdb) - { - int left = 0, right = tzdb->index_size - 1; - -@@ -400,9 +840,48 @@ static int seek_to_tz_position(const uns - return 0; - } - -+static int seek_to_tz_position(const unsigned char **tzf, char *timezone, -+ char **map, size_t *maplen, -+ const timelib_tzdb *tzdb) -+{ -+#ifdef HAVE_SYSTEM_TZDATA -+ if (tzdb == timezonedb_system) { -+ char *orig; -+ -+ orig = map_tzfile(timezone, maplen); -+ if (orig == NULL) { -+ return 0; -+ } -+ -+ (*tzf) = (unsigned char *)orig; -+ *map = orig; -+ return 1; -+ } -+ else -+#endif -+ { -+ return inmem_seek_to_tz_position(tzf, timezone, tzdb); -+ } -+} -+ - const timelib_tzdb *timelib_builtin_db(void) - { -+#ifdef HAVE_SYSTEM_TZDATA -+ if (timezonedb_system == NULL) { -+ timelib_tzdb *tmp = malloc(sizeof *tmp); -+ -+ tmp->version = "0.system"; -+ tmp->data = NULL; -+ create_zone_index(tmp); -+ system_location_table = create_location_table(); -+ fake_data_segment(tmp, system_location_table); -+ timezonedb_system = tmp; -+ } -+ -+ return timezonedb_system; -+#else - return &timezonedb_builtin; -+#endif - } - - const timelib_tzdb_index_entry *timelib_timezone_identifiers_list(const timelib_tzdb *tzdb, int *count) -@@ -414,7 +893,30 @@ const timelib_tzdb_index_entry *timelib_ - int timelib_timezone_id_is_valid(char *timezone, const timelib_tzdb *tzdb) - { - const unsigned char *tzf; -- return (seek_to_tz_position(&tzf, timezone, tzdb)); -+ -+#ifdef HAVE_SYSTEM_TZDATA -+ if (tzdb == timezonedb_system) { -+ char fname[PATH_MAX]; -+ struct stat st; -+ -+ if (timezone[0] == '\0' || strstr(timezone, "..") != NULL) { -+ return 0; -+ } -+ -+ if (system_location_table) { -+ if (find_zone_info(system_location_table, timezone) != NULL) { -+ /* found in cache */ -+ return 1; -+ } -+ } -+ -+ snprintf(fname, sizeof fname, ZONEINFO_PREFIX "/%s", canonical_tzname(timezone)); -+ -+ return stat(fname, &st) == 0 && is_valid_tzfile(&st, 0); -+ } -+#endif -+ -+ return (inmem_seek_to_tz_position(&tzf, timezone, tzdb)); - } - - static int skip_64bit_preamble(const unsigned char **tzf, timelib_tzinfo *tz) -@@ -456,12 +958,14 @@ static timelib_tzinfo* timelib_tzinfo_ct - timelib_tzinfo *timelib_parse_tzfile(char *timezone, const timelib_tzdb *tzdb, int *error_code) - { - const unsigned char *tzf; -+ char *memmap = NULL; -+ size_t maplen; - timelib_tzinfo *tmp; - int version; - int transitions_result, types_result; - unsigned int type; /* TIMELIB_TZINFO_PHP or TIMELIB_TZINFO_ZONEINFO */ - -- if (seek_to_tz_position(&tzf, timezone, tzdb)) { -+ if (seek_to_tz_position(&tzf, timezone, &memmap, &maplen, tzdb)) { - tmp = timelib_tzinfo_ctor(timezone); - - version = read_preamble(&tzf, tmp, &type); -@@ -484,6 +988,29 @@ timelib_tzinfo *timelib_parse_tzfile(cha - timelib_tzinfo_dtor(tmp); - return NULL; - } -+ -+#ifdef HAVE_SYSTEM_TZDATA -+ if (memmap) { -+ const struct location_info *li; -+ -+ /* TZif-style - grok the location info from the system database, -+ * if possible. */ -+ -+ if ((li = find_zone_info(system_location_table, timezone)) != NULL) { -+ tmp->location.comments = timelib_strdup(li->comment); -+ strncpy(tmp->location.country_code, li->code, 2); -+ tmp->location.longitude = li->longitude; -+ tmp->location.latitude = li->latitude; -+ tmp->bc = 1; -+ } -+ else { -+ set_default_location_and_comments(&tzf, tmp); -+ } -+ -+ /* Now done with the mmap segment - discard it. */ -+ munmap(memmap, maplen); -+ } else { -+#endif - if (version == 2 || version == 3) { - if (!skip_64bit_preamble(&tzf, tmp)) { - /* 64 bit preamble is not in place */ -@@ -501,6 +1028,9 @@ timelib_tzinfo *timelib_parse_tzfile(cha - } else { - set_default_location_and_comments(&tzf, tmp); - } -+#ifdef HAVE_SYSTEM_TZDATA -+ } -+#endif - } else { - *error_code = TIMELIB_ERROR_NO_SUCH_TIMEZONE; - tmp = NULL; -diff -up php-7.2.3RC1/ext/date/lib/timelib.m4.systzdata php-7.2.3RC1/ext/date/lib/timelib.m4 ---- php-7.2.3RC1/ext/date/lib/timelib.m4.systzdata 2018-02-13 20:18:34.000000000 +0100 -+++ php-7.2.3RC1/ext/date/lib/timelib.m4 2018-02-14 06:11:54.273089963 +0100 -@@ -81,3 +81,16 @@ io.h - - dnl Check for strtoll, atoll - AC_CHECK_FUNCS(strtoll atoll strftime gettimeofday) -+ -+PHP_ARG_WITH(system-tzdata, for use of system timezone data, -+[ --with-system-tzdata[=DIR] to specify use of system timezone data], -+no, no) -+ -+if test "$PHP_SYSTEM_TZDATA" != "no"; then -+ AC_DEFINE(HAVE_SYSTEM_TZDATA, 1, [Define if system timezone data is used]) -+ -+ if test "$PHP_SYSTEM_TZDATA" != "yes"; then -+ AC_DEFINE_UNQUOTED(HAVE_SYSTEM_TZDATA_PREFIX, "$PHP_SYSTEM_TZDATA", -+ [Define for location of system timezone data]) -+ fi -+fi diff --git a/SPECS/php.spec b/SPECS/php.spec index 53e12f6..f51ac48 100644 --- a/SPECS/php.spec +++ b/SPECS/php.spec @@ -87,8 +87,8 @@ Summary: PHP scripting language for creating dynamic web sites Name: %{?scl_prefix}php -Version: 7.2.10 -Release: 3%{?dist} +Version: 7.2.24 +Release: 1%{?dist} # All files licensed under PHP version 3.01, except # Zend is licensed under Zend # TSRM is licensed under BSD @@ -125,9 +125,9 @@ Patch9: php-7.0.7-curl.patch # Functional changes Patch40: php-7.2.4-dlopen.patch -Patch42: php-7.2.3-systzdata-v16.patch +Patch42: php-7.2.16-systzdata-v17.patch # See http://bugs.php.net/53436 -Patch43: php-5.4.0-phpize.patch +Patch43: php-7.2.12-phpize.patch # Use -lldap_r for OpenLDAP Patch45: php-7.2.3-ldap_r.patch # Make php_config.h constant across builds @@ -138,8 +138,6 @@ Patch47: php-5.6.3-phpinfo.patch Patch48: php-7.2.8-getallheaders.patch # Upstream fixes (100+) -Patch100: php-7.2.10-mysql8.patch -Patch101: php-7.2.10-fileinfo.patch # Security fixes (200+) @@ -688,6 +686,7 @@ support for JavaScript Object Notation (JSON) to PHP. %patch40 -p1 -b .dlopen %patch42 -p1 -b .systzdata %patch43 -p1 -b .headers +sed -e 's/php-devel/%{?scl_prefix}php-devel/' -i scripts/phpize.in %if 0%{?fedora} >= 18 || 0%{?rhel} >= 7 %patch45 -p1 -b .ldap_r %endif @@ -696,8 +695,6 @@ support for JavaScript Object Notation (JSON) to PHP. %patch48 -p1 -b .getallheaders # upstream patches -%patch100 -p1 -b .mysql8 -%patch101 -p1 -b .fileinfo # security patches @@ -1588,6 +1585,9 @@ fi %changelog +* Wed Oct 30 2019 Remi Collet - 7.2.24-1 +- update to 7.2.24 #1766603 + * Wed Nov 7 2018 Remi Collet - 7.2.10-3 - add upstream patch for fileinfo performance #1644378