This commit is contained in:
Funda Wang 2022-09-20 15:32:22 +08:00
parent f931e0f886
commit a30654f80d
21 changed files with 79 additions and 2439 deletions

View File

@ -1,193 +0,0 @@
From 3c939e3f69955d087e0bb671868f7267dfb2a502 Mon Sep 17 00:00:00 2001
From: Stanislav Malyshev <stas@php.net>
Date: Sun, 31 Jan 2021 21:15:23 -0800
Subject: [PATCH] Fix bug #80672 - Null Dereference in SoapClient
---
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, 37 insertions(+), 14 deletions(-)
create mode 100644 ext/soap/tests/bug80672.phpt
create mode 100644 ext/soap/tests/bug80672.xml
diff --git a/ext/soap/php_sdl.c b/ext/soap/php_sdl.c
index 1875bec41d..67ab4097c2 100644
--- a/ext/soap/php_sdl.c
+++ b/ext/soap/php_sdl.c
@@ -313,6 +313,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;
@@ -374,7 +376,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;
}
@@ -435,7 +437,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;
}
@@ -545,7 +547,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;
}
@@ -647,7 +649,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;
}
@@ -679,14 +681,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));
@@ -695,7 +697,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);
@@ -764,7 +766,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;
@@ -803,7 +805,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;
}
@@ -905,7 +907,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;
@@ -924,7 +926,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;
}
@@ -1102,7 +1104,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 8d07bb0d83..a1ab525de3 100644
--- a/ext/soap/php_xml.c
+++ b/ext/soap/php_xml.c
@@ -203,7 +203,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) {
@@ -219,7 +219,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.11.0

View File

@ -1,211 +0,0 @@
From 4a89e726bd4d0571991dc22a9a1ad4509e8fe347 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>
---
ext/filter/logical_filters.c | 23 +++++++++++++++++++
.../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 +-
.../tests/url/parse_url_unterminated.phpt | 6 +++--
ext/standard/url.c | 6 +----
8 files changed, 38 insertions(+), 28 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 076d2479461f..1cf345dbb58a 100644
--- a/ext/filter/logical_filters.c
+++ b/ext/filter/logical_filters.c
@@ -532,6 +532,22 @@ void php_filter_validate_domain(PHP_INPUT_FILTER_PARAM_DECL) /* {{{ */
}
/* }}} */
+static int is_userinfo_valid(zend_string *str)
+{
+ const char *valid = "-._~!$&'()*+,;=:";
+ const char *p = ZSTR_VAL(str);
+ while (p - ZSTR_VAL(str) < ZSTR_LEN(str)) {
+ if (isalpha(*p) || isdigit(*p) || strchr(valid, *p)) {
+ p++;
+ } else if (*p == '%' && p - ZSTR_VAL(str) <= ZSTR_LEN(str) - 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;
@@ -592,6 +608,13 @@ void php_filter_validate_url(PHP_INPUT_FILTER_PARAM_DECL) /* {{{ */
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 be03fe95e24e..761c7c359a92 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 f564f59f0632..79ff3bc4a8e3 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 57014f08391a..7ffd001856c8 100644
--- a/ext/standard/tests/url/parse_url_basic_001.phpt
+++ b/ext/standard/tests/url/parse_url_basic_001.phpt
@@ -506,13 +506,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 e7cd24c9698c..8b0e7eb87500 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 8617d37059ec..a5ca381a691f 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/tests/url/parse_url_unterminated.phpt b/ext/standard/tests/url/parse_url_unterminated.phpt
index 1377cb7735f0..8f46eb3dbedf 100644
--- a/ext/standard/tests/url/parse_url_unterminated.phpt
+++ b/ext/standard/tests/url/parse_url_unterminated.phpt
@@ -508,13 +508,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/url.c b/ext/standard/url.c
index 157d61466e69..9743a00166b1 100644
--- a/ext/standard/url.c
+++ b/ext/standard/url.c
@@ -260,9 +260,6 @@ parse_host:
ret->pass = zend_string_init(pp, (p-pp), 0);
php_replace_controlchars_ex(ZSTR_VAL(ret->pass), ZSTR_LEN(ret->pass));
} else {
- if (!is_userinfo_valid(s, p-s)) {
- goto check_port;
- }
ret->user = zend_string_init(s, (p-s), 0);
php_replace_controlchars_ex(ZSTR_VAL(ret->user), ZSTR_LEN(ret->user));
}
@@ -271,7 +268,6 @@ parse_host:
s = p + 1;
}
-check_port:
/* check for port */
if (s < ue && *s == '[' && *(e-1) == ']') {
/* Short circuit portscan,

View File

@ -1,58 +0,0 @@
From a5538c62293fa782fcc382d0635cfc0c8b9190e3 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] 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.
---
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 1cf345dbb58a..3f314fefa0e1 100644
--- a/ext/filter/logical_filters.c
+++ b/ext/filter/logical_filters.c
@@ -609,7 +609,9 @@ void php_filter_validate_url(PHP_INPUT_FILTER_PARAM_DECL) /* {{{ */
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 000000000000..d89d4114a547
--- /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.27.0

View File

@ -1,36 +0,0 @@
From 9c673083cd46ee2a954a62156acbe4b6e657c048 Mon Sep 17 00:00:00 2001
From: Stanislav Malyshev <stas@php.net>
Date: Wed, 27 Jan 2021 00:13:43 -0800
Subject: [PATCH] Rm unneeded function
---
ext/standard/url.c | 16 ----------------
1 file changed, 16 deletions(-)
diff --git a/ext/standard/url.c b/ext/standard/url.c
index 9743a00166b1..0b3d97a76691 100644
--- a/ext/standard/url.c
+++ b/ext/standard/url.c
@@ -102,22 +102,6 @@ static const char *binary_strcspn(const char *s, const char *e
return e;
}
-static int is_userinfo_valid(const char *str, size_t len)
-{
- const char *valid = "-._~!$&'()*+,;=:";
- const 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)
{

View File

@ -1,28 +0,0 @@
From 7bab67c2d0d3c30b1176d5bcf6f20b0e1c50c589 Mon Sep 17 00:00:00 2001
From: Stanislav Malyshev <stas@php.net>
Date: Sun, 27 Jun 2021 21:57:58 -0700
Subject: [PATCH] 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 721da45d532d..1ffc467b43c1 100644
--- a/ext/filter/logical_filters.c
+++ b/ext/filter/logical_filters.c
@@ -632,8 +632,8 @@ void php_filter_validate_url(PHP_INPUT_FILTER_PARAM_DECL) /* {{{ */
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.27.0

View File

@ -1,71 +0,0 @@
From be8217368b85ab078905e17a732965053f3443d6 Mon Sep 17 00:00:00 2001
From: Nikita Popov <nikita.ppv@gmail.com>
Date: Thu, 23 Sep 2021 12:44:51 +0200
Subject: [PATCH] Bail on exception during delayed autoload
We shouldn't try to load further classes if one autoload throws.
This fixes oss-fuzz #38881, though I believe there are still two
deeper issues here: 1) Why do we allow autoloading with an active
exception? 2) Exception save & restore should probably also save
and restore the exception opline.
---
Zend/tests/exception_during_variance_autoload.phpt | 31 ++++++++++++++++++++++
Zend/zend_inheritance.c | 3 +++
2 files changed, 34 insertions(+)
create mode 100644 Zend/tests/exception_during_variance_autoload.phpt
diff --git a/Zend/tests/exception_during_variance_autoload.phpt b/Zend/tests/exception_during_variance_autoload.phpt
new file mode 100644
index 0000000..995931d
--- /dev/null
+++ b/Zend/tests/exception_during_variance_autoload.phpt
@@ -0,0 +1,31 @@
+--TEST--
+Exception during delayed variance autoload
+--FILE--
+<?php
+spl_autoload_register(function($class) {
+ echo "$class\n";
+ if ($class == 'X') {
+ new Y;
+ }
+ if ($class == 'Y') {
+ new Q;
+ }
+});
+class A {
+ function method(): X {}
+}
+class B extends A {
+ function method(): Y {}
+}
+?>
+--EXPECTF--
+Y
+Q
+
+Warning: Uncaught Error: Class "Q" not found in %s:%d
+Stack trace:
+#0 %s(%d): {closure}('Y')
+#1 {main}
+ thrown in %s on line %d
+
+Fatal error: Could not check compatibility between B::method(): Y and A::method(): X, because class Y is not available in %s on line %d
diff --git a/Zend/zend_inheritance.c b/Zend/zend_inheritance.c
index b00c5e5..33869d6 100644
--- a/Zend/zend_inheritance.c
+++ b/Zend/zend_inheritance.c
@@ -2348,6 +2348,9 @@ static void load_delayed_classes() {
ZEND_HASH_FOREACH_STR_KEY(delayed_autoloads, name) {
zend_lookup_class(name);
+ if (EG(exception)) {
+ break;
+ }
} ZEND_HASH_FOREACH_END();
zend_hash_destroy(delayed_autoloads);
--
1.8.3.1

View File

@ -1,197 +0,0 @@
From 5174de7cd33c3d4fa591c9c93859ff9989b07e8c 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] 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.
---
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 +-
.../tests/url/parse_url_unterminated.phpt | 6 ++--
ext/standard/url.c | 24 +++++++++++++--
7 files changed, 60 insertions(+), 16 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 caa93cb9cf01..dc13018b14a0 100644
--- a/ext/standard/tests/strings/url_t.phpt
+++ b/ext/standard/tests/strings/url_t.phpt
@@ -589,15 +589,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 000000000000..be03fe95e24e
--- /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 f3abd703b263..89b1b7b3d683 100644
--- a/ext/standard/tests/url/parse_url_basic_001.phpt
+++ b/ext/standard/tests/url/parse_url_basic_001.phpt
@@ -514,15 +514,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 1eb64d6a1b1c..da35b927821a 100644
--- a/ext/standard/tests/url/parse_url_basic_003.phpt
+++ b/ext/standard/tests/url/parse_url_basic_003.phpt
@@ -62,7 +62,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 dfbe7e7971e4..731a4adb3149 100644
--- a/ext/standard/tests/url/parse_url_basic_005.phpt
+++ b/ext/standard/tests/url/parse_url_basic_005.phpt
@@ -62,7 +62,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/tests/url/parse_url_unterminated.phpt b/ext/standard/tests/url/parse_url_unterminated.phpt
index 7c9150a513d9..f859fc7d407f 100644
--- a/ext/standard/tests/url/parse_url_unterminated.phpt
+++ b/ext/standard/tests/url/parse_url_unterminated.phpt
@@ -522,15 +522,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/url.c b/ext/standard/url.c
index a33091a86b75..113e0100243a 100644
--- a/ext/standard/url.c
+++ b/ext/standard/url.c
@@ -92,6 +92,22 @@ static const char *binary_strcspn(const char *s, const char *e, const char *char
return e;
}
+static int is_userinfo_valid(const char *str, size_t len)
+{
+ const char *valid = "-._~!$&'()*+,;=:";
+ const 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)
{
@@ -233,13 +249,17 @@ PHPAPI php_url *php_url_parse_ex2(char const *str, size_t length, zend_bool *has
ret->pass = zend_string_init(pp, (p-pp), 0);
php_replace_controlchars_ex(ZSTR_VAL(ret->pass), ZSTR_LEN(ret->pass));
} else {
- ret->user = zend_string_init(s, (p-s), 0);
- php_replace_controlchars_ex(ZSTR_VAL(ret->user), ZSTR_LEN(ret->user));
+ if (!is_userinfo_valid(s, p-s)) {
+ goto check_port;
+ }
+ ret->user = zend_string_init(s, (p-s), 0);
+ php_replace_controlchars_ex(ZSTR_VAL(ret->user), ZSTR_LEN(ret->user));
}
s = p + 1;
}
+check_port:
/* check for port */
if (s < ue && *s == '[' && *(e-1) == ']') {
/* Short circuit portscan,

View File

@ -1,396 +0,0 @@
From fadb1f8c1d08ae62b4f0a16917040fde57a3b93b Mon Sep 17 00:00:00 2001
From: Jakub Zelenka <bukka@php.net>
Date: Sat, 2 Oct 2021 22:53:41 +0100
Subject: [PATCH] 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>
---
sapi/fpm/fpm/fpm_children.c | 14 ++---
sapi/fpm/fpm/fpm_request.c | 4 +-
sapi/fpm/fpm/fpm_scoreboard.c | 106 ++++++++++++++++++++-------------
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(+), 60 deletions(-)
diff --git a/sapi/fpm/fpm/fpm_children.c b/sapi/fpm/fpm/fpm_children.c
index fe92bdf1b0c0..a24e06fc483b 100644
--- a/sapi/fpm/fpm/fpm_children.c
+++ b/sapi/fpm/fpm/fpm_children.c
@@ -246,7 +246,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);
@@ -256,9 +256,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 */);
@@ -324,7 +324,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;
@@ -336,7 +336,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);
}
@@ -349,10 +349,10 @@ static void fpm_child_resources_use(struct fpm_child_s *child) /* {{{ */
if (wp == child->wp || wp == child->wp->shared) {
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 c80aa144628f..0a6f6a7cfbf0 100644
--- a/sapi/fpm/fpm/fpm_request.c
+++ b/sapi/fpm/fpm/fpm_request.c
@@ -285,7 +285,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;
}
@@ -300,7 +300,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 fe36a9755bba..5380d184901b 100644
--- a/sapi/fpm/fpm/fpm_scoreboard.c
+++ b/sapi/fpm/fpm/fpm_scoreboard.c
@@ -6,6 +6,7 @@
#include <time.h>
#include "fpm_config.h"
+#include "fpm_children.h"
#include "fpm_scoreboard.h"
#include "fpm_shm.h"
#include "fpm_sockets.h"
@@ -23,7 +24,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))
@@ -40,7 +40,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) {
@@ -53,22 +53,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));
@@ -167,28 +160,48 @@ 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 || (unsigned int)child_index >= scoreboard->nprocs) {
- return NULL;
- }
+ return fpm_scoreboard_proc_get_ex(scoreboard, child_index, scoreboard->nprocs);
+}
+/* }}} */
- return scoreboard->procs[child_index];
+struct fpm_scoreboard_proc_s *fpm_scoreboard_proc_get_from_child(struct fpm_child_s *child) /* {{{*/
+{
+ struct fpm_worker_pool_s *wp = child->wp;
+ unsigned int nprocs = wp->config->pm_max_children;
+ struct fpm_scoreboard_s *scoreboard = wp->scoreboard;
+ int child_index = child->scoreboard_i;
+
+ return fpm_scoreboard_proc_get_ex(scoreboard, child_index, nprocs);
}
/* }}} */
+
struct fpm_scoreboard_s *fpm_scoreboard_acquire(struct fpm_scoreboard_s *scoreboard, int nohang) /* {{{ */
{
struct fpm_scoreboard_s *s;
@@ -239,28 +252,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;
+ scoreboard_procs_size = sizeof(struct fpm_scoreboard_proc_s) * wp->config->pm_max_children;
- fpm_shm_free(scoreboard, scoreboard_size + scoreboard_nprocs_size);
+ fpm_shm_free(scoreboard, sizeof(struct fpm_scoreboard_s) + scoreboard_procs_size);
}
/* }}} */
-void fpm_scoreboard_child_use(struct fpm_scoreboard_s *scoreboard, int child_index, pid_t pid) /* {{{ */
+void fpm_scoreboard_child_use(struct fpm_child_s *child, pid_t pid) /* {{{ */
{
struct fpm_scoreboard_proc_s *proc;
- fpm_scoreboard = scoreboard;
- fpm_scoreboard_i = child_index;
- proc = fpm_scoreboard_proc_get(scoreboard, child_index);
+ fpm_scoreboard = child->wp->scoreboard;
+ fpm_scoreboard_i = child->scoreboard_i;
+ proc = fpm_scoreboard_proc_get_from_child(child);
if (!proc) {
return;
}
@@ -269,18 +282,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 || (unsigned int)child_index >= scoreboard->nprocs) {
+ if (child_index < 0 || child_index >= wp->config->pm_max_children) {
return;
}
- if (scoreboard->procs[child_index] && scoreboard->procs[child_index]->used > 0) {
- memset(scoreboard->procs[child_index], 0, sizeof(struct fpm_scoreboard_proc_s));
+ if (scoreboard->procs[child_index].used > 0) {
+ memset(&scoreboard->procs[child_index], 0, sizeof(struct fpm_scoreboard_proc_s));
}
/* set this slot as free to avoid search on next alloc */
@@ -288,41 +305,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 && (unsigned int)scoreboard->free_proc < scoreboard->nprocs) {
- if (scoreboard->procs[scoreboard->free_proc] && !scoreboard->procs[scoreboard->free_proc]->used) {
+ if (scoreboard->free_proc >= 0 && scoreboard->free_proc < nprocs) {
+ if (!scoreboard->procs[scoreboard->free_proc].used) {
i = scoreboard->free_proc;
}
}
if (i < 0) { /* the supposed free slot is not, let's search for a free slot */
zlog(ZLOG_DEBUG, "[pool %s] the proc->free_slot was not free. Let's search", scoreboard->pool);
- for (i = 0; i < (int)scoreboard->nprocs; i++) {
- if (scoreboard->procs[i] && !scoreboard->procs[i]->used) { /* found */
+ for (i = 0; i < nprocs; i++) {
+ if (!scoreboard->procs[i].used) { /* found */
break;
}
}
}
/* no free slot */
- if (i < 0 || i >= (int)scoreboard->nprocs) {
+ if (i < 0 || i >= nprocs) {
zlog(ZLOG_ERROR, "[pool %s] no free scoreboard slot", scoreboard->pool);
return -1;
}
- scoreboard->procs[i]->used = 1;
- *child_index = i;
+ scoreboard->procs[i].used = 1;
+ child->scoreboard_i = i;
/* supposed next slot is free */
- if (i + 1 >= (int)scoreboard->nprocs) {
+ if (i + 1 >= nprocs) {
scoreboard->free_proc = 0;
} else {
scoreboard->free_proc = i + 1;
diff --git a/sapi/fpm/fpm/fpm_scoreboard.h b/sapi/fpm/fpm/fpm_scoreboard.h
index 060eddea982a..363bdd260547 100644
--- a/sapi/fpm/fpm/fpm_scoreboard.h
+++ b/sapi/fpm/fpm/fpm_scoreboard.h
@@ -64,7 +64,7 @@ struct fpm_scoreboard_s {
int free_proc;
unsigned long int slow_rq;
struct fpm_scoreboard_s *shared;
- struct fpm_scoreboard_proc_s *procs[];
+ struct fpm_scoreboard_proc_s procs[];
};
int fpm_scoreboard_init_main();
@@ -73,18 +73,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 ecce6e32c4a6..0d74f551b797 100644
--- a/sapi/fpm/fpm/fpm_status.c
+++ b/sapi/fpm/fpm/fpm_status.c
@@ -472,10 +472,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 d04528f4e0d0..65a9b226b1ae 100644
--- a/sapi/fpm/fpm/fpm_worker_pool.c
+++ b/sapi/fpm/fpm/fpm_worker_pool.c
@@ -54,7 +54,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);
}

View File

@ -1,68 +0,0 @@
From 08da7c73726f7b86b67d6f0ff87c73c585a7834a 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] 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.
---
ext/pdo_firebird/firebird_driver.c | 10 ++++++++++
ext/pdo_firebird/tests/bug_76449.phpt | 23 +++++++++++++++++++++++
2 files changed, 33 insertions(+)
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 c27a9e2e..303e0f47 100644
--- a/ext/pdo_firebird/firebird_driver.c
+++ b/ext/pdo_firebird/firebird_driver.c
@@ -626,8 +626,18 @@ 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);
}
diff --git a/ext/pdo_firebird/tests/bug_76449.phpt b/ext/pdo_firebird/tests/bug_76449.phpt
new file mode 100644
index 00000000..48a09c1d
--- /dev/null
+++ b/ext/pdo_firebird/tests/bug_76449.phpt
@@ -0,0 +1,23 @@
+--TEST--
+Bug #76449 (SIGSEGV in firebird_handle_doer)
+--SKIPIF--
+<?php
+if (!extension_loaded('pdo_firebird')) die("skip pdo_firebird extension not available");
+if (!extension_loaded('sockets')) die("skip sockets extension not available");
+?>
+--FILE--
+<?php
+require_once "payload_server.inc";
+
+$address = run_server(__DIR__ . "/bug_76449.data");
+
+// no need to change the credentials; we're running against a fake server
+$dsn = "firebird:dbname=inet://$address/test";
+$username = 'SYSDBA';
+$password = 'masterkey';
+
+$dbh = new PDO($dsn, $username, $password, [PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION]);
+var_dump($dbh->exec("INSERT INTO test VALUES ('hihi2', 'xxxxx')"));
+?>
+--EXPECT--
+bool(false)
--
2.27.0

View File

@ -1,54 +0,0 @@
From 82f1bf1b6bc3a43aba62214870e6d0931e93a6d9 Mon Sep 17 00:00:00 2001
From: "Christoph M. Becker" <cmbecker69@gmx.de>
Date: Mon, 31 Jan 2022 15:43:24 +0100
Subject: [PATCH] Fix #81708: UAF due to php_filter_float() failing for ints
We must only release the zval, if we actually assign a new zval.
---
ext/filter/logical_filters.c | 2 +-
ext/filter/tests/bug81708.phpt | 20 ++++++++++++++++++++
2 files changed, 21 insertions(+), 1 deletion(-)
create mode 100644 ext/filter/tests/bug81708.phpt
diff --git a/ext/filter/logical_filters.c b/ext/filter/logical_filters.c
index 1bf7c00d13c6..95f7a99e34b1 100644
--- a/ext/filter/logical_filters.c
+++ b/ext/filter/logical_filters.c
@@ -436,10 +436,10 @@ void php_filter_float(PHP_INPUT_FILTER_PARAM_DECL) /* {{{ */
switch (is_numeric_string(num, p - num, &lval, &dval, 0)) {
case IS_LONG:
- zval_ptr_dtor(value);
if ((min_range_set && (lval < min_range)) || (max_range_set && (lval > max_range))) {
goto error;
}
+ zval_ptr_dtor(value);
ZVAL_DOUBLE(value, (double)lval);
break;
case IS_DOUBLE:
diff --git a/ext/filter/tests/bug81708.phpt b/ext/filter/tests/bug81708.phpt
new file mode 100644
index 000000000000..d0036af13682
--- /dev/null
+++ b/ext/filter/tests/bug81708.phpt
@@ -0,0 +1,20 @@
+--TEST--
+Bug #81708 (UAF due to php_filter_float() failing for ints)
+--SKIPIF--
+<?php
+if (!extension_loaded("filter")) die("skip filter extension not available");
+?>
+--INI--
+opcache.enable_cli=0
+--FILE--
+<?php
+$input = "+" . str_repeat("1", 2); // avoid string interning
+filter_var(
+ $input,
+ FILTER_VALIDATE_FLOAT,
+ ["options" => ['min_range' => -1, 'max_range' => 1]]
+);
+var_dump($input);
+?>
+--EXPECT--
+string(3) "+11"

View File

@ -1,68 +0,0 @@
From 55f6895f4b4c677272fd4ee1113acdbd99c4b5ab 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] 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.
---
ext/pgsql/pgsql.c | 6 +++---
ext/pgsql/tests/bug81720.phpt | 27 +++++++++++++++++++++++++++
2 files changed, 30 insertions(+), 3 deletions(-)
create mode 100644 ext/pgsql/tests/bug81720.phpt
--- a/ext/pgsql/pgsql.c
+++ b/ext/pgsql/pgsql.c
@@ -1201,7 +1201,7 @@ PHP_FUNCTION(pg_query_params)
} else {
zend_string *param_str = zval_try_get_string(tmp);
if (!param_str) {
- _php_pgsql_free_params(params, num_params);
+ _php_pgsql_free_params(params, i);
RETURN_THROWS();
}
params[i] = estrndup(ZSTR_VAL(param_str), ZSTR_LEN(param_str));
@@ -3918,8 +3918,8 @@ PHP_FUNCTION(pg_send_execute)
params[i] = NULL;
} else {
zend_string *tmp_str = zval_try_get_string(tmp);
- if (UNEXPECTED(!tmp)) {
- _php_pgsql_free_params(params, num_params);
+ if (UNEXPECTED(!tmp_str)) {
+ _php_pgsql_free_params(params, i);
return;
}
params[i] = estrndup(ZSTR_VAL(tmp_str), ZSTR_LEN(tmp_str));
--- /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

View File

@ -1,21 +0,0 @@
From 58006537fc5f133ae8549efe5118cde418b3ace9 Mon Sep 17 00:00:00 2001
From: Stanislav Malyshev <smalyshev@gmail.com>
Date: Mon, 6 Jun 2022 00:56:51 -0600
Subject: [PATCH] Fix bug #81719: mysqlnd/pdo password buffer overflow
---
ext/mysqlnd/mysqlnd_wireprotocol.c | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)
--- a/ext/mysqlnd/mysqlnd_wireprotocol.c
+++ b/ext/mysqlnd/mysqlnd_wireprotocol.c
@@ -768,7 +768,8 @@ php_mysqlnd_change_auth_response_write(M
MYSQLND_VIO * vio = conn->vio;
MYSQLND_STATS * stats = conn->stats;
MYSQLND_CONNECTION_STATE * connection_state = &conn->state;
- zend_uchar * const buffer = pfc->cmd_buffer.length >= packet->auth_data_len? pfc->cmd_buffer.buffer : mnd_emalloc(packet->auth_data_len);
+ size_t total_packet_size = packet->auth_data_len + MYSQLND_HEADER_SIZE;
+ zend_uchar * const buffer = pfc->cmd_buffer.length >= total_packet_size? pfc->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");

View File

@ -1,710 +0,0 @@
From 6d5ae6496c6d1b7a563a0b189d868dd7089be395 Mon Sep 17 00:00:00 2001
From: Nikita Popov <nikita.ppv@gmail.com>
Date: Tue, 3 Aug 2021 10:19:23 +0200
Subject: [PATCH] Fix ASSIGN_DIM to NEXT with rc=1 reference value
The reference wrapper was destroyed while value still pointed into
it and was later used to assign the ASSIGN_DIM return value. This
could be fixed either by moving the return value assignment earlier,
or by working with the value that has been stored in the array.
I'm going with the latter here, because that matches what the
non-NEXT codepath does via assign_to_variable more closely.
Fixes oss-fuzz #36807.
---
Zend/tests/assign_dim_ref_free.phpt | 13 +++
Zend/zend_vm_def.h | 6 +-
Zend/zend_vm_execute.h | 192 ++++++++++++++++++------------------
3 files changed, 112 insertions(+), 99 deletions(-)
create mode 100644 Zend/tests/assign_dim_ref_free.phpt
diff --git a/Zend/tests/assign_dim_ref_free.phpt b/Zend/tests/assign_dim_ref_free.phpt
new file mode 100644
index 0000000..ecea75c
--- /dev/null
+++ b/Zend/tests/assign_dim_ref_free.phpt
@@ -0,0 +1,13 @@
+--TEST--
+Assigning rc=1 reference to next dim
+--FILE--
+<?php
+var_dump($ary[] = [&$x] = $x);
+var_dump($x);
+?>
+--EXPECT--
+array(1) {
+ [0]=>
+ &NULL
+}
+NULL
diff --git a/Zend/zend_vm_def.h b/Zend/zend_vm_def.h
index fa70e04..2b9fe5b 100644
--- a/Zend/zend_vm_def.h
+++ b/Zend/zend_vm_def.h
@@ -2527,8 +2527,8 @@ ZEND_VM_C_LABEL(try_assign_dim_array):
if (OP_DATA_TYPE == IS_CV || OP_DATA_TYPE == IS_VAR) {
ZVAL_DEREF(value);
}
- variable_ptr = zend_hash_next_index_insert(Z_ARRVAL_P(object_ptr), value);
- if (UNEXPECTED(variable_ptr == NULL)) {
+ value = zend_hash_next_index_insert(Z_ARRVAL_P(object_ptr), value);
+ if (UNEXPECTED(value == NULL)) {
zend_cannot_add_element();
ZEND_VM_C_GOTO(assign_dim_error);
} else if (OP_DATA_TYPE == IS_CV) {
@@ -2537,7 +2537,7 @@ ZEND_VM_C_LABEL(try_assign_dim_array):
}
} else if (OP_DATA_TYPE == IS_VAR) {
zval *free_op_data = EX_VAR((opline+1)->op1.var);
- if (value != free_op_data) {
+ if (Z_ISREF_P(free_op_data)) {
if (Z_REFCOUNTED_P(value)) {
Z_ADDREF_P(value);
}
diff --git a/Zend/zend_vm_execute.h b/Zend/zend_vm_execute.h
index 8e2cd21..a18ee13 100644
--- a/Zend/zend_vm_execute.h
+++ b/Zend/zend_vm_execute.h
@@ -23288,8 +23288,8 @@ try_assign_dim_array:
if (IS_CONST == IS_CV || IS_CONST == IS_VAR) {
ZVAL_DEREF(value);
}
- variable_ptr = zend_hash_next_index_insert(Z_ARRVAL_P(object_ptr), value);
- if (UNEXPECTED(variable_ptr == NULL)) {
+ value = zend_hash_next_index_insert(Z_ARRVAL_P(object_ptr), value);
+ if (UNEXPECTED(value == NULL)) {
zend_cannot_add_element();
goto assign_dim_error;
} else if (IS_CONST == IS_CV) {
@@ -23298,7 +23298,7 @@ try_assign_dim_array:
}
} else if (IS_CONST == IS_VAR) {
zval *free_op_data = EX_VAR((opline+1)->op1.var);
- if (value != free_op_data) {
+ if (Z_ISREF_P(free_op_data)) {
if (Z_REFCOUNTED_P(value)) {
Z_ADDREF_P(value);
}
@@ -23404,8 +23404,8 @@ try_assign_dim_array:
if (IS_TMP_VAR == IS_CV || IS_TMP_VAR == IS_VAR) {
ZVAL_DEREF(value);
}
- variable_ptr = zend_hash_next_index_insert(Z_ARRVAL_P(object_ptr), value);
- if (UNEXPECTED(variable_ptr == NULL)) {
+ value = zend_hash_next_index_insert(Z_ARRVAL_P(object_ptr), value);
+ if (UNEXPECTED(value == NULL)) {
zend_cannot_add_element();
goto assign_dim_error;
} else if (IS_TMP_VAR == IS_CV) {
@@ -23414,7 +23414,7 @@ try_assign_dim_array:
}
} else if (IS_TMP_VAR == IS_VAR) {
zval *free_op_data = EX_VAR((opline+1)->op1.var);
- if (value != free_op_data) {
+ if (Z_ISREF_P(free_op_data)) {
if (Z_REFCOUNTED_P(value)) {
Z_ADDREF_P(value);
}
@@ -23521,8 +23521,8 @@ try_assign_dim_array:
if (IS_VAR == IS_CV || IS_VAR == IS_VAR) {
ZVAL_DEREF(value);
}
- variable_ptr = zend_hash_next_index_insert(Z_ARRVAL_P(object_ptr), value);
- if (UNEXPECTED(variable_ptr == NULL)) {
+ value = zend_hash_next_index_insert(Z_ARRVAL_P(object_ptr), value);
+ if (UNEXPECTED(value == NULL)) {
zend_cannot_add_element();
goto assign_dim_error;
} else if (IS_VAR == IS_CV) {
@@ -23531,7 +23531,7 @@ try_assign_dim_array:
}
} else if (IS_VAR == IS_VAR) {
zval *free_op_data = EX_VAR((opline+1)->op1.var);
- if (value != free_op_data) {
+ if (Z_ISREF_P(free_op_data)) {
if (Z_REFCOUNTED_P(value)) {
Z_ADDREF_P(value);
}
@@ -23638,8 +23638,8 @@ try_assign_dim_array:
if (IS_CV == IS_CV || IS_CV == IS_VAR) {
ZVAL_DEREF(value);
}
- variable_ptr = zend_hash_next_index_insert(Z_ARRVAL_P(object_ptr), value);
- if (UNEXPECTED(variable_ptr == NULL)) {
+ value = zend_hash_next_index_insert(Z_ARRVAL_P(object_ptr), value);
+ if (UNEXPECTED(value == NULL)) {
zend_cannot_add_element();
goto assign_dim_error;
} else if (IS_CV == IS_CV) {
@@ -23648,7 +23648,7 @@ try_assign_dim_array:
}
} else if (IS_CV == IS_VAR) {
zval *free_op_data = EX_VAR((opline+1)->op1.var);
- if (value != free_op_data) {
+ if (Z_ISREF_P(free_op_data)) {
if (Z_REFCOUNTED_P(value)) {
Z_ADDREF_P(value);
}
@@ -25846,8 +25846,8 @@ try_assign_dim_array:
if (IS_CONST == IS_CV || IS_CONST == IS_VAR) {
ZVAL_DEREF(value);
}
- variable_ptr = zend_hash_next_index_insert(Z_ARRVAL_P(object_ptr), value);
- if (UNEXPECTED(variable_ptr == NULL)) {
+ value = zend_hash_next_index_insert(Z_ARRVAL_P(object_ptr), value);
+ if (UNEXPECTED(value == NULL)) {
zend_cannot_add_element();
goto assign_dim_error;
} else if (IS_CONST == IS_CV) {
@@ -25856,7 +25856,7 @@ try_assign_dim_array:
}
} else if (IS_CONST == IS_VAR) {
zval *free_op_data = EX_VAR((opline+1)->op1.var);
- if (value != free_op_data) {
+ if (Z_ISREF_P(free_op_data)) {
if (Z_REFCOUNTED_P(value)) {
Z_ADDREF_P(value);
}
@@ -25962,8 +25962,8 @@ try_assign_dim_array:
if (IS_TMP_VAR == IS_CV || IS_TMP_VAR == IS_VAR) {
ZVAL_DEREF(value);
}
- variable_ptr = zend_hash_next_index_insert(Z_ARRVAL_P(object_ptr), value);
- if (UNEXPECTED(variable_ptr == NULL)) {
+ value = zend_hash_next_index_insert(Z_ARRVAL_P(object_ptr), value);
+ if (UNEXPECTED(value == NULL)) {
zend_cannot_add_element();
goto assign_dim_error;
} else if (IS_TMP_VAR == IS_CV) {
@@ -25972,7 +25972,7 @@ try_assign_dim_array:
}
} else if (IS_TMP_VAR == IS_VAR) {
zval *free_op_data = EX_VAR((opline+1)->op1.var);
- if (value != free_op_data) {
+ if (Z_ISREF_P(free_op_data)) {
if (Z_REFCOUNTED_P(value)) {
Z_ADDREF_P(value);
}
@@ -26079,8 +26079,8 @@ try_assign_dim_array:
if (IS_VAR == IS_CV || IS_VAR == IS_VAR) {
ZVAL_DEREF(value);
}
- variable_ptr = zend_hash_next_index_insert(Z_ARRVAL_P(object_ptr), value);
- if (UNEXPECTED(variable_ptr == NULL)) {
+ value = zend_hash_next_index_insert(Z_ARRVAL_P(object_ptr), value);
+ if (UNEXPECTED(value == NULL)) {
zend_cannot_add_element();
goto assign_dim_error;
} else if (IS_VAR == IS_CV) {
@@ -26089,7 +26089,7 @@ try_assign_dim_array:
}
} else if (IS_VAR == IS_VAR) {
zval *free_op_data = EX_VAR((opline+1)->op1.var);
- if (value != free_op_data) {
+ if (Z_ISREF_P(free_op_data)) {
if (Z_REFCOUNTED_P(value)) {
Z_ADDREF_P(value);
}
@@ -26196,8 +26196,8 @@ try_assign_dim_array:
if (IS_CV == IS_CV || IS_CV == IS_VAR) {
ZVAL_DEREF(value);
}
- variable_ptr = zend_hash_next_index_insert(Z_ARRVAL_P(object_ptr), value);
- if (UNEXPECTED(variable_ptr == NULL)) {
+ value = zend_hash_next_index_insert(Z_ARRVAL_P(object_ptr), value);
+ if (UNEXPECTED(value == NULL)) {
zend_cannot_add_element();
goto assign_dim_error;
} else if (IS_CV == IS_CV) {
@@ -26206,7 +26206,7 @@ try_assign_dim_array:
}
} else if (IS_CV == IS_VAR) {
zval *free_op_data = EX_VAR((opline+1)->op1.var);
- if (value != free_op_data) {
+ if (Z_ISREF_P(free_op_data)) {
if (Z_REFCOUNTED_P(value)) {
Z_ADDREF_P(value);
}
@@ -27236,8 +27236,8 @@ try_assign_dim_array:
if (IS_CONST == IS_CV || IS_CONST == IS_VAR) {
ZVAL_DEREF(value);
}
- variable_ptr = zend_hash_next_index_insert(Z_ARRVAL_P(object_ptr), value);
- if (UNEXPECTED(variable_ptr == NULL)) {
+ value = zend_hash_next_index_insert(Z_ARRVAL_P(object_ptr), value);
+ if (UNEXPECTED(value == NULL)) {
zend_cannot_add_element();
goto assign_dim_error;
} else if (IS_CONST == IS_CV) {
@@ -27246,7 +27246,7 @@ try_assign_dim_array:
}
} else if (IS_CONST == IS_VAR) {
zval *free_op_data = EX_VAR((opline+1)->op1.var);
- if (value != free_op_data) {
+ if (Z_ISREF_P(free_op_data)) {
if (Z_REFCOUNTED_P(value)) {
Z_ADDREF_P(value);
}
@@ -27352,8 +27352,8 @@ try_assign_dim_array:
if (IS_TMP_VAR == IS_CV || IS_TMP_VAR == IS_VAR) {
ZVAL_DEREF(value);
}
- variable_ptr = zend_hash_next_index_insert(Z_ARRVAL_P(object_ptr), value);
- if (UNEXPECTED(variable_ptr == NULL)) {
+ value = zend_hash_next_index_insert(Z_ARRVAL_P(object_ptr), value);
+ if (UNEXPECTED(value == NULL)) {
zend_cannot_add_element();
goto assign_dim_error;
} else if (IS_TMP_VAR == IS_CV) {
@@ -27362,7 +27362,7 @@ try_assign_dim_array:
}
} else if (IS_TMP_VAR == IS_VAR) {
zval *free_op_data = EX_VAR((opline+1)->op1.var);
- if (value != free_op_data) {
+ if (Z_ISREF_P(free_op_data)) {
if (Z_REFCOUNTED_P(value)) {
Z_ADDREF_P(value);
}
@@ -27469,8 +27469,8 @@ try_assign_dim_array:
if (IS_VAR == IS_CV || IS_VAR == IS_VAR) {
ZVAL_DEREF(value);
}
- variable_ptr = zend_hash_next_index_insert(Z_ARRVAL_P(object_ptr), value);
- if (UNEXPECTED(variable_ptr == NULL)) {
+ value = zend_hash_next_index_insert(Z_ARRVAL_P(object_ptr), value);
+ if (UNEXPECTED(value == NULL)) {
zend_cannot_add_element();
goto assign_dim_error;
} else if (IS_VAR == IS_CV) {
@@ -27479,7 +27479,7 @@ try_assign_dim_array:
}
} else if (IS_VAR == IS_VAR) {
zval *free_op_data = EX_VAR((opline+1)->op1.var);
- if (value != free_op_data) {
+ if (Z_ISREF_P(free_op_data)) {
if (Z_REFCOUNTED_P(value)) {
Z_ADDREF_P(value);
}
@@ -27586,8 +27586,8 @@ try_assign_dim_array:
if (IS_CV == IS_CV || IS_CV == IS_VAR) {
ZVAL_DEREF(value);
}
- variable_ptr = zend_hash_next_index_insert(Z_ARRVAL_P(object_ptr), value);
- if (UNEXPECTED(variable_ptr == NULL)) {
+ value = zend_hash_next_index_insert(Z_ARRVAL_P(object_ptr), value);
+ if (UNEXPECTED(value == NULL)) {
zend_cannot_add_element();
goto assign_dim_error;
} else if (IS_CV == IS_CV) {
@@ -27596,7 +27596,7 @@ try_assign_dim_array:
}
} else if (IS_CV == IS_VAR) {
zval *free_op_data = EX_VAR((opline+1)->op1.var);
- if (value != free_op_data) {
+ if (Z_ISREF_P(free_op_data)) {
if (Z_REFCOUNTED_P(value)) {
Z_ADDREF_P(value);
}
@@ -29771,8 +29771,8 @@ try_assign_dim_array:
if (IS_CONST == IS_CV || IS_CONST == IS_VAR) {
ZVAL_DEREF(value);
}
- variable_ptr = zend_hash_next_index_insert(Z_ARRVAL_P(object_ptr), value);
- if (UNEXPECTED(variable_ptr == NULL)) {
+ value = zend_hash_next_index_insert(Z_ARRVAL_P(object_ptr), value);
+ if (UNEXPECTED(value == NULL)) {
zend_cannot_add_element();
goto assign_dim_error;
} else if (IS_CONST == IS_CV) {
@@ -29781,7 +29781,7 @@ try_assign_dim_array:
}
} else if (IS_CONST == IS_VAR) {
zval *free_op_data = EX_VAR((opline+1)->op1.var);
- if (value != free_op_data) {
+ if (Z_ISREF_P(free_op_data)) {
if (Z_REFCOUNTED_P(value)) {
Z_ADDREF_P(value);
}
@@ -29887,8 +29887,8 @@ try_assign_dim_array:
if (IS_TMP_VAR == IS_CV || IS_TMP_VAR == IS_VAR) {
ZVAL_DEREF(value);
}
- variable_ptr = zend_hash_next_index_insert(Z_ARRVAL_P(object_ptr), value);
- if (UNEXPECTED(variable_ptr == NULL)) {
+ value = zend_hash_next_index_insert(Z_ARRVAL_P(object_ptr), value);
+ if (UNEXPECTED(value == NULL)) {
zend_cannot_add_element();
goto assign_dim_error;
} else if (IS_TMP_VAR == IS_CV) {
@@ -29897,7 +29897,7 @@ try_assign_dim_array:
}
} else if (IS_TMP_VAR == IS_VAR) {
zval *free_op_data = EX_VAR((opline+1)->op1.var);
- if (value != free_op_data) {
+ if (Z_ISREF_P(free_op_data)) {
if (Z_REFCOUNTED_P(value)) {
Z_ADDREF_P(value);
}
@@ -30004,8 +30004,8 @@ try_assign_dim_array:
if (IS_VAR == IS_CV || IS_VAR == IS_VAR) {
ZVAL_DEREF(value);
}
- variable_ptr = zend_hash_next_index_insert(Z_ARRVAL_P(object_ptr), value);
- if (UNEXPECTED(variable_ptr == NULL)) {
+ value = zend_hash_next_index_insert(Z_ARRVAL_P(object_ptr), value);
+ if (UNEXPECTED(value == NULL)) {
zend_cannot_add_element();
goto assign_dim_error;
} else if (IS_VAR == IS_CV) {
@@ -30014,7 +30014,7 @@ try_assign_dim_array:
}
} else if (IS_VAR == IS_VAR) {
zval *free_op_data = EX_VAR((opline+1)->op1.var);
- if (value != free_op_data) {
+ if (Z_ISREF_P(free_op_data)) {
if (Z_REFCOUNTED_P(value)) {
Z_ADDREF_P(value);
}
@@ -30121,8 +30121,8 @@ try_assign_dim_array:
if (IS_CV == IS_CV || IS_CV == IS_VAR) {
ZVAL_DEREF(value);
}
- variable_ptr = zend_hash_next_index_insert(Z_ARRVAL_P(object_ptr), value);
- if (UNEXPECTED(variable_ptr == NULL)) {
+ value = zend_hash_next_index_insert(Z_ARRVAL_P(object_ptr), value);
+ if (UNEXPECTED(value == NULL)) {
zend_cannot_add_element();
goto assign_dim_error;
} else if (IS_CV == IS_CV) {
@@ -30131,7 +30131,7 @@ try_assign_dim_array:
}
} else if (IS_CV == IS_VAR) {
zval *free_op_data = EX_VAR((opline+1)->op1.var);
- if (value != free_op_data) {
+ if (Z_ISREF_P(free_op_data)) {
if (Z_REFCOUNTED_P(value)) {
Z_ADDREF_P(value);
}
@@ -40635,8 +40635,8 @@ try_assign_dim_array:
if (IS_CONST == IS_CV || IS_CONST == IS_VAR) {
ZVAL_DEREF(value);
}
- variable_ptr = zend_hash_next_index_insert(Z_ARRVAL_P(object_ptr), value);
- if (UNEXPECTED(variable_ptr == NULL)) {
+ value = zend_hash_next_index_insert(Z_ARRVAL_P(object_ptr), value);
+ if (UNEXPECTED(value == NULL)) {
zend_cannot_add_element();
goto assign_dim_error;
} else if (IS_CONST == IS_CV) {
@@ -40645,7 +40645,7 @@ try_assign_dim_array:
}
} else if (IS_CONST == IS_VAR) {
zval *free_op_data = EX_VAR((opline+1)->op1.var);
- if (value != free_op_data) {
+ if (Z_ISREF_P(free_op_data)) {
if (Z_REFCOUNTED_P(value)) {
Z_ADDREF_P(value);
}
@@ -40751,8 +40751,8 @@ try_assign_dim_array:
if (IS_TMP_VAR == IS_CV || IS_TMP_VAR == IS_VAR) {
ZVAL_DEREF(value);
}
- variable_ptr = zend_hash_next_index_insert(Z_ARRVAL_P(object_ptr), value);
- if (UNEXPECTED(variable_ptr == NULL)) {
+ value = zend_hash_next_index_insert(Z_ARRVAL_P(object_ptr), value);
+ if (UNEXPECTED(value == NULL)) {
zend_cannot_add_element();
goto assign_dim_error;
} else if (IS_TMP_VAR == IS_CV) {
@@ -40761,7 +40761,7 @@ try_assign_dim_array:
}
} else if (IS_TMP_VAR == IS_VAR) {
zval *free_op_data = EX_VAR((opline+1)->op1.var);
- if (value != free_op_data) {
+ if (Z_ISREF_P(free_op_data)) {
if (Z_REFCOUNTED_P(value)) {
Z_ADDREF_P(value);
}
@@ -40868,8 +40868,8 @@ try_assign_dim_array:
if (IS_VAR == IS_CV || IS_VAR == IS_VAR) {
ZVAL_DEREF(value);
}
- variable_ptr = zend_hash_next_index_insert(Z_ARRVAL_P(object_ptr), value);
- if (UNEXPECTED(variable_ptr == NULL)) {
+ value = zend_hash_next_index_insert(Z_ARRVAL_P(object_ptr), value);
+ if (UNEXPECTED(value == NULL)) {
zend_cannot_add_element();
goto assign_dim_error;
} else if (IS_VAR == IS_CV) {
@@ -40878,7 +40878,7 @@ try_assign_dim_array:
}
} else if (IS_VAR == IS_VAR) {
zval *free_op_data = EX_VAR((opline+1)->op1.var);
- if (value != free_op_data) {
+ if (Z_ISREF_P(free_op_data)) {
if (Z_REFCOUNTED_P(value)) {
Z_ADDREF_P(value);
}
@@ -40985,8 +40985,8 @@ try_assign_dim_array:
if (IS_CV == IS_CV || IS_CV == IS_VAR) {
ZVAL_DEREF(value);
}
- variable_ptr = zend_hash_next_index_insert(Z_ARRVAL_P(object_ptr), value);
- if (UNEXPECTED(variable_ptr == NULL)) {
+ value = zend_hash_next_index_insert(Z_ARRVAL_P(object_ptr), value);
+ if (UNEXPECTED(value == NULL)) {
zend_cannot_add_element();
goto assign_dim_error;
} else if (IS_CV == IS_CV) {
@@ -40995,7 +40995,7 @@ try_assign_dim_array:
}
} else if (IS_CV == IS_VAR) {
zval *free_op_data = EX_VAR((opline+1)->op1.var);
- if (value != free_op_data) {
+ if (Z_ISREF_P(free_op_data)) {
if (Z_REFCOUNTED_P(value)) {
Z_ADDREF_P(value);
}
@@ -44263,8 +44263,8 @@ try_assign_dim_array:
if (IS_CONST == IS_CV || IS_CONST == IS_VAR) {
ZVAL_DEREF(value);
}
- variable_ptr = zend_hash_next_index_insert(Z_ARRVAL_P(object_ptr), value);
- if (UNEXPECTED(variable_ptr == NULL)) {
+ value = zend_hash_next_index_insert(Z_ARRVAL_P(object_ptr), value);
+ if (UNEXPECTED(value == NULL)) {
zend_cannot_add_element();
goto assign_dim_error;
} else if (IS_CONST == IS_CV) {
@@ -44273,7 +44273,7 @@ try_assign_dim_array:
}
} else if (IS_CONST == IS_VAR) {
zval *free_op_data = EX_VAR((opline+1)->op1.var);
- if (value != free_op_data) {
+ if (Z_ISREF_P(free_op_data)) {
if (Z_REFCOUNTED_P(value)) {
Z_ADDREF_P(value);
}
@@ -44379,8 +44379,8 @@ try_assign_dim_array:
if (IS_TMP_VAR == IS_CV || IS_TMP_VAR == IS_VAR) {
ZVAL_DEREF(value);
}
- variable_ptr = zend_hash_next_index_insert(Z_ARRVAL_P(object_ptr), value);
- if (UNEXPECTED(variable_ptr == NULL)) {
+ value = zend_hash_next_index_insert(Z_ARRVAL_P(object_ptr), value);
+ if (UNEXPECTED(value == NULL)) {
zend_cannot_add_element();
goto assign_dim_error;
} else if (IS_TMP_VAR == IS_CV) {
@@ -44389,7 +44389,7 @@ try_assign_dim_array:
}
} else if (IS_TMP_VAR == IS_VAR) {
zval *free_op_data = EX_VAR((opline+1)->op1.var);
- if (value != free_op_data) {
+ if (Z_ISREF_P(free_op_data)) {
if (Z_REFCOUNTED_P(value)) {
Z_ADDREF_P(value);
}
@@ -44496,8 +44496,8 @@ try_assign_dim_array:
if (IS_VAR == IS_CV || IS_VAR == IS_VAR) {
ZVAL_DEREF(value);
}
- variable_ptr = zend_hash_next_index_insert(Z_ARRVAL_P(object_ptr), value);
- if (UNEXPECTED(variable_ptr == NULL)) {
+ value = zend_hash_next_index_insert(Z_ARRVAL_P(object_ptr), value);
+ if (UNEXPECTED(value == NULL)) {
zend_cannot_add_element();
goto assign_dim_error;
} else if (IS_VAR == IS_CV) {
@@ -44506,7 +44506,7 @@ try_assign_dim_array:
}
} else if (IS_VAR == IS_VAR) {
zval *free_op_data = EX_VAR((opline+1)->op1.var);
- if (value != free_op_data) {
+ if (Z_ISREF_P(free_op_data)) {
if (Z_REFCOUNTED_P(value)) {
Z_ADDREF_P(value);
}
@@ -44613,8 +44613,8 @@ try_assign_dim_array:
if (IS_CV == IS_CV || IS_CV == IS_VAR) {
ZVAL_DEREF(value);
}
- variable_ptr = zend_hash_next_index_insert(Z_ARRVAL_P(object_ptr), value);
- if (UNEXPECTED(variable_ptr == NULL)) {
+ value = zend_hash_next_index_insert(Z_ARRVAL_P(object_ptr), value);
+ if (UNEXPECTED(value == NULL)) {
zend_cannot_add_element();
goto assign_dim_error;
} else if (IS_CV == IS_CV) {
@@ -44623,7 +44623,7 @@ try_assign_dim_array:
}
} else if (IS_CV == IS_VAR) {
zval *free_op_data = EX_VAR((opline+1)->op1.var);
- if (value != free_op_data) {
+ if (Z_ISREF_P(free_op_data)) {
if (Z_REFCOUNTED_P(value)) {
Z_ADDREF_P(value);
}
@@ -46098,8 +46098,8 @@ try_assign_dim_array:
if (IS_CONST == IS_CV || IS_CONST == IS_VAR) {
ZVAL_DEREF(value);
}
- variable_ptr = zend_hash_next_index_insert(Z_ARRVAL_P(object_ptr), value);
- if (UNEXPECTED(variable_ptr == NULL)) {
+ value = zend_hash_next_index_insert(Z_ARRVAL_P(object_ptr), value);
+ if (UNEXPECTED(value == NULL)) {
zend_cannot_add_element();
goto assign_dim_error;
} else if (IS_CONST == IS_CV) {
@@ -46108,7 +46108,7 @@ try_assign_dim_array:
}
} else if (IS_CONST == IS_VAR) {
zval *free_op_data = EX_VAR((opline+1)->op1.var);
- if (value != free_op_data) {
+ if (Z_ISREF_P(free_op_data)) {
if (Z_REFCOUNTED_P(value)) {
Z_ADDREF_P(value);
}
@@ -46214,8 +46214,8 @@ try_assign_dim_array:
if (IS_TMP_VAR == IS_CV || IS_TMP_VAR == IS_VAR) {
ZVAL_DEREF(value);
}
- variable_ptr = zend_hash_next_index_insert(Z_ARRVAL_P(object_ptr), value);
- if (UNEXPECTED(variable_ptr == NULL)) {
+ value = zend_hash_next_index_insert(Z_ARRVAL_P(object_ptr), value);
+ if (UNEXPECTED(value == NULL)) {
zend_cannot_add_element();
goto assign_dim_error;
} else if (IS_TMP_VAR == IS_CV) {
@@ -46224,7 +46224,7 @@ try_assign_dim_array:
}
} else if (IS_TMP_VAR == IS_VAR) {
zval *free_op_data = EX_VAR((opline+1)->op1.var);
- if (value != free_op_data) {
+ if (Z_ISREF_P(free_op_data)) {
if (Z_REFCOUNTED_P(value)) {
Z_ADDREF_P(value);
}
@@ -46331,8 +46331,8 @@ try_assign_dim_array:
if (IS_VAR == IS_CV || IS_VAR == IS_VAR) {
ZVAL_DEREF(value);
}
- variable_ptr = zend_hash_next_index_insert(Z_ARRVAL_P(object_ptr), value);
- if (UNEXPECTED(variable_ptr == NULL)) {
+ value = zend_hash_next_index_insert(Z_ARRVAL_P(object_ptr), value);
+ if (UNEXPECTED(value == NULL)) {
zend_cannot_add_element();
goto assign_dim_error;
} else if (IS_VAR == IS_CV) {
@@ -46341,7 +46341,7 @@ try_assign_dim_array:
}
} else if (IS_VAR == IS_VAR) {
zval *free_op_data = EX_VAR((opline+1)->op1.var);
- if (value != free_op_data) {
+ if (Z_ISREF_P(free_op_data)) {
if (Z_REFCOUNTED_P(value)) {
Z_ADDREF_P(value);
}
@@ -46448,8 +46448,8 @@ try_assign_dim_array:
if (IS_CV == IS_CV || IS_CV == IS_VAR) {
ZVAL_DEREF(value);
}
- variable_ptr = zend_hash_next_index_insert(Z_ARRVAL_P(object_ptr), value);
- if (UNEXPECTED(variable_ptr == NULL)) {
+ value = zend_hash_next_index_insert(Z_ARRVAL_P(object_ptr), value);
+ if (UNEXPECTED(value == NULL)) {
zend_cannot_add_element();
goto assign_dim_error;
} else if (IS_CV == IS_CV) {
@@ -46458,7 +46458,7 @@ try_assign_dim_array:
}
} else if (IS_CV == IS_VAR) {
zval *free_op_data = EX_VAR((opline+1)->op1.var);
- if (value != free_op_data) {
+ if (Z_ISREF_P(free_op_data)) {
if (Z_REFCOUNTED_P(value)) {
Z_ADDREF_P(value);
}
@@ -49291,8 +49291,8 @@ try_assign_dim_array:
if (IS_CONST == IS_CV || IS_CONST == IS_VAR) {
ZVAL_DEREF(value);
}
- variable_ptr = zend_hash_next_index_insert(Z_ARRVAL_P(object_ptr), value);
- if (UNEXPECTED(variable_ptr == NULL)) {
+ value = zend_hash_next_index_insert(Z_ARRVAL_P(object_ptr), value);
+ if (UNEXPECTED(value == NULL)) {
zend_cannot_add_element();
goto assign_dim_error;
} else if (IS_CONST == IS_CV) {
@@ -49301,7 +49301,7 @@ try_assign_dim_array:
}
} else if (IS_CONST == IS_VAR) {
zval *free_op_data = EX_VAR((opline+1)->op1.var);
- if (value != free_op_data) {
+ if (Z_ISREF_P(free_op_data)) {
if (Z_REFCOUNTED_P(value)) {
Z_ADDREF_P(value);
}
@@ -49407,8 +49407,8 @@ try_assign_dim_array:
if (IS_TMP_VAR == IS_CV || IS_TMP_VAR == IS_VAR) {
ZVAL_DEREF(value);
}
- variable_ptr = zend_hash_next_index_insert(Z_ARRVAL_P(object_ptr), value);
- if (UNEXPECTED(variable_ptr == NULL)) {
+ value = zend_hash_next_index_insert(Z_ARRVAL_P(object_ptr), value);
+ if (UNEXPECTED(value == NULL)) {
zend_cannot_add_element();
goto assign_dim_error;
} else if (IS_TMP_VAR == IS_CV) {
@@ -49417,7 +49417,7 @@ try_assign_dim_array:
}
} else if (IS_TMP_VAR == IS_VAR) {
zval *free_op_data = EX_VAR((opline+1)->op1.var);
- if (value != free_op_data) {
+ if (Z_ISREF_P(free_op_data)) {
if (Z_REFCOUNTED_P(value)) {
Z_ADDREF_P(value);
}
@@ -49524,8 +49524,8 @@ try_assign_dim_array:
if (IS_VAR == IS_CV || IS_VAR == IS_VAR) {
ZVAL_DEREF(value);
}
- variable_ptr = zend_hash_next_index_insert(Z_ARRVAL_P(object_ptr), value);
- if (UNEXPECTED(variable_ptr == NULL)) {
+ value = zend_hash_next_index_insert(Z_ARRVAL_P(object_ptr), value);
+ if (UNEXPECTED(value == NULL)) {
zend_cannot_add_element();
goto assign_dim_error;
} else if (IS_VAR == IS_CV) {
@@ -49534,7 +49534,7 @@ try_assign_dim_array:
}
} else if (IS_VAR == IS_VAR) {
zval *free_op_data = EX_VAR((opline+1)->op1.var);
- if (value != free_op_data) {
+ if (Z_ISREF_P(free_op_data)) {
if (Z_REFCOUNTED_P(value)) {
Z_ADDREF_P(value);
}
@@ -49641,8 +49641,8 @@ try_assign_dim_array:
if (IS_CV == IS_CV || IS_CV == IS_VAR) {
ZVAL_DEREF(value);
}
- variable_ptr = zend_hash_next_index_insert(Z_ARRVAL_P(object_ptr), value);
- if (UNEXPECTED(variable_ptr == NULL)) {
+ value = zend_hash_next_index_insert(Z_ARRVAL_P(object_ptr), value);
+ if (UNEXPECTED(value == NULL)) {
zend_cannot_add_element();
goto assign_dim_error;
} else if (IS_CV == IS_CV) {
@@ -49651,7 +49651,7 @@ try_assign_dim_array:
}
} else if (IS_CV == IS_VAR) {
zval *free_op_data = EX_VAR((opline+1)->op1.var);
- if (value != free_op_data) {
+ if (Z_ISREF_P(free_op_data)) {
if (Z_REFCOUNTED_P(value)) {
Z_ADDREF_P(value);
}
--
1.8.3.1

View File

@ -1,46 +0,0 @@
From f40c8fdf672923fd585023574e954b79b85b8777 Mon Sep 17 00:00:00 2001
From: Nikita Popov <nikita.ppv@gmail.com>
Date: Thu, 15 Apr 2021 12:32:05 +0200
Subject: [PATCH] Fix return-by-ref from array_reduce callback
Fixes oss-fuzz #32990.
---
ext/standard/array.c | 3 +++
ext/standard/tests/array/array_reduce_return_by_ref.phpt | 11 +++++++++++
2 files changed, 14 insertions(+)
create mode 100644 ext/standard/tests/array/array_reduce_return_by_ref.phpt
diff --git a/ext/standard/array.c b/ext/standard/array.c
index 3967d83..4556cfe 100644
--- a/ext/standard/array.c
+++ b/ext/standard/array.c
@@ -5877,6 +5877,9 @@ PHP_FUNCTION(array_reduce)
zval_ptr_dtor(&args[1]);
zval_ptr_dtor(&args[0]);
ZVAL_COPY_VALUE(return_value, &retval);
+ if (UNEXPECTED(Z_ISREF_P(return_value))) {
+ zend_unwrap_reference(return_value);
+ }
} else {
zval_ptr_dtor(&args[1]);
zval_ptr_dtor(&args[0]);
diff --git a/ext/standard/tests/array/array_reduce_return_by_ref.phpt b/ext/standard/tests/array/array_reduce_return_by_ref.phpt
new file mode 100644
index 0000000..8da7018
--- /dev/null
+++ b/ext/standard/tests/array/array_reduce_return_by_ref.phpt
@@ -0,0 +1,11 @@
+--TEST--
+Return by reference from array_reduce() callback
+--FILE--
+<?php
+$array = [1, 2];
+var_dump(array_reduce($array, function &($a, $b) {
+ return $b;
+}, 0));
+?>
+--EXPECT--
+int(2)
--
1.8.3.1

View File

@ -1,53 +0,0 @@
From 46f9fed0d8e4ca5264abd2da94105925024ede14 Mon Sep 17 00:00:00 2001
From: Nikita Popov <nikita.ppv@gmail.com>
Date: Thu, 15 Apr 2021 13:04:47 +0200
Subject: [PATCH] Handle ref return from Iterator::key()
Handle this in the implementation of get_current_key of user_it,
so that the callers may assume that the key is not a reference.
Fixes oss-fuzz #33018.
---
Zend/tests/iterator_key_by_ref.phpt | 15 +++++++++++++++
Zend/zend_interfaces.c | 3 +++
2 files changed, 18 insertions(+)
create mode 100644 Zend/tests/iterator_key_by_ref.phpt
diff --git a/Zend/tests/iterator_key_by_ref.phpt b/Zend/tests/iterator_key_by_ref.phpt
new file mode 100644
index 0000000..3bd2bcf
--- /dev/null
+++ b/Zend/tests/iterator_key_by_ref.phpt
@@ -0,0 +1,15 @@
+--TEST--
+Iterator::key() with by-ref return
+--FILE--
+<?php
+class Test extends ArrayIterator {
+ function &key() {
+ return $foo;
+ }
+}
+foreach (new Test([0]) as $k => $v) {
+ var_dump($k);
+}
+?>
+--EXPECT--
+NULL
diff --git a/Zend/zend_interfaces.c b/Zend/zend_interfaces.c
index 0d5af66..51b7717 100644
--- a/Zend/zend_interfaces.c
+++ b/Zend/zend_interfaces.c
@@ -154,6 +154,9 @@ ZEND_API void zend_user_it_get_current_key(zend_object_iterator *_iter, zval *ke
zend_user_iterator *iter = (zend_user_iterator*)_iter;
zval *object = &iter->it.data;
zend_call_method_with_0_params(Z_OBJ_P(object), iter->ce, &iter->ce->iterator_funcs_ptr->zf_key, "key", key);
+ if (UNEXPECTED(Z_ISREF_P(key))) {
+ zend_unwrap_reference(key);
+ }
}
/* }}} */
--
1.8.3.1

View File

@ -1,88 +0,0 @@
From ec54ffad1e3b15fedfd07f7d29d97ec3e8d1c45a Mon Sep 17 00:00:00 2001
From: Nikita Popov <nikita.ppv@gmail.com>
Date: Wed, 29 Sep 2021 10:14:33 +0200
Subject: [PATCH] Handle throwing destructor in BIND_STATIC
Fixes oss-fuzz #39406.
---
Zend/tests/bind_static_exception.phpt | 18 ++++++++++++++++++
Zend/zend_vm_def.h | 4 ++--
Zend/zend_vm_execute.h | 4 ++--
3 files changed, 22 insertions(+), 4 deletions(-)
create mode 100644 Zend/tests/bind_static_exception.phpt
diff --git a/Zend/tests/bind_static_exception.phpt b/Zend/tests/bind_static_exception.phpt
new file mode 100644
index 0000000..c374130
--- /dev/null
+++ b/Zend/tests/bind_static_exception.phpt
@@ -0,0 +1,18 @@
+--TEST--
+BIND_STATIC may destroy a variable with a throwing destructor
+--FILE--
+<?php
+class Test {
+ function __destruct() {
+ throw new Exception("Foo");
+ }
+}
+try {
+ $new = new Test;
+ static $new;
+} catch (Exception $e) {
+ echo $e->getMessage(), "\n";
+}
+?>
+--EXPECT--
+Foo
diff --git a/Zend/zend_vm_def.h b/Zend/zend_vm_def.h
index 3262ddb..f324d80 100644
--- a/Zend/zend_vm_def.h
+++ b/Zend/zend_vm_def.h
@@ -8652,9 +8652,9 @@ ZEND_VM_HANDLER(183, ZEND_BIND_STATIC, CV, UNUSED, REF)
value = (zval*)((char*)ht->arData + (opline->extended_value & ~(ZEND_BIND_REF|ZEND_BIND_IMPLICIT)));
+ SAVE_OPLINE();
if (opline->extended_value & ZEND_BIND_REF) {
if (Z_TYPE_P(value) == IS_CONSTANT_AST) {
- SAVE_OPLINE();
if (UNEXPECTED(zval_update_constant_ex(value, EX(func)->op_array.scope) != SUCCESS)) {
HANDLE_EXCEPTION();
}
@@ -8679,7 +8679,7 @@ ZEND_VM_HANDLER(183, ZEND_BIND_STATIC, CV, UNUSED, REF)
ZVAL_COPY(variable_ptr, value);
}
- ZEND_VM_NEXT_OPCODE();
+ ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
}
ZEND_VM_HOT_HANDLER(184, ZEND_FETCH_THIS, UNUSED, UNUSED)
diff --git a/Zend/zend_vm_execute.h b/Zend/zend_vm_execute.h
index 987406a..a4a268d 100644
--- a/Zend/zend_vm_execute.h
+++ b/Zend/zend_vm_execute.h
@@ -46983,9 +46983,9 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_BIND_STATIC_SPEC_CV_UNUSED_HAN
value = (zval*)((char*)ht->arData + (opline->extended_value & ~(ZEND_BIND_REF|ZEND_BIND_IMPLICIT)));
+ SAVE_OPLINE();
if (opline->extended_value & ZEND_BIND_REF) {
if (Z_TYPE_P(value) == IS_CONSTANT_AST) {
- SAVE_OPLINE();
if (UNEXPECTED(zval_update_constant_ex(value, EX(func)->op_array.scope) != SUCCESS)) {
HANDLE_EXCEPTION();
}
@@ -47010,7 +47010,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_BIND_STATIC_SPEC_CV_UNUSED_HAN
ZVAL_COPY(variable_ptr, value);
}
- ZEND_VM_NEXT_OPCODE();
+ ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
}
static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_CHECK_VAR_SPEC_CV_UNUSED_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
--
1.8.3.1

View File

@ -1,105 +0,0 @@
From ebd3a210021ec3b8f210822f0c69ee8f3132f1dc Mon Sep 17 00:00:00 2001
From: Nikita Popov <nikita.ppv@gmail.com>
Date: Thu, 15 Jul 2021 09:29:08 +0200
Subject: [PATCH] Undef slot before destroying in unset_property
We need to make sure that destructors can't access the partially
destroyed property. Do the same we do in HTs.
Fixes oss-fuzz #36205.
---
Zend/tests/unset_prop_recursion.phpt | 65 ++++++++++++++++++++++++++++++++++++
Zend/zend_object_handlers.c | 4 ++-
2 files changed, 68 insertions(+), 1 deletion(-)
create mode 100644 Zend/tests/unset_prop_recursion.phpt
diff --git a/Zend/tests/unset_prop_recursion.phpt b/Zend/tests/unset_prop_recursion.phpt
new file mode 100644
index 0000000..afb1929
--- /dev/null
+++ b/Zend/tests/unset_prop_recursion.phpt
@@ -0,0 +1,65 @@
+--TEST--
+Unset property where unset will recursively access property again
+--FILE--
+<?php
+class Node {
+ public $parent = null;
+ public $children = [];
+ function insert(Node $node) {
+ $node->parent = $this;
+ $this->children[] = $node;
+ }
+ function __destruct() {
+ var_dump($this);
+ unset($this->children);
+ }
+}
+
+$a = new Node;
+$a->insert(new Node);
+$a->insert(new Node);
+?>
+--EXPECT--
+object(Node)#1 (2) {
+ ["parent"]=>
+ NULL
+ ["children"]=>
+ array(2) {
+ [0]=>
+ object(Node)#2 (2) {
+ ["parent"]=>
+ *RECURSION*
+ ["children"]=>
+ array(0) {
+ }
+ }
+ [1]=>
+ object(Node)#3 (2) {
+ ["parent"]=>
+ *RECURSION*
+ ["children"]=>
+ array(0) {
+ }
+ }
+ }
+}
+object(Node)#2 (2) {
+ ["parent"]=>
+ object(Node)#1 (2) {
+ ["parent"]=>
+ NULL
+ }
+ ["children"]=>
+ array(0) {
+ }
+}
+object(Node)#3 (2) {
+ ["parent"]=>
+ object(Node)#1 (2) {
+ ["parent"]=>
+ NULL
+ }
+ ["children"]=>
+ array(0) {
+ }
+}
diff --git a/Zend/zend_object_handlers.c b/Zend/zend_object_handlers.c
index 7c2bd13..e61a5af 100644
--- a/Zend/zend_object_handlers.c
+++ b/Zend/zend_object_handlers.c
@@ -1137,8 +1137,10 @@ ZEND_API void zend_std_unset_property(zval *object, zval *member, void **cache_s
ZEND_REF_DEL_TYPE_SOURCE(Z_REF_P(slot), prop_info);
}
}
- zval_ptr_dtor(slot);
+ zval tmp;
+ ZVAL_COPY_VALUE(&tmp, slot);
ZVAL_UNDEF(slot);
+ zval_ptr_dtor(&tmp);
if (zobj->properties) {
HT_FLAGS(zobj->properties) |= HASH_FLAG_HAS_EMPTY_IND;
}
--
1.8.3.1

View File

@ -5,6 +5,8 @@ Add support for use of the system timezone database, rather
than embedding a copy. Discussed upstream but was not desired.
History:
r21: retrieve tzdata version from /usr/share/zoneinfo/tzdata.zi
r20: adapt for timelib 2020.03 (in 8.0.10RC1)
r19: adapt for timelib 2020.02 (in 8.0.0beta2)
r18: adapt for autotool change in 7.3.3RC1
r17: adapt for timelib 2018.01 (in 7.3.2RC1)
@ -30,9 +32,10 @@ r3: fix a crash if /usr/share/zoneinfo doesn't exist (Raphael Geissert)
r2: add filesystem trawl to set up name alias index
r1: initial revision
diff -up php-8.0.0beta3/ext/date/config0.m4.systzdata php-8.0.0beta3/ext/date/config0.m4
--- php-8.0.0beta3/ext/date/config0.m4.systzdata 2020-09-01 19:13:26.000000000 +0200
+++ php-8.0.0beta3/ext/date/config0.m4 2020-09-02 08:07:51.039979873 +0200
diff --git a/ext/date/config0.m4 b/ext/date/config0.m4
index 20e4164aaa..a61243646d 100644
--- a/ext/date/config0.m4
+++ b/ext/date/config0.m4
@@ -4,6 +4,19 @@ AC_CHECK_HEADERS([io.h])
dnl Check for strtoll, atoll
AC_CHECK_FUNCS(strtoll atoll)
@ -53,9 +56,10 @@ diff -up php-8.0.0beta3/ext/date/config0.m4.systzdata php-8.0.0beta3/ext/date/co
PHP_DATE_CFLAGS="-I@ext_builddir@/lib -DZEND_ENABLE_STATIC_TSRMLS_CACHE=1 -DHAVE_TIMELIB_CONFIG_H=1"
timelib_sources="lib/astro.c lib/dow.c lib/parse_date.c lib/parse_tz.c
lib/timelib.c lib/tm2unixtime.c lib/unixtime2tm.c lib/parse_iso_intervals.c lib/interval.c"
diff -up php-8.0.0beta3/ext/date/lib/parse_tz.c.systzdata php-8.0.0beta3/ext/date/lib/parse_tz.c
--- php-8.0.0beta3/ext/date/lib/parse_tz.c.systzdata 2020-09-01 19:13:26.000000000 +0200
+++ php-8.0.0beta3/ext/date/lib/parse_tz.c 2020-09-02 08:07:51.039979873 +0200
diff --git a/ext/date/lib/parse_tz.c b/ext/date/lib/parse_tz.c
index e9bd0f136d..c04ff01adc 100644
--- a/ext/date/lib/parse_tz.c
+++ b/ext/date/lib/parse_tz.c
@@ -26,8 +26,21 @@
#include "timelib.h"
#include "timelib_private.h"
@ -78,7 +82,7 @@ diff -up php-8.0.0beta3/ext/date/lib/parse_tz.c.systzdata php-8.0.0beta3/ext/dat
#if (defined(__APPLE__) || defined(__APPLE_CC__)) && (defined(__BIG_ENDIAN__) || defined(__LITTLE_ENDIAN__))
# if defined(__LITTLE_ENDIAN__)
@@ -94,6 +107,11 @@ static int read_php_preamble(const unsig
@@ -94,6 +107,11 @@ static int read_php_preamble(const unsigned char **tzf, timelib_tzinfo *tz)
{
uint32_t version;
@ -90,7 +94,7 @@ diff -up php-8.0.0beta3/ext/date/lib/parse_tz.c.systzdata php-8.0.0beta3/ext/dat
/* read ID */
version = (*tzf)[3] - '0';
*tzf += 4;
@@ -418,7 +436,429 @@ void timelib_dump_tzinfo(timelib_tzinfo
@@ -435,7 +453,467 @@ void timelib_dump_tzinfo(timelib_tzinfo *tz)
}
}
@ -321,6 +325,44 @@ diff -up php-8.0.0beta3/ext/date/lib/parse_tz.c.systzdata php-8.0.0beta3/ext/dat
+}
+
+
+/* Retrieve tzdata version. */
+static void retrieve_zone_version(timelib_tzdb *db)
+{
+ static char buf[30];
+ char path[PATH_MAX];
+ FILE *fp;
+
+ strncpy(path, ZONEINFO_PREFIX "/tzdata.zi", sizeof(path));
+
+ fp = fopen(path, "r");
+ if (fp) {
+ if (fgets(buf, sizeof(buf), fp)) {
+ if (!memcmp(buf, "# version ", 10) &&
+ isdigit(buf[10]) &&
+ isdigit(buf[11]) &&
+ isdigit(buf[12]) &&
+ isdigit(buf[13]) &&
+ islower(buf[14])) {
+ if (buf[14] >= 't') { /* 2022t = 2022.20 */
+ buf[17] = 0;
+ buf[16] = buf[14] - 't' + '0';
+ buf[15] = '2';
+ } else if (buf[14] >= 'j') { /* 2022j = 2022.10 */
+ buf[17] = 0;
+ buf[16] = buf[14] - 'j' + '0';
+ buf[15] = '1';
+ } else { /* 2022a = 2022.1 */
+ buf[16] = 0;
+ buf[15] = buf[14] - 'a' + '1';
+ }
+ buf[14] = '.';
+ db->version = buf+10;
+ }
+ }
+ fclose(fp);
+ }
+}
+
+/* Create the zone identifier index by trawling the filesystem. */
+static void create_zone_index(timelib_tzdb *db)
+{
@ -521,7 +563,7 @@ diff -up php-8.0.0beta3/ext/date/lib/parse_tz.c.systzdata php-8.0.0beta3/ext/dat
{
int left = 0, right = tzdb->index_size - 1;
@@ -444,9 +884,48 @@ static int seek_to_tz_position(const uns
@@ -461,9 +939,49 @@ static int seek_to_tz_position(const unsigned char **tzf, const char *timezone,
return 0;
}
@ -558,6 +600,7 @@ diff -up php-8.0.0beta3/ext/date/lib/parse_tz.c.systzdata php-8.0.0beta3/ext/dat
+ tmp->version = "0.system";
+ tmp->data = NULL;
+ create_zone_index(tmp);
+ retrieve_zone_version(tmp);
+ system_location_table = create_location_table();
+ fake_data_segment(tmp, system_location_table);
+ timezonedb_system = tmp;
@ -570,7 +613,7 @@ diff -up php-8.0.0beta3/ext/date/lib/parse_tz.c.systzdata php-8.0.0beta3/ext/dat
}
const timelib_tzdb_index_entry *timelib_timezone_identifiers_list(const timelib_tzdb *tzdb, int *count)
@@ -458,7 +937,30 @@ const timelib_tzdb_index_entry *timelib_
@@ -475,7 +993,30 @@ const timelib_tzdb_index_entry *timelib_timezone_identifiers_list(const timelib_
int timelib_timezone_id_is_valid(const char *timezone, const timelib_tzdb *tzdb)
{
const unsigned char *tzf;
@ -602,7 +645,7 @@ diff -up php-8.0.0beta3/ext/date/lib/parse_tz.c.systzdata php-8.0.0beta3/ext/dat
}
static int skip_64bit_preamble(const unsigned char **tzf, timelib_tzinfo *tz)
@@ -500,12 +1002,14 @@ static timelib_tzinfo* timelib_tzinfo_ct
@@ -517,6 +1058,8 @@ static timelib_tzinfo* timelib_tzinfo_ctor(const char *name)
timelib_tzinfo *timelib_parse_tzfile(const char *timezone, const timelib_tzdb *tzdb, int *error_code)
{
const unsigned char *tzf;
@ -611,14 +654,16 @@ diff -up php-8.0.0beta3/ext/date/lib/parse_tz.c.systzdata php-8.0.0beta3/ext/dat
timelib_tzinfo *tmp;
int version;
int transitions_result, types_result;
unsigned int type; /* TIMELIB_TZINFO_PHP or TIMELIB_TZINFO_ZONEINFO */
@@ -524,7 +1067,7 @@ timelib_tzinfo *timelib_parse_tzfile(const char *timezone, const timelib_tzdb *t
*error_code = TIMELIB_ERROR_NO_ERROR;
- if (seek_to_tz_position(&tzf, timezone, tzdb)) {
+ if (seek_to_tz_position(&tzf, timezone, &memmap, &maplen, tzdb)) {
tmp = timelib_tzinfo_ctor(timezone);
version = read_preamble(&tzf, tmp, &type);
@@ -540,11 +1044,36 @@ timelib_tzinfo *timelib_parse_tzfile(con
@@ -563,11 +1106,36 @@ timelib_tzinfo *timelib_parse_tzfile(const char *timezone, const timelib_tzdb *t
}
skip_posix_string(&tzf, tmp);
@ -655,3 +700,19 @@ diff -up php-8.0.0beta3/ext/date/lib/parse_tz.c.systzdata php-8.0.0beta3/ext/dat
} else {
*error_code = TIMELIB_ERROR_NO_SUCH_TIMEZONE;
tmp = NULL;
diff --git a/ext/date/php_date.c b/ext/date/php_date.c
index 2d5cffb963..389f09f313 100644
--- a/ext/date/php_date.c
+++ b/ext/date/php_date.c
@@ -457,7 +457,11 @@ PHP_MINFO_FUNCTION(date)
php_info_print_table_row(2, "date/time support", "enabled");
php_info_print_table_row(2, "timelib version", TIMELIB_ASCII_VERSION);
php_info_print_table_row(2, "\"Olson\" Timezone Database Version", tzdb->version);
+#ifdef HAVE_SYSTEM_TZDATA
+ php_info_print_table_row(2, "Timezone Database", "system");
+#else
php_info_print_table_row(2, "Timezone Database", php_date_global_timezone_db_enabled ? "external" : "internal");
+#endif
php_info_print_table_row(2, "Default timezone", guess_timezone(tzdb));
php_info_print_table_end();

View File

@ -6,7 +6,7 @@
# Cannot load both php5 and php7 modules
<IfModule !mod_php5.c>
<IfModule prefork.c>
LoadModule php7_module modules/libphp7.so
LoadModule php7_module modules/libphp.so
</IfModule>
</IfModule>

View File

@ -20,13 +20,13 @@
%global with_firebird 0
%global with_imap 0
%global with_freetds 0
%global with_sodium 0
%global with_sodium 1
%global with_pspell 0
%global upver 8.0.0
%global upver 8.0.23
Name: php
Version: %{upver}
Release: 10
Release: 1
Summary: PHP scripting language for creating dynamic web sites
License: PHP and Zend-2.0 and BSD and MIT and ASL 1.0 and NCSA
URL: http://www.php.net/
@ -50,28 +50,11 @@ Source52: 20-ffi.ini
Patch0: php-7.4.0-httpd.patch
Patch1: php-7.2.0-includedir.patch
Patch2: php-8.0.0-embed.patch
Patch3: php-8.0.0-systzdata-v19.patch
Patch3: php-8.0.10-systzdata-v21.patch
Patch4: php-7.4.0-phpize.patch
Patch5: php-7.4.0-ldap_r.patch
Patch6: php-8.0.0-phpinfo.patch
Patch7: php-7.4.0-datetests.patch
Patch8: backport-CVE-2020-7071-Fix-bug-77423.patch
Patch9: CVE-2021-21702.patch
Patch10: backport-0001-CVE-2020-7071.patch
Patch11: backport-0002-CVE-2020-7071.patch
Patch12: backport-0001-CVE-2021-21705.patch
Patch13: backport-0002-CVE-2021-21705.patch
Patch14: backport-CVE-2021-21704.patch
Patch15: backport-CVE-2021-21703.patch
Patch16: backport-Handle-throwing-destructor-in-BIND_STATIC.patch
Patch17: backport-Bail-on-exception-during-delayed-autoload.patch
Patch18: backport-Fix-ASSIGN_DIM-to-NEXT-with-rc-1-reference-value.patch
Patch19: backport-Undef-slot-before-destroying-in-unset_property.patch
Patch20: backport-Handle-ref-return-from-Iterator-key.patch
Patch21: backport-Fix-return-by-ref-from-array_reduce-callback.patch
Patch22: backport-CVE-2021-21708-Fix-81708.patch
Patch23: backport-CVE-2022-31625.patch
Patch24: backport-CVE-2022-31626.patch
BuildRequires: bzip2-devel, curl-devel >= 7.9, httpd-devel >= 2.0.46-1, pam-devel, httpd-filesystem, nginx-filesystem
BuildRequires: libstdc++-devel, openssl-devel, sqlite-devel >= 3.6.0, zlib-devel, smtpdaemon, libedit-devel
@ -126,7 +109,6 @@ The php-dbg package contains the interactive PHP debugger.
Summary: PHP FastCGI Process Manager
BuildRequires: libacl-devel
Requires: php-common%{?_isa} = %{version}-%{release}
Requires(pre): /usr/sbin/useradd
BuildRequires: systemd-devel
%{?systemd_requires}
Requires(pre): httpd-filesystem