found more backports for dev-lang/php-7.4.33

This commit is contained in:
2026-05-21 13:34:40 +02:00
parent 6241e0c826
commit 9e72279007
26 changed files with 3550 additions and 5 deletions
@@ -0,0 +1,42 @@
From 72ba182fff763341313e5dc2a4ad8579d2396d1b Mon Sep 17 00:00:00 2001
From: Arnaud Le Blanc <arnaud.lb@gmail.com>
Date: Mon, 8 Apr 2024 14:58:12 +0200
Subject: [PATCH 1/2] Fix cookie_seek_function_t signature under musl (#13890)
Fixes GH-11678
Upstream-Status: Backport [577b8ae4226368e66fee7a9b5c58f9e2428372fc]
---
main/streams/cast.c | 10 +++-------
1 file changed, 3 insertions(+), 7 deletions(-)
diff --git a/main/streams/cast.c b/main/streams/cast.c
index 2109239effa..f0d65a141bd 100644
--- a/main/streams/cast.c
+++ b/main/streams/cast.c
@@ -104,6 +104,9 @@ static ssize_t stream_cookie_writer(void *cookie, const char *buffer, size_t siz
# ifdef COOKIE_SEEKER_USES_OFF64_T
static int stream_cookie_seeker(void *cookie, off64_t *position, int whence)
+# else
+static int stream_cookie_seeker(void *cookie, off_t *position, int whence)
+# endif
{
*position = php_stream_seek((php_stream *)cookie, (zend_off_t)*position, whence);
@@ -113,13 +116,6 @@ static int stream_cookie_seeker(void *cookie, off64_t *position, int whence)
}
return 0;
}
-# else
-static int stream_cookie_seeker(void *cookie, zend_off_t position, int whence)
-{
-
- return php_stream_seek((php_stream *)cookie, position, whence);
-}
-# endif
static int stream_cookie_closer(void *cookie)
{
--
2.46.2
@@ -0,0 +1,34 @@
From f476b5c4f1d308703a0b06942b34539704296511 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Zolt=C3=A1n=20B=C3=B6sz=C3=B6rm=C3=A9nyi?=
<zboszor@gmail.com>
Date: Tue, 9 Sep 2025 17:13:09 +0200
Subject: [PATCH] ext/libxml: Use ZEND_ATTRIBUTE_UNUSED in
php_libxml_output_buffer_create_filename
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
ATTRIBUTE_UNUSED is not defined everywhere, use ZEND_ATTRIBUTE_UNUSED.
Signed-off-by: Zoltán Böszörményi <zboszor@gmail.com>
Upstream-Status: Inappropriate [oe specific]
---
ext/libxml/libxml.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/ext/libxml/libxml.c b/ext/libxml/libxml.c
index d343135b98d..5b8aad8e1e5 100644
--- a/ext/libxml/libxml.c
+++ b/ext/libxml/libxml.c
@@ -476,7 +476,7 @@ php_libxml_input_buffer_create_filename(const char *URI, xmlCharEncoding enc)
static xmlOutputBufferPtr
php_libxml_output_buffer_create_filename(const char *URI,
xmlCharEncodingHandlerPtr encoder,
- int compression ATTRIBUTE_UNUSED)
+ int compression ZEND_ATTRIBUTE_UNUSED)
{
xmlOutputBufferPtr ret;
xmlURIPtr puri;
--
2.51.0
@@ -0,0 +1,33 @@
From: =?utf-8?b?T25kxZllaiBTdXLDvQ==?= <ondrej@sury.org>
Date: Thu, 21 Apr 2022 12:52:24 +0200
Subject: Add minimal OpenSSL 3.0 patch
---
ext/openssl/openssl.c | 6 ++++++
1 file changed, 6 insertions(+)
diff --git a/ext/openssl/openssl.c b/ext/openssl/openssl.c
index aa819be..2fa74f2 100644
--- a/ext/openssl/openssl.c
+++ b/ext/openssl/openssl.c
@@ -55,6 +55,10 @@
#include <openssl/rand.h>
#include <openssl/ssl.h>
#include <openssl/pkcs12.h>
+#if PHP_OPENSSL_API_VERSION >= 0x30000
+#include <openssl/core_names.h>
+#include <openssl/param_build.h>
+#endif
/* Common */
#include <time.h>
@@ -1517,7 +1521,9 @@ PHP_MINIT_FUNCTION(openssl)
REGISTER_LONG_CONSTANT("PKCS7_NOSIGS", PKCS7_NOSIGS, CONST_CS|CONST_PERSISTENT);
REGISTER_LONG_CONSTANT("OPENSSL_PKCS1_PADDING", RSA_PKCS1_PADDING, CONST_CS|CONST_PERSISTENT);
+#ifdef RSA_SSLV23_PADDING
REGISTER_LONG_CONSTANT("OPENSSL_SSLV23_PADDING", RSA_SSLV23_PADDING, CONST_CS|CONST_PERSISTENT);
+#endif
REGISTER_LONG_CONSTANT("OPENSSL_NO_PADDING", RSA_NO_PADDING, CONST_CS|CONST_PERSISTENT);
REGISTER_LONG_CONSTANT("OPENSSL_PKCS1_OAEP_PADDING", RSA_PKCS1_OAEP_PADDING, CONST_CS|CONST_PERSISTENT);
@@ -0,0 +1,39 @@
From 9e7e6a5a1e4a8785e237a9c94b533e0c6d9dab91 Mon Sep 17 00:00:00 2001
From: David Carlier <devnexen@gmail.com>
Date: Sat, 17 Feb 2024 21:38:21 +0000
Subject: [PATCH 2/2] ext/intl: level up c++ runtime std for icu 74 and
onwards.
to align with what is required to build icu 74 itself.
Close GH-14002
Upstream-Status: Backport [cc46a4e6b5a413bab3e264c1dcaaf7052f54fbc4]
---
ext/intl/config.m4 | 11 ++++++++++-
1 file changed, 10 insertions(+), 1 deletion(-)
diff --git a/ext/intl/config.m4 b/ext/intl/config.m4
index 7285f75e06a..36cf76e2932 100644
--- a/ext/intl/config.m4
+++ b/ext/intl/config.m4
@@ -83,7 +83,16 @@ if test "$PHP_INTL" != "no"; then
breakiterator/codepointiterator_methods.cpp"
PHP_REQUIRE_CXX()
- PHP_CXX_COMPILE_STDCXX(11, mandatory, PHP_INTL_STDCXX)
+
+ AC_MSG_CHECKING([if intl requires -std=gnu++17])
+ AS_IF([test "$PKG_CONFIG icu-uc --atleast-version=74"],[
+ AC_MSG_RESULT([yes])
+ PHP_CXX_COMPILE_STDCXX(17, mandatory, PHP_INTL_STDCXX)
+ ],[
+ AC_MSG_RESULT([no])
+ PHP_CXX_COMPILE_STDCXX(11, mandatory, PHP_INTL_STDCXX)
+ ])
+
PHP_INTL_CXX_FLAGS="$INTL_COMMON_FLAGS $PHP_INTL_STDCXX $ICU_CXXFLAGS"
if test "$ext_shared" = "no"; then
PHP_ADD_SOURCES(PHP_EXT_DIR(intl), $PHP_INTL_CXX_SOURCES, $PHP_INTL_CXX_FLAGS)
--
2.46.2
@@ -0,0 +1,61 @@
From: Jakub Zelenka <bukka@php.net>
Date: Sun, 15 May 2022 13:49:17 +0100
Subject: Fix bug #79589: ssl3_read_n:unexpected eof while reading
The unexpected EOF failure was introduced in OpenSSL 3.0 to prevent
truncation attack. However there are many non complaint servers and
it is causing break for many users including potential majority
of those where the truncation attack is not applicable. For that reason
we try to keep behavior consitent with older OpenSSL versions which is
also the path chosen by some other languages and web servers.
Closes GH-8369
---
ext/openssl/tests/bug79589.phpt | 21 +++++++++++++++++++++
ext/openssl/xp_ssl.c | 5 +++++
2 files changed, 26 insertions(+)
create mode 100644 ext/openssl/tests/bug79589.phpt
diff --git a/ext/openssl/tests/bug79589.phpt b/ext/openssl/tests/bug79589.phpt
new file mode 100644
index 0000000..5d277e8
--- /dev/null
+++ b/ext/openssl/tests/bug79589.phpt
@@ -0,0 +1,21 @@
+--TEST--
+Bug #65538: TLS unexpected EOF failure
+--EXTENSIONS--
+openssl
+--SKIPIF--
+<?php
+if (getenv("SKIP_ONLINE_TESTS")) die("skip online test");
+?>
+--FILE--
+<?php
+
+$release = file_get_contents(
+ 'https://chromedriver.storage.googleapis.com/LATEST_RELEASE',
+ false,
+ stream_context_create(['ssl' => ['verify_peer'=> false]])
+);
+echo gettype($release);
+
+?>
+--EXPECT--
+string
diff --git a/ext/openssl/xp_ssl.c b/ext/openssl/xp_ssl.c
index 9710e44..1f808bd 100644
--- a/ext/openssl/xp_ssl.c
+++ b/ext/openssl/xp_ssl.c
@@ -1640,6 +1640,11 @@ int php_openssl_setup_crypto(php_stream *stream,
ssl_ctx_options &= ~SSL_OP_DONT_INSERT_EMPTY_FRAGMENTS;
+#ifdef SSL_OP_IGNORE_UNEXPECTED_EOF
+ /* Only for OpenSSL 3+ to keep OpenSSL 1.1.1 behavior */
+ ssl_ctx_options |= SSL_OP_IGNORE_UNEXPECTED_EOF;
+#endif
+
if (!GET_VER_OPT("disable_compression") || zend_is_true(val)) {
ssl_ctx_options |= SSL_OP_NO_COMPRESSION;
}
@@ -0,0 +1,39 @@
From 272da51bfd562f5b9847c1b41eaa5d7018058490 Mon Sep 17 00:00:00 2001
From: Shivam Mathur <shivam_jpr@hotmail.com>
Date: Fri, 4 June 2024 13:40:00 +0530
Subject: [PATCH] Use ITIMER_REAL for timeout handling on MacOS / Apple Silicon
system
setitimer(ITIMER_PROF) fires too early on MacOS 14 when running on Apple
Silicon. See https://openradar.appspot.com/radar?id=5583058442911744.
Fixes GH-12814
Closes GH-13567
---
Zend/zend_execute_API.c | 6 ++++--
1 files changed, 3 insertions(+), 2 deletions(-)
diff --git a/Zend/zend_execute_API.c b/Zend/zend_execute_API.c
index c7f814138d00d774205ec78e8fd98a81b16e69db..fa126f959b3edf9d2e91d1b19d6029432ba4e210 100644
--- a/Zend/zend_execute_API.c
+++ b/Zend/zend_execute_API.c
@@ -1294,7 +1294,9 @@ static void zend_set_timeout_ex(zend_long seconds, int reset_signals) /* {{{ */
t_r.it_value.tv_sec = seconds;
t_r.it_value.tv_usec = t_r.it_interval.tv_sec = t_r.it_interval.tv_usec = 0;
-# if defined(__CYGWIN__) || defined(__PASE__)
+# if defined(__CYGWIN__) || defined(__PASE__) || (defined(__aarch64__) && defined(__APPLE__))
+ // ITIMER_PROF is broken in Apple Silicon system with MacOS >= 14
+ // See https://openradar.appspot.com/radar?id=5583058442911744.
setitimer(ITIMER_REAL, &t_r, NULL);
}
signo = SIGALRM;
@@ -1356,7 +1358,7 @@ void zend_unset_timeout(void) /* {{{ */
no_timeout.it_value.tv_sec = no_timeout.it_value.tv_usec = no_timeout.it_interval.tv_sec = no_timeout.it_interval.tv_usec = 0;
-# if defined(__CYGWIN__) || defined(__PASE__)
+# if defined(__CYGWIN__) || defined(__PASE__) || (defined(__aarch64__) && defined(__APPLE__))
setitimer(ITIMER_REAL, &no_timeout, NULL);
# else
setitimer(ITIMER_PROF, &no_timeout, NULL);
@@ -0,0 +1,64 @@
From 67259e451d5d58b4842776c5696a66d74e157609 Mon Sep 17 00:00:00 2001
From: Niels Dossche <7771979+nielsdos@users.noreply.github.com>
Date: Fri, 5 Jul 2024 23:34:09 +0200
Subject: [PATCH] Fix GH-14834: Error installing PHP when --with-pear is used
libxml2 2.13 makes changes to how the parsing state is set, update our
code accordingly. In particular, it started reporting entities within
attributes, while it should only report entities inside text nodes.
Closes GH-14837.
---
ext/xml/compat.c | 2 +-
ext/xml/tests/gh14834.phpt | 29 +++++++++++++++++++++++++++++
3 files changed, 32 insertions(+), 1 deletion(-)
create mode 100644 ext/xml/tests/gh14834.phpt
diff --git a/ext/xml/compat.c b/ext/xml/compat.c
index 242cc4ba7c40c..5f55dc62b3687 100644
--- a/ext/xml/compat.c
+++ b/ext/xml/compat.c
@@ -375,7 +375,7 @@ _get_entity(void *user, const xmlChar *name)
if (ret == NULL)
ret = xmlGetDocEntity(parser->parser->myDoc, name);
- if (ret == NULL || (parser->parser->instate != XML_PARSER_ENTITY_VALUE && parser->parser->instate != XML_PARSER_ATTRIBUTE_VALUE)) {
+ if (ret == NULL || parser->parser->instate == XML_PARSER_CONTENT) {
if (ret == NULL || ret->etype == XML_INTERNAL_GENERAL_ENTITY || ret->etype == XML_INTERNAL_PARAMETER_ENTITY || ret->etype == XML_INTERNAL_PREDEFINED_ENTITY) {
/* Predefined entities will expand unless no cdata handler is present */
if (parser->h_default && ! (ret && ret->etype == XML_INTERNAL_PREDEFINED_ENTITY && parser->h_cdata)) {
diff --git a/ext/xml/tests/gh14834.phpt b/ext/xml/tests/gh14834.phpt
new file mode 100644
index 0000000000000..2781ba2ed0941
--- /dev/null
+++ b/ext/xml/tests/gh14834.phpt
@@ -0,0 +1,29 @@
+--TEST--
+GH-14834 (Error installing PHP when --with-pear is used)
+--EXTENSIONS--
+xml
+--FILE--
+<?php
+$xml = <<<XML
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE root [
+ <!ENTITY foo "ent">
+]>
+<root>
+ <element hint="hello&apos;world">&foo;<![CDATA[ &amp; ]]><?x &amp; ?></element>
+</root>
+XML;
+
+$parser = xml_parser_create();
+xml_set_character_data_handler($parser, function($_, $data) {
+ var_dump($data);
+});
+xml_parse($parser, $xml, true);
+?>
+--EXPECT--
+string(3) "
+ "
+string(3) "ent"
+string(7) " &amp; "
+string(1) "
+"
@@ -0,0 +1,392 @@
From f566cba0bb6bd53b1d44d5097e68201412b00f7a Mon Sep 17 00:00:00 2001
From: Remi Collet <remi@php.net>
Date: Thu, 25 Nov 2021 13:16:26 +0100
Subject: [PATCH] fix [-Wstrict-prototypes] build warnings in ext/gd
---
ext/gd/config.m4 | 2 --
ext/gd/gd.c | 58 ++++++++++++++++++++++++------------------------
2 files changed, 29 insertions(+), 31 deletions(-)
diff -up a/ext/gd/gd.c.proto b/ext/gd/gd.c
--- a/ext/gd/gd.c.proto 2022-10-31 11:36:07.000000000 +0100
+++ b/ext/gd/gd.c 2025-02-13 12:04:07.860118321 +0100
@@ -138,9 +138,9 @@ static void php_image_filter_pixelate(IN
static void php_image_filter_scatter(INTERNAL_FUNCTION_PARAMETERS);
/* End Section filters declarations */
-static gdImagePtr _php_image_create_from_string (zval *Data, char *tn, gdImagePtr (*ioctx_func_p)());
-static void _php_image_create_from(INTERNAL_FUNCTION_PARAMETERS, int image_type, char *tn, gdImagePtr (*func_p)(), gdImagePtr (*ioctx_func_p)());
-static void _php_image_output(INTERNAL_FUNCTION_PARAMETERS, int image_type, char *tn, void (*func_p)());
+static gdImagePtr _php_image_create_from_string (zval *Data, char *tn, gdImagePtr (*ioctx_func_p)(gdIOCtxPtr));
+static void _php_image_create_from(INTERNAL_FUNCTION_PARAMETERS, int image_type, char *tn, gdImagePtr (*func_p)(FILE *), gdImagePtr (*ioctx_func_p)(gdIOCtxPtr));
+static void _php_image_output(INTERNAL_FUNCTION_PARAMETERS, int image_type, char *tn);
static int _php_image_type(char data[12]);
static void _php_image_convert(INTERNAL_FUNCTION_PARAMETERS, int image_type);
@@ -2330,7 +2330,7 @@ static int _php_image_type (char data[12
/* {{{ _php_image_create_from_string
*/
-gdImagePtr _php_image_create_from_string(zval *data, char *tn, gdImagePtr (*ioctx_func_p)())
+gdImagePtr _php_image_create_from_string(zval *data, char *tn, gdImagePtr (*ioctx_func_p)(gdIOCtxPtr))
{
gdImagePtr im;
gdIOCtx *io_ctx;
@@ -2440,7 +2440,7 @@ PHP_FUNCTION(imagecreatefromstring)
/* {{{ _php_image_create_from
*/
-static void _php_image_create_from(INTERNAL_FUNCTION_PARAMETERS, int image_type, char *tn, gdImagePtr (*func_p)(), gdImagePtr (*ioctx_func_p)())
+static void _php_image_create_from(INTERNAL_FUNCTION_PARAMETERS, int image_type, char *tn, gdImagePtr (*func_p)(FILE *), gdImagePtr (*ioctx_func_p)(gdIOCtxPtr))
{
char *file;
size_t file_len;
@@ -2477,7 +2477,7 @@ static void _php_image_create_from(INTER
if (FAILURE == php_stream_cast(stream, PHP_STREAM_AS_STDIO, (void**)&fp, REPORT_ERRORS)) {
goto out_err;
}
- } else if (ioctx_func_p) {
+ } else if (ioctx_func_p || image_type == PHP_GDIMG_TYPE_GD2PART) {
/* we can create an io context */
gdIOCtx* io_ctx;
zend_string *buff;
@@ -2501,7 +2501,7 @@ static void _php_image_create_from(INTER
}
if (image_type == PHP_GDIMG_TYPE_GD2PART) {
- im = (*ioctx_func_p)(io_ctx, srcx, srcy, width, height);
+ im = gdImageCreateFromGd2PartCtx(io_ctx, srcx, srcy, width, height);
} else {
im = (*ioctx_func_p)(io_ctx);
}
@@ -2519,7 +2519,7 @@ static void _php_image_create_from(INTER
if (!im && fp) {
switch (image_type) {
case PHP_GDIMG_TYPE_GD2PART:
- im = (*func_p)(fp, srcx, srcy, width, height);
+ im = gdImageCreateFromGd2Part(fp, srcx, srcy, width, height);
break;
#if defined(HAVE_GD_XPM)
case PHP_GDIMG_TYPE_XPM:
@@ -2608,7 +2608,7 @@ PHP_FUNCTION(imagecreatefromxbm)
Create a new image from XPM file or URL */
PHP_FUNCTION(imagecreatefromxpm)
{
- _php_image_create_from(INTERNAL_FUNCTION_PARAM_PASSTHRU, PHP_GDIMG_TYPE_XPM, "XPM", gdImageCreateFromXpm, NULL);
+ _php_image_create_from(INTERNAL_FUNCTION_PARAM_PASSTHRU, PHP_GDIMG_TYPE_XPM, "XPM", NULL, NULL);
}
/* }}} */
#endif
@@ -2641,7 +2641,7 @@ PHP_FUNCTION(imagecreatefromgd2)
Create a new image from a given part of GD2 file or URL */
PHP_FUNCTION(imagecreatefromgd2part)
{
- _php_image_create_from(INTERNAL_FUNCTION_PARAM_PASSTHRU, PHP_GDIMG_TYPE_GD2PART, "GD2", gdImageCreateFromGd2Part, gdImageCreateFromGd2PartCtx);
+ _php_image_create_from(INTERNAL_FUNCTION_PARAM_PASSTHRU, PHP_GDIMG_TYPE_GD2PART, "GD2", NULL, NULL);
}
/* }}} */
@@ -2667,7 +2667,7 @@ PHP_FUNCTION(imagecreatefromtga)
/* {{{ _php_image_output
*/
-static void _php_image_output(INTERNAL_FUNCTION_PARAMETERS, int image_type, char *tn, void (*func_p)())
+static void _php_image_output(INTERNAL_FUNCTION_PARAMETERS, int image_type, char *tn)
{
zval *imgind;
char *file = NULL;
@@ -2720,13 +2720,13 @@ static void _php_image_output(INTERNAL_F
gdImageWBMP(im, q, fp);
break;
case PHP_GDIMG_TYPE_GD:
- (*func_p)(im, fp);
+ gdImageGd(im, fp);
break;
case PHP_GDIMG_TYPE_GD2:
if (q == -1) {
q = 128;
}
- (*func_p)(im, fp, q, t);
+ gdImageGd2(im, fp, q, t);
break;
default:
ZEND_ASSERT(0);
@@ -2756,13 +2756,13 @@ static void _php_image_output(INTERNAL_F
gdImageWBMP(im, q, tmp);
break;
case PHP_GDIMG_TYPE_GD:
- (*func_p)(im, tmp);
+ gdImageGd(im, tmp);
break;
case PHP_GDIMG_TYPE_GD2:
if (q == -1) {
q = 128;
}
- (*func_p)(im, tmp, q, t);
+ gdImageGd2(im, tmp, q, t);
break;
default:
ZEND_ASSERT(0);
@@ -2786,7 +2786,7 @@ static void _php_image_output(INTERNAL_F
Output XBM image to browser or file */
PHP_FUNCTION(imagexbm)
{
- _php_image_output_ctx(INTERNAL_FUNCTION_PARAM_PASSTHRU, PHP_GDIMG_TYPE_XBM, "XBM", gdImageXbmCtx);
+ _php_image_output_ctx(INTERNAL_FUNCTION_PARAM_PASSTHRU, PHP_GDIMG_TYPE_XBM, "XBM");
}
/* }}} */
@@ -2794,7 +2794,7 @@ PHP_FUNCTION(imagexbm)
Output GIF image to browser or file */
PHP_FUNCTION(imagegif)
{
- _php_image_output_ctx(INTERNAL_FUNCTION_PARAM_PASSTHRU, PHP_GDIMG_TYPE_GIF, "GIF", gdImageGifCtx);
+ _php_image_output_ctx(INTERNAL_FUNCTION_PARAM_PASSTHRU, PHP_GDIMG_TYPE_GIF, "GIF");
}
/* }}} */
@@ -2803,7 +2803,7 @@ PHP_FUNCTION(imagegif)
Output PNG image to browser or file */
PHP_FUNCTION(imagepng)
{
- _php_image_output_ctx(INTERNAL_FUNCTION_PARAM_PASSTHRU, PHP_GDIMG_TYPE_PNG, "PNG", gdImagePngCtxEx);
+ _php_image_output_ctx(INTERNAL_FUNCTION_PARAM_PASSTHRU, PHP_GDIMG_TYPE_PNG, "PNG");
}
/* }}} */
#endif /* HAVE_GD_PNG */
@@ -2814,7 +2814,7 @@ PHP_FUNCTION(imagepng)
Output WEBP image to browser or file */
PHP_FUNCTION(imagewebp)
{
- _php_image_output_ctx(INTERNAL_FUNCTION_PARAM_PASSTHRU, PHP_GDIMG_TYPE_WEBP, "WEBP", gdImageWebpCtx);
+ _php_image_output_ctx(INTERNAL_FUNCTION_PARAM_PASSTHRU, PHP_GDIMG_TYPE_WEBP, "WEBP");
}
/* }}} */
#endif /* HAVE_GD_WEBP */
@@ -2825,7 +2825,7 @@ PHP_FUNCTION(imagewebp)
Output JPEG image to browser or file */
PHP_FUNCTION(imagejpeg)
{
- _php_image_output_ctx(INTERNAL_FUNCTION_PARAM_PASSTHRU, PHP_GDIMG_TYPE_JPG, "JPEG", gdImageJpegCtx);
+ _php_image_output_ctx(INTERNAL_FUNCTION_PARAM_PASSTHRU, PHP_GDIMG_TYPE_JPG, "JPEG");
}
/* }}} */
#endif /* HAVE_GD_JPG */
@@ -2834,7 +2834,7 @@ PHP_FUNCTION(imagejpeg)
Output WBMP image to browser or file */
PHP_FUNCTION(imagewbmp)
{
- _php_image_output_ctx(INTERNAL_FUNCTION_PARAM_PASSTHRU, PHP_GDIMG_TYPE_WBM, "WBMP", gdImageWBMPCtx);
+ _php_image_output_ctx(INTERNAL_FUNCTION_PARAM_PASSTHRU, PHP_GDIMG_TYPE_WBM, "WBMP");
}
/* }}} */
@@ -2842,7 +2842,7 @@ PHP_FUNCTION(imagewbmp)
Output GD image to browser or file */
PHP_FUNCTION(imagegd)
{
- _php_image_output(INTERNAL_FUNCTION_PARAM_PASSTHRU, PHP_GDIMG_TYPE_GD, "GD", gdImageGd);
+ _php_image_output(INTERNAL_FUNCTION_PARAM_PASSTHRU, PHP_GDIMG_TYPE_GD, "GD");
}
/* }}} */
@@ -2850,7 +2850,7 @@ PHP_FUNCTION(imagegd)
Output GD2 image to browser or file */
PHP_FUNCTION(imagegd2)
{
- _php_image_output(INTERNAL_FUNCTION_PARAM_PASSTHRU, PHP_GDIMG_TYPE_GD2, "GD2", gdImageGd2);
+ _php_image_output(INTERNAL_FUNCTION_PARAM_PASSTHRU, PHP_GDIMG_TYPE_GD2, "GD2");
}
/* }}} */
@@ -2859,7 +2859,7 @@ PHP_FUNCTION(imagegd2)
Output BMP image to browser or file */
PHP_FUNCTION(imagebmp)
{
- _php_image_output_ctx(INTERNAL_FUNCTION_PARAM_PASSTHRU, PHP_GDIMG_TYPE_BMP, "BMP", gdImageBmpCtx);
+ _php_image_output_ctx(INTERNAL_FUNCTION_PARAM_PASSTHRU, PHP_GDIMG_TYPE_BMP, "BMP");
}
/* }}} */
#endif
@@ -4146,7 +4146,7 @@ static void php_imagettftext_common(INTE
Output WBMP image to browser or file */
PHP_FUNCTION(image2wbmp)
{
- _php_image_output(INTERNAL_FUNCTION_PARAM_PASSTHRU, PHP_GDIMG_CONVERT_WBM, "WBMP", NULL);
+ _php_image_output(INTERNAL_FUNCTION_PARAM_PASSTHRU, PHP_GDIMG_CONVERT_WBM, "WBMP");
}
/* }}} */
diff -up a/ext/gd/gd_ctx.c.proto b/ext/gd/gd_ctx.c
--- a/ext/gd/gd_ctx.c.proto 2025-02-13 11:42:48.478248591 +0100
+++ b/ext/gd/gd_ctx.c 2025-02-13 11:52:48.325740296 +0100
@@ -77,7 +77,7 @@ static void _php_image_stream_ctxfreeand
} /* }}} */
/* {{{ _php_image_output_ctx */
-static void _php_image_output_ctx(INTERNAL_FUNCTION_PARAMETERS, int image_type, char *tn, void (*func_p)())
+static void _php_image_output_ctx(INTERNAL_FUNCTION_PARAMETERS, int image_type, char *tn)
{
zval *imgind;
char *file = NULL;
@@ -177,16 +177,20 @@ static void _php_image_output_ctx(INTERN
switch(image_type) {
case PHP_GDIMG_TYPE_JPG:
- (*func_p)(im, ctx, q);
+ gdImageJpegCtx(im, ctx, q);
break;
case PHP_GDIMG_TYPE_WEBP:
if (q == -1) {
q = 80;
}
- (*func_p)(im, ctx, q);
+ gdImageWebpCtx(im, ctx, q);
break;
case PHP_GDIMG_TYPE_PNG:
- (*func_p)(im, ctx, q, f);
+#ifdef HAVE_GD_BUNDLED
+ gdImagePngCtxEx(im, ctx, q, f);
+#else
+ gdImagePngCtxEx(im, ctx, q);
+#endif
break;
case PHP_GDIMG_TYPE_XBM:
case PHP_GDIMG_TYPE_WBM:
@@ -197,16 +201,16 @@ static void _php_image_output_ctx(INTERN
q = i;
}
if (image_type == PHP_GDIMG_TYPE_XBM) {
- (*func_p)(im, file ? file : "", q, ctx);
+ gdImageXbmCtx(im, file ? file : "", q, ctx);
} else {
- (*func_p)(im, q, ctx);
+ gdImageWBMPCtx(im, q, ctx);
}
break;
case PHP_GDIMG_TYPE_BMP:
- (*func_p)(im, ctx, (int) compressed);
+ gdImageBmpCtx(im, ctx, (int) compressed);
break;
- default:
- (*func_p)(im, ctx);
+ case PHP_GDIMG_TYPE_GIF:
+ gdImageGifCtx(im, ctx);
break;
}
From b7356692f69f4ac0a07ea54e83debdd04b426dcb Mon Sep 17 00:00:00 2001
From: George Peter Banyard <girgias@php.net>
Date: Wed, 12 May 2021 14:41:11 +0100
Subject: [PATCH] Specify function pointer signature for scanf implementation
Fix [-Wstrict-prototypes] warnings in standard/scanf.c
---
ext/standard/scanf.c | 14 ++++++++------
1 file changed, 8 insertions(+), 6 deletions(-)
diff --git a/ext/standard/scanf.c b/ext/standard/scanf.c
index f58b4195cc599..78ecc1642cf92 100644
--- a/ext/standard/scanf.c
+++ b/ext/standard/scanf.c
@@ -108,6 +108,8 @@ typedef struct CharSet {
} *ranges;
} CharSet;
+typedef zend_long (*int_string_formater)(const char*, char**, int);
+
/*
* Declarations for functions used only in this file.
*/
@@ -585,7 +587,7 @@ PHPAPI int php_sscanf_internal( char *string, char *format,
int base = 0;
int underflow = 0;
size_t width;
- zend_long (*fn)() = NULL;
+ int_string_formater fn = NULL;
char *ch, sch;
int flags;
char buf[64]; /* Temporary buffer to hold scanned number
@@ -750,29 +752,29 @@ PHPAPI int php_sscanf_internal( char *string, char *format,
case 'D':
op = 'i';
base = 10;
- fn = (zend_long (*)())ZEND_STRTOL_PTR;
+ fn = (int_string_formater)ZEND_STRTOL_PTR;
break;
case 'i':
op = 'i';
base = 0;
- fn = (zend_long (*)())ZEND_STRTOL_PTR;
+ fn = (int_string_formater)ZEND_STRTOL_PTR;
break;
case 'o':
op = 'i';
base = 8;
- fn = (zend_long (*)())ZEND_STRTOL_PTR;
+ fn = (int_string_formater)ZEND_STRTOL_PTR;
break;
case 'x':
case 'X':
op = 'i';
base = 16;
- fn = (zend_long (*)())ZEND_STRTOL_PTR;
+ fn = (int_string_formater)ZEND_STRTOL_PTR;
break;
case 'u':
op = 'i';
base = 10;
flags |= SCAN_UNSIGNED;
- fn = (zend_long (*)())ZEND_STRTOUL_PTR;
+ fn = (int_string_formater)ZEND_STRTOUL_PTR;
break;
case 'f':
From 2068d230d981d7b06b41b87ebc37ab2581b79852 Mon Sep 17 00:00:00 2001
From: George Peter Banyard <girgias@php.net>
Date: Wed, 12 May 2021 18:54:57 +0100
Subject: [PATCH] Fix [-Wstrict-prototypes] warning in PCNTL extension
To achieve this we need to introduce a new wrapper function with
dummy arguments which calls pcntl_signal_dispatch() to respect
the function pointer signature for a tick function.
---
ext/pcntl/pcntl.c | 10 ++++++++--
1 file changed, 8 insertions(+), 2 deletions(-)
diff --git a/ext/pcntl/pcntl.c b/ext/pcntl/pcntl.c
index 1e8690ae75144..c116eff7d034a 100644
--- a/ext/pcntl/pcntl.c
+++ b/ext/pcntl/pcntl.c
@@ -252,7 +252,8 @@ static void pcntl_siginfo_to_zval(int, s
#else
static void pcntl_signal_handler(int);
#endif
-static void pcntl_signal_dispatch();
+static void pcntl_signal_dispatch(void);
+static void pcntl_signal_dispatch_tick_function(int dummy_int, void *dummy_pointer);
static void pcntl_interrupt_function(zend_execute_data *execute_data);
void php_register_signal_constants(INIT_FUNC_ARGS)
@@ -587,7 +588,7 @@ static PHP_GINIT_FUNCTION(pcntl)
PHP_RINIT_FUNCTION(pcntl)
{
- php_add_tick_function(pcntl_signal_dispatch, NULL);
+ php_add_tick_function(pcntl_signal_dispatch_tick_function, NULL);
zend_hash_init(&PCNTL_G(php_signal_table), 16, NULL, ZVAL_PTR_DTOR, 0);
PCNTL_G(head) = PCNTL_G(tail) = PCNTL_G(spares) = NULL;
PCNTL_G(async_signals) = 0;
@@ -1549,6 +1550,11 @@ void pcntl_signal_dispatch()
sigprocmask(SIG_SETMASK, &old_mask, NULL);
}
+static void pcntl_signal_dispatch_tick_function(int dummy_int, void *dummy_pointer)
+{
+ return pcntl_signal_dispatch();
+}
+
/* {{{ proto bool pcntl_async_signals([bool on[)
Enable/disable asynchronous signal handling and return the old setting. */
PHP_FUNCTION(pcntl_async_signals)
@@ -0,0 +1,103 @@
From 9fbcc192064146df6c7784265ca826ce63c7c402 Mon Sep 17 00:00:00 2001
From: Shivam Mathur <shivam_jpr@hotmail.com>
Date: Sun, 12 Oct 2025 04:26:14 +0530
Subject: [PATCH 1/1] Fix GH-16168: Fix inline assembly labels to not crash
with Xcode 16 clang
---
Zend/zend_string.c | 40 ++++++++++++++++++++--------------------
1 file changed, 20 insertions(+), 20 deletions(-)
diff --git a/Zend/zend_string.c b/Zend/zend_string.c
index 75e7e6249f..ee6a89125c 100644
--- a/Zend/zend_string.c
+++ b/Zend/zend_string.c
@@ -328,32 +328,32 @@ ZEND_API void zend_interned_strings_switch_storage(zend_bool request)
ZEND_API zend_bool ZEND_FASTCALL zend_string_equal_val(zend_string *s1, zend_string *s2)
{
char *ptr = ZSTR_VAL(s1);
- size_t delta = (char*)s2 - (char*)s1;
+ uintptr_t delta = (uintptr_t) s2 - (uintptr_t) s1;
size_t len = ZSTR_LEN(s1);
zend_ulong ret;
__asm__ (
- ".LL0%=:\n\t"
+ "0:\n\t"
"movl (%2,%3), %0\n\t"
"xorl (%2), %0\n\t"
- "jne .LL1%=\n\t"
+ "jne 1f\n\t"
"addl $0x4, %2\n\t"
"subl $0x4, %1\n\t"
- "ja .LL0%=\n\t"
+ "ja 0b\n\t"
"movl $0x1, %0\n\t"
- "jmp .LL3%=\n\t"
- ".LL1%=:\n\t"
+ "jmp 3f\n\t"
+ "1:\n\t"
"cmpl $0x4,%1\n\t"
- "jb .LL2%=\n\t"
+ "jb 2f\n\t"
"xorl %0, %0\n\t"
- "jmp .LL3%=\n\t"
- ".LL2%=:\n\t"
+ "jmp 3f\n\t"
+ "2:\n\t"
"negl %1\n\t"
"lea 0x20(,%1,8), %1\n\t"
"shll %b1, %0\n\t"
"sete %b0\n\t"
"movzbl %b0, %0\n\t"
- ".LL3%=:\n"
+ "3:\n"
: "=&a"(ret),
"+c"(len),
"+r"(ptr)
@@ -396,32 +396,32 @@ ZEND_API zend_bool ZEND_FASTCALL I_WRAP_SONAME_FNNAME_ZU(NONE,zend_string_equal_
ZEND_API zend_bool ZEND_FASTCALL zend_string_equal_val(zend_string *s1, zend_string *s2)
{
char *ptr = ZSTR_VAL(s1);
- size_t delta = (char*)s2 - (char*)s1;
+ uintptr_t delta = (uintptr_t) s2 - (uintptr_t) s1;
size_t len = ZSTR_LEN(s1);
zend_ulong ret;
__asm__ (
- ".LL0%=:\n\t"
+ "0:\n\t"
"movq (%2,%3), %0\n\t"
"xorq (%2), %0\n\t"
- "jne .LL1%=\n\t"
+ "jne 1f\n\t"
"addq $0x8, %2\n\t"
"subq $0x8, %1\n\t"
- "ja .LL0%=\n\t"
+ "ja 0b\n\t"
"movq $0x1, %0\n\t"
- "jmp .LL3%=\n\t"
- ".LL1%=:\n\t"
+ "jmp 3f\n\t"
+ "1:\n\t"
"cmpq $0x8,%1\n\t"
- "jb .LL2%=\n\t"
+ "jb 2f\n\t"
"xorq %0, %0\n\t"
- "jmp .LL3%=\n\t"
- ".LL2%=:\n\t"
+ "jmp 3f\n\t"
+ "2:\n\t"
"negq %1\n\t"
"lea 0x40(,%1,8), %1\n\t"
"shlq %b1, %0\n\t"
"sete %b0\n\t"
"movzbq %b0, %0\n\t"
- ".LL3%=:\n"
+ "3:\n"
: "=&a"(ret),
"+c"(len),
"+r"(ptr)
--
2.50.1 (Apple Git-155)
@@ -0,0 +1,82 @@
Upstream-Status: Inappropriate [cross compile specific]
diff -durpN php-7.4.11.orig/ext/iconv/config.m4 php-7.4.11/ext/iconv/config.m4
--- php-7.4.11.orig/ext/iconv/config.m4 2020-10-09 08:04:45.951837732 -0400
+++ php-7.4.11/ext/iconv/config.m4 2020-10-09 08:06:36.874657935 -0400
@@ -150,9 +150,9 @@ int main() {
PHP_DEFINE([ICONV_SUPPORTS_ERRNO],0,[ext/iconv])
AC_DEFINE([ICONV_SUPPORTS_ERRNO],0,[Whether iconv supports error no or not])
],[
- AC_MSG_RESULT(no, cross-compiling)
- PHP_DEFINE([ICONV_SUPPORTS_ERRNO],0,[ext/iconv])
- AC_DEFINE([ICONV_SUPPORTS_ERRNO],0,[Whether iconv supports error no or not])
+ AC_MSG_RESULT(yes)
+ PHP_DEFINE([ICONV_SUPPORTS_ERRNO],1,[ext/iconv])
+ AC_DEFINE([ICONV_SUPPORTS_ERRNO],1,[Whether iconv supports error no or not])
])
AC_MSG_CHECKING([if iconv supports //IGNORE])
diff -durpN php-7.4.11.orig/ext/opcache/config.m4 php-7.4.11/ext/opcache/config.m4
--- php-7.4.11.orig/ext/opcache/config.m4 2020-10-09 08:04:45.953837747 -0400
+++ php-7.4.11/ext/opcache/config.m4 2020-10-09 08:06:36.874657935 -0400
@@ -89,7 +89,9 @@ int main() {
}
]])],[dnl
AC_DEFINE(HAVE_SHM_IPC, 1, [Define if you have SysV IPC SHM support])
- msg=yes],[msg=no],[msg=no])
+ msg=yes],[msg=no],[
+ AC_DEFINE(HAVE_SHM_IPC, 1, [Define if you have SysV IPC SHM support])
+ msg=yes])
AC_MSG_RESULT([$msg])
AC_MSG_CHECKING(for mmap() using MAP_ANON shared memory support)
@@ -141,7 +143,9 @@ int main() {
}
]])],[dnl
AC_DEFINE(HAVE_SHM_MMAP_ANON, 1, [Define if you have mmap(MAP_ANON) SHM support])
- msg=yes],[msg=no],[msg=no])
+ msg=yes],[msg=no],[
+ AC_DEFINE(HAVE_SHM_MMAP_ANON, 1, [Define if you have mmap(MAP_ANON) SHM support])
+ msg=yes])
AC_MSG_RESULT([$msg])
PHP_CHECK_FUNC_LIB(shm_open, rt)
@@ -216,7 +220,9 @@ int main() {
],[
AC_MSG_RESULT([no])
],[
- AC_MSG_RESULT([no])
+ AC_DEFINE(HAVE_SHM_MMAP_POSIX, 1, [Define if you have POSIX mmap() SHM support])
+ AC_MSG_RESULT([yes])
+ PHP_CHECK_LIBRARY(rt, shm_unlink, [PHP_ADD_LIBRARY(rt,1,OPCACHE_SHARED_LIBADD)])
])
PHP_NEW_EXTENSION(opcache,
diff -durpN php-7.4.11.orig/ext/posix/config.m4 php-7.4.11/ext/posix/config.m4
--- php-7.4.11.orig/ext/posix/config.m4 2020-10-09 08:04:45.954837755 -0400
+++ php-7.4.11/ext/posix/config.m4 2020-10-09 08:06:36.875657943 -0400
@@ -28,7 +28,10 @@ int main(int argc, char *argv[])
],[
AC_MSG_RESULT([no, posix_ttyname() will be thread-unsafe])
], [
- AC_MSG_RESULT([no, cannot detect working ttyname_r() when cross compiling. posix_ttyname() will be thread-unsafe])
+ AC_CHECK_FUNCS(ttyname_r,
+ [AC_MSG_RESULT([yes])
+ AC_DEFINE(HAVE_TTYNAME_R, 1, [Whether you have a working ttyname_r])],
+ [AC_MSG_RESULT([no, cannot detect working ttyname_r() when cross compiling. posix_ttyname() will be thread-unsafe])])
])
AC_CACHE_CHECK([for utsname.domainname], ac_cv_have_utsname_domainname, [
diff -durpN php-7.4.11.orig/sapi/fpm/config.m4 php-7.4.11/sapi/fpm/config.m4
--- php-7.4.11.orig/sapi/fpm/config.m4 2020-10-09 08:04:45.955837762 -0400
+++ php-7.4.11/sapi/fpm/config.m4 2020-10-09 08:06:37.012658955 -0400
@@ -262,7 +262,8 @@ AC_DEFUN([AC_FPM_TRACE],
proc_mem_file=""
AC_MSG_RESULT([no])
], [
- AC_MSG_RESULT([skipped (cross-compiling)])
+ AC_MSG_RESULT([cross compiling for Linux, using 'mem'])
+ proc_mem_file="mem"
])
fi
+203
View File
@@ -0,0 +1,203 @@
Upstream-Status: Backport [aeaab8ee3e52f74c042a861e394437d6554b36be]
diff -up php-7.4.33/ext/pdo_oci/oci_statement.c.gcc14 php-7.4.33/ext/pdo_oci/oci_statement.c
--- php-7.4.33/ext/pdo_oci/oci_statement.c.gcc14 2022-10-31 11:36:05.000000000 +0100
+++ php-7.4.33/ext/pdo_oci/oci_statement.c 2024-02-14 15:05:34.224568567 +0100
@@ -654,7 +654,7 @@ static ssize_t oci_blob_write(php_stream
return amt;
}
-static size_t oci_blob_read(php_stream *stream, char *buf, size_t count)
+static ssize_t oci_blob_read(php_stream *stream, char *buf, size_t count)
{
struct oci_lob_self *self = (struct oci_lob_self*)stream->abstract;
ub4 amt;
@@ -666,7 +666,7 @@ static size_t oci_blob_read(php_stream *
NULL, NULL, 0, SQLCS_IMPLICIT);
if (r != OCI_SUCCESS && r != OCI_NEED_DATA) {
- return (size_t)-1;
+ return -1;
}
self->offset += amt;
diff -up php-7.4.33/sapi/litespeed/lsapi_main.c.gcc14 php-7.4.33/sapi/litespeed/lsapi_main.c
--- php-7.4.33/sapi/litespeed/lsapi_main.c.gcc14 2024-02-14 15:09:59.523706463 +0100
+++ php-7.4.33/sapi/litespeed/lsapi_main.c 2024-02-14 15:10:13.979258854 +0100
@@ -25,6 +25,7 @@
#include "zend.h"
#include "ext/standard/basic_functions.h"
#include "ext/standard/info.h"
+#include "ext/standard/head.h"
#include "lsapilib.h"
#include <stdio.h>
Adapted for 7.4 from:
From aeaab8ee3e52f74c042a861e394437d6554b36be Mon Sep 17 00:00:00 2001
From: Florian Weimer <fweimer@redhat.com>
Date: Mon, 9 Sep 2019 21:29:03 +0200
Subject: [PATCH] Port various autoconf bits to C99 compilers
C99 no longer has implicit function declarations and implicit ints.
Current GCC versions enable them as an extension, but this will
change in a future GCC version.
---
Zend/Zend.m4 | 2 ++
build/libtool.m4 | 5 +----
build/php.m4 | 17 ++++++++++-------
configure.ac | 2 ++
ext/standard/config.m4 | 22 ++++++++++++++++++++++
5 files changed, 37 insertions(+), 11 deletions(-)
diff --git a/Zend/Zend.m4 b/Zend/Zend.m4
index 054e2621a4057..57a12ac36ba60 100644
--- a/Zend/Zend.m4
+++ b/Zend/Zend.m4
@@ -157,6 +157,7 @@ AC_MSG_CHECKING(whether double cast to long preserves least significant bits)
AC_RUN_IFELSE([AC_LANG_SOURCE([[
#include <limits.h>
+#include <stdlib.h>
int main()
{
@@ -256,6 +257,7 @@ AC_MSG_CHECKING(for MM alignment and log values)
AC_RUN_IFELSE([AC_LANG_SOURCE([[
#include <stdio.h>
+#include <stdlib.h>
typedef union _mm_align_test {
void *ptr;
diff --git a/build/libtool.m4 b/build/libtool.m4
index f7f51642920f9..577dad4cbe313 100644
--- a/build/libtool.m4
+++ b/build/libtool.m4
@@ -945,6 +945,7 @@ else
#endif
#include <stdio.h>
+#include <stdlib.h>
#ifdef RTLD_GLOBAL
# define LT_DLGLOBAL RTLD_GLOBAL
diff --git a/build/php.m4 b/build/php.m4
index 25f5aa762b892..529876b6b67c6 100644
--- a/build/php.m4
+++ b/build/php.m4
@@ -1120,7 +1120,7 @@ AC_CACHE_CHECK(for type of reentrant time-related functions, ac_cv_time_r_type,[
AC_RUN_IFELSE([AC_LANG_SOURCE([[
#include <time.h>
-main() {
+int main() {
char buf[27];
struct tm t;
time_t old = 0;
@@ -1136,7 +1136,7 @@ return (1);
],[
AC_RUN_IFELSE([AC_LANG_SOURCE([[
#include <time.h>
-main() {
+int main() {
struct tm t, *s;
time_t old = 0;
char buf[27], *p;
@@ -1597,7 +1600,7 @@ AC_DEFUN([PHP_CHECK_FUNC_LIB],[
if test "$found" = "yes"; then
ac_libs=$LIBS
LIBS="$LIBS -l$2"
- AC_RUN_IFELSE([AC_LANG_SOURCE([[main() { return (0); }]])],[found=yes],[found=no],[found=no])
+ AC_RUN_IFELSE([AC_LANG_SOURCE([[int main() { return (0); }]])],[found=yes],[found=no],[found=no])
LIBS=$ac_libs
fi
@@ -2285,7 +2288,7 @@ AC_DEFUN([PHP_TEST_WRITE_STDOUT],[
#define TEXT "This is the test message -- "
-main()
+int main()
{
int n;
diff --git a/configure.ac b/configure.ac
index d759b027517e5..e15b83ca25296 100644
--- a/configure.ac
+++ b/configure.ac
@@ -665,6 +665,8 @@
#include <string.h>
#include <netdb.h>
#include <sys/types.h>
+#include <string.h>
+#include <stdlib.h>
#ifndef AF_INET
# include <sys/socket.h>
#endif
diff --git a/ext/standard/config.m4 b/ext/standard/config.m4
index 9f85ec2b7080d..5b49e5d661f3c 100644
--- a/ext/standard/config.m4
+++ b/ext/standard/config.m4
@@ -71,6 +71,9 @@ AC_CACHE_CHECK(for standard DES crypt, ac_cv_crypt_des,[
#include <crypt.h>
#endif
+#include <stdlib.h>
+#include <string.h>
+
int main() {
#if HAVE_CRYPT
char *encrypted = crypt("rasmuslerdorf","rl");
@@ -98,6 +101,9 @@ AC_CACHE_CHECK(for extended DES crypt, ac_cv_crypt_ext_des,[
#include <crypt.h>
#endif
+#include <stdlib.h>
+#include <string.h>
+
int main() {
#if HAVE_CRYPT
char *encrypted = crypt("rasmuslerdorf","_J9..rasm");
@@ -125,6 +131,9 @@ AC_RUN_IFELSE([AC_LANG_SOURCE([[
#include <crypt.h>
#endif
+#include <stdlib.h>
+#include <string.h>
+
int main() {
#if HAVE_CRYPT
char salt[15], answer[40];
@@ -162,6 +171,9 @@ AC_RUN_IFELSE([AC_LANG_SOURCE([[
#include <crypt.h>
#endif
+#include <stdlib.h>
+#include <string.h>
+
int main() {
#if HAVE_CRYPT
char salt[30], answer[70];
@@ -196,6 +208,9 @@ AC_RUN_IFELSE([AC_LANG_SOURCE([[
#include <crypt.h>
#endif
+#include <stdlib.h>
+#include <string.h>
+
int main() {
#if HAVE_CRYPT
char salt[21], answer[21+86];
@@ -229,6 +244,9 @@ AC_RUN_IFELSE([AC_LANG_SOURCE([[
#include <crypt.h>
#endif
+#include <stdlib.h>
+#include <string.h>
+
int main() {
#if HAVE_CRYPT
char salt[21], answer[21+43];
@@ -0,0 +1,662 @@
From 1fa2356f4f580d2df4068809a4aba6d5356a22e6 Mon Sep 17 00:00:00 2001
From: Niels Dossche <7771979+nielsdos@users.noreply.github.com>
Date: Fri, 17 Nov 2023 19:45:40 +0100
Subject: [PATCH 1/4] Fix GH-12702: libxml2 2.12.0 issue building from src
Fixes GH-12702.
Co-authored-by: nono303 <github@nono303.net>
Upstream-Status: Backport [6a76e5d0a2dcf46b4ab74cc3ffcbfeb860c4fdb3]
---
ext/dom/document.c | 1 +
ext/libxml/php_libxml.h | 1 +
2 files changed, 2 insertions(+)
diff --git a/ext/dom/document.c b/ext/dom/document.c
index b478e1a1aa..707a1fbb20 100644
--- a/ext/dom/document.c
+++ b/ext/dom/document.c
@@ -25,6 +25,7 @@
#if HAVE_LIBXML && HAVE_DOM
#include "php_dom.h"
#include <libxml/SAX.h>
+#include <libxml/xmlsave.h>
#ifdef LIBXML_SCHEMAS_ENABLED
#include <libxml/relaxng.h>
#include <libxml/xmlschemas.h>
diff --git a/ext/libxml/php_libxml.h b/ext/libxml/php_libxml.h
index cf936e95de..9bbcbf6783 100644
--- a/ext/libxml/php_libxml.h
+++ b/ext/libxml/php_libxml.h
@@ -37,6 +37,7 @@ extern zend_module_entry libxml_module_entry;
#include "zend_smart_str.h"
#include <libxml/tree.h>
+#include <libxml/parser.h>
#define LIBXML_SAVE_NOEMPTYTAG 1<<2
--
2.43.0
From c2a134e08fe4ac4a2ed753548a18fc27da8ae2e1 Mon Sep 17 00:00:00 2001
From: Niels Dossche <7771979+nielsdos@users.noreply.github.com>
Date: Fri, 1 Dec 2023 18:03:35 +0100
Subject: [PATCH 2/4] Fix libxml2 2.12 build due to API breaks
See https://github.com/php/php-src/actions/runs/7062192818/job/19225478601
---
ext/libxml/libxml.c | 14 ++++++++++----
ext/soap/php_sdl.c | 2 +-
2 files changed, 11 insertions(+), 5 deletions(-)
diff --git a/ext/libxml/libxml.c b/ext/libxml/libxml.c
index d343135b98..b54ab40953 100644
--- a/ext/libxml/libxml.c
+++ b/ext/libxml/libxml.c
@@ -530,7 +530,11 @@ static int _php_libxml_free_error(xmlErrorPtr error)
return 1;
}
-static void _php_list_set_error_structure(xmlErrorPtr error, const char *msg)
+#if LIBXML_VERSION >= 21200
+static void _php_list_set_error_structure(const xmlError *error, const char *msg)
+#else
+static void _php_list_set_error_structure(xmlError *error, const char *msg)
+#endif
{
xmlError error_copy;
int ret;
@@ -782,7 +786,11 @@ PHP_LIBXML_API void php_libxml_ctx_warning(void *ctx, const char *msg, ...)
va_end(args);
}
+#if LIBXML_VERSION >= 21200
+PHP_LIBXML_API void php_libxml_structured_error_handler(void *userData, const xmlError *error)
+#else
PHP_LIBXML_API void php_libxml_structured_error_handler(void *userData, xmlErrorPtr error)
+#endif
{
_php_list_set_error_structure(error, NULL);
@@ -1061,9 +1069,7 @@ static PHP_FUNCTION(libxml_use_internal_errors)
Retrieve last error from libxml */
static PHP_FUNCTION(libxml_get_last_error)
{
- xmlErrorPtr error;
-
- error = xmlGetLastError();
+ const xmlError *error = xmlGetLastError();
if (error) {
object_init_ex(return_value, libxmlerror_class_entry);
diff --git a/ext/soap/php_sdl.c b/ext/soap/php_sdl.c
index 26a23f57db..3df532a2d6 100644
--- a/ext/soap/php_sdl.c
+++ b/ext/soap/php_sdl.c
@@ -333,7 +333,7 @@ static void load_wsdl_ex(zval *this_ptr, char *struri, sdlCtx *ctx, int include)
sdl_restore_uri_credentials(ctx);
if (!wsdl) {
- xmlErrorPtr xmlErrorPtr = xmlGetLastError();
+ const xmlError *xmlErrorPtr = xmlGetLastError();
if (xmlErrorPtr) {
soap_error2(E_ERROR, "Parsing WSDL: Couldn't load from '%s' : %s", struri, xmlErrorPtr->message);
--
2.43.0
From f9da49aa0a5b033c4b1e8072b9c0915d7672f34e Mon Sep 17 00:00:00 2001
From: Niels Dossche <7771979+nielsdos@users.noreply.github.com>
Date: Sat, 29 Apr 2023 21:07:50 +0200
Subject: [PATCH 3/4] Fix GH-11160: Few tests failed building with new libxml
2.11.0
It's possible to categorise the failures into 2 categories:
- Changed error message. In this case we either duplicate the test and
modify the error message. Or if the change in error message is
small, we use the EXPECTF matchers to make the test compatible with both
old and new versions of libxml2.
- Missing warnings. This is caused by a change in libxml2 where the
parser started using SAX APIs internally [1]. In this case the
error_type passed to php_libxml_internal_error_handler() changed from
PHP_LIBXML_ERROR to PHP_LIBXML_CTX_WARNING because it internally
started to use the SAX handlers instead of the generic handlers.
However, for the SAX handlers the current input stack is empty, so
nothing is actually printed. I fixed this by falling back to a
regular warning without a filename & line number reference, which
mimicks the old behaviour. Furthermore, this change now also shows
an additional warning in a test which was previously hidden.
[1] https://gitlab.gnome.org/GNOME/libxml2/-/commit/9a82b94a94bd310db426edd453b0f38c6c8f69f5
Closes GH-11162.
---
.../DOMDocument_loadXML_error2_gte2_11.phpt | 34 +++++++
...> DOMDocument_loadXML_error2_pre2_11.phpt} | 4 +
.../DOMDocument_load_error2_gte2_11.phpt | 34 +++++++
...t => DOMDocument_load_error2_pre2_11.phpt} | 4 +
ext/libxml/libxml.c | 2 +
ext/libxml/tests/bug61367-read_2.phpt | 2 +-
.../tests/libxml_disable_entity_loader_2.phpt | 2 +-
...set_external_entity_loader_variation2.phpt | 2 +
ext/xml/tests/bug26614_libxml_gte2_11.phpt | 95 +++++++++++++++++++
...bxml.phpt => bug26614_libxml_pre2_11.phpt} | 1 +
10 files changed, 178 insertions(+), 2 deletions(-)
create mode 100644 ext/dom/tests/DOMDocument_loadXML_error2_gte2_11.phpt
rename ext/dom/tests/{DOMDocument_loadXML_error2.phpt => DOMDocument_loadXML_error2_pre2_11.phpt} (90%)
create mode 100644 ext/dom/tests/DOMDocument_load_error2_gte2_11.phpt
rename ext/dom/tests/{DOMDocument_load_error2.phpt => DOMDocument_load_error2_pre2_11.phpt} (90%)
create mode 100644 ext/xml/tests/bug26614_libxml_gte2_11.phpt
rename ext/xml/tests/{bug26614_libxml.phpt => bug26614_libxml_pre2_11.phpt} (96%)
diff --git a/ext/dom/tests/DOMDocument_loadXML_error2_gte2_11.phpt b/ext/dom/tests/DOMDocument_loadXML_error2_gte2_11.phpt
new file mode 100644
index 0000000000..ff5ceb3fbe
--- /dev/null
+++ b/ext/dom/tests/DOMDocument_loadXML_error2_gte2_11.phpt
@@ -0,0 +1,34 @@
+--TEST--
+Test DOMDocument::loadXML() detects not-well formed XML
+--SKIPIF--
+<?php
+if (LIBXML_VERSION < 21100) die('skip libxml2 test variant for version >= 2.11');
+?>
+--DESCRIPTION--
+This test verifies the method detects attributes values not closed between " or '
+Environment variables used in the test:
+- XML_FILE: the xml file to load
+- LOAD_OPTIONS: the second parameter to pass to the method
+- EXPECTED_RESULT: the expected result
+--CREDITS--
+Antonio Diaz Ruiz <dejalatele@gmail.com>
+--INI--
+assert.bail=true
+--EXTENSIONS--
+dom
+--ENV--
+XML_FILE=/not_well_formed2.xml
+LOAD_OPTIONS=0
+EXPECTED_RESULT=0
+--FILE_EXTERNAL--
+domdocumentloadxml_test_method.inc
+--EXPECTF--
+Warning: DOMDocument::loadXML(): AttValue: " or ' expected in Entity, line: 4 in %s on line %d
+
+Warning: DOMDocument::loadXML(): internal error: xmlParseStartTag: problem parsing attributes in Entity, line: 4 in %s on line %d
+
+Warning: DOMDocument::loadXML(): Couldn't find end of Start Tag book line 4 in Entity, line: 4 in %s on line %d
+
+Warning: DOMDocument::loadXML(): Opening and ending tag mismatch: books line 3 and book in Entity, line: 7 in %s on line %d
+
+Warning: DOMDocument::loadXML(): Extra content at the end of the document in Entity, line: 8 in %s on line %d
diff --git a/ext/dom/tests/DOMDocument_loadXML_error2.phpt b/ext/dom/tests/DOMDocument_loadXML_error2_pre2_11.phpt
similarity index 90%
rename from ext/dom/tests/DOMDocument_loadXML_error2.phpt
rename to ext/dom/tests/DOMDocument_loadXML_error2_pre2_11.phpt
index 6d56a317ed..0e36d20905 100644
--- a/ext/dom/tests/DOMDocument_loadXML_error2.phpt
+++ b/ext/dom/tests/DOMDocument_loadXML_error2_pre2_11.phpt
@@ -1,5 +1,9 @@
--TEST--
Test DOMDocument::loadXML() detects not-well formed XML
+--SKIPIF--
+<?php
+if (LIBXML_VERSION >= 21100) die('skip libxml2 test variant for version < 2.11');
+?>
--DESCRIPTION--
This test verifies the method detects attributes values not closed between " or '
Environment variables used in the test:
diff --git a/ext/dom/tests/DOMDocument_load_error2_gte2_11.phpt b/ext/dom/tests/DOMDocument_load_error2_gte2_11.phpt
new file mode 100644
index 0000000000..32b6bf1611
--- /dev/null
+++ b/ext/dom/tests/DOMDocument_load_error2_gte2_11.phpt
@@ -0,0 +1,34 @@
+--TEST--
+Test DOMDocument::load() detects not-well formed
+--SKIPIF--
+<?php
+if (LIBXML_VERSION < 21100) die('skip libxml2 test variant for version >= 2.11');
+?>
+--DESCRIPTION--
+This test verifies the method detects attributes values not closed between " or '
+Environment variables used in the test:
+- XML_FILE: the xml file to load
+- LOAD_OPTIONS: the second parameter to pass to the method
+- EXPECTED_RESULT: the expected result
+--CREDITS--
+Antonio Diaz Ruiz <dejalatele@gmail.com>
+--INI--
+assert.bail=true
+--EXTENSIONS--
+dom
+--ENV--
+XML_FILE=/not_well_formed2.xml
+LOAD_OPTIONS=0
+EXPECTED_RESULT=0
+--FILE_EXTERNAL--
+domdocumentload_test_method.inc
+--EXPECTF--
+Warning: DOMDocument::load(): AttValue: " or ' expected in %s on line %d
+
+Warning: DOMDocument::load(): internal error: xmlParseStartTag: problem parsing attributes in %s on line %d
+
+Warning: DOMDocument::load(): Couldn't find end of Start Tag book line 4 in %s on line %d
+
+Warning: DOMDocument::load(): Opening and ending tag mismatch: books line 3 and book in %s on line %d
+
+Warning: DOMDocument::load(): Extra content at the end of the document in %s on line %d
diff --git a/ext/dom/tests/DOMDocument_load_error2.phpt b/ext/dom/tests/DOMDocument_load_error2_pre2_11.phpt
similarity index 90%
rename from ext/dom/tests/DOMDocument_load_error2.phpt
rename to ext/dom/tests/DOMDocument_load_error2_pre2_11.phpt
index f450cf1654..b97fff9d2f 100644
--- a/ext/dom/tests/DOMDocument_load_error2.phpt
+++ b/ext/dom/tests/DOMDocument_load_error2_pre2_11.phpt
@@ -1,5 +1,9 @@
--TEST--
Test DOMDocument::load() detects not-well formed XML
+--SKIPIF--
+<?php
+if (LIBXML_VERSION >= 21100) die('skip libxml2 test variant for version < 2.11');
+?>
--DESCRIPTION--
This test verifies the method detects attributes values not closed between " or '
Environment variables used in the test:
diff --git a/ext/libxml/libxml.c b/ext/libxml/libxml.c
index b54ab40953..7917f636a9 100644
--- a/ext/libxml/libxml.c
+++ b/ext/libxml/libxml.c
@@ -578,6 +578,8 @@ static void php_libxml_ctx_error_level(int level, void *ctx, const char *msg)
} else {
php_error_docref(NULL, level, "%s in Entity, line: %d", msg, parser->input->line);
}
+ } else {
+ php_error_docref(NULL, E_WARNING, "%s", msg);
}
}
diff --git a/ext/libxml/tests/bug61367-read_2.phpt b/ext/libxml/tests/bug61367-read_2.phpt
index 8cc0b50144..12743adab1 100644
--- a/ext/libxml/tests/bug61367-read_2.phpt
+++ b/ext/libxml/tests/bug61367-read_2.phpt
@@ -55,6 +55,6 @@ bool(true)
int(4)
bool(true)
-Warning: DOMDocument::loadXML(): I/O warning : failed to load external entity "file:///%s/test_bug_61367-read/bad" in %s on line %d
+Warning: DOMDocument::loadXML(): %Sfailed to load external entity "file:///%s/test_bug_61367-read/bad" in %s on line %d
Notice: Trying to get property 'nodeValue' of non-object in %s on line %d
diff --git a/ext/libxml/tests/libxml_disable_entity_loader_2.phpt b/ext/libxml/tests/libxml_disable_entity_loader_2.phpt
index 845bd4bbe3..55d8e61ee0 100644
--- a/ext/libxml/tests/libxml_disable_entity_loader_2.phpt
+++ b/ext/libxml/tests/libxml_disable_entity_loader_2.phpt
@@ -36,6 +36,6 @@ echo "Done\n";
bool(true)
bool(false)
-Warning: DOMDocument::loadXML(): I/O warning : failed to load external entity "%s" in %s on line %d
+Warning: DOMDocument::loadXML(): %Sfailed to load external entity "%s" in %s on line %d
bool(true)
Done
diff --git a/ext/libxml/tests/libxml_set_external_entity_loader_variation2.phpt b/ext/libxml/tests/libxml_set_external_entity_loader_variation2.phpt
index e51869cf47..0664de1ea6 100644
--- a/ext/libxml/tests/libxml_set_external_entity_loader_variation2.phpt
+++ b/ext/libxml/tests/libxml_set_external_entity_loader_variation2.phpt
@@ -38,6 +38,8 @@ echo "Done.\n";
string(10) "-//FOO/BAR"
string(%d) "%sfoobar.dtd"
+Warning: DOMDocument::validate(): Failed to load external entity "-//FOO/BAR" in %s on line %d
+
Warning: DOMDocument::validate(): Could not load the external subset "foobar.dtd" in %s on line %d
bool(false)
bool(true)
diff --git a/ext/xml/tests/bug26614_libxml_gte2_11.phpt b/ext/xml/tests/bug26614_libxml_gte2_11.phpt
new file mode 100644
index 0000000000..9a81b67686
--- /dev/null
+++ b/ext/xml/tests/bug26614_libxml_gte2_11.phpt
@@ -0,0 +1,95 @@
+--TEST--
+Bug #26614 (CDATA sections skipped on line count)
+--EXTENSIONS--
+xml
+--SKIPIF--
+<?php
+if (!defined("LIBXML_VERSION")) die('skip libxml2 test');
+if (LIBXML_VERSION < 21100) die('skip libxml2 test variant for version >= 2.11');
+?>
+--FILE--
+<?php
+/*
+this test works fine with Expat but fails with libxml
+which we now use as default
+
+further investigation has shown that not only line count
+is skipped on CDATA sections but that libxml does also
+show different column numbers and byte positions depending
+on context and in opposition to what one would expect to
+see and what good old Expat reported just fine ...
+*/
+
+$xmls = array();
+
+// Case 1: CDATA Sections
+$xmls["CDATA"] ='<?xml version="1.0" encoding="iso-8859-1" ?>
+<data>
+<![CDATA[
+multi
+line
+CDATA
+block
+]]>
+</data>';
+
+// Case 2: replace some characters so that we get comments instead
+$xmls["Comment"] ='<?xml version="1.0" encoding="iso-8859-1" ?>
+<data>
+<!-- ATA[
+multi
+line
+CDATA
+block
+-->
+</data>';
+
+// Case 3: replace even more characters so that only textual data is left
+$xmls["Text"] ='<?xml version="1.0" encoding="iso-8859-1" ?>
+<data>
+-!-- ATA[
+multi
+line
+CDATA
+block
+---
+</data>';
+
+function startElement($parser, $name, $attrs) {
+ printf("<$name> at line %d, col %d (byte %d)\n",
+ xml_get_current_line_number($parser),
+ xml_get_current_column_number($parser),
+ xml_get_current_byte_index($parser));
+}
+
+function endElement($parser, $name) {
+ printf("</$name> at line %d, col %d (byte %d)\n",
+ xml_get_current_line_number($parser),
+ xml_get_current_column_number($parser),
+ xml_get_current_byte_index($parser));
+}
+
+function characterData($parser, $data) {
+ // dummy
+}
+
+foreach ($xmls as $desc => $xml) {
+ echo "$desc\n";
+ $xml_parser = xml_parser_create();
+ xml_set_element_handler($xml_parser, "startElement", "endElement");
+ xml_set_character_data_handler($xml_parser, "characterData");
+ if (!xml_parse($xml_parser, $xml, true))
+ echo "Error: ".xml_error_string(xml_get_error_code($xml_parser))."\n";
+ xml_parser_free($xml_parser);
+}
+?>
+--EXPECTF--
+CDATA
+<DATA> at line 2, col %d (byte 50)
+</DATA> at line 9, col %d (byte 96)
+Comment
+<DATA> at line 2, col %d (byte 50)
+</DATA> at line 9, col %d (byte 96)
+Text
+<DATA> at line 2, col %d (byte 50)
+</DATA> at line 9, col %d (byte 96)
diff --git a/ext/xml/tests/bug26614_libxml.phpt b/ext/xml/tests/bug26614_libxml_pre2_11.phpt
similarity index 96%
rename from ext/xml/tests/bug26614_libxml.phpt
rename to ext/xml/tests/bug26614_libxml_pre2_11.phpt
index 3ddd35ed0e..afacaa1c59 100644
--- a/ext/xml/tests/bug26614_libxml.phpt
+++ b/ext/xml/tests/bug26614_libxml_pre2_11.phpt
@@ -4,6 +4,7 @@ Bug #26614 (CDATA sections skipped on line count)
<?php
require_once("skipif.inc");
if (!defined("LIBXML_VERSION")) die('skip libxml2 test');
+if (LIBXML_VERSION >= 21100) die('skip libxml2 test variant for version < 2.11');
?>
--FILE--
<?php
--
2.43.0
From b2ac6c4fe4213258e7e9489ef50fe3afb2fdf4be Mon Sep 17 00:00:00 2001
From: Niels Dossche <7771979+nielsdos@users.noreply.github.com>
Date: Wed, 29 Nov 2023 20:49:29 +0100
Subject: [PATCH 4/4] Test fixes for libxml2 2.12.0
---
ext/dom/tests/DOMDocument_loadXML_error1.phpt | 4 +++
.../DOMDocument_loadXML_error1_gte2_12.phpt | 26 ++++++++++++++++
.../DOMDocument_loadXML_error2_gte2_11.phpt | 2 +-
.../DOMDocument_loadXML_error2_gte2_12.phpt | 30 +++++++++++++++++++
ext/dom/tests/DOMDocument_load_error1.phpt | 4 +++
.../DOMDocument_load_error1_gte2_12.phpt | 26 ++++++++++++++++
.../DOMDocument_load_error2_gte2_11.phpt | 2 +-
.../DOMDocument_load_error2_gte2_12.phpt | 30 +++++++++++++++++++
ext/xml/tests/bug81351.phpt | 4 +--
9 files changed, 124 insertions(+), 4 deletions(-)
create mode 100644 ext/dom/tests/DOMDocument_loadXML_error1_gte2_12.phpt
create mode 100644 ext/dom/tests/DOMDocument_loadXML_error2_gte2_12.phpt
create mode 100644 ext/dom/tests/DOMDocument_load_error1_gte2_12.phpt
create mode 100644 ext/dom/tests/DOMDocument_load_error2_gte2_12.phpt
diff --git a/ext/dom/tests/DOMDocument_loadXML_error1.phpt b/ext/dom/tests/DOMDocument_loadXML_error1.phpt
index 4d3b81db79..0549d67630 100644
--- a/ext/dom/tests/DOMDocument_loadXML_error1.phpt
+++ b/ext/dom/tests/DOMDocument_loadXML_error1.phpt
@@ -1,5 +1,9 @@
--TEST--
Test DOMDocument::loadXML() detects not-well formed XML
+--SKIPIF--
+<?php
+if (LIBXML_VERSION >= 21200) die('skip libxml2 test variant for version < 2.12');
+?>
--DESCRIPTION--
This test verifies the method detects an opening and ending tag mismatch
Environment variables used in the test:
diff --git a/ext/dom/tests/DOMDocument_loadXML_error1_gte2_12.phpt b/ext/dom/tests/DOMDocument_loadXML_error1_gte2_12.phpt
new file mode 100644
index 0000000000..e1ded0ffad
--- /dev/null
+++ b/ext/dom/tests/DOMDocument_loadXML_error1_gte2_12.phpt
@@ -0,0 +1,26 @@
+--TEST--
+Test DOMDocument::loadXML() detects not-well formed XML
+--SKIPIF--
+<?php
+if (LIBXML_VERSION < 21200) die('skip libxml2 test variant for version >= 2.12');
+?>
+--DESCRIPTION--
+This test verifies the method detects an opening and ending tag mismatch
+Environment variables used in the test:
+- XML_FILE: the xml file to load
+- LOAD_OPTIONS: the second parameter to pass to the method
+- EXPECTED_RESULT: the expected result
+--CREDITS--
+Antonio Diaz Ruiz <dejalatele@gmail.com>
+--EXTENSIONS--
+dom
+--ENV--
+XML_FILE=/not_well_formed.xml
+LOAD_OPTIONS=0
+EXPECTED_RESULT=0
+--FILE_EXTERNAL--
+domdocumentloadxml_test_method.inc
+--EXPECTF--
+Warning: DOMDocument::load%r(XML){0,1}%r(): Opening and ending tag mismatch: title line 5 and book %s
+
+Warning: DOMDocument::load%r(XML){0,1}%r(): %rexpected '>'|Opening and ending tag mismatch: book line (4|5) and books%r %s
diff --git a/ext/dom/tests/DOMDocument_loadXML_error2_gte2_11.phpt b/ext/dom/tests/DOMDocument_loadXML_error2_gte2_11.phpt
index ff5ceb3fbe..f52d334813 100644
--- a/ext/dom/tests/DOMDocument_loadXML_error2_gte2_11.phpt
+++ b/ext/dom/tests/DOMDocument_loadXML_error2_gte2_11.phpt
@@ -2,7 +2,7 @@
Test DOMDocument::loadXML() detects not-well formed XML
--SKIPIF--
<?php
-if (LIBXML_VERSION < 21100) die('skip libxml2 test variant for version >= 2.11');
+if (LIBXML_VERSION < 21100 || LIBXML_VERSION >= 21200) die('skip libxml2 test variant for version >= 2.11 && <= 2.12');
?>
--DESCRIPTION--
This test verifies the method detects attributes values not closed between " or '
diff --git a/ext/dom/tests/DOMDocument_loadXML_error2_gte2_12.phpt b/ext/dom/tests/DOMDocument_loadXML_error2_gte2_12.phpt
new file mode 100644
index 0000000000..6a3ff5841f
--- /dev/null
+++ b/ext/dom/tests/DOMDocument_loadXML_error2_gte2_12.phpt
@@ -0,0 +1,30 @@
+--TEST--
+Test DOMDocument::loadXML() detects not-well formed XML
+--SKIPIF--
+<?php
+if (LIBXML_VERSION < 21200) die('skip libxml2 test variant for version >= 2.12');
+?>
+--DESCRIPTION--
+This test verifies the method detects attributes values not closed between " or '
+Environment variables used in the test:
+- XML_FILE: the xml file to load
+- LOAD_OPTIONS: the second parameter to pass to the method
+- EXPECTED_RESULT: the expected result
+--CREDITS--
+Antonio Diaz Ruiz <dejalatele@gmail.com>
+--EXTENSIONS--
+dom
+--ENV--
+XML_FILE=/not_well_formed2.xml
+LOAD_OPTIONS=0
+EXPECTED_RESULT=0
+--FILE_EXTERNAL--
+domdocumentloadxml_test_method.inc
+--EXPECTF--
+Warning: DOMDocument::loadXML(): AttValue: " or ' expected in Entity, line: 4 in %s on line %d
+
+Warning: DOMDocument::loadXML(): internal error: xmlParseStartTag: problem parsing attributes in Entity, line: 4 in %s on line %d
+
+Warning: DOMDocument::loadXML(): Couldn't find end of Start Tag book line 4 in Entity, line: 4 in %s on line %d
+
+Warning: DOMDocument::loadXML(): Opening and ending tag mismatch: books line 3 and book in Entity, line: 7 in %s on line %d
diff --git a/ext/dom/tests/DOMDocument_load_error1.phpt b/ext/dom/tests/DOMDocument_load_error1.phpt
index 8ac181d769..4416f5f6fe 100644
--- a/ext/dom/tests/DOMDocument_load_error1.phpt
+++ b/ext/dom/tests/DOMDocument_load_error1.phpt
@@ -1,5 +1,9 @@
--TEST--
Test DOMDocument::load() detects not-well formed XML
+--SKIPIF--
+<?php
+if (LIBXML_VERSION >= 21200) die('skip libxml2 test variant for version < 2.12');
+?>
--DESCRIPTION--
This test verifies the method detects an opening and ending tag mismatch
Environment variables used in the test:
diff --git a/ext/dom/tests/DOMDocument_load_error1_gte2_12.phpt b/ext/dom/tests/DOMDocument_load_error1_gte2_12.phpt
new file mode 100644
index 0000000000..183c8406fd
--- /dev/null
+++ b/ext/dom/tests/DOMDocument_load_error1_gte2_12.phpt
@@ -0,0 +1,26 @@
+--TEST--
+Test DOMDocument::load() detects not-well formed XML
+--SKIPIF--
+<?php
+if (LIBXML_VERSION < 21200) die('skip libxml2 test variant for version >= 2.12');
+?>
+--DESCRIPTION--
+This test verifies the method detects an opening and ending tag mismatch
+Environment variables used in the test:
+- XML_FILE: the xml file to load
+- LOAD_OPTIONS: the second parameter to pass to the method
+- EXPECTED_RESULT: the expected result
+--CREDITS--
+Antonio Diaz Ruiz <dejalatele@gmail.com>
+--EXTENSIONS--
+dom
+--ENV--
+XML_FILE=/not_well_formed.xml
+LOAD_OPTIONS=0
+EXPECTED_RESULT=0
+--FILE_EXTERNAL--
+domdocumentload_test_method.inc
+--EXPECTF--
+Warning: DOMDocument::load%r(XML){0,1}%r(): Opening and ending tag mismatch: title line 5 and book %s
+
+Warning: DOMDocument::load%r(XML){0,1}%r(): %rexpected '>'|Opening and ending tag mismatch: book line (4|5) and books%r %s
diff --git a/ext/dom/tests/DOMDocument_load_error2_gte2_11.phpt b/ext/dom/tests/DOMDocument_load_error2_gte2_11.phpt
index 32b6bf1611..4d9f992b3b 100644
--- a/ext/dom/tests/DOMDocument_load_error2_gte2_11.phpt
+++ b/ext/dom/tests/DOMDocument_load_error2_gte2_11.phpt
@@ -2,7 +2,7 @@
Test DOMDocument::load() detects not-well formed
--SKIPIF--
<?php
-if (LIBXML_VERSION < 21100) die('skip libxml2 test variant for version >= 2.11');
+if (LIBXML_VERSION < 21100 || LIBXML_VERSION >= 21200) die('skip libxml2 test variant for version >= 2.11 && <= 2.12');
?>
--DESCRIPTION--
This test verifies the method detects attributes values not closed between " or '
diff --git a/ext/dom/tests/DOMDocument_load_error2_gte2_12.phpt b/ext/dom/tests/DOMDocument_load_error2_gte2_12.phpt
new file mode 100644
index 0000000000..4fadf41736
--- /dev/null
+++ b/ext/dom/tests/DOMDocument_load_error2_gte2_12.phpt
@@ -0,0 +1,30 @@
+--TEST--
+Test DOMDocument::load() detects not-well formed
+--SKIPIF--
+<?php
+if (LIBXML_VERSION < 21200) die('skip libxml2 test variant for version >= 2.12');
+?>
+--DESCRIPTION--
+This test verifies the method detects attributes values not closed between " or '
+Environment variables used in the test:
+- XML_FILE: the xml file to load
+- LOAD_OPTIONS: the second parameter to pass to the method
+- EXPECTED_RESULT: the expected result
+--CREDITS--
+Antonio Diaz Ruiz <dejalatele@gmail.com>
+--EXTENSIONS--
+dom
+--ENV--
+XML_FILE=/not_well_formed2.xml
+LOAD_OPTIONS=0
+EXPECTED_RESULT=0
+--FILE_EXTERNAL--
+domdocumentload_test_method.inc
+--EXPECTF--
+Warning: DOMDocument::load(): AttValue: " or ' expected in %s on line %d
+
+Warning: DOMDocument::load(): internal error: xmlParseStartTag: problem parsing attributes in %s on line %d
+
+Warning: DOMDocument::load(): Couldn't find end of Start Tag book line 4 in %s on line %d
+
+Warning: DOMDocument::load(): Opening and ending tag mismatch: books line 3 and book in %s on line %d
diff --git a/ext/xml/tests/bug81351.phpt b/ext/xml/tests/bug81351.phpt
index 19e4ca590b..dc934001be 100644
--- a/ext/xml/tests/bug81351.phpt
+++ b/ext/xml/tests/bug81351.phpt
@@ -23,6 +23,6 @@ $code = xml_get_error_code($parser);
$error = xml_error_string($code);
echo "xml_parse returned $success, xml_get_error_code = $code, xml_error_string = $error\r\n";
?>
---EXPECT--
+--EXPECTF--
xml_parse returned 1, xml_get_error_code = 0, xml_error_string = No error
-xml_parse returned 0, xml_get_error_code = 5, xml_error_string = Invalid document end
+%rxml_parse returned 0, xml_get_error_code = 5, xml_error_string = Invalid document end|xml_parse returned 0, xml_get_error_code = 77, xml_error_string = Tag not finished%r
--
2.43.0
+189
View File
@@ -0,0 +1,189 @@
From 7437aaae38cf4b3357e7580f9e22fd4a403b6c23 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/7] crypt: Fix validation of malformed BCrypt hashes
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
PHPs 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 PHPs own crypt_blowfish
implementation that was added in 1e820eca02dcf322b41fd2fe4ed2a6b8309f8ab5.
No clear reason is given for the PHP Hacks existence. This commit removes it,
because BCrypt hashes containing a `$` character in their salt are not valid
BCrypt hashes.
(cherry picked from commit c840f71524067aa474c00c3eacfb83bd860bfc8a)
Upstream-Status: Backport [c840f71524067aa474c00c3eacfb83bd860bfc8a]
---
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 c1f945f29ed..aa7e1bc2e68 100644
--- a/ext/standard/crypt_blowfish.c
+++ b/ext/standard/crypt_blowfish.c
@@ -376,7 +376,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; \
@@ -404,13 +403,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 00000000000..32e335f4b08
--- /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 ed0281b588a6840cb95f3134a4e68847a3be5bb7 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/7] crypt: Fix possible buffer overread in php_crypt()
(cherry picked from commit a92acbad873a05470af1a47cb785a18eadd827b5)
---
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 92430b69f77..04487f3fe5a 100644
--- a/ext/standard/crypt.c
+++ b/ext/standard/crypt.c
@@ -151,6 +151,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 00000000000..085bc8a2390
--- /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
+109
View File
@@ -0,0 +1,109 @@
From 0cfca9aa1395271833848daec0bace51d965531d 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)
Upstream-Status: Backport [126d517ce240e9f638d9a5eaa509eaca49ef562a]
---
NEWS | 6 ++++++
ext/soap/php_http.c | 21 +++++++++++++--------
2 files changed, 19 insertions(+), 8 deletions(-)
diff --git a/ext/soap/php_http.c b/ext/soap/php_http.c
index ee3dcbdc9a..e3a9afdbe9 100644
--- a/ext/soap/php_http.c
+++ b/ext/soap/php_http.c
@@ -666,18 +666,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];
- zend_long nonce;
+ unsigned char nonce[16];
PHP_MD5_CTX md5ctx;
unsigned char hash[16];
- php_random_bytes_throw(&nonce, sizeof(nonce));
- nonce &= 0x7fffffff;
+ 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_MD5Init(&md5ctx);
- snprintf(cnonce, sizeof(cnonce), ZEND_LONG_FMT, nonce);
- PHP_MD5Update(&md5ctx, (unsigned char*)cnonce, strlen(cnonce));
- PHP_MD5Final(hash, &md5ctx);
- make_digest(cnonce, hash);
+ 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 40439039c224bb8cdebd1b7b3d03b8cc11e7cce7 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
---
ext/soap/php_http.c | 1 +
1 file changed, 1 insertion(+)
diff --git a/ext/soap/php_http.c b/ext/soap/php_http.c
index e3a9afdbe9f..912b8e341d8 100644
--- a/ext/soap/php_http.c
+++ b/ext/soap/php_http.c
@@ -22,6 +22,7 @@
#include "ext/standard/base64.h"
#include "ext/standard/md5.h"
#include "ext/standard/php_random.h"
+#include "ext/hash/php_hash.h"
static char *get_http_header_value_nodup(char *headers, char *type, size_t *len);
static char *get_http_header_value(char *headers, char *type);
--
File diff suppressed because one or more lines are too long
@@ -0,0 +1,97 @@
From 494de65139592da0e5e5b6fdf198c2f9c762f4d6 Mon Sep 17 00:00:00 2001
From: Jakub Zelenka <bukka@php.net>
Date: Fri, 8 Nov 2024 23:43:47 +0100
Subject: [PATCH 3/7] Fix GHSA-c5f2-jwm7-mmq2: stream HTTP fulluri CRLF
injection
(cherry picked from commit 426a6d4539ebee34879ac5de857036bb6ff0e732)
(cherry picked from commit bc1f192102dd8cbda028e40aa31604c4885d387c)
(cherry picked from commit 8d130e16fbfda7d154fedfa0f1ff1d5ad5e26815)
Upstream-Status: Backport
---
ext/standard/http_fopen_wrapper.c | 18 ++++++++----
.../tests/http/ghsa-c5f2-jwm7-mmq2.phpt | 28 +++++++++++++++++++
2 files changed, 40 insertions(+), 6 deletions(-)
create mode 100644 ext/standard/tests/http/ghsa-c5f2-jwm7-mmq2.phpt
diff --git a/ext/standard/http_fopen_wrapper.c b/ext/standard/http_fopen_wrapper.c
index 4d918b21e65..aeeb438f0f9 100644
--- a/ext/standard/http_fopen_wrapper.c
+++ b/ext/standard/http_fopen_wrapper.c
@@ -186,6 +186,11 @@ static php_stream *php_stream_url_wrap_http_ex(php_stream_wrapper *wrapper,
return NULL;
}
+ /* Should we send the entire path in the request line, default to no. */
+ if (context && (tmpzval = php_stream_context_get_option(context, "http", "request_fulluri")) != NULL) {
+ request_fulluri = zend_is_true(tmpzval);
+ }
+
use_ssl = resource->scheme && (ZSTR_LEN(resource->scheme) > 4) && ZSTR_VAL(resource->scheme)[4] == 's';
/* choose default ports */
if (use_ssl && resource->port == 0)
@@ -205,6 +210,13 @@ static php_stream *php_stream_url_wrap_http_ex(php_stream_wrapper *wrapper,
}
}
+ if (request_fulluri && (strchr(path, '\n') != NULL || strchr(path, '\r') != NULL)) {
+ php_stream_wrapper_log_error(wrapper, options, "HTTP wrapper full URI path does not allow CR or LF characters");
+ php_url_free(resource);
+ efree(transport_string);
+ return NULL;
+ }
+
if (context && (tmpzval = php_stream_context_get_option(context, wrapper->wops->label, "timeout")) != NULL) {
double d = zval_get_double(tmpzval);
#ifndef PHP_WIN32
@@ -385,12 +397,6 @@ finish:
smart_str_appends(&req_buf, "GET ");
}
- /* Should we send the entire path in the request line, default to no. */
- if (!request_fulluri && context &&
- (tmpzval = php_stream_context_get_option(context, "http", "request_fulluri")) != NULL) {
- request_fulluri = zend_is_true(tmpzval);
- }
-
if (request_fulluri) {
/* Ask for everything */
smart_str_appends(&req_buf, path);
diff --git a/ext/standard/tests/http/ghsa-c5f2-jwm7-mmq2.phpt b/ext/standard/tests/http/ghsa-c5f2-jwm7-mmq2.phpt
new file mode 100644
index 00000000000..5b2e04f94f2
--- /dev/null
+++ b/ext/standard/tests/http/ghsa-c5f2-jwm7-mmq2.phpt
@@ -0,0 +1,28 @@
+--TEST--
+GHSA-c5f2-jwm7-mmq2 (Configuring a proxy in a stream context might allow for CRLF injection in URIs)
+--INI--
+allow_url_fopen=1
+--CONFLICTS--
+server
+--FILE--
+<?php
+$serverCode = <<<'CODE'
+echo $_SERVER['REQUEST_URI'];
+CODE;
+
+include __DIR__."/../../../../sapi/cli/tests/php_cli_server.inc";
+php_cli_server_start($serverCode, null, []);
+
+$host = PHP_CLI_SERVER_ADDRESS;
+$userinput = "index.php HTTP/1.1\r\nHost: $host\r\n\r\nGET /index2.php HTTP/1.1\r\nHost: $host\r\n\r\nGET /index.php";
+$context = stream_context_create(['http' => ['proxy' => 'tcp://' . $host, 'request_fulluri' => true]]);
+echo file_get_contents("http://$host/$userinput", false, $context);
+?>
+--EXPECTF--
+Warning: file_get_contents(http://localhost:%d/index.php HTTP/1.1
+Host: localhost:%d
+
+GET /index2.php HTTP/1.1
+Host: localhost:%d
+
+GET /index.php): failed to open stream: HTTP wrapper full URI path does not allow CR or LF characters in %s on line %d
--
2.47.0
+121
View File
@@ -0,0 +1,121 @@
From 97546df8d6900b115536c17af9213f1da837b82e Mon Sep 17 00:00:00 2001
From: Niels Dossche <7771979+nielsdos@users.noreply.github.com>
Date: Thu, 24 Oct 2024 22:02:17 +0200
Subject: [PATCH 1/7] Fix GHSA-5hqh-c84r-qjcv: Integer overflow in the dblib
quoter causing OOB writes
(cherry picked from commit d9baa9fed8c3ba692a36b388c0c7762e5102e2e0)
(cherry picked from commit 5d9e54065ed18c51e4f25d8900635f90810c7394)
Upstream-Status: Backport
---
ext/pdo_dblib/dblib_driver.c | 8 ++++++-
ext/pdo_dblib/tests/GHSA-5hqh-c84r-qjcv.phpt | 24 ++++++++++++++++++++
2 files changed, 31 insertions(+), 1 deletion(-)
create mode 100644 ext/pdo_dblib/tests/GHSA-5hqh-c84r-qjcv.phpt
diff --git a/ext/pdo_dblib/dblib_driver.c b/ext/pdo_dblib/dblib_driver.c
index f36451afeeb..1dc75a4d2e3 100644
--- a/ext/pdo_dblib/dblib_driver.c
+++ b/ext/pdo_dblib/dblib_driver.c
@@ -154,6 +154,7 @@ static int dblib_handle_quoter(pdo_dbh_t *dbh, const char *unquoted, size_t unqu
size_t i;
char * q;
+ size_t extralen = 0;
*quotedlen = 0;
if (H->assume_national_character_set_strings) {
@@ -168,7 +169,7 @@ static int dblib_handle_quoter(pdo_dbh_t *dbh, const char *unquoted, size_t unqu
/* Detect quoted length, adding extra char for doubled single quotes */
for (i = 0; i < unquotedlen; i++) {
- if (unquoted[i] == '\'') ++*quotedlen;
+ if (unquoted[i] == '\'') ++extralen;
++*quotedlen;
}
@@ -176,6 +177,11 @@ static int dblib_handle_quoter(pdo_dbh_t *dbh, const char *unquoted, size_t unqu
if (use_national_character_set) {
++*quotedlen; /* N prefix */
}
+ if (UNEXPECTED(*quotedlen > ZSTR_MAX_LEN - extralen)) {
+ return 0;
+ }
+
+ *quotedlen += extralen;
q = *quoted = emalloc(*quotedlen + 1); /* Add byte for terminal null */
if (use_national_character_set) {
*q++ = 'N';
diff --git a/ext/pdo_dblib/tests/GHSA-5hqh-c84r-qjcv.phpt b/ext/pdo_dblib/tests/GHSA-5hqh-c84r-qjcv.phpt
new file mode 100644
index 00000000000..431c61951ee
--- /dev/null
+++ b/ext/pdo_dblib/tests/GHSA-5hqh-c84r-qjcv.phpt
@@ -0,0 +1,24 @@
+--TEST--
+GHSA-5hqh-c84r-qjcv (Integer overflow in the dblib quoter causing OOB writes)
+--EXTENSIONS--
+pdo_dblib
+--SKIPIF--
+<?php
+if (PHP_INT_SIZE != 4) die("skip for 32bit platforms only");
+if (PHP_OS_FAMILY === "Windows") die("skip not for Windows because the virtual address space for application is only 2GiB");
+if (getenv("SKIP_SLOW_TESTS")) die("skip slow test");
+require __DIR__ . '/config.inc';
+getDbConnection();
+?>
+--INI--
+memory_limit=-1
+--FILE--
+<?php
+
+require __DIR__ . '/config.inc';
+$db = getDbConnection();
+var_dump($db->quote(str_repeat("'", 2147483646)));
+
+?>
+--EXPECT--
+bool(false)
--
2.47.0
From 0530cbfe5c3044537de52d8382eba5d69dbac726 Mon Sep 17 00:00:00 2001
From: Niels Dossche <7771979+nielsdos@users.noreply.github.com>
Date: Thu, 24 Oct 2024 22:02:36 +0200
Subject: [PATCH 2/7] Fix GHSA-5hqh-c84r-qjcv: Integer overflow in the firebird
quoter causing OOB writes
(cherry picked from commit 69c5f68fdc3deed9ebce2cc44b4bf5e0c47cd28f)
(cherry picked from commit b4f73be75dbdde970a18cc7a636898b10400fb3f)
---
ext/pdo_firebird/firebird_driver.c | 6 +++++-
1 file changed, 5 insertions(+), 1 deletion(-)
diff --git a/ext/pdo_firebird/firebird_driver.c b/ext/pdo_firebird/firebird_driver.c
index 3e403afd368..5b74290abcc 100644
--- a/ext/pdo_firebird/firebird_driver.c
+++ b/ext/pdo_firebird/firebird_driver.c
@@ -243,7 +243,7 @@ free_statement:
static int firebird_handle_quoter(pdo_dbh_t *dbh, const char *unquoted, size_t unquotedlen, /* {{{ */
char **quoted, size_t *quotedlen, enum pdo_param_type paramtype)
{
- int qcount = 0;
+ size_t qcount = 0;
char const *co, *l, *r;
char *c;
@@ -258,6 +258,10 @@ static int firebird_handle_quoter(pdo_dbh_t *dbh, const char *unquoted, size_t u
/* count the number of ' characters */
for (co = unquoted; (co = strchr(co,'\'')); qcount++, co++);
+ if (UNEXPECTED(unquotedlen + 2 > ZSTR_MAX_LEN - qcount)) {
+ return 0;
+ }
+
*quotedlen = unquotedlen + qcount + 2;
*quoted = c = emalloc(*quotedlen+1);
*c++ = '\'';
--
2.47.0
+163
View File
@@ -0,0 +1,163 @@
From a6c1c62a25ac23b08a86af11d68f0e2eaafc102b 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)
Upstream-Status: Backport [093c08af25fb323efa0c8e6154aa9fdeae3d3b53, 2e07a3acd7a6b53c55325b94bed97748d7697b53]
---
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 00000000000..77fcb680894
--- /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 18f6b65a6c5..e971d497337 100644
--- a/main/php_variables.c
+++ b/main/php_variables.c
@@ -65,6 +65,21 @@ static zend_always_inline void php_register_variable_quick(const char *name, siz
zend_string_release_ex(key, 0);
}
+/* 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;
@@ -115,20 +130,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_ptr_dtor_nogc(val);
free_alloca(var_orig, use_heap);
@@ -226,6 +227,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;
@@ -263,6 +270,12 @@ plain_var:
zval_ptr_dtor_nogc(val);
}
} else {
+ if (php_is_forbidden_variable_name(index, index_len, var_name)) {
+ zval_ptr_dtor_nogc(val);
+ free_alloca(var_orig, use_heap);
+ return;
+ }
+
zend_ulong idx;
/*
--
@@ -0,0 +1,55 @@
From 4a7ceb9d6427f8d368f1a8739267b1f8310ec201 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)
Upstream-Status: Backport [0ba5229a3f7572846e91c8f5382e87785f543826, 81794c73068d9a44bf109bbcc9793e7b56a1c051]
---
ext/standard/password.c | 5 +++++
ext/standard/tests/password/password_bcrypt_errors.phpt | 6 ++++++
2 files changed, 11 insertions(+)
diff --git a/ext/standard/password.c b/ext/standard/password.c
index 9fe7fb1a422..af80670246a 100644
--- a/ext/standard/password.c
+++ b/ext/standard/password.c
@@ -260,6 +260,11 @@ static zend_string* php_password_bcrypt_hash(const zend_string *password, zend_a
zval *zcost;
zend_long cost = PHP_PASSWORD_BCRYPT_COST;
+ if (memchr(ZSTR_VAL(password), '\0', ZSTR_LEN(password))) {
+ php_error_docref(NULL, E_WARNING, "Bcrypt password must not contain null character");
+ return NULL;
+ }
+
if (options && (zcost = zend_hash_str_find(options, "cost", sizeof("cost")-1)) != NULL) {
cost = zval_get_long(zcost);
}
diff --git a/ext/standard/tests/password/password_bcrypt_errors.phpt b/ext/standard/tests/password/password_bcrypt_errors.phpt
index a0826080e62..f95b72670ae 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
@@ -41,3 +43,7 @@ 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
+
--
+150
View File
@@ -0,0 +1,150 @@
From 08be64e40197fc12dca5f802d16748d9c3cb4cb4 Mon Sep 17 00:00:00 2001
From: Niels Dossche <7771979+nielsdos@users.noreply.github.com>
Date: Wed, 22 May 2024 22:25:02 +0200
Subject: [PATCH 1/2] Fix GHSA-w8qr-v226-r27w
We should not early-out with success status if we found an ipv6
hostname, we should keep checking the rest of the conditions.
Because integrating the if-check of the ipv6 hostname in the
"Validate domain" if-check made the code hard to read, I extracted the
condition out to a separate function. This also required to make
a few pointers const in order to have some clean code.
(cherry picked from commit 4066610b47e22c24cbee91be434a94357056a479)
Upstream-Status: Backport [4066610b47e22c24cbee91be434a94357056a479]
---
ext/filter/logical_filters.c | 35 ++++++++++---------
ext/filter/tests/ghsa-w8qr-v226-r27w.phpt | 41 +++++++++++++++++++++++
2 files changed, 61 insertions(+), 15 deletions(-)
create mode 100644 ext/filter/tests/ghsa-w8qr-v226-r27w.phpt
diff --git a/ext/filter/logical_filters.c b/ext/filter/logical_filters.c
index e5e87c01568..9c86ad072cc 100644
--- a/ext/filter/logical_filters.c
+++ b/ext/filter/logical_filters.c
@@ -91,7 +91,7 @@
#define FORMAT_IPV4 4
#define FORMAT_IPV6 6
-static int _php_filter_validate_ipv6(char *str, size_t str_len, int ip[8]);
+static int _php_filter_validate_ipv6(const char *str, size_t str_len, int ip[8]);
static int php_filter_parse_int(const char *str, size_t str_len, zend_long *ret) { /* {{{ */
zend_long ctx_value;
@@ -571,6 +571,14 @@ static int is_userinfo_valid(zend_string *str)
return 1;
}
+static zend_bool php_filter_is_valid_ipv6_hostname(const char *s, size_t l)
+{
+ const char *e = s + l;
+ const char *t = e - 1;
+
+ return *s == '[' && *t == ']' && _php_filter_validate_ipv6(s + 1, l - 2, NULL);
+}
+
void php_filter_validate_url(PHP_INPUT_FILTER_PARAM_DECL) /* {{{ */
{
php_url *url;
@@ -596,7 +604,7 @@ void php_filter_validate_url(PHP_INPUT_FILTER_PARAM_DECL) /* {{{ */
if (url->scheme != NULL &&
(zend_string_equals_literal_ci(url->scheme, "http") || zend_string_equals_literal_ci(url->scheme, "https"))) {
- char *e, *s, *t;
+ const char *s;
size_t l;
if (url->host == NULL) {
@@ -605,17 +613,14 @@ void php_filter_validate_url(PHP_INPUT_FILTER_PARAM_DECL) /* {{{ */
s = ZSTR_VAL(url->host);
l = ZSTR_LEN(url->host);
- e = s + l;
- t = e - 1;
-
- /* An IPv6 enclosed by square brackets is a valid hostname */
- if (*s == '[' && *t == ']' && _php_filter_validate_ipv6((s + 1), l - 2, NULL)) {
- php_url_free(url);
- return;
- }
- // Validate domain
- if (!_php_filter_validate_domain(ZSTR_VAL(url->host), l, FILTER_FLAG_HOSTNAME)) {
+ if (
+ /* An IPv6 enclosed by square brackets is a valid hostname.*/
+ !php_filter_is_valid_ipv6_hostname(s, l) &&
+ /* Validate domain.
+ * This includes a loose check for an IPv4 address. */
+ !_php_filter_validate_domain(ZSTR_VAL(url->host), l, FILTER_FLAG_HOSTNAME)
+ ) {
php_url_free(url);
RETURN_VALIDATION_FAILED
}
@@ -749,15 +754,15 @@ static int _php_filter_validate_ipv4(char *str, size_t str_len, int *ip) /* {{{
}
/* }}} */
-static int _php_filter_validate_ipv6(char *str, size_t str_len, int ip[8]) /* {{{ */
+static int _php_filter_validate_ipv6(const char *str, size_t str_len, int ip[8]) /* {{{ */
{
int compressed_pos = -1;
int blocks = 0;
int num, n, i;
char *ipv4;
- char *end;
+ const char *end;
int ip4elm[4];
- char *s = str;
+ const char *s = str;
if (!memchr(str, ':', str_len)) {
return 0;
diff --git a/ext/filter/tests/ghsa-w8qr-v226-r27w.phpt b/ext/filter/tests/ghsa-w8qr-v226-r27w.phpt
new file mode 100644
index 00000000000..0092408ee5a
--- /dev/null
+++ b/ext/filter/tests/ghsa-w8qr-v226-r27w.phpt
@@ -0,0 +1,41 @@
+--TEST--
+GHSA-w8qr-v226-r27w
+--EXTENSIONS--
+filter
+--FILE--
+<?php
+
+function test(string $input) {
+ var_dump(filter_var($input, FILTER_VALIDATE_URL));
+}
+
+echo "--- These ones should fail ---\n";
+test("http://t[est@127.0.0.1");
+test("http://t[est@[::1]");
+test("http://t[est@[::1");
+test("http://t[est@::1]");
+test("http://php.net\\@aliyun.com/aaa.do");
+test("http://test[@2001:db8:3333:4444:5555:6666:1.2.3.4]");
+test("http://te[st@2001:db8:3333:4444:5555:6666:1.2.3.4]");
+test("http://te[st@2001:db8:3333:4444:5555:6666:1.2.3.4");
+
+echo "--- These ones should work ---\n";
+test("http://test@127.0.0.1");
+test("http://test@[2001:db8:3333:4444:5555:6666:1.2.3.4]");
+test("http://test@[::1]");
+
+?>
+--EXPECT--
+--- These ones should fail ---
+bool(false)
+bool(false)
+bool(false)
+bool(false)
+bool(false)
+bool(false)
+bool(false)
+bool(false)
+--- These ones should work ---
+string(21) "http://test@127.0.0.1"
+string(50) "http://test@[2001:db8:3333:4444:5555:6666:1.2.3.4]"
+string(17) "http://test@[::1]"
--
+228
View File
@@ -0,0 +1,228 @@
From a24ac172f52e75101913f3946cfa5515f723c99f Mon Sep 17 00:00:00 2001
From: Arnaud Le Blanc <arnaud.lb@gmail.com>
Date: Mon, 9 Sep 2024 15:22:07 +0200
Subject: [PATCH 04/11] Fix GHSA-9pqp-7h25-4f32
multipart/form-data boundaries larger than the read buffer result in erroneous
parsing, which violates data integrity.
Limit boundary size, as allowed by RFC 1521:
Encapsulation boundaries [...] must be no longer than 70 characters, not
counting the two leading hyphens.
We correctly parse payloads with boundaries of length up to
FILLUNIT-strlen("\r\n--") bytes, so allow this for BC.
(cherry picked from commit 19b49258d0c5a61398d395d8afde1123e8d161e0)
(cherry picked from commit 2b0daf421c162376892832588eccdfa9a286ed09)
Upstream-Status: Backport [19b49258d0c5a61398d395d8afde1123e8d161e0, 2b0daf421c162376892832588eccdfa9a286ed09]
---
main/rfc1867.c | 7 ++
tests/basic/GHSA-9pqp-7h25-4f32.inc | 3 +
tests/basic/GHSA-9pqp-7h25-4f32.phpt | 100 +++++++++++++++++++++++++++
3 files changed, 110 insertions(+)
create mode 100644 tests/basic/GHSA-9pqp-7h25-4f32.inc
create mode 100644 tests/basic/GHSA-9pqp-7h25-4f32.phpt
diff --git a/main/rfc1867.c b/main/rfc1867.c
index 1b212c93325..43ccce120c3 100644
--- a/main/rfc1867.c
+++ b/main/rfc1867.c
@@ -759,6 +759,13 @@ SAPI_API SAPI_POST_HANDLER_FUNC(rfc1867_post_handler) /* {{{ */
boundary_len = boundary_end-boundary;
}
+ /* Boundaries larger than FILLUNIT-strlen("\r\n--") characters lead to
+ * erroneous parsing */
+ if (boundary_len > FILLUNIT-strlen("\r\n--")) {
+ sapi_module.sapi_error(E_WARNING, "Boundary too large in multipart/form-data POST data");
+ return;
+ }
+
/* Initialize the buffer */
if (!(mbuff = multipart_buffer_new(boundary, boundary_len))) {
sapi_module.sapi_error(E_WARNING, "Unable to initialize the input buffer");
diff --git a/tests/basic/GHSA-9pqp-7h25-4f32.inc b/tests/basic/GHSA-9pqp-7h25-4f32.inc
new file mode 100644
index 00000000000..adf72a361a2
--- /dev/null
+++ b/tests/basic/GHSA-9pqp-7h25-4f32.inc
@@ -0,0 +1,3 @@
+<?php
+print "Hello world\n";
+var_dump($_POST);
diff --git a/tests/basic/GHSA-9pqp-7h25-4f32.phpt b/tests/basic/GHSA-9pqp-7h25-4f32.phpt
new file mode 100644
index 00000000000..af819163705
--- /dev/null
+++ b/tests/basic/GHSA-9pqp-7h25-4f32.phpt
@@ -0,0 +1,100 @@
+--TEST--
+GHSA-9pqp-7h25-4f32
+--SKIPIF--
+<?php
+if (!getenv('TEST_PHP_CGI_EXECUTABLE')) {
+ die("skip php-cgi not available");
+}
+?>
+--FILE--
+<?php
+
+const FILLUNIT = 5 * 1024;
+
+function test($boundaryLen) {
+ printf("Boundary len: %d\n", $boundaryLen);
+
+ $cmd = [
+ getenv('TEST_PHP_CGI_EXECUTABLE'),
+ '-C',
+ '-n',
+ __DIR__ . '/GHSA-9pqp-7h25-4f32.inc',
+ ];
+
+ $boundary = str_repeat('A', $boundaryLen);
+ $body = ""
+ . "--$boundary\r\n"
+ . "Content-Disposition: form-data; name=\"koko\"\r\n"
+ . "\r\n"
+ . "BBB\r\n--" . substr($boundary, 0, -1) . "CCC\r\n"
+ . "--$boundary--\r\n"
+ ;
+
+ $env = array_merge($_ENV, [
+ 'REDIRECT_STATUS' => '1',
+ 'CONTENT_TYPE' => "multipart/form-data; boundary=$boundary",
+ 'CONTENT_LENGTH' => strlen($body),
+ 'REQUEST_METHOD' => 'POST',
+ 'SCRIPT_FILENAME' => __DIR__ . '/GHSA-9pqp-7h25-4f32.inc',
+ ]);
+
+ $spec = [
+ 0 => ['pipe', 'r'],
+ 1 => STDOUT,
+ 2 => STDOUT,
+ ];
+
+ $pipes = [];
+
+ print "Starting...\n";
+
+ $handle = proc_open($cmd, $spec, $pipes, getcwd(), $env);
+
+ fwrite($pipes[0], $body);
+
+ $status = proc_close($handle);
+
+ print "\n";
+}
+
+for ($offset = -1; $offset <= 1; $offset++) {
+ test(FILLUNIT - strlen("\r\n--") + $offset);
+}
+
+?>
+--EXPECTF--
+Boundary len: 5115
+Starting...
+X-Powered-By: %s
+Content-type: text/html; charset=UTF-8
+
+Hello world
+array(1) {
+ ["koko"]=>
+ string(5124) "BBB
+--AAA%sCCC"
+}
+
+Boundary len: 5116
+Starting...
+X-Powered-By: %s
+Content-type: text/html; charset=UTF-8
+
+Hello world
+array(1) {
+ ["koko"]=>
+ string(5125) "BBB
+--AAA%sCCC"
+}
+
+Boundary len: 5117
+Starting...
+X-Powered-By: %s
+Content-type: text/html; charset=UTF-8
+
+<br />
+<b>Warning</b>: Boundary too large in multipart/form-data POST data in <b>Unknown</b> on line <b>0</b><br />
+Hello world
+array(0) {
+}
+
--
2.46.1
From 2fd1b83817d20523e72bef3ad524cd5797f51acf Mon Sep 17 00:00:00 2001
From: Jakub Zelenka <bukka@php.net>
Date: Mon, 23 Sep 2024 18:54:31 +0100
Subject: [PATCH 08/11] Skip GHSA-9pqp-7h25-4f32 test on Windows
(cherry picked from commit c70e25630832fa10d421328eed2b8e1a36af7a64)
(cherry picked from commit c75683864f6e4188439e8ca2adbb05824918be12)
---
tests/basic/GHSA-9pqp-7h25-4f32.phpt | 3 +++
1 file changed, 3 insertions(+)
diff --git a/tests/basic/GHSA-9pqp-7h25-4f32.phpt b/tests/basic/GHSA-9pqp-7h25-4f32.phpt
index af819163705..29bcb6557d5 100644
--- a/tests/basic/GHSA-9pqp-7h25-4f32.phpt
+++ b/tests/basic/GHSA-9pqp-7h25-4f32.phpt
@@ -5,6 +5,9 @@ GHSA-9pqp-7h25-4f32
if (!getenv('TEST_PHP_CGI_EXECUTABLE')) {
die("skip php-cgi not available");
}
+if (substr(PHP_OS, 0, 3) == 'WIN') {
+ die("skip not for Windows in CI - probably resource issue");
+}
?>
--FILE--
<?php
--
2.46.1
From 29065f33f37f99ba33254cb23c941647bcd7372c Mon Sep 17 00:00:00 2001
From: Remi Collet <remi@remirepo.net>
Date: Thu, 26 Sep 2024 15:49:03 +0200
Subject: [PATCH 11/11] adapt GHSA-9pqp-7h25-4f32 test for 7.x
---
tests/basic/GHSA-9pqp-7h25-4f32.phpt | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/tests/basic/GHSA-9pqp-7h25-4f32.phpt b/tests/basic/GHSA-9pqp-7h25-4f32.phpt
index 29bcb6557d5..a1ead918ff3 100644
--- a/tests/basic/GHSA-9pqp-7h25-4f32.phpt
+++ b/tests/basic/GHSA-9pqp-7h25-4f32.phpt
@@ -21,6 +21,7 @@ function test($boundaryLen) {
getenv('TEST_PHP_CGI_EXECUTABLE'),
'-C',
'-n',
+ '-dlog_errors=1',
__DIR__ . '/GHSA-9pqp-7h25-4f32.inc',
];
@@ -92,11 +93,10 @@ array(1) {
Boundary len: 5117
Starting...
+PHP Warning: Boundary too large in multipart/form-data POST data in Unknown on line 0
X-Powered-By: %s
Content-type: text/html; charset=UTF-8
-<br />
-<b>Warning</b>: Boundary too large in multipart/form-data POST data in <b>Unknown</b> on line <b>0</b><br />
Hello world
array(0) {
}
--
2.46.1
+176
View File
@@ -0,0 +1,176 @@
From fb718aa6f2117933566bb7bb2f70b2b0d9a9c08f Mon Sep 17 00:00:00 2001
From: Jan Ehrhardt <github@ehrhardt.nl>
Date: Wed, 5 Jun 2024 20:24:52 +0200
Subject: [PATCH 01/11] Fix GHSA-3qgc-jrrr-25jv
Upstream-Status: Backport [938267314835de3c2ed1a3da4f2959f1d2709468]
---
sapi/cgi/cgi_main.c | 23 ++++++++++++++-
sapi/cgi/tests/ghsa-3qgc-jrrr-25jv.phpt | 38 +++++++++++++++++++++++++
2 files changed, 60 insertions(+), 1 deletion(-)
create mode 100644 sapi/cgi/tests/ghsa-3qgc-jrrr-25jv.phpt
diff --git a/sapi/cgi/cgi_main.c b/sapi/cgi/cgi_main.c
index a36f426d266..8d1342727dc 100644
--- a/sapi/cgi/cgi_main.c
+++ b/sapi/cgi/cgi_main.c
@@ -1827,8 +1827,13 @@ int main(int argc, char *argv[])
}
}
+ /* Apache CGI will pass the query string to the command line if it doesn't contain a '='.
+ * This can create an issue where a malicious request can pass command line arguments to
+ * the executable. Ideally we skip argument parsing when we're in cgi or fastcgi mode,
+ * but that breaks PHP scripts on Linux with a hashbang: `#!/php-cgi -d option=value`.
+ * Therefore, this code only prevents passing arguments if the query string starts with a '-'.
+ * Similarly, scripts spawned in subprocesses on Windows may have the same issue. */
if((query_string = getenv("QUERY_STRING")) != NULL && strchr(query_string, '=') == NULL) {
- /* we've got query string that has no = - apache CGI will pass it to command line */
unsigned char *p;
decoded_query_string = strdup(query_string);
php_url_decode(decoded_query_string, strlen(decoded_query_string));
@@ -1838,6 +1843,22 @@ int main(int argc, char *argv[])
if(*p == '-') {
skip_getopt = 1;
}
+
+ /* On Windows we have to take into account the "best fit" mapping behaviour. */
+#ifdef PHP_WIN32
+ if (*p >= 0x80) {
+ wchar_t wide_buf[1];
+ wide_buf[0] = *p;
+ char char_buf[4];
+ size_t wide_buf_len = sizeof(wide_buf) / sizeof(wide_buf[0]);
+ size_t char_buf_len = sizeof(char_buf) / sizeof(char_buf[0]);
+ if (WideCharToMultiByte(CP_ACP, 0, wide_buf, wide_buf_len, char_buf, char_buf_len, NULL, NULL) == 0
+ || char_buf[0] == '-') {
+ skip_getopt = 1;
+ }
+ }
+#endif
+
free(decoded_query_string);
}
diff --git a/sapi/cgi/tests/ghsa-3qgc-jrrr-25jv.phpt b/sapi/cgi/tests/ghsa-3qgc-jrrr-25jv.phpt
new file mode 100644
index 00000000000..fd2fcdfbf89
--- /dev/null
+++ b/sapi/cgi/tests/ghsa-3qgc-jrrr-25jv.phpt
@@ -0,0 +1,38 @@
+--TEST--
+GHSA-3qgc-jrrr-25jv
+--SKIPIF--
+<?php
+include 'skipif.inc';
+if (PHP_OS_FAMILY !== "Windows") die("skip Only for Windows");
+
+$codepage = trim(shell_exec("powershell Get-ItemPropertyValue HKLM:\\SYSTEM\\CurrentControlSet\\Control\\Nls\\CodePage ACP"));
+if ($codepage !== '932' && $codepage !== '936' && $codepage !== '950') die("skip Wrong codepage");
+?>
+--FILE--
+<?php
+include 'include.inc';
+
+$filename = __DIR__."/GHSA-3qgc-jrrr-25jv_tmp.php";
+$script = '<?php echo "hello "; echo "world"; ?>';
+file_put_contents($filename, $script);
+
+$php = get_cgi_path();
+reset_env_vars();
+
+putenv("SERVER_NAME=Test");
+putenv("SCRIPT_FILENAME=$filename");
+putenv("QUERY_STRING=%ads");
+putenv("REDIRECT_STATUS=1");
+
+passthru("$php -s");
+
+?>
+--CLEAN--
+<?php
+@unlink(__DIR__."/GHSA-3qgc-jrrr-25jv_tmp.php");
+?>
+--EXPECTF--
+X-Powered-By: PHP/%s
+Content-type: %s
+
+hello world
--
2.46.1
From 1158d06f0b20532ab7309cb20f0be843f9662e3c Mon Sep 17 00:00:00 2001
From: Niels Dossche <7771979+nielsdos@users.noreply.github.com>
Date: Fri, 14 Jun 2024 19:49:22 +0200
Subject: [PATCH 05/11] Fix GHSA-p99j-rfp4-xqvq
It's no use trying to work around whatever the operating system and Apache
do because we'll be fighting that until eternity.
Change the skip_getopt condition such that when we're running in
CGI or FastCGI mode we always skip the argument parsing.
This is a BC break, but this seems to be the only way to get rid of this
class of issues.
(cherry picked from commit abcfd980bfa03298792fd3aba051c78d52f10642)
(cherry picked from commit 2d2552e092b6ff32cd823692d512f126ee629842)
---
sapi/cgi/cgi_main.c | 26 ++++++++------------------
1 file changed, 8 insertions(+), 18 deletions(-)
diff --git a/sapi/cgi/cgi_main.c b/sapi/cgi/cgi_main.c
index 8d1342727dc..a2761aafd7b 100644
--- a/sapi/cgi/cgi_main.c
+++ b/sapi/cgi/cgi_main.c
@@ -1777,7 +1777,6 @@ int main(int argc, char *argv[])
int status = 0;
#endif
char *query_string;
- char *decoded_query_string;
int skip_getopt = 0;
#if defined(SIGPIPE) && defined(SIG_IGN)
@@ -1832,10 +1831,15 @@ int main(int argc, char *argv[])
* the executable. Ideally we skip argument parsing when we're in cgi or fastcgi mode,
* but that breaks PHP scripts on Linux with a hashbang: `#!/php-cgi -d option=value`.
* Therefore, this code only prevents passing arguments if the query string starts with a '-'.
- * Similarly, scripts spawned in subprocesses on Windows may have the same issue. */
+ * Similarly, scripts spawned in subprocesses on Windows may have the same issue.
+ * However, Windows has lots of conversion rules and command line parsing rules that
+ * are too difficult and dangerous to reliably emulate. */
if((query_string = getenv("QUERY_STRING")) != NULL && strchr(query_string, '=') == NULL) {
+#ifdef PHP_WIN32
+ skip_getopt = cgi || fastcgi;
+#else
unsigned char *p;
- decoded_query_string = strdup(query_string);
+ char *decoded_query_string = strdup(query_string);
php_url_decode(decoded_query_string, strlen(decoded_query_string));
for (p = (unsigned char *)decoded_query_string; *p && *p <= ' '; p++) {
/* skip all leading spaces */
@@ -1844,22 +1848,8 @@ int main(int argc, char *argv[])
skip_getopt = 1;
}
- /* On Windows we have to take into account the "best fit" mapping behaviour. */
-#ifdef PHP_WIN32
- if (*p >= 0x80) {
- wchar_t wide_buf[1];
- wide_buf[0] = *p;
- char char_buf[4];
- size_t wide_buf_len = sizeof(wide_buf) / sizeof(wide_buf[0]);
- size_t char_buf_len = sizeof(char_buf) / sizeof(char_buf[0]);
- if (WideCharToMultiByte(CP_ACP, 0, wide_buf, wide_buf_len, char_buf, char_buf_len, NULL, NULL) == 0
- || char_buf[0] == '-') {
- skip_getopt = 1;
- }
- }
-#endif
-
free(decoded_query_string);
+#endif
}
while (!skip_getopt && (c = php_getopt(argc, argv, OPTIONS, &php_optarg, &php_optind, 0, 2)) != -1) {
--
2.46.1
@@ -0,0 +1,58 @@
From c7308ba7cd0533501b40eba255602bb5e085550f Mon Sep 17 00:00:00 2001
From: Niels Dossche <7771979+nielsdos@users.noreply.github.com>
Date: Tue, 18 Jun 2024 21:28:26 +0200
Subject: [PATCH 06/11] Fix GHSA-94p6-54jq-9mwp
Apache only generates REDIRECT_STATUS, so explicitly check for that
if the server name is Apache, don't allow other variable names.
Furthermore, redirect.so and Netscape no longer exist, so
remove those entries as we can't check their server name anymore.
We now also check for the configuration override *first* such that it
always take precedence. This would allow for a mitigation path if
something like this happens in the future.
(cherry picked from commit 48808d98f4fc2a05193cdcc1aedd6c66816450f1)
(cherry picked from commit 8aa748ee0657cdee8d883ba50d04b68bc450f686)
Upstream-Status: Backport [48808d98f4fc2a05193cdcc1aedd6c66816450f1, 8aa748ee0657cdee8d883ba50d04b68bc450f686]
---
sapi/cgi/cgi_main.c | 23 +++++++++++------------
1 file changed, 11 insertions(+), 12 deletions(-)
diff --git a/sapi/cgi/cgi_main.c b/sapi/cgi/cgi_main.c
index a2761aafd7b..ebce6302b93 100644
--- a/sapi/cgi/cgi_main.c
+++ b/sapi/cgi/cgi_main.c
@@ -1939,18 +1939,17 @@ int main(int argc, char *argv[])
/* check force_cgi after startup, so we have proper output */
if (cgi && CGIG(force_redirect)) {
- /* Apache will generate REDIRECT_STATUS,
- * Netscape and redirect.so will generate HTTP_REDIRECT_STATUS.
- * redirect.so and installation instructions available from
- * http://www.koehntopp.de/php.
- * -- kk@netuse.de
- */
- if (!getenv("REDIRECT_STATUS") &&
- !getenv ("HTTP_REDIRECT_STATUS") &&
- /* this is to allow a different env var to be configured
- * in case some server does something different than above */
- (!CGIG(redirect_status_env) || !getenv(CGIG(redirect_status_env)))
- ) {
+ /* This is to allow a different environment variable to be configured
+ * in case the we cannot auto-detect which environment variable to use.
+ * Checking this first to allow user overrides in case the environment
+ * variable can be set by an untrusted party. */
+ const char *redirect_status_env = CGIG(redirect_status_env);
+ if (!redirect_status_env) {
+ /* Apache will generate REDIRECT_STATUS. */
+ redirect_status_env = "REDIRECT_STATUS";
+ }
+
+ if (!getenv(redirect_status_env)) {
zend_try {
SG(sapi_headers).http_response_code = 400;
PUTS("<b>Security Alert!</b> The PHP CGI cannot be accessed directly.\n\n\
--
2.46.1
+141
View File
@@ -0,0 +1,141 @@
From 50e9e72530a4805980384b8ea6672877af816145 Mon Sep 17 00:00:00 2001
From: Niels Dossche <7771979+nielsdos@users.noreply.github.com>
Date: Thu, 26 Sep 2024 22:22:27 +0200
Subject: [PATCH 4/7] Fix GHSA-g665-fm4p-vhff: OOB access in ldap_escape
(cherry picked from commit f9ecf90070a11dad09ca7671a712f81cc2a7d52f)
(cherry picked from commit 9f367d847989b339c33369737daf573e30bab5f1)
Upstream-Status: Backport
---
ext/ldap/ldap.c | 21 ++++++++++++++--
ext/ldap/tests/GHSA-g665-fm4p-vhff-1.phpt | 28 ++++++++++++++++++++++
ext/ldap/tests/GHSA-g665-fm4p-vhff-2.phpt | 29 +++++++++++++++++++++++
3 files changed, 76 insertions(+), 2 deletions(-)
create mode 100644 ext/ldap/tests/GHSA-g665-fm4p-vhff-1.phpt
create mode 100644 ext/ldap/tests/GHSA-g665-fm4p-vhff-2.phpt
diff --git a/ext/ldap/ldap.c b/ext/ldap/ldap.c
index 72a39bd93df..75adf1b5df2 100644
--- a/ext/ldap/ldap.c
+++ b/ext/ldap/ldap.c
@@ -49,6 +49,7 @@
#include "ext/standard/php_string.h"
#include "ext/standard/info.h"
+#include "Zend/zend_exceptions.h"
#ifdef HAVE_LDAP_SASL
#include <sasl/sasl.h>
@@ -3836,13 +3837,23 @@ static zend_string* php_ldap_do_escape(const zend_bool *map, const char *value,
zend_string *ret;
for (i = 0; i < valuelen; i++) {
- len += (map[(unsigned char) value[i]]) ? 3 : 1;
+ size_t addend = (map[(unsigned char) value[i]]) ? 3 : 1;
+ if (len > ZSTR_MAX_LEN - addend) {
+ return NULL;
+ }
+ len += addend;
}
/* Per RFC 4514, a leading and trailing space must be escaped */
if ((flags & PHP_LDAP_ESCAPE_DN) && (value[0] == ' ')) {
+ if (len > ZSTR_MAX_LEN - 2) {
+ return NULL;
+ }
len += 2;
}
if ((flags & PHP_LDAP_ESCAPE_DN) && ((valuelen > 1) && (value[valuelen - 1] == ' '))) {
+ if (len > ZSTR_MAX_LEN - 2) {
+ return NULL;
+ }
len += 2;
}
@@ -3909,7 +3920,13 @@ PHP_FUNCTION(ldap_escape)
php_ldap_escape_map_set_chars(map, ignores, ignoreslen, 0);
}
- RETURN_NEW_STR(php_ldap_do_escape(map, value, valuelen, flags));
+ zend_string *result = php_ldap_do_escape(map, value, valuelen, flags);
+ if (UNEXPECTED(!result)) {
+ zend_throw_exception(NULL, "Argument #1 ($value) is too long", 0);
+ return;
+ }
+
+ RETURN_NEW_STR(result);
}
#ifdef STR_TRANSLATION
diff --git a/ext/ldap/tests/GHSA-g665-fm4p-vhff-1.phpt b/ext/ldap/tests/GHSA-g665-fm4p-vhff-1.phpt
new file mode 100644
index 00000000000..734bbe91d42
--- /dev/null
+++ b/ext/ldap/tests/GHSA-g665-fm4p-vhff-1.phpt
@@ -0,0 +1,28 @@
+--TEST--
+GHSA-g665-fm4p-vhff (OOB access in ldap_escape)
+--EXTENSIONS--
+ldap
+--INI--
+memory_limit=-1
+--SKIPIF--
+<?php
+if (PHP_INT_SIZE !== 4) die("skip only for 32-bit");
+if (getenv("SKIP_SLOW_TESTS")) die("skip slow test");
+?>
+--FILE--
+<?php
+try {
+ ldap_escape(' '.str_repeat("#", 1431655758), "", LDAP_ESCAPE_DN);
+} catch (Exception $e) {
+ echo $e->getMessage(), "\n";
+}
+
+try {
+ ldap_escape(str_repeat("#", 1431655758).' ', "", LDAP_ESCAPE_DN);
+} catch (Exception $e) {
+ echo $e->getMessage(), "\n";
+}
+?>
+--EXPECT--
+ldap_escape(): Argument #1 ($value) is too long
+ldap_escape(): Argument #1 ($value) is too long
diff --git a/ext/ldap/tests/GHSA-g665-fm4p-vhff-2.phpt b/ext/ldap/tests/GHSA-g665-fm4p-vhff-2.phpt
new file mode 100644
index 00000000000..5c1b0fb6611
--- /dev/null
+++ b/ext/ldap/tests/GHSA-g665-fm4p-vhff-2.phpt
@@ -0,0 +1,29 @@
+--TEST--
+GHSA-g665-fm4p-vhff (OOB access in ldap_escape)
+--EXTENSIONS--
+ldap
+--INI--
+memory_limit=-1
+--SKIPIF--
+<?php
+if (PHP_INT_SIZE !== 4) die("skip only for 32-bit");
+if (getenv("SKIP_SLOW_TESTS")) die("skip slow test");
+?>
+--FILE--
+<?php
+try {
+ ldap_escape(str_repeat("*", 1431655759), "", LDAP_ESCAPE_FILTER);
+} catch (Exception $e) {
+ echo $e->getMessage(), "\n";
+}
+
+// would allocate a string of length 2
+try {
+ ldap_escape(str_repeat("*", 1431655766), "", LDAP_ESCAPE_FILTER);
+} catch (Exception $e) {
+ echo $e->getMessage(), "\n";
+}
+?>
+--EXPECT--
+ldap_escape(): Argument #1 ($value) is too long
+ldap_escape(): Argument #1 ($value) is too long
--
2.47.0
+205
View File
@@ -0,0 +1,205 @@
From 4a8b8fa2592bd8862adeacb5b2faacb30500b9f9 Mon Sep 17 00:00:00 2001
From: Jakub Zelenka <bukka@php.net>
Date: Thu, 12 Sep 2024 13:11:11 +0100
Subject: [PATCH 07/11] Fix GHSA-865w-9rf3-2wh5: FPM: Logs from childrens may
be altered
(cherry picked from commit 1f8e16172c7961045c2b0f34ba7613e3f21cdee8)
(cherry picked from commit 22f4d3504d7613ce78bb96aa53cbfe7d672fa036)
Upstream-Status: Backport [1f8e16172c7961045c2b0f34ba7613e3f21cdee8, 22f4d3504d7613ce78bb96aa53cbfe7d672fa036]
---
sapi/fpm/fpm/fpm_stdio.c | 2 +-
.../log-bwp-msg-flush-split-sep-pos-end.phpt | 47 +++++++++++++++++++
...log-bwp-msg-flush-split-sep-pos-start.phpt | 47 +++++++++++++++++++
3 files changed, 95 insertions(+), 1 deletion(-)
create mode 100644 sapi/fpm/tests/log-bwp-msg-flush-split-sep-pos-end.phpt
create mode 100644 sapi/fpm/tests/log-bwp-msg-flush-split-sep-pos-start.phpt
diff --git a/sapi/fpm/fpm/fpm_stdio.c b/sapi/fpm/fpm/fpm_stdio.c
index ddedfb48c7c..9d87273314a 100644
--- a/sapi/fpm/fpm/fpm_stdio.c
+++ b/sapi/fpm/fpm/fpm_stdio.c
@@ -177,7 +177,7 @@ stdio_read:
if ((sizeof(FPM_STDIO_CMD_FLUSH) - cmd_pos) <= in_buf &&
!memcmp(buf, &FPM_STDIO_CMD_FLUSH[cmd_pos], sizeof(FPM_STDIO_CMD_FLUSH) - cmd_pos)) {
zlog_stream_finish(log_stream);
- start = cmd_pos;
+ start = sizeof(FPM_STDIO_CMD_FLUSH) - cmd_pos;
} else {
zlog_stream_str(log_stream, &FPM_STDIO_CMD_FLUSH[0], cmd_pos);
}
diff --git a/sapi/fpm/tests/log-bwp-msg-flush-split-sep-pos-end.phpt b/sapi/fpm/tests/log-bwp-msg-flush-split-sep-pos-end.phpt
new file mode 100644
index 00000000000..52826320080
--- /dev/null
+++ b/sapi/fpm/tests/log-bwp-msg-flush-split-sep-pos-end.phpt
@@ -0,0 +1,47 @@
+--TEST--
+FPM: Buffered worker output plain log with msg with flush split position towards separator end
+--SKIPIF--
+<?php include "skipif.inc"; ?>
+--FILE--
+<?php
+
+require_once "tester.inc";
+
+$cfg = <<<EOT
+[global]
+error_log = {{FILE:LOG}}
+[unconfined]
+listen = {{ADDR}}
+pm = dynamic
+pm.max_children = 5
+pm.start_servers = 1
+pm.min_spare_servers = 1
+pm.max_spare_servers = 3
+catch_workers_output = yes
+decorate_workers_output = no
+EOT;
+
+$code = <<<EOT
+<?php
+file_put_contents('php://stderr', str_repeat('a', 1013) . "Quarkslab\0fscf\0Quarkslab");
+EOT;
+
+$tester = new FPM\Tester($cfg, $code);
+$tester->start();
+$tester->expectLogStartNotices();
+$tester->request()->expectEmptyBody();
+$tester->expectLogLine(str_repeat('a', 1013) . "Quarkslab", decorated: false);
+$tester->expectLogLine("Quarkslab", decorated: false);
+$tester->terminate();
+$tester->expectLogTerminatingNotices();
+$tester->close();
+
+?>
+Done
+--EXPECT--
+Done
+--CLEAN--
+<?php
+require_once "tester.inc";
+FPM\Tester::clean();
+?>
diff --git a/sapi/fpm/tests/log-bwp-msg-flush-split-sep-pos-start.phpt b/sapi/fpm/tests/log-bwp-msg-flush-split-sep-pos-start.phpt
new file mode 100644
index 00000000000..34905938553
--- /dev/null
+++ b/sapi/fpm/tests/log-bwp-msg-flush-split-sep-pos-start.phpt
@@ -0,0 +1,47 @@
+--TEST--
+FPM: Buffered worker output plain log with msg with flush split position towards separator start
+--SKIPIF--
+<?php include "skipif.inc"; ?>
+--FILE--
+<?php
+
+require_once "tester.inc";
+
+$cfg = <<<EOT
+[global]
+error_log = {{FILE:LOG}}
+[unconfined]
+listen = {{ADDR}}
+pm = dynamic
+pm.max_children = 5
+pm.start_servers = 1
+pm.min_spare_servers = 1
+pm.max_spare_servers = 3
+catch_workers_output = yes
+decorate_workers_output = no
+EOT;
+
+$code = <<<EOT
+<?php
+file_put_contents('php://stderr', str_repeat('a', 1009) . "Quarkslab\0fscf\0Quarkslab");
+EOT;
+
+$tester = new FPM\Tester($cfg, $code);
+$tester->start();
+$tester->expectLogStartNotices();
+$tester->request()->expectEmptyBody();
+$tester->expectLogLine(str_repeat('a', 1009) . "Quarkslab", decorated: false);
+$tester->expectLogLine("Quarkslab", decorated: false);
+$tester->terminate();
+$tester->expectLogTerminatingNotices();
+$tester->close();
+
+?>
+Done
+--EXPECT--
+Done
+--CLEAN--
+<?php
+require_once "tester.inc";
+FPM\Tester::clean();
+?>
--
2.46.1
From bc574c256596abc4966e7f0e3e0913839092151e Mon Sep 17 00:00:00 2001
From: Remi Collet <remi@remirepo.net>
Date: Thu, 26 Sep 2024 15:48:11 +0200
Subject: [PATCH 10/11] adapt GHSA-865w-9rf3-2wh5 test for 7.x
---
sapi/fpm/tests/log-bwp-msg-flush-split-sep-pos-end.phpt | 4 ++--
sapi/fpm/tests/log-bwp-msg-flush-split-sep-pos-start.phpt | 4 ++--
sapi/fpm/tests/tester.inc | 4 ++--
3 files changed, 6 insertions(+), 6 deletions(-)
diff --git a/sapi/fpm/tests/log-bwp-msg-flush-split-sep-pos-end.phpt b/sapi/fpm/tests/log-bwp-msg-flush-split-sep-pos-end.phpt
index 52826320080..bdd61782bfa 100644
--- a/sapi/fpm/tests/log-bwp-msg-flush-split-sep-pos-end.phpt
+++ b/sapi/fpm/tests/log-bwp-msg-flush-split-sep-pos-end.phpt
@@ -30,8 +30,8 @@ $tester = new FPM\Tester($cfg, $code);
$tester->start();
$tester->expectLogStartNotices();
$tester->request()->expectEmptyBody();
-$tester->expectLogLine(str_repeat('a', 1013) . "Quarkslab", decorated: false);
-$tester->expectLogLine("Quarkslab", decorated: false);
+$tester->expectLogLine(str_repeat('a', 1013) . "Quarkslab", true, false);
+$tester->expectLogLine("Quarkslab", true, false);
$tester->terminate();
$tester->expectLogTerminatingNotices();
$tester->close();
diff --git a/sapi/fpm/tests/log-bwp-msg-flush-split-sep-pos-start.phpt b/sapi/fpm/tests/log-bwp-msg-flush-split-sep-pos-start.phpt
index 34905938553..f3461e4a0c8 100644
--- a/sapi/fpm/tests/log-bwp-msg-flush-split-sep-pos-start.phpt
+++ b/sapi/fpm/tests/log-bwp-msg-flush-split-sep-pos-start.phpt
@@ -30,8 +30,8 @@ $tester = new FPM\Tester($cfg, $code);
$tester->start();
$tester->expectLogStartNotices();
$tester->request()->expectEmptyBody();
-$tester->expectLogLine(str_repeat('a', 1009) . "Quarkslab", decorated: false);
-$tester->expectLogLine("Quarkslab", decorated: false);
+$tester->expectLogLine(str_repeat('a', 1009) . "Quarkslab", true, false);
+$tester->expectLogLine("Quarkslab", true, false);
$tester->terminate();
$tester->expectLogTerminatingNotices();
$tester->close();
diff --git a/sapi/fpm/tests/tester.inc b/sapi/fpm/tests/tester.inc
index 7868afc4ac1..fe5f0c2fde7 100644
--- a/sapi/fpm/tests/tester.inc
+++ b/sapi/fpm/tests/tester.inc
@@ -1315,7 +1315,7 @@ class Tester
* @param string $message
* @return bool
*/
- public function expectLogLine(string $message, bool $is_stderr = true)
+ public function expectLogLine(string $message, bool $is_stderr = true, bool $decorated = true)
{
$messageLen = strlen($message);
$limit = $messageLen > 1024 ? $messageLen + 16 : 1024;
@@ -1325,7 +1325,7 @@ class Tester
$this->message("LOG LINE: " . ($logLines[0] ?? ''));
}
- return $this->logTool->checkWrappedMessage($logLines, false, true, $is_stderr);
+ return $this->logTool->checkWrappedMessage($logLines, false, $decorated, $is_stderr);
}
/**
--
2.46.1
@@ -5,7 +5,7 @@ EAPI="7"
WANT_AUTOMAKE="none"
inherit flag-o-matic systemd autotools
inherit flag-o-matic systemd autotools multilib
MY_PV=${PV/_rc/RC}
DESCRIPTION="The PHP language runtime engine"
@@ -148,8 +148,37 @@ PHP_MV="$(ver_cut 1)"
PATCHES=(
"${FILESDIR}"/php-iodbc-header-location.patch
"${FILESDIR}"/bug81656-gcc-11.patch
"${FILESDIR}"/php-7.4-openssl.patch
"${FILESDIR}"/php-7.4.33-CVE-2022-31631.patch
#
# Patches from: https://github.com/zboszor/meta-parallel-php
"${FILESDIR}"/0001-ext-libxml-Use-ZEND_ATTRIBUTE_UNUSED-in-php_libxml_o.patch
"${FILESDIR}"/0001-Fix-cookie_seek_function_t-signature-under-musl-1389.patch
"${FILESDIR}"/0002-ext-intl-level-up-c-runtime-std-for-icu-74-and-onwar.patch
"${FILESDIR}"/php-bug81744.patch
"${FILESDIR}"/php-7.4.33-gcc14.patch
"${FILESDIR}"/php-7.4.33-libxml212.patch
"${FILESDIR}"/php-7.4.11-crosscompile.patch
#
# Patches from: https://github.com/shivammathur/php-src-backports/blob/main/patches/7.4
"${FILESDIR}"/0002-Add-minimal-OpenSSL-3.0-patch-PHP7.4.patch
"${FILESDIR}"/0003-Fix-bug-79589-ssl3_read_n-unexpected-eof-while-reading-PHP7.4.patch
"${FILESDIR}"/0006-Use-ITIMER_REAL-for-timeout-handling-PHP-7.4.patch
"${FILESDIR}"/0007-Fix-PEAR-installation-with-libxml2.13.patch
"${FILESDIR}"/0009-Fix-w-strict-prototype-build-warnings-PHP-7.4.patch
"${FILESDIR}"/0010-Fix-GH-16168-Fix-inline-assembly-labels-to-not-crash-PHP7.4.patch
"${FILESDIR}"/php-cve-2023-3247.patch
"${FILESDIR}"/php-cve-2024-2756.patch
"${FILESDIR}"/php-cve-2024-3096.patch
"${FILESDIR}"/php-cve-2024-5458.patch
"${FILESDIR}"/php-cve-2024-8925.patch
"${FILESDIR}"/php-cve-2024-8926.patch
"${FILESDIR}"/php-cve-2024-8927.patch
"${FILESDIR}"/php-cve-2024-8932.patch
"${FILESDIR}"/php-cve-2024-9026.patch
"${FILESDIR}"/php-cve-2024-11233.patch
"${FILESDIR}"/php-cve-2024-11234.patch
"${FILESDIR}"/php-cve-2024-11236.patch
)
php_install_ini() {