Commit 2a712fb5577 for php.net

commit 2a712fb55775da4cdee2334c15ad391ff8852b20
Author: Jakub Zelenka <bukka@php.net>
Date:   Sun Jul 12 21:02:45 2026 +0200

    Fix flaky stream_socket_get_crypto_status handshake test (#22707)

    The test could intermittently fail because a non-blocking TLS handshake
    can complete in a single stream_socket_enable_crypto() call, so
    WANT_READ/WANT_WRITE was never observed and $sawWant stayed false.

    Route the connection through a plain TCP proxy that forwards the server
    handshake flight in fragments, forcing the client to see a partial TLS
    record and report WANT_READ at least once.

diff --git a/ext/openssl/tests/stream_socket_get_crypto_status_handshake.phpt b/ext/openssl/tests/stream_socket_get_crypto_status_handshake.phpt
index 2a1c554a79d..7e0f660c980 100644
--- a/ext/openssl/tests/stream_socket_get_crypto_status_handshake.phpt
+++ b/ext/openssl/tests/stream_socket_get_crypto_status_handshake.phpt
@@ -27,6 +27,46 @@
 CODE;
 $serverCode = sprintf($serverCode, $certFile);

+/* Plain TCP proxy that forwards the server handshake flight in fragments, so the client's
+ * non-blocking handshake sees a partial TLS record and reports WANT_READ instead of completing
+ * in a single call (which can otherwise happen depending on timing). */
+$proxyCode = <<<'CODE'
+    $upstream = stream_socket_client("tcp://{{ ADDR }}", $errno, $errstr, 30, STREAM_CLIENT_CONNECT);
+    stream_set_blocking($upstream, false);
+
+    $flags = STREAM_SERVER_BIND|STREAM_SERVER_LISTEN;
+    $server = stream_socket_server("tcp://127.0.0.1:0", $errno, $errstr, $flags);
+    phpt_notify_server_start($server);
+
+    $conn = stream_socket_accept($server);
+    stream_set_blocking($conn, false);
+
+    $read = [$upstream, $conn];
+    while (stream_select($read, $write, $except, 1)) {
+        foreach ($read as $fp) {
+            $data = stream_get_contents($fp);
+            if ($data === '') {
+                continue;
+            }
+            if ($fp === $conn) {
+                fwrite($upstream, $data);
+            } else {
+                /* Fragment server -> client to force a partial TLS record. */
+                foreach (str_split($data, (int) ceil(strlen($data) / 3)) as $part) {
+                    fwrite($conn, $part);
+                    usleep(50000);
+                }
+            }
+        }
+        if (feof($upstream) || feof($conn)) {
+            break;
+        }
+        $read = [$upstream, $conn];
+    }
+
+    phpt_wait();
+CODE;
+
 /* Client connects over plain TCP, then completes the TLS handshake in non-blocking mode, using
  *  the reported crypto status to select the right direction to wait on. */
 $clientCode = <<<'CODE'
@@ -73,7 +113,8 @@

     stream_set_blocking($client, true);
     echo trim(fgets($client)), "\n";
-    phpt_notify();
+    phpt_notify('server');
+    phpt_notify('proxy');
     fclose($client);
 CODE;
 $clientCode = sprintf($clientCode, $peerName);
@@ -83,7 +124,10 @@
 $certificateGenerator->saveNewCertAsFileWithKey($peerName, $certFile);

 include 'ServerClientTestCase.inc';
-ServerClientTestCase::getInstance()->run($clientCode, $serverCode);
+ServerClientTestCase::getInstance()->run($clientCode, [
+    'server' => $serverCode,
+    'proxy' => $proxyCode,
+]);
 ?>
 --CLEAN--
 <?php