From a1097677a5497aa1d2ef54cf127a047d01f01631 Mon Sep 17 00:00:00 2001 From: George Peter Banyard Date: Tue, 21 Jul 2020 00:19:32 +0100 Subject: [PATCH] Use ZPP callable for PDO Sqlite --- ext/pdo_sqlite/sqlite_driver.c | 59 ++++++------------- .../tests/pdo_sqlite_createaggregate_002.phpt | 19 ++++-- .../tests/pdo_sqlite_createfunction_002.phpt | 10 +++- 3 files changed, 37 insertions(+), 51 deletions(-) diff --git a/ext/pdo_sqlite/sqlite_driver.c b/ext/pdo_sqlite/sqlite_driver.c index b96d59152e..c0962ff3f9 100644 --- a/ext/pdo_sqlite/sqlite_driver.c +++ b/ext/pdo_sqlite/sqlite_driver.c @@ -514,12 +514,13 @@ static int php_sqlite3_collation_callback(void *context, return ret; } -/* {{{ bool SQLite::sqliteCreateFunction(string name, mixed callback [, int argcount, int flags]) +/* {{{ bool SQLite::sqliteCreateFunction(string name, callable callback [, int argcount, int flags]) Registers a UDF with the sqlite db handle */ static PHP_METHOD(SQLite, sqliteCreateFunction) { struct pdo_sqlite_func *func; - zval *callback; + zend_fcall_info fci; + zend_fcall_info_cache fcc; char *func_name; size_t func_name_len; zend_long argc = -1; @@ -530,7 +531,7 @@ static PHP_METHOD(SQLite, sqliteCreateFunction) ZEND_PARSE_PARAMETERS_START(2, 4) Z_PARAM_STRING(func_name, func_name_len) - Z_PARAM_ZVAL(callback) + Z_PARAM_FUNC(fci, fcc) Z_PARAM_OPTIONAL Z_PARAM_LONG(argc) Z_PARAM_LONG(flags) @@ -539,13 +540,6 @@ static PHP_METHOD(SQLite, sqliteCreateFunction) dbh = Z_PDO_DBH_P(ZEND_THIS); PDO_CONSTRUCT_CHECK; - if (!zend_is_callable(callback, 0, NULL)) { - zend_string *cbname = zend_get_callable_name(callback); - php_error_docref(NULL, E_WARNING, "Function '%s' is not callable", ZSTR_VAL(cbname)); - zend_string_release_ex(cbname, 0); - RETURN_FALSE; - } - H = (pdo_sqlite_db_handle *)dbh->driver_data; func = (struct pdo_sqlite_func*)ecalloc(1, sizeof(*func)); @@ -555,7 +549,7 @@ static PHP_METHOD(SQLite, sqliteCreateFunction) if (ret == SQLITE_OK) { func->funcname = estrdup(func_name); - ZVAL_COPY(&func->func, callback); + ZVAL_COPY(&func->func, &fci.function_name); func->argc = argc; @@ -570,7 +564,7 @@ static PHP_METHOD(SQLite, sqliteCreateFunction) } /* }}} */ -/* {{{ bool SQLite::sqliteCreateAggregate(string name, mixed step, mixed fini [, int argcount]) +/* {{{ bool SQLite::sqliteCreateAggregate(string name, callable step, callable fini [, int argcount]) Registers a UDF with the sqlite db handle */ /* The step function should have the prototype: @@ -592,7 +586,8 @@ static PHP_METHOD(SQLite, sqliteCreateFunction) static PHP_METHOD(SQLite, sqliteCreateAggregate) { struct pdo_sqlite_func *func; - zval *step_callback, *fini_callback; + zend_fcall_info step_fci, fini_fci; + zend_fcall_info_cache step_fcc, fini_fcc; char *func_name; size_t func_name_len; zend_long argc = -1; @@ -602,8 +597,8 @@ static PHP_METHOD(SQLite, sqliteCreateAggregate) ZEND_PARSE_PARAMETERS_START(3, 4) Z_PARAM_STRING(func_name, func_name_len) - Z_PARAM_ZVAL(step_callback) - Z_PARAM_ZVAL(fini_callback) + Z_PARAM_FUNC(step_fci, step_fcc) + Z_PARAM_FUNC(fini_fci, fini_fcc) Z_PARAM_OPTIONAL Z_PARAM_LONG(argc) ZEND_PARSE_PARAMETERS_END(); @@ -611,20 +606,6 @@ static PHP_METHOD(SQLite, sqliteCreateAggregate) dbh = Z_PDO_DBH_P(ZEND_THIS); PDO_CONSTRUCT_CHECK; - if (!zend_is_callable(step_callback, 0, NULL)) { - zend_string *cbname = zend_get_callable_name(step_callback); - php_error_docref(NULL, E_WARNING, "Function '%s' is not callable", ZSTR_VAL(cbname)); - zend_string_release_ex(cbname, 0); - RETURN_FALSE; - } - - if (!zend_is_callable(fini_callback, 0, NULL)) { - zend_string *cbname = zend_get_callable_name(fini_callback); - php_error_docref(NULL, E_WARNING, "Function '%s' is not callable", ZSTR_VAL(cbname)); - zend_string_release_ex(cbname, 0); - RETURN_FALSE; - } - H = (pdo_sqlite_db_handle *)dbh->driver_data; func = (struct pdo_sqlite_func*)ecalloc(1, sizeof(*func)); @@ -634,9 +615,9 @@ static PHP_METHOD(SQLite, sqliteCreateAggregate) if (ret == SQLITE_OK) { func->funcname = estrdup(func_name); - ZVAL_COPY(&func->step, step_callback); + ZVAL_COPY(&func->step, &step_fci.function_name); - ZVAL_COPY(&func->fini, fini_callback); + ZVAL_COPY(&func->fini, &fini_fci.function_name); func->argc = argc; @@ -651,12 +632,13 @@ static PHP_METHOD(SQLite, sqliteCreateAggregate) } /* }}} */ -/* {{{ bool SQLite::sqliteCreateCollation(string name, mixed callback) +/* {{{ bool SQLite::sqliteCreateCollation(string name, callable callback) Registers a collation with the sqlite db handle */ static PHP_METHOD(SQLite, sqliteCreateCollation) { struct pdo_sqlite_collation *collation; - zval *callback; + zend_fcall_info fci; + zend_fcall_info_cache fcc; char *collation_name; size_t collation_name_len; pdo_dbh_t *dbh; @@ -665,19 +647,12 @@ static PHP_METHOD(SQLite, sqliteCreateCollation) ZEND_PARSE_PARAMETERS_START(2, 2) Z_PARAM_STRING(collation_name, collation_name_len) - Z_PARAM_ZVAL(callback) + Z_PARAM_FUNC(fci, fcc) ZEND_PARSE_PARAMETERS_END(); dbh = Z_PDO_DBH_P(ZEND_THIS); PDO_CONSTRUCT_CHECK; - if (!zend_is_callable(callback, 0, NULL)) { - zend_string *cbname = zend_get_callable_name(callback); - php_error_docref(NULL, E_WARNING, "Function '%s' is not callable", ZSTR_VAL(cbname)); - zend_string_release_ex(cbname, 0); - RETURN_FALSE; - } - H = (pdo_sqlite_db_handle *)dbh->driver_data; collation = (struct pdo_sqlite_collation*)ecalloc(1, sizeof(*collation)); @@ -686,7 +661,7 @@ static PHP_METHOD(SQLite, sqliteCreateCollation) if (ret == SQLITE_OK) { collation->name = estrdup(collation_name); - ZVAL_COPY(&collation->callback, callback); + ZVAL_COPY(&collation->callback, &fci.function_name); collation->next = H->collations; H->collations = collation; diff --git a/ext/pdo_sqlite/tests/pdo_sqlite_createaggregate_002.phpt b/ext/pdo_sqlite/tests/pdo_sqlite_createaggregate_002.phpt index 8bddde7165..04e4e3076b 100644 --- a/ext/pdo_sqlite/tests/pdo_sqlite_createaggregate_002.phpt +++ b/ext/pdo_sqlite/tests/pdo_sqlite_createaggregate_002.phpt @@ -7,11 +7,18 @@ PDO_sqlite: Testing invalid callback for sqliteCreateAggregate() $pdo = new PDO('sqlite::memory:'); -$pdo->sqliteCreateAggregate('foo', 'a', ''); -$pdo->sqliteCreateAggregate('foo', 'strlen', ''); +try { + $pdo->sqliteCreateAggregate('foo', 'a', ''); +} catch (\TypeError $e) { + echo $e->getMessage() . \PHP_EOL; +} +try { + $pdo->sqliteCreateAggregate('foo', 'strlen', ''); +} catch (\TypeError $e) { + echo $e->getMessage() . \PHP_EOL; +} ?> ---EXPECTF-- -Warning: PDO::sqliteCreateAggregate(): Function 'a' is not callable in %s on line %d - -Warning: PDO::sqliteCreateAggregate(): Function '' is not callable in %s on line %d +--EXPECT-- +PDO::sqliteCreateAggregate(): Argument #2 must be a valid callback, function "a" not found or invalid function name +PDO::sqliteCreateAggregate(): Argument #3 must be a valid callback, function "" not found or invalid function name diff --git a/ext/pdo_sqlite/tests/pdo_sqlite_createfunction_002.phpt b/ext/pdo_sqlite/tests/pdo_sqlite_createfunction_002.phpt index 190c0d8b6c..d0a87201dc 100644 --- a/ext/pdo_sqlite/tests/pdo_sqlite_createfunction_002.phpt +++ b/ext/pdo_sqlite/tests/pdo_sqlite_createfunction_002.phpt @@ -10,8 +10,12 @@ Chris MacPherson chris@kombine.co.uk $db = new PDO( 'sqlite::memory:'); -$db->sqliteCreateFunction('bar-alias', 'bar'); +try { + $db->sqliteCreateFunction('bar-alias', 'bar'); +} catch (\TypeError $e) { + echo $e->getMessage() . \PHP_EOL; +} ?> ---EXPECTF-- -Warning: PDO::sqliteCreateFunction(): Function 'bar' is not callable in %s on line %d +--EXPECT-- +PDO::sqliteCreateFunction(): Argument #2 must be a valid callback, function "bar" not found or invalid function name -- 2.50.1