From 40ccc8ea7e0b69d4580588a459a78a73b1209d08 Mon Sep 17 00:00:00 2001 From: Jakub Zelenka Date: Sun, 10 Dec 2023 22:30:04 +0000 Subject: [PATCH] Fix GH-9698: stream_wrapper_register crashes with FFI\CData provided as class Closes GH-12926 --- NEWS | 4 ++++ ext/ffi/ffi.c | 4 ++++ ext/ffi/tests/gh9698.phpt | 21 +++++++++++++++++++++ main/streams/userspace.c | 6 ++++++ 4 files changed, 35 insertions(+) create mode 100644 ext/ffi/tests/gh9698.phpt diff --git a/NEWS b/NEWS index e832fbeea0e..4a53cc18122 100644 --- a/NEWS +++ b/NEWS @@ -6,6 +6,10 @@ PHP NEWS . Fix incorrect timeout in built-in web server when using router script and max_input_time. (ilutov) +- FFI: + . Fixed bug GH-9698 (stream_wrapper_register crashes with FFI\CData). + (Jakub Zelenka) + - Hash: . Fixed bug GH-12936 (hash() function hangs endlessly if using sha512 on strings >= 4GiB). (nielsdos) diff --git a/ext/ffi/ffi.c b/ext/ffi/ffi.c index 9be5ac34059..098e35aba3d 100644 --- a/ext/ffi/ffi.c +++ b/ext/ffi/ffi.c @@ -1289,6 +1289,10 @@ static zval *zend_ffi_cdata_write_field(zend_object *obj, zend_string *field_nam if (cache_slot && *cache_slot == type) { field = *(cache_slot + 1); } else { + if (UNEXPECTED(type == NULL)) { + zend_throw_error(zend_ffi_exception_ce, "Attempt to assign field '%s' to uninitialized FFI\\CData object", ZSTR_VAL(field_name)); + return value; + } if (type->kind == ZEND_FFI_TYPE_POINTER) { type = ZEND_FFI_TYPE(type->pointer.type); } diff --git a/ext/ffi/tests/gh9698.phpt b/ext/ffi/tests/gh9698.phpt new file mode 100644 index 00000000000..bab403810cd --- /dev/null +++ b/ext/ffi/tests/gh9698.phpt @@ -0,0 +1,21 @@ +--TEST-- +GH-9698 (stream_wrapper_register crashes with FFI\CData provided as class) +--EXTENSIONS-- +ffi +--SKIPIF-- + +--FILE-- +getMessage(); +} +?> + +DONE +--EXPECT-- +Attempt to assign field 'context' to uninitialized FFI\CData object +DONE diff --git a/main/streams/userspace.c b/main/streams/userspace.c index f7223eab129..136654b1df2 100644 --- a/main/streams/userspace.c +++ b/main/streams/userspace.c @@ -304,6 +304,12 @@ static void user_stream_create_object(struct php_user_stream_wrapper *uwrap, php add_property_null(object, "context"); } + if (EG(exception) != NULL) { + zval_ptr_dtor(object); + ZVAL_UNDEF(object); + return; + } + if (uwrap->ce->constructor) { zend_call_known_instance_method_with_0_params( uwrap->ce->constructor, Z_OBJ_P(object), NULL);