Commit e10141588ac for php.net

commit e10141588ac5446851386a04a96d638cf0a0e681
Author: Gina Peter Banyard <girgias@php.net>
Date:   Sun Jul 19 17:15:32 2026 +0100

    stream: improve bugfix, check class is instantiable prior to registering (#22806)

    Rather than when attempting to create an instance of it within the stream layer.

diff --git a/ext/standard/tests/streams/bug74951.phpt b/ext/standard/tests/streams/bug74951.phpt
index b30b5fe2824..2668f541fb3 100644
--- a/ext/standard/tests/streams/bug74951.phpt
+++ b/ext/standard/tests/streams/bug74951.phpt
@@ -6,8 +6,12 @@ trait Stream00ploiter{
   public function s() {}
   public function n($_) {}
 }
-stream_wrapper_register('e0ploit','Stream00ploiter');
-$s=fopen('e0ploit://',0);
+
+try {
+	stream_wrapper_register('e0ploit','Stream00ploiter');
+} catch (\Throwable $e) {
+    echo $e::class, ': ', $e->getMessage(), \PHP_EOL;
+}
 ?>
---EXPECTF--
-Warning: fopen(): Failed to open stream: operation failed in %s%ebug74951.php on line 7
+--EXPECT--
+ValueError: stream_wrapper_register(): Argument #2 ($class) must be a concrete class
diff --git a/main/streams/userspace.c b/main/streams/userspace.c
index bf6ffa50096..9b6f283c075 100644
--- a/main/streams/userspace.c
+++ b/main/streams/userspace.c
@@ -249,10 +249,7 @@ typedef struct _php_userstream_data php_userstream_data_t;

 static void user_stream_create_object(struct php_user_stream_wrapper *uwrap, php_stream_context *context, zval *object)
 {
-	if (uwrap->ce->ce_flags & (ZEND_ACC_INTERFACE|ZEND_ACC_TRAIT|ZEND_ACC_IMPLICIT_ABSTRACT_CLASS|ZEND_ACC_EXPLICIT_ABSTRACT_CLASS)) {
-		ZVAL_UNDEF(object);
-		return;
-	}
+	ZEND_ASSERT((uwrap->ce->ce_flags & ZEND_ACC_UNINSTANTIABLE) == 0);

 	/* create an instance of our class */
 	if (object_init_ex(object, uwrap->ce) == FAILURE) {
@@ -467,6 +464,11 @@ PHP_FUNCTION(stream_wrapper_register)
 		RETURN_THROWS();
 	}

+	if (UNEXPECTED(ce->ce_flags & ZEND_ACC_UNINSTANTIABLE)) {
+		zend_argument_value_error(2, "must be a concrete class");
+		RETURN_THROWS();
+	}
+
 	uwrap = (struct php_user_stream_wrapper *)ecalloc(1, sizeof(*uwrap));
 	uwrap->ce = ce;
 	uwrap->wrapper.wops = &user_stream_wops;