From 29a96e09b295f78d249423f9e0dd3c4becdd96fe Mon Sep 17 00:00:00 2001 From: nielsdos <7771979+nielsdos@users.noreply.github.com> Date: Wed, 14 Jun 2023 20:37:03 +0200 Subject: [PATCH] Fix GH-11451: Invalid associative array containing duplicate keys It used the "add_new" variant which assumes the key doesn't already exist. But in case of duplicate keys we have to take the last result. Closes GH-11453. --- NEWS | 4 ++++ ext/sqlite3/sqlite3.c | 4 +++- ext/sqlite3/tests/gh11451.phpt | 25 +++++++++++++++++++++++++ 3 files changed, 32 insertions(+), 1 deletion(-) create mode 100644 ext/sqlite3/tests/gh11451.phpt diff --git a/NEWS b/NEWS index 19fd47a3000..3e0eee0d5e5 100644 --- a/NEWS +++ b/NEWS @@ -63,6 +63,10 @@ PHP NEWS . Fix access on NULL pointer in array_merge_recursive(). (ilutov) . Fix exception handling in array_multisort(). (ilutov) +- SQLite3: + . Fixed bug GH-11451 (Invalid associative array containing duplicate + keys). (nielsdos) + 08 Jun 2023, PHP 8.2.7 - Core: diff --git a/ext/sqlite3/sqlite3.c b/ext/sqlite3/sqlite3.c index d97f8b5fa53..2b9e18d12f1 100644 --- a/ext/sqlite3/sqlite3.c +++ b/ext/sqlite3/sqlite3.c @@ -1982,7 +1982,9 @@ PHP_METHOD(SQLite3Result, fetchArray) Z_ADDREF(data); } } - zend_symtable_add_new(Z_ARR_P(return_value), result_obj->column_names[i], &data); + /* Note: we can't use the "add_new" variant here instead of "update" because + * when the same column name is encountered, the last result should be taken. */ + zend_symtable_update(Z_ARR_P(return_value), result_obj->column_names[i], &data); } } break; diff --git a/ext/sqlite3/tests/gh11451.phpt b/ext/sqlite3/tests/gh11451.phpt new file mode 100644 index 00000000000..e518c39b18b --- /dev/null +++ b/ext/sqlite3/tests/gh11451.phpt @@ -0,0 +1,25 @@ +--TEST-- +GH-11451 (Invalid associative array containing duplicate keys) +--EXTENSIONS-- +sqlite3 +--FILE-- +query('SELECT 1 AS key, 2 AS key') + ->fetchArray(SQLITE3_ASSOC)); + +var_dump((new SQLite3(':memory:')) + ->query('SELECT 0 AS dummy, 1 AS key, 2 AS key') + ->fetchArray(SQLITE3_ASSOC)); +?> +--EXPECT-- +array(1) { + ["key"]=> + int(2) +} +array(2) { + ["dummy"]=> + int(0) + ["key"]=> + int(2) +}