From d72161505cd8904b5f3244bba0f7a51f6f6008fd Mon Sep 17 00:00:00 2001 From: =?utf8?q?M=C3=A1t=C3=A9=20Kocsis?= Date: Fri, 14 Aug 2020 11:59:25 +0200 Subject: [PATCH] Add a few callable method parameter types to ext/sqlite3 Closes GH-5988 --- ext/sqlite3/sqlite3.c | 51 +++++-------------- ext/sqlite3/sqlite3.stub.php | 26 +++------- ext/sqlite3/sqlite3_arginfo.h | 10 ++-- ...qlite3_33_createAggregate_notcallable.phpt | 21 +++++--- 4 files changed, 41 insertions(+), 67 deletions(-) diff --git a/ext/sqlite3/sqlite3.c b/ext/sqlite3/sqlite3.c index 333116d415..ad85d0f11f 100644 --- a/ext/sqlite3/sqlite3.c +++ b/ext/sqlite3/sqlite3.c @@ -952,12 +952,13 @@ PHP_METHOD(SQLite3, createFunction) php_sqlite3_func *func; char *sql_func; size_t sql_func_len; - zval *callback_func; + zend_fcall_info fci; + zend_fcall_info_cache fcc; zend_long sql_func_num_args = -1; zend_long flags = 0; db_obj = Z_SQLITE3_DB_P(object); - if (zend_parse_parameters(ZEND_NUM_ARGS(), "sz|ll", &sql_func, &sql_func_len, &callback_func, &sql_func_num_args, &flags) == FAILURE) { + if (zend_parse_parameters(ZEND_NUM_ARGS(), "sf|ll", &sql_func, &sql_func_len, &fci, &fcc, &sql_func_num_args, &flags) == FAILURE) { RETURN_THROWS(); } @@ -967,19 +968,12 @@ PHP_METHOD(SQLite3, createFunction) RETURN_FALSE; } - if (!zend_is_callable(callback_func, 0, NULL)) { - zend_string *callback_name = zend_get_callable_name(callback_func); - php_sqlite3_error(db_obj, "Not a valid callback function %s", ZSTR_VAL(callback_name)); - zend_string_release_ex(callback_name, 0); - RETURN_FALSE; - } - func = (php_sqlite3_func *)ecalloc(1, sizeof(*func)); if (sqlite3_create_function(db_obj->db, sql_func, sql_func_num_args, flags | SQLITE_UTF8, func, php_sqlite3_callback_func, NULL, NULL) == SQLITE_OK) { func->func_name = estrdup(sql_func); - ZVAL_COPY(&func->func, callback_func); + ZVAL_COPY(&func->func, &fci.function_name); func->argc = sql_func_num_args; func->next = db_obj->funcs; @@ -1001,11 +995,12 @@ PHP_METHOD(SQLite3, createAggregate) php_sqlite3_func *func; char *sql_func; size_t sql_func_len; - zval *step_callback, *fini_callback; + zend_fcall_info step_fci, fini_fci; + zend_fcall_info_cache step_fcc, fini_fcc; zend_long sql_func_num_args = -1; db_obj = Z_SQLITE3_DB_P(object); - if (zend_parse_parameters(ZEND_NUM_ARGS(), "szz|l", &sql_func, &sql_func_len, &step_callback, &fini_callback, &sql_func_num_args) == FAILURE) { + if (zend_parse_parameters(ZEND_NUM_ARGS(), "sff|l", &sql_func, &sql_func_len, &step_fci, &step_fcc, &fini_fci, &fini_fcc, &sql_func_num_args) == FAILURE) { RETURN_THROWS(); } @@ -1015,27 +1010,13 @@ PHP_METHOD(SQLite3, createAggregate) RETURN_FALSE; } - if (!zend_is_callable(step_callback, 0, NULL)) { - zend_string *callback_name = zend_get_callable_name(step_callback); - php_sqlite3_error(db_obj, "Not a valid callback function %s", ZSTR_VAL(callback_name)); - zend_string_release_ex(callback_name, 0); - RETURN_FALSE; - } - - if (!zend_is_callable(fini_callback, 0, NULL)) { - zend_string *callback_name = zend_get_callable_name(fini_callback); - php_sqlite3_error(db_obj, "Not a valid callback function %s", ZSTR_VAL(callback_name)); - zend_string_release_ex(callback_name, 0); - RETURN_FALSE; - } - func = (php_sqlite3_func *)ecalloc(1, sizeof(*func)); if (sqlite3_create_function(db_obj->db, sql_func, sql_func_num_args, SQLITE_UTF8, func, NULL, php_sqlite3_callback_step, php_sqlite3_callback_final) == SQLITE_OK) { func->func_name = estrdup(sql_func); - ZVAL_COPY(&func->step, step_callback); - ZVAL_COPY(&func->fini, fini_callback); + ZVAL_COPY(&func->step, &step_fci.function_name); + ZVAL_COPY(&func->fini, &fini_fci.function_name); func->argc = sql_func_num_args; func->next = db_obj->funcs; @@ -1057,10 +1038,11 @@ PHP_METHOD(SQLite3, createCollation) php_sqlite3_collation *collation; char *collation_name; size_t collation_name_len; - zval *callback_func; + zend_fcall_info fci; + zend_fcall_info_cache fcc; db_obj = Z_SQLITE3_DB_P(object); - if (zend_parse_parameters(ZEND_NUM_ARGS(), "sz", &collation_name, &collation_name_len, &callback_func) == FAILURE) { + if (zend_parse_parameters(ZEND_NUM_ARGS(), "sf", &collation_name, &collation_name_len, &fci, &fcc) == FAILURE) { RETURN_THROWS(); } @@ -1070,18 +1052,11 @@ PHP_METHOD(SQLite3, createCollation) RETURN_FALSE; } - if (!zend_is_callable(callback_func, 0, NULL)) { - zend_string *callback_name = zend_get_callable_name(callback_func); - php_sqlite3_error(db_obj, "Not a valid callback function %s", ZSTR_VAL(callback_name)); - zend_string_release_ex(callback_name, 0); - RETURN_FALSE; - } - collation = (php_sqlite3_collation *)ecalloc(1, sizeof(*collation)); if (sqlite3_create_collation(db_obj->db, collation_name, SQLITE_UTF8, collation, php_sqlite3_callback_compare) == SQLITE_OK) { collation->collation_name = estrdup(collation_name); - ZVAL_COPY(&collation->cmp_func, callback_func); + ZVAL_COPY(&collation->cmp_func, &fci.function_name); collation->next = db_obj->collations; db_obj->collations = collation; diff --git a/ext/sqlite3/sqlite3.stub.php b/ext/sqlite3/sqlite3.stub.php index bae34bd0ff..d2435051e1 100644 --- a/ext/sqlite3/sqlite3.stub.php +++ b/ext/sqlite3/sqlite3.stub.php @@ -59,24 +59,14 @@ class SQLite3 /** @return mixed */ public function querySingle(string $query, bool $entire_row = false) {} - /** - * @param callable $callback - * @return bool - */ - public function createFunction(string $name, $callback, int $argument_count = -1, int $flags = 0) {} - - /** - * @param callable $step_callback - * @param callable $final_callback - * @return bool - */ - public function createAggregate(string $name, $step_callback, $final_callback, int $argument_count = -1) {} - - /** - * @param callable $callback - * @return bool - */ - public function createCollation(string $name, $callback) {} + /** @return bool */ + public function createFunction(string $name, callable $callback, int $argument_count = -1, int $flags = 0) {} + + /** @return bool */ + public function createAggregate(string $name, callable $step_callback, callable $final_callback, int $argument_count = -1) {} + + /** @return bool */ + public function createCollation(string $name, callable $callback) {} /** @return resource|false */ public function openBlob(string $table, string $column, int $rowid, string $dbname = "main", int $flags = SQLITE3_OPEN_READONLY) {} diff --git a/ext/sqlite3/sqlite3_arginfo.h b/ext/sqlite3/sqlite3_arginfo.h index 79b0cfbcb1..7e0cf2ec17 100644 --- a/ext/sqlite3/sqlite3_arginfo.h +++ b/ext/sqlite3/sqlite3_arginfo.h @@ -1,5 +1,5 @@ /* This is a generated file, edit the .stub.php file instead. - * Stub hash: cc36f3299089a453fac76179377b68647c33786c */ + * Stub hash: d40496bbba4787b192a58896a9ca4858dc59dc76 */ ZEND_BEGIN_ARG_INFO_EX(arginfo_class_SQLite3___construct, 0, 0, 1) ZEND_ARG_TYPE_INFO(0, filename, IS_STRING, 0) @@ -61,21 +61,21 @@ ZEND_END_ARG_INFO() ZEND_BEGIN_ARG_INFO_EX(arginfo_class_SQLite3_createFunction, 0, 0, 2) ZEND_ARG_TYPE_INFO(0, name, IS_STRING, 0) - ZEND_ARG_INFO(0, callback) + ZEND_ARG_TYPE_INFO(0, callback, IS_CALLABLE, 0) ZEND_ARG_TYPE_INFO_WITH_DEFAULT_VALUE(0, argument_count, IS_LONG, 0, "-1") ZEND_ARG_TYPE_INFO_WITH_DEFAULT_VALUE(0, flags, IS_LONG, 0, "0") ZEND_END_ARG_INFO() ZEND_BEGIN_ARG_INFO_EX(arginfo_class_SQLite3_createAggregate, 0, 0, 3) ZEND_ARG_TYPE_INFO(0, name, IS_STRING, 0) - ZEND_ARG_INFO(0, step_callback) - ZEND_ARG_INFO(0, final_callback) + ZEND_ARG_TYPE_INFO(0, step_callback, IS_CALLABLE, 0) + ZEND_ARG_TYPE_INFO(0, final_callback, IS_CALLABLE, 0) ZEND_ARG_TYPE_INFO_WITH_DEFAULT_VALUE(0, argument_count, IS_LONG, 0, "-1") ZEND_END_ARG_INFO() ZEND_BEGIN_ARG_INFO_EX(arginfo_class_SQLite3_createCollation, 0, 0, 2) ZEND_ARG_TYPE_INFO(0, name, IS_STRING, 0) - ZEND_ARG_INFO(0, callback) + ZEND_ARG_TYPE_INFO(0, callback, IS_CALLABLE, 0) ZEND_END_ARG_INFO() ZEND_BEGIN_ARG_INFO_EX(arginfo_class_SQLite3_openBlob, 0, 0, 3) diff --git a/ext/sqlite3/tests/sqlite3_33_createAggregate_notcallable.phpt b/ext/sqlite3/tests/sqlite3_33_createAggregate_notcallable.phpt index fe7c8fb75a..0a277d41b5 100644 --- a/ext/sqlite3/tests/sqlite3_33_createAggregate_notcallable.phpt +++ b/ext/sqlite3/tests/sqlite3_33_createAggregate_notcallable.phpt @@ -13,17 +13,26 @@ function aggregate_final ($var) { return $var; } $db = new SQLite3(':memory:'); -$db->createAggregate ('TESTAGGREGATE', 'aggregate_test_step', 'aggregate_final'); -$db->createAggregate ('TESTAGGREGATE2', 'aggregate_step', 'aggregate_test_final'); +try { + $db->createAggregate('TESTAGGREGATE', 'aggregate_test_step', 'aggregate_final'); +} catch (TypeError $exception) { + echo $exception->getMessage() . "\n"; +} + +try { + $db->createAggregate('TESTAGGREGATE2', 'aggregate_step', 'aggregate_test_final'); +} catch (TypeError $exception) { + echo $exception->getMessage() . "\n"; +} + var_dump($db->createAggregate ('TESTAGGREGATE3', 'aggregate_step', 'aggregate_final')); $db->close(); echo "Done" ?> ---EXPECTF-- -Warning: SQLite3::createAggregate(): Not a valid callback function aggregate_test_step in %s on line %d - -Warning: SQLite3::createAggregate(): Not a valid callback function aggregate_test_final in %s on line %d +--EXPECT-- +SQLite3::createAggregate(): Argument #2 ($step_callback) must be a valid callback, function "aggregate_test_step" not found or invalid function name +SQLite3::createAggregate(): Argument #3 ($final_callback) must be a valid callback, function "aggregate_test_final" not found or invalid function name bool(true) Done -- 2.40.0