summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--.gitignore1
-rw-r--r--failed.txt14
-rw-r--r--macros.php4
-rw-r--r--php-5.6.3-oci8conf.patch35
-rw-r--r--php-7.0.0-systzdata-v14.patch2
-rw-r--r--php-7.0.31-icu62.patch2
-rw-r--r--php-bug75457.patch119
-rw-r--r--php-bug76450.patch278
-rw-r--r--php-bug77423.patch431
-rw-r--r--php-bug77569.patch106
-rw-r--r--php-bug78380.patch47
-rw-r--r--php-bug78599.patch53
-rw-r--r--php-bug78793.patch62
-rw-r--r--php-bug78862.patch68
-rw-r--r--php-bug78863.patch85
-rw-r--r--php-bug78875.patch38
-rw-r--r--php-bug78876.patch74
-rw-r--r--php-bug78878.patch68
-rw-r--r--php-bug78910.patch148
-rw-r--r--php-bug79037.patch93
-rw-r--r--php-bug79082.patch152
-rw-r--r--php-bug79099.patch113
-rw-r--r--php-bug79221.patch86
-rw-r--r--php-bug79282.patch110
-rw-r--r--php-bug79329.patch57
-rw-r--r--php-bug79330.patch31
-rw-r--r--php-bug79465.patch59
-rw-r--r--php-bug79699.patch142
-rw-r--r--php-bug79797.patch52
-rw-r--r--php-bug79877.patch62
-rw-r--r--php-bug79971.patch208
-rw-r--r--php-bug80672.patch239
-rw-r--r--php-bug80710.patch373
-rw-r--r--php-bug81026.patch430
-rw-r--r--php-bug81122.patch88
-rw-r--r--php-bug81211.patch164
-rw-r--r--php-bug81719.patch66
-rw-r--r--php-bug81720.patch79
-rw-r--r--php-bug81726.patch180
-rw-r--r--php-bug81727.patch81
-rw-r--r--php-bug81740.patch87
-rw-r--r--php-bug81744.patch190
-rw-r--r--php-bug81746.patch100
-rw-r--r--php-cve-2023-0662.patch148
-rw-r--r--php-cve-2023-3247.patch151
-rw-r--r--php-cve-2023-3823.patch93
-rw-r--r--php-cve-2023-3824.patch408
-rw-r--r--php-cve-2024-2756.patch201
-rw-r--r--php-cve-2024-3096.patch88
-rw-r--r--php-net-snmp.patch38
-rw-r--r--php-openssl-cert.patch148
-rw-r--r--php.spec442
52 files changed, 6473 insertions, 121 deletions
diff --git a/.gitignore b/.gitignore
index df4c9dc..73e1878 100644
--- a/.gitignore
+++ b/.gitignore
@@ -1,2 +1,3 @@
+clog
php-*.tar.xz
php70-php-*src.rpm
diff --git a/failed.txt b/failed.txt
index 92dffa4..fa60712 100644
--- a/failed.txt
+++ b/failed.txt
@@ -1,17 +1,13 @@
-===== 7.0.33-12 (2019-07-30)
+===== 7.0.33-41 (2024-04-11)
$ grep -r 'Tests failed' /var/lib/mock/scl70*/build.log
-/var/lib/mock/scl70el6x/build.log:Tests failed : 0
-/var/lib/mock/scl70el7x/build.log:Tests failed : 0
-/var/lib/mock/scl70el8x/build.log:Tests failed : 28
-/var/lib/mock/scl70fc28x/build.log:Tests failed : 0
-/var/lib/mock/scl70fc29x/build.log:Tests failed : 1
-/var/lib/mock/scl70fc30x/build.log:Tests failed : 1
+/var/lib/mock/scl70el7x/build.log:Tests failed : 18
+/var/lib/mock/scl70el8x/build.log:Tests failed : 30
-fc29x, fc30x:
- TLS server rate-limits client-initiated renegotiation [ext/openssl/tests/stream_server_reneg_limit.phpt]
+el7x, el8x:
+ 2 related to tzdata, expired test cert and openssl policy
1 proc_open give erratic test results :(
diff --git a/macros.php b/macros.php
index 3943a74..d3e937f 100644
--- a/macros.php
+++ b/macros.php
@@ -14,3 +14,7 @@
%@SCL@__php @BINDIR@/php
+%@SCL@__phpize @BINDIR@/phpize
+
+%@SCL@__phpconfig @BINDIR@/php-config
+
diff --git a/php-5.6.3-oci8conf.patch b/php-5.6.3-oci8conf.patch
index f2d8f99..0f923f7 100644
--- a/php-5.6.3-oci8conf.patch
+++ b/php-5.6.3-oci8conf.patch
@@ -10,28 +10,29 @@ diff -up php5.3-201104170830/ext/ldap/php_ldap.h.remi-oci8 php5.3-201104170830/e
extern zend_module_entry ldap_module_entry;
#define ldap_module_ptr &ldap_module_entry
-diff -up php5.3-201104170830/ext/oci8/config.m4.remi-oci8 php5.3-201104170830/ext/oci8/config.m4
---- php5.3-201104170830/ext/oci8/config.m4.remi-oci8 2011-03-30 00:35:22.000000000 +0200
-+++ php5.3-201104170830/ext/oci8/config.m4 2011-04-17 11:55:25.628871315 +0200
-@@ -376,6 +376,7 @@ if test "$PHP_OCI8" != "no"; then
-
- dnl Header directory for Instant Client SDK RPM install
- OCISDKRPMINC=`echo "$PHP_OCI8_INSTANT_CLIENT" | $PHP_OCI8_SED -e 's!^/usr/lib/oracle/\(.*\)/client\('${PHP_OCI8_IC_LIBDIR_SUFFIX}'\)*/lib[/]*$!/usr/include/oracle/\1/client\2!'`
-+ OCISDKRPMINC=`echo "$PHP_OCI8_INSTANT_CLIENT" | $PHP_OCI8_SED -e 's!^/usr/\(lib64\|lib\)/oracle/\(.*\)/\(client64\|client\)/lib[/]*$!/usr/include/oracle/\2/\3!'`
-
- dnl Header directory for Instant Client SDK zip file install
- OCISDKZIPINC=$PHP_OCI8_INSTANT_CLIENT/sdk/include
-diff -up php5.3-201104170830/ext/pdo_oci/config.m4.remi-oci8 php5.3-201104170830/ext/pdo_oci/config.m4
---- php5.3-201104170830/ext/pdo_oci/config.m4.remi-oci8 2011-04-02 04:35:24.000000000 +0200
-+++ php5.3-201104170830/ext/pdo_oci/config.m4 2011-04-17 12:02:42.837194120 +0200
-@@ -104,8 +104,10 @@ You need to tell me where to find your O
+diff -up ./ext/pdo_oci/config.m4.remi-oci8 ./ext/pdo_oci/config.m4
+--- ./ext/pdo_oci/config.m4.remi-oci8 2019-10-22 18:59:47.000000000 +0200
++++ ./ext/pdo_oci/config.m4 2023-09-22 09:49:00.888471382 +0200
+@@ -104,7 +104,10 @@ You need to tell me where to find your O
+ fi
+ fi
+ AC_MSG_CHECKING([for oci.h])
+- if test -f $PDO_OCI_IC_PREFIX/include/oracle/$PDO_OCI_IC_VERS/$PDO_OCI_CLIENT_DIR/oci.h ; then
++ if test -f $PDO_OCI_IC_PREFIX/include/oracle/$PDO_OCI_IC_MAJ_VER/$PDO_OCI_CLIENT_DIR/oci.h ; then
++ PHP_ADD_INCLUDE($PDO_OCI_IC_PREFIX/include/oracle/$PDO_OCI_IC_MAJ_VER/$PDO_OCI_CLIENT_DIR)
++ AC_MSG_RESULT($PDO_OCI_IC_PREFIX/include/oracle/$PDO_OCI_IC_MAJ_VER/$PDO_OCI_CLIENT_DIR)
++ elif test -f $PDO_OCI_IC_PREFIX/include/oracle/$PDO_OCI_IC_VERS/$PDO_OCI_CLIENT_DIR/oci.h ; then
+ PHP_ADD_INCLUDE($PDO_OCI_IC_PREFIX/include/oracle/$PDO_OCI_IC_VERS/$PDO_OCI_CLIENT_DIR)
+ AC_MSG_RESULT($PDO_OCI_IC_PREFIX/include/oracle/$PDO_OCI_IC_VERS/$PDO_OCI_CLIENT_DIR)
+ elif test -f $PDO_OCI_IC_PREFIX/lib/oracle/$PDO_OCI_IC_VERS/$PDO_OCI_CLIENT_DIR/include/oci.h ; then
+@@ -119,8 +122,10 @@ You need to tell me where to find your O
else
AC_MSG_ERROR([I'm too dumb to figure out where the include dir is in your Instant Client install])
fi
- if test -f "$PDO_OCI_IC_PREFIX/lib/oracle/$PDO_OCI_IC_VERS/$PDO_OCI_CLIENT_DIR/lib/libclntsh.$SHLIB_SUFFIX_NAME" ; then
- PDO_OCI_LIB_DIR="$PDO_OCI_IC_PREFIX/lib/oracle/$PDO_OCI_IC_VERS/$PDO_OCI_CLIENT_DIR/lib"
-+ if test -f "$PDO_OCI_IC_PREFIX/lib64/oracle/$PDO_OCI_IC_VERS/$PDO_OCI_CLIENT_DIR/lib/libclntsh.$SHLIB_SUFFIX_NAME" ; then
-+ PDO_OCI_LIB_DIR="$PDO_OCI_IC_PREFIX/lib64/oracle/$PDO_OCI_IC_VERS/$PDO_OCI_CLIENT_DIR/lib"
++ if test -f "$PDO_OCI_IC_PREFIX/lib/oracle/$PDO_OCI_IC_MAJ_VER/$PDO_OCI_CLIENT_DIR/lib/libclntsh.$SHLIB_SUFFIX_NAME" ; then
++ PDO_OCI_LIB_DIR="$PDO_OCI_IC_PREFIX/lib/oracle/$PDO_OCI_IC_MAJ_VER/$PDO_OCI_CLIENT_DIR/lib"
+ elif test -f "$PDO_OCI_IC_PREFIX/lib/oracle/$PDO_OCI_IC_VERS/$PDO_OCI_CLIENT_DIR/lib/libclntsh.$SHLIB_SUFFIX_NAME" ; then
+ PDO_OCI_LIB_DIR="$PDO_OCI_IC_PREFIX/lib/oracle/$PDO_OCI_IC_VERS/$PDO_OCI_CLIENT_DIR/lib"
elif test -f "$PDO_OCI_IC_PREFIX/$PDO_OCI_CLIENT_DIR/lib/libclntsh.$SHLIB_SUFFIX_NAME" ; then
diff --git a/php-7.0.0-systzdata-v14.patch b/php-7.0.0-systzdata-v14.patch
index dd6b784..bbf65ed 100644
--- a/php-7.0.0-systzdata-v14.patch
+++ b/php-7.0.0-systzdata-v14.patch
@@ -392,7 +392,7 @@ diff -up php-7.0.12RC1/ext/date/lib/parse_tz.c.systzdata php-7.0.12RC1/ext/date/
+ size_t n;
+ char *data, *p;
+
-+ data = malloc(3 * sysdb->index_size + 7);
++ data = malloc(3 * sysdb->index_size + sizeof(FAKE_HEADER) - 1);
+
+ p = mempcpy(data, FAKE_HEADER, sizeof(FAKE_HEADER) - 1);
+
diff --git a/php-7.0.31-icu62.patch b/php-7.0.31-icu62.patch
index 50ec038..f65271c 100644
--- a/php-7.0.31-icu62.patch
+++ b/php-7.0.31-icu62.patch
@@ -571,7 +571,7 @@ index e8428e1cbbe8..52408f8e9183 100644
PHP_SETUP_ICU(INTL_SHARED_LIBADD)
PHP_SUBST(INTL_SHARED_LIBADD)
PHP_REQUIRE_CXX()
-+ INTL_COMMON_FLAGS="$ICU_INCS -Wno-write-strings -D__STDC_LIMIT_MACROS -DZEND_ENABLE_STATIC_TSRMLS_CACHE=1"
++ INTL_COMMON_FLAGS="$ICU_INCS -Wno-write-strings -DU_DEFINE_FALSE_AND_TRUE=1 -D__STDC_LIMIT_MACROS -DZEND_ENABLE_STATIC_TSRMLS_CACHE=1"
if test "$icu_version" -ge "4002"; then
icu_spoof_src=" spoofchecker/spoofchecker_class.c \
spoofchecker/spoofchecker.c\
diff --git a/php-bug75457.patch b/php-bug75457.patch
new file mode 100644
index 0000000..2e2d6c9
--- /dev/null
+++ b/php-bug75457.patch
@@ -0,0 +1,119 @@
+From 1ea539fe2afbc3bfa7ffa80e680b88aa52e03527 Mon Sep 17 00:00:00 2001
+From: "Christoph M. Becker" <cmbecker69@gmx.de>
+Date: Fri, 16 Aug 2019 14:29:19 +0200
+Subject: [PATCH 2/3] Fix #75457: heap-use-after-free in php7.0.25
+
+Backport <https://vcs.pcre.org/pcre?view=revision&revision=1638>.
+
+(cherry picked from commit 7bf1f9d561826c4a3ed748e55bb756375cdf28b9)
+---
+ ext/pcre/pcrelib/pcre_compile.c | 11 ++++++++++-
+ ext/pcre/tests/bug75457.phpt | 10 ++++++++++
+ 2 files changed, 20 insertions(+), 1 deletion(-)
+ create mode 100644 ext/pcre/tests/bug75457.phpt
+
+diff --git a/ext/pcre/pcrelib/pcre_compile.c b/ext/pcre/pcrelib/pcre_compile.c
+index c7827745c8..402c4284d1 100644
+--- a/ext/pcre/pcrelib/pcre_compile.c
++++ b/ext/pcre/pcrelib/pcre_compile.c
+@@ -483,7 +483,7 @@ static const char error_texts[] =
+ "lookbehind assertion is not fixed length\0"
+ "malformed number or name after (?(\0"
+ "conditional group contains more than two branches\0"
+- "assertion expected after (?(\0"
++ "assertion expected after (?( or (?(?C)\0"
+ "(?R or (?[+-]digits must be followed by )\0"
+ /* 30 */
+ "unknown POSIX class name\0"
+@@ -6732,6 +6732,15 @@ for (;; ptr++)
+ for (i = 3;; i++) if (!IS_DIGIT(ptr[i])) break;
+ if (ptr[i] == CHAR_RIGHT_PARENTHESIS)
+ tempptr += i + 1;
++
++ /* tempptr should now be pointing to the opening parenthesis of the
++ assertion condition. */
++
++ if (*tempptr != CHAR_LEFT_PARENTHESIS)
++ {
++ *errorcodeptr = ERR28;
++ goto FAILED;
++ }
+ }
+
+ /* For conditions that are assertions, check the syntax, and then exit
+diff --git a/ext/pcre/tests/bug75457.phpt b/ext/pcre/tests/bug75457.phpt
+new file mode 100644
+index 0000000000..c7ce9ed0f9
+--- /dev/null
++++ b/ext/pcre/tests/bug75457.phpt
+@@ -0,0 +1,10 @@
++--TEST--
++Bug #75457 (heap-use-after-free in php7.0.25)
++--FILE--
++<?php
++$pattern = "/(((?(?C)0?=))(?!()0|.(?0)0)())/";
++var_dump(preg_match($pattern, "hello"));
++?>
++--EXPECTF--
++Warning: preg_match(): Compilation failed: assertion expected after (?( or (?(?C) at offset 4 in %sbug75457.php on line %d
++bool(false)
+--
+2.20.1
+
+From 41dc3ff967e44932a6646de9ac7331f0d5c5fdc4 Mon Sep 17 00:00:00 2001
+From: Remi Collet <remi@remirepo.net>
+Date: Wed, 28 Aug 2019 10:00:28 +0200
+Subject: [PATCH 3/3] NEWS
+
+---
+ NEWS | 8 ++++++++
+ 1 file changed, 8 insertions(+)
+
+diff --git a/NEWS b/NEWS
+index 62f3f8f4b8..a3c0c90143 100644
+--- a/NEWS
++++ b/NEWS
+@@ -1,7 +1,15 @@
+ PHP NEWS
+ |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
+
+- Backported from 7.1.31
++Backported from 7.1.32
++
++- mbstring:
++ . Fixed CVE-2019-13224 (don't allow different encodings for onig_new_deluxe) (stas)
++
++- pcre:
++ . Fixed bug #75457 (heap use-after-free in pcrelib) (cmb)
++
++Backported from 7.1.31
+
+ - EXIF:
+ . Fixed bug #78256 (heap-buffer-overflow on exif_process_user_comment).
+--
+2.20.1
+
+From b781eb2900cc0d74e385e704711a0002a9ecc8cb Mon Sep 17 00:00:00 2001
+From: Remi Collet <remi@remirepo.net>
+Date: Wed, 28 Aug 2019 14:34:48 +0200
+Subject: [PATCH] relax test, offset may be different on various system lib
+ versions
+
+---
+ ext/pcre/tests/bug75457.phpt | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/ext/pcre/tests/bug75457.phpt b/ext/pcre/tests/bug75457.phpt
+index c7ce9ed0f9..571a4bde77 100644
+--- a/ext/pcre/tests/bug75457.phpt
++++ b/ext/pcre/tests/bug75457.phpt
+@@ -6,5 +6,5 @@ $pattern = "/(((?(?C)0?=))(?!()0|.(?0)0)())/";
+ var_dump(preg_match($pattern, "hello"));
+ ?>
+ --EXPECTF--
+-Warning: preg_match(): Compilation failed: assertion expected after (?( or (?(?C) at offset 4 in %sbug75457.php on line %d
++Warning: preg_match(): Compilation failed: assertion expected after (?( or (?(?C) at offset %d in %sbug75457.php on line %d
+ bool(false)
+--
+2.20.1
+
diff --git a/php-bug76450.patch b/php-bug76450.patch
new file mode 100644
index 0000000..e745e42
--- /dev/null
+++ b/php-bug76450.patch
@@ -0,0 +1,278 @@
+From b671a8dd887ae7f661f6233e734179e8bca3daf6 Mon Sep 17 00:00:00 2001
+From: sim1984 <sim-mail@list.ru>
+Date: Mon, 25 Jun 2018 21:35:51 +0300
+Subject: [PATCH 3/8] Fix bug #76488 Memory leak when fetching a BLOB field
+
+Add a phpt test
+
+(cherry picked from commit 3847a6fcb63c362548e9434b195232f2dcf7a6c7)
+---
+ ext/pdo_firebird/firebird_statement.c | 2 +-
+ ext/pdo_firebird/tests/bug_76488.phpt | 32 +++++++++++++++++++++++++++
+ 2 files changed, 33 insertions(+), 1 deletion(-)
+ create mode 100644 ext/pdo_firebird/tests/bug_76488.phpt
+
+diff --git a/ext/pdo_firebird/firebird_statement.c b/ext/pdo_firebird/firebird_statement.c
+index 3feeedf39f..88be6da369 100644
+--- a/ext/pdo_firebird/firebird_statement.c
++++ b/ext/pdo_firebird/firebird_statement.c
+@@ -294,7 +294,7 @@ static int firebird_fetch_blob(pdo_stmt_t *stmt, int colno, char **ptr, /* {{{ *
+ unsigned short seg_len;
+ ISC_STATUS stat;
+
+- *ptr = S->fetch_buf[colno] = erealloc(*ptr, *len+1);
++ *ptr = S->fetch_buf[colno] = erealloc(S->fetch_buf[colno], *len+1);
+
+ for (cur_len = stat = 0; (!stat || stat == isc_segment) && cur_len < *len; cur_len += seg_len) {
+
+diff --git a/ext/pdo_firebird/tests/bug_76488.phpt b/ext/pdo_firebird/tests/bug_76488.phpt
+new file mode 100644
+index 0000000000..dba6734c28
+--- /dev/null
++++ b/ext/pdo_firebird/tests/bug_76488.phpt
+@@ -0,0 +1,32 @@
++--TEST--
++PDO_Firebird: Bug #76488 Memory leak when fetching a BLOB field
++--SKIPIF--
++<?php if (!extension_loaded('interbase') || !extension_loaded('pdo_firebird')) die('skip'); ?>
++--FILE--
++<?php
++require 'testdb.inc';
++$dbh = new PDO('firebird:dbname='.$test_base, $user, $password) or die;
++
++$sql = '
++with recursive r(n) as (
++ select 1 from rdb$database
++ union all
++ select n+1 from r where n < 1000
++)
++select n,
++ cast(lpad(\'A\', 8000, \'A\') as BLOB sub_type TEXT) as SRC
++from r
++';
++
++ for ($i = 0; $i < 10; $i++) {
++ $sth = $dbh->prepare($sql);
++ $sth->execute();
++ $rows = $sth->fetchAll();
++ unset($rows);
++ unset($sth);
++ }
++ unset($dbh);
++ echo "OK";
++?>
++--EXPECT--
++OK
+\ No newline at end of file
+--
+2.31.1
+
+From 9a58cd2ba3d99f5312966566a3632b197b676830 Mon Sep 17 00:00:00 2001
+From: "Christoph M. Becker" <cmbecker69@gmx.de>
+Date: Wed, 5 May 2021 12:42:17 +0200
+Subject: [PATCH 4/8] Fix #76452: Crash while parsing blob data in
+ firebird_fetch_blob
+
+We need to prevent integer overflow when calling `erealloc()` with
+`len+1`.
+
+(cherry picked from commit 286162e9b03071c4308e7e92597bca4239f49d89)
+---
+ ext/pdo_firebird/firebird_statement.c | 5 +++++
+ ext/pdo_firebird/tests/bug_76452.data | Bin 0 -> 856 bytes
+ ext/pdo_firebird/tests/bug_76452.phpt | 31 ++++++++++++++++++++++++++
+ 3 files changed, 36 insertions(+)
+ create mode 100644 ext/pdo_firebird/tests/bug_76452.data
+ create mode 100644 ext/pdo_firebird/tests/bug_76452.phpt
+
+diff --git a/ext/pdo_firebird/firebird_statement.c b/ext/pdo_firebird/firebird_statement.c
+index 88be6da369..fde897186d 100644
+--- a/ext/pdo_firebird/firebird_statement.c
++++ b/ext/pdo_firebird/firebird_statement.c
+@@ -294,6 +294,11 @@ static int firebird_fetch_blob(pdo_stmt_t *stmt, int colno, char **ptr, /* {{{ *
+ unsigned short seg_len;
+ ISC_STATUS stat;
+
++ /* prevent overflow */
++ if (*len == ZEND_ULONG_MAX) {
++ result = 0;
++ goto fetch_blob_end;
++ }
+ *ptr = S->fetch_buf[colno] = erealloc(S->fetch_buf[colno], *len+1);
+
+ for (cur_len = stat = 0; (!stat || stat == isc_segment) && cur_len < *len; cur_len += seg_len) {
+
+From 7b11e10fa679a575ca61e5bcd66db68193a3b2fb Mon Sep 17 00:00:00 2001
+From: "Christoph M. Becker" <cmbecker69@gmx.de>
+Date: Fri, 30 Apr 2021 14:10:50 +0200
+Subject: [PATCH 5/8] Fix #76450: SIGSEGV in firebird_stmt_execute
+
+We need to verify that the `result_size` is not larger than our buffer,
+and also should make sure that the `len` which is passed to
+`isc_vax_integer()` has a permissible value; otherwise we bail out.
+
+(cherry picked from commit bcbf8aa0c96d8d9e81ec3428232485555fae0b37)
+---
+ ext/pdo_firebird/firebird_statement.c | 7 +++++++
+ ext/pdo_firebird/tests/bug_76450.data | Bin 0 -> 464 bytes
+ ext/pdo_firebird/tests/bug_76450.phpt | 29 ++++++++++++++++++++++++++
+ 3 files changed, 36 insertions(+)
+ create mode 100644 ext/pdo_firebird/tests/bug_76450.data
+ create mode 100644 ext/pdo_firebird/tests/bug_76450.phpt
+
+diff --git a/ext/pdo_firebird/firebird_statement.c b/ext/pdo_firebird/firebird_statement.c
+index fde897186d..537f6f4038 100644
+--- a/ext/pdo_firebird/firebird_statement.c
++++ b/ext/pdo_firebird/firebird_statement.c
+@@ -133,8 +133,14 @@ static int firebird_stmt_execute(pdo_stmt_t *stmt) /* {{{ */
+ }
+ if (result[0] == isc_info_sql_records) {
+ unsigned i = 3, result_size = isc_vax_integer(&result[1], 2);
++ if (result_size > sizeof(result)) {
++ goto error;
++ }
+ while (result[i] != isc_info_end && i < result_size) {
+ short len = (short) isc_vax_integer(&result[i + 1], 2);
++ if (len != 1 && len != 2 && len != 4) {
++ goto error;
++ }
+ if (result[i] != isc_info_req_select_count) {
+ affected_rows += isc_vax_integer(&result[i + 3], len);
+ }
+@@ -158,6 +164,7 @@ static int firebird_stmt_execute(pdo_stmt_t *stmt) /* {{{ */
+ return 1;
+ } while (0);
+
++error:
+ RECORD_ERROR(stmt);
+
+ return 0;
+
+From 5952ac3d2e87d5f00a32f28d6f66209955e6e777 Mon Sep 17 00:00:00 2001
+From: "Christoph M. Becker" <cmbecker69@gmx.de>
+Date: Fri, 30 Apr 2021 13:53:21 +0200
+Subject: [PATCH 6/8] Fix #76449: SIGSEGV in firebird_handle_doer
+
+We need to verify that the `result_size` is not larger than our buffer,
+and also should make sure that the `len` which is passed to
+`isc_vax_integer()` has a permissible value; otherwise we bail out.
+
+(cherry picked from commit 08da7c73726f7b86b67d6f0ff87c73c585a7834a)
+---
+ ext/pdo_firebird/firebird_driver.c | 9 +++++++++
+ ext/pdo_firebird/tests/bug_76449.data | Bin 0 -> 464 bytes
+ ext/pdo_firebird/tests/bug_76449.phpt | 23 +++++++++++++++++++++++
+ 3 files changed, 32 insertions(+)
+ create mode 100644 ext/pdo_firebird/tests/bug_76449.data
+ create mode 100644 ext/pdo_firebird/tests/bug_76449.phpt
+
+diff --git a/ext/pdo_firebird/firebird_driver.c b/ext/pdo_firebird/firebird_driver.c
+index 166fb13d43..46699d51d4 100644
+--- a/ext/pdo_firebird/firebird_driver.c
++++ b/ext/pdo_firebird/firebird_driver.c
+@@ -253,8 +253,17 @@ static zend_long firebird_handle_doer(pdo_dbh_t *dbh, const char *sql, size_t sq
+ if (result[0] == isc_info_sql_records) {
+ unsigned i = 3, result_size = isc_vax_integer(&result[1],2);
+
++ if (result_size > sizeof(result)) {
++ ret = -1;
++ goto free_statement;
++ }
+ while (result[i] != isc_info_end && i < result_size) {
+ short len = (short)isc_vax_integer(&result[i+1],2);
++ /* bail out on bad len */
++ if (len != 1 && len != 2 && len != 4) {
++ ret = -1;
++ goto free_statement;
++ }
+ if (result[i] != isc_info_req_select_count) {
+ ret += isc_vax_integer(&result[i+3],len);
+ }
+
+From a1793d85e89a0c33b5496beec204ef3491af4bdc Mon Sep 17 00:00:00 2001
+From: "Christoph M. Becker" <cmbecker69@gmx.de>
+Date: Thu, 29 Apr 2021 15:26:22 +0200
+Subject: [PATCH 7/8] Fix #76448: Stack buffer overflow in firebird_info_cb
+
+We ensure not to overflow the stack allocated buffer by using `strlcat`.
+
+(cherry picked from commit 67afa32541ebc4abbf633cb1e7e879b2fbb616ad)
+---
+ ext/pdo_firebird/firebird_driver.c | 8 +++++---
+ ext/pdo_firebird/tests/bug_76448.data | Bin 0 -> 749 bytes
+ ext/pdo_firebird/tests/bug_76448.phpt | 23 +++++++++++++++++++++++
+ 3 files changed, 28 insertions(+), 3 deletions(-)
+ create mode 100644 ext/pdo_firebird/tests/bug_76448.data
+ create mode 100644 ext/pdo_firebird/tests/bug_76448.phpt
+
+diff --git a/ext/pdo_firebird/firebird_driver.c b/ext/pdo_firebird/firebird_driver.c
+index 46699d51d4..48808d6f3d 100644
+--- a/ext/pdo_firebird/firebird_driver.c
++++ b/ext/pdo_firebird/firebird_driver.c
+@@ -556,14 +556,16 @@ static int firebird_handle_set_attribute(pdo_dbh_t *dbh, zend_long attr, zval *v
+ }
+ /* }}} */
+
++#define INFO_BUF_LEN 512
++
+ /* callback to used to report database server info */
+ static void firebird_info_cb(void *arg, char const *s) /* {{{ */
+ {
+ if (arg) {
+ if (*(char*)arg) { /* second call */
+- strcat(arg, " ");
++ strlcat(arg, " ", INFO_BUF_LEN);
+ }
+- strcat(arg, s);
++ strlcat(arg, s, INFO_BUF_LEN);
+ }
+ }
+ /* }}} */
+@@ -574,7 +576,7 @@ static int firebird_handle_get_attribute(pdo_dbh_t *dbh, zend_long attr, zval *v
+ pdo_firebird_db_handle *H = (pdo_firebird_db_handle *)dbh->driver_data;
+
+ switch (attr) {
+- char tmp[512];
++ char tmp[INFO_BUF_LEN];
+
+ case PDO_ATTR_AUTOCOMMIT:
+ ZVAL_LONG(val,dbh->auto_commit);
+
+From 4faea6cc54c742245639ba2736b199c711f2a77b Mon Sep 17 00:00:00 2001
+From: Stanislav Malyshev <stas@php.net>
+Date: Sun, 20 Jun 2021 22:20:38 -0700
+Subject: [PATCH 8/8] Update NEWS
+
+(cherry picked from commit c68a687566591e2268f35d124a90c7d556ce968b)
+(cherry picked from commit 7598733c51af30611aa64e456c9a777069d2efb9)
+---
+ NEWS | 13 +++++++++++++
+ 1 file changed, 13 insertions(+)
+
+diff --git a/NEWS b/NEWS
+index 9eff4bd7ae..861dbd7dd5 100644
+--- a/NEWS
++++ b/NEWS
+@@ -1,6 +1,19 @@
+ PHP NEWS
+ |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
+
++Backported from 7.3.29
++
++- Core:
++ . Fixed #81122: SSRF bypass in FILTER_VALIDATE_URL. (CVE-2021-21705) (cmb)
++
++- PDO_Firebird:
++ . Fixed #76448: Stack buffer overflow in firebird_info_cb. (CVE-2021-21704)
++ (cmb)
++ . Fixed #76449: SIGSEGV in firebird_handle_doer. (CVE-2021-21704) (cmb)
++ . Fixed #76450: SIGSEGV in firebird_stmt_execute. (CVE-2021-21704) (cmb)
++ . Fixed #76452: Crash while parsing blob data in firebird_fetch_blob.
++ (CVE-2021-21704) (cmb)
++
+ Backported from 7.3.28
+
+ - Imap:
+--
+2.31.1
+
diff --git a/php-bug77423.patch b/php-bug77423.patch
new file mode 100644
index 0000000..cbe84df
--- /dev/null
+++ b/php-bug77423.patch
@@ -0,0 +1,431 @@
+From 6d88ee38ec98c500c4a596307ce6b3e83becd0e9 Mon Sep 17 00:00:00 2001
+From: "Christoph M. Becker" <cmbecker69@gmx.de>
+Date: Wed, 13 May 2020 09:36:52 +0200
+Subject: [PATCH 1/2] Fix #77423: parse_url() will deliver a wrong host to user
+
+To avoid that `parse_url()` returns an erroneous host, which would be
+valid for `FILTER_VALIDATE_URL`, we make sure that only userinfo which
+is valid according to RFC 3986 is treated as such.
+
+For consistency with the existing url parsing code, we use ctype
+functions, although that is not necessarily correct.
+
+(cherry picked from commit 2d3d72412a6734e19a38ed10f385227a6238e4a6)
+(cherry picked from commit 31459f94f2780e748e15d5c2951ba20adbba2366)
+---
+ ext/standard/tests/strings/url_t.phpt | 6 ++--
+ ext/standard/tests/url/bug77423.phpt | 30 +++++++++++++++++++
+ .../tests/url/parse_url_basic_001.phpt | 6 ++--
+ .../tests/url/parse_url_basic_003.phpt | 2 +-
+ .../tests/url/parse_url_basic_005.phpt | 2 +-
+ ext/standard/url.c | 21 +++++++++++++
+ 6 files changed, 57 insertions(+), 10 deletions(-)
+ create mode 100644 ext/standard/tests/url/bug77423.phpt
+
+diff --git a/ext/standard/tests/strings/url_t.phpt b/ext/standard/tests/strings/url_t.phpt
+index e172061ec2..80e164a08e 100644
+--- a/ext/standard/tests/strings/url_t.phpt
++++ b/ext/standard/tests/strings/url_t.phpt
+@@ -575,15 +575,13 @@ $sample_urls = array (
+ string(16) "some_page_ref123"
+ }
+
+---> http://secret@hideout@www.php.net:80/index.php?test=1&test2=char&test3=mixesCI#some_page_ref123: array(7) {
++--> http://secret@hideout@www.php.net:80/index.php?test=1&test2=char&test3=mixesCI#some_page_ref123: array(6) {
+ ["scheme"]=>
+ string(4) "http"
+ ["host"]=>
+- string(11) "www.php.net"
++ string(26) "secret@hideout@www.php.net"
+ ["port"]=>
+ int(80)
+- ["user"]=>
+- string(14) "secret@hideout"
+ ["path"]=>
+ string(10) "/index.php"
+ ["query"]=>
+diff --git a/ext/standard/tests/url/bug77423.phpt b/ext/standard/tests/url/bug77423.phpt
+new file mode 100644
+index 0000000000..be03fe95e2
+--- /dev/null
++++ b/ext/standard/tests/url/bug77423.phpt
+@@ -0,0 +1,30 @@
++--TEST--
++Bug #77423 (parse_url() will deliver a wrong host to user)
++--FILE--
++<?php
++$urls = array(
++ "http://php.net\@aliyun.com/aaa.do",
++ "https://example.com\uFF03@bing.com",
++);
++foreach ($urls as $url) {
++ var_dump(filter_var($url, FILTER_VALIDATE_URL));
++ var_dump(parse_url($url));
++}
++?>
++--EXPECT--
++bool(false)
++array(3) {
++ ["scheme"]=>
++ string(4) "http"
++ ["host"]=>
++ string(19) "php.net\@aliyun.com"
++ ["path"]=>
++ string(7) "/aaa.do"
++}
++bool(false)
++array(2) {
++ ["scheme"]=>
++ string(5) "https"
++ ["host"]=>
++ string(26) "example.com\uFF03@bing.com"
++}
+diff --git a/ext/standard/tests/url/parse_url_basic_001.phpt b/ext/standard/tests/url/parse_url_basic_001.phpt
+index e468066a42..c9e9d32de0 100644
+--- a/ext/standard/tests/url/parse_url_basic_001.phpt
++++ b/ext/standard/tests/url/parse_url_basic_001.phpt
+@@ -507,15 +507,13 @@ echo "Done";
+ string(16) "some_page_ref123"
+ }
+
+---> http://secret@hideout@www.php.net:80/index.php?test=1&test2=char&test3=mixesCI#some_page_ref123: array(7) {
++--> http://secret@hideout@www.php.net:80/index.php?test=1&test2=char&test3=mixesCI#some_page_ref123: array(6) {
+ ["scheme"]=>
+ string(4) "http"
+ ["host"]=>
+- string(11) "www.php.net"
++ string(26) "secret@hideout@www.php.net"
+ ["port"]=>
+ int(80)
+- ["user"]=>
+- string(14) "secret@hideout"
+ ["path"]=>
+ string(10) "/index.php"
+ ["query"]=>
+diff --git a/ext/standard/tests/url/parse_url_basic_003.phpt b/ext/standard/tests/url/parse_url_basic_003.phpt
+index 70dc4bb90b..431de27009 100644
+--- a/ext/standard/tests/url/parse_url_basic_003.phpt
++++ b/ext/standard/tests/url/parse_url_basic_003.phpt
+@@ -68,7 +68,7 @@ echo "Done";
+ --> http://secret:@www.php.net/index.php?test=1&test2=char&test3=mixesCI#some_page_ref123 : string(11) "www.php.net"
+ --> http://:hideout@www.php.net:80/index.php?test=1&test2=char&test3=mixesCI#some_page_ref123 : string(11) "www.php.net"
+ --> http://secret:hideout@www.php.net/index.php?test=1&test2=char&test3=mixesCI#some_page_ref123 : string(11) "www.php.net"
+---> http://secret@hideout@www.php.net:80/index.php?test=1&test2=char&test3=mixesCI#some_page_ref123 : string(11) "www.php.net"
++--> http://secret@hideout@www.php.net:80/index.php?test=1&test2=char&test3=mixesCI#some_page_ref123 : string(26) "secret@hideout@www.php.net"
+ --> http://secret:hid:out@www.php.net:80/index.php?test=1&test2=char&test3=mixesCI#some_page_ref123 : string(11) "www.php.net"
+ --> nntp://news.php.net : string(12) "news.php.net"
+ --> ftp://ftp.gnu.org/gnu/glic/glibc.tar.gz : string(11) "ftp.gnu.org"
+diff --git a/ext/standard/tests/url/parse_url_basic_005.phpt b/ext/standard/tests/url/parse_url_basic_005.phpt
+index b2ca06ff96..b2c1a1d6dd 100644
+--- a/ext/standard/tests/url/parse_url_basic_005.phpt
++++ b/ext/standard/tests/url/parse_url_basic_005.phpt
+@@ -68,7 +68,7 @@ echo "Done";
+ --> http://secret:@www.php.net/index.php?test=1&test2=char&test3=mixesCI#some_page_ref123 : string(6) "secret"
+ --> http://:hideout@www.php.net:80/index.php?test=1&test2=char&test3=mixesCI#some_page_ref123 : string(0) ""
+ --> http://secret:hideout@www.php.net/index.php?test=1&test2=char&test3=mixesCI#some_page_ref123 : string(6) "secret"
+---> http://secret@hideout@www.php.net:80/index.php?test=1&test2=char&test3=mixesCI#some_page_ref123 : string(14) "secret@hideout"
++--> http://secret@hideout@www.php.net:80/index.php?test=1&test2=char&test3=mixesCI#some_page_ref123 : NULL
+ --> http://secret:hid:out@www.php.net:80/index.php?test=1&test2=char&test3=mixesCI#some_page_ref123 : string(6) "secret"
+ --> nntp://news.php.net : NULL
+ --> ftp://ftp.gnu.org/gnu/glic/glibc.tar.gz : NULL
+diff --git a/ext/standard/url.c b/ext/standard/url.c
+index a9cc06b1c0..3bb62c7da3 100644
+--- a/ext/standard/url.c
++++ b/ext/standard/url.c
+@@ -92,6 +92,22 @@ PHPAPI php_url *php_url_parse(char const *str)
+ return php_url_parse_ex(str, strlen(str));
+ }
+
++static int is_userinfo_valid(const char *str, size_t len)
++{
++ char *valid = "-._~!$&'()*+,;=:";
++ char *p = str;
++ while (p - str < len) {
++ if (isalpha(*p) || isdigit(*p) || strchr(valid, *p)) {
++ p++;
++ } else if (*p == '%' && p - str <= len - 3 && isdigit(*(p+1)) && isxdigit(*(p+2))) {
++ p += 3;
++ } else {
++ return 0;
++ }
++ }
++ return 1;
++}
++
+ /* {{{ php_url_parse
+ */
+ PHPAPI php_url *php_url_parse_ex(char const *str, size_t length)
+@@ -235,13 +251,18 @@ PHPAPI php_url *php_url_parse_ex(char const *str, size_t length)
+ ret->pass = estrndup(pp, (p-pp));
+ php_replace_controlchars_ex(ret->pass, (p-pp));
+ } else {
++ if (!is_userinfo_valid(s, p-s)) {
++ goto check_port;
++ }
+ ret->user = estrndup(s, (p-s));
+ php_replace_controlchars_ex(ret->user, (p-s));
++
+ }
+
+ s = p + 1;
+ }
+
++check_port:
+ /* check for port */
+ if (s < ue && *s == '[' && *(e-1) == ']') {
+ /* Short circuit portscan,
+--
+2.29.2
+
+From 745ba68440670440bdddd6cfb7e0f02eacef0f29 Mon Sep 17 00:00:00 2001
+From: Remi Collet <remi@remirepo.net>
+Date: Mon, 4 Jan 2021 14:20:55 +0100
+Subject: [PATCH 2/2] NEWS
+
+(cherry picked from commit c784479182b92b9b3b96a7be42aa86a6c6d0b693)
+---
+ NEWS | 6 ++++++
+ 1 file changed, 6 insertions(+)
+
+diff --git a/NEWS b/NEWS
+index 47848d24b7..e328fd39c0 100644
+--- a/NEWS
++++ b/NEWS
+@@ -1,6 +1,12 @@
+ PHP NEWS
+ |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
+
++Backported from 7.3.26
++
++- Standard:
++ . Fixed bug #77423 (FILTER_VALIDATE_URL accepts URLs with invalid userinfo).
++ (CVE-2020-7071) (cmb)
++
+ Backported from 7.2.34
+
+ - Core:
+--
+2.29.2
+
+From efb6c49f08314aca84733b0e83d72cd20c8e0015 Mon Sep 17 00:00:00 2001
+From: "Christoph M. Becker" <cmbecker69@gmx.de>
+Date: Tue, 19 Jan 2021 11:23:25 +0100
+Subject: [PATCH] Alternative fix for bug 77423
+
+That bug report originally was about `parse_url()` misbehaving, but the
+security aspect was actually only regarding `FILTER_VALIDATE_URL`.
+Since the changes to `parse_url_ex()` apparently affect userland code
+which is relying on the sloppy URL parsing[1], this alternative
+restores the old parsing behavior, but ensures that the userinfo is
+checked for correctness for `FILTER_VALIDATE_URL`.
+
+[1] <https://github.com/php/php-src/commit/5174de7cd33c3d4fa591c9c93859ff9989b07e8c#commitcomment-45967652>
+
+(cherry picked from commit 4a89e726bd4d0571991dc22a9a1ad4509e8fe347)
+(cherry picked from commit 9c673083cd46ee2a954a62156acbe4b6e657c048)
+(cherry picked from commit 356f7008f36da60ec9794d48c55d117f1dd31903)
+(cherry picked from commit b5d4f109bab648c0d07273d2a52a5f2560e7832b)
+---
+ ext/filter/logical_filters.c | 25 +++++++++++++++++++
+ .../tests/url => filter/tests}/bug77423.phpt | 15 -----------
+ ext/standard/tests/strings/url_t.phpt | 6 +++--
+ .../tests/url/parse_url_basic_001.phpt | 6 +++--
+ .../tests/url/parse_url_basic_003.phpt | 2 +-
+ .../tests/url/parse_url_basic_005.phpt | 2 +-
+ ext/standard/url.c | 21 ----------------
+ 7 files changed, 35 insertions(+), 42 deletions(-)
+ rename ext/{standard/tests/url => filter/tests}/bug77423.phpt (53%)
+
+diff --git a/ext/filter/logical_filters.c b/ext/filter/logical_filters.c
+index a0fed76fce..22868fd8c1 100644
+--- a/ext/filter/logical_filters.c
++++ b/ext/filter/logical_filters.c
+@@ -514,6 +514,24 @@ void php_filter_validate_domain(PHP_INPUT_FILTER_PARAM_DECL) /* {{{ */
+ }
+ /* }}} */
+
++static int is_userinfo_valid(char *str)
++{
++ const char *valid = "-._~!$&'()*+,;=:";
++ const char *p = str;
++ size_t len = strlen(str);
++
++ while (p - str < len) {
++ if (isalpha(*p) || isdigit(*p) || strchr(valid, *p)) {
++ p++;
++ } else if (*p == '%' && p - str <= len - 3 && isdigit(*(p+1)) && isxdigit(*(p+2))) {
++ p += 3;
++ } else {
++ return 0;
++ }
++ }
++ return 1;
++}
++
+ void php_filter_validate_url(PHP_INPUT_FILTER_PARAM_DECL) /* {{{ */
+ {
+ php_url *url;
+@@ -568,6 +586,13 @@ bad_url:
+ php_url_free(url);
+ RETURN_VALIDATION_FAILED
+ }
++
++ if (url->user != NULL && !is_userinfo_valid(url->user)) {
++ php_url_free(url);
++ RETURN_VALIDATION_FAILED
++
++ }
++
+ php_url_free(url);
+ }
+ /* }}} */
+diff --git a/ext/standard/tests/url/bug77423.phpt b/ext/filter/tests/bug77423.phpt
+similarity index 53%
+rename from ext/standard/tests/url/bug77423.phpt
+rename to ext/filter/tests/bug77423.phpt
+index be03fe95e2..761c7c359a 100644
+--- a/ext/standard/tests/url/bug77423.phpt
++++ b/ext/filter/tests/bug77423.phpt
+@@ -8,23 +8,8 @@ $urls = array(
+ );
+ foreach ($urls as $url) {
+ var_dump(filter_var($url, FILTER_VALIDATE_URL));
+- var_dump(parse_url($url));
+ }
+ ?>
+ --EXPECT--
+ bool(false)
+-array(3) {
+- ["scheme"]=>
+- string(4) "http"
+- ["host"]=>
+- string(19) "php.net\@aliyun.com"
+- ["path"]=>
+- string(7) "/aaa.do"
+-}
+ bool(false)
+-array(2) {
+- ["scheme"]=>
+- string(5) "https"
+- ["host"]=>
+- string(26) "example.com\uFF03@bing.com"
+-}
+diff --git a/ext/standard/tests/strings/url_t.phpt b/ext/standard/tests/strings/url_t.phpt
+index 80e164a08e..e172061ec2 100644
+--- a/ext/standard/tests/strings/url_t.phpt
++++ b/ext/standard/tests/strings/url_t.phpt
+@@ -575,13 +575,15 @@ $sample_urls = array (
+ string(16) "some_page_ref123"
+ }
+
+---> http://secret@hideout@www.php.net:80/index.php?test=1&test2=char&test3=mixesCI#some_page_ref123: array(6) {
++--> http://secret@hideout@www.php.net:80/index.php?test=1&test2=char&test3=mixesCI#some_page_ref123: array(7) {
+ ["scheme"]=>
+ string(4) "http"
+ ["host"]=>
+- string(26) "secret@hideout@www.php.net"
++ string(11) "www.php.net"
+ ["port"]=>
+ int(80)
++ ["user"]=>
++ string(14) "secret@hideout"
+ ["path"]=>
+ string(10) "/index.php"
+ ["query"]=>
+diff --git a/ext/standard/tests/url/parse_url_basic_001.phpt b/ext/standard/tests/url/parse_url_basic_001.phpt
+index c9e9d32de0..e468066a42 100644
+--- a/ext/standard/tests/url/parse_url_basic_001.phpt
++++ b/ext/standard/tests/url/parse_url_basic_001.phpt
+@@ -507,13 +507,15 @@ echo "Done";
+ string(16) "some_page_ref123"
+ }
+
+---> http://secret@hideout@www.php.net:80/index.php?test=1&test2=char&test3=mixesCI#some_page_ref123: array(6) {
++--> http://secret@hideout@www.php.net:80/index.php?test=1&test2=char&test3=mixesCI#some_page_ref123: array(7) {
+ ["scheme"]=>
+ string(4) "http"
+ ["host"]=>
+- string(26) "secret@hideout@www.php.net"
++ string(11) "www.php.net"
+ ["port"]=>
+ int(80)
++ ["user"]=>
++ string(14) "secret@hideout"
+ ["path"]=>
+ string(10) "/index.php"
+ ["query"]=>
+diff --git a/ext/standard/tests/url/parse_url_basic_003.phpt b/ext/standard/tests/url/parse_url_basic_003.phpt
+index 431de27009..70dc4bb90b 100644
+--- a/ext/standard/tests/url/parse_url_basic_003.phpt
++++ b/ext/standard/tests/url/parse_url_basic_003.phpt
+@@ -68,7 +68,7 @@ echo "Done";
+ --> http://secret:@www.php.net/index.php?test=1&test2=char&test3=mixesCI#some_page_ref123 : string(11) "www.php.net"
+ --> http://:hideout@www.php.net:80/index.php?test=1&test2=char&test3=mixesCI#some_page_ref123 : string(11) "www.php.net"
+ --> http://secret:hideout@www.php.net/index.php?test=1&test2=char&test3=mixesCI#some_page_ref123 : string(11) "www.php.net"
+---> http://secret@hideout@www.php.net:80/index.php?test=1&test2=char&test3=mixesCI#some_page_ref123 : string(26) "secret@hideout@www.php.net"
++--> http://secret@hideout@www.php.net:80/index.php?test=1&test2=char&test3=mixesCI#some_page_ref123 : string(11) "www.php.net"
+ --> http://secret:hid:out@www.php.net:80/index.php?test=1&test2=char&test3=mixesCI#some_page_ref123 : string(11) "www.php.net"
+ --> nntp://news.php.net : string(12) "news.php.net"
+ --> ftp://ftp.gnu.org/gnu/glic/glibc.tar.gz : string(11) "ftp.gnu.org"
+diff --git a/ext/standard/tests/url/parse_url_basic_005.phpt b/ext/standard/tests/url/parse_url_basic_005.phpt
+index b2c1a1d6dd..b2ca06ff96 100644
+--- a/ext/standard/tests/url/parse_url_basic_005.phpt
++++ b/ext/standard/tests/url/parse_url_basic_005.phpt
+@@ -68,7 +68,7 @@ echo "Done";
+ --> http://secret:@www.php.net/index.php?test=1&test2=char&test3=mixesCI#some_page_ref123 : string(6) "secret"
+ --> http://:hideout@www.php.net:80/index.php?test=1&test2=char&test3=mixesCI#some_page_ref123 : string(0) ""
+ --> http://secret:hideout@www.php.net/index.php?test=1&test2=char&test3=mixesCI#some_page_ref123 : string(6) "secret"
+---> http://secret@hideout@www.php.net:80/index.php?test=1&test2=char&test3=mixesCI#some_page_ref123 : NULL
++--> http://secret@hideout@www.php.net:80/index.php?test=1&test2=char&test3=mixesCI#some_page_ref123 : string(14) "secret@hideout"
+ --> http://secret:hid:out@www.php.net:80/index.php?test=1&test2=char&test3=mixesCI#some_page_ref123 : string(6) "secret"
+ --> nntp://news.php.net : NULL
+ --> ftp://ftp.gnu.org/gnu/glic/glibc.tar.gz : NULL
+diff --git a/ext/standard/url.c b/ext/standard/url.c
+index 3bb62c7da3..a9cc06b1c0 100644
+--- a/ext/standard/url.c
++++ b/ext/standard/url.c
+@@ -92,22 +92,6 @@ PHPAPI php_url *php_url_parse(char const *str)
+ return php_url_parse_ex(str, strlen(str));
+ }
+
+-static int is_userinfo_valid(const char *str, size_t len)
+-{
+- char *valid = "-._~!$&'()*+,;=:";
+- char *p = str;
+- while (p - str < len) {
+- if (isalpha(*p) || isdigit(*p) || strchr(valid, *p)) {
+- p++;
+- } else if (*p == '%' && p - str <= len - 3 && isdigit(*(p+1)) && isxdigit(*(p+2))) {
+- p += 3;
+- } else {
+- return 0;
+- }
+- }
+- return 1;
+-}
+-
+ /* {{{ php_url_parse
+ */
+ PHPAPI php_url *php_url_parse_ex(char const *str, size_t length)
+@@ -251,18 +235,13 @@ PHPAPI php_url *php_url_parse_ex(char const *str, size_t length)
+ ret->pass = estrndup(pp, (p-pp));
+ php_replace_controlchars_ex(ret->pass, (p-pp));
+ } else {
+- if (!is_userinfo_valid(s, p-s)) {
+- goto check_port;
+- }
+ ret->user = estrndup(s, (p-s));
+ php_replace_controlchars_ex(ret->user, (p-s));
+-
+ }
+
+ s = p + 1;
+ }
+
+-check_port:
+ /* check for port */
+ if (s < ue && *s == '[' && *(e-1) == ']') {
+ /* Short circuit portscan,
+--
+2.29.2
+
diff --git a/php-bug77569.patch b/php-bug77569.patch
new file mode 100644
index 0000000..d030342
--- /dev/null
+++ b/php-bug77569.patch
@@ -0,0 +1,106 @@
+From 2a58d1391f2c46e6404dae42b9b64505f94323da Mon Sep 17 00:00:00 2001
+From: "Christoph M. Becker" <cmbecker69@gmx.de>
+Date: Thu, 13 Feb 2020 15:13:26 +0100
+Subject: [PATCH 1/5] Fix #77569: Write Acess Violation in DomImplementation
+
+We must not assume that the zval IS_STRING.
+
+(cherry picked from commit cec8b24c848bab8562c82422f3692c193f0afcdb)
+---
+ NEWS | 6 ++++++
+ ext/dom/document.c | 2 +-
+ ext/dom/tests/bug77569.phpt | 14 ++++++++++++++
+ 3 files changed, 21 insertions(+), 1 deletion(-)
+ create mode 100644 ext/dom/tests/bug77569.phpt
+
+diff --git a/NEWS b/NEWS
+index a1dc8a81c3..5a6549e834 100644
+--- a/NEWS
++++ b/NEWS
+@@ -1,6 +1,12 @@
+ PHP NEWS
+ |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
+
++Backported from 7.2.28
++
++- DOM:
++ . Fixed bug #77569: (Write Acess Violation in DomImplementation). (Nikita,
++ cmb)
++
+ Backported from 7.2.27
+
+ - Mbstring:
+diff --git a/ext/dom/document.c b/ext/dom/document.c
+index a884087f5f..29ef0a8cab 100644
+--- a/ext/dom/document.c
++++ b/ext/dom/document.c
+@@ -341,7 +341,7 @@ int dom_document_encoding_write(dom_object *obj, zval *newval)
+
+ str = zval_get_string(newval);
+
+- handler = xmlFindCharEncodingHandler(Z_STRVAL_P(newval));
++ handler = xmlFindCharEncodingHandler(ZSTR_VAL(str));
+
+ if (handler != NULL) {
+ xmlCharEncCloseFunc(handler);
+diff --git a/ext/dom/tests/bug77569.phpt b/ext/dom/tests/bug77569.phpt
+new file mode 100644
+index 0000000000..f0f3566708
+--- /dev/null
++++ b/ext/dom/tests/bug77569.phpt
+@@ -0,0 +1,14 @@
++--TEST--
++Bug #77569 (Write Acess Violation in DomImplementation)
++--SKIPIF--
++<?php
++if (!extension_loaded('dom')) die('skip dom extension not available');
++?>
++--FILE--
++<?php
++$imp = new DOMImplementation;
++$dom = $imp->createDocument("", "");
++$dom->encoding = null;
++?>
++--EXPECTF--
++Warning: main(): Invalid Document Encoding in %s on line %d
+--
+2.24.1
+
+From 47310971e97b5be294a793bee7415c82f24d72ec Mon Sep 17 00:00:00 2001
+From: "Christoph M. Becker" <cmbecker69@gmx.de>
+Date: Fri, 14 Feb 2020 09:21:13 +0100
+Subject: [PATCH 2/5] Fix typo in recent bugfix
+
+(cherry picked from commit 8308196c97418ba4c8381bed0962ae160623027a)
+---
+ NEWS | 2 +-
+ ext/dom/tests/bug77569.phpt | 2 +-
+ 2 files changed, 2 insertions(+), 2 deletions(-)
+
+diff --git a/NEWS b/NEWS
+index 5a6549e834..9467c98e33 100644
+--- a/NEWS
++++ b/NEWS
+@@ -4,7 +4,7 @@ PHP NEWS
+ Backported from 7.2.28
+
+ - DOM:
+- . Fixed bug #77569: (Write Acess Violation in DomImplementation). (Nikita,
++ . Fixed bug #77569: (Write Access Violation in DomImplementation). (Nikita,
+ cmb)
+
+ Backported from 7.2.27
+diff --git a/ext/dom/tests/bug77569.phpt b/ext/dom/tests/bug77569.phpt
+index f0f3566708..9eef2af65a 100644
+--- a/ext/dom/tests/bug77569.phpt
++++ b/ext/dom/tests/bug77569.phpt
+@@ -1,5 +1,5 @@
+ --TEST--
+-Bug #77569 (Write Acess Violation in DomImplementation)
++Bug #77569 (Write Access Violation in DomImplementation)
+ --SKIPIF--
+ <?php
+ if (!extension_loaded('dom')) die('skip dom extension not available');
+--
+2.24.1
+
diff --git a/php-bug78380.patch b/php-bug78380.patch
new file mode 100644
index 0000000..f25a780
--- /dev/null
+++ b/php-bug78380.patch
@@ -0,0 +1,47 @@
+From 2c8138bda7cb4a98ee34fad4815538dd463e57f9 Mon Sep 17 00:00:00 2001
+From: Stanislav Malyshev <stas@php.net>
+Date: Sat, 24 Aug 2019 23:11:45 -0700
+Subject: [PATCH 1/3] Fix CVE-2019-13224: don't allow different encodings for
+ onig_new_deluxe()
+
+Backport from https://github.com/kkos/oniguruma/commit/0f7f61ed1b7b697e283e37bd2d731d0bd57adb55
+
+(cherry picked from commit 1258303e66d8dede4f02347334b9f6576e98a21b)
+---
+ ext/mbstring/oniguruma/regext.c | 6 +++---
+ 1 file changed, 3 insertions(+), 3 deletions(-)
+
+diff --git a/ext/mbstring/oniguruma/regext.c b/ext/mbstring/oniguruma/regext.c
+index b1b957b40c..b108e638c6 100644
+--- a/ext/mbstring/oniguruma/regext.c
++++ b/ext/mbstring/oniguruma/regext.c
+@@ -29,6 +29,7 @@
+
+ #include "regint.h"
+
++#if 0
+ static void
+ conv_ext0be32(const UChar* s, const UChar* end, UChar* conv)
+ {
+@@ -158,6 +159,7 @@ conv_encoding(OnigEncoding from, OnigEncoding to, const UChar* s, const UChar* e
+
+ return ONIGERR_NOT_SUPPORTED_ENCODING_COMBINATION;
+ }
++#endif
+
+ extern int
+ onig_new_deluxe(regex_t** reg, const UChar* pattern, const UChar* pattern_end,
+@@ -169,9 +171,7 @@ onig_new_deluxe(regex_t** reg, const UChar* pattern, const UChar* pattern_end,
+ if (IS_NOT_NULL(einfo)) einfo->par = (UChar* )NULL;
+
+ if (ci->pattern_enc != ci->target_enc) {
+- r = conv_encoding(ci->pattern_enc, ci->target_enc, pattern, pattern_end,
+- &cpat, &cpat_end);
+- if (r) return r;
++ return ONIGERR_NOT_SUPPORTED_ENCODING_COMBINATION;
+ }
+ else {
+ cpat = (UChar* )pattern;
+--
+2.20.1
+
diff --git a/php-bug78599.patch b/php-bug78599.patch
new file mode 100644
index 0000000..106b080
--- /dev/null
+++ b/php-bug78599.patch
@@ -0,0 +1,53 @@
+From 6e705460ff4f02358b9fb037169c53f4103a21b7 Mon Sep 17 00:00:00 2001
+From: Jakub Zelenka <bukka@php.net>
+Date: Sat, 12 Oct 2019 15:56:16 +0100
+Subject: [PATCH] Fix bug #78599 (env_path_info underflow can lead to RCE)
+ (CVE-2019-11043)
+
+cheery-picked from ab061f95ca966731b1c84cf5b7b20155c0a1c06a
+without the test as tester not available
+---
+ sapi/fpm/fpm/fpm_main.c | 4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+diff --git a/sapi/fpm/fpm/fpm_main.c b/sapi/fpm/fpm/fpm_main.c
+index 695839cd9a..88c7c9f118 100644
+--- a/sapi/fpm/fpm/fpm_main.c
++++ b/sapi/fpm/fpm/fpm_main.c
+@@ -1208,8 +1208,8 @@ static void init_request_info(void)
+ path_info = script_path_translated + ptlen;
+ tflag = (slen != 0 && (!orig_path_info || strcmp(orig_path_info, path_info) != 0));
+ } else {
+- path_info = env_path_info ? env_path_info + pilen - slen : NULL;
+- tflag = (orig_path_info != path_info);
++ path_info = (env_path_info && pilen > slen) ? env_path_info + pilen - slen : NULL;
++ tflag = path_info && (orig_path_info != path_info);
+ }
+
+ if (tflag) {
+From 8df4c9426c4810699e9290382d4e60453caa96e2 Mon Sep 17 00:00:00 2001
+From: Remi Collet <remi@remirepo.net>
+Date: Tue, 22 Oct 2019 08:41:53 +0200
+Subject: [PATCH] add NEWS entry
+
+---
+ NEWS | 6 ++++++
+ 1 file changed, 6 insertions(+)
+
+diff --git a/NEWS b/NEWS
+index a3c0c90143..b5a736947b 100644
+--- a/NEWS
++++ b/NEWS
+@@ -1,6 +1,12 @@
+ PHP NEWS
+ |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
+
++Backported from 7.1.33
++
++- FPM:
++ . Fixed bug #78599 (env_path_info underflow in fpm_main.c can lead to RCE).
++ (CVE-2019-11043) (Jakub Zelenka)
++
+ Backported from 7.1.32
+
+ - mbstring:
diff --git a/php-bug78793.patch b/php-bug78793.patch
new file mode 100644
index 0000000..21d7a1d
--- /dev/null
+++ b/php-bug78793.patch
@@ -0,0 +1,62 @@
+From f71d4343a205d820e35a815d298a9bb3e92d49cd Mon Sep 17 00:00:00 2001
+From: Stanislav Malyshev <stas@php.net>
+Date: Mon, 16 Dec 2019 01:14:38 -0800
+Subject: [PATCH] Fix bug #78793
+
+(cherry picked from commit c14eb8de974fc8a4d74f3515424c293bc7a40fba)
+---
+ NEWS | 4 ++++
+ ext/exif/exif.c | 5 +++--
+ ext/exif/tests/bug78793.phpt | 12 ++++++++++++
+ 3 files changed, 19 insertions(+), 2 deletions(-)
+ create mode 100644 ext/exif/tests/bug78793.phpt
+
+diff --git a/NEWS b/NEWS
+index 39a2f43818..723cc69be6 100644
+--- a/NEWS
++++ b/NEWS
+@@ -13,6 +13,10 @@ Backported from 7.2.26
+ . Fixed bug #78863 (DirectoryIterator class silently truncates after a null
+ byte). (CVE-2019-11045). (cmb)
+
++- EXIF:
++ . Fixed bug #78793 (Use-after-free in exif parsing under memory sanitizer).
++ (CVE-2019-11050). (Nikita)
++
+ Backported from 7.1.33
+
+ - FPM:
+diff --git a/ext/exif/exif.c b/ext/exif/exif.c
+index 3f8dd907dc..a7da928800 100644
+--- a/ext/exif/exif.c
++++ b/ext/exif/exif.c
+@@ -2820,8 +2820,9 @@ static int exif_process_IFD_in_MAKERNOTE(image_info_type *ImageInfo, char * valu
+ }
+
+ for (de=0;de<NumDirEntries;de++) {
+- if (!exif_process_IFD_TAG(ImageInfo, dir_start + 2 + 12 * de,
+- offset_base, data_len, displacement, section_index, 0, maker_note->tag_table)) {
++ size_t offset = 2 + 12 * de;
++ if (!exif_process_IFD_TAG(ImageInfo, dir_start + offset,
++ offset_base, data_len - offset, displacement, section_index, 0, maker_note->tag_table)) {
+ return FALSE;
+ }
+ }
+diff --git a/ext/exif/tests/bug78793.phpt b/ext/exif/tests/bug78793.phpt
+new file mode 100644
+index 0000000000..033f255ace
+--- /dev/null
++++ b/ext/exif/tests/bug78793.phpt
+@@ -0,0 +1,12 @@
++--TEST--
++Bug #78793: Use-after-free in exif parsing under memory sanitizer
++--FILE--
++<?php
++$f = "ext/exif/tests/bug77950.tiff";
++for ($i = 0; $i < 10; $i++) {
++ @exif_read_data($f);
++}
++?>
++===DONE===
++--EXPECT--
++===DONE===
diff --git a/php-bug78862.patch b/php-bug78862.patch
new file mode 100644
index 0000000..1ecc1f5
--- /dev/null
+++ b/php-bug78862.patch
@@ -0,0 +1,68 @@
+From 76a8b07ed74add68c52ed1a5399416ff267cef88 Mon Sep 17 00:00:00 2001
+From: "Christoph M. Becker" <cmbecker69@gmx.de>
+Date: Tue, 17 Dec 2019 10:53:47 +0100
+Subject: [PATCH] Fix #78862: link() silently truncates after a null byte on
+ Windows
+
+Since link() is supposed to accepts paths (i.e. strings without NUL
+bytes), we must not accept arbitrary strings.
+
+(cherry picked from commit 0e6c0654ed06751ced134515f7629c40bd979d7f)
+---
+ NEWS | 4 ++++
+ ext/standard/link_win32.c | 2 +-
+ .../tests/file/windows_links/bug78862.phpt | 17 +++++++++++++++++
+ 3 files changed, 22 insertions(+), 1 deletion(-)
+ create mode 100644 ext/standard/tests/file/windows_links/bug78862.phpt
+
+diff --git a/NEWS b/NEWS
+index 29fcce8947..02cd502c8c 100644
+--- a/NEWS
++++ b/NEWS
+@@ -7,6 +7,10 @@ Backported from 7.2.26
+ . Fixed bug #78878 (Buffer underflow in bc_shift_addsub). (CVE-2019-11046).
+ (cmb)
+
++- Core:
++ . Fixed bug #78862 (link() silently truncates after a null byte on Windows).
++ (CVE-2019-11044). (cmb)
++
+ Backported from 7.1.33
+
+ - FPM:
+diff --git a/ext/standard/link_win32.c b/ext/standard/link_win32.c
+index 0068a3edb1..c6133c7ef6 100644
+--- a/ext/standard/link_win32.c
++++ b/ext/standard/link_win32.c
+@@ -208,7 +208,7 @@ PHP_FUNCTION(link)
+
+ /*First argument to link function is the target and hence should go to frompath
+ Second argument to link function is the link itself and hence should go to topath */
+- if (zend_parse_parameters(ZEND_NUM_ARGS(), "ss", &frompath, &frompath_len, &topath, &topath_len) == FAILURE) {
++ if (zend_parse_parameters(ZEND_NUM_ARGS(), "pp", &frompath, &frompath_len, &topath, &topath_len) == FAILURE) {
+ return;
+ }
+
+diff --git a/ext/standard/tests/file/windows_links/bug78862.phpt b/ext/standard/tests/file/windows_links/bug78862.phpt
+new file mode 100644
+index 0000000000..33b4b49293
+--- /dev/null
++++ b/ext/standard/tests/file/windows_links/bug78862.phpt
+@@ -0,0 +1,17 @@
++--TEST--
++Bug #78862 (link() silently truncates after a null byte on Windows)
++--FILE--
++<?php
++file_put_contents(__DIR__ . '/bug78862.target', 'foo');
++var_dump(link(__DIR__ . "/bug78862.target\0more", __DIR__ . "/bug78862.link\0more"));
++var_dump(file_exists(__DIR__ . '/bug78862.link'));
++?>
++--EXPECTF--
++Warning: link() expects parameter 1 to be a valid path, string given in %s on line %d
++NULL
++bool(false)
++--CLEAN--
++<?php
++unlink(__DIR__ . '/bug78862.target');
++unlink(__DIR__ . '/bug78862.link');
++?>
diff --git a/php-bug78863.patch b/php-bug78863.patch
new file mode 100644
index 0000000..b218dfc
--- /dev/null
+++ b/php-bug78863.patch
@@ -0,0 +1,85 @@
+From f76bef09fce6c438ecee2d2e6f9804d54709174b Mon Sep 17 00:00:00 2001
+From: "Christoph M. Becker" <cmbecker69@gmx.de>
+Date: Tue, 17 Dec 2019 11:03:29 +0100
+Subject: [PATCH] Fix #78863: DirectoryIterator class silently truncates after
+ a null byte
+
+Since the constructor of DirectoryIterator and friends is supposed to
+accepts paths (i.e. strings without NUL bytes), we must not accept
+arbitrary strings.
+
+(cherry picked from commit a5a15965da23c8e97657278fc8dfbf1dfb20c016)
+---
+ NEWS | 2 ++
+ ext/spl/spl_directory.c | 4 ++--
+ ext/spl/tests/bug78863.phpt | 31 +++++++++++++++++++++++++++++++
+ 3 files changed, 35 insertions(+), 2 deletions(-)
+ create mode 100644 ext/spl/tests/bug78863.phpt
+
+diff --git a/NEWS b/NEWS
+index 02cd502c8c..39a2f43818 100644
+--- a/NEWS
++++ b/NEWS
+@@ -10,6 +10,8 @@ Backported from 7.2.26
+ - Core:
+ . Fixed bug #78862 (link() silently truncates after a null byte on Windows).
+ (CVE-2019-11044). (cmb)
++ . Fixed bug #78863 (DirectoryIterator class silently truncates after a null
++ byte). (CVE-2019-11045). (cmb)
+
+ Backported from 7.1.33
+
+diff --git a/ext/spl/spl_directory.c b/ext/spl/spl_directory.c
+index 300cf01909..abfce1525a 100644
+--- a/ext/spl/spl_directory.c
++++ b/ext/spl/spl_directory.c
+@@ -684,10 +684,10 @@ void spl_filesystem_object_construct(INTERNAL_FUNCTION_PARAMETERS, zend_long cto
+
+ if (SPL_HAS_FLAG(ctor_flags, DIT_CTOR_FLAGS)) {
+ flags = SPL_FILE_DIR_KEY_AS_PATHNAME|SPL_FILE_DIR_CURRENT_AS_FILEINFO;
+- parsed = zend_parse_parameters(ZEND_NUM_ARGS(), "s|l", &path, &len, &flags);
++ parsed = zend_parse_parameters(ZEND_NUM_ARGS(), "p|l", &path, &len, &flags);
+ } else {
+ flags = SPL_FILE_DIR_KEY_AS_PATHNAME|SPL_FILE_DIR_CURRENT_AS_SELF;
+- parsed = zend_parse_parameters(ZEND_NUM_ARGS(), "s", &path, &len);
++ parsed = zend_parse_parameters(ZEND_NUM_ARGS(), "p", &path, &len);
+ }
+ if (SPL_HAS_FLAG(ctor_flags, SPL_FILE_DIR_SKIPDOTS)) {
+ flags |= SPL_FILE_DIR_SKIPDOTS;
+diff --git a/ext/spl/tests/bug78863.phpt b/ext/spl/tests/bug78863.phpt
+new file mode 100644
+index 0000000000..dc88d98dee
+--- /dev/null
++++ b/ext/spl/tests/bug78863.phpt
+@@ -0,0 +1,31 @@
++--TEST--
++Bug #78863 (DirectoryIterator class silently truncates after a null byte)
++--FILE--
++<?php
++$dir = __DIR__ . '/bug78863';
++mkdir($dir);
++touch("$dir/bad");
++mkdir("$dir/sub");
++touch("$dir/sub/good");
++
++$it = new DirectoryIterator(__DIR__ . "/bug78863\0/sub");
++foreach ($it as $fileinfo) {
++ if (!$fileinfo->isDot()) {
++ var_dump($fileinfo->getFilename());
++ }
++}
++?>
++--EXPECTF--
++Fatal error: Uncaught UnexpectedValueException: DirectoryIterator::__construct() expects parameter 1 to be a valid path, string given in %s:%d
++Stack trace:
++#0 %s(%d): DirectoryIterator->__construct('%s')
++#1 {main}
++ thrown in %s on line %d
++--CLEAN--
++<?php
++$dir = __DIR__ . '/bug78863';
++unlink("$dir/sub/good");
++rmdir("$dir/sub");
++unlink("$dir/bad");
++rmdir($dir);
++?>
diff --git a/php-bug78875.patch b/php-bug78875.patch
new file mode 100644
index 0000000..87bc103
--- /dev/null
+++ b/php-bug78875.patch
@@ -0,0 +1,38 @@
+From a8aca370e9ba4d9b402f1c6256653c683c4019a1 Mon Sep 17 00:00:00 2001
+From: "Christoph M. Becker" <cmbecker69@gmx.de>
+Date: Wed, 18 Mar 2020 10:26:53 +0100
+Subject: [PATCH] Fix #78875: Long filenames cause OOM and temp files are not
+ cleaned
+
+We must not cast `size_t` to `int` (unless the `size_t` value is
+guaranteed to be less than or equal to `INT_MAX`). In this case we can
+declare `array_len` as `size_t` in the first place.
+
+(cherry picked from commit 1c9bd513ac5c7c1d13d7f0dfa7c16a7ad2ce0f87)
+---
+ main/rfc1867.c | 5 +++--
+ 1 file changed, 3 insertions(+), 2 deletions(-)
+
+diff --git a/main/rfc1867.c b/main/rfc1867.c
+index 5949802d6d..ee07ea557d 100644
+--- a/main/rfc1867.c
++++ b/main/rfc1867.c
+@@ -690,7 +690,8 @@ SAPI_API SAPI_POST_HANDLER_FUNC(rfc1867_post_handler) /* {{{ */
+ char *boundary, *s = NULL, *boundary_end = NULL, *start_arr = NULL, *array_index = NULL;
+ char *lbuf = NULL, *abuf = NULL;
+ zend_string *temp_filename = NULL;
+- int boundary_len = 0, cancel_upload = 0, is_arr_upload = 0, array_len = 0;
++ int boundary_len = 0, cancel_upload = 0, is_arr_upload = 0;
++ size_t array_len = 0;
+ int64_t total_bytes = 0, max_file_size = 0;
+ int skip_upload = 0, anonindex = 0, is_anonymous;
+ HashTable *uploaded_files = NULL;
+@@ -1124,7 +1125,7 @@ SAPI_API SAPI_POST_HANDLER_FUNC(rfc1867_post_handler) /* {{{ */
+ is_arr_upload = (start_arr = strchr(param,'[')) && (param[strlen(param)-1] == ']');
+
+ if (is_arr_upload) {
+- array_len = (int)strlen(start_arr);
++ array_len = strlen(start_arr);
+ if (array_index) {
+ efree(array_index);
+ }
diff --git a/php-bug78876.patch b/php-bug78876.patch
new file mode 100644
index 0000000..d6333b5
--- /dev/null
+++ b/php-bug78876.patch
@@ -0,0 +1,74 @@
+From 07007c74a4f30407668548bfb8ab67eb48fcb2f3 Mon Sep 17 00:00:00 2001
+From: "Christoph M. Becker" <cmbecker69@gmx.de>
+Date: Wed, 18 Mar 2020 10:57:42 +0100
+Subject: [PATCH] Fix #78876: Long variables cause OOM and temp files are not
+ cleaned
+
+We use the proper type for size calculations, which is `size_t`.
+
+(cherry picked from commit 3c8582ca4b8e84e5647220b647914876d2c3b124)
+---
+ main/rfc1867.c | 6 +++---
+ 1 file changed, 3 insertions(+), 3 deletions(-)
+
+diff --git a/main/rfc1867.c b/main/rfc1867.c
+index ee07ea557d..6159284311 100644
+--- a/main/rfc1867.c
++++ b/main/rfc1867.c
+@@ -614,7 +614,7 @@ static void *php_ap_memstr(char *haystack, int haystacklen, char *needle, int ne
+ }
+
+ /* read until a boundary condition */
+-static int multipart_buffer_read(multipart_buffer *self, char *buf, size_t bytes, int *end)
++static size_t multipart_buffer_read(multipart_buffer *self, char *buf, size_t bytes, int *end)
+ {
+ size_t len, max;
+ char *bound;
+@@ -653,7 +653,7 @@ static int multipart_buffer_read(multipart_buffer *self, char *buf, size_t bytes
+ self->buf_begin += len;
+ }
+
+- return (int)len;
++ return len;
+ }
+
+ /*
+@@ -663,7 +663,7 @@ static int multipart_buffer_read(multipart_buffer *self, char *buf, size_t bytes
+ static char *multipart_buffer_read_body(multipart_buffer *self, size_t *len)
+ {
+ char buf[FILLUNIT], *out=NULL;
+- int total_bytes=0, read_bytes=0;
++ size_t total_bytes=0, read_bytes=0;
+
+ while((read_bytes = multipart_buffer_read(self, buf, sizeof(buf), NULL))) {
+ out = erealloc(out, total_bytes + read_bytes + 1);
+From c2776813404fbf5d35e3cc7b3d831f449887b0e5 Mon Sep 17 00:00:00 2001
+From: Stanislav Malyshev <stas@php.net>
+Date: Mon, 11 May 2020 14:28:51 -0700
+Subject: [PATCH] Update NEWS
+
+(cherry picked from commit b4afd21428e09133228fd84bf048157526c2c705)
+(cherry picked from commit f1a89efe27650b62d58fceb77252480b19da6555)
+---
+ NEWS | 8 ++++++++
+ 1 file changed, 8 insertions(+)
+
+diff --git a/NEWS b/NEWS
+index 6310d94581..e153539d98 100644
+--- a/NEWS
++++ b/NEWS
+@@ -1,6 +1,14 @@
+ PHP NEWS
+ |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
+
++Backported from 7.2.31
++
++- Core:
++ . Fixed bug #78875 (Long filenames cause OOM and temp files are not cleaned).
++ (CVE-2019-11048) (cmb)
++ . Fixed bug #78876 (Long variables in multipart/form-data cause OOM and temp
++ files are not cleaned). (CVE-2019-11048) (cmb)
++
+ Backported from 7.2.30
+
+ - Standard:
diff --git a/php-bug78878.patch b/php-bug78878.patch
new file mode 100644
index 0000000..7cba243
--- /dev/null
+++ b/php-bug78878.patch
@@ -0,0 +1,68 @@
+From 4bd85120b04621bee88b54f4b4f23fa1386d37ec Mon Sep 17 00:00:00 2001
+From: "Christoph M. Becker" <cmbecker69@gmx.de>
+Date: Sat, 30 Nov 2019 12:26:37 +0100
+Subject: [PATCH] Fix #78878: Buffer underflow in bc_shift_addsub
+
+We must not rely on `isdigit()` to detect digits, since we only support
+decimal ASCII digits in the following processing.
+
+(cherry picked from commit eb23c6008753b1cdc5359dead3a096dce46c9018)
+---
+ NEWS | 6 ++++++
+ ext/bcmath/libbcmath/src/str2num.c | 4 ++--
+ ext/bcmath/tests/bug78878.phpt | 13 +++++++++++++
+ 3 files changed, 21 insertions(+), 2 deletions(-)
+ create mode 100644 ext/bcmath/tests/bug78878.phpt
+
+diff --git a/NEWS b/NEWS
+index b5a736947b..29fcce8947 100644
+--- a/NEWS
++++ b/NEWS
+@@ -1,6 +1,12 @@
+ PHP NEWS
+ |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
+
++Backported from 7.2.26
++
++- Bcmath:
++ . Fixed bug #78878 (Buffer underflow in bc_shift_addsub). (CVE-2019-11046).
++ (cmb)
++
+ Backported from 7.1.33
+
+ - FPM:
+diff --git a/ext/bcmath/libbcmath/src/str2num.c b/ext/bcmath/libbcmath/src/str2num.c
+index 62544de80e..76b71a7e93 100644
+--- a/ext/bcmath/libbcmath/src/str2num.c
++++ b/ext/bcmath/libbcmath/src/str2num.c
+@@ -57,9 +57,9 @@ bc_str2num (bc_num *num, char *str, int scale)
+ zero_int = FALSE;
+ if ( (*ptr == '+') || (*ptr == '-')) ptr++; /* Sign */
+ while (*ptr == '0') ptr++; /* Skip leading zeros. */
+- while (isdigit((int)*ptr)) ptr++, digits++; /* digits */
++ while (*ptr >= '0' && *ptr <= '9') ptr++, digits++; /* digits */
+ if (*ptr == '.') ptr++; /* decimal point */
+- while (isdigit((int)*ptr)) ptr++, strscale++; /* digits */
++ while (*ptr >= '0' && *ptr <= '9') ptr++, strscale++; /* digits */
+ if ((*ptr != '\0') || (digits+strscale == 0))
+ {
+ *num = bc_copy_num (BCG(_zero_));
+diff --git a/ext/bcmath/tests/bug78878.phpt b/ext/bcmath/tests/bug78878.phpt
+new file mode 100644
+index 0000000000..2c9d72b946
+--- /dev/null
++++ b/ext/bcmath/tests/bug78878.phpt
+@@ -0,0 +1,13 @@
++--TEST--
++Bug #78878 (Buffer underflow in bc_shift_addsub)
++--SKIPIF--
++<?php
++if (!extension_loaded('bcmath')) die('skip bcmath extension not available');
++?>
++--FILE--
++<?php
++print @bcmul("\xB26483605105519922841849335928742092", bcpowmod(2, 65535, -4e-4));
++?>
++--EXPECT--
++bc math warning: non-zero scale in modulus
++0
diff --git a/php-bug78910.patch b/php-bug78910.patch
new file mode 100644
index 0000000..f164d0a
--- /dev/null
+++ b/php-bug78910.patch
@@ -0,0 +1,148 @@
+From 75149a9a02d3bc44411a6e7ab35aee7110d053f3 Mon Sep 17 00:00:00 2001
+From: Stanislav Malyshev <stas@php.net>
+Date: Mon, 16 Dec 2019 00:10:39 -0800
+Subject: [PATCH] Fixed bug #78910
+
+(cherry picked from commit d348cfb96f2543565691010ade5e0346338be5a7)
+---
+ NEWS | 2 ++
+ ext/exif/exif.c | 3 ++-
+ ext/exif/tests/bug78910.phpt | 17 +++++++++++++++++
+ 3 files changed, 21 insertions(+), 1 deletion(-)
+ create mode 100644 ext/exif/tests/bug78910.phpt
+
+diff --git a/NEWS b/NEWS
+index 723cc69be6..ba237b8e33 100644
+--- a/NEWS
++++ b/NEWS
+@@ -16,6 +16,8 @@ Backported from 7.2.26
+ - EXIF:
+ . Fixed bug #78793 (Use-after-free in exif parsing under memory sanitizer).
+ (CVE-2019-11050). (Nikita)
++ . Fixed bug #78910 (Heap-buffer-overflow READ in exif). (CVE-2019-11047).
++ (Nikita)
+
+ Backported from 7.1.33
+
+diff --git a/ext/exif/exif.c b/ext/exif/exif.c
+index a7da928800..9e42a62812 100644
+--- a/ext/exif/exif.c
++++ b/ext/exif/exif.c
+@@ -2748,7 +2748,8 @@ static int exif_process_IFD_in_MAKERNOTE(image_info_type *ImageInfo, char * valu
+ continue;
+ if (maker_note->model && (!ImageInfo->model || strcmp(maker_note->model, ImageInfo->model)))
+ continue;
+- if (maker_note->id_string && strncmp(maker_note->id_string, value_ptr, maker_note->id_string_len))
++ if (maker_note->id_string && value_len >= maker_note->id_string_len
++ && strncmp(maker_note->id_string, value_ptr, maker_note->id_string_len))
+ continue;
+ break;
+ }
+diff --git a/ext/exif/tests/bug78910.phpt b/ext/exif/tests/bug78910.phpt
+new file mode 100644
+index 0000000000..f5b1c32c1b
+--- /dev/null
++++ b/ext/exif/tests/bug78910.phpt
+@@ -0,0 +1,17 @@
++--TEST--
++Bug #78910: Heap-buffer-overflow READ in exif (OSS-Fuzz #19044)
++--FILE--
++<?php
++
++var_dump(exif_read_data('data:image/jpg;base64,TU0AKgAAAAwgICAgAAIBDwAEAAAAAgAAACKSfCAgAAAAAEZVSklGSUxN'));
++
++?>
++--EXPECTF--
++Notice: exif_read_data(): Read from TIFF: tag(0x927C, MakerNote ): Illegal format code 0x2020, switching to BYTE in %s on line %d
++
++Warning: exif_read_data(): Process tag(x927C=MakerNote ): Illegal format code 0x2020, suppose BYTE in %s on line %d
++
++Warning: exif_read_data(): IFD data too short: 0x0000 offset 0x000C in %s on line %d
++
++Warning: exif_read_data(): Invalid TIFF file in %s on line %d
++bool(false)
+From ec1dc05c2415f55507b5710dbeed9f0623c9b44d Mon Sep 17 00:00:00 2001
+From: "Christoph M. Becker" <cmbecker69@gmx.de>
+Date: Tue, 17 Dec 2019 15:26:04 +0100
+Subject: [PATCH] Fix tests
+
+---
+ ext/bcmath/tests/bug72093-win32.phpt | 2 +-
+ ext/bcmath/tests/bug75178-win32.phpt | 4 ++--
+ ext/exif/tests/bug76557.phpt | 2 +-
+ ext/exif/tests/bug78910.phpt | 8 ++++----
+ ext/spl/tests/bug54291.phpt | 2 +-
+ 5 files changed, 9 insertions(+), 9 deletions(-)
+
+diff --git a/ext/bcmath/tests/bug72093-win32.phpt b/ext/bcmath/tests/bug72093-win32.phpt
+index a9b2077823..bcea8740b5 100644
+--- a/ext/bcmath/tests/bug72093-win32.phpt
++++ b/ext/bcmath/tests/bug72093-win32.phpt
+@@ -14,5 +14,5 @@ var_dump(bcpowmod(1, 1.2, 1, 1));
+ ?>
+ --EXPECTF--
+ string(1) "1"
+-string(3) "0.0"
+ bc math warning: non-zero scale in exponent
++string(3) "0.0"
+diff --git a/ext/bcmath/tests/bug75178-win32.phpt b/ext/bcmath/tests/bug75178-win32.phpt
+index bae590fb5b..c70e3aa810 100644
+--- a/ext/bcmath/tests/bug75178-win32.phpt
++++ b/ext/bcmath/tests/bug75178-win32.phpt
+@@ -14,8 +14,8 @@ var_dump(bcpowmod('4', '4', '3.1', 3));
+ ?>
+ ===DONE===
+ --EXPECT--
++bc math warning: non-zero scale in base
+ string(5) "1.000"
++bc math warning: non-zero scale in modulus
+ string(5) "1.000"
+ ===DONE===
+-bc math warning: non-zero scale in base
+-bc math warning: non-zero scale in modulus
+diff --git a/ext/exif/tests/bug76557.phpt b/ext/exif/tests/bug76557.phpt
+index 4553b62772..8920de658a 100644
+--- a/ext/exif/tests/bug76557.phpt
++++ b/ext/exif/tests/bug76557.phpt
+@@ -70,7 +70,7 @@ Warning: exif_read_data(bug76557.jpg): Process tag(x3030=UndefinedTa): Illegal f
+
+ Warning: exif_read_data(bug76557.jpg): Process tag(x3030=UndefinedTa): Illegal format code 0x3030, suppose BYTE in %sbug76557.php on line %d
+
+-Warning: exif_read_data(bug76557.jpg): Process tag(x3030=UndefinedTa): Illegal pointer offset(x30303030 + x30303030 = x60606060 > x00EE) in %sbug76557.php on line %d
++Warning: exif_read_data(bug76557.jpg): Process tag(x3030=UndefinedTa): Illegal pointer offset(x30303030 + x30303030 = x60606060 > %s) in %sbug76557.php on line %d
+
+ Warning: exif_read_data(bug76557.jpg): File structure corrupted in %sbug76557.php on line %d
+
+diff --git a/ext/exif/tests/bug78910.phpt b/ext/exif/tests/bug78910.phpt
+index f5b1c32c1b..7e40b82389 100644
+--- a/ext/exif/tests/bug78910.phpt
++++ b/ext/exif/tests/bug78910.phpt
+@@ -7,11 +7,11 @@ var_dump(exif_read_data('data:image/jpg;base64,TU0AKgAAAAwgICAgAAIBDwAEAAAAAgAAA
+
+ ?>
+ --EXPECTF--
+-Notice: exif_read_data(): Read from TIFF: tag(0x927C, MakerNote ): Illegal format code 0x2020, switching to BYTE in %s on line %d
++Notice: exif_read_data(jpg;base64,TU0AKgAAAAwgICAgAAIBDwAEAAAAAgAAACKSfCAgAAAAAEZVSklGSUxN): Read from TIFF: tag(0x927C, MakerNote ): Illegal format code 0x2020, switching to BYTE in %s on line %d
+
+-Warning: exif_read_data(): Process tag(x927C=MakerNote ): Illegal format code 0x2020, suppose BYTE in %s on line %d
++Warning: exif_read_data(jpg;base64,TU0AKgAAAAwgICAgAAIBDwAEAAAAAgAAACKSfCAgAAAAAEZVSklGSUxN): Process tag(x927C=MakerNote ): Illegal format code 0x2020, suppose BYTE in %s on line %d
+
+-Warning: exif_read_data(): IFD data too short: 0x0000 offset 0x000C in %s on line %d
++Warning: exif_read_data(jpg;base64,TU0AKgAAAAwgICAgAAIBDwAEAAAAAgAAACKSfCAgAAAAAEZVSklGSUxN): IFD data too short: 0x0000 offset 0x000C in %s on line %d
+
+-Warning: exif_read_data(): Invalid TIFF file in %s on line %d
++Warning: exif_read_data(jpg;base64,TU0AKgAAAAwgICAgAAIBDwAEAAAAAgAAACKSfCAgAAAAAEZVSklGSUxN): Invalid TIFF file in %s on line %d
+ bool(false)
+diff --git a/ext/spl/tests/bug54291.phpt b/ext/spl/tests/bug54291.phpt
+index c0119c4360..5e4a5a0607 100644
+--- a/ext/spl/tests/bug54291.phpt
++++ b/ext/spl/tests/bug54291.phpt
+@@ -5,7 +5,7 @@ Bug #54291 (Crash iterating DirectoryIterator for dir name starting with \0)
+ $dir = new DirectoryIterator("\x00/abc");
+ $dir->isFile();
+ --EXPECTF--
+-Fatal error: Uncaught UnexpectedValueException: Failed to open directory "" in %s:%d
++Fatal error: Uncaught UnexpectedValueException: DirectoryIterator::__construct() expects parameter 1 to be a valid path, string given in %s:%d
+ Stack trace:
+ #0 %s(%d): DirectoryIterator->__construct('\x00/abc')
+ #1 {main}
diff --git a/php-bug79037.patch b/php-bug79037.patch
new file mode 100644
index 0000000..65d9a39
--- /dev/null
+++ b/php-bug79037.patch
@@ -0,0 +1,93 @@
+From 8abd64d9c5999d42b8e93ab21e84911ec4ca751e Mon Sep 17 00:00:00 2001
+From: Stanislav Malyshev <stas@php.net>
+Date: Mon, 20 Jan 2020 21:42:44 -0800
+Subject: [PATCH] Fix bug #79037 (global buffer-overflow in
+ `mbfl_filt_conv_big5_wchar`)
+
+(cherry picked from commit 2bcbc95f033c31b00595ed39f79c3a99b4ed0501)
+---
+ ext/mbstring/libmbfl/filters/mbfilter_big5.c | 17 ++++++++++++-----
+ ext/mbstring/tests/bug79037.phpt | 10 ++++++++++
+ 2 files changed, 22 insertions(+), 5 deletions(-)
+ create mode 100644 ext/mbstring/tests/bug79037.phpt
+
+diff --git a/ext/mbstring/libmbfl/filters/mbfilter_big5.c b/ext/mbstring/libmbfl/filters/mbfilter_big5.c
+index 122ff4c778..657eb98aa5 100644
+--- a/ext/mbstring/libmbfl/filters/mbfilter_big5.c
++++ b/ext/mbstring/libmbfl/filters/mbfilter_big5.c
+@@ -138,6 +138,17 @@ static unsigned short cp950_pua_tbl[][4] = {
+ {0xf70f,0xf848,0xc740,0xc8fe},
+ };
+
++static inline int is_in_cp950_pua(int c1, int c) {
++ if ((c1 >= 0xfa && c1 <= 0xfe) || (c1 >= 0x8e && c1 <= 0xa0) ||
++ (c1 >= 0x81 && c1 <= 0x8d) || (c1 >= 0xc7 && c1 <= 0xc8)) {
++ return (c >=0x40 && c <= 0x7e) || (c >= 0xa1 && c <= 0xfe);
++ }
++ if (c1 == 0xc6) {
++ return c >= 0xa1 && c <= 0xfe;
++ }
++ return 0;
++}
++
+ /*
+ * Big5 => wchar
+ */
+@@ -186,11 +197,7 @@ mbfl_filt_conv_big5_wchar(int c, mbfl_convert_filter *filter)
+
+ if (filter->from->no_encoding == mbfl_no_encoding_cp950) {
+ /* PUA for CP950 */
+- if (w <= 0 &&
+- (((c1 >= 0xfa && c1 <= 0xfe) || (c1 >= 0x8e && c1 <= 0xa0) ||
+- (c1 >= 0x81 && c1 <= 0x8d) ||(c1 >= 0xc7 && c1 <= 0xc8))
+- && ((c > 0x39 && c < 0x7f) || (c > 0xa0 && c < 0xff))) ||
+- ((c1 == 0xc6) && (c > 0xa0 && c < 0xff))) {
++ if (w <= 0 && is_in_cp950_pua(c1, c)) {
+ c2 = c1 << 8 | c;
+ for (k = 0; k < sizeof(cp950_pua_tbl)/(sizeof(unsigned short)*4); k++) {
+ if (c2 >= cp950_pua_tbl[k][2] && c2 <= cp950_pua_tbl[k][3]) {
+diff --git a/ext/mbstring/tests/bug79037.phpt b/ext/mbstring/tests/bug79037.phpt
+new file mode 100644
+index 0000000000..94ff01a4a1
+--- /dev/null
++++ b/ext/mbstring/tests/bug79037.phpt
+@@ -0,0 +1,10 @@
++--TEST--
++Bug #79037: global buffer-overflow in `mbfl_filt_conv_big5_wchar`
++--FILE--
++<?php
++
++var_dump(mb_convert_encoding("\x81\x3a", "UTF-8", "CP950"));
++
++?>
++--EXPECT--
++string(1) "?"
+From 2f7a097fb2ad1020a179e596f9ee18b02d0d90ae Mon Sep 17 00:00:00 2001
+From: Remi Collet <remi@remirepo.net>
+Date: Tue, 21 Jan 2020 09:36:28 +0100
+Subject: [PATCH] update NEWS
+
+---
+ NEWS | 9 +++++++++
+ 1 file changed, 9 insertions(+)
+
+diff --git a/NEWS b/NEWS
+index ba237b8e33..a1dc8a81c3 100644
+--- a/NEWS
++++ b/NEWS
+@@ -1,6 +1,15 @@
+ PHP NEWS
+ |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
+
++Backported from 7.2.27
++
++- Mbstring:
++ . Fixed bug #79037 (global buffer-overflow in `mbfl_filt_conv_big5_wchar`).
++ (CVE-2020-7060) (Nikita)
++
++- Standard:
++ . Fixed bug #79099 (OOB read in php_strip_tags_ex). (CVE-2020-7059). (cmb)
++
+ Backported from 7.2.26
+
+ - Bcmath:
diff --git a/php-bug79082.patch b/php-bug79082.patch
new file mode 100644
index 0000000..384ecd7
--- /dev/null
+++ b/php-bug79082.patch
@@ -0,0 +1,152 @@
+From a4173e5e7a7f0f927c7bd8fcaffbc0d2caa914d9 Mon Sep 17 00:00:00 2001
+From: Stanislav Malyshev <stas@php.net>
+Date: Sat, 15 Feb 2020 22:17:14 -0800
+Subject: [PATCH 4/5] Fix bug #79082 - Files added to tar with
+ Phar::buildFromIterator have all-access permissions
+
+(cherry picked from commit e5c95234d87fcb8f6b7569a96a89d1e1544749a6)
+---
+ ext/phar/phar_object.c | 11 +++++
+ ext/phar/tests/bug79082.phpt | 52 ++++++++++++++++++++
+ ext/phar/tests/test79082/test79082-testfile | 1 +
+ ext/phar/tests/test79082/test79082-testfile2 | 1 +
+ 4 files changed, 65 insertions(+)
+ create mode 100644 ext/phar/tests/bug79082.phpt
+ create mode 100644 ext/phar/tests/test79082/test79082-testfile
+ create mode 100644 ext/phar/tests/test79082/test79082-testfile2
+
+diff --git a/ext/phar/phar_object.c b/ext/phar/phar_object.c
+index d4ad4e0dcf..8a0d369287 100644
+--- a/ext/phar/phar_object.c
++++ b/ext/phar/phar_object.c
+@@ -1451,6 +1451,7 @@ static int phar_build(zend_object_iterator *iter, void *puser) /* {{{ */
+ char *str_key;
+ zend_class_entry *ce = p_obj->c;
+ phar_archive_object *phar_obj = p_obj->p;
++ php_stream_statbuf ssb;
+
+ value = iter->funcs->get_current_data(iter);
+
+@@ -1745,6 +1746,16 @@ after_open_fp:
+ php_stream_copy_to_stream_ex(fp, p_obj->fp, PHP_STREAM_COPY_ALL, &contents_len);
+ data->internal_file->uncompressed_filesize = data->internal_file->compressed_filesize =
+ php_stream_tell(p_obj->fp) - data->internal_file->offset;
++ if (php_stream_stat(fp, &ssb) != -1) {
++ data->internal_file->flags = ssb.sb.st_mode & PHAR_ENT_PERM_MASK ;
++ } else {
++#ifndef _WIN32
++ mode_t mask;
++ mask = umask(0);
++ umask(mask);
++ data->internal_file->flags &= ~mask;
++#endif
++ }
+ }
+
+ if (close_fp) {
+diff --git a/ext/phar/tests/bug79082.phpt b/ext/phar/tests/bug79082.phpt
+new file mode 100644
+index 0000000000..ca453d1b57
+--- /dev/null
++++ b/ext/phar/tests/bug79082.phpt
+@@ -0,0 +1,52 @@
++--TEST--
++Phar: Bug #79082: Files added to tar with Phar::buildFromIterator have all-access permissions
++--SKIPIF--
++<?php
++if (!extension_loaded("phar")) die("skip");
++if (defined("PHP_WINDOWS_VERSION_MAJOR")) die("skip not for Windows")
++?>
++--FILE--
++<?php
++umask(022);
++var_dump(decoct(umask()));
++chmod(__DIR__ . '/test79082/test79082-testfile', 0644);
++chmod(__DIR__ . '/test79082/test79082-testfile2', 0400);
++
++foreach([Phar::TAR => 'tar', Phar::ZIP => 'zip'] as $mode => $ext) {
++ clearstatcache();
++ $phar = new PharData(__DIR__ . '/test79082.' . $ext, null, null, $mode);
++ $phar->buildFromIterator(new \RecursiveDirectoryIterator(__DIR__ . '/test79082', \FilesystemIterator::SKIP_DOTS), __DIR__ . '/test79082');
++ $phar->extractTo(__DIR__);
++ var_dump(decoct(stat(__DIR__ . '/test79082-testfile')['mode']));
++ var_dump(decoct(stat(__DIR__ . '/test79082-testfile2')['mode']));
++ unlink(__DIR__ . '/test79082-testfile');
++ unlink(__DIR__ . '/test79082-testfile2');
++}
++foreach([Phar::TAR => 'tar', Phar::ZIP => 'zip'] as $mode => $ext) {
++ clearstatcache();
++ $phar = new PharData(__DIR__ . '/test79082-d.' . $ext, null, null, $mode);
++ $phar->buildFromDirectory(__DIR__ . '/test79082');
++ $phar->extractTo(__DIR__);
++ var_dump(decoct(stat(__DIR__ . '/test79082-testfile')['mode']));
++ var_dump(decoct(stat(__DIR__ . '/test79082-testfile2')['mode']));
++ unlink(__DIR__ . '/test79082-testfile');
++ unlink(__DIR__ . '/test79082-testfile2');
++}
++?>
++--CLEAN--
++<?
++unlink(__DIR__ . '/test79082.tar');
++unlink(__DIR__ . '/test79082.zip');
++unlink(__DIR__ . '/test79082-d.tar');
++unlink(__DIR__ . '/test79082-d.zip');
++?>
++--EXPECT--
++string(2) "22"
++string(6) "100644"
++string(6) "100400"
++string(6) "100644"
++string(6) "100400"
++string(6) "100644"
++string(6) "100400"
++string(6) "100644"
++string(6) "100400"
+diff --git a/ext/phar/tests/test79082/test79082-testfile b/ext/phar/tests/test79082/test79082-testfile
+new file mode 100644
+index 0000000000..9daeafb986
+--- /dev/null
++++ b/ext/phar/tests/test79082/test79082-testfile
+@@ -0,0 +1 @@
++test
+diff --git a/ext/phar/tests/test79082/test79082-testfile2 b/ext/phar/tests/test79082/test79082-testfile2
+new file mode 100644
+index 0000000000..9daeafb986
+--- /dev/null
++++ b/ext/phar/tests/test79082/test79082-testfile2
+@@ -0,0 +1 @@
++test
+--
+2.24.1
+
+From 9e5dbc9e3c6d970868d112175a286ceddc648aff Mon Sep 17 00:00:00 2001
+From: Remi Collet <remi@remirepo.net>
+Date: Tue, 18 Feb 2020 06:35:00 +0100
+Subject: [PATCH 5/5] NEWS
+
+---
+ NEWS | 8 ++++++++
+ 1 file changed, 8 insertions(+)
+
+diff --git a/NEWS b/NEWS
+index 9467c98e33..853e9b5341 100644
+--- a/NEWS
++++ b/NEWS
+@@ -7,6 +7,14 @@ Backported from 7.2.28
+ . Fixed bug #77569: (Write Access Violation in DomImplementation). (Nikita,
+ cmb)
+
++- Phar:
++ . Fixed bug #79082 (Files added to tar with Phar::buildFromIterator have
++ all-access permissions). (CVE-2020-7063) (stas)
++
++- Session:
++ . Fixed bug #79221 (Null Pointer Dereference in PHP Session Upload Progress).
++ (CVE-2020-7062) (stas)
++
+ Backported from 7.2.27
+
+ - Mbstring:
+--
+2.24.1
+
diff --git a/php-bug79099.patch b/php-bug79099.patch
new file mode 100644
index 0000000..3de1998
--- /dev/null
+++ b/php-bug79099.patch
@@ -0,0 +1,113 @@
+From 89084ce9e34ed38403f8cbb5d67e6299f1b1ab60 Mon Sep 17 00:00:00 2001
+From: Stanislav Malyshev <stas@php.net>
+Date: Mon, 20 Jan 2020 21:33:17 -0800
+Subject: [PATCH] Fix #79099: OOB read in php_strip_tags_ex
+
+(cherry picked from commit 0f79b1bf301f455967676b5129240140c5c45b09)
+---
+ ext/standard/string.c | 6 ++---
+ ext/standard/tests/file/bug79099.phpt | 32 +++++++++++++++++++++++++++
+ 2 files changed, 35 insertions(+), 3 deletions(-)
+ create mode 100644 ext/standard/tests/file/bug79099.phpt
+
+diff --git a/ext/standard/string.c b/ext/standard/string.c
+index a8b39ee615..c4b5e031ed 100644
+--- a/ext/standard/string.c
++++ b/ext/standard/string.c
+@@ -4757,7 +4757,7 @@ PHPAPI size_t php_strip_tags_ex(char *rbuf, size_t len, int *stateptr, const cha
+ if (state == 4) {
+ /* Inside <!-- comment --> */
+ break;
+- } else if (state == 2 && *(p-1) != '\\') {
++ } else if (state == 2 && p >= buf + 1 && *(p-1) != '\\') {
+ if (lc == c) {
+ lc = '\0';
+ } else if (lc != '\\') {
+@@ -4784,7 +4784,7 @@ PHPAPI size_t php_strip_tags_ex(char *rbuf, size_t len, int *stateptr, const cha
+
+ case '!':
+ /* JavaScript & Other HTML scripting languages */
+- if (state == 1 && *(p-1) == '<') {
++ if (state == 1 && p >= buf + 1 && *(p-1) == '<') {
+ state = 3;
+ lc = c;
+ } else {
+@@ -4811,7 +4811,7 @@ PHPAPI size_t php_strip_tags_ex(char *rbuf, size_t len, int *stateptr, const cha
+
+ case '?':
+
+- if (state == 1 && *(p-1) == '<') {
++ if (state == 1 && p >= buf + 1 && *(p-1) == '<') {
+ br=0;
+ state=2;
+ break;
+diff --git a/ext/standard/tests/file/bug79099.phpt b/ext/standard/tests/file/bug79099.phpt
+new file mode 100644
+index 0000000000..7c842f4654
+--- /dev/null
++++ b/ext/standard/tests/file/bug79099.phpt
+@@ -0,0 +1,32 @@
++--TEST--
++Bug #79099 (OOB read in php_strip_tags_ex)
++--FILE--
++<?php
++$stream = fopen('php://memory', 'w+');
++fputs($stream, "<?\n\"\n");
++rewind($stream);
++var_dump(fgetss($stream));
++var_dump(fgetss($stream));
++fclose($stream);
++
++$stream = fopen('php://memory', 'w+');
++fputs($stream, "<\0\n!\n");
++rewind($stream);
++var_dump(fgetss($stream));
++var_dump(fgetss($stream));
++fclose($stream);
++
++$stream = fopen('php://memory', 'w+');
++fputs($stream, "<\0\n?\n");
++rewind($stream);
++var_dump(fgetss($stream));
++var_dump(fgetss($stream));
++fclose($stream);
++?>
++--EXPECT--
++string(0) ""
++string(0) ""
++string(0) ""
++string(0) ""
++string(0) ""
++string(0) ""
+From 740b58637d71aade0a748117b7fbe9a21a1fab70 Mon Sep 17 00:00:00 2001
+From: Stanislav Malyshev <stas@php.net>
+Date: Wed, 22 Jan 2020 22:36:53 -0800
+Subject: [PATCH] More checks for php_strip_tags_ex
+
+(cherry picked from commit 2dc170e25d86a725fefd4c08f2bd8378820b28f5)
+---
+ ext/standard/string.c | 4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+diff --git a/ext/standard/string.c b/ext/standard/string.c
+index c4b5e031ed..7c044af0fd 100644
+--- a/ext/standard/string.c
++++ b/ext/standard/string.c
+@@ -4707,7 +4707,7 @@ PHPAPI size_t php_strip_tags_ex(char *rbuf, size_t len, int *stateptr, const cha
+ switch (state) {
+ case 1: /* HTML/XML */
+ lc = '>';
+- if (is_xml && *(p -1) == '-') {
++ if (is_xml && p >= buf + 1 && *(p-1) == '-') {
+ break;
+ }
+ in_q = state = is_xml = 0;
+@@ -4728,7 +4728,7 @@ PHPAPI size_t php_strip_tags_ex(char *rbuf, size_t len, int *stateptr, const cha
+ break;
+
+ case 2: /* PHP */
+- if (!br && lc != '\"' && *(p-1) == '?') {
++ if (!br && lc != '\"' && p >= buf + 1 && *(p-1) == '?') {
+ in_q = state = 0;
+ tp = tbuf;
+ }
diff --git a/php-bug79221.patch b/php-bug79221.patch
new file mode 100644
index 0000000..3b1c372
--- /dev/null
+++ b/php-bug79221.patch
@@ -0,0 +1,86 @@
+From 28397333d0b510c7759ee272fb7521f9d9358e9b Mon Sep 17 00:00:00 2001
+From: Stanislav Malyshev <stas@php.net>
+Date: Sat, 15 Feb 2020 20:52:19 -0800
+Subject: [PATCH 3/5] Fix bug #79221 - Null Pointer Dereference in PHP Session
+ Upload Progress
+
+(cherry picked from commit d76f7c6c636b8240e06a1fa29eebb98ad005008a)
+---
+ ext/session/session.c | 8 +++---
+ ext/session/tests/bug79221.phpt | 45 +++++++++++++++++++++++++++++++++
+ 2 files changed, 50 insertions(+), 3 deletions(-)
+ create mode 100644 ext/session/tests/bug79221.phpt
+
+diff --git a/ext/session/session.c b/ext/session/session.c
+index daea59c4ff..4d397c3bca 100644
+--- a/ext/session/session.c
++++ b/ext/session/session.c
+@@ -3108,9 +3108,11 @@ static int php_session_rfc1867_callback(unsigned int event, void *event_data, vo
+ if (PS(rfc1867_cleanup)) {
+ php_session_rfc1867_cleanup(progress);
+ } else {
+- add_assoc_bool_ex(&progress->data, "done", sizeof("done") - 1, 1);
+- Z_LVAL_P(progress->post_bytes_processed) = data->post_bytes_processed;
+- php_session_rfc1867_update(progress, 1);
++ if (!Z_ISUNDEF(progress->data)) {
++ add_assoc_bool_ex(&progress->data, "done", sizeof("done") - 1, 1);
++ Z_LVAL_P(progress->post_bytes_processed) = data->post_bytes_processed;
++ php_session_rfc1867_update(progress, 1);
++ }
+ }
+ php_rshutdown_session_globals();
+ }
+diff --git a/ext/session/tests/bug79221.phpt b/ext/session/tests/bug79221.phpt
+new file mode 100644
+index 0000000000..b0972c4697
+--- /dev/null
++++ b/ext/session/tests/bug79221.phpt
+@@ -0,0 +1,45 @@
++--TEST--
++Null Pointer Dereference in PHP Session Upload Progress
++--INI--
++error_reporting=0
++file_uploads=1
++upload_max_filesize=1024
++session.save_path=
++session.name=PHPSESSID
++session.serialize_handler=php
++session.use_strict_mode=0
++session.use_cookies=1
++session.use_only_cookies=0
++session.upload_progress.enabled=1
++session.upload_progress.cleanup=0
++session.upload_progress.prefix=upload_progress_
++session.upload_progress.name=PHP_SESSION_UPLOAD_PROGRESS
++session.upload_progress.freq=1%
++session.upload_progress.min_freq=0.000000001
++--COOKIE--
++PHPSESSID=session-upload
++--POST_RAW--
++Content-Type: multipart/form-data; boundary=---------------------------20896060251896012921717172737
++-----------------------------20896060251896012921717172737
++Content-Disposition: form-data; name="PHPSESSID"
++
++session-upload
++-----------------------------20896060251896012921717172737
++Content-Disposition: form-data; name="PHP_SESSION_UPLOAD_PROGRESS"
++
++ryat
++-----------------------------20896060251896012921717172737
++Content-Disposition: form-data; file="file"; ryat="filename"
++
++1
++-----------------------------20896060251896012921717172737--
++--FILE--
++<?php
++
++session_start();
++var_dump($_SESSION);
++session_destroy();
++
++--EXPECTF--
++array(0) {
++}
+--
+2.24.1
+
diff --git a/php-bug79282.patch b/php-bug79282.patch
new file mode 100644
index 0000000..a026939
--- /dev/null
+++ b/php-bug79282.patch
@@ -0,0 +1,110 @@
+From 59119490c9e2359ea720928b2e71b68e5c20f195 Mon Sep 17 00:00:00 2001
+From: Stanislav Malyshev <stas@php.net>
+Date: Sun, 15 Mar 2020 17:26:00 -0700
+Subject: [PATCH] Fixed bug #79282
+
+(cherry picked from commit 41f66e2a2cfd611e35be5ac3bf747f0b56161216)
+(cherry picked from commit 8577fa5891220dac40d42b2f745fa159dcd871ad)
+---
+ ext/exif/exif.c | 7 ++++++-
+ ext/exif/tests/bug79282.phpt | 15 +++++++++++++++
+ 2 files changed, 21 insertions(+), 1 deletion(-)
+ create mode 100644 ext/exif/tests/bug79282.phpt
+
+diff --git a/ext/exif/exif.c b/ext/exif/exif.c
+index 9e42a62812..4c38f17593 100644
+--- a/ext/exif/exif.c
++++ b/ext/exif/exif.c
+@@ -3242,6 +3242,11 @@ static void exif_process_TIFF_in_JPEG(image_info_type *ImageInfo, char *CharBuf,
+ {
+ unsigned exif_value_2a, offset_of_ifd;
+
++ if (length < 2) {
++ exif_error_docref(NULL EXIFERR_CC, ImageInfo, E_WARNING, "Missing TIFF alignment marker");
++ return;
++ }
++
+ /* set the thumbnail stuff to nothing so we can test to see if they get set up */
+ if (memcmp(CharBuf, "II", 2) == 0) {
+ ImageInfo->motorola_intel = 0;
+@@ -3394,7 +3399,7 @@ static int exif_scan_JPEG_header(image_info_type *ImageInfo)
+ return FALSE;
+ }
+
+- sn = exif_file_sections_add(ImageInfo, marker, itemlen+1, NULL);
++ sn = exif_file_sections_add(ImageInfo, marker, itemlen, NULL);
+ Data = ImageInfo->file.list[sn].data;
+
+ /* Store first two pre-read bytes. */
+diff --git a/ext/exif/tests/bug79282.phpt b/ext/exif/tests/bug79282.phpt
+new file mode 100644
+index 0000000000..7b7e365657
+--- /dev/null
++++ b/ext/exif/tests/bug79282.phpt
+@@ -0,0 +1,15 @@
++--TEST--
++Bug #79282: Use-of-uninitialized-value in exif
++--FILE--
++<?php
++
++var_dump(exif_read_data('data://image/jpeg;base64,/9jhAAlFeGlmAAAg'));
++
++?>
++--EXPECTF--
++Warning: exif_read_data(): Invalid TIFF alignment marker in %s on line %d
++
++Warning: exif_read_data(): File structure corrupted in %s on line %d
++
++Warning: exif_read_data(): Invalid JPEG file in %s on line %d
++bool(false)
+From c1d08859cdac23aeff99953797231f6824d045c5 Mon Sep 17 00:00:00 2001
+From: Stanislav Malyshev <stas@php.net>
+Date: Sun, 15 Mar 2020 17:55:28 -0700
+Subject: [PATCH] Fix test
+
+(cherry picked from commit 2c081b7e269d0f63cd9d60a40997f18b5cf793be)
+(cherry picked from commit ad05ad4dbafc29dd23828760d4bfa2be12ccbb1c)
+---
+ ext/exif/tests/bug79282.phpt | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/ext/exif/tests/bug79282.phpt b/ext/exif/tests/bug79282.phpt
+index 7b7e365657..df91127c9c 100644
+--- a/ext/exif/tests/bug79282.phpt
++++ b/ext/exif/tests/bug79282.phpt
+@@ -7,7 +7,7 @@ var_dump(exif_read_data('data://image/jpeg;base64,/9jhAAlFeGlmAAAg'));
+
+ ?>
+ --EXPECTF--
+-Warning: exif_read_data(): Invalid TIFF alignment marker in %s on line %d
++Warning: exif_read_data(): Missing TIFF alignment marker in %s on line %d
+
+ Warning: exif_read_data(): File structure corrupted in %s on line %d
+
+From 51cc7a6225bbf1f7dfe0ffeb318fb0ff098780f9 Mon Sep 17 00:00:00 2001
+From: Remi Collet <remi@remirepo.net>
+Date: Tue, 17 Mar 2020 07:23:32 +0100
+Subject: [PATCH] fix test
+
+(cherry picked from commit b42b6d0ff774fdced1155cb0c721d91914d619f5)
+---
+ ext/exif/tests/bug79282.phpt | 6 +++---
+ 1 file changed, 3 insertions(+), 3 deletions(-)
+
+diff --git a/ext/exif/tests/bug79282.phpt b/ext/exif/tests/bug79282.phpt
+index df91127c9c..142cf28a6c 100644
+--- a/ext/exif/tests/bug79282.phpt
++++ b/ext/exif/tests/bug79282.phpt
+@@ -7,9 +7,9 @@ var_dump(exif_read_data('data://image/jpeg;base64,/9jhAAlFeGlmAAAg'));
+
+ ?>
+ --EXPECTF--
+-Warning: exif_read_data(): Missing TIFF alignment marker in %s on line %d
++Warning: exif_read_data(%s): Missing TIFF alignment marker in %s on line %d
+
+-Warning: exif_read_data(): File structure corrupted in %s on line %d
++Warning: exif_read_data(%s): File structure corrupted in %s on line %d
+
+-Warning: exif_read_data(): Invalid JPEG file in %s on line %d
++Warning: exif_read_data(%s): Invalid JPEG file in %s on line %d
+ bool(false)
diff --git a/php-bug79329.patch b/php-bug79329.patch
new file mode 100644
index 0000000..0101c68
--- /dev/null
+++ b/php-bug79329.patch
@@ -0,0 +1,57 @@
+From b9a1e6bfd762d2bf7fa3c5bbcfbb6dcdfdfa982c Mon Sep 17 00:00:00 2001
+From: Remi Collet <remi@remirepo.net>
+Date: Tue, 17 Mar 2020 07:25:12 +0100
+Subject: [PATCH] Fix bug #79329 - get_headers should not accept \0
+
+From 0d139c5b94a5f485a66901919e51faddb0371c43
+
+(cherry picked from commit b7b9302660a23a67285e204bc3d7fcf6ba7f6533)
+---
+ ext/standard/url.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/ext/standard/url.c b/ext/standard/url.c
+index 9c42afbdea..2990bd96f6 100644
+--- a/ext/standard/url.c
++++ b/ext/standard/url.c
+@@ -659,7 +659,7 @@ PHP_FUNCTION(get_headers)
+ HashTable *hashT;
+ zend_long format = 0;
+
+- if (zend_parse_parameters(ZEND_NUM_ARGS(), "s|l", &url, &url_len, &format) == FAILURE) {
++ if (zend_parse_parameters(ZEND_NUM_ARGS(), "p|l", &url, &url_len, &format) == FAILURE) {
+ return;
+ }
+ context = FG(default_context) ? FG(default_context) : (FG(default_context) = php_stream_context_alloc());
+From 4844343ac37e8e3ca4d995b1d91fc0f9daf03d5f Mon Sep 17 00:00:00 2001
+From: Stanislav Malyshev <stas@php.net>
+Date: Sun, 15 Mar 2020 19:35:26 -0700
+Subject: [PATCH] [ci skip] Update NEWS
+
+(cherry picked from commit c8d21d7728109b0f911033c098cfaeb7438ba1d5)
+(cherry picked from commit 03471e31c9b467d1d8d944e44fa009ef247e81bd)
+---
+ NEWS | 10 ++++++++++
+ 1 file changed, 10 insertions(+)
+
+diff --git a/NEWS b/NEWS
+index 853e9b5341..f2f1d2ed2a 100644
+--- a/NEWS
++++ b/NEWS
+@@ -1,6 +1,16 @@
+ PHP NEWS
+ |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
+
++Backported from 7.2.29
++
++- Core:
++ . Fixed bug #79329 (get_headers() silently truncates after a null byte)
++ (CVE-2020-7066) (cmb)
++
++- EXIF:
++ . Fixed bug #79282 (Use-of-uninitialized-value in exif) (CVE-2020-7064)
++ (Nikita)
++
+ Backported from 7.2.28
+
+ - DOM:
diff --git a/php-bug79330.patch b/php-bug79330.patch
new file mode 100644
index 0000000..a041f0f
--- /dev/null
+++ b/php-bug79330.patch
@@ -0,0 +1,31 @@
+From d35cb9cdee586a9668ca1d9a72ffdb4f0902b2ba Mon Sep 17 00:00:00 2001
+From: Stanislav Malyshev <stas@php.net>
+Date: Mon, 13 Apr 2020 21:00:44 -0700
+Subject: [PATCH] Fix bug #79330 - make all execution modes consistent in
+ rejecting \0
+
+(cherry picked from commit 14fcc813948254b84f382ff537247d8a7e5e0e62)
+---
+ ext/standard/exec.c | 9 +++++++++
+ 1 file changed, 9 insertions(+)
+
+diff --git a/ext/standard/exec.c b/ext/standard/exec.c
+index d6f0cbfeb2..e486f52a3d 100644
+--- a/ext/standard/exec.c
++++ b/ext/standard/exec.c
+@@ -524,6 +524,15 @@ PHP_FUNCTION(shell_exec)
+ return;
+ }
+
++ if (!command_len) {
++ php_error_docref(NULL, E_WARNING, "Cannot execute a blank command");
++ RETURN_FALSE;
++ }
++ if (strlen(command) != command_len) {
++ php_error_docref(NULL, E_WARNING, "NULL byte detected. Possible attack");
++ RETURN_FALSE;
++ }
++
+ #ifdef PHP_WIN32
+ if ((in=VCWD_POPEN(command, "rt"))==NULL) {
+ #else
diff --git a/php-bug79465.patch b/php-bug79465.patch
new file mode 100644
index 0000000..87477e4
--- /dev/null
+++ b/php-bug79465.patch
@@ -0,0 +1,59 @@
+From 865342c94703cc5a1d0890b51b47a300c0d297ec Mon Sep 17 00:00:00 2001
+From: Stanislav Malyshev <stas@php.net>
+Date: Mon, 13 Apr 2020 21:07:04 -0700
+Subject: [PATCH] Fix bug #79465 - use unsigneds as indexes.
+
+(cherry picked from commit 9d6bf8221b05f86ce5875832f0f646c4c1f218be)
+---
+ ext/standard/url.c | 4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+diff --git a/ext/standard/url.c b/ext/standard/url.c
+index 2990bd96f6..a9cc06b1c0 100644
+--- a/ext/standard/url.c
++++ b/ext/standard/url.c
+@@ -540,7 +540,7 @@ PHPAPI size_t php_url_decode(char *str, size_t len)
+ #ifndef CHARSET_EBCDIC
+ *dest = (char) php_htoi(data + 1);
+ #else
+- *dest = os_toebcdic[(char) php_htoi(data + 1)];
++ *dest = os_toebcdic[(unsigned char) php_htoi(data + 1)];
+ #endif
+ data += 2;
+ len -= 2;
+@@ -632,7 +632,7 @@ PHPAPI size_t php_raw_url_decode(char *str, size_t len)
+ #ifndef CHARSET_EBCDIC
+ *dest = (char) php_htoi(data + 1);
+ #else
+- *dest = os_toebcdic[(char) php_htoi(data + 1)];
++ *dest = os_toebcdic[(unsigned char) php_htoi(data + 1)];
+ #endif
+ data += 2;
+ len -= 2;
+From a83b195cb02e3b42c2fa9e0387922acba4fc7cce Mon Sep 17 00:00:00 2001
+From: Remi Collet <remi@remirepo.net>
+Date: Tue, 14 Apr 2020 08:02:28 +0200
+Subject: [PATCH] NEWS
+
+(cherry picked from commit bd4a5ebe653f36ea7705fbc95a6ec4842d7f86fc)
+---
+ NEWS | 6 ++++++
+ 1 file changed, 6 insertions(+)
+
+diff --git a/NEWS b/NEWS
+index f2f1d2ed2a..6310d94581 100644
+--- a/NEWS
++++ b/NEWS
+@@ -1,6 +1,12 @@
+ PHP NEWS
+ |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
+
++Backported from 7.2.30
++
++- Standard:
++ . Fixed bug #79330 (shell_exec silently truncates after a null byte). (stas)
++ . Fixed bug #79465 (OOB Read in urldecode). (CVE-2020-7067) (stas)
++
+ Backported from 7.2.29
+
+ - Core:
diff --git a/php-bug79699.patch b/php-bug79699.patch
new file mode 100644
index 0000000..b37cbbf
--- /dev/null
+++ b/php-bug79699.patch
@@ -0,0 +1,142 @@
+From 33a0a05b0995907eb1b2b922676ab765ac6fcac2 Mon Sep 17 00:00:00 2001
+From: Stanislav Malyshev <stas@php.net>
+Date: Sun, 20 Sep 2020 18:08:55 -0700
+Subject: [PATCH] Do not decode cookie names anymore
+
+(cherry picked from commit 6559fe912661ca5ce5f0eeeb591d928451428ed0)
+---
+ main/php_variables.c | 8 ++++++--
+ tests/basic/022.phpt | 10 +++++++---
+ tests/basic/023.phpt | 4 +++-
+ tests/basic/bug79699.phpt | 22 ++++++++++++++++++++++
+ 4 files changed, 38 insertions(+), 6 deletions(-)
+ create mode 100644 tests/basic/bug79699.phpt
+
+diff --git a/main/php_variables.c b/main/php_variables.c
+index d3cfb7f737..50ecc663bd 100644
+--- a/main/php_variables.c
++++ b/main/php_variables.c
+@@ -464,7 +464,9 @@ SAPI_API SAPI_TREAT_DATA_FUNC(php_default_treat_data)
+ size_t new_val_len;
+
+ *val++ = '\0';
+- php_url_decode(var, strlen(var));
++ if (arg != PARSE_COOKIE) {
++ php_url_decode(var, strlen(var));
++ }
+ val_len = php_url_decode(val, strlen(val));
+ val = estrndup(val, val_len);
+ if (sapi_module.input_filter(arg, var, &val, val_len, &new_val_len)) {
+@@ -475,7 +477,9 @@ SAPI_API SAPI_TREAT_DATA_FUNC(php_default_treat_data)
+ size_t val_len;
+ size_t new_val_len;
+
+- php_url_decode(var, strlen(var));
++ if (arg != PARSE_COOKIE) {
++ php_url_decode(var, strlen(var));
++ }
+ val_len = 0;
+ val = estrndup("", val_len);
+ if (sapi_module.input_filter(arg, var, &val, val_len, &new_val_len)) {
+diff --git a/tests/basic/022.phpt b/tests/basic/022.phpt
+index 0ab70d4be7..bd1db13701 100644
+--- a/tests/basic/022.phpt
++++ b/tests/basic/022.phpt
+@@ -10,7 +10,7 @@ cookie1=val1 ; cookie2=val2%20; cookie3=val 3.; cookie 4= value 4 %3B; cookie1=
+ var_dump($_COOKIE);
+ ?>
+ --EXPECT--
+-array(10) {
++array(12) {
+ ["cookie1"]=>
+ string(6) "val1 "
+ ["cookie2"]=>
+@@ -19,11 +19,15 @@ array(10) {
+ string(6) "val 3."
+ ["cookie_4"]=>
+ string(10) " value 4 ;"
++ ["%20cookie1"]=>
++ string(6) "ignore"
++ ["+cookie1"]=>
++ string(6) "ignore"
+ ["cookie__5"]=>
+ string(7) " value"
+- ["cookie_6"]=>
++ ["cookie%206"]=>
+ string(3) "þæö"
+- ["cookie_7"]=>
++ ["cookie+7"]=>
+ string(0) ""
+ ["$cookie_8"]=>
+ string(0) ""
+diff --git a/tests/basic/023.phpt b/tests/basic/023.phpt
+index ca5f1dcfbb..0e2e0ac669 100644
+--- a/tests/basic/023.phpt
++++ b/tests/basic/023.phpt
+@@ -10,9 +10,11 @@ c o o k i e=value; c o o k i e= v a l u e ;;c%20o+o k+i%20e=v;name="value","valu
+ var_dump($_COOKIE);
+ ?>
+ --EXPECT--
+-array(3) {
++array(4) {
+ ["c_o_o_k_i_e"]=>
+ string(5) "value"
++ ["c%20o+o_k+i%20e"]=>
++ string(1) "v"
+ ["name"]=>
+ string(24) ""value","value",UEhQIQ=="
+ ["UEhQIQ"]=>
+diff --git a/tests/basic/bug79699.phpt b/tests/basic/bug79699.phpt
+new file mode 100644
+index 0000000000..fc3d3fedb0
+--- /dev/null
++++ b/tests/basic/bug79699.phpt
+@@ -0,0 +1,22 @@
++--TEST--
++Cookies Security Bug
++--INI--
++max_input_vars=1000
++filter.default=unsafe_raw
++--COOKIE--
++__%48ost-evil=evil; __Host-evil=good; %66oo=baz;foo=bar
++--FILE--
++<?php
++var_dump($_COOKIE);
++?>
++--EXPECT--
++array(4) {
++ ["__%48ost-evil"]=>
++ string(4) "evil"
++ ["__Host-evil"]=>
++ string(4) "good"
++ ["%66oo"]=>
++ string(3) "baz"
++ ["foo"]=>
++ string(3) "bar"
++}
+From 4248ab3d8ef089f23b93cdf979ce7a5690f8bf9d Mon Sep 17 00:00:00 2001
+From: Remi Collet <remi@remirepo.net>
+Date: Tue, 29 Sep 2020 09:11:38 +0200
+Subject: [PATCH] NEWS
+
+---
+ NEWS | 6 ++++++
+ 1 file changed, 6 insertions(+)
+
+diff --git a/NEWS b/NEWS
+index d826960c11..47848d24b7 100644
+--- a/NEWS
++++ b/NEWS
+@@ -1,6 +1,12 @@
+ PHP NEWS
+ |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
+
++Backported from 7.2.34
++
++- Core:
++ . Fixed bug #79699 (PHP parses encoded cookie names so malicious `__Host-`
++ cookies can be sent). (CVE-2020-7070) (Stas)
++
+ Backported from 7.2.33
+
+ - Core:
diff --git a/php-bug79797.patch b/php-bug79797.patch
new file mode 100644
index 0000000..c386b13
--- /dev/null
+++ b/php-bug79797.patch
@@ -0,0 +1,52 @@
+Partial, without binary part
+
+
+
+From bd3395d35b2bbed0f6716c33cff217b00eddc2eb Mon Sep 17 00:00:00 2001
+From: "Christoph M. Becker" <cmbecker69@gmx.de>
+Date: Tue, 14 Jul 2020 17:04:24 +0200
+Subject: [PATCH] Fix #79797: Use of freed hash key in the phar_parse_zipfile
+ function
+
+We must not use heap memory after we freed it.
+
+(cherry picked from commit 7355ab81763a3d6a04ac11660e6a16d58838d187)
+---
+ NEWS | 6 ++++++
+ ext/phar/tests/bug79797.phar | Bin 0 -> 274 bytes
+ ext/phar/tests/bug79797.phpt | 14 ++++++++++++++
+ ext/phar/zip.c | 2 +-
+ 4 files changed, 21 insertions(+), 1 deletion(-)
+ create mode 100644 ext/phar/tests/bug79797.phar
+ create mode 100644 ext/phar/tests/bug79797.phpt
+
+diff --git a/NEWS b/NEWS
+index e153539d98..2655a1747f 100644
+--- a/NEWS
++++ b/NEWS
+@@ -1,6 +1,12 @@
+ PHP NEWS
+ |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
+
++Backported from 7.2.33
++
++- Phar:
++ . Fixed bug #79797 (Use of freed hash key in the phar_parse_zipfile
++ function). (CVE-2020-7068) (cmb)
++
+ Backported from 7.2.31
+
+ - Core:
+diff --git a/ext/phar/zip.c b/ext/phar/zip.c
+index 1c05fbd80f..f9b43a5487 100644
+--- a/ext/phar/zip.c
++++ b/ext/phar/zip.c
+@@ -704,7 +704,7 @@ int phar_parse_zipfile(php_stream *fp, char *fname, int fname_len, char *alias,
+ efree(actual_alias);
+ }
+
+- zend_hash_str_add_ptr(&(PHAR_G(phar_alias_map)), actual_alias, mydata->alias_len, mydata);
++ zend_hash_str_add_ptr(&(PHAR_G(phar_alias_map)), mydata->alias, mydata->alias_len, mydata);
+ } else {
+ phar_archive_data *fd_ptr;
+
diff --git a/php-bug79877.patch b/php-bug79877.patch
new file mode 100644
index 0000000..932edb2
--- /dev/null
+++ b/php-bug79877.patch
@@ -0,0 +1,62 @@
+From 849eea1e486b64530235f03a91079337851f2d85 Mon Sep 17 00:00:00 2001
+From: "Christoph M. Becker" <cmbecker69@gmx.de>
+Date: Tue, 21 Jul 2020 11:07:43 +0200
+Subject: [PATCH] Fix #79877: getimagesize function silently truncates after a
+ null byte
+
+We have to check for NUL bytes if `getimagesize()` has been called.
+
+(cherry picked from commit ff577b04c0d250473a0ef46f8e332960fec3ca2c)
+---
+ NEWS | 4 ++++
+ ext/standard/image.c | 5 +++++
+ ext/standard/tests/image/bug79877.phpt | 9 +++++++++
+ 3 files changed, 18 insertions(+)
+ create mode 100644 ext/standard/tests/image/bug79877.phpt
+
+diff --git a/NEWS b/NEWS
+index 2655a1747f..d826960c11 100644
+--- a/NEWS
++++ b/NEWS
+@@ -3,6 +3,10 @@ PHP NEWS
+
+ Backported from 7.2.33
+
++- Core:
++ . Fixed bug #79877 (getimagesize function silently truncates after a null
++ byte) (cmb)
++
+ - Phar:
+ . Fixed bug #79797 (Use of freed hash key in the phar_parse_zipfile
+ function). (CVE-2020-7068) (cmb)
+diff --git a/ext/standard/image.c b/ext/standard/image.c
+index 2074d289df..c2f40923ad 100644
+--- a/ext/standard/image.c
++++ b/ext/standard/image.c
+@@ -1403,6 +1403,11 @@ static void php_getimagesize_from_any(INTERNAL_FUNCTION_PARAMETERS, int mode) {
+ return;
+ }
+
++ if (mode == FROM_PATH && CHECK_NULL_PATH(input, input_len)) {
++ php_error_docref(NULL, E_WARNING, "Invalid path");
++ return;
++ }
++
+ if (argc == 2) {
+ zval_dtor(info);
+ array_init(info);
+diff --git a/ext/standard/tests/image/bug79877.phpt b/ext/standard/tests/image/bug79877.phpt
+new file mode 100644
+index 0000000000..92e93e59e5
+--- /dev/null
++++ b/ext/standard/tests/image/bug79877.phpt
+@@ -0,0 +1,9 @@
++--TEST--
++Bug #79877 (getimagesize function silently truncates after a null byte)
++--FILE--
++<?php
++var_dump(getimagesize("/tmp/a.png\0xx"));
++?>
++--EXPECTF--
++Warning: getimagesize(): Invalid path in %s on line %d
++NULL
diff --git a/php-bug79971.patch b/php-bug79971.patch
new file mode 100644
index 0000000..28e7889
--- /dev/null
+++ b/php-bug79971.patch
@@ -0,0 +1,208 @@
+From 9e9a4876bb9cafe4d4ef20a469ffd4124d8f0ef1 Mon Sep 17 00:00:00 2001
+From: "Christoph M. Becker" <cmbecker69@gmx.de>
+Date: Tue, 1 Sep 2020 10:04:28 +0200
+Subject: [PATCH 1/3] Fix #79971: special character is breaking the path in xml
+ function
+
+The libxml based XML functions accepting a filename actually accept
+URIs with possibly percent-encoded characters. Percent-encoded NUL
+bytes lead to truncation, like non-encoded NUL bytes would. We catch
+those, and let the functions fail with a respective warning.
+
+(cherry picked from commit f15f8fc573eb38c3c73e23e0930063a6f6409ed4)
+---
+ ext/dom/domimplementation.c | 5 +++++
+ ext/dom/tests/bug79971_2.phpt | 20 ++++++++++++++++++++
+ ext/libxml/libxml.c | 9 +++++++++
+ ext/simplexml/tests/bug79971_1.phpt | 27 +++++++++++++++++++++++++++
+ ext/simplexml/tests/bug79971_1.xml | 2 ++
+ 5 files changed, 63 insertions(+)
+ create mode 100644 ext/dom/tests/bug79971_2.phpt
+ create mode 100644 ext/simplexml/tests/bug79971_1.phpt
+ create mode 100644 ext/simplexml/tests/bug79971_1.xml
+
+diff --git a/ext/dom/domimplementation.c b/ext/dom/domimplementation.c
+index ee050e21fd..486a49d52b 100644
+--- a/ext/dom/domimplementation.c
++++ b/ext/dom/domimplementation.c
+@@ -114,6 +114,11 @@ PHP_METHOD(domimplementation, createDocumentType)
+ pch2 = (xmlChar *) systemid;
+ }
+
++ if (strstr(name, "%00")) {
++ php_error_docref(NULL, E_WARNING, "URI must not contain percent-encoded NUL bytes");
++ RETURN_FALSE;
++ }
++
+ uri = xmlParseURI(name);
+ if (uri != NULL && uri->opaque != NULL) {
+ localname = xmlStrdup((xmlChar *) uri->opaque);
+diff --git a/ext/dom/tests/bug79971_2.phpt b/ext/dom/tests/bug79971_2.phpt
+new file mode 100644
+index 0000000000..c4e6b1e4e0
+--- /dev/null
++++ b/ext/dom/tests/bug79971_2.phpt
+@@ -0,0 +1,20 @@
++--TEST--
++Bug #79971 (special character is breaking the path in xml function)
++--SKIPIF--
++<?php
++if (!extension_loaded('dom')) die('skip dom extension not available');
++?>
++--FILE--
++<?php
++$imp = new DOMImplementation;
++if (PHP_OS_FAMILY === 'Windows') {
++ $path = '/' . str_replace('\\', '/', __DIR__);
++} else {
++ $path = __DIR__;
++}
++$uri = "file://$path/bug79971_2.xml";
++var_dump($imp->createDocumentType("$uri%00foo"));
++?>
++--EXPECTF--
++Warning: DOMImplementation::createDocumentType(): URI must not contain percent-encoded NUL bytes in %s on line %d
++bool(false)
+diff --git a/ext/libxml/libxml.c b/ext/libxml/libxml.c
+index da30004f36..f481353683 100644
+--- a/ext/libxml/libxml.c
++++ b/ext/libxml/libxml.c
+@@ -308,6 +308,10 @@ static void *php_libxml_streams_IO_open_wrapper(const char *filename, const char
+ int isescaped=0;
+ xmlURI *uri;
+
++ if (strstr(filename, "%00")) {
++ php_error_docref(NULL, E_WARNING, "URI must not contain percent-encoded NUL bytes");
++ return NULL;
++ }
+
+ uri = xmlParseURI(filename);
+ if (uri && (uri->scheme == NULL ||
+@@ -438,6 +442,11 @@ php_libxml_output_buffer_create_filename(const char *URI,
+ if (URI == NULL)
+ return(NULL);
+
++ if (strstr(URI, "%00")) {
++ php_error_docref(NULL, E_WARNING, "URI must not contain percent-encoded NUL bytes");
++ return NULL;
++ }
++
+ puri = xmlParseURI(URI);
+ if (puri != NULL) {
+ if (puri->scheme != NULL)
+diff --git a/ext/simplexml/tests/bug79971_1.phpt b/ext/simplexml/tests/bug79971_1.phpt
+new file mode 100644
+index 0000000000..197776d82d
+--- /dev/null
++++ b/ext/simplexml/tests/bug79971_1.phpt
+@@ -0,0 +1,27 @@
++--TEST--
++Bug #79971 (special character is breaking the path in xml function)
++--SKIPIF--
++<?php
++if (!extension_loaded('simplexml')) die('skip simplexml extension not available');
++?>
++--FILE--
++<?php
++if (PHP_OS_FAMILY === 'Windows') {
++ $path = '/' . str_replace('\\', '/', __DIR__);
++} else {
++ $path = __DIR__;
++}
++$uri = "file://$path/bug79971_1.xml";
++var_dump(simplexml_load_file("$uri%00foo"));
++
++$sxe = simplexml_load_file($uri);
++var_dump($sxe->asXML("$uri.out%00foo"));
++?>
++--EXPECTF--
++Warning: simplexml_load_file(): URI must not contain percent-encoded NUL bytes in %s on line %d
++
++Warning: simplexml_load_file(): I/O warning : failed to load external entity "%s/bug79971_1.xml%00foo" in %s on line %d
++bool(false)
++
++Warning: SimpleXMLElement::asXML(): URI must not contain percent-encoded NUL bytes in %s on line %d
++bool(false)
+diff --git a/ext/simplexml/tests/bug79971_1.xml b/ext/simplexml/tests/bug79971_1.xml
+new file mode 100644
+index 0000000000..912bb76d9d
+--- /dev/null
++++ b/ext/simplexml/tests/bug79971_1.xml
+@@ -0,0 +1,2 @@
++<?xml version="1.0"?>
++<root></root>
+--
+2.31.1
+
+From 927082f30d8bfb1434df25494e804bdc3d13ca5b Mon Sep 17 00:00:00 2001
+From: Remi Collet <remi@remirepo.net>
+Date: Mon, 15 Nov 2021 09:05:33 +0100
+Subject: [PATCH 2/3] NEWS
+
+(cherry picked from commit c032381da0bfb6457aa9cfa7a430790f6eab8178)
+---
+ NEWS | 8 +++++++-
+ 1 file changed, 7 insertions(+), 1 deletion(-)
+
+diff --git a/NEWS b/NEWS
+index fe2c75f2cf..0207f4caed 100644
+--- a/NEWS
++++ b/NEWS
+@@ -1,7 +1,13 @@
+ PHP NEWS
+ |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
+
+-Backported from 7.4.25
++Backported from 7.3.33
++
++- XML:
++ . Fix #79971: special character is breaking the path in xml function.
++ (CVE-2021-21707) (cmb)
++
++Backported from 7.3.32
+
+ - FPM:
+ . Fixed bug #81026 (PHP-FPM oob R/W in root process leading to privilege
+--
+2.31.1
+
+From 271e8b9203ba752de436cb090e3fe8f27c792de4 Mon Sep 17 00:00:00 2001
+From: Remi Collet <remi@remirepo.net>
+Date: Mon, 15 Nov 2021 09:57:10 +0100
+Subject: [PATCH 3/3] fix new tests
+
+(cherry picked from commit b21524ff3db15da5a7779cba73e3774eb5404d40)
+---
+ ext/dom/tests/bug79971_2.phpt | 2 +-
+ ext/simplexml/tests/bug79971_1.phpt | 2 +-
+ 2 files changed, 2 insertions(+), 2 deletions(-)
+
+diff --git a/ext/dom/tests/bug79971_2.phpt b/ext/dom/tests/bug79971_2.phpt
+index c4e6b1e4e0..01cd123541 100644
+--- a/ext/dom/tests/bug79971_2.phpt
++++ b/ext/dom/tests/bug79971_2.phpt
+@@ -7,7 +7,7 @@ if (!extension_loaded('dom')) die('skip dom extension not available');
+ --FILE--
+ <?php
+ $imp = new DOMImplementation;
+-if (PHP_OS_FAMILY === 'Windows') {
++if (DIRECTORY_SEPARATOR !== '/') {
+ $path = '/' . str_replace('\\', '/', __DIR__);
+ } else {
+ $path = __DIR__;
+diff --git a/ext/simplexml/tests/bug79971_1.phpt b/ext/simplexml/tests/bug79971_1.phpt
+index 197776d82d..464112c99e 100644
+--- a/ext/simplexml/tests/bug79971_1.phpt
++++ b/ext/simplexml/tests/bug79971_1.phpt
+@@ -6,7 +6,7 @@ if (!extension_loaded('simplexml')) die('skip simplexml extension not available'
+ ?>
+ --FILE--
+ <?php
+-if (PHP_OS_FAMILY === 'Windows') {
++if (DIRECTORY_SEPARATOR !== '/') {
+ $path = '/' . str_replace('\\', '/', __DIR__);
+ } else {
+ $path = __DIR__;
+--
+2.31.1
+
diff --git a/php-bug80672.patch b/php-bug80672.patch
new file mode 100644
index 0000000..cfc39d6
--- /dev/null
+++ b/php-bug80672.patch
@@ -0,0 +1,239 @@
+From 59fbaa328950cc73b47aaa975b53dc8ca423a440 Mon Sep 17 00:00:00 2001
+From: Stanislav Malyshev <stas@php.net>
+Date: Sun, 31 Jan 2021 21:15:23 -0800
+Subject: [PATCH 1/2] Fix bug #80672 - Null Dereference in SoapClient
+
+(cherry picked from commit 3c939e3f69955d087e0bb671868f7267dfb2a502)
+(cherry picked from commit f1e2cfa008d1596251968d13eb9a8539dba6879f)
+---
+ NEWS | 5 +++++
+ ext/soap/php_sdl.c | 26 ++++++++++++++------------
+ ext/soap/php_xml.c | 4 ++--
+ ext/soap/tests/bug80672.phpt | 15 +++++++++++++++
+ ext/soap/tests/bug80672.xml | 6 ++++++
+ 5 files changed, 42 insertions(+), 14 deletions(-)
+ create mode 100644 ext/soap/tests/bug80672.phpt
+ create mode 100644 ext/soap/tests/bug80672.xml
+
+diff --git a/NEWS b/NEWS
+index e328fd39c0..fe5564de15 100644
+--- a/NEWS
++++ b/NEWS
+@@ -1,6 +1,11 @@
+ PHP NEWS
+ |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
+
++Backported from 7.3.27
++
++- SOAP:
++ . Fixed bug #80672 (Null Dereference in SoapClient). (CVE-2021-21702) (cmb, Stas)
++
+ Backported from 7.3.26
+
+ - Standard:
+diff --git a/ext/soap/php_sdl.c b/ext/soap/php_sdl.c
+index c53fa8a758..c15b7b4323 100644
+--- a/ext/soap/php_sdl.c
++++ b/ext/soap/php_sdl.c
+@@ -314,6 +314,8 @@ void sdl_restore_uri_credentials(sdlCtx *ctx)
+ ctx->context = NULL;
+ }
+
++#define SAFE_STR(a) ((a)?a:"")
++
+ static void load_wsdl_ex(zval *this_ptr, char *struri, sdlCtx *ctx, int include)
+ {
+ sdlPtr tmpsdl = ctx->sdl;
+@@ -375,7 +377,7 @@ static void load_wsdl_ex(zval *this_ptr, char *struri, sdlCtx *ctx, int include)
+ if (node_is_equal_ex(trav2, "schema", XSD_NAMESPACE)) {
+ load_schema(ctx, trav2);
+ } else if (is_wsdl_element(trav2) && !node_is_equal(trav2,"documentation")) {
+- soap_error1(E_ERROR, "Parsing WSDL: Unexpected WSDL element <%s>", trav2->name);
++ soap_error1(E_ERROR, "Parsing WSDL: Unexpected WSDL element <%s>", SAFE_STR(trav2->name));
+ }
+ trav2 = trav2->next;
+ }
+@@ -436,7 +438,7 @@ static void load_wsdl_ex(zval *this_ptr, char *struri, sdlCtx *ctx, int include)
+ soap_error0(E_ERROR, "Parsing WSDL: <service> has no name attribute");
+ }
+ } else if (!node_is_equal(trav,"documentation")) {
+- soap_error1(E_ERROR, "Parsing WSDL: Unexpected WSDL element <%s>", trav->name);
++ soap_error1(E_ERROR, "Parsing WSDL: Unexpected WSDL element <%s>", SAFE_STR(trav->name));
+ }
+ trav = trav->next;
+ }
+@@ -546,7 +548,7 @@ static sdlSoapBindingFunctionHeaderPtr wsdl_soap_binding_header(sdlCtx* ctx, xml
+ }
+ smart_str_free(&key);
+ } else if (is_wsdl_element(trav) && !node_is_equal(trav,"documentation")) {
+- soap_error1(E_ERROR, "Parsing WSDL: Unexpected WSDL element <%s>", trav->name);
++ soap_error1(E_ERROR, "Parsing WSDL: Unexpected WSDL element <%s>", SAFE_STR(trav->name));
+ }
+ trav = trav->next;
+ }
+@@ -648,7 +650,7 @@ static void wsdl_soap_binding_body(sdlCtx* ctx, xmlNodePtr node, char* wsdl_soap
+ }
+ smart_str_free(&key);
+ } else if (is_wsdl_element(trav) && !node_is_equal(trav,"documentation")) {
+- soap_error1(E_ERROR, "Parsing WSDL: Unexpected WSDL element <%s>", trav->name);
++ soap_error1(E_ERROR, "Parsing WSDL: Unexpected WSDL element <%s>", SAFE_STR(trav->name));
+ }
+ trav = trav->next;
+ }
+@@ -680,14 +682,14 @@ static HashTable* wsdl_message(sdlCtx *ctx, xmlChar* message_name)
+ sdlParamPtr param;
+
+ if (trav->ns != NULL && strcmp((char*)trav->ns->href, WSDL_NAMESPACE) != 0) {
+- soap_error1(E_ERROR, "Parsing WSDL: Unexpected extensibility element <%s>", trav->name);
++ soap_error1(E_ERROR, "Parsing WSDL: Unexpected extensibility element <%s>", SAFE_STR(trav->name));
+ }
+ if (node_is_equal(trav,"documentation")) {
+ trav = trav->next;
+ continue;
+ }
+ if (!node_is_equal(trav,"part")) {
+- soap_error1(E_ERROR, "Parsing WSDL: Unexpected WSDL element <%s>", trav->name);
++ soap_error1(E_ERROR, "Parsing WSDL: Unexpected WSDL element <%s>", SAFE_STR(trav->name));
+ }
+ part = trav;
+ param = emalloc(sizeof(sdlParam));
+@@ -696,7 +698,7 @@ static HashTable* wsdl_message(sdlCtx *ctx, xmlChar* message_name)
+
+ name = get_attribute(part->properties, "name");
+ if (name == NULL) {
+- soap_error1(E_ERROR, "Parsing WSDL: No name associated with <part> '%s'", message->name);
++ soap_error1(E_ERROR, "Parsing WSDL: No name associated with <part> '%s'", SAFE_STR(message->name));
+ }
+
+ param->paramName = estrdup((char*)name->children->content);
+@@ -765,7 +767,7 @@ static sdlPtr load_wsdl(zval *this_ptr, char *struri)
+ continue;
+ }
+ if (!node_is_equal(trav,"port")) {
+- soap_error1(E_ERROR, "Parsing WSDL: Unexpected WSDL element <%s>", trav->name);
++ soap_error1(E_ERROR, "Parsing WSDL: Unexpected WSDL element <%s>", SAFE_STR(trav->name));
+ }
+
+ port = trav;
+@@ -804,7 +806,7 @@ static sdlPtr load_wsdl(zval *this_ptr, char *struri)
+ }
+ }
+ if (trav2 != address && is_wsdl_element(trav2) && !node_is_equal(trav2,"documentation")) {
+- soap_error1(E_ERROR, "Parsing WSDL: Unexpected WSDL element <%s>", trav2->name);
++ soap_error1(E_ERROR, "Parsing WSDL: Unexpected WSDL element <%s>", SAFE_STR(trav2->name));
+ }
+ trav2 = trav2->next;
+ }
+@@ -906,7 +908,7 @@ static sdlPtr load_wsdl(zval *this_ptr, char *struri)
+ continue;
+ }
+ if (!node_is_equal(trav2,"operation")) {
+- soap_error1(E_ERROR, "Parsing WSDL: Unexpected WSDL element <%s>", trav2->name);
++ soap_error1(E_ERROR, "Parsing WSDL: Unexpected WSDL element <%s>", SAFE_STR(trav2->name));
+ }
+
+ operation = trav2;
+@@ -925,7 +927,7 @@ static sdlPtr load_wsdl(zval *this_ptr, char *struri)
+ !node_is_equal(trav3,"output") &&
+ !node_is_equal(trav3,"fault") &&
+ !node_is_equal(trav3,"documentation")) {
+- soap_error1(E_ERROR, "Parsing WSDL: Unexpected WSDL element <%s>", trav3->name);
++ soap_error1(E_ERROR, "Parsing WSDL: Unexpected WSDL element <%s>", SAFE_STR(trav3->name));
+ }
+ trav3 = trav3->next;
+ }
+@@ -1103,7 +1105,7 @@ static sdlPtr load_wsdl(zval *this_ptr, char *struri)
+ }
+ }
+ } else if (is_wsdl_element(trav) && !node_is_equal(trav,"documentation")) {
+- soap_error1(E_ERROR, "Parsing WSDL: Unexpected WSDL element <%s>", trav->name);
++ soap_error1(E_ERROR, "Parsing WSDL: Unexpected WSDL element <%s>", SAFE_STR(trav->name));
+ }
+ trav = trav->next;
+ }
+diff --git a/ext/soap/php_xml.c b/ext/soap/php_xml.c
+index fb00c420a6..a9c6a56858 100644
+--- a/ext/soap/php_xml.c
++++ b/ext/soap/php_xml.c
+@@ -204,7 +204,7 @@ xmlNsPtr node_find_ns(xmlNodePtr node)
+
+ int attr_is_equal_ex(xmlAttrPtr node, char *name, char *ns)
+ {
+- if (name == NULL || strcmp((char*)node->name, name) == 0) {
++ if (name == NULL || ((node->name) && strcmp((char*)node->name, name) == 0)) {
+ if (ns) {
+ xmlNsPtr nsPtr = attr_find_ns(node);
+ if (nsPtr) {
+@@ -220,7 +220,7 @@ int attr_is_equal_ex(xmlAttrPtr node, char *name, char *ns)
+
+ int node_is_equal_ex(xmlNodePtr node, char *name, char *ns)
+ {
+- if (name == NULL || strcmp((char*)node->name, name) == 0) {
++ if (name == NULL || ((node->name) && strcmp((char*)node->name, name) == 0)) {
+ if (ns) {
+ xmlNsPtr nsPtr = node_find_ns(node);
+ if (nsPtr) {
+diff --git a/ext/soap/tests/bug80672.phpt b/ext/soap/tests/bug80672.phpt
+new file mode 100644
+index 0000000000..71e2b1d841
+--- /dev/null
++++ b/ext/soap/tests/bug80672.phpt
+@@ -0,0 +1,15 @@
++--TEST--
++Bug #80672 Null Dereference in SoapClient
++--SKIPIF--
++<?php require_once('skipif.inc'); ?>
++--FILE--
++<?php
++try {
++ $client = new SoapClient(__DIR__ . "/bug80672.xml");
++ $query = $soap->query(array('sXML' => 'something'));
++} catch(SoapFault $e) {
++ print $e->getMessage();
++}
++?>
++--EXPECTF--
++SOAP-ERROR: Parsing WSDL: Unexpected WSDL element <>
+\ No newline at end of file
+diff --git a/ext/soap/tests/bug80672.xml b/ext/soap/tests/bug80672.xml
+new file mode 100644
+index 0000000000..0fa185bf1e
+--- /dev/null
++++ b/ext/soap/tests/bug80672.xml
+@@ -0,0 +1,6 @@
++<?xml version="1.0" encoding="ISO-8859-1"?>
++<soap:definitions xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
++ xmlns:xsd="http://www.w3.org/2001/XMLSchema"
++ xmlns:soap="http://schemas.xmlsoap.org/wsdl/">
++<![CDATA[test]]>
++</soap:definitions>
+--
+2.29.2
+
+From e031e2f5eeb29881947899378d70318bca46249c Mon Sep 17 00:00:00 2001
+From: Nikita Popov <nikita.ppv@gmail.com>
+Date: Mon, 1 Feb 2021 09:46:17 +0100
+Subject: [PATCH 2/2] Fix build
+
+(cherry picked from commit e5d767d27f94895e09f0321562fd3774d4656164)
+(cherry picked from commit 02352d5acc1896756dcb4645f54689ffdcc4ca52)
+---
+ ext/soap/php_sdl.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/ext/soap/php_sdl.c b/ext/soap/php_sdl.c
+index c15b7b4323..4cc1ee69e7 100644
+--- a/ext/soap/php_sdl.c
++++ b/ext/soap/php_sdl.c
+@@ -314,7 +314,7 @@ void sdl_restore_uri_credentials(sdlCtx *ctx)
+ ctx->context = NULL;
+ }
+
+-#define SAFE_STR(a) ((a)?a:"")
++#define SAFE_STR(a) ((a)?((const char *)a):"")
+
+ static void load_wsdl_ex(zval *this_ptr, char *struri, sdlCtx *ctx, int include)
+ {
+--
+2.29.2
+
diff --git a/php-bug80710.patch b/php-bug80710.patch
new file mode 100644
index 0000000..d66dd07
--- /dev/null
+++ b/php-bug80710.patch
@@ -0,0 +1,373 @@
+From bfa81ac72836e53a75665eb1f78a6d67489da2e3 Mon Sep 17 00:00:00 2001
+From: "Christoph M. Becker" <cmbecker69@gmx.de>
+Date: Fri, 5 Feb 2021 22:51:41 +0100
+Subject: [PATCH 1/2] Fix #80710: imap_mail_compose() header injection
+
+Like `mail()` and `mb_send_mail()`, `imap_mail_compose()` must prevent
+header injection. For maximum backward compatibility, we still allow
+header folding for general headers, and still accept trailing line
+breaks for address lists.
+
+(cherry picked from commit 37962c61d29794645ec45d45d78123382d82c2e5)
+(cherry picked from commit 9017896cccefe000938f80b49361b1c183849922)
+---
+ ext/imap/php_imap.c | 56 ++++++++++++++++++++++++++++++++++
+ ext/imap/tests/bug80710_1.phpt | 37 ++++++++++++++++++++++
+ ext/imap/tests/bug80710_2.phpt | 37 ++++++++++++++++++++++
+ 3 files changed, 130 insertions(+)
+ create mode 100644 ext/imap/tests/bug80710_1.phpt
+ create mode 100644 ext/imap/tests/bug80710_2.phpt
+
+diff --git a/ext/imap/php_imap.c b/ext/imap/php_imap.c
+index 011cbc0dfd..5f8c0da79a 100644
+--- a/ext/imap/php_imap.c
++++ b/ext/imap/php_imap.c
+@@ -3531,6 +3531,23 @@ PHP_FUNCTION(imap_fetch_overview)
+ }
+ /* }}} */
+
++static zend_bool header_injection(zend_string *str, zend_bool adrlist)
++{
++ char *p = ZSTR_VAL(str);
++
++ while ((p = strpbrk(p, "\r\n")) != NULL) {
++ if (!(p[0] == '\r' && p[1] == '\n')
++ /* adrlists do not support folding, but swallow trailing line breaks */
++ && !((adrlist && p[1] == '\0')
++ /* other headers support folding */
++ || !adrlist && (p[1] == ' ' || p[1] == '\t'))) {
++ return 1;
++ }
++ p++;
++ }
++ return 0;
++}
++
+ /* {{{ proto string imap_mail_compose(array envelope, array body)
+ Create a MIME message based on given envelope and body sections */
+ PHP_FUNCTION(imap_mail_compose)
+@@ -3551,6 +3568,13 @@ PHP_FUNCTION(imap_mail_compose)
+ return;
+ }
+
++#define CHECK_HEADER_INJECTION(zstr, adrlist, header) \
++ if (header_injection(zstr, adrlist)) { \
++ php_error_docref(NULL, E_WARNING, "header injection attempt in " header); \
++ RETVAL_FALSE; \
++ goto done; \
++ }
++
+ #define PHP_RFC822_PARSE_ADRLIST(target, value) \
+ str_copy = estrndup(Z_STRVAL_P(value), Z_STRLEN_P(value)); \
+ rfc822_parse_adrlist(target, str_copy, "NO HOST"); \
+@@ -3559,46 +3583,57 @@ PHP_FUNCTION(imap_mail_compose)
+ env = mail_newenvelope();
+ if ((pvalue = zend_hash_str_find(Z_ARRVAL_P(envelope), "remail", sizeof("remail") - 1)) != NULL) {
+ convert_to_string_ex(pvalue);
++ CHECK_HEADER_INJECTION(Z_STR_P(pvalue), 0, "remail");
+ env->remail = cpystr(Z_STRVAL_P(pvalue));
+ }
+ if ((pvalue = zend_hash_str_find(Z_ARRVAL_P(envelope), "return_path", sizeof("return_path") - 1)) != NULL) {
+ convert_to_string_ex(pvalue);
++ CHECK_HEADER_INJECTION(Z_STR_P(pvalue), 1, "return_path");
+ PHP_RFC822_PARSE_ADRLIST(&env->return_path, pvalue);
+ }
+ if ((pvalue = zend_hash_str_find(Z_ARRVAL_P(envelope), "date", sizeof("date") - 1)) != NULL) {
+ convert_to_string_ex(pvalue);
++ CHECK_HEADER_INJECTION(Z_STR_P(pvalue), 0, "date");
+ env->date = (unsigned char*)cpystr(Z_STRVAL_P(pvalue));
+ }
+ if ((pvalue = zend_hash_str_find(Z_ARRVAL_P(envelope), "from", sizeof("from") - 1)) != NULL) {
+ convert_to_string_ex(pvalue);
++ CHECK_HEADER_INJECTION(Z_STR_P(pvalue), 1, "from");
+ PHP_RFC822_PARSE_ADRLIST(&env->from, pvalue);
+ }
+ if ((pvalue = zend_hash_str_find(Z_ARRVAL_P(envelope), "reply_to", sizeof("reply_to") - 1)) != NULL) {
+ convert_to_string_ex(pvalue);
++ CHECK_HEADER_INJECTION(Z_STR_P(pvalue), 1, "reply_to");
+ PHP_RFC822_PARSE_ADRLIST(&env->reply_to, pvalue);
+ }
+ if ((pvalue = zend_hash_str_find(Z_ARRVAL_P(envelope), "in_reply_to", sizeof("in_reply_to") - 1)) != NULL) {
+ convert_to_string_ex(pvalue);
++ CHECK_HEADER_INJECTION(Z_STR_P(pvalue), 0, "in_reply_to");
+ env->in_reply_to = cpystr(Z_STRVAL_P(pvalue));
+ }
+ if ((pvalue = zend_hash_str_find(Z_ARRVAL_P(envelope), "subject", sizeof("subject") - 1)) != NULL) {
+ convert_to_string_ex(pvalue);
++ CHECK_HEADER_INJECTION(Z_STR_P(pvalue), 0, "subject");
+ env->subject = cpystr(Z_STRVAL_P(pvalue));
+ }
+ if ((pvalue = zend_hash_str_find(Z_ARRVAL_P(envelope), "to", sizeof("to") - 1)) != NULL) {
+ convert_to_string_ex(pvalue);
++ CHECK_HEADER_INJECTION(Z_STR_P(pvalue), 1, "to");
+ PHP_RFC822_PARSE_ADRLIST(&env->to, pvalue);
+ }
+ if ((pvalue = zend_hash_str_find(Z_ARRVAL_P(envelope), "cc", sizeof("cc") - 1)) != NULL) {
+ convert_to_string_ex(pvalue);
++ CHECK_HEADER_INJECTION(Z_STR_P(pvalue), 1, "cc");
+ PHP_RFC822_PARSE_ADRLIST(&env->cc, pvalue);
+ }
+ if ((pvalue = zend_hash_str_find(Z_ARRVAL_P(envelope), "bcc", sizeof("bcc") - 1)) != NULL) {
+ convert_to_string_ex(pvalue);
++ CHECK_HEADER_INJECTION(Z_STR_P(pvalue), 1, "bcc");
+ PHP_RFC822_PARSE_ADRLIST(&env->bcc, pvalue);
+ }
+ if ((pvalue = zend_hash_str_find(Z_ARRVAL_P(envelope), "message_id", sizeof("message_id") - 1)) != NULL) {
+ convert_to_string_ex(pvalue);
++ CHECK_HEADER_INJECTION(Z_STR_P(pvalue), 0, "message_id");
+ env->message_id=cpystr(Z_STRVAL_P(pvalue));
+ }
+
+@@ -3608,6 +3643,7 @@ PHP_FUNCTION(imap_mail_compose)
+ ZEND_HASH_FOREACH_VAL(Z_ARRVAL_P(pvalue), env_data) {
+ custom_headers_param = mail_newbody_parameter();
+ convert_to_string_ex(env_data);
++ CHECK_HEADER_INJECTION(Z_STR_P(env_data), 0, "custom_headers");
+ custom_headers_param->value = (char *) fs_get(Z_STRLEN_P(env_data) + 1);
+ custom_headers_param->attribute = NULL;
+ memcpy(custom_headers_param->value, Z_STRVAL_P(env_data), Z_STRLEN_P(env_data) + 1);
+@@ -3640,6 +3676,7 @@ PHP_FUNCTION(imap_mail_compose)
+ }
+ if ((pvalue = zend_hash_str_find(Z_ARRVAL_P(data), "charset", sizeof("charset") - 1)) != NULL) {
+ convert_to_string_ex(pvalue);
++ CHECK_HEADER_INJECTION(Z_STR_P(pvalue), 0, "body charset");
+ tmp_param = mail_newbody_parameter();
+ tmp_param->value = cpystr(Z_STRVAL_P(pvalue));
+ tmp_param->attribute = cpystr("CHARSET");
+@@ -3650,9 +3687,11 @@ PHP_FUNCTION(imap_mail_compose)
+ if(Z_TYPE_P(pvalue) == IS_ARRAY) {
+ disp_param = tmp_param = NULL;
+ ZEND_HASH_FOREACH_STR_KEY_VAL(Z_ARRVAL_P(pvalue), key, disp_data) {
++ CHECK_HEADER_INJECTION(key, 0, "body disposition key");
+ disp_param = mail_newbody_parameter();
+ disp_param->attribute = cpystr(ZSTR_VAL(key));
+ convert_to_string_ex(disp_data);
++ CHECK_HEADER_INJECTION(Z_STR_P(disp_data), 0, "body disposition value");
+ disp_param->value = (char *) fs_get(Z_STRLEN_P(disp_data) + 1);
+ memcpy(disp_param->value, Z_STRVAL_P(disp_data), Z_STRLEN_P(disp_data) + 1);
+ disp_param->next = tmp_param;
+@@ -3663,18 +3702,22 @@ PHP_FUNCTION(imap_mail_compose)
+ }
+ if ((pvalue = zend_hash_str_find(Z_ARRVAL_P(data), "subtype", sizeof("subtype") - 1)) != NULL) {
+ convert_to_string_ex(pvalue);
++ CHECK_HEADER_INJECTION(Z_STR_P(pvalue), 0, "body subtype");
+ bod->subtype = cpystr(Z_STRVAL_P(pvalue));
+ }
+ if ((pvalue = zend_hash_str_find(Z_ARRVAL_P(data), "id", sizeof("id") - 1)) != NULL) {
+ convert_to_string_ex(pvalue);
++ CHECK_HEADER_INJECTION(Z_STR_P(pvalue), 0, "body id");
+ bod->id = cpystr(Z_STRVAL_P(pvalue));
+ }
+ if ((pvalue = zend_hash_str_find(Z_ARRVAL_P(data), "description", sizeof("description") - 1)) != NULL) {
+ convert_to_string_ex(pvalue);
++ CHECK_HEADER_INJECTION(Z_STR_P(pvalue), 0, "body description");
+ bod->description = cpystr(Z_STRVAL_P(pvalue));
+ }
+ if ((pvalue = zend_hash_str_find(Z_ARRVAL_P(data), "disposition.type", sizeof("disposition.type") - 1)) != NULL) {
+ convert_to_string_ex(pvalue);
++ CHECK_HEADER_INJECTION(Z_STR_P(pvalue), 0, "body disposition.type");
+ bod->disposition.type = (char *) fs_get(Z_STRLEN_P(pvalue) + 1);
+ memcpy(bod->disposition.type, Z_STRVAL_P(pvalue), Z_STRLEN_P(pvalue)+1);
+ }
+@@ -3682,9 +3725,11 @@ PHP_FUNCTION(imap_mail_compose)
+ if (Z_TYPE_P(pvalue) == IS_ARRAY) {
+ disp_param = tmp_param = NULL;
+ ZEND_HASH_FOREACH_STR_KEY_VAL(Z_ARRVAL_P(pvalue), key, disp_data) {
++ CHECK_HEADER_INJECTION(key, 0, "body type.parameters key");
+ disp_param = mail_newbody_parameter();
+ disp_param->attribute = cpystr(ZSTR_VAL(key));
+ convert_to_string_ex(disp_data);
++ CHECK_HEADER_INJECTION(Z_STR_P(disp_data), 0, "body type.parameters value");
+ disp_param->value = (char *) fs_get(Z_STRLEN_P(disp_data) + 1);
+ memcpy(disp_param->value, Z_STRVAL_P(disp_data), Z_STRLEN_P(disp_data) + 1);
+ disp_param->next = tmp_param;
+@@ -3713,6 +3758,7 @@ PHP_FUNCTION(imap_mail_compose)
+ }
+ if ((pvalue = zend_hash_str_find(Z_ARRVAL_P(data), "md5", sizeof("md5") - 1)) != NULL) {
+ convert_to_string_ex(pvalue);
++ CHECK_HEADER_INJECTION(Z_STR_P(pvalue), 0, "body md5");
+ bod->md5 = cpystr(Z_STRVAL_P(pvalue));
+ }
+ } else if (Z_TYPE_P(data) == IS_ARRAY) {
+@@ -3743,6 +3789,7 @@ PHP_FUNCTION(imap_mail_compose)
+ }
+ if ((pvalue = zend_hash_str_find(Z_ARRVAL_P(data), "charset", sizeof("charset") - 1)) != NULL) {
+ convert_to_string_ex(pvalue);
++ CHECK_HEADER_INJECTION(Z_STR_P(pvalue), 0, "body charset");
+ tmp_param = mail_newbody_parameter();
+ tmp_param->value = (char *) fs_get(Z_STRLEN_P(pvalue) + 1);
+ memcpy(tmp_param->value, Z_STRVAL_P(pvalue), Z_STRLEN_P(pvalue) + 1);
+@@ -3754,9 +3801,11 @@ PHP_FUNCTION(imap_mail_compose)
+ if (Z_TYPE_P(pvalue) == IS_ARRAY) {
+ disp_param = tmp_param = NULL;
+ ZEND_HASH_FOREACH_STR_KEY_VAL(Z_ARRVAL_P(pvalue), key, disp_data) {
++ CHECK_HEADER_INJECTION(key, 0, "body type.parameters key");
+ disp_param = mail_newbody_parameter();
+ disp_param->attribute = cpystr(ZSTR_VAL(key));
+ convert_to_string_ex(disp_data);
++ CHECK_HEADER_INJECTION(Z_STR_P(disp_data), 0, "body type.parameters value");
+ disp_param->value = (char *)fs_get(Z_STRLEN_P(disp_data) + 1);
+ memcpy(disp_param->value, Z_STRVAL_P(disp_data), Z_STRLEN_P(disp_data) + 1);
+ disp_param->next = tmp_param;
+@@ -3767,18 +3816,22 @@ PHP_FUNCTION(imap_mail_compose)
+ }
+ if ((pvalue = zend_hash_str_find(Z_ARRVAL_P(data), "subtype", sizeof("subtype") - 1)) != NULL) {
+ convert_to_string_ex(pvalue);
++ CHECK_HEADER_INJECTION(Z_STR_P(pvalue), 0, "body subtype");
+ bod->subtype = cpystr(Z_STRVAL_P(pvalue));
+ }
+ if ((pvalue = zend_hash_str_find(Z_ARRVAL_P(data), "id", sizeof("id") - 1)) != NULL) {
+ convert_to_string_ex(pvalue);
++ CHECK_HEADER_INJECTION(Z_STR_P(pvalue), 0, "body id");
+ bod->id = cpystr(Z_STRVAL_P(pvalue));
+ }
+ if ((pvalue = zend_hash_str_find(Z_ARRVAL_P(data), "description", sizeof("description") - 1)) != NULL) {
+ convert_to_string_ex(pvalue);
++ CHECK_HEADER_INJECTION(Z_STR_P(pvalue), 0, "body description");
+ bod->description = cpystr(Z_STRVAL_P(pvalue));
+ }
+ if ((pvalue = zend_hash_str_find(Z_ARRVAL_P(data), "disposition.type", sizeof("disposition.type") - 1)) != NULL) {
+ convert_to_string_ex(pvalue);
++ CHECK_HEADER_INJECTION(Z_STR_P(pvalue), 0, "body disposition.type");
+ bod->disposition.type = (char *) fs_get(Z_STRLEN_P(pvalue) + 1);
+ memcpy(bod->disposition.type, Z_STRVAL_P(pvalue), Z_STRLEN_P(pvalue)+1);
+ }
+@@ -3786,9 +3839,11 @@ PHP_FUNCTION(imap_mail_compose)
+ if (Z_TYPE_P(pvalue) == IS_ARRAY) {
+ disp_param = tmp_param = NULL;
+ ZEND_HASH_FOREACH_STR_KEY_VAL(Z_ARRVAL_P(pvalue), key, disp_data) {
++ CHECK_HEADER_INJECTION(key, 0, "body disposition key");
+ disp_param = mail_newbody_parameter();
+ disp_param->attribute = cpystr(ZSTR_VAL(key));
+ convert_to_string_ex(disp_data);
++ CHECK_HEADER_INJECTION(Z_STR_P(disp_data), 0, "body disposition value");
+ disp_param->value = (char *) fs_get(Z_STRLEN_P(disp_data) + 1);
+ memcpy(disp_param->value, Z_STRVAL_P(disp_data), Z_STRLEN_P(disp_data) + 1);
+ disp_param->next = tmp_param;
+@@ -3817,6 +3872,7 @@ PHP_FUNCTION(imap_mail_compose)
+ }
+ if ((pvalue = zend_hash_str_find(Z_ARRVAL_P(data), "md5", sizeof("md5") - 1)) != NULL) {
+ convert_to_string_ex(pvalue);
++ CHECK_HEADER_INJECTION(Z_STR_P(pvalue), 0, "body md5");
+ bod->md5 = cpystr(Z_STRVAL_P(pvalue));
+ }
+ }
+diff --git a/ext/imap/tests/bug80710_1.phpt b/ext/imap/tests/bug80710_1.phpt
+new file mode 100644
+index 0000000000..5cdee03401
+--- /dev/null
++++ b/ext/imap/tests/bug80710_1.phpt
+@@ -0,0 +1,37 @@
++--TEST--
++Bug #80710 (imap_mail_compose() header injection) - MIME Splitting Attack
++--SKIPIF--
++<?php
++if (!extension_loaded("imap")) die("skip imap extension not available");
++?>
++--FILE--
++<?php
++$envelope["from"]= "joe@example.com\n From : X-INJECTED";
++$envelope["to"] = "foo@example.com\nFrom: X-INJECTED";
++$envelope["cc"] = "bar@example.com\nFrom: X-INJECTED";
++$envelope["subject"] = "bar@example.com\n\n From : X-INJECTED";
++$envelope["x-remail"] = "bar@example.com\nFrom: X-INJECTED";
++$envelope["something"] = "bar@example.com\nFrom: X-INJECTED";
++
++$part1["type"] = TYPEMULTIPART;
++$part1["subtype"] = "mixed";
++
++$part2["type"] = TYPEAPPLICATION;
++$part2["encoding"] = ENCBINARY;
++$part2["subtype"] = "octet-stream\nContent-Type: X-INJECTED";
++$part2["description"] = "some file\nContent-Type: X-INJECTED";
++$part2["contents.data"] = "ABC\nContent-Type: X-INJECTED";
++
++$part3["type"] = TYPETEXT;
++$part3["subtype"] = "plain";
++$part3["description"] = "description3";
++$part3["contents.data"] = "contents.data3\n\n\n\t";
++
++$body[1] = $part1;
++$body[2] = $part2;
++$body[3] = $part3;
++
++echo imap_mail_compose($envelope, $body);
++?>
++--EXPECTF--
++Warning: imap_mail_compose(): header injection attempt in from in %s on line %d
+diff --git a/ext/imap/tests/bug80710_2.phpt b/ext/imap/tests/bug80710_2.phpt
+new file mode 100644
+index 0000000000..b9f2fa8544
+--- /dev/null
++++ b/ext/imap/tests/bug80710_2.phpt
+@@ -0,0 +1,37 @@
++--TEST--
++Bug #80710 (imap_mail_compose() header injection) - Remail
++--SKIPIF--
++<?php
++if (!extension_loaded("imap")) die("skip imap extension not available");
++?>
++--FILE--
++<?php
++$envelope["from"]= "joe@example.com\n From : X-INJECTED";
++$envelope["to"] = "foo@example.com\nFrom: X-INJECTED";
++$envelope["cc"] = "bar@example.com\nFrom: X-INJECTED";
++$envelope["subject"] = "bar@example.com\n\n From : X-INJECTED";
++$envelope["remail"] = "X-INJECTED-REMAIL: X-INJECTED\nFrom: X-INJECTED-REMAIL-FROM"; //<--- Injected as first hdr
++$envelope["something"] = "bar@example.com\nFrom: X-INJECTED";
++
++$part1["type"] = TYPEMULTIPART;
++$part1["subtype"] = "mixed";
++
++$part2["type"] = TYPEAPPLICATION;
++$part2["encoding"] = ENCBINARY;
++$part2["subtype"] = "octet-stream\nContent-Type: X-INJECTED";
++$part2["description"] = "some file\nContent-Type: X-INJECTED";
++$part2["contents.data"] = "ABC\nContent-Type: X-INJECTED";
++
++$part3["type"] = TYPETEXT;
++$part3["subtype"] = "plain";
++$part3["description"] = "description3";
++$part3["contents.data"] = "contents.data3\n\n\n\t";
++
++$body[1] = $part1;
++$body[2] = $part2;
++$body[3] = $part3;
++
++echo imap_mail_compose($envelope, $body);
++?>
++--EXPECTF--
++Warning: imap_mail_compose(): header injection attempt in remail in %s on line %d
+--
+2.30.2
+
+From 5a31584debadbb8e7195d768edece32b249e14bb Mon Sep 17 00:00:00 2001
+From: "Christoph M. Becker" <cmbecker69@gmx.de>
+Date: Tue, 27 Apr 2021 13:38:39 +0200
+Subject: [PATCH 2/2] Add missing NEWS entry for #80710
+
+(cherry picked from commit 60a68a45c3e9f63585151221e7fe9ddff78bd71f)
+(cherry picked from commit f16c623ec8ae3f3cdc73ab3fa05ae6bb0a77d1f3)
+---
+ NEWS | 5 +++++
+ 1 file changed, 5 insertions(+)
+
+diff --git a/NEWS b/NEWS
+index fe5564de15..9eff4bd7ae 100644
+--- a/NEWS
++++ b/NEWS
+@@ -1,6 +1,11 @@
+ PHP NEWS
+ |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
+
++Backported from 7.3.28
++
++- Imap:
++ . Fixed bug #80710 (imap_mail_compose() header injection). (cmb, Stas)
++
+ Backported from 7.3.27
+
+ - SOAP:
+--
+2.30.2
+
diff --git a/php-bug81026.patch b/php-bug81026.patch
new file mode 100644
index 0000000..7338dde
--- /dev/null
+++ b/php-bug81026.patch
@@ -0,0 +1,430 @@
+From 4699cc1b1b957c843c71a79fa816446b622d4278 Mon Sep 17 00:00:00 2001
+From: Jakub Zelenka <bukka@php.net>
+Date: Sat, 2 Oct 2021 22:53:41 +0100
+Subject: [PATCH 1/2] Fix bug #81026 (PHP-FPM oob R/W in root process leading
+ to priv escalation)
+
+The main change is to store scoreboard procs directly to the variable sized
+array rather than indirectly through the pointer.
+
+Signed-off-by: Stanislav Malyshev <stas@php.net>
+(cherry picked from commit cb2021e5f69da5e2868130a05bb53db0f9f89e4b)
+---
+ sapi/fpm/fpm/fpm_children.c | 14 ++---
+ sapi/fpm/fpm/fpm_request.c | 4 +-
+ sapi/fpm/fpm/fpm_scoreboard.c | 107 +++++++++++++++++++--------------
+ sapi/fpm/fpm/fpm_scoreboard.h | 11 ++--
+ sapi/fpm/fpm/fpm_status.c | 4 +-
+ sapi/fpm/fpm/fpm_worker_pool.c | 2 +-
+ 6 files changed, 81 insertions(+), 61 deletions(-)
+
+diff --git a/sapi/fpm/fpm/fpm_children.c b/sapi/fpm/fpm/fpm_children.c
+index b48fa54f53..c7f97fd490 100644
+--- a/sapi/fpm/fpm/fpm_children.c
++++ b/sapi/fpm/fpm/fpm_children.c
+@@ -239,7 +239,7 @@ void fpm_children_bury() /* {{{ */
+
+ fpm_child_unlink(child);
+
+- fpm_scoreboard_proc_free(wp->scoreboard, child->scoreboard_i);
++ fpm_scoreboard_proc_free(child);
+
+ fpm_clock_get(&tv1);
+
+@@ -249,9 +249,9 @@ void fpm_children_bury() /* {{{ */
+ if (!fpm_pctl_can_spawn_children()) {
+ severity = ZLOG_DEBUG;
+ }
+- zlog(severity, "[pool %s] child %d exited %s after %ld.%06d seconds from start", child->wp->config->name, (int) pid, buf, tv2.tv_sec, (int) tv2.tv_usec);
++ zlog(severity, "[pool %s] child %d exited %s after %ld.%06d seconds from start", wp->config->name, (int) pid, buf, tv2.tv_sec, (int) tv2.tv_usec);
+ } else {
+- zlog(ZLOG_DEBUG, "[pool %s] child %d has been killed by the process management after %ld.%06d seconds from start", child->wp->config->name, (int) pid, tv2.tv_sec, (int) tv2.tv_usec);
++ zlog(ZLOG_DEBUG, "[pool %s] child %d has been killed by the process management after %ld.%06d seconds from start", wp->config->name, (int) pid, tv2.tv_sec, (int) tv2.tv_usec);
+ }
+
+ fpm_child_close(child, 1 /* in event_loop */);
+@@ -317,7 +317,7 @@ static struct fpm_child_s *fpm_resources_prepare(struct fpm_worker_pool_s *wp) /
+ return 0;
+ }
+
+- if (0 > fpm_scoreboard_proc_alloc(wp->scoreboard, &c->scoreboard_i)) {
++ if (0 > fpm_scoreboard_proc_alloc(c)) {
+ fpm_stdio_discard_pipes(c);
+ fpm_child_free(c);
+ return 0;
+@@ -329,7 +329,7 @@ static struct fpm_child_s *fpm_resources_prepare(struct fpm_worker_pool_s *wp) /
+
+ static void fpm_resources_discard(struct fpm_child_s *child) /* {{{ */
+ {
+- fpm_scoreboard_proc_free(child->wp->scoreboard, child->scoreboard_i);
++ fpm_scoreboard_proc_free(child);
+ fpm_stdio_discard_pipes(child);
+ fpm_child_free(child);
+ }
+@@ -342,10 +342,10 @@ static void fpm_child_resources_use(struct fpm_child_s *child) /* {{{ */
+ if (wp == child->wp) {
+ continue;
+ }
+- fpm_scoreboard_free(wp->scoreboard);
++ fpm_scoreboard_free(wp);
+ }
+
+- fpm_scoreboard_child_use(child->wp->scoreboard, child->scoreboard_i, getpid());
++ fpm_scoreboard_child_use(child, getpid());
+ fpm_stdio_child_use_pipes(child);
+ fpm_child_free(child);
+ }
+diff --git a/sapi/fpm/fpm/fpm_request.c b/sapi/fpm/fpm/fpm_request.c
+index 3f82a7d4f7..a707fd29f6 100644
+--- a/sapi/fpm/fpm/fpm_request.c
++++ b/sapi/fpm/fpm/fpm_request.c
+@@ -287,7 +287,7 @@ int fpm_request_is_idle(struct fpm_child_s *child) /* {{{ */
+ struct fpm_scoreboard_proc_s *proc;
+
+ /* no need in atomicity here */
+- proc = fpm_scoreboard_proc_get(child->wp->scoreboard, child->scoreboard_i);
++ proc = fpm_scoreboard_proc_get_from_child(child);
+ if (!proc) {
+ return 0;
+ }
+@@ -302,7 +302,7 @@ int fpm_request_last_activity(struct fpm_child_s *child, struct timeval *tv) /*
+
+ if (!tv) return -1;
+
+- proc = fpm_scoreboard_proc_get(child->wp->scoreboard, child->scoreboard_i);
++ proc = fpm_scoreboard_proc_get_from_child(child);
+ if (!proc) {
+ return -1;
+ }
+diff --git a/sapi/fpm/fpm/fpm_scoreboard.c b/sapi/fpm/fpm/fpm_scoreboard.c
+index 5693ce4e49..45d44f4bbb 100644
+--- a/sapi/fpm/fpm/fpm_scoreboard.c
++++ b/sapi/fpm/fpm/fpm_scoreboard.c
+@@ -8,6 +8,7 @@
+ #include <time.h>
+
+ #include "fpm_config.h"
++#include "fpm_children.h"
+ #include "fpm_scoreboard.h"
+ #include "fpm_shm.h"
+ #include "fpm_sockets.h"
+@@ -25,7 +26,6 @@ static float fpm_scoreboard_tick;
+ int fpm_scoreboard_init_main() /* {{{ */
+ {
+ struct fpm_worker_pool_s *wp;
+- unsigned int i;
+
+ #ifdef HAVE_TIMES
+ #if (defined(HAVE_SYSCONF) && defined(_SC_CLK_TCK))
+@@ -42,7 +42,7 @@ int fpm_scoreboard_init_main() /* {{{ */
+
+
+ for (wp = fpm_worker_all_pools; wp; wp = wp->next) {
+- size_t scoreboard_size, scoreboard_nprocs_size;
++ size_t scoreboard_procs_size;
+ void *shm_mem;
+
+ if (wp->config->pm_max_children < 1) {
+@@ -55,22 +55,15 @@ int fpm_scoreboard_init_main() /* {{{ */
+ return -1;
+ }
+
+- scoreboard_size = sizeof(struct fpm_scoreboard_s) + (wp->config->pm_max_children) * sizeof(struct fpm_scoreboard_proc_s *);
+- scoreboard_nprocs_size = sizeof(struct fpm_scoreboard_proc_s) * wp->config->pm_max_children;
+- shm_mem = fpm_shm_alloc(scoreboard_size + scoreboard_nprocs_size);
++ scoreboard_procs_size = sizeof(struct fpm_scoreboard_proc_s) * wp->config->pm_max_children;
++ shm_mem = fpm_shm_alloc(sizeof(struct fpm_scoreboard_s) + scoreboard_procs_size);
+
+ if (!shm_mem) {
+ return -1;
+ }
+- wp->scoreboard = shm_mem;
++ wp->scoreboard = shm_mem;
++ wp->scoreboard->pm = wp->config->pm;
+ wp->scoreboard->nprocs = wp->config->pm_max_children;
+- shm_mem += scoreboard_size;
+-
+- for (i = 0; i < wp->scoreboard->nprocs; i++, shm_mem += sizeof(struct fpm_scoreboard_proc_s)) {
+- wp->scoreboard->procs[i] = shm_mem;
+- }
+-
+- wp->scoreboard->pm = wp->config->pm;
+ wp->scoreboard->start_epoch = time(NULL);
+ strlcpy(wp->scoreboard->pool, wp->config->name, sizeof(wp->scoreboard->pool));
+ }
+@@ -164,28 +157,47 @@ struct fpm_scoreboard_s *fpm_scoreboard_get() /* {{{*/
+ }
+ /* }}} */
+
+-struct fpm_scoreboard_proc_s *fpm_scoreboard_proc_get(struct fpm_scoreboard_s *scoreboard, int child_index) /* {{{*/
++static inline struct fpm_scoreboard_proc_s *fpm_scoreboard_proc_get_ex(
++ struct fpm_scoreboard_s *scoreboard, int child_index, unsigned int nprocs) /* {{{*/
+ {
+ if (!scoreboard) {
+- scoreboard = fpm_scoreboard;
++ return NULL;
+ }
+
+- if (!scoreboard) {
++ if (child_index < 0 || (unsigned int)child_index >= nprocs) {
+ return NULL;
+ }
+
++ return &scoreboard->procs[child_index];
++}
++/* }}} */
++
++struct fpm_scoreboard_proc_s *fpm_scoreboard_proc_get(
++ struct fpm_scoreboard_s *scoreboard, int child_index) /* {{{*/
++{
++ if (!scoreboard) {
++ scoreboard = fpm_scoreboard;
++ }
++
+ if (child_index < 0) {
+ child_index = fpm_scoreboard_i;
+ }
+
+- if (child_index < 0 || child_index >= scoreboard->nprocs) {
+- return NULL;
+- }
++ return fpm_scoreboard_proc_get_ex(scoreboard, child_index, scoreboard->nprocs);
++}
++
++struct fpm_scoreboard_proc_s *fpm_scoreboard_proc_get_from_child(struct fpm_child_s *child) /* {{{*/
++{
++ struct fpm_worker_pool_s *wp = child->wp;
++ unsigned int nprocs = wp->config->pm_max_children;
++ struct fpm_scoreboard_s *scoreboard = wp->scoreboard;
++ int child_index = child->scoreboard_i;
+
+- return scoreboard->procs[child_index];
++ return fpm_scoreboard_proc_get_ex(scoreboard, child_index, nprocs);
+ }
+ /* }}} */
+
++
+ struct fpm_scoreboard_s *fpm_scoreboard_acquire(struct fpm_scoreboard_s *scoreboard, int nohang) /* {{{ */
+ {
+ struct fpm_scoreboard_s *s;
+@@ -236,28 +248,28 @@ void fpm_scoreboard_proc_release(struct fpm_scoreboard_proc_s *proc) /* {{{ */
+ proc->lock = 0;
+ }
+
+-void fpm_scoreboard_free(struct fpm_scoreboard_s *scoreboard) /* {{{ */
++void fpm_scoreboard_free(struct fpm_worker_pool_s *wp) /* {{{ */
+ {
+- size_t scoreboard_size, scoreboard_nprocs_size;
++ size_t scoreboard_procs_size;
++ struct fpm_scoreboard_s *scoreboard = wp->scoreboard;
+
+ if (!scoreboard) {
+ zlog(ZLOG_ERROR, "**scoreboard is NULL");
+ return;
+ }
+
+- scoreboard_size = sizeof(struct fpm_scoreboard_s) + (scoreboard->nprocs) * sizeof(struct fpm_scoreboard_proc_s *);
+- scoreboard_nprocs_size = sizeof(struct fpm_scoreboard_proc_s) * scoreboard->nprocs;
+-
+- fpm_shm_free(scoreboard, scoreboard_size + scoreboard_nprocs_size);
++ scoreboard_procs_size = sizeof(struct fpm_scoreboard_proc_s) * wp->config->pm_max_children;
++
++ fpm_shm_free(scoreboard, sizeof(struct fpm_scoreboard_s) + scoreboard_procs_size);
+ }
+ /* }}} */
+
+-void fpm_scoreboard_child_use(struct fpm_scoreboard_s *scoreboard, int child_index, pid_t pid) /* {{{ */
++void fpm_scoreboard_child_use(struct fpm_child_s *child, pid_t pid) /* {{{ */
+ {
+ struct fpm_scoreboard_proc_s *proc;
+- fpm_scoreboard = scoreboard;
+- fpm_scoreboard_i = child_index;
+- proc = fpm_scoreboard_proc_get(scoreboard, child_index);
++ fpm_scoreboard = child->wp->scoreboard;
++ fpm_scoreboard_i = child->scoreboard_i;
++ proc = fpm_scoreboard_proc_get_from_child(child);
+ if (!proc) {
+ return;
+ }
+@@ -266,18 +278,22 @@ void fpm_scoreboard_child_use(struct fpm_scoreboard_s *scoreboard, int child_ind
+ }
+ /* }}} */
+
+-void fpm_scoreboard_proc_free(struct fpm_scoreboard_s *scoreboard, int child_index) /* {{{ */
++void fpm_scoreboard_proc_free(struct fpm_child_s *child) /* {{{ */
+ {
++ struct fpm_worker_pool_s *wp = child->wp;
++ struct fpm_scoreboard_s *scoreboard = wp->scoreboard;
++ int child_index = child->scoreboard_i;
++
+ if (!scoreboard) {
+ return;
+ }
+
+- if (child_index < 0 || child_index >= scoreboard->nprocs) {
++ if (child_index < 0 || child_index >= wp->config->pm_max_children) {
+ return;
+ }
+
+- if (scoreboard->procs[child_index] && scoreboard->procs[child_index]->used > 0) {
+- memset(scoreboard->procs[child_index], 0, sizeof(struct fpm_scoreboard_proc_s));
++ if (scoreboard->procs[child_index].used > 0) {
++ memset(&scoreboard->procs[child_index], 0, sizeof(struct fpm_scoreboard_proc_s));
+ }
+
+ /* set this slot as free to avoid search on next alloc */
+@@ -285,41 +301,44 @@ void fpm_scoreboard_proc_free(struct fpm_scoreboard_s *scoreboard, int child_ind
+ }
+ /* }}} */
+
+-int fpm_scoreboard_proc_alloc(struct fpm_scoreboard_s *scoreboard, int *child_index) /* {{{ */
++int fpm_scoreboard_proc_alloc(struct fpm_child_s *child) /* {{{ */
+ {
+ int i = -1;
++ struct fpm_worker_pool_s *wp = child->wp;
++ struct fpm_scoreboard_s *scoreboard = wp->scoreboard;
++ int nprocs = wp->config->pm_max_children;
+
+- if (!scoreboard || !child_index) {
++ if (!scoreboard) {
+ return -1;
+ }
+
+ /* first try the slot which is supposed to be free */
+- if (scoreboard->free_proc >= 0 && scoreboard->free_proc < scoreboard->nprocs) {
+- if (scoreboard->procs[scoreboard->free_proc] && !scoreboard->procs[scoreboard->free_proc]->used) {
++ if (scoreboard->free_proc >= 0 && scoreboard->free_proc < nprocs) {
++ if (!scoreboard->procs[scoreboard->free_proc].used) {
+ i = scoreboard->free_proc;
+ }
+ }
+
+ if (i < 0) { /* the supposed free slot is not, let's search for a free slot */
+ zlog(ZLOG_DEBUG, "[pool %s] the proc->free_slot was not free. Let's search", scoreboard->pool);
+- for (i = 0; i < scoreboard->nprocs; i++) {
+- if (scoreboard->procs[i] && !scoreboard->procs[i]->used) { /* found */
++ for (i = 0; i < nprocs; i++) {
++ if (!scoreboard->procs[i].used) { /* found */
+ break;
+ }
+ }
+ }
+
+ /* no free slot */
+- if (i < 0 || i >= scoreboard->nprocs) {
++ if (i < 0 || i >= nprocs) {
+ zlog(ZLOG_ERROR, "[pool %s] no free scoreboard slot", scoreboard->pool);
+ return -1;
+ }
+
+- scoreboard->procs[i]->used = 1;
+- *child_index = i;
++ scoreboard->procs[i].used = 1;
++ child->scoreboard_i = i;
+
+ /* supposed next slot is free */
+- if (i + 1 >= scoreboard->nprocs) {
++ if (i + 1 >= nprocs) {
+ scoreboard->free_proc = 0;
+ } else {
+ scoreboard->free_proc = i + 1;
+diff --git a/sapi/fpm/fpm/fpm_scoreboard.h b/sapi/fpm/fpm/fpm_scoreboard.h
+index f58a28737d..a0cc093b8c 100644
+--- a/sapi/fpm/fpm/fpm_scoreboard.h
++++ b/sapi/fpm/fpm/fpm_scoreboard.h
+@@ -65,7 +65,7 @@ struct fpm_scoreboard_s {
+ unsigned int nprocs;
+ int free_proc;
+ unsigned long int slow_rq;
+- struct fpm_scoreboard_proc_s *procs[];
++ struct fpm_scoreboard_proc_s procs[];
+ };
+
+ int fpm_scoreboard_init_main();
+@@ -74,18 +74,19 @@ int fpm_scoreboard_init_child(struct fpm_worker_pool_s *wp);
+ void fpm_scoreboard_update(int idle, int active, int lq, int lq_len, int requests, int max_children_reached, int slow_rq, int action, struct fpm_scoreboard_s *scoreboard);
+ struct fpm_scoreboard_s *fpm_scoreboard_get();
+ struct fpm_scoreboard_proc_s *fpm_scoreboard_proc_get(struct fpm_scoreboard_s *scoreboard, int child_index);
++struct fpm_scoreboard_proc_s *fpm_scoreboard_proc_get_from_child(struct fpm_child_s *child);
+
+ struct fpm_scoreboard_s *fpm_scoreboard_acquire(struct fpm_scoreboard_s *scoreboard, int nohang);
+ void fpm_scoreboard_release(struct fpm_scoreboard_s *scoreboard);
+ struct fpm_scoreboard_proc_s *fpm_scoreboard_proc_acquire(struct fpm_scoreboard_s *scoreboard, int child_index, int nohang);
+ void fpm_scoreboard_proc_release(struct fpm_scoreboard_proc_s *proc);
+
+-void fpm_scoreboard_free(struct fpm_scoreboard_s *scoreboard);
++void fpm_scoreboard_free(struct fpm_worker_pool_s *wp);
+
+-void fpm_scoreboard_child_use(struct fpm_scoreboard_s *scoreboard, int child_index, pid_t pid);
++void fpm_scoreboard_child_use(struct fpm_child_s *child, pid_t pid);
+
+-void fpm_scoreboard_proc_free(struct fpm_scoreboard_s *scoreboard, int child_index);
+-int fpm_scoreboard_proc_alloc(struct fpm_scoreboard_s *scoreboard, int *child_index);
++void fpm_scoreboard_proc_free(struct fpm_child_s *child);
++int fpm_scoreboard_proc_alloc(struct fpm_child_s *child);
+
+ #ifdef HAVE_TIMES
+ float fpm_scoreboard_get_tick();
+diff --git a/sapi/fpm/fpm/fpm_status.c b/sapi/fpm/fpm/fpm_status.c
+index 3e82face3c..666a1d9aba 100644
+--- a/sapi/fpm/fpm/fpm_status.c
++++ b/sapi/fpm/fpm/fpm_status.c
+@@ -402,10 +402,10 @@ int fpm_status_handle_request(void) /* {{{ */
+
+ first = 1;
+ for (i=0; i<scoreboard_p->nprocs; i++) {
+- if (!scoreboard_p->procs[i] || !scoreboard_p->procs[i]->used) {
++ if (!scoreboard_p->procs[i].used) {
+ continue;
+ }
+- proc = *scoreboard_p->procs[i];
++ proc = scoreboard_p->procs[i];
+
+ if (first) {
+ first = 0;
+diff --git a/sapi/fpm/fpm/fpm_worker_pool.c b/sapi/fpm/fpm/fpm_worker_pool.c
+index a0022915cd..c778b33c8c 100644
+--- a/sapi/fpm/fpm/fpm_worker_pool.c
++++ b/sapi/fpm/fpm/fpm_worker_pool.c
+@@ -44,7 +44,7 @@ static void fpm_worker_pool_cleanup(int which, void *arg) /* {{{ */
+ fpm_worker_pool_config_free(wp->config);
+ fpm_children_free(wp->children);
+ if ((which & FPM_CLEANUP_CHILD) == 0 && fpm_globals.parent_pid == getpid()) {
+- fpm_scoreboard_free(wp->scoreboard);
++ fpm_scoreboard_free(wp);
+ }
+ fpm_worker_pool_free(wp);
+ }
+--
+2.31.1
+
+From 9e0b951aee92deb470e31bd9f0e14f1434861b6a Mon Sep 17 00:00:00 2001
+From: Remi Collet <remi@remirepo.net>
+Date: Wed, 20 Oct 2021 14:11:20 +0200
+Subject: [PATCH 2/2] NEWS
+
+(cherry picked from commit 28c4ee7da2cf3428113e07326dbd46550c50c2bd)
+---
+ NEWS | 6 ++++++
+ 1 file changed, 6 insertions(+)
+
+diff --git a/NEWS b/NEWS
+index 8167eb8552..26c5f70de9 100644
+--- a/NEWS
++++ b/NEWS
+@@ -1,6 +1,12 @@
+ PHP NEWS
+ |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
+
++Backported from 7.4.25
++
++- FPM:
++ . Fixed bug #81026 (PHP-FPM oob R/W in root process leading to privilege
++ escalation) (CVE-2021-21703). (Jakub Zelenka)
++
+ Backported from 7.3.30
+
+ - Phar:
+--
+2.31.1
+
diff --git a/php-bug81122.patch b/php-bug81122.patch
new file mode 100644
index 0000000..3d200d6
--- /dev/null
+++ b/php-bug81122.patch
@@ -0,0 +1,88 @@
+From bb524cfbd498cebedd9f866c51cef97b69f59644 Mon Sep 17 00:00:00 2001
+From: "Christoph M. Becker" <cmbecker69@gmx.de>
+Date: Mon, 14 Jun 2021 13:22:27 +0200
+Subject: [PATCH 1/8] Fix #81122: SSRF bypass in FILTER_VALIDATE_URL
+
+We need to ensure that the password detected by parse_url() is actually
+a valid password; we can re-use is_userinfo_valid() for that.
+
+(cherry picked from commit a5538c62293fa782fcc382d0635cfc0c8b9190e3)
+---
+ ext/filter/logical_filters.c | 4 +++-
+ ext/filter/tests/bug81122.phpt | 21 +++++++++++++++++++++
+ 2 files changed, 24 insertions(+), 1 deletion(-)
+ create mode 100644 ext/filter/tests/bug81122.phpt
+
+diff --git a/ext/filter/logical_filters.c b/ext/filter/logical_filters.c
+index 22868fd8c1..357f7f2f43 100644
+--- a/ext/filter/logical_filters.c
++++ b/ext/filter/logical_filters.c
+@@ -587,7 +587,9 @@ bad_url:
+ RETURN_VALIDATION_FAILED
+ }
+
+- if (url->user != NULL && !is_userinfo_valid(url->user)) {
++ if (url->user != NULL && !is_userinfo_valid(url->user)
++ || url->pass != NULL && !is_userinfo_valid(url->pass)
++ ) {
+ php_url_free(url);
+ RETURN_VALIDATION_FAILED
+
+diff --git a/ext/filter/tests/bug81122.phpt b/ext/filter/tests/bug81122.phpt
+new file mode 100644
+index 0000000000..d89d4114a5
+--- /dev/null
++++ b/ext/filter/tests/bug81122.phpt
+@@ -0,0 +1,21 @@
++--TEST--
++Bug #81122 (SSRF bypass in FILTER_VALIDATE_URL)
++--SKIPIF--
++<?php
++if (!extension_loaded('filter')) die("skip filter extension not available");
++?>
++--FILE--
++<?php
++$urls = [
++ "https://example.com:\\@test.com/",
++ "https://user:\\epass@test.com",
++ "https://user:\\@test.com",
++];
++foreach ($urls as $url) {
++ var_dump(filter_var($url, FILTER_VALIDATE_URL));
++}
++?>
++--EXPECT--
++bool(false)
++bool(false)
++bool(false)
+--
+2.31.1
+
+From db917b17e82344db82a67c4c68f627246b484ac4 Mon Sep 17 00:00:00 2001
+From: Stanislav Malyshev <stas@php.net>
+Date: Sun, 27 Jun 2021 21:57:58 -0700
+Subject: [PATCH 2/8] Fix warning
+
+(cherry picked from commit 190013787bbc424c240413d914e3a038f974ccef)
+---
+ ext/filter/logical_filters.c | 4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+diff --git a/ext/filter/logical_filters.c b/ext/filter/logical_filters.c
+index 357f7f2f43..7a37f80e46 100644
+--- a/ext/filter/logical_filters.c
++++ b/ext/filter/logical_filters.c
+@@ -587,8 +587,8 @@ bad_url:
+ RETURN_VALIDATION_FAILED
+ }
+
+- if (url->user != NULL && !is_userinfo_valid(url->user)
+- || url->pass != NULL && !is_userinfo_valid(url->pass)
++ if ((url->user != NULL && !is_userinfo_valid(url->user))
++ || (url->pass != NULL && !is_userinfo_valid(url->pass))
+ ) {
+ php_url_free(url);
+ RETURN_VALIDATION_FAILED
+--
+2.31.1
+
diff --git a/php-bug81211.patch b/php-bug81211.patch
new file mode 100644
index 0000000..2df28c6
--- /dev/null
+++ b/php-bug81211.patch
@@ -0,0 +1,164 @@
+From bc182403e00c9da5a51f52a443047946266ca5d8 Mon Sep 17 00:00:00 2001
+From: "Christoph M. Becker" <cmbecker69@gmx.de>
+Date: Mon, 23 Aug 2021 13:42:17 +0200
+Subject: [PATCH 1/3] Fix #81211: Symlinks are followed when creating PHAR
+ archive
+
+It is insufficient to check whether the `base` is contained in `fname`;
+we also need to ensure that `fname` is properly separated. And of
+course, `fname` has to start with `base`.
+
+(cherry picked from commit 2ff853aa113e52637c85e28d1a03df1aa2d747b5)
+---
+ ext/phar/phar_object.c | 3 +-
+ ext/phar/tests/bug81211.phpt | 45 +++++++++++++++++++
+ .../tests/file/windows_links/common.inc | 9 +++-
+ 3 files changed, 55 insertions(+), 2 deletions(-)
+ create mode 100644 ext/phar/tests/bug81211.phpt
+
+diff --git a/ext/phar/phar_object.c b/ext/phar/phar_object.c
+index 8a0d369287..c8898a4a9d 100644
+--- a/ext/phar/phar_object.c
++++ b/ext/phar/phar_object.c
+@@ -1452,6 +1452,7 @@ static int phar_build(zend_object_iterator *iter, void *puser) /* {{{ */
+ zend_class_entry *ce = p_obj->c;
+ phar_archive_object *phar_obj = p_obj->p;
+ php_stream_statbuf ssb;
++ char ch;
+
+ value = iter->funcs->get_current_data(iter);
+
+@@ -1581,7 +1582,7 @@ phar_spl_fileinfo:
+ base = temp;
+ base_len = (int)strlen(base);
+
+- if (strstr(fname, base)) {
++ if (fname_len >= base_len && strncmp(fname, base, base_len) == 0 && ((ch = fname[base_len - IS_SLASH(base[base_len - 1])]) == '\0' || IS_SLASH(ch))) {
+ str_key_len = fname_len - base_len;
+
+ if (str_key_len <= 0) {
+diff --git a/ext/phar/tests/bug81211.phpt b/ext/phar/tests/bug81211.phpt
+new file mode 100644
+index 0000000000..43d82143f2
+--- /dev/null
++++ b/ext/phar/tests/bug81211.phpt
+@@ -0,0 +1,45 @@
++--TEST--
++Bug #81211 (Symlinks are followed when creating PHAR archive)
++--SKIPIF--
++<?php
++if (!extension_loaded('phar')) die('skip phar extension is not available');
++if (PHP_OS_FAMILY === 'Windows') {
++ if (false === include __DIR__ . '/../../standard/tests/file/windows_links/common.inc') {
++ die('skip windows_links/common.inc is not available');
++ }
++ skipIfSeCreateSymbolicLinkPrivilegeIsDisabled(__FILE__);
++}
++?>
++--FILE--
++<?php
++mkdir(__DIR__ . '/bug81211');
++mkdir(__DIR__ . '/bug81211/foobar');
++mkdir(__DIR__ . '/bug81211/foo');
++
++file_put_contents(__DIR__ . '/bug81211/foobar/file', 'this file should NOT be included in the archive!');
++symlink(__DIR__ . '/bug81211/foobar/file', __DIR__ . '/bug81211/foo/symlink');
++
++$archive = new PharData(__DIR__ . '/bug81211/archive.tar');
++try {
++ $archive->buildFromDirectory(__DIR__ . '/bug81211/foo');
++} catch (UnexpectedValueException $ex) {
++ echo $ex->getMessage(), PHP_EOL;
++}
++try {
++ $archive->buildFromIterator(new RecursiveDirectoryIterator(__DIR__ . '/bug81211/foo', FilesystemIterator::SKIP_DOTS), __DIR__ . '/bug81211/foo');
++} catch (UnexpectedValueException $ex) {
++ echo $ex->getMessage(), PHP_EOL;
++}
++?>
++--CLEAN--
++<?php
++@unlink(__DIR__ . '/bug81211/archive.tar');
++@unlink(__DIR__ . '/bug81211/foo/symlink');
++@unlink(__DIR__ . '/bug81211/foobar/file');
++@rmdir(__DIR__ . '/bug81211/foo');
++@rmdir(__DIR__ . '/bug81211/foobar');
++@rmdir(__DIR__ . '/bug81211');
++?>
++--EXPECTF--
++Iterator RecursiveIteratorIterator returned a path "%s%ebug81211\foobar\file" that is not in the base directory "%s%ebug81211\foo"
++Iterator RecursiveDirectoryIterator returned a path "%s%ebug81211\foobar\file" that is not in the base directory "%s%ebug81211\foo"
+diff --git a/ext/standard/tests/file/windows_links/common.inc b/ext/standard/tests/file/windows_links/common.inc
+index 2d4b47cd51..936a1e31e8 100644
+--- a/ext/standard/tests/file/windows_links/common.inc
++++ b/ext/standard/tests/file/windows_links/common.inc
+@@ -20,4 +20,11 @@ function get_mountvol() {
+ return "$sysroot\\System32\\mountvol.exe";
+ }
+
+-?>
++function skipIfSeCreateSymbolicLinkPrivilegeIsDisabled(string $filename) {
++ $ln = "$filename.lnk";
++ $ret = exec("mklink $ln " . __FILE__ .' 2>&1', $out);
++ @unlink($ln);
++ if (strpos($ret, 'privilege') !== false) {
++ die('skip SeCreateSymbolicLinkPrivilege not enabled');
++ }
++}
+--
+2.31.1
+
+From 3d93ceed09ce3e575676d349863c23f4d878cb0f Mon Sep 17 00:00:00 2001
+From: Stanislav Malyshev <stas@php.net>
+Date: Mon, 23 Aug 2021 23:43:32 -0700
+Subject: [PATCH 2/3] Fix test
+
+(cherry picked from commit b815645aac76b494dc119fa6b88de32fa9bcccf1)
+---
+ ext/phar/tests/bug81211.phpt | 4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+diff --git a/ext/phar/tests/bug81211.phpt b/ext/phar/tests/bug81211.phpt
+index 43d82143f2..96b1401b40 100644
+--- a/ext/phar/tests/bug81211.phpt
++++ b/ext/phar/tests/bug81211.phpt
+@@ -41,5 +41,5 @@ try {
+ @rmdir(__DIR__ . '/bug81211');
+ ?>
+ --EXPECTF--
+-Iterator RecursiveIteratorIterator returned a path "%s%ebug81211\foobar\file" that is not in the base directory "%s%ebug81211\foo"
+-Iterator RecursiveDirectoryIterator returned a path "%s%ebug81211\foobar\file" that is not in the base directory "%s%ebug81211\foo"
++Iterator RecursiveIteratorIterator returned a path "%s%ebug81211%efoobar%efile" that is not in the base directory "%s%ebug81211%efoo"
++Iterator RecursiveDirectoryIterator returned a path "%s%ebug81211%efoobar%efile" that is not in the base directory "%s%ebug81211%efoo"
+--
+2.31.1
+
+From 3acef06f1251525fe938606a00677c36ad18ff4f Mon Sep 17 00:00:00 2001
+From: Remi Collet <remi@remirepo.net>
+Date: Wed, 25 Aug 2021 15:23:50 +0200
+Subject: [PATCH 3/3] NEWS
+
+(cherry picked from commit 5539cefcda6aca7af220e7be7760a682abb88200)
+---
+ NEWS | 5 +++++
+ 1 file changed, 5 insertions(+)
+
+diff --git a/NEWS b/NEWS
+index 861dbd7dd5..8167eb8552 100644
+--- a/NEWS
++++ b/NEWS
+@@ -1,6 +1,11 @@
+ PHP NEWS
+ |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
+
++Backported from 7.3.30
++
++- Phar:
++ . Fixed bug #81211: Symlinks are followed when creating PHAR archive (cmb)
++
+ Backported from 7.3.29
+
+ - Core:
+--
+2.31.1
+
diff --git a/php-bug81719.patch b/php-bug81719.patch
new file mode 100644
index 0000000..40ba272
--- /dev/null
+++ b/php-bug81719.patch
@@ -0,0 +1,66 @@
+From 1f8f48703c7800b0e90344ccd73e74a1727f8a72 Mon Sep 17 00:00:00 2001
+From: Stanislav Malyshev <smalyshev@gmail.com>
+Date: Mon, 6 Jun 2022 00:56:51 -0600
+Subject: [PATCH 2/3] Fix bug #81719: mysqlnd/pdo password buffer overflow
+
+(cherry picked from commit 58006537fc5f133ae8549efe5118cde418b3ace9)
+(cherry picked from commit 9433de72e291db518357fe55531cc15432d43ec4)
+(cherry picked from commit 1560224d3a26574f0195af3853e4d7e050b0b06f)
+(cherry picked from commit 5e1d9182748c5330c4bf2154da858206e76914b6)
+---
+ ext/mysqlnd/mysqlnd_wireprotocol.c | 3 ++-
+ 1 file changed, 2 insertions(+), 1 deletion(-)
+
+diff --git a/ext/mysqlnd/mysqlnd_wireprotocol.c b/ext/mysqlnd/mysqlnd_wireprotocol.c
+index 6113543e2b..fa8c6bff46 100644
+--- a/ext/mysqlnd/mysqlnd_wireprotocol.c
++++ b/ext/mysqlnd/mysqlnd_wireprotocol.c
+@@ -798,7 +798,8 @@ static size_t
+ php_mysqlnd_change_auth_response_write(void * _packet, MYSQLND_CONN_DATA * conn)
+ {
+ MYSQLND_PACKET_CHANGE_AUTH_RESPONSE *packet= (MYSQLND_PACKET_CHANGE_AUTH_RESPONSE *) _packet;
+- zend_uchar * buffer = conn->net->cmd_buffer.length >= packet->auth_data_len? conn->net->cmd_buffer.buffer : mnd_emalloc(packet->auth_data_len);
++ size_t total_packet_size = packet->auth_data_len + MYSQLND_HEADER_SIZE;
++ zend_uchar * buffer = conn->net->cmd_buffer.length >= total_packet_size? conn->net->cmd_buffer.buffer : mnd_emalloc(total_packet_size);
+ zend_uchar *p = buffer + MYSQLND_HEADER_SIZE; /* start after the header */
+
+ DBG_ENTER("php_mysqlnd_change_auth_response_write");
+--
+2.35.3
+
+From b243ab09f95d2737b99ce87d485c052734c2f3f5 Mon Sep 17 00:00:00 2001
+From: Remi Collet <remi@remirepo.net>
+Date: Tue, 7 Jun 2022 09:57:15 +0200
+Subject: [PATCH 3/3] NEWS
+
+(cherry picked from commit f451082baf14ee9ea86cdd19870e906adb368f02)
+(cherry picked from commit 87247fb08e905e629836350ac4e639edd1b40ed8)
+(cherry picked from commit 151499ec0f70bf4f1bd65aebf037bd6273f0ef34)
+---
+ NEWS | 10 ++++++++++
+ 1 file changed, 10 insertions(+)
+
+diff --git a/NEWS b/NEWS
+index 0207f4caed..8d609a489c 100644
+--- a/NEWS
++++ b/NEWS
+@@ -1,6 +1,16 @@
+ PHP NEWS
+ |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
+
++Backported from 7.4.30
++
++- mysqlnd:
++ . Fixed bug #81719: mysqlnd/pdo password buffer overflow.
++ (CVE-2022-31626) (c dot fol at ambionics dot io)
++
++- pgsql
++ . Fixed bug #81720: Uninitialized array in pg_query_params().
++ (CVE-2022-31625) (cmb)
++
+ Backported from 7.3.33
+
+ - XML:
+--
+2.35.3
+
diff --git a/php-bug81720.patch b/php-bug81720.patch
new file mode 100644
index 0000000..7e947c3
--- /dev/null
+++ b/php-bug81720.patch
@@ -0,0 +1,79 @@
+From f8b8096675156bb0560256af790532e2a810311e Mon Sep 17 00:00:00 2001
+From: "Christoph M. Becker" <cmbecker69@gmx.de>
+Date: Tue, 17 May 2022 12:59:23 +0200
+Subject: [PATCH 1/3] Fix #81720: Uninitialized array in pg_query_params()
+ leading to RCE
+
+We must not free parameters which we haven't initialized yet.
+
+We also fix the not directly related issue, that we checked for the
+wrong value being `NULL`, potentially causing a segfault.
+
+(cherry picked from commit 55f6895f4b4c677272fd4ee1113acdbd99c4b5ab)
+(cherry picked from commit 6f979c832c861fb32e2dbad5e0cc29edcee7c500)
+(cherry picked from commit 310b17f5c8938389b1dbd7d8ff5a8144bfb9a351)
+(cherry picked from commit 9e7d6a2a1e8f43bdb86a0b6c1199f938f6ba78f5)
+---
+ ext/pgsql/pgsql.c | 4 ++--
+ ext/pgsql/tests/bug81720.phpt | 27 +++++++++++++++++++++++++++
+ 2 files changed, 29 insertions(+), 2 deletions(-)
+ create mode 100644 ext/pgsql/tests/bug81720.phpt
+
+diff --git a/ext/pgsql/pgsql.c b/ext/pgsql/pgsql.c
+index b215697ca9..b9b7776f4d 100644
+--- a/ext/pgsql/pgsql.c
++++ b/ext/pgsql/pgsql.c
+@@ -1981,7 +1981,7 @@ PHP_FUNCTION(pg_query_params)
+ if (Z_TYPE(tmp_val) != IS_STRING) {
+ php_error_docref(NULL, E_WARNING,"Error converting parameter");
+ zval_ptr_dtor(&tmp_val);
+- _php_pgsql_free_params(params, num_params);
++ _php_pgsql_free_params(params, i);
+ RETURN_FALSE;
+ }
+ params[i] = estrndup(Z_STRVAL(tmp_val), Z_STRLEN(tmp_val));
+@@ -5146,7 +5146,7 @@ PHP_FUNCTION(pg_send_execute)
+ if (Z_TYPE(tmp_val) != IS_STRING) {
+ php_error_docref(NULL, E_WARNING,"Error converting parameter");
+ zval_ptr_dtor(&tmp_val);
+- _php_pgsql_free_params(params, num_params);
++ _php_pgsql_free_params(params, i);
+ RETURN_FALSE;
+ }
+ params[i] = estrndup(Z_STRVAL(tmp_val), Z_STRLEN(tmp_val));
+diff --git a/ext/pgsql/tests/bug81720.phpt b/ext/pgsql/tests/bug81720.phpt
+new file mode 100644
+index 0000000000..d79f1fcdd6
+--- /dev/null
++++ b/ext/pgsql/tests/bug81720.phpt
+@@ -0,0 +1,27 @@
++--TEST--
++Bug #81720 (Uninitialized array in pg_query_params() leading to RCE)
++--SKIPIF--
++<?php include("skipif.inc"); ?>
++--FILE--
++<?php
++include('config.inc');
++
++$conn = pg_connect($conn_str);
++
++try {
++ pg_query_params($conn, 'SELECT $1, $2', [1, new stdClass()]);
++} catch (Throwable $ex) {
++ echo $ex->getMessage(), PHP_EOL;
++}
++
++try {
++ pg_send_prepare($conn, "my_query", 'SELECT $1, $2');
++ pg_get_result($conn);
++ pg_send_execute($conn, "my_query", [1, new stdClass()]);
++} catch (Throwable $ex) {
++ echo $ex->getMessage(), PHP_EOL;
++}
++?>
++--EXPECT--
++Object of class stdClass could not be converted to string
++Object of class stdClass could not be converted to string
+--
+2.35.3
+
diff --git a/php-bug81726.patch b/php-bug81726.patch
new file mode 100644
index 0000000..ebeb4a2
--- /dev/null
+++ b/php-bug81726.patch
@@ -0,0 +1,180 @@
+From ce0c274748a7b2fa3f0faf7a671b93e0da8faf07 Mon Sep 17 00:00:00 2001
+From: "Christoph M. Becker" <cmbecker69@gmx.de>
+Date: Mon, 25 Jul 2022 15:58:59 +0200
+Subject: [PATCH 2/2] Fix #81726: phar wrapper: DOS when using quine gzip file
+
+The phar wrapper needs to uncompress the file; the uncompressed file
+might be compressed, so the wrapper implementation loops. This raises
+potential DOS issues regarding too deep or even infinite recursion (the
+latter are called compressed file quines[1]). We avoid that by
+introducing a recursion limit; we choose the somewhat arbitrary limit
+`3`.
+
+This issue has been reported by real_as3617 and gPayl0ad.
+
+[1] <https://honno.dev/gzip-quine/>
+
+(cherry picked from commit 404e8bdb68350931176a5bdc86fc417b34fb583d)
+(cherry picked from commit 96fda78bcddd1d793cf2d0ee463dbb49621b577f)
+---
+ NEWS | 2 ++
+ ext/phar/phar.c | 16 +++++++++++-----
+ ext/phar/tests/bug81726.gz | Bin 0 -> 204 bytes
+ ext/phar/tests/bug81726.phpt | 14 ++++++++++++++
+ 4 files changed, 27 insertions(+), 5 deletions(-)
+ create mode 100644 ext/phar/tests/bug81726.gz
+ create mode 100644 ext/phar/tests/bug81726.phpt
+
+diff --git a/NEWS b/NEWS
+index e82f34bbd5..cb09d494b8 100644
+--- a/NEWS
++++ b/NEWS
+@@ -4,6 +4,8 @@ PHP NEWS
+ Backported from 7.4.31
+
+ - Core:
++ . Fixed bug #81726: phar wrapper: DOS when using quine gzip file.
++ (CVE-2022-31628). (cmb)
+ . Fixed bug #81727: Don't mangle HTTP variable names that clash with ones
+ that have a specific semantic meaning. (CVE-2022-31629). (Derick)
+
+diff --git a/ext/phar/phar.c b/ext/phar/phar.c
+index 583ed453e6..c9928ecdcd 100644
+--- a/ext/phar/phar.c
++++ b/ext/phar/phar.c
+@@ -1584,7 +1584,8 @@ static int phar_open_from_fp(php_stream* fp, char *fname, int fname_len, char *a
+ const char zip_magic[] = "PK\x03\x04";
+ const char gz_magic[] = "\x1f\x8b\x08";
+ const char bz_magic[] = "BZh";
+- char *pos, test = '\0';
++ char *pos;
++ int recursion_count = 3; // arbitrary limit to avoid too deep or even infinite recursion
+ const int window_size = 1024;
+ char buffer[1024 + sizeof(token)]; /* a 1024 byte window + the size of the halt_compiler token (moving window) */
+ const zend_long readsize = sizeof(buffer) - sizeof(token);
+@@ -1612,8 +1613,7 @@ static int phar_open_from_fp(php_stream* fp, char *fname, int fname_len, char *a
+ MAPPHAR_ALLOC_FAIL("internal corruption of phar \"%s\" (truncated entry)")
+ }
+
+- if (!test) {
+- test = '\1';
++ if (recursion_count) {
+ pos = buffer+tokenlen;
+ if (!memcmp(pos, gz_magic, 3)) {
+ char err = 0;
+@@ -1673,7 +1673,10 @@ static int phar_open_from_fp(php_stream* fp, char *fname, int fname_len, char *a
+ compression = PHAR_FILE_COMPRESSED_GZ;
+
+ /* now, start over */
+- test = '\0';
++ if (!--recursion_count) {
++ MAPPHAR_ALLOC_FAIL("unable to decompress gzipped phar archive \"%s\"");
++ break;
++ }
+ continue;
+ } else if (!memcmp(pos, bz_magic, 3)) {
+ php_stream_filter *filter;
+@@ -1711,7 +1714,10 @@ static int phar_open_from_fp(php_stream* fp, char *fname, int fname_len, char *a
+ compression = PHAR_FILE_COMPRESSED_BZ2;
+
+ /* now, start over */
+- test = '\0';
++ if (!--recursion_count) {
++ MAPPHAR_ALLOC_FAIL("unable to decompress bzipped phar archive \"%s\"");
++ break;
++ }
+ continue;
+ }
+
+From f80e21336cc4dc37b6dc8808fec05a584c39d403 Mon Sep 17 00:00:00 2001
+From: "Christoph M. Becker" <cmbecker69@gmx.de>
+Date: Tue, 27 Sep 2022 17:43:40 +0200
+Subject: [PATCH] Fix regression introduced by fixing bug 81726
+
+When a tar phar is created, `phar_open_from_fp()` is also called, but
+since the file has just been created, none of the format checks can
+succeed, so we continue to loop, but must not check again for the
+format. Therefore, we bring back the old `test` variable.
+
+Closes GH-9620.
+
+(cherry picked from commit 432bf196d59bcb661fcf9cb7029cea9b43f490af)
+---
+ ext/phar/phar.c | 7 +++++--
+ 1 file changed, 5 insertions(+), 2 deletions(-)
+
+diff --git a/ext/phar/phar.c b/ext/phar/phar.c
+index c9928ecdcd..f55e5fd4d8 100644
+--- a/ext/phar/phar.c
++++ b/ext/phar/phar.c
+@@ -1584,7 +1584,7 @@ static int phar_open_from_fp(php_stream* fp, char *fname, int fname_len, char *a
+ const char zip_magic[] = "PK\x03\x04";
+ const char gz_magic[] = "\x1f\x8b\x08";
+ const char bz_magic[] = "BZh";
+- char *pos;
++ char *pos, test = '\0';
+ int recursion_count = 3; // arbitrary limit to avoid too deep or even infinite recursion
+ const int window_size = 1024;
+ char buffer[1024 + sizeof(token)]; /* a 1024 byte window + the size of the halt_compiler token (moving window) */
+@@ -1613,7 +1613,8 @@ static int phar_open_from_fp(php_stream* fp, char *fname, int fname_len, char *a
+ MAPPHAR_ALLOC_FAIL("internal corruption of phar \"%s\" (truncated entry)")
+ }
+
+- if (recursion_count) {
++ if (!test && recursion_count) {
++ test = '\1';
+ pos = buffer+tokenlen;
+ if (!memcmp(pos, gz_magic, 3)) {
+ char err = 0;
+@@ -1673,6 +1674,7 @@ static int phar_open_from_fp(php_stream* fp, char *fname, int fname_len, char *a
+ compression = PHAR_FILE_COMPRESSED_GZ;
+
+ /* now, start over */
++ test = '\0';
+ if (!--recursion_count) {
+ MAPPHAR_ALLOC_FAIL("unable to decompress gzipped phar archive \"%s\"");
+ break;
+@@ -1714,6 +1716,7 @@ static int phar_open_from_fp(php_stream* fp, char *fname, int fname_len, char *a
+ compression = PHAR_FILE_COMPRESSED_BZ2;
+
+ /* now, start over */
++ test = '\0';
+ if (!--recursion_count) {
+ MAPPHAR_ALLOC_FAIL("unable to decompress bzipped phar archive \"%s\"");
+ break;
+--
+2.37.3
+
+From 9d32d284b25f5df75780911a47b3c23cbaac1761 Mon Sep 17 00:00:00 2001
+From: Remi Collet <remi@remirepo.net>
+Date: Fri, 30 Sep 2022 09:22:14 +0200
+Subject: [PATCH] fix NEWS
+
+---
+ NEWS | 8 +++++---
+ 1 file changed, 5 insertions(+), 3 deletions(-)
+
+diff --git a/NEWS b/NEWS
+index fe4cb9c484..b7a19aea19 100644
+--- a/NEWS
++++ b/NEWS
+@@ -1,14 +1,16 @@
+ PHP NEWS
+ |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
+
+-Backported from 7.4.31
++Backported from 7.4.32
+
+ - Core:
+- . Fixed bug #81726: phar wrapper: DOS when using quine gzip file.
+- (CVE-2022-31628). (cmb)
+ . Fixed bug #81727: Don't mangle HTTP variable names that clash with ones
+ that have a specific semantic meaning. (CVE-2022-31629). (Derick)
+
++- Phar:
++ . Fixed bug #81726: phar wrapper: DOS when using quine gzip file.
++ (CVE-2022-31628). (cmb)
++
+ Backported from 7.4.30
+
+ - mysqlnd:
diff --git a/php-bug81727.patch b/php-bug81727.patch
new file mode 100644
index 0000000..c80c3c9
--- /dev/null
+++ b/php-bug81727.patch
@@ -0,0 +1,81 @@
+From bab5b52a66d7af02b4940e31a500c1fc4fd5e894 Mon Sep 17 00:00:00 2001
+From: Derick Rethans <github@derickrethans.nl>
+Date: Fri, 9 Sep 2022 16:54:03 +0100
+Subject: [PATCH 1/2] Fix #81727: Don't mangle HTTP variable names that clash
+ with ones that have a specific semantic meaning.
+
+(cherry picked from commit 0611be4e82887cee0de6c4cbae320d34eec946ca)
+(cherry picked from commit 8b300e157e92b0e945ad813d608f076b5323d721)
+---
+ NEWS | 6 ++++++
+ ext/standard/tests/bug81727.phpt | 15 +++++++++++++++
+ main/php_variables.c | 14 ++++++++++++++
+ 3 files changed, 35 insertions(+)
+ create mode 100644 ext/standard/tests/bug81727.phpt
+
+diff --git a/NEWS b/NEWS
+index 8d609a489c..e82f34bbd5 100644
+--- a/NEWS
++++ b/NEWS
+@@ -1,6 +1,12 @@
+ PHP NEWS
+ |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
+
++Backported from 7.4.31
++
++- Core:
++ . Fixed bug #81727: Don't mangle HTTP variable names that clash with ones
++ that have a specific semantic meaning. (CVE-2022-31629). (Derick)
++
+ Backported from 7.4.30
+
+ - mysqlnd:
+diff --git a/ext/standard/tests/bug81727.phpt b/ext/standard/tests/bug81727.phpt
+new file mode 100644
+index 0000000000..71a9cb46c8
+--- /dev/null
++++ b/ext/standard/tests/bug81727.phpt
+@@ -0,0 +1,15 @@
++--TEST--
++Bug #81727: $_COOKIE name starting with ..Host/..Secure should be discarded
++--COOKIE--
++..Host-test=ignore; __Host-test=correct; . Secure-test=ignore; . Elephpant=Awesome;
++--FILE--
++<?php
++var_dump($_COOKIE);
++?>
++--EXPECT--
++array(2) {
++ ["__Host-test"]=>
++ string(7) "correct"
++ ["__Elephpant"]=>
++ string(7) "Awesome"
++}
+diff --git a/main/php_variables.c b/main/php_variables.c
+index 50ecc663bd..e5d3ffcf52 100644
+--- a/main/php_variables.c
++++ b/main/php_variables.c
+@@ -103,6 +103,20 @@ PHPAPI void php_register_variable_ex(char *var_name, zval *val, zval *track_vars
+ }
+ var_len = p - var;
+
++ /* Discard variable if mangling made it start with __Host-, where pre-mangling it did not start with __Host- */
++ if (strncmp(var, "__Host-", sizeof("__Host-")-1) == 0 && strncmp(var_name, "__Host-", sizeof("__Host-")-1) != 0) {
++ zval_ptr_dtor_nogc(val);
++ free_alloca(var_orig, use_heap);
++ return;
++ }
++
++ /* Discard variable if mangling made it start with __Secure-, where pre-mangling it did not start with __Secure- */
++ if (strncmp(var, "__Secure-", sizeof("__Secure-")-1) == 0 && strncmp(var_name, "__Secure-", sizeof("__Secure-")-1) != 0) {
++ zval_ptr_dtor_nogc(val);
++ free_alloca(var_orig, use_heap);
++ return;
++ }
++
+ if (var_len==0) { /* empty variable name, or variable name with a space in it */
+ zval_dtor(val);
+ free_alloca(var_orig, use_heap);
+--
+2.37.3
+
diff --git a/php-bug81740.patch b/php-bug81740.patch
new file mode 100644
index 0000000..5962dd9
--- /dev/null
+++ b/php-bug81740.patch
@@ -0,0 +1,87 @@
+From dad5b771fba02359facd7be0cd2fd0896cdc91ae Mon Sep 17 00:00:00 2001
+From: "Christoph M. Becker" <cmbecker69@gmx.de>
+Date: Mon, 31 Oct 2022 17:20:23 +0100
+Subject: [PATCH 1/2] Fix #81740: PDO::quote() may return unquoted string
+
+`sqlite3_snprintf()` expects its first parameter to be `int`; we need
+to avoid overflow.
+
+(cherry picked from commit 921b6813da3237a83e908998483f46ae3d8bacba)
+(cherry picked from commit 7cb160efe19d3dfb8b92629805733ea186b55050)
+---
+ ext/pdo_sqlite/sqlite_driver.c | 3 +++
+ ext/pdo_sqlite/tests/bug81740.phpt | 17 +++++++++++++++++
+ 2 files changed, 20 insertions(+)
+ create mode 100644 ext/pdo_sqlite/tests/bug81740.phpt
+
+diff --git a/ext/pdo_sqlite/sqlite_driver.c b/ext/pdo_sqlite/sqlite_driver.c
+index 481b62de97..56d15ae2c0 100644
+--- a/ext/pdo_sqlite/sqlite_driver.c
++++ b/ext/pdo_sqlite/sqlite_driver.c
+@@ -232,6 +232,9 @@ static char *pdo_sqlite_last_insert_id(pdo_dbh_t *dbh, const char *name, size_t
+ /* NB: doesn't handle binary strings... use prepared stmts for that */
+ static int sqlite_handle_quoter(pdo_dbh_t *dbh, const char *unquoted, size_t unquotedlen, char **quoted, size_t *quotedlen, enum pdo_param_type paramtype )
+ {
++ if (unquotedlen > (INT_MAX - 3) / 2) {
++ return 0;
++ }
+ *quoted = safe_emalloc(2, unquotedlen, 3);
+ sqlite3_snprintf(2*unquotedlen + 3, *quoted, "'%q'", unquoted);
+ *quotedlen = strlen(*quoted);
+diff --git a/ext/pdo_sqlite/tests/bug81740.phpt b/ext/pdo_sqlite/tests/bug81740.phpt
+new file mode 100644
+index 0000000000..99fb07c304
+--- /dev/null
++++ b/ext/pdo_sqlite/tests/bug81740.phpt
+@@ -0,0 +1,17 @@
++--TEST--
++Bug #81740 (PDO::quote() may return unquoted string)
++--SKIPIF--
++<?php
++if (!extension_loaded('pdo_sqlite')) print 'skip not loaded';
++if (getenv("SKIP_SLOW_TESTS")) die("skip slow test");
++?>
++--INI--
++memory_limit=-1
++--FILE--
++<?php
++$pdo = new PDO("sqlite::memory:");
++$string = str_repeat("a", 0x80000000);
++var_dump($pdo->quote($string));
++?>
++--EXPECT--
++bool(false)
+--
+2.38.1
+
+From 3a800d9c39caca74158a0aa7a2e268cb5ebac701 Mon Sep 17 00:00:00 2001
+From: Remi Collet <remi@remirepo.net>
+Date: Mon, 19 Dec 2022 09:24:02 +0100
+Subject: [PATCH 2/2] NEWS
+
+(cherry picked from commit 7328f3a0344806b846bd05657bdce96e47810bf0)
+(cherry picked from commit dbfbd99e91701c0a5613133c06305fd70545e9ad)
+---
+ NEWS | 6 ++++++
+ 1 file changed, 6 insertions(+)
+
+diff --git a/NEWS b/NEWS
+index eded1b91d6..b7d4bf3082 100644
+--- a/NEWS
++++ b/NEWS
+@@ -1,6 +1,12 @@
+ PHP NEWS
+ |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
+
++Backported from 8.0.27
++
++- PDO/SQLite:
++ . Fixed bug #81740 (PDO::quote() may return unquoted string).
++ (CVE-2022-31631) (cmb)
++
+ Backported from 7.4.32
+
+ - Core:
+--
+2.38.1
+
diff --git a/php-bug81744.patch b/php-bug81744.patch
new file mode 100644
index 0000000..b4090f4
--- /dev/null
+++ b/php-bug81744.patch
@@ -0,0 +1,190 @@
+From 07efe5ef4a45f7b0fd99751892fafdc6604173cb Mon Sep 17 00:00:00 2001
+From: =?UTF-8?q?Tim=20D=C3=BCsterhus?= <tim@bastelstu.be>
+Date: Mon, 23 Jan 2023 21:15:24 +0100
+Subject: [PATCH 1/8] 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.
+
+(cherry picked from commit c840f71524067aa474c00c3eacfb83bd860bfc8a)
+(cherry picked from commit 7437aaae38cf4b3357e7580f9e22fd4a403b6c23)
+---
+ 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 5cf306715f..e923b55ed0 100644
+--- a/ext/standard/crypt_blowfish.c
++++ b/ext/standard/crypt_blowfish.c
+@@ -377,7 +377,6 @@ static 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; \
+@@ -405,13 +404,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 0000000000..32e335f4b0
+--- /dev/null
++++ b/ext/standard/tests/crypt/bcrypt_salt_dollar.phpt
+@@ -0,0 +1,82 @@
++--TEST--
++bcrypt correctly rejects salts containing $
++--FILE--
++<?php
++for ($i = 0; $i < 23; $i++) {
++ $salt = '$2y$04$' . str_repeat('0', $i) . '$';
++ $result = crypt("foo", $salt);
++ var_dump($salt);
++ var_dump($result);
++ var_dump($result === $salt);
++}
++?>
++--EXPECT--
++string(8) "$2y$04$$"
++string(2) "*0"
++bool(false)
++string(9) "$2y$04$0$"
++string(2) "*0"
++bool(false)
++string(10) "$2y$04$00$"
++string(2) "*0"
++bool(false)
++string(11) "$2y$04$000$"
++string(2) "*0"
++bool(false)
++string(12) "$2y$04$0000$"
++string(2) "*0"
++bool(false)
++string(13) "$2y$04$00000$"
++string(2) "*0"
++bool(false)
++string(14) "$2y$04$000000$"
++string(2) "*0"
++bool(false)
++string(15) "$2y$04$0000000$"
++string(2) "*0"
++bool(false)
++string(16) "$2y$04$00000000$"
++string(2) "*0"
++bool(false)
++string(17) "$2y$04$000000000$"
++string(2) "*0"
++bool(false)
++string(18) "$2y$04$0000000000$"
++string(2) "*0"
++bool(false)
++string(19) "$2y$04$00000000000$"
++string(2) "*0"
++bool(false)
++string(20) "$2y$04$000000000000$"
++string(2) "*0"
++bool(false)
++string(21) "$2y$04$0000000000000$"
++string(2) "*0"
++bool(false)
++string(22) "$2y$04$00000000000000$"
++string(2) "*0"
++bool(false)
++string(23) "$2y$04$000000000000000$"
++string(2) "*0"
++bool(false)
++string(24) "$2y$04$0000000000000000$"
++string(2) "*0"
++bool(false)
++string(25) "$2y$04$00000000000000000$"
++string(2) "*0"
++bool(false)
++string(26) "$2y$04$000000000000000000$"
++string(2) "*0"
++bool(false)
++string(27) "$2y$04$0000000000000000000$"
++string(2) "*0"
++bool(false)
++string(28) "$2y$04$00000000000000000000$"
++string(2) "*0"
++bool(false)
++string(29) "$2y$04$000000000000000000000$"
++string(2) "*0"
++bool(false)
++string(30) "$2y$04$0000000000000000000000$"
++string(60) "$2y$04$000000000000000000000u2a2UpVexIt9k3FMJeAVr3c04F5tcI8K"
++bool(false)
+--
+2.39.1
+
+From 31b760acb171475a8960f2eb5cff26eeb7b55728 Mon Sep 17 00:00:00 2001
+From: =?UTF-8?q?Tim=20D=C3=BCsterhus?= <tim@bastelstu.be>
+Date: Mon, 23 Jan 2023 22:13:57 +0100
+Subject: [PATCH 2/8] crypt: Fix possible buffer overread in php_crypt()
+
+(cherry picked from commit a92acbad873a05470af1a47cb785a18eadd827b5)
+(cherry picked from commit ed0281b588a6840cb95f3134a4e68847a3be5bb7)
+---
+ 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 13a7cec5b9..9913635fba 100644
+--- a/ext/standard/crypt.c
++++ b/ext/standard/crypt.c
+@@ -202,6 +202,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 0000000000..085bc8a239
+--- /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--
++<?php
++var_dump(password_verify("foo", '$2'));
++?>
++--EXPECT--
++bool(false)
+--
+2.39.1
+
diff --git a/php-bug81746.patch b/php-bug81746.patch
new file mode 100644
index 0000000..9872b1d
--- /dev/null
+++ b/php-bug81746.patch
@@ -0,0 +1,100 @@
+From fdbd028d614508c83dfd5c8be83edd6839297abf 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 3/8] 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.
+
+(cherry picked from commit ec10b28d64decbc54aa1e585dce580f0bd7a5953)
+(cherry picked from commit 887cd0710ad856a0d22c329b6ea6c71ebd8621ae)
+---
+ 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 29ef0a8cab..f13e1c8e76 100644
+--- a/ext/dom/document.c
++++ b/ext/dom/document.c
+@@ -1359,7 +1359,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 40b7d462cd..87a03f9bf7 100644
+--- a/ext/xmlreader/php_xmlreader.c
++++ b/ext/xmlreader/php_xmlreader.c
+@@ -1040,7 +1040,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 e1f89ce5cc..1eb0f109f2 100644
+--- a/main/fopen_wrappers.c
++++ b/main/fopen_wrappers.c
+@@ -137,10 +137,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;
+ int resolved_basedir_len;
+ int resolved_name_len;
+--
+2.39.1
+
+From 562442bebf64686f2df2b93dfab88fb17f9b247a Mon Sep 17 00:00:00 2001
+From: Remi Collet <remi@remirepo.net>
+Date: Mon, 13 Feb 2023 11:46:47 +0100
+Subject: [PATCH 4/8] NEWS
+
+(cherry picked from commit 614468ce4056c0ef93aae09532dcffdf65b594b5)
+---
+ NEWS | 8 ++++++++
+ 1 file changed, 8 insertions(+)
+
+diff --git a/NEWS b/NEWS
+index b7d4bf3082..1fcd07f38b 100644
+--- a/NEWS
++++ b/NEWS
+@@ -1,6 +1,14 @@
+ PHP NEWS
+ |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
+
++Backported from 8.0.28
++
++- Core:
++ . Fixed bug #81744 (Password_verify() always return true with some hash).
++ (CVE-2023-0567). (Tim Düsterhus)
++ . Fixed bug #81746 (1-byte array overrun in common path resolve code).
++ (CVE-2023-0568). (Niels Dossche)
++
+ Backported from 8.0.27
+
+ - PDO/SQLite:
+--
+2.39.1
+
diff --git a/php-cve-2023-0662.patch b/php-cve-2023-0662.patch
new file mode 100644
index 0000000..7996367
--- /dev/null
+++ b/php-cve-2023-0662.patch
@@ -0,0 +1,148 @@
+From bbac8f5d5f4c1a42b01de76fbde0d951947f39f6 Mon Sep 17 00:00:00 2001
+From: Jakub Zelenka <bukka@php.net>
+Date: Thu, 19 Jan 2023 14:11:18 +0000
+Subject: [PATCH 5/8] Fix repeated warning for file uploads limit exceeding
+
+(cherry picked from commit 3a2fdef1ae38881110006616ee1f0534b082ca45)
+---
+ main/rfc1867.c | 5 ++++-
+ 1 file changed, 4 insertions(+), 1 deletion(-)
+
+diff --git a/main/rfc1867.c b/main/rfc1867.c
+index 6159284311..1c2373c84a 100644
+--- a/main/rfc1867.c
++++ b/main/rfc1867.c
+@@ -930,7 +930,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 */
+--
+2.39.1
+
+From a249335e6c4d76e58884c5aba23953e09fddc089 Mon Sep 17 00:00:00 2001
+From: Jakub Zelenka <bukka@php.net>
+Date: Thu, 19 Jan 2023 14:31:25 +0000
+Subject: [PATCH 6/8] 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.
+
+(cherry picked from commit 8ec78d28d20c82c75c4747f44c52601cfdb22516)
+---
+ main/main.c | 1 +
+ main/rfc1867.c | 11 +++++++++++
+ 2 files changed, 12 insertions(+)
+
+diff --git a/main/main.c b/main/main.c
+index 93ac6cabdd..0d61542229 100644
+--- a/main/main.c
++++ b/main/main.c
+@@ -587,6 +587,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 1c2373c84a..022bb94028 100644
+--- a/main/rfc1867.c
++++ b/main/rfc1867.c
+@@ -702,6 +702,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;
+@@ -723,6 +724,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) {
+@@ -807,6 +813,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;
+ }
+--
+2.39.1
+
+From 0f375f617e475209d0ffaeb5c710f916098e4ebd Mon Sep 17 00:00:00 2001
+From: Remi Collet <remi@remirepo.net>
+Date: Tue, 14 Feb 2023 09:14:47 +0100
+Subject: [PATCH 7/8] NEWS
+
+(cherry picked from commit 472db3ee3a00ac00d36019eee0b3b7362334481c)
+---
+ NEWS | 4 ++++
+ 1 file changed, 4 insertions(+)
+
+diff --git a/NEWS b/NEWS
+index 1fcd07f38b..5f3b8c743f 100644
+--- a/NEWS
++++ b/NEWS
+@@ -9,6 +9,10 @@ Backported from 8.0.28
+ . Fixed bug #81746 (1-byte array overrun in common path resolve code).
+ (CVE-2023-0568). (Niels Dossche)
+
++- FPM:
++ . Fixed bug GHSA-54hq-v5wp-fqgv (DOS vulnerability when parsing multipart
++ request body). (CVE-2023-0662) (Jakub Zelenka)
++
+ Backported from 8.0.27
+
+ - PDO/SQLite:
+--
+2.39.1
+
+From 5bfe7527d4ad3fc662d04d5ba6b645202105b82f Mon Sep 17 00:00:00 2001
+From: Remi Collet <remi@remirepo.net>
+Date: Tue, 14 Feb 2023 11:47:22 +0100
+Subject: [PATCH 8/8] fix NEWS, not FPM specific
+
+(cherry picked from commit c04f310440a906fc4ca885f4ecf6e3e4cd36edc7)
+---
+ NEWS | 2 --
+ 1 file changed, 2 deletions(-)
+
+diff --git a/NEWS b/NEWS
+index 5f3b8c743f..11f6e7ad5a 100644
+--- a/NEWS
++++ b/NEWS
+@@ -8,8 +8,6 @@ Backported from 8.0.28
+ (CVE-2023-0567). (Tim Düsterhus)
+ . Fixed bug #81746 (1-byte array overrun in common path resolve code).
+ (CVE-2023-0568). (Niels Dossche)
+-
+-- FPM:
+ . Fixed bug GHSA-54hq-v5wp-fqgv (DOS vulnerability when parsing multipart
+ request body). (CVE-2023-0662) (Jakub Zelenka)
+
+--
+2.39.1
+
diff --git a/php-cve-2023-3247.patch b/php-cve-2023-3247.patch
new file mode 100644
index 0000000..d16530a
--- /dev/null
+++ b/php-cve-2023-3247.patch
@@ -0,0 +1,151 @@
+From b9e09489f8160eb5e38a11e84ef6c8b74c2ec828 Mon Sep 17 00:00:00 2001
+From: Niels Dossche <7771979+nielsdos@users.noreply.github.com>
+Date: Sun, 16 Apr 2023 15:05:03 +0200
+Subject: [PATCH] Fix missing randomness check and insufficient random bytes
+ for SOAP HTTP Digest
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+If php_random_bytes_throw fails, the nonce will be uninitialized, but
+still sent to the server. The client nonce is intended to protect
+against a malicious server. See section 5.10 and 5.12 of RFC 7616 [1],
+and bullet point 2 below.
+
+Tim pointed out that even though it's the MD5 of the nonce that gets sent,
+enumerating 31 bits is trivial. So we have still a stack information leak
+of 31 bits.
+
+Furthermore, Tim found the following issues:
+* The small size of cnonce might cause the server to erroneously reject
+ a request due to a repeated (cnonce, nc) pair. As per the birthday
+ problem 31 bits of randomness will return a duplication with 50%
+ chance after less than 55000 requests and nc always starts counting at 1.
+* The cnonce is intended to protect the client and password against a
+ malicious server that returns a constant server nonce where the server
+ precomputed a rainbow table between passwords and correct client response.
+ As storage is fairly cheap, a server could precompute the client responses
+ for (a subset of) client nonces and still have a chance of reversing the
+ client response with the same probability as the cnonce duplication.
+
+ Precomputing the rainbow table for all 2^31 cnonces increases the rainbow
+ table size by factor 2 billion, which is infeasible. But precomputing it
+ for 2^14 cnonces only increases the table size by factor 16k and the server
+ would still have a 10% chance of successfully reversing a password with a
+ single client request.
+
+This patch fixes the issues by increasing the nonce size, and checking
+the return value of php_random_bytes_throw(). In the process we also get
+rid of the MD5 hashing of the nonce.
+
+[1] RFC 7616: https://www.rfc-editor.org/rfc/rfc7616
+
+Co-authored-by: Tim Düsterhus <timwolla@php.net>
+(cherry picked from commit 126d517ce240e9f638d9a5eaa509eaca49ef562a)
+(cherry picked from commit 0cfca9aa1395271833848daec0bace51d965531d)
+---
+ NEWS | 6 ++++++
+ ext/soap/php_http.c | 19 ++++++++++++++-----
+ 2 files changed, 20 insertions(+), 5 deletions(-)
+
+diff --git a/NEWS b/NEWS
+index 11f6e7ad5a8..0770d913467 100644
+--- a/NEWS
++++ b/NEWS
+@@ -1,6 +1,12 @@
+ PHP NEWS
+ |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
+
++Backported from 8.0.29
++
++- Soap:
++ . Fixed bug GHSA-76gg-c692-v2mw (Missing error check and insufficient random
++ bytes in HTTP Digest authentication for SOAP). (nielsdos, timwolla)
++
+ Backported from 8.0.28
+
+ - Core:
+diff --git a/ext/soap/php_http.c b/ext/soap/php_http.c
+index 3a890d7c36f..3bfa4f6f54c 100644
+--- a/ext/soap/php_http.c
++++ b/ext/soap/php_http.c
+@@ -646,14 +646,23 @@ int make_http_soap_request(zval *this_ptr,
+ if ((digest = zend_hash_str_find(Z_OBJPROP_P(this_ptr), "_digest", sizeof("_digest")-1)) != NULL) {
+ if (Z_TYPE_P(digest) == IS_ARRAY) {
+ char HA1[33], HA2[33], response[33], cnonce[33], nc[9];
++ unsigned char nonce[16];
+ PHP_MD5_CTX md5ctx;
+ unsigned char hash[16];
+
+- PHP_MD5Init(&md5ctx);
+- snprintf(cnonce, sizeof(cnonce), ZEND_LONG_FMT, php_rand());
+- PHP_MD5Update(&md5ctx, (unsigned char*)cnonce, strlen(cnonce));
+- PHP_MD5Final(hash, &md5ctx);
+- make_digest(cnonce, hash);
++ if (UNEXPECTED(php_random_bytes_throw(&nonce, sizeof(nonce)) != SUCCESS)) {
++ ZEND_ASSERT(EG(exception));
++ php_stream_close(stream);
++ zend_hash_str_del(Z_OBJPROP_P(this_ptr), "httpurl", sizeof("httpurl")-1);
++ zend_hash_str_del(Z_OBJPROP_P(this_ptr), "httpsocket", sizeof("httpsocket")-1);
++ zend_hash_str_del(Z_OBJPROP_P(this_ptr), "_use_proxy", sizeof("_use_proxy")-1);
++ smart_str_free(&soap_headers_z);
++ smart_str_free(&soap_headers);
++ return FALSE;
++ }
++
++ php_hash_bin2hex(cnonce, nonce, sizeof(nonce));
++ cnonce[32] = 0;
+
+ if ((tmp = zend_hash_str_find(Z_ARRVAL_P(digest), "nc", sizeof("nc")-1)) != NULL &&
+ Z_TYPE_P(tmp) == IS_LONG) {
+From e4dd20803ac5579deec54dc6b699d359890f96f0 Mon Sep 17 00:00:00 2001
+From: Remi Collet <remi@remirepo.net>
+Date: Tue, 6 Jun 2023 18:05:22 +0200
+Subject: [PATCH] Fix GH-11382 add missing hash header for bin2hex
+
+(cherry picked from commit 40439039c224bb8cdebd1b7b3d03b8cc11e7cce7)
+---
+ ext/soap/php_http.c | 3 ++-
+ 1 file changed, 2 insertions(+), 1 deletion(-)
+
+diff --git a/ext/soap/php_http.c b/ext/soap/php_http.c
+index 3bfa4f6f54..72b5bdec2b 100644
+--- a/ext/soap/php_http.c
++++ b/ext/soap/php_http.c
+@@ -22,7 +22,8 @@
+ #include "php_soap.h"
+ #include "ext/standard/base64.h"
+ #include "ext/standard/md5.h"
+-#include "ext/standard/php_rand.h"
++#include "ext/standard/php_random.h"
++#include "ext/hash/php_hash.h"
+
+ static char *get_http_header_value(char *headers, char *type);
+ static zend_string *get_http_body(php_stream *socketd, int close, char *headers);
+From 4e2dda0221e03b9b9dfc767b26dae656bc7a2407 Mon Sep 17 00:00:00 2001
+From: Remi Collet <remi@remirepo.net>
+Date: Thu, 15 Jun 2023 08:47:55 +0200
+Subject: [PATCH] add cve
+
+(cherry picked from commit f3021d66d7bb42d2578530cc94f9bde47e58eb10)
+---
+ NEWS | 3 ++-
+ 1 file changed, 2 insertions(+), 1 deletion(-)
+
+diff --git a/NEWS b/NEWS
+index 0770d91346..835c538663 100644
+--- a/NEWS
++++ b/NEWS
+@@ -5,7 +5,8 @@ Backported from 8.0.29
+
+ - Soap:
+ . Fixed bug GHSA-76gg-c692-v2mw (Missing error check and insufficient random
+- bytes in HTTP Digest authentication for SOAP). (nielsdos, timwolla)
++ bytes in HTTP Digest authentication for SOAP).
++ (CVE-2023-3247) (nielsdos, timwolla)
+
+ Backported from 8.0.28
+
+--
+2.40.1
+
diff --git a/php-cve-2023-3823.patch b/php-cve-2023-3823.patch
new file mode 100644
index 0000000..b1397b5
--- /dev/null
+++ b/php-cve-2023-3823.patch
@@ -0,0 +1,93 @@
+From 47388f7e4e1369feeffdb6976b469e7dfa72d9cb Mon Sep 17 00:00:00 2001
+From: Niels Dossche <7771979+nielsdos@users.noreply.github.com>
+Date: Mon, 10 Jul 2023 13:25:34 +0200
+Subject: [PATCH 1/3] Fix buffer mismanagement in phar_dir_read()
+
+Fixes GHSA-jqcx-ccgc-xwhv.
+
+(cherry picked from commit 80316123f3e9dcce8ac419bd9dd43546e2ccb5ef)
+(cherry picked from commit c398fe98c044c8e7c23135acdc38d4ef7bedc983)
+(cherry picked from commit 3f14261065e4c0552afa9cb16411475050a41c2c)
+(cherry picked from commit f8f433d0d8eaac21af4f4532496d33f9c2b381d6)
+(cherry picked from commit f41261182dad0f831d8727967c127da1f08c8ce5)
+---
+ ext/phar/dirstream.c | 15 ++++++++------
+ ext/phar/tests/GHSA-jqcx-ccgc-xwhv.phpt | 27 +++++++++++++++++++++++++
+ 2 files changed, 36 insertions(+), 6 deletions(-)
+ create mode 100644 ext/phar/tests/GHSA-jqcx-ccgc-xwhv.phpt
+
+diff --git a/ext/phar/dirstream.c b/ext/phar/dirstream.c
+index d81f6939bc..aca53ba79a 100644
+--- a/ext/phar/dirstream.c
++++ b/ext/phar/dirstream.c
+@@ -92,25 +92,28 @@ static int phar_dir_seek(php_stream *stream, zend_off_t offset, int whence, zend
+ */
+ static size_t phar_dir_read(php_stream *stream, char *buf, size_t count) /* {{{ */
+ {
+- size_t to_read;
+ HashTable *data = (HashTable *)stream->abstract;
+ zend_string *str_key;
+ zend_ulong unused;
+
++ if (count != sizeof(php_stream_dirent)) {
++ return -1;
++ }
++
+ if (HASH_KEY_NON_EXISTENT == zend_hash_get_current_key(data, &str_key, &unused)) {
+ return 0;
+ }
+
+ zend_hash_move_forward(data);
+- to_read = MIN(ZSTR_LEN(str_key), count);
+
+- if (to_read == 0 || count < ZSTR_LEN(str_key)) {
++ php_stream_dirent *dirent = (php_stream_dirent *) buf;
++
++ if (sizeof(dirent->d_name) <= ZSTR_LEN(str_key)) {
+ return 0;
+ }
+
+- memset(buf, 0, sizeof(php_stream_dirent));
+- memcpy(((php_stream_dirent *) buf)->d_name, ZSTR_VAL(str_key), to_read);
+- ((php_stream_dirent *) buf)->d_name[to_read + 1] = '\0';
++ memset(dirent, 0, sizeof(php_stream_dirent));
++ PHP_STRLCPY(dirent->d_name, ZSTR_VAL(str_key), sizeof(dirent->d_name), ZSTR_LEN(str_key));
+
+ return sizeof(php_stream_dirent);
+ }
+diff --git a/ext/phar/tests/GHSA-jqcx-ccgc-xwhv.phpt b/ext/phar/tests/GHSA-jqcx-ccgc-xwhv.phpt
+new file mode 100644
+index 0000000000..4e12f05fb6
+--- /dev/null
++++ b/ext/phar/tests/GHSA-jqcx-ccgc-xwhv.phpt
+@@ -0,0 +1,27 @@
++--TEST--
++GHSA-jqcx-ccgc-xwhv (Buffer overflow and overread in phar_dir_read())
++--SKIPIF--
++<?php if (!extension_loaded("phar")) die("skip"); ?>
++--INI--
++phar.readonly=0
++--FILE--
++<?php
++$phar = new Phar(__DIR__. '/GHSA-jqcx-ccgc-xwhv.phar');
++$phar->startBuffering();
++$phar->addFromString(str_repeat('A', PHP_MAXPATHLEN - 1), 'This is the content of file 1.');
++$phar->addFromString(str_repeat('B', PHP_MAXPATHLEN - 1).'C', 'This is the content of file 2.');
++$phar->stopBuffering();
++
++$handle = opendir('phar://' . __DIR__ . '/GHSA-jqcx-ccgc-xwhv.phar');
++var_dump(strlen(readdir($handle)));
++// Must not be a string of length PHP_MAXPATHLEN+1
++var_dump(readdir($handle));
++closedir($handle);
++?>
++--CLEAN--
++<?php
++unlink(__DIR__. '/GHSA-jqcx-ccgc-xwhv.phar');
++?>
++--EXPECTF--
++int(%d)
++bool(false)
+--
+2.41.0
+
diff --git a/php-cve-2023-3824.patch b/php-cve-2023-3824.patch
new file mode 100644
index 0000000..e071bb2
--- /dev/null
+++ b/php-cve-2023-3824.patch
@@ -0,0 +1,408 @@
+From 3824593952c6ce4c37cd43137b0877202f5c304e Mon Sep 17 00:00:00 2001
+From: Niels Dossche <7771979+nielsdos@users.noreply.github.com>
+Date: Sat, 15 Jul 2023 17:33:52 +0200
+Subject: [PATCH 2/3] Sanitize libxml2 globals before parsing
+
+Fixes GHSA-3qrf-m4j2-pcrr.
+
+To parse a document with libxml2, you first need to create a parsing context.
+The parsing context contains parsing options (e.g. XML_NOENT to substitute
+entities) that the application (in this case PHP) can set.
+Unfortunately, libxml2 also supports providing default set options.
+For example, if you call xmlSubstituteEntitiesDefault(1) then the XML_NOENT
+option will be added to the parsing options every time you create a parsing
+context **even if the application never requested XML_NOENT**.
+
+Third party extensions can override these globals, in particular the
+substitute entity global. This causes entity substitution to be
+unexpectedly active.
+
+Fix it by setting the parsing options to a sane known value.
+For API calls that depend on global state we introduce
+PHP_LIBXML_SANITIZE_GLOBALS() and PHP_LIBXML_RESTORE_GLOBALS().
+For other APIs that work directly with a context we introduce
+php_libxml_sanitize_parse_ctxt_options().
+
+(cherry picked from commit c283c3ab0ba45d21b2b8745c1f9c7cbfe771c975)
+(cherry picked from commit b3758bd21223b97c042cae7bd26a66cde081ea98)
+(cherry picked from commit 4fb61f06b1aff89a4d7e548c37ffa5bf573270c3)
+(cherry picked from commit d7de6908dfc8774e86a54100ad4e2ee810426001)
+(cherry picked from commit 66a1fcc69765bb704146fe7d084848302dd3c89e)
+---
+ ext/dom/document.c | 15 +++++++++++++++
+ ext/dom/documentfragment.c | 2 ++
+ ext/libxml/php_libxml.h | 36 +++++++++++++++++++++++++++++++++++
+ ext/simplexml/simplexml.c | 6 ++++++
+ ext/soap/php_xml.c | 2 ++
+ ext/xml/compat.c | 2 ++
+ ext/xmlreader/php_xmlreader.c | 9 +++++++++
+ ext/xsl/xsltprocessor.c | 9 ++++-----
+ 8 files changed, 76 insertions(+), 5 deletions(-)
+
+diff --git a/ext/dom/document.c b/ext/dom/document.c
+index f13e1c8e76..1d9c7023b5 100644
+--- a/ext/dom/document.c
++++ b/ext/dom/document.c
+@@ -1438,6 +1438,7 @@ static xmlDocPtr dom_document_parser(zval *id, int mode, char *source, size_t so
+ options |= XML_PARSE_NOBLANKS;
+ }
+
++ php_libxml_sanitize_parse_ctxt_options(ctxt);
+ xmlCtxtUseOptions(ctxt, options);
+
+ ctxt->recovery = recover;
+@@ -1735,7 +1736,9 @@ PHP_FUNCTION(dom_document_xinclude)
+
+ DOM_GET_OBJ(docp, id, xmlDocPtr, intern);
+
++ PHP_LIBXML_SANITIZE_GLOBALS(xinclude);
+ err = xmlXIncludeProcessFlags(docp, (int)flags);
++ PHP_LIBXML_RESTORE_GLOBALS(xinclude);
+
+ /* XML_XINCLUDE_START and XML_XINCLUDE_END nodes need to be removed as these
+ are added via xmlXIncludeProcess to mark beginning and ending of xincluded document
+@@ -1774,6 +1777,7 @@ PHP_FUNCTION(dom_document_validate)
+
+ DOM_GET_OBJ(docp, id, xmlDocPtr, intern);
+
++ PHP_LIBXML_SANITIZE_GLOBALS(validate);
+ cvp = xmlNewValidCtxt();
+
+ cvp->userData = NULL;
+@@ -1785,6 +1789,7 @@ PHP_FUNCTION(dom_document_validate)
+ } else {
+ RETVAL_FALSE;
+ }
++ PHP_LIBXML_RESTORE_GLOBALS(validate);
+
+ xmlFreeValidCtxt(cvp);
+
+@@ -1818,14 +1823,18 @@ static void _dom_document_schema_validate(INTERNAL_FUNCTION_PARAMETERS, int type
+
+ DOM_GET_OBJ(docp, id, xmlDocPtr, intern);
+
++ PHP_LIBXML_SANITIZE_GLOBALS(new_parser_ctxt);
++
+ switch (type) {
+ case DOM_LOAD_FILE:
+ if (CHECK_NULL_PATH(source, source_len)) {
++ PHP_LIBXML_RESTORE_GLOBALS(new_parser_ctxt);
+ php_error_docref(NULL, E_WARNING, "Invalid Schema file source");
+ RETURN_FALSE;
+ }
+ valid_file = _dom_get_valid_file_path(source, resolved_path, MAXPATHLEN);
+ if (!valid_file) {
++ PHP_LIBXML_RESTORE_GLOBALS(new_parser_ctxt);
+ php_error_docref(NULL, E_WARNING, "Invalid Schema file source");
+ RETURN_FALSE;
+ }
+@@ -1846,6 +1855,7 @@ static void _dom_document_schema_validate(INTERNAL_FUNCTION_PARAMETERS, int type
+ parser);
+ sptr = xmlSchemaParse(parser);
+ xmlSchemaFreeParserCtxt(parser);
++ PHP_LIBXML_RESTORE_GLOBALS(new_parser_ctxt);
+ if (!sptr) {
+ php_error_docref(NULL, E_WARNING, "Invalid Schema");
+ RETURN_FALSE;
+@@ -1866,11 +1876,13 @@ static void _dom_document_schema_validate(INTERNAL_FUNCTION_PARAMETERS, int type
+ }
+ #endif
+
++ PHP_LIBXML_SANITIZE_GLOBALS(validate);
+ xmlSchemaSetValidOptions(vptr, valid_opts);
+ xmlSchemaSetValidErrors(vptr, php_libxml_error_handler, php_libxml_error_handler, vptr);
+ is_valid = xmlSchemaValidateDoc(vptr, docp);
+ xmlSchemaFree(sptr);
+ xmlSchemaFreeValidCtxt(vptr);
++ PHP_LIBXML_RESTORE_GLOBALS(validate);
+
+ if (is_valid == 0) {
+ RETURN_TRUE;
+@@ -1940,12 +1952,14 @@ static void _dom_document_relaxNG_validate(INTERNAL_FUNCTION_PARAMETERS, int typ
+ return;
+ }
+
++ PHP_LIBXML_SANITIZE_GLOBALS(parse);
+ xmlRelaxNGSetParserErrors(parser,
+ (xmlRelaxNGValidityErrorFunc) php_libxml_error_handler,
+ (xmlRelaxNGValidityWarningFunc) php_libxml_error_handler,
+ parser);
+ sptr = xmlRelaxNGParse(parser);
+ xmlRelaxNGFreeParserCtxt(parser);
++ PHP_LIBXML_RESTORE_GLOBALS(parse);
+ if (!sptr) {
+ php_error_docref(NULL, E_WARNING, "Invalid RelaxNG");
+ RETURN_FALSE;
+@@ -2045,6 +2059,7 @@ static void dom_load_html(INTERNAL_FUNCTION_PARAMETERS, int mode) /* {{{ */
+ ctxt->sax->error = php_libxml_ctx_error;
+ ctxt->sax->warning = php_libxml_ctx_warning;
+ }
++ php_libxml_sanitize_parse_ctxt_options(ctxt);
+ if (options) {
+ htmlCtxtUseOptions(ctxt, (int)options);
+ }
+diff --git a/ext/dom/documentfragment.c b/ext/dom/documentfragment.c
+index 0b08202726..84e03aab32 100644
+--- a/ext/dom/documentfragment.c
++++ b/ext/dom/documentfragment.c
+@@ -134,7 +134,9 @@ PHP_METHOD(domdocumentfragment, appendXML) {
+ }
+
+ if (data) {
++ PHP_LIBXML_SANITIZE_GLOBALS(parse);
+ err = xmlParseBalancedChunkMemory(nodep->doc, NULL, NULL, 0, (xmlChar *) data, &lst);
++ PHP_LIBXML_RESTORE_GLOBALS(parse);
+ if (err != 0) {
+ RETURN_FALSE;
+ }
+diff --git a/ext/libxml/php_libxml.h b/ext/libxml/php_libxml.h
+index 5021a3d43f..db5dfad66d 100644
+--- a/ext/libxml/php_libxml.h
++++ b/ext/libxml/php_libxml.h
+@@ -122,6 +122,42 @@ PHP_LIBXML_API void php_libxml_shutdown(void);
+ ZEND_TSRMLS_CACHE_EXTERN()
+ #endif
+
++/* Other extension may override the global state options, these global options
++ * are copied initially to ctxt->options. Set the options to a known good value.
++ * See libxml2 globals.c and parserInternals.c.
++ * The unique_name argument allows multiple sanitizes and restores within the
++ * same function, even nested is necessary. */
++#define PHP_LIBXML_SANITIZE_GLOBALS(unique_name) \
++ int xml_old_loadsubset_##unique_name = xmlLoadExtDtdDefaultValue; \
++ xmlLoadExtDtdDefaultValue = 0; \
++ int xml_old_validate_##unique_name = xmlDoValidityCheckingDefaultValue; \
++ xmlDoValidityCheckingDefaultValue = 0; \
++ int xml_old_pedantic_##unique_name = xmlPedanticParserDefault(0); \
++ int xml_old_substitute_##unique_name = xmlSubstituteEntitiesDefault(0); \
++ int xml_old_linenrs_##unique_name = xmlLineNumbersDefault(0); \
++ int xml_old_blanks_##unique_name = xmlKeepBlanksDefault(1);
++
++#define PHP_LIBXML_RESTORE_GLOBALS(unique_name) \
++ xmlLoadExtDtdDefaultValue = xml_old_loadsubset_##unique_name; \
++ xmlDoValidityCheckingDefaultValue = xml_old_validate_##unique_name; \
++ (void) xmlPedanticParserDefault(xml_old_pedantic_##unique_name); \
++ (void) xmlSubstituteEntitiesDefault(xml_old_substitute_##unique_name); \
++ (void) xmlLineNumbersDefault(xml_old_linenrs_##unique_name); \
++ (void) xmlKeepBlanksDefault(xml_old_blanks_##unique_name);
++
++/* Alternative for above, working directly on the context and not setting globals.
++ * Generally faster because no locking is involved, and this has the advantage that it sets the options to a known good value. */
++static zend_always_inline void php_libxml_sanitize_parse_ctxt_options(xmlParserCtxtPtr ctxt)
++{
++ ctxt->loadsubset = 0;
++ ctxt->validate = 0;
++ ctxt->pedantic = 0;
++ ctxt->replaceEntities = 0;
++ ctxt->linenumbers = 0;
++ ctxt->keepBlanks = 1;
++ ctxt->options = 0;
++}
++
+ #else /* HAVE_LIBXML */
+ #define libxml_module_ptr NULL
+ #endif
+diff --git a/ext/simplexml/simplexml.c b/ext/simplexml/simplexml.c
+index 0637e06af8..435096e9f5 100644
+--- a/ext/simplexml/simplexml.c
++++ b/ext/simplexml/simplexml.c
+@@ -2229,7 +2229,9 @@ PHP_FUNCTION(simplexml_load_file)
+ RETURN_FALSE;
+ }
+
++ PHP_LIBXML_SANITIZE_GLOBALS(read_file);
+ docp = xmlReadFile(filename, NULL, (int)options);
++ PHP_LIBXML_RESTORE_GLOBALS(read_file);
+
+ if (!docp) {
+ RETURN_FALSE;
+@@ -2283,7 +2285,9 @@ PHP_FUNCTION(simplexml_load_string)
+ RETURN_FALSE;
+ }
+
++ PHP_LIBXML_SANITIZE_GLOBALS(read_memory);
+ docp = xmlReadMemory(data, (int)data_len, NULL, NULL, (int)options);
++ PHP_LIBXML_RESTORE_GLOBALS(read_memory);
+
+ if (!docp) {
+ RETURN_FALSE;
+@@ -2333,7 +2337,9 @@ SXE_METHOD(__construct)
+ return;
+ }
+
++ PHP_LIBXML_SANITIZE_GLOBALS(read_file_or_memory);
+ docp = is_url ? xmlReadFile(data, NULL, (int)options) : xmlReadMemory(data, (int)data_len, NULL, NULL, (int)options);
++ PHP_LIBXML_RESTORE_GLOBALS(read_file_or_memory);
+
+ if (!docp) {
+ ((php_libxml_node_object *)sxe)->document = NULL;
+diff --git a/ext/soap/php_xml.c b/ext/soap/php_xml.c
+index a9c6a56858..84366e96c9 100644
+--- a/ext/soap/php_xml.c
++++ b/ext/soap/php_xml.c
+@@ -94,6 +94,7 @@ xmlDocPtr soap_xmlParseFile(const char *filename)
+ if (ctxt) {
+ zend_bool old;
+
++ php_libxml_sanitize_parse_ctxt_options(ctxt);
+ ctxt->keepBlanks = 0;
+ ctxt->sax->ignorableWhitespace = soap_ignorableWhitespace;
+ ctxt->sax->comment = soap_Comment;
+@@ -144,6 +145,7 @@ xmlDocPtr soap_xmlParseMemory(const void *buf, size_t buf_size)
+ if (ctxt) {
+ zend_bool old;
+
++ php_libxml_sanitize_parse_ctxt_options(ctxt);
+ ctxt->sax->ignorableWhitespace = soap_ignorableWhitespace;
+ ctxt->sax->comment = soap_Comment;
+ ctxt->sax->warning = NULL;
+diff --git a/ext/xml/compat.c b/ext/xml/compat.c
+index 694fde95c3..02d1093b9f 100644
+--- a/ext/xml/compat.c
++++ b/ext/xml/compat.c
+@@ -19,6 +19,7 @@
+ #include "php.h"
+ #if defined(HAVE_LIBXML) && (defined(HAVE_XML) || defined(HAVE_XMLRPC)) && !defined(HAVE_LIBEXPAT)
+ #include "expat_compat.h"
++#include "ext/libxml/php_libxml.h"
+
+ typedef struct _php_xml_ns {
+ xmlNsPtr nsptr;
+@@ -473,6 +474,7 @@ XML_ParserCreate_MM(const XML_Char *encoding, const XML_Memory_Handling_Suite *m
+ parser->parser->charset = XML_CHAR_ENCODING_NONE;
+ #endif
+
++ php_libxml_sanitize_parse_ctxt_options(parser->parser);
+ #if LIBXML_VERSION >= 20703
+ xmlCtxtUseOptions(parser->parser, XML_PARSE_OLDSAX);
+ #endif
+diff --git a/ext/xmlreader/php_xmlreader.c b/ext/xmlreader/php_xmlreader.c
+index 87a03f9bf7..8f03fa57ed 100644
+--- a/ext/xmlreader/php_xmlreader.c
++++ b/ext/xmlreader/php_xmlreader.c
+@@ -301,6 +301,7 @@ static xmlRelaxNGPtr _xmlreader_get_relaxNG(char *source, size_t source_len, siz
+ return NULL;
+ }
+
++ PHP_LIBXML_SANITIZE_GLOBALS(parse);
+ if (error_func || warn_func) {
+ xmlRelaxNGSetParserErrors(parser,
+ (xmlRelaxNGValidityErrorFunc) error_func,
+@@ -309,6 +310,7 @@ static xmlRelaxNGPtr _xmlreader_get_relaxNG(char *source, size_t source_len, siz
+ }
+ sptr = xmlRelaxNGParse(parser);
+ xmlRelaxNGFreeParserCtxt(parser);
++ PHP_LIBXML_RESTORE_GLOBALS(parse);
+
+ return sptr;
+ }
+@@ -881,7 +883,9 @@ PHP_METHOD(xmlreader, open)
+ valid_file = _xmlreader_get_valid_file_path(source, resolved_path, MAXPATHLEN );
+
+ if (valid_file) {
++ PHP_LIBXML_SANITIZE_GLOBALS(reader_for_file);
+ reader = xmlReaderForFile(valid_file, encoding, options);
++ PHP_LIBXML_RESTORE_GLOBALS(reader_for_file);
+ }
+
+ if (reader == NULL) {
+@@ -959,7 +963,9 @@ PHP_METHOD(xmlreader, setSchema)
+
+ intern = Z_XMLREADER_P(id);
+ if (intern && intern->ptr) {
++ PHP_LIBXML_SANITIZE_GLOBALS(schema);
+ retval = xmlTextReaderSchemaValidate(intern->ptr, source);
++ PHP_LIBXML_RESTORE_GLOBALS(schema);
+
+ if (retval == 0) {
+ RETURN_TRUE;
+@@ -1079,6 +1085,7 @@ PHP_METHOD(xmlreader, XML)
+ }
+ uri = (char *) xmlCanonicPath((const xmlChar *) resolved_path);
+ }
++ PHP_LIBXML_SANITIZE_GLOBALS(text_reader);
+ reader = xmlNewTextReader(inputbfr, uri);
+
+ if (reader != NULL) {
+@@ -1099,9 +1106,11 @@ PHP_METHOD(xmlreader, XML)
+ xmlFree(uri);
+ }
+
++ PHP_LIBXML_RESTORE_GLOBALS(text_reader);
+ return;
+ }
+ }
++ PHP_LIBXML_RESTORE_GLOBALS(text_reader);
+ }
+
+ if (uri) {
+diff --git a/ext/xsl/xsltprocessor.c b/ext/xsl/xsltprocessor.c
+index d12da0e655..3e9031531b 100644
+--- a/ext/xsl/xsltprocessor.c
++++ b/ext/xsl/xsltprocessor.c
+@@ -399,7 +399,7 @@ PHP_FUNCTION(xsl_xsltprocessor_import_stylesheet)
+ xmlDoc *doc = NULL, *newdoc = NULL;
+ xsltStylesheetPtr sheetp, oldsheetp;
+ xsl_object *intern;
+- int prevSubstValue, prevExtDtdValue, clone_docu = 0;
++ int clone_docu = 0;
+ xmlNode *nodep = NULL;
+ zend_object_handlers *std_hnd;
+ zval *cloneDocu, member, rv;
+@@ -422,13 +422,12 @@ PHP_FUNCTION(xsl_xsltprocessor_import_stylesheet)
+ stylesheet document otherwise the node proxies will be a mess */
+ newdoc = xmlCopyDoc(doc, 1);
+ xmlNodeSetBase((xmlNodePtr) newdoc, (xmlChar *)doc->URL);
+- prevSubstValue = xmlSubstituteEntitiesDefault(1);
+- prevExtDtdValue = xmlLoadExtDtdDefaultValue;
++ PHP_LIBXML_SANITIZE_GLOBALS(parse);
++ xmlSubstituteEntitiesDefault(1);
+ xmlLoadExtDtdDefaultValue = XML_DETECT_IDS | XML_COMPLETE_ATTRS;
+
+ sheetp = xsltParseStylesheetDoc(newdoc);
+- xmlSubstituteEntitiesDefault(prevSubstValue);
+- xmlLoadExtDtdDefaultValue = prevExtDtdValue;
++ PHP_LIBXML_RESTORE_GLOBALS(parse);
+
+ if (!sheetp) {
+ xmlFreeDoc(newdoc);
+--
+2.41.0
+
+From 59ec21e12409bd87106f3437dbcc680608eb85a8 Mon Sep 17 00:00:00 2001
+From: Remi Collet <remi@remirepo.net>
+Date: Tue, 1 Aug 2023 07:22:33 +0200
+Subject: [PATCH 3/3] NEWS
+
+(cherry picked from commit ef1d507acf7be23d7624dc3c891683b2218feb51)
+(cherry picked from commit 3cf7c2b10e577136b267f2d90bfdff6743271c5c)
+(cherry picked from commit 79c0bf87711036b83f8ee1723c034ccc839d847b)
+(cherry picked from commit 3ac0ce8a462cb31815330d1410e1a8a615c395eb)
+---
+ NEWS | 10 ++++++++++
+ 1 file changed, 10 insertions(+)
+
+diff --git a/NEWS b/NEWS
+index 835c538663..53ca87c8e6 100644
+--- a/NEWS
++++ b/NEWS
+@@ -1,6 +1,16 @@
+ PHP NEWS
+ |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
+
++Backported from 8.0.30
++
++- Libxml:
++ . Fixed bug GHSA-3qrf-m4j2-pcrr (Security issue with external entity loading
++ in XML without enabling it). (CVE-2023-3823) (nielsdos, ilutov)
++
++- Phar:
++ . Fixed bug GHSA-jqcx-ccgc-xwhv (Buffer mismanagement in phar_dir_read()).
++ (CVE-2023-3824) (nielsdos)
++
+ Backported from 8.0.29
+
+ - Soap:
+--
+2.41.0
+
diff --git a/php-cve-2024-2756.patch b/php-cve-2024-2756.patch
new file mode 100644
index 0000000..7a9e942
--- /dev/null
+++ b/php-cve-2024-2756.patch
@@ -0,0 +1,201 @@
+From ec9b61593fa2b9400d4519b9969645c1266a381d Mon Sep 17 00:00:00 2001
+From: Niels Dossche <7771979+nielsdos@users.noreply.github.com>
+Date: Sun, 17 Mar 2024 21:04:47 +0100
+Subject: [PATCH 1/4] Fix GHSA-wpj3-hf5j-x4v4: __Host-/__Secure- cookie bypass
+ due to partial CVE-2022-31629 fix
+
+The check happened too early as later code paths may perform more
+mangling rules. Move the check downwards right before adding the actual
+variable.
+
+(cherry picked from commit 093c08af25fb323efa0c8e6154aa9fdeae3d3b53)
+(cherry picked from commit 2e07a3acd7a6b53c55325b94bed97748d7697b53)
+(cherry picked from commit a6c1c62a25ac23b08a86af11d68f0e2eaafc102b)
+(cherry picked from commit 46b570a1e4aeb4a414898fcc09503ac388d16256)
+(cherry picked from commit c213de619a532d35e8f7abe4a245433dbf21c960)
+(cherry picked from commit a1b0060906bc4eedaf5bb3577a0d6d4b0e6b9dfd)
+---
+ ext/standard/tests/ghsa-wpj3-hf5j-x4v4.phpt | 63 +++++++++++++++++++++
+ main/php_variables.c | 41 +++++++++-----
+ 2 files changed, 90 insertions(+), 14 deletions(-)
+ create mode 100644 ext/standard/tests/ghsa-wpj3-hf5j-x4v4.phpt
+
+diff --git a/ext/standard/tests/ghsa-wpj3-hf5j-x4v4.phpt b/ext/standard/tests/ghsa-wpj3-hf5j-x4v4.phpt
+new file mode 100644
+index 0000000000..77fcb68089
+--- /dev/null
++++ b/ext/standard/tests/ghsa-wpj3-hf5j-x4v4.phpt
+@@ -0,0 +1,63 @@
++--TEST--
++ghsa-wpj3-hf5j-x4v4 (__Host-/__Secure- cookie bypass due to partial CVE-2022-31629 fix)
++--COOKIE--
++..Host-test=ignore_1;
++._Host-test=ignore_2;
++.[Host-test=ignore_3;
++_.Host-test=ignore_4;
++__Host-test=ignore_5;
++_[Host-test=ignore_6;
++[.Host-test=ignore_7;
++[_Host-test=ignore_8;
++[[Host-test=ignore_9;
++..Host-test[]=ignore_10;
++._Host-test[]=ignore_11;
++.[Host-test[]=ignore_12;
++_.Host-test[]=ignore_13;
++__Host-test[]=legitimate_14;
++_[Host-test[]=legitimate_15;
++[.Host-test[]=ignore_16;
++[_Host-test[]=ignore_17;
++[[Host-test[]=ignore_18;
++..Secure-test=ignore_1;
++._Secure-test=ignore_2;
++.[Secure-test=ignore_3;
++_.Secure-test=ignore_4;
++__Secure-test=ignore_5;
++_[Secure-test=ignore_6;
++[.Secure-test=ignore_7;
++[_Secure-test=ignore_8;
++[[Secure-test=ignore_9;
++..Secure-test[]=ignore_10;
++._Secure-test[]=ignore_11;
++.[Secure-test[]=ignore_12;
++_.Secure-test[]=ignore_13;
++__Secure-test[]=legitimate_14;
++_[Secure-test[]=legitimate_15;
++[.Secure-test[]=ignore_16;
++[_Secure-test[]=ignore_17;
++[[Secure-test[]=ignore_18;
++--FILE--
++<?php
++var_dump($_COOKIE);
++?>
++--EXPECT--
++array(3) {
++ ["__Host-test"]=>
++ array(1) {
++ [0]=>
++ string(13) "legitimate_14"
++ }
++ ["_"]=>
++ array(2) {
++ ["Host-test["]=>
++ string(13) "legitimate_15"
++ ["Secure-test["]=>
++ string(13) "legitimate_15"
++ }
++ ["__Secure-test"]=>
++ array(1) {
++ [0]=>
++ string(13) "legitimate_14"
++ }
++}
+diff --git a/main/php_variables.c b/main/php_variables.c
+index e5d3ffcf52..46de3477ca 100644
+--- a/main/php_variables.c
++++ b/main/php_variables.c
+@@ -53,6 +53,21 @@ PHPAPI void php_register_variable_safe(char *var, char *strval, size_t str_len,
+ php_register_variable_ex(var, &new_entry, track_vars_array);
+ }
+
++/* Discard variable if mangling made it start with __Host-, where pre-mangling it did not start with __Host-
++ * Discard variable if mangling made it start with __Secure-, where pre-mangling it did not start with __Secure- */
++static zend_bool php_is_forbidden_variable_name(const char *mangled_name, size_t mangled_name_len, const char *pre_mangled_name)
++{
++ if (mangled_name_len >= sizeof("__Host-")-1 && strncmp(mangled_name, "__Host-", sizeof("__Host-")-1) == 0 && strncmp(pre_mangled_name, "__Host-", sizeof("__Host-")-1) != 0) {
++ return 1;
++ }
++
++ if (mangled_name_len >= sizeof("__Secure-")-1 && strncmp(mangled_name, "__Secure-", sizeof("__Secure-")-1) == 0 && strncmp(pre_mangled_name, "__Secure-", sizeof("__Secure-")-1) != 0) {
++ return 1;
++ }
++
++ return 0;
++}
++
+ PHPAPI void php_register_variable_ex(char *var_name, zval *val, zval *track_vars_array)
+ {
+ char *p = NULL;
+@@ -103,20 +118,6 @@ PHPAPI void php_register_variable_ex(char *var_name, zval *val, zval *track_vars
+ }
+ var_len = p - var;
+
+- /* Discard variable if mangling made it start with __Host-, where pre-mangling it did not start with __Host- */
+- if (strncmp(var, "__Host-", sizeof("__Host-")-1) == 0 && strncmp(var_name, "__Host-", sizeof("__Host-")-1) != 0) {
+- zval_ptr_dtor_nogc(val);
+- free_alloca(var_orig, use_heap);
+- return;
+- }
+-
+- /* Discard variable if mangling made it start with __Secure-, where pre-mangling it did not start with __Secure- */
+- if (strncmp(var, "__Secure-", sizeof("__Secure-")-1) == 0 && strncmp(var_name, "__Secure-", sizeof("__Secure-")-1) != 0) {
+- zval_ptr_dtor_nogc(val);
+- free_alloca(var_orig, use_heap);
+- return;
+- }
+-
+ if (var_len==0) { /* empty variable name, or variable name with a space in it */
+ zval_dtor(val);
+ free_alloca(var_orig, use_heap);
+@@ -194,6 +195,12 @@ PHPAPI void php_register_variable_ex(char *var_name, zval *val, zval *track_vars
+ return;
+ }
+ } else {
++ if (php_is_forbidden_variable_name(index, index_len, var_name)) {
++ zval_ptr_dtor_nogc(val);
++ free_alloca(var_orig, use_heap);
++ return;
++ }
++
+ gpc_element_p = zend_symtable_str_find(symtable1, index, index_len);
+ if (!gpc_element_p) {
+ zval tmp;
+@@ -230,6 +237,12 @@ plain_var:
+ zval_ptr_dtor(&gpc_element);
+ }
+ } else {
++ if (php_is_forbidden_variable_name(index, index_len, var_name)) {
++ zval_ptr_dtor_nogc(val);
++ free_alloca(var_orig, use_heap);
++ return;
++ }
++
+ /*
+ * According to rfc2965, more specific paths are listed above the less specific ones.
+ * If we encounter a duplicate cookie name, we should skip it, since it is not possible
+--
+2.44.0
+
+From d8e42d4a8471e19710dbb60018ed956eed34af90 Mon Sep 17 00:00:00 2001
+From: Remi Collet <remi@remirepo.net>
+Date: Wed, 10 Apr 2024 08:59:32 +0200
+Subject: [PATCH 2/4] NEWS
+
+(cherry picked from commit 366cc249b7d54707572beb7096e8f6c65ee79719)
+(cherry picked from commit dcdd49ef3bfbd8ccc778850d6a0f9b98adf625d4)
+(cherry picked from commit 8642473b624f809b768180b104c013f74e3a99a0)
+(cherry picked from commit ee591001f7a3db7405b4fa027659768c2355df6d)
+(cherry picked from commit 035bc48bafe5d567f4ab8de6d1752a724e361690)
+---
+ NEWS | 6 ++++++
+ 1 file changed, 6 insertions(+)
+
+diff --git a/NEWS b/NEWS
+index 53ca87c8e6..fae611c48c 100644
+--- a/NEWS
++++ b/NEWS
+@@ -1,6 +1,12 @@
+ PHP NEWS
+ |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
+
++Backported from 8.1.28
++
++- Standard:
++ . Fixed bug GHSA-wpj3-hf5j-x4v4 (__Host-/__Secure- cookie bypass due to
++ partial CVE-2022-31629 fix). (CVE-2024-2756) (nielsdos)
++
+ Backported from 8.0.30
+
+ - Libxml:
+--
+2.44.0
+
diff --git a/php-cve-2024-3096.patch b/php-cve-2024-3096.patch
new file mode 100644
index 0000000..7ba38c1
--- /dev/null
+++ b/php-cve-2024-3096.patch
@@ -0,0 +1,88 @@
+From 459b4ac6a8d9bec32110b68ac194d71ec2b72182 Mon Sep 17 00:00:00 2001
+From: Jakub Zelenka <bukka@php.net>
+Date: Fri, 29 Mar 2024 15:27:59 +0000
+Subject: [PATCH 3/4] Fix bug GHSA-q6x7-frmf-grcw: password_verify can
+ erroneously return true
+
+Disallow null character in bcrypt password
+
+(cherry picked from commit 0ba5229a3f7572846e91c8f5382e87785f543826)
+(cherry picked from commit 81794c73068d9a44bf109bbcc9793e7b56a1c051)
+(cherry picked from commit 4a7ceb9d6427f8d368f1a8739267b1f8310ec201)
+(cherry picked from commit 747100905eceffb1f67096b437001e42900eb6bb)
+(cherry picked from commit d22d9ebb29dce86edd622205dd1196a2796c08c7)
+(cherry picked from commit cd9a376c28c6f4ce83aab53ec069234fe1d2a819)
+---
+ ext/standard/password.c | 5 +++++
+ ext/standard/tests/password/password_bcrypt_errors.phpt | 4 ++++
+ 2 files changed, 9 insertions(+)
+
+diff --git a/ext/standard/password.c b/ext/standard/password.c
+index 33c6e5c718..e2466d1179 100644
+--- a/ext/standard/password.c
++++ b/ext/standard/password.c
+@@ -283,6 +283,11 @@ PHP_FUNCTION(password_hash)
+ cost = zval_get_long(option_buffer);
+ }
+
++ if (memchr(password, '\0', password_len)) {
++ php_error_docref(NULL, E_WARNING, "Bcrypt password must not contain null character");
++ RETURN_NULL();
++ }
++
+ if (cost < 4 || cost > 31) {
+ php_error_docref(NULL, E_WARNING, "Invalid bcrypt cost parameter specified: " ZEND_LONG_FMT, cost);
+ RETURN_NULL();
+diff --git a/ext/standard/tests/password/password_bcrypt_errors.phpt b/ext/standard/tests/password/password_bcrypt_errors.phpt
+index e8f7600b63..f95b72670a 100644
+--- a/ext/standard/tests/password/password_bcrypt_errors.phpt
++++ b/ext/standard/tests/password/password_bcrypt_errors.phpt
+@@ -16,6 +16,8 @@ var_dump(password_hash("foo", PASSWORD_BCRYPT, array("salt" => 123)));
+
+ var_dump(password_hash("foo", PASSWORD_BCRYPT, array("cost" => "foo")));
+
++var_dump(password_hash("null\0password", PASSWORD_BCRYPT));
++
+ ?>
+ --EXPECTF--
+ Warning: password_hash(): Invalid bcrypt cost parameter specified: 3 in %s on line %d
+@@ -42,4 +44,6 @@ NULL
+ Warning: password_hash(): Invalid bcrypt cost parameter specified: 0 in %s on line %d
+ NULL
+
++Warning: password_hash(): Bcrypt password must not contain null character in %s on line %d
++NULL
+
+--
+2.44.0
+
+From d339e614f1e4cbf1aeb5fbee76bb0583885aeb30 Mon Sep 17 00:00:00 2001
+From: Remi Collet <remi@remirepo.net>
+Date: Wed, 10 Apr 2024 09:01:09 +0200
+Subject: [PATCH 4/4] NEWS
+
+(cherry picked from commit 24f77904ee2259d722559f129f96a1f145a2367b)
+(cherry picked from commit 027bdbc636632be49ecfad8d4191509faacb34ac)
+(cherry picked from commit fbeed182bb0b0c4c453e064198b5cc3814a10de0)
+(cherry picked from commit be830600a8e4c33a25e965d0782903e885e91c6d)
+(cherry picked from commit 9ec5a1ed8bed7ca5a14e991ff3e767dbfa773dcd)
+---
+ NEWS | 2 ++
+ 1 file changed, 2 insertions(+)
+
+diff --git a/NEWS b/NEWS
+index fae611c48c..fed03499f6 100644
+--- a/NEWS
++++ b/NEWS
+@@ -6,6 +6,8 @@ Backported from 8.1.28
+ - Standard:
+ . Fixed bug GHSA-wpj3-hf5j-x4v4 (__Host-/__Secure- cookie bypass due to
+ partial CVE-2022-31629 fix). (CVE-2024-2756) (nielsdos)
++ . Fixed bug GHSA-h746-cjrr-wfmr (password_verify can erroneously return true,
++ opening ATO risk). (CVE-2024-3096) (Jakub Zelenka)
+
+ Backported from 8.0.30
+
+--
+2.44.0
+
diff --git a/php-net-snmp.patch b/php-net-snmp.patch
new file mode 100644
index 0000000..e9f819e
--- /dev/null
+++ b/php-net-snmp.patch
@@ -0,0 +1,38 @@
+Backported from 8.0 for 7.0 by Remi
+
+
+From f9fd3595ecb36c8dc6add0515782a18f15216d77 Mon Sep 17 00:00:00 2001
+From: Remi Collet <remi@remirepo.net>
+Date: Thu, 27 May 2021 14:20:07 +0200
+Subject: [PATCH] Fix snmp build without DES
+
+---
+ ext/snmp/snmp.c | 16 ++++++++++++++--
+ 1 file changed, 14 insertions(+), 2 deletions(-)
+
+diff --git a/ext/snmp/snmp.c b/ext/snmp/snmp.c
+index 35d19c8738828..d31995827880d 100644
+--- a/ext/snmp/snmp.c
++++ b/ext/snmp/snmp.c
+@@ -1266,15 +1266,19 @@ static int netsnmp_session_set_auth_prot
+ Set the security protocol in the snmpv3 session */
+ static int netsnmp_session_set_sec_protocol(struct snmp_session *s, char *prot)
+ {
++#ifndef NETSNMP_DISABLE_DES
+ if (!strcasecmp(prot, "DES")) {
+ s->securityPrivProto = usmDESPrivProtocol;
+ s->securityPrivProtoLen = USM_PRIV_PROTO_DES_LEN;
++ } else
++#endif
+ #ifdef HAVE_AES
+- } else if (!strcasecmp(prot, "AES128") || !strcasecmp(prot, "AES")) {
++ if (!strcasecmp(prot, "AES128") || !strcasecmp(prot, "AES")) {
+ s->securityPrivProto = usmAESPrivProtocol;
+ s->securityPrivProtoLen = USM_PRIV_PROTO_AES_LEN;
++ } else
+ #endif
+- } else {
++ {
+ php_error_docref(NULL, E_WARNING, "Unknown security protocol '%s'", prot);
+ return (-1);
+ }
diff --git a/php-openssl-cert.patch b/php-openssl-cert.patch
index adea20c..771645d 100644
--- a/php-openssl-cert.patch
+++ b/php-openssl-cert.patch
@@ -1,3 +1,7 @@
+Without binary patch
+
+
+
From f51062523d03911cc141507112e3ce14b41f73a2 Mon Sep 17 00:00:00 2001
From: Alexander Kurilo <alex@kurilo.me>
Date: Mon, 31 Dec 2018 12:19:36 +0300
@@ -201,3 +205,147 @@ index 39d62b29c901..3bca7cb640c6 100644
]);
var_dump(stream_socket_client($serverUri, $errno, $errstr, 2, $clientFlags, $clientCtx));
CODE;
+From 4c49896e965358ecbceb95f0afbb26a0d03f8221 Mon Sep 17 00:00:00 2001
+From: Remi Collet <remi@remirepo.net>
+Date: Tue, 18 Feb 2020 09:53:18 +0100
+Subject: [PATCH] renew certs for openssl tests
+
+---
+ ext/openssl/tests/bug54992-ca.pem | 54 +++++++++---------
+ ext/openssl/tests/bug54992.pem | 28 ++++-----
+ ext/openssl/tests/bug65538.phar | Bin 11278 -> 11278 bytes
+ .../tests/openssl_peer_fingerprint_basic.phpt | 4 +-
+ 4 files changed, 43 insertions(+), 43 deletions(-)
+
+diff --git a/ext/openssl/tests/bug54992-ca.pem b/ext/openssl/tests/bug54992-ca.pem
+index 743a11e8fd..266f08c907 100644
+--- a/ext/openssl/tests/bug54992-ca.pem
++++ b/ext/openssl/tests/bug54992-ca.pem
+@@ -1,35 +1,35 @@
+ -----BEGIN CERTIFICATE-----
+-MIIGAzCCA+ugAwIBAgIUZ7ZvvfVqSEf1EswMT9LfMIPc/U8wDQYJKoZIhvcNAQEL
++MIIGAzCCA+ugAwIBAgIUZOucIjT7OfT7rQQu4W5rghLGMYEwDQYJKoZIhvcNAQEL
+ BQAwgZAxCzAJBgNVBAYTAlBUMQ8wDQYDVQQIDAZMaXNib2ExDzANBgNVBAcMBkxp
+ c2JvYTEXMBUGA1UECgwOUEhQIEZvdW5kYXRpb24xHjAcBgNVBAMMFVJvb3QgQ0Eg
+ Zm9yIFBIUCBUZXN0czEmMCQGCSqGSIb3DQEJARYXaW50ZXJuYWxzQGxpc3RzLnBo
+-cC5uZXQwHhcNMTgxMjMxMDg0NDU3WhcNMjAwMjA0MDg0NDU3WjCBkDELMAkGA1UE
++cC5uZXQwHhcNMjAwMjE4MDg1MDM0WhcNMjEwMzI0MDg1MDM0WjCBkDELMAkGA1UE
+ BhMCUFQxDzANBgNVBAgMBkxpc2JvYTEPMA0GA1UEBwwGTGlzYm9hMRcwFQYDVQQK
+ DA5QSFAgRm91bmRhdGlvbjEeMBwGA1UEAwwVUm9vdCBDQSBmb3IgUEhQIFRlc3Rz
+ MSYwJAYJKoZIhvcNAQkBFhdpbnRlcm5hbHNAbGlzdHMucGhwLm5ldDCCAiIwDQYJ
+-KoZIhvcNAQEBBQADggIPADCCAgoCggIBAPVThsunmhda5hbNi+pXD3WF9ijryB9H
+-JDnIbPW/vMffWcQgtiRzc+6aCykBygnhnN91NNRpxOsoLCb7OjUMM0TjhSE9DxKD
+-aVLRoDcs5VSaddQjq3AwdkU6ek9InUOeDuZ8gatrpWlEyuQPwwnMAfR9NkcTajuF
+-hGO0BlqkHg98GckQD0N5x6CrrDJt6RE6hf9gUZSGSWdPTiETBQUN8LTuxo/ybFSN
+-hcpVNCF+r3eozATbSU8YvQU52RmPIZWHHmYb7KtMO3TEX4LnLJUOefUK4qk+ZJ0s
+-f4JfnY7RhBlZGh2kIyE5jwqz8/KzKtxrutNaupdTFZO8nX09QSgmDCxVWVclrPaG
+-q2ZFYpeauTy71pTm8DjF7PwQI/+PUrBdFIX0V6uxqUEG0pvPdb8zenVbaK4Jh39u
+-w0V5tH/rbtd7zZX4vl3bmKo1Wk0SQxd83iXitxLiJnWNOsmrJcM/Hx91kE10+/ly
+-zgL/w5A9HSA616kfPdNzny0laH1TXVLJsnyyV3DyfnU4O6VI0JG3WjhgRdMkgobn
+-GvGJ2ZsZAxds9lBtT2y+gw5BU+jkSilPk3jM9MA7Kmyci93U9xxMuDNzyUzfcnXR
+-UIq99dZWeMMy1LT3buZXrAWu1WRgPdQtDKcQHDIQaIkxlWsT8q2q/wIirb6fwxlw
+-vXkFp+aEP35BAgMBAAGjUzBRMB0GA1UdDgQWBBR37F1+W1gcCp8bhZaFFi9JKQhu
+-tTAfBgNVHSMEGDAWgBR37F1+W1gcCp8bhZaFFi9JKQhutTAPBgNVHRMBAf8EBTAD
+-AQH/MA0GCSqGSIb3DQEBCwUAA4ICAQAYHqpISUI/x8UW33i35rYkFYNvXBMQDc8J
+-v4G2eqEBNCOVmHg6P//lq1F2jrtAEr/saESN1uS1Q80sUsthlVsceV1z1isdpugG
+-kMbfHxLe0QpthnP3PEChQw30TPB22BThuGVkteNSZKTCPGdzjSTPq2kOR6PCBZRd
+-r0r/TW3lT/Ng3KgjT6g7E3ZUpAeFEQMlmNYr/eEOL7K+1jzQrbCLmXbs6rmtffr7
+-n4p+wMPMPaSRqQoQ86ff9GPzxWuAQGlytVoiS5Xt3jotd/RWlOy0YQ2QSzOQvFUW
+-4te5lwdOvOFnJTo43U3DqASqMcaazvIsN41zVlOyOyKEr9oZERju6FU1aZmuZtHQ
+-wMCmXVj/Swj67Zp9tG+vVQenbEk314+8c2nenuOIFP1F2C/NG3vMLIpENRGxpmAm
+-s5gIT6mXvJ4JCwWYc75zucOr2KVkDmEziJh/pARuOrOAPdc6NjKku8HBC9UI96+x
+-Db4hG2SqXUzShkFX/px7vlCADvgO3FDk2aiyW02PFsItob2O6OB98VGsU26hgRO/
+-Czz/jbjWTPHNOt6/fcL0m7XLwlJ+K9gRArY15DeJGumcHEq/Vd/Z8iPQKKdzgF4O
+-9XFZvu+VHP82AS5TeiYHCddFJyzktQYcNu5/OBuxzO83d7rpqrLFETTEOL4cN8O7
+-LJ7Q89hYAQ==
++KoZIhvcNAQEBBQADggIPADCCAgoCggIBANDtiwpbgpWNthaPNRpgjvNagqaq1EjS
++19CNFq1+w5jRI8K130RvAWkDwnDcr70RSuNKhbJ2dEool3sUi8puNdvWLa8p95k9
++wg1HtCICixxIdLoYAzprkBJw7QUu/XH9SJeJRkYL7EUFoSDnQF9kbW1qMxZBRlFI
++JEacK1crUBGekudu1DjHCM6dumyObrH4FYZtDdKHLu3PVTO299J7ILsHlAJ31qOG
++zK96yBkjRomru/+Yr9ZjT915slvg19+PGLRSRLMXoolw+WEk5gc00/AsGqXQpavN
++njDu9uw+33Eimrj8KnVsCh9cBQFmrCdqOdJmv8VwD63lcYLruAXkfHIUgdyeVMVT
++Q8O+bgGQWaUrxRED4pJ932TicC23BhiZ/78/nyLwry473mHSIw4Y3M6kGSmEOs+3
++fDcsF8waqOeGXbgdOUjBTu92io+lGsCnUZBRe7sOus6aKHYDE1aBDeGtO4oALS+V
++kNrbCh/VpRIwO9Ah4PvxweqW0ZdloW3TRIXRgRxmGJ9NFe1Rkvv7FB7i2l8IeAKS
++ckuew31vxP6LgGUe5j/qt6xv6GOysefOCAAoHHeNEH+ZSlD1tiglvMVhsUmY9Rit
++XEnB+X8FtOAM3SFiX5tsgB6n4hRKue5WkZywnbkPx7sDu4LQCA00i55dzjP/39M0
++yPnsQrJfOnj5AgMBAAGjUzBRMB0GA1UdDgQWBBSHvApjxItCycV/u9J4Z3b6UAP7
++jzAfBgNVHSMEGDAWgBSHvApjxItCycV/u9J4Z3b6UAP7jzAPBgNVHRMBAf8EBTAD
++AQH/MA0GCSqGSIb3DQEBCwUAA4ICAQB6ffwQmqI9Rq3qiPspJiFLsAT9Um8A/kd0
++unYdMyBRl9T0llGXBeN3YYrJLVAd01UAOSSDV3Cf8L2J2zvKRT8YbC3/LxB/RLIM
++/eHVMGSxpy0S5U8HVChbYGEx/zC9p71HwL31Xj+NfOW1nFbEEPqSbGRmou+X2twZ
++Omwz4Vm4MEpIQLRdgV5bLMN1SETH3TGwdMmTE2S8iKrqeDGB8NEl2LcDvbHAvPNw
++KjitZRiicU99KzSSiGh7dsG/d9JsZqtCSmD+a2PesoUPSPsCaInLQG3aGkApt8Gl
++TtFTxJo9QW7YWxFr9Efb2eU6UIilPSsVj8tvIfS1PRTTJrOlBpJDI6TL5YYtFuw3
++Ij27ILbXSwqUM5MIDYoRDxschNiMRhkRjmnebir2KQdvbt43rW8czwooOzTkd1Bi
++RCAbUCAh1TqVu4vLGcoA8/Rf/1n4M8Zdgq19yfInmU4xs7kaiVvnnAxLSF1TmJl6
++8FCN7ONvHNNXciRkzIxw5Yn6GODa/e8Fzvaza/vkSvW4ry4Hu7T6ze10SuHagN3R
++wwBGBlEI5FEyEKFsTZeHdDMoYzv7Ls4OXZzAo7B/Lwa4OTql7ApVw7MwHEplN3SS
++1Qn4YhhmwJqiGvTGQZSA1gv6Ua/HPHjs1y1fSz+uRukUqlBemDhllmVjWHKJetOv
+++FMLf6DmBw==
+ -----END CERTIFICATE-----
+diff --git a/ext/openssl/tests/bug54992.pem b/ext/openssl/tests/bug54992.pem
+index f207c30448..a04c68cfa0 100644
+--- a/ext/openssl/tests/bug54992.pem
++++ b/ext/openssl/tests/bug54992.pem
+@@ -1,26 +1,26 @@
+ -----BEGIN CERTIFICATE-----
+-MIID7jCCAdYCFDw0rvm7q8y5HfispK5A2I2+RBqHMA0GCSqGSIb3DQEBCwUAMIGQ
++MIID7jCCAdYCFF2eDgBNSufPjQA1YmkSEu4tWGvTMA0GCSqGSIb3DQEBCwUAMIGQ
+ MQswCQYDVQQGEwJQVDEPMA0GA1UECAwGTGlzYm9hMQ8wDQYDVQQHDAZMaXNib2Ex
+ FzAVBgNVBAoMDlBIUCBGb3VuZGF0aW9uMR4wHAYDVQQDDBVSb290IENBIGZvciBQ
+ SFAgVGVzdHMxJjAkBgkqhkiG9w0BCQEWF2ludGVybmFsc0BsaXN0cy5waHAubmV0
+-MB4XDTE4MTIzMTA4NDY0M1oXDTIwMDIwNDA4NDY0M1owWjEXMBUGA1UEAxMOYnVn
++MB4XDTIwMDIxODA4NTA0N1oXDTIxMDMyNDA4NTA0N1owWjEXMBUGA1UEAxMOYnVn
+ NTQ5OTIubG9jYWwxCzAJBgNVBAYTAlBUMQ8wDQYDVQQHEwZMaXNib2ExDzANBgNV
+ BAgTBkxpc2JvYTEQMA4GA1UEChMHcGhwLm5ldDCBnzANBgkqhkiG9w0BAQEFAAOB
+ jQAwgYkCgYEAtUAVQKTgpUPgtFOJ3w3kDJETS45tWeT96kUg1NeYLKW+jNbFhxPo
+ PJv7XhfemCaqh2tbq1cdYW906Wp1L+eNQvdTYA2IQG4EQBUlmfyIakOIMsN/RizV
+ kF09vlNQwTpaMpqTv7wB8vvwbxb9jbC2ZhQUBEg6PIn18dSstbM9FZ0CAwEAATAN
+-BgkqhkiG9w0BAQsFAAOCAgEAKtSMguV5ZQ2KpdZ9MAFa+GiHL0APb58OrvwNK4BF
+-6032UZLOWnsBZlo85WGLNnIT/GNzKKr7n9jHeuZcBVOFQLsebahSlfJZs9FPatlI
+-9Md1tRzVoTKohjG86HeFhhL+gZQ69SdIcK40wpH1qNv7KyMGA8gnx6rRKbOxZqsx
+-pkA/wS7CTqP9/DeOxh/MZPg7N/GZXW1QOz+SE537E9iyiRsbldNYFtwn5iaVfjpr
+-xz09wYYW3HJpR+QKPCfJ79JxDhuMHMoUOpIy8vGFnt5zVTcFLa378Sy3vCT1Qwvt
+-tTavFGHby4A7OqT6xu+9GTW37OaiV91UelLLV0+MoR4XiMVMX76mvqzmKCp6L9ae
+-7RYHrrCtNxkYUKUSkOEc2VHnT+sENkJIZu7zzN7/QNlc0yE9Rtsmgy4QAxo2m9u0
+-pUZLAulZ1lS7g/sr7/8Pp17RDvJiJh+oAPyVYZ7OoLF1IoHDHcZI0bqcqhDhiHZs
+-PXYqyMCxyYzHFOAOgvbrEkmp8z/E8ATVwdUbAYN1dMrYHre1P4HFEtJh2QiGG2KE
+-4jheuNhH1R25AizbwYbD33Kdp7ltCgBlfYqjl771SlgY45QYs0mUdc1Pv39SGIwf
+-ZUm7mOWjaTBdYANrkvGM5NNT9kESjKkWykyTg4UF5rHV6nlyexR4b3fjabroi4BS
+-v6w=
++BgkqhkiG9w0BAQsFAAOCAgEAEhDpl41vWZF9lGSlxz5uwIGguibrbeBYn/1PYpw4
++jF0i/DxNWYmAh/9vM/ClXhL9rVtHev88eO6goIDjiU2W59ksffxxw0Xno6XOgElb
++8sdWBF4wLKiCuZrAYJ+N+CWKWkWFgsdBEHGktBk/UIh7Aw2LjVneMMj8lIgpDw9l
++PfMZ1SAajBEh5D4TrM6TR3ImT2x0t4Rb1LOrfdn34eHHp/K1wpsZfDwzQKXF1RNb
++XqQwzsB5kEMdOBC1ykOXcLqiUPxMakiVAfnt8w1UCdCB3TH63HkxATqoqZLXFYRX
++JZRLkAUvoqdDNVP2gOYRewInWJL+EaRNt3P5DR8tEgCOUyw0UYgpI7KDHV5cL3MB
++JKeLXmQu0o9ZviPk3saEdmhnSaPCGcVoF5E1vnSudcla7wz65U0w+bEX94DxGad/
++CrsGVS0VbdTV6lPQgcbP/IP4sxBUqZvpDlr20XzgsgdwCBgGwcJ47Y1zDQh17sAe
++rZxhtxHG6PJbCwdj7z9FNgsMPmfFXoqcLFyN+N3vbGMpOaO6KCoylmFvNSQCwFrm
++y/V+z5fQFe42trqLr04DEVw7rzGN6I8vyGPu7267FNDO5bdwuJ0FVjB88IW2mcRw
++S52CzP5H7wavwVsKQ9iZTsBWYwxiU2YCwjhx0v5WWZAnQfjjzA5vvFokWhrWDvca
++auw=
+ -----END CERTIFICATE-----
+ -----BEGIN RSA PRIVATE KEY-----
+ MIICXgIBAAKBgQC1QBVApOClQ+C0U4nfDeQMkRNLjm1Z5P3qRSDU15gspb6M1sWH
+diff --git a/ext/openssl/tests/openssl_peer_fingerprint_basic.phpt b/ext/openssl/tests/openssl_peer_fingerprint_basic.phpt
+index 3bca7cb640..49ecaac7e6 100644
+--- a/ext/openssl/tests/openssl_peer_fingerprint_basic.phpt
++++ b/ext/openssl/tests/openssl_peer_fingerprint_basic.phpt
+@@ -36,13 +36,13 @@ $clientCode = <<<'CODE'
+ // openssl x509 -noout -fingerprint -md5 -inform pem -in ext/openssl/tests/bug54992.pem | cut -d '=' -f 2 | tr -d ':' | tr 'A-F' 'a-f'
+ // Currently it's 4edbbaf40a6a4b6af22b6d6d9818378f
+ // One below is intentionally broken (compare the last character):
+- stream_context_set_option($clientCtx, 'ssl', 'peer_fingerprint', '4edbbaf40a6a4b6af22b6d6d98183780');
++ stream_context_set_option($clientCtx, 'ssl', 'peer_fingerprint', '9aa2c02d62358f2fa0db575806e37799');
+ var_dump(stream_socket_client($serverUri, $errno, $errstr, 2, $clientFlags, $clientCtx));
+
+ // Run the following to get actual sha256 (from sources root):
+ // openssl x509 -noout -fingerprint -sha256 -inform pem -in ext/openssl/tests/bug54992.pem | cut -d '=' -f 2 | tr -d ':' | tr 'A-F' 'a-f'
+ stream_context_set_option($clientCtx, 'ssl', 'peer_fingerprint', [
+- 'sha256' => 'b1d480a2f83594fa243d26378cf611f334d369e59558d87e3de1abe8f36cb997',
++ 'sha256' => '62e70554daabf366ba9ada30d3af794ec421368e79b68f64dc9ed546d834ae7d',
+ ]);
+ var_dump(stream_socket_client($serverUri, $errno, $errstr, 2, $clientFlags, $clientCtx));
+ CODE;
diff --git a/php.spec b/php.spec
index 29fa21c..4e43e52 100644
--- a/php.spec
+++ b/php.spec
@@ -55,12 +55,14 @@
%global mysql_sock %(mysql_config --socket 2>/dev/null || echo /var/lib/mysql/mysql.sock)
-%if 0%{?rhel} == 6
-%global oraclever 18.3
-%global oraclelib 18.1
-%else
-%global oraclever 19.3
+%ifarch aarch64
+%global oraclever 19.19
%global oraclelib 19.1
+%global oracledir 19.19
+%else
+%global oraclever 21.13
+%global oraclelib 21.1
+%global oracledir 21
%endif
# Build for LiteSpeed Web Server (LSAPI)
@@ -77,12 +79,7 @@
# Optional components; pass "--with mssql" etc to rpmbuild.
%global with_oci8 %{?_with_oci8:1}%{!?_with_oci8:0}
%global with_imap 1
-# until firebird available in EPEL
-%if 0%{?rhel} == 8
-%global with_interbase 0
-%else
%global with_interbase 1
-%endif
%global with_mcrypt 1
%global with_freetds 1
%global with_tidy 1
@@ -137,7 +134,7 @@
Summary: PHP scripting language for creating dynamic web sites
Name: %{?scl_prefix}php
Version: %{upver}%{?rcver:~%{rcver}}
-Release: 12%{?dist}
+Release: 41%{?dist}
# All files licensed under PHP version 3.01, except
# Zend is licensed under Zend
# TSRM is licensed under BSD
@@ -179,6 +176,8 @@ Patch7: php-5.3.0-recode.patch
Patch8: php-7.0.2-libdb.patch
Patch9: php-7.0.7-curl.patch
Patch10: php-7.0.31-icu62.patch
+# backported from 8.0
+Patch11: php-net-snmp.patch
# Functional changes
Patch40: php-7.0.17-dlopen.patch
@@ -198,7 +197,6 @@ Patch91: php-5.6.3-oci8conf.patch
# Upstream fixes (100+)
Patch100: https://github.com/php/php-src/commit/be50a72715c141befe6f34ece660745da894aaf3.patch
Patch101: https://github.com/php/php-src/commit/2ef8809ef3beb5f58b81dcff49bdcde4d2cb8426.patch
-Patch102: php-openssl-cert.patch
Patch103: php-bug76846.patch
# Security fixes (200+)
@@ -227,12 +225,57 @@ Patch221: php-bug77967.patch
Patch222: php-bug78222.patch
Patch223: php-bug78256.patch
Patch224: php-bug77919.patch
+Patch225: php-bug75457.patch
+Patch226: php-bug78380.patch
+Patch227: php-bug78599.patch
+Patch228: php-bug78878.patch
+Patch229: php-bug78862.patch
+Patch230: php-bug78863.patch
+Patch231: php-bug78793.patch
+Patch232: php-bug78910.patch
+Patch233: php-bug79099.patch
+Patch234: php-bug79037.patch
+Patch235: php-bug77569.patch
+Patch236: php-bug79221.patch
+Patch237: php-bug79082.patch
+Patch238: php-bug79282.patch
+Patch239: php-bug79329.patch
+Patch240: php-bug79330.patch
+Patch241: php-bug79465.patch
+Patch242: php-bug78875.patch
+Patch243: php-bug78876.patch
+Patch244: php-bug79797.patch
+Patch245: php-bug79877.patch
+Patch246: php-bug79699.patch
+Patch247: php-bug77423.patch
+Patch248: php-bug80672.patch
+Patch249: php-bug80710.patch
+Patch250: php-bug81122.patch
+Patch251: php-bug76450.patch
+Patch252: php-bug81211.patch
+Patch253: php-bug81026.patch
+Patch254: php-bug79971.patch
+Patch255: php-bug81719.patch
+Patch256: php-bug81720.patch
+Patch257: php-bug81727.patch
+Patch258: php-bug81726.patch
+Patch259: php-bug81740.patch
+Patch260: php-bug81744.patch
+Patch261: php-bug81746.patch
+Patch262: php-cve-2023-0662.patch
+Patch263: php-cve-2023-3247.patch
+Patch264: php-cve-2023-3823.patch
+Patch265: php-cve-2023-3824.patch
+Patch266: php-cve-2024-2756.patch
+Patch267: php-cve-2024-3096.patch
# Fixes for tests (300+)
# Factory is droped from system tzdata
Patch300: php-7.0.10-datetests.patch
# Revert changes for pcre < 8.34
Patch301: php-7.0.0-oldpcre.patch
+# Renew openssl certs
+Patch302: php-openssl-cert.patch
# WIP
@@ -259,6 +302,7 @@ BuildRequires: bzip2
BuildRequires: perl
BuildRequires: autoconf
BuildRequires: automake
+BuildRequires: make
BuildRequires: gcc
BuildRequires: gcc-c++
BuildRequires: libtool
@@ -332,7 +376,6 @@ The %{?scl_prefix}php-dbg package contains the interactive PHP debugger.
Group: Development/Languages
Summary: PHP FastCGI Process Manager
BuildRequires: libacl-devel
-Requires(pre): %{_root_sbindir}/useradd
Requires: %{?scl_prefix}php-common%{?_isa} = %{version}-%{release}
%if %{with_systemd}
BuildRequires: systemd-devel
@@ -356,6 +399,8 @@ Requires(pre): httpd-filesystem
# For php.conf in /etc/httpd/conf.d
# and version 2.4.10 for proxy support in SetHandler
Requires: httpd-filesystem >= 2.4.10
+%else
+Requires(pre): %{_root_sbindir}/useradd
%endif
%description fpm
@@ -442,6 +487,7 @@ Requires: %{?scl_prefix}php-cli%{?_isa} = %{version}-%{release}
# always needed to build extension
Requires: autoconf
Requires: automake
+Requires: make
Requires: gcc
Requires: gcc-c++
Requires: libtool
@@ -645,15 +691,20 @@ Summary: A module for PHP applications that use OCI8 databases
Group: Development/Languages
# All files licensed under PHP version 3.01
License: PHP
+%ifarch aarch64
+BuildRequires: oracle-instantclient%{oraclever}-devel
+# Should requires libclntsh.so.19.1()(aarch-64), but it's not provided by Oracle RPM.
+Requires: libclntsh.so.%{oraclelib}
+AutoReq: 0
+%else
BuildRequires: oracle-instantclient-devel >= %{oraclever}
+%endif
Requires: %{?scl_prefix}php-pdo%{?_isa} = %{version}-%{release}
Provides: %{?scl_prefix}php_database
Provides: %{?scl_prefix}php-pdo_oci, %{?scl_prefix}php-pdo_oci%{?_isa}
Obsoletes: %{?scl_prefix}php-pecl-oci8 < %{oci8ver}
Conflicts: %{?scl_prefix}php-pecl-oci8 >= %{oci8ver}
Provides: %{?scl_prefix}php-pecl(oci8) = %{oci8ver}, %{?scl_prefix}php-pecl(oci8)%{?_isa} = %{oci8ver}
-# Should requires libclntsh.so.12.1, but it's not provided by Oracle RPM.
-AutoReq: 0
%description oci8
The %{?scl_prefix}php-oci8 packages provides the OCI8 extension version %{oci8ver}
@@ -663,13 +714,9 @@ The extension is linked with Oracle client libraries %{oraclever}
(Oracle Instant Client). For details, see Oracle's note
"Oracle Client / Server Interoperability Support" (ID 207303.1).
-You must install libclntsh.so.%{oraclelib} to use this package, provided
-in the database installation, or in the free Oracle Instant Client
-available from Oracle.
-
-Notice:
-- %{?scl_prefix}php-oci8 provides oci8 and pdo_oci extensions from php sources.
-- %{?scl_prefix}php-pecl-oci8 only provides oci8 extension.
+You must install libclntsh.so.%{oraclelib} to use this package,
+provided by Oracle Instant Client RPM available from Oracle on:
+https://www.oracle.com/database/technologies/instant-client/downloads.html
Documentation is at http://php.net/oci8 and http://php.net/pdo_oci
%endif
@@ -749,12 +796,7 @@ Requires: %{?scl_prefix}php-common%{?_isa} = %{version}-%{release}
BuildRequires: libjpeg-devel, libpng-devel, freetype-devel
BuildRequires: libXpm-devel
%if %{with_libgd}
-BuildRequires: gd-devel >= 2.1.1
-%if 0%{?fedora} <= 19 && 0%{?rhel} <= 7
-Requires: gd-last%{?_isa} >= 2.1.1
-%else
-Requires: gd%{?_isa} >= 2.1.1
-%endif
+BuildRequires: gd-devel >= 2.3.3
%else
BuildRequires: libwebp-devel
%endif
@@ -875,8 +917,8 @@ Group: System Environment/Libraries
# All files licensed under PHP version 3.01
License: PHP
Requires: %{?scl_prefix}php-common%{?_isa} = %{version}-%{release}
-# Upstream requires 4.0, we require 50 to ensure use of libicu-last
-BuildRequires: libicu-devel >= 50
+# Upstream requires 4.0, we require 69.1 to ensure use of libicu69
+BuildRequires: libicu-devel = 69.1
%description intl
The %{?scl_prefix}php-intl package contains a dynamic shared object that will add
@@ -934,81 +976,125 @@ support for JavaScript Object Notation (JSON) to PHP.
%setup -q -n php-%{upver}%{?rcver}
%endif
-%patch1 -p1 -b .mpmcheck
-%patch2 -p1 -b .fb_config
-%patch5 -p1 -b .includedir
-%patch6 -p1 -b .embed
-%patch7 -p1 -b .recode
-%patch8 -p1 -b .libdb
+%patch -P1 -p1 -b .mpmcheck
+%patch -P2 -p1 -b .fb_config
+%patch -P5 -p1 -b .includedir
+%patch -P6 -p1 -b .embed
+%patch -P7 -p1 -b .recode
+%patch -P8 -p1 -b .libdb
%if 0%{?rhel}
-%patch9 -p1 -b .curltls
+%patch -P9 -p1 -b .curltls
%endif
-%if 0%{?fedora} >= 29 || 0%{?rhel} >= 8
-%patch10 -p1 -b .icu62
+%if 0%{?fedora} >= 29 || 0%{?rhel} >= 7
+%patch -P10 -p1 -b .icu62
%endif
+%patch -P11 -p1 -b .nodes
-%patch40 -p1 -b .dlopen
+%patch -P40 -p1 -b .dlopen
%if 0%{?fedora} >= 28 || 0%{?rhel} >= 6
-%patch42 -p1 -b .systzdata
+%patch -P42 -p1 -b .systzdata
%endif
-%patch43 -p1 -b .headers
+%patch -P43 -p1 -b .headers
sed -e 's/php-devel/%{?scl_prefix}php-devel/' -i scripts/phpize.in
%if 0%{?fedora} >= 18 || 0%{?rhel} >= 7
-%patch45 -p1 -b .ldap_r
+%patch -P45 -p1 -b .ldap_r
%endif
-%patch46 -p1 -b .fixheader
-%patch47 -p1 -b .phpinfo
+%patch -P46 -p1 -b .fixheader
+%patch -P47 -p1 -b .phpinfo
-%patch91 -p1 -b .remi-oci8
+%patch -P91 -p1 -b .remi-oci8
# upstream patches
-%patch100 -p1 -b .up1
-%patch101 -p1 -b .up2
-%patch102 -p1 -b .up3
-%patch103 -p1 -b .bug76846
+%patch -P100 -p1 -b .up1
+%patch -P101 -p1 -b .up2
+%patch -P103 -p1 -b .bug76846
# security patches
-%patch200 -p1 -b .bug77242
-%patch201 -p1 -b .bug77247
-%patch202 -p1 -b .bug77370
-%patch203 -p1 -b .bug77371
-%patch204 -p1 -b .bug77380
-%patch205 -p1 -b .bug77381
-%patch206 -p1 -b .bug77369
-%patch207 -p1 -b .bug77418
-%patch208 -p1 -b .bug77396
-%patch209 -p1 -b .bug77431
-%patch210 -p1 -b .bug77540
-%patch211 -p1 -b .bug77563
-%patch212 -p1 -b .bug77586
-%patch213 -p1 -b .bug77630
-%patch214 -p1 -b .backport
-%patch215 -p1 -b .sqlite3.defensive
-%patch216 -p1 -b .bug77753
-%patch217 -p1 -b .bug77831
-%patch218 -p1 -b .bug77950
-%patch219 -p1 -b .bug78069
-%patch220 -p1 -b .bug77988
-%patch221 -p1 -b .bug77967
-%patch222 -p1 -b .bug78222
-%patch223 -p1 -b .bug78256
-%patch224 -p1 -b .bug77919
-: ---------------------------
-#exit 1
+%patch -P200 -p1 -b .bug77242
+%patch -P201 -p1 -b .bug77247
+%patch -P202 -p1 -b .bug77370
+%patch -P203 -p1 -b .bug77371
+%patch -P204 -p1 -b .bug77380
+%patch -P205 -p1 -b .bug77381
+%patch -P206 -p1 -b .bug77369
+%patch -P207 -p1 -b .bug77418
+%patch -P208 -p1 -b .bug77396
+%patch -P209 -p1 -b .bug77431
+%patch -P210 -p1 -b .bug77540
+%patch -P211 -p1 -b .bug77563
+%patch -P212 -p1 -b .bug77586
+%patch -P213 -p1 -b .bug77630
+%patch -P214 -p1 -b .backport
+%patch -P215 -p1 -b .sqlite3.defensive
+%patch -P216 -p1 -b .bug77753
+%patch -P217 -p1 -b .bug77831
+%patch -P218 -p1 -b .bug77950
+%patch -P219 -p1 -b .bug78069
+%patch -P220 -p1 -b .bug77988
+%patch -P221 -p1 -b .bug77967
+%patch -P222 -p1 -b .bug78222
+%patch -P223 -p1 -b .bug78256
+%patch -P224 -p1 -b .bug77919
+%patch -P225 -p1 -b .bug75457
+%patch -P226 -p1 -b .bug78380
+%patch -P227 -p1 -b .bug78599
+%patch -P228 -p1 -b .bug78878
+%patch -P229 -p1 -b .bug78862
+%patch -P230 -p1 -b .bug78863
+%patch -P231 -p1 -b .bug78793
+%patch -P232 -p1 -b .bug78910
+%patch -P233 -p1 -b .bug79099
+%patch -P234 -p1 -b .bug79037
+%patch -P235 -p1 -b .bug77569
+%patch -P236 -p1 -b .bug79221
+%patch -P237 -p1 -b .bug79082
+%patch -P238 -p1 -b .bug79282
+%patch -P239 -p1 -b .bug79329
+%patch -P240 -p1 -b .bug79330
+%patch -P241 -p1 -b .bug79465
+%patch -P242 -p1 -b .bug78875
+%patch -P243 -p1 -b .bug78876
+%patch -P244 -p1 -b .bug79797
+%patch -P245 -p1 -b .bug79877
+%patch -P246 -p1 -b .bug79699
+%patch -P247 -p1 -b .bug77423
+%patch -P248 -p1 -b .bug80672
+%patch -P249 -p1 -b .bug80710
+%patch -P250 -p1 -b .bug81122
+%patch -P251 -p1 -b .bug76450
+%patch -P252 -p1 -b .bug81211
+%patch -P253 -p1 -b .bug81026
+%patch -P254 -p1 -b .bug79971
+%patch -P255 -p1 -b .bug81719
+%patch -P256 -p1 -b .bug81720
+%patch -P257 -p1 -b .bug81727
+%patch -P258 -p1 -b .bug81726
+%patch -P259 -p1 -b .bug81740
+%patch -P260 -p1 -b .bug81744
+%patch -P261 -p1 -b .bug81746
+%patch -P262 -p1 -b .cve0662
+%patch -P263 -p1 -b .cve3247
+%patch -P264 -p1 -b .cve3823
+%patch -P265 -p1 -b .cve3824
+%patch -P266 -p1 -b .cve2756
+%patch -P267 -p1 -b .cve3096
# Fixes for tests
-%patch300 -p1 -b .datetests
+%patch -P300 -p1 -b .datetests
%if %{with_libpcre}
if ! pkg-config libpcre --atleast-version 8.34 ; then
# Only apply when system libpcre < 8.34
-%patch301 -p1 -b .pcre834
+%patch -P301 -p1 -b .pcre834
fi
%endif
+# New openssl certs
+%patch -P302 -p1 -b .renewcert
+rm ext/openssl/tests/bug65538_003.phpt
# WIP patch
# Prevent %%doc confusion over LICENSE files
-cp Zend/LICENSE Zend/ZEND_LICENSE
+cp Zend/LICENSE ZEND_LICENSE
cp TSRM/LICENSE TSRM_LICENSE
%if ! %{with_libgd}
cp ext/gd/libgd/README libgd_README
@@ -1141,6 +1227,12 @@ exit 1
%build
+# This package fails to build with LTO due to undefined symbols. LTO
+# was disabled in OpenSuSE as well, but with no real explanation why
+# beyond the undefined symbols. It really shold be investigated further.
+# Disable LTO
+%define _lto_cflags %{nil}
+
# aclocal workaround - to be improved
cat $(aclocal --print-ac-dir)/{libtool,ltoptions,ltsugar,ltversion,lt~obsolete}.m4 >>aclocal.m4
@@ -1267,7 +1359,7 @@ build --libdir=%{_libdir}/php \
--with-mysqli=shared,mysqlnd \
--with-mysql-sock=%{mysql_sock} \
%if %{with_oci8}
- --with-oci8=shared,instantclient,%{_root_libdir}/oracle/%{oraclever}/client64/lib,%{oraclever} \
+ --with-oci8=shared,instantclient,%{_root_prefix}/lib/oracle/%{oracledir}/client64/lib,%{oraclever} \
--with-pdo-oci=shared,instantclient,%{_root_prefix},%{oraclever} \
%endif
%if %{with_interbase}
@@ -1379,12 +1471,12 @@ popd
%check
%if %runselftest
-
-cd build-apache
+cd build-fpm
# Run tests, using the CLI SAPI
export NO_INTERACTION=1 REPORT_EXIT_STATUS=1 MALLOC_CHECK_=2
export SKIP_ONLINE_TESTS=1
+export SKIP_SLOW_TESTS=1
unset TZ LANG LC_ALL
if ! make test; then
set +x
@@ -1492,8 +1584,8 @@ mv $RPM_BUILD_ROOT%{_sysconfdir}/php-fpm.d/www.conf.default .
%if %{with_systemd}
install -Dm 644 %{SOURCE6} $RPM_BUILD_ROOT%{_unitdir}/%{?scl_prefix}php-fpm.service
%if 0%{?fedora} >= 27 || 0%{?rhel} >= 8
-install -Dm 644 %{SOURCE12} $RPM_BUILD_ROOT%{_unitdir}/httpd.service.d/%{?scl_prefix}php-fpm.conf
-install -Dm 644 %{SOURCE12} $RPM_BUILD_ROOT%{_unitdir}/nginx.service.d/%{?scl_prefix}php-fpm.conf
+install -Dm 644 %{SOURCE12} $RPM_BUILD_ROOT%{_root_sysconfdir}/systemd/system/httpd.service.d/%{?scl_prefix}php-fpm.conf
+install -Dm 644 %{SOURCE12} $RPM_BUILD_ROOT%{_root_sysconfdir}/systemd/system/nginx.service.d/%{?scl_prefix}php-fpm.conf
%endif
sed -e 's:/run:%{_localstatedir}/run:' \
-e 's:/etc/sysconfig:%{_sysconfdir}/sysconfig:' \
@@ -1757,13 +1849,9 @@ cat << EOF
WARNING : PHP 7.0 have reached its "End of Life" in
December 2018. Even, if this package includes some of
- the important security fix, backported from 7.1, the
+ the important security fixes, backported from 8.1, the
UPGRADE to a maintained version is very strongly RECOMMENDED.
-%if %{?fedora}%{!?fedora:99} < 28
- WARNING : Fedora %{fedora} is now EOL :
- You should consider upgrading to a supported release
-%endif
=====================================================================
EOF
@@ -1788,7 +1876,7 @@ EOF
%files common -f files.common
%doc CODING_STANDARDS CREDITS EXTENSIONS NEWS README*
-%license LICENSE TSRM_LICENSE
+%license LICENSE TSRM_LICENSE ZEND_LICENSE
%license libmagic_LICENSE
%license phar_LICENSE
%license timelib_LICENSE
@@ -1852,8 +1940,8 @@ EOF
%if %{with_systemd}
%{_unitdir}/%{?scl_prefix}php-fpm.service
%if 0%{?fedora} >= 27 || 0%{?rhel} >= 8
-%{_unitdir}/httpd.service.d/%{?scl_prefix}php-fpm.conf
-%{_unitdir}/nginx.service.d/%{?scl_prefix}php-fpm.conf
+%config(noreplace) %{_root_sysconfdir}/systemd/system/httpd.service.d/%{?scl_prefix}php-fpm.conf
+%config(noreplace) %{_root_sysconfdir}/systemd/system/nginx.service.d/%{?scl_prefix}php-fpm.conf
%endif
%dir %{_root_sysconfdir}/systemd/system/%{?scl_prefix}php-fpm.service.d
%else
@@ -1945,6 +2033,174 @@ EOF
%changelog
+* Wed Apr 10 2024 Remi Collet <remi@remirepo.net> - 7.0.33-41
+- use oracle client library version 21.13 on x86_64, 19.19 on aarch64
+- Fix __Host-/__Secure- cookie bypass due to partial CVE-2022-31629 fix
+ CVE-2024-2756
+- Fix password_verify can erroneously return true opening ATO risk
+ CVE-2024-3096
+
+* Wed Aug 2 2023 Remi Collet <remi@remirepo.net> - 7.0.33-40
+- Fix Security issue with external entity loading in XML without enabling it
+ GHSA-3qrf-m4j2-pcrr CVE-2023-3823
+- Fix Buffer mismanagement in phar_dir_read()
+ GHSA-jqcx-ccgc-xwhv CVE-2023-3824
+- move httpd/nginx wants directive to config files in /etc
+
+* Wed Jun 21 2023 Remi Collet <remi@remirepo.net> - 7.0.33-39
+- fix possible buffer overflow in date
+- define %%php70___phpize and %%php70___phpconfig
+
+* Wed Jun 7 2023 Remi Collet <remi@remirepo.net> - 7.0.33-38
+- Fix Missing error check and insufficient random bytes in HTTP Digest
+ authentication for SOAP
+ GHSA-76gg-c692-v2mw CVE-2023-3247
+- use oracle client library version 21.10
+
+* Tue Feb 14 2023 Remi Collet <remi@remirepo.net> - 7.0.33-37
+- fix #81744: Password_verify() always return true with some hash
+ CVE-2023-0567
+- fix #81746: 1-byte array overrun in common path resolve code
+ CVE-2023-0568
+- fix DOS vulnerability when parsing multipart request body
+ CVE-2023-0662
+
+* Tue Dec 20 2022 Remi Collet <remi@remirepo.net> - 7.0.33-36
+- pdo: fix #81740: PDO::quote() may return unquoted string
+ CVE-2022-31631
+- use oracle client library version 21.8
+
+* Tue Sep 27 2022 Remi Collet <remi@remirepo.net> - 7.0.33-35
+- phar: fix #81726 DOS when using quine gzip file. CVE-2022-31628
+- core: fix #81727 Don't mangle HTTP variable names that clash with ones
+ that have a specific semantic meaning. CVE-2022-31629
+- use oracle client library version 21.7
+
+* Tue Jun 7 2022 Remi Collet <remi@remirepo.net> - 7.0.33-33
+- use oracle client library version 21.6
+- mysqlnd: fix #81719: mysqlnd/pdo password buffer overflow. CVE-2022-31626
+- pgsql: fix #81720: Uninitialized array in pg_query_params(). CVE-2022-31625
+
+* Mon Nov 15 2021 Remi Collet <remi@remirepo.net> - 7.0.33-32
+- Fix #79971 special character is breaking the path in xml function
+ CVE-2021-21707
+
+* Wed Oct 20 2021 Remi Collet <remi@remirepo.net> - 7.0.33-31
+- fix PHP-FPM oob R/W in root process leading to priv escalation
+ CVE-2021-21703
+- use libicu version 69
+- use oracle client library version 21.3
+
+* Tue Sep 7 2021 Remi Collet <remi@remirepo.net> - 7.0.33-30
+- fix intl build on F35
+
+* Thu Aug 26 2021 Remi Collet <remi@remirepo.net> - 7.0.33-29
+- Fix #81211 Symlinks are followed when creating PHAR archive
+
+* Mon Jun 28 2021 Remi Collet <remi@remirepo.net> - 7.0.33-28
+- Fix #81122 SSRF bypass in FILTER_VALIDATE_URL
+ CVE-2021-21705
+- Fix #76488 Memory leak when fetching a BLOB field
+- Fix #76448 Stack buffer overflow in firebird_info_cb
+- Fix #76449 SIGSEGV in firebird_handle_doer
+- Fix #76450 SIGSEGV in firebird_stmt_execute
+- Fix #76452 Crash while parsing blob data in firebird_fetch_blob
+ CVE-2021-21704
+
+* Thu May 27 2021 Remi Collet <remi@remirepo.net> - 7.0.33-27
+- fix snmp extension build with net-snmp without DES
+
+* Wed Apr 28 2021 Remi Collet <remi@remirepo.net> - 7.0.33-26
+- Fix #80710 imap_mail_compose() header injection
+- use oracle client library version 21.1
+
+* Wed Feb 3 2021 Remi Collet <remi@remirepo.net> - 7.0.33-25
+- Fix #80672 Null Dereference in SoapClient
+ CVE-2021-21702
+- better fix for #77423
+
+* Mon Jan 4 2021 Remi Collet <remi@remirepo.net> - 7.0.33-24
+- Fix #77423 FILTER_VALIDATE_URL accepts URLs with invalid userinfo
+ CVE-2020-7071
+
+* Tue Sep 29 2020 Remi Collet <remi@remirepo.net> - 7.0.33-23
+- Core:
+ Fix #79699 PHP parses encoded cookie names so malicious `__Host-` cookies can be sent
+ CVE-2020-7070
+
+* Tue Aug 4 2020 Remi Collet <remi@remirepo.net> - 7.0.33-22
+- Core:
+ Fix #79877 getimagesize function silently truncates after a null byte
+- Phar:
+ Fix #79797 use of freed hash key in the phar_parse_zipfile function
+ CVE-2020-7068
+
+* Tue May 12 2020 Remi Collet <remi@remirepo.net> - 7.0.33-21
+- Core:
+ Fix #78875 Long filenames cause OOM and temp files are not cleaned
+ CVE-2019-11048
+ Fix #78876 Long variables in multipart/form-data cause OOM and temp
+ files are not cleaned
+
+* Tue Apr 14 2020 Remi Collet <remi@remirepo.net> - 7.0.33-20
+- standard:
+ Fix #79330 shell_exec silently truncates after a null byte
+ Fix #79465 OOB Read in urldecode
+ CVE-2020-7067
+
+* Tue Mar 17 2020 Remi Collet <remi@remirepo.net> - 7.0.33-19
+- standard:
+ Fix #79329 get_headers() silently truncates after a null byte
+ CVE-2020-7066
+- exif:
+ Fix #79282 Use-of-uninitialized-value in exif
+ CVE-2020-7064
+- use oracle client library version 19.6 (18.5 on EL-6)
+
+* Tue Feb 18 2020 Remi Collet <remi@remirepo.net> - 7.0.33-18
+- dom:
+ Fix #77569 Write Access Violation in DomImplementation
+- phar:
+ Fix #79082 Files added to tar with Phar::buildFromIterator have all-access permissions
+ CVE-2020-7063
+- session:
+ Fix #79221 Null Pointer Dereference in PHP Session Upload Progress
+ CVE-2020-7062
+
+* Thu Jan 23 2020 Remi Collet <remi@remirepo.net> - 7.0.33-17
+- mbstring:
+ Fix #79037 global buffer-overflow in mbfl_filt_conv_big5_wchar
+ CVE-2020-7060
+- standard:
+ Fix #79099 OOB read in php_strip_tags_ex
+ CVE-2020-7059
+
+* Tue Dec 17 2019 Remi Collet <remi@remirepo.net> - 7.0.33-15
+- bcmath:
+ Fix #78878 Buffer underflow in bc_shift_addsub
+ CVE-2019-11046
+- core:
+ Fix #78862 link() silently truncates after a null byte on Windows
+ CVE-2019-11044
+ Fix #78863 DirectoryIterator class silently truncates after a null byte
+ CVE-2019-11045
+- exif
+ Fix #78793 Use-after-free in exif parsing under memory sanitizer
+ CVE-2019-11050
+ Fix #78910 Heap-buffer-overflow READ in exif
+ CVE-2019-11047
+- use oracle client library version 19.5 (18.5 on EL-6)
+
+* Tue Oct 22 2019 Remi Collet <remi@remirepo.net> - 7.0.33-14
+- FPM:
+ Fix CVE-2019-11043 env_path_info underflow in fpm_main.c
+
+* Wed Aug 28 2019 Remi Collet <remi@remirepo.net> - 7.0.33-13
+- mbstring:
+ Fix CVE-2019-13224 don't allow different encodings for onig_new_deluxe
+- pcre:
+ Fix #75457 heap use-after-free in pcrelib
+
* Tue Jul 30 2019 Remi Collet <remi@remirepo.net> - 7.0.33-12
- exif:
Fix #78256 heap-buffer-overflow on exif_process_user_comment