diff --git a/UPGRADING.INTERNALS b/UPGRADING.INTERNALS index 455eff41e7e8a..94c2a9c14652d 100644 --- a/UPGRADING.INTERNALS +++ b/UPGRADING.INTERNALS @@ -47,8 +47,12 @@ PHP 8.1 INTERNALS UPGRADE NOTES getColumnMeta(). The type provided here does not need to match the type returned by get_col (in fact no corresponding type might exist, e.g. for floats). It should be the closest logical equivalent for the column type. - - The transaction, set_attribute, quoter, and preparer handler's return type + - The transaction, set_attribute, and preparer handler's return type has been formalized to bool instead of int. - The check_liveness handler's return type has been formalized to zend_return instead of int. - The closer, and fetch_error handlers have been voidified. + - The quoter handler now returns the quoted string as zend_string* instead + of returning a boolean, and the quoted string as a pair of out params. + Similarly the unquoted string is now a zend_string* instead of a pair of + char* and size_t length. diff --git a/ext/pdo/pdo_dbh.c b/ext/pdo/pdo_dbh.c index a53c9f052d58c..5a2c25e232e31 100644 --- a/ext/pdo/pdo_dbh.c +++ b/ext/pdo/pdo_dbh.c @@ -1119,18 +1119,17 @@ PHP_METHOD(PDO, query) } /* }}} */ -/* {{{ quotes string for use in a query. The optional paramtype acts as a hint for drivers that have alternate quoting styles. The default value is PDO_PARAM_STR */ +/* {{{ quotes string for use in a query. + * The optional paramtype acts as a hint for drivers that have alternate quoting styles. + * The default value is PDO_PARAM_STR */ PHP_METHOD(PDO, quote) { pdo_dbh_t *dbh = Z_PDO_DBH_P(ZEND_THIS); - char *str; - size_t str_len; + zend_string *str; zend_long paramtype = PDO_PARAM_STR; - char *qstr; - size_t qlen; ZEND_PARSE_PARAMETERS_START(1, 2) - Z_PARAM_STRING(str, str_len) + Z_PARAM_STR(str) Z_PARAM_OPTIONAL Z_PARAM_LONG(paramtype) ZEND_PARSE_PARAMETERS_END(); @@ -1143,13 +1142,7 @@ PHP_METHOD(PDO, quote) RETURN_FALSE; } - if (dbh->methods->quoter(dbh, str, str_len, &qstr, &qlen, paramtype)) { - RETVAL_STRINGL(qstr, qlen); - efree(qstr); - return; - } - PDO_HANDLE_DBH_ERR(); - RETURN_FALSE; + RETURN_STR(dbh->methods->quoter(dbh, str, paramtype)); } /* }}} */ diff --git a/ext/pdo/pdo_sql_parser.re b/ext/pdo/pdo_sql_parser.re index 29e99bfd9bd2f..6716401187ab9 100644 --- a/ext/pdo/pdo_sql_parser.re +++ b/ext/pdo/pdo_sql_parser.re @@ -70,15 +70,13 @@ static int scan(Scanner *s) struct placeholder { const char *pos; size_t len; - size_t qlen; /* quoted length of value */ - char *quoted; /* quoted value */ - int freeq; + zend_string *quoted; /* quoted value */ int bindno; struct placeholder *next; }; static void free_param_name(zval *el) { - efree(Z_PTR_P(el)); + zend_string_release(Z_PTR_P(el)); } PDO_API int pdo_parse_params(pdo_stmt_t *stmt, zend_string *inquery, zend_string **outquery) @@ -123,9 +121,7 @@ PDO_API int pdo_parse_params(pdo_stmt_t *stmt, zend_string *inquery, zend_string if (t == PDO_PARSER_ESCAPED_QUESTION) { plc->bindno = PDO_PARSER_BINDNO_ESCAPED_CHAR; - plc->quoted = "?"; - plc->qlen = 1; - plc->freeq = 0; + plc->quoted = ZSTR_CHAR('?'); escapes++; } else { plc->bindno = bindno++; @@ -240,16 +236,9 @@ safe: if (!buf) { buf = ZSTR_EMPTY_ALLOC(); } - if (!stmt->dbh->methods->quoter(stmt->dbh, ZSTR_VAL(buf), ZSTR_LEN(buf), &plc->quoted, &plc->qlen, - param->param_type)) { - /* bork */ - ret = -1; - strncpy(stmt->error_code, stmt->dbh->error_code, 6); - if (buf) { - zend_string_release_ex(buf, 0); - } - goto clean_up; - } + + plc->quoted = stmt->dbh->methods->quoter(stmt->dbh, buf, param->param_type); + if (buf) { zend_string_release_ex(buf, 0); } @@ -258,7 +247,6 @@ safe: ret = -1; goto clean_up; } - plc->freeq = 1; } else { enum pdo_param_type param_type = param->param_type; zend_string *buf = NULL; @@ -270,40 +258,29 @@ safe: switch (param_type) { case PDO_PARAM_BOOL: - plc->quoted = zend_is_true(parameter) ? "1" : "0"; - plc->qlen = sizeof("1")-1; - plc->freeq = 0; + plc->quoted = zend_is_true(parameter) ? ZSTR_CHAR('1') : ZSTR_CHAR('0'); break; case PDO_PARAM_INT: - buf = zend_long_to_str(zval_get_long(parameter)); - - plc->qlen = ZSTR_LEN(buf); - plc->quoted = estrdup(ZSTR_VAL(buf)); - plc->freeq = 1; + plc->quoted = zend_long_to_str(zval_get_long(parameter)); break; case PDO_PARAM_NULL: - plc->quoted = "NULL"; - plc->qlen = sizeof("NULL")-1; - plc->freeq = 0; + plc->quoted = ZSTR_KNOWN(ZEND_STR_NULL); break; - default: - buf = zval_get_string(parameter); - if (EG(exception) || - !stmt->dbh->methods->quoter(stmt->dbh, ZSTR_VAL(buf), - ZSTR_LEN(buf), &plc->quoted, &plc->qlen, - param_type)) { + default: { + buf = zval_try_get_string(parameter); + /* parameter does not have a string representation, buf == NULL */ + if (EG(exception)) { /* bork */ ret = -1; strncpy(stmt->error_code, stmt->dbh->error_code, 6); - if (buf) { - zend_string_release_ex(buf, 0); - } goto clean_up; } - plc->freeq = 1; + + plc->quoted = stmt->dbh->methods->quoter(stmt->dbh, buf, param_type); + } } if (buf) { @@ -317,10 +294,9 @@ safe: } else { parameter = ¶m->parameter; } - plc->quoted = Z_STRVAL_P(parameter); - plc->qlen = Z_STRLEN_P(parameter); + plc->quoted = zend_string_copy(Z_STR_P(parameter)); } - newbuffer_len += plc->qlen; + newbuffer_len += ZSTR_LEN(plc->quoted); } rewrite: @@ -339,8 +315,8 @@ rewrite: newbuffer += t; } if (plc->quoted) { - memcpy(newbuffer, plc->quoted, plc->qlen); - newbuffer += plc->qlen; + memcpy(newbuffer, ZSTR_VAL(plc->quoted), ZSTR_LEN(plc->quoted)); + newbuffer += ZSTR_LEN(plc->quoted); } else { memcpy(newbuffer, plc->pos, plc->len); newbuffer += plc->len; @@ -363,7 +339,6 @@ rewrite: } else if (query_type == PDO_PLACEHOLDER_POSITIONAL) { /* rewrite ? to :pdoX */ - char *name, *idxbuf; const char *tmpl = stmt->named_rewrite_template ? stmt->named_rewrite_template : ":pdo%d"; int bind_no = 1; @@ -376,36 +351,35 @@ rewrite: for (plc = placeholders; plc; plc = plc->next) { int skip_map = 0; - char *p; + zend_string *p; + zend_string *idxbuf; if (plc->bindno == PDO_PARSER_BINDNO_ESCAPED_CHAR) { continue; } - name = estrndup(plc->pos, plc->len); + zend_string *name = zend_string_init(plc->pos, plc->len, 0); /* check if bound parameter is already available */ - if (!strcmp(name, "?") || (p = zend_hash_str_find_ptr(stmt->bound_param_map, name, plc->len)) == NULL) { - spprintf(&idxbuf, 0, tmpl, bind_no++); + if (zend_string_equals_literal(name, "?") || (p = zend_hash_find_ptr(stmt->bound_param_map, name)) == NULL) { + idxbuf = zend_strpprintf(0, tmpl, bind_no++); } else { - idxbuf = estrdup(p); + idxbuf = zend_string_copy(p); skip_map = 1; } plc->quoted = idxbuf; - plc->qlen = strlen(plc->quoted); - plc->freeq = 1; - newbuffer_len += plc->qlen; + newbuffer_len += ZSTR_LEN(plc->quoted); if (!skip_map && stmt->named_rewrite_template) { /* create a mapping */ - zend_hash_str_update_mem(stmt->bound_param_map, name, plc->len, idxbuf, plc->qlen + 1); + zend_hash_update_ptr(stmt->bound_param_map, name, zend_string_copy(plc->quoted)); } /* map number to name */ - zend_hash_index_update_mem(stmt->bound_param_map, plc->bindno, idxbuf, plc->qlen + 1); + zend_hash_index_update_ptr(stmt->bound_param_map, plc->bindno, zend_string_copy(plc->quoted)); - efree(name); + zend_string_release(name); } goto rewrite; @@ -421,12 +395,9 @@ rewrite: } for (plc = placeholders; plc; plc = plc->next) { - char *name; - name = estrndup(plc->pos, plc->len); - zend_hash_index_update_mem(stmt->bound_param_map, plc->bindno, name, plc->len + 1); - efree(name); - plc->quoted = "?"; - plc->qlen = 1; + zend_string *name = zend_string_init(plc->pos, plc->len, 0); + zend_hash_index_update_ptr(stmt->bound_param_map, plc->bindno, name); + plc->quoted = ZSTR_CHAR('?'); newbuffer_len -= plc->len - 1; } @@ -438,11 +409,9 @@ clean_up: while (placeholders) { plc = placeholders; placeholders = plc->next; - - if (plc->freeq) { - efree(plc->quoted); + if (plc->quoted) { + zend_string_release_ex(plc->quoted, 0); } - efree(plc); } diff --git a/ext/pdo/pdo_stmt.c b/ext/pdo/pdo_stmt.c index fc12e44f10549..2744549d22db3 100644 --- a/ext/pdo/pdo_stmt.c +++ b/ext/pdo/pdo_stmt.c @@ -50,7 +50,7 @@ static inline bool rewrite_name_to_position(pdo_stmt_t *stmt, struct pdo_bound_p * we will raise an error, as we can't be sure that it is safe * to bind multiple parameters onto the same zval in the underlying * driver */ - char *name; + zend_string *name; int position = 0; if (stmt->named_rewrite_template) { @@ -60,7 +60,7 @@ static inline bool rewrite_name_to_position(pdo_stmt_t *stmt, struct pdo_bound_p if (!param->name) { /* do the reverse; map the parameter number to the name */ if ((name = zend_hash_index_find_ptr(stmt->bound_param_map, param->paramno)) != NULL) { - param->name = zend_string_init(name, strlen(name), 0); + param->name = zend_string_copy(name); return 1; } /* TODO Error? */ @@ -69,7 +69,7 @@ static inline bool rewrite_name_to_position(pdo_stmt_t *stmt, struct pdo_bound_p } ZEND_HASH_FOREACH_PTR(stmt->bound_param_map, name) { - if (strncmp(name, ZSTR_VAL(param->name), ZSTR_LEN(param->name) + 1)) { + if (!zend_string_equals(name, param->name)) { position++; continue; } diff --git a/ext/pdo/php_pdo_driver.h b/ext/pdo/php_pdo_driver.h index c6bdf49f8e14e..e31ea7ed1d719 100644 --- a/ext/pdo/php_pdo_driver.h +++ b/ext/pdo/php_pdo_driver.h @@ -236,7 +236,7 @@ typedef bool (*pdo_dbh_prepare_func)(pdo_dbh_t *dbh, zend_string *sql, pdo_stmt_ typedef zend_long (*pdo_dbh_do_func)(pdo_dbh_t *dbh, const char *sql, size_t sql_len); /* quote a string */ -typedef bool (*pdo_dbh_quote_func)(pdo_dbh_t *dbh, const char *unquoted, size_t unquotedlen, char **quoted, size_t *quotedlen, enum pdo_param_type paramtype); +typedef zend_string* (*pdo_dbh_quote_func)(pdo_dbh_t *dbh, const zend_string *unquoted, enum pdo_param_type paramtype); /* transaction related (beingTransaction(), commit, rollBack, inTransaction) * Return true if currently inside a transaction, false otherwise. */ diff --git a/ext/pdo_dblib/dblib_driver.c b/ext/pdo_dblib/dblib_driver.c index 00ba5308fcde1..5017d0cd417de 100644 --- a/ext/pdo_dblib/dblib_driver.c +++ b/ext/pdo_dblib/dblib_driver.c @@ -142,14 +142,14 @@ static zend_long dblib_handle_doer(pdo_dbh_t *dbh, const char *sql, size_t sql_l return DBCOUNT(H->link); } -static bool dblib_handle_quoter(pdo_dbh_t *dbh, const char *unquoted, size_t unquotedlen, char **quoted, size_t *quotedlen, enum pdo_param_type paramtype) +static zend_string* dblib_handle_quoter(pdo_dbh_t *dbh, const zend_string *unquoted, enum pdo_param_type paramtype) { pdo_dblib_db_handle *H = (pdo_dblib_db_handle *)dbh->driver_data; zend_bool use_national_character_set = 0; - size_t i; - char * q; - *quotedlen = 0; + char *q; + size_t quotedlen = 0; + zend_string *quoted_str; if (H->assume_national_character_set_strings) { use_national_character_set = 1; @@ -162,34 +162,34 @@ static bool dblib_handle_quoter(pdo_dbh_t *dbh, const char *unquoted, size_t unq } /* Detect quoted length, adding extra char for doubled single quotes */ - for (i = 0; i < unquotedlen; i++) { - if (unquoted[i] == '\'') ++*quotedlen; - ++*quotedlen; + for (i = 0; i < ZSTR_LEN(unquoted); i++) { + if (ZSTR_VAL(unquoted)[i] == '\'') ++quotedlen; + ++quotedlen; } - *quotedlen += 2; /* +2 for opening, closing quotes */ + quotedlen += 2; /* +2 for opening, closing quotes */ if (use_national_character_set) { - ++*quotedlen; /* N prefix */ + ++quotedlen; /* N prefix */ } - q = *quoted = emalloc(*quotedlen + 1); /* Add byte for terminal null */ + quoted_str = zend_string_alloc(quotedlen, 0); + q = ZSTR_VAL(quoted_str); if (use_national_character_set) { *q++ = 'N'; } *q++ = '\''; - for (i = 0; i < unquotedlen; i++) { - if (unquoted[i] == '\'') { + for (i = 0; i < ZSTR_LEN(unquoted); i++) { + if (ZSTR_VAL(unquoted)[i] == '\'') { *q++ = '\''; *q++ = '\''; } else { - *q++ = unquoted[i]; + *q++ = ZSTR_VAL(unquoted)[i]; } } *q++ = '\''; + *q = '\0'; - *q = 0; - - return true; + return quoted_str; } static bool pdo_dblib_transaction_cmd(const char *cmd, pdo_dbh_t *dbh) diff --git a/ext/pdo_firebird/firebird_driver.c b/ext/pdo_firebird/firebird_driver.c index d51ca61effc2f..858cf53035807 100644 --- a/ext/pdo_firebird/firebird_driver.c +++ b/ext/pdo_firebird/firebird_driver.c @@ -649,30 +649,29 @@ static zend_long firebird_handle_doer(pdo_dbh_t *dbh, const char *sql, size_t sq /* }}} */ /* called by the PDO SQL parser to add quotes to values that are copied into SQL */ -static bool firebird_handle_quoter(pdo_dbh_t *dbh, const char *unquoted, size_t unquotedlen, /* {{{ */ - char **quoted, size_t *quotedlen, enum pdo_param_type paramtype) +static zend_string* firebird_handle_quoter(pdo_dbh_t *dbh, const zend_string *unquoted, enum pdo_param_type paramtype) { int qcount = 0; char const *co, *l, *r; char *c; + size_t quotedlen; + zend_string *quoted_str; - if (!unquotedlen) { - *quotedlen = 2; - *quoted = emalloc(*quotedlen+1); - strcpy(*quoted, "''"); - return true; + if (ZSTR_LEN(unquoted) == 0) { + return zend_string_init("''", 2, 0); } /* Firebird only requires single quotes to be doubled if string lengths are used */ /* count the number of ' characters */ - for (co = unquoted; (co = strchr(co,'\'')); qcount++, co++); + for (co = ZSTR_VAL(unquoted); (co = strchr(co,'\'')); qcount++, co++); - *quotedlen = unquotedlen + qcount + 2; - *quoted = c = emalloc(*quotedlen+1); + quotedlen = ZSTR_LEN(unquoted) + qcount + 2; + quoted_str = zend_string_alloc(quotedlen, 0); + c = ZSTR_VAL(quoted_str); *c++ = '\''; /* foreach (chunk that ends in a quote) */ - for (l = unquoted; (r = strchr(l,'\'')); l = r+1) { + for (l = ZSTR_VAL(unquoted); (r = strchr(l,'\'')); l = r+1) { strncpy(c, l, r-l+1); c += (r-l+1); /* add the second quote */ @@ -680,11 +679,11 @@ static bool firebird_handle_quoter(pdo_dbh_t *dbh, const char *unquoted, size_t } /* copy the remainder */ - strncpy(c, l, *quotedlen-(c-*quoted)-1); - (*quoted)[*quotedlen-1] = '\''; - (*quoted)[*quotedlen] = '\0'; + strncpy(c, l, quotedlen-(c-ZSTR_VAL(quoted_str))-1); + ZSTR_VAL(quoted_str)[quotedlen-1] = '\''; + ZSTR_VAL(quoted_str)[quotedlen] = '\0'; - return true; + return quoted_str; } /* }}} */ diff --git a/ext/pdo_mysql/mysql_driver.c b/ext/pdo_mysql/mysql_driver.c index 70ca64a3e0af2..1c60dd5989842 100644 --- a/ext/pdo_mysql/mysql_driver.c +++ b/ext/pdo_mysql/mysql_driver.c @@ -301,10 +301,13 @@ static char *pdo_mysql_last_insert_id(pdo_dbh_t *dbh, const char *name, size_t * #endif /* {{{ mysql_handle_quoter */ -static bool mysql_handle_quoter(pdo_dbh_t *dbh, const char *unquoted, size_t unquotedlen, char **quoted, size_t *quotedlen, enum pdo_param_type paramtype ) +static zend_string* mysql_handle_quoter(pdo_dbh_t *dbh, const zend_string *unquoted, enum pdo_param_type paramtype ) { pdo_mysql_db_handle *H = (pdo_mysql_db_handle *)dbh->driver_data; zend_bool use_national_character_set = 0; + char *quoted; + size_t quotedlen; + zend_string *quoted_str; if (H->assume_national_character_set_strings) { use_national_character_set = 1; @@ -318,24 +321,27 @@ static bool mysql_handle_quoter(pdo_dbh_t *dbh, const char *unquoted, size_t unq PDO_DBG_ENTER("mysql_handle_quoter"); PDO_DBG_INF_FMT("dbh=%p", dbh); - PDO_DBG_INF_FMT("unquoted=%.*s", (int)unquotedlen, unquoted); - *quoted = safe_emalloc(2, unquotedlen, 3 + (use_national_character_set ? 1 : 0)); + PDO_DBG_INF_FMT("unquoted=%.*s", (int)ZSTR_LEN(unquoted), ZSTR_VAL(unquoted)); + quoted = safe_emalloc(2, ZSTR_LEN(unquoted), 3 + (use_national_character_set ? 1 : 0)); if (use_national_character_set) { - *quotedlen = mysql_real_escape_string_quote(H->server, *quoted + 2, unquoted, unquotedlen, '\''); - (*quoted)[0] = 'N'; - (*quoted)[1] = '\''; + quotedlen = mysql_real_escape_string_quote(H->server, quoted + 2, ZSTR_VAL(unquoted), ZSTR_LEN(unquoted), '\''); + quoted[0] = 'N'; + quoted[1] = '\''; - ++*quotedlen; /* N prefix */ + ++quotedlen; /* N prefix */ } else { - *quotedlen = mysql_real_escape_string_quote(H->server, *quoted + 1, unquoted, unquotedlen, '\''); - (*quoted)[0] = '\''; + quotedlen = mysql_real_escape_string_quote(H->server, quoted + 1, ZSTR_VAL(unquoted), ZSTR_LEN(unquoted), '\''); + quoted[0] = '\''; } - (*quoted)[++*quotedlen] = '\''; - (*quoted)[++*quotedlen] = '\0'; - PDO_DBG_INF_FMT("quoted=%.*s", (int)*quotedlen, *quoted); - PDO_DBG_RETURN(true); + quoted[++quotedlen] = '\''; + quoted[++quotedlen] = '\0'; + PDO_DBG_INF_FMT("quoted=%.*s", (int)quotedlen, quoted); + + quoted_str = zend_string_init(quoted, quotedlen, 0); + efree(quoted); + PDO_DBG_RETURN(quoted_str); } /* }}} */ diff --git a/ext/pdo_oci/oci_driver.c b/ext/pdo_oci/oci_driver.c index fbe70a5df867b..415af87c669b1 100644 --- a/ext/pdo_oci/oci_driver.c +++ b/ext/pdo_oci/oci_driver.c @@ -350,40 +350,40 @@ static zend_long oci_handle_doer(pdo_dbh_t *dbh, const char *sql, size_t sql_len } /* }}} */ -static bool oci_handle_quoter(pdo_dbh_t *dbh, const char *unquoted, size_t unquotedlen, char **quoted, size_t *quotedlen, enum pdo_param_type paramtype ) /* {{{ */ +static zend_string* oci_handle_quoter(pdo_dbh_t *dbh, const zend_string *unquoted, enum pdo_param_type paramtype ) /* {{{ */ { int qcount = 0; char const *cu, *l, *r; - char *c; + char *c, *quoted; + zend_string *quoted_str; - if (!unquotedlen) { - *quotedlen = 2; - *quoted = emalloc(*quotedlen+1); - strcpy(*quoted, "''"); - return true; + if (ZSTR_LEN(unquoted) == 0) { + return zend_string_init("''", 2, 0); } /* count single quotes */ - for (cu = unquoted; (cu = strchr(cu,'\'')); qcount++, cu++) + for (cu = ZSTR_VAL(unquoted); (cu = strchr(cu,'\'')); qcount++, cu++) ; /* empty loop */ - *quotedlen = unquotedlen + qcount + 2; - *quoted = c = emalloc(*quotedlen+1); + quotedlen = ZSTR_LEN(unquoted) + qcount + 2; + quoted = c = emalloc(quotedlen+1); *c++ = '\''; /* foreach (chunk that ends in a quote) */ - for (l = unquoted; (r = strchr(l,'\'')); l = r+1) { + for (l = ZSTR_VAL(unquoted); (r = strchr(l,'\'')); l = r+1) { strncpy(c, l, r-l+1); c += (r-l+1); *c++ = '\''; /* add second quote */ } /* Copy remainder and add enclosing quote */ - strncpy(c, l, *quotedlen-(c-*quoted)-1); - (*quoted)[*quotedlen-1] = '\''; - (*quoted)[*quotedlen] = '\0'; + strncpy(c, l, quotedlen-(c-quoted)-1); + quoted[quotedlen-1] = '\''; + quoted[quotedlen] = '\0'; - return true; + quoted_str = zend_string_init(quoted, quotedlen, 0); + efree(quoted); + return quoted_str; } /* }}} */ diff --git a/ext/pdo_pgsql/pgsql_driver.c b/ext/pdo_pgsql/pgsql_driver.c index c7f9d46f7fa81..1377f7096979e 100644 --- a/ext/pdo_pgsql/pgsql_driver.c +++ b/ext/pdo_pgsql/pgsql_driver.c @@ -317,33 +317,39 @@ static zend_long pgsql_handle_doer(pdo_dbh_t *dbh, const char *sql, size_t sql_l return ret; } -static bool pgsql_handle_quoter(pdo_dbh_t *dbh, const char *unquoted, size_t unquotedlen, char **quoted, size_t *quotedlen, enum pdo_param_type paramtype) +static zend_string* pgsql_handle_quoter(pdo_dbh_t *dbh, const zend_string *unquoted, enum pdo_param_type paramtype) { unsigned char *escaped; + char *quoted; + size_t quotedlen; + zend_string *quoted_str; pdo_pgsql_db_handle *H = (pdo_pgsql_db_handle *)dbh->driver_data; size_t tmp_len; switch (paramtype) { case PDO_PARAM_LOB: /* escapedlen returned by PQescapeBytea() accounts for trailing 0 */ - escaped = PQescapeByteaConn(H->server, (unsigned char *)unquoted, unquotedlen, &tmp_len); - *quotedlen = tmp_len + 1; - *quoted = emalloc(*quotedlen + 1); - memcpy((*quoted)+1, escaped, *quotedlen-2); - (*quoted)[0] = '\''; - (*quoted)[*quotedlen-1] = '\''; - (*quoted)[*quotedlen] = '\0'; + escaped = PQescapeByteaConn(H->server, (unsigned char *)ZSTR_VAL(unquoted), ZSTR_LEN(unquoted), &tmp_len); + quotedlen = tmp_len + 1; + quoted = emalloc(quotedlen + 1); + memcpy(quoted+1, escaped, quotedlen-2); + quoted[0] = '\''; + quoted[quotedlen-1] = '\''; + quoted[quotedlen] = '\0'; PQfreemem(escaped); break; default: - *quoted = safe_emalloc(2, unquotedlen, 3); - (*quoted)[0] = '\''; - *quotedlen = PQescapeStringConn(H->server, *quoted + 1, unquoted, unquotedlen, NULL); - (*quoted)[*quotedlen + 1] = '\''; - (*quoted)[*quotedlen + 2] = '\0'; - *quotedlen += 2; + quoted = safe_emalloc(2, ZSTR_LEN(unquoted), 3); + quoted[0] = '\''; + quotedlen = PQescapeStringConn(H->server, quoted + 1, ZSTR_VAL(unquoted), ZSTR_LEN(unquoted), NULL); + quoted[quotedlen + 1] = '\''; + quoted[quotedlen + 2] = '\0'; + quotedlen += 2; } - return true; + + quoted_str = zend_string_init(quoted, quotedlen, 0); + efree(quoted); + return quoted_str; } static char *pdo_pgsql_last_insert_id(pdo_dbh_t *dbh, const char *name, size_t *len) diff --git a/ext/pdo_pgsql/pgsql_statement.c b/ext/pdo_pgsql/pgsql_statement.c index 98ea8cb7803c3..c136d69c52b7d 100644 --- a/ext/pdo_pgsql/pgsql_statement.c +++ b/ext/pdo_pgsql/pgsql_statement.c @@ -275,11 +275,11 @@ static int pgsql_stmt_param_hook(pdo_stmt_t *stmt, struct pdo_bound_param_data * ZEND_ATOL(param->paramno, ZSTR_VAL(param->name) + 1); } else { /* resolve parameter name to rewritten name */ - char *namevar; + zend_string *namevar; if (stmt->bound_param_map && (namevar = zend_hash_find_ptr(stmt->bound_param_map, param->name)) != NULL) { - ZEND_ATOL(param->paramno, namevar + 1); + ZEND_ATOL(param->paramno, ZSTR_VAL(namevar) + 1); param->paramno--; } else { pdo_pgsql_error_stmt_msg(stmt, 0, "HY093", ZSTR_VAL(param->name)); diff --git a/ext/pdo_sqlite/sqlite_driver.c b/ext/pdo_sqlite/sqlite_driver.c index 344850b099062..ca069ec300403 100644 --- a/ext/pdo_sqlite/sqlite_driver.c +++ b/ext/pdo_sqlite/sqlite_driver.c @@ -227,12 +227,14 @@ static char *pdo_sqlite_last_insert_id(pdo_dbh_t *dbh, const char *name, size_t } /* NB: doesn't handle binary strings... use prepared stmts for that */ -static bool sqlite_handle_quoter(pdo_dbh_t *dbh, const char *unquoted, size_t unquotedlen, char **quoted, size_t *quotedlen, enum pdo_param_type paramtype ) +static zend_string* sqlite_handle_quoter(pdo_dbh_t *dbh, const zend_string *unquoted, enum pdo_param_type paramtype) { - *quoted = safe_emalloc(2, unquotedlen, 3); - sqlite3_snprintf(2*unquotedlen + 3, *quoted, "'%q'", unquoted); - *quotedlen = strlen(*quoted); - return true; + char *quoted = safe_emalloc(2, ZSTR_LEN(unquoted), 3); + /* TODO use %Q format? */ + sqlite3_snprintf(2*ZSTR_LEN(unquoted) + 3, quoted, "'%q'", ZSTR_VAL(unquoted)); + zend_string *quoted_str = zend_string_init(quoted, strlen(quoted), 0); + efree(quoted); + return quoted_str; } static bool sqlite_handle_begin(pdo_dbh_t *dbh)