From ef29ddcc274ef9ff835c9976a9e5c93087933d21 Mon Sep 17 00:00:00 2001 From: "Christoph M. Becker" Date: Thu, 10 Mar 2022 19:21:06 +0100 Subject: [PATCH] Fix GH-8068: mysqli_fetch_object creates inaccessible properties When fetching into objects, we need to create object style hash tables, i.e. where numeric column names are stored as string keys instead of integer keys. Instead of the slightly more efficient alternative to create the desired hash table in the first place, we go for the more readable implementation and convert the array style hash table using `zend_symtable_to_proptable()`. Co-authored-by: Kamil Tekiela Closes GH-8189. --- NEWS | 4 ++++ ext/mysqli/mysqli.c | 8 +++++--- ext/mysqli/tests/gh8068.phpt | 25 +++++++++++++++++++++++++ 3 files changed, 34 insertions(+), 3 deletions(-) create mode 100644 ext/mysqli/tests/gh8068.phpt diff --git a/NEWS b/NEWS index 6b31ab2f7c8..f0382c53877 100644 --- a/NEWS +++ b/NEWS @@ -11,6 +11,10 @@ PHP NEWS - Intl: . Fixed bug GH-8142 (Compilation error on cygwin). (David Carlier) +- MySQLi: + . Fixed bug GH-8068 (mysqli_fetch_object creates inaccessible properties). + (cmb) + - Pcntl: . Fixed bug GH-8142 (Compilation error on cygwin). (David Carlier) diff --git a/ext/mysqli/mysqli.c b/ext/mysqli/mysqli.c index 852eb02c6bc..165893b32f4 100644 --- a/ext/mysqli/mysqli.c +++ b/ext/mysqli/mysqli.c @@ -1198,11 +1198,13 @@ void php_mysqli_fetch_into_hash(INTERNAL_FUNCTION_PARAMETERS, int override_flags ZVAL_COPY_VALUE(&dataset, return_value); object_init_ex(return_value, ce); + HashTable *prop_table = zend_symtable_to_proptable(Z_ARR(dataset)); + zval_ptr_dtor(&dataset); if (!ce->default_properties_count && !ce->__set) { - Z_OBJ_P(return_value)->properties = Z_ARR(dataset); + Z_OBJ_P(return_value)->properties = prop_table; } else { - zend_merge_properties(return_value, Z_ARRVAL(dataset)); - zval_ptr_dtor(&dataset); + zend_merge_properties(return_value, prop_table); + zend_array_release(prop_table); } if (ce->constructor) { diff --git a/ext/mysqli/tests/gh8068.phpt b/ext/mysqli/tests/gh8068.phpt new file mode 100644 index 00000000000..db6ce230b93 --- /dev/null +++ b/ext/mysqli/tests/gh8068.phpt @@ -0,0 +1,25 @@ +--TEST-- +GH-8068 (mysqli_fetch_object creates inaccessible properties) +--SKIPIF-- + +--FILE-- +query('SELECT 42'); +$obj = $res->fetch_object(); +var_dump( + $obj, + $obj->{42} +); +?> +--EXPECT-- +object(stdClass)#4 (1) { + ["42"]=> + string(2) "42" +} +string(2) "42"