[php-src] master: Merge branch 'PHP-8.4' into PHP-8.5

Ilia Alshanetsky <[email protected]>
Newsgroups gmane.comp.php.cvs.general
Message-ID <[email protected]>
Author: Ilia Alshanetsky (iliaal)
Date: 2026-08-31T06:26:14-04:00

Commit: https://github.com/php/php-src/commit/5bf50210a6c8110e0af88ebf3b4d667bf49f85f7
Raw diff: https://github.com/php/php-src/commit/5bf50210a6c8110e0af88ebf3b4d667bf49f85f7.diff

Merge branch 'PHP-8.4' into PHP-8.5

* PHP-8.4:
  Revert the mysqlnd wireprotocol length-encoded bounds checks

Changed paths:
  D  ext/mysqli/tests/mysqlnd_ok_packet_message_over_read.phpt
  D  ext/mysqli/tests/mysqlnd_rset_field_len_over_read.phpt
  D  ext/mysqli/tests/mysqlnd_rset_field_len_past_packet.phpt
  M  ext/mysqli/tests/fake_server.inc
  M  ext/mysqlnd/mysqlnd_wireprotocol.c


Diff:

diff --git a/ext/mysqli/tests/fake_server.inc b/ext/mysqli/tests/fake_server.inc
index 3af5c7459159..dad8bc52ddd1 100644
--- a/ext/mysqli/tests/fake_server.inc
+++ b/ext/mysqli/tests/fake_server.inc
@@ -721,19 +721,6 @@ function my_mysqli_test_auth_response_message_over_read(my_mysqli_fake_server_co
     $conn->read();
 }
 
-function my_mysqli_test_ok_packet_message_over_read(my_mysqli_fake_server_conn $conn): void
-{
-    $p = new my_mysqli_fake_packet();
-    $p->full = "08000001" . "00" . "00" . "00" . "0200" . "0000" . "fa";
-
-    $conn->send_server_greetings();
-    $conn->read_packets(1);
-    $conn->send_server_ok();
-    $conn->read_packets(1);
-    $conn->send($p->to_bytes(), "Malicious OK Packet [message length past the packet size]");
-    $conn->read();
-}
-
 function my_mysqli_test_stmt_response_row_over_read_string(my_mysqli_fake_server_conn $conn): void
 {
     $rh = $conn->packet_generator->server_stmt_execute_items_response();
@@ -829,50 +816,6 @@ function my_mysqli_test_stmt_response_row_read_two_fields(my_mysqli_fake_server_
     }
 }
 
-function my_mysqli_test_rset_field_metadata_len_over_read(my_mysqli_fake_server_conn $conn): void
-{
-    $rh = $conn->packet_generator->server_tabular_query_response();
-
-    $qr2 = new my_mysqli_fake_packet();
-    $qr2->packet_length = "0c0000";
-    $qr2->packet_number = "02";
-    $qr2->catalog_length_plus_name = "0161";
-    $qr2->db_length_plus_name = "0162";
-    $qr2->table_length_plus_name = "0163";
-    $qr2->original_t = "0164";
-    $qr2->name_length_plus_name = "0165";
-    $qr2->original_n = "fcff";
-
-    $conn->send_server_greetings();
-    $conn->read_packets(1);
-    $conn->send_server_ok();
-    $conn->read_packets(1);
-    $conn->send($conn->packets_to_bytes([$rh[0], $qr2]), "Malicious Tabular Response [metadata string length past the packet size]");
-    $conn->read();
-}
-
-function my_mysqli_test_rset_field_metadata_len_past_packet(my_mysqli_fake_server_conn $conn): void
-{
-    $rh = $conn->packet_generator->server_tabular_query_response();
-
-    $qr2 = new my_mysqli_fake_packet();
-    $qr2->packet_length = "0c0000";
-    $qr2->packet_number = "02";
-    $qr2->catalog_length_plus_name = "0161";
-    $qr2->db_length_plus_name = "0162";
-    $qr2->table_length_plus_name = "0163";
-    $qr2->original_t = "0164";
-    $qr2->name_length_plus_name = "0165";
-    $qr2->original_n = "0561";
-
-    $conn->send_server_greetings();
-    $conn->read_packets(1);
-    $conn->send_server_ok();
-    $conn->read_packets(1);
-    $conn->send($conn->packets_to_bytes([$rh[0], $qr2]), "Malicious Tabular Response [metadata string length past the packet size]");
-    $conn->read();
-}
-
 function my_mysqli_test_query_response_row_length_overflow(my_mysqli_fake_server_conn $conn): void
 {
     $rh = $conn->packet_generator->server_query_execute_data_response('strval');
diff --git a/ext/mysqli/tests/mysqlnd_ok_packet_message_over_read.phpt b/ext/mysqli/tests/mysqlnd_ok_packet_message_over_read.phpt
deleted file mode 100644
index 8364251e8df4..000000000000
--- a/ext/mysqli/tests/mysqlnd_ok_packet_message_over_read.phpt
+++ /dev/null
@@ -1,40 +0,0 @@
---TEST--
-mysqlnd OK packet message length buffer over-read
---EXTENSIONS--
-mysqli
---FILE--
-<?php
-require_once 'fake_server.inc';
-
-$servername = "127.0.0.1";
-$username = "root";
-$password = "";
-
-$process = run_fake_server_in_background('ok_packet_message_over_read');
-$process->wait();
-
-try {
-    $conn = new mysqli( $servername, $username, $password, "", $process->getPort());
-    var_dump($conn->select_db("test"));
-} catch (Exception $e) {
-    echo $e::class, ": ", $e->getMessage(), PHP_EOL;
-}
-
-$process->terminate();
-
-print "done!";
-?>
---EXPECTF--
-[*] Server started on 127.0.0.1:%d
-[*] Connection established
-[*] Sending - Server Greeting: %s
-[*] Received: %s
-[*] Sending - Server OK: %s
-[*] Received: %s
-[*] Sending - Malicious OK Packet [message length past the packet size]: %s
-
-Warning: mysqli::select_db(): OK packet message length is past the packet size in %s on line %d
-
-Warning: mysqli::select_db(): Error while reading INIT_DB's response packet. PID=%d in %s on line %d
-mysqli_sql_exception: Malformed packet
-done!
diff --git a/ext/mysqli/tests/mysqlnd_rset_field_len_over_read.phpt b/ext/mysqli/tests/mysqlnd_rset_field_len_over_read.phpt
deleted file mode 100644
index 274468ded63d..000000000000
--- a/ext/mysqli/tests/mysqlnd_rset_field_len_over_read.phpt
+++ /dev/null
@@ -1,42 +0,0 @@
---TEST--
-mysqlnd result set field metadata string length buffer over-read (len clamped to packet size)
---EXTENSIONS--
-mysqli
---FILE--
-<?php
-require_once 'fake_server.inc';
-
-$servername = "127.0.0.1";
-$username = "root";
-$password = "";
-
-$process = run_fake_server_in_background('rset_field_metadata_len_over_read');
-$process->wait();
-
-try {
-    $conn = new mysqli( $servername, $username, $password, "", $process->getPort());
-    var_dump($conn->query("SELECT * from users"));
-} catch (Exception $e) {
-    echo $e::class, ": ", $e->getMessage(), PHP_EOL;
-}
-
-$conn->close();
-
-$process->terminate();
-
-print "done!";
-?>
---EXPECTF--
-[*] Server started on 127.0.0.1:%d
-[*] Connection established
-[*] Sending - Server Greeting: 580000000a352e352e352d31302e352e31382d4d6172696144420003000000473e3f6047257c6700fef7080200ff81150000000000000f0000006c6b55463f49335f686c6431006d7973716c5f6e61746976655f70617373776f7264
-[*] Received: %s
-[*] Sending - Server OK: 0700000200000002000000
-[*] Received: %s
-[*] Sending - Malicious Tabular Response [metadata string length past the packet size]: 01000001010c00000201610162016301640165fcff
-
-Warning: mysqli::query(): Premature end of data (mysqlnd_wireprotocol.c:%d) in %s on line %d
-
-Warning: mysqli::query(): Result set field packet %d bytes shorter than expected in %s on line %d
-bool(false)
-done!
diff --git a/ext/mysqli/tests/mysqlnd_rset_field_len_past_packet.phpt b/ext/mysqli/tests/mysqlnd_rset_field_len_past_packet.phpt
deleted file mode 100644
index 020d28d95b25..000000000000
--- a/ext/mysqli/tests/mysqlnd_rset_field_len_past_packet.phpt
+++ /dev/null
@@ -1,40 +0,0 @@
---TEST--
-mysqlnd result set field metadata string length exceeds remaining packet bytes
---EXTENSIONS--
-mysqli
---FILE--
-<?php
-require_once 'fake_server.inc';
-
-$servername = "127.0.0.1";
-$username = "root";
-$password = "";
-
-$process = run_fake_server_in_background('rset_field_metadata_len_past_packet');
-$process->wait();
-
-try {
-    $conn = new mysqli( $servername, $username, $password, "", $process->getPort());
-    var_dump($conn->query("SELECT * from users"));
-} catch (Exception $e) {
-    echo $e::class, ": ", $e->getMessage(), PHP_EOL;
-}
-
-$conn->close();
-
-$process->terminate();
-
-print "done!";
-?>
---EXPECTF--
-[*] Server started on 127.0.0.1:%d
-[*] Connection established
-[*] Sending - Server Greeting: %s
-[*] Received: %s
-[*] Sending - Server OK: %s
-[*] Received: %s
-[*] Sending - Malicious Tabular Response [metadata string length past the packet size]: %s
-
-Warning: mysqli::query(): Result set field metadata string length is past the packet size in %s on line %d
-bool(false)
-done!
diff --git a/ext/mysqlnd/mysqlnd_wireprotocol.c b/ext/mysqlnd/mysqlnd_wireprotocol.c
index f0f95a970899..64c2c7969619 100644
--- a/ext/mysqlnd/mysqlnd_wireprotocol.c
+++ b/ext/mysqlnd/mysqlnd_wireprotocol.c
@@ -878,12 +878,7 @@ php_mysqlnd_ok_read(MYSQLND_CONN_DATA * conn, void * _packet)
 
 	/* There is a message */
 	if (packet->header.size > (size_t) (p - buf) && (net_len = php_mysqlnd_net_field_length(&p))) {
-		if ((p - buf) > packet->header.size || packet->header.size - (p - buf) < net_len) {
-			DBG_ERR_FMT("OK packet message length is past the packet size");
-			php_error_docref(NULL, E_WARNING, "OK packet message length is past the packet size");
-			DBG_RETURN(FAIL);
-		}
-		packet->message_len = net_len;
+		packet->message_len = MIN(net_len, buf_len - (p - begin));
 		packet->message = mnd_pestrndup((char *)p, packet->message_len, FALSE);
 	} else {
 		packet->message = NULL;
@@ -1176,17 +1171,10 @@ void php_mysqlnd_rset_header_free_mem(void * _packet)
 /* }}} */
 
 #define READ_RSET_FIELD(field_name) do { \
-		BAIL_IF_NO_MORE_DATA; \
 		len = php_mysqlnd_net_field_length(&p); \
 		if (UNEXPECTED(len == MYSQLND_NULL_LENGTH)) { \
 			goto faulty_or_fake; \
 		} else if (len != 0) { \
-			BAIL_IF_NO_MORE_DATA; \
-			if (UNEXPECTED((p - begin) > packet->header.size || packet->header.size - (p - begin) < len)) { \
-				DBG_ERR_FMT("Result set field metadata string length is past the packet size"); \
-				php_error_docref(NULL, E_WARNING, "Result set field metadata string length is past the packet size"); \
-				DBG_RETURN(FAIL); \
-			} \
 			meta->field_name = (const char *)p; \
 			meta->field_name ## _length = len; \
 			p += len; \
@@ -1255,7 +1243,7 @@ php_mysqlnd_rset_field_read(MYSQLND_CONN_DATA * conn, void * _packet)
 	READ_RSET_FIELD(name);
 	READ_RSET_FIELD(org_name);
 
-	BAIL_IF_NO_MORE_DATA;
+	/* 1 byte length */
 	if (UNEXPECTED(12 != *p)) {
 		DBG_ERR_FMT("Protocol error. Server sent false length. Expected 12 got %d", (int) *p);
 		php_error_docref(NULL, E_WARNING, "Protocol error. Server sent false length. Expected 12");
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.