From abd9f0875283e55b803613da2dd09ea164665640 Mon Sep 17 00:00:00 2001 From: BohwaZ Date: Fri, 7 Dec 2018 14:06:03 +0100 Subject: SQLite3: Separating parameters binding in a function --- ext/sqlite3/sqlite3.c | 197 +++++++++++++++++++++++++++----------------------- 1 file changed, 107 insertions(+), 90 deletions(-) (limited to 'ext/sqlite3') diff --git a/ext/sqlite3/sqlite3.c b/ext/sqlite3/sqlite3.c index 58d8cf2791..27104a5807 100644 --- a/ext/sqlite3/sqlite3.c +++ b/ext/sqlite3/sqlite3.c @@ -1393,6 +1393,108 @@ PHP_METHOD(sqlite3stmt, readOnly) } /* }}} */ +/* bind parameters to a statement before execution */ +static int php_sqlite3_bind_params(php_sqlite3_stmt *stmt_obj) /* {{{ */ +{ + struct php_sqlite3_bound_param *param; + int return_code; + + if (stmt_obj->bound_params) { + ZEND_HASH_FOREACH_PTR(stmt_obj->bound_params, param) { + zval *parameter; + /* parameter must be a reference? */ + if (Z_ISREF(param->parameter)) { + parameter = Z_REFVAL(param->parameter); + } else { + parameter = ¶m->parameter; + } + + /* If the ZVAL is null then it should be bound as that */ + if (Z_TYPE_P(parameter) == IS_NULL) { + return_code = sqlite3_bind_null(stmt_obj->stmt, param->param_number); + if (return_code != SQLITE_OK) { + php_sqlite3_error(stmt_obj->db_obj, "Unable to bind parameter number " ZEND_LONG_FMT " (%d)", param->param_number, return_code); + } + continue; + } + + switch (param->type) { + case SQLITE_INTEGER: + convert_to_long(parameter); +#if ZEND_LONG_MAX > 2147483647 + return_code = sqlite3_bind_int64(stmt_obj->stmt, param->param_number, Z_LVAL_P(parameter)); +#else + return_code = sqlite3_bind_int(stmt_obj->stmt, param->param_number, Z_LVAL_P(parameter)); +#endif + if (return_code != SQLITE_OK) { + php_sqlite3_error(stmt_obj->db_obj, "Unable to bind parameter number " ZEND_LONG_FMT " (%d)", param->param_number, return_code); + } + break; + + case SQLITE_FLOAT: + convert_to_double(parameter); + return_code = sqlite3_bind_double(stmt_obj->stmt, param->param_number, Z_DVAL_P(parameter)); + if (return_code != SQLITE_OK) { + php_sqlite3_error(stmt_obj->db_obj, "Unable to bind parameter number " ZEND_LONG_FMT " (%d)", param->param_number, return_code); + } + break; + + case SQLITE_BLOB: + { + php_stream *stream = NULL; + zend_string *buffer = NULL; + if (Z_TYPE_P(parameter) == IS_RESOURCE) { + php_stream_from_zval_no_verify(stream, parameter); + if (stream == NULL) { + php_sqlite3_error(stmt_obj->db_obj, "Unable to read stream for parameter %ld", param->param_number); + return FAILURE; + } + buffer = php_stream_copy_to_mem(stream, PHP_STREAM_COPY_ALL, 0); + } else { + buffer = zval_get_string(parameter); + } + + if (buffer) { + return_code = sqlite3_bind_blob(stmt_obj->stmt, param->param_number, ZSTR_VAL(buffer), ZSTR_LEN(buffer), SQLITE_TRANSIENT); + zend_string_release_ex(buffer, 0); + if (return_code != SQLITE_OK) { + php_sqlite3_error(stmt_obj->db_obj, "Unable to bind parameter number " ZEND_LONG_FMT " (%d)", param->param_number, return_code); + } + } else { + return_code = sqlite3_bind_null(stmt_obj->stmt, param->param_number); + if (return_code != SQLITE_OK) { + php_sqlite3_error(stmt_obj->db_obj, "Unable to bind parameter number " ZEND_LONG_FMT " (%d)", param->param_number, return_code); + } + } + break; + } + + case SQLITE3_TEXT: + convert_to_string(parameter); + return_code = sqlite3_bind_text(stmt_obj->stmt, param->param_number, Z_STRVAL_P(parameter), Z_STRLEN_P(parameter), SQLITE_STATIC); + if (return_code != SQLITE_OK) { + php_sqlite3_error(stmt_obj->db_obj, "Unable to bind parameter number " ZEND_LONG_FMT " (%d)", param->param_number, return_code); + } + break; + + case SQLITE_NULL: + return_code = sqlite3_bind_null(stmt_obj->stmt, param->param_number); + if (return_code != SQLITE_OK) { + php_sqlite3_error(stmt_obj->db_obj, "Unable to bind parameter number " ZEND_LONG_FMT " (%d)", param->param_number, return_code); + } + break; + + default: + php_sqlite3_error(stmt_obj->db_obj, "Unknown parameter type: %pd for parameter %pd", param->type, param->param_number); + return FAILURE; + } + } ZEND_HASH_FOREACH_END(); + } + + return SUCCESS; +} +/* }}} */ + static int register_bound_parameter_to_sqlite(struct php_sqlite3_bound_param *param, php_sqlite3_stmt *stmt) /* {{{ */ { HashTable *hash; @@ -1548,7 +1650,7 @@ PHP_METHOD(sqlite3stmt, execute) php_sqlite3_result *result; zval *object = ZEND_THIS; int return_code = 0; - struct php_sqlite3_bound_param *param; + int bind_rc = 0; stmt_obj = Z_SQLITE3_STMT_P(object); @@ -1561,96 +1663,11 @@ PHP_METHOD(sqlite3stmt, execute) /* Always reset statement before execution, see bug #77051 */ sqlite3_reset(stmt_obj->stmt); - if (stmt_obj->bound_params) { - ZEND_HASH_FOREACH_PTR(stmt_obj->bound_params, param) { - zval *parameter; - /* parameter must be a reference? */ - if (Z_ISREF(param->parameter)) { - parameter = Z_REFVAL(param->parameter); - } else { - parameter = ¶m->parameter; - } - - /* If the ZVAL is null then it should be bound as that */ - if (Z_TYPE_P(parameter) == IS_NULL) { - return_code = sqlite3_bind_null(stmt_obj->stmt, param->param_number); - if (return_code != SQLITE_OK) { - php_sqlite3_error(stmt_obj->db_obj, "Unable to bind parameter number " ZEND_LONG_FMT " (%d)", param->param_number, return_code); - } - continue; - } + /* Bind parameters to the statement */ + bind_rc = php_sqlite3_bind_params(stmt_obj); - switch (param->type) { - case SQLITE_INTEGER: - convert_to_long(parameter); -#if ZEND_LONG_MAX > 2147483647 - return_code = sqlite3_bind_int64(stmt_obj->stmt, param->param_number, Z_LVAL_P(parameter)); -#else - return_code = sqlite3_bind_int(stmt_obj->stmt, param->param_number, Z_LVAL_P(parameter)); -#endif - if (return_code != SQLITE_OK) { - php_sqlite3_error(stmt_obj->db_obj, "Unable to bind parameter number " ZEND_LONG_FMT " (%d)", param->param_number, return_code); - } - break; - - case SQLITE_FLOAT: - convert_to_double(parameter); - return_code = sqlite3_bind_double(stmt_obj->stmt, param->param_number, Z_DVAL_P(parameter)); - if (return_code != SQLITE_OK) { - php_sqlite3_error(stmt_obj->db_obj, "Unable to bind parameter number " ZEND_LONG_FMT " (%d)", param->param_number, return_code); - } - break; - - case SQLITE_BLOB: - { - php_stream *stream = NULL; - zend_string *buffer = NULL; - if (Z_TYPE_P(parameter) == IS_RESOURCE) { - php_stream_from_zval_no_verify(stream, parameter); - if (stream == NULL) { - php_sqlite3_error(stmt_obj->db_obj, "Unable to read stream for parameter %ld", param->param_number); - RETURN_FALSE; - } - buffer = php_stream_copy_to_mem(stream, PHP_STREAM_COPY_ALL, 0); - } else { - buffer = zval_get_string(parameter); - } - - if (buffer) { - return_code = sqlite3_bind_blob(stmt_obj->stmt, param->param_number, ZSTR_VAL(buffer), ZSTR_LEN(buffer), SQLITE_TRANSIENT); - zend_string_release_ex(buffer, 0); - if (return_code != SQLITE_OK) { - php_sqlite3_error(stmt_obj->db_obj, "Unable to bind parameter number " ZEND_LONG_FMT " (%d)", param->param_number, return_code); - } - } else { - return_code = sqlite3_bind_null(stmt_obj->stmt, param->param_number); - if (return_code != SQLITE_OK) { - php_sqlite3_error(stmt_obj->db_obj, "Unable to bind parameter number " ZEND_LONG_FMT " (%d)", param->param_number, return_code); - } - } - break; - } - - case SQLITE3_TEXT: - convert_to_string(parameter); - return_code = sqlite3_bind_text(stmt_obj->stmt, param->param_number, Z_STRVAL_P(parameter), Z_STRLEN_P(parameter), SQLITE_STATIC); - if (return_code != SQLITE_OK) { - php_sqlite3_error(stmt_obj->db_obj, "Unable to bind parameter number " ZEND_LONG_FMT " (%d)", param->param_number, return_code); - } - break; - - case SQLITE_NULL: - return_code = sqlite3_bind_null(stmt_obj->stmt, param->param_number); - if (return_code != SQLITE_OK) { - php_sqlite3_error(stmt_obj->db_obj, "Unable to bind parameter number " ZEND_LONG_FMT " (%d)", param->param_number, return_code); - } - break; - - default: - php_sqlite3_error(stmt_obj->db_obj, "Unknown parameter type: %pd for parameter %pd", param->type, param->param_number); - RETURN_FALSE; - } - } ZEND_HASH_FOREACH_END(); + if (bind_rc == FAILURE) { + RETURN_FALSE; } return_code = sqlite3_step(stmt_obj->stmt); -- cgit v1.2.1