From 17e41b00ed74bde609471b1f53c8cd5a871ca508 Mon Sep 17 00:00:00 2001 From: Saki Takamachi Date: Fri, 19 Apr 2024 22:02:30 +0900 Subject: [PATCH 1/2] Add test first --- ext/pdo_sqlite/tests/gh13998.phpt | 25 +++++++++++++++++++++++++ 1 file changed, 25 insertions(+) create mode 100644 ext/pdo_sqlite/tests/gh13998.phpt diff --git a/ext/pdo_sqlite/tests/gh13998.phpt b/ext/pdo_sqlite/tests/gh13998.phpt new file mode 100644 index 0000000000000..c87b4acdd214b --- /dev/null +++ b/ext/pdo_sqlite/tests/gh13998.phpt @@ -0,0 +1,25 @@ +--TEST-- +Fix GH-13998: Manage refcount of agg_context->val correctly +--EXTENSIONS-- +pdo_sqlite +--FILE-- +query('CREATE TABLE test (a int, b int)'); +$stmt = $db->query('INSERT INTO test VALUES (1, 1), (2, 2), (3, 3)'); +$db->sqliteCreateAggregate('S', $step, $finalize, 1); + +try { + $db->query('SELECT S(a) FROM test'); +} catch (Exception $e) { + echo 'done!'; +} +?> +--EXPECT-- +done! From a3a2e02b0c049a36cd67a688cfde10bfba784e11 Mon Sep 17 00:00:00 2001 From: Saki Takamachi Date: Fri, 19 Apr 2024 22:47:02 +0900 Subject: [PATCH 2/2] Manage refcount of agg_context->val correctly When step_callback fails, agg_context->val is passed dtor, but agg_context->val is also used in final_callback regardless of the success/failure of step_callback, so should not call dtor. --- ext/pdo_sqlite/sqlite_driver.c | 1 - 1 file changed, 1 deletion(-) diff --git a/ext/pdo_sqlite/sqlite_driver.c b/ext/pdo_sqlite/sqlite_driver.c index 2f494c2ddb8b3..03b212bf75c1b 100644 --- a/ext/pdo_sqlite/sqlite_driver.c +++ b/ext/pdo_sqlite/sqlite_driver.c @@ -441,7 +441,6 @@ static int do_callback(struct pdo_sqlite_fci *fc, zval *cb, * the context */ if (agg_context) { if (Z_ISUNDEF(retval)) { - zval_ptr_dtor(&agg_context->val); return FAILURE; } zval_ptr_dtor(Z_REFVAL(agg_context->val));