Commit d2780bcbaea for php.net

commit d2780bcbaea2c9e90dbff482eced68ad3a98b499
Author: Ilija Tovilo <ilija.tovilo@me.com>
Date:   Wed Aug 5 16:28:48 2026 +0200

    Fix use-after-free in OpenSSL empty cafile warning (GH-22880)

diff --git a/ext/openssl/tests/stream_cafile_no_valid_certs.phpt b/ext/openssl/tests/stream_cafile_no_valid_certs.phpt
new file mode 100644
index 00000000000..4622dfbf576
--- /dev/null
+++ b/ext/openssl/tests/stream_cafile_no_valid_certs.phpt
@@ -0,0 +1,42 @@
+--TEST--
+SSL cafile stream containing no valid certificates
+--EXTENSIONS--
+openssl
+--SKIPIF--
+<?php
+if (!function_exists('proc_open')) die('skip no proc_open');
+?>
+--FILE--
+<?php
+$serverCode = <<<'CODE'
+    $server = stream_socket_server('tcp://127.0.0.1:0', $errno, $errstr);
+    phpt_notify_server_start($server);
+
+    $client = stream_socket_accept($server, 2);
+    if ($client) {
+        fclose($client);
+    }
+CODE;
+
+$clientCode = <<<'CODE'
+    $context = stream_context_create(['ssl' => [
+        'cafile' => 'file://%s',
+    ]]);
+    var_dump(stream_socket_client(
+        'ssl://{{ ADDR }}',
+        timeout: 2,
+        context: $context,
+    ));
+CODE;
+$clientCode = sprintf($clientCode, __DIR__ . '/plain.txt');
+
+include 'ServerClientTestCase.inc';
+ServerClientTestCase::getInstance()->run($clientCode, $serverCode);
+?>
+--EXPECTF--
+Warning: stream_socket_client(): no valid certs found cafile stream: '%s' in %sServerClientTestCase.inc(%d) : eval()'d code on line 4
+
+Warning: stream_socket_client(): Failed to enable crypto in %sServerClientTestCase.inc(%d) : eval()'d code on line 4
+
+Warning: stream_socket_client(): Unable to connect to ssl://127.0.0.1:%d (Unknown error) in %sServerClientTestCase.inc(%d) : eval()'d code on line 4
+bool(false)
diff --git a/ext/openssl/xp_ssl.c b/ext/openssl/xp_ssl.c
index 130d3717ccc..269de954538 100644
--- a/ext/openssl/xp_ssl.c
+++ b/ext/openssl/xp_ssl.c
@@ -947,15 +947,14 @@ static long php_openssl_load_stream_cafile(X509_STORE *cert_store, const char *c
 		goto cert_start;
 	}

-	stream_complete: {
-		php_stream_close(stream);
-		if (buffer_active == 1) {
-			BIO_free(buffer);
-		}
+stream_complete:
+	if (certs_added == 0) {
+		php_stream_warn(stream, DecodingFailed, "no valid certs found cafile stream: '%s'", cafile);
 	}

-	if (certs_added == 0) {
-		php_stream_warn(stream, DecodingFailed, "no valid certs found cafile stream: `%s'", cafile);
+	php_stream_close(stream);
+	if (buffer_active == 1) {
+		BIO_free(buffer);
 	}

 	return certs_added;