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;