From 2d51c203f09551323ed595514e03ab206fd93129 Mon Sep 17 00:00:00 2001 From: Nikita Popov Date: Fri, 11 Dec 2020 17:13:38 +0100 Subject: [PATCH] PDO: Store/pass query_string as zend_string Rather than storing char* + size_t, use a zend_string*. Also avoid various copies of the query string. --- ext/pdo/pdo_dbh.c | 31 ++++++++++++------------------ ext/pdo/pdo_sql_parser.re | 29 +++++++++++++--------------- ext/pdo/pdo_stmt.c | 26 ++++++++++++------------- ext/pdo/php_pdo_driver.h | 11 ++++------- ext/pdo_dblib/dblib_driver.c | 4 ++-- ext/pdo_dblib/dblib_stmt.c | 2 +- ext/pdo_firebird/firebird_driver.c | 4 ++-- ext/pdo_mysql/mysql_driver.c | 18 ++++++++--------- ext/pdo_mysql/mysql_statement.c | 2 +- ext/pdo_oci/oci_driver.c | 16 +++++++-------- ext/pdo_odbc/odbc_driver.c | 15 +++++++-------- ext/pdo_pgsql/pgsql_driver.c | 9 ++++----- ext/pdo_pgsql/pgsql_statement.c | 10 +++++----- ext/pdo_pgsql/php_pdo_pgsql_int.h | 2 +- ext/pdo_sqlite/sqlite_driver.c | 4 ++-- 15 files changed, 81 insertions(+), 102 deletions(-) diff --git a/ext/pdo/pdo_dbh.c b/ext/pdo/pdo_dbh.c index 0bbf14668c..08bb61fc0f 100644 --- a/ext/pdo/pdo_dbh.c +++ b/ext/pdo/pdo_dbh.c @@ -452,10 +452,9 @@ static void pdo_stmt_construct(zend_execute_data *execute_data, pdo_stmt_t *stmt zval query_string; zend_string *key; - ZVAL_STRINGL(&query_string, stmt->query_string, stmt->query_stringlen); + ZVAL_STR(&query_string, stmt->query_string); key = zend_string_init("queryString", sizeof("queryString") - 1, 0); zend_std_write_property(Z_OBJ_P(object), key, &query_string, NULL); - zval_ptr_dtor(&query_string); zend_string_release_ex(key, 0); if (dbstmt_ce->constructor) { @@ -490,22 +489,21 @@ static void pdo_stmt_construct(zend_execute_data *execute_data, pdo_stmt_t *stmt PHP_METHOD(PDO, prepare) { pdo_stmt_t *stmt; - char *statement; - size_t statement_len; + zend_string *statement; zval *options = NULL, *value, *item, ctor_args; zend_class_entry *dbstmt_ce, *pce; pdo_dbh_object_t *dbh_obj = Z_PDO_OBJECT_P(ZEND_THIS); pdo_dbh_t *dbh = dbh_obj->inner; ZEND_PARSE_PARAMETERS_START(1, 2) - Z_PARAM_STRING(statement, statement_len) + Z_PARAM_STR(statement) Z_PARAM_OPTIONAL Z_PARAM_ARRAY(options) ZEND_PARSE_PARAMETERS_END(); PDO_CONSTRUCT_CHECK; - if (statement_len == 0) { + if (ZSTR_LEN(statement) == 0) { zend_argument_value_error(1, "cannot be empty"); RETURN_THROWS(); } @@ -557,8 +555,7 @@ PHP_METHOD(PDO, prepare) stmt = Z_PDO_STMT_P(return_value); /* unconditionally keep this for later reference */ - stmt->query_string = estrndup(statement, statement_len); - stmt->query_stringlen = statement_len; + stmt->query_string = zend_string_copy(statement); stmt->default_fetch_type = dbh->default_fetch_type; stmt->dbh = dbh; /* give it a reference to me */ @@ -566,7 +563,7 @@ PHP_METHOD(PDO, prepare) /* we haven't created a lazy object yet */ ZVAL_UNDEF(&stmt->lazy_object_ref); - if (dbh->methods->preparer(dbh, statement, statement_len, stmt, options)) { + if (dbh->methods->preparer(dbh, statement, stmt, options)) { pdo_stmt_construct(execute_data, stmt, return_value, dbstmt_ce, &ctor_args); return; } @@ -1051,8 +1048,7 @@ fill_array: PHP_METHOD(PDO, query) { pdo_stmt_t *stmt; - char *statement; - size_t statement_len; + zend_string *statement; zend_long fetch_mode; zend_bool fetch_mode_is_null = 1; zval *args = NULL; @@ -1060,14 +1056,14 @@ PHP_METHOD(PDO, query) pdo_dbh_object_t *dbh_obj = Z_PDO_OBJECT_P(ZEND_THIS); pdo_dbh_t *dbh = dbh_obj->inner; - if (FAILURE == zend_parse_parameters(ZEND_NUM_ARGS(), "s|l!*", &statement, &statement_len, + if (FAILURE == zend_parse_parameters(ZEND_NUM_ARGS(), "S|l!*", &statement, &fetch_mode, &fetch_mode_is_null, &args, &num_args)) { RETURN_THROWS(); } PDO_CONSTRUCT_CHECK; - if (statement_len == 0) { + if (ZSTR_LEN(statement) == 0) { zend_argument_value_error(1, "cannot be empty"); RETURN_THROWS(); } @@ -1080,19 +1076,16 @@ PHP_METHOD(PDO, query) stmt = Z_PDO_STMT_P(return_value); /* unconditionally keep this for later reference */ - stmt->query_string = estrndup(statement, statement_len); - stmt->query_stringlen = statement_len; - + stmt->query_string = zend_string_copy(statement); + stmt->active_query_string = zend_string_copy(stmt->query_string); stmt->default_fetch_type = dbh->default_fetch_type; - stmt->active_query_string = stmt->query_string; - stmt->active_query_stringlen = statement_len; stmt->dbh = dbh; /* give it a reference to me */ ZVAL_OBJ_COPY(&stmt->database_object_handle, &dbh_obj->std); /* we haven't created a lazy object yet */ ZVAL_UNDEF(&stmt->lazy_object_ref); - if (dbh->methods->preparer(dbh, statement, statement_len, stmt, NULL)) { + if (dbh->methods->preparer(dbh, statement, stmt, NULL)) { PDO_STMT_CLEAR_ERR(); if (fetch_mode_is_null || pdo_stmt_setup_fetch_mode(stmt, fetch_mode, 2, args, num_args)) { /* now execute the statement */ diff --git a/ext/pdo/pdo_sql_parser.re b/ext/pdo/pdo_sql_parser.re index 04a4118fc4..29e99bfd9b 100644 --- a/ext/pdo/pdo_sql_parser.re +++ b/ext/pdo/pdo_sql_parser.re @@ -81,11 +81,9 @@ static void free_param_name(zval *el) { efree(Z_PTR_P(el)); } -PDO_API int pdo_parse_params(pdo_stmt_t *stmt, const char *inquery, size_t inquery_len, - char **outquery, size_t *outquery_len) +PDO_API int pdo_parse_params(pdo_stmt_t *stmt, zend_string *inquery, zend_string **outquery) { Scanner s; - const char *ptr; char *newbuffer; ptrdiff_t t; uint32_t bindno = 0; @@ -96,9 +94,8 @@ PDO_API int pdo_parse_params(pdo_stmt_t *stmt, const char *inquery, size_t inque int query_type = PDO_PLACEHOLDER_NONE; struct placeholder *placeholders = NULL, *placetail = NULL, *plc = NULL; - ptr = *outquery; - s.cur = inquery; - s.end = inquery + inquery_len + 1; + s.cur = ZSTR_VAL(inquery); + s.end = s.cur + ZSTR_LEN(inquery) + 1; /* phase 1: look for args */ while((t = scan(&s)) != PDO_PARSER_EOI) { @@ -110,7 +107,7 @@ PDO_API int pdo_parse_params(pdo_stmt_t *stmt, const char *inquery, size_t inque if (t == PDO_PARSER_BIND) { ptrdiff_t len = s.cur - s.tok; - if ((inquery < (s.cur - len)) && isalnum(*(s.cur - len - 1))) { + if ((ZSTR_VAL(inquery) < (s.cur - len)) && isalnum(*(s.cur - len - 1))) { continue; } query_type |= PDO_PLACEHOLDER_NAMED; @@ -179,7 +176,7 @@ PDO_API int pdo_parse_params(pdo_stmt_t *stmt, const char *inquery, size_t inque if (stmt->supports_placeholders == query_type && !stmt->named_rewrite_template) { /* query matches native syntax */ if (escapes) { - newbuffer_len = inquery_len; + newbuffer_len = ZSTR_LEN(inquery); goto rewrite; } @@ -201,7 +198,7 @@ safe: if (stmt->supports_placeholders == PDO_PLACEHOLDER_NONE) { /* query generation */ - newbuffer_len = inquery_len; + newbuffer_len = ZSTR_LEN(inquery); /* let's quote all the values */ for (plc = placeholders; plc && params; plc = plc->next) { @@ -328,12 +325,12 @@ safe: rewrite: /* allocate output buffer */ - newbuffer = emalloc(newbuffer_len + 1); - *outquery = newbuffer; + *outquery = zend_string_alloc(newbuffer_len, 0); + newbuffer = ZSTR_VAL(*outquery); /* and build the query */ + const char *ptr = ZSTR_VAL(inquery); plc = placeholders; - ptr = inquery; do { t = plc->pos - ptr; @@ -353,13 +350,13 @@ rewrite: plc = plc->next; } while (plc); - t = (inquery + inquery_len) - ptr; + t = ZSTR_VAL(inquery) + ZSTR_LEN(inquery) - ptr; if (t) { memcpy(newbuffer, ptr, t); newbuffer += t; } *newbuffer = '\0'; - *outquery_len = newbuffer - *outquery; + ZSTR_LEN(*outquery) = newbuffer - ZSTR_VAL(*outquery); ret = 1; goto clean_up; @@ -370,7 +367,7 @@ rewrite: const char *tmpl = stmt->named_rewrite_template ? stmt->named_rewrite_template : ":pdo%d"; int bind_no = 1; - newbuffer_len = inquery_len; + newbuffer_len = ZSTR_LEN(inquery); if (stmt->bound_param_map == NULL) { ALLOC_HASHTABLE(stmt->bound_param_map); @@ -416,7 +413,7 @@ rewrite: } else { /* rewrite :name to ? */ - newbuffer_len = inquery_len; + newbuffer_len = ZSTR_LEN(inquery); if (stmt->bound_param_map == NULL) { ALLOC_HASHTABLE(stmt->bound_param_map); diff --git a/ext/pdo/pdo_stmt.c b/ext/pdo/pdo_stmt.c index a172ae27c5..5163e65a98 100644 --- a/ext/pdo/pdo_stmt.c +++ b/ext/pdo/pdo_stmt.c @@ -443,18 +443,16 @@ PHP_METHOD(PDOStatement, execute) */ /* string is leftover from previous calls so PDOStatement::debugDumpParams() can access */ - if (stmt->active_query_string && stmt->active_query_string != stmt->query_string) { - efree(stmt->active_query_string); + if (stmt->active_query_string) { + zend_string_release(stmt->active_query_string); + stmt->active_query_string = NULL; } - stmt->active_query_string = NULL; - ret = pdo_parse_params(stmt, stmt->query_string, stmt->query_stringlen, - &stmt->active_query_string, &stmt->active_query_stringlen); + ret = pdo_parse_params(stmt, stmt->query_string, &stmt->active_query_string); if (ret == 0) { /* no changes were made */ - stmt->active_query_string = stmt->query_string; - stmt->active_query_stringlen = stmt->query_stringlen; + stmt->active_query_string = zend_string_copy(stmt->query_string); ret = 1; } else if (ret == -1) { /* something broke */ @@ -2035,16 +2033,16 @@ PHP_METHOD(PDOStatement, debugDumpParams) } /* break into multiple operations so query string won't be truncated at FORMAT_CONV_MAX_PRECISION */ - php_stream_printf(out, "SQL: [%zd] ", stmt->query_stringlen); - php_stream_write(out, stmt->query_string, stmt->query_stringlen); + php_stream_printf(out, "SQL: [%zd] ", ZSTR_LEN(stmt->query_string)); + php_stream_write(out, ZSTR_VAL(stmt->query_string), ZSTR_LEN(stmt->query_string)); php_stream_write(out, "\n", 1); /* show parsed SQL if emulated prepares enabled */ /* pointers will be equal if PDO::query() was invoked */ if (stmt->active_query_string != NULL && stmt->active_query_string != stmt->query_string) { /* break into multiple operations so query string won't be truncated at FORMAT_CONV_MAX_PRECISION */ - php_stream_printf(out, "Sent SQL: [%zd] ", stmt->active_query_stringlen); - php_stream_write(out, stmt->active_query_string, stmt->active_query_stringlen); + php_stream_printf(out, "Sent SQL: [%zd] ", ZSTR_LEN(stmt->active_query_string)); + php_stream_write(out, ZSTR_VAL(stmt->active_query_string), ZSTR_LEN(stmt->active_query_string)); php_stream_write(out, "\n", 1); } @@ -2175,11 +2173,11 @@ PDO_API void php_pdo_free_statement(pdo_stmt_t *stmt) if (stmt->methods && stmt->methods->dtor) { stmt->methods->dtor(stmt); } - if (stmt->active_query_string && stmt->active_query_string != stmt->query_string) { - efree(stmt->active_query_string); + if (stmt->active_query_string) { + zend_string_release(stmt->active_query_string); } if (stmt->query_string) { - efree(stmt->query_string); + zend_string_release(stmt->query_string); } pdo_stmt_reset_columns(stmt); diff --git a/ext/pdo/php_pdo_driver.h b/ext/pdo/php_pdo_driver.h index 2c6bd96600..da53c1a3b9 100644 --- a/ext/pdo/php_pdo_driver.h +++ b/ext/pdo/php_pdo_driver.h @@ -247,7 +247,7 @@ typedef struct { typedef int (*pdo_dbh_close_func)(pdo_dbh_t *dbh); /* prepare a statement and stash driver specific portion into stmt */ -typedef int (*pdo_dbh_prepare_func)(pdo_dbh_t *dbh, const char *sql, size_t sql_len, pdo_stmt_t *stmt, zval *driver_options); +typedef int (*pdo_dbh_prepare_func)(pdo_dbh_t *dbh, zend_string *sql, pdo_stmt_t *stmt, zval *driver_options); /* execute a statement (that does not return a result set) */ typedef zend_long (*pdo_dbh_do_func)(pdo_dbh_t *dbh, const char *sql, size_t sql_len); @@ -604,12 +604,10 @@ struct _pdo_stmt_t { zend_long row_count; /* used to hold the statement's current query */ - char *query_string; - size_t query_stringlen; + zend_string *query_string; /* the copy of the query with expanded binds ONLY for emulated-prepare drivers */ - char *active_query_string; - size_t active_query_stringlen; + zend_string *active_query_string; /* the cursor specific error code. */ pdo_error_type error_code; @@ -685,8 +683,7 @@ PDO_API int php_pdo_parse_data_source(const char *data_source, PDO_API zend_class_entry *php_pdo_get_dbh_ce(void); PDO_API zend_class_entry *php_pdo_get_exception(void); -PDO_API int pdo_parse_params(pdo_stmt_t *stmt, const char *inquery, size_t inquery_len, - char **outquery, size_t *outquery_len); +PDO_API int pdo_parse_params(pdo_stmt_t *stmt, zend_string *inquery, zend_string **outquery); PDO_API void pdo_raise_impl_error(pdo_dbh_t *dbh, pdo_stmt_t *stmt, const char *sqlstate, const char *supp); diff --git a/ext/pdo_dblib/dblib_driver.c b/ext/pdo_dblib/dblib_driver.c index e581642037..085b6990d2 100644 --- a/ext/pdo_dblib/dblib_driver.c +++ b/ext/pdo_dblib/dblib_driver.c @@ -59,7 +59,7 @@ static int dblib_fetch_error(pdo_dbh_t *dbh, pdo_stmt_t *stmt, zval *info) } spprintf(&message, 0, "%s [%d] (severity %d) [%s]", - msg, einfo->dberr, einfo->severity, stmt ? stmt->active_query_string : ""); + msg, einfo->dberr, einfo->severity, stmt ? ZSTR_VAL(stmt->active_query_string) : ""); add_next_index_long(info, einfo->dberr); add_next_index_string(info, message); @@ -94,7 +94,7 @@ static int dblib_handle_closer(pdo_dbh_t *dbh) return 0; } -static int dblib_handle_preparer(pdo_dbh_t *dbh, const char *sql, size_t sql_len, pdo_stmt_t *stmt, zval *driver_options) +static int dblib_handle_preparer(pdo_dbh_t *dbh, zend_string *sql, pdo_stmt_t *stmt, zval *driver_options) { pdo_dblib_db_handle *H = (pdo_dblib_db_handle *)dbh->driver_data; pdo_dblib_stmt *S = ecalloc(1, sizeof(*S)); diff --git a/ext/pdo_dblib/dblib_stmt.c b/ext/pdo_dblib/dblib_stmt.c index 94526a4c6e..0dca4c79cf 100644 --- a/ext/pdo_dblib/dblib_stmt.c +++ b/ext/pdo_dblib/dblib_stmt.c @@ -177,7 +177,7 @@ static int pdo_dblib_stmt_execute(pdo_stmt_t *stmt) pdo_dblib_stmt_cursor_closer(stmt); - if (FAIL == dbcmd(H->link, stmt->active_query_string)) { + if (FAIL == dbcmd(H->link, ZSTR_VAL(stmt->active_query_string))) { return 0; } diff --git a/ext/pdo_firebird/firebird_driver.c b/ext/pdo_firebird/firebird_driver.c index 390871cc20..0a6223454c 100644 --- a/ext/pdo_firebird/firebird_driver.c +++ b/ext/pdo_firebird/firebird_driver.c @@ -504,7 +504,7 @@ static int firebird_handle_closer(pdo_dbh_t *dbh) /* {{{ */ /* }}} */ /* called by PDO to prepare an SQL query */ -static int firebird_handle_preparer(pdo_dbh_t *dbh, const char *sql, size_t sql_len, /* {{{ */ +static int firebird_handle_preparer(pdo_dbh_t *dbh, zend_string *sql, /* {{{ */ pdo_stmt_t *stmt, zval *driver_options) { pdo_firebird_db_handle *H = (pdo_firebird_db_handle *)dbh->driver_data; @@ -524,7 +524,7 @@ static int firebird_handle_preparer(pdo_dbh_t *dbh, const char *sql, size_t sql_ zend_hash_init(np, 8, NULL, NULL, 0); /* allocate and prepare statement */ - if (!firebird_alloc_prepare_stmt(dbh, sql, sql_len, &num_sqlda, &s, np)) { + if (!firebird_alloc_prepare_stmt(dbh, ZSTR_VAL(sql), ZSTR_LEN(sql), &num_sqlda, &s, np)) { break; } diff --git a/ext/pdo_mysql/mysql_driver.c b/ext/pdo_mysql/mysql_driver.c index 911e7c2160..04d0f52cbb 100644 --- a/ext/pdo_mysql/mysql_driver.c +++ b/ext/pdo_mysql/mysql_driver.c @@ -162,18 +162,17 @@ static int mysql_handle_closer(pdo_dbh_t *dbh) /* }}} */ /* {{{ mysql_handle_preparer */ -static int mysql_handle_preparer(pdo_dbh_t *dbh, const char *sql, size_t sql_len, pdo_stmt_t *stmt, zval *driver_options) +static int mysql_handle_preparer(pdo_dbh_t *dbh, zend_string *sql, pdo_stmt_t *stmt, zval *driver_options) { pdo_mysql_db_handle *H = (pdo_mysql_db_handle *)dbh->driver_data; pdo_mysql_stmt *S = ecalloc(1, sizeof(pdo_mysql_stmt)); - char *nsql = NULL; - size_t nsql_len = 0; + zend_string *nsql = NULL; int ret; int server_version; PDO_DBG_ENTER("mysql_handle_preparer"); PDO_DBG_INF_FMT("dbh=%p", dbh); - PDO_DBG_INF_FMT("sql=%.*s", (int)sql_len, sql); + PDO_DBG_INF_FMT("sql=%.*s", ZSTR_LEN(sql), ZSTR_VAL(sql)); S->H = H; stmt->driver_data = S; @@ -188,12 +187,11 @@ static int mysql_handle_preparer(pdo_dbh_t *dbh, const char *sql, size_t sql_len goto fallback; } stmt->supports_placeholders = PDO_PLACEHOLDER_POSITIONAL; - ret = pdo_parse_params(stmt, (char*)sql, sql_len, &nsql, &nsql_len); + ret = pdo_parse_params(stmt, sql, &nsql); if (ret == 1) { /* query was rewritten */ sql = nsql; - sql_len = nsql_len; } else if (ret == -1) { /* failed to parse */ strcpy(dbh->error_code, stmt->error_code); @@ -203,14 +201,14 @@ static int mysql_handle_preparer(pdo_dbh_t *dbh, const char *sql, size_t sql_len if (!(S->stmt = mysql_stmt_init(H->server))) { pdo_mysql_error(dbh); if (nsql) { - efree(nsql); + zend_string_release(nsql); } PDO_DBG_RETURN(0); } - if (mysql_stmt_prepare(S->stmt, sql, sql_len)) { + if (mysql_stmt_prepare(S->stmt, ZSTR_VAL(sql), ZSTR_LEN(sql))) { if (nsql) { - efree(nsql); + zend_string_release(nsql); } /* TODO: might need to pull statement specific info here? */ /* if the query isn't supported by the protocol, fallback to emulation */ @@ -223,7 +221,7 @@ static int mysql_handle_preparer(pdo_dbh_t *dbh, const char *sql, size_t sql_len PDO_DBG_RETURN(0); } if (nsql) { - efree(nsql); + zend_string_release(nsql); } S->num_params = mysql_stmt_param_count(S->stmt); diff --git a/ext/pdo_mysql/mysql_statement.c b/ext/pdo_mysql/mysql_statement.c index 871b7f9c7c..95c5c4bbd5 100644 --- a/ext/pdo_mysql/mysql_statement.c +++ b/ext/pdo_mysql/mysql_statement.c @@ -317,7 +317,7 @@ static int pdo_mysql_stmt_execute(pdo_stmt_t *stmt) /* {{{ */ PDO_DBG_RETURN(pdo_mysql_stmt_execute_prepared(stmt)); } - if (mysql_real_query(H->server, stmt->active_query_string, stmt->active_query_stringlen) != 0) { + if (mysql_real_query(H->server, ZSTR_VAL(stmt->active_query_string), ZSTR_LEN(stmt->active_query_string)) != 0) { pdo_mysql_error_stmt(stmt); PDO_DBG_RETURN(0); } diff --git a/ext/pdo_oci/oci_driver.c b/ext/pdo_oci/oci_driver.c index 2c65fc973b..18faa538b9 100644 --- a/ext/pdo_oci/oci_driver.c +++ b/ext/pdo_oci/oci_driver.c @@ -238,13 +238,12 @@ static int oci_handle_closer(pdo_dbh_t *dbh) /* {{{ */ } /* }}} */ -static int oci_handle_preparer(pdo_dbh_t *dbh, const char *sql, size_t sql_len, pdo_stmt_t *stmt, zval *driver_options) /* {{{ */ +static int oci_handle_preparer(pdo_dbh_t *dbh, zend_string *sql, pdo_stmt_t *stmt, zval *driver_options) /* {{{ */ { pdo_oci_db_handle *H = (pdo_oci_db_handle *)dbh->driver_data; pdo_oci_stmt *S = ecalloc(1, sizeof(*S)); ub4 prefetch; - char *nsql = NULL; - size_t nsql_len = 0; + zend_string *nsql = NULL; int ret; #ifdef HAVE_OCISTMTFETCH2 @@ -257,12 +256,11 @@ static int oci_handle_preparer(pdo_dbh_t *dbh, const char *sql, size_t sql_len, S->H = H; stmt->supports_placeholders = PDO_PLACEHOLDER_NAMED; - ret = pdo_parse_params(stmt, (char*)sql, sql_len, &nsql, &nsql_len); + ret = pdo_parse_params(stmt, sql, &nsql); if (ret == 1) { /* query was re-written */ sql = nsql; - sql_len = nsql_len; } else if (ret == -1) { /* couldn't grok it */ strcpy(dbh->error_code, stmt->error_code); @@ -276,10 +274,10 @@ static int oci_handle_preparer(pdo_dbh_t *dbh, const char *sql, size_t sql_len, /* and our own private error handle */ OCIHandleAlloc(H->env, (dvoid*)&S->err, OCI_HTYPE_ERROR, 0, NULL); - if (sql_len) { - H->last_err = OCIStmtPrepare(S->stmt, H->err, (text*)sql, (ub4) sql_len, OCI_NTV_SYNTAX, OCI_DEFAULT); + if (ZSTR_LEN(sql) != 0) { + H->last_err = OCIStmtPrepare(S->stmt, H->err, (text*) ZSTR_VAL(sql), (ub4) ZSTR_LEN(sql), OCI_NTV_SYNTAX, OCI_DEFAULT); if (nsql) { - efree(nsql); + zend_string_release(nsql); nsql = NULL; } if (H->last_err) { @@ -304,7 +302,7 @@ static int oci_handle_preparer(pdo_dbh_t *dbh, const char *sql, size_t sql_len, stmt->driver_data = S; stmt->methods = &oci_stmt_methods; if (nsql) { - efree(nsql); + zend_string_release(nsql); nsql = NULL; } diff --git a/ext/pdo_odbc/odbc_driver.c b/ext/pdo_odbc/odbc_driver.c index 1729cf0fef..123d86e2cf 100644 --- a/ext/pdo_odbc/odbc_driver.c +++ b/ext/pdo_odbc/odbc_driver.c @@ -138,15 +138,14 @@ static int odbc_handle_closer(pdo_dbh_t *dbh) return 0; } -static int odbc_handle_preparer(pdo_dbh_t *dbh, const char *sql, size_t sql_len, pdo_stmt_t *stmt, zval *driver_options) +static int odbc_handle_preparer(pdo_dbh_t *dbh, zend_string *sql, pdo_stmt_t *stmt, zval *driver_options) { RETCODE rc; pdo_odbc_db_handle *H = (pdo_odbc_db_handle *)dbh->driver_data; pdo_odbc_stmt *S = ecalloc(1, sizeof(*S)); enum pdo_cursor_type cursor_type = PDO_CURSOR_FWDONLY; int ret; - char *nsql = NULL; - size_t nsql_len = 0; + zend_string *nsql = NULL; S->H = H; S->assume_utf8 = H->assume_utf8; @@ -154,7 +153,7 @@ static int odbc_handle_preparer(pdo_dbh_t *dbh, const char *sql, size_t sql_len, /* before we prepare, we need to peek at the query; if it uses named parameters, * we want PDO to rewrite them for us */ stmt->supports_placeholders = PDO_PLACEHOLDER_POSITIONAL; - ret = pdo_parse_params(stmt, (char*)sql, sql_len, &nsql, &nsql_len); + ret = pdo_parse_params(stmt, sql, &nsql); if (ret == 1) { /* query was re-written */ @@ -171,7 +170,7 @@ static int odbc_handle_preparer(pdo_dbh_t *dbh, const char *sql, size_t sql_len, if (rc == SQL_INVALID_HANDLE || rc == SQL_ERROR) { efree(S); if (nsql) { - efree(nsql); + zend_string_release(nsql); } pdo_odbc_drv_error("SQLAllocStmt"); return 0; @@ -186,15 +185,15 @@ static int odbc_handle_preparer(pdo_dbh_t *dbh, const char *sql, size_t sql_len, pdo_odbc_stmt_error("SQLSetStmtAttr: SQL_ATTR_CURSOR_SCROLLABLE"); SQLFreeHandle(SQL_HANDLE_STMT, S->stmt); if (nsql) { - efree(nsql); + zend_string_release(nsql); } return 0; } } - rc = SQLPrepare(S->stmt, (SQLCHAR *) sql, SQL_NTS); + rc = SQLPrepare(S->stmt, (SQLCHAR *) ZSTR_VAL(sql), SQL_NTS); if (nsql) { - efree(nsql); + zend_string_release(nsql); } stmt->methods = &odbc_stmt_methods; diff --git a/ext/pdo_pgsql/pgsql_driver.c b/ext/pdo_pgsql/pgsql_driver.c index 6c3375557b..3ae15e7511 100644 --- a/ext/pdo_pgsql/pgsql_driver.c +++ b/ext/pdo_pgsql/pgsql_driver.c @@ -222,14 +222,13 @@ static int pgsql_handle_closer(pdo_dbh_t *dbh) /* {{{ */ } /* }}} */ -static int pgsql_handle_preparer(pdo_dbh_t *dbh, const char *sql, size_t sql_len, pdo_stmt_t *stmt, zval *driver_options) +static int pgsql_handle_preparer(pdo_dbh_t *dbh, zend_string *sql, pdo_stmt_t *stmt, zval *driver_options) { pdo_pgsql_db_handle *H = (pdo_pgsql_db_handle *)dbh->driver_data; pdo_pgsql_stmt *S = ecalloc(1, sizeof(pdo_pgsql_stmt)); int scrollable; int ret; - char *nsql = NULL; - size_t nsql_len = 0; + zend_string *nsql = NULL; int emulate = 0; int execute_only = 0; @@ -269,7 +268,7 @@ static int pgsql_handle_preparer(pdo_dbh_t *dbh, const char *sql, size_t sql_len stmt->named_rewrite_template = "$%d"; } - ret = pdo_parse_params(stmt, (char*)sql, sql_len, &nsql, &nsql_len); + ret = pdo_parse_params(stmt, sql, &nsql); if (ret == -1) { /* couldn't grok it */ @@ -279,7 +278,7 @@ static int pgsql_handle_preparer(pdo_dbh_t *dbh, const char *sql, size_t sql_len /* query was re-written */ S->query = nsql; } else { - S->query = estrdup(sql); + S->query = zend_string_copy(sql); } if (!emulate && !execute_only) { diff --git a/ext/pdo_pgsql/pgsql_statement.c b/ext/pdo_pgsql/pgsql_statement.c index 21f4c83807..89513fe9cc 100644 --- a/ext/pdo_pgsql/pgsql_statement.c +++ b/ext/pdo_pgsql/pgsql_statement.c @@ -100,7 +100,7 @@ static int pgsql_stmt_dtor(pdo_stmt_t *stmt) S->param_types = NULL; } if (S->query) { - efree(S->query); + zend_string_release(S->query); S->query = NULL; } @@ -151,7 +151,7 @@ static int pgsql_stmt_execute(pdo_stmt_t *stmt) efree(q); } - spprintf(&q, 0, "DECLARE %s SCROLL CURSOR WITH HOLD FOR %s", S->cursor_name, stmt->active_query_string); + spprintf(&q, 0, "DECLARE %s SCROLL CURSOR WITH HOLD FOR %s", S->cursor_name, ZSTR_VAL(stmt->active_query_string)); S->result = PQexec(H->server, q); efree(q); @@ -177,7 +177,7 @@ static int pgsql_stmt_execute(pdo_stmt_t *stmt) stmt_retry: /* we deferred the prepare until now, because we didn't * know anything about the parameter types; now we do */ - S->result = PQprepare(H->server, S->stmt_name, S->query, + S->result = PQprepare(H->server, S->stmt_name, ZSTR_VAL(S->query), stmt->bound_params ? zend_hash_num_elements(stmt->bound_params) : 0, S->param_types); status = PQresultStatus(S->result); @@ -222,7 +222,7 @@ stmt_retry: 0); } else if (stmt->supports_placeholders == PDO_PLACEHOLDER_NAMED) { /* execute query with parameters */ - S->result = PQexecParams(H->server, S->query, + S->result = PQexecParams(H->server, ZSTR_VAL(S->query), stmt->bound_params ? zend_hash_num_elements(stmt->bound_params) : 0, S->param_types, (const char**)S->param_values, @@ -231,7 +231,7 @@ stmt_retry: 0); } else { /* execute plain query (with embedded parameters) */ - S->result = PQexec(H->server, stmt->active_query_string); + S->result = PQexec(H->server, ZSTR_VAL(stmt->active_query_string)); } status = PQresultStatus(S->result); diff --git a/ext/pdo_pgsql/php_pdo_pgsql_int.h b/ext/pdo_pgsql/php_pdo_pgsql_int.h index bc31c9cdee..b00004cca7 100644 --- a/ext/pdo_pgsql/php_pdo_pgsql_int.h +++ b/ext/pdo_pgsql/php_pdo_pgsql_int.h @@ -60,7 +60,7 @@ typedef struct { pdo_pgsql_column *cols; char *cursor_name; char *stmt_name; - char *query; + zend_string *query; char **param_values; int *param_lengths; int *param_formats; diff --git a/ext/pdo_sqlite/sqlite_driver.c b/ext/pdo_sqlite/sqlite_driver.c index a8a96c7a13..fcf82c62bf 100644 --- a/ext/pdo_sqlite/sqlite_driver.c +++ b/ext/pdo_sqlite/sqlite_driver.c @@ -175,7 +175,7 @@ static int sqlite_handle_closer(pdo_dbh_t *dbh) /* {{{ */ } /* }}} */ -static int sqlite_handle_preparer(pdo_dbh_t *dbh, const char *sql, size_t sql_len, pdo_stmt_t *stmt, zval *driver_options) +static int sqlite_handle_preparer(pdo_dbh_t *dbh, zend_string *sql, pdo_stmt_t *stmt, zval *driver_options) { pdo_sqlite_db_handle *H = (pdo_sqlite_db_handle *)dbh->driver_data; pdo_sqlite_stmt *S = ecalloc(1, sizeof(pdo_sqlite_stmt)); @@ -193,7 +193,7 @@ static int sqlite_handle_preparer(pdo_dbh_t *dbh, const char *sql, size_t sql_le return 0; } - i = sqlite3_prepare_v2(H->db, sql, sql_len, &S->stmt, &tail); + i = sqlite3_prepare_v2(H->db, ZSTR_VAL(sql), ZSTR_LEN(sql), &S->stmt, &tail); if (i == SQLITE_OK) { return 1; } -- 2.40.0