diff --git a/7.4/Dockerfile b/7.4/Dockerfile index 0ad2b6a..fe8bbef 100644 --- a/7.4/Dockerfile +++ b/7.4/Dockerfile @@ -1,4 +1,23 @@ -FROM alpine:3.13 +FROM alpine:3.15 AS php7-build + +ENV PACKAGER="graze " + +RUN apk add --no-cache alpine-sdk \ + && apk update \ + && adduser -D builder \ + && addgroup builder abuild + +USER builder + +COPY --chown=builder aports/community/php7 /home/builder/community/php7 + +WORKDIR /home/builder/community/php7 + +RUN abuild-keygen -a -n \ + && abuild -r \ + && rm -f /home/builder/.abuild/*.rsa + +FROM alpine:3.15 LABEL maintainer="developers@graze.com" \ license="MIT" \ @@ -8,12 +27,16 @@ LABEL maintainer="developers@graze.com" \ org.label-schema.description="small php image based on alpine" \ org.label-schema.vcs-url="https://github.com/graze/docker-php-alpine" +COPY --from=php7-build /home/builder/.abuild/*.rsa.pub /etc/apk/keys/ +COPY --from=php7-build /home/builder/packages/community /opt/php7-apk + RUN set -xe \ - && echo "@php http://dl-cdn.alpinelinux.org/alpine/v3.13/community" >> /etc/apk/repositories \ + && sed -i '1i /opt/php7-apk' /etc/apk/repositories \ + && echo "@php http://dl-cdn.alpinelinux.org/alpine/v3.15/community" >> /etc/apk/repositories \ + && apk add --no-cache --repository http://dl-cdn.alpinelinux.org/alpine/v3.13/community gnu-libiconv=1.15-r3 \ && apk add --update --no-cache \ ca-certificates \ curl \ - gnu-libiconv \ openssh-client \ libmemcached-libs \ libevent \ diff --git a/7.4/aports/community/php7/APKBUILD b/7.4/aports/community/php7/APKBUILD new file mode 100644 index 0000000..f500453 --- /dev/null +++ b/7.4/aports/community/php7/APKBUILD @@ -0,0 +1,734 @@ +# Contributor: Valery Kartel +# Contributor: Jakub Jirutka +# Maintainer: Valery Kartel + +# Bundled libraries +# +# Name | License | Location | State +# ----------+---------------------+------------------------+--------- +# bcmath | LGPL-2.1-or-later | ext/bcmath/libbcmath | used +# date | MIT | ext/date/lib | used +# fileinfo | BSD-2-Clause | ext/fileinfo/libmagic | used +# gd | BSD | ext/gd/libgd | used +# hash | CC0-1.0 | ext/hash/sha3 | used +# libmbfl | LGPL-2.1-only | ext/mbstring/libmbfl | used +# pcre | BSD-3-Clause | ext/pcre/pcrelib | not used +# sqlite3 | Public | ext/sqlite3/libsqlite | not used +# libXMLRPC | BSD-3-Clause | ext/xmlrpc/libxmlrpc | used +# libzip | BSD-3-Clause | ext/zip/lib | not used + +# Static extensions +# +# Name | Reason +# ----------+-------------------------------------------- +# zlib | https://bugs.alpinelinux.org/issues/8299 + +pkgname=php7 +_pkgreal=php +pkgver=7.4.33 +pkgrel=2 +_apiver=20190902 +_suffix=${pkgname#php} +# Is this package the default (latest) PHP version? +_default_php="yes" +pkgdesc="The PHP$_suffix language runtime engine" +url="https://www.php.net/" +arch="all" +license="PHP-3.01 BSD-3-Clause LGPL-2.0-or-later MIT Zend-2.0" +depends="$pkgname-common" +depends_dev="$pkgname=$pkgver-r$pkgrel autoconf pcre2-dev re2c" +# Most dependencies between extensions is auto-discovered (see _extension()). +_depends_mysqlnd="$pkgname-openssl" +_depends_pdo_mysql="$pkgname-pdo $pkgname-mysqlnd" +_depends_phar="$pkgname" +# openssl is actually transitive dependency here, but we need to because of +# load index based on number of dependencies. +_depends_mysqli="$pkgname-mysqlnd $pkgname-openssl" +makedepends=" + $depends_dev + apache2-dev + argon2-dev + aspell-dev + bison + bzip2-dev + curl-dev + enchant2-dev + freetds-dev + freetype-dev + gdbm-dev + gettext-dev + gmp-dev + icu-dev + imap-dev + krb5-dev + libedit-dev + libical-dev + libjpeg-turbo-dev + libpng-dev + libpq-dev + lmdb-dev + oniguruma-dev + libsodium-dev + libwebp-dev + libxml2-dev + libxpm-dev + libxslt-dev + libzip-dev + net-snmp-dev + openldap-dev + sqlite-dev + tidyhtml-dev + unixodbc-dev + zlib-dev + " +provides="$pkgname-cli php-cli php" # for backward compatibility +provider_priority=100 +subpackages="$pkgname-dbg $pkgname-dev $pkgname-doc + $pkgname-phpdbg $pkgname-apache2 + $pkgname-embed $pkgname-cgi $pkgname-fpm + $pkgname-pear::noarch + " +source="https://php.net/distributions/$_pkgreal-$pkgver.tar.xz + $pkgname-fpm.initd + $pkgname-fpm.logrotate + $pkgname-module.conf + disabled-tests.list + install-pear.patch + includedir.patch + sharedir.patch + php7-fpm-version-suffix.patch + fix-tests-devserver.patch + enchant-2.patch + xfail-openssl-1.1-test.patch + CVE-2023-0567-1.patch + CVE-2023-0567-2.patch + CVE-2023-0568.patch + CVE-2023-0662-1.patch + CVE-2023-0662-2.patch + fix-fpm-tests.patch + fix-fpm-syntax.patch + fix-curl-7.83-test.patch + CVE-2026-109618-109619.patch + CVE-2026-109618-109619-tests.patch + " +builddir="$srcdir/$_pkgreal-$pkgver" + +_libdir="/usr/lib/$pkgname" +_extension_dir="$_libdir/modules" +_extension_confd="/etc/$pkgname/conf.d" + +_extensions=" + bcmath + bz2 + calendar + ctype + curl + dba + dom + enchant + exif + ffi + fileinfo + ftp + gd + gettext + gmp + iconv + imap + intl + json + ldap + mbstring + mysqli + mysqlnd + odbc + opcache + openssl + pcntl + pdo + pdo_dblib + pdo_mysql + pdo_odbc + pdo_pgsql + pdo_sqlite + pgsql + phar + posix + pspell + session + shmop + simplexml + snmp + soap + sodium + sockets + sqlite3 + sysvmsg + sysvsem + sysvshm + tidy + tokenizer + xml + xmlreader + xmlrpc + xmlwriter + xsl + zip + " +for _ext in $_extensions; do + case "$_ext" in + phar) subpackages="$subpackages $pkgname-$_ext:$_ext";; + *) subpackages="$subpackages $pkgname-$_ext:_extension";; + esac +done +subpackages="$subpackages $pkgname-common::noarch" + +# see https://gitlab.alpinelinux.org/alpine/aports/-/issues/12775 +[ "$CARCH" != "riscv64" ] && subpackages="$subpackages $pkgname-litespeed" + +# secfixes: +# 7.4.33-r1: +# - CVE-2023-0567 +# - CVE-2023-0568 +# - CVE-2023-0662 +# 7.4.33-r0: +# - CVE-2022-31630 +# - CVE-2022-37454 +# 7.4.32-r0: +# - CVE-2022-31628 +# - CVE-2022-31629 +# - CVE-2022-31625 +# - CVE-2022-31626 +# 7.4.28-r0: +# - CVE-2021-21708 +# 7.4.26-r0: +# - CVE-2021-21707 +# 7.4.25-r0: +# - CVE-2021-21703 +# 7.4.24-r0: +# - CVE-2021-21706 +# 7.4.21-r0: +# - CVE-2021-21705 +# 7.4.15-r0: +# - CVE-2021-21702 +# 7.4.14-r0: +# - CVE-2020-7071 +# 7.4.11-r0: +# - CVE-2020-7069 +# - CVE-2020-7070 +# 7.3.18-r0: +# - CVE-2019-11048 +# 7.3.17-r0: +# - CVE-2020-7067 +# 7.3.16-r0: +# - CVE-2020-7064 +# - CVE-2020-7065 +# - CVE-2020-7066 +# 7.3.15-r0: +# - CVE-2020-7061 +# - CVE-2020-7062 +# - CVE-2020-7063 +# 7.3.14-r0: +# - CVE-2020-7059 +# - CVE-2020-7060 +# 7.3.13-r0: +# - CVE-2019-11045 +# - CVE-2019-11047 +# - CVE-2019-11050 +# 7.3.11-r0: +# - CVE-2019-11043 +# 7.3.9-r0: +# - CVE-2019-13224 +# 7.3.8-r0: +# - CVE-2019-11041 +# - CVE-2019-11042 +# 7.2.19-r0: +# - CVE-2019-11039 +# - CVE-2019-11040 +# 7.2.18-r0: +# - CVE-2019-11036 +# 7.2.17-r0: +# - CVE-2019-11034 +# - CVE-2019-11035 +# 7.2.16-r0: +# - CVE-2019-9641 +# - CVE-2019-9640 +# - CVE-2019-9639 +# - CVE-2019-9638 +# - CVE-2019-9637 +# 7.2.14-r0: +# - CVE-2019-9024 +# - CVE-2019-9023 +# - CVE-2019-9022 +# - CVE-2019-9021 +# - CVE-2019-9020 +# 7.2.13-r0: +# - CVE-2018-20783 +# 7.2.8-r0: +# - CVE-2015-9253 +# - CVE-2018-12882 +# - CVE-2018-12883 +# - CVE-2018-14851 +# 7.2.5-r0: +# - CVE-2018-5712 +# - CVE-2018-10546 +# - CVE-2018-10547 +# - CVE-2018-10548 +# - CVE-2018-10549 + +prepare() { + default_prepare + + local vapi=$(sed -n '/#define PHP_API_VERSION/{s/.* //;p}' main/php.h) + if [ "$vapi" != "$_apiver" ]; then + error "Upstream API version is now $vapi. Expecting $_apiver" + error "After updating _apiver, all 3rd-party extensions must be rebuilt." + return 1 + fi + + # https://bugs.php.net/63362 - Not needed but installed headers. + # Drop some Windows specific headers to avoid installation, + # before build to ensure they are really not needed. + rm -f TSRM/tsrm_win32.h \ + TSRM/tsrm_config.w32.h \ + Zend/zend_config.w32.h \ + ext/mysqlnd/config-win.h \ + ext/standard/winver.h + + # Fix some bogus permissions. + find . -name '*.[ch]' -exec chmod 644 {} \; + + # XXX: Delete failing tests. + sed -n '/^[^#]/p' "$srcdir"/disabled-tests.list | while read -r item; do + rm -r $item # do it in this way to apply globbing... + done + + autoconf +} + +# Notes: +# * gd-jis-conv breaks any non-latin font rendering (vakartel). +# * libxml cannot be build as shared. +# * -D_LARGEFILE_SOURCE and -D_FILE_OFFSET_BITS=64 (https://www.php.net/manual/en/intro.filesystem.php andypost) +# * -O2 optimize for apps usage (andypost) +_build() { + local common_flags="-D_LARGEFILE_SOURCE -D_FILE_OFFSET_BITS=64" + export CFLAGS="${CFLAGS/-Os/-O2} $common_flags" + export CXXFLAGS="${CXXFLAGS/-Os/-O2} $common_flags" + + local without_pcre_jit + [ "$CARCH" = "s390x" ] && without_pcre_jit="--without-pcre-jit" + + EXTENSION_DIR=$_extension_dir ./configure \ + --build=$CBUILD \ + --host=$CHOST \ + --prefix=/usr \ + --program-suffix=$_suffix \ + --libdir=$_libdir \ + --datadir=/usr/share/$pkgname \ + --sysconfdir=/etc/$pkgname \ + --localstatedir=/var \ + --with-layout=GNU \ + --with-pic \ + --with-config-file-path=/etc/$pkgname \ + --with-config-file-scan-dir=$_extension_confd \ + --disable-short-tags \ + \ + --enable-bcmath=shared \ + --with-bz2=shared \ + --enable-calendar=shared \ + --enable-ctype=shared \ + --with-curl=shared \ + --enable-dba=shared \ + --with-dbmaker=shared \ + --with-gdbm \ + --with-lmdb \ + --enable-dom=shared \ + --with-enchant=shared \ + --enable-exif=shared \ + --with-ffi=shared \ + --enable-fileinfo=shared \ + --enable-ftp=shared \ + --enable-gd=shared \ + --with-freetype \ + --with-jpeg \ + --with-webp \ + --with-xpm \ + --disable-gd-jis-conv \ + --with-gettext=shared \ + --with-gmp=shared \ + --with-iconv=shared \ + --with-imap=shared \ + --with-imap-ssl \ + --enable-intl=shared \ + --enable-json=shared \ + --with-ldap=shared \ + --with-ldap-sasl \ + --with-libedit \ + --with-libxml \ + --enable-mbstring=shared \ + --with-mysqli=shared,mysqlnd \ + --with-mysql-sock=/run/mysqld/mysqld.sock \ + --enable-mysqlnd=shared \ + --enable-opcache=shared \ + --with-openssl=shared \ + --with-kerberos \ + --with-system-ciphers \ + --with-password-argon2 \ + --enable-pcntl=shared \ + --with-external-pcre \ + $without_pcre_jit \ + --enable-pdo=shared \ + --with-pdo-dblib=shared \ + --with-pdo-mysql=shared,mysqlnd \ + --with-pdo-odbc=shared,unixODBC,/usr \ + --with-pdo-pgsql=shared \ + --with-pdo-sqlite=shared \ + --with-pgsql=shared \ + --enable-phar=shared \ + --enable-posix=shared \ + --with-pspell=shared \ + --without-readline \ + --enable-session=shared \ + --enable-shmop=shared \ + --enable-simplexml=shared \ + --with-snmp=shared \ + --enable-soap=shared \ + --with-sodium=shared \ + --enable-sockets=shared \ + --with-sqlite3=shared \ + --enable-sysvmsg=shared \ + --enable-sysvsem=shared \ + --enable-sysvshm=shared \ + --with-tidy=shared \ + --enable-tokenizer=shared \ + --with-unixODBC=shared,/usr \ + --enable-xml=shared \ + --enable-xmlreader=shared \ + --with-xmlrpc=shared \ + --enable-xmlwriter=shared \ + --with-xsl=shared \ + --with-zip=shared \ + --with-zlib \ + "$@" + make +} + +build() { + # apache2 SAPIs because not fixed https://bugs.php.net/bug.php?id=52419 + _build --disable-phpdbg \ + --disable-cli \ + --with-apxs2 + mv libs/libphp$_suffix.so sapi/apache2handler/mod_php$_suffix.so + + local enable_litespeed + [ -z ${subpackages##*-litespeed*} ] && enable_litespeed=--enable-litespeed + # cgi, cli, fpm, embed, pear, litespeed + _build --enable-phpdbg \ + --enable-phpdbg-webhelper \ + --with-pear=/usr/share/$pkgname \ + --enable-fpm \ + $enable_litespeed \ + --enable-embed +} + +check() { + # PHP is so stupid that it's not able to resolve dependencies + # between extensions and load them in correct order, so we must + # help it... + # opcache is Zend extension, it's handled specially in Makefile + local php_modules=$(_extensions_by_load_order \ + | grep -vx opcache \ + | xargs -n 1 printf "'$builddir/modules/%s.la' ") + sed -i "/^PHP_TEST_SHARED_EXTENSIONS/,/extension=/ \ + s|in \$(PHP_MODULES)\"*|in $php_modules|" Makefile + + # XXX: Few tests fail on the named platforms. + # Ignore it for now and continue build even on test failures. + local allow_fail='no' + case "$CARCH" in + x86 | s390x | mips*) allow_fail='yes' + esac + + TESTS="${TESTS:- --show-diff}" NO_INTERACTION=1 REPORT_EXIT_STATUS=1 \ + SKIP_SLOW_TESTS=1 SKIP_ONLINE_TESTS=1 TEST_TIMEOUT=10 \ + TZ='' LANG='' LC_ALL='' \ + TRAVIS=true SKIP_IO_CAPTURE_TESTS=1 \ + make test || [ "$allow_fail" = yes ] + + echo 'NOTE: We have skipped quite a lot tests, see disabled-tests.list.' +} + +package() { + make -j1 INSTALL_ROOT="$pkgdir" install + + install -Dm644 php.ini-production "$pkgdir"/etc/$pkgname/php.ini + + local file; for file in pear peardev pecl; do + sed -i -e "s|/usr/bin/php|/usr/bin/php$_suffix|g" \ + -e "s|PHP=php|PHP=php$_suffix|" \ + "$pkgdir"/usr/bin/$file + done + + find "$pkgdir" -name '.*' -print0 | xargs -0 rm -rf + rmdir "$pkgdir"/var/run + + if [ "$_default_php" = yes ]; then + ln -s php$_suffix "$pkgdir"/usr/bin/php + fi +} + +dev() { + default_dev + replaces="php-dev" + + cd "$pkgdir" + + _mv usr/bin/php-config$_suffix \ + usr/bin/phpize$_suffix \ + "$subpkgdir"/usr/bin/ + + _mv ./$_libdir/build "$subpkgdir"/$_libdir/ + + if [ "$_default_php" = yes ]; then + ln -s phpize$_suffix "$subpkgdir"/usr/bin/phpize + ln -s php-config$_suffix "$subpkgdir"/usr/bin/php-config + fi +} + +doc() { + default_doc + + cd "$builddir" + + mkdir -p "$subpkgdir"/usr/share/doc/$pkgname + cp CODING_STANDARDS.md EXTENSIONS LICENSE NEWS \ + README* UPGRADING* \ + "$subpkgdir"/usr/share/doc/$pkgname/ +} + +apache2() { + pkgdesc="PHP$_suffix Module for Apache2" + depends="$depends apache2" + provides="php-apache2" + + install -D -m 755 "$builddir"/sapi/apache2handler/mod_php$_suffix.so \ + "$subpkgdir"/usr/lib/apache2/mod_php$_suffix.so + + install -D -m 644 "$srcdir"/php$_suffix-module.conf \ + "$subpkgdir"/etc/apache2/conf.d/php$_suffix-module.conf +} + +phpdbg() { + pkgdesc="Interactive PHP$_suffix debugger" + provides="php-phpdbg" + + amove usr/bin/phpdbg$_suffix + + if [ "$_default_php" = yes ]; then + ln -s phpdbg$_suffix "$subpkgdir"/usr/bin/phpdbg + fi +} + +embed() { + pkgdesc="PHP$_suffix Embedded Library" + provides="php-embed" + + _mv "$pkgdir"/usr/lib/libphp*.so "$subpkgdir"/usr/lib/ +} + +litespeed() { + pkgdesc="PHP$_suffix LiteSpeed SAPI" + provides="php-lightspeed" + + mkdir -p "$subpkgdir"/usr/bin + mv "$pkgdir"/usr/bin/lsphp$_suffix "$subpkgdir"/usr/bin + + if [ "$_default_php" = yes ]; then + ln -s lsphp$_suffix "$subpkgdir"/usr/bin/lsphp + fi +} + +cgi() { + pkgdesc="PHP$_suffix Common Gateway Interface" + provides="php-cgi" + + _mv "$pkgdir"/usr/bin/php-cgi$_suffix "$subpkgdir"/usr/bin/ + + if [ "$_default_php" = yes ]; then + ln -s php-cgi$_suffix "$subpkgdir"/usr/bin/php-cgi + fi +} + +fpm() { + pkgdesc="PHP$_suffix FastCGI Process Manager" + provides="php-fpm" + + cd "$pkgdir" + + _mv var "$subpkgdir"/ + _mv usr/share/$pkgname/fpm "$subpkgdir"/var/lib/$pkgname/ + _mv usr/sbin "$subpkgdir"/usr/ + _mv etc/$pkgname/php-fpm* "$subpkgdir"/etc/$pkgname/ + + local file; for file in php-fpm.conf php-fpm.d/www.conf; do + mv "$subpkgdir"/etc/$pkgname/$file.default \ + "$subpkgdir"/etc/$pkgname/$file + done + + install -D -m 755 "$srcdir"/$pkgname-fpm.initd \ + "$subpkgdir"/etc/init.d/php-fpm$_suffix + + install -D -m 644 "$srcdir"/$pkgname-fpm.logrotate \ + "$subpkgdir"/etc/logrotate.d/php-fpm$_suffix + + mkdir -p "$subpkgdir"/var/log/$pkgname +} + +pear() { + pkgdesc="PHP$_suffix Extension and Application Repository" + depends="$pkgname $pkgname-xml" + provides="php-pear" + + cd "$pkgdir" + + mkdir -p "$subpkgdir"/usr/bin + local file; for file in pecl pear peardev; do + mv usr/bin/$file "$subpkgdir"/usr/bin/$file$_suffix + if [ "$_default_php" = yes ]; then + ln -s $file$_suffix "$subpkgdir"/usr/bin/$file + fi + done + + _mv etc/$pkgname/pear.conf "$subpkgdir"/etc/$pkgname/ + _mv usr/share "$subpkgdir"/usr/ +} + +common() { + pkgdesc="$pkgdesc (common config)" + provides="php-common $pkgname-zlib php-zlib" # for backward compatibility + depends="" + + cd "$pkgdir" + + _mv usr/lib "$subpkgdir"/usr/ + _mv etc "$subpkgdir"/ + mkdir -p "$subpkgdir"/$_extension_confd +} + +phar() { + _extension + + cd "$pkgdir" + + mkdir -p "$subpkgdir"/usr/bin + rm usr/bin/phar$_suffix + mv usr/bin/phar$_suffix.phar "$subpkgdir"/usr/bin/phar$_suffix.phar + ln -s phar$_suffix.phar "$subpkgdir"/usr/bin/phar$_suffix + ln -s phar$_suffix.phar "$subpkgdir"/usr/bin/phar.phar$_suffix + + if [ "$_default_php" = yes ]; then + ln -s phar$_suffix.phar "$subpkgdir"/usr/bin/phar.phar + ln -s phar$_suffix.phar "$subpkgdir"/usr/bin/phar + fi +} + +_extension() { + local extname="${subpkgname#$pkgname-}" + local extdepends="$(eval "echo \$_depends_$extname")" + local extdesc="$(head -n1 "$builddir"/ext/$extname/CREDITS 2>/dev/null ||:)" + pkgdesc="PHP$_suffix extension: ${extdesc:-$extname}" + provides="php-$extname" + + : ${extdepends:=$(_resolve_extension_deps "$extname")} + depends="$depends $extdepends" + + local load_order=$(_extension_load_order "$extname") + + # extension prefix + local prefix= + [ "$extname" != "opcache" ] || prefix="zend_" + + _mv "$pkgdir"/$_extension_dir/$extname.so \ + "$subpkgdir"/$_extension_dir/ + + mkdir -p "$subpkgdir"/$_extension_confd + echo "${prefix}extension=$extname.so" \ + > "$subpkgdir"/$_extension_confd/"$(printf %02d $load_order)"_$extname.ini +} + +# Resolves dependencies of the given extension name (without $pkgname- prefix) +# on other extensions in $_extensions and prints them with $pkgname- prefix. +_resolve_extension_deps() { + local name="$1" + + # We use config.w32 just because it's more accurate than config.m4. + local config="$builddir/ext/$name/config.w32" + [ -f "$config" ] || return 0 + + cat "$config" \ + | sed -En "s/.*ADD_EXTENSION_DEP\('$name', ([^)]+)\).*/\1/p" \ + | tr -d "'," | tr ' ' '\n' \ + | sort -u \ + | while read -r dep; do + if echo "$_extensions" | grep -qw "$dep"; then + echo "$pkgname-$dep" + fi + done +} + +# Prints a load order (0-based integer) for the given extension name. Extension +# with lower load order should be loaded before exts with higher load order. +# It's based on number of dependencies of the extension (with exception for +# "imap"), which is flawed, but simple and good enough for now. +_extension_load_order() { + local name="$1" + local deps=$(eval "echo \$_depends_$name") + + case "$name" in + # XXX: This must be loaded after recode, even though it does + # not depend on it. So we must use this hack... + *) echo "${deps:=$(_resolve_extension_deps $name)}" | wc -w;; + esac +} + +# Prints $_extensions sorted by load order and name. +_extensions_by_load_order() { + local deps list name + + for name in $_extensions; do + list="$list $(_extension_load_order $name);$name" + done + printf '%s\n' $list | sort -t ';' -k 1 | sed -E 's/\d+;//' +} + +_mv() { + local dest; for dest; do true; done # get last argument + mkdir -p "$dest" + mv "$@" +} + +sha512sums=" +499b63b99e5d8e8082ff89d3a91b4cb9a593ea7553b96e48863414c13d2e50275904ed29070e2232e529ee91160f505e6060a4d129cb5bf098aa5b6ea0928d3d php-7.4.33.tar.xz +1c708de82d1086f272f484faf6cf6d087af7c31750cc2550b0b94ed723961b363f28a947b015b2dfc0765caea185a75f5d2c2f2b099c948b65c290924f606e4f php7-fpm.initd +cacce7bf789467ff40647b7319e3760c6c587218720538516e8d400baa75651f72165c4e28056cd0c1dc89efecb4d00d0d7823bed80b29136262c825ce816691 php7-fpm.logrotate +274bd7b0b2b7002fa84c779640af37b59258bb37b05cb7dd5c89452977d71807f628d91b523b5039608376d1f760f3425d165242ca75ee5129b2730e71c4e198 php7-module.conf +cfc219aef8b3da67ceb66cd4af01eb8f273342d8bd638013adec9408cc516c73a49f5f32fcca0e6e39fc5fa04643046ff75ce0c217be9795786528eebf07e11f disabled-tests.list +a4130d29c7fee2b8cb561b116baf603bdc3a7b5b4985ec3c9918f253d1851197539dfad72c6b36d9f7008f85982904731184c79e4cee4415c1a1b88016639225 install-pear.patch +ebf571c5e595221b9944d7e840807ebb68c1be38bf117186e19a3bd1070310ece5918bcaa5f941679f3371a2108ad57bf179c3f90e612a5a2b982db941172859 includedir.patch +965b52893affb666af64e00d09e0208dcd41b17ce2864cf05616c6d05a05c0121694c0b209d403b8c0c55d18e6f1528c4aba1a4fcdce7b282a13304d12cd0f9d sharedir.patch +16399fbf6a966f9beffe00f659f9551ef8e52285bca116da5bd5b15ec99a2b0bd5fa03be0faa6c893802aa44c100d634083343a9ac0cd2467812865df66dd572 php7-fpm-version-suffix.patch +3bfeea79f9acfaa7be5bab85cd3d02713abb569e54024a22bb2c747c06d97f83ac2c63dcd75c7c409426ac03f8bc2ccc01bcd66bc39a767930d32542349123f9 fix-tests-devserver.patch +7c8c3cac9efce81d525cb5a70e1402e393881b83ef4c7b5d39d3565803d21cd283daf3d74e9a8b059ecac66cf339756acc63608ffcb83d960dba86583bd45108 enchant-2.patch +996b9a542858b0385a300265194afc57eddb72b9d7e4dcdf63b4f1ba7d3588e67309030acc73f00af1717168becd50b1d3582fcb88605e9892fd683a33cae023 xfail-openssl-1.1-test.patch +8dd578f264edaf372a6e787d65e2f8d45ea1af88036cc0d62251b6796aef327b8bd0a4df90eecdbd9e8a8c0e7501f90813a3af745e262151b7f7fe995c7a8c1b CVE-2023-0567-1.patch +35c9c4bdc8b4091d68ad65732c016dd33a0e3e92b3669dfbda7a107ca7c22d72955fecd73add0338873faf8344721838d72c0aa637fefdb6cdae7a1d310d570b CVE-2023-0567-2.patch +5fe3a0e9e1cf2e069d3b97c74a12d6f1c05faf694be7527a40a358afc1ee2dd6004f6ce0027c483eda7f6e835dc384258760b098c03d2af04950b58ac0e83cc8 CVE-2023-0568.patch +f7e87369658e333247896cb3cc6d56a54e2041453c0dc78180d7d31ac5008f98837039c215beda24e12b78ac183d70b7488e3d2978b159e565fc6517ed023cb1 CVE-2023-0662-1.patch +22c8f8b31b76832a0ccd45e0df808ba07e2cab67c7e6ca94d5cc124ad185fd0494a11ed1573b4ac03094c21979de40ecb4ee76cf8e63cd27f716aff189e9b28d CVE-2023-0662-2.patch +81fe1bc37129c8902c572d63f9c4c266cabf61c1217d8b079b020dd60ad49e725426dc201b4c0d044d8a6793b15a2a58eac6595ceb1f8a91aa9b2ea9728adfd6 fix-fpm-tests.patch +5582cbf13dcc9c536c6a9881183fedd40d35497c527e20e9e8e3288ce6219d9218dd16d9f43cc4412fd471b84df786076141f8409f950578b50d1540244f29f2 fix-fpm-syntax.patch +be6a57063414bd255def54d5f6e42cbdc3baec55c8eaf9c8ca6e96d0cb3fec942ebb1868806850859d34c5c45d03a2abfec3fecd1aef04524da8eda01d9041ed fix-curl-7.83-test.patch +1f73855623c03ce6202610500989a6f08eb3a7cd4a80d007fd078644b142b8e51aab28fefab876c03c935f112c7162d696d42cb983961f6cb6c3c4586513bb49 CVE-2026-109618-109619.patch +4e077c3818e395eed735d450971c5bde250fecbf32c258c3e7b56c54cb7e59350e211b48ea2ac870f15eefc8b860e5aa7d824b12d2e9ab7333fe6231e17e55d7 CVE-2026-109618-109619-tests.patch +" diff --git a/7.4/aports/community/php7/CVE-2023-0567-1.patch b/7.4/aports/community/php7/CVE-2023-0567-1.patch new file mode 100644 index 0000000..2863840 --- /dev/null +++ b/7.4/aports/community/php7/CVE-2023-0567-1.patch @@ -0,0 +1,144 @@ +Patch-Source: https://github.com/php/php-src/commit/c840f71524067aa474c00c3eacfb83bd860bfc8a + +From c840f71524067aa474c00c3eacfb83bd860bfc8a Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Tim=20D=C3=BCsterhus?= +Date: Mon, 23 Jan 2023 21:15:24 +0100 +Subject: [PATCH] crypt: Fix validation of malformed BCrypt hashes +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +PHP’s implementation of crypt_blowfish differs from the upstream Openwall +version by adding a “PHP Hack”, which allows one to cut short the BCrypt salt +by including a `$` character within the characters that represent the salt. + +Hashes that are affected by the “PHP Hack” may erroneously validate any +password as valid when used with `password_verify` and when comparing the +return value of `crypt()` against the input. + +The PHP Hack exists since the first version of PHP’s own crypt_blowfish +implementation that was added in 1e820eca02dcf322b41fd2fe4ed2a6b8309f8ab5. + +No clear reason is given for the PHP Hack’s existence. This commit removes it, +because BCrypt hashes containing a `$` character in their salt are not valid +BCrypt hashes. +--- + ext/standard/crypt_blowfish.c | 8 -- + .../tests/crypt/bcrypt_salt_dollar.phpt | 82 +++++++++++++++++++ + 2 files changed, 82 insertions(+), 8 deletions(-) + create mode 100644 ext/standard/tests/crypt/bcrypt_salt_dollar.phpt + +diff --git a/ext/standard/crypt_blowfish.c b/ext/standard/crypt_blowfish.c +index 3806a290aee4..351d40308089 100644 +--- a/ext/standard/crypt_blowfish.c ++++ b/ext/standard/crypt_blowfish.c +@@ -371,7 +371,6 @@ static const unsigned char BF_atoi64[0x60] = { + #define BF_safe_atoi64(dst, src) \ + { \ + tmp = (unsigned char)(src); \ +- if (tmp == '$') break; /* PHP hack */ \ + if ((unsigned int)(tmp -= 0x20) >= 0x60) return -1; \ + tmp = BF_atoi64[tmp]; \ + if (tmp > 63) return -1; \ +@@ -399,13 +398,6 @@ static int BF_decode(BF_word *dst, const char *src, int size) + *dptr++ = ((c3 & 0x03) << 6) | c4; + } while (dptr < end); + +- if (end - dptr == size) { +- return -1; +- } +- +- while (dptr < end) /* PHP hack */ +- *dptr++ = 0; +- + return 0; + } + +diff --git a/ext/standard/tests/crypt/bcrypt_salt_dollar.phpt b/ext/standard/tests/crypt/bcrypt_salt_dollar.phpt +new file mode 100644 +index 000000000000..32e335f4b087 +--- /dev/null ++++ b/ext/standard/tests/crypt/bcrypt_salt_dollar.phpt +@@ -0,0 +1,82 @@ ++--TEST-- ++bcrypt correctly rejects salts containing $ ++--FILE-- ++ ++--EXPECT-- ++string(8) "$2y$04$$" ++string(1) "*" ++bool(false) ++string(9) "$2y$04$0$" ++string(1) "*" ++bool(false) ++string(10) "$2y$04$00$" ++string(1) "*" ++bool(false) ++string(11) "$2y$04$000$" ++string(1) "*" ++bool(false) ++string(12) "$2y$04$0000$" ++string(1) "*" ++bool(false) ++string(13) "$2y$04$00000$" ++string(1) "*" ++bool(false) ++string(14) "$2y$04$000000$" ++string(1) "*" ++bool(false) ++string(15) "$2y$04$0000000$" ++string(1) "*" ++bool(false) ++string(16) "$2y$04$00000000$" ++string(1) "*" ++bool(false) ++string(17) "$2y$04$000000000$" ++string(1) "*" ++bool(false) ++string(18) "$2y$04$0000000000$" ++string(1) "*" ++bool(false) ++string(19) "$2y$04$00000000000$" ++string(1) "*" ++bool(false) ++string(20) "$2y$04$000000000000$" ++string(1) "*" ++bool(false) ++string(21) "$2y$04$0000000000000$" ++string(1) "*" ++bool(false) ++string(22) "$2y$04$00000000000000$" ++string(1) "*" ++bool(false) ++string(23) "$2y$04$000000000000000$" ++string(1) "*" ++bool(false) ++string(24) "$2y$04$0000000000000000$" ++string(1) "*" ++bool(false) ++string(25) "$2y$04$00000000000000000$" ++string(1) "*" ++bool(false) ++string(26) "$2y$04$000000000000000000$" ++string(1) "*" ++bool(false) ++string(27) "$2y$04$0000000000000000000$" ++string(1) "*" ++bool(false) ++string(28) "$2y$04$00000000000000000000$" ++string(1) "*" ++bool(false) ++string(29) "$2y$04$000000000000000000000$" ++string(1) "*" ++bool(false) ++string(30) "$2y$04$0000000000000000000000$" ++string(60) "$2y$04$000000000000000000000u2a2UpVexIt9k3FMJeAVr3c04F5tcI8K" ++bool(false) diff --git a/7.4/aports/community/php7/CVE-2023-0567-2.patch b/7.4/aports/community/php7/CVE-2023-0567-2.patch new file mode 100644 index 0000000..9141a9a --- /dev/null +++ b/7.4/aports/community/php7/CVE-2023-0567-2.patch @@ -0,0 +1,39 @@ +Patch-Source: https://github.com/php/php-src/commit/a92acbad873a05470af1a47cb785a18eadd827b5 + +From a92acbad873a05470af1a47cb785a18eadd827b5 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Tim=20D=C3=BCsterhus?= +Date: Mon, 23 Jan 2023 22:13:57 +0100 +Subject: [PATCH] crypt: Fix possible buffer overread in php_crypt() + +--- + ext/standard/crypt.c | 1 + + ext/standard/tests/password/password_bcrypt_short.phpt | 8 ++++++++ + 2 files changed, 9 insertions(+) + create mode 100644 ext/standard/tests/password/password_bcrypt_short.phpt + +diff --git a/ext/standard/crypt.c b/ext/standard/crypt.c +index 8c105cf910e8..8316c8b96063 100644 +--- a/ext/standard/crypt.c ++++ b/ext/standard/crypt.c +@@ -135,6 +135,7 @@ PHPAPI zend_string *php_crypt(const char *password, const int pass_len, const ch + } else if ( + salt[0] == '$' && + salt[1] == '2' && ++ salt[2] != 0 && + salt[3] == '$') { + char output[PHP_MAX_SALT_LEN + 1]; + +diff --git a/ext/standard/tests/password/password_bcrypt_short.phpt b/ext/standard/tests/password/password_bcrypt_short.phpt +new file mode 100644 +index 000000000000..085bc8a23904 +--- /dev/null ++++ b/ext/standard/tests/password/password_bcrypt_short.phpt +@@ -0,0 +1,8 @@ ++--TEST-- ++Test that password_hash() does not overread buffers when a short hash is passed ++--FILE-- ++ ++--EXPECT-- ++bool(false) diff --git a/7.4/aports/community/php7/CVE-2023-0568.patch b/7.4/aports/community/php7/CVE-2023-0568.patch new file mode 100644 index 0000000..510fb6d --- /dev/null +++ b/7.4/aports/community/php7/CVE-2023-0568.patch @@ -0,0 +1,64 @@ +Patch-Source: https://github.com/php/php-src/commit/ec10b28d64decbc54aa1e585dce580f0bd7a5953 + +From ec10b28d64decbc54aa1e585dce580f0bd7a5953 Mon Sep 17 00:00:00 2001 +From: Niels Dossche <7771979+nielsdos@users.noreply.github.com> +Date: Fri, 27 Jan 2023 19:28:27 +0100 +Subject: [PATCH] Fix array overrun when appending slash to paths + +Fix it by extending the array sizes by one character. As the input is +limited to the maximum path length, there will always be place to append +the slash. As the php_check_specific_open_basedir() simply uses the +strings to compare against each other, no new failures related to too +long paths are introduced. +We'll let the DOM and XML case handle a potentially too long path in the +library code. +--- + ext/dom/document.c | 2 +- + ext/xmlreader/php_xmlreader.c | 2 +- + main/fopen_wrappers.c | 6 +++--- + 3 files changed, 5 insertions(+), 5 deletions(-) + +diff --git a/ext/dom/document.c b/ext/dom/document.c +index dbbabb8bffde..fa6a6377ad5c 100644 +--- a/ext/dom/document.c ++++ b/ext/dom/document.c +@@ -1174,7 +1174,7 @@ static xmlDocPtr dom_document_parser(zval *id, int mode, char *source, size_t so + int validate, recover, resolve_externals, keep_blanks, substitute_ent; + int resolved_path_len; + int old_error_reporting = 0; +- char *directory=NULL, resolved_path[MAXPATHLEN]; ++ char *directory=NULL, resolved_path[MAXPATHLEN + 1]; + + if (id != NULL) { + intern = Z_DOMOBJ_P(id); +diff --git a/ext/xmlreader/php_xmlreader.c b/ext/xmlreader/php_xmlreader.c +index ecc52aa1d6f4..d8f8105010c7 100644 +--- a/ext/xmlreader/php_xmlreader.c ++++ b/ext/xmlreader/php_xmlreader.c +@@ -1024,7 +1024,7 @@ PHP_METHOD(XMLReader, XML) + xmlreader_object *intern = NULL; + char *source, *uri = NULL, *encoding = NULL; + int resolved_path_len, ret = 0; +- char *directory=NULL, resolved_path[MAXPATHLEN]; ++ char *directory=NULL, resolved_path[MAXPATHLEN + 1]; + xmlParserInputBufferPtr inputbfr; + xmlTextReaderPtr reader; + +diff --git a/main/fopen_wrappers.c b/main/fopen_wrappers.c +index 39a9c82d5984..5e4a619c8fe7 100644 +--- a/main/fopen_wrappers.c ++++ b/main/fopen_wrappers.c +@@ -129,10 +129,10 @@ PHPAPI ZEND_INI_MH(OnUpdateBaseDir) + */ + PHPAPI int php_check_specific_open_basedir(const char *basedir, const char *path) + { +- char resolved_name[MAXPATHLEN]; +- char resolved_basedir[MAXPATHLEN]; ++ char resolved_name[MAXPATHLEN + 1]; ++ char resolved_basedir[MAXPATHLEN + 1]; + char local_open_basedir[MAXPATHLEN]; +- char path_tmp[MAXPATHLEN]; ++ char path_tmp[MAXPATHLEN + 1]; + char *path_file; + size_t resolved_basedir_len; + size_t resolved_name_len; diff --git a/7.4/aports/community/php7/CVE-2023-0662-1.patch b/7.4/aports/community/php7/CVE-2023-0662-1.patch new file mode 100644 index 0000000..df7cf26 --- /dev/null +++ b/7.4/aports/community/php7/CVE-2023-0662-1.patch @@ -0,0 +1,27 @@ +Patch-Source: https://github.com/php/php-src/commit/e45850c195dcd5534394cf357a3f776d4916b655 + +From e45850c195dcd5534394cf357a3f776d4916b655 Mon Sep 17 00:00:00 2001 +From: Jakub Zelenka +Date: Thu, 19 Jan 2023 14:11:18 +0000 +Subject: [PATCH] Fix repeated warning for file uploads limit exceeding + +--- + main/rfc1867.c | 5 ++++- + 1 file changed, 4 insertions(+), 1 deletion(-) + +diff --git a/main/rfc1867.c b/main/rfc1867.c +index c2f606c64aa1..b43cfae5a1e2 100644 +--- a/main/rfc1867.c ++++ b/main/rfc1867.c +@@ -911,7 +911,10 @@ SAPI_API SAPI_POST_HANDLER_FUNC(rfc1867_post_handler) /* {{{ */ + skip_upload = 1; + } else if (upload_cnt <= 0) { + skip_upload = 1; +- sapi_module.sapi_error(E_WARNING, "Maximum number of allowable file uploads has been exceeded"); ++ if (upload_cnt == 0) { ++ --upload_cnt; ++ sapi_module.sapi_error(E_WARNING, "Maximum number of allowable file uploads has been exceeded"); ++ } + } + + /* Return with an error if the posted data is garbled */ diff --git a/7.4/aports/community/php7/CVE-2023-0662-2.patch b/7.4/aports/community/php7/CVE-2023-0662-2.patch new file mode 100644 index 0000000..360f86d --- /dev/null +++ b/7.4/aports/community/php7/CVE-2023-0662-2.patch @@ -0,0 +1,413 @@ +Patch-Source: https://github.com/php/php-src/commit/716de0cff539f46294ef70fe75d548cd66766370 + +From 716de0cff539f46294ef70fe75d548cd66766370 Mon Sep 17 00:00:00 2001 +From: Jakub Zelenka +Date: Thu, 19 Jan 2023 14:31:25 +0000 +Subject: [PATCH] Introduce max_multipart_body_parts INI + +This fixes GHSA-54hq-v5wp-fqgv DOS vulnerabality by limitting number of +parsed multipart body parts as currently all parts were always parsed. +--- + main/main.c | 1 + + main/rfc1867.c | 11 ++ + ...-54hq-v5wp-fqgv-max-body-parts-custom.phpt | 53 +++++++++ + ...54hq-v5wp-fqgv-max-body-parts-default.phpt | 54 +++++++++ + .../ghsa-54hq-v5wp-fqgv-max-file-uploads.phpt | 52 +++++++++ + sapi/fpm/tests/tester.inc | 106 +++++++++++++++--- + 6 files changed, 262 insertions(+), 15 deletions(-) + create mode 100644 sapi/fpm/tests/ghsa-54hq-v5wp-fqgv-max-body-parts-custom.phpt + create mode 100644 sapi/fpm/tests/ghsa-54hq-v5wp-fqgv-max-body-parts-default.phpt + create mode 100644 sapi/fpm/tests/ghsa-54hq-v5wp-fqgv-max-file-uploads.phpt + +diff --git a/main/main.c b/main/main.c +index 40684f32dc14..c58ea58bf5ac 100644 +--- a/main/main.c ++++ b/main/main.c +@@ -751,6 +751,7 @@ PHP_INI_BEGIN() + PHP_INI_ENTRY("disable_functions", "", PHP_INI_SYSTEM, NULL) + PHP_INI_ENTRY("disable_classes", "", PHP_INI_SYSTEM, NULL) + PHP_INI_ENTRY("max_file_uploads", "20", PHP_INI_SYSTEM|PHP_INI_PERDIR, NULL) ++ PHP_INI_ENTRY("max_multipart_body_parts", "-1", PHP_INI_SYSTEM|PHP_INI_PERDIR, NULL) + + STD_PHP_INI_BOOLEAN("allow_url_fopen", "1", PHP_INI_SYSTEM, OnUpdateBool, allow_url_fopen, php_core_globals, core_globals) + STD_PHP_INI_BOOLEAN("allow_url_include", "0", PHP_INI_SYSTEM, OnUpdateBool, allow_url_include, php_core_globals, core_globals) +diff --git a/main/rfc1867.c b/main/rfc1867.c +index b43cfae5a1e2..3086e8da3dbe 100644 +--- a/main/rfc1867.c ++++ b/main/rfc1867.c +@@ -687,6 +687,7 @@ SAPI_API SAPI_POST_HANDLER_FUNC(rfc1867_post_handler) /* {{{ */ + void *event_extra_data = NULL; + unsigned int llen = 0; + int upload_cnt = INI_INT("max_file_uploads"); ++ int body_parts_cnt = INI_INT("max_multipart_body_parts"); + const zend_encoding *internal_encoding = zend_multibyte_get_internal_encoding(); + php_rfc1867_getword_t getword; + php_rfc1867_getword_conf_t getword_conf; +@@ -708,6 +709,11 @@ SAPI_API SAPI_POST_HANDLER_FUNC(rfc1867_post_handler) /* {{{ */ + return; + } + ++ if (body_parts_cnt < 0) { ++ body_parts_cnt = PG(max_input_vars) + upload_cnt; ++ } ++ int body_parts_limit = body_parts_cnt; ++ + /* Get the boundary */ + boundary = strstr(content_type_dup, "boundary"); + if (!boundary) { +@@ -792,6 +798,11 @@ SAPI_API SAPI_POST_HANDLER_FUNC(rfc1867_post_handler) /* {{{ */ + char *pair = NULL; + int end = 0; + ++ if (--body_parts_cnt < 0) { ++ php_error_docref(NULL, E_WARNING, "Multipart body parts limit exceeded %d. To increase the limit change max_multipart_body_parts in php.ini.", body_parts_limit); ++ goto fileupload_done; ++ } ++ + while (isspace(*cd)) { + ++cd; + } +diff --git a/sapi/fpm/tests/ghsa-54hq-v5wp-fqgv-max-body-parts-custom.phpt b/sapi/fpm/tests/ghsa-54hq-v5wp-fqgv-max-body-parts-custom.phpt +new file mode 100644 +index 000000000000..d2239ac3c410 +--- /dev/null ++++ b/sapi/fpm/tests/ghsa-54hq-v5wp-fqgv-max-body-parts-custom.phpt +@@ -0,0 +1,53 @@ ++--TEST-- ++FPM: GHSA-54hq-v5wp-fqgv - max_multipart_body_parts ini custom value ++--SKIPIF-- ++ ++--FILE-- ++start(); ++$tester->expectLogStartNotices(); ++echo $tester ++ ->request(stdin: [ ++ 'parts' => [ ++ 'count' => 30, ++ ] ++ ]) ++ ->getBody(); ++$tester->terminate(); ++$tester->close(); ++ ++?> ++--EXPECT-- ++Warning: Unknown: Multipart body parts limit exceeded 10. To increase the limit change max_multipart_body_parts in php.ini. in Unknown on line 0 ++int(10) ++--CLEAN-- ++ +diff --git a/sapi/fpm/tests/ghsa-54hq-v5wp-fqgv-max-body-parts-default.phpt b/sapi/fpm/tests/ghsa-54hq-v5wp-fqgv-max-body-parts-default.phpt +new file mode 100644 +index 000000000000..42b5afbf9ee7 +--- /dev/null ++++ b/sapi/fpm/tests/ghsa-54hq-v5wp-fqgv-max-body-parts-default.phpt +@@ -0,0 +1,54 @@ ++--TEST-- ++FPM: GHSA-54hq-v5wp-fqgv - max_multipart_body_parts ini default ++--SKIPIF-- ++ ++--FILE-- ++start(); ++$tester->expectLogStartNotices(); ++echo $tester ++ ->request(stdin: [ ++ 'parts' => [ ++ 'count' => 30, ++ ] ++ ]) ++ ->getBody(); ++$tester->terminate(); ++$tester->close(); ++ ++?> ++--EXPECT-- ++Warning: Unknown: Input variables exceeded 20. To increase the limit change max_input_vars in php.ini. in Unknown on line 0 ++ ++Warning: Unknown: Multipart body parts limit exceeded 25. To increase the limit change max_multipart_body_parts in php.ini. in Unknown on line 0 ++int(20) ++--CLEAN-- ++ +diff --git a/sapi/fpm/tests/ghsa-54hq-v5wp-fqgv-max-file-uploads.phpt b/sapi/fpm/tests/ghsa-54hq-v5wp-fqgv-max-file-uploads.phpt +new file mode 100644 +index 000000000000..da81174c7280 +--- /dev/null ++++ b/sapi/fpm/tests/ghsa-54hq-v5wp-fqgv-max-file-uploads.phpt +@@ -0,0 +1,52 @@ ++--TEST-- ++FPM: GHSA-54hq-v5wp-fqgv - exceeding max_file_uploads ++--SKIPIF-- ++ ++--FILE-- ++start(); ++$tester->expectLogStartNotices(); ++echo $tester ++ ->request(stdin: [ ++ 'parts' => [ ++ 'count' => 10, ++ 'param' => 'filename' ++ ] ++ ]) ++ ->getBody(); ++$tester->terminate(); ++$tester->close(); ++ ++?> ++--EXPECT-- ++Warning: Maximum number of allowable file uploads has been exceeded in Unknown on line 0 ++int(5) ++--CLEAN-- ++ +diff --git a/sapi/fpm/tests/tester.inc b/sapi/fpm/tests/tester.inc +index 6197cdba53f5..e51aa0f69143 100644 +--- a/sapi/fpm/tests/tester.inc ++++ b/sapi/fpm/tests/tester.inc +@@ -527,16 +527,16 @@ + * @param string $query + * @param array $headers + * @param string|null $uri +- * @param string|null $address +- * @param string|null $successMessage +- * @param string|null $errorMessage +- * @param bool $connKeepAlive ++ * @param string|null $scriptFilename ++ * @param string|null $stdin + * @return array + */ + private function getRequestParams( + string $query = '', + array $headers = [], +- string $uri = null ++ string $uri = null, ++ string $scriptFilename = null, ++ string $stdin = null + ) { + if (is_null($uri)) { + $uri = $this->makeSourceFile(); +@@ -545,8 +545,8 @@ + $params = array_merge( + [ + 'GATEWAY_INTERFACE' => 'FastCGI/1.0', +- 'REQUEST_METHOD' => 'GET', +- 'SCRIPT_FILENAME' => $uri, ++ 'REQUEST_METHOD' => is_null($stdin) ? 'GET' : 'POST', ++ 'SCRIPT_FILENAME' => $scriptFilename ?: $uri, + 'SCRIPT_NAME' => $uri, + 'QUERY_STRING' => $query, + 'REQUEST_URI' => $uri . ($query ? '?'.$query : ""), +@@ -560,7 +560,7 @@ + 'SERVER_PROTOCOL' => 'HTTP/1.1', + 'DOCUMENT_ROOT' => __DIR__, + 'CONTENT_TYPE' => '', +- 'CONTENT_LENGTH' => 0 ++ 'CONTENT_LENGTH' => strlen($stdin ?? "") // Default to 0 + ], + $headers + ); +@@ -571,16 +571,85 @@ + } + + /** +- * Execute request. ++ * Parse stdin and generate data for multipart config. + * +- * @param string $query ++ * @param array $stdin + * @param array $headers +- * @param string|null $uri +- * @param string|null $address +- * @param string|null $successMessage +- * @param string|null $errorMessage +- * @param bool $connKeepAlive ++ * ++ * @return void ++ * @throws \Exception ++ */ ++ private function parseStdin(array $stdin, array &$headers) ++ { ++ $parts = $stdin['parts'] ?? null; ++ if (empty($parts)) { ++ throw new \Exception('The stdin array needs to contain parts'); ++ } ++ $boundary = $stdin['boundary'] ?? 'AaB03x'; ++ if ( ! isset($headers['CONTENT_TYPE'])) { ++ $headers['CONTENT_TYPE'] = 'multipart/form-data; boundary=' . $boundary; ++ } ++ $count = $parts['count'] ?? null; ++ if ( ! is_null($count)) { ++ $dispositionType = $parts['disposition'] ?? 'form-data'; ++ $dispositionParam = $parts['param'] ?? 'name'; ++ $namePrefix = $parts['prefix'] ?? 'f'; ++ $nameSuffix = $parts['suffix'] ?? ''; ++ $value = $parts['value'] ?? 'test'; ++ $parts = []; ++ for ($i = 0; $i < $count; $i++) { ++ $parts[] = [ ++ 'disposition' => $dispositionType, ++ 'param' => $dispositionParam, ++ 'name' => "$namePrefix$i$nameSuffix", ++ 'value' => $value ++ ]; ++ } ++ } ++ $out = ''; ++ $nl = "\r\n"; ++ foreach ($parts as $part) { ++ if (!is_array($part)) { ++ $part = ['name' => $part]; ++ } elseif ( ! isset($part['name'])) { ++ throw new \Exception('Each part has to have a name'); ++ } ++ $name = $part['name']; ++ $dispositionType = $part['disposition'] ?? 'form-data'; ++ $dispositionParam = $part['param'] ?? 'name'; ++ $value = $part['value'] ?? 'test'; ++ $partHeaders = $part['headers'] ?? []; ++ ++ $out .= "--$boundary$nl"; ++ $out .= "Content-disposition: $dispositionType; $dispositionParam=\"$name\"$nl"; ++ foreach ($partHeaders as $headerName => $headerValue) { ++ $out .= "$headerName: $headerValue$nl"; ++ } ++ $out .= $nl; ++ $out .= "$value$nl"; ++ } ++ $out .= "--$boundary--$nl"; ++ ++ return $out; ++ } ++ ++ /** ++ * Execute request. ++ * ++ * @param string $query ++ * @param array $headers ++ * @param string|null $uri ++ * @param string|null $address ++ * @param string|null $successMessage ++ * @param string|null $errorMessage ++ * @param bool $connKeepAlive ++ * @param string|null $scriptFilename = null ++ * @param string|array|null $stdin = null ++ * @param bool $expectError ++ * @param int $readLimit ++ * + * @return Response ++ * @throws \Exception + */ + public function request( + string $query = '', +@@ -589,17 +658,24 @@ + string $address = null, + string $successMessage = null, + string $errorMessage = null, +- bool $connKeepAlive = false ++ bool $connKeepAlive = false, ++ string $scriptFilename = null, ++ $stdin = null, ++ bool $expectError = false, ++ int $readLimit = -1 + ) { + if ($this->hasError()) { + return new Response(null, true); + } + +- $params = $this->getRequestParams($query, $headers, $uri); ++ if (is_array($stdin)) { ++ $stdin = $this->parseStdin($stdin, $headers); ++ } + ++ $params = $this->getRequestParams($query, $headers, $uri, $scriptFilename, $stdin); + try { + $this->response = new Response( +- $this->getClient($address, $connKeepAlive)->request_data($params, false) ++ $this->getClient($address, $connKeepAlive)->request_data($params, $stdin, $readLimit) + ); + $this->message($successMessage); + } catch (\Exception $exception) { diff --git a/7.4/aports/community/php7/CVE-2026-109618-109619-tests.patch b/7.4/aports/community/php7/CVE-2026-109618-109619-tests.patch new file mode 100644 index 0000000..0f66f08 --- /dev/null +++ b/7.4/aports/community/php7/CVE-2026-109618-109619-tests.patch @@ -0,0 +1,8 @@ +--- a/tests/lang/bug45392.phpt ++++ b/tests/lang/bug45392.phpt +@@ -20,4 +20,5 @@ + ?> + --EXPECTF-- + 2 ++ + Fatal error: Allowed memory size of %d bytes exhausted%s diff --git a/7.4/aports/community/php7/CVE-2026-109618-109619.patch b/7.4/aports/community/php7/CVE-2026-109618-109619.patch new file mode 100644 index 0000000..e6d2734 --- /dev/null +++ b/7.4/aports/community/php7/CVE-2026-109618-109619.patch @@ -0,0 +1,932 @@ +From 712e60f9edfd03f0960fc4fc3c2c375f42b90aa2 Mon Sep 17 00:00:00 2001 +From: Arnaud Le Blanc +Date: Sun, 18 Oct 2026 20:09:54 +0200 +Subject: [PATCH] Avoid state corruption via bailout + +Minimal mitigation for EOL version. + +Fix GHSA-w8hw-w9fx-j79w (CVE-2026-109618) +Fix GHSA-6wmf-4rv5-p3rp (CVE-2026-109619) + +Co-authored-by: Ilija Tovilo +--- + Zend/zend_API.h | 1 + + Zend/zend_alloc.c | 68 ++++++++++++++++++++--------- + Zend/zend_alloc.h | 2 + + Zend/zend_execute_API.c | 13 ++++++ + Zend/zend_hash.c | 13 ++++-- + Zend/zend_hash.h | 1 + + Zend/zend_llist.c | 2 + + Zend/zend_multiply.h | 4 +- + Zend/zend_strtod.c | 4 +- + Zend/zend_types.h | 26 +++++++----- + Zend/zend_vm_def.h | 11 ++++- + Zend/zend_vm_execute.h | 94 +++++++++++++++++++++++++++++++++++++---- + ext/session/session.c | 2 +- + main/SAPI.c | 5 +++ + main/main.c | 6 +++ + main/php_variables.c | 8 ++-- + main/rfc1867.c | 39 ++++++++++++++--- + 17 files changed, 240 insertions(+), 59 deletions(-) +diff --git a/Zend/zend_API.h b/Zend/zend_API.h +index 2a3b582902f3..26f7726bd8cc 100644 +--- a/Zend/zend_API.h ++++ b/Zend/zend_API.h +@@ -380,6 +380,7 @@ ZEND_API char *zend_get_type_by_const(int type); + + #define array_init(arg) ZVAL_ARR((arg), zend_new_array(0)) + #define array_init_size(arg, size) ZVAL_ARR((arg), zend_new_array(size)) ++#define array_init_singleton(arg) ZVAL_ARR((arg), zend_new_array_singleton()) + ZEND_API int object_init(zval *arg); + ZEND_API int object_init_ex(zval *arg, zend_class_entry *ce); + ZEND_API int object_and_properties_init(zval *arg, zend_class_entry *ce, HashTable *properties); +diff --git a/Zend/zend_alloc.c b/Zend/zend_alloc.c +index 3a33e5441c70..be9b975426be 100644 +--- a/Zend/zend_alloc.c ++++ b/Zend/zend_alloc.c +@@ -57,6 +57,7 @@ + #include "zend_operators.h" + #include "zend_multiply.h" + #include "zend_bitset.h" ++#include "zend_execute.h" + #include + + #ifdef HAVE_UNISTD_H +@@ -363,7 +364,42 @@ static ZEND_COLD ZEND_NORETURN void zend_mm_panic(const char *message) + #if ZEND_DEBUG && defined(HAVE_KILL) && defined(HAVE_GETPID) + kill(getpid(), SIGSEGV); + #endif +- exit(1); ++ _exit(1); ++} ++ ++ZEND_API ZEND_COLD ZEND_NORETURN void zend_mm_safe_error_ex(const char *format, ...) ++{ ++ zend_string *script_filename = NULL; ++ uint32_t script_lineno = 0; ++ ++ if (zend_is_executing()) { ++ script_filename = zend_get_executed_filename_ex(); ++ script_lineno = zend_get_executed_lineno(); ++ } else if (zend_is_compiling()) { ++ script_filename = zend_get_compiled_filename(); ++ script_lineno = zend_get_compiled_lineno(); ++ } ++ ++ va_list args; ++ va_start(args, format); ++ ++ char buf[1024]; ++ vsnprintf(buf, sizeof(buf), format, args); ++ ++ va_end(args); ++ ++ fprintf(stderr, ++ "\nFatal error: %s in %s on line %d\n", ++ buf, ++ script_filename ? ZSTR_VAL(script_filename) : "Unknown", ++ script_lineno); ++ ++ /* See http://support.microsoft.com/kb/190351 */ ++# ifdef ZEND_WIN32 ++ fflush(stderr); ++# endif ++ ++ _exit(1); + } + + static ZEND_COLD ZEND_NORETURN void zend_mm_safe_error(zend_mm_heap *heap, +@@ -375,22 +411,14 @@ static ZEND_COLD ZEND_NORETURN void zend_mm_safe_error(zend_mm_heap *heap, + #endif + size_t size) + { ++ (void) heap; + +- heap->overflow = 1; +- zend_try { +- zend_error_noreturn(E_ERROR, +- format, +- limit, ++ zend_mm_safe_error_ex(format, limit, + #if ZEND_DEBUG +- filename, +- lineno, ++ filename, ++ lineno, + #endif +- size); +- } zend_catch { +- } zend_end_try(); +- heap->overflow = 0; +- zend_bailout(); +- exit(1); ++ size); + } + + #ifdef _WIN32 +@@ -1318,7 +1346,7 @@ static zend_always_inline void *zend_mm_alloc_heap(zend_mm_heap *heap, size_t si + size = MAX(size, 1); + size = ZEND_MM_ALIGNED_SIZE(size) + ZEND_MM_ALIGNED_SIZE(sizeof(zend_mm_debug_info)); + if (UNEXPECTED(size < real_size)) { +- zend_error_noreturn(E_ERROR, "Possible integer overflow in memory allocation (%zu + %zu)", ZEND_MM_ALIGNED_SIZE(real_size), ZEND_MM_ALIGNED_SIZE(sizeof(zend_mm_debug_info))); ++ zend_mm_safe_error_ex("Possible integer overflow in memory allocation (%zu + %zu)", ZEND_MM_ALIGNED_SIZE(real_size), ZEND_MM_ALIGNED_SIZE(sizeof(zend_mm_debug_info))); + return NULL; + } + #endif +@@ -1762,7 +1790,7 @@ static void *zend_mm_alloc_huge(zend_mm_heap *heap, size_t size ZEND_FILE_LINE_D + void *ptr; + + if (UNEXPECTED(new_size < size)) { +- zend_error_noreturn(E_ERROR, "Possible integer overflow in memory allocation (%zu + %zu)", size, alignment); ++ zend_mm_safe_error_ex("Possible integer overflow in memory allocation (%zu + %zu)", size, alignment); + } + + #if ZEND_MM_LIMIT +@@ -2617,7 +2645,7 @@ ZEND_API char* ZEND_FASTCALL _estrdup(const char *s ZEND_FILE_LINE_DC ZEND_FILE_ + + length = strlen(s); + if (UNEXPECTED(length + 1 == 0)) { +- zend_error_noreturn(E_ERROR, "Possible integer overflow in memory allocation (1 * %zu + 1)", length); ++ zend_mm_safe_error_ex("Possible integer overflow in memory allocation (1 * %zu + 1)", length); + } + p = (char *) _emalloc(length + 1 ZEND_FILE_LINE_RELAY_CC ZEND_FILE_LINE_ORIG_RELAY_CC); + memcpy(p, s, length+1); +@@ -2629,7 +2657,7 @@ ZEND_API char* ZEND_FASTCALL _estrndup(const char *s, size_t length ZEND_FILE_LI + char *p; + + if (UNEXPECTED(length + 1 == 0)) { +- zend_error_noreturn(E_ERROR, "Possible integer overflow in memory allocation (1 * %zu + 1)", length); ++ zend_mm_safe_error_ex("Possible integer overflow in memory allocation (1 * %zu + 1)", length); + } + p = (char *) _emalloc(length + 1 ZEND_FILE_LINE_RELAY_CC ZEND_FILE_LINE_ORIG_RELAY_CC); + memcpy(p, s, length); +@@ -2643,7 +2671,7 @@ ZEND_API char* ZEND_FASTCALL zend_strndup(const char *s, size_t length) + char *p; + + if (UNEXPECTED(length + 1 == 0)) { +- zend_error_noreturn(E_ERROR, "Possible integer overflow in memory allocation (1 * %zu + 1)", length); ++ zend_mm_safe_error_ex("Possible integer overflow in memory allocation (1 * %zu + 1)", length); + } + p = (char *) malloc(length + 1); + if (UNEXPECTED(p == NULL)) { +@@ -2974,7 +3002,7 @@ ZEND_API zend_mm_heap *zend_mm_startup_ex(const zend_mm_handlers *handlers, void + static ZEND_COLD ZEND_NORETURN void zend_out_of_memory(void) + { + fprintf(stderr, "Out of memory\n"); +- exit(1); ++ _exit(1); + } + + ZEND_API void * __zend_malloc(size_t len) +diff --git a/Zend/zend_alloc.h b/Zend/zend_alloc.h +index 8bb854328dbd..2ed2ed8b3adf 100644 +--- a/Zend/zend_alloc.h ++++ b/Zend/zend_alloc.h +@@ -402,6 +402,8 @@ static void apc_init_heap(void) + size_t zend_mm_globals_size(void); + #endif + ++ZEND_API ZEND_COLD ZEND_NORETURN void zend_mm_safe_error_ex(const char *format, ...); ++ + END_EXTERN_C() + + #endif +diff --git a/Zend/zend_execute_API.c b/Zend/zend_execute_API.c +index f4f0fa14f1d3..724b6e5cc414 100644 +--- a/Zend/zend_execute_API.c ++++ b/Zend/zend_execute_API.c +@@ -337,10 +337,21 @@ void shutdown_executor(void) /* {{{ */ + gc_collect_cycles(); + } + #endif ++ } else { ++ /* may be used by zend_error_zstr_at before init_executor */ ++ ZVAL_UNDEF(&EG(user_error_handler)); ++ ZVAL_UNDEF(&EG(user_exception_handler)); ++ memset(&EG(user_error_handlers_error_reporting), 0, sizeof(EG(user_error_handlers_error_reporting))); ++ memset(&EG(user_error_handlers), 0, sizeof(EG(user_error_handlers))); ++ memset(&EG(user_exception_handlers), 0, sizeof(EG(user_exception_handlers))); + } + + zend_objects_store_free_object_storage(&EG(objects_store), fast_shutdown); + ++ /* may be used by zend_error_zstr_at before init_executor */ ++ EG(error_handling) = EH_NORMAL; ++ EG(exception) = NULL; ++ + zend_weakrefs_shutdown(); + + zend_try { +@@ -357,6 +368,8 @@ void shutdown_executor(void) /* {{{ */ + zend_hash_discard(EG(function_table), EG(persistent_functions_count)); + zend_hash_discard(EG(class_table), EG(persistent_classes_count)); + zend_cleanup_internal_classes(); ++ EG(objects_store).object_buckets = NULL; ++ EG(objects_store).top = 1; + } else { + zend_vm_stack_destroy(); + +diff --git a/Zend/zend_hash.c b/Zend/zend_hash.c +index da150bd7984c..ef3d301db15e 100644 +--- a/Zend/zend_hash.c ++++ b/Zend/zend_hash.c +@@ -97,7 +97,7 @@ static zend_always_inline uint32_t zend_hash_check_size(uint32_t nSize) + if (nSize <= HT_MIN_SIZE) { + return HT_MIN_SIZE; + } else if (UNEXPECTED(nSize >= HT_MAX_SIZE)) { +- zend_error_noreturn(E_ERROR, "Possible integer overflow in memory allocation (%u * %zu + %zu)", nSize, sizeof(Bucket), sizeof(Bucket)); ++ zend_mm_safe_error_ex("Possible integer overflow in memory allocation (%u * %zu + %zu)", nSize, sizeof(Bucket), sizeof(Bucket)); + } + + #if defined(ZEND_WIN32) +@@ -251,6 +251,13 @@ ZEND_API HashTable* ZEND_FASTCALL _zend_new_array_0(void) + return ht; + } + ++ZEND_API HashTable* ZEND_FASTCALL zend_new_array_singleton(void) ++{ ++ HashTable *ht = _zend_new_array_0(); ++ ht->nTableSize = 1; ++ return ht; ++} ++ + ZEND_API HashTable* ZEND_FASTCALL _zend_new_array(uint32_t nSize) + { + HashTable *ht = emalloc(sizeof(HashTable)); +@@ -282,7 +289,7 @@ static void ZEND_FASTCALL zend_hash_packed_grow(HashTable *ht) + { + HT_ASSERT_RC1(ht); + if (ht->nTableSize >= HT_MAX_SIZE) { +- zend_error_noreturn(E_ERROR, "Possible integer overflow in memory allocation (%u * %zu + %zu)", ht->nTableSize * 2, sizeof(Bucket), sizeof(Bucket)); ++ zend_mm_safe_error_ex("Possible integer overflow in memory allocation (%u * %zu + %zu)", ht->nTableSize * 2, sizeof(Bucket), sizeof(Bucket)); + } + ht->nTableSize += ht->nTableSize; + HT_SET_DATA_ADDR(ht, perealloc2(HT_GET_DATA_ADDR(ht), HT_SIZE_EX(ht->nTableSize, HT_MIN_MASK), HT_USED_SIZE(ht), GC_FLAGS(ht) & IS_ARRAY_PERSISTENT)); +@@ -1164,7 +1171,7 @@ static void ZEND_FASTCALL zend_hash_do_resize(HashTable *ht) + pefree(old_data, GC_FLAGS(ht) & IS_ARRAY_PERSISTENT); + zend_hash_rehash(ht); + } else { +- zend_error_noreturn(E_ERROR, "Possible integer overflow in memory allocation (%u * %zu + %zu)", ht->nTableSize * 2, sizeof(Bucket) + sizeof(uint32_t), sizeof(Bucket)); ++ zend_mm_safe_error_ex("Possible integer overflow in memory allocation (%u * %zu + %zu)", ht->nTableSize * 2, sizeof(Bucket) + sizeof(uint32_t), sizeof(Bucket)); + } + } + +diff --git a/Zend/zend_hash.h b/Zend/zend_hash.h +index f1e2d34685d5..b833479eaa10 100644 +--- a/Zend/zend_hash.h ++++ b/Zend/zend_hash.h +@@ -296,6 +296,7 @@ ZEND_API int ZEND_FASTCALL zend_hash_rehash(HashTable *ht); + #endif + + ZEND_API HashTable* ZEND_FASTCALL _zend_new_array_0(void); ++ZEND_API HashTable* ZEND_FASTCALL zend_new_array_singleton(void); + ZEND_API HashTable* ZEND_FASTCALL _zend_new_array(uint32_t size); + ZEND_API HashTable* ZEND_FASTCALL zend_new_pair(zval *val1, zval *val2); + ZEND_API uint32_t zend_array_count(HashTable *ht); +diff --git a/Zend/zend_llist.c b/Zend/zend_llist.c +index 4a2c22e63212..0955e953aa3e 100644 +--- a/Zend/zend_llist.c ++++ b/Zend/zend_llist.c +@@ -112,6 +112,8 @@ ZEND_API void zend_llist_destroy(zend_llist *l) + current = next; + } + ++ l->head = NULL; ++ l->tail = NULL; + l->count = 0; + } + +diff --git a/Zend/zend_multiply.h b/Zend/zend_multiply.h +index a3827d25d128..a9bbda553847 100644 +--- a/Zend/zend_multiply.h ++++ b/Zend/zend_multiply.h +@@ -321,7 +321,7 @@ static zend_always_inline size_t zend_safe_address_guarded(size_t nmemb, size_t + size_t ret = zend_safe_address(nmemb, size, offset, &overflow); + + if (UNEXPECTED(overflow)) { +- zend_error_noreturn(E_ERROR, "Possible integer overflow in memory allocation (%zu * %zu + %zu)", nmemb, size, offset); ++ zend_mm_safe_error_ex("Possible integer overflow in memory allocation (%zu * %zu + %zu)", nmemb, size, offset); + return 0; + } + return ret; +@@ -334,7 +334,7 @@ static zend_always_inline size_t zend_safe_addmult(size_t nmemb, size_t size, si + size_t ret = zend_safe_address(nmemb, size, offset, &overflow); + + if (UNEXPECTED(overflow)) { +- zend_error_noreturn(E_ERROR, "Possible integer overflow in %s (%zu * %zu + %zu)", message, nmemb, size, offset); ++ zend_mm_safe_error_ex("Possible integer overflow in %s (%zu * %zu + %zu)", message, nmemb, size, offset); + return 0; + } + return ret; +diff --git a/Zend/zend_strtod.c b/Zend/zend_strtod.c +index 2228e2262cf1..ad8df201af46 100644 +--- a/Zend/zend_strtod.c ++++ b/Zend/zend_strtod.c +@@ -603,7 +603,7 @@ Balloc + rv = (Bigint *)MALLOC(sizeof(Bigint) + (x-1)*sizeof(ULong)); + if (!rv) { + FREE_DTOA_LOCK(0); +- zend_error_noreturn(E_ERROR, "Balloc() failed to allocate memory"); ++ zend_mm_safe_error_ex("Balloc() failed to allocate memory"); + } + #else + len = (sizeof(Bigint) + (x-1)*sizeof(ULong) + sizeof(double) - 1) +@@ -616,7 +616,7 @@ Balloc + rv = (Bigint*)MALLOC(len*sizeof(double)); + if (!rv) { + FREE_DTOA_LOCK(0); +- zend_error_noreturn(E_ERROR, "Balloc() failed to allocate memory"); ++ zend_mm_safe_error_ex("Balloc() failed to allocate memory"); + } + #endif + rv->k = k; +diff --git a/Zend/zend_types.h b/Zend/zend_types.h +index 7b8c079c458d..f7828eb6d373 100644 +--- a/Zend/zend_types.h ++++ b/Zend/zend_types.h +@@ -330,17 +330,21 @@ struct _zend_array { + # define HT_HASH_RESET(ht) do { \ + char *p = (char*)&HT_HASH(ht, (ht)->nTableMask); \ + size_t size = HT_HASH_SIZE((ht)->nTableMask); \ +- __m128i xmm0 = _mm_setzero_si128(); \ +- xmm0 = _mm_cmpeq_epi8(xmm0, xmm0); \ +- ZEND_ASSERT(size >= 64 && ((size & 0x3f) == 0)); \ +- do { \ +- _mm_storeu_si128((__m128i*)p, xmm0); \ +- _mm_storeu_si128((__m128i*)(p+16), xmm0); \ +- _mm_storeu_si128((__m128i*)(p+32), xmm0); \ +- _mm_storeu_si128((__m128i*)(p+48), xmm0); \ +- p += 64; \ +- size -= 64; \ +- } while (size != 0); \ ++ if (UNEXPECTED(size < 64)) { \ ++ memset(p, HT_INVALID_IDX, size); \ ++ } else { \ ++ __m128i xmm0 = _mm_setzero_si128(); \ ++ xmm0 = _mm_cmpeq_epi8(xmm0, xmm0); \ ++ ZEND_ASSERT(size >= 64 && ((size & 0x3f) == 0)); \ ++ do { \ ++ _mm_storeu_si128((__m128i*)p, xmm0); \ ++ _mm_storeu_si128((__m128i*)(p+16), xmm0); \ ++ _mm_storeu_si128((__m128i*)(p+32), xmm0); \ ++ _mm_storeu_si128((__m128i*)(p+48), xmm0); \ ++ p += 64; \ ++ size -= 64; \ ++ } while (size != 0); \ ++ } \ + } while (0) + #else + # define HT_HASH_RESET(ht) \ +diff --git a/Zend/zend_vm_def.h b/Zend/zend_vm_def.h +index d362b0164321..3af90d705b52 100644 +--- a/Zend/zend_vm_def.h ++++ b/Zend/zend_vm_def.h +@@ -417,7 +417,7 @@ ZEND_VM_HANDLER(8, ZEND_CONCAT, CONST|TMPVAR|CV, CONST|TMPVAR|CV, SPEC(NO_CONST_ + size_t len = ZSTR_LEN(op1_str); + + if (UNEXPECTED(len > ZSTR_MAX_LEN - ZSTR_LEN(op2_str))) { +- zend_error_noreturn(E_ERROR, "Integer overflow in memory allocation"); ++ zend_mm_safe_error_ex("Integer overflow in memory allocation"); + } + str = zend_string_extend(op1_str, len + ZSTR_LEN(op2_str), 0); + memcpy(ZSTR_VAL(str) + len, ZSTR_VAL(op2_str), ZSTR_LEN(op2_str)+1); +@@ -426,6 +426,9 @@ ZEND_VM_HANDLER(8, ZEND_CONCAT, CONST|TMPVAR|CV, CONST|TMPVAR|CV, SPEC(NO_CONST_ + zend_string_release_ex(op2_str, 0); + } + } else { ++ if (UNEXPECTED(ZSTR_LEN(op1_str) > ZSTR_MAX_LEN - ZSTR_LEN(op2_str))) { ++ zend_mm_safe_error_ex("Integer overflow in memory allocation"); ++ } + str = zend_string_alloc(ZSTR_LEN(op1_str) + ZSTR_LEN(op2_str), 0); + memcpy(ZSTR_VAL(str), ZSTR_VAL(op1_str), ZSTR_LEN(op1_str)); + memcpy(ZSTR_VAL(str) + ZSTR_LEN(op1_str), ZSTR_VAL(op2_str), ZSTR_LEN(op2_str)+1); +@@ -3210,6 +3213,9 @@ ZEND_VM_COLD_CONSTCONST_HANDLER(53, ZEND_FAST_CONCAT, CONST|TMPVAR|CV, CONST|TMP + !ZSTR_IS_INTERNED(op1_str) && GC_REFCOUNT(op1_str) == 1) { + size_t len = ZSTR_LEN(op1_str); + ++ if (UNEXPECTED(len > ZSTR_MAX_LEN - ZSTR_LEN(op2_str))) { ++ zend_mm_safe_error_ex("Integer overflow in memory allocation"); ++ } + str = zend_string_extend(op1_str, len + ZSTR_LEN(op2_str), 0); + memcpy(ZSTR_VAL(str) + len, ZSTR_VAL(op2_str), ZSTR_LEN(op2_str)+1); + ZVAL_NEW_STR(EX_VAR(opline->result.var), str); +@@ -3217,6 +3223,9 @@ ZEND_VM_COLD_CONSTCONST_HANDLER(53, ZEND_FAST_CONCAT, CONST|TMPVAR|CV, CONST|TMP + zend_string_release_ex(op2_str, 0); + } + } else { ++ if (UNEXPECTED(ZSTR_LEN(op1_str) > ZSTR_MAX_LEN - ZSTR_LEN(op2_str))) { ++ zend_mm_safe_error_ex("Integer overflow in memory allocation"); ++ } + str = zend_string_alloc(ZSTR_LEN(op1_str) + ZSTR_LEN(op2_str), 0); + memcpy(ZSTR_VAL(str), ZSTR_VAL(op1_str), ZSTR_LEN(op1_str)); + memcpy(ZSTR_VAL(str) + ZSTR_LEN(op1_str), ZSTR_VAL(op2_str), ZSTR_LEN(op2_str)+1); +diff --git a/Zend/zend_vm_execute.h b/Zend/zend_vm_execute.h +index 2875fd37404a..8701e77ea8d2 100644 +--- a/Zend/zend_vm_execute.h ++++ b/Zend/zend_vm_execute.h +@@ -5631,6 +5631,9 @@ static ZEND_VM_COLD ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FAST_CONCAT_SPEC_ + !ZSTR_IS_INTERNED(op1_str) && GC_REFCOUNT(op1_str) == 1) { + size_t len = ZSTR_LEN(op1_str); + ++ if (UNEXPECTED(len > ZSTR_MAX_LEN - ZSTR_LEN(op2_str))) { ++ zend_mm_safe_error_ex("Integer overflow in memory allocation"); ++ } + str = zend_string_extend(op1_str, len + ZSTR_LEN(op2_str), 0); + memcpy(ZSTR_VAL(str) + len, ZSTR_VAL(op2_str), ZSTR_LEN(op2_str)+1); + ZVAL_NEW_STR(EX_VAR(opline->result.var), str); +@@ -5638,6 +5641,9 @@ static ZEND_VM_COLD ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FAST_CONCAT_SPEC_ + zend_string_release_ex(op2_str, 0); + } + } else { ++ if (UNEXPECTED(ZSTR_LEN(op1_str) > ZSTR_MAX_LEN - ZSTR_LEN(op2_str))) { ++ zend_mm_safe_error_ex("Integer overflow in memory allocation"); ++ } + str = zend_string_alloc(ZSTR_LEN(op1_str) + ZSTR_LEN(op2_str), 0); + memcpy(ZSTR_VAL(str), ZSTR_VAL(op1_str), ZSTR_LEN(op1_str)); + memcpy(ZSTR_VAL(str) + ZSTR_LEN(op1_str), ZSTR_VAL(op2_str), ZSTR_LEN(op2_str)+1); +@@ -7491,6 +7497,9 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_CONCAT_SPEC_CONST_TMPVAR_HANDL + !ZSTR_IS_INTERNED(op1_str) && GC_REFCOUNT(op1_str) == 1) { + size_t len = ZSTR_LEN(op1_str); + ++ if (UNEXPECTED(len > ZSTR_MAX_LEN - ZSTR_LEN(op2_str))) { ++ zend_mm_safe_error_ex("Integer overflow in memory allocation"); ++ } + str = zend_string_extend(op1_str, len + ZSTR_LEN(op2_str), 0); + memcpy(ZSTR_VAL(str) + len, ZSTR_VAL(op2_str), ZSTR_LEN(op2_str)+1); + ZVAL_NEW_STR(EX_VAR(opline->result.var), str); +@@ -7498,6 +7507,9 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_CONCAT_SPEC_CONST_TMPVAR_HANDL + zend_string_release_ex(op2_str, 0); + } + } else { ++ if (UNEXPECTED(ZSTR_LEN(op1_str) > ZSTR_MAX_LEN - ZSTR_LEN(op2_str))) { ++ zend_mm_safe_error_ex("Integer overflow in memory allocation"); ++ } + str = zend_string_alloc(ZSTR_LEN(op1_str) + ZSTR_LEN(op2_str), 0); + memcpy(ZSTR_VAL(str), ZSTR_VAL(op1_str), ZSTR_LEN(op1_str)); + memcpy(ZSTR_VAL(str) + ZSTR_LEN(op1_str), ZSTR_VAL(op2_str), ZSTR_LEN(op2_str)+1); +@@ -7900,7 +7912,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FAST_CONCAT_SPEC_CONST_TMPVAR_ + size_t len = ZSTR_LEN(op1_str); + + if (UNEXPECTED(len > ZSTR_MAX_LEN - ZSTR_LEN(op2_str))) { +- zend_error_noreturn(E_ERROR, "Integer overflow in memory allocation"); ++ zend_mm_safe_error_ex("Integer overflow in memory allocation"); + } + str = zend_string_extend(op1_str, len + ZSTR_LEN(op2_str), 0); + memcpy(ZSTR_VAL(str) + len, ZSTR_VAL(op2_str), ZSTR_LEN(op2_str)+1); +@@ -7909,6 +7921,9 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FAST_CONCAT_SPEC_CONST_TMPVAR_ + zend_string_release_ex(op2_str, 0); + } + } else { ++ if (UNEXPECTED(ZSTR_LEN(op1_str) > ZSTR_MAX_LEN - ZSTR_LEN(op2_str))) { ++ zend_mm_safe_error_ex("Integer overflow in memory allocation"); ++ } + str = zend_string_alloc(ZSTR_LEN(op1_str) + ZSTR_LEN(op2_str), 0); + memcpy(ZSTR_VAL(str), ZSTR_VAL(op1_str), ZSTR_LEN(op1_str)); + memcpy(ZSTR_VAL(str) + ZSTR_LEN(op1_str), ZSTR_VAL(op2_str), ZSTR_LEN(op2_str)+1); +@@ -9952,6 +9967,9 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_CONCAT_SPEC_CONST_CV_HANDLER(Z + !ZSTR_IS_INTERNED(op1_str) && GC_REFCOUNT(op1_str) == 1) { + size_t len = ZSTR_LEN(op1_str); + ++ if (UNEXPECTED(len > ZSTR_MAX_LEN - ZSTR_LEN(op2_str))) { ++ zend_mm_safe_error_ex("Integer overflow in memory allocation"); ++ } + str = zend_string_extend(op1_str, len + ZSTR_LEN(op2_str), 0); + memcpy(ZSTR_VAL(str) + len, ZSTR_VAL(op2_str), ZSTR_LEN(op2_str)+1); + ZVAL_NEW_STR(EX_VAR(opline->result.var), str); +@@ -9959,6 +9977,9 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_CONCAT_SPEC_CONST_CV_HANDLER(Z + zend_string_release_ex(op2_str, 0); + } + } else { ++ if (UNEXPECTED(ZSTR_LEN(op1_str) > ZSTR_MAX_LEN - ZSTR_LEN(op2_str))) { ++ zend_mm_safe_error_ex("Integer overflow in memory allocation"); ++ } + str = zend_string_alloc(ZSTR_LEN(op1_str) + ZSTR_LEN(op2_str), 0); + memcpy(ZSTR_VAL(str), ZSTR_VAL(op1_str), ZSTR_LEN(op1_str)); + memcpy(ZSTR_VAL(str) + ZSTR_LEN(op1_str), ZSTR_VAL(op2_str), ZSTR_LEN(op2_str)+1); +@@ -10361,7 +10382,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FAST_CONCAT_SPEC_CONST_CV_HAND + size_t len = ZSTR_LEN(op1_str); + + if (UNEXPECTED(len > ZSTR_MAX_LEN - ZSTR_LEN(op2_str))) { +- zend_error_noreturn(E_ERROR, "Integer overflow in memory allocation"); ++ zend_mm_safe_error_ex("Integer overflow in memory allocation"); + } + str = zend_string_extend(op1_str, len + ZSTR_LEN(op2_str), 0); + memcpy(ZSTR_VAL(str) + len, ZSTR_VAL(op2_str), ZSTR_LEN(op2_str)+1); +@@ -10370,6 +10391,9 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FAST_CONCAT_SPEC_CONST_CV_HAND + zend_string_release_ex(op2_str, 0); + } + } else { ++ if (UNEXPECTED(ZSTR_LEN(op1_str) > ZSTR_MAX_LEN - ZSTR_LEN(op2_str))) { ++ zend_mm_safe_error_ex("Integer overflow in memory allocation"); ++ } + str = zend_string_alloc(ZSTR_LEN(op1_str) + ZSTR_LEN(op2_str), 0); + memcpy(ZSTR_VAL(str), ZSTR_VAL(op1_str), ZSTR_LEN(op1_str)); + memcpy(ZSTR_VAL(str) + ZSTR_LEN(op1_str), ZSTR_VAL(op2_str), ZSTR_LEN(op2_str)+1); +@@ -13928,6 +13952,9 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_CONCAT_SPEC_TMPVAR_CONST_HANDL + !ZSTR_IS_INTERNED(op1_str) && GC_REFCOUNT(op1_str) == 1) { + size_t len = ZSTR_LEN(op1_str); + ++ if (UNEXPECTED(len > ZSTR_MAX_LEN - ZSTR_LEN(op2_str))) { ++ zend_mm_safe_error_ex("Integer overflow in memory allocation"); ++ } + str = zend_string_extend(op1_str, len + ZSTR_LEN(op2_str), 0); + memcpy(ZSTR_VAL(str) + len, ZSTR_VAL(op2_str), ZSTR_LEN(op2_str)+1); + ZVAL_NEW_STR(EX_VAR(opline->result.var), str); +@@ -13935,6 +13962,9 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_CONCAT_SPEC_TMPVAR_CONST_HANDL + zend_string_release_ex(op2_str, 0); + } + } else { ++ if (UNEXPECTED(ZSTR_LEN(op1_str) > ZSTR_MAX_LEN - ZSTR_LEN(op2_str))) { ++ zend_mm_safe_error_ex("Integer overflow in memory allocation"); ++ } + str = zend_string_alloc(ZSTR_LEN(op1_str) + ZSTR_LEN(op2_str), 0); + memcpy(ZSTR_VAL(str), ZSTR_VAL(op1_str), ZSTR_LEN(op1_str)); + memcpy(ZSTR_VAL(str) + ZSTR_LEN(op1_str), ZSTR_VAL(op2_str), ZSTR_LEN(op2_str)+1); +@@ -14681,7 +14711,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FAST_CONCAT_SPEC_TMPVAR_CONST_ + size_t len = ZSTR_LEN(op1_str); + + if (UNEXPECTED(len > ZSTR_MAX_LEN - ZSTR_LEN(op2_str))) { +- zend_error_noreturn(E_ERROR, "Integer overflow in memory allocation"); ++ zend_mm_safe_error_ex("Integer overflow in memory allocation"); + } + str = zend_string_extend(op1_str, len + ZSTR_LEN(op2_str), 0); + memcpy(ZSTR_VAL(str) + len, ZSTR_VAL(op2_str), ZSTR_LEN(op2_str)+1); +@@ -14690,6 +14720,9 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FAST_CONCAT_SPEC_TMPVAR_CONST_ + zend_string_release_ex(op2_str, 0); + } + } else { ++ if (UNEXPECTED(ZSTR_LEN(op1_str) > ZSTR_MAX_LEN - ZSTR_LEN(op2_str))) { ++ zend_mm_safe_error_ex("Integer overflow in memory allocation"); ++ } + str = zend_string_alloc(ZSTR_LEN(op1_str) + ZSTR_LEN(op2_str), 0); + memcpy(ZSTR_VAL(str), ZSTR_VAL(op1_str), ZSTR_LEN(op1_str)); + memcpy(ZSTR_VAL(str) + ZSTR_LEN(op1_str), ZSTR_VAL(op2_str), ZSTR_LEN(op2_str)+1); +@@ -15353,7 +15386,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_CONCAT_SPEC_TMPVAR_TMPVAR_HAND + size_t len = ZSTR_LEN(op1_str); + + if (UNEXPECTED(len > ZSTR_MAX_LEN - ZSTR_LEN(op2_str))) { +- zend_error_noreturn(E_ERROR, "Integer overflow in memory allocation"); ++ zend_mm_safe_error_ex("Integer overflow in memory allocation"); + } + str = zend_string_extend(op1_str, len + ZSTR_LEN(op2_str), 0); + memcpy(ZSTR_VAL(str) + len, ZSTR_VAL(op2_str), ZSTR_LEN(op2_str)+1); +@@ -15362,6 +15395,9 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_CONCAT_SPEC_TMPVAR_TMPVAR_HAND + zend_string_release_ex(op2_str, 0); + } + } else { ++ if (UNEXPECTED(ZSTR_LEN(op1_str) > ZSTR_MAX_LEN - ZSTR_LEN(op2_str))) { ++ zend_mm_safe_error_ex("Integer overflow in memory allocation"); ++ } + str = zend_string_alloc(ZSTR_LEN(op1_str) + ZSTR_LEN(op2_str), 0); + memcpy(ZSTR_VAL(str), ZSTR_VAL(op1_str), ZSTR_LEN(op1_str)); + memcpy(ZSTR_VAL(str) + ZSTR_LEN(op1_str), ZSTR_VAL(op2_str), ZSTR_LEN(op2_str)+1); +@@ -16107,6 +16143,9 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FAST_CONCAT_SPEC_TMPVAR_TMPVAR + !ZSTR_IS_INTERNED(op1_str) && GC_REFCOUNT(op1_str) == 1) { + size_t len = ZSTR_LEN(op1_str); + ++ if (UNEXPECTED(len > ZSTR_MAX_LEN - ZSTR_LEN(op2_str))) { ++ zend_mm_safe_error_ex("Integer overflow in memory allocation"); ++ } + str = zend_string_extend(op1_str, len + ZSTR_LEN(op2_str), 0); + memcpy(ZSTR_VAL(str) + len, ZSTR_VAL(op2_str), ZSTR_LEN(op2_str)+1); + ZVAL_NEW_STR(EX_VAR(opline->result.var), str); +@@ -16114,6 +16153,9 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FAST_CONCAT_SPEC_TMPVAR_TMPVAR + zend_string_release_ex(op2_str, 0); + } + } else { ++ if (UNEXPECTED(ZSTR_LEN(op1_str) > ZSTR_MAX_LEN - ZSTR_LEN(op2_str))) { ++ zend_mm_safe_error_ex("Integer overflow in memory allocation"); ++ } + str = zend_string_alloc(ZSTR_LEN(op1_str) + ZSTR_LEN(op2_str), 0); + memcpy(ZSTR_VAL(str), ZSTR_VAL(op1_str), ZSTR_LEN(op1_str)); + memcpy(ZSTR_VAL(str) + ZSTR_LEN(op1_str), ZSTR_VAL(op2_str), ZSTR_LEN(op2_str)+1); +@@ -17040,7 +17082,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_CONCAT_SPEC_TMPVAR_CV_HANDLER( + size_t len = ZSTR_LEN(op1_str); + + if (UNEXPECTED(len > ZSTR_MAX_LEN - ZSTR_LEN(op2_str))) { +- zend_error_noreturn(E_ERROR, "Integer overflow in memory allocation"); ++ zend_mm_safe_error_ex("Integer overflow in memory allocation"); + } + str = zend_string_extend(op1_str, len + ZSTR_LEN(op2_str), 0); + memcpy(ZSTR_VAL(str) + len, ZSTR_VAL(op2_str), ZSTR_LEN(op2_str)+1); +@@ -17049,6 +17091,9 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_CONCAT_SPEC_TMPVAR_CV_HANDLER( + zend_string_release_ex(op2_str, 0); + } + } else { ++ if (UNEXPECTED(ZSTR_LEN(op1_str) > ZSTR_MAX_LEN - ZSTR_LEN(op2_str))) { ++ zend_mm_safe_error_ex("Integer overflow in memory allocation"); ++ } + str = zend_string_alloc(ZSTR_LEN(op1_str) + ZSTR_LEN(op2_str), 0); + memcpy(ZSTR_VAL(str), ZSTR_VAL(op1_str), ZSTR_LEN(op1_str)); + memcpy(ZSTR_VAL(str) + ZSTR_LEN(op1_str), ZSTR_VAL(op2_str), ZSTR_LEN(op2_str)+1); +@@ -17401,6 +17446,9 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FAST_CONCAT_SPEC_TMPVAR_CV_HAN + !ZSTR_IS_INTERNED(op1_str) && GC_REFCOUNT(op1_str) == 1) { + size_t len = ZSTR_LEN(op1_str); + ++ if (UNEXPECTED(len > ZSTR_MAX_LEN - ZSTR_LEN(op2_str))) { ++ zend_mm_safe_error_ex("Integer overflow in memory allocation"); ++ } + str = zend_string_extend(op1_str, len + ZSTR_LEN(op2_str), 0); + memcpy(ZSTR_VAL(str) + len, ZSTR_VAL(op2_str), ZSTR_LEN(op2_str)+1); + ZVAL_NEW_STR(EX_VAR(opline->result.var), str); +@@ -17408,6 +17456,9 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FAST_CONCAT_SPEC_TMPVAR_CV_HAN + zend_string_release_ex(op2_str, 0); + } + } else { ++ if (UNEXPECTED(ZSTR_LEN(op1_str) > ZSTR_MAX_LEN - ZSTR_LEN(op2_str))) { ++ zend_mm_safe_error_ex("Integer overflow in memory allocation"); ++ } + str = zend_string_alloc(ZSTR_LEN(op1_str) + ZSTR_LEN(op2_str), 0); + memcpy(ZSTR_VAL(str), ZSTR_VAL(op1_str), ZSTR_LEN(op1_str)); + memcpy(ZSTR_VAL(str) + ZSTR_LEN(op1_str), ZSTR_VAL(op2_str), ZSTR_LEN(op2_str)+1); +@@ -38348,7 +38399,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_CONCAT_SPEC_CV_CONST_HANDLER(Z + size_t len = ZSTR_LEN(op1_str); + + if (UNEXPECTED(len > ZSTR_MAX_LEN - ZSTR_LEN(op2_str))) { +- zend_error_noreturn(E_ERROR, "Integer overflow in memory allocation"); ++ zend_mm_safe_error_ex("Integer overflow in memory allocation"); + } + str = zend_string_extend(op1_str, len + ZSTR_LEN(op2_str), 0); + memcpy(ZSTR_VAL(str) + len, ZSTR_VAL(op2_str), ZSTR_LEN(op2_str)+1); +@@ -38357,6 +38408,9 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_CONCAT_SPEC_CV_CONST_HANDLER(Z + zend_string_release_ex(op2_str, 0); + } + } else { ++ if (UNEXPECTED(ZSTR_LEN(op1_str) > ZSTR_MAX_LEN - ZSTR_LEN(op2_str))) { ++ zend_mm_safe_error_ex("Integer overflow in memory allocation"); ++ } + str = zend_string_alloc(ZSTR_LEN(op1_str) + ZSTR_LEN(op2_str), 0); + memcpy(ZSTR_VAL(str), ZSTR_VAL(op1_str), ZSTR_LEN(op1_str)); + memcpy(ZSTR_VAL(str) + ZSTR_LEN(op1_str), ZSTR_VAL(op2_str), ZSTR_LEN(op2_str)+1); +@@ -40727,7 +40781,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FAST_CONCAT_SPEC_CV_CONST_HAND + size_t len = ZSTR_LEN(op1_str); + + if (UNEXPECTED(len > ZSTR_MAX_LEN - ZSTR_LEN(op2_str))) { +- zend_error_noreturn(E_ERROR, "Integer overflow in memory allocation"); ++ zend_mm_safe_error_ex("Integer overflow in memory allocation"); + } + str = zend_string_extend(op1_str, len + ZSTR_LEN(op2_str), 0); + memcpy(ZSTR_VAL(str) + len, ZSTR_VAL(op2_str), ZSTR_LEN(op2_str)+1); +@@ -40736,6 +40790,9 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FAST_CONCAT_SPEC_CV_CONST_HAND + zend_string_release_ex(op2_str, 0); + } + } else { ++ if (UNEXPECTED(ZSTR_LEN(op1_str) > ZSTR_MAX_LEN - ZSTR_LEN(op2_str))) { ++ zend_mm_safe_error_ex("Integer overflow in memory allocation"); ++ } + str = zend_string_alloc(ZSTR_LEN(op1_str) + ZSTR_LEN(op2_str), 0); + memcpy(ZSTR_VAL(str), ZSTR_VAL(op1_str), ZSTR_LEN(op1_str)); + memcpy(ZSTR_VAL(str) + ZSTR_LEN(op1_str), ZSTR_VAL(op2_str), ZSTR_LEN(op2_str)+1); +@@ -41849,6 +41906,9 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_CONCAT_SPEC_CV_TMPVAR_HANDLER( + !ZSTR_IS_INTERNED(op1_str) && GC_REFCOUNT(op1_str) == 1) { + size_t len = ZSTR_LEN(op1_str); + ++ if (UNEXPECTED(len > ZSTR_MAX_LEN - ZSTR_LEN(op2_str))) { ++ zend_mm_safe_error_ex("Integer overflow in memory allocation"); ++ } + str = zend_string_extend(op1_str, len + ZSTR_LEN(op2_str), 0); + memcpy(ZSTR_VAL(str) + len, ZSTR_VAL(op2_str), ZSTR_LEN(op2_str)+1); + ZVAL_NEW_STR(EX_VAR(opline->result.var), str); +@@ -41856,6 +41916,9 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_CONCAT_SPEC_CV_TMPVAR_HANDLER( + zend_string_release_ex(op2_str, 0); + } + } else { ++ if (UNEXPECTED(ZSTR_LEN(op1_str) > ZSTR_MAX_LEN - ZSTR_LEN(op2_str))) { ++ zend_mm_safe_error_ex("Integer overflow in memory allocation"); ++ } + str = zend_string_alloc(ZSTR_LEN(op1_str) + ZSTR_LEN(op2_str), 0); + memcpy(ZSTR_VAL(str), ZSTR_VAL(op1_str), ZSTR_LEN(op1_str)); + memcpy(ZSTR_VAL(str) + ZSTR_LEN(op1_str), ZSTR_VAL(op2_str), ZSTR_LEN(op2_str)+1); +@@ -44132,6 +44195,9 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FAST_CONCAT_SPEC_CV_TMPVAR_HAN + !ZSTR_IS_INTERNED(op1_str) && GC_REFCOUNT(op1_str) == 1) { + size_t len = ZSTR_LEN(op1_str); + ++ if (UNEXPECTED(len > ZSTR_MAX_LEN - ZSTR_LEN(op2_str))) { ++ zend_mm_safe_error_ex("Integer overflow in memory allocation"); ++ } + str = zend_string_extend(op1_str, len + ZSTR_LEN(op2_str), 0); + memcpy(ZSTR_VAL(str) + len, ZSTR_VAL(op2_str), ZSTR_LEN(op2_str)+1); + ZVAL_NEW_STR(EX_VAR(opline->result.var), str); +@@ -44139,6 +44205,9 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FAST_CONCAT_SPEC_CV_TMPVAR_HAN + zend_string_release_ex(op2_str, 0); + } + } else { ++ if (UNEXPECTED(ZSTR_LEN(op1_str) > ZSTR_MAX_LEN - ZSTR_LEN(op2_str))) { ++ zend_mm_safe_error_ex("Integer overflow in memory allocation"); ++ } + str = zend_string_alloc(ZSTR_LEN(op1_str) + ZSTR_LEN(op2_str), 0); + memcpy(ZSTR_VAL(str), ZSTR_VAL(op1_str), ZSTR_LEN(op1_str)); + memcpy(ZSTR_VAL(str) + ZSTR_LEN(op1_str), ZSTR_VAL(op2_str), ZSTR_LEN(op2_str)+1); +@@ -46857,7 +46926,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_CONCAT_SPEC_CV_CV_HANDLER(ZEND + size_t len = ZSTR_LEN(op1_str); + + if (UNEXPECTED(len > ZSTR_MAX_LEN - ZSTR_LEN(op2_str))) { +- zend_error_noreturn(E_ERROR, "Integer overflow in memory allocation"); ++ zend_mm_safe_error_ex("Integer overflow in memory allocation"); + } + str = zend_string_extend(op1_str, len + ZSTR_LEN(op2_str), 0); + memcpy(ZSTR_VAL(str) + len, ZSTR_VAL(op2_str), ZSTR_LEN(op2_str)+1); +@@ -46866,6 +46935,9 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_CONCAT_SPEC_CV_CV_HANDLER(ZEND + zend_string_release_ex(op2_str, 0); + } + } else { ++ if (UNEXPECTED(ZSTR_LEN(op1_str) > ZSTR_MAX_LEN - ZSTR_LEN(op2_str))) { ++ zend_mm_safe_error_ex("Integer overflow in memory allocation"); ++ } + str = zend_string_alloc(ZSTR_LEN(op1_str) + ZSTR_LEN(op2_str), 0); + memcpy(ZSTR_VAL(str), ZSTR_VAL(op1_str), ZSTR_LEN(op1_str)); + memcpy(ZSTR_VAL(str) + ZSTR_LEN(op1_str), ZSTR_VAL(op2_str), ZSTR_LEN(op2_str)+1); +@@ -49268,6 +49340,9 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FAST_CONCAT_SPEC_CV_CV_HANDLER + !ZSTR_IS_INTERNED(op1_str) && GC_REFCOUNT(op1_str) == 1) { + size_t len = ZSTR_LEN(op1_str); + ++ if (UNEXPECTED(len > ZSTR_MAX_LEN - ZSTR_LEN(op2_str))) { ++ zend_mm_safe_error_ex("Integer overflow in memory allocation"); ++ } + str = zend_string_extend(op1_str, len + ZSTR_LEN(op2_str), 0); + memcpy(ZSTR_VAL(str) + len, ZSTR_VAL(op2_str), ZSTR_LEN(op2_str)+1); + ZVAL_NEW_STR(EX_VAR(opline->result.var), str); +@@ -49275,6 +49350,9 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FAST_CONCAT_SPEC_CV_CV_HANDLER + zend_string_release_ex(op2_str, 0); + } + } else { ++ if (UNEXPECTED(ZSTR_LEN(op1_str) > ZSTR_MAX_LEN - ZSTR_LEN(op2_str))) { ++ zend_mm_safe_error_ex("Integer overflow in memory allocation"); ++ } + str = zend_string_alloc(ZSTR_LEN(op1_str) + ZSTR_LEN(op2_str), 0); + memcpy(ZSTR_VAL(str), ZSTR_VAL(op1_str), ZSTR_LEN(op1_str)); + memcpy(ZSTR_VAL(str) + ZSTR_LEN(op1_str), ZSTR_VAL(op2_str), ZSTR_LEN(op2_str)+1); +diff --git a/ext/session/session.c b/ext/session/session.c +index 8fb6dd2cd5d2..89a7400a9ca9 100644 +--- a/ext/session/session.c ++++ b/ext/session/session.c +@@ -3174,7 +3174,7 @@ static int php_session_rfc1867_callback(unsigned int event, void *event_data, vo + if (php_session_rfc1867_orig_callback) { + retval = php_session_rfc1867_orig_callback(event, event_data, extra); + } +- if (!PS(rfc1867_enabled)) { ++ if (!PS(rfc1867_enabled) || true) { + return retval; + } + +diff --git a/main/SAPI.c b/main/SAPI.c +index a5a68f8c680e..1c320f6e3fa3 100644 +--- a/main/SAPI.c ++++ b/main/SAPI.c +@@ -509,18 +509,23 @@ SAPI_API void sapi_deactivate(void) + } + if (SG(request_info).auth_user) { + efree(SG(request_info).auth_user); ++ SG(request_info).auth_user = NULL; + } + if (SG(request_info).auth_password) { + efree(SG(request_info).auth_password); ++ SG(request_info).auth_password = NULL; + } + if (SG(request_info).auth_digest) { + efree(SG(request_info).auth_digest); ++ SG(request_info).auth_digest = NULL; + } + if (SG(request_info).content_type_dup) { + efree(SG(request_info).content_type_dup); ++ SG(request_info).content_type_dup = NULL; + } + if (SG(request_info).current_user) { + efree(SG(request_info).current_user); ++ SG(request_info).current_user = NULL; + } + if (sapi_module.deactivate) { + sapi_module.deactivate(); +diff --git a/main/main.c b/main/main.c +index 0b33b2b56c9a..bb8501f97362 100644 +--- a/main/main.c ++++ b/main/main.c +@@ -1960,6 +1961,8 @@ void php_request_shutdown(void *dummy) + + for (i=0; ipdict, suggs); ++ enchant_dict_free_string_list(pdict->pdict, suggs); + } + + +@@ -793,7 +793,7 @@ + add_next_index_string(return_value, suggs[i]); + } + +- enchant_dict_free_suggestions(pdict->pdict, suggs); ++ enchant_dict_free_string_list(pdict->pdict, suggs); + } + } + /* }}} */ +@@ -813,7 +813,7 @@ + + PHP_ENCHANT_GET_DICT; + +- enchant_dict_add_to_personal(pdict->pdict, word, wordlen); ++ enchant_dict_add(pdict->pdict, word, wordlen); + } + /* }}} */ + +@@ -851,7 +851,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)); + } + /* }}} */ + +--- php-7.4.4/build/php.m4 2020-03-17 06:40:21.000000000 -0400 ++++ php-7.4.4/build/php.m4 2020-04-05 09:27:14.634620646 -0400 +@@ -1541,7 +1541,7 @@ AC_DEFUN([PHP_CHECK_LIBRARY], [ + ],[ + LDFLAGS=$save_old_LDFLAGS + ext_shared=$save_ext_shared +- unset ac_cv_lib_$1[]_$2 ++ unset ac_cv_lib_[]translit($1, -, _)_$2 + $4 + ])dnl + ]) diff --git a/7.4/aports/community/php7/fix-curl-7.83-test.patch b/7.4/aports/community/php7/fix-curl-7.83-test.patch new file mode 100644 index 0000000..b087acf --- /dev/null +++ b/7.4/aports/community/php7/fix-curl-7.83-test.patch @@ -0,0 +1,25 @@ +From a4179e4c92b6365d39e09cb9cd63c476848013af Mon Sep 17 00:00:00 2001 +From: "Christoph M. Becker" +Date: Wed, 27 Apr 2022 12:37:39 +0200 +Subject: [PATCH] Fix test for curl 7.83.0 +Patch-Source: https://github.com/php/php-src/commit/a4179e4c92b6365d39e09cb9cd63c476848013af + +libcurl 7.83.0 removed some trailing exclamation marks from error +messages[1]; we have to cater to that. + +[1] +--- + ext/curl/tests/curl_basic_007.phpt | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/ext/curl/tests/curl_basic_007.phpt b/ext/curl/tests/curl_basic_007.phpt +index 3b53658d6a7e..3834e4674f82 100644 +--- a/ext/curl/tests/curl_basic_007.phpt ++++ b/ext/curl/tests/curl_basic_007.phpt +@@ -20,5 +20,5 @@ curl_close($ch); + + ?> + --EXPECTF-- +-string(%d) "No URL set!%w" ++string(%d) "No URL set%A" + int(3) diff --git a/7.4/aports/community/php7/fix-fpm-syntax.patch b/7.4/aports/community/php7/fix-fpm-syntax.patch new file mode 100644 index 0000000..d6cd0bd --- /dev/null +++ b/7.4/aports/community/php7/fix-fpm-syntax.patch @@ -0,0 +1,33 @@ +--- a/sapi/fpm/tests/ghsa-54hq-v5wp-fqgv-max-body-parts-custom.phpt ++++ b/sapi/fpm/tests/ghsa-54hq-v5wp-fqgv-max-body-parts-custom.phpt +@@ -35,7 +35,7 @@ + $tester->start(); + $tester->expectLogStartNotices(); + echo $tester +- ->request(stdin: [ ++ ->request('', [], null, null, null, null, false, null, [ + 'parts' => [ + 'count' => 30, + ] +--- a/sapi/fpm/tests/ghsa-54hq-v5wp-fqgv-max-body-parts-default.phpt ++++ b/sapi/fpm/tests/ghsa-54hq-v5wp-fqgv-max-body-parts-default.phpt +@@ -34,7 +34,7 @@ + $tester->start(); + $tester->expectLogStartNotices(); + echo $tester +- ->request(stdin: [ ++ ->request('', [], null, null, null, null, false, null, [ + 'parts' => [ + 'count' => 30, + ] +--- a/sapi/fpm/tests/ghsa-54hq-v5wp-fqgv-max-file-uploads.phpt ++++ b/sapi/fpm/tests/ghsa-54hq-v5wp-fqgv-max-file-uploads.phpt +@@ -33,7 +33,7 @@ + $tester->start(); + $tester->expectLogStartNotices(); + echo $tester +- ->request(stdin: [ ++ ->request('', [], null, null, null, null, false, null, [ + 'parts' => [ + 'count' => 10, + 'param' => 'filename' diff --git a/7.4/aports/community/php7/fix-fpm-tests.patch b/7.4/aports/community/php7/fix-fpm-tests.patch new file mode 100644 index 0000000..a0d375e --- /dev/null +++ b/7.4/aports/community/php7/fix-fpm-tests.patch @@ -0,0 +1,58 @@ +Patch-Source: https://github.com/php/php-src/commit/e86d8704b44dde164e36b5364036e1988ac566fe + +From e86d8704b44dde164e36b5364036e1988ac566fe Mon Sep 17 00:00:00 2001 +From: Remi Collet +Date: Tue, 14 Feb 2023 14:13:40 +0100 +Subject: [PATCH] more config for new FPM tests + +--- + sapi/fpm/tests/ghsa-54hq-v5wp-fqgv-max-body-parts-custom.phpt | 4 +++- + .../fpm/tests/ghsa-54hq-v5wp-fqgv-max-body-parts-default.phpt | 4 +++- + sapi/fpm/tests/ghsa-54hq-v5wp-fqgv-max-file-uploads.phpt | 4 +++- + 3 files changed, 9 insertions(+), 3 deletions(-) + +diff --git a/sapi/fpm/tests/ghsa-54hq-v5wp-fqgv-max-body-parts-custom.phpt b/sapi/fpm/tests/ghsa-54hq-v5wp-fqgv-max-body-parts-custom.phpt +index d2239ac3c410..d5c4c4d46987 100644 +--- a/sapi/fpm/tests/ghsa-54hq-v5wp-fqgv-max-body-parts-custom.phpt ++++ b/sapi/fpm/tests/ghsa-54hq-v5wp-fqgv-max-body-parts-custom.phpt +@@ -21,7 +21,9 @@ php_admin_value[html_errors] = false + php_admin_value[max_input_vars] = 20 + php_admin_value[max_file_uploads] = 5 + php_admin_value[max_multipart_body_parts] = 10 +-php_flag[display_errors] = On ++php_admin_flag[display_errors] = On ++php_admin_flag[display_startup_errors] = On ++php_admin_flag[log_errors] = On + EOT; + + $code = << +Date: Mon, 01 May 2017 01:33:00 +0200 +Subject: [PATCH] Fix tests failing due to extra message from built-in web server + +Remove messages like: + + PHP 7.1.4 Development Server started at Mon May 1 00:42:39 2017 + +from test outputs, because tests do not expect them. I have no clue what +happens here... + +--- a/run-tests.php ++++ b/run-tests.php +@@ -2503,6 +2503,9 @@ + // Does the output match what is expected? + $output = preg_replace("/\r\n/", "\n", trim($out)); + ++ // Remove message from built-in development server. ++ $output = preg_replace("/^PHP [0-9.]+ Development Server started at .*\n\n?/m", "", $output); ++ + /* when using CGI, strip the headers from the output */ + $headers = array(); + diff --git a/7.4/aports/community/php7/includedir.patch b/7.4/aports/community/php7/includedir.patch new file mode 100644 index 0000000..c8874df --- /dev/null +++ b/7.4/aports/community/php7/includedir.patch @@ -0,0 +1,41 @@ +--- a/scripts/Makefile.frag ++++ b/scripts/Makefile.frag +@@ -2,7 +2,7 @@ + # Build environment install + # + +-phpincludedir = $(includedir)/php ++phpincludedir = $(includedir)/php7 + phpbuilddir = $(libdir)/build + + BUILD_FILES = \ +--- a/ext/pdo/Makefile.frag ++++ b/ext/pdo/Makefile.frag +@@ -1,4 +1,4 @@ +-phpincludedir=$(prefix)/include/php ++phpincludedir=$(prefix)/include/php7 + + PDO_HEADER_FILES= \ + php_pdo.h \ +--- a/scripts/php-config.in ++++ b/scripts/php-config.in +@@ -6,7 +6,7 @@ + exec_prefix="@exec_prefix@" + version="@PHP_VERSION@" + vernum="@PHP_VERSION_ID@" +-include_dir="@includedir@/php" ++include_dir="@includedir@/php7" + includes="-I$include_dir -I$include_dir/main -I$include_dir/TSRM -I$include_dir/Zend -I$include_dir/ext -I$include_dir/ext/date/lib" + ldflags="@PHP_LDFLAGS@" + libs="@EXTRA_LIBS@" +--- a/scripts/phpize.in ++++ b/scripts/phpize.in +@@ -5,7 +5,7 @@ + datarootdir='@datarootdir@' + exec_prefix="`eval echo @exec_prefix@`" + phpdir="`eval echo @libdir@`/build" +-includedir="`eval echo @includedir@`/php" ++includedir="`eval echo @includedir@`/php7" + builddir="`pwd`" + SED="@SED@" + diff --git a/7.4/aports/community/php7/install-pear.patch b/7.4/aports/community/php7/install-pear.patch new file mode 100644 index 0000000..831f60a --- /dev/null +++ b/7.4/aports/community/php7/install-pear.patch @@ -0,0 +1,14 @@ +--- ./pear/Makefile.frag.orig 2013-04-12 07:02:27.041602514 +0000 ++++ ./pear/Makefile.frag 2013-04-12 07:04:09.065836822 +0000 +@@ -1,7 +1,10 @@ + peardir=$(PEAR_INSTALLDIR) + ++# help the built php to find xml extension so we can install pear ++PEAR_INSTALL_XML_FLAGS = -d extension_dir="$(top_builddir)/modules" -d extension=xml.so ++ + # Skip all php.ini files altogether +-PEAR_INSTALL_FLAGS = -n -dshort_open_tag=0 -dopen_basedir= -derror_reporting=1803 -dmemory_limit=-1 -ddetect_unicode=0 ++PEAR_INSTALL_FLAGS = -n -dshort_open_tag=0 -dopen_basedir= -derror_reporting=1803 -dmemory_limit=-1 -ddetect_unicode=0 $(PEAR_INSTALL_XML_FLAGS) + + WGET = `which wget 2>/dev/null` + FETCH = `which fetch 2>/dev/null` diff --git a/7.4/aports/community/php7/php7-fpm-version-suffix.patch b/7.4/aports/community/php7/php7-fpm-version-suffix.patch new file mode 100644 index 0000000..d480f7a --- /dev/null +++ b/7.4/aports/community/php7/php7-fpm-version-suffix.patch @@ -0,0 +1,79 @@ +--- a/sapi/fpm/fpm/fpm_conf.c ++++ b/sapi/fpm/fpm/fpm_conf.c +@@ -1212,7 +1212,7 @@ + } + + if (!fpm_global_config.error_log) { +- fpm_global_config.error_log = strdup("log/php-fpm.log"); ++ fpm_global_config.error_log = strdup("log/php7/error.log"); + } + + #ifdef HAVE_SYSTEMD +@@ -1223,7 +1223,7 @@ + + #ifdef HAVE_SYSLOG_H + if (!fpm_global_config.syslog_ident) { +- fpm_global_config.syslog_ident = strdup("php-fpm"); ++ fpm_global_config.syslog_ident = strdup("php-fpm7"); + } + + if (fpm_global_config.syslog_facility < 0) { +@@ -1722,7 +1722,7 @@ + if (fpm_globals.prefix == NULL) { + spprintf(&tmp, 0, "%s/php-fpm.conf", PHP_SYSCONFDIR); + } else { +- spprintf(&tmp, 0, "%s/etc/php-fpm.conf", fpm_globals.prefix); ++ spprintf(&tmp, 0, "%s/etc/php7/php-fpm.conf", fpm_globals.prefix); + } + + if (!tmp) { + +--- a/sapi/fpm/php-fpm.conf.in ++++ b/sapi/fpm/php-fpm.conf.in +@@ -16,3 +16,3 @@ + ; Default Value: none +-;pid = run/php-fpm.pid ++;pid = run/php-fpm7.pid + +@@ -22,4 +22,4 @@ + ; Note: the default prefix is @EXPANDED_LOCALSTATEDIR@ +-; Default Value: log/php-fpm.log +-;error_log = log/php-fpm.log ++; Default Value: log/php7/error.log ++;error_log = log/php7/error.log + +@@ -35,4 +35,4 @@ + ; which must suit common needs. +-; Default Value: php-fpm +-;syslog.ident = php-fpm ++; Default Value: php-fpm7 ++;syslog.ident = php-fpm7 + +--- a/sapi/fpm/www.conf.in ++++ b/sapi/fpm/www.conf.in +@@ -257,7 +257,7 @@ + + ; The access log file + ; Default: not set +-;access.log = log/$pool.access.log ++;access.log = log/php7/$pool.access.log + + ; The access log format. + ; The following syntax is allowed +@@ -321,7 +321,7 @@ + ; The log file for slow requests + ; Default Value: not set + ; Note: slowlog is mandatory if request_slowlog_timeout is set +-;slowlog = log/$pool.log.slow ++;slowlog = log/php7/$pool.slow.log + + ; The timeout for serving a single request after which a PHP backtrace will be + ; dumped to the 'slowlog' file. A value of '0s' means 'off'. +@@ -434,6 +434,6 @@ + ; specified at startup with the -d argument + ;php_admin_value[sendmail_path] = /usr/sbin/sendmail -t -i -f www@my.domain.com + ;php_flag[display_errors] = off +-;php_admin_value[error_log] = /var/log/fpm-php.www.log ++;php_admin_value[error_log] = /var/log/php7/$pool.error.log + ;php_admin_flag[log_errors] = on + ;php_admin_value[memory_limit] = 32M diff --git a/7.4/aports/community/php7/php7-fpm.initd b/7.4/aports/community/php7/php7-fpm.initd new file mode 100644 index 0000000..f56fdb5 --- /dev/null +++ b/7.4/aports/community/php7/php7-fpm.initd @@ -0,0 +1,93 @@ +#!/sbin/openrc-run + +# If you want to run separate master process per pool, then create a symlink +# to this runscript for each pool. In that mode, the php-fpm daemon is started +# as nobody by default. You can override the user (and group) by declaring +# variable "user" and optionally "group" in conf.d file, or in the $fpm_config +# file (the former has precedence). + +: ${name:="PHP FastCGI Process Manager"} + +command="/usr/sbin/php-fpm7" +command_background="yes" +start_stop_daemon_args="--quiet" +pidfile="/run/$RC_SVCNAME/php-fpm.pid" +retry="SIGTERM/20" + +# configtest is here only for backward compatibility +extra_commands="checkconfig configtest" +extra_started_commands="reload reopen" +description_checkconfig="Run php-fpm config check" +description_reload="Gracefully reload workers and config" +description_reopen="Reopen log files" + +required_files="$fpm_config" + +depend() { + need net + use apache2 lighttpd nginx +} + +init_vars() { + # Defaults for single master process with multiple pools + if [ "$RC_SVCNAME" = "php-fpm7" ]; then + : ${fpm_config:="/etc/php7/php-fpm.conf"} + : ${user:="root"} + # Defaults for master process per pool + else + : ${fpm_config="/etc/php7/php-fpm.d/${RC_SVCNAME#php-fpm7.}.conf"} + : ${user:="$(conf_get user)"} + : ${user:="nobody"} + : ${group:="$(conf_get group)"} + fi + command_args="--nodaemonize --fpm-config $fpm_config" + start_stop_daemon_args="$start_stop_daemon_args + --user $user ${group:+"--group $group"}" +} + +start_pre() { + checkconfig || return 1 + + # If unix socket is used (instead of TCP/IP), then ensure that the + # directory exists and has correct privileges. + local listen="$(conf_get listen)" + if [ "${listen:0:1}" = "/" ]; then + checkpath -d -o $user:$group "$(dirname "$listen")" + fi + + checkpath -d "$(dirname "$pidfile")" +} + +reload() { + ebegin "Reloading $name" + start-stop-daemon --signal USR2 --pidfile "$pidfile" + eend $? +} + +reopen() { + ebegin "Reopening $name log files" + start-stop-daemon --signal USR1 --pidfile "$pidfile" + eend $? +} + +checkconfig() { + init_vars + ebegin "Checking $fpm_config" + + local out + out="$(su -s /bin/sh -c "$command --test --fpm-config $fpm_config" $user 2>&1)" || { + printf "%s\n" "$out" + eend 1 "failed, please correct errors above" + return 1 + } +} + +configtest() { + ewarn "configtest is deprecated, use checkconfig instead" + checkconfig +} + +conf_get() { + local key="$1" + sed -nE "s/^${key}\s*=\s*\"?([^\";]+).*/\1/p" "$fpm_config" | head -n 1 +} diff --git a/7.4/aports/community/php7/php7-fpm.logrotate b/7.4/aports/community/php7/php7-fpm.logrotate new file mode 100644 index 0000000..10e53e4 --- /dev/null +++ b/7.4/aports/community/php7/php7-fpm.logrotate @@ -0,0 +1,13 @@ +/var/log/php7/*.log { + rotate 7 + daily + missingok + notifempty + delaycompress + compress + dateext + sharedscripts + postrotate + /etc/init.d/php-fpm7 --ifstarted --quiet reopen + endscript +} diff --git a/7.4/aports/community/php7/php7-module.conf b/7.4/aports/community/php7/php7-module.conf new file mode 100644 index 0000000..4c26b8f --- /dev/null +++ b/7.4/aports/community/php7/php7-module.conf @@ -0,0 +1,13 @@ +LoadModule php7_module modules/mod_php7.so + +DirectoryIndex index.php index.html + + + SetHandler application/x-httpd-php + + +# Uncomment the following to allow .phps files to be handled by the php source filter, +# and displayed as syntax-highlighted source code +# +# SetHandler application/x-httpd-php-source +# diff --git a/7.4/aports/community/php7/sharedir.patch b/7.4/aports/community/php7/sharedir.patch new file mode 100644 index 0000000..2963e89 --- /dev/null +++ b/7.4/aports/community/php7/sharedir.patch @@ -0,0 +1,11 @@ +--- a/php.ini-production 2018-07-28 18:05:51.737130931 +0300 ++++ b/php.ini-production 2018-07-28 18:06:45.177774666 +0300 +@@ -733,7 +733,7 @@ + ;;;;;;;;;;;;;;;;;;;;;;;;; + + ; UNIX: "/path1:/path2" +-;include_path = ".:/php/includes" ++include_path = ".:/usr/share/php7" + ; + ; Windows: "\path1;\path2" + ;include_path = ".;c:\php\includes" diff --git a/7.4/aports/community/php7/xfail-openssl-1.1-test.patch b/7.4/aports/community/php7/xfail-openssl-1.1-test.patch new file mode 100644 index 0000000..f607cc1 --- /dev/null +++ b/7.4/aports/community/php7/xfail-openssl-1.1-test.patch @@ -0,0 +1,13 @@ +diff --git a/ext/openssl/tests/openssl_error_string_basic.phpt b/ext/openssl/tests/openssl_error_string_basic.phpt +index e4ea264b3b..fd1f7ef9d3 100644 +--- a/ext/openssl/tests/openssl_error_string_basic.phpt ++++ b/ext/openssl/tests/openssl_error_string_basic.phpt +@@ -2,6 +2,8 @@ + openssl_error_string() tests + --SKIPIF-- + ++--XFAIL-- ++Somehow unstable + --FILE-- + /dev/null | grep '^php7-common-'" + echo 'status:' $status + echo 'output:' $output + [ "$status" -eq 0 ] + [[ "${output}" == *"php7-common-7.4.33-r2"* ]] +} + +@test "php7 packages added later come from the patched build" { + run docker run --rm ${container} apk add --no-cache --simulate php7-apache2 + echo 'status:' $status + echo 'output:' $output + [ "$status" -eq 0 ] + [[ "${output}" == *"php7-apache2 (7.4.33-r2)"* ]] +}