]> granicus.if.org Git - php/commitdiff
Add a few callable method parameter types to ext/sqlite3
authorMáté Kocsis <kocsismate@woohoolabs.com>
Fri, 14 Aug 2020 09:59:25 +0000 (11:59 +0200)
committerMáté Kocsis <kocsismate@woohoolabs.com>
Fri, 14 Aug 2020 11:43:11 +0000 (13:43 +0200)
Closes GH-5988

ext/sqlite3/sqlite3.c
ext/sqlite3/sqlite3.stub.php
ext/sqlite3/sqlite3_arginfo.h
ext/sqlite3/tests/sqlite3_33_createAggregate_notcallable.phpt

index 333116d4158ed4893c3d6cf87d0ce695bffdc9c0..ad85d0f11f465bb4faef56fdad322cec0e0dbb6c 100644 (file)
@@ -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;
index bae34bd0ffebef4486c0075cf7234e8110327874..d2435051e14e0fff18fdb15d1b344d7826a489d3 100644 (file)
@@ -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) {}
index 79b0cfbcb13603168f400414bffb27a6ac0e30a4..7e0cf2ec175bb0dcd1ea08d32f9fd30f2beabc62 100644 (file)
@@ -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)
index fe7c8fb75a05ce15d51f0fec8919e30a20670024..0a277d41b5507eebd8d2f457dd609e2e286a3303 100644 (file)
@@ -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