Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
28 commits
Select commit Hold shift + click to select a range
175b962
Fix NEWS versions for posterity
ericmann Mar 11, 2025
cd04535
Merge branch 'PHP-8.3'
ericmann Mar 11, 2025
21fd08b
ext/sockets: adding SO_BUSY_POLL socket option for Linux. (#17954)
devnexen Mar 11, 2025
d20b4c9
Fix GHSA-ghsa-v8xr-gpvj-cx9g: http header folding
bukka Dec 31, 2024
0548c4c
Fix GHSA-pcmh-g36c-qc44: http headers without colon
bukka Jan 19, 2025
ac1a054
Fix GHSA-52jp-hrpf-2jff: http redirect location truncation
bukka Mar 4, 2025
41d49ab
Fix GHSA-hgf5-96fm-v528: http user header check of crlf
bukka Feb 14, 2025
b6004a0
Fix GHSA-p3x9-6h7p-cgfc: libxml streams wrong `content-type` on redirect
TimWolla Nov 20, 2024
0e715e7
Fix GHSA-wg4p-4hqh-c3g9
ndossche Dec 18, 2024
74d548b
Update NEWS with entries for security fixes
bukka Mar 7, 2025
4af1830
Merge branch 'PHP-8.1' into PHP-8.2
bukka Mar 11, 2025
acf2f49
Merge branch 'PHP-8.2' into PHP-8.3
bukka Mar 11, 2025
ef2c459
Use-after-free for ??= due to incorrect live-range calculation
iluuu1994 Nov 13, 2024
6976fb6
Merge branch 'PHP-8.3' into PHP-8.4
bukka Mar 11, 2025
5c8025e
Merge branch 'PHP-8.4'
bukka Mar 11, 2025
858c378
PHP-8.1 is now for PHP 8.1.33-dev
ramsey Mar 11, 2025
b6d61f5
Merge branch 'PHP-8.1' into PHP-8.2
ramsey Mar 11, 2025
4d42056
Merge branch 'PHP-8.2' into PHP-8.3
ramsey Mar 11, 2025
109230d
Merge branch 'PHP-8.3' into PHP-8.4
ramsey Mar 11, 2025
3ae4421
Merge branch 'PHP-8.4'
ramsey Mar 11, 2025
a8d3a80
Fix GHSA-p3x9-6h7p-cgfc: libxml streams wrong `content-type` on redirect
TimWolla Nov 19, 2024
3d6f4c8
Merge branch 'PHP-8.4'
ndossche Mar 11, 2025
8156a89
Fix incorrectly merged bug75535.phpt
ndossche Mar 11, 2025
5e1b40c
Merge branch 'PHP-8.4'
ndossche Mar 11, 2025
b617b08
PHP-8.2 is now for PHP 8.2.29-dev
adoy Mar 11, 2025
25887b3
Merge branch 'PHP-8.2' into PHP-8.3
adoy Mar 11, 2025
d465449
Merge branch 'PHP-8.3' into PHP-8.4
adoy Mar 11, 2025
645cd6a
Merge branch 'PHP-8.4'
adoy Mar 11, 2025
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions NEWS
Original file line number Diff line number Diff line change
Expand Up @@ -150,6 +150,7 @@ PHP NEWS
. socket_getsockname/socket_create/socket_bind handled AF_PACKET family socket.
(David Carlier)
. Added IP_BINDANY for a socket to bind to any address. (David Carlier)
. Added SO_BUSY_POOL to reduce packets poll latency. (David Carlier)

- Sodium:
. Fix overall theorical overflows on zend_string buffer allocations.
Expand Down
1 change: 1 addition & 0 deletions UPGRADING
Original file line number Diff line number Diff line change
Expand Up @@ -308,6 +308,7 @@ PHP 8.5 UPGRADE NOTES
. TCP_BBR_ALGORITHM (FreeBSD only).
. AF_PACKET (Linux only).
. IP_BINDANY (FreeBSD/NetBSD/OpenBSD only).
. SO_BUSY_POLL (Linux only).

========================================
11. Changes to INI File Handling
Expand Down
26 changes: 26 additions & 0 deletions Zend/tests/ghsa-rwp7-7vc6-8477_001.phpt
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
--TEST--
GHSA-rwp7-7vc6-8477: Use-after-free for ??= due to incorrect live-range calculation
--FILE--
<?php

class Foo {
public function foo() {
return $this;
}

public function __set($name, $value) {
throw new Exception('Hello');
}
}

$foo = new Foo();

try {
$foo->foo()->baz ??= 1;
} catch (Exception $e) {
echo $e->getMessage();
}

?>
--EXPECT--
Hello
24 changes: 24 additions & 0 deletions Zend/tests/ghsa-rwp7-7vc6-8477_002.phpt
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
--TEST--
GHSA-rwp7-7vc6-8477: Use-after-free for ??= due to incorrect live-range calculation
--FILE--
<?php

class Foo {
public int $prop;

public function foo() {
return $this;
}
}

$foo = new Foo();

try {
$foo->foo()->prop ??= 'foo';
} catch (Error $e) {
echo $e->getMessage();
}

?>
--EXPECT--
Cannot assign string to property Foo::$prop of type int
22 changes: 22 additions & 0 deletions Zend/tests/ghsa-rwp7-7vc6-8477_003.phpt
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
--TEST--
GHSA-rwp7-7vc6-8477: Use-after-free for ??= due to incorrect live-range calculation
--FILE--
<?php

class Foo {
public int $prop;
}

function newFoo() {
return new Foo();
}

try {
newFoo()->prop ??= 'foo';
} catch (Error $e) {
echo $e->getMessage();
}

?>
--EXPECT--
Cannot assign string to property Foo::$prop of type int
8 changes: 8 additions & 0 deletions Zend/zend_opcode.c
Original file line number Diff line number Diff line change
Expand Up @@ -940,6 +940,14 @@ static void zend_calc_live_ranges(
opnum--;
opline--;

/* SEPARATE always redeclares its op1. For the purposes of live-ranges,
* its declaration is irrelevant. Don't terminate the current live-range
* to avoid breaking special handling of COPY_TMP. */
if (opline->opcode == ZEND_SEPARATE) {
ZEND_ASSERT(opline->op1.var == opline->result.var);
continue;
}

if ((opline->result_type & (IS_TMP_VAR|IS_VAR)) && !is_fake_def(opline)) {
uint32_t var_num = EX_VAR_TO_NUM(opline->result.var) - var_offset;
/* Defs without uses can occur for two reasons: Either because the result is
Expand Down
60 changes: 60 additions & 0 deletions ext/dom/tests/ghsa-p3x9-6h7p-cgfc_001.phpt
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
--TEST--
GHSA-p3x9-6h7p-cgfc: libxml streams use wrong `content-type` header when requesting a redirected resource (Basic)
--EXTENSIONS--
dom
--SKIPIF--
<?php
if (@!include "./ext/standard/tests/http/server.inc") die('skip server.inc not available');
http_server_skipif();
?>
--FILE--
<?php
require "./ext/standard/tests/http/server.inc";

function genResponses($server) {
$uri = 'http://' . stream_socket_get_name($server, false);
yield "data://text/plain,HTTP/1.1 302 Moved Temporarily\r\nLocation: $uri/document.xml\r\nContent-Type: text/html;charset=utf-16\r\n\r\n";
$xml = <<<'EOT'
<!doctype html>
<html>
<head>
<title>GHSA-p3x9-6h7p-cgfc</title>

<meta charset="utf-8" />
<meta http-equiv="Content-type" content="text/html; charset=utf-8" />
</head>

<body>
<h1>GHSA-p3x9-6h7p-cgfc</h1>
</body>
</html>
EOT;
// Intentionally using non-standard casing for content-type to verify it is matched not case sensitively.
yield "data://text/plain,HTTP/1.1 200 OK\r\nconteNt-tyPe: text/html; charset=utf-8\r\n\r\n{$xml}";
}

['pid' => $pid, 'uri' => $uri] = http_server('genResponses', $output);
$document = new \DOMDocument();
$document->loadHTMLFile($uri);

$h1 = $document->getElementsByTagName('h1');
var_dump($h1->length);
var_dump($document->saveHTML());
http_server_kill($pid);
?>
--EXPECT--
int(1)
string(266) "<!DOCTYPE html>
<html>
<head>
<title>GHSA-p3x9-6h7p-cgfc</title>

<meta charset="utf-8">
<meta http-equiv="Content-type" content="text/html; charset=utf-8">
</head>

<body>
<h1>GHSA-p3x9-6h7p-cgfc</h1>
</body>
</html>
"
60 changes: 60 additions & 0 deletions ext/dom/tests/ghsa-p3x9-6h7p-cgfc_002.phpt
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
--TEST--
GHSA-p3x9-6h7p-cgfc: libxml streams use wrong `content-type` header when requesting a redirected resource (Missing content-type)
--EXTENSIONS--
dom
--SKIPIF--
<?php
if (@!include "./ext/standard/tests/http/server.inc") die('skip server.inc not available');
http_server_skipif();
?>
--FILE--
<?php
require "./ext/standard/tests/http/server.inc";

function genResponses($server) {
$uri = 'http://' . stream_socket_get_name($server, false);
yield "data://text/plain,HTTP/1.1 302 Moved Temporarily\r\nLocation: $uri/document.xml\r\nContent-Type: text/html;charset=utf-16\r\n\r\n";
$xml = <<<'EOT'
<!doctype html>
<html>
<head>
<title>GHSA-p3x9-6h7p-cgfc</title>

<meta charset="utf-8" />
<meta http-equiv="Content-type" content="text/html; charset=utf-8" />
</head>

<body>
<h1>GHSA-p3x9-6h7p-cgfc</h1>
</body>
</html>
EOT;
// Missing content-type in actual response.
yield "data://text/plain,HTTP/1.1 200 OK\r\n\r\n{$xml}";
}

['pid' => $pid, 'uri' => $uri] = http_server('genResponses', $output);
$document = new \DOMDocument();
$document->loadHTMLFile($uri);

$h1 = $document->getElementsByTagName('h1');
var_dump($h1->length);
var_dump($document->saveHTML());
http_server_kill($pid);
?>
--EXPECT--
int(1)
string(266) "<!DOCTYPE html>
<html>
<head>
<title>GHSA-p3x9-6h7p-cgfc</title>

<meta charset="utf-8">
<meta http-equiv="Content-type" content="text/html; charset=utf-8">
</head>

<body>
<h1>GHSA-p3x9-6h7p-cgfc</h1>
</body>
</html>
"
60 changes: 60 additions & 0 deletions ext/dom/tests/ghsa-p3x9-6h7p-cgfc_003.phpt
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
--TEST--
GHSA-p3x9-6h7p-cgfc: libxml streams use wrong `content-type` header when requesting a redirected resource (Reason with colon)
--EXTENSIONS--
dom
--SKIPIF--
<?php
if (@!include "./ext/standard/tests/http/server.inc") die('skip server.inc not available');
http_server_skipif();
?>
--FILE--
<?php
require "./ext/standard/tests/http/server.inc";

function genResponses($server) {
$uri = 'http://' . stream_socket_get_name($server, false);
yield "data://text/plain,HTTP/1.1 302 Moved Temporarily\r\nLocation: $uri/document.xml\r\nContent-Type: text/html;charset=utf-16\r\n\r\n";
$xml = <<<'EOT'
<!doctype html>
<html>
<head>
<title>GHSA-p3x9-6h7p-cgfc</title>
<meta charset="utf-8" />
<meta http-equiv="Content-type" content="text/html; charset=utf-8" />
</head>
<body>
<h1>GHSA-p3x9-6h7p-cgfc</h1>
</body>
</html>
EOT;
// Missing content-type in actual response.
yield "data://text/plain,HTTP/1.1 200 OK: This is fine\r\n\r\n{$xml}";
}

['pid' => $pid, 'uri' => $uri] = http_server('genResponses', $output);
$document = new \DOMDocument();
$document->loadHTMLFile($uri);

$h1 = $document->getElementsByTagName('h1');
var_dump($h1->length);
var_dump($document->saveHTML());
http_server_kill($pid);
?>
--EXPECT--
int(1)
string(266) "<!DOCTYPE html>
<html>
<head>
<title>GHSA-p3x9-6h7p-cgfc</title>

<meta charset="utf-8">
<meta http-equiv="Content-type" content="text/html; charset=utf-8">
</head>

<body>
<h1>GHSA-p3x9-6h7p-cgfc</h1>
</body>
</html>
"
20 changes: 15 additions & 5 deletions ext/libxml/mime_sniff.c
Original file line number Diff line number Diff line change
Expand Up @@ -308,11 +308,21 @@ PHP_LIBXML_API zend_string *php_libxml_sniff_charset_from_stream(const php_strea
if (Z_TYPE(s->wrapperdata) == IS_ARRAY) {
zval *header;

ZEND_HASH_FOREACH_VAL_IND(Z_ARRVAL(s->wrapperdata), header) {
const char buf[] = "Content-Type:";
if (Z_TYPE_P(header) == IS_STRING &&
!zend_binary_strncasecmp(Z_STRVAL_P(header), Z_STRLEN_P(header), buf, sizeof(buf)-1, sizeof(buf)-1)) {
return php_libxml_sniff_charset_from_string(Z_STRVAL_P(header) + sizeof(buf) - 1, Z_STRVAL_P(header) + Z_STRLEN_P(header));
/* Scan backwards: The header array might contain the headers for multiple responses, if
* a redirect was followed.
*/
ZEND_HASH_REVERSE_FOREACH_VAL_IND(Z_ARRVAL(s->wrapperdata), header) {
if (Z_TYPE_P(header) == IS_STRING) {
/* If no colon is found in the header, we assume it's the HTTP status line and bail out. */
char *colon = memchr(Z_STRVAL_P(header), ':', Z_STRLEN_P(header));
char *space = memchr(Z_STRVAL_P(header), ' ', Z_STRLEN_P(header));
if (colon == NULL || space < colon) {
return NULL;
}

if (zend_string_starts_with_literal_ci(Z_STR_P(header), "content-type:")) {
return php_libxml_sniff_charset_from_string(Z_STRVAL_P(header) + strlen("content-type:"), Z_STRVAL_P(header) + Z_STRLEN_P(header));
}
}
} ZEND_HASH_FOREACH_END();
}
Expand Down
7 changes: 7 additions & 0 deletions ext/sockets/sockets.stub.php
Original file line number Diff line number Diff line change
Expand Up @@ -454,6 +454,13 @@
*/
const SO_EXCLBIND = UNKNOWN;
#endif
#ifdef SO_BUSY_POLL
/**
* @var int
* @cvalue SO_BUSY_POLL
*/
const SO_BUSY_POLL = UNKNOWN;
#endif
#ifdef SKF_AD_OFF
/**
* @var int
Expand Down
5 changes: 4 additions & 1 deletion ext/sockets/sockets_arginfo.h

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Loading
Loading