diff options
author | Eugene Lamskoy | 2021-12-16 18:15:26 +0200 |
---|---|---|
committer | Eugene Lamskoy | 2021-12-16 18:15:26 +0200 |
commit | 82e9513a3e5770bc8ceef73f91c6d57148e75949 (patch) | |
tree | 9eb4ded7232e834bbb0ca66c283e5da7f2ce3f4f | |
parent | d592cbb0852cd36c2c18d44fd81afb446418af4e (diff) | |
download | aur-82e9513a3e5770bc8ceef73f91c6d57148e75949.tar.gz |
Upgraded pkgbuild
30 files changed, 6668 insertions, 804 deletions
@@ -1,153 +1,331 @@ +# Generated by makepkg 6.0.1 +# Thu Dec 16 15:49:05 UTC 2021 pkgbase = php72 - pkgdesc = php 7.2.34 compiled as to not conflict with mainline php + pkgdesc = PHP 7.2.34 compiled as to not conflict with mainline php pkgver = 7.2.34 - pkgrel = 6 + pkgrel = 7 url = http://www.php.net arch = i686 arch = x86_64 license = PHP checkdepends = procps-ng + makedepends = libtool + makedepends = autoconf + makedepends = automake + makedepends = patchelf + makedepends = gawk + makedepends = sed + makedepends = bash + makedepends = python + makedepends = libxml2 + makedepends = pam + makedepends = openssl + makedepends = openssl-1.0 + makedepends = argon2 + makedepends = libmcrypt + makedepends = libsodium + makedepends = libldap + makedepends = libsasl + makedepends = krb5 + makedepends = libxslt + makedepends = libzip + makedepends = freetds makedepends = apache makedepends = aspell makedepends = c-client makedepends = db makedepends = enchant - makedepends = gd + makedepends = readline makedepends = gmp makedepends = icu - makedepends = libmcrypt - makedepends = libxslt - makedepends = libzip makedepends = net-snmp makedepends = postgresql-libs makedepends = sqlite - makedepends = systemd - makedepends = tidy + makedepends = systemd-libs makedepends = unixodbc makedepends = curl - makedepends = libtool + makedepends = ncurses makedepends = freetds makedepends = pcre - makedepends = libsodium - makedepends = patchutils + makedepends = tidy + makedepends = libfbclient makedepends = oniguruma + makedepends = gd + makedepends = recode + makedepends = bzip2 + makedepends = gdbm + makedepends = zlib + source = https://php.net/distributions/php-7.2.34.tar.xz + source = pear-config-patcher.php + source = php-apache.conf + source = mysql-socket-php7.1.patch + source = enchant-php7.4.patch + source = debian-php-7.4.26.patch + source = php-phpinfo.patch + source = timezonedb-guess.patch + source = timezonedb-php7.4.patch + source = https://php.net/distributions/php-7.2.34.tar.xz + source = pear-config-patcher.php + source = php-apache.conf + source = fpm-numeric-uid-gid.patch + source = fpm-reload-sighup.patch + source = mysql-socket-php7.1.patch + source = php-enchant-php5.3.patch + source = php-enchant-depr.patch + source = php-freetype-2.9.1.patch + source = php-icu-php7.3.patch + source = recode-php5.4.patch + source = debian-php-7.3.33.patch + source = php-phpinfo.patch + source = timezonedb-guess.patch + source = timezonedb-php7.3.patch source = https://php.net/distributions/php-7.2.34.tar.xz - source = icu.patch - source = apache.patch - source = apache.conf - source = php-fpm.patch - source = php-fpm.tmpfiles - source = php.ini.patch - source = enchant.patch + source = pear-config-patcher.php + source = php-apache.conf + source = fpm-numeric-uid-gid.patch + source = fpm-reload-sighup.patch + source = mysql-socket-php7.1.patch + source = php-enchant-php5.3.patch + source = php-enchant-depr.patch source = php-freetype-2.9.1.patch + source = php-icu-php5.5.patch + source = recode-php5.4.patch + source = debian-php-7.2.34.patch + source = php-phpinfo.patch + source = timezonedb-guess.patch + source = timezonedb-php7.2.patch sha256sums = 409e11bc6a2c18707dfc44bc61c820ddfd81e17481470f3405ee7822d8379903 - sha256sums = e438f7a429915d9fe5affce2a32315b670fa0f2b2638ca51e7072374d367ca07 - sha256sums = a67ed00467fb886e73808a3246e7a6f6bfb60fa3c24a692e21a4dd474b8353fd - sha256sums = ebc0af1ef3a6baccb013d0ccb29923895a7b22ff2d032e3bba802dc6328301ce - sha256sums = bdd47c439c81b46384332c8b0180e70b80d8b38d844f0dde9d1be329e4c62f18 - sha256sums = 3217979d2ea17f9c6c9209e220d41a5f4e6a6b65fcc7cd5ab8d938f65ca2b59e - sha256sums = d47310dfa4c53fd30744e49b0bacfcabe055568a33af08e28bc5bc80a852b4c4 - sha256sums = b11c3de747ef222696f5135556d624e3f7f0135a3cb1b06082f1ec8e9b7eeb0a - sha256sums = f9fe57f809ac13e0043d18b795ef777af3e8c710a83745b37b09db536f683d2a + sha256sums = 0201d0fa811b80614737424a72c7bb127125807e5d7eeec5e1578a0a58f77d2f + sha256sums = 6d0ad9becb5470ce8e5929d7d45660b0f32579038978496317544c5310281a91 + sha256sums = 0a3a6e8ff04ff1e0869befcf2c7bca4e886d94065da6d7a10b809a4750b961a0 + sha256sums = 433c542ba7f77f5f69d99e8e12ac0e9520cead3361a152ba2d04291b3d0365b8 + sha256sums = ccaad50d9e855bebd9d98bec4db6085dde3446ecd68bdbb58c1d450e1f5aeab9 + sha256sums = 558e780e93dfa861a366c49b4d156d8fc43f17898f001ae6033ec63c33d5d41c + sha256sums = 40bcc1e5058602302198d0925e431495391d8469499593af477f59d84d32f764 + sha256sums = 6ef318bf8d53a2288d037e3284f4dbfc26c36fd2ecc7d62e3d5036c19ec0a707 + sha256sums = 409e11bc6a2c18707dfc44bc61c820ddfd81e17481470f3405ee7822d8379903 + sha256sums = 0201d0fa811b80614737424a72c7bb127125807e5d7eeec5e1578a0a58f77d2f + sha256sums = 6d0ad9becb5470ce8e5929d7d45660b0f32579038978496317544c5310281a91 + sha256sums = d175f0c14fdb22855090c93f76e18f04320d7bf15afc057ffde947f9bb361242 + sha256sums = f5ae925036744a5e88cea2698879aea0498e1e23aee7801923d90f16be383908 + sha256sums = 0a3a6e8ff04ff1e0869befcf2c7bca4e886d94065da6d7a10b809a4750b961a0 + sha256sums = 84d0b3bce1be8e0113f3ba63a3dcce774fc79a002d754a2e31348f24a574d8f7 + sha256sums = 3049b76460c65a70017ba2aac8f8c45725df2bbea458a96ec7164db63639e87f + sha256sums = 581d230715bb01a878cd8aba1c1f37c6123691ed80d9c43d53de381f09df8399 + sha256sums = 68517bf6fd6ab2890877252f4233f1f7134b412b29d2dba20ef14d6fd1ac368b + sha256sums = 19b64388efbeb178eda9e19cf089a096300ef2732d40c128d3ca424526724787 + sha256sums = d706ded57ed3e46a7993f9e3f5838eea690f66e59e2e3549c6dda1cec44bcc1f + sha256sums = 558e780e93dfa861a366c49b4d156d8fc43f17898f001ae6033ec63c33d5d41c + sha256sums = 40bcc1e5058602302198d0925e431495391d8469499593af477f59d84d32f764 + sha256sums = 1cb8f76b465e3c5cd383450bc1f898859f58270d3645fb7405f93d0e06cddac7 + sha256sums = 409e11bc6a2c18707dfc44bc61c820ddfd81e17481470f3405ee7822d8379903 + sha256sums = 0201d0fa811b80614737424a72c7bb127125807e5d7eeec5e1578a0a58f77d2f + sha256sums = 6d0ad9becb5470ce8e5929d7d45660b0f32579038978496317544c5310281a91 + sha256sums = d175f0c14fdb22855090c93f76e18f04320d7bf15afc057ffde947f9bb361242 + sha256sums = f5ae925036744a5e88cea2698879aea0498e1e23aee7801923d90f16be383908 + sha256sums = 0a3a6e8ff04ff1e0869befcf2c7bca4e886d94065da6d7a10b809a4750b961a0 + sha256sums = 84d0b3bce1be8e0113f3ba63a3dcce774fc79a002d754a2e31348f24a574d8f7 + sha256sums = 3049b76460c65a70017ba2aac8f8c45725df2bbea458a96ec7164db63639e87f + sha256sums = 581d230715bb01a878cd8aba1c1f37c6123691ed80d9c43d53de381f09df8399 + sha256sums = ed3184d5a6f7a3bf35ee32169f8dc3b6cba09c38f60e868e24652fe9a7dd844d + sha256sums = 19b64388efbeb178eda9e19cf089a096300ef2732d40c128d3ca424526724787 + sha256sums = 1377d3627fbccb6edca87742836771a6546ecca121bbd43c3981880217258c22 + sha256sums = 558e780e93dfa861a366c49b4d156d8fc43f17898f001ae6033ec63c33d5d41c + sha256sums = 40bcc1e5058602302198d0925e431495391d8469499593af477f59d84d32f764 + sha256sums = db38b1fe1f6d6aa80bbca3c142bf7a166e3e83212dcc1396f9ec706daad36ad2 pkgname = php72 pkgdesc = A general-purpose scripting language that is especially suited to web development - depends = libxml2 - depends = curl - depends = libzip + depends = zlib depends = pcre + depends = oniguruma + depends = readline + depends = argon2 + depends = openssl-1.0 + depends = openssl backup = etc/php72/php.ini +pkgname = php72-cli + pkgdesc = cli (command-line executable) version for php72 + depends = php72 + pkgname = php72-cgi - pkgdesc = CGI and FCGI SAPI for PHP + pkgdesc = CGI and FCGI SAPI for php72 depends = php72 pkgname = php72-apache - pkgdesc = Apache SAPI for PHP + pkgdesc = Apache SAPI for php72 depends = php72 depends = apache - backup = etc/httpd/conf/extra/php72_module.conf + backup = etc/httpd/conf/extra/ pkgname = php72-fpm - pkgdesc = FastCGI Process Manager for PHP + pkgdesc = FastCGI Process Manager for php72 depends = php72 - depends = systemd + depends = systemd-libs options = !emptydirs backup = etc/php72/php-fpm.conf backup = etc/php72/php-fpm.d/www.conf pkgname = php72-embed - pkgdesc = Embedded PHP SAPI library + pkgdesc = Embedded PHP SAPI library for php72 depends = php72 - depends = libsystemd + depends = ncurses + depends = systemd-libs options = !emptydirs -pkgname = php72-phpdbg - pkgdesc = Interactive PHP debugger +pkgname = php72-bz2 + pkgdesc = bz2 module for php72 depends = php72 - options = !emptydirs + depends = bzip2 + +pkgname = php72-bcmath + pkgdesc = bcmath module for php72 + depends = php72 + +pkgname = php72-curl + pkgdesc = curl module for php72 + depends = php72 + depends = curl pkgname = php72-dblib - pkgdesc = dblib module for PHP + pkgdesc = mssql and pdo_dblib modules for php72 depends = php72 depends = freetds + provides = php72-sybase=7.2.34 + +pkgname = php72-dba + pkgdesc = dba module for php72 + depends = php72 + depends = gdbm + depends = db pkgname = php72-enchant - pkgdesc = enchant module for PHP + pkgdesc = enchant module for php72 depends = php72 depends = enchant pkgname = php72-gd - pkgdesc = gd module for PHP + pkgdesc = gd module for php72 depends = php72 depends = gd + depends = libxpm + depends = libpng + depends = libjpeg + +pkgname = php72-gmp + pkgdesc = gmp module for php72 + depends = php72 + depends = gmp pkgname = php72-imap - pkgdesc = imap module for PHP + pkgdesc = imap module for php72 depends = php72 + depends = pam + depends = krb5 depends = c-client pkgname = php72-intl - pkgdesc = intl module for PHP + pkgdesc = intl module for php72 depends = php72 depends = icu +pkgname = php72-interbase + pkgdesc = Interbase modules for php72 + depends = php72 + depends = libfbclient + +pkgname = php72-ldap + pkgdesc = ldap module for php72 + depends = php72 + depends = libldap + depends = libsasl + +pkgname = php72-mysql + pkgdesc = MySQL modules for php72 + depends = php72 + pkgname = php72-odbc - pkgdesc = ODBC modules for PHP + pkgdesc = ODBC modules for php72 depends = php72 depends = unixodbc pkgname = php72-pgsql - pkgdesc = PostgreSQL modules for PHP + pkgdesc = PostgreSQL modules for php72 depends = php72 depends = postgresql-libs pkgname = php72-pspell - pkgdesc = pspell module for PHP + pkgdesc = pspell module for php72 depends = php72 depends = aspell pkgname = php72-snmp - pkgdesc = snmp module for PHP + pkgdesc = snmp module for php72 depends = php72 depends = net-snmp -pkgname = php72-sqlite - pkgdesc = sqlite module for PHP +pkgname = php72-soap + pkgdesc = soap module for php72 depends = php72 - depends = sqlite + depends = libxml2 pkgname = php72-tidy - pkgdesc = tidy module for PHP + pkgdesc = tidy module for php72 depends = php72 depends = tidy +pkgname = php72-sqlite + pkgdesc = sqlite module for php72 + depends = php72 + depends = sqlite + +pkgname = php72-xml + pkgdesc = xml modules for php72 + depends = php72 + depends = libxml2 + pkgname = php72-xsl - pkgdesc = xsl module for PHP + pkgdesc = xsl module for php72 depends = php72 + depends = php72-xml=7.2.34 depends = libxslt + depends = libxml2 + +pkgname = php72-zip + pkgdesc = zip module for php72 + depends = php72 + depends = libzip + +pkgname = php72-phpdbg + pkgdesc = Interactive PHP debugger for php72 + depends = php72 + options = !emptydirs + +pkgname = php72-pear + pkgdesc = PHP Extension and Application Repository for php72 + depends = php72 + depends = php72-xml + backup = etc/php72/pear.conf + +pkgname = php72-xmlrpc + pkgdesc = xmlrpc module for php72 + depends = php72 + +pkgname = php72-opcache + pkgdesc = opcache zend module for php72 + depends = php72 pkgname = php72-sodium - pkgdesc = sodium module for PHP + pkgdesc = sodium (libsodium) module for php72 depends = php72 depends = libsodium + +pkgname = php72-recode + pkgdesc = recode module for php72 + depends = php72 + depends = recode + +pkgname = php72-json + pkgdesc = json module for php72 + depends = php72 diff --git a/.gitignore b/.gitignore deleted file mode 100644 index de726ef3c9d0..000000000000 --- a/.gitignore +++ /dev/null @@ -1,7 +0,0 @@ -*.tar.xz -*.tar.gz -*.tar.bz2 -pkg/ -src/ -*.tar.zst - @@ -1,402 +1,1228 @@ -# Build props -phpbase=72 -pkgver=7.2.34 -pkgrel=6 -# Custom suffix -suffix= +_phpbase="72" +_suffix="" +pkgver="7.2.34" +pkgrel="7" +pkgbase="php${_phpbase}${_suffix}" +pkgdesc="PHP ${pkgver} compiled as to not conflict with mainline php" +_cppflags=" -DU_USING_ICU_NAMESPACE=1 -DU_DEFINE_FALSE_AND_TRUE=1 " -# Const props -arch=('i686' 'x86_64') -license=('PHP') -url='http://www.php.net' -makedepends=('apache' 'aspell' 'c-client' 'db' 'enchant' 'gd' 'gmp' 'icu' 'libmcrypt' 'libxslt' 'libzip' 'net-snmp' - 'postgresql-libs' 'sqlite' 'systemd' 'tidy' 'unixodbc' 'curl' 'libtool' 'freetds' 'pcre' 'libsodium' - 'patchutils' 'oniguruma') -checkdepends=('procps-ng') +_pkgver_icu="64-1" +_suffix="" +_suffix_so="7" -# Has "php" string -_base="php" +pkgname=( + "${pkgbase}" + "php${_phpbase}-cli${_suffix}" + "php${_phpbase}-cgi${_suffix}" + "php${_phpbase}-apache${_suffix}" + "php${_phpbase}-fpm${_suffix}" + "php${_phpbase}-embed${_suffix}" + "php${_phpbase}-bz2${_suffix}" + "php${_phpbase}-bcmath${_suffix}" + "php${_phpbase}-curl${_suffix}" + "php${_phpbase}-dblib${_suffix}" + "php${_phpbase}-dba${_suffix}" + "php${_phpbase}-enchant${_suffix}" + "php${_phpbase}-gd${_suffix}" + "php${_phpbase}-gmp${_suffix}" + "php${_phpbase}-imap${_suffix}" + "php${_phpbase}-intl${_suffix}" + "php${_phpbase}-interbase${_suffix}" + "php${_phpbase}-ldap${_suffix}" + "php${_phpbase}-mysql${_suffix}" + "php${_phpbase}-odbc${_suffix}" + "php${_phpbase}-pgsql${_suffix}" + "php${_phpbase}-pspell${_suffix}" + "php${_phpbase}-snmp${_suffix}" + "php${_phpbase}-soap${_suffix}" + "php${_phpbase}-tidy${_suffix}" + "php${_phpbase}-sqlite${_suffix}" + "php${_phpbase}-xml${_suffix}" + "php${_phpbase}-xsl${_suffix}" + "php${_phpbase}-zip${_suffix}" + "php${_phpbase}-phpdbg${_suffix}" + "php${_phpbase}-pear${_suffix}" + "php${_phpbase}-xmlrpc${_suffix}" + "php${_phpbase}-opcache${_suffix}" + "php${_phpbase}-sodium${_suffix}" + "php${_phpbase}-recode${_suffix}" + "php${_phpbase}-json${_suffix}" +) -# Calculated props -pkgdesc="${_base} ${pkgver} compiled as to not conflict with mainline ${_base}" -pkgbase="${_base}${phpbase}${suffix}" -pkgname=("${pkgbase}" "${_base}${phpbase}-"{cgi,apache,fpm,embed,phpdbg,dblib,enchant,gd,imap,intl,odbc,pgsql,pspell,snmp,sqlite,tidy,xsl,sodium}${suffix}) +source=( + "https://php.net/distributions/php-${pkgver}.tar.xz" + "pear-config-patcher.php" + "php-apache.conf" + "mysql-socket-php7.1.patch" + "enchant-php7.4.patch" + "debian-php-7.4.26.patch" + "php-phpinfo.patch" + "timezonedb-guess.patch" + "timezonedb-php7.4.patch" + "https://php.net/distributions/php-${pkgver}.tar.xz" + "pear-config-patcher.php" + "php-apache.conf" + "fpm-numeric-uid-gid.patch" + "fpm-reload-sighup.patch" + "mysql-socket-php7.1.patch" + "php-enchant-php5.3.patch" + "php-enchant-depr.patch" + "php-freetype-2.9.1.patch" + "php-icu-php7.3.patch" + "recode-php5.4.patch" + "debian-php-7.3.33.patch" + "php-phpinfo.patch" + "timezonedb-guess.patch" + "timezonedb-php7.3.patch" + "https://php.net/distributions/php-${pkgver}.tar.xz" + "pear-config-patcher.php" + "php-apache.conf" + "fpm-numeric-uid-gid.patch" + "fpm-reload-sighup.patch" + "mysql-socket-php7.1.patch" + "php-enchant-php5.3.patch" + "php-enchant-depr.patch" + "php-freetype-2.9.1.patch" + "php-icu-php5.5.patch" + "recode-php5.4.patch" + "debian-php-7.2.34.patch" + "php-phpinfo.patch" + "timezonedb-guess.patch" + "timezonedb-php7.2.patch" +) -# Source -source=("https://php.net/distributions/${_base}-${pkgver}.tar.xz" 'icu.patch' - 'apache.patch' 'apache.conf' 'php-fpm.patch' 'php-fpm.tmpfiles' 'php.ini.patch' 'enchant.patch' 'php-freetype-2.9.1.patch' ) +depends=( +) -# Version specific" -name_libapache_source="libphp7.so" -name_libembed_source="libphp7.so" +checkdepends=( + "procps-ng" +) -# Path -path_prefix="usr" -path_config="etc/${pkgbase}" -path_extensions="${path_prefix}/lib/${pkgbase}/modules" +arch=( + "i686" + "x86_64" +) -# Binary names -name_phpconfig="php-config${phpbase}${suffix}" -name_phpize="phpize${phpbase}${suffix}" -name_phar="phar${phpbase}${suffix}" +_patches=( + "fpm-numeric-uid-gid.patch" + "fpm-reload-sighup.patch" + "mysql-socket-php7.1.patch" + "php-enchant-php5.3.patch" + "php-enchant-depr.patch" + "php-freetype-2.9.1.patch" + "php-icu-php5.5.patch" + "recode-php5.4.patch" + "debian-php-7.2.34.patch" + "php-phpinfo.patch" + "timezonedb-guess.patch" + "timezonedb-php7.2.patch" +) -# Conf names -name_apache_module_conf="${pkgbase/-/_}_module.conf" +_build_apache_cfg="etc/httpd/conf/extra" +_build_bundled_gd="0" +_build_ffi="0" +_build_fpm_group="http" +_build_fpm_user="http" +_build_icu_src_dir="icu/source" +_build_interbase="1" +_build_json="1" +_build_mcrypt="0" +_build_mssql="0" +_build_opcache="1" +_build_openssl_v10_patch="0" +_build_openssl_v11_patch="0" +_build_outdated_mysql="0" +_build_pear="1" +_build_per_sapi="0" +_build_phpdbg="1" +_build_recode="1" +_build_shared_gd="1" +_build_sodium="1" +_build_static_pdo="0" +_build_uses_autoconf="1" +_build_wddx="1" +_build_with_custom_icu="0" +_build_xmlrpc="1" +_priority_default="20" +_priority_json="15" +_priority_mysqlnd="10" +_priority_opcache="10" +_priority_pdo="10" +_priority_xml="15" +_phpextensions="\ + --enable-bcmath=shared \ + --with-bz2=shared,/usr \ + --with-gmp=shared,/usr \ + --enable-intl=shared \ + --with-pspell=shared,/usr \ + --with-snmp=shared,/usr \ + --with-tidy=shared,/usr \ + --enable-filter \ + --with-readline \ + --enable-pcntl \ + --enable-calendar=shared \ + --enable-ctype=shared \ + --enable-exif=shared \ + --enable-fileinfo=shared \ + --enable-ftp=shared \ + --with-gettext=shared,/usr \ + --with-iconv=shared \ + --enable-phar=shared \ + --enable-posix=shared \ + --enable-shmop=shared \ + --enable-sockets=shared \ + --enable-sysvmsg=shared \ + --enable-sysvsem=shared \ + --enable-sysvshm=shared \ + --enable-tokenizer=shared \ + --enable-mysqlnd=shared \ + --enable-mysqlnd-compression-support \ + --with-mysqli=shared,mysqlnd \ + --with-pdo-mysql=shared,mysqlnd \ + --with-mysql-sock=/run/mysqld/mysqld.sock \ + --enable-dom=shared \ + --enable-simplexml=shared \ + --enable-xml=shared \ + --enable-xmlreader=shared \ + --enable-xmlwriter=shared \ + --with-xsl=shared \ + --enable-dba=shared \ + --with-db4=/usr \ + --with-gdbm \ + --enable-inifile \ + --enable-flatfile \ + --with-imap=shared,/usr \ + --with-kerberos \ + --with-imap-ssl=yes \ + --enable-json=shared \ + --with-ffi=shared \ + --with-zip=shared \ + --with-curl=shared \ + --with-enchant=shared \ + --with-pcre-jit \ + --with-external-pcre=/usr \ + --with-openssl \ + --with-unixODBC=shared \ + --with-pdo-odbc=shared,unixODBC,/usr \ + --with-ldap=shared,/usr \ + --with-ldap-sasl \ + --with-pdo-sqlite=shared,/usr \ + --with-sqlite3=shared \ + --enable-gd=shared \ + --with-external-gd=/usr \ + --with-jpeg \ + --with-xpm \ + --with-webp \ + --with-freetype \ + --enable-pdo=shared \ + --with-zlib \ + --with-pdo-firebird=shared,/usr \ + --with-pgsql=shared,/usr \ + --with-pdo-pgsql=shared,/usr \ + --enable-soap=shared \ + --enable-opcache \ + --enable-huge-code-pages \ + --with-sodium=shared \ + --enable-mbstring=shared \ + --enable-mbregex \ + --with-pdo-dblib=shared,/usr \ + --enable-bcmath=shared \ + --with-bz2=shared,/usr \ + --with-gmp=shared,/usr \ + --enable-intl=shared \ + --with-pspell=shared,/usr \ + --with-snmp=shared,/usr \ + --with-tidy=shared,/usr \ + --enable-filter \ + --with-readline \ + --enable-pcntl \ + --enable-calendar=shared \ + --enable-ctype=shared \ + --enable-exif=shared \ + --enable-fileinfo=shared \ + --enable-ftp=shared \ + --with-gettext=shared,/usr \ + --with-iconv=shared \ + --enable-phar=shared \ + --enable-posix=shared \ + --enable-shmop=shared \ + --enable-sockets=shared \ + --enable-sysvmsg=shared \ + --enable-sysvsem=shared \ + --enable-sysvshm=shared \ + --enable-tokenizer=shared \ + --enable-mysqlnd=shared \ + --enable-mysqlnd-compression-support \ + --with-mysqli=shared,mysqlnd \ + --with-pdo-mysql=shared,mysqlnd \ + --with-mysql-sock=/run/mysqld/mysqld.sock \ + --enable-dom=shared \ + --enable-simplexml=shared \ + --enable-xml=shared \ + --enable-xmlreader=shared \ + --enable-xmlwriter=shared \ + --with-xsl=shared \ + --enable-dba=shared \ + --with-db4=/usr \ + --with-gdbm \ + --enable-inifile \ + --enable-flatfile \ + --with-imap=shared,/usr \ + --with-kerberos \ + --with-imap-ssl=yes \ + --enable-json=shared \ + --with-recode=shared \ + --enable-zip=shared \ + --with-curl=shared,/usr \ + --with-enchant=shared,/usr \ + --with-pcre-regex=/usr \ + --with-openssl=/usr \ + --with-unixODBC=shared,/usr \ + --with-pdo-odbc=shared,unixODBC,/usr \ + --with-ldap=shared,/usr \ + --with-ldap-sasl=/usr \ + --with-pdo-sqlite=shared,/usr \ + --with-sqlite3=shared,/usr \ + --enable-hash \ + --with-mhash=/usr \ + --with-gd=shared,/usr \ + --with-webp-dir=/usr \ + --with-jpeg-dir=/usr \ + --with-png-dir=/usr \ + --with-xpm-dir=/usr \ + --with-freetype-dir=/usr \ + --with-libzip=/usr \ + --enable-pdo=shared \ + --with-zlib \ + --enable-wddx=shared \ + --with-pdo-firebird=shared,/usr \ + --with-interbase=shared,/usr \ + --with-pgsql=shared,/usr \ + --with-pdo-pgsql=shared,/usr \ + --enable-soap=shared \ + --with-libxml-dir=/usr \ + --enable-opcache \ + --enable-huge-code-pages \ + --with-xmlrpc=shared \ + --with-sodium=shared \ + --enable-mbstring=shared \ + --enable-mbregex \ + --enable-mbregex-backtrack \ + --with-pdo-dblib=shared,/usr \ + --enable-bcmath=shared \ + --with-bz2=shared,/usr \ + --with-gmp=shared,/usr \ + --enable-intl=shared \ + --with-pspell=shared,/usr \ + --with-snmp=shared,/usr \ + --with-tidy=shared,/usr \ + --enable-filter \ + --with-readline \ + --enable-pcntl \ + --enable-calendar=shared \ + --enable-ctype=shared \ + --enable-exif=shared \ + --enable-fileinfo=shared \ + --enable-ftp=shared \ + --with-gettext=shared,/usr \ + --with-iconv=shared \ + --enable-phar=shared \ + --enable-posix=shared \ + --enable-shmop=shared \ + --enable-sockets=shared \ + --enable-sysvmsg=shared \ + --enable-sysvsem=shared \ + --enable-sysvshm=shared \ + --enable-tokenizer=shared \ + --enable-mysqlnd=shared \ + --enable-mysqlnd-compression-support \ + --with-mysqli=shared,mysqlnd \ + --with-pdo-mysql=shared,mysqlnd \ + --with-mysql-sock=/run/mysqld/mysqld.sock \ + --enable-dom=shared \ + --enable-simplexml=shared \ + --enable-xml=shared \ + --enable-xmlreader=shared \ + --enable-xmlwriter=shared \ + --with-xsl=shared \ + --enable-dba=shared \ + --with-db4=/usr \ + --with-gdbm \ + --enable-inifile \ + --enable-flatfile \ + --with-imap=shared,/usr \ + --with-kerberos \ + --with-imap-ssl=yes \ + --enable-json=shared \ + --with-recode=shared \ + --enable-zip=shared \ + --with-curl=shared,/usr \ + --with-enchant=shared,/usr \ + --with-pcre-regex=/usr \ + --with-openssl=/usr \ + --with-unixODBC=shared,/usr \ + --with-pdo-odbc=shared,unixODBC,/usr \ + --with-ldap=shared,/usr \ + --with-ldap-sasl=/usr \ + --with-pdo-sqlite=shared,/usr \ + --with-sqlite3=shared,/usr \ + --enable-hash \ + --with-mhash=/usr \ + --with-gd=shared,/usr \ + --with-webp-dir=/usr \ + --with-jpeg-dir=/usr \ + --with-png-dir=/usr \ + --with-xpm-dir=/usr \ + --with-freetype-dir=/usr \ + --with-libzip=/usr \ + --enable-pdo=shared \ + --with-zlib \ + --enable-wddx=shared \ + --with-pdo-firebird=shared,/usr \ + --with-interbase=shared,/usr \ + --with-pgsql=shared,/usr \ + --with-pdo-pgsql=shared,/usr \ + --enable-soap=shared \ + --with-libxml-dir=/usr \ + --enable-opcache \ + --enable-huge-code-pages \ + --with-xmlrpc=shared \ + --with-sodium=shared \ + --enable-mbstring=shared \ + --enable-mbregex \ + --enable-mbregex-backtrack \ + --with-pdo-dblib=shared,/usr" +_phpconfig="\ + --prefix=/usr \ + --sbindir=/usr/bin \ + --localstatedir=/var \ + --with-layout=GNU \ + --disable-debug \ + --mandir=/usr/share/man \ + --srcdir=../php-${pkgver} \ + --sysconfdir=/etc/php${_phpbase}${_suffix} \ + --libdir=/usr/lib/php${_phpbase}${_suffix} \ + --datadir=/usr/share/php${_phpbase}${_suffix} \ + --program-suffix=${_phpbase}${_suffix} \ + --with-config-file-path=/etc/php${_phpbase}${_suffix} \ + --with-config-file-scan-dir=/etc/php${_phpbase}${_suffix}/conf.d \ + --without-pear \ + --datarootdir=/usr/share/php${_phpbase}${_suffix} \ + --disable-rpath \ + --config-cache \ + --with-system-tzdata" +_phpextensions_fpm="\ + --with-fpm-user=${_build_fpm_user} \ + --with-fpm-group=${_build_fpm_group} \ + --with-fpm-systemd \ + --with-fpm-acl" + + + +makedepends=( + 'libtool' 'autoconf' 'automake' 'patchelf' 'gawk' 'sed' 'bash' 'python' 'libxml2' 'pam' + 'openssl' 'openssl-1.0' 'argon2' 'libmcrypt' 'libsodium' 'libldap' 'libsasl' 'krb5' + 'libxslt' 'libzip' 'freetds' 'apache' 'aspell' 'c-client' 'db' 'enchant' 'readline' + 'gmp' 'icu' 'net-snmp' 'postgresql-libs' 'sqlite' 'systemd-libs' 'unixodbc' 'curl' 'ncurses' + 'freetds' 'pcre' 'tidy' 'libfbclient' 'oniguruma' 'gd' 'recode' 'bzip2' 'gdbm' 'zlib' +) +arch=('i686' 'x86_64') +checkdepends=('procps-ng') +license=('PHP') +url='http://www.php.net' + + +# Prepare it prepare() { - cd "${_base}-${pkgver}" - patch -p0 -i ${srcdir}/apache.patch - patch -p0 -i ${srcdir}/php-fpm.patch - patch -p0 -i ${srcdir}/php.ini.patch - patch -p1 -i ${srcdir}/enchant.patch - patch -p1 -i ${srcdir}/php-freetype-2.9.1.patch - patch -p1 -i ${srcdir}/icu.patch - rm tests/output/stream_isatty_*.phpt + pushd "php-${pkgver}" + echo "[SED] sapi/apache2handler/config.m4 and configure" + sed -e '/APACHE_THREADED_MPM=/d' \ + -i sapi/apache2handler/config.m4 \ + -i configure + + echo "[SED] sapi/fpm/Makefile.frag" + sed -e 's#php-fpm\$(program_suffix)#php\$(program_suffix)-fpm#' \ + -e 's/.conf.default/.conf/g' \ + -i sapi/fpm/Makefile.frag + + echo "[SED] sapi/fpm/php-fpm.service.in" + sed -E "s|ExecStart[\s]?=[\s]?@([a-zA-Z_]+)@/php-fpm|ExecStart=@\1@/php${_phpbase}${_suffix}-fpm|g; \ + s|PIDFile[\s]?=[\s]?@([a-zA-Z_]+)@/run/php-fpm.pid|PIDFile=/run/php${_phpbase}${_suffix}-fpm/php-fpm.pid|g" \ + -i sapi/fpm/php-fpm.service.in + + local _check_files=("sapi/fpm/www.conf.in" "sapi/fpm/php-fpm.conf.in"); + for file_conf in "${_check_files[@]}"; do + if [[ ! -f $file_conf ]]; then + continue; + fi + echo "[SED] ${file_conf}" + sed -e "s#^listen =.*#listen = /run/php${_phpbase}${_suffix}-fpm/php-fpm.sock#" \ + -e "s#run/php-fpm.pid#/run/php${_phpbase}${_suffix}-fpm/php-fpm.pid#" \ + -e 's#^;*[ \t]*listen.owner =#listen.owner =#' \ + -e 's#^;*[ \t]*listen.group =#listen.group =#' \ + -e 's#^;*[ \t]*error_log =.*#error_log = syslog#' \ + -e 's#^;*[ \t]*chdir =.*#;chdir = /srv/http#' \ + -i "${file_conf}" + done + + echo "[SED] php.ini-production" + sed -e 's#^;*[ \t]*extension_dir[\t ]*=.*/.*$#extension_dir = "___EXTENSIONDIR___"#' \ + -e "s#___EXTENSIONDIR___#/usr/lib/php${_phpbase}${_suffix}/modules#g" \ + -e "s#^;*[ \t]*extension=#;extension=#g" \ + -i php.ini-production + + for patch_name in "${_patches[@]}"; do + echo "[PATCH] Applying source patch ${patch_name}"; + patch -p1 -i "../${patch_name}" + done + if ((_build_uses_autoconf)); then + autoconf + fi + echo "[SED] Sed for ${pkgdir}/usr/lib/php${_phpbase}${_suffix}/scripts/phpize.m4" + sed -i "/^\[ --with-php-config=/c \[ --with-php-config=PATH Path to php-config [php-config${_phpbase}${_suffix}]], php-config${_phpbase}${_suffix}, no)" "scripts/phpize.m4" + rm -f tests/output/stream_isatty_*.phpt + rm -f Zend/tests/arginfo_zpp_mismatch*.phpt + popd } +# BUILD them all build() { - CPPFLAGS+=' -DU_USING_ICU_NAMESPACE=1' - CPPFLAGS+=' -DU_DEFINE_FALSE_AND_TRUE=1' - CPPFLAGS+=' -DEL_BUILD=1' - export EXTENSION_DIR="/${path_extensions}" - - local _phpconfig="--srcdir=../${_base}-${pkgver} \ - --config-cache \ - --cache-file=config-${pkgbase}-${pkgver}-${pkgrel}.cache - --prefix=/${path_prefix} \ - --sbindir=/${path_prefix}/bin \ - --sysconfdir=/${path_config} \ - --localstatedir=/var \ - --libdir=/${path_prefix}/lib/${pkgbase} \ - --datarootdir=/${path_prefix}/share/${pkgbase} \ - --datadir=/${path_prefix}/share/${pkgbase} \ - --program-suffix=${phpbase}${suffix} \ - --with-layout=GNU \ - --with-config-file-path=/${path_config} \ - --with-config-file-scan-dir=/${path_config}/conf.d \ - --disable-rpath \ - --mandir=/${path_prefix}/share/man \ - --without-pear \ - " - - local _phpextensions="\ - --enable-bcmath=shared \ - --enable-calendar=shared \ - --enable-dba=shared \ - --enable-exif=shared \ - --enable-ftp=shared \ - --enable-intl=shared \ - --enable-mbstring \ - --enable-shmop=shared \ - --enable-soap=shared \ - --enable-sockets=shared \ - --enable-sysvmsg=shared \ - --enable-sysvsem=shared \ - --enable-sysvshm=shared \ - --enable-zip=shared \ - --with-bz2=shared \ - --with-curl=shared \ - --with-db4=/${path_prefix} \ - --with-enchant=shared,/${path_prefix} \ - --with-freetype-dir=/${path_prefix} \ - --with-gd=shared,/${path_prefix} \ - --with-gdbm \ - --with-gettext=shared \ - --with-gmp=shared \ - --with-iconv=shared \ - --with-imap-ssl \ - --with-imap=shared \ - --with-kerberos=/${path_prefix} \ - --with-ldap=shared \ - --with-ldap-sasl \ - --with-libzip \ - --with-mhash \ - --with-mysql-sock=/run/mysqld/mysqld.sock \ - --with-mysqli=shared,mysqlnd \ - --with-openssl \ - --with-pcre-regex=/${path_prefix} \ - --with-pdo-dblib=shared,/${path_prefix} \ - --with-pdo-mysql=shared,mysqlnd \ - --with-pdo-odbc=shared,unixODBC,/${path_prefix} \ - --with-pdo-pgsql=shared \ - --with-pdo-sqlite=shared,/${path_prefix} \ - --with-pgsql=shared \ - --with-pspell=shared \ - --with-readline \ - --with-snmp=shared \ - --with-sodium=shared \ - --with-sqlite3=shared,/${path_prefix} \ - --with-tidy=shared \ - --with-unixODBC=shared,/${path_prefix} \ - --with-xmlrpc=shared \ - --with-xsl=shared \ - --with-zlib \ - --enable-pcntl \ - " - - # php - if [ ! -d "${srcdir}/build" ]; then - mkdir "${srcdir}/build" + export EXTENSION_DIR="/usr/lib/php${_phpbase}${_suffix}/modules" + if ((_build_openssl_v10_patch)); then + export PHP_OPENSSL_DIR="/usr/lib/openssl-1.0" + fi + + if ((_build_with_custom_icu)); then + local _php5_icu_first="${srcdir}/${_build_icu_src_dir}/php${_phpbase}${suffix}-icu${_pkgver_icu}" + _ldflags="-Wl,-rpath=$ORIGIN/usr/lib/php${_phpbase}${_suffix}/icu${_pkgver_icu}/lib" + _phpextensions+=" --with-icu-dir=${_php5_icu_first} " + if [[ ! -d $_php5_icu_first ]]; then + mkdir -p "${_php5_icu_first}" + fi + pushd "${_build_icu_src_dir}" + ./configure --prefix="${_php5_icu_first}" \ + --sysconfdir="${_php5_icu_first}/etc" \ + --mandir="${_php5_icu_first}/share/man" \ + --sbindir="${_php5_icu_first}/bin" \ + --libdir="${_php5_icu_first}/lib" \ + --includedir="${_php5_icu_first}/include" \ + --disable-tests \ + --disable-debug + make + make install + ./configure --prefix="/usr/lib/php${_phpbase}${_suffix}/icu${_pkgver_icu}" \ + --sysconfdir="/usr/lib/php${_phpbase}${_suffix}/icu${_pkgver_icu}/etc" \ + --mandir="/usr/lib/php${_phpbase}${_suffix}/icu${_pkgver_icu}/share/man" \ + --sbindir="/usr/lib/php${_phpbase}${_suffix}/icu${_pkgver_icu}/bin" \ + --libdir="/usr/lib/php${_phpbase}${_suffix}/icu${_pkgver_icu}/lib" \ + --includedir="/usr/lib/php${_phpbase}${_suffix}/icu${_pkgver_icu}/include" \ + --disable-tests \ + --disable-debug + make + popd + fi + + if [[ ! -z "${_cppflags}" ]]; then + CPPFLAGS+=" $_cppflags " + fi + if [[ ! -z "${_ldflags}" ]]; then + LDFLAGS+=" $_ldflags " + fi + + + echo "[DEBUG] CPPFLAGS ${_cppflags}" + echo "[DEBUG] LDGFLAGS ${_ldflags}" + echo "[DEBUG] PHPCONF ${_phpconfig}" | sed -E 's|[ \t]+|\n|g'; + echo "[DEBUG] PHPEXT ${_phpextensions}" | sed -E 's|[ \t]+|\n |g'; + echo "[DEBUG] FPMEXT ${_phpextensions_fpm}" | sed -E 's|[ \t]+|\n|g'; + + if [[ ! -d "build" ]]; then + mkdir "build" + fi + + pushd "build" + if [[ -L configure ]]; then + rm configure fi - cd "${srcdir}/build" - if [ -L configure ]; then - rm configure + + ln -s "../php-${pkgver}/configure" + popd + if (( ! _build_per_sapi )); then + # SAPIs: cli+cgi+fpm+embed + pushd "build" + ./configure ${_phpconfig} \ + --enable-cgi \ + --enable-fpm \ + ${_phpextensions_fpm} \ + --enable-embed=shared \ + ${_phpextensions} + make + popd + else + # Per sapi build: cli,cgi,fpm,embed + + # cli + pushd "build" + ./configure ${_phpconfig} \ + --disable-cgi \ + ${_phpextensions} + make + popd + # cgi + cp -Ta build build-cgi + pushd build-cgi + ./configure ${_phpconfig} \ + --disable-cli \ + --enable-cgi \ + ${_phpextensions} + make + popd + + # fpm + cp -Ta build build-fpm + pushd build-fpm + ./configure ${_phpconfig} \ + --disable-cli \ + --enable-fpm \ + ${_phpextensions_fpm} \ + ${_phpextensions} + make + popd + + + # embed + cp -Ta build build-embed + pushd build-embed + ./configure ${_phpconfig} \ + --disable-cli \ + --enable-embed=shared \ + ${_phpextensions} + make + popd + fi + + # apache build + cp -a "build" "build-apache" + pushd "build-apache" + ./configure ${_phpconfig} \ + --with-apxs2 \ + ${_phpextensions} + make + popd + + # phpdbg build + if ((_build_phpdbg)); then + cp -a "build" "build-phpdbg" + pushd "build-phpdbg" + ./configure ${_phpconfig} \ + --enable-phpdbg \ + ${_phpextensions} + make + popd fi - ln -s ../${_base}-${pkgver}/configure - ./configure ${_phpconfig} \ - --enable-cgi \ - --enable-fpm \ - --with-fpm-systemd \ - --with-fpm-acl \ - --with-fpm-user=http \ - --with-fpm-group=http \ - --enable-embed=shared \ - ${_phpextensions} - make - - # apache - # reuse the previous run; this will save us a lot of time - cp -a "${srcdir}/build" "${srcdir}/build-apache" - cd "${srcdir}/build-apache" - ./configure ${_phpconfig} \ - --with-apxs2 \ - ${_phpextensions} - make - - # phpdbg - cp -a "${srcdir}/build" "${srcdir}/build-phpdbg" - cd "${srcdir}/build-phpdbg" - ./configure ${_phpconfig} \ - --enable-phpdbg \ - ${_phpextensions} - make + # PEAR build + if ((_build_pear)); then + cp -a "build" "build-pear" + # Pear can't be built properly with shared xml + local _ext_pear=$(echo ${_phpextensions} | sed 's/--enable-xml=shared/--enable-xml/g') + export PEAR_INSTALLDIR="/usr/share/php${_phpbase}${_suffix}/pear" + pushd "build-pear" + ./configure ${_phpconfig} \ + --disable-cgi \ + --with-pear \ + ${_ext_pear} + make + popd + fi + unset EXTENSION_DIR } check() { - cd "${_base}-${pkgver}" + pushd "php-${pkgver}" + # Check if sendmail was configured correctly (FS#47600) + ../build/sapi/cli/php -n -r 'echo ini_get("sendmail_path");' | grep -q '/usr/bin/sendmail' + + export REPORT_EXIT_STATUS=1 + export NO_INTERACTION=1 + export SKIP_ONLINE_TESTS=1 + export SKIP_SLOW_TESTS=1 - # Check if sendmail was configured correctly (FS#47600) - ${srcdir}/build/sapi/cli/php -n -r 'echo ini_get("sendmail_path");' | grep -q '/usr/bin/sendmail' + if ((_phpbase <= 54)); then + TEST_PHP_EXECUTABLE="../build/sapi/cli/php" \ + ../build/sapi/cli/php -n run-tests.php -n {tests,Zend} + elif ((_phpbase >= 55 && _phpbase < 73)); then + ../build/sapi/cli/php -n run-tests.php -n -P {tests,Zend} + elif ((73 == _phpbase)); then + export TESTS='tests Zend' + make test + elif ((_phpbase > 73)); then + export TEST_PHP_ARGS="-j$(nproc)" + export TESTS='tests Zend' + make test + fi + popd +} - export REPORT_EXIT_STATUS=1 - export NO_INTERACTION=1 - export SKIP_ONLINE_TESTS=1 - export SKIP_SLOW_TESTS=1 +# Custom code +_install_module_ini() { + local extension=$(echo "${1}" | sed 's/\.so//') + local priority="${_priority_default}" + case "${extension}" in + "json") + priority="${_priority_json}" + ;; + "xml") + priority="${_priority_xml}" + ;; + "mysqlnd") + priority="${_priority_mysqlnd}" + ;; + "pdo") + priority="${_priority_pdo}" + ;; + "opcache") + priority="${_priority_opcache}" + ;; + esac + local extension_type="extension" + case "${extension}" in + "opcache" | "xdebug") + extension_type="zend_extension" + ;; + "recode") + extension_type=";extension" + ;; + esac + + if [[ ! -d "${pkgdir}/etc/php${_phpbase}${_suffix}/conf.d" ]]; then + mkdir -p "${pkgdir}/etc/php${_phpbase}${_suffix}/conf.d" + fi + echo "${extension_type}=${extension}.so" > "${pkgdir}/etc/php${_phpbase}${_suffix}/conf.d/${priority}-${extension}.ini" + chmod 0644 "$pkgdir/etc/php${_phpbase}${_suffix}/conf.d/${priority}-${extension}.ini" + _last_priority=${priority} + _last_extension=${extension} +} - ${srcdir}/build/sapi/cli/php -n run-tests.php -n -P {tests,Zend} +_install_module() { + install -D -m755 "build/modules/${1}.so" "${pkgdir}/usr/lib/php${_phpbase}${_suffix}/modules/${1}.so"; + _install_module_ini "${1}" } +# Custom code end package_php72() { + # Binary names pkgdesc='A general-purpose scripting language that is especially suited to web development' - depends=('libxml2' 'curl' 'libzip' 'pcre') - backup=("${path_config}/php.ini") - #provides=("${pkgbase}=${pkgver}") + depends=('zlib' 'pcre' 'oniguruma' 'readline' 'argon2') + if ((_build_openssl_v10_patch)); then + depends+=("openssl-1.0") + else + depends+=("openssl") + fi + backup=("etc/php${_phpbase}${_suffix}/php.ini") + if ((_build_with_custom_icu)); then + pushd "${_build_icu_src_dir}" + make DESTDIR="${pkgdir}" install + make clean + popd + pushd "${pkgdir}/usr/lib/php${_phpbase}${_suffix}/icu${_pkgver_icu}" + rm -rf bin include share + popd + fi + pushd "build" + make -j1 INSTALL_ROOT=${pkgdir} install-{modules,build,headers,programs,pharcmd} - cd ${srcdir}/build - make -j1 INSTALL_ROOT=${pkgdir} install-{modules,cli,build,headers,programs,pharcmd} - - install -D -m644 ${srcdir}/${_base}-${pkgver}/php.ini-production ${pkgdir}/${path_config}/php.ini - install -d -m755 ${pkgdir}/${path_config}/conf.d/ + install -D -m644 "../php-${pkgver}/php.ini-production" "${pkgdir}/etc/php${_phpbase}${_suffix}/php.ini" + install -d -m755 "${pkgdir}/etc/php${_phpbase}${_suffix}/conf.d/" + pushd "${pkgdir}/usr/lib/php${_phpbase}${_suffix}/modules/" # remove static modules - rm -f ${pkgdir}/${path_extensions}/*.a + rm -f *.a + # remove modules provided by sub packages - rm -f ${pkgdir}/${path_extensions}/{enchant,gd,imap,intl,sodium,mcrypt,odbc,pdo_dblib,pdo_odbc,pgsql,pdo_pgsql,pspell,snmp,sqlite3,pdo_sqlite,tidy,xsl}.so + rm -f {enchant,imap,intl,pspell,snmp,tidy,curl,ldap,bz2,bcmath,soap,zip,gmp,dba,opcache,json,gd,mcrypt,sodium,recode}.so + # dblib package + rm -rf {pdo_dblib,mssql}.so + # xml package + rm -f {dom,simplexml,xml,xmlreader,xmlwriter,xsl,wddx,xmlrpc}.so + # PostgreSQL + rm -f {pgsql,pdo_pgsql}.so + # ODBC + rm -f {odbc,pdo_odbc}.so + # SQLite + rm -f {pdo_sqlite,sqlite3}.so + # pdo_firebird + rm -f {pdo_firebird.so,interbase.so} + # MySQL modules + rm -f {mysqli,pdo_mysql,mysqlnd,mysql}.so + + # Install COMMON modules + for i in *.so; do + _install_module_ini "${i}" + done + popd + # remove empty directory - rmdir ${pkgdir}/${path_prefix}/include/php/include - + rmdir "${pkgdir}/usr/include/php/include" + # move include directory - mv ${pkgdir}/${path_prefix}/include/php ${pkgdir}/${path_prefix}/include/${pkgbase} + mv "${pkgdir}/usr/include/php" "${pkgdir}/usr/include/php${_phpbase}${_suffix}" - # fix phar symlink - rm ${pkgdir}/${path_prefix}/bin/phar - ln -sf ${name_phar}.phar ${pkgdir}/${path_prefix}/bin/${name_phar} + # Link to phar + ln -sf "phar${_phpbase}${_suffix}.phar" "${pkgdir}/usr/bin/phar${_phpbase}${_suffix}" # rename executables - mv ${pkgdir}/${path_prefix}/bin/phar.phar ${pkgdir}/${path_prefix}/bin/${name_phar}.phar - + if [[ -f "${pkgdir}/usr/bin/phar.phar" ]]; then + mv "${pkgdir}/usr/bin/phar.phar" "${pkgdir}/usr/bin/phar${_phpbase}${_suffix}.phar" + fi # rename man pages - mv ${pkgdir}/${path_prefix}/share/man/man1/{phar,${name_phar}}.1 - mv ${pkgdir}/${path_prefix}/share/man/man1/phar.{phar,${name_phar}}.1 + if [[ -f "${pkgdir}/usr/share/man/man1/phar.1" ]]; then + mv "${pkgdir}/usr/share/man/man1/phar.1" \ + "${pkgdir}/usr/share/man/man1/phar${_phpbase}${_suffix}.1" + fi + + if [[ -f "${pkgdir}/usr/share/man/man1/phar.phar.1" ]]; then + mv "${pkgdir}/usr/share/man/man1/phar.phar.1" \ + "${pkgdir}/usr/share/man/man1/phar.phar${_phpbase}${_suffix}.1" + fi + + # kill phar symlink in old php builds + rm -f "${pkgdir}/usr/bin/phar" # fix paths in executables - sed -i "/^includedir=/c \includedir=/${path_prefix}/include/${pkgbase}" ${pkgdir}/${path_prefix}/bin/${name_phpize} - sed -i "/^include_dir=/c \include_dir=/${path_prefix}/include/${pkgbase}" ${pkgdir}/${path_prefix}/bin/${name_phpconfig} + echo "[SED] ${pkgdir}/usr/bin/phpize${_phpbase}${_suffix}" + sed -i "/^includedir=/c \includedir=/usr/include/php${_phpbase}${_suffix}" "${pkgdir}/usr/bin/phpize${_phpbase}${_suffix}" + echo "[SED] ${pkgdir}/usr/bin/php-config${_phpbase}${_suffix}" + sed -i "/^include_dir=/c \include_dir=/usr/include/php${_phpbase}${_suffix}" "${pkgdir}/usr/bin/php-config${_phpbase}${_suffix}" - # make phpize use php-config${phpbase} - sed -i "/^\[ --with-php-config=/c \[ --with-php-config=PATH Path to php-config [${name_phpconfig}]], ${name_phpconfig}, no)" ${pkgdir}/${path_prefix}/lib/${pkgbase}/build/phpize.m4 + #sed -i "/^php_cli_binary=/c \include_dir=/usr/bin/php${_phpbase}${_suffix}" "${pkgdir}/usr/bin/php-config${_phpbase}${_suffix}" + #sed -i "/^php_cgi_binary=/c \include_dir=/usr/bin/php-cgi${_phpbase}${_suffix}" "${pkgdir}/usr/bin/php-config${_phpbase}${_suffix}" + + echo "[SED] Sed for ${pkgdir}/usr/lib/php${_phpbase}${_suffix}/build/phpize.m4" + sed -i "/^\[ --with-php-config=/c \[ --with-php-config=PATH Path to php-config [php-config${_phpbase}${_suffix}]], php-config${_phpbase}${_suffix}, no)" \ + "${pkgdir}/usr/lib/php${_phpbase}${_suffix}/build/phpize.m4" + # popd + popd } +# End install common -package_php72-cgi() { - pkgdesc='CGI and FCGI SAPI for PHP' - depends=("${pkgbase}") - #provides=("${pkgbase}-cgi=${pkgver}") +# Cli +package_php72-cli() { + pkgdesc="cli (command-line executable) version for php${_phpbase}${_suffix}" + depends=("php${_phpbase}${_suffix}") + pushd "build" + make -j1 INSTALL_ROOT="${pkgdir}" install-cli + popd +} +# End cli - cd ${srcdir}/build - make -j1 INSTALL_ROOT=${pkgdir} install-cgi +# CGI +package_php72-cgi() { + pkgdesc="CGI and FCGI SAPI for php${_phpbase}${_suffix}" + depends=("php${_phpbase}${_suffix}") + if ((_build_per_sapi)); then + pushd "build-cgi" + else + pushd "build" + fi + case "${_phpbase}" in + 53) + install -D -m755 sapi/cgi/php-cgi "${pkgdir}/usr/bin/php${_phpbase}${_suffix}-cgi" + ;; + *) + make -j1 INSTALL_ROOT="${pkgdir}" install-cgi + ;; + esac + popd } +# End CGI package_php72-apache() { - pkgdesc='Apache SAPI for PHP' - depends=("${pkgbase}" 'apache') - backup=("etc/httpd/conf/extra/${name_apache_module_conf}") - #provides=("${pkgbase}-apache=${pkgver}") + _build_mod_php_so="libphp${_suffix_so}.so" + _build_mod_php_module="php_module${_suffix_so}" + _build_build_php_script_name="php${_suffix_so}-script" + _apache_module_conf="${pkgbase}-module.conf" + pkgdesc="Apache SAPI for php${_phpbase}${_suffix}" + depends=("php${_phpbase}${_suffix}" 'apache') + backup=("${_build_apache_cfg}/${_apache_module_conf}") echo "# End of LoadModule in httpd.conf - see ArchWiki Apache HTTP Server" - echo "LoadModule php_module7 modules/lib${pkgbase}.so" - echo "AddHandler php7-script .php" + echo "LoadModule ${_build_mod_php_module} modules/libphp${_phpbase}${_suffix}.so" + echo "AddHandler ${_build_php_script_name} .php" echo "# End of Include List" - echo "Include conf/extra/${name_apache_module_conf}" - install -D -m755 ${srcdir}/build-apache/libs/${name_libapache_source} ${pkgdir}/${path_prefix}/lib/httpd/modules/lib${pkgbase}.so - install -D -m644 ${srcdir}/apache.conf ${pkgdir}/etc/httpd/conf/extra/${name_apache_module_conf} + echo "Include conf/extra/${_apache_module_conf}" + install -D -m755 "build-apache/libs/${_build_mod_php_so}" "${pkgdir}/usr/lib/httpd/modules/libphp${_phpbase}${_suffix}.so" + install -D -m644 "php-apache.conf" "${pkgdir}/${_build_apache_cfg}/${_apache_module_conf}" + echo "Sed for ${pkgdir}/${_build_apache_cfg}/${_apache_module_conf}" + sed -e "s#@MODULE@#${_build_mod_php_module}#" \ + -i "${pkgdir}/${_build_apache_cfg}/${_apache_module_conf}" } package_php72-fpm() { - pkgdesc='FastCGI Process Manager for PHP' - depends=("${pkgbase}" 'systemd') - backup=("etc/${pkgbase}/php-fpm.conf" "etc/${pkgbase}/php-fpm.d/www.conf") + pkgdesc="FastCGI Process Manager for php${_phpbase}${_suffix}" + depends=("php${_phpbase}${_suffix}" 'systemd-libs') + backup=("etc/php${_phpbase}${_suffix}/php-fpm.conf") + if ((_phpbase>=70)); then + backup+=("etc/php${_phpbase}${_suffix}/php-fpm.d/www.conf") + fi options=('!emptydirs') - #provides=("${pkgbase}-fpm=${pkgver}") - cd ${srcdir}/build - make -j1 INSTALL_ROOT=${pkgdir} install-fpm - install -D -m644 sapi/fpm/php-fpm.service ${pkgdir}/${path_prefix}/lib/systemd/system/${pkgbase}-fpm.service - install -D -m644 ${srcdir}/php-fpm.tmpfiles ${pkgdir}/${path_prefix}/lib/tmpfiles.d/${pkgbase}-fpm.conf + if ((_build_per_sapi)); then + pushd "build-fpm" + else + pushd "build" + fi + case "${_phpbase}" in + 53) + install -d -m755 "${pkgdir}/usr/bin" + install -D -m755 sapi/fpm/php-fpm "${pkgdir}/usr/bin/php${_phpbase}${_suffix}-fpm" + install -D -m644 sapi/fpm/php-fpm.8 "${pkgdir}/usr/share/man/man8/php${_phpbase}${_suffix}-fpm.8" + install -D -m644 sapi/fpm/php-fpm.conf "${pkgdir}/etc/php${_phpbase}${_suffix}/php-fpm.conf" + install -d -m755 "${pkgdir}/etc/php${_phpbase}${_suffix}/fpm.d" + ;; + *) + make -j1 INSTALL_ROOT="${pkgdir}" install-fpm + ;; + esac + + install -D -m644 "sapi/fpm/php-fpm.service" "${pkgdir}/usr/lib/systemd/system/php${_phpbase}${_suffix}-fpm.service" + echo "d /run/php${_phpbase}${_suffix}-fpm 755 root root" > php-fpm.tmpfiles + install -D -m644 "php-fpm.tmpfiles" "${pkgdir}/usr/lib/tmpfiles.d/php${_phpbase}${_suffix}-fpm.conf" + popd } package_php72-embed() { - pkgdesc='Embedded PHP SAPI library' - depends=("${pkgbase}" 'libsystemd') + pkgdesc="Embedded PHP SAPI library for php${_phpbase}${_suffix}" + depends=("php${_phpbase}${_suffix}" 'ncurses' 'systemd-libs') options=('!emptydirs') - #provides=("${pkgbase}-embed=${pkgver}") - - cd ${srcdir}/build - make -j1 INSTALL_ROOT=${pkgdir} PHP_SAPI=embed install-sapi - mv ${pkgdir}/${path_prefix}/lib/${name_libembed_source} ${pkgdir}/${path_prefix}/lib/libphp${phpbase}${suffix}.so + if ((_build_per_sapi)); then + pushd "build-embed" + else + pushd "build" + fi + patchelf --set-soname "libphp${_phpbase}${_suffix}.so" "libs/libphp${_suffix_so}.so" + case "${_phpbase}" in + 53) + install -D -m755 "libs/libphp${_suffix_so}.so" "${pkgdir}/usr/lib/libphp${_phpbase}${_suffix}.so" + install -D -m644 "../php-${pkgver}/sapi/embed/php_embed.h" "${pkgdir}/usr/include/php${_phpbase}${_suffix}/sapi/embed/php_embed.h" + ;; + *) + make -j1 INSTALL_ROOT="${pkgdir}" PHP_SAPI=embed install-sapi + mv "${pkgdir}/usr/lib/libphp${_suffix_so}.so" "${pkgdir}/usr/lib/libphp${_phpbase}${_suffix}.so" + ;; + esac + popd } package_php72-phpdbg() { - pkgdesc='Interactive PHP debugger' - depends=("${pkgbase}") + pkgdesc="Interactive PHP debugger for php${_phpbase}${_suffix}" + depends=("php${_phpbase}${_suffix}") options=('!emptydirs') - #provides=("${pkgbase}-phpdbg=${pkgver}") + pushd "build-phpdbg" + make -j1 INSTALL_ROOT="${pkgdir}" install-phpdbg + popd +} - cd ${srcdir}/build-phpdbg - make -j1 INSTALL_ROOT=${pkgdir} install-phpdbg +package_php72-pear() { + pkgdesc="PHP Extension and Application Repository for php${_phpbase}${_suffix}" + depends=("php${_phpbase}${_suffix}" "php${_phpbase}-xml${_suffix}") + backup=("etc/php${_phpbase}${_suffix}/pear.conf") + # + pushd "build-pear" + + make install-pear INSTALL_ROOT="${pkgdir}" + + # remove unneeded files + rm -rf "${pkgdir}"/.{channels,depdb,depdblock,filemap,lock,registry} + + # rename binaries + for i in pear peardev pecl; do + echo "Moving ${pkgdir}/usr/bin/${i} => ${pkgdir}/usr/bin/${pkgbase/php/$i}" + mv "${pkgdir}/usr/bin/${i}" "${pkgdir}/usr/bin/${pkgbase/php/$i}" + # fix hardcoded php paths in pear + sed -i "s|/usr/bin/php|/usr/bin/php${_phpbase}${_suffix}|g" "${pkgdir}/usr/bin/${pkgbase/php/$i}" + sed -i "s|PHP=php|PHP=${_phpbase}${_suffix}|g" "${pkgdir}/usr/bin/${pkgbase/php/$i}" + done + # fix pear.conf with unserialize + ./sapi/cli/php ../pear-config-patcher.php "${pkgdir}/etc/php${_phpbase}${_suffix}/pear.conf" "/usr/bin/php${_phpbase}${_suffix}" "${_phpbase}${_suffix}" + + #popd + popd } package_php72-dblib() { - pkgdesc='dblib module for PHP' - depends=("${pkgbase}" 'freetds') - #provides=("${pkgbase}-dblib=${pkgver}") - - install -D -m755 ${srcdir}/build/modules/pdo_dblib.so ${pkgdir}/${path_extensions}/pdo_dblib.so + depends=("php${_phpbase}${_suffix}" 'freetds') + provides=( + "php${_phpbase}${_suffix}-sybase=${pkgver}" + ) + _install_module pdo_dblib + if ((_build_mssql)); then + _install_module mssql + provided+=("php${_phpbase}${_suffix}-mssql=${pkgver}") + pkgdesc="pdo_dblib module for php${_phpbase}${_suffix}" + else + pkgdesc="mssql and pdo_dblib modules for php${_phpbase}${_suffix}" + fi } package_php72-enchant() { - pkgdesc='enchant module for PHP' - depends=("${pkgbase}" 'enchant') - #provides=("${pkgbase}-enchant=${pkgver}") - - install -D -m755 ${srcdir}/build/modules/enchant.so ${pkgdir}/${path_extensions}/enchant.so + pkgdesc="enchant module for php${_phpbase}${_suffix}" + depends=("php${_phpbase}${_suffix}" 'enchant') + _install_module enchant } package_php72-gd() { - pkgdesc='gd module for PHP' - depends=("${pkgbase}" 'gd') - #provides=("${pkgbase}-gd=${pkgver}") - - install -D -m755 ${srcdir}/build/modules/gd.so ${pkgdir}/${path_extensions}/gd.so + pkgdesc="gd module for php${_phpbase}${_suffix}" + depends=("php${_phpbase}${_suffix}" 'gd') + if ((_build_bundled_gd)); then + depends+=('libxpm' 'libpng' 'libjpeg') + fi + _install_module gd } -package_php72-imap() { - pkgdesc='imap module for PHP' - depends=("${pkgbase}" 'c-client') - #provides=("${pkgbase}-imap=${pkgver}") - install -D -m755 ${srcdir}/build/modules/imap.so ${pkgdir}/${path_extensions}/imap.so +package_php72-imap() { + pkgdesc="imap module for php${_phpbase}${_suffix}" + depends=("php${_phpbase}${_suffix}" 'pam' 'krb5' 'c-client') + _install_module imap } package_php72-intl() { - pkgdesc='intl module for PHP' - depends=("${pkgbase}" 'icu') - #provides=("${pkgbase}-intl=${pkgver}") + pkgdesc="intl module for php${_phpbase}${_suffix}" + depends=("php${_phpbase}${_suffix}") + if ((_build_with_custom_icu)); then + # Patch to proper path inside intl.so + patchelf --set-rpath "/usr/lib/php${_phpbase}${_suffix}/icu${_pkgver_icu}/lib" "build/modules/intl.so" + else + depends+=('icu') + fi + _install_module intl +} - install -D -m755 ${srcdir}/build/modules/intl.so ${pkgdir}/${path_extensions}/intl.so +package_php72-mcrypt() { + pkgdesc="mcrypt module for php${_phpbase}${_suffix}" + depends=("php${_phpbase}${_suffix}" 'libmcrypt') + _install_module mcrypt } package_php72-odbc() { - pkgdesc='ODBC modules for PHP' - depends=("${pkgbase}" 'unixodbc') - #provides=("${pkgbase}-odbc=${pkgver}") - - install -D -m755 ${srcdir}/build/modules/odbc.so ${pkgdir}/${path_extensions}/odbc.so - install -D -m755 ${srcdir}/build/modules/pdo_odbc.so ${pkgdir}/${path_extensions}/pdo_odbc.so + pkgdesc="ODBC modules for php${_phpbase}${_suffix}" + depends=("php${_phpbase}${_suffix}" 'unixodbc') + _install_module odbc + _install_module pdo_odbc } package_php72-pgsql() { - pkgdesc='PostgreSQL modules for PHP' - depends=("${pkgbase}" 'postgresql-libs') - #provides=("${pkgbase}-pgsql=${pkgver}") - - install -D -m755 ${srcdir}/build/modules/pgsql.so ${pkgdir}/${path_extensions}/pgsql.so - install -D -m755 ${srcdir}/build/modules/pdo_pgsql.so ${pkgdir}/${path_extensions}/pdo_pgsql.so + pkgdesc="PostgreSQL modules for php${_phpbase}${_suffix}" + depends=("php${_phpbase}${_suffix}" 'postgresql-libs') + _install_module pgsql + _install_module pdo_pgsql } package_php72-pspell() { - pkgdesc='pspell module for PHP' - depends=("${pkgbase}" 'aspell') - #provides=("${pkgbase}-pspell=${pkgver}") - - install -D -m755 ${srcdir}/build/modules/pspell.so ${pkgdir}/${path_extensions}/pspell.so + pkgdesc="pspell module for php${_phpbase}${_suffix}" + depends=("php${_phpbase}${_suffix}" 'aspell') + _install_module pspell } package_php72-snmp() { - pkgdesc='snmp module for PHP' - depends=("${pkgbase}" 'net-snmp') - #provides=("${pkgbase}-snmp=${pkgver}") - - install -D -m755 ${srcdir}/build/modules/snmp.so ${pkgdir}/${path_extensions}/snmp.so + pkgdesc="snmp module for php${_phpbase}${_suffix}" + depends=("php${_phpbase}${_suffix}" 'net-snmp') + _install_module snmp } package_php72-sqlite() { - pkgdesc='sqlite module for PHP' - depends=("${pkgbase}" 'sqlite') - #provides=("${pkgbase}-sqlite=${pkgver}") - install -D -m755 ${srcdir}/build/modules/sqlite3.so ${pkgdir}/${path_extensions}/sqlite3.so - install -D -m755 ${srcdir}/build/modules/pdo_sqlite.so ${pkgdir}/${path_extensions}/pdo_sqlite.so + pkgdesc="sqlite module for php${_phpbase}${_suffix}" + depends=("php${_phpbase}${_suffix}" 'sqlite') + _install_module sqlite3 + _install_module pdo_sqlite } package_php72-tidy() { - pkgdesc='tidy module for PHP' - depends=("${pkgbase}" 'tidy') - #provides=("${pkgbase}-tidy=${pkgver}") - install -D -m755 ${srcdir}/build/modules/tidy.so ${pkgdir}/${path_extensions}/tidy.so + pkgdesc="tidy module for php${_phpbase}${_suffix}" + depends=("php${_phpbase}${_suffix}" 'tidy') + _install_module tidy +} + +package_php72-xml() { + pkgdesc="xml modules for php${_phpbase}${_suffix}" + depends=("php${_phpbase}${_suffix}" 'libxml2') + _install_module dom + _install_module simplexml + if ((_build_wddx)); then + _install_module wddx + fi + _install_module xml + _install_module xmlreader + _install_module xmlwriter } package_php72-xsl() { - pkgdesc='xsl module for PHP' - depends=("${pkgbase}" 'libxslt') - #provides=("${pkgbase}-xsl=${pkgver}") - install -D -m755 ${srcdir}/build/modules/xsl.so ${pkgdir}/${path_extensions}/xsl.so + pkgdesc="xsl module for php${_phpbase}${_suffix}" + depends=( + "php${_phpbase}${_suffix}" + "php${_phpbase}-xml${_suffix}=${pkgver}" + 'libxslt' + 'libxml2' + ) + _install_module xsl +} + +package_php72-xmlrpc() { + pkgdesc="xmlrpc module for php${_phpbase}${_suffix}" + depends=("php${_phpbase}${_suffix}") + _install_module xmlrpc } +package_php72-soap() { + pkgdesc="soap module for php${_phpbase}${_suffix}" + depends=("php${_phpbase}${_suffix}" 'libxml2') + _install_module soap +} + +package_php72-zip() { + pkgdesc="zip module for php${_phpbase}${_suffix}" + depends=("php${_phpbase}${_suffix}" 'libzip') + _install_module zip +} + + +package_php72-bcmath() { + pkgdesc="bcmath module for php${_phpbase}${_suffix}" + depends=("php${_phpbase}${_suffix}") + _install_module bcmath +} + +package_php72-bz2() { + pkgdesc="bz2 module for php${_phpbase}${_suffix}" + depends=("php${_phpbase}${_suffix}" 'bzip2') + _install_module bz2 +} + +package_php72-ldap() { + pkgdesc="ldap module for php${_phpbase}${_suffix}" + depends=("php${_phpbase}${_suffix}" 'libldap' 'libsasl') + _install_module ldap +} + +package_php72-curl() { + pkgdesc="curl module for php${_phpbase}${_suffix}" + depends=("php${_phpbase}${_suffix}" "curl") + _install_module curl +} + +# gmp +package_php72-gmp() { + pkgdesc="gmp module for php${_phpbase}${_suffix}" + depends=("php${_phpbase}${_suffix}" 'gmp') + _install_module gmp +} +# End gmp + +# Dba +package_php72-dba() { + pkgdesc="dba module for php${_phpbase}${_suffix}" + depends=("php${_phpbase}${_suffix}" 'gdbm' 'db') + _install_module dba +} +# End dba + +# Json +package_php72-json() { + pkgdesc="json module for php${_phpbase}${_suffix}" + depends=("php${_phpbase}${_suffix}") + _install_module json +} +# End json + +# Recode +package_php72-recode() { + pkgdesc="recode module for php${_phpbase}${_suffix}" + depends=("php${_phpbase}${_suffix}" 'recode') + _install_module recode +} +# End recode + +# Recode package_php72-sodium() { - pkgdesc='sodium module for PHP' - depends=("${pkgbase}" 'libsodium') - #provides=("${pkgbase}-sodium=${pkgver}") - install -D -m755 ${srcdir}/build/modules/sodium.so ${pkgdir}/${path_extensions}/sodium.so + pkgdesc="sodium (libsodium) module for php${_phpbase}${_suffix}" + depends=("php${_phpbase}${_suffix}" "libsodium") + _install_module sodium +} +# End recode + +# Opcache +package_php72-opcache() { + pkgdesc="opcache zend module for php${_phpbase}${_suffix}" + depends=("php${_phpbase}${_suffix}") + _install_module opcache +} +# End opcache + +# Interbase modules +package_php72-interbase() { + pkgdesc="Interbase modules for php${_phpbase}${_suffix}" + depends=("php${_phpbase}${_suffix}" "libfbclient") + #backup=() + if ((_build_interbase)); then + _install_module interbase + fi + _install_module pdo_firebird +} +# End interbase + +# MySQL modules +package_php72-mysql() { + pkgdesc="MySQL modules for php${_phpbase}${_suffix}" + depends=("php${_phpbase}${_suffix}") + _install_module mysqlnd + _install_module mysqli + _install_module pdo_mysql + if ((_build_outdated_mysql)); then + _install_module mysql + fi } +# End mysql sha256sums=('409e11bc6a2c18707dfc44bc61c820ddfd81e17481470f3405ee7822d8379903' - 'e438f7a429915d9fe5affce2a32315b670fa0f2b2638ca51e7072374d367ca07' - 'a67ed00467fb886e73808a3246e7a6f6bfb60fa3c24a692e21a4dd474b8353fd' - 'ebc0af1ef3a6baccb013d0ccb29923895a7b22ff2d032e3bba802dc6328301ce' - 'bdd47c439c81b46384332c8b0180e70b80d8b38d844f0dde9d1be329e4c62f18' - '3217979d2ea17f9c6c9209e220d41a5f4e6a6b65fcc7cd5ab8d938f65ca2b59e' - 'd47310dfa4c53fd30744e49b0bacfcabe055568a33af08e28bc5bc80a852b4c4' - 'b11c3de747ef222696f5135556d624e3f7f0135a3cb1b06082f1ec8e9b7eeb0a' - 'f9fe57f809ac13e0043d18b795ef777af3e8c710a83745b37b09db536f683d2a') + '0201d0fa811b80614737424a72c7bb127125807e5d7eeec5e1578a0a58f77d2f' + '6d0ad9becb5470ce8e5929d7d45660b0f32579038978496317544c5310281a91' + '0a3a6e8ff04ff1e0869befcf2c7bca4e886d94065da6d7a10b809a4750b961a0' + '433c542ba7f77f5f69d99e8e12ac0e9520cead3361a152ba2d04291b3d0365b8' + 'ccaad50d9e855bebd9d98bec4db6085dde3446ecd68bdbb58c1d450e1f5aeab9' + '558e780e93dfa861a366c49b4d156d8fc43f17898f001ae6033ec63c33d5d41c' + '40bcc1e5058602302198d0925e431495391d8469499593af477f59d84d32f764' + '6ef318bf8d53a2288d037e3284f4dbfc26c36fd2ecc7d62e3d5036c19ec0a707' + '409e11bc6a2c18707dfc44bc61c820ddfd81e17481470f3405ee7822d8379903' + '0201d0fa811b80614737424a72c7bb127125807e5d7eeec5e1578a0a58f77d2f' + '6d0ad9becb5470ce8e5929d7d45660b0f32579038978496317544c5310281a91' + 'd175f0c14fdb22855090c93f76e18f04320d7bf15afc057ffde947f9bb361242' + 'f5ae925036744a5e88cea2698879aea0498e1e23aee7801923d90f16be383908' + '0a3a6e8ff04ff1e0869befcf2c7bca4e886d94065da6d7a10b809a4750b961a0' + '84d0b3bce1be8e0113f3ba63a3dcce774fc79a002d754a2e31348f24a574d8f7' + '3049b76460c65a70017ba2aac8f8c45725df2bbea458a96ec7164db63639e87f' + '581d230715bb01a878cd8aba1c1f37c6123691ed80d9c43d53de381f09df8399' + '68517bf6fd6ab2890877252f4233f1f7134b412b29d2dba20ef14d6fd1ac368b' + '19b64388efbeb178eda9e19cf089a096300ef2732d40c128d3ca424526724787' + 'd706ded57ed3e46a7993f9e3f5838eea690f66e59e2e3549c6dda1cec44bcc1f' + '558e780e93dfa861a366c49b4d156d8fc43f17898f001ae6033ec63c33d5d41c' + '40bcc1e5058602302198d0925e431495391d8469499593af477f59d84d32f764' + '1cb8f76b465e3c5cd383450bc1f898859f58270d3645fb7405f93d0e06cddac7' + '409e11bc6a2c18707dfc44bc61c820ddfd81e17481470f3405ee7822d8379903' + '0201d0fa811b80614737424a72c7bb127125807e5d7eeec5e1578a0a58f77d2f' + '6d0ad9becb5470ce8e5929d7d45660b0f32579038978496317544c5310281a91' + 'd175f0c14fdb22855090c93f76e18f04320d7bf15afc057ffde947f9bb361242' + 'f5ae925036744a5e88cea2698879aea0498e1e23aee7801923d90f16be383908' + '0a3a6e8ff04ff1e0869befcf2c7bca4e886d94065da6d7a10b809a4750b961a0' + '84d0b3bce1be8e0113f3ba63a3dcce774fc79a002d754a2e31348f24a574d8f7' + '3049b76460c65a70017ba2aac8f8c45725df2bbea458a96ec7164db63639e87f' + '581d230715bb01a878cd8aba1c1f37c6123691ed80d9c43d53de381f09df8399' + 'ed3184d5a6f7a3bf35ee32169f8dc3b6cba09c38f60e868e24652fe9a7dd844d' + '19b64388efbeb178eda9e19cf089a096300ef2732d40c128d3ca424526724787' + '1377d3627fbccb6edca87742836771a6546ecca121bbd43c3981880217258c22' + '558e780e93dfa861a366c49b4d156d8fc43f17898f001ae6033ec63c33d5d41c' + '40bcc1e5058602302198d0925e431495391d8469499593af477f59d84d32f764' + 'db38b1fe1f6d6aa80bbca3c142bf7a166e3e83212dcc1396f9ec706daad36ad2') diff --git a/apache.conf b/apache.conf deleted file mode 100644 index b516b5e66ffa..000000000000 --- a/apache.conf +++ /dev/null @@ -1,13 +0,0 @@ -# Required modules: dir_module, php7_module - -<IfModule dir_module> - <IfModule php7_module> - DirectoryIndex index.php index.html - <FilesMatch "\.php$"> - SetHandler application/x-httpd-php - </FilesMatch> - <FilesMatch "\.phps$"> - SetHandler application/x-httpd-php-source - </FilesMatch> - </IfModule> -</IfModule> diff --git a/apache.patch b/apache.patch deleted file mode 100644 index 3eef19ebecc8..000000000000 --- a/apache.patch +++ /dev/null @@ -1,20 +0,0 @@ ---- sapi/apache2handler/config.m4.orig -+++ sapi/apache2handler/config.m4 -@@ -122,7 +122,6 @@ - PHP_BUILD_THREAD_SAFE - fi - else -- APACHE_THREADED_MPM=`$APXS_HTTPD -V | grep 'threaded:.*yes'` - if test -n "$APACHE_THREADED_MPM"; then - PHP_BUILD_THREAD_SAFE - fi ---- configure.orig -+++ configure -@@ -7021,7 +7021,6 @@ - - fi - else -- APACHE_THREADED_MPM=`$APXS_HTTPD -V | grep 'threaded:.*yes'` - if test -n "$APACHE_THREADED_MPM"; then - - enable_maintainer_zts=yes diff --git a/debian-php-7.2.34.patch b/debian-php-7.2.34.patch new file mode 100644 index 000000000000..6f6a8e208fa9 --- /dev/null +++ b/debian-php-7.2.34.patch @@ -0,0 +1,2039 @@ + +diff --git a/ext/standard/proc_open.c b/ext/standard/proc_open.c +index 9aa5f74..81368fd 100644 +--- a/ext/standard/proc_open.c ++++ b/ext/standard/proc_open.c +@@ -57,7 +57,7 @@ + * */ + #ifdef PHP_CAN_SUPPORT_PROC_OPEN + +-#if 0 && HAVE_PTSNAME && HAVE_GRANTPT && HAVE_UNLOCKPT && HAVE_SYS_IOCTL_H && HAVE_TERMIOS_H ++#if HAVE_PTSNAME && HAVE_GRANTPT && HAVE_UNLOCKPT && HAVE_SYS_IOCTL_H && HAVE_TERMIOS_H + # include <sys/ioctl.h> + # include <termios.h> + # define PHP_CAN_DO_PTS 1 +diff --git a/php.ini-development b/php.ini-development +index 2cb93e1..c2b4771 100644 +--- a/php.ini-development ++++ b/php.ini-development +@@ -302,6 +302,12 @@ + ; or per-virtualhost web server configuration file. + ; Note: disables the realpath cache + ; http://php.net/open-basedir ++ ++; NOTE: this is considered a "broken" security measure. ++; Applications relying on this feature will not receive full ++; support by the security team. For more information please ++; see /usr/share/doc/php-common/README.Debian.security ++; + ;open_basedir = + + ; This directive allows you to disable certain functions for security reasons. +diff --git a/ext/dba/config.m4 b/ext/dba/config.m4 +index bc0fd55..0f270a8 100644 +--- a/ext/dba/config.m4 ++++ b/ext/dba/config.m4 +@@ -346,61 +346,13 @@ + dbdp4="/usr/local/BerkeleyDB.4." + dbdp5="/usr/local/BerkeleyDB.5." + for i in $PHP_DB4 ${dbdp5}1 ${dbdp5}0 ${dbdp4}8 ${dbdp4}7 ${dbdp4}6 ${dbdp4}5 ${dbdp4}4 ${dbdp4}3 ${dbdp4}2 ${dbdp4}1 ${dbdp}0 /usr/local /usr; do +- if test -f "$i/db5/db.h"; then +- THIS_PREFIX=$i +- THIS_INCLUDE=$i/db5/db.h +- break +- elif test -f "$i/db4/db.h"; then +- THIS_PREFIX=$i +- THIS_INCLUDE=$i/db4/db.h +- break +- elif test -f "$i/include/db5.3/db.h"; then +- THIS_PREFIX=$i +- THIS_INCLUDE=$i/include/db5.3/db.h +- break +- elif test -f "$i/include/db5.1/db.h"; then +- THIS_PREFIX=$i +- THIS_INCLUDE=$i/include/db5.1/db.h +- break +- elif test -f "$i/include/db5.0/db.h"; then +- THIS_PREFIX=$i +- THIS_INCLUDE=$i/include/db5.0/db.h +- break +- elif test -f "$i/include/db4.8/db.h"; then +- THIS_PREFIX=$i +- THIS_INCLUDE=$i/include/db4.8/db.h +- break +- elif test -f "$i/include/db4.7/db.h"; then +- THIS_PREFIX=$i +- THIS_INCLUDE=$i/include/db4.7/db.h +- break +- elif test -f "$i/include/db4.6/db.h"; then +- THIS_PREFIX=$i +- THIS_INCLUDE=$i/include/db4.6/db.h +- break +- elif test -f "$i/include/db4.5/db.h"; then +- THIS_PREFIX=$i +- THIS_INCLUDE=$i/include/db4.5/db.h +- break +- elif test -f "$i/include/db4/db.h"; then +- THIS_PREFIX=$i +- THIS_INCLUDE=$i/include/db4/db.h +- break +- elif test -f "$i/include/db/db4.h"; then +- THIS_PREFIX=$i +- THIS_INCLUDE=$i/include/db/db4.h +- break +- elif test -f "$i/include/db4.h"; then +- THIS_PREFIX=$i +- THIS_INCLUDE=$i/include/db4.h +- break +- elif test -f "$i/include/db.h"; then ++ if test -f "$i/include/db.h"; then + THIS_PREFIX=$i + THIS_INCLUDE=$i/include/db.h + break + fi + done +- PHP_DBA_DB_CHECK(4, db-5.3 db-5.1 db-5.0 db-4.8 db-4.7 db-4.6 db-4.5 db-4.4 db-4.3 db-4.2 db-4.1 db-4.0 db-4 db4 db, [(void)db_create((DB**)0, (DB_ENV*)0, 0)]) ++ PHP_DBA_DB_CHECK(4, db, [(void)db_create((DB**)0, (DB_ENV*)0, 0)]) + fi + PHP_DBA_STD_RESULT(db4,Berkeley DB4) + +diff --git a/ext/dba/dba.c b/ext/dba/dba.c +index a003416..6cd3b4d 100644 +--- a/ext/dba/dba.c ++++ b/ext/dba/dba.c +@@ -53,6 +53,10 @@ + #include "php_tcadb.h" + #include "php_lmdb.h" + ++#ifdef DB4_INCLUDE_FILE ++#include DB4_INCLUDE_FILE ++#endif ++ + /* {{{ arginfo */ + ZEND_BEGIN_ARG_INFO_EX(arginfo_dba_popen, 0, 0, 2) + ZEND_ARG_INFO(0, path) +@@ -558,6 +562,10 @@ + + php_info_print_table_start(); + php_info_print_table_row(2, "DBA support", "enabled"); ++#ifdef DB_VERSION_STRING ++ php_info_print_table_row(2, "libdb header version", DB_VERSION_STRING); ++ php_info_print_table_row(2, "libdb library version", db_version(NULL, NULL, NULL)); ++#endif + if (handlers.s) { + smart_str_0(&handlers); + php_info_print_table_row(2, "Supported handlers", ZSTR_VAL(handlers.s)); +diff --git a/ext/mysqli/config.m4 b/ext/mysqli/config.m4 +index c5dfe5d..87dd43e 100644 +--- a/ext/mysqli/config.m4 ++++ b/ext/mysqli/config.m4 +@@ -59,7 +59,7 @@ + MYSQL_LIB_CFG='--libmysqld-libs' + dnl mysqlnd doesn't support embedded, so we have to add some extra stuff + mysqli_extra_sources="mysqli_embedded.c" +- elif test "$enable_maintainer_zts" = "yes"; then ++ elif true || test "$enable_maintainer_zts" = "yes"; then + MYSQL_LIB_CFG='--libs_r' + MYSQL_LIB_NAME='mysqlclient_r' + else +diff --git a/ext/pdo_mysql/config.m4 b/ext/pdo_mysql/config.m4 +index 4991df0..7227b3a 100755 +--- a/ext/pdo_mysql/config.m4 ++++ b/ext/pdo_mysql/config.m4 +@@ -67,7 +67,7 @@ + if test "x$SED" = "x"; then + AC_PATH_PROG(SED, sed) + fi +- if test "$enable_maintainer_zts" = "yes"; then ++ if true || test "$enable_maintainer_zts" = "yes"; then + PDO_MYSQL_LIBNAME=mysqlclient_r + PDO_MYSQL_LIBS=`$PDO_MYSQL_CONFIG --libs_r | $SED -e "s/'//g"` + else +--- /dev/null ++++ b/tests/func/null-new_val.phpt +@@ -0,0 +1,10 @@ ++--TEST-- ++ini_restore strcmp NULL new_val ++--FILE-- ++<?php ++ ++ini_set('error_log','ini_set_works'); ++ini_restore('error_log'); ++ ++?> ++--EXPECT-- +diff --git a/build/build.mk b/build/build.mk +index 1ce958f..b8c7492 100644 +--- a/build/build.mk ++++ b/build/build.mk +@@ -63,6 +63,5 @@ + @if (test ! -f '.git/info/exclude' || grep -s "git-ls-files" .git/info/exclude); then \ + (echo "Rebuild .git/info/exclude" && echo '*.o' > .git/info/exclude && git svn propget svn:ignore | grep -v config.nice >> .git/info/exclude); \ + fi; \ +- git clean -X -f -d; + + .PHONY: $(ALWAYS) snapshot +diff --git a/ext/dba/config.m4 b/ext/dba/config.m4 +index 0f270a8..7d074f7 100644 +--- a/ext/dba/config.m4 ++++ b/ext/dba/config.m4 +@@ -116,6 +116,10 @@ + THIS_PREFIX=$i + THIS_INCLUDE=$i/include/depot.h + break ++ elif test -f "$i/include/qdbm/depot.h"; then ++ THIS_PREFIX=$i ++ THIS_INCLUDE=$i/include/qdbm/depot.h ++ break + fi + done + +diff --git a/sapi/fpm/php-fpm.8.in b/sapi/fpm/php-fpm.8.in +index 86edaa8..19e66a0 100644 +--- a/sapi/fpm/php-fpm.8.in ++++ b/sapi/fpm/php-fpm.8.in +@@ -139,22 +139,8 @@ + .TP + .B php.ini + The standard php configuration file. +-.SH EXAMPLES +-For any unix systems which use init.d for their main process manager, you should use the init script provided to start and stop the php-fpm daemon. +-.P +-.PD 1 +-.RS +-sudo /etc/init.d/php-fpm start +-.RE +-.TP +-For any unix systems which use systemd for their main process manager, you should use the unit file provided to start and stop the php-fpm daemon. +-.P +-.PD 1 +-.RS +-sudo systemctl start php-fpm.service +-.RE +-.TP +-If your installation has no appropriate init script, launch php-fpm with no arguments. It will launch as a daemon (background process) by default. The file @php_fpm_localstatedir@/run/php-fpm.pid determines whether php-fpm is already up and running. Once started, php-fpm then responds to several POSIX signals: ++.SH SIGNAL ++Once started, php-fpm then responds to several POSIX signals: + .P + .PD 0 + .RS +@@ -168,10 +154,6 @@ + .RE + .PD 1 + .P +-.SH TIPS +-The PHP-FPM CGI daemon will work well with most popular webservers, including Apache2, lighttpd and nginx. +-.PD 1 +-.P + .SH SEE ALSO + The PHP-FPM website: + .PD 0 +diff --git a/main/streams/plain_wrapper.c b/main/streams/plain_wrapper.c +index 8374857..6c27345 100644 +--- a/main/streams/plain_wrapper.c ++++ b/main/streams/plain_wrapper.c +@@ -693,7 +693,13 @@ + + switch (value) { + case PHP_STREAM_MMAP_SUPPORTED: +- return fd == -1 ? PHP_STREAM_OPTION_RETURN_ERR : PHP_STREAM_OPTION_RETURN_OK; ++ if (fd == -1) ++ return PHP_STREAM_OPTION_RETURN_ERR; ++ /* Don't mmap large files */ ++ do_fstat(data, 1); ++ if (data->sb.st_size > 4 * 1024 * 1024) ++ return PHP_STREAM_OPTION_RETURN_ERR; ++ return PHP_STREAM_OPTION_RETURN_OK; + + case PHP_STREAM_MMAP_MAP_RANGE: + if (do_fstat(data, 1) != 0) { +diff --git a/ext/dba/dba.c b/ext/dba/dba.c +index 6cd3b4d..370ac08 100644 +--- a/ext/dba/dba.c ++++ b/ext/dba/dba.c +@@ -993,7 +993,7 @@ + } + } + +- if (error || hptr->open(info, &error) != SUCCESS) { ++ if (error || (hptr->open)(info, &error) != SUCCESS) { + dba_close(info); + php_error_docref2(NULL, Z_STRVAL(args[0]), Z_STRVAL(args[1]), E_WARNING, "Driver initialization failed for handler: %s%s%s", hptr->name, error?": ":"", error?error:""); + FREENOW; +diff --git a/ext/dba/dba_db3.c b/ext/dba/dba_db3.c +index dd1bcb8..aca3c93 100644 +--- a/ext/dba/dba_db3.c ++++ b/ext/dba/dba_db3.c +@@ -96,9 +96,9 @@ + dbp->set_errcall(dbp, php_dba_db3_errcall_fcn); + if( + #if (DB_VERSION_MAJOR > 4 || (DB_VERSION_MAJOR == 4 && DB_VERSION_MINOR >= 1)) +- (err=dbp->open(dbp, 0, info->path, NULL, type, gmode, filemode)) == 0) { ++ (err=(dbp->open)(dbp, 0, info->path, NULL, type, gmode, filemode)) == 0) { + #else +- (err=dbp->open(dbp, info->path, NULL, type, gmode, filemode)) == 0) { ++ (err=(dbp->open)(dbp, info->path, NULL, type, gmode, filemode)) == 0) { + #endif + dba_db3_data *data; + +diff --git a/ext/dba/dba_db4.c b/ext/dba/dba_db4.c +index 63a69bd..a77cc22 100644 +--- a/ext/dba/dba_db4.c ++++ b/ext/dba/dba_db4.c +@@ -125,9 +125,9 @@ + dbp->set_errcall(dbp, php_dba_db4_errcall_fcn); + if ( + #if (DB_VERSION_MAJOR > 4 || (DB_VERSION_MAJOR == 4 && DB_VERSION_MINOR >= 1)) +- (err=dbp->open(dbp, 0, info->path, NULL, type, gmode, filemode)) == 0) { ++ (err=(dbp->open)(dbp, 0, info->path, NULL, type, gmode, filemode)) == 0) { + #else +- (err=dbp->open(dbp, info->path, NULL, type, gmode, filemode)) == 0) { ++ (err=(dbp->open)(dbp, info->path, NULL, type, gmode, filemode)) == 0) { + #endif + dba_db4_data *data; + +diff --git a/ext/zlib/zlib.c b/ext/zlib/zlib.c +index fde9f02..592793c 100644 +--- a/ext/zlib/zlib.c ++++ b/ext/zlib/zlib.c +@@ -49,6 +49,18 @@ + int le_deflate; + int le_inflate; + ++/* ++ * zlib include files can define the following preprocessor defines which rename ++ * the corresponding PHP functions to gzopen64, gzseek64 and gztell64 and thereby ++ * breaking some software, most notably PEAR's Archive_Tar, which halts execution ++ * without error message on gzip compressed archivesa. ++ * ++ * This only seems to happen on 32bit systems with large file support. ++ */ ++#undef gzopen ++#undef gzseek ++#undef gztell ++ + ZEND_DECLARE_MODULE_GLOBALS(zlib); + + /* {{{ Memory management wrappers */ +diff --git a/ext/standard/tests/strings/setlocale_variation2.phpt b/ext/standard/tests/strings/setlocale_variation2.phpt +index fad3298..346c987 100644 +--- a/ext/standard/tests/strings/setlocale_variation2.phpt ++++ b/ext/standard/tests/strings/setlocale_variation2.phpt +@@ -55,6 +55,7 @@ + //try different locale names + $failure_locale = array(); + $success_count = 0; ++$expected = 0; + + echo "-- Test setlocale() with all available locale in the system --\n"; + // gather all locales installed in the system(stored $all_system_locales), +@@ -64,6 +65,10 @@ + if(setlocale(LC_ALL,$value )){ + $success_count++; + } ++ else if ($value == 'no_NO.ISO-8859-1') { ++ // ignore this one, see rhbz #971416 ++ $expected++; ++ } + else{ + //failure values are put in to an array $failure_locale + $failure_locale[] = $value; +@@ -72,11 +77,11 @@ + + echo "No of locales found on the machine = ".count($all_system_locales)."\n"; + echo "No of setlocale() success = ".$success_count."\n"; +-echo "Expected no of failures = 0\n"; ++echo "Expected no of failures = $expected\n"; + echo "Test "; + // check if there were any failure of setlocale() function earlier, if any + // failure then dump the list of failing locales +-if($success_count != count($all_system_locales)){ ++if($success_count + $expected != count($all_system_locales)){ + echo "FAILED\n"; + echo "Names of locale() for which setlocale() failed ...\n"; + var_dump($failure_locale); +@@ -92,6 +97,6 @@ + -- Test setlocale() with all available locale in the system -- + No of locales found on the machine = %d + No of setlocale() success = %d +-Expected no of failures = 0 ++Expected no of failures = %d + Test PASSED + Done +diff --git a/ext/pcre/tests/bug37911.phpt b/ext/pcre/tests/bug37911.phpt +index 2b7481a..0d2859d 100644 +--- a/ext/pcre/tests/bug37911.phpt ++++ b/ext/pcre/tests/bug37911.phpt +@@ -37,5 +37,5 @@ + string(4) "blub" + } + +-Warning: preg_replace_callback(): Compilation failed: group name must start with a non-digit at offset %d in %sbug37911.php on line %d ++Warning: preg_replace_callback(): Numeric named subpatterns are not allowed in %sbug37911.php on line %d + NULL +diff --git a/ext/pcre/tests/grep2.phpt b/ext/pcre/tests/grep2.phpt +index 1a8476c..0cf8d4a 100644 +--- a/ext/pcre/tests/grep2.phpt ++++ b/ext/pcre/tests/grep2.phpt +@@ -40,12 +40,6 @@ + string(1) "1" + } + bool(true) +-array(3) { +- [5]=> +- string(1) "a" +- ["xyz"]=> +- string(2) "q6" +- [6]=> +- string(3) "h20" ++array(0) { + } +-bool(false) ++bool(true) +diff --git a/ext/pcre/tests/match_flags3.phpt b/ext/pcre/tests/match_flags3.phpt +index 695f0c1..05c62a0 100644 +--- a/ext/pcre/tests/match_flags3.phpt ++++ b/ext/pcre/tests/match_flags3.phpt +@@ -41,5 +41,5 @@ + } + } + +-Warning: preg_match(): Compilation failed: group name must start with a non-digit at offset %d in %smatch_flags3.php on line %d ++Warning: preg_match(): Numeric named subpatterns are not allowed in %smatch_flags3.php on line %d + bool(false) +diff --git a/main/SAPI.c b/main/SAPI.c +index 6216fd8..0138335 100644 +--- a/main/SAPI.c ++++ b/main/SAPI.c +@@ -1104,6 +1104,56 @@ + } + } + ++SAPI_API void sapi_add_request_header(char *var, unsigned int var_len, char *val, unsigned int val_len, void *arg) /* {{{ */ ++{ ++ zval *return_value = (zval*)arg; ++ char *str = NULL; ++ ++ ALLOCA_FLAG(use_heap) ++ ++ if (var_len > 5 && ++ var[0] == 'H' && ++ var[1] == 'T' && ++ var[2] == 'T' && ++ var[3] == 'P' && ++ var[4] == '_') { ++ ++ char *p; ++ ++ var_len -= 5; ++ p = var + 5; ++ var = str = do_alloca(var_len + 1, use_heap); ++ *str++ = *p++; ++ while (*p) { ++ if (*p == '_') { ++ *str++ = '-'; ++ p++; ++ if (*p) { ++ *str++ = *p++; ++ } ++ } else if (*p >= 'A' && *p <= 'Z') { ++ *str++ = (*p++ - 'A' + 'a'); ++ } else { ++ *str++ = *p++; ++ } ++ } ++ *str = 0; ++ } else if (var_len == sizeof("CONTENT_TYPE")-1 && ++ memcmp(var, "CONTENT_TYPE", sizeof("CONTENT_TYPE")-1) == 0) { ++ var = "Content-Type"; ++ } else if (var_len == sizeof("CONTENT_LENGTH")-1 && ++ memcmp(var, "CONTENT_LENGTH", sizeof("CONTENT_LENGTH")-1) == 0) { ++ var = "Content-Length"; ++ } else { ++ return; ++ } ++ add_assoc_stringl_ex(return_value, var, var_len, val, val_len); ++ if (str) { ++ free_alloca(var, use_heap); ++ } ++} ++/* }}} */ ++ + /* + * Local variables: + * tab-width: 4 +diff --git a/main/SAPI.h b/main/SAPI.h +index 5a5620b..d452240 100644 +--- a/main/SAPI.h ++++ b/main/SAPI.h +@@ -151,6 +151,7 @@ + SAPI_API void sapi_activate(void); + SAPI_API void sapi_deactivate(void); + SAPI_API void sapi_initialize_empty_request(void); ++SAPI_API void sapi_add_request_header(char *var, unsigned int var_len, char *val, unsigned int val_len, void *arg); + END_EXTERN_C() + + /* +diff --git a/sapi/cgi/cgi_main.c b/sapi/cgi/cgi_main.c +index 16bb212..2eed928 100644 +--- a/sapi/cgi/cgi_main.c ++++ b/sapi/cgi/cgi_main.c +@@ -1596,54 +1596,6 @@ + } + /* }}} */ + +-static void add_request_header(char *var, unsigned int var_len, char *val, unsigned int val_len, void *arg) /* {{{ */ +-{ +- zval *return_value = (zval*)arg; +- char *str = NULL; +- char *p; +- ALLOCA_FLAG(use_heap) +- +- if (var_len > 5 && +- var[0] == 'H' && +- var[1] == 'T' && +- var[2] == 'T' && +- var[3] == 'P' && +- var[4] == '_') { +- +- var_len -= 5; +- p = var + 5; +- var = str = do_alloca(var_len + 1, use_heap); +- *str++ = *p++; +- while (*p) { +- if (*p == '_') { +- *str++ = '-'; +- p++; +- if (*p) { +- *str++ = *p++; +- } +- } else if (*p >= 'A' && *p <= 'Z') { +- *str++ = (*p++ - 'A' + 'a'); +- } else { +- *str++ = *p++; +- } +- } +- *str = 0; +- } else if (var_len == sizeof("CONTENT_TYPE")-1 && +- memcmp(var, "CONTENT_TYPE", sizeof("CONTENT_TYPE")-1) == 0) { +- var = "Content-Type"; +- } else if (var_len == sizeof("CONTENT_LENGTH")-1 && +- memcmp(var, "CONTENT_LENGTH", sizeof("CONTENT_LENGTH")-1) == 0) { +- var = "Content-Length"; +- } else { +- return; +- } +- add_assoc_stringl_ex(return_value, var, var_len, val, val_len); +- if (str) { +- free_alloca(var, use_heap); +- } +-} +-/* }}} */ +- + PHP_FUNCTION(apache_request_headers) /* {{{ */ + { + if (zend_parse_parameters_none()) { +@@ -1653,7 +1605,7 @@ + if (fcgi_is_fastcgi()) { + fcgi_request *request = (fcgi_request*) SG(server_context); + +- fcgi_loadenv(request, add_request_header, return_value); ++ fcgi_loadenv(request, sapi_add_request_header, return_value); + } else { + char buf[128]; + char **env, *p, *q, *var, *val, *t = buf; +diff --git a/sapi/fpm/fpm/fpm_main.c b/sapi/fpm/fpm/fpm_main.c +index b0e6226..702946a 100644 +--- a/sapi/fpm/fpm/fpm_main.c ++++ b/sapi/fpm/fpm/fpm_main.c +@@ -1533,6 +1533,10 @@ + { + fcgi_request *request = (fcgi_request*) SG(server_context); + ++ if (zend_parse_parameters_none() == FAILURE) { ++ return; ++ } ++ + if (!fcgi_is_closed(request)) { + php_output_end_all(); + php_header(); +@@ -1547,8 +1551,27 @@ + } + /* }}} */ + ++ZEND_BEGIN_ARG_INFO(cgi_fcgi_sapi_no_arginfo, 0) ++ZEND_END_ARG_INFO() ++ ++PHP_FUNCTION(apache_request_headers) /* {{{ */ ++{ ++ fcgi_request *request; ++ ++ if (zend_parse_parameters_none() == FAILURE) { ++ return; ++ } ++ ++ array_init(return_value); ++ if ((request = (fcgi_request*) SG(server_context))) { ++ fcgi_loadenv(request, sapi_add_request_header, return_value); ++ } ++} /* }}} */ ++ + static const zend_function_entry cgi_fcgi_sapi_functions[] = { +- PHP_FE(fastcgi_finish_request, NULL) ++ PHP_FE(fastcgi_finish_request, cgi_fcgi_sapi_no_arginfo) ++ PHP_FE(apache_request_headers, cgi_fcgi_sapi_no_arginfo) ++ PHP_FALIAS(getallheaders, apache_request_headers, cgi_fcgi_sapi_no_arginfo) + PHP_FE_END + }; + +--- /dev/null ++++ b/sapi/fpm/tests/getallheaders.phpt +@@ -0,0 +1,67 @@ ++--TEST-- ++FPM: Function getallheaders basic test ++--SKIPIF-- ++<?php include "skipif.inc"; ?> ++--FILE-- ++<?php ++ ++require_once "tester.inc"; ++ ++$cfg = <<<EOT ++[global] ++error_log = {{FILE:LOG}} ++[unconfined] ++listen = {{ADDR}} ++pm = dynamic ++pm.max_children = 5 ++pm.start_servers = 1 ++pm.min_spare_servers = 1 ++pm.max_spare_servers = 3 ++EOT; ++ ++$code = <<<EOT ++<?php ++echo "Test Start\n"; ++var_dump(getallheaders()); ++echo "Test End\n"; ++EOT; ++ ++$headers = []; ++$tester = new FPM\Tester($cfg, $code); ++$tester->start(); ++$tester->expectLogStartNotices(); ++$tester->request( ++ '', ++ [ ++ 'HTTP_X_FOO' => 'BAR', ++ 'HTTP_FOO' => 'foo' ++ ] ++ )->expectBody( ++ [ ++ 'Test Start', ++ 'array(4) {', ++ ' ["Foo"]=>', ++ ' string(3) "foo"', ++ ' ["X-Foo"]=>', ++ ' string(3) "BAR"', ++ ' ["Content-Length"]=>', ++ ' string(1) "0"', ++ ' ["Content-Type"]=>', ++ ' string(0) ""', ++ '}', ++ 'Test End', ++ ] ++ ); ++$tester->terminate(); ++$tester->expectLogTerminatingNotices(); ++$tester->close(); ++ ++?> ++Done ++--EXPECT-- ++Done ++--CLEAN-- ++<?php ++require_once "tester.inc"; ++FPM\Tester::clean(); ++?> +diff --git a/ext/zip/php_zip.c b/ext/zip/php_zip.c +index 6b29266..af1d8db 100644 +--- a/ext/zip/php_zip.c ++++ b/ext/zip/php_zip.c +@@ -1477,6 +1477,21 @@ + ze_obj->filename = NULL; + } + ++#if LIBZIP_VERSION_MAJOR > 1 || LIBZIP_VERSION_MAJOR == 1 && LIBZIP_VERSION_MINOR >= 6 ++ /* reduce BC break introduce in libzip 1.6.0 ++ "Do not accept empty files as valid zip archives any longer" */ ++ ++ /* open for write without option to empty the archive */ ++ if ((flags & (ZIP_TRUNCATE | ZIP_RDONLY)) == 0) { ++ zend_stat_t st; ++ ++ /* exists and is empty */ ++ if (VCWD_STAT(resolved_path, &st) == 0 && st.st_size == 0) { ++ flags |= ZIP_TRUNCATE; ++ } ++ } ++#endif ++ + intern = zip_open(resolved_path, flags, &err); + if (!intern || err) { + efree(resolved_path); +diff --git a/sapi/fpm/tests/tester.inc b/sapi/fpm/tests/tester.inc +index 89bbb90..5335d76 100644 +--- a/sapi/fpm/tests/tester.inc ++++ b/sapi/fpm/tests/tester.inc +@@ -860,7 +860,17 @@ + { + $port = $this->getPort($type, $pool, true); + if ($type === 'uds') { +- return $this->getFile($port . '.sock'); ++ $address = $this->getFile($port . '.sock'); ++ ++ // Socket max path length is 108 on Linux and 104 on BSD, ++ // so we use the latter ++ if (strlen($address) <= 104) { ++ return $address; ++ } ++ ++ return sys_get_temp_dir().'/'. ++ hash('crc32', dirname($address)).'-'. ++ basename($address); + } + + return $this->getHost($type) . ':' . $port; +diff --git a/ext/standard/tests/strings/url_t.phpt b/ext/standard/tests/strings/url_t.phpt +index 79ff3bc..f564f59 100644 +--- a/ext/standard/tests/strings/url_t.phpt ++++ b/ext/standard/tests/strings/url_t.phpt +@@ -575,15 +575,13 @@ + string(16) "some_page_ref123" + } + +---> http://secret@hideout@www.php.net:80/index.php?test=1&test2=char&test3=mixesCI#some_page_ref123: array(7) { ++--> http://secret@hideout@www.php.net:80/index.php?test=1&test2=char&test3=mixesCI#some_page_ref123: array(6) { + ["scheme"]=> + string(4) "http" + ["host"]=> +- string(11) "www.php.net" ++ string(26) "secret@hideout@www.php.net" + ["port"]=> + int(80) +- ["user"]=> +- string(14) "secret@hideout" + ["path"]=> + string(10) "/index.php" + ["query"]=> +--- /dev/null ++++ b/ext/standard/tests/url/bug77423.phpt +@@ -0,0 +1,30 @@ ++--TEST-- ++Bug #77423 (parse_url() will deliver a wrong host to user) ++--FILE-- ++<?php ++$urls = array( ++ "http://php.net\@aliyun.com/aaa.do", ++ "https://example.com\uFF03@bing.com", ++); ++foreach ($urls as $url) { ++ var_dump(filter_var($url, FILTER_VALIDATE_URL)); ++ var_dump(parse_url($url)); ++} ++?> ++--EXPECT-- ++bool(false) ++array(3) { ++ ["scheme"]=> ++ string(4) "http" ++ ["host"]=> ++ string(19) "php.net\@aliyun.com" ++ ["path"]=> ++ string(7) "/aaa.do" ++} ++bool(false) ++array(2) { ++ ["scheme"]=> ++ string(5) "https" ++ ["host"]=> ++ string(26) "example.com\uFF03@bing.com" ++} +diff --git a/ext/standard/tests/url/parse_url_basic_001.phpt b/ext/standard/tests/url/parse_url_basic_001.phpt +index 4606849..5101099 100644 +--- a/ext/standard/tests/url/parse_url_basic_001.phpt ++++ b/ext/standard/tests/url/parse_url_basic_001.phpt +@@ -506,15 +506,13 @@ + string(16) "some_page_ref123" + } + +---> http://secret@hideout@www.php.net:80/index.php?test=1&test2=char&test3=mixesCI#some_page_ref123: array(7) { ++--> http://secret@hideout@www.php.net:80/index.php?test=1&test2=char&test3=mixesCI#some_page_ref123: array(6) { + ["scheme"]=> + string(4) "http" + ["host"]=> +- string(11) "www.php.net" ++ string(26) "secret@hideout@www.php.net" + ["port"]=> + int(80) +- ["user"]=> +- string(14) "secret@hideout" + ["path"]=> + string(10) "/index.php" + ["query"]=> +diff --git a/ext/standard/tests/url/parse_url_basic_003.phpt b/ext/standard/tests/url/parse_url_basic_003.phpt +index 3d5a4a3..7968fd3 100644 +--- a/ext/standard/tests/url/parse_url_basic_003.phpt ++++ b/ext/standard/tests/url/parse_url_basic_003.phpt +@@ -68,7 +68,7 @@ + --> http://secret:@www.php.net/index.php?test=1&test2=char&test3=mixesCI#some_page_ref123 : string(11) "www.php.net" + --> http://:hideout@www.php.net:80/index.php?test=1&test2=char&test3=mixesCI#some_page_ref123 : string(11) "www.php.net" + --> http://secret:hideout@www.php.net/index.php?test=1&test2=char&test3=mixesCI#some_page_ref123 : string(11) "www.php.net" +---> http://secret@hideout@www.php.net:80/index.php?test=1&test2=char&test3=mixesCI#some_page_ref123 : string(11) "www.php.net" ++--> http://secret@hideout@www.php.net:80/index.php?test=1&test2=char&test3=mixesCI#some_page_ref123 : string(26) "secret@hideout@www.php.net" + --> http://secret:hid:out@www.php.net:80/index.php?test=1&test2=char&test3=mixesCI#some_page_ref123 : string(11) "www.php.net" + --> nntp://news.php.net : string(12) "news.php.net" + --> ftp://ftp.gnu.org/gnu/glic/glibc.tar.gz : string(11) "ftp.gnu.org" +diff --git a/ext/standard/tests/url/parse_url_basic_005.phpt b/ext/standard/tests/url/parse_url_basic_005.phpt +index aefb339..ba778bf 100644 +--- a/ext/standard/tests/url/parse_url_basic_005.phpt ++++ b/ext/standard/tests/url/parse_url_basic_005.phpt +@@ -68,7 +68,7 @@ + --> http://secret:@www.php.net/index.php?test=1&test2=char&test3=mixesCI#some_page_ref123 : string(6) "secret" + --> http://:hideout@www.php.net:80/index.php?test=1&test2=char&test3=mixesCI#some_page_ref123 : string(0) "" + --> http://secret:hideout@www.php.net/index.php?test=1&test2=char&test3=mixesCI#some_page_ref123 : string(6) "secret" +---> http://secret@hideout@www.php.net:80/index.php?test=1&test2=char&test3=mixesCI#some_page_ref123 : string(14) "secret@hideout" ++--> http://secret@hideout@www.php.net:80/index.php?test=1&test2=char&test3=mixesCI#some_page_ref123 : NULL + --> http://secret:hid:out@www.php.net:80/index.php?test=1&test2=char&test3=mixesCI#some_page_ref123 : string(6) "secret" + --> nntp://news.php.net : NULL + --> ftp://ftp.gnu.org/gnu/glic/glibc.tar.gz : NULL +diff --git a/ext/standard/tests/url/parse_url_unterminated.phpt b/ext/standard/tests/url/parse_url_unterminated.phpt +index 912b6a5..875d93a 100644 +--- a/ext/standard/tests/url/parse_url_unterminated.phpt ++++ b/ext/standard/tests/url/parse_url_unterminated.phpt +@@ -508,15 +508,13 @@ + string(16) "some_page_ref123" + } + +---> http://secret@hideout@www.php.net:80/index.php?test=1&test2=char&test3=mixesCI#some_page_ref123: array(7) { ++--> http://secret@hideout@www.php.net:80/index.php?test=1&test2=char&test3=mixesCI#some_page_ref123: array(6) { + ["scheme"]=> + string(4) "http" + ["host"]=> +- string(11) "www.php.net" ++ string(26) "secret@hideout@www.php.net" + ["port"]=> + int(80) +- ["user"]=> +- string(14) "secret@hideout" + ["path"]=> + string(10) "/index.php" + ["query"]=> +diff --git a/ext/standard/url.c b/ext/standard/url.c +index 1dd073e..8d155bb 100644 +--- a/ext/standard/url.c ++++ b/ext/standard/url.c +@@ -92,6 +92,22 @@ + return php_url_parse_ex(str, strlen(str)); + } + ++static int is_userinfo_valid(const char *str, size_t len) ++{ ++ char *valid = "-._~!$&'()*+,;=:"; ++ char *p = str; ++ while (p - str < len) { ++ if (isalpha(*p) || isdigit(*p) || strchr(valid, *p)) { ++ p++; ++ } else if (*p == '%' && p - str <= len - 3 && isdigit(*(p+1)) && isxdigit(*(p+2))) { ++ p += 3; ++ } else { ++ return 0; ++ } ++ } ++ return 1; ++} ++ + /* {{{ php_url_parse + */ + PHPAPI php_url *php_url_parse_ex(char const *str, size_t length) +@@ -235,13 +251,18 @@ + ret->pass = estrndup(pp, (p-pp)); + php_replace_controlchars_ex(ret->pass, (p-pp)); + } else { ++ if (!is_userinfo_valid(s, p-s)) { ++ goto check_port; ++ } + ret->user = estrndup(s, (p-s)); + php_replace_controlchars_ex(ret->user, (p-s)); ++ + } + + s = p + 1; + } + ++check_port: + /* check for port */ + if (s < ue && *s == '[' && *(e-1) == ']') { + /* Short circuit portscan, +diff --git a/ext/imap/php_imap.c b/ext/imap/php_imap.c +index 37eb5e1..9cac226 100644 +--- a/ext/imap/php_imap.c ++++ b/ext/imap/php_imap.c +@@ -3528,6 +3528,23 @@ + } + /* }}} */ + ++static zend_bool header_injection(zend_string *str, zend_bool adrlist) ++{ ++ char *p = ZSTR_VAL(str); ++ ++ while ((p = strpbrk(p, "\r\n")) != NULL) { ++ if (!(p[0] == '\r' && p[1] == '\n') ++ /* adrlists do not support folding, but swallow trailing line breaks */ ++ && !((adrlist && p[1] == '\0') ++ /* other headers support folding */ ++ || !adrlist && (p[1] == ' ' || p[1] == '\t'))) { ++ return 1; ++ } ++ p++; ++ } ++ return 0; ++} ++ + /* {{{ proto string imap_mail_compose(array envelope, array body) + Create a MIME message based on given envelope and body sections */ + PHP_FUNCTION(imap_mail_compose) +@@ -3548,6 +3565,13 @@ + return; + } + ++#define CHECK_HEADER_INJECTION(zstr, adrlist, header) \ ++ if (header_injection(zstr, adrlist)) { \ ++ php_error_docref(NULL, E_WARNING, "header injection attempt in " header); \ ++ RETVAL_FALSE; \ ++ goto done; \ ++ } ++ + #define PHP_RFC822_PARSE_ADRLIST(target, value) \ + str_copy = estrndup(Z_STRVAL_P(value), Z_STRLEN_P(value)); \ + rfc822_parse_adrlist(target, str_copy, "NO HOST"); \ +@@ -3556,46 +3580,57 @@ + env = mail_newenvelope(); + if ((pvalue = zend_hash_str_find(Z_ARRVAL_P(envelope), "remail", sizeof("remail") - 1)) != NULL) { + convert_to_string_ex(pvalue); ++ CHECK_HEADER_INJECTION(Z_STR_P(pvalue), 0, "remail"); + env->remail = cpystr(Z_STRVAL_P(pvalue)); + } + if ((pvalue = zend_hash_str_find(Z_ARRVAL_P(envelope), "return_path", sizeof("return_path") - 1)) != NULL) { + convert_to_string_ex(pvalue); ++ CHECK_HEADER_INJECTION(Z_STR_P(pvalue), 1, "return_path"); + PHP_RFC822_PARSE_ADRLIST(&env->return_path, pvalue); + } + if ((pvalue = zend_hash_str_find(Z_ARRVAL_P(envelope), "date", sizeof("date") - 1)) != NULL) { + convert_to_string_ex(pvalue); ++ CHECK_HEADER_INJECTION(Z_STR_P(pvalue), 0, "date"); + env->date = (unsigned char*)cpystr(Z_STRVAL_P(pvalue)); + } + if ((pvalue = zend_hash_str_find(Z_ARRVAL_P(envelope), "from", sizeof("from") - 1)) != NULL) { + convert_to_string_ex(pvalue); ++ CHECK_HEADER_INJECTION(Z_STR_P(pvalue), 1, "from"); + PHP_RFC822_PARSE_ADRLIST(&env->from, pvalue); + } + if ((pvalue = zend_hash_str_find(Z_ARRVAL_P(envelope), "reply_to", sizeof("reply_to") - 1)) != NULL) { + convert_to_string_ex(pvalue); ++ CHECK_HEADER_INJECTION(Z_STR_P(pvalue), 1, "reply_to"); + PHP_RFC822_PARSE_ADRLIST(&env->reply_to, pvalue); + } + if ((pvalue = zend_hash_str_find(Z_ARRVAL_P(envelope), "in_reply_to", sizeof("in_reply_to") - 1)) != NULL) { + convert_to_string_ex(pvalue); ++ CHECK_HEADER_INJECTION(Z_STR_P(pvalue), 0, "in_reply_to"); + env->in_reply_to = cpystr(Z_STRVAL_P(pvalue)); + } + if ((pvalue = zend_hash_str_find(Z_ARRVAL_P(envelope), "subject", sizeof("subject") - 1)) != NULL) { + convert_to_string_ex(pvalue); ++ CHECK_HEADER_INJECTION(Z_STR_P(pvalue), 0, "subject"); + env->subject = cpystr(Z_STRVAL_P(pvalue)); + } + if ((pvalue = zend_hash_str_find(Z_ARRVAL_P(envelope), "to", sizeof("to") - 1)) != NULL) { + convert_to_string_ex(pvalue); ++ CHECK_HEADER_INJECTION(Z_STR_P(pvalue), 1, "to"); + PHP_RFC822_PARSE_ADRLIST(&env->to, pvalue); + } + if ((pvalue = zend_hash_str_find(Z_ARRVAL_P(envelope), "cc", sizeof("cc") - 1)) != NULL) { + convert_to_string_ex(pvalue); ++ CHECK_HEADER_INJECTION(Z_STR_P(pvalue), 1, "cc"); + PHP_RFC822_PARSE_ADRLIST(&env->cc, pvalue); + } + if ((pvalue = zend_hash_str_find(Z_ARRVAL_P(envelope), "bcc", sizeof("bcc") - 1)) != NULL) { + convert_to_string_ex(pvalue); ++ CHECK_HEADER_INJECTION(Z_STR_P(pvalue), 1, "bcc"); + PHP_RFC822_PARSE_ADRLIST(&env->bcc, pvalue); + } + if ((pvalue = zend_hash_str_find(Z_ARRVAL_P(envelope), "message_id", sizeof("message_id") - 1)) != NULL) { + convert_to_string_ex(pvalue); ++ CHECK_HEADER_INJECTION(Z_STR_P(pvalue), 0, "message_id"); + env->message_id=cpystr(Z_STRVAL_P(pvalue)); + } + +@@ -3605,6 +3640,7 @@ + ZEND_HASH_FOREACH_VAL(Z_ARRVAL_P(pvalue), env_data) { + custom_headers_param = mail_newbody_parameter(); + convert_to_string_ex(env_data); ++ CHECK_HEADER_INJECTION(Z_STR_P(env_data), 0, "custom_headers"); + custom_headers_param->value = (char *) fs_get(Z_STRLEN_P(env_data) + 1); + custom_headers_param->attribute = NULL; + memcpy(custom_headers_param->value, Z_STRVAL_P(env_data), Z_STRLEN_P(env_data) + 1); +@@ -3637,6 +3673,7 @@ + } + if ((pvalue = zend_hash_str_find(Z_ARRVAL_P(data), "charset", sizeof("charset") - 1)) != NULL) { + convert_to_string_ex(pvalue); ++ CHECK_HEADER_INJECTION(Z_STR_P(pvalue), 0, "body charset"); + tmp_param = mail_newbody_parameter(); + tmp_param->value = cpystr(Z_STRVAL_P(pvalue)); + tmp_param->attribute = cpystr("CHARSET"); +@@ -3647,9 +3684,11 @@ + if(Z_TYPE_P(pvalue) == IS_ARRAY) { + disp_param = tmp_param = NULL; + ZEND_HASH_FOREACH_STR_KEY_VAL(Z_ARRVAL_P(pvalue), key, disp_data) { ++ CHECK_HEADER_INJECTION(key, 0, "body disposition key"); + disp_param = mail_newbody_parameter(); + disp_param->attribute = cpystr(ZSTR_VAL(key)); + convert_to_string_ex(disp_data); ++ CHECK_HEADER_INJECTION(Z_STR_P(disp_data), 0, "body disposition value"); + disp_param->value = (char *) fs_get(Z_STRLEN_P(disp_data) + 1); + memcpy(disp_param->value, Z_STRVAL_P(disp_data), Z_STRLEN_P(disp_data) + 1); + disp_param->next = tmp_param; +@@ -3660,18 +3699,22 @@ + } + if ((pvalue = zend_hash_str_find(Z_ARRVAL_P(data), "subtype", sizeof("subtype") - 1)) != NULL) { + convert_to_string_ex(pvalue); ++ CHECK_HEADER_INJECTION(Z_STR_P(pvalue), 0, "body subtype"); + bod->subtype = cpystr(Z_STRVAL_P(pvalue)); + } + if ((pvalue = zend_hash_str_find(Z_ARRVAL_P(data), "id", sizeof("id") - 1)) != NULL) { + convert_to_string_ex(pvalue); ++ CHECK_HEADER_INJECTION(Z_STR_P(pvalue), 0, "body id"); + bod->id = cpystr(Z_STRVAL_P(pvalue)); + } + if ((pvalue = zend_hash_str_find(Z_ARRVAL_P(data), "description", sizeof("description") - 1)) != NULL) { + convert_to_string_ex(pvalue); ++ CHECK_HEADER_INJECTION(Z_STR_P(pvalue), 0, "body description"); + bod->description = cpystr(Z_STRVAL_P(pvalue)); + } + if ((pvalue = zend_hash_str_find(Z_ARRVAL_P(data), "disposition.type", sizeof("disposition.type") - 1)) != NULL) { + convert_to_string_ex(pvalue); ++ CHECK_HEADER_INJECTION(Z_STR_P(pvalue), 0, "body disposition.type"); + bod->disposition.type = (char *) fs_get(Z_STRLEN_P(pvalue) + 1); + memcpy(bod->disposition.type, Z_STRVAL_P(pvalue), Z_STRLEN_P(pvalue)+1); + } +@@ -3679,9 +3722,11 @@ + if (Z_TYPE_P(pvalue) == IS_ARRAY) { + disp_param = tmp_param = NULL; + ZEND_HASH_FOREACH_STR_KEY_VAL(Z_ARRVAL_P(pvalue), key, disp_data) { ++ CHECK_HEADER_INJECTION(key, 0, "body type.parameters key"); + disp_param = mail_newbody_parameter(); + disp_param->attribute = cpystr(ZSTR_VAL(key)); + convert_to_string_ex(disp_data); ++ CHECK_HEADER_INJECTION(Z_STR_P(disp_data), 0, "body type.parameters value"); + disp_param->value = (char *) fs_get(Z_STRLEN_P(disp_data) + 1); + memcpy(disp_param->value, Z_STRVAL_P(disp_data), Z_STRLEN_P(disp_data) + 1); + disp_param->next = tmp_param; +@@ -3710,6 +3755,7 @@ + } + if ((pvalue = zend_hash_str_find(Z_ARRVAL_P(data), "md5", sizeof("md5") - 1)) != NULL) { + convert_to_string_ex(pvalue); ++ CHECK_HEADER_INJECTION(Z_STR_P(pvalue), 0, "body md5"); + bod->md5 = cpystr(Z_STRVAL_P(pvalue)); + } + } else if (Z_TYPE_P(data) == IS_ARRAY) { +@@ -3740,6 +3786,7 @@ + } + if ((pvalue = zend_hash_str_find(Z_ARRVAL_P(data), "charset", sizeof("charset") - 1)) != NULL) { + convert_to_string_ex(pvalue); ++ CHECK_HEADER_INJECTION(Z_STR_P(pvalue), 0, "body charset"); + tmp_param = mail_newbody_parameter(); + tmp_param->value = (char *) fs_get(Z_STRLEN_P(pvalue) + 1); + memcpy(tmp_param->value, Z_STRVAL_P(pvalue), Z_STRLEN_P(pvalue) + 1); +@@ -3751,9 +3798,11 @@ + if (Z_TYPE_P(pvalue) == IS_ARRAY) { + disp_param = tmp_param = NULL; + ZEND_HASH_FOREACH_STR_KEY_VAL(Z_ARRVAL_P(pvalue), key, disp_data) { ++ CHECK_HEADER_INJECTION(key, 0, "body type.parameters key"); + disp_param = mail_newbody_parameter(); + disp_param->attribute = cpystr(ZSTR_VAL(key)); + convert_to_string_ex(disp_data); ++ CHECK_HEADER_INJECTION(Z_STR_P(disp_data), 0, "body type.parameters value"); + disp_param->value = (char *)fs_get(Z_STRLEN_P(disp_data) + 1); + memcpy(disp_param->value, Z_STRVAL_P(disp_data), Z_STRLEN_P(disp_data) + 1); + disp_param->next = tmp_param; +@@ -3764,18 +3813,22 @@ + } + if ((pvalue = zend_hash_str_find(Z_ARRVAL_P(data), "subtype", sizeof("subtype") - 1)) != NULL) { + convert_to_string_ex(pvalue); ++ CHECK_HEADER_INJECTION(Z_STR_P(pvalue), 0, "body subtype"); + bod->subtype = cpystr(Z_STRVAL_P(pvalue)); + } + if ((pvalue = zend_hash_str_find(Z_ARRVAL_P(data), "id", sizeof("id") - 1)) != NULL) { + convert_to_string_ex(pvalue); ++ CHECK_HEADER_INJECTION(Z_STR_P(pvalue), 0, "body id"); + bod->id = cpystr(Z_STRVAL_P(pvalue)); + } + if ((pvalue = zend_hash_str_find(Z_ARRVAL_P(data), "description", sizeof("description") - 1)) != NULL) { + convert_to_string_ex(pvalue); ++ CHECK_HEADER_INJECTION(Z_STR_P(pvalue), 0, "body description"); + bod->description = cpystr(Z_STRVAL_P(pvalue)); + } + if ((pvalue = zend_hash_str_find(Z_ARRVAL_P(data), "disposition.type", sizeof("disposition.type") - 1)) != NULL) { + convert_to_string_ex(pvalue); ++ CHECK_HEADER_INJECTION(Z_STR_P(pvalue), 0, "body disposition.type"); + bod->disposition.type = (char *) fs_get(Z_STRLEN_P(pvalue) + 1); + memcpy(bod->disposition.type, Z_STRVAL_P(pvalue), Z_STRLEN_P(pvalue)+1); + } +@@ -3783,9 +3836,11 @@ + if (Z_TYPE_P(pvalue) == IS_ARRAY) { + disp_param = tmp_param = NULL; + ZEND_HASH_FOREACH_STR_KEY_VAL(Z_ARRVAL_P(pvalue), key, disp_data) { ++ CHECK_HEADER_INJECTION(key, 0, "body disposition key"); + disp_param = mail_newbody_parameter(); + disp_param->attribute = cpystr(ZSTR_VAL(key)); + convert_to_string_ex(disp_data); ++ CHECK_HEADER_INJECTION(Z_STR_P(disp_data), 0, "body disposition value"); + disp_param->value = (char *) fs_get(Z_STRLEN_P(disp_data) + 1); + memcpy(disp_param->value, Z_STRVAL_P(disp_data), Z_STRLEN_P(disp_data) + 1); + disp_param->next = tmp_param; +@@ -3814,6 +3869,7 @@ + } + if ((pvalue = zend_hash_str_find(Z_ARRVAL_P(data), "md5", sizeof("md5") - 1)) != NULL) { + convert_to_string_ex(pvalue); ++ CHECK_HEADER_INJECTION(Z_STR_P(pvalue), 0, "body md5"); + bod->md5 = cpystr(Z_STRVAL_P(pvalue)); + } + } +--- /dev/null ++++ b/ext/imap/tests/bug80710_1.phpt +@@ -0,0 +1,37 @@ ++--TEST-- ++Bug #80710 (imap_mail_compose() header injection) - MIME Splitting Attack ++--SKIPIF-- ++<?php ++if (!extension_loaded("imap")) die("skip imap extension not available"); ++?> ++--FILE-- ++<?php ++$envelope["from"]= "joe@example.com\n From : X-INJECTED"; ++$envelope["to"] = "foo@example.com\nFrom: X-INJECTED"; ++$envelope["cc"] = "bar@example.com\nFrom: X-INJECTED"; ++$envelope["subject"] = "bar@example.com\n\n From : X-INJECTED"; ++$envelope["x-remail"] = "bar@example.com\nFrom: X-INJECTED"; ++$envelope["something"] = "bar@example.com\nFrom: X-INJECTED"; ++ ++$part1["type"] = TYPEMULTIPART; ++$part1["subtype"] = "mixed"; ++ ++$part2["type"] = TYPEAPPLICATION; ++$part2["encoding"] = ENCBINARY; ++$part2["subtype"] = "octet-stream\nContent-Type: X-INJECTED"; ++$part2["description"] = "some file\nContent-Type: X-INJECTED"; ++$part2["contents.data"] = "ABC\nContent-Type: X-INJECTED"; ++ ++$part3["type"] = TYPETEXT; ++$part3["subtype"] = "plain"; ++$part3["description"] = "description3"; ++$part3["contents.data"] = "contents.data3\n\n\n\t"; ++ ++$body[1] = $part1; ++$body[2] = $part2; ++$body[3] = $part3; ++ ++echo imap_mail_compose($envelope, $body); ++?> ++--EXPECTF-- ++Warning: imap_mail_compose(): header injection attempt in from in %s on line %d +--- /dev/null ++++ b/ext/imap/tests/bug80710_2.phpt +@@ -0,0 +1,37 @@ ++--TEST-- ++Bug #80710 (imap_mail_compose() header injection) - Remail ++--SKIPIF-- ++<?php ++if (!extension_loaded("imap")) die("skip imap extension not available"); ++?> ++--FILE-- ++<?php ++$envelope["from"]= "joe@example.com\n From : X-INJECTED"; ++$envelope["to"] = "foo@example.com\nFrom: X-INJECTED"; ++$envelope["cc"] = "bar@example.com\nFrom: X-INJECTED"; ++$envelope["subject"] = "bar@example.com\n\n From : X-INJECTED"; ++$envelope["remail"] = "X-INJECTED-REMAIL: X-INJECTED\nFrom: X-INJECTED-REMAIL-FROM"; //<--- Injected as first hdr ++$envelope["something"] = "bar@example.com\nFrom: X-INJECTED"; ++ ++$part1["type"] = TYPEMULTIPART; ++$part1["subtype"] = "mixed"; ++ ++$part2["type"] = TYPEAPPLICATION; ++$part2["encoding"] = ENCBINARY; ++$part2["subtype"] = "octet-stream\nContent-Type: X-INJECTED"; ++$part2["description"] = "some file\nContent-Type: X-INJECTED"; ++$part2["contents.data"] = "ABC\nContent-Type: X-INJECTED"; ++ ++$part3["type"] = TYPETEXT; ++$part3["subtype"] = "plain"; ++$part3["description"] = "description3"; ++$part3["contents.data"] = "contents.data3\n\n\n\t"; ++ ++$body[1] = $part1; ++$body[2] = $part2; ++$body[3] = $part3; ++ ++echo imap_mail_compose($envelope, $body); ++?> ++--EXPECTF-- ++Warning: imap_mail_compose(): header injection attempt in remail in %s on line %d +diff --git a/ext/pdo_firebird/firebird_statement.c b/ext/pdo_firebird/firebird_statement.c +index 1c0f5b6..c5e6b68 100644 +--- a/ext/pdo_firebird/firebird_statement.c ++++ b/ext/pdo_firebird/firebird_statement.c +@@ -294,6 +294,11 @@ + unsigned short seg_len; + ISC_STATUS stat; + ++ /* prevent overflow */ ++ if (*len == ZEND_ULONG_MAX) { ++ result = 0; ++ goto fetch_blob_end; ++ } + *ptr = S->fetch_buf[colno] = erealloc(S->fetch_buf[colno], *len+1); + + for (cur_len = stat = 0; (!stat || stat == isc_segment) && cur_len < *len; cur_len += seg_len) { +--- /dev/null ++++ b/ext/pdo_firebird/tests/bug_76452.data +@@ -0,0 +1 @@ ++ +\ No newline at end of file +--- /dev/null ++++ b/ext/pdo_firebird/tests/bug_76452.phpt +@@ -0,0 +1,31 @@ ++--TEST-- ++Bug ##76452 (Crash while parsing blob data in firebird_fetch_blob) ++--SKIPIF-- ++<?php require('skipif.inc'); ?> ++--FILE-- ++<?php ++require_once "payload_server.inc"; ++ ++$address = run_server(__DIR__ . "/bug_76452.data"); ++ ++// no need to change the credentials; we're running against a falke server ++$dsn = "firebird:dbname=inet://$address/test"; ++$username = 'SYSDBA'; ++$password = 'masterkey'; ++ ++$dbh = new PDO($dsn, $username, $password, [PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION]); ++$query = $dbh->prepare("select * from test"); ++$query->execute(); ++var_dump($query->fetch()); ++?> ++--EXPECT-- ++array(4) { ++ ["AAA"]=> ++ string(4) "hihi" ++ [0]=> ++ string(4) "hihi" ++ ["BBBB"]=> ++ NULL ++ [1]=> ++ NULL ++} +diff --git a/ext/pdo_firebird/firebird_statement.c b/ext/pdo_firebird/firebird_statement.c +index c5e6b68..bdde6c7 100644 +--- a/ext/pdo_firebird/firebird_statement.c ++++ b/ext/pdo_firebird/firebird_statement.c +@@ -133,8 +133,14 @@ + } + if (result[0] == isc_info_sql_records) { + unsigned i = 3, result_size = isc_vax_integer(&result[1], 2); ++ if (result_size > sizeof(result)) { ++ goto error; ++ } + while (result[i] != isc_info_end && i < result_size) { + short len = (short) isc_vax_integer(&result[i + 1], 2); ++ if (len != 1 && len != 2 && len != 4) { ++ goto error; ++ } + if (result[i] != isc_info_req_select_count) { + affected_rows += isc_vax_integer(&result[i + 3], len); + } +@@ -158,6 +164,7 @@ + return 1; + } while (0); + ++error: + RECORD_ERROR(stmt); + + return 0; +--- /dev/null ++++ b/ext/pdo_firebird/tests/bug_76450.data +@@ -0,0 +1 @@ ++ +\ No newline at end of file +--- /dev/null ++++ b/ext/pdo_firebird/tests/bug_76450.phpt +@@ -0,0 +1,29 @@ ++--TEST-- ++Bug #76450 (SIGSEGV in firebird_stmt_execute) ++--SKIPIF-- ++<?php ++if (!extension_loaded('pdo_firebird')) die("skip pdo_firebird extension not available"); ++if (!extension_loaded('sockets')) die("skip sockets extension not available"); ++?> ++--FILE-- ++<?php ++require_once "payload_server.inc"; ++ ++$address = run_server(__DIR__ . "/bug_76450.data"); ++ ++// no need to change the credentials; we're running against a fake server ++$dsn = "firebird:dbname=inet://$address/test"; ++$username = 'SYSDBA'; ++$password = 'masterkey'; ++ ++$dbh = new PDO($dsn, $username, $password, [PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION]); ++$sql = "EXECUTE PROCEDURE test_proc 123"; ++$query = $dbh->prepare($sql); ++try { ++ $query->execute(); ++} catch (Exception $ex) { ++ echo "{$ex->getMessage()}\n"; ++} ++?> ++--EXPECT-- ++SQLSTATE[HY000]: General error +diff --git a/ext/pdo_firebird/firebird_driver.c b/ext/pdo_firebird/firebird_driver.c +index 34e234a..fb9dbaa 100644 +--- a/ext/pdo_firebird/firebird_driver.c ++++ b/ext/pdo_firebird/firebird_driver.c +@@ -205,8 +205,17 @@ + if (result[0] == isc_info_sql_records) { + unsigned i = 3, result_size = isc_vax_integer(&result[1],2); + ++ if (result_size > sizeof(result)) { ++ ret = -1; ++ goto free_statement; ++ } + while (result[i] != isc_info_end && i < result_size) { + short len = (short)isc_vax_integer(&result[i+1],2); ++ /* bail out on bad len */ ++ if (len != 1 && len != 2 && len != 4) { ++ ret = -1; ++ goto free_statement; ++ } + if (result[i] != isc_info_req_select_count) { + ret += isc_vax_integer(&result[i+3],len); + } +--- /dev/null ++++ b/ext/pdo_firebird/tests/bug_76449.data +@@ -0,0 +1 @@ ++ +\ No newline at end of file +--- /dev/null ++++ b/ext/pdo_firebird/tests/bug_76449.phpt +@@ -0,0 +1,23 @@ ++--TEST-- ++Bug #76449 (SIGSEGV in firebird_handle_doer) ++--SKIPIF-- ++<?php ++if (!extension_loaded('pdo_firebird')) die("skip pdo_firebird extension not available"); ++if (!extension_loaded('sockets')) die("skip sockets extension not available"); ++?> ++--FILE-- ++<?php ++require_once "payload_server.inc"; ++ ++$address = run_server(__DIR__ . "/bug_76449.data"); ++ ++// no need to change the credentials; we're running against a fake server ++$dsn = "firebird:dbname=inet://$address/test"; ++$username = 'SYSDBA'; ++$password = 'masterkey'; ++ ++$dbh = new PDO($dsn, $username, $password, [PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION]); ++var_dump($dbh->exec("INSERT INTO test VALUES ('hihi2', 'xxxxx')")); ++?> ++--EXPECT-- ++bool(false) +diff --git a/ext/pdo_firebird/firebird_driver.c b/ext/pdo_firebird/firebird_driver.c +index fb9dbaa..48e8ec6 100644 +--- a/ext/pdo_firebird/firebird_driver.c ++++ b/ext/pdo_firebird/firebird_driver.c +@@ -508,14 +508,16 @@ + } + /* }}} */ + ++#define INFO_BUF_LEN 512 ++ + /* callback to used to report database server info */ + static void firebird_info_cb(void *arg, char const *s) /* {{{ */ + { + if (arg) { + if (*(char*)arg) { /* second call */ +- strcat(arg, " "); ++ strlcat(arg, " ", INFO_BUF_LEN); + } +- strcat(arg, s); ++ strlcat(arg, s, INFO_BUF_LEN); + } + } + /* }}} */ +@@ -526,7 +528,7 @@ + pdo_firebird_db_handle *H = (pdo_firebird_db_handle *)dbh->driver_data; + + switch (attr) { +- char tmp[512]; ++ char tmp[INFO_BUF_LEN]; + + case PDO_ATTR_AUTOCOMMIT: + ZVAL_LONG(val,dbh->auto_commit); +--- /dev/null ++++ b/ext/pdo_firebird/tests/bug_76448.data +@@ -0,0 +1 @@ ++ +\ No newline at end of file +--- /dev/null ++++ b/ext/pdo_firebird/tests/bug_76448.phpt +@@ -0,0 +1,23 @@ ++--TEST-- ++Bug #76448 (Stack buffer overflow in firebird_info_cb) ++--SKIPIF-- ++<?php ++if (!extension_loaded('pdo_firebird')) die("skip podo_firebird extension not available"); ++if (!extension_loaded('sockets')) die("skip sockets extension not available"); ++?> ++--FILE-- ++<?php ++require_once "payload_server.inc"; ++ ++$address = run_server(__DIR__ . "/bug_76448.data"); ++ ++// no need to change the credentials; we're running against a falke server ++$dsn = "firebird:dbname=inet://$address/test"; ++$username = 'SYSDBA'; ++$password = 'masterkey'; ++ ++$dbh = new PDO($dsn, $username, $password, [PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION]); ++var_dump($dbh->getAttribute(PDO::ATTR_SERVER_INFO)); ++?> ++--EXPECT-- ++bool(false) +diff --git a/ext/phar/phar_object.c b/ext/phar/phar_object.c +index 2987b64..01bdc05 100644 +--- a/ext/phar/phar_object.c ++++ b/ext/phar/phar_object.c +@@ -1440,6 +1440,7 @@ + zend_class_entry *ce = p_obj->c; + phar_archive_object *phar_obj = p_obj->p; + php_stream_statbuf ssb; ++ char ch; + + value = iter->funcs->get_current_data(iter); + +@@ -1569,7 +1570,7 @@ + base = temp; + base_len = (int)strlen(base); + +- if (strstr(fname, base)) { ++ if (fname_len >= base_len && strncmp(fname, base, base_len) == 0 && ((ch = fname[base_len - IS_SLASH(base[base_len - 1])]) == '\0' || IS_SLASH(ch))) { + str_key_len = fname_len - base_len; + + if (str_key_len <= 0) { +--- /dev/null ++++ b/ext/phar/tests/bug81211.phpt +@@ -0,0 +1,45 @@ ++--TEST-- ++Bug #81211 (Symlinks are followed when creating PHAR archive) ++--SKIPIF-- ++<?php ++if (!extension_loaded('phar')) die('skip phar extension is not available'); ++if (PHP_OS_FAMILY === 'Windows') { ++ if (false === include __DIR__ . '/../../standard/tests/file/windows_links/common.inc') { ++ die('skip windows_links/common.inc is not available'); ++ } ++ skipIfSeCreateSymbolicLinkPrivilegeIsDisabled(__FILE__); ++} ++?> ++--FILE-- ++<?php ++mkdir(__DIR__ . '/bug81211'); ++mkdir(__DIR__ . '/bug81211/foobar'); ++mkdir(__DIR__ . '/bug81211/foo'); ++ ++file_put_contents(__DIR__ . '/bug81211/foobar/file', 'this file should NOT be included in the archive!'); ++symlink(__DIR__ . '/bug81211/foobar/file', __DIR__ . '/bug81211/foo/symlink'); ++ ++$archive = new PharData(__DIR__ . '/bug81211/archive.tar'); ++try { ++ $archive->buildFromDirectory(__DIR__ . '/bug81211/foo'); ++} catch (UnexpectedValueException $ex) { ++ echo $ex->getMessage(), PHP_EOL; ++} ++try { ++ $archive->buildFromIterator(new RecursiveDirectoryIterator(__DIR__ . '/bug81211/foo', FilesystemIterator::SKIP_DOTS), __DIR__ . '/bug81211/foo'); ++} catch (UnexpectedValueException $ex) { ++ echo $ex->getMessage(), PHP_EOL; ++} ++?> ++--CLEAN-- ++<?php ++@unlink(__DIR__ . '/bug81211/archive.tar'); ++@unlink(__DIR__ . '/bug81211/foo/symlink'); ++@unlink(__DIR__ . '/bug81211/foobar/file'); ++@rmdir(__DIR__ . '/bug81211/foo'); ++@rmdir(__DIR__ . '/bug81211/foobar'); ++@rmdir(__DIR__ . '/bug81211'); ++?> ++--EXPECTF-- ++Iterator RecursiveIteratorIterator returned a path "%s%ebug81211\foobar\file" that is not in the base directory "%s%ebug81211\foo" ++Iterator RecursiveDirectoryIterator returned a path "%s%ebug81211\foobar\file" that is not in the base directory "%s%ebug81211\foo" +diff --git a/ext/standard/tests/file/windows_links/common.inc b/ext/standard/tests/file/windows_links/common.inc +index 505368b..caa3758 100644 +--- a/ext/standard/tests/file/windows_links/common.inc ++++ b/ext/standard/tests/file/windows_links/common.inc +@@ -20,4 +20,11 @@ + return "$sysroot\\System32\\mountvol.exe"; + } + +-?> ++function skipIfSeCreateSymbolicLinkPrivilegeIsDisabled(string $filename) { ++ $ln = "$filename.lnk"; ++ $ret = exec("mklink $ln " . __FILE__ .' 2>&1', $out); ++ @unlink($ln); ++ if (strpos($ret, 'privilege') !== false) { ++ die('skip SeCreateSymbolicLinkPrivilege not enabled'); ++ } ++} +diff --git a/sapi/fpm/fpm/fpm_children.c b/sapi/fpm/fpm/fpm_children.c +index eed0c67..05513f0 100644 +--- a/sapi/fpm/fpm/fpm_children.c ++++ b/sapi/fpm/fpm/fpm_children.c +@@ -243,7 +243,7 @@ + + fpm_child_unlink(child); + +- fpm_scoreboard_proc_free(wp->scoreboard, child->scoreboard_i); ++ fpm_scoreboard_proc_free(child); + + fpm_clock_get(&tv1); + +@@ -253,9 +253,9 @@ + if (!fpm_pctl_can_spawn_children()) { + severity = ZLOG_DEBUG; + } +- zlog(severity, "[pool %s] child %d exited %s after %ld.%06d seconds from start", child->wp->config->name, (int) pid, buf, tv2.tv_sec, (int) tv2.tv_usec); ++ zlog(severity, "[pool %s] child %d exited %s after %ld.%06d seconds from start", wp->config->name, (int) pid, buf, tv2.tv_sec, (int) tv2.tv_usec); + } else { +- zlog(ZLOG_DEBUG, "[pool %s] child %d has been killed by the process management after %ld.%06d seconds from start", child->wp->config->name, (int) pid, tv2.tv_sec, (int) tv2.tv_usec); ++ zlog(ZLOG_DEBUG, "[pool %s] child %d has been killed by the process management after %ld.%06d seconds from start", wp->config->name, (int) pid, tv2.tv_sec, (int) tv2.tv_usec); + } + + fpm_child_close(child, 1 /* in event_loop */); +@@ -321,7 +321,7 @@ + return 0; + } + +- if (0 > fpm_scoreboard_proc_alloc(wp->scoreboard, &c->scoreboard_i)) { ++ if (0 > fpm_scoreboard_proc_alloc(c)) { + fpm_stdio_discard_pipes(c); + fpm_child_free(c); + return 0; +@@ -333,7 +333,7 @@ + + static void fpm_resources_discard(struct fpm_child_s *child) /* {{{ */ + { +- fpm_scoreboard_proc_free(child->wp->scoreboard, child->scoreboard_i); ++ fpm_scoreboard_proc_free(child); + fpm_stdio_discard_pipes(child); + fpm_child_free(child); + } +@@ -346,10 +346,10 @@ + if (wp == child->wp) { + continue; + } +- fpm_scoreboard_free(wp->scoreboard); ++ fpm_scoreboard_free(wp); + } + +- fpm_scoreboard_child_use(child->wp->scoreboard, child->scoreboard_i, getpid()); ++ fpm_scoreboard_child_use(child, getpid()); + fpm_stdio_child_use_pipes(child); + fpm_child_free(child); + } +diff --git a/sapi/fpm/fpm/fpm_request.c b/sapi/fpm/fpm/fpm_request.c +index a4ace85..deaccf4 100644 +--- a/sapi/fpm/fpm/fpm_request.c ++++ b/sapi/fpm/fpm/fpm_request.c +@@ -286,7 +286,7 @@ + struct fpm_scoreboard_proc_s *proc; + + /* no need in atomicity here */ +- proc = fpm_scoreboard_proc_get(child->wp->scoreboard, child->scoreboard_i); ++ proc = fpm_scoreboard_proc_get_from_child(child); + if (!proc) { + return 0; + } +@@ -301,7 +301,7 @@ + + if (!tv) return -1; + +- proc = fpm_scoreboard_proc_get(child->wp->scoreboard, child->scoreboard_i); ++ proc = fpm_scoreboard_proc_get_from_child(child); + if (!proc) { + return -1; + } +diff --git a/sapi/fpm/fpm/fpm_scoreboard.c b/sapi/fpm/fpm/fpm_scoreboard.c +index 7a65fcb..091efdc 100644 +--- a/sapi/fpm/fpm/fpm_scoreboard.c ++++ b/sapi/fpm/fpm/fpm_scoreboard.c +@@ -7,6 +7,7 @@ + #include <time.h> + + #include "fpm_config.h" ++#include "fpm_children.h" + #include "fpm_scoreboard.h" + #include "fpm_shm.h" + #include "fpm_sockets.h" +@@ -24,7 +25,6 @@ + int fpm_scoreboard_init_main() /* {{{ */ + { + struct fpm_worker_pool_s *wp; +- unsigned int i; + + #ifdef HAVE_TIMES + #if (defined(HAVE_SYSCONF) && defined(_SC_CLK_TCK)) +@@ -41,7 +41,7 @@ + + + for (wp = fpm_worker_all_pools; wp; wp = wp->next) { +- size_t scoreboard_size, scoreboard_nprocs_size; ++ size_t scoreboard_procs_size; + void *shm_mem; + + if (wp->config->pm_max_children < 1) { +@@ -54,22 +54,15 @@ + return -1; + } + +- scoreboard_size = sizeof(struct fpm_scoreboard_s) + (wp->config->pm_max_children) * sizeof(struct fpm_scoreboard_proc_s *); +- scoreboard_nprocs_size = sizeof(struct fpm_scoreboard_proc_s) * wp->config->pm_max_children; +- shm_mem = fpm_shm_alloc(scoreboard_size + scoreboard_nprocs_size); ++ scoreboard_procs_size = sizeof(struct fpm_scoreboard_proc_s) * wp->config->pm_max_children; ++ shm_mem = fpm_shm_alloc(sizeof(struct fpm_scoreboard_s) + scoreboard_procs_size); + + if (!shm_mem) { + return -1; + } +- wp->scoreboard = shm_mem; ++ wp->scoreboard = shm_mem; ++ wp->scoreboard->pm = wp->config->pm; + wp->scoreboard->nprocs = wp->config->pm_max_children; +- shm_mem += scoreboard_size; +- +- for (i = 0; i < wp->scoreboard->nprocs; i++, shm_mem += sizeof(struct fpm_scoreboard_proc_s)) { +- wp->scoreboard->procs[i] = shm_mem; +- } +- +- wp->scoreboard->pm = wp->config->pm; + wp->scoreboard->start_epoch = time(NULL); + strlcpy(wp->scoreboard->pool, wp->config->name, sizeof(wp->scoreboard->pool)); + } +@@ -163,28 +156,48 @@ + } + /* }}} */ + +-struct fpm_scoreboard_proc_s *fpm_scoreboard_proc_get(struct fpm_scoreboard_s *scoreboard, int child_index) /* {{{*/ ++static inline struct fpm_scoreboard_proc_s *fpm_scoreboard_proc_get_ex( ++ struct fpm_scoreboard_s *scoreboard, int child_index, unsigned int nprocs) /* {{{*/ + { + if (!scoreboard) { +- scoreboard = fpm_scoreboard; ++ return NULL; + } + +- if (!scoreboard) { ++ if (child_index < 0 || (unsigned int)child_index >= nprocs) { + return NULL; + } + ++ return &scoreboard->procs[child_index]; ++} ++/* }}} */ ++ ++struct fpm_scoreboard_proc_s *fpm_scoreboard_proc_get( ++ struct fpm_scoreboard_s *scoreboard, int child_index) /* {{{*/ ++{ ++ if (!scoreboard) { ++ scoreboard = fpm_scoreboard; ++ } ++ + if (child_index < 0) { + child_index = fpm_scoreboard_i; + } + +- if (child_index < 0 || (unsigned int)child_index >= scoreboard->nprocs) { +- return NULL; +- } ++ return fpm_scoreboard_proc_get_ex(scoreboard, child_index, scoreboard->nprocs); ++} ++/* }}} */ + +- return scoreboard->procs[child_index]; ++struct fpm_scoreboard_proc_s *fpm_scoreboard_proc_get_from_child(struct fpm_child_s *child) /* {{{*/ ++{ ++ struct fpm_worker_pool_s *wp = child->wp; ++ unsigned int nprocs = wp->config->pm_max_children; ++ struct fpm_scoreboard_s *scoreboard = wp->scoreboard; ++ int child_index = child->scoreboard_i; ++ ++ return fpm_scoreboard_proc_get_ex(scoreboard, child_index, nprocs); + } + /* }}} */ + ++ + struct fpm_scoreboard_s *fpm_scoreboard_acquire(struct fpm_scoreboard_s *scoreboard, int nohang) /* {{{ */ + { + struct fpm_scoreboard_s *s; +@@ -235,28 +248,28 @@ + proc->lock = 0; + } + +-void fpm_scoreboard_free(struct fpm_scoreboard_s *scoreboard) /* {{{ */ ++void fpm_scoreboard_free(struct fpm_worker_pool_s *wp) /* {{{ */ + { +- size_t scoreboard_size, scoreboard_nprocs_size; ++ size_t scoreboard_procs_size; ++ struct fpm_scoreboard_s *scoreboard = wp->scoreboard; + + if (!scoreboard) { + zlog(ZLOG_ERROR, "**scoreboard is NULL"); + return; + } + +- scoreboard_size = sizeof(struct fpm_scoreboard_s) + (scoreboard->nprocs) * sizeof(struct fpm_scoreboard_proc_s *); +- scoreboard_nprocs_size = sizeof(struct fpm_scoreboard_proc_s) * scoreboard->nprocs; ++ scoreboard_procs_size = sizeof(struct fpm_scoreboard_proc_s) * wp->config->pm_max_children; + +- fpm_shm_free(scoreboard, scoreboard_size + scoreboard_nprocs_size); ++ fpm_shm_free(scoreboard, sizeof(struct fpm_scoreboard_s) + scoreboard_procs_size); + } + /* }}} */ + +-void fpm_scoreboard_child_use(struct fpm_scoreboard_s *scoreboard, int child_index, pid_t pid) /* {{{ */ ++void fpm_scoreboard_child_use(struct fpm_child_s *child, pid_t pid) /* {{{ */ + { + struct fpm_scoreboard_proc_s *proc; +- fpm_scoreboard = scoreboard; +- fpm_scoreboard_i = child_index; +- proc = fpm_scoreboard_proc_get(scoreboard, child_index); ++ fpm_scoreboard = child->wp->scoreboard; ++ fpm_scoreboard_i = child->scoreboard_i; ++ proc = fpm_scoreboard_proc_get_from_child(child); + if (!proc) { + return; + } +@@ -265,18 +278,22 @@ + } + /* }}} */ + +-void fpm_scoreboard_proc_free(struct fpm_scoreboard_s *scoreboard, int child_index) /* {{{ */ ++void fpm_scoreboard_proc_free(struct fpm_child_s *child) /* {{{ */ + { ++ struct fpm_worker_pool_s *wp = child->wp; ++ struct fpm_scoreboard_s *scoreboard = wp->scoreboard; ++ int child_index = child->scoreboard_i; ++ + if (!scoreboard) { + return; + } + +- if (child_index < 0 || (unsigned int)child_index >= scoreboard->nprocs) { ++ if (child_index < 0 || child_index >= wp->config->pm_max_children) { + return; + } + +- if (scoreboard->procs[child_index] && scoreboard->procs[child_index]->used > 0) { +- memset(scoreboard->procs[child_index], 0, sizeof(struct fpm_scoreboard_proc_s)); ++ if (scoreboard->procs[child_index].used > 0) { ++ memset(&scoreboard->procs[child_index], 0, sizeof(struct fpm_scoreboard_proc_s)); + } + + /* set this slot as free to avoid search on next alloc */ +@@ -284,41 +301,44 @@ + } + /* }}} */ + +-int fpm_scoreboard_proc_alloc(struct fpm_scoreboard_s *scoreboard, int *child_index) /* {{{ */ ++int fpm_scoreboard_proc_alloc(struct fpm_child_s *child) /* {{{ */ + { + int i = -1; ++ struct fpm_worker_pool_s *wp = child->wp; ++ struct fpm_scoreboard_s *scoreboard = wp->scoreboard; ++ int nprocs = wp->config->pm_max_children; + +- if (!scoreboard || !child_index) { ++ if (!scoreboard) { + return -1; + } + + /* first try the slot which is supposed to be free */ +- if (scoreboard->free_proc >= 0 && (unsigned int)scoreboard->free_proc < scoreboard->nprocs) { +- if (scoreboard->procs[scoreboard->free_proc] && !scoreboard->procs[scoreboard->free_proc]->used) { ++ if (scoreboard->free_proc >= 0 && scoreboard->free_proc < nprocs) { ++ if (!scoreboard->procs[scoreboard->free_proc].used) { + i = scoreboard->free_proc; + } + } + + if (i < 0) { /* the supposed free slot is not, let's search for a free slot */ + zlog(ZLOG_DEBUG, "[pool %s] the proc->free_slot was not free. Let's search", scoreboard->pool); +- for (i = 0; i < (int)scoreboard->nprocs; i++) { +- if (scoreboard->procs[i] && !scoreboard->procs[i]->used) { /* found */ ++ for (i = 0; i < nprocs; i++) { ++ if (!scoreboard->procs[i].used) { /* found */ + break; + } + } + } + + /* no free slot */ +- if (i < 0 || i >= (int)scoreboard->nprocs) { ++ if (i < 0 || i >= nprocs) { + zlog(ZLOG_ERROR, "[pool %s] no free scoreboard slot", scoreboard->pool); + return -1; + } + +- scoreboard->procs[i]->used = 1; +- *child_index = i; ++ scoreboard->procs[i].used = 1; ++ child->scoreboard_i = i; + + /* supposed next slot is free */ +- if (i + 1 >= (int)scoreboard->nprocs) { ++ if (i + 1 >= nprocs) { + scoreboard->free_proc = 0; + } else { + scoreboard->free_proc = i + 1; +diff --git a/sapi/fpm/fpm/fpm_scoreboard.h b/sapi/fpm/fpm/fpm_scoreboard.h +index abce616..6405abb 100644 +--- a/sapi/fpm/fpm/fpm_scoreboard.h ++++ b/sapi/fpm/fpm/fpm_scoreboard.h +@@ -64,7 +64,7 @@ + unsigned int nprocs; + int free_proc; + unsigned long int slow_rq; +- struct fpm_scoreboard_proc_s *procs[]; ++ struct fpm_scoreboard_proc_s procs[]; + }; + + int fpm_scoreboard_init_main(); +@@ -73,18 +73,19 @@ + void fpm_scoreboard_update(int idle, int active, int lq, int lq_len, int requests, int max_children_reached, int slow_rq, int action, struct fpm_scoreboard_s *scoreboard); + struct fpm_scoreboard_s *fpm_scoreboard_get(); + struct fpm_scoreboard_proc_s *fpm_scoreboard_proc_get(struct fpm_scoreboard_s *scoreboard, int child_index); ++struct fpm_scoreboard_proc_s *fpm_scoreboard_proc_get_from_child(struct fpm_child_s *child); + + struct fpm_scoreboard_s *fpm_scoreboard_acquire(struct fpm_scoreboard_s *scoreboard, int nohang); + void fpm_scoreboard_release(struct fpm_scoreboard_s *scoreboard); + struct fpm_scoreboard_proc_s *fpm_scoreboard_proc_acquire(struct fpm_scoreboard_s *scoreboard, int child_index, int nohang); + void fpm_scoreboard_proc_release(struct fpm_scoreboard_proc_s *proc); + +-void fpm_scoreboard_free(struct fpm_scoreboard_s *scoreboard); ++void fpm_scoreboard_free(struct fpm_worker_pool_s *wp); + +-void fpm_scoreboard_child_use(struct fpm_scoreboard_s *scoreboard, int child_index, pid_t pid); ++void fpm_scoreboard_child_use(struct fpm_child_s *child, pid_t pid); + +-void fpm_scoreboard_proc_free(struct fpm_scoreboard_s *scoreboard, int child_index); +-int fpm_scoreboard_proc_alloc(struct fpm_scoreboard_s *scoreboard, int *child_index); ++void fpm_scoreboard_proc_free(struct fpm_child_s *child); ++int fpm_scoreboard_proc_alloc(struct fpm_child_s *child); + + #ifdef HAVE_TIMES + float fpm_scoreboard_get_tick(); +diff --git a/sapi/fpm/fpm/fpm_status.c b/sapi/fpm/fpm/fpm_status.c +index 1d78ebf..45852a5 100644 +--- a/sapi/fpm/fpm/fpm_status.c ++++ b/sapi/fpm/fpm/fpm_status.c +@@ -402,10 +402,10 @@ + + first = 1; + for (i=0; i<scoreboard_p->nprocs; i++) { +- if (!scoreboard_p->procs[i] || !scoreboard_p->procs[i]->used) { ++ if (!scoreboard_p->procs[i].used) { + continue; + } +- proc = *scoreboard_p->procs[i]; ++ proc = scoreboard_p->procs[i]; + + if (first) { + first = 0; +diff --git a/sapi/fpm/fpm/fpm_worker_pool.c b/sapi/fpm/fpm/fpm_worker_pool.c +index 90e1559..96b7ca5 100644 +--- a/sapi/fpm/fpm/fpm_worker_pool.c ++++ b/sapi/fpm/fpm/fpm_worker_pool.c +@@ -43,7 +43,7 @@ + fpm_worker_pool_config_free(wp->config); + fpm_children_free(wp->children); + if ((which & FPM_CLEANUP_CHILD) == 0 && fpm_globals.parent_pid == getpid()) { +- fpm_scoreboard_free(wp->scoreboard); ++ fpm_scoreboard_free(wp); + } + fpm_worker_pool_free(wp); + } +diff --git a/ext/zip/php_zip.c b/ext/zip/php_zip.c +index af1d8db..c467a81 100644 +--- a/ext/zip/php_zip.c ++++ b/ext/zip/php_zip.c +@@ -106,8 +106,8 @@ + return NULL; + } + +- if (IS_SLASH(path[0])) { +- return path + 1; ++ if (IS_ABSOLUTE_PATH(path, path_len)) { ++ return path + COPY_WHEN_ABSOLUTE(path) + 1; + } + + i = path_len; +--- /dev/null ++++ b/ext/zip/tests/bug81420.phpt +@@ -0,0 +1,24 @@ ++--TEST-- ++Bug #81420 (ZipArchive::extractTo extracts outside of destination) ++--SKIPIF-- ++<?php ++if (!extension_loaded("zip")) die("skip zip extension not available"); ++?> ++--FILE-- ++<?php ++$zip = new ZipArchive(); ++$zip->open(__DIR__ . "/bug81420.zip"); ++$destination = __DIR__ . "/bug81420"; ++mkdir($destination); ++$zip->extractTo($destination); ++var_dump(file_exists("$destination/nt1/zzr_noharm.php")); ++?> ++--CLEAN-- ++<?php ++$destination = __DIR__ . "/bug81420"; ++@unlink("$destination/nt1/zzr_noharm.php"); ++@rmdir("$destination/nt1"); ++@rmdir($destination); ++?> ++--EXPECT-- ++bool(true) +--- /dev/null ++++ b/ext/zip/tests/bug81420.zip +@@ -0,0 +1,2 @@ ++PK ++ +\ No newline at end of file +diff --git a/ext/dom/domimplementation.c b/ext/dom/domimplementation.c +index 28e35eb..f4d1358 100644 +--- a/ext/dom/domimplementation.c ++++ b/ext/dom/domimplementation.c +@@ -114,6 +114,11 @@ + pch2 = (xmlChar *) systemid; + } + ++ if (strstr(name, "%00")) { ++ php_error_docref(NULL, E_WARNING, "URI must not contain percent-encoded NUL bytes"); ++ RETURN_FALSE; ++ } ++ + uri = xmlParseURI(name); + if (uri != NULL && uri->opaque != NULL) { + localname = xmlStrdup((xmlChar *) uri->opaque); +--- /dev/null ++++ b/ext/dom/tests/bug79971_2.phpt +@@ -0,0 +1,20 @@ ++--TEST-- ++Bug #79971 (special character is breaking the path in xml function) ++--SKIPIF-- ++<?php ++if (!extension_loaded('dom')) die('skip dom extension not available'); ++?> ++--FILE-- ++<?php ++$imp = new DOMImplementation; ++if (PHP_OS_FAMILY === 'Windows') { ++ $path = '/' . str_replace('\\', '/', __DIR__); ++} else { ++ $path = __DIR__; ++} ++$uri = "file://$path/bug79971_2.xml"; ++var_dump($imp->createDocumentType("$uri%00foo")); ++?> ++--EXPECTF-- ++Warning: DOMImplementation::createDocumentType(): URI must not contain percent-encoded NUL bytes in %s on line %d ++bool(false) +diff --git a/ext/libxml/libxml.c b/ext/libxml/libxml.c +index c871cb8..da553d6 100644 +--- a/ext/libxml/libxml.c ++++ b/ext/libxml/libxml.c +@@ -308,6 +308,10 @@ + int isescaped=0; + xmlURI *uri; + ++ if (strstr(filename, "%00")) { ++ php_error_docref(NULL, E_WARNING, "URI must not contain percent-encoded NUL bytes"); ++ return NULL; ++ } + + uri = xmlParseURI(filename); + if (uri && (uri->scheme == NULL || +@@ -438,6 +442,11 @@ + if (URI == NULL) + return(NULL); + ++ if (strstr(URI, "%00")) { ++ php_error_docref(NULL, E_WARNING, "URI must not contain percent-encoded NUL bytes"); ++ return NULL; ++ } ++ + puri = xmlParseURI(URI); + if (puri != NULL) { + if (puri->scheme != NULL) +--- /dev/null ++++ b/ext/simplexml/tests/bug79971_1.phpt +@@ -0,0 +1,27 @@ ++--TEST-- ++Bug #79971 (special character is breaking the path in xml function) ++--SKIPIF-- ++<?php ++if (!extension_loaded('simplexml')) die('skip simplexml extension not available'); ++?> ++--FILE-- ++<?php ++if (PHP_OS_FAMILY === 'Windows') { ++ $path = '/' . str_replace('\\', '/', __DIR__); ++} else { ++ $path = __DIR__; ++} ++$uri = "file://$path/bug79971_1.xml"; ++var_dump(simplexml_load_file("$uri%00foo")); ++ ++$sxe = simplexml_load_file($uri); ++var_dump($sxe->asXML("$uri.out%00foo")); ++?> ++--EXPECTF-- ++Warning: simplexml_load_file(): URI must not contain percent-encoded NUL bytes in %s on line %d ++ ++Warning: simplexml_load_file(): I/O warning : failed to load external entity "%s/bug79971_1.xml%00foo" in %s on line %d ++bool(false) ++ ++Warning: SimpleXMLElement::asXML(): URI must not contain percent-encoded NUL bytes in %s on line %d ++bool(false) +--- /dev/null ++++ b/ext/simplexml/tests/bug79971_1.xml +@@ -0,0 +1,2 @@ ++<?xml version="1.0"?> ++<root></root> diff --git a/debian-php-7.3.33.patch b/debian-php-7.3.33.patch new file mode 100644 index 000000000000..812555b99900 --- /dev/null +++ b/debian-php-7.3.33.patch @@ -0,0 +1,389 @@ + +diff --git a/ext/standard/proc_open.c b/ext/standard/proc_open.c +index 612cdf0..7edba08 100644 +--- a/ext/standard/proc_open.c ++++ b/ext/standard/proc_open.c +@@ -56,7 +56,7 @@ + * */ + #ifdef PHP_CAN_SUPPORT_PROC_OPEN + +-#if 0 && HAVE_PTSNAME && HAVE_GRANTPT && HAVE_UNLOCKPT && HAVE_SYS_IOCTL_H && HAVE_TERMIOS_H ++#if HAVE_PTSNAME && HAVE_GRANTPT && HAVE_UNLOCKPT && HAVE_SYS_IOCTL_H && HAVE_TERMIOS_H + # include <sys/ioctl.h> + # include <termios.h> + # define PHP_CAN_DO_PTS 1 +diff --git a/php.ini-development b/php.ini-development +index 990e095..c768f17 100644 +--- a/php.ini-development ++++ b/php.ini-development +@@ -302,6 +302,12 @@ + ; or per-virtualhost web server configuration file. + ; Note: disables the realpath cache + ; http://php.net/open-basedir ++ ++; NOTE: this is considered a "broken" security measure. ++; Applications relying on this feature will not receive full ++; support by the security team. For more information please ++; see /usr/share/doc/php-common/README.Debian.security ++; + ;open_basedir = + + ; This directive allows you to disable certain functions for security reasons. +diff --git a/ext/dba/config.m4 b/ext/dba/config.m4 +index 86fa480..ef13306 100644 +--- a/ext/dba/config.m4 ++++ b/ext/dba/config.m4 +@@ -344,61 +344,13 @@ + dbdp4="/usr/local/BerkeleyDB.4." + dbdp5="/usr/local/BerkeleyDB.5." + for i in $PHP_DB4 ${dbdp5}1 ${dbdp5}0 ${dbdp4}8 ${dbdp4}7 ${dbdp4}6 ${dbdp4}5 ${dbdp4}4 ${dbdp4}3 ${dbdp4}2 ${dbdp4}1 ${dbdp}0 /usr/local /usr; do +- if test -f "$i/db5/db.h"; then +- THIS_PREFIX=$i +- THIS_INCLUDE=$i/db5/db.h +- break +- elif test -f "$i/db4/db.h"; then +- THIS_PREFIX=$i +- THIS_INCLUDE=$i/db4/db.h +- break +- elif test -f "$i/include/db5.3/db.h"; then +- THIS_PREFIX=$i +- THIS_INCLUDE=$i/include/db5.3/db.h +- break +- elif test -f "$i/include/db5.1/db.h"; then +- THIS_PREFIX=$i +- THIS_INCLUDE=$i/include/db5.1/db.h +- break +- elif test -f "$i/include/db5.0/db.h"; then +- THIS_PREFIX=$i +- THIS_INCLUDE=$i/include/db5.0/db.h +- break +- elif test -f "$i/include/db4.8/db.h"; then +- THIS_PREFIX=$i +- THIS_INCLUDE=$i/include/db4.8/db.h +- break +- elif test -f "$i/include/db4.7/db.h"; then +- THIS_PREFIX=$i +- THIS_INCLUDE=$i/include/db4.7/db.h +- break +- elif test -f "$i/include/db4.6/db.h"; then +- THIS_PREFIX=$i +- THIS_INCLUDE=$i/include/db4.6/db.h +- break +- elif test -f "$i/include/db4.5/db.h"; then +- THIS_PREFIX=$i +- THIS_INCLUDE=$i/include/db4.5/db.h +- break +- elif test -f "$i/include/db4/db.h"; then +- THIS_PREFIX=$i +- THIS_INCLUDE=$i/include/db4/db.h +- break +- elif test -f "$i/include/db/db4.h"; then +- THIS_PREFIX=$i +- THIS_INCLUDE=$i/include/db/db4.h +- break +- elif test -f "$i/include/db4.h"; then +- THIS_PREFIX=$i +- THIS_INCLUDE=$i/include/db4.h +- break +- elif test -f "$i/include/db.h"; then ++ if test -f "$i/include/db.h"; then + THIS_PREFIX=$i + THIS_INCLUDE=$i/include/db.h + break + fi + done +- PHP_DBA_DB_CHECK(4, db-5.3 db-5.1 db-5.0 db-4.8 db-4.7 db-4.6 db-4.5 db-4.4 db-4.3 db-4.2 db-4.1 db-4.0 db-4 db4 db, [(void)db_create((DB**)0, (DB_ENV*)0, 0)]) ++ PHP_DBA_DB_CHECK(4, db, [(void)db_create((DB**)0, (DB_ENV*)0, 0)]) + fi + PHP_DBA_STD_RESULT(db4,Berkeley DB4) + +diff --git a/ext/dba/dba.c b/ext/dba/dba.c +index c7bea22..0aca1a5 100644 +--- a/ext/dba/dba.c ++++ b/ext/dba/dba.c +@@ -51,6 +51,10 @@ + #include "php_tcadb.h" + #include "php_lmdb.h" + ++#ifdef DB4_INCLUDE_FILE ++#include DB4_INCLUDE_FILE ++#endif ++ + /* {{{ arginfo */ + ZEND_BEGIN_ARG_INFO_EX(arginfo_dba_popen, 0, 0, 2) + ZEND_ARG_INFO(0, path) +@@ -556,6 +560,10 @@ + + php_info_print_table_start(); + php_info_print_table_row(2, "DBA support", "enabled"); ++#ifdef DB_VERSION_STRING ++ php_info_print_table_row(2, "libdb header version", DB_VERSION_STRING); ++ php_info_print_table_row(2, "libdb library version", db_version(NULL, NULL, NULL)); ++#endif + if (handlers.s) { + smart_str_0(&handlers); + php_info_print_table_row(2, "Supported handlers", ZSTR_VAL(handlers.s)); +--- /dev/null ++++ b/tests/func/null-new_val.phpt +@@ -0,0 +1,10 @@ ++--TEST-- ++ini_restore strcmp NULL new_val ++--FILE-- ++<?php ++ ++ini_set('error_log','ini_set_works'); ++ini_restore('error_log'); ++ ++?> ++--EXPECT-- +diff --git a/build/build.mk b/build/build.mk +index 1ce958f..b8c7492 100644 +--- a/build/build.mk ++++ b/build/build.mk +@@ -63,6 +63,5 @@ + @if (test ! -f '.git/info/exclude' || grep -s "git-ls-files" .git/info/exclude); then \ + (echo "Rebuild .git/info/exclude" && echo '*.o' > .git/info/exclude && git svn propget svn:ignore | grep -v config.nice >> .git/info/exclude); \ + fi; \ +- git clean -X -f -d; + + .PHONY: $(ALWAYS) snapshot +diff --git a/ext/dba/config.m4 b/ext/dba/config.m4 +index ef13306..84ab6a9 100644 +--- a/ext/dba/config.m4 ++++ b/ext/dba/config.m4 +@@ -114,6 +114,10 @@ + THIS_PREFIX=$i + THIS_INCLUDE=$i/include/depot.h + break ++ elif test -f "$i/include/qdbm/depot.h"; then ++ THIS_PREFIX=$i ++ THIS_INCLUDE=$i/include/qdbm/depot.h ++ break + fi + done + +diff --git a/sapi/fpm/php-fpm.8.in b/sapi/fpm/php-fpm.8.in +index 86edaa8..19e66a0 100644 +--- a/sapi/fpm/php-fpm.8.in ++++ b/sapi/fpm/php-fpm.8.in +@@ -139,22 +139,8 @@ + .TP + .B php.ini + The standard php configuration file. +-.SH EXAMPLES +-For any unix systems which use init.d for their main process manager, you should use the init script provided to start and stop the php-fpm daemon. +-.P +-.PD 1 +-.RS +-sudo /etc/init.d/php-fpm start +-.RE +-.TP +-For any unix systems which use systemd for their main process manager, you should use the unit file provided to start and stop the php-fpm daemon. +-.P +-.PD 1 +-.RS +-sudo systemctl start php-fpm.service +-.RE +-.TP +-If your installation has no appropriate init script, launch php-fpm with no arguments. It will launch as a daemon (background process) by default. The file @php_fpm_localstatedir@/run/php-fpm.pid determines whether php-fpm is already up and running. Once started, php-fpm then responds to several POSIX signals: ++.SH SIGNAL ++Once started, php-fpm then responds to several POSIX signals: + .P + .PD 0 + .RS +@@ -168,10 +154,6 @@ + .RE + .PD 1 + .P +-.SH TIPS +-The PHP-FPM CGI daemon will work well with most popular webservers, including Apache2, lighttpd and nginx. +-.PD 1 +-.P + .SH SEE ALSO + The PHP-FPM website: + .PD 0 +diff --git a/main/streams/plain_wrapper.c b/main/streams/plain_wrapper.c +index 131f77c..018ff2f 100644 +--- a/main/streams/plain_wrapper.c ++++ b/main/streams/plain_wrapper.c +@@ -691,7 +691,13 @@ + + switch (value) { + case PHP_STREAM_MMAP_SUPPORTED: +- return fd == -1 ? PHP_STREAM_OPTION_RETURN_ERR : PHP_STREAM_OPTION_RETURN_OK; ++ if (fd == -1) ++ return PHP_STREAM_OPTION_RETURN_ERR; ++ /* Don't mmap large files */ ++ do_fstat(data, 1); ++ if (data->sb.st_size > 4 * 1024 * 1024) ++ return PHP_STREAM_OPTION_RETURN_ERR; ++ return PHP_STREAM_OPTION_RETURN_OK; + + case PHP_STREAM_MMAP_MAP_RANGE: + if (do_fstat(data, 1) != 0) { +diff --git a/ext/dba/dba.c b/ext/dba/dba.c +index 0aca1a5..715f57c 100644 +--- a/ext/dba/dba.c ++++ b/ext/dba/dba.c +@@ -991,7 +991,7 @@ + } + } + +- if (error || hptr->open(info, &error) != SUCCESS) { ++ if (error || (hptr->open)(info, &error) != SUCCESS) { + dba_close(info); + php_error_docref2(NULL, Z_STRVAL(args[0]), Z_STRVAL(args[1]), E_WARNING, "Driver initialization failed for handler: %s%s%s", hptr->name, error?": ":"", error?error:""); + FREENOW; +diff --git a/ext/dba/dba_db3.c b/ext/dba/dba_db3.c +index e59ecc2..1eda914 100644 +--- a/ext/dba/dba_db3.c ++++ b/ext/dba/dba_db3.c +@@ -93,9 +93,9 @@ + dbp->set_errcall(dbp, php_dba_db3_errcall_fcn); + if( + #if (DB_VERSION_MAJOR > 4 || (DB_VERSION_MAJOR == 4 && DB_VERSION_MINOR >= 1)) +- (err=dbp->open(dbp, 0, info->path, NULL, type, gmode, filemode)) == 0) { ++ (err=(dbp->open)(dbp, 0, info->path, NULL, type, gmode, filemode)) == 0) { + #else +- (err=dbp->open(dbp, info->path, NULL, type, gmode, filemode)) == 0) { ++ (err=(dbp->open)(dbp, info->path, NULL, type, gmode, filemode)) == 0) { + #endif + dba_db3_data *data; + +diff --git a/ext/dba/dba_db4.c b/ext/dba/dba_db4.c +index b793020..96f6a67 100644 +--- a/ext/dba/dba_db4.c ++++ b/ext/dba/dba_db4.c +@@ -122,9 +122,9 @@ + dbp->set_errcall(dbp, php_dba_db4_errcall_fcn); + if ( + #if (DB_VERSION_MAJOR > 4 || (DB_VERSION_MAJOR == 4 && DB_VERSION_MINOR >= 1)) +- (err=dbp->open(dbp, 0, info->path, NULL, type, gmode, filemode)) == 0) { ++ (err=(dbp->open)(dbp, 0, info->path, NULL, type, gmode, filemode)) == 0) { + #else +- (err=dbp->open(dbp, info->path, NULL, type, gmode, filemode)) == 0) { ++ (err=(dbp->open)(dbp, info->path, NULL, type, gmode, filemode)) == 0) { + #endif + dba_db4_data *data; + +diff --git a/ext/zlib/zlib.c b/ext/zlib/zlib.c +index f4283c8..f8a73b8 100644 +--- a/ext/zlib/zlib.c ++++ b/ext/zlib/zlib.c +@@ -47,6 +47,18 @@ + int le_deflate; + int le_inflate; + ++/* ++ * zlib include files can define the following preprocessor defines which rename ++ * the corresponding PHP functions to gzopen64, gzseek64 and gztell64 and thereby ++ * breaking some software, most notably PEAR's Archive_Tar, which halts execution ++ * without error message on gzip compressed archivesa. ++ * ++ * This only seems to happen on 32bit systems with large file support. ++ */ ++#undef gzopen ++#undef gzseek ++#undef gztell ++ + ZEND_DECLARE_MODULE_GLOBALS(zlib); + + /* {{{ Memory management wrappers */ +diff --git a/ext/standard/tests/strings/setlocale_variation2.phpt b/ext/standard/tests/strings/setlocale_variation2.phpt +index fad3298..3449b28 100644 +--- a/ext/standard/tests/strings/setlocale_variation2.phpt ++++ b/ext/standard/tests/strings/setlocale_variation2.phpt +@@ -55,6 +55,7 @@ + //try different locale names + $failure_locale = array(); + $success_count = 0; ++$expected = 0; + + echo "-- Test setlocale() with all available locale in the system --\n"; + // gather all locales installed in the system(stored $all_system_locales), +@@ -64,6 +65,10 @@ + if(setlocale(LC_ALL,$value )){ + $success_count++; + } ++ else if ($value == 'no_NO.ISO-8859-1') { ++ // ignore this one, see rhbz #971416 ++ $expected++; ++ } + else{ + //failure values are put in to an array $failure_locale + $failure_locale[] = $value; +@@ -72,11 +77,11 @@ + + echo "No of locales found on the machine = ".count($all_system_locales)."\n"; + echo "No of setlocale() success = ".$success_count."\n"; +-echo "Expected no of failures = 0\n"; ++echo "Expected no of failures = $expected\n"; + echo "Test "; + // check if there were any failure of setlocale() function earlier, if any + // failure then dump the list of failing locales +-if($success_count != count($all_system_locales)){ ++if(($success_count + $expected) != count($all_system_locales)){ + echo "FAILED\n"; + echo "Names of locale() for which setlocale() failed ...\n"; + var_dump($failure_locale); +@@ -92,6 +97,6 @@ + -- Test setlocale() with all available locale in the system -- + No of locales found on the machine = %d + No of setlocale() success = %d +-Expected no of failures = 0 ++Expected no of failures = %d + Test PASSED + Done +diff --git a/ext/pcre/tests/grep2.phpt b/ext/pcre/tests/grep2.phpt +index 4c6f9b1..a6247cc 100644 +--- a/ext/pcre/tests/grep2.phpt ++++ b/ext/pcre/tests/grep2.phpt +@@ -44,12 +44,6 @@ + string(1) "1" + } + bool(true) +-array(3) { +- [5]=> +- string(1) "a" +- ["xyz"]=> +- string(2) "q6" +- [6]=> +- string(3) "h20" ++array(0) { + } +-bool(false) ++bool(true) +diff --git a/ext/pcre/tests/match_flags3.phpt b/ext/pcre/tests/match_flags3.phpt +index 6511c71..05c62a0 100644 +--- a/ext/pcre/tests/match_flags3.phpt ++++ b/ext/pcre/tests/match_flags3.phpt +@@ -41,5 +41,5 @@ + } + } + +-Warning: preg_match(): Compilation failed: %s name must start with a non-digit at offset %d in %smatch_flags3.php on line %d ++Warning: preg_match(): Numeric named subpatterns are not allowed in %smatch_flags3.php on line %d + bool(false) +diff --git a/sapi/fpm/tests/tester.inc b/sapi/fpm/tests/tester.inc +index c07fabe..48cfdcc 100644 +--- a/sapi/fpm/tests/tester.inc ++++ b/sapi/fpm/tests/tester.inc +@@ -860,7 +860,17 @@ + { + $port = $this->getPort($type, $pool, true); + if ($type === 'uds') { +- return $this->getFile($port . '.sock'); ++ $address = $this->getFile($port . '.sock'); ++ ++ // Socket max path length is 108 on Linux and 104 on BSD, ++ // so we use the latter ++ if (strlen($address) <= 104) { ++ return $address; ++ } ++ ++ return sys_get_temp_dir().'/'. ++ hash('crc32', dirname($address)).'-'. ++ basename($address); + } + + return $this->getHost($type) . ':' . $port; diff --git a/debian-php-7.4.26.patch b/debian-php-7.4.26.patch new file mode 100644 index 000000000000..8e4252b8a74a --- /dev/null +++ b/debian-php-7.4.26.patch @@ -0,0 +1,355 @@ + +diff --git a/ext/standard/proc_open.c b/ext/standard/proc_open.c +index 25a5f7f..93c47af 100644 +--- a/ext/standard/proc_open.c ++++ b/ext/standard/proc_open.c +@@ -55,7 +55,7 @@ + * */ + #ifdef PHP_CAN_SUPPORT_PROC_OPEN + +-#if 0 && HAVE_PTSNAME && HAVE_GRANTPT && HAVE_UNLOCKPT && HAVE_SYS_IOCTL_H && HAVE_TERMIOS_H ++#if HAVE_PTSNAME && HAVE_GRANTPT && HAVE_UNLOCKPT && HAVE_SYS_IOCTL_H && HAVE_TERMIOS_H + # include <sys/ioctl.h> + # include <termios.h> + # define PHP_CAN_DO_PTS 1 +diff --git a/php.ini-development b/php.ini-development +index 23a35a2..0292501 100644 +--- a/php.ini-development ++++ b/php.ini-development +@@ -304,6 +304,12 @@ + ; or per-virtualhost web server configuration file. + ; Note: disables the realpath cache + ; http://php.net/open-basedir ++ ++; NOTE: this is considered a "broken" security measure. ++; Applications relying on this feature will not receive full ++; support by the security team. For more information please ++; see /usr/share/doc/php-common/README.Debian.security ++; + ;open_basedir = + + ; This directive allows you to disable certain functions. +diff --git a/ext/dba/config.m4 b/ext/dba/config.m4 +index 1e80319..51bdd84 100644 +--- a/ext/dba/config.m4 ++++ b/ext/dba/config.m4 +@@ -375,61 +375,13 @@ + dbdp4="/usr/local/BerkeleyDB.4." + dbdp5="/usr/local/BerkeleyDB.5." + for i in $PHP_DB4 ${dbdp5}1 ${dbdp5}0 ${dbdp4}8 ${dbdp4}7 ${dbdp4}6 ${dbdp4}5 ${dbdp4}4 ${dbdp4}3 ${dbdp4}2 ${dbdp4}1 ${dbdp}0 /usr/local /usr; do +- if test -f "$i/db5/db.h"; then +- THIS_PREFIX=$i +- THIS_INCLUDE=$i/db5/db.h +- break +- elif test -f "$i/db4/db.h"; then +- THIS_PREFIX=$i +- THIS_INCLUDE=$i/db4/db.h +- break +- elif test -f "$i/include/db5.3/db.h"; then +- THIS_PREFIX=$i +- THIS_INCLUDE=$i/include/db5.3/db.h +- break +- elif test -f "$i/include/db5.1/db.h"; then +- THIS_PREFIX=$i +- THIS_INCLUDE=$i/include/db5.1/db.h +- break +- elif test -f "$i/include/db5.0/db.h"; then +- THIS_PREFIX=$i +- THIS_INCLUDE=$i/include/db5.0/db.h +- break +- elif test -f "$i/include/db4.8/db.h"; then +- THIS_PREFIX=$i +- THIS_INCLUDE=$i/include/db4.8/db.h +- break +- elif test -f "$i/include/db4.7/db.h"; then +- THIS_PREFIX=$i +- THIS_INCLUDE=$i/include/db4.7/db.h +- break +- elif test -f "$i/include/db4.6/db.h"; then +- THIS_PREFIX=$i +- THIS_INCLUDE=$i/include/db4.6/db.h +- break +- elif test -f "$i/include/db4.5/db.h"; then +- THIS_PREFIX=$i +- THIS_INCLUDE=$i/include/db4.5/db.h +- break +- elif test -f "$i/include/db4/db.h"; then +- THIS_PREFIX=$i +- THIS_INCLUDE=$i/include/db4/db.h +- break +- elif test -f "$i/include/db/db4.h"; then +- THIS_PREFIX=$i +- THIS_INCLUDE=$i/include/db/db4.h +- break +- elif test -f "$i/include/db4.h"; then +- THIS_PREFIX=$i +- THIS_INCLUDE=$i/include/db4.h +- break +- elif test -f "$i/include/db.h"; then ++ if test -f "$i/include/db.h"; then + THIS_PREFIX=$i + THIS_INCLUDE=$i/include/db.h + break + fi + done +- PHP_DBA_DB_CHECK(4, db-5.3 db-5.1 db-5.0 db-4.8 db-4.7 db-4.6 db-4.5 db-4.4 db-4.3 db-4.2 db-4.1 db-4.0 db-4 db4 db, [(void)db_create((DB**)0, (DB_ENV*)0, 0)]) ++ PHP_DBA_DB_CHECK(4, db, [(void)db_create((DB**)0, (DB_ENV*)0, 0)]) + fi + PHP_DBA_STD_RESULT(db4,Berkeley DB4) + +diff --git a/ext/dba/dba.c b/ext/dba/dba.c +index 9581a57..21d3f11 100644 +--- a/ext/dba/dba.c ++++ b/ext/dba/dba.c +@@ -51,6 +51,10 @@ + #include "php_tcadb.h" + #include "php_lmdb.h" + ++#ifdef DB4_INCLUDE_FILE ++#include DB4_INCLUDE_FILE ++#endif ++ + /* {{{ arginfo */ + ZEND_BEGIN_ARG_INFO_EX(arginfo_dba_popen, 0, 0, 2) + ZEND_ARG_INFO(0, path) +@@ -558,6 +562,10 @@ + + php_info_print_table_start(); + php_info_print_table_row(2, "DBA support", "enabled"); ++#ifdef DB_VERSION_STRING ++ php_info_print_table_row(2, "libdb header version", DB_VERSION_STRING); ++ php_info_print_table_row(2, "libdb library version", db_version(NULL, NULL, NULL)); ++#endif + if (handlers.s) { + smart_str_0(&handlers); + php_info_print_table_row(2, "Supported handlers", ZSTR_VAL(handlers.s)); +--- /dev/null ++++ b/tests/func/null-new_val.phpt +@@ -0,0 +1,10 @@ ++--TEST-- ++ini_restore strcmp NULL new_val ++--FILE-- ++<?php ++ ++ini_set('error_log','ini_set_works'); ++ini_restore('error_log'); ++ ++?> ++--EXPECT-- +diff --git a/ext/dba/config.m4 b/ext/dba/config.m4 +index 51bdd84..79136d5 100644 +--- a/ext/dba/config.m4 ++++ b/ext/dba/config.m4 +@@ -145,6 +145,10 @@ + THIS_PREFIX=$i + THIS_INCLUDE=$i/include/qdbm/depot.h + break ++ elif test -f "$i/include/qdbm/depot.h"; then ++ THIS_PREFIX=$i ++ THIS_INCLUDE=$i/include/qdbm/depot.h ++ break + fi + done + +diff --git a/sapi/fpm/php-fpm.8.in b/sapi/fpm/php-fpm.8.in +index 972c242..002c44b 100644 +--- a/sapi/fpm/php-fpm.8.in ++++ b/sapi/fpm/php-fpm.8.in +@@ -139,22 +139,8 @@ + .TP + .B php.ini + The standard php configuration file. +-.SH EXAMPLES +-For any unix systems which use init.d for their main process manager, you should use the init script provided to start and stop the php-fpm daemon. +-.P +-.PD 1 +-.RS +-sudo /etc/init.d/php-fpm start +-.RE +-.TP +-For any unix systems which use systemd for their main process manager, you should use the unit file provided to start and stop the php-fpm daemon. +-.P +-.PD 1 +-.RS +-sudo systemctl start php-fpm.service +-.RE +-.TP +-If your installation has no appropriate init script, launch php-fpm with no arguments. It will launch as a daemon (background process) by default. The file @php_fpm_localstatedir@/run/php-fpm.pid determines whether php-fpm is already up and running. Once started, php-fpm then responds to several POSIX signals: ++.SH SIGNAL ++Once started, php-fpm then responds to several POSIX signals: + .P + .PD 0 + .RS +@@ -168,10 +154,6 @@ + .RE + .PD 1 + .P +-.SH TIPS +-The PHP-FPM CGI daemon will work well with most popular webservers, including Apache2, lighttpd and nginx. +-.PD 1 +-.P + .SH SEE ALSO + The PHP-FPM website: + .PD 0 +diff --git a/main/streams/plain_wrapper.c b/main/streams/plain_wrapper.c +index 4d10e68..f74a936 100644 +--- a/main/streams/plain_wrapper.c ++++ b/main/streams/plain_wrapper.c +@@ -713,7 +713,13 @@ + + switch (value) { + case PHP_STREAM_MMAP_SUPPORTED: +- return fd == -1 ? PHP_STREAM_OPTION_RETURN_ERR : PHP_STREAM_OPTION_RETURN_OK; ++ if (fd == -1) ++ return PHP_STREAM_OPTION_RETURN_ERR; ++ /* Don't mmap large files */ ++ do_fstat(data, 1); ++ if (data->sb.st_size > 4 * 1024 * 1024) ++ return PHP_STREAM_OPTION_RETURN_ERR; ++ return PHP_STREAM_OPTION_RETURN_OK; + + case PHP_STREAM_MMAP_MAP_RANGE: + if (do_fstat(data, 1) != 0) { +diff --git a/ext/dba/dba.c b/ext/dba/dba.c +index 21d3f11..ac2d212 100644 +--- a/ext/dba/dba.c ++++ b/ext/dba/dba.c +@@ -999,7 +999,7 @@ + } + } + +- if (error || hptr->open(info, &error) != SUCCESS) { ++ if (error || (hptr->open)(info, &error) != SUCCESS) { + dba_close(info); + php_error_docref2(NULL, Z_STRVAL(args[0]), Z_STRVAL(args[1]), E_WARNING, "Driver initialization failed for handler: %s%s%s", hptr->name, error?": ":"", error?error:""); + FREENOW; +diff --git a/ext/dba/dba_db3.c b/ext/dba/dba_db3.c +index bc0fdac..1b1b5c9 100644 +--- a/ext/dba/dba_db3.c ++++ b/ext/dba/dba_db3.c +@@ -93,9 +93,9 @@ + dbp->set_errcall(dbp, php_dba_db3_errcall_fcn); + if( + #if (DB_VERSION_MAJOR > 4 || (DB_VERSION_MAJOR == 4 && DB_VERSION_MINOR >= 1)) +- (err=dbp->open(dbp, 0, info->path, NULL, type, gmode, filemode)) == 0) { ++ (err=(dbp->open)(dbp, 0, info->path, NULL, type, gmode, filemode)) == 0) { + #else +- (err=dbp->open(dbp, info->path, NULL, type, gmode, filemode)) == 0) { ++ (err=(dbp->open)(dbp, info->path, NULL, type, gmode, filemode)) == 0) { + #endif + dba_db3_data *data; + +diff --git a/ext/dba/dba_db4.c b/ext/dba/dba_db4.c +index ee296b9..22ca32d 100644 +--- a/ext/dba/dba_db4.c ++++ b/ext/dba/dba_db4.c +@@ -122,9 +122,9 @@ + dbp->set_errcall(dbp, php_dba_db4_errcall_fcn); + if ( + #if (DB_VERSION_MAJOR > 4 || (DB_VERSION_MAJOR == 4 && DB_VERSION_MINOR >= 1)) +- (err=dbp->open(dbp, 0, info->path, NULL, type, gmode, filemode)) == 0) { ++ (err=(dbp->open)(dbp, 0, info->path, NULL, type, gmode, filemode)) == 0) { + #else +- (err=dbp->open(dbp, info->path, NULL, type, gmode, filemode)) == 0) { ++ (err=(dbp->open)(dbp, info->path, NULL, type, gmode, filemode)) == 0) { + #endif + dba_db4_data *data; + +diff --git a/ext/zlib/zlib.c b/ext/zlib/zlib.c +index 9060dcb..2678751 100644 +--- a/ext/zlib/zlib.c ++++ b/ext/zlib/zlib.c +@@ -47,6 +47,18 @@ + int le_deflate; + int le_inflate; + ++/* ++ * zlib include files can define the following preprocessor defines which rename ++ * the corresponding PHP functions to gzopen64, gzseek64 and gztell64 and thereby ++ * breaking some software, most notably PEAR's Archive_Tar, which halts execution ++ * without error message on gzip compressed archivesa. ++ * ++ * This only seems to happen on 32bit systems with large file support. ++ */ ++#undef gzopen ++#undef gzseek ++#undef gztell ++ + ZEND_DECLARE_MODULE_GLOBALS(zlib); + + /* {{{ Memory management wrappers */ +diff --git a/ext/standard/tests/strings/setlocale_variation2.phpt b/ext/standard/tests/strings/setlocale_variation2.phpt +index 6fd6f4d..9be9dc6 100644 +--- a/ext/standard/tests/strings/setlocale_variation2.phpt ++++ b/ext/standard/tests/strings/setlocale_variation2.phpt +@@ -59,6 +59,7 @@ + //try different locale names + $failure_locale = array(); + $success_count = 0; ++$expected = 0; + + echo "-- Test setlocale() with all available locale in the system --\n"; + // gather all locales installed in the system(stored $all_system_locales), +@@ -68,6 +69,10 @@ + if(setlocale(LC_ALL,$value )){ + $success_count++; + } ++ else if ($value == 'no_NO.ISO-8859-1') { ++ // ignore this one, see rhbz #971416 ++ $expected++; ++ } + else{ + //failure values are put in to an array $failure_locale + $failure_locale[] = $value; +@@ -76,11 +81,11 @@ + + echo "No of locales found on the machine = ".count($all_system_locales)."\n"; + echo "No of setlocale() success = ".$success_count."\n"; +-echo "Expected no of failures = 0\n"; ++echo "Expected no of failures = $expected\n"; + echo "Test "; + // check if there were any failure of setlocale() function earlier, if any + // failure then dump the list of failing locales +-if($success_count != count($all_system_locales)){ ++if(($success_count + $expected) != count($all_system_locales)){ + echo "FAILED\n"; + echo "Names of locale() for which setlocale() failed ...\n"; + var_dump($failure_locale); +@@ -96,6 +101,6 @@ + -- Test setlocale() with all available locale in the system -- + No of locales found on the machine = %d + No of setlocale() success = %d +-Expected no of failures = 0 ++Expected no of failures = %d + Test PASSED + Done +diff --git a/ext/pcre/tests/grep2.phpt b/ext/pcre/tests/grep2.phpt +index 4c6f9b1..a6247cc 100644 +--- a/ext/pcre/tests/grep2.phpt ++++ b/ext/pcre/tests/grep2.phpt +@@ -44,12 +44,6 @@ + string(1) "1" + } + bool(true) +-array(3) { +- [5]=> +- string(1) "a" +- ["xyz"]=> +- string(2) "q6" +- [6]=> +- string(3) "h20" ++array(0) { + } +-bool(false) ++bool(true) +diff --git a/ext/pcre/tests/match_flags3.phpt b/ext/pcre/tests/match_flags3.phpt +index 6511c71..05c62a0 100644 +--- a/ext/pcre/tests/match_flags3.phpt ++++ b/ext/pcre/tests/match_flags3.phpt +@@ -41,5 +41,5 @@ + } + } + +-Warning: preg_match(): Compilation failed: %s name must start with a non-digit at offset %d in %smatch_flags3.php on line %d ++Warning: preg_match(): Numeric named subpatterns are not allowed in %smatch_flags3.php on line %d + bool(false) diff --git a/enchant-php7.4.patch b/enchant-php7.4.patch new file mode 100644 index 000000000000..d3f0c74ed75b --- /dev/null +++ b/enchant-php7.4.patch @@ -0,0 +1,301 @@ +diff -ur php-7.4.26.orig/ext/enchant/config.m4 php-7.4.26/ext/enchant/config.m4 +--- php-7.4.26.orig/ext/enchant/config.m4 2021-11-16 17:31:31.000000000 +0200 ++++ php-7.4.26/ext/enchant/config.m4 2021-12-14 10:38:53.318024515 +0200 +@@ -4,26 +4,38 @@ + [Include Enchant support])]) + + if test "$PHP_ENCHANT" != "no"; then +- PKG_CHECK_MODULES([ENCHANT], [enchant]) ++ PKG_CHECK_MODULES([ENCHANT2], [enchant-2], [found_enchant_2=yes], [found_enchant_2=no]) + +- PHP_EVAL_INCLINE($ENCHANT_CFLAGS) +- PHP_EVAL_LIBLINE($ENCHANT_LIBS, ENCHANT_SHARED_LIBADD) ++ if test "$found_enchant_2" = "yes"; then + +- AC_DEFINE(HAVE_ENCHANT, 1, [ ]) ++ PHP_EVAL_INCLINE($ENCHANT2_CFLAGS) ++ PHP_EVAL_LIBLINE($ENCHANT2_LIBS, ENCHANT_SHARED_LIBADD) ++ ++ AC_DEFINE(HAVE_ENCHANT_GET_VERSION, 1, [ enchant_get_version since 1.6.0 ]) + +- PHP_CHECK_LIBRARY(enchant, enchant_get_version, +- [ +- AC_DEFINE(HAVE_ENCHANT_GET_VERSION, 1, [ ]) +- ], [ ], [ +- $ENCHANT_LIBS +- ]) +- +- PHP_CHECK_LIBRARY(enchant, enchant_broker_set_param, +- [ +- AC_DEFINE(HAVE_ENCHANT_BROKER_SET_PARAM, 1, [ ]) +- ], [ ], [ +- $ENCHANT_LIBS +- ]) ++ else ++ AC_MSG_WARN([libenchant-2 not found trying with old libenchant]) ++ PKG_CHECK_MODULES([ENCHANT], [enchant >= 1.4.2]) ++ ++ PHP_EVAL_INCLINE($ENCHANT_CFLAGS) ++ PHP_EVAL_LIBLINE($ENCHANT_LIBS, ENCHANT_SHARED_LIBADD) ++ ++ PHP_CHECK_LIBRARY(enchant, enchant_get_version, ++ [ ++ AC_DEFINE(HAVE_ENCHANT_GET_VERSION, 1, [ enchant_get_version since 1.6.0 ]) ++ ], [ ], [ ++ $ENCHANT_LIBS ++ ]) ++ ++ PHP_CHECK_LIBRARY(enchant, enchant_broker_set_param, ++ [ ++ AC_DEFINE(HAVE_ENCHANT_BROKER_SET_PARAM, 1, [ enchant_broker_set_param since 1.5.0 and removed in 2.x ]) ++ ], [ ], [ ++ $ENCHANT_LIBS ++ ]) ++ fi ++ ++ AC_DEFINE(HAVE_ENCHANT, 1, [ ]) + + PHP_NEW_EXTENSION(enchant, enchant.c, $ext_shared) + PHP_SUBST(ENCHANT_SHARED_LIBADD) +diff -ur php-7.4.26.orig/ext/enchant/enchant.c php-7.4.26/ext/enchant/enchant.c +--- php-7.4.26.orig/ext/enchant/enchant.c 2021-11-16 17:31:31.000000000 +0200 ++++ php-7.4.26/ext/enchant/enchant.c 2021-12-14 10:38:53.318024515 +0200 +@@ -135,9 +135,10 @@ + PHP_FE(enchant_broker_describe, arginfo_enchant_broker_free) + PHP_FE(enchant_dict_check, arginfo_enchant_dict_check) + PHP_FE(enchant_dict_suggest, arginfo_enchant_dict_check) +- PHP_FE(enchant_dict_add_to_personal, arginfo_enchant_dict_check) ++ PHP_FE(enchant_dict_add, arginfo_enchant_dict_check) ++ PHP_FALIAS(enchant_dict_add_to_personal, enchant_dict_add, arginfo_enchant_dict_check) + PHP_FE(enchant_dict_add_to_session, arginfo_enchant_dict_check) +- PHP_FE(enchant_dict_is_in_session, arginfo_enchant_dict_check) ++ PHP_FE(enchant_dict_is_added, arginfo_enchant_dict_check) + PHP_FE(enchant_dict_store_replacement, arginfo_enchant_dict_store_replacement) + PHP_FE(enchant_dict_get_error, arginfo_enchant_broker_free_dict) + PHP_FE(enchant_dict_describe, arginfo_enchant_broker_free_dict) +@@ -285,6 +286,9 @@ + le_enchant_dict = zend_register_list_destructors_ex(php_enchant_dict_free, NULL, "enchant_dict", module_number); + REGISTER_LONG_CONSTANT("ENCHANT_MYSPELL", PHP_ENCHANT_MYSPELL, CONST_CS | CONST_PERSISTENT); + REGISTER_LONG_CONSTANT("ENCHANT_ISPELL", PHP_ENCHANT_ISPELL, CONST_CS | CONST_PERSISTENT); ++#ifdef HAVE_ENCHANT_GET_VERSION ++ REGISTER_STRING_CONSTANT("LIBENCHANT_VERSION", enchant_get_version(), CONST_CS | CONST_PERSISTENT); ++#endif + return SUCCESS; + } + /* }}} */ +@@ -392,7 +396,7 @@ + { + zval *broker; + enchant_broker *pbroker; +- char *msg; ++ const char *msg; + + if (zend_parse_parameters(ZEND_NUM_ARGS(), "r", &broker) == FAILURE) { + RETURN_FALSE; +@@ -738,7 +742,7 @@ + for (i = 0; i < n_sugg; i++) { + add_next_index_string(sugg, suggs[i]); + } +- enchant_dict_free_suggestions(pdict->pdict, suggs); ++ enchant_dict_free_string_list(pdict->pdict, suggs); + } + + +@@ -793,14 +797,14 @@ + add_next_index_string(return_value, suggs[i]); + } + +- enchant_dict_free_suggestions(pdict->pdict, suggs); ++ enchant_dict_free_string_list(pdict->pdict, suggs); + } + } + /* }}} */ + +-/* {{{ proto void enchant_dict_add_to_personal(resource dict, string word) ++/* {{{ proto void enchant_dict_add(resource dict, string word) + add 'word' to personal word list */ +-PHP_FUNCTION(enchant_dict_add_to_personal) ++PHP_FUNCTION(enchant_dict_add) + { + zval *dict; + char *word; +@@ -813,7 +817,7 @@ + + PHP_ENCHANT_GET_DICT; + +- enchant_dict_add_to_personal(pdict->pdict, word, wordlen); ++ enchant_dict_add(pdict->pdict, word, wordlen); + } + /* }}} */ + +@@ -836,9 +840,9 @@ + } + /* }}} */ + +-/* {{{ proto bool enchant_dict_is_in_session(resource dict, string word) ++/* {{{ proto bool enchant_dict_is_added(resource dict, string word) + whether or not 'word' exists in this spelling-session */ +-PHP_FUNCTION(enchant_dict_is_in_session) ++PHP_FUNCTION(enchant_dict_is_added) + { + zval *dict; + char *word; +@@ -851,7 +855,7 @@ + + PHP_ENCHANT_GET_DICT; + +- RETURN_BOOL(enchant_dict_is_in_session(pdict->pdict, word, wordlen)); ++ RETURN_BOOL(enchant_dict_is_added(pdict->pdict, word, wordlen)); + } + /* }}} */ + +@@ -884,7 +888,7 @@ + { + zval *dict; + enchant_dict *pdict; +- char *msg; ++ const char *msg; + + if (zend_parse_parameters(ZEND_NUM_ARGS(), "r", &dict) == FAILURE) { + RETURN_FALSE; +diff -ur php-7.4.26.orig/ext/enchant/php_enchant.h php-7.4.26/ext/enchant/php_enchant.h +--- php-7.4.26.orig/ext/enchant/php_enchant.h 2021-11-16 17:31:31.000000000 +0200 ++++ php-7.4.26/ext/enchant/php_enchant.h 2021-12-14 10:38:53.318024515 +0200 +@@ -53,9 +53,9 @@ + + PHP_FUNCTION(enchant_dict_check); + PHP_FUNCTION(enchant_dict_suggest); +-PHP_FUNCTION(enchant_dict_add_to_personal); ++PHP_FUNCTION(enchant_dict_add); + PHP_FUNCTION(enchant_dict_add_to_session); +-PHP_FUNCTION(enchant_dict_is_in_session); ++PHP_FUNCTION(enchant_dict_is_added); + PHP_FUNCTION(enchant_dict_store_replacement); + PHP_FUNCTION(enchant_dict_get_error); + PHP_FUNCTION(enchant_dict_describe); +diff -ur php-7.4.26.orig/ext/enchant/tests/broker_free_02.phpt php-7.4.26/ext/enchant/tests/broker_free_02.phpt +--- php-7.4.26.orig/ext/enchant/tests/broker_free_02.phpt 2021-11-16 17:31:31.000000000 +0200 ++++ php-7.4.26/ext/enchant/tests/broker_free_02.phpt 2021-12-14 10:38:53.318024515 +0200 +@@ -21,7 +21,7 @@ + if ($requestDict) { + echo("OK\n"); + for($x=0;$x<count($newWord);$x++) { +- $AddtoPersonalDict = enchant_dict_add_to_personal($requestDict,$newWord[$x]); ++ $AddtoPersonalDict = enchant_dict_add($requestDict,$newWord[$x]); + } + + if (NULL === $AddtoPersonalDict) { +diff -ur php-7.4.26.orig/ext/enchant/tests/broker_free_dict.phpt php-7.4.26/ext/enchant/tests/broker_free_dict.phpt +--- php-7.4.26.orig/ext/enchant/tests/broker_free_dict.phpt 2021-11-16 17:31:31.000000000 +0200 ++++ php-7.4.26/ext/enchant/tests/broker_free_dict.phpt 2021-12-14 10:38:53.318024515 +0200 +@@ -19,7 +19,7 @@ + + if ($requestDict) { + echo("OK\n"); +- $AddtoPersonalDict = enchant_dict_add_to_personal($requestDict, $newWord); ++ $AddtoPersonalDict = enchant_dict_add($requestDict, $newWord); + + if (NULL === $AddtoPersonalDict) { + var_dump($AddtoPersonalDict); +diff -ur php-7.4.26.orig/ext/enchant/tests/bug53070.phpt php-7.4.26/ext/enchant/tests/bug53070.phpt +--- php-7.4.26.orig/ext/enchant/tests/bug53070.phpt 2021-11-16 17:31:31.000000000 +0200 ++++ php-7.4.26/ext/enchant/tests/bug53070.phpt 2021-12-14 10:38:53.318024515 +0200 +@@ -4,6 +4,7 @@ + <?php + if(!extension_loaded('enchant')) die('skip, enchant not loader'); + if (!is_resource(enchant_broker_init())) {die("skip, resource dont load\n");} ++if (defined("LIBENCHANT_VERSION") && version_compare(LIBENCHANT_VERSION, "2", ">")) die('skip libenchant v1 only'); + ?> + --FILE-- + <?php +@@ -12,8 +13,12 @@ + var_dump(enchant_broker_get_dict_path($broker, ENCHANT_ISPELL)); + ?> + --EXPECTF-- ++Deprecated: Function enchant_broker_get_dict_path() is deprecated in %s ++ + Warning: enchant_broker_get_dict_path(): dict_path not set in %s on line %d + bool(false) + ++Deprecated: Function enchant_broker_get_dict_path() is deprecated in %s ++ + Warning: enchant_broker_get_dict_path(): dict_path not set in %s on line %d + bool(false) +diff -ur php-7.4.26.orig/ext/enchant/tests/dict_add_to_personal.phpt php-7.4.26/ext/enchant/tests/dict_add_to_personal.phpt +--- php-7.4.26.orig/ext/enchant/tests/dict_add_to_personal.phpt 2021-11-16 17:31:31.000000000 +0200 ++++ php-7.4.26/ext/enchant/tests/dict_add_to_personal.phpt 2021-12-14 10:38:53.318024515 +0200 +@@ -1,5 +1,5 @@ + --TEST-- +-enchant_dict_add_to_personal() function ++enchant_dict_add() function + --CREDITS-- + marcosptf - <marcosptf@yahoo.com.br> + --SKIPIF-- +@@ -20,7 +20,7 @@ + + if ($requestDict) { + echo("OK\n"); +- $AddtoPersonalDict = enchant_dict_add_to_personal($requestDict,$newWord); ++ $AddtoPersonalDict = enchant_dict_add($requestDict,$newWord); + + if (NULL === $AddtoPersonalDict) { + var_dump($AddtoPersonalDict); +diff -ur php-7.4.26.orig/ext/enchant/tests/dict_check.phpt php-7.4.26/ext/enchant/tests/dict_check.phpt +--- php-7.4.26.orig/ext/enchant/tests/dict_check.phpt 2021-11-16 17:31:31.000000000 +0200 ++++ php-7.4.26/ext/enchant/tests/dict_check.phpt 2021-12-14 10:38:53.318024515 +0200 +@@ -20,7 +20,7 @@ + + if ($requestDict) { + echo("OK\n"); +- enchant_dict_add_to_personal($requestDict, $newWord); ++ enchant_dict_add($requestDict, $newWord); + + if (enchant_dict_check($requestDict, $newWord)) { + echo("OK\n"); +diff -ur php-7.4.26.orig/ext/enchant/tests/dict_is_in_session.phpt php-7.4.26/ext/enchant/tests/dict_is_in_session.phpt +--- php-7.4.26.orig/ext/enchant/tests/dict_is_in_session.phpt 2021-11-16 17:31:31.000000000 +0200 ++++ php-7.4.26/ext/enchant/tests/dict_is_in_session.phpt 2021-12-14 10:38:53.318024515 +0200 +@@ -20,10 +20,10 @@ + + if ($requestDict) { + echo("OK\n"); +- $AddtoPersonalDict = enchant_dict_add_to_personal($requestDict,$newWord); ++ $AddtoPersonalDict = enchant_dict_add($requestDict,$newWord); + + if (NULL === $AddtoPersonalDict) { +- var_dump(enchant_dict_is_in_session($requestDict,$newWord)); ++ var_dump(enchant_dict_is_added($requestDict,$newWord)); + } else { + echo("dict add to personal failed\n"); + } +diff -ur php-7.4.26.orig/ext/enchant/tests/enchant_broker_set_dict_path.phpt php-7.4.26/ext/enchant/tests/enchant_broker_set_dict_path.phpt +--- php-7.4.26.orig/ext/enchant/tests/enchant_broker_set_dict_path.phpt 2021-11-16 17:31:31.000000000 +0200 ++++ php-7.4.26/ext/enchant/tests/enchant_broker_set_dict_path.phpt 2021-12-14 10:38:53.318024515 +0200 +@@ -7,7 +7,8 @@ + <?php + if(!extension_loaded('enchant')) die('skip, enchant not loader'); + if (!is_resource(enchant_broker_init())) {die("skip, resource dont load\n");} +-if (!is_array(enchant_broker_list_dicts(enchant_broker_init()))) {die("skip, dont has dictionary install in this machine! \n");} ++if (!is_array(enchant_broker_list_dicts(enchant_broker_init()))) {die("skip, no dictionary installed on this machine! \n");} ++if (defined("LIBENCHANT_VERSION") && version_compare(LIBENCHANT_VERSION, "2", ">")) die('skip libenchant v1 only'); + ?> + --FILE-- + <?php +@@ -46,8 +47,16 @@ + echo("broker is not a resource; failed; \n"); + } + ?> +---EXPECT-- ++--EXPECTF-- + OK ++ ++Deprecated: Function enchant_broker_set_dict_path() is deprecated in %s + OK ++ ++Deprecated: Function enchant_broker_set_dict_path() is deprecated in %s + OK ++ ++Deprecated: Function enchant_broker_get_dict_path() is deprecated in %s ++ ++Deprecated: Function enchant_broker_get_dict_path() is deprecated in %s + OK diff --git a/fpm-numeric-uid-gid.patch b/fpm-numeric-uid-gid.patch new file mode 100644 index 000000000000..f99dbe048037 --- /dev/null +++ b/fpm-numeric-uid-gid.patch @@ -0,0 +1,52 @@ +--- a/sapi/fpm/fpm/fpm_unix.c ++++ b/sapi/fpm/fpm/fpm_unix.c +@@ -165,27 +165,35 @@ + #endif + + if (c->listen_owner && *c->listen_owner) { +- struct passwd *pwd; ++ if (strlen(c->listen_owner) == strspn(c->listen_owner, "0123456789")) { ++ wp->socket_uid = strtoul(c->listen_owner, 0, 10); ++ } else { ++ struct passwd *pwd; + +- pwd = getpwnam(c->listen_owner); +- if (!pwd) { +- zlog(ZLOG_SYSERROR, "[pool %s] cannot get uid for user '%s'", wp->config->name, c->listen_owner); +- return -1; +- } ++ pwd = getpwnam(c->listen_owner); ++ if (!pwd) { ++ zlog(ZLOG_SYSERROR, "[pool %s] cannot get uid for user '%s'", wp->config->name, c->listen_owner); ++ return -1; ++ } + +- wp->socket_uid = pwd->pw_uid; +- wp->socket_gid = pwd->pw_gid; ++ wp->socket_uid = pwd->pw_uid; ++ wp->socket_gid = pwd->pw_gid; ++ } + } + + if (c->listen_group && *c->listen_group) { +- struct group *grp; ++ if (strlen(c->listen_group) == strspn(c->listen_group, "0123456789")) { ++ wp->socket_gid = strtoul(c->listen_group, 0, 10); ++ } else { ++ struct group *grp; + +- grp = getgrnam(c->listen_group); +- if (!grp) { +- zlog(ZLOG_SYSERROR, "[pool %s] cannot get gid for group '%s'", wp->config->name, c->listen_group); +- return -1; ++ grp = getgrnam(c->listen_group); ++ if (!grp) { ++ zlog(ZLOG_SYSERROR, "[pool %s] cannot get gid for group '%s'", wp->config->name, c->listen_group); ++ return -1; ++ } ++ wp->socket_gid = grp->gr_gid; + } +- wp->socket_gid = grp->gr_gid; + } + + return 0; diff --git a/fpm-reload-sighup.patch b/fpm-reload-sighup.patch new file mode 100644 index 000000000000..09b32b73ba06 --- /dev/null +++ b/fpm-reload-sighup.patch @@ -0,0 +1,57 @@ +diff --git a/sapi/fpm/fpm/fpm_events.c b/sapi/fpm/fpm/fpm_events.c +index ce5d543..63de0a4 100644 +--- a/sapi/fpm/fpm/fpm_events.c ++++ b/sapi/fpm/fpm/fpm_events.c +@@ -113,6 +113,11 @@ + zlog(ZLOG_NOTICE, "Reloading in progress ..."); + fpm_pctl(FPM_PCTL_STATE_RELOADING, FPM_PCTL_ACTION_SET); + break; ++ case 'H' : /* SIGHUP */ ++ zlog(ZLOG_DEBUG, "received SIGHUP"); ++ zlog(ZLOG_NOTICE, "Reloading in progress ..."); ++ fpm_pctl(FPM_PCTL_STATE_RELOADING, FPM_PCTL_ACTION_SET); ++ break; + } + + if (fpm_globals.is_child) { +diff --git a/sapi/fpm/fpm/fpm_signals.c b/sapi/fpm/fpm/fpm_signals.c +index c5d0692..9fae650 100644 +--- a/sapi/fpm/fpm/fpm_signals.c ++++ b/sapi/fpm/fpm/fpm_signals.c +@@ -160,6 +160,7 @@ + [SIGINT] = 'I', + [SIGUSR1] = '1', + [SIGUSR2] = '2', ++ [SIGHUP] = 'H', + [SIGQUIT] = 'Q', + [SIGCHLD] = 'C' + }; +@@ -206,6 +207,7 @@ + 0 > sigaction(SIGINT, &act, 0) || + 0 > sigaction(SIGUSR1, &act, 0) || + 0 > sigaction(SIGUSR2, &act, 0) || ++ 0 > sigaction(SIGHUP, &act, 0) || + 0 > sigaction(SIGCHLD, &act, 0) || + 0 > sigaction(SIGQUIT, &act, 0)) { + +@@ -235,6 +237,7 @@ + 0 > sigaction(SIGINT, &act_dfl, 0) || + 0 > sigaction(SIGUSR1, &act_dfl, 0) || + 0 > sigaction(SIGUSR2, &act_dfl, 0) || ++ 0 > sigaction(SIGHUP, &act_dfl, 0) || + 0 > sigaction(SIGCHLD, &act_dfl, 0) || + 0 > sigaction(SIGQUIT, &act, 0)) { + +diff --git a/sapi/fpm/php-fpm.8.in b/sapi/fpm/php-fpm.8.in +index 794f508..b1bcf08 100644 +--- a/sapi/fpm/php-fpm.8.in ++++ b/sapi/fpm/php-fpm.8.in +@@ -150,7 +150,7 @@ + .TP + .B SIGUSR1 \fPre-open log file + .TP +-.B SIGUSR2 \fPgraceful reload of all workers + reload of fpm conf/binary ++.B SIGUSR2,SIGHUP \fPgraceful reload of all workers + reload of fpm conf/binary + .RE + .PD 1 + .P diff --git a/generate_patches b/generate_patches deleted file mode 100755 index 6ef746525b8f..000000000000 --- a/generate_patches +++ /dev/null @@ -1,63 +0,0 @@ -#!/bin/bash - -. PKGBUILD - -makepkg -o --nodeps --noprepare --skipinteg - -pushd src/${_base}-${pkgver} - -sed '/APACHE_THREADED_MPM=/d' -i.orig sapi/apache2handler/config.m4 -sed '/APACHE_THREADED_MPM=/d' -i.orig configure - -sed 's/.conf.default/.conf/g' -i.orig sapi/fpm/Makefile.frag - -sed \ - -e "s#run/php-fpm.pid#/run/${_base}${phpbase}${suffix}-fpm/php-fpm.pid#" \ - -e 's#^;error_log =.*#error_log = syslog#' \ - -i.orig sapi/fpm/php-fpm.conf.in - -sed \ - -e "s#^listen =.*#listen = /run/${_base}${phpbase}${suffix}-fpm/php-fpm.sock#" \ - -e 's#^;listen.owner =#listen.owner =#' \ - -e 's#^;listen.group =#listen.group =#' \ - -e 's#^;chdir =.*#;chdir = /srv/http#' \ - -i.orig sapi/fpm/www.conf.in - -sed \ - -e "s#^PIDFile=.*#PIDFile=/run/${_base}${phpbase}${suffix}-fpm/php-fpm.pid#" \ - -e "s#^ExecStart=@EXPANDED_SBINDIR@/php-fpm --nodaemonize#ExecStart=@EXPANDED_SBINDIR@/php-fpm${phpbase}${suffix} --nodaemonize#" \ - -i.orig sapi/fpm/php-fpm.service.in - -extensions=";extension=bcmath\n;extension=bz2\n;extension=calendar\nextension=curl\n;extension=dba\n;extension=enchant\n;extension=exif\n;extension=ffi\n;extension=ftp\n;extension=gd\n;extension=gettext\n;extension=gmp\n;extension=iconv\n;extension=imap\n;extension=intl\n;extension=ldap\n;extension=mysqli\n;extension=odbc\n;zend_extension=opcache\n;extension=pdo_dblib\n;extension=pdo_mysql\n;extension=pdo_odbc\n;extension=pdo_pgsql\n;extension=pdo_sqlite\n;extension=pgsql\n;extension=pspell\n;extension=shmop\n;extension=snmp\n;extension=soap\n;extension=sockets\n;extension=sodium\n;extension=sqlite3\n;extension=sysvmsg\n;extension=sysvsem\n;extension=sysvshm\n;extension=tidy\n;extension=xmlrpc\n;extension=xsl\nextension=zip\n" - -sed \ - -r ":a;N;\$!ba;s/; Notes for Windows environments :\n.+;?extension=\w+\n/${extensions}/g" \ - -i.orig php.ini-production - -sed \ - -e 's#^; extension_dir = "\./"$#extension_dir = "BIG_BAD_MODULES"#g' \ - -i php.ini-production - -sed \ - -e 's#^;extension_dir = "\./"$#extension_dir = "BIG_BAD_MODULES"#g' \ - -i php.ini-production - -sed \ - -e "s#BIG_BAD_MODULES#/usr/lib/${_base}${phpbase}${suffix}/modules#g" \ - -i php.ini-production - -diff -u sapi/apache2handler/config.m4.orig sapi/apache2handler/config.m4 | filterdiff --clean --remove-timestamps > ../../apache.patch -diff -u configure.orig configure | filterdiff --clean --remove-timestamps >> ../../apache.patch - -diff -u sapi/fpm/Makefile.frag.orig sapi/fpm/Makefile.frag | filterdiff --clean --remove-timestamps > ../../php-fpm.patch -diff -u sapi/fpm/php-fpm.conf.in.orig sapi/fpm/php-fpm.conf.in | filterdiff --clean --remove-timestamps >> ../../php-fpm.patch -diff -u sapi/fpm/www.conf.in.orig sapi/fpm/www.conf.in | filterdiff --clean --remove-timestamps >> ../../php-fpm.patch -diff -u sapi/fpm/php-fpm.service.in.orig sapi/fpm/php-fpm.service.in | filterdiff --clean --remove-timestamps >> ../../php-fpm.patch - -diff -u php.ini-production.orig php.ini-production | filterdiff --clean --remove-timestamps > ../../php.ini.patch - -popd - -echo "d /run/${_base}${phpbase}${suffix}-fpm 755 root root" > php-fpm.tmpfiles - - diff --git a/intl.patch b/intl.patch deleted file mode 100644 index bc7e2e55ffef..000000000000 --- a/intl.patch +++ /dev/null @@ -1,147 +0,0 @@ -diff -urNp php-7.2.34-orig/ext/intl/breakiterator/codepointiterator_internal.cpp php-7.2.34-dwok/ext/intl/breakiterator/codepointiterator_internal.cpp ---- php-7.2.34-orig/ext/intl/breakiterator/codepointiterator_internal.cpp -+++ php-7.2.34-dwok/ext/intl/breakiterator/codepointiterator_internal.cpp -@@ -59,7 +59,7 @@ - return *this; - } - -- this->fText = utext_clone(this->fText, that.fText, FALSE, TRUE, &uec); -+ this->fText = utext_clone(this->fText, that.fText, false, true, &uec); - - //don't bother copying the character iterator, getText() is deprecated - clearCurrentCharIter(); -@@ -79,17 +79,17 @@ - UBool CodePointBreakIterator::operator==(const BreakIterator& that) const - { - if (typeid(*this) != typeid(that)) { -- return FALSE; -+ return false; - } - - const CodePointBreakIterator& that2 = - static_cast<const CodePointBreakIterator&>(that); - - if (!utext_equals(this->fText, that2.fText)) { -- return FALSE; -+ return false; - } - -- return TRUE; -+ return true; - } - - CodePointBreakIterator* CodePointBreakIterator::clone(void) const -@@ -110,7 +110,7 @@ - - UText *CodePointBreakIterator::getUText(UText *fillIn, UErrorCode &status) const - { -- return utext_clone(fillIn, this->fText, FALSE, TRUE, &status); -+ return utext_clone(fillIn, this->fText, false, true, &status); - } - - void CodePointBreakIterator::setText(const UnicodeString &text) -@@ -129,7 +129,7 @@ - return; - } - -- this->fText = utext_clone(this->fText, text, FALSE, TRUE, &status); -+ this->fText = utext_clone(this->fText, text, false, true, &status); - - clearCurrentCharIter(); - } -@@ -281,7 +281,7 @@ - } - - int64_t pos = utext_getNativeIndex(this->fText); -- this->fText = utext_clone(this->fText, input, FALSE, TRUE, &status); -+ this->fText = utext_clone(this->fText, input, false, true, &status); - if (U_FAILURE(status)) { - return *this; - } -diff -urNp php-7.2.34-orig/ext/intl/collator/collator_sort.c php-7.2.34-dwok/ext/intl/collator/collator_sort.c ---- php-7.2.34-orig/ext/intl/collator/collator_sort.c -+++ php-7.2.34-dwok/ext/intl/collator/collator_sort.c -@@ -346,7 +346,7 @@ - */ - PHP_FUNCTION( collator_sort ) - { -- collator_sort_internal( TRUE, INTERNAL_FUNCTION_PARAM_PASSTHRU ); -+ collator_sort_internal( true, INTERNAL_FUNCTION_PARAM_PASSTHRU ); - } - /* }}} */ - -@@ -540,7 +540,7 @@ - */ - PHP_FUNCTION( collator_asort ) - { -- collator_sort_internal( FALSE, INTERNAL_FUNCTION_PARAM_PASSTHRU ); -+ collator_sort_internal( false, INTERNAL_FUNCTION_PARAM_PASSTHRU ); - } - /* }}} */ - -diff -urNp php-7.2.34-orig/ext/intl/dateformat/dateformat_attr.c php-7.2.34-dwok/ext/intl/dateformat/dateformat_attr.c ---- php-7.2.34-orig/ext/intl/dateformat/dateformat_attr.c -+++ php-7.2.34-dwok/ext/intl/dateformat/dateformat_attr.c -@@ -88,7 +88,7 @@ - UChar value_buf[64]; - uint32_t length = USIZE( value_buf ); - UChar* value = value_buf; -- zend_bool is_pattern_localized =FALSE; -+ zend_bool is_pattern_localized = false; - - DATE_FORMAT_METHOD_INIT_VARS; - -@@ -131,7 +131,7 @@ - size_t value_len = 0; - int32_t slength = 0; - UChar* svalue = NULL; -- zend_bool is_pattern_localized =FALSE; -+ zend_bool is_pattern_localized = false; - - - DATE_FORMAT_METHOD_INIT_VARS; -@@ -227,7 +227,7 @@ - */ - PHP_FUNCTION( datefmt_set_lenient ) - { -- zend_bool isLenient = FALSE; -+ zend_bool isLenient = false; - - DATE_FORMAT_METHOD_INIT_VARS; - -diff -urNp php-7.2.34-orig/ext/intl/normalizer/normalizer_normalize.c php-7.2.34-dwok/ext/intl/normalizer/normalizer_normalize.c ---- php-7.2.34-orig/ext/intl/normalizer/normalizer_normalize.c -+++ php-7.2.34-dwok/ext/intl/normalizer/normalizer_normalize.c -@@ -179,7 +179,7 @@ - int uinput_len = 0; - UErrorCode status = U_ZERO_ERROR; - -- UBool uret = FALSE; -+ UBool uret = false; - - intl_error_reset( NULL ); - -diff -urNp php-7.2.34-orig/ext/intl/timezone/timezone_class.cpp php-7.2.34-dwok/ext/intl/timezone/timezone_class.cpp ---- php-7.2.34-orig/ext/intl/timezone/timezone_class.cpp -+++ php-7.2.34-dwok/ext/intl/timezone/timezone_class.cpp -@@ -323,7 +323,7 @@ - - int32_t rawOffset, dstOffset; - UDate now = Calendar::getNow(); -- tz->getOffset(now, FALSE, rawOffset, dstOffset, uec); -+ tz->getOffset(now, false, rawOffset, dstOffset, uec); - if (U_FAILURE(uec)) { - return debug_info; - } -diff -urNp php-7.2.34-orig/ext/intl/timezone/timezone_methods.cpp php-7.2.34-dwok/ext/intl/timezone/timezone_methods.cpp ---- php-7.2.34-orig/ext/intl/timezone/timezone_methods.cpp -+++ php-7.2.34-dwok/ext/intl/timezone/timezone_methods.cpp -@@ -95,7 +95,7 @@ - RETURN_NULL(); - } - -- tz = timezone_convert_datetimezone(tzobj->type, tzobj, FALSE, NULL, -+ tz = timezone_convert_datetimezone(tzobj->type, tzobj, false, NULL, - "intltz_from_date_time_zone"); - if (tz == NULL) { - RETURN_NULL(); diff --git a/mysql-socket-php7.1.patch b/mysql-socket-php7.1.patch new file mode 100644 index 000000000000..580a53572980 --- /dev/null +++ b/mysql-socket-php7.1.patch @@ -0,0 +1,26 @@ +diff --git a/ext/mysqlnd/mysqlnd_connection.c b/ext/mysqlnd/mysqlnd_connection.c +index 8897038..6121317 100644 +--- a/ext/mysqlnd/mysqlnd_connection.c ++++ b/ext/mysqlnd/mysqlnd_connection.c +@@ -554,7 +554,7 @@ + if (hostname.l == sizeof("localhost") - 1 && !strncasecmp(hostname.s, "localhost", hostname.l)) { + DBG_INF_FMT("socket=%s", socket_or_pipe->s? socket_or_pipe->s:"n/a"); + if (!socket_or_pipe->s) { +- socket_or_pipe->s = "/tmp/mysql.sock"; ++ socket_or_pipe->s = "/run/mysqld/mysqld.sock"; + socket_or_pipe->l = strlen(socket_or_pipe->s); + } + transport.l = mnd_sprintf(&transport.s, 0, "unix://%s", socket_or_pipe->s); +diff --git a/ext/pdo_mysql/pdo_mysql.c b/ext/pdo_mysql/pdo_mysql.c +index 54e1c93..b355a83 100644 +--- a/ext/pdo_mysql/pdo_mysql.c ++++ b/ext/pdo_mysql/pdo_mysql.c +@@ -51,7 +51,7 @@ + # define PDO_MYSQL_UNIX_ADDR PHP_MYSQL_UNIX_SOCK_ADDR + # else + # if !PHP_WIN32 +-# define PDO_MYSQL_UNIX_ADDR "/tmp/mysql.sock" ++# define PDO_MYSQL_UNIX_ADDR "/run/mysqld/mysqld.sock" + # else + # define PDO_MYSQL_UNIX_ADDR NULL + # endif diff --git a/pear-config-patcher.php b/pear-config-patcher.php new file mode 100644 index 000000000000..3c724c2e196e --- /dev/null +++ b/pear-config-patcher.php @@ -0,0 +1,43 @@ +<?php +if (!isset($argv, $argc)) { + echo "No command line args provided\n"; + exit(1); +} +if ($argc < 4) { + echo "Not all command line args provided\n"; + exit(2); +} +$targetFile = $confFile = $argv[1]; +$phpBin = $argv[2]; +$pearSuffix = $argv[3]; + +$data = ''; +$file = fopen($confFile, "r"); + +if ($file !== false) { + while(!feof($file)) { + $line = fgets($file); + $serialized = @unserialize($line); + if (is_array($serialized)) { + $serialized['cache_dir'] = "/tmp/pear{$pearSuffix}/cache"; + $serialized['temp_dir'] = "/tmp/pear{$pearSuffix}"; + $serialized['download_dir'] = "/tmp/pear{$pearSuffix}/download"; + $serialized['php_bin'] = $phpBin; + $data .= @serialize($serialized); + $data .= "\n"; + } else { + $data .= $line; + } + } + fclose($file); + if (false !== file_put_contents($targetFile, $data)) { + echo "Written to $targetFile\n"; + } else { + echo "Failed to write to $targetFile\n"; + exit(3); + } +} else { + echo "File was not found {$confFile}\n"; + exit(4); +} +exit(0); diff --git a/php-apache.conf b/php-apache.conf new file mode 100644 index 000000000000..e74ae8d9b7a8 --- /dev/null +++ b/php-apache.conf @@ -0,0 +1,13 @@ +# Required modules: dir_module, @MODULE@ + +<IfModule dir_module> + <IfModule @MODULE@> + DirectoryIndex index.php index.html + <FilesMatch "\.php$"> + SetHandler application/x-httpd-php + </FilesMatch> + <FilesMatch "\.phps$"> + SetHandler application/x-httpd-php-source + </FilesMatch> + </IfModule> +</IfModule> diff --git a/php-enchant-depr.patch b/php-enchant-depr.patch new file mode 100644 index 000000000000..0e2d2c0cf676 --- /dev/null +++ b/php-enchant-depr.patch @@ -0,0 +1,38 @@ +--- php-7.2.1/ext/enchant/enchant.c.orig ++++ php-7.2.1/ext/enchant/enchant.c +@@ -741,7 +741,7 @@ + for (i = 0; i < n_sugg; i++) { + add_next_index_string(sugg, suggs[i]); + } +- enchant_dict_free_suggestions(pdict->pdict, suggs); ++ enchant_dict_free_string_list(pdict->pdict, suggs); + } + + +@@ -798,7 +798,7 @@ + add_next_index_string(return_value, suggs[i]); + } + +- enchant_dict_free_suggestions(pdict->pdict, suggs); ++ enchant_dict_free_string_list(pdict->pdict, suggs); + } + } + /* }}} */ +@@ -818,7 +818,7 @@ + + PHP_ENCHANT_GET_DICT; + +- enchant_dict_add_to_personal(pdict->pdict, word, wordlen); ++ enchant_dict_add(pdict->pdict, word, wordlen); + } + /* }}} */ + +@@ -856,7 +856,7 @@ + + PHP_ENCHANT_GET_DICT; + +- RETURN_BOOL(enchant_dict_is_in_session(pdict->pdict, word, wordlen)); ++ RETURN_BOOL(enchant_dict_is_added(pdict->pdict, word, wordlen)); + } + /* }}} */ + diff --git a/enchant.patch b/php-enchant-php5.3.patch index 93c0ce5c269e..4ef8395e76fe 100644 --- a/enchant.patch +++ b/php-enchant-php5.3.patch @@ -1,5 +1,5 @@ ---- php-7.1.13/ext/enchant/config.m4.orig 2018-01-03 02:32:29.000000000 +0000 -+++ php-7.1.13/ext/enchant/config.m4 2018-01-21 22:10:03.788875780 +0000 +--- php-7.1.13/ext/enchant/config.m4.orig ++++ php-7.1.13/ext/enchant/config.m4 @@ -14,9 +14,9 @@ ENCHANT_SEARCH_DIRS="/usr/local /usr" fi @@ -21,8 +21,8 @@ PHP_ADD_INCLUDE($ENCHANT_INCDIR) PHP_CHECK_LIBRARY(enchant, enchant_broker_set_param, [ ---- php-7.1.13/configure.orig 2018-01-21 22:03:51.494656374 +0000 -+++ php-7.1.13/configure 2018-01-21 22:12:35.932571143 +0000 +--- php-7.1.13/configure.orig ++++ php-7.1.13/configure @@ -29838,9 +29838,9 @@ ENCHANT_SEARCH_DIRS="/usr/local /usr" fi @@ -44,41 +44,3 @@ if test -n "$ENCHANT_LIBDIR"; then if test "$ENCHANT_LIBDIR" != "/usr/$PHP_LIBDIR" && test "$ENCHANT_LIBDIR" != "/usr/lib"; then ---- php-7.2.1/ext/enchant/enchant.c.orig 2018-01-02 22:36:05.000000000 +0000 -+++ php-7.2.1/ext/enchant/enchant.c 2018-01-21 22:34:50.205791491 +0000 -@@ -741,7 +741,7 @@ - for (i = 0; i < n_sugg; i++) { - add_next_index_string(sugg, suggs[i]); - } -- enchant_dict_free_suggestions(pdict->pdict, suggs); -+ enchant_dict_free_string_list(pdict->pdict, suggs); - } - - -@@ -798,7 +798,7 @@ - add_next_index_string(return_value, suggs[i]); - } - -- enchant_dict_free_suggestions(pdict->pdict, suggs); -+ enchant_dict_free_string_list(pdict->pdict, suggs); - } - } - /* }}} */ -@@ -818,7 +818,7 @@ - - PHP_ENCHANT_GET_DICT; - -- enchant_dict_add_to_personal(pdict->pdict, word, wordlen); -+ enchant_dict_add(pdict->pdict, word, wordlen); - } - /* }}} */ - -@@ -856,7 +856,7 @@ - - PHP_ENCHANT_GET_DICT; - -- RETURN_BOOL(enchant_dict_is_in_session(pdict->pdict, word, wordlen)); -+ RETURN_BOOL(enchant_dict_is_added(pdict->pdict, word, wordlen)); - } - /* }}} */ - diff --git a/php-fpm.patch b/php-fpm.patch deleted file mode 100644 index d9feb53b005d..000000000000 --- a/php-fpm.patch +++ /dev/null @@ -1,76 +0,0 @@ ---- sapi/fpm/Makefile.frag.orig -+++ sapi/fpm/Makefile.frag -@@ -15,8 +15,8 @@ - else \ - echo "Installing PHP FPM defconfig: $(INSTALL_ROOT)$(sysconfdir)/" && \ - $(mkinstalldirs) $(INSTALL_ROOT)$(sysconfdir)/php-fpm.d; \ -- $(INSTALL_DATA) sapi/fpm/php-fpm.conf $(INSTALL_ROOT)$(sysconfdir)/php-fpm.conf.default; \ -- $(INSTALL_DATA) sapi/fpm/www.conf $(INSTALL_ROOT)$(sysconfdir)/php-fpm.d/www.conf.default; \ -+ $(INSTALL_DATA) sapi/fpm/php-fpm.conf $(INSTALL_ROOT)$(sysconfdir)/php-fpm.conf; \ -+ $(INSTALL_DATA) sapi/fpm/www.conf $(INSTALL_ROOT)$(sysconfdir)/php-fpm.d/www.conf; \ - fi - - @echo "Installing PHP FPM man page: $(INSTALL_ROOT)$(mandir)/man8/" ---- sapi/fpm/php-fpm.conf.in.orig -+++ sapi/fpm/php-fpm.conf.in -@@ -14,14 +14,14 @@ - ; Pid file - ; Note: the default prefix is @EXPANDED_LOCALSTATEDIR@ - ; Default Value: none --;pid = run/php-fpm.pid -+;pid = /run/php72-fpm/php-fpm.pid - - ; Error log file - ; If it's set to "syslog", log is sent to syslogd instead of being written - ; into a local file. - ; Note: the default prefix is @EXPANDED_LOCALSTATEDIR@ - ; Default Value: log/php-fpm.log --;error_log = log/php-fpm.log -+error_log = syslog - - ; syslog_facility is used to specify what type of program is logging the - ; message. This lets syslogd specify that messages from different facilities ---- sapi/fpm/www.conf.in.orig -+++ sapi/fpm/www.conf.in -@@ -33,7 +33,7 @@ - ; (IPv6 and IPv4-mapped) on a specific port; - ; '/path/to/unix/socket' - to listen on a unix socket. - ; Note: This value is mandatory. --listen = 127.0.0.1:9000 -+listen = /run/php72-fpm/php-fpm.sock - - ; Set listen(2) backlog. - ; Default Value: 511 (-1 on FreeBSD and OpenBSD) -@@ -44,8 +44,8 @@ - ; BSD-derived systems allow connections regardless of permissions. - ; Default Values: user and group are set as the running user - ; mode is set to 0660 --;listen.owner = @php_fpm_user@ --;listen.group = @php_fpm_group@ -+listen.owner = @php_fpm_user@ -+listen.group = @php_fpm_group@ - ;listen.mode = 0660 - ; When POSIX Access Control Lists are supported you can set them using - ; these options, value is a comma separated list of user/group names. -@@ -362,7 +362,7 @@ - ; Chdir to this directory at the start. - ; Note: relative path can be used. - ; Default Value: current directory or / when chroot --;chdir = /var/www -+;chdir = /srv/http - - ; Redirect worker stdout and stderr into main error log. If not set, stdout and - ; stderr will be redirected to /dev/null according to FastCGI specs. ---- sapi/fpm/php-fpm.service.in.orig -+++ sapi/fpm/php-fpm.service.in -@@ -8,8 +8,8 @@ - - [Service] - Type=@php_fpm_systemd@ --PIDFile=@EXPANDED_LOCALSTATEDIR@/run/php-fpm.pid --ExecStart=@EXPANDED_SBINDIR@/php-fpm --nodaemonize --fpm-config @EXPANDED_SYSCONFDIR@/php-fpm.conf -+PIDFile=/run/php72-fpm/php-fpm.pid -+ExecStart=@EXPANDED_SBINDIR@/php-fpm72 --nodaemonize --fpm-config @EXPANDED_SYSCONFDIR@/php-fpm.conf - ExecReload=/bin/kill -USR2 $MAINPID - PrivateTmp=true - diff --git a/php-fpm.tmpfiles b/php-fpm.tmpfiles deleted file mode 100644 index 29f29ad70793..000000000000 --- a/php-fpm.tmpfiles +++ /dev/null @@ -1 +0,0 @@ -d /run/php72-fpm 755 root root diff --git a/php-freetype-2.9.1.patch b/php-freetype-2.9.1.patch index 02dfd9ce3cd4..7347efcdfd7e 100644 --- a/php-freetype-2.9.1.patch +++ b/php-freetype-2.9.1.patch @@ -1,5 +1,5 @@ ---- a/ext/gd/config.m4 2018-04-24 11:09:54.000000000 -0400 -+++ b/ext/gd/config.m4 2018-05-04 15:18:49.867283889 -0400 +--- a/ext/gd/config.m4 ++++ b/ext/gd/config.m4 @@ -186,21 +186,36 @@ AC_DEFUN([PHP_GD_FREETYPE2],[ if test "$PHP_FREETYPE_DIR" != "no"; then @@ -48,8 +48,8 @@ PHP_EVAL_INCLINE($FREETYPE2_CFLAGS) PHP_EVAL_LIBLINE($FREETYPE2_LIBS, GD_SHARED_LIBADD) AC_DEFINE(HAVE_LIBFREETYPE,1,[ ]) ---- a/configure 2018-04-24 11:10:05.000000000 -0400 -+++ b/configure 2018-05-04 15:18:45.626367913 -0400 +--- a/configure ++++ b/configure @@ -34348,21 +34348,79 @@ if test "$PHP_FREETYPE_DIR" != "no"; then diff --git a/icu.patch b/php-icu-php5.5.patch index 1b06e0f0196e..4dde37a4c30e 100644 --- a/icu.patch +++ b/php-icu-php5.5.patch @@ -1,5 +1,5 @@ ---- 7.2.34/ext/intl/breakiterator/codepointiterator_internal.cpp -+++ 7.2.34/ext/intl/breakiterator/codepointiterator_internal.cpp +--- a/ext/intl/breakiterator/codepointiterator_internal.cpp ++++ b/ext/intl/breakiterator/codepointiterator_internal.cpp @@ -74,7 +74,11 @@ clearCurrentCharIter(); } @@ -27,8 +27,8 @@ virtual CodePointBreakIterator* clone(void) const; virtual UClassID getDynamicClassID(void) const; ---- 7.2.34/ext/intl/locale/locale_methods.c -+++ 7.2.34/ext/intl/locale/locale_methods.c +--- a/ext/intl/locale/locale_methods.c ++++ b/ext/intl/locale/locale_methods.c @@ -1333,7 +1333,7 @@ if( token && (token==cur_lang_tag) ){ /* check if the char. after match is SEPARATOR */ diff --git a/php-icu-php7.3.patch b/php-icu-php7.3.patch new file mode 100644 index 000000000000..82120023b79c --- /dev/null +++ b/php-icu-php7.3.patch @@ -0,0 +1,40 @@ +--- a/ext/intl/breakiterator/codepointiterator_internal.cpp ++++ b/ext/intl/breakiterator/codepointiterator_internal.cpp +@@ -74,7 +74,11 @@ + clearCurrentCharIter(); + } + ++#if U_ICU_VERSION_MAJOR_NUM >= 70 ++bool CodePointBreakIterator::operator==(const BreakIterator& that) const ++#else + UBool CodePointBreakIterator::operator==(const BreakIterator& that) const ++#endif + { + if (typeid(*this) != typeid(that)) { + return FALSE; +--- a/ext/intl/breakiterator/codepointiterator_internal.h ++++ b/ext/intl/breakiterator/codepointiterator_internal.h +@@ -36,8 +36,11 @@ + + virtual ~CodePointBreakIterator(); + ++#if U_ICU_VERSION_MAJOR_NUM >= 70 ++ virtual bool operator==(const BreakIterator& that) const; ++#else + virtual UBool operator==(const BreakIterator& that) const; +- ++#endif + virtual CodePointBreakIterator* clone(void) const; + + virtual UClassID getDynamicClassID(void) const; +--- a/ext/intl/locale/locale_methods.c ++++ b/ext/intl/locale/locale_methods.c +@@ -1326,7 +1326,7 @@ + if( token && (token==cur_lang_tag) ){ + /* check if the char. after match is SEPARATOR */ + chrcheck = token + (strlen(cur_loc_range)); +- if( isIDSeparator(*chrcheck) || isEndOfTag(*chrcheck) ){ ++ if( isIDSeparator(*chrcheck) || isKeywordSeparator(*chrcheck) || isEndOfTag(*chrcheck) ){ + efree( cur_lang_tag ); + efree( cur_loc_range ); + if( can_lang_tag){ diff --git a/php-phpinfo.patch b/php-phpinfo.patch new file mode 100644 index 000000000000..72d0beaea4bd --- /dev/null +++ b/php-phpinfo.patch @@ -0,0 +1,22 @@ +--- a/ext/standard/info.c ++++ b/ext/standard/info.c +@@ -810,9 +810,6 @@ PHPAPI ZEND_COLD void php_print_info(int flag) + #ifdef ARCHITECTURE + php_info_print_table_row(2, "Architecture", ARCHITECTURE); + #endif +-#ifdef CONFIGURE_COMMAND +- php_info_print_table_row(2, "Configure Command", CONFIGURE_COMMAND ); +-#endif + + if (sapi_module.pretty_name) { + php_info_print_table_row(2, "Server API", sapi_module.pretty_name ); +--- a/ext/standard/tests/general_functions/phpinfo.phpt ++++ b/ext/standard/tests/general_functions/phpinfo.phpt +@@ -20,7 +20,6 @@ PHP Version => %s + + System => %s + Build Date => %s%a +-Configure Command => %s + Server API => Command Line Interface + Virtual Directory Support => %s + Configuration File (php.ini) Path => %s diff --git a/php.ini.patch b/php.ini.patch deleted file mode 100644 index 0d7a91c59c11..000000000000 --- a/php.ini.patch +++ /dev/null @@ -1,78 +0,0 @@ ---- php.ini-production.orig -+++ php.ini-production -@@ -731,7 +731,7 @@ - - ; Directory in which the loadable extensions (modules) reside. - ; http://php.net/extension-dir --; extension_dir = "./" -+extension_dir = "/usr/lib/php72/modules" - ; On windows: - ; extension_dir = "ext" - -@@ -880,47 +880,45 @@ - ; deprecated in a future PHP major version. So, when it is possible, please - ; move to the new ('extension=<ext>) syntax. - ; --; Notes for Windows environments : --; --; - Many DLL files are located in the extensions/ (PHP 4) or ext/ (PHP 5+) --; extension folders as well as the separate PECL DLL download (PHP 5+). --; Be sure to appropriately set the extension_dir directive. --; -+;extension=bcmath - ;extension=bz2 --;extension=curl --;extension=fileinfo --;extension=gd2 -+;extension=calendar -+extension=curl -+;extension=dba -+;extension=enchant -+;extension=exif -+;extension=ffi -+;extension=ftp -+;extension=gd - ;extension=gettext - ;extension=gmp --;extension=intl -+;extension=iconv - ;extension=imap --;extension=interbase -+;extension=intl - ;extension=ldap --;extension=mbstring --;extension=exif ; Must be after mbstring as it depends on it - ;extension=mysqli --;extension=oci8_12c ; Use with Oracle Database 12c Instant Client - ;extension=odbc --;extension=openssl --;extension=pdo_firebird -+;zend_extension=opcache -+;extension=pdo_dblib - ;extension=pdo_mysql --;extension=pdo_oci - ;extension=pdo_odbc - ;extension=pdo_pgsql - ;extension=pdo_sqlite - ;extension=pgsql -+;extension=pspell - ;extension=shmop -- --; The MIBS data available in the PHP distribution must be installed. --; See http://www.php.net/manual/en/snmp.installation.php - ;extension=snmp -- - ;extension=soap - ;extension=sockets -+;extension=sodium - ;extension=sqlite3 -+;extension=sysvmsg -+;extension=sysvsem -+;extension=sysvshm - ;extension=tidy - ;extension=xmlrpc - ;extension=xsl -+extension=zip - - ;;;;;;;;;;;;;;;;;;; - ; Module Settings ; diff --git a/recode-php5.4.patch b/recode-php5.4.patch new file mode 100644 index 000000000000..10a5d83e2e52 --- /dev/null +++ b/recode-php5.4.patch @@ -0,0 +1,23 @@ +--- a/ext/recode/config9.m4 ++++ b/ext/recode/config9.m4 +@@ -13,6 +13,6 @@ + fi + + if test -n "$recode_conflict"; then +- AC_MSG_ERROR([recode extension can not be configured together with:$recode_conflict]) ++ AC_MSG_WARN([recode extension can not be configured together with:$recode_conflict]) + fi + fi +--- php-5.6.40/configure ++++ php-5.6.40/configure +@@ -104651,10 +104651,6 @@ + fi + + fi +- +- if test -n "$recode_conflict"; then +- as_fn_error $? "recode extension can not be configured together with:$recode_conflict" "$LINENO" 5 +- fi + fi + + diff --git a/timezonedb-guess.patch b/timezonedb-guess.patch new file mode 100644 index 000000000000..10c057e40799 --- /dev/null +++ b/timezonedb-guess.patch @@ -0,0 +1,27 @@ +index cf4a11b..f2ea919 100644 +--- a/ext/date/php_date.c ++++ b/ext/date/php_date.c +@@ -545,6 +545,23 @@ static char* guess_timezone(const timelib_tzdb *tzdb) + DATEG(timezone_valid) = 1; + return DATEG(default_timezone); + } ++ /* Try to guess timezone from system information */ ++ { ++ struct tm *ta, tmbuf; ++ time_t the_time; ++ char *tzid = NULL; ++ ++ the_time = time(NULL); ++ ta = php_localtime_r(&the_time, &tmbuf); ++ if (ta) { ++ tzid = timelib_timezone_id_from_abbr(ta->tm_zone, ta->tm_gmtoff, ta->tm_isdst); ++ } ++ if (! tzid) { ++ tzid = "UTC"; ++ } ++ ++ return tzid; ++ } + /* Fallback to UTC */ + return "UTC"; + } diff --git a/timezonedb-php7.2.patch b/timezonedb-php7.2.patch new file mode 100644 index 000000000000..9e2b95c06d9d --- /dev/null +++ b/timezonedb-php7.2.patch @@ -0,0 +1,628 @@ +--- a/ext/date/config0.m4 ++++ b/ext/date/config0.m4 +@@ -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 --git a/ext/date/lib/parse_tz.c b/ext/date/lib/parse_tz.c +index 960e528..501b09e 100644 +--- a/ext/date/lib/parse_tz.c ++++ b/ext/date/lib/parse_tz.c +@@ -25,8 +25,21 @@ + #include "timelib.h" + #include "timelib_private.h" + ++#ifdef HAVE_SYSTEM_TZDATA ++#include <sys/mman.h> ++#include <sys/stat.h> ++#include <limits.h> ++#include <fcntl.h> ++#include <unistd.h> ++ ++#include "php_scandir.h" ++ ++#else + #define TIMELIB_SUPPORTS_V2DATA + #include "timezonedb.h" ++#endif ++ ++#include <ctype.h> + + #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 unsigned char **tzf, timelib_tzinfo *tz) + { + 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 *tz) + } + } + +-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 unsigned char **tzf, char *timezone, const + 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_timezone_identifiers_list(const 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_ctor(char *name) + 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(char *timezone, const timelib_tzdb *tzdb, i + 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(char *timezone, const timelib_tzdb *tzdb, i + } 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/timezonedb-php7.3.patch b/timezonedb-php7.3.patch new file mode 100644 index 000000000000..7c8ecb2f904a --- /dev/null +++ b/timezonedb-php7.3.patch @@ -0,0 +1,625 @@ +--- a/ext/date/config0.m4 ++++ b/ext/date/config0.m4 +@@ -9,6 +9,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 --git a/ext/date/lib/parse_tz.c b/ext/date/lib/parse_tz.c +index 020da31..9b39c6e 100644 +--- a/ext/date/lib/parse_tz.c ++++ b/ext/date/lib/parse_tz.c +@@ -26,8 +26,21 @@ + #include "timelib.h" + #include "timelib_private.h" + ++#ifdef HAVE_SYSTEM_TZDATA ++#include <sys/mman.h> ++#include <sys/stat.h> ++#include <limits.h> ++#include <fcntl.h> ++#include <unistd.h> ++ ++#include "php_scandir.h" ++ ++#else + #define TIMELIB_SUPPORTS_V2DATA + #include "timezonedb.h" ++#endif ++ ++#include <ctype.h> + + #if (defined(__APPLE__) || defined(__APPLE_CC__)) && (defined(__BIG_ENDIAN__) || defined(__LITTLE_ENDIAN__)) + # if defined(__LITTLE_ENDIAN__) +@@ -88,6 +101,11 @@ static int read_php_preamble(const unsigned char **tzf, timelib_tzinfo *tz) + { + uint32_t version; + ++ if (memcmp(*tzf, "TZif", 4) == 0) { ++ *tzf += 20; ++ return 0; ++ } ++ + /* read ID */ + version = (*tzf)[3] - '0'; + *tzf += 4; +@@ -412,7 +430,429 @@ void timelib_dump_tzinfo(timelib_tzinfo *tz) + } + } + +-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; + +@@ -438,9 +878,48 @@ static int seek_to_tz_position(const unsigned char **tzf, char *timezone, const + 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) +@@ -452,7 +931,30 @@ const timelib_tzdb_index_entry *timelib_timezone_identifiers_list(const 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) +@@ -494,12 +996,14 @@ static timelib_tzinfo* timelib_tzinfo_ctor(char *name) + 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); +@@ -534,11 +1038,36 @@ timelib_tzinfo *timelib_parse_tzfile(char *timezone, const timelib_tzdb *tzdb, i + } + skip_posix_string(&tzf, tmp); + ++#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 (type == TIMELIB_TZINFO_PHP) { + read_location(&tzf, tmp); + } 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/timezonedb-php7.4.patch b/timezonedb-php7.4.patch new file mode 100644 index 000000000000..011d81674f31 --- /dev/null +++ b/timezonedb-php7.4.patch @@ -0,0 +1,625 @@ +--- a/ext/date/config0.m4 ++++ b/ext/date/config0.m4 +@@ -4,6 +4,19 @@ AC_CHECK_HEADERS([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 --git a/ext/date/lib/parse_tz.c b/ext/date/lib/parse_tz.c +index 020da31..9b39c6e 100644 +--- a/ext/date/lib/parse_tz.c ++++ b/ext/date/lib/parse_tz.c +@@ -26,8 +26,21 @@ + #include "timelib.h" + #include "timelib_private.h" + ++#ifdef HAVE_SYSTEM_TZDATA ++#include <sys/mman.h> ++#include <sys/stat.h> ++#include <limits.h> ++#include <fcntl.h> ++#include <unistd.h> ++ ++#include "php_scandir.h" ++ ++#else + #define TIMELIB_SUPPORTS_V2DATA + #include "timezonedb.h" ++#endif ++ ++#include <ctype.h> + + #if (defined(__APPLE__) || defined(__APPLE_CC__)) && (defined(__BIG_ENDIAN__) || defined(__LITTLE_ENDIAN__)) + # if defined(__LITTLE_ENDIAN__) +@@ -88,6 +101,11 @@ static int read_php_preamble(const unsigned char **tzf, timelib_tzinfo *tz) + { + uint32_t version; + ++ if (memcmp(*tzf, "TZif", 4) == 0) { ++ *tzf += 20; ++ return 0; ++ } ++ + /* read ID */ + version = (*tzf)[3] - '0'; + *tzf += 4; +@@ -412,7 +430,429 @@ void timelib_dump_tzinfo(timelib_tzinfo *tz) + } + } + +-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; + +@@ -438,9 +878,48 @@ static int seek_to_tz_position(const unsigned char **tzf, char *timezone, const + 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) +@@ -452,7 +931,30 @@ const timelib_tzdb_index_entry *timelib_timezone_identifiers_list(const 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) +@@ -494,12 +996,14 @@ static timelib_tzinfo* timelib_tzinfo_ctor(char *name) + 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); +@@ -534,11 +1038,36 @@ timelib_tzinfo *timelib_parse_tzfile(char *timezone, const timelib_tzdb *tzdb, i + } + skip_posix_string(&tzf, tmp); + ++#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 (type == TIMELIB_TZINFO_PHP) { + read_location(&tzf, tmp); + } else { + set_default_location_and_comments(&tzf, tmp); + } ++#ifdef HAVE_SYSTEM_TZDATA ++ } ++#endif + } else { + *error_code = TIMELIB_ERROR_NO_SUCH_TIMEZONE; + tmp = NULL; |